aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore46
-rw-r--r--Makefile.am8
-rw-r--r--README2
-rw-r--r--README.vty-tests2
-rw-r--r--TODO-RELEASE2
-rw-r--r--configure.ac180
-rw-r--r--contrib/Makefile.am2
-rwxr-xr-xcontrib/ipa.py278
-rwxr-xr-xcontrib/jenkins.sh38
-rwxr-xr-xcontrib/soap.py188
-rw-r--r--contrib/systemd/Makefile.am13
-rw-r--r--contrib/systemd/osmo-gtphub.service12
-rw-r--r--contrib/systemd/osmo-sgsn.service2
-rwxr-xr-xcontrib/twisted_ipa.py384
-rw-r--r--debian/changelog444
-rw-r--r--debian/control33
-rw-r--r--debian/copyright237
-rw-r--r--debian/osmo-gbproxy.install5
-rw-r--r--debian/osmo-gtphub.install5
-rw-r--r--debian/osmo-sgsn-doc.install1
-rw-r--r--debian/osmo-sgsn.install5
-rwxr-xr-xdebian/rules18
-rw-r--r--doc/Makefile.am1
-rw-r--r--doc/examples/Makefile.am10
-rw-r--r--doc/examples/osmo-gbproxy/osmo-gbproxy-legacy.cfg28
-rw-r--r--doc/examples/osmo-gbproxy/osmo-gbproxy.cfg1
-rw-r--r--doc/examples/osmo-gtphub/gtphub-example.txt2
-rw-r--r--doc/examples/osmo-gtphub/osmo-gtphub.cfg2
-rw-r--r--doc/examples/osmo-sgsn/osmo-sgsn-accept-all.cfg2
-rw-r--r--doc/examples/osmo-sgsn/osmo-sgsn.cfg2
-rw-r--r--doc/examples/osmo-sgsn/osmo-sgsn_custom-sccp.cfg39
-rw-r--r--doc/manuals/Makefile.am23
-rw-r--r--doc/manuals/chapters/configuration.adoc378
-rw-r--r--doc/manuals/chapters/control.adoc23
-rw-r--r--doc/manuals/chapters/counters.adoc4
-rw-r--r--doc/manuals/chapters/counters_generated.adoc82
-rw-r--r--doc/manuals/chapters/gbproxy-configuration.adoc6
-rw-r--r--doc/manuals/chapters/gbproxy-control.adoc29
-rw-r--r--doc/manuals/chapters/gbproxy-overview.adoc127
-rw-r--r--doc/manuals/chapters/gbproxy-running.adoc39
-rw-r--r--doc/manuals/chapters/overview.adoc109
-rw-r--r--doc/manuals/chapters/running.adoc35
-rw-r--r--doc/manuals/osmogbproxy-usermanual-docinfo.xml46
-rw-r--r--doc/manuals/osmogbproxy-usermanual.adoc34
-rw-r--r--doc/manuals/osmogbproxy-vty-reference.xml38
-rw-r--r--doc/manuals/osmosgsn-usermanual-docinfo.xml54
-rw-r--r--doc/manuals/osmosgsn-usermanual.adoc40
-rw-r--r--doc/manuals/osmosgsn-vty-reference.xml44
-rwxr-xr-xdoc/manuals/regen_doc.sh77
-rw-r--r--doc/manuals/vty-osmogbproxy/gbproxy_vty_additions.xml5
-rw-r--r--doc/manuals/vty-osmogbproxy/gbproxy_vty_reference.xml1627
-rw-r--r--doc/manuals/vty/sgsn_vty_additions.xml6
-rw-r--r--doc/manuals/vty/sgsn_vty_reference.xml2536
-rwxr-xr-xgit-version-gen4
-rw-r--r--include/Makefile.am2
-rw-r--r--include/openbsc/gprs_gmm.h35
-rw-r--r--include/openbsc/gsup_client.h63
-rw-r--r--include/openbsc/oap_client.h82
-rw-r--r--include/openbsc/rest_octets.h139
-rw-r--r--include/osmocom/Makefile.am3
-rw-r--r--include/osmocom/sgsn/Makefile.am (renamed from include/openbsc/Makefile.am)10
-rw-r--r--include/osmocom/sgsn/common.h (renamed from include/openbsc/common.h)0
-rw-r--r--include/osmocom/sgsn/crc24.h (renamed from include/openbsc/crc24.h)0
-rw-r--r--include/osmocom/sgsn/debug.h (renamed from include/openbsc/debug.h)3
-rw-r--r--include/osmocom/sgsn/gb_proxy.h (renamed from include/openbsc/gb_proxy.h)100
-rw-r--r--include/osmocom/sgsn/gprs_gb.h14
-rw-r--r--include/osmocom/sgsn/gprs_gb_parse.h (renamed from include/openbsc/gprs_gb_parse.h)2
-rw-r--r--include/osmocom/sgsn/gprs_gmm.h47
-rw-r--r--include/osmocom/sgsn/gprs_gmm_attach.h39
-rw-r--r--include/osmocom/sgsn/gprs_gmm_fsm.h42
-rw-r--r--include/osmocom/sgsn/gprs_llc.h (renamed from include/openbsc/gprs_llc.h)27
-rw-r--r--include/osmocom/sgsn/gprs_llc_xid.h (renamed from include/openbsc/gprs_llc_xid.h)0
-rw-r--r--include/osmocom/sgsn/gprs_mm_state_gb_fsm.h26
-rw-r--r--include/osmocom/sgsn/gprs_mm_state_iu_fsm.h25
-rw-r--r--include/osmocom/sgsn/gprs_ranap.h34
-rw-r--r--include/osmocom/sgsn/gprs_sgsn.h (renamed from include/openbsc/gprs_sgsn.h)110
-rw-r--r--include/osmocom/sgsn/gprs_sm.h15
-rw-r--r--include/osmocom/sgsn/gprs_sndcp.h (renamed from include/openbsc/gprs_sndcp.h)0
-rw-r--r--include/osmocom/sgsn/gprs_sndcp_comp.h (renamed from include/openbsc/gprs_sndcp_comp.h)8
-rw-r--r--include/osmocom/sgsn/gprs_sndcp_dcomp.h (renamed from include/openbsc/gprs_sndcp_dcomp.h)2
-rw-r--r--include/osmocom/sgsn/gprs_sndcp_pcomp.h (renamed from include/openbsc/gprs_sndcp_pcomp.h)2
-rw-r--r--include/osmocom/sgsn/gprs_sndcp_xid.h (renamed from include/openbsc/gprs_sndcp_xid.h)36
-rw-r--r--include/osmocom/sgsn/gprs_subscriber.h (renamed from include/openbsc/gprs_subscriber.h)4
-rw-r--r--include/osmocom/sgsn/gprs_utils.h (renamed from include/openbsc/gprs_utils.h)3
-rw-r--r--include/osmocom/sgsn/gtphub.h (renamed from include/openbsc/gtphub.h)2
-rw-r--r--include/osmocom/sgsn/sgsn.h (renamed from include/openbsc/sgsn.h)56
-rw-r--r--include/osmocom/sgsn/signal.h (renamed from include/openbsc/signal.h)0
-rw-r--r--include/osmocom/sgsn/slhc.h (renamed from include/openbsc/slhc.h)0
-rw-r--r--include/osmocom/sgsn/v42bis.h (renamed from include/openbsc/v42bis.h)2
-rw-r--r--include/osmocom/sgsn/v42bis_private.h (renamed from include/openbsc/v42bis_private.h)2
-rw-r--r--include/osmocom/sgsn/vty.h (renamed from include/openbsc/vty.h)0
-rw-r--r--osmo-sgsn.pc.in10
-rw-r--r--osmoappdesc.py10
-rw-r--r--src/Makefile.am3
-rw-r--r--src/gbproxy/Makefile.am46
-rw-r--r--src/gbproxy/gb_proxy.c (renamed from src/gprs/gb_proxy.c)175
-rw-r--r--src/gbproxy/gb_proxy_ctrl.c98
-rw-r--r--src/gbproxy/gb_proxy_main.c (renamed from src/gprs/gb_proxy_main.c)110
-rw-r--r--src/gbproxy/gb_proxy_patch.c (renamed from src/gprs/gb_proxy_patch.c)73
-rw-r--r--src/gbproxy/gb_proxy_peer.c (renamed from src/gprs/gb_proxy_peer.c)45
-rw-r--r--src/gbproxy/gb_proxy_tlli.c (renamed from src/gprs/gb_proxy_tlli.c)26
-rw-r--r--src/gbproxy/gb_proxy_vty.c (renamed from src/gprs/gb_proxy_vty.c)151
-rw-r--r--src/gprs/Makefile.am96
-rw-r--r--src/gprs/crc24.c2
-rw-r--r--src/gprs/gprs_gb_parse.c38
-rw-r--r--src/gprs/gprs_llc_parse.c10
-rw-r--r--src/gprs/gprs_utils.c94
-rw-r--r--src/gprs/gsup_client.c355
-rw-r--r--src/gprs/oap_client.c280
-rw-r--r--src/gprs/osmo_sgsn.cfg23
-rw-r--r--src/gprs/sgsn_ares.c22
-rw-r--r--src/gtphub/Makefile.am45
-rw-r--r--src/gtphub/gtphub.c (renamed from src/gprs/gtphub.c)63
-rw-r--r--src/gtphub/gtphub_ares.c (renamed from src/gprs/gtphub_ares.c)6
-rw-r--r--src/gtphub/gtphub_main.c (renamed from src/gprs/gtphub_main.c)42
-rw-r--r--src/gtphub/gtphub_sock.c (renamed from src/gprs/gtphub_sock.c)4
-rw-r--r--src/gtphub/gtphub_vty.c (renamed from src/gprs/gtphub_vty.c)11
-rw-r--r--src/libcommon/Makefile.am47
-rw-r--r--src/libcommon/bsc_version.c30
-rw-r--r--src/libcommon/common_vty.c152
-rw-r--r--src/libcommon/debug.c232
-rw-r--r--src/libcommon/gsm_data.c459
-rw-r--r--src/libcommon/gsm_data_shared.c853
-rw-r--r--src/libcommon/gsm_subscriber_base.c64
-rw-r--r--src/libcommon/gsup_client.c347
-rw-r--r--src/libcommon/gsup_test_client.c298
-rw-r--r--src/libcommon/oap_client.c280
-rw-r--r--src/libcommon/socket.c111
-rw-r--r--src/libcommon/talloc_ctx.c55
-rw-r--r--src/sgsn/Makefile.am93
-rw-r--r--src/sgsn/gprs_gb.c105
-rw-r--r--src/sgsn/gprs_gmm.c (renamed from src/gprs/gprs_gmm.c)1601
-rw-r--r--src/sgsn/gprs_gmm_attach.c461
-rw-r--r--src/sgsn/gprs_gmm_fsm.c210
-rw-r--r--src/sgsn/gprs_llc.c (renamed from src/gprs/gprs_llc.c)180
-rw-r--r--src/sgsn/gprs_llc_vty.c (renamed from src/gprs/gprs_llc_vty.c)8
-rw-r--r--src/sgsn/gprs_llc_xid.c (renamed from src/gprs/gprs_llc_xid.c)10
-rw-r--r--src/sgsn/gprs_mm_state_gb_fsm.c129
-rw-r--r--src/sgsn/gprs_mm_state_iu_fsm.c150
-rw-r--r--src/sgsn/gprs_ranap.c260
-rw-r--r--src/sgsn/gprs_sgsn.c (renamed from src/gprs/gprs_sgsn.c)358
-rw-r--r--src/sgsn/gprs_sm.c754
-rw-r--r--src/sgsn/gprs_sndcp.c (renamed from src/gprs/gprs_sndcp.c)51
-rw-r--r--src/sgsn/gprs_sndcp_comp.c (renamed from src/gprs/gprs_sndcp_comp.c)39
-rw-r--r--src/sgsn/gprs_sndcp_dcomp.c (renamed from src/gprs/gprs_sndcp_dcomp.c)26
-rw-r--r--src/sgsn/gprs_sndcp_pcomp.c (renamed from src/gprs/gprs_sndcp_pcomp.c)24
-rw-r--r--src/sgsn/gprs_sndcp_vty.c (renamed from src/gprs/gprs_sndcp_vty.c)8
-rw-r--r--src/sgsn/gprs_sndcp_xid.c (renamed from src/gprs/gprs_sndcp_xid.c)185
-rw-r--r--src/sgsn/gprs_subscriber.c (renamed from src/gprs/gprs_subscriber.c)60
-rw-r--r--src/sgsn/sgsn_auth.c (renamed from src/gprs/sgsn_auth.c)26
-rw-r--r--src/sgsn/sgsn_cdr.c (renamed from src/gprs/sgsn_cdr.c)126
-rw-r--r--src/sgsn/sgsn_ctrl.c (renamed from src/gprs/sgsn_ctrl.c)12
-rw-r--r--src/sgsn/sgsn_libgtp.c (renamed from src/gprs/sgsn_libgtp.c)266
-rw-r--r--src/sgsn/sgsn_main.c (renamed from src/gprs/sgsn_main.c)162
-rw-r--r--src/sgsn/sgsn_vty.c (renamed from src/gprs/sgsn_vty.c)487
-rw-r--r--src/sgsn/slhc.c (renamed from src/gprs/slhc.c)4
-rw-r--r--src/sgsn/v42bis.c (renamed from src/gprs/v42bis.c)8
-rw-r--r--tests/Makefile.am44
-rw-r--r--tests/atlocal.in4
-rwxr-xr-x[-rw-r--r--]tests/ctrl_test_runner.py409
-rw-r--r--tests/gbproxy/Makefile.am12
-rw-r--r--tests/gbproxy/gbproxy_test.c242
-rw-r--r--tests/gbproxy/gbproxy_test.ok1002
-rw-r--r--tests/gprs/gprs_test.c9
-rw-r--r--tests/gtphub/Makefile.am6
-rw-r--r--tests/gtphub/gtphub_test.c11
-rw-r--r--tests/oap/Makefile.am36
-rw-r--r--tests/oap/oap_client_test.c270
-rw-r--r--tests/oap/oap_client_test.err35
-rw-r--r--tests/oap/oap_client_test.ok2
-rw-r--r--tests/sgsn/Makefile.am51
-rw-r--r--tests/sgsn/sgsn_test.c933
-rw-r--r--tests/sgsn/sgsn_test.ok19
-rw-r--r--tests/slhc/Makefile.am2
-rw-r--r--tests/slhc/slhc_test.c11
-rw-r--r--tests/sndcp_xid/Makefile.am3
-rw-r--r--tests/sndcp_xid/sndcp_xid_test.c21
-rw-r--r--tests/test_nodes.vty63
-rw-r--r--tests/testsuite.at8
-rw-r--r--tests/v42bis/Makefile.am2
-rw-r--r--tests/v42bis/v42bis_test.c13
-rwxr-xr-x[-rw-r--r--]tests/vty_test_runner.py167
-rw-r--r--tests/xid/Makefile.am3
-rw-r--r--tests/xid/xid_test.c11
184 files changed, 12424 insertions, 9827 deletions
diff --git a/.gitignore b/.gitignore
index a9e6b846c..b3e50f55e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,20 +2,12 @@ debian/*.log
*.o
*.lo
*.a
+*.la
.deps
Makefile
Makefile.in
bscconfig.h
bscconfig.h.in
-openbsc.pc
-src/osmo-nitb/osmo-nitb
-src/osmo-bsc_mgcp/osmo-bsc_mgcp
-src/osmo-bsc/osmo-bsc
-src/utils/meas_vis
-src/utils/meas_json
-src/utils/osmo-meas-pcap2db
-src/utils/osmo-meas-udp2db
-src/utils/smpp_mirror
*.*~
*.sw?
.libs
@@ -26,6 +18,8 @@ src/utils/smpp_mirror
#configure
aclocal.m4
autom4te.cache/
+m4/*.m4
+!m4/ax_*.m4
config.log
config.status
config.guess
@@ -45,30 +39,14 @@ ltmain.sh
# apps and app data
-hlr.sqlite3
-src/utils/bs11_config
-src/ipaccess/ipaccess-config
-src/ipaccess/abisip-find
-src/ipaccess/ipaccess-firmware
-src/ipaccess/ipaccess-proxy
-src/utils/isdnsync
-src/nat/bsc_nat
-src/gprs/osmo-sgsn
-src/gprs/osmo-gbproxy
-src/gprs/osmo-gtphub
-src/osmo-bsc_nat/osmo-bsc_nat
+src/sgsn/osmo-sgsn
+src/gbproxy/osmo-gbproxy
+src/gtphub/osmo-gtphub
src/libcommon/gsup_test_client
-src/osmo-msc/osmo-msc
#tests
tests/testsuite.dir
tests/*/*_test
-# ignore compiled binaries like msc_vlr_test_foo; do not ignore
-# msc_vlr_test_foo.{c,ok,err}, but do still ignore the corresponding .o object
-# files:
-tests/msc_vlr/msc_vlr_test_*
-!tests/msc_vlr/msc_vlr_test_*.*
-tests/msc_vlr/msc_vlr_test_*.o
tests/atconfig
@@ -78,6 +56,16 @@ tests/testsuite
tests/testsuite.log
gsn_restart
-src/openbsc.cfg*
writtenconfig/
gtphub_restart_count
+
+# manuals
+doc/manuals/*.html
+doc/manuals/*.svg
+doc/manuals/*.pdf
+doc/manuals/*__*.png
+doc/manuals/*.check
+doc/manuals/generated/
+doc/manuals/osmomsc-usermanual.xml
+doc/manuals/common
+doc/manuals/build
diff --git a/Makefile.am b/Makefile.am
index d57b66d8d..3f89896a3 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -12,16 +12,16 @@ SUBDIRS = \
doc \
include \
src \
- tests \
contrib \
+ tests \
$(NULL)
-pkgconfigdir = $(libdir)/pkgconfig
-pkgconfig_DATA = osmo-sgsn.pc
-
BUILT_SOURCES = $(top_srcdir)/.version
EXTRA_DIST = git-version-gen osmoappdesc.py .version
+AM_DISTCHECK_CONFIGURE_FLAGS = \
+ --with-systemdsystemunitdir=$$dc_install_base/$(systemdsystemunitdir)
+
@RELMAKE@
$(top_srcdir)/.version:
diff --git a/README b/README
index b968211fa..a14ba3803 100644
--- a/README
+++ b/README
@@ -9,7 +9,7 @@ OsmoSGSN exposes
- GSUP towards OsmoHLR (or a MAP proxy);
- GTP towards a GGSN (e.g. OsmoGGSN);
- Gb towards a BSS (e.g. OsmoPCU);
-- IuPS towards a HNB-GW (e.g. OsmoHNBGW) for 3G data;
+- IuPS towards an RNC or HNB-GW (e.g. OsmoHNBGW) for 3G data;
- The Osmocom typical telnet VTY and CTRL interfaces.
Find OsmoSGSN issue tracker and wiki online at
diff --git a/README.vty-tests b/README.vty-tests
index ba1b87cb0..0669ea8e8 100644
--- a/README.vty-tests
+++ b/README.vty-tests
@@ -4,7 +4,7 @@ To run the configuration parsing and output (VTY) test suite, first install
and pass the following configure options here:
- ./configure --enable-vty-tests --enable-external-tests
+ ./configure --enable-external-tests
The VTY tests are then included in the standard check target:
diff --git a/TODO-RELEASE b/TODO-RELEASE
new file mode 100644
index 000000000..3096c4b54
--- /dev/null
+++ b/TODO-RELEASE
@@ -0,0 +1,2 @@
+#component what description / commit summary line
+manual needs common chapter cs7-config.adoc from osmo-gsm-manuals > 0.3.0
diff --git a/configure.ac b/configure.ac
index f1167d6d1..5c0beded7 100644
--- a/configure.ac
+++ b/configure.ac
@@ -22,6 +22,11 @@ AC_PROG_CC
AC_PROG_INSTALL
LT_INIT
+dnl patching ${archive_cmds} to affect generation of file "libtool" to fix linking with clang
+AS_CASE(["$LD"],[*clang*],
+ [AS_CASE(["${host_os}"],
+ [*linux*],[archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'])])
+
dnl check for pkg-config (explained in detail in libosmocore/configure.ac)
AC_PATH_PROG(PKG_CONFIG_INSTALLED, pkg-config, no)
if test "x$PKG_CONFIG_INSTALLED" = "xno"; then
@@ -38,64 +43,69 @@ dnl checks for libraries
AC_SEARCH_LIBS([dlopen], [dl dld], [LIBRARY_DL="$LIBS";LIBS=""])
AC_SUBST(LIBRARY_DL)
+AC_SEARCH_LIBS([dlsym], [dl dld], [LIBRARY_DLSYM="$LIBS";LIBS=""])
+AC_SUBST(LIBRARY_DLSYM)
+
-PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore >= 0.9.5)
-PKG_CHECK_MODULES(LIBOSMOVTY, libosmovty >= 0.3.0)
-PKG_CHECK_MODULES(LIBOSMOCTRL, libosmoctrl)
-PKG_CHECK_MODULES(LIBOSMOGSM, libosmogsm >= 0.9.5)
-PKG_CHECK_MODULES(LIBOSMOABIS, libosmoabis >= 0.2.0)
-PKG_CHECK_MODULES(LIBOSMOGB, libosmogb >= 0.6.4)
-PKG_CHECK_MODULES(LIBOSMONETIF, libosmo-netif >= 0.0.1)
-PKG_CHECK_MODULES(LIBOSMOSIGTRAN, libosmo-sigtran) # TODO version?
-PKG_CHECK_MODULES(LIBCRYPTO, libcrypto >= 0.9.5)
+PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore >= 1.2.0)
+PKG_CHECK_MODULES(LIBOSMOVTY, libosmovty >= 1.2.0)
+PKG_CHECK_MODULES(LIBOSMOCTRL, libosmoctrl >= 1.2.0)
+PKG_CHECK_MODULES(LIBOSMOGSM, libosmogsm >= 1.2.0)
+PKG_CHECK_MODULES(LIBOSMOGB, libosmogb >= 1.2.0)
+PKG_CHECK_MODULES(LIBOSMOABIS, libosmoabis >= 0.6.0)
+PKG_CHECK_MODULES(LIBOSMONETIF, libosmo-netif >= 0.4.0)
+PKG_CHECK_MODULES(LIBOSMOGSUPCLIENT, libosmo-gsup-client >= 1.0.0)
# Enable/disable 3G aka IuPS + IuCS support?
-AC_ARG_ENABLE([iu], [AS_HELP_STRING([--disable-iu], [Build without 3G support, i.e. without IuPS and IuCS interfaces])],
- [osmo_ac_iu="$enableval"],[osmo_ac_iu="yes"])
+AC_ARG_ENABLE([iu], [AS_HELP_STRING([--enable-iu], [Build 3G support, aka IuPS and IuCS interfaces])],
+ [osmo_ac_iu="$enableval"],[osmo_ac_iu="no"])
if test "x$osmo_ac_iu" = "xyes" ; then
- PKG_CHECK_MODULES(LIBASN1C, libasn1c, [], [AC_MSG_ERROR(libasn1c not found. Build with --disable-iu?)]) # TODO version?
- PKG_CHECK_MODULES(LIBOSMORANAP, libosmo-ranap, [], [AC_MSG_ERROR(libosmo-ranap not found. Build with --disable-iu?)]) # TODO version?
+ PKG_CHECK_MODULES(LIBOSMOSIGTRAN, libosmo-sigtran >= 1.0.0)
+ PKG_CHECK_MODULES(LIBASN1C, libasn1c >= 0.9.30)
+ PKG_CHECK_MODULES(LIBOSMORANAP, libosmo-ranap >= 0.6.0)
AC_DEFINE(BUILD_IU, 1, [Define if we want to build IuPS and IuCS interfaces support])
fi
AM_CONDITIONAL(BUILD_IU, test "x$osmo_ac_iu" = "xyes")
AC_SUBST(osmo_ac_iu)
-found_libgtp=yes
-PKG_CHECK_MODULES(LIBGTP, libgtp >= 0.92, , found_libgtp=no)
-AM_CONDITIONAL(HAVE_LIBGTP, test "$found_libgtp" = yes)
-AC_SUBST(found_libgtp)
-
-found_libcares=yes
-PKG_CHECK_MODULES([LIBCARES], [libcares], [], [found_libcares=no])
-AM_CONDITIONAL(HAVE_LIBCARES, test "$found_libcares" = yes)
-AC_SUBST(found_libcares)
-
-found_libgtp_and_libcares=no
-if test "$found_libgtp" = "yes" -a "$found_libcares" = "yes"; then
- found_libgtp_and_libcares=yes
-fi
-AC_SUBST(found_libgtp_and_libcares)
+PKG_CHECK_MODULES(LIBGTP, libgtp >= 1.5.0)
+PKG_CHECK_MODULES(LIBCARES, libcares)
dnl checks for header files
AC_HEADER_STDC
-AC_CHECK_HEADERS(dbi/dbd.h,,AC_MSG_ERROR(DBI library is not installed))
-
-found_pcap=yes
-AC_CHECK_HEADERS(pcap/pcap.h,,found_pcap=no)
-AM_CONDITIONAL(HAVE_PCAP, test "$found_pcap" = yes)
-
-found_cdk=yes
-AC_CHECK_HEADERS(cdk/cdk.h,,found_cdk=no)
-AM_CONDITIONAL(HAVE_LIBCDK, test "$found_cdk" = yes)
-found_sqlite3=yes
-PKG_CHECK_MODULES(SQLITE3, sqlite3, ,found_sqlite3=no)
-AM_CONDITIONAL(HAVE_SQLITE3, test "$found_sqlite3" = yes)
-AC_SUBST(found_sqlite3)
+dnl Checks for typedefs, structures and compiler characteristics
+AC_ARG_ENABLE(sanitize,
+ [AS_HELP_STRING(
+ [--enable-sanitize],
+ [Compile with address sanitizer enabled],
+ )],
+ [sanitize=$enableval], [sanitize="no"])
+if test x"$sanitize" = x"yes"
+then
+ CFLAGS="$CFLAGS -fsanitize=address -fsanitize=undefined"
+ CPPFLAGS="$CPPFLAGS -fsanitize=address -fsanitize=undefined"
+fi
-dnl Checks for typedefs, structures and compiler characteristics
+AC_ARG_ENABLE(werror,
+ [AS_HELP_STRING(
+ [--enable-werror],
+ [Turn all compiler warnings into errors, with exceptions:
+ a) deprecation (allow upstream to mark deprecation without breaking builds);
+ b) "#warning" pragmas (allow to remind ourselves of errors without breaking builds)
+ ]
+ )],
+ [werror=$enableval], [werror="no"])
+if test x"$werror" = x"yes"
+then
+ WERROR_FLAGS="-Werror"
+ WERROR_FLAGS+=" -Wno-error=deprecated -Wno-error=deprecated-declarations"
+ WERROR_FLAGS+=" -Wno-error=cpp" # "#warning"
+ CFLAGS="$CFLAGS $WERROR_FLAGS"
+ CPPFLAGS="$CPPFLAGS $WERROR_FLAGS"
+fi
# The following test is taken from WebKit's webkit.m4
saved_CFLAGS="$CFLAGS"
@@ -108,10 +118,13 @@ AC_COMPILE_IFELSE([AC_LANG_SOURCE([char foo;])],
CFLAGS="$saved_CFLAGS"
AC_SUBST(SYMBOL_VISIBILITY)
+CPPFLAGS="$CPPFLAGS -Wall"
+CFLAGS="$CFLAGS -Wall"
+
AX_CHECK_COMPILE_FLAG([-Werror=implicit], [CFLAGS="$CFLAGS -Werror=implicit"])
AX_CHECK_COMPILE_FLAG([-Werror=maybe-uninitialized], [CFLAGS="$CFLAGS -Werror=maybe-uninitialized"])
AX_CHECK_COMPILE_FLAG([-Werror=memset-transposed-args], [CFLAGS="$CFLAGS -Werror=memset-transposed-args"])
-AX_CHECK_COMPILE_FLAG([-Werror=null-dereference], [CFLAGS="$CFLAGS -Werror=null-dereference"])
+AX_CHECK_COMPILE_FLAG([-Wnull-dereference], [CFLAGS="$CFLAGS -Wnull-dereference"])
AX_CHECK_COMPILE_FLAG([-Werror=sizeof-array-argument], [CFLAGS="$CFLAGS -Werror=sizeof-array-argument"])
AX_CHECK_COMPILE_FLAG([-Werror=sizeof-pointer-memaccess], [CFLAGS="$CFLAGS -Werror=sizeof-pointer-memaccess"])
@@ -154,17 +167,15 @@ AC_DEFUN([CHECK_TM_INCLUDES_TM_GMTOFF], [
CHECK_TM_INCLUDES_TM_GMTOFF
-AC_ARG_ENABLE([vty_tests],
- AC_HELP_STRING([--enable-vty-tests],
- [Include the VTY/CTRL tests in make check (deprecated)
- [default=no]]),
- [enable_ext_tests="$enableval"],[enable_ext_tests="no"])
AC_ARG_ENABLE([external_tests],
AC_HELP_STRING([--enable-external-tests],
[Include the VTY/CTRL tests in make check [default=no]]),
[enable_ext_tests="$enableval"],[enable_ext_tests="no"])
if test "x$enable_ext_tests" = "xyes" ; then
- AM_PATH_PYTHON
+ AC_CHECK_PROG(PYTHON2_AVAIL,python2,yes)
+ if test "x$PYTHON2_AVAIL" != "xyes" ; then
+ AC_MSG_ERROR([Please install python2 to run the VTY/CTRL tests.])
+ fi
AC_CHECK_PROG(OSMOTESTEXT_CHECK,osmotestvty.py,yes)
if test "x$OSMOTESTEXT_CHECK" != "xyes" ; then
AC_MSG_ERROR([Please install git://osmocom.org/python/osmo-python-tests to run the VTY/CTRL tests.])
@@ -174,21 +185,84 @@ AC_MSG_CHECKING([whether to enable VTY/CTRL tests])
AC_MSG_RESULT([$enable_ext_tests])
AM_CONDITIONAL(ENABLE_EXT_TESTS, test "x$enable_ext_tests" = "xyes")
+# Generate manuals
+AC_ARG_ENABLE(manuals,
+ [AS_HELP_STRING(
+ [--enable-manuals],
+ [Generate manual PDFs [default=no]],
+ )],
+ [osmo_ac_build_manuals=$enableval], [osmo_ac_build_manuals="no"])
+AM_CONDITIONAL([BUILD_MANUALS], [test x"$osmo_ac_build_manuals" = x"yes"])
+AC_ARG_VAR(OSMO_GSM_MANUALS_DIR, [path to common osmo-gsm-manuals files, overriding pkg-config and "../osmo-gsm-manuals"
+ fallback])
+if test x"$osmo_ac_build_manuals" = x"yes"
+then
+ # Find OSMO_GSM_MANUALS_DIR (env, pkg-conf, fallback)
+ if test -n "$OSMO_GSM_MANUALS_DIR"; then
+ echo "checking for OSMO_GSM_MANUALS_DIR... $OSMO_GSM_MANUALS_DIR (from env)"
+ else
+ OSMO_GSM_MANUALS_DIR="$($PKG_CONFIG osmo-gsm-manuals --variable=osmogsmmanualsdir 2>/dev/null)"
+ if test -n "$OSMO_GSM_MANUALS_DIR"; then
+ echo "checking for OSMO_GSM_MANUALS_DIR... $OSMO_GSM_MANUALS_DIR (from pkg-conf)"
+ else
+ OSMO_GSM_MANUALS_DIR="../osmo-gsm-manuals"
+ echo "checking for OSMO_GSM_MANUALS_DIR... $OSMO_GSM_MANUALS_DIR (fallback)"
+ fi
+ fi
+ if ! test -d "$OSMO_GSM_MANUALS_DIR"; then
+ AC_MSG_ERROR("OSMO_GSM_MANUALS_DIR does not exist! Install osmo-gsm-manuals or set OSMO_GSM_MANUALS_DIR.")
+ fi
+
+ # Find and run check-depends
+ CHECK_DEPENDS="$OSMO_GSM_MANUALS_DIR/check-depends.sh"
+ if ! test -x "$CHECK_DEPENDS"; then
+ CHECK_DEPENDS="osmo-gsm-manuals-check-depends"
+ fi
+ if ! $CHECK_DEPENDS; then
+ AC_MSG_ERROR("missing dependencies for --enable-manuals")
+ fi
+
+ # Put in Makefile with absolute path
+ OSMO_GSM_MANUALS_DIR="$(realpath "$OSMO_GSM_MANUALS_DIR")"
+ AC_SUBST([OSMO_GSM_MANUALS_DIR])
+fi
+
+# https://www.freedesktop.org/software/systemd/man/daemon.html
+AC_ARG_WITH([systemdsystemunitdir],
+ [AS_HELP_STRING([--with-systemdsystemunitdir=DIR], [Directory for systemd service files])],,
+ [with_systemdsystemunitdir=auto])
+AS_IF([test "x$with_systemdsystemunitdir" = "xyes" -o "x$with_systemdsystemunitdir" = "xauto"], [
+ def_systemdsystemunitdir=$($PKG_CONFIG --variable=systemdsystemunitdir systemd)
+
+ AS_IF([test "x$def_systemdsystemunitdir" = "x"],
+ [AS_IF([test "x$with_systemdsystemunitdir" = "xyes"],
+ [AC_MSG_ERROR([systemd support requested but pkg-config unable to query systemd package])])
+ with_systemdsystemunitdir=no],
+ [with_systemdsystemunitdir="$def_systemdsystemunitdir"])])
+AS_IF([test "x$with_systemdsystemunitdir" != "xno"],
+ [AC_SUBST([systemdsystemunitdir], [$with_systemdsystemunitdir])])
+AM_CONDITIONAL([HAVE_SYSTEMD], [test "x$with_systemdsystemunitdir" != "xno"])
+
+AC_MSG_RESULT([CFLAGS="$CFLAGS"])
+AC_MSG_RESULT([CPPFLAGS="$CPPFLAGS"])
+
dnl Generate the output
AM_CONFIG_HEADER(bscconfig.h)
AC_OUTPUT(
- osmo-sgsn.pc
- include/openbsc/Makefile
include/Makefile
+ include/osmocom/Makefile
+ include/osmocom/sgsn/Makefile
src/Makefile
src/gprs/Makefile
+ src/sgsn/Makefile
+ src/gbproxy/Makefile
+ src/gtphub/Makefile
tests/Makefile
tests/atlocal
tests/gprs/Makefile
tests/gbproxy/Makefile
tests/sgsn/Makefile
- tests/oap/Makefile
tests/gtphub/Makefile
tests/xid/Makefile
tests/sndcp_xid/Makefile
@@ -196,5 +270,7 @@ AC_OUTPUT(
tests/v42bis/Makefile
doc/Makefile
doc/examples/Makefile
+ doc/manuals/Makefile
contrib/Makefile
+ contrib/systemd/Makefile
Makefile)
diff --git a/contrib/Makefile.am b/contrib/Makefile.am
index db6d0f536..3439c97be 100644
--- a/contrib/Makefile.am
+++ b/contrib/Makefile.am
@@ -1 +1 @@
-EXTRA_DIST = ipa.py
+SUBDIRS = systemd
diff --git a/contrib/ipa.py b/contrib/ipa.py
deleted file mode 100755
index 71cbf45a4..000000000
--- a/contrib/ipa.py
+++ /dev/null
@@ -1,278 +0,0 @@
-#!/usr/bin/python3
-# -*- mode: python-mode; py-indent-tabs-mode: nil -*-
-"""
-/*
- * Copyright (C) 2016 sysmocom s.f.m.c. GmbH
- *
- * All Rights Reserved
- *
- * This program 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; either version 3 of the License, or
- * (at your option) any later version.
- *
- * 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, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-"""
-
-import struct, random, sys
-
-class IPA(object):
- """
- Stateless IPA protocol multiplexer: add/remove/parse (extended) header
- """
- version = "0.0.5"
- TCP_PORT_OML = 3002
- TCP_PORT_RSL = 3003
- # OpenBSC extensions: OSMO, MGCP_OLD
- PROTO = dict(RSL=0x00, CCM=0xFE, SCCP=0xFD, OML=0xFF, OSMO=0xEE, MGCP_OLD=0xFC)
- # ...OML Router Control, GSUP GPRS extension, Osmocom Authn Protocol
- EXT = dict(CTRL=0, MGCP=1, LAC=2, SMSC=3, ORC=4, GSUP=5, OAP=6)
- # OpenBSC extension: SCCP_OLD
- MSGT = dict(PING=0x00, PONG=0x01, ID_GET=0x04, ID_RESP=0x05, ID_ACK=0x06, SCCP_OLD=0xFF)
- _IDTAG = dict(SERNR=0, UNITNAME=1, LOCATION=2, TYPE=3, EQUIPVERS=4, SWVERSION=5, IPADDR=6, MACADDR=7, UNIT=8)
- CTRL_GET = 'GET'
- CTRL_SET = 'SET'
- CTRL_REP = 'REPLY'
- CTRL_ERR = 'ERR'
- CTRL_TRAP = 'TRAP'
-
- def _l(self, d, p):
- """
- Reverse dictionary lookup: return key for a given value
- """
- if p is None:
- return 'UNKNOWN'
- return list(d.keys())[list(d.values()).index(p)]
-
- def _tag(self, t, v):
- """
- Create TAG as TLV data
- """
- return struct.pack(">HB", len(v) + 1, t) + v
-
- def proto(self, p):
- """
- Lookup protocol name
- """
- return self._l(self.PROTO, p)
-
- def ext(self, p):
- """
- Lookup protocol extension name
- """
- return self._l(self.EXT, p)
-
- def msgt(self, p):
- """
- Lookup message type name
- """
- return self._l(self.MSGT, p)
-
- def idtag(self, p):
- """
- Lookup ID tag name
- """
- return self._l(self._IDTAG, p)
-
- def ext_name(self, proto, exten):
- """
- Return proper extension byte name depending on the protocol used
- """
- if self.PROTO['CCM'] == proto:
- return self.msgt(exten)
- if self.PROTO['OSMO'] == proto:
- return self.ext(exten)
- return None
-
- def add_header(self, data, proto, ext=None):
- """
- Add IPA header (with extension if necessary), data must be represented as bytes
- """
- if ext is None:
- return struct.pack(">HB", len(data) + 1, proto) + data
- return struct.pack(">HBB", len(data) + 1, proto, ext) + data
-
- def del_header(self, data):
- """
- Strip IPA protocol header correctly removing extension if present
- Returns data length, IPA protocol, extension (or None if not defined for a give protocol) and the data without header
- """
- if not len(data):
- return None, None, None, None
- (dlen, proto) = struct.unpack('>HB', data[:3])
- if self.PROTO['OSMO'] == proto or self.PROTO['CCM'] == proto: # there's extension which we have to unpack
- return struct.unpack('>HBB', data[:4]) + (data[4:], ) # length, protocol, extension, data
- return dlen, proto, None, data[3:] # length, protocol, _, data
-
- def split_combined(self, data):
- """
- Split the data which contains multiple concatenated IPA messages into tuple (first, rest) where rest contains remaining messages, first is the single IPA message
- """
- (length, _, _, _) = self.del_header(data)
- return data[:(length + 3)], data[(length + 3):]
-
- def tag_serial(self, data):
- """
- Make TAG for serial number
- """
- return self._tag(self._IDTAG['SERNR'], data)
-
- def tag_name(self, data):
- """
- Make TAG for unit name
- """
- return self._tag(self._IDTAG['UNITNAME'], data)
-
- def tag_loc(self, data):
- """
- Make TAG for location
- """
- return self._tag(self._IDTAG['LOCATION'], data)
-
- def tag_type(self, data):
- """
- Make TAG for unit type
- """
- return self._tag(self._IDTAG['TYPE'], data)
-
- def tag_equip(self, data):
- """
- Make TAG for equipment version
- """
- return self._tag(self._IDTAG['EQUIPVERS'], data)
-
- def tag_sw(self, data):
- """
- Make TAG for software version
- """
- return self._tag(self._IDTAG['SWVERSION'], data)
-
- def tag_ip(self, data):
- """
- Make TAG for IP address
- """
- return self._tag(self._IDTAG['IPADDR'], data)
-
- def tag_mac(self, data):
- """
- Make TAG for MAC address
- """
- return self._tag(self._IDTAG['MACADDR'], data)
-
- def tag_unit(self, data):
- """
- Make TAG for unit ID
- """
- return self._tag(self._IDTAG['UNIT'], data)
-
- def identity(self, unit=b'', mac=b'', location=b'', utype=b'', equip=b'', sw=b'', name=b'', serial=b''):
- """
- Make IPA IDENTITY tag list, by default returns empty concatenated bytes of tag list
- """
- return self.tag_unit(unit) + self.tag_mac(mac) + self.tag_loc(location) + self.tag_type(utype) + self.tag_equip(equip) + self.tag_sw(sw) + self.tag_name(name) + self.tag_serial(serial)
-
- def ping(self):
- """
- Make PING message
- """
- return self.add_header(b'', self.PROTO['CCM'], self.MSGT['PING'])
-
- def pong(self):
- """
- Make PONG message
- """
- return self.add_header(b'', self.PROTO['CCM'], self.MSGT['PONG'])
-
- def id_ack(self):
- """
- Make ID_ACK CCM message
- """
- return self.add_header(b'', self.PROTO['CCM'], self.MSGT['ID_ACK'])
-
- def id_get(self):
- """
- Make ID_GET CCM message
- """
- return self.add_header(self.identity(), self.PROTO['CCM'], self.MSGT['ID_GET'])
-
- def id_resp(self, data):
- """
- Make ID_RESP CCM message
- """
- return self.add_header(data, self.PROTO['CCM'], self.MSGT['ID_RESP'])
-
-class Ctrl(IPA):
- """
- Osmocom CTRL protocol implemented on top of IPA multiplexer
- """
- def __init__(self):
- random.seed()
-
- def add_header(self, data):
- """
- Add CTRL header
- """
- return super(Ctrl, self).add_header(data.encode('utf-8'), IPA.PROTO['OSMO'], IPA.EXT['CTRL'])
-
- def rem_header(self, data):
- """
- Remove CTRL header, check for appropriate protocol and extension
- """
- (_, proto, ext, d) = super(Ctrl, self).del_header(data)
- if self.PROTO['OSMO'] != proto or self.EXT['CTRL'] != ext:
- return None
- return d
-
- def parse(self, data, op=None):
- """
- Parse Ctrl string returning (var, value) pair
- var could be None in case of ERROR message
- value could be None in case of GET message
- """
- (s, i, v) = data.split(' ', 2)
- if s == self.CTRL_ERR:
- return None, v
- if s == self.CTRL_GET:
- return v, None
- (s, i, var, val) = data.split(' ', 3)
- if s == self.CTRL_TRAP and i != '0':
- return None, '%s with non-zero id %s' % (s, i)
- if op is not None and i != op:
- if s == self.CTRL_GET + '_' + self.CTRL_REP or s == self.CTRL_SET + '_' + self.CTRL_REP:
- return None, '%s with unexpected id %s' % (s, i)
- return var, val
-
- def trap(self, var, val):
- """
- Make TRAP message with given (vak, val) pair
- """
- return self.add_header("%s 0 %s %s" % (self.CTRL_TRAP, var, val))
-
- def cmd(self, var, val=None):
- """
- Make SET/GET command message: returns (r, m) tuple where r is random operation id and m is assembled message
- """
- r = random.randint(1, sys.maxsize)
- if val is not None:
- return r, self.add_header("%s %s %s %s" % (self.CTRL_SET, r, var, val))
- return r, self.add_header("%s %s %s" % (self.CTRL_GET, r, var))
-
- def verify(self, reply, r, var, val=None):
- """
- Verify reply to SET/GET command: returns (b, v) tuple where v is True/False verification result and v is the variable value
- """
- (k, v) = self.parse(reply)
- if k != var or (val is not None and v != val):
- return False, v
- return True, v
-
-if __name__ == '__main__':
- print("IPA multiplexer v%s loaded." % IPA.version)
diff --git a/contrib/jenkins.sh b/contrib/jenkins.sh
index 288298907..51583f8f4 100755
--- a/contrib/jenkins.sh
+++ b/contrib/jenkins.sh
@@ -1,5 +1,11 @@
#!/usr/bin/env bash
# jenkins build helper script for openbsc. This is how we build on jenkins.osmocom.org
+#
+# environment variables:
+# * IU: configure 3G support (values: "--enable-iu", "--disable-iu")
+# * WITH_MANUALS: build manual PDFs if set to "1"
+# * PUBLISH: upload manuals after building if set to "1" (ignored without WITH_MANUALS = "1")
+#
if ! [ -x "$(command -v osmo-build-dep.sh)" ]; then
echo "Error: We need to have scripts/osmo-deps.sh from http://git.osmocom.org/osmo-ci/ in PATH !"
@@ -14,8 +20,9 @@ deps="$base/deps"
inst="$deps/install"
export deps inst
+osmo-clean-workspace.sh
+
mkdir "$deps" || true
-rm -rf "$inst"
osmo-build-dep.sh libosmocore "" ac_cv_path_DOXYGEN=false
@@ -23,33 +30,52 @@ verify_value_string_arrays_are_terminated.py $(find . -name "*.[hc]")
export PKG_CONFIG_PATH="$inst/lib/pkgconfig:$PKG_CONFIG_PATH"
export LD_LIBRARY_PATH="$inst/lib"
+export PATH="$inst/bin:$PATH"
osmo-build-dep.sh libosmo-abis
osmo-build-dep.sh libosmo-netif
-osmo-build-dep.sh libosmo-sccp
-osmo-build-dep.sh openggsn
+osmo-build-dep.sh osmo-ggsn
+osmo-build-dep.sh osmo-hlr
+enable_werror=""
if [ "x$IU" = "x--enable-iu" ]; then
+ osmo-build-dep.sh libosmo-sccp
osmo-build-dep.sh libasn1c
#osmo-build-dep.sh asn1c aper-prefix # only needed for make regen in osmo-iuh
osmo-build-dep.sh osmo-iuh
+else
+ enable_werror="--enable-werror"
+fi
+
+# Additional configure options and depends
+CONFIG=""
+if [ "$WITH_MANUALS" = "1" ]; then
+ osmo-build-dep.sh osmo-gsm-manuals
+ CONFIG="--enable-manuals"
fi
set +x
echo
echo
echo
-echo " =============================== osmo-msc ==============================="
+echo " =============================== osmo-sgsn ==============================="
echo
set -x
cd "$base"
autoreconf --install --force
-./configure --enable-osmo-bsc --enable-nat $SMPP $MGCP $IU --enable-vty-tests --enable-external-tests
+./configure --enable-sanitize $enable_werror $IU --enable-external-tests $CONFIG
$MAKE $PARALLEL_MAKE
LD_LIBRARY_PATH="$inst/lib" $MAKE check \
|| cat-testlogs.sh
LD_LIBRARY_PATH="$inst/lib" \
- DISTCHECK_CONFIGURE_FLAGS="--enable-osmo-bsc --enable-nat $SMPP $MGCP $IU --enable-vty-tests --enable-external-tests" \
+ DISTCHECK_CONFIGURE_FLAGS="$enable_werror $IU --enable-external-tests $CONFIG" \
$MAKE distcheck \
|| cat-testlogs.sh
+
+if [ "$WITH_MANUALS" = "1" ] && [ "$PUBLISH" = "1" ]; then
+ make -C "$base/doc/manuals" publish
+fi
+
+$MAKE maintainer-clean
+osmo-clean-workspace.sh
diff --git a/contrib/soap.py b/contrib/soap.py
deleted file mode 100755
index 4d0a023f9..000000000
--- a/contrib/soap.py
+++ /dev/null
@@ -1,188 +0,0 @@
-#!/usr/bin/python3
-# -*- mode: python-mode; py-indent-tabs-mode: nil -*-
-"""
-/*
- * Copyright (C) 2016 sysmocom s.f.m.c. GmbH
- *
- * All Rights Reserved
- *
- * This program 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; either version 3 of the License, or
- * (at your option) any later version.
- *
- * 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, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-"""
-
-__version__ = "v0.7" # bump this on every non-trivial change
-
-from twisted.internet import defer, reactor
-from twisted_ipa import CTRL, IPAFactory, __version__ as twisted_ipa_version
-from ipa import Ctrl
-from treq import post, collect
-from suds.client import Client
-from functools import partial
-from distutils.version import StrictVersion as V # FIXME: use NormalizedVersion from PEP-386 when available
-import argparse, datetime, signal, sys, os, logging, logging.handlers
-
-# we don't support older versions of TwistedIPA module
-assert V(twisted_ipa_version) > V('0.4')
-
-# keys from OpenBSC openbsc/src/libbsc/bsc_rf_ctrl.c, values SOAP-specific
-oper = { 'inoperational' : 0, 'operational' : 1 }
-admin = { 'locked' : 0, 'unlocked' : 1 }
-policy = { 'off' : 0, 'on' : 1, 'grace' : 2, 'unknown' : 3 }
-
-# keys from OpenBSC openbsc/src/libbsc/bsc_vty.c
-fix = { 'invalid' : 0, 'fix2d' : 1, 'fix3d' : 1 } # SOAP server treats it as boolean but expects int
-
-
-def handle_reply(p, f, log, r):
- """
- Reply handler: takes function p to process raw SOAP server reply r, function f to run for each command and verbosity flag v
- """
- repl = p(r) # result is expected to have both commands[] array and error string (could be None)
- bsc_id = repl.commands[0].split()[0].split('.')[3] # we expect 1st command to have net.0.bsc.666.bts.2.trx.1 location prefix format
- log.info("Received SOAP response for BSC %s with %d commands, error status: %s" % (bsc_id, len(repl.commands), repl.error))
- log.debug("BSC %s commands: %s" % (bsc_id, repl.commands))
- for t in repl.commands: # Process OpenBscCommands format from .wsdl
- (_, m) = Ctrl().cmd(*t.split())
- f(m)
-
-
-class Trap(CTRL):
- """
- TRAP handler (agnostic to factory's client object)
- """
- def ctrl_TRAP(self, data, op_id, v):
- """
- Parse CTRL TRAP and dispatch to appropriate handler after normalization
- """
- (l, r) = v.split()
- loc = l.split('.')
- t_type = loc[-1]
- p = partial(lambda a, i: a[i] if len(a) > i else None, loc) # parse helper
- method = getattr(self, 'handle_' + t_type.replace('-', ''), lambda: "Unhandled %s trap" % t_type)
- method(p(1), p(3), p(5), p(7), r) # we expect net.0.bsc.666.bts.2.trx.1 format for trap prefix
-
- def ctrl_SET_REPLY(self, data, _, v):
- """
- Debug log for replies to our commands
- """
- self.factory.log.debug('SET REPLY %s' % v)
-
- def ctrl_ERROR(self, data, op_id, v):
- """
- We want to know if smth went wrong
- """
- self.factory.log.debug('CTRL ERROR [%s] %s' % (op_id, v))
-
- def connectionMade(self):
- """
- Logging wrapper, calling super() is necessary not to break reconnection logic
- """
- self.factory.log.info("Connected to CTRL@%s:%d" % (self.factory.host, self.factory.port))
- super(CTRL, self).connectionMade()
-
- @defer.inlineCallbacks
- def handle_locationstate(self, net, bsc, bts, trx, data):
- """
- Handle location-state TRAP: parse trap content, build SOAP context and use treq's routines to post it while setting up async handlers
- """
- (ts, fx, lat, lon, height, opr, adm, pol, mcc, mnc) = data.split(',')
- tstamp = datetime.datetime.fromtimestamp(float(ts)).isoformat()
- self.factory.log.debug('location-state@%s.%s.%s.%s (%s) [%s/%s] => %s' % (net, bsc, bts, trx, tstamp, mcc, mnc, data))
- ctx = self.factory.client.registerSiteLocation(bsc, float(lon), float(lat), fix.get(fx, 0), tstamp, oper.get(opr, 2), admin.get(adm, 2), policy.get(pol, 3))
- d = post(self.factory.location, ctx.envelope)
- d.addCallback(collect, partial(handle_reply, ctx.process_reply, self.transport.write, self.factory.log)) # treq's collect helper is handy to get all reply content at once using closure on ctx
- d.addErrback(lambda e, bsc: self.factory.log.critical("HTTP POST error %s while trying to register BSC %s" % (e, bsc)), bsc) # handle HTTP errors
- # Ensure that we run only limited number of requests in parallel:
- yield self.factory.semaphore.acquire()
- yield d # we end up here only if semaphore is available which means it's ok to fire the request without exceeding the limit
- self.factory.semaphore.release()
-
- def handle_notificationrejectionv1(self, net, bsc, bts, trx, data):
- """
- Handle notification-rejection-v1 TRAP: just an example to show how more message types can be handled
- """
- self.factory.log.debug('notification-rejection-v1@bsc-id %s => %s' % (bsc, data))
-
-
-class TrapFactory(IPAFactory):
- """
- Store SOAP client object so TRAP handler can use it for requests
- """
- location = None
- log = None
- semaphore = None
- client = None
- host = None
- port = None
- def __init__(self, host, port, proto, semaphore, log, wsdl=None, location=None):
- self.host = host # for logging only,
- self.port = port # seems to be no way to get it from ReconnectingClientFactory
- self.log = log
- self.semaphore = semaphore
- soap = Client(wsdl, location=location, nosend=True) # make async SOAP client
- self.location = location.encode() if location else soap.wsdl.services[0].ports[0].location # necessary for dispatching HTTP POST via treq
- self.client = soap.service
- level = self.log.getEffectiveLevel()
- self.log.setLevel(logging.WARNING) # we do not need excessive debug from lower levels
- super(TrapFactory, self).__init__(proto, self.log)
- self.log.setLevel(level)
- self.log.debug("Using IPA %s, SUDS client: %s" % (Ctrl.version, soap))
-
-
-def reloader(path, script, log, dbg1, dbg2, signum, _):
- """
- Signal handler: we have to use execl() because twisted's reactor is not restartable due to some bug in twisted implementation
- """
- log.info("Received Signal %d - restarting..." % signum)
- if signum == signal.SIGUSR1 and dbg1 not in sys.argv and dbg2 not in sys.argv:
- sys.argv.append(dbg1) # enforce debug
- if signum == signal.SIGUSR2 and (dbg1 in sys.argv or dbg2 in sys.argv): # disable debug
- if dbg1 in sys.argv:
- sys.argv.remove(dbg1)
- if dbg2 in sys.argv:
- sys.argv.remove(dbg2)
- os.execl(path, script, *sys.argv[1:])
-
-
-if __name__ == '__main__':
- p = argparse.ArgumentParser(description='Proxy between given SOAP service and Osmocom CTRL protocol.')
- p.add_argument('-v', '--version', action='version', version=("%(prog)s " + __version__))
- p.add_argument('-p', '--port', type=int, default=4250, help="Port to use for CTRL interface, defaults to 4250")
- p.add_argument('-c', '--ctrl', default='localhost', help="Adress to use for CTRL interface, defaults to localhost")
- p.add_argument('-w', '--wsdl', required=True, help="WSDL URL for SOAP")
- p.add_argument('-n', '--num', type=int, default=5, help="Max number of concurrent HTTP requests to SOAP server")
- p.add_argument('-d', '--debug', action='store_true', help="Enable debug log")
- p.add_argument('-o', '--output', action='store_true', help="Log to STDOUT in addition to SYSLOG")
- p.add_argument('-l', '--location', help="Override location found in WSDL file (don't use unless you know what you're doing)")
- args = p.parse_args()
-
- log = logging.getLogger('CTRL2SOAP')
- if args.debug:
- log.setLevel(logging.DEBUG)
- else:
- log.setLevel(logging.INFO)
- log.addHandler(logging.handlers.SysLogHandler('/dev/log'))
- if args.output:
- log.addHandler(logging.StreamHandler(sys.stdout))
-
- reboot = partial(reloader, os.path.abspath(__file__), os.path.basename(__file__), log, '-d', '--debug') # keep in sync with add_argument() call above
- signal.signal(signal.SIGHUP, reboot)
- signal.signal(signal.SIGQUIT, reboot)
- signal.signal(signal.SIGUSR1, reboot) # restart and enabled debug output
- signal.signal(signal.SIGUSR2, reboot) # restart and disable debug output
-
- log.info("SOAP proxy %s starting with PID %d ..." % (__version__, os.getpid()))
- reactor.connectTCP(args.ctrl, args.port, TrapFactory(args.ctrl, args.port, Trap, defer.DeferredSemaphore(args.num), log, args.wsdl, args.location))
- reactor.run()
diff --git a/contrib/systemd/Makefile.am b/contrib/systemd/Makefile.am
new file mode 100644
index 000000000..11e8f9815
--- /dev/null
+++ b/contrib/systemd/Makefile.am
@@ -0,0 +1,13 @@
+EXTRA_DIST = \
+ osmo-gbproxy.service \
+ osmo-gtphub.service \
+ osmo-sgsn.service
+
+if HAVE_SYSTEMD
+SYSTEMD_SERVICES = \
+ osmo-gbproxy.service \
+ osmo-gtphub.service \
+ osmo-sgsn.service
+
+systemdsystemunit_DATA = $(SYSTEMD_SERVICES)
+endif
diff --git a/contrib/systemd/osmo-gtphub.service b/contrib/systemd/osmo-gtphub.service
new file mode 100644
index 000000000..488178584
--- /dev/null
+++ b/contrib/systemd/osmo-gtphub.service
@@ -0,0 +1,12 @@
+[Unit]
+Description=Osmocom GTP Hub
+
+[Service]
+Type=simple
+ExecStart=/usr/bin/osmo-gtphub -c /etc/osmocom/osmo-gtphub.cfg
+Restart=always
+RestartSec=2
+RestartPreventExitStatus=1
+
+[Install]
+WantedBy=multi-user.target
diff --git a/contrib/systemd/osmo-sgsn.service b/contrib/systemd/osmo-sgsn.service
index bf6a8e098..0991c70c6 100644
--- a/contrib/systemd/osmo-sgsn.service
+++ b/contrib/systemd/osmo-sgsn.service
@@ -1,5 +1,5 @@
[Unit]
-Description=OpenBSC SGSN
+Description=Osmocom SGSN (Serving GPRS Support Node)
Wants=osmo-hlr.service
After=osmo-hlr.service
After=osmo-hnbgw.service
diff --git a/contrib/twisted_ipa.py b/contrib/twisted_ipa.py
deleted file mode 100755
index e6d7b1a16..000000000
--- a/contrib/twisted_ipa.py
+++ /dev/null
@@ -1,384 +0,0 @@
-#!/usr/bin/python3
-# -*- mode: python-mode; py-indent-tabs-mode: nil -*-
-"""
-/*
- * Copyright (C) 2016 sysmocom s.f.m.c. GmbH
- *
- * All Rights Reserved
- *
- * This program 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; either version 3 of the License, or
- * (at your option) any later version.
- *
- * 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, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-"""
-
-__version__ = "0.6" # bump this on every non-trivial change
-
-from ipa import Ctrl, IPA
-from twisted.internet.protocol import ReconnectingClientFactory
-from twisted.internet import reactor
-from twisted.protocols import basic
-import argparse, logging
-
-class IPACommon(basic.Int16StringReceiver):
- """
- Generic IPA protocol handler: include some routines for simpler subprotocols.
- It's not intended as full implementation of all subprotocols, rather common ground and example code.
- """
- def dbg(self, line):
- """
- Debug print helper
- """
- self.factory.log.debug(line)
-
- def osmo_CTRL(self, data):
- """
- OSMO CTRL protocol
- Placeholder, see corresponding derived class
- """
- pass
-
- def osmo_MGCP(self, data):
- """
- OSMO MGCP extension
- """
- self.dbg('OSMO MGCP received %s' % data)
-
- def osmo_LAC(self, data):
- """
- OSMO LAC extension
- """
- self.dbg('OSMO LAC received %s' % data)
-
- def osmo_SMSC(self, data):
- """
- OSMO SMSC extension
- """
- self.dbg('OSMO SMSC received %s' % data)
-
- def osmo_ORC(self, data):
- """
- OSMO ORC extension
- """
- self.dbg('OSMO ORC received %s' % data)
-
- def osmo_GSUP(self, data):
- """
- OSMO GSUP extension
- """
- self.dbg('OSMO GSUP received %s' % data)
-
- def osmo_OAP(self, data):
- """
- OSMO OAP extension
- """
- self.dbg('OSMO OAP received %s' % data)
-
- def osmo_UNKNOWN(self, data):
- """
- OSMO defaul extension handler
- """
- self.dbg('OSMO unknown extension received %s' % data)
-
- def handle_RSL(self, data, proto, extension):
- """
- RSL protocol handler
- """
- self.dbg('IPA RSL received message with extension %s' % extension)
-
- def handle_CCM(self, data, proto, msgt):
- """
- CCM (IPA Connection Management)
- Placeholder, see corresponding derived class
- """
- pass
-
- def handle_SCCP(self, data, proto, extension):
- """
- SCCP protocol handler
- """
- self.dbg('IPA SCCP received message with extension %s' % extension)
-
- def handle_OML(self, data, proto, extension):
- """
- OML protocol handler
- """
- self.dbg('IPA OML received message with extension %s' % extension)
-
- def handle_OSMO(self, data, proto, extension):
- """
- Dispatcher point for OSMO subprotocols based on extension name, lambda default should never happen
- """
- method = getattr(self, 'osmo_' + IPA().ext(extension), lambda: "extension dispatch failure")
- method(data)
-
- def handle_MGCP(self, data, proto, extension):
- """
- MGCP protocol handler
- """
- self.dbg('IPA MGCP received message with attribute %s' % extension)
-
- def handle_UNKNOWN(self, data, proto, extension):
- """
- Default protocol handler
- """
- self.dbg('IPA received message for %s (%s) protocol with attribute %s' % (IPA().proto(proto), proto, extension))
-
- def process_chunk(self, data):
- """
- Generic message dispatcher for IPA (sub)protocols based on protocol name, lambda default should never happen
- """
- (_, proto, extension, content) = IPA().del_header(data)
- if content is not None:
- self.dbg('IPA received %s::%s [%d/%d] %s' % (IPA().proto(proto), IPA().ext_name(proto, extension), len(data), len(content), content))
- method = getattr(self, 'handle_' + IPA().proto(proto), lambda: "protocol dispatch failure")
- method(content, proto, extension)
-
- def dataReceived(self, data):
- """
- Override for dataReceived from Int16StringReceiver because of inherently incompatible interpretation of length
- If default handler is used than we would always get off-by-1 error (Int16StringReceiver use equivalent of l + 2)
- """
- if len(data):
- (head, tail) = IPA().split_combined(data)
- self.process_chunk(head)
- self.dataReceived(tail)
-
- def connectionMade(self):
- """
- We have to resetDelay() here to drop internal state to default values to make reconnection logic work
- Make sure to call this via super() if overriding to keep reconnection logic intact
- """
- addr = self.transport.getPeer()
- self.dbg('IPA connected to %s:%d peer' % (addr.host, addr.port))
- self.factory.resetDelay()
-
-
-class CCM(IPACommon):
- """
- Implementation of CCM protocol for IPA multiplex
- """
- def ack(self):
- self.transport.write(IPA().id_ack())
-
- def ping(self):
- self.transport.write(IPA().ping())
-
- def pong(self):
- self.transport.write(IPA().pong())
-
- def handle_CCM(self, data, proto, msgt):
- """
- CCM (IPA Connection Management)
- Only basic logic necessary for tests is implemented (ping-pong, id ack etc)
- """
- if msgt == IPA.MSGT['ID_GET']:
- self.transport.getHandle().sendall(IPA().id_resp(self.factory.ccm_id))
- # if we call
- # self.transport.write(IPA().id_resp(self.factory.test_id))
- # instead, than we would have to also call
- # reactor.callLater(1, self.ack)
- # instead of self.ack()
- # otherwise the writes will be glued together - hence the necessity for ugly hack with 1s timeout
- # Note: this still might work depending on the IPA implementation details on the other side
- self.ack()
- # schedule PING in 4s
- reactor.callLater(4, self.ping)
- if msgt == IPA.MSGT['PING']:
- self.pong()
-
-
-class CTRL(IPACommon):
- """
- Implementation of Osmocom control protocol for IPA multiplex
- """
- def ctrl_SET(self, data, op_id, v):
- """
- Handle CTRL SET command
- """
- self.dbg('CTRL SET [%s] %s' % (op_id, v))
-
- def ctrl_SET_REPLY(self, data, op_id, v):
- """
- Handle CTRL SET reply
- """
- self.dbg('CTRL SET REPLY [%s] %s' % (op_id, v))
-
- def ctrl_GET(self, data, op_id, v):
- """
- Handle CTRL GET command
- """
- self.dbg('CTRL GET [%s] %s' % (op_id, v))
-
- def ctrl_GET_REPLY(self, data, op_id, v):
- """
- Handle CTRL GET reply
- """
- self.dbg('CTRL GET REPLY [%s] %s' % (op_id, v))
-
- def ctrl_TRAP(self, data, op_id, v):
- """
- Handle CTRL TRAP command
- """
- self.dbg('CTRL TRAP [%s] %s' % (op_id, v))
-
- def ctrl_ERROR(self, data, op_id, v):
- """
- Handle CTRL ERROR reply
- """
- self.dbg('CTRL ERROR [%s] %s' % (op_id, v))
-
- def osmo_CTRL(self, data):
- """
- OSMO CTRL message dispatcher, lambda default should never happen
- For basic tests only, appropriate handling routines should be replaced: see CtrlServer for example
- """
- self.dbg('OSMO CTRL received %s::%s' % Ctrl().parse(data.decode('utf-8')))
- (cmd, op_id, v) = data.decode('utf-8').split(' ', 2)
- method = getattr(self, 'ctrl_' + cmd, lambda: "CTRL unknown command")
- method(data, op_id, v)
-
-
-class IPAServer(CCM):
- """
- Test implementation of IPA server
- Demonstrate CCM opearation by overriding necessary bits from CCM
- """
- def connectionMade(self):
- """
- Keep reconnection logic working by calling routine from CCM
- Initiate CCM upon connection
- """
- addr = self.transport.getPeer()
- self.factory.log.info('IPA server: connection from %s:%d client' % (addr.host, addr.port))
- super(IPAServer, self).connectionMade()
- self.transport.write(IPA().id_get())
-
-
-class CtrlServer(CTRL):
- """
- Test implementation of CTRL server
- Demonstarte CTRL handling by overriding simpler routines from CTRL
- """
- def connectionMade(self):
- """
- Keep reconnection logic working by calling routine from CTRL
- Send TRAP upon connection
- Note: we can't use sendString() because of it's incompatibility with IPA interpretation of length prefix
- """
- addr = self.transport.getPeer()
- self.factory.log.info('CTRL server: connection from %s:%d client' % (addr.host, addr.port))
- super(CtrlServer, self).connectionMade()
- self.transport.write(Ctrl().trap('LOL', 'what'))
- self.transport.write(Ctrl().trap('rulez', 'XXX'))
-
- def reply(self, r):
- self.transport.write(Ctrl().add_header(r))
-
- def ctrl_SET(self, data, op_id, v):
- """
- CTRL SET command: always succeed
- """
- self.dbg('SET [%s] %s' % (op_id, v))
- self.reply('SET_REPLY %s %s' % (op_id, v))
-
- def ctrl_GET(self, data, op_id, v):
- """
- CTRL GET command: always fail
- """
- self.dbg('GET [%s] %s' % (op_id, v))
- self.reply('ERROR %s No variable found' % op_id)
-
-
-class IPAFactory(ReconnectingClientFactory):
- """
- Generic IPA Client Factory which can be used to store state for various subprotocols and manage connections
- Note: so far we do not really need separate Factory for acting as a server due to protocol simplicity
- """
- protocol = IPACommon
- log = None
- ccm_id = IPA().identity(unit=b'1515/0/1', mac=b'b0:0b:fa:ce:de:ad:be:ef', utype=b'sysmoBTS', name=b'StingRay', location=b'hell', sw=IPA.version.encode('utf-8'))
-
- def __init__(self, proto=None, log=None, ccm_id=None):
- if proto:
- self.protocol = proto
- if ccm_id:
- self.ccm_id = ccm_id
- if log:
- self.log = log
- else:
- self.log = logging.getLogger('IPAFactory')
- self.log.setLevel(logging.CRITICAL)
- self.log.addHandler(logging.NullHandler)
-
- def clientConnectionFailed(self, connector, reason):
- """
- Only necessary for as debugging aid - if we can somehow set parent's class noisy attribute then we can omit this method
- """
- self.log.warning('IPAFactory connection failed: %s' % reason.getErrorMessage())
- ReconnectingClientFactory.clientConnectionFailed(self, connector, reason)
-
- def clientConnectionLost(self, connector, reason):
- """
- Only necessary for as debugging aid - if we can somehow set parent's class noisy attribute then we can omit this method
- """
- self.log.warning('IPAFactory connection lost: %s' % reason.getErrorMessage())
- ReconnectingClientFactory.clientConnectionLost(self, connector, reason)
-
-
-if __name__ == '__main__':
- p = argparse.ArgumentParser("Twisted IPA (module v%s) app" % IPA.version)
- p.add_argument('-v', '--version', action='version', version="%(prog)s v" + __version__)
- p.add_argument('-p', '--port', type=int, default=4250, help="Port to use for CTRL interface")
- p.add_argument('-d', '--host', default='localhost', help="Adress to use for CTRL interface")
- cs = p.add_mutually_exclusive_group()
- cs.add_argument("-c", "--client", action='store_true', help="asume client role")
- cs.add_argument("-s", "--server", action='store_true', help="asume server role")
- ic = p.add_mutually_exclusive_group()
- ic.add_argument("--ipa", action='store_true', help="use IPA protocol")
- ic.add_argument("--ctrl", action='store_true', help="use CTRL protocol")
- args = p.parse_args()
- test = False
-
- log = logging.getLogger('TwistedIPA')
- log.setLevel(logging.DEBUG)
- log.addHandler(logging.StreamHandler(sys.stdout))
-
- if args.ctrl:
- if args.client:
- # Start osmo-bsc to receive TRAP messages when osmo-bts-* connects to it
- print('CTRL client, connecting to %s:%d' % (args.host, args.port))
- reactor.connectTCP(args.host, args.port, IPAFactory(CTRL, log))
- test = True
- if args.server:
- # Use bsc_control.py to issue set/get commands
- print('CTRL server, listening on port %d' % args.port)
- reactor.listenTCP(args.port, IPAFactory(CtrlServer, log))
- test = True
- if args.ipa:
- if args.client:
- # Start osmo-nitb which would initiate A-bis/IP session
- print('IPA client, connecting to %s ports %d and %d' % (args.host, IPA.TCP_PORT_OML, IPA.TCP_PORT_RSL))
- reactor.connectTCP(args.host, IPA.TCP_PORT_OML, IPAFactory(CCM, log))
- reactor.connectTCP(args.host, IPA.TCP_PORT_RSL, IPAFactory(CCM, log))
- test = True
- if args.server:
- # Start osmo-bts-* which would attempt to connect to us
- print('IPA server, listening on ports %d and %d' % (IPA.TCP_PORT_OML, IPA.TCP_PORT_RSL))
- reactor.listenTCP(IPA.TCP_PORT_RSL, IPAFactory(IPAServer, log))
- reactor.listenTCP(IPA.TCP_PORT_OML, IPAFactory(IPAServer, log))
- test = True
- if test:
- reactor.run()
- else:
- print("Please specify which protocol in which role you'd like to test.")
diff --git a/debian/changelog b/debian/changelog
index 62166956d..2827f43b0 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,447 @@
+osmo-sgsn (1.6.0) unstable; urgency=medium
+
+ [ Pau Espin Pedrol ]
+ * gprs_gmm: Introduce macros to access msgb's associated IU UE ctx
+ * gprs_llc.h: Improve documentation of some structs
+ * gprs_gmm.c: Improve doc on nullable parameters
+ * gprs_gmm.c: Drop unneeded brackets
+ * Introduce define TLLI_UNASSIGNED
+ * gprs_sgsn.c: Warn upon llme free unexpected scenarios
+ * gprs_gmm: Clarify comment during TLLI assignment
+ * gprs_sgsn.c: Remove recently introduced assert
+ * gprs_gmm: Introduce assert to guard against unexpected condition
+ * gprs_gmm.c: Use correct function to set MM_IDLE state during cleanup
+ * gprs_sgsn.h: Flag MM_CTX_T_GERAN_Iu as not supported
+ * gprs_gmm.c: Flag mmctx_set_(p)mm_state() functions static
+ * sgsn: use sccp_simple_client API to setup ss7 id 0 instead of 1
+ * gprs_gmm.c: Fix typo in log message
+ * gprs_gmm.c: Call mmctx_set_(p)mm_state only on related ran_type
+ * Introduce and use log macros when no mm ctx available
+ * gprs_gmm: Avoid spaces in fsm events and enum strings
+ * tests: Verify that timers can be set over VTY
+ * Replace own timer infra with libosmocore osmo_tdef
+ * tests: Introduce vty-transcript-test tests
+ * gprs_gmm.c: Use osmo_rai_name() in log line
+ * examples: Add osmo-sgsn_custom-sccp.cfg
+ * vty: Introduce cs7-instance-iu
+ * gprs_gmm.c: Print value_string of reject cause
+ * gprs_gmm.c: Add spec document to function documentation
+ * gtp: make echo_interval unsigned
+ * gtp: cb_delete_context(): Clarify why pdp->lib is set to NULL
+ * Introduce log helper LOGGGSN and log category DGTP
+ * sgsn: gtp: Drop related pdp contexts on echo timeout against GGSN
+ * Move lots of Iu/ranap specific code into its own file
+ * Move llc->MM/SM Gb specific glue code to its own file
+ * Split enum gprs_pmm_state into Iu and Gb counterparts
+ * Merge common allocation steps for Gb and Iu ctx
+ * gprs_gmm.c: Replace inet_ntoa with inet_ntop
+ * sgsn_cdr.c: Fix ip addr string buffer size
+ * sgsn_vty: Fix mmctx rate_ctr output indentation
+ * sgsn_vty: Print correct Iu mmctx id in 'show mm-context'
+ * Introduce FSM mm_state_gb_fsm
+ * Introduce FSM mm_state_iu_fsm
+ * vty: Print MM state and RAN type in show mm-context
+ * src/gprs/Makefile.am: Move build of shared .c files to an internal lib
+ * Move out gbproxy to its own subdir
+ * Move out gtphub to its own subdir
+ * Move out sgsn to its own subdir
+ * gmm: Move code handling GMM Attach Complete to its own function
+ * gmm: Move code handling GMM Routing Area Update Complete to its own function
+ * gmm: Move code handling GMM PTMSI Realloc Complete to its own function
+ * enum gprs_gmm_state: Fix spec reference
+ * Implement GMM State using osmocom FSM
+ * Split out GPRS SM layer into its own file
+ * sgsn: Reject PdpActReq if no GTP pdp ctx exists
+ * Introduce TODO-RELEASE file
+ * sgsn_libgtp.c: Drop use of deprecated libgtp APIs gtp_retrans*()
+ * gmm: Fix assertion hit during RA UPD REQ before completting gmm attach
+ * Improve logging in gprs_llc.c code
+ * gprs_llc.c: Use enum instead of hardcoded value
+ * gprs_gmm.c: Send XID reset with received TLLI
+
+ [ Alexander Couzens ]
+ * gprs/gprs_gmm: implement T3314. Timeout to reset MM state READY->STANDBY
+ * gprs_gmm: only update gb/iu cell information when Iu/Gb present
+ * gprs_gmm: clarify comment of Iu follow-on request
+ * gprs_gmm: gsm48_rx_gmm_att_req(): refactor duplicated code
+ * sgsn_pdp_ctx_terminate: check llme before accessing
+ * gprs_ranap: send CommonId after receiving Security Mode Complete
+ * mm_gb_fsm: unassign the llme when entering MM_IDLE
+ * gprs_ranap: refactor REQUIRE_MM define
+ * sgsn: when receiving data PDU notify the Gb GMM fsm
+ * Avoid compiling unneeded files when building without Iu
+ * gprs_ranap: release Iu UE Context when exiting PMM Connected
+ * Iu: implement a user inactivity timer
+ * gprs_ranap: on Iu release, stop the attach fsm if running
+ * gprs_mm_state_gb_fsm: ensure T3350 is not running when entering IDLE
+ * gprs_ranap: add missing rc = 0
+ * gprs_sgsn: always allocate Gb/Iu mm fsm
+ * sgsn: MM Gb Fsm: fix event handling for implicit detach
+ * ranap: add non-spec X1001
+ * gprs_gmm: release Iu connection on RAU failures
+ * sgsn_mm_ctx_alloc(): check for unallocated fsms
+ * sgsn_libgtp: refactor ps paging into gprs_gb
+ * sgsn: Gb: implementing PS Paging when MS is MM_STANDBY
+
+ [ Vadim Yanitskiy ]
+ * gprs_mm_state_iu_fsm.c: fix: assign timer_cb to mm_state_iu_fsm
+
+ [ Max ]
+ * Use libosmocore constant for IMSI length in ACL entry
+
+ [ Harald Welte ]
+ * LLC: Don't use hard-coded N201-U / N201-I values in XID
+ * Initial OsmoGbPROXY user manual
+ * check for osmo_fsm_register() error return values
+ * check for osmo_ss7_init() error return value
+ * manual: Fix copy+paste error
+ * exit(2) on unsupported positional arguments on command line
+
+ [ Oliver Smith ]
+ * gitignore: fix paths to binaries
+ * doc: add OsmoGbProxy VTY reference
+ * regen_doc.sh: support gbproxy, run without docker
+ * osmoappdesc.py, tests: switch to python 3
+
+ -- Pau Espin Pedrol <pespin@sysmocom.de> Fri, 03 Jan 2020 19:17:56 +0100
+
+osmo-sgsn (1.5.0) unstable; urgency=medium
+
+ [ Max ]
+ * Improve 'show subscriber cache' vty command
+ * GMM: permit VLR_ANSWERED event in attach FSM
+ * Fix IMSI padding in imsi-acl
+
+ [ Harald Welte ]
+ * gbproxy_test: Fix test expectations of gprs_ns_rcvmsg()
+ * LLC XID: Fix string representation of N201_U
+ * LLC: Don't blindly assume all LLC frames have data payload
+ * LLC: Avoid NOTICE message on LLC NULL
+ * gprs_llc: Correctly refuse any ABM command (SABM, DISC) with DM
+ * LLC: Store the XID inside the LLC Entity, not LLC Mgmg Entity
+ * gb_proxy.h: Add missing comments; improve comments
+ * gb_proxy: cosmetic: Use 'bool' in data structures where applicable
+
+ [ efistokl ]
+ * gsm0408_rcv_gmm: send Iu-ReleaseCommand upon receiving Attach Complete.
+ * gprs_gmm: send Service Reject when no PDP ctxs are available.
+
+ [ Alexander Couzens ]
+ * gprs_gmm: reintroduce calling gsm48_gmm_authorize when not handling GMM Attach Requests
+ * gbproxy: parse dtap GSM48_MT_GSM_DEACT_PDP_REQ|ACK
+
+ [ Pau Espin Pedrol ]
+ * gprs_sndcp_comp_free: Replace ifelse with switch and better handling of error
+ * sgsn: vty: Improve log warning content with spec section
+ * Document max retransmit times for T3395
+ * sgsn: Fix echo timer not started upon first pdp ctx created
+ * sgsn_libgtp: Use new per-GSN libgtp API instead of deprecated API
+ * sgsn: Have authentication required on by default
+ * Remove undefined param passed to {logging,osmo_stats}_vty_add_cmds
+ * Require newer versions of dependencies
+
+ [ Keith ]
+ * Echo zero byte XID-Field of Type L3_PAR
+
+ [ Oliver Smith ]
+ * debian: create -doc subpackage with pdf manuals
+ * contrib/jenkins.sh: run "make maintainer-clean"
+ * osmo-gtphub.cfg: fix conflict with osmo-sgsn.cfg
+ * osmo-gbproxy.cfg: fix conflict with osmo-sgsn.cfg
+
+ [ Vadim Yanitskiy ]
+ * doc/manuals/vty: regenerate sgsn_vty_reference.xml
+ * osmo-sgsn: add VTY parameter to toggle authentication
+ * sgsn_mm_ctx_find_ggsn_ctx(): fix: always set gsm_cause
+
+ [ Eric Wild ]
+ * replace magic tmsi constant with define
+ * turn -Werror=null-dereference into a warning
+
+ [ Daniel Willmann ]
+ * manuals: Add script to regenerate vty/counter documentation
+ * manuals: Update vty/counter documentation
+ * Add/fix help string for version option
+ * osmo-sgsn: Fix outdated information in usermanual
+ * configuration.adoc: Small fixes
+ * configuration.adoc: Add a section about encryption
+
+ [ Ruben Undheim ]
+ * Spelling fixes
+
+ -- Pau Espin Pedrol <pespin@sysmocom.de> Thu, 08 Aug 2019 16:46:31 +0200
+
+osmo-sgsn (1.4.0) unstable; urgency=medium
+
+ [ Alexander Couzens ]
+ * gprs_subscriber: gsup_auth_error: reject MS in all cases
+ * gprs_gmm: make functions relating to GMM Attach Request public
+ * gprs_gmm: make extract_subscr_msisdn extract_subscr_hlr public
+ * gprs_gmm: Cancel Location: use detach type IMSI
+ * vty: add cmd "reset sgsn state"
+ * tests: remove gmm unit tests
+ * gprs_gmm: introduce a GMM Attach Request FSM
+ * debian: add missing build dependencies
+ * sgsn: use gtp_clear_queues() when reset sgsn state
+ * vty: restart sgsn state: improve output message
+ * sgsn_ggsn_ctx_drop_pdp: protect against nullpointer when MM is gone
+ * gprs_sgsn.h: fix wrong type of re-attempts
+ * GTP: refactor the echo timer
+ * gprs_gmm: dont answer unknown IMSI/TMSI on Service Requests NET_FAIL
+ * gprs_gmm: Fix missing Security Command for 3G when attaching
+ * sgsn_libgtp: fix a potential memleak when the GGSN is not reachable
+ * gprs_llc: remove the FCS from the msgb by trim'ing the msgb
+ * OsmoSGSN: add rate counter documentation
+
+ [ Daniel Willmann ]
+ * gb_proxy: tallocate memory for gbproxy cfg so it can be a talloc ctx
+ * gb_proxy: Add ctrl interface and nsvc-state, gbproxy-state commands
+ * git-version-gen: Don't check for .git directory
+
+ [ Stefan Sperling ]
+ * add a test for OS#3178 (invalid unitdata message)
+ * finish gbproxy_parse_bssgp_unitdata test
+ * fix bogus assertion in encode_comp_field()
+ * fix bogus error check in gprs_sndcp_comp_create()
+ * use enums consistently instead of falling back to int
+ * update gbproxy test expected output
+ * consistently check the result of osmo_shift_v_fixed()
+ * remove pointless declaration of struct gsm_network
+ * make gsup ipa name configurable in osmo-sgsn.cfg
+
+ [ Pau Espin Pedrol ]
+ * jenkins.sh: Use --enable-werror only when iu support is disabled
+ * jenkins.sh: Remove non-existent configure options
+ * Drop all references of unused SMPP
+ * Drop all references of unused MGCP
+ * Drop unused common_vty.c
+ * sgsn_libgtp.c: Log pointer of deleted context
+ * Maintain per ggsn pdp ctx list
+ * osmo-sgsn: ping GGSN periodically and check for restart counter
+ * Disarm T3395 when dettaching mmctx from pdpctx
+ * examples: Enable by default echo req towards active GGSNs
+ * vty: Add cmd to disable echo loop explictly
+ * Add optional TearDownInd IE in PDP DEACT REQ towards PCU
+ * sgsn: Don't attempt to delete GTP pdp ctx if GGSN was restarted
+ * Forward GGSN originated DEACT PDP CTX REQ
+ * sgsn: Fix T3395 firing forever
+ * sgsn: subscriber: Avoid calling memcpy with NULL src
+ * sgsn: cdr: Fix uninitialized string access if ggsn is detached
+ * sgsn: gtp: Use new API to send PDP DEL CTX REQ without freeing ctx locally
+ * sgsn: Fix crash using new libgtp cb_recovery2 API
+ * gbproxy: Replace '.' in counter names with ':'
+ * Drop gprs_msgb_copy with libosmocore replacement
+ * Drop gprs_msgb_resize_area with libosmocore replacement
+ * Use osmo_clock_gettime from libosmocore
+ * gbproxy: Add VTY parameter: link stored-msgs-max-length
+ * gbproxy: Add new VTY-managed timer: link-list clean-stale-timer
+ * gbproxy: Replace '.' in counter names with ':'
+ * Add osmo-gtphub systemd service file
+ * debian: Fix typo in rules preventing build with IU support
+ * Install systemd services with autotools
+ * Install sample cfg file to /etc/osmocom
+ * Update wrong references to bsc in sgsn code
+ * Allocate sgsn_instance with talloc
+ * gbproxy: flag gbproxy_assign_imsi as static
+ * gbproxy: Fix abort during APN patch
+ * gbproxy: Remove unneeded parse_ctx param
+ * gbproxy: flush_stored_messages: Move comment to func description
+ * gbproxy: flush_stored_messages: Log and route using stored_msg info
+ * gbproxy: flush_stored_messages: Get rid of msg param
+ * Allow easily disabling GFDL references
+ * OsmoSGSN: configuration: Move pdp ctx specific CDR fields to its own table
+ * OsmoSGSN: configuration: Add missing pdp-periodic event
+ * OsmoSGSN: configuration: Document CDR CTRL interface
+ * OsmoSGSN: overview: Fix typo and reference OpenGGSN->OsmoGGSN
+
+ [ Harald Welte ]
+ * migrate to oap_client in libosmogsm
+ * remove libcommon
+ * gbproxy-legacy: Ensure well-formed config file
+ * Remove local libgsupclient; Use libosmo-gsup-client from osmo-hlr
+ * initial checkin of manuals to public repo
+ * Add link to Asciidoc source code of manual
+ * OsmoSGSN: Fix formatting/cross reference in CDR section
+ * Update GSUP chapter regarding UMTS AKA and other recent changes
+ * GSUP: Add ladder diagrams for protocol transactions / procedures
+ * share chapters/gsup.adoc from OsmoSGSN to OsmoMSC + OsmoHLR
+ * vty-ref: Update URI of docbook 5.0 schema
+
+ [ Neels Hofmeyr ]
+ * use __FILE__, not __BASE_FILE__
+ * vty: fix doc str for 'reset sgsn state'
+ * vty: add SCCP related vty commands
+ * fix build: remove unused variable
+ * Importing history from osmo-gsm-manuals.git
+ * add 'make check' target
+ * fix 'make clean': shell glob, ignore failure
+ * refactor Makefile build rules, don't use the FORCE
+ * OsmoSGSN: update VTY reference
+ * sgsn: update vty reference
+
+ [ Oliver Smith ]
+ * gtphub: Add --version cmdline option
+ * build manuals moved here from osmo-gsm-manuals.git
+ * Fix DISTCHECK_CONFIGURE_FLAGS override
+ * contrib/jenkins.sh: build and publish manuals
+ * contrib: fix makedistcheck with disabled systemd
+
+ [ Max ]
+ * Cleanup non-existent files from debian/copyright
+ * Use safer functions for IMSI ACL
+ * gbproxy: fix formatting in gbproxy-state command
+ * gbproxy: add number-of-peers ctrl command
+ * Revert "gbproxy: fix formatting in gbproxy-state command"
+ * Add OsmoSGSN control interface description
+ * Remove misleading comment
+ * Constify sgsn_acl_lookup() parameter
+ * Drop unused osmo-sgsn.pc
+ * Use explicit length check
+ * Use explicit parameter for sgsn_auth_init()
+
+ [ Jonathan Brielmaier ]
+ * fix various typos across all manuals
+
+ [ ikostov ]
+ * SGSN: add Auth. policy, NS Statistics and BSSGP state examples, tweaks
+ * GSUP, OAP: fix AUTS length to 14, not 16
+
+ [ Philipp Maier ]
+ * osmo-sgsn: Update VTY command reference
+ * osmo-sgsn: improve auth-policy explaination
+ * osmo-sgsn: Explain TCP/IP header compression
+ * osmo-sgsn: fix arrow tips in flow diagrams
+
+ [ Holger Hans Peter Freyther ]
+ * sgsn: Fix numbering of QoS and add basic description for APN
+ * sgsn: Add charging characteristics to GSUP
+
+ -- Harald Welte <laforge@gnumonks.org> Wed, 23 Jan 2019 18:32:41 +0100
+
+osmo-sgsn (1.3.0) unstable; urgency=medium
+
+ [ Neels Hofmeyr ]
+ * drop osmo_sgsn.cfg from src/gprs dir
+ * change default config filename to osmo-sgsn.cfg, not osmo_sgsn.cfg
+ * vty: skip installing cmds now always installed by default
+ * add --enable-sanitize config option
+ * use default point-code as listed on Point_Codes wiki page
+ * gprs_gmm: segfault: gracefully handle failure to alloc context
+ * gsm48_rx_gmm_att_req: fix error handling: don't clean up NULL llme
+ * gprs_llc: tx dl ud: make mismatching LLE not crash osmo-sgsn
+ * fix build: missing LIBGTP_CFLAGS in sgsn_test
+ * sgsn_test: guard against struct gprs_ra_id changing
+ * vty: absorb command explanations from osmo-gsm-manuals
+ * configure: add --enable-werror
+ * implement support for 3-digit MNC with leading zeros
+ * osmo-gbproxy: use 'osmo-gbproxy.cfg' as default config name
+ * compiler warnings: use enum ranap_nsap_addr_enc, constify local var
+ * use osmo_init_logging2(), fix regression test memleaks
+ * auth+ciph: log is_r99 and auth types
+ * log two RA Update Request failure causes
+ * GERAN: allow GSM SRES on UMTS AKA challenge
+
+ [ Alexander Couzens ]
+ * .gitignore: remove unneeded ignores of bsc/msc/nitb files
+ * tests/ctrl_test_runner.py: remove BSC/NAT TestRunner
+ * debian: remove doublicated project name in example files
+ * .gitignore: remove non-existent /src/utils exludes
+ * configure.ac: remove pcap check
+ * configure.ac: remove unused libcdk check
+ * .service: remove OpenBSC from service desription
+ * mandatory depend on libc-ares and libgtp
+ * GMM: dont reply to GMM_DETACH_REQ with POWER OFF when MS is unknown
+
+ [ Harald Welte ]
+ * Replace '.' in counter names with ':'
+ * Add talloc context introspection via VTY
+
+ [ Pau Espin Pedrol ]
+ * Replace '.' in counter names with ':'
+ * tests: Fix selection of python version
+ * sgsn_cdr: Split log formatting into a snprintf function
+ * Add vty cmd 'cdr trap' to send CDR through CTRL iface
+ * tests: sgsn_test: Define wrap APIs with correct parameters
+ * cosmetic: tests: sgsn_test: Use proper formatting and remove uneeded semicolons
+ * gprs_gmm: Remove unused variable
+ * cosmetic: gprs_gmm: Remove trailing whitespace
+ * gprs_gmm: Convert warning message to pragma message
+ * configure.ac: Enable Wall in CFLAGS
+ * .gitignore: Add m4 files
+ * sgsn_libgtp.c: Fix typos and whitespace
+
+ [ Max ]
+ * Fix display of GTP addresses
+ * Show GTP version for PDP context in vty
+ * Remove unneeded .py scripts
+ * Replace '.' in counter names with ':'
+ * Remove dead code
+ * Enable sanitize for CI tests
+ * cosmetic: use macro for gtphub plane iteration
+ * Use connection id when allocating rate counters
+ * Migrate from OpenSSL to osmo_get_rand_id()
+ * Remove obsolete ./configure option
+ * Fix RAI construction
+ * gtphub: make rate_ctr unique
+ * Remove unused bsc_version.c
+ * Use gsm48_encode_ra() for RAI encoding
+ * gtphub: check for gsn_addr_from_sockaddr() errors
+ * gtphub: check for gsn_addr_from_sockaddr() error
+
+ -- Pau Espin Pedrol <pespin@sysmocom.de> Thu, 03 May 2018 19:01:44 +0200
+
+osmo-sgsn (1.2.0) unstable; urgency=medium
+
+ [ Neels Hofmeyr ]
+ * jenkins: fix build: remove unused dependencies
+ * debian: fix osmo-sgsn.install, tweak VCS link and descriptions
+ * drop files unrelated to osmo-sgsn
+ * rewrite README
+ * configure.ac: set name to osmo-sgsn, fix ML addr
+ * move openbsc.pc to osmo-sgsn.pc
+ * move include/openbsc to include/osmocom/sgsn
+ * jenkins.sh: fix echo string to say osmo-sgsn, not msc
+ * jenkins: use osmo-clean-workspace.sh before and after build
+
+ [ Alexander Couzens ]
+ * debian: fix paths of examples
+ * debian/rules: show testsuite.log when tests are failing
+
+ [ Max ]
+ * Remove rest_octets.h
+ * gbproxy: ensure peer allocation result
+ * jenkins: use osmo-ggsn for tests
+ * Cleanup configure checks
+ * Use extended logging for PDP contexts
+ * deb: fix copyright file issues
+ * Move P-TMSI alloc/update into separate function
+ * Check for correct P-TMSI allocation
+ * Use new FSF address in license header
+ * SGSN: uncomment BSSGP vty tests
+ * SGSN: print additional GTP-related info
+ * SGSN: check that GSN is created in proper mode
+ * Fix APN printing
+ * Fix build after recent rate_ctr patches
+ * gbproxy: don't link unnecessary
+ * Fix libosmo-sigtran dependency
+ * jenkins: check for IU properly
+ * Log GTP-U endpoints update
+ * Log address on GTP creation
+
+ [ Pau Espin Pedrol ]
+ * Remove unneeded dep libdbi
+
+ [ Philipp Maier ]
+ * log: fix default loglevels
+ * non-iu-build: guard vty libosmo-sigtran function calls.
+ * configure: fix libosmo-sigtran dependency
+
+ [ Harald Welte ]
+ * Debian: Add systemd service files for osmo-sgsn and osmo-gbproxy
+ * Debian: fix dh_strip rules for creating one -dbg per program
+
+ -- Harald Welte <laforge@gnumonks.org> Sat, 28 Oct 2017 19:07:48 +0200
+
osmo-sgsn (0.1.0) unstable; urgency=low
* Initial release.
diff --git a/debian/control b/debian/control
index 4a3a07f73..a37ff6589 100644
--- a/debian/control
+++ b/debian/control
@@ -4,22 +4,24 @@ Priority: extra
Maintainer: Alexander Couzens <lynxis@fe80.eu>
Build-Depends: debhelper (>=9),
dh-autoreconf,
+ dh-systemd (>= 1.5),
autotools-dev,
autoconf,
automake,
libtool,
pkg-config,
- libssl-dev,
libtalloc-dev,
libc-ares-dev,
- libgtp-dev,
- libdbi-dev,
- libdbd-sqlite3,
- libosmocore-dev,
- libosmo-abis-dev,
- libosmo-ranap-dev,
- libosmo-sccp-dev,
- libosmo-netif-dev
+ libgtp-dev (>= 1.5.0),
+ libosmocore-dev (>= 1.2.0),
+ libosmo-abis-dev (>= 0.6.0),
+ libosmo-netif-dev (>= 0.4.0),
+ libosmo-gsup-client-dev (>= 1.0.0),
+ libasn1c-dev (>= 0.9.30),
+ libosmo-ranap-dev (>= 0.6.0),
+ libosmo-sigtran-dev (>= 1.0.0),
+ libosmo-sccp-dev (>= 1.0.0),
+ osmo-gsm-manuals-dev
Standards-Version: 3.9.8
Vcs-Git: git://git.osmocom.org/osmo-sgsn.git
Vcs-Browser: https://git.osmocom.org/osmo-sgsn
@@ -30,14 +32,14 @@ Package: osmo-sgsn
Architecture: any
Multi-Arch: foreign
Depends: ${misc:Depends}, ${shlibs:Depends}
-Description: OsmoSGSN: Osmocom's Serving GPRS Support Node for 2G and 3G packet-switched mobile networks
+Description: OsmoSGSN: Osmocom's Serving GPRS Support Node for 2G and 3G packet-switched mobile networks
Package: osmo-sgsn-dbg
Section: debug
Architecture: any
Multi-Arch: same
Depends: osmo-sgsn (= ${binary:Version}), ${misc:Depends}
-Description: OsmoSGSN: Osmocom's Serving GPRS Support Node for 2G and 3G packet-switched mobile networks
+Description: OsmoSGSN: Osmocom's Serving GPRS Support Node for 2G and 3G packet-switched mobile networks
Package: osmo-gtphub
Architecture: any
@@ -66,3 +68,12 @@ Section: debug
Priority: extra
Depends: osmo-gbproxy (= ${binary:Version}), ${misc:Depends}
Description: Debug symbols for Osmocom GPRS Gb Interface Proxy
+
+Package: osmo-sgsn-doc
+Architecture: all
+Section: doc
+Priority: optional
+Depends: ${misc:Depends}
+Description: ${misc:Package} PDF documentation
+ Various manuals: user manual, VTY reference manual and/or
+ protocol/interface manuals.
diff --git a/debian/copyright b/debian/copyright
index b58117edc..fa7405fed 100644
--- a/debian/copyright
+++ b/debian/copyright
@@ -11,95 +11,44 @@ Files: .gitignore
README.vty-tests
configure.ac
contrib/Makefile.am
- contrib/a-link/sccp-split-by-con.lua
- contrib/bsc-test/README
- contrib/bsc-test/all_dial
- contrib/bsc-test/dial.sh
- contrib/bsc-test/drop-oml.sh
- contrib/bsc-test/drop.sh
- contrib/bsc-test/hangup
- contrib/bsc-test/msc.sh
- contrib/bsc_control.py
- contrib/bt.py
- contrib/convert_to_enum.py
- contrib/ctrl2sse.py
contrib/gprs/gb-proxy-unblock-bug.py
contrib/gprs/gprs-bssgp-histogram.lua
contrib/gprs/gprs-buffer-count.lua
contrib/gprs/gprs-split-trace-by-tlli.lua
contrib/gprs/gprs-verify-nu.lua
- contrib/hlr-remove-old.sql
- contrib/hlrsync/hlrsync.py
contrib/ipa.py
contrib/jenkins.sh
- contrib/mgcp_server.py
- contrib/nat/test_regexp.c
- contrib/nat/ussd_example.py
- contrib/rtp/gen_rtp_header.erl
- contrib/rtp/rtp_replay.st
- contrib/rtp/rtp_replay_shared.st
- contrib/rtp/rtp_replay_sip.st
- contrib/rtp/timestamp_rtp.lua
- contrib/sms/fill-hlr.st
- contrib/sms/hlr-query.st
- contrib/sms/sqlite-probe.tap.d
contrib/soap.py
- contrib/systemd/osmo-bsc-mgcp.service
- contrib/systemd/osmo-bsc.service
contrib/systemd/osmo-gbproxy.service
- contrib/systemd/osmo-msc.service
- contrib/systemd/osmo-nitb.service
contrib/systemd/osmo-sgsn.service
- contrib/testconv/Makefile
- contrib/testconv/testconv_main.c
contrib/twisted_ipa.py
- doc/BS11-OML.txt
doc/Makefile.am
- doc/call-routing.txt
- doc/channel_release.txt
- doc/e1-data-model.txt
doc/examples/Makefile.am
- doc/examples/osmo-bsc/osmo-bsc.cfg
- doc/examples/osmo-bsc_mgcp/mgcp.cfg
- doc/examples/osmo-bsc_nat/black-list.cfg
- doc/examples/osmo-bsc_nat/bscs.cfg
- doc/examples/osmo-bsc_nat/osmo-bsc_nat.cfg
doc/examples/osmo-gbproxy/osmo-gbproxy-legacy.cfg
doc/examples/osmo-gbproxy/osmo-gbproxy.cfg
doc/examples/osmo-gtphub/gtphub-example.txt
doc/examples/osmo-gtphub/osmo-gtphub-1iface.cfg
doc/examples/osmo-gtphub/osmo-gtphub.cfg
- doc/examples/osmo-msc/osmo-msc.cfg
doc/examples/osmo-sgsn/osmo-sgsn.cfg
- doc/gsm-hopping.txt
- doc/handover.txt
- doc/ipa-sccp.txt
- doc/oml-interface.txt
- doc/osmo-nitb-data_structures.dot
- doc/paging.txt
include/Makefile.am
- include/openbsc/Makefile.am
- include/openbsc/common.h
- include/openbsc/crc24.h
- include/openbsc/debug.h
- include/openbsc/gb_proxy.h
- include/openbsc/gprs_gb_parse.h
- include/openbsc/gprs_gmm.h
- include/openbsc/gprs_llc.h
- include/openbsc/gprs_sgsn.h
- include/openbsc/gprs_sndcp.h
- include/openbsc/gprs_subscriber.h
- include/openbsc/rest_octets.h
- include/openbsc/sgsn.h
- include/openbsc/vty.h
+ include/osmocom/sgsn/Makefile.am
+ include/osmocom/sgsn/common.h
+ include/osmocom/sgsn/crc24.h
+ include/osmocom/sgsn/debug.h
+ include/osmocom/sgsn/gb_proxy.h
+ include/osmocom/sgsn/gprs_gb_parse.h
+ include/osmocom/sgsn/gprs_gmm.h
+ include/osmocom/sgsn/gprs_llc.h
+ include/osmocom/sgsn/gprs_sgsn.h
+ include/osmocom/sgsn/gprs_sndcp.h
+ include/osmocom/sgsn/gprs_subscriber.h
+ include/osmocom/sgsn/sgsn.h
+ include/osmocom/sgsn/vty.h
m4/README
- openbsc.pc.in
src/Makefile.am
src/gprs/.gitignore
src/gprs/Makefile.am
src/gprs/osmo_sgsn.cfg
- src/libcommon/Makefile.am
- src/libcommon/gsup_test_client.c
tests/Makefile.am
tests/atlocal.in
tests/gbproxy/Makefile.am
@@ -109,12 +58,6 @@ Files: .gitignore
tests/gprs/gprs_test.ok
tests/gtphub/Makefile.am
tests/gtphub/gtphub_test.ok
- tests/libiudummy/Makefile.am
- tests/libiudummy/README
- tests/libiudummy/iudummy.c
- tests/oap/Makefile.am
- tests/oap/oap_client_test.err
- tests/oap/oap_client_test.ok
tests/sgsn/Makefile.am
tests/sgsn/sgsn_test.ok
tests/slhc/Makefile.am
@@ -126,67 +69,51 @@ Files: .gitignore
tests/v42bis/v42bis_test.ok
tests/xid/Makefile.am
tests/xid/xid_test.ok
- tools/hlrstat.pl
Copyright: __NO_COPYRIGHT_NOR_LICENSE__
License: __NO_COPYRIGHT_NOR_LICENSE__
-Files: include/openbsc/a_reset.h
- include/openbsc/gprs_llc_xid.h
- include/openbsc/gprs_sndcp_comp.h
- include/openbsc/gprs_sndcp_dcomp.h
- include/openbsc/gprs_sndcp_pcomp.h
- include/openbsc/gprs_sndcp_xid.h
- include/openbsc/gprs_utils.h
- include/openbsc/gsup_client.h
- include/openbsc/gtphub.h
- include/openbsc/oap_client.h
- include/openbsc/signal.h
+Files: include/osmocom/sgsn/a_reset.h
+ include/osmocom/sgsn/gprs_llc_xid.h
+ include/osmocom/sgsn/gprs_sndcp_comp.h
+ include/osmocom/sgsn/gprs_sndcp_dcomp.h
+ include/osmocom/sgsn/gprs_sndcp_pcomp.h
+ include/osmocom/sgsn/gprs_sndcp_xid.h
+ include/osmocom/sgsn/gprs_utils.h
+ include/osmocom/sgsn/gtphub.h
+ include/osmocom/sgsn/signal.h
+ src/gprs/gprs_llc_parse.c
src/gprs/crc24.c
- src/gprs/gb_proxy.c
- src/gprs/gb_proxy_main.c
- src/gprs/gb_proxy_patch.c
- src/gprs/gb_proxy_peer.c
- src/gprs/gb_proxy_tlli.c
- src/gprs/gb_proxy_vty.c
src/gprs/gprs_gb_parse.c
- src/gprs/gprs_gmm.c
- src/gprs/gprs_llc.c
- src/gprs/gprs_llc_parse.c
- src/gprs/gprs_llc_vty.c
- src/gprs/gprs_llc_xid.c
- src/gprs/gprs_sgsn.c
- src/gprs/gprs_sndcp.c
- src/gprs/gprs_sndcp_comp.c
- src/gprs/gprs_sndcp_dcomp.c
- src/gprs/gprs_sndcp_pcomp.c
- src/gprs/gprs_sndcp_vty.c
- src/gprs/gprs_sndcp_xid.c
- src/gprs/gprs_subscriber.c
src/gprs/gprs_utils.c
- src/gprs/gsup_client.c
- src/gprs/gtphub.c
- src/gprs/gtphub_main.c
- src/gprs/gtphub_vty.c
- src/gprs/oap_client.c
src/gprs/sgsn_ares.c
- src/gprs/sgsn_auth.c
- src/gprs/sgsn_cdr.c
- src/gprs/sgsn_ctrl.c
- src/gprs/sgsn_libgtp.c
- src/gprs/sgsn_main.c
- src/gprs/sgsn_vty.c
- src/libcommon/bsc_version.c
- src/libcommon/common_vty.c
- src/libcommon/debug.c
- src/libcommon/gsm_data.c
- src/libcommon/gsm_data_shared.c
- src/libcommon/gsm_subscriber_base.c
- src/libcommon/gsup_client.c
- src/libcommon/oap_client.c
- src/libcommon/socket.c
- src/libcommon/talloc_ctx.c
+ src/gbproxy/gb_proxy.c
+ src/gbproxy/gb_proxy_main.c
+ src/gbproxy/gb_proxy_patch.c
+ src/gbproxy/gb_proxy_peer.c
+ src/gbproxy/gb_proxy_tlli.c
+ src/gbproxy/gb_proxy_vty.c
+ src/gtphub/gtphub.c
+ src/gtphub/gtphub_main.c
+ src/gtphub/gtphub_vty.c
+ src/sgsn/gprs_gmm.c
+ src/sgsn/gprs_llc.c
+ src/sgsn/gprs_llc_vty.c
+ src/sgsn/gprs_llc_xid.c
+ src/sgsn/gprs_sgsn.c
+ src/sgsn/gprs_sndcp.c
+ src/sgsn/gprs_sndcp_comp.c
+ src/sgsn/gprs_sndcp_dcomp.c
+ src/sgsn/gprs_sndcp_pcomp.c
+ src/sgsn/gprs_sndcp_vty.c
+ src/sgsn/gprs_sndcp_xid.c
+ src/sgsn/gprs_subscriber.c
+ src/sgsn/sgsn_auth.c
+ src/sgsn/sgsn_cdr.c
+ src/sgsn/sgsn_ctrl.c
+ src/sgsn/sgsn_libgtp.c
+ src/sgsn/sgsn_main.c
+ src/sgsn/sgsn_vty.c
tests/gtphub/gtphub_test.c
- tests/oap/oap_client_test.c
tests/sgsn/sgsn_test.c
tests/slhc/slhc_test.c
tests/sndcp_xid/sndcp_xid_test.c
@@ -213,9 +140,8 @@ License: AGPL-3.0+
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
-Files: src/gprs/gtphub_ares.c
- src/gprs/gtphub_sock.c
- tests/ctrl_test_runner.py
+Files: src/gtphub/gtphub_ares.c
+ src/gtphub/gtphub_sock.c
tests/gbproxy/gbproxy_test.c
Copyright: 2013 Jacob Erlbeck <jerlbeck@sysmocom.de>
2013 sysmocom s.f.m.c. GmbH
@@ -223,8 +149,8 @@ Copyright: 2013 Jacob Erlbeck <jerlbeck@sysmocom.de>
2015 sysmocom s.f.m.c. GmbH <info@sysmocom.de>
License: __NO_LICENSE__
-Files: include/openbsc/v42bis.h
- include/openbsc/v42bis_private.h
+Files: include/osmocom/sgsn/v42bis.h
+ include/osmocom/sgsn/v42bis_private.h
Copyright: 2005-2011 Steve Underwood
License: LGPL-2.1
This program is free software; you can redistribute it and/or modify
@@ -238,33 +164,20 @@ License: LGPL-2.1
.
You should have received a copy of the GNU Lesser General Public
License along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
.
The FSF address in the above text is the old one.
.
On Debian systems, the complete text of the GNU Lesser General Public License
Version 2.1 can be found in `/usr/share/common-licenses/LGPL-2.1'.
-Files: osmoappdesc.py
-Copyright: 2013 Katerina Barone-Adesi <kat.obsc@gmail.com>
-License: GPL-3.0+
- This program 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, either version 3 of the License, or
- (at your option) any later version.
- .
- 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/>
- .
- Most systems won't be able to use these, so they're separated out
- .
- On Debian systems, the complete text of the GNU General Public License
- Version 3 can be found in `/usr/share/common-licenses/GPL-3'.
+Files: osmoappdesc.py
+ tests/ctrl_test_runner.py
+ tests/vty_test_runner.py
+Copyright: 2013 Katerina Barone-Adesi <kat.obsc@gmail.com>
+ 2013 Jacob Erlbeck <jerlbeck@sysmocom.de>
+ 2013-2014 Holger Hans Peter Freyther <zecke@selfish.org>
+License: GPL-3+
Files: git-version-gen
Copyright: 2007-2010 Free Software Foundation, Inc.
@@ -320,26 +233,6 @@ License: GPL-3.0+
On Debian systems, the complete text of the GNU General Public License
Version 3 can be found in `/usr/share/common-licenses/GPL-3'.
-Files: tests/vty_test_runner.py
-Copyright: 2013 Holger Hans Peter Freyther
- 2013 Katerina Barone-Adesi <kat.obsc@gmail.com>
-License: GPL-3.0+
- This program 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, either version 3 of the License, or
- (at your option) any later version.
- .
- 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'.
-
Files: src/gprs/v42bis.c
Copyright: 2005-2011 Steve Underwood
License: LGPL-2.1
@@ -354,7 +247,7 @@ License: LGPL-2.1
.
You should have received a copy of the GNU Lesser General Public
License along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
.
THIS IS A WORK IN PROGRESS. IT IS NOT FINISHED.
Currently it performs the core compression and decompression functions OK.
@@ -367,7 +260,7 @@ License: LGPL-2.1
On Debian systems, the complete text of the GNU Lesser General Public License
Version 2.1 can be found in `/usr/share/common-licenses/LGPL-2.1'.
-Files: include/openbsc/slhc.h
+Files: include/osmocom/sgsn/slhc.h
Copyright: 1989 Regents of the University of California.
License: __UNKNOWN__
Redistribution and use in source and binary forms are permitted
@@ -422,7 +315,7 @@ License: __UNKNOWN__
Files: m4/ax_check_compile_flag.m4
Copyright: 2008 Guido U. Draheim <guidod@gmx.de>
2011 Maarten Bosmans <mkbosmans@gmail.com>
-License: GPL-3.0+ with unknown exception *** check multiple exceptions ***
+License: GNU-All-Permissive-License
This program 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, either version 3 of the License, or (at your
diff --git a/debian/osmo-gbproxy.install b/debian/osmo-gbproxy.install
index 62ebe2a20..a8c0dadd1 100644
--- a/debian/osmo-gbproxy.install
+++ b/debian/osmo-gbproxy.install
@@ -1,2 +1,5 @@
+etc/osmocom/osmo-gbproxy.cfg
+lib/systemd/system/osmo-gbproxy.service
usr/bin/osmo-gbproxy
-usr/share/doc/openbsc/examples/osmo-gbproxy
+usr/share/doc/osmo-sgsn/examples/osmo-gbproxy/osmo-gbproxy-legacy.cfg usr/share/doc/osmo-gbproxy/examples
+usr/share/doc/osmo-sgsn/examples/osmo-gbproxy/osmo-gbproxy.cfg usr/share/doc/osmo-gbproxy/examples
diff --git a/debian/osmo-gtphub.install b/debian/osmo-gtphub.install
index 8a5dafd25..078207672 100644
--- a/debian/osmo-gtphub.install
+++ b/debian/osmo-gtphub.install
@@ -1,2 +1,5 @@
+etc/osmocom/osmo-gtphub.cfg
+lib/systemd/system/osmo-gtphub.service
usr/bin/osmo-gtphub
-usr/share/doc/openbsc/examples/osmo-gtphub
+usr/share/doc/osmo-sgsn/examples/osmo-gtphub/osmo-gtphub-1iface.cfg usr/share/doc/osmo-gtphub/examples
+usr/share/doc/osmo-sgsn/examples/osmo-gtphub/osmo-gtphub.cfg usr/share/doc/osmo-gtphub/examples
diff --git a/debian/osmo-sgsn-doc.install b/debian/osmo-sgsn-doc.install
new file mode 100644
index 000000000..bdc6a9922
--- /dev/null
+++ b/debian/osmo-sgsn-doc.install
@@ -0,0 +1 @@
+usr/share/doc/osmo-sgsn-doc/*.pdf
diff --git a/debian/osmo-sgsn.install b/debian/osmo-sgsn.install
index a92ae18f9..b9a46abf2 100644
--- a/debian/osmo-sgsn.install
+++ b/debian/osmo-sgsn.install
@@ -1,2 +1,5 @@
+/etc/osmocom/osmo-sgsn.cfg
+lib/systemd/system/osmo-sgsn.service
usr/bin/osmo-sgsn
-usr/share/doc/openbsc/examples/osmo-sgsn
+usr/share/doc/osmo-sgsn/examples/osmo-sgsn/osmo-sgsn.cfg usr/share/doc/osmo-sgsn/examples
+usr/share/doc/osmo-sgsn/examples/osmo-sgsn/osmo-sgsn-accept-all.cfg usr/share/doc/osmo-sgsn/examples
diff --git a/debian/rules b/debian/rules
index 4fe1f467d..cfd692a48 100755
--- a/debian/rules
+++ b/debian/rules
@@ -46,8 +46,8 @@
# debmake generated override targets
# Set options for ./configure
-CONFIGURE_FLAGS += --enable-iu
-override_dh_configure:
+CONFIGURE_FLAGS += --enable-iu --with-systemdsystemunitdir=/lib/systemd/system --enable-manuals
+override_dh_auto_configure:
dh_auto_configure -- $(CONFIGURE_FLAGS)
#
# Do not install libtool archive, python .pyc .pyo
@@ -56,6 +56,14 @@ override_dh_configure:
# See https://www.debian.org/doc/manuals/developers-reference/best-pkging-practices.html#bpp-dbg
override_dh_strip:
- dh_strip --dbg-package=osmo-sgsn-dbg
- dh_strip --dbg-package=osmo-gtphub-dbg
- dh_strip --dbg-package=osmo-gbproxy-dbg
+ dh_strip -posmo-sgsn --dbg-package=osmo-sgsn-dbg
+ dh_strip -posmo-gtphub --dbg-package=osmo-gtphub-dbg
+ dh_strip -posmo-gbproxy --dbg-package=osmo-gbproxy-dbg
+
+# Print test results in case of a failure
+override_dh_auto_test:
+ dh_auto_test || (find . -name testsuite.log -exec cat {} \; ; false)
+
+# Don't create .pdf.gz files (barely saves space and they can't be opened directly by most pdf readers)
+override_dh_compress:
+ dh_compress -X.pdf
diff --git a/doc/Makefile.am b/doc/Makefile.am
index 5a231074c..15f36b7eb 100644
--- a/doc/Makefile.am
+++ b/doc/Makefile.am
@@ -1,3 +1,4 @@
SUBDIRS = \
examples \
+ manuals \
$(NULL)
diff --git a/doc/examples/Makefile.am b/doc/examples/Makefile.am
index 530c3fa8f..2b5781a59 100644
--- a/doc/examples/Makefile.am
+++ b/doc/examples/Makefile.am
@@ -1,3 +1,13 @@
+OSMOCONF_FILES = \
+ osmo-gtphub/osmo-gtphub.cfg \
+ osmo-sgsn/osmo-sgsn.cfg \
+ osmo-gbproxy/osmo-gbproxy.cfg
+
+osmoconfdir = $(sysconfdir)/osmocom
+osmoconf_DATA = $(OSMOCONF_FILES)
+
+EXTRA_DIST = $(OSMOCONF_FILES)
+
CFG_FILES = find $(srcdir) -name '*.cfg*' | sed -e 's,^$(srcdir),,'
dist-hook:
diff --git a/doc/examples/osmo-gbproxy/osmo-gbproxy-legacy.cfg b/doc/examples/osmo-gbproxy/osmo-gbproxy-legacy.cfg
index 15fd74a2b..c471c38b5 100644
--- a/doc/examples/osmo-gbproxy/osmo-gbproxy-legacy.cfg
+++ b/doc/examples/osmo-gbproxy/osmo-gbproxy-legacy.cfg
@@ -3,20 +3,20 @@
!!
!
log stderr
- logging filter all 1
- logging color 1
- logging timestamp 0
- logging level all debug
- logging level gprs debug
- logging level ns info
- logging level bssgp debug
- logging level lglobal notice
- logging level llapd notice
- logging level linp notice
- logging level lmux notice
- logging level lmi notice
- logging level lmib notice
- logging level lsms notice
+ logging filter all 1
+ logging color 1
+ logging timestamp 0
+ logging level all debug
+ logging level gprs debug
+ logging level ns info
+ logging level bssgp debug
+ logging level lglobal notice
+ logging level llapd notice
+ logging level linp notice
+ logging level lmux notice
+ logging level lmi notice
+ logging level lmib notice
+ logging level lsms notice
!
line vty
no login
diff --git a/doc/examples/osmo-gbproxy/osmo-gbproxy.cfg b/doc/examples/osmo-gbproxy/osmo-gbproxy.cfg
index 0c3917a3e..29f698f32 100644
--- a/doc/examples/osmo-gbproxy/osmo-gbproxy.cfg
+++ b/doc/examples/osmo-gbproxy/osmo-gbproxy.cfg
@@ -22,4 +22,5 @@ ns
timer tns-alive-retries 10
encapsulation framerelay-gre enabled 0
encapsulation framerelay-gre local-ip 0.0.0.0
+ encapsulation udp local-ip 127.0.0.100
encapsulation udp local-port 23000
diff --git a/doc/examples/osmo-gtphub/gtphub-example.txt b/doc/examples/osmo-gtphub/gtphub-example.txt
index 9c65f925f..17f6914d3 100644
--- a/doc/examples/osmo-gtphub/gtphub-example.txt
+++ b/doc/examples/osmo-gtphub/gtphub-example.txt
@@ -59,7 +59,7 @@ The LD_LIBRARY_PATH below may be needed if OpenGGSN installed to /usr/local.
2. GTPHub:
cd <your-test-dir>
- path/to/openbsc/openbsc/src/gprs/osmo-gtphub -c gtphub.conf #-e 1 #for DEBUG level
+ path/to/openbsc/openbsc/src/gtphub/osmo-gtphub -c gtphub.conf #-e 1 #for DEBUG level
3. SGSN tests:
diff --git a/doc/examples/osmo-gtphub/osmo-gtphub.cfg b/doc/examples/osmo-gtphub/osmo-gtphub.cfg
index 0dc415047..0bb63e312 100644
--- a/doc/examples/osmo-gtphub/osmo-gtphub.cfg
+++ b/doc/examples/osmo-gtphub/osmo-gtphub.cfg
@@ -8,7 +8,7 @@ line vty
gtphub
! Local addresses to listen on and send from, each on standard ports
! 2123 and 2152. Setting these addresses is mandatory.
- bind-to-sgsns 127.0.0.1
+ bind-to-sgsns 127.0.0.10
bind-to-ggsns 127.0.0.2
! Local nonstandard ports or separate IPs:
diff --git a/doc/examples/osmo-sgsn/osmo-sgsn-accept-all.cfg b/doc/examples/osmo-sgsn/osmo-sgsn-accept-all.cfg
index 5e6434263..85112f41c 100644
--- a/doc/examples/osmo-sgsn/osmo-sgsn-accept-all.cfg
+++ b/doc/examples/osmo-sgsn/osmo-sgsn-accept-all.cfg
@@ -9,6 +9,8 @@ sgsn
gtp local-ip 127.0.0.1
ggsn 0 remote-ip 127.0.0.2
ggsn 0 gtp-version 1
+ ggsn 0 echo-interval 60
+ authentication optional
auth-policy accept-all
!
ns
diff --git a/doc/examples/osmo-sgsn/osmo-sgsn.cfg b/doc/examples/osmo-sgsn/osmo-sgsn.cfg
index 06f035f1b..3be4d4935 100644
--- a/doc/examples/osmo-sgsn/osmo-sgsn.cfg
+++ b/doc/examples/osmo-sgsn/osmo-sgsn.cfg
@@ -9,6 +9,8 @@ sgsn
gtp local-ip 127.0.0.1
ggsn 0 remote-ip 127.0.0.2
ggsn 0 gtp-version 1
+ ggsn 0 echo-interval 60
+ authentication required
auth-policy remote
gsup remote-ip 127.0.0.1
gsup remote-port 4222
diff --git a/doc/examples/osmo-sgsn/osmo-sgsn_custom-sccp.cfg b/doc/examples/osmo-sgsn/osmo-sgsn_custom-sccp.cfg
new file mode 100644
index 000000000..f60c076c2
--- /dev/null
+++ b/doc/examples/osmo-sgsn/osmo-sgsn_custom-sccp.cfg
@@ -0,0 +1,39 @@
+!
+! Osmocom SGSN configuration
+!
+!
+line vty
+ no login
+!
+cs7 instance 0
+ point-code 0.23.4
+ asp asp-clnt-OsmoSGSN-A 2905 0 m3ua
+ remote-ip 172.18.8.200 ! where to reach the STP
+ as as-clnt-OsmoSGSN-A m3ua
+ asp asp-clnt-OsmoSGSN-A
+ routing-key 3 0.23.4
+sgsn
+ gtp local-ip 127.0.0.1
+ ggsn 0 remote-ip 127.0.0.2
+ ggsn 0 gtp-version 1
+ ggsn 0 echo-interval 60
+ authentication required
+ auth-policy remote
+ gsup remote-ip 127.0.0.1
+ gsup remote-port 4222
+ cs7-instance-iu 0
+!
+ns
+ timer tns-block 3
+ timer tns-block-retries 3
+ timer tns-reset 3
+ timer tns-reset-retries 3
+ timer tns-test 30
+ timer tns-alive 3
+ timer tns-alive-retries 10
+ encapsulation udp local-ip 127.0.0.1
+ encapsulation udp local-port 23000
+ encapsulation framerelay-gre enabled 0
+!
+bssgp
+!
diff --git a/doc/manuals/Makefile.am b/doc/manuals/Makefile.am
new file mode 100644
index 000000000..cd57cf148
--- /dev/null
+++ b/doc/manuals/Makefile.am
@@ -0,0 +1,23 @@
+EXTRA_DIST = osmosgsn-usermanual.adoc \
+ osmosgsn-usermanual-docinfo.xml \
+ osmosgsn-vty-reference.xml \
+ osmogbproxy-usermanual.adoc \
+ osmogbproxy-usermanual-docinfo.xml \
+ regen_doc.sh \
+ chapters \
+ vty \
+ osmogbproxy-vty-reference.xml \
+ vty-osmogbproxy \
+ $(NULL)
+
+if BUILD_MANUALS
+ ASCIIDOC = osmosgsn-usermanual.adoc osmogbproxy-usermanual.adoc
+ ASCIIDOC_DEPS = $(srcdir)/chapters/*.adoc
+ include $(OSMO_GSM_MANUALS_DIR)/build/Makefile.asciidoc.inc
+
+ VTY_REFERENCE = osmosgsn-vty-reference.xml osmogbproxy-vty-reference.xml
+ include $(OSMO_GSM_MANUALS_DIR)/build/Makefile.vty-reference.inc
+
+ OSMO_REPOSITORY = osmo-sgsn
+ include $(OSMO_GSM_MANUALS_DIR)/build/Makefile.common.inc
+endif
diff --git a/doc/manuals/chapters/configuration.adoc b/doc/manuals/chapters/configuration.adoc
new file mode 100644
index 000000000..7d3072ec0
--- /dev/null
+++ b/doc/manuals/chapters/configuration.adoc
@@ -0,0 +1,378 @@
+== Configuring OsmoSGSN
+
+Contrary to other network elements (like OsmoBSC, OsmoNITB), the
+OsmoSGSN has a relatively simple configuration.
+
+On the one hand, this is primary because the PCU configuration happens
+from the BSC side.
+
+On the other hand, it is because the Gb interface does not need an
+explicit configuration of each PCU connecting to the SGSN. The
+administrator only has to ensure that the NS and BSSGP layer identities
+(NSEI, NSVCI, BVCI) are unique for each PCU connecting to the SGSN.
+
+=== Configuring the Gp interface
+
+The Gp interface is the GTP-C and GTP-U based interface between the SGSN
+and the GGSNs. It is implemented via UDP on well-known source and
+destination ports.
+
+When an MS requests establishment of a PDP context, it specifies the APN
+(Access Point Name) to which the context shall be established. This APN
+determines which GGSN shall be used, and that in turn determines which
+external IP network the MS will be connected to.
+
+There are two modes in which GGSNs can be configured:
+
+. static GGSN/APN configuration
+. dynamic GGSN/APN configuration
+
+==== Static GGSN/APN configuration
+
+In this mode, there is a static list of GGSNs and APNs configured in
+OsmoSGSN via the VTY / config file.
+
+This is a non-standard method outside of the 3GPP specifications for the
+SGSN, and is typically only used in private/small GPRS networks without
+any access to a GRX.
+
+.Example: Static GGSN/APN configuration (single catch-all GGSN)
+----
+OsmoSGSN(config-sgsn)# gtp local-ip 172.0.0.1 <1>
+OsmoSGSN(config-sgsn)# ggsn 0 remote-ip 127.0.0.2 <2>
+OsmoSGSN(config-sgsn)# ggsn 0 gtp-version 1 <3>
+OsmoSGSN(config-sgsn)# apn * ggsn 0 <4>
+----
+<1> Configure the local IP address at the SGSN used for Gp/GTP
+<2> Specify the remote IP address of the GGSN (for GGSN 0)
+<3> Specify the GTP protocol version used for GGSN 0
+<4> Route all APN names to GGSN 0
+
+
+==== Dynamic GGSN/APN configuration
+
+In this mode, the SGSN will use a DNS-based method to perform the lookup
+from the APN (as specified by the MS) towards the GGSN IP address.
+
+This is the official method as per the 3GPP specifications for the SGSN,
+and what is used on GRX.
+
+.Example: Dynamic GGSN/APN configuration
+----
+OsmoSGSN(config-sgsn)# gtp local-ip 192.168.0.11 <1>
+OsmoSGSN(config-sgsn)# ggsn dynamic <2>
+OsmoSGSN(config-sgsn)# grx-dns-add 1.2.3.4 <3>
+----
+<1> Configure the local IP address at the SGSN used for Gp/GTP
+<2> Enable the dynamic GGSN resolving mode
+<3> Specify the IP address of a DNS server for APN resolution
+
+[[auth-pol]]
+=== Authorization Policy
+
+The authorization policy controls by which rules a subscriber is accepted or
+rejected. The possible options range from accepting just all subscribers without
+further checking, to a fine grained access-control, handled by an external HLR.
+
+accept-all:: All subscribers that attempt to attach to the GPRS network are
+accepted without further checking. This option is intended to be used for
+testing in a controlled environment only. A wide-open network may attract
+subscribers from foreign networks and disrupt their service. It is highly
+recommended to pick one of the options below.
+
+remote:: This option allows to connect OsmoSGSN to an external HLR via the
+GSUP protocol. This will be the preferred option in larger networks.
+
+acl-only:: If no external HLR is available, the network operator has the
+option to control the access using an access control list. The access control
+list contains the IMSI numbers of the allowed subscribers. This method offers
+fine grained access control and is ideal for small networks and lab test
+environments.
+
+closed:: This policy mode softens the strict *acl-only* only mode by also
+implicitly accepting home network subscribers. The decision is made by the MCC
+and MNC part of the IMSI number. The combination of MCC and MNC fully identifies
+a subscribers home network, also known as a Home Network Identity (HNI, i.e.
+MCC and MNC found at the start of the IMSI, e.g. MCC 901 and MNC 700 with
+IMSI 901700000003080).
+
+NOTE: The policy mode *closed* must not be confused with the equally named
+policy that is defined for osmo-nitb!
+
+
+.Example: Assign or change authorization policy
+----
+OsmoSGSN> enable
+OsmoSGSN# configure terminal
+OsmoSGSN(config)# sgsn
+OsmoSGSN(config-sgsn)# auth-policy acl-only <1>
+OsmoSGSN(config-sgsn)# write <2>
+Configuration saved to sgsn.cfg
+OsmoSGSN(config-sgsn)# end
+OsmoSGSN# disable
+OsmoSGSN>
+----
+<1> 'acl-only' is selected as authorization policy
+<2> Saves current changes to cofiguration to make this policy
+persistent
+
+.Example: Access control list
+----
+sgsn
+ auth-policy acl-only <1>
+ imsi-acl add 001010000000003
+ imsi-acl add 001010000000002
+ imsi-acl add 001010000000001
+ imsi-acl add 901700000000068 <2>
+----
+<1> Set the authorization policy
+<2> Add as many subscribers as required
+
+=== Subscriber Configuration
+
+As opposed to OsmoNITB, OsmoSGSN does not feature a built-in HLR.
+
+It can thus operate only in the following two modes:
+
+. Accessing an external HLR (or HLR gateway) via the GSUP protocol
+. Accepting subscribers based on internal ACL (access control list),
+ see also <<auth-pol>>
+
+==== Accessing an external HLR via GSUP
+
+The non-standard GSUP protocol was created to provide OsmoSGSN with
+access to an external HLR while avoiding the complexities of the
+TCAP/MAP protocol stack commonly used by HLRs.
+
+A custom HLR could either directly implement GSUP, or an external gateway
+can be used to convert GSUP to the respective MAP operations.
+
+The primitives/operations of GSUP are modelled to have a 1:1
+correspondence to their MAP counterparts. However, the encoding is much
+simplified by use of a binary TLV encoding similar to Layer 3 of
+GSM/GPRS.
+
+GSUP performs a challenge-response authentication protocol called OAP,
+which uses the standard MILENAGE algorithm for mutual authentication
+between OsmoSGSN and the HLR/HLR-GW.
+
+[[sgsn-ex-gsup]]
+.Example: Using an external HLR via GSUP
+----
+OsmoSGSN(config-sgsn)# gsup remote-ip 2.3.4.5 <1>
+OsmoSGSN(config-sgsn)# gsup remote-port 10000 <2>
+OsmoSGSN(config-sgsn)# gsup oap-k 000102030405060708090a0b0c0d0e0f <3>
+OsmoSGSN(config-sgsn)# gsup oap-opc 101112131415161718191a1b1c1d1e1f <4>
+----
+<1> Configure the IP address of the (remote) HLR or HLR-GW
+<2> Configure the TCP port of the (remote) HLR or HLR-GW
+<3> Specify the OAP shared key
+<4> Specify the OAP shared OPC
+
+
+=== CDR configuration
+
+OsmoSGSN can write a text log file containing CDR (call data records),
+which are commonly used for accounting/billing purpose.
+
+.Example: CDR log file configuration
+----
+OsmoSGSN(config-sgsn)# cdr filename /var/log/osmosgsn.cdr
+OsmoSGSN(config-sgsn)# cdr interval 600 <1>
+----
+<1> Periodically log existing PDP contexts every 600 seconds (10 min)
+
+The CDR file is a simple CSV file including a header line naming the
+individual fields of each CSV line.
+
+==== CDR CTRL interface
+
+Independently of whether logging CDR to a file is enabled or not, OsmoSGSN can
+also provide delivery of CDR through the CTRL interface. CDR are sent by means
+of TRAP messages with variable name _cdr-v1_, and its value is filled using the
+same CSV line format as in the log file, but without CSV header line.
+
+.Example: CDR delivery through CTRL TRAP messages
+----
+OsmoSGSN(config-sgsn)# cdr trap
+----
+
+==== CDR Format
+
+[[sgsn-cdr]]
+.Description of CSV fields in OsmoSGSN CDR file
+[options="header",cols="15%,85%"]
+|===
+|Field Name|Description
+|timestamp|Timestamp in YYYYMMDDhhmmssXXX where XXX are milli-seconds
+|imsi|IMSI causing this CDR
+|imei|IMEI causing this CDR
+|msisdn|MSISDN causing this CDR (if known)
+|cell_id|Cell ID in which the MS was registered last
+|lac|Location Area Code in which the MS was registered last
+|hlr|HLR of the subscriber
+|event|Possible events are explained below in <<sgsn-cdr-event>>
+|===
+
+If the _event_ field describes a pdp context related action (starts with
+_pdp-_), then the following extra CSV fields are appended to the line:
+
+[[sgsn-cdr-pdp]]
+.Description of extra CSV fields for pdp context related events
+[options="header",cols="15%,85%"]
+|===
+|Field Name|Description
+|pdp_duration|duration of the PDP context so far
+|ggsn_addr|GGSN related to the PDP context
+|sgsn_addr|SGSN related to the PDP context
+|apni|APN identifier of the PDP context
+|eua_addr|IP address allocated to the PDP context
+|vol_in|Number of bytes in MO direction
+|vol_out|Number of bytes in MT direction
+|charging_id|Related charging ID
+|===
+
+[[sgsn-cdr-event]]
+.Description of OsmoSGSN CDR Events
+[options="header",cols="15%,85%"]
+|===
+|Event|Description
+|attach|GMM ATTACH COMPLETE about to be sent to MS
+|update|GMM ROUTING AREA UPDATE COMPLETE about to be sent to MS
+|detach|GMM DETACH REQUEST received from MS
+|free|Release of the MM context memory
+|pdp-act|GTP CREATE PDP CONTEXT CONFIRM received from GGSN
+|pdp-deact|GTP DELETE PDP CONTEXT CONFIRM received from GGSN
+|pdp-terminate|Forced PDP context termination during MM context release
+|pdp-free|Release of the PDP context memory
+|pdp-periodic|Triggered by periodic timer, see VTY cmd _cdr interval_
+|===
+
+
+=== User traffic compression
+
+In order to save GPRS bandwith, OsmoSGSN implements header and data
+compression schemes which will reduce the packet length.
+
+==== Header compression
+
+On TCP/IP connections, each packet is prepended with a fairly long TCP/IP
+header. The header contains a lot of static information that never changes
+throughout the connection. (source and destination address, port numbers etc.)
+OsmoSGSN implements a TCP/IP header compression scheme called RFC1144, also
+known as SLHC. This type of header compression removes the TCP/IP header
+entirely and replaces it with a shorter version, that only contains the
+information that is absolutely necessary to identify and check the packet.
+The receiving part then restores the original header and forwards it to higher
+layers.
+
+*compression rfc1144 passive*::
+TCP/IP header compression has to be actively requested by the modem. The
+network will not promote compression by itself. This is the recommended mode
+of operation.
+
+*compression rfc1144 active slots <1-256>*::
+TCP/IP header compression is actively promoted by the network. Modems may still
+actively request different compression parameters or reject the offered
+compression parameters entirely. The number of slots is the maximum number
+of packet headers per subscriber that can be stored in the codebook.
+
+.Example: Accept compression if requested
+----
+sgsn
+ compression rfc1144 passive
+----
+
+.Example: Actively promote compression
+----
+sgsn
+ compression rfc1144 active slots 8
+----
+
+.Example: Turn off compression
+----
+sgsn
+ no compression rfc1144
+----
+
+NOTE: The usage of TCP/IP options may disturb the RFC1144 header compression
+scheme. TCP/IP options may render RFC1144 ineffective if variable data is
+encoded into the option section of the TCP/IP packet. (e.g. TCP option 8,
+Timestamp)
+
+
+==== Data compression
+
+Data compression works on the raw packet data, including the header part of the
+packet. If enabled, header compression is applied first before data compression
+is applied. OsmoSGSN implements the V.42bis data compression scheme.
+
+*compression v42bis passive*::
+V42bis data compression has to be actively requested by the modem. The network
+will not promote compression by itself. This is the recommended mode of
+operation.
+
+*compression v42bis active direction (ms|sgsn|both) codewords <512-65535> strlen <6-250>*::
+V42bis data compression is actively promoted by the network. Modems may still
+actively request different compression parameters or reject the offered
+compression parameters entirely. The direction configures which sides are
+allowed to send compressed packets. For most cases, compressing 'both'
+directions will be the preferred option. The following to parameters configure
+the codebook size by the maxium number ('codewords') and size ('strlen') of
+entries.
+
+.Example: Accept compression if requested
+----
+sgsn
+ compression v42bis passive
+----
+
+.Example: Actively promote compression
+----
+sgsn
+ compression v42bis active direction both codewords 512 strlen 20
+----
+
+.Example: Turn off compression
+----
+sgsn
+ no compression v42bis
+----
+
+=== Encryption
+
+Encryption can be enabled if the auth-policy is set to remote and the
+HLR subscriber entries contain the keys of the SIM card. See
+<<sgsn-ex-gsup>> on how to connect to an external HLR.
+
+.Example: Turn on encryption (GEA3)
+----
+sgsn
+ encryption GEA3
+----
+
+.Example: Turn off encryption (GEA0)
+----
+sgsn
+ encryption GEA0
+----
+
+=== Configure SCCP/M3UA to accept _IuPS_ links
+
+OsmoSGSN acts as client to contact an STP instance and establish an SCCP/M3UA
+link.
+
+An example configuration of OsmoSGSN's SCCP link:
+
+----
+cs7 instance 0
+ point-code 0.23.4
+ asp asp-clnt-OsmoSGSN 2905 0 m3ua
+ remote-ip 127.0.0.1
+ sctp-role client
+ as as-clnt-OsmoSGSN m3ua
+ asp asp-clnt-OsmoSGSN
+ routing-key 0 0.23.4
+----
+
+This configuration is explained in detail in <<cs7_config>>.
diff --git a/doc/manuals/chapters/control.adoc b/doc/manuals/chapters/control.adoc
new file mode 100644
index 000000000..0f2bfae0a
--- /dev/null
+++ b/doc/manuals/chapters/control.adoc
@@ -0,0 +1,23 @@
+[[control]]
+== Control interface
+
+The actual protocol is described in <<common-control-if>>, the variables
+common to all programs using it are described in <<ctrl_common_vars>>. Here we
+describe variables specific to OsmoSGSN.
+
+.Variables available over control interface
+[options="header",width="100%",cols="20%,5%,5%,50%,20%"]
+|===
+|Name|Access|Trap|Value|Comment
+|subscriber-list-active-v1|RO|No|"<imsi>,<addr>"|See <<subs>> for details.
+|===
+
+[[subs]]
+=== subscriber-list-active-v1
+
+Return the list of active subscribers as a concatenated set of pairs "<imsi>",
+"addr" where first element of the pair is subscriber's IMSI and the second
+element (which might be empty) is the subscriber's address. The address value
+might be "none", "invalid" and "PPP" in addition to actual IP address. In case
+of IP address it will be prefixed with "IPv4" or "IPv6" string depending on the
+version of IP protocol.
diff --git a/doc/manuals/chapters/counters.adoc b/doc/manuals/chapters/counters.adoc
new file mode 100644
index 000000000..7fbb10c6f
--- /dev/null
+++ b/doc/manuals/chapters/counters.adoc
@@ -0,0 +1,4 @@
+[[counters]]
+== Counters
+
+include::./counters_generated.adoc[]
diff --git a/doc/manuals/chapters/counters_generated.adoc b/doc/manuals/chapters/counters_generated.adoc
new file mode 100644
index 000000000..dac46aa4f
--- /dev/null
+++ b/doc/manuals/chapters/counters_generated.adoc
@@ -0,0 +1,82 @@
+
+// autogenerated by show asciidoc counters
+These counters and their description based on OsmoSGSN 1.4.0.31-05fe (OsmoSGSN).
+
+=== Rate Counters
+
+// generating tables for rate_ctr_group
+// rate_ctr_group table BSSGP Peer Statistics
+.bssgp:bss_ctx - BSSGP Peer Statistics
+[options="header"]
+|===
+| Name | Reference | Description
+| packets:in | <<bssgp:bss_ctx_packets:in>> | Packets at BSSGP Level ( In)
+| packets:out | <<bssgp:bss_ctx_packets:out>> | Packets at BSSGP Level (Out)
+| bytes:in | <<bssgp:bss_ctx_bytes:in>> | Bytes at BSSGP Level ( In)
+| bytes:out | <<bssgp:bss_ctx_bytes:out>> | Bytes at BSSGP Level (Out)
+| blocked | <<bssgp:bss_ctx_blocked>> | BVC Blocking count
+| discarded | <<bssgp:bss_ctx_discarded>> | BVC LLC Discarded count
+| status | <<bssgp:bss_ctx_status>> | BVC Status count
+|===
+// rate_ctr_group table SGSN Overall Statistics
+.sgsn - SGSN Overall Statistics
+[options="header"]
+|===
+| Name | Reference | Description
+| llc:dl_bytes | <<sgsn_llc:dl_bytes>> | Count sent LLC bytes before giving it to the bssgp layer
+| llc:ul_bytes | <<sgsn_llc:ul_bytes>> | Count successful received LLC bytes (encrypt & fcs correct)
+| llc:dl_packets | <<sgsn_llc:dl_packets>> | Count successful sent LLC packets before giving it to the bssgp layer
+| llc:ul_packets | <<sgsn_llc:ul_packets>> | Count successful received LLC packets (encrypt & fcs correct)
+| gprs:attach_requested | <<sgsn_gprs:attach_requested>> | Received attach requests
+| gprs:attach_accepted | <<sgsn_gprs:attach_accepted>> | Sent attach accepts
+| gprs:attach_rejected | <<sgsn_gprs:attach_rejected>> | Sent attach rejects
+| gprs:detach_requested | <<sgsn_gprs:detach_requested>> | Received detach requests
+| gprs:detach_acked | <<sgsn_gprs:detach_acked>> | Sent detach acks
+| gprs:routing_area_requested | <<sgsn_gprs:routing_area_requested>> | Received routing area requests
+| gprs:routing_area_requested | <<sgsn_gprs:routing_area_requested>> | Sent routing area acks
+| gprs:routing_area_requested | <<sgsn_gprs:routing_area_requested>> | Sent routing area rejects
+| pdp:activate_requested | <<sgsn_pdp:activate_requested>> | Received activate requests
+| pdp:activate_rejected | <<sgsn_pdp:activate_rejected>> | Sent activate rejects
+| pdp:activate_accepted | <<sgsn_pdp:activate_accepted>> | Sent activate accepts
+| pdp:request_activated | <<sgsn_pdp:request_activated>> | unused
+| pdp:request_activate_rejected | <<sgsn_pdp:request_activate_rejected>> | unused
+| pdp:modify_requested | <<sgsn_pdp:modify_requested>> | unused
+| pdp:modify_accepted | <<sgsn_pdp:modify_accepted>> | unused
+| pdp:dl_deactivate_requested | <<sgsn_pdp:dl_deactivate_requested>> | Sent deactivate requests
+| pdp:dl_deactivate_accepted | <<sgsn_pdp:dl_deactivate_accepted>> | Sent deactivate accepted
+| pdp:ul_deactivate_requested | <<sgsn_pdp:ul_deactivate_requested>> | Received deactivate requests
+| pdp:ul_deactivate_accepted | <<sgsn_pdp:ul_deactivate_accepted>> | Received deactivate accepts
+|===
+// rate_ctr_group table NSVC Peer Statistics
+.ns:nsvc - NSVC Peer Statistics
+[options="header"]
+|===
+| Name | Reference | Description
+| packets:in | <<ns:nsvc_packets:in>> | Packets at NS Level ( In)
+| packets:out | <<ns:nsvc_packets:out>> | Packets at NS Level (Out)
+| bytes:in | <<ns:nsvc_bytes:in>> | Bytes at NS Level ( In)
+| bytes:out | <<ns:nsvc_bytes:out>> | Bytes at NS Level (Out)
+| blocked | <<ns:nsvc_blocked>> | NS-VC Block count
+| dead | <<ns:nsvc_dead>> | NS-VC gone dead count
+| replaced | <<ns:nsvc_replaced>> | NS-VC replaced other count
+| nsei-chg | <<ns:nsvc_nsei-chg>> | NS-VC changed NSEI count
+| inv-nsvci | <<ns:nsvc_inv-nsvci>> | NS-VCI was invalid count
+| inv-nsei | <<ns:nsvc_inv-nsei>> | NSEI was invalid count
+| lost:alive | <<ns:nsvc_lost:alive>> | ALIVE ACK missing count
+| lost:reset | <<ns:nsvc_lost:reset>> | RESET ACK missing count
+|===
+== Osmo Stat Items
+
+// generating tables for osmo_stat_items
+NSVC Peer Statistics
+// osmo_stat_item_group table NSVC Peer Statistics
+.ns.nsvc - NSVC Peer Statistics
+[options="header"]
+|===
+| Name | Reference | Description | Unit
+| alive.delay | <<ns.nsvc_alive.delay>> | ALIVE response time | ms
+|===
+== Osmo Counters
+
+// generating tables for osmo_counters
+// there are no ungrouped osmo_counters
diff --git a/doc/manuals/chapters/gbproxy-configuration.adoc b/doc/manuals/chapters/gbproxy-configuration.adoc
new file mode 100644
index 000000000..599b3f7ba
--- /dev/null
+++ b/doc/manuals/chapters/gbproxy-configuration.adoc
@@ -0,0 +1,6 @@
+== Configuring OsmoGbPROXY
+
+TBD. Unfortunately this chapter of the manual still needs to be written.
+Osmocom has very limited funding and support resources; Feel free to help
+us completing this documentation by contributing with code, documentation
+or by supporting the developers financially.
diff --git a/doc/manuals/chapters/gbproxy-control.adoc b/doc/manuals/chapters/gbproxy-control.adoc
new file mode 100644
index 000000000..afe23adfe
--- /dev/null
+++ b/doc/manuals/chapters/gbproxy-control.adoc
@@ -0,0 +1,29 @@
+[[control]]
+== Control interface
+
+The actual protocol is described in <<common-control-if>>, the variables
+common to all programs using it are described in <<ctrl_common_vars>>. Here we
+describe variables specific to OsmoGbPROXY.
+
+.Variables available over control interface
+[options="header",width="100%",cols="20%,5%,5%,50%,20%"]
+|===
+|Name|Access|Trap|Value|Comment
+|nsvc-state|RO|No|"<nsei>,<nsvci>,<local-alive>,<local-blocked>,<remote-role>,<remote-alive>,<remote-blocked>"|See <<nsvc_state>> for details.
+|gbproxy-state|RO|No|"<nsei>,<bvci>,<mcc>,<mnc>,<lac>,<rac>,<blocked>"|See <<gbproxy_state>> for details.
+|number-of-peers|RO|No|"<num-of-bss>"|Count of concurrent BSS(BTS) peers.
+|===
+
+[[nsvc_state]]
+=== nsvc-state
+
+Return the list of active NS-VCs (NS Virtual Circuits), including information
+on the key parameters, such as NSEI, NSVCI and the local + remote ALIVE
+and BLOCKED state.
+
+[[gbproxy_state]]
+=== gbproxy-state
+
+Return the list of active Peers, including information on the key
+parameters, such as NSEI, BVCI, and the MCC-MNC-LAC-RAC of the attached
+BSS, as well as the overall state (BLOCKED or UNBLOCKED).
diff --git a/doc/manuals/chapters/gbproxy-overview.adoc b/doc/manuals/chapters/gbproxy-overview.adoc
new file mode 100644
index 000000000..580afae61
--- /dev/null
+++ b/doc/manuals/chapters/gbproxy-overview.adoc
@@ -0,0 +1,127 @@
+[[chapter_overview]]
+== Overview
+
+=== About OsmoGbPROXY
+
+OsmoGbPROXY is the Osmocom proxy for the 3GPP Gb interface. The Gb
+interface is defined by 3GPP as the protocol between the BSS and the
+SGSN inside the 2G/2.5G/2.75G packet switched network domain.
+
+As Osmocom implements a BTS-colocated PCU, there are potentially many
+Gb interface connections between all those many PCUs in the network
+and the SGSN. This can be cumbersome to configure/maintain at the
+SGSN sine.
+
+OsmoGbPROXY aggregates many PCU-facing Gb connections into one Gb
+connection to the SGSN. This is achieved by
+
+* maintaining sepaate NS-VCs on the PCU side and on the SGSN side
+* more or less transparently routing BSSGP peer-to-peer Virtual Circuits
+ (BVCs) through the proxy
+* having some special handling for the signaling BVC (BVCI=0) which is
+ shared among all the PCUs connected to the proxy
+
+=== Data Model
+
+==== gbproxy_config
+
+This contains the parsed configuration of the OsmoGbPROXY.
+
+==== gproxy_peer
+
+A "peer" is any remote NS-entity that the proxy interacts with. A peer
+includes information about:
+
+* the [unique] NSEI of the peer
+* the [unique] BVCI of the peer
+* the Routeing Area (RA) of the peer
+
+==== gbproxy_tlli_state
+
+One of the (unique) TLLI of any of the subscribers/UEs attached to any of
+the BTSs/PCUs served by the proxy.
+
+==== gbproxy_link_info
+
+One of the [unique] subscribers/connections that are served through this
+proxy. The information includes
+
+* the TLLI on BSS side
+* the TLLI on SGSN side (may be different due to P-TMSI rewriting)
+* the NSEI of the SGSN for this link
+* a timestamp when we last conversed with this subscriber
+* state related to IMSI acquisition
+** a temporary queue of stored messages (until IMSI acquisition succeeds)
+** N(U) rewriting state (inserting IDENTTIY REQ changes LLC sequence numbers)
+
+==== gbproxy_match
+
+A single matching rule against which IMSIs are matched. The matching rule
+is expressed as regular expression. There can be one such matching rule for
+each
+
+* routing between two different SGSNs, see below
+* patching of messages (e.g. APN, PLMN)
+
+
+=== Advanced Features
+
+==== PLMN patching
+
+This feature permits to modify the PLMN inside any BSSGP messages
+containing the Routing Area ID (RAID).
+
+The configured core-mcc and core-mnc will be used towards the SGSN,
+irrespective of which MCC/MNC the PCU is using/reporting on Gb.
+
+==== APN patching
+
+This will transparently re-write the APN name inside SM ACTIVATE PDP
+REQUEST messages on the way from the MS to the SGSN. The patching is
+performed based on matching on the IMSI of the subscriber.
+
+The configured core-apn will be used towards the SGSN, irrespective
+of which APN the MS is requesting in its Layer3 signaling.
+
+APN patching can only be performed if no GPRS encryption is enabled in
+the network!
+
+APN patching is useful in case a valid APN cannot reliably be
+provisioned via other means, such as via the SIM Card, OTA-DM or via
+CAMEL rewriting in the SGSN.
+
+==== P-TMSI patching
+
+This feature transparently rewrite the P-TMSI between MS and SGSN. This
+is required when using the Secondary SGSN support, as both SGSNs could
+allocate overlapping TMSIs and we must make sure they're unique across
+both SGSNs.
+
+P-TMSI patching is required by (and hence automatically enablede if
+secondary SGSN support is enabled.
+
+P-TMSI patching can only be performed if no GPRS encryption is enabled in
+the network!
+
+==== IMSI Acquisition
+
+This is a special feature where the proxy will by itself inject GMM IDENTITY
+REQUEST messages for the IMSI into the downlink BSSGP traffic in order
+to establish the IMSI of subscribers for which it is not otherwise known
+
+IMSI acquisition is automatically enabled if secondary SGSN support is
+enabled.
+
+==== Secondary SGSN Support
+
+This allows the proxy to connect not only to one SGSN, but to two
+different SGSNs. IMSI matching rules are applied to determine which of
+the SGSNs is to be used for traffic of this subscriber.
+
+One possible use case of this feature is to have a "local break-out" for
+subscribers who are native to this network (and hence save
+latencies/overhead of back-hauling all related traffic via the
+SGSN+GGSN) while at the same time maintaining the classic behavior for
+inbound roaming subscribers, where the roaming agreements mandate that
+data traffic is brought back to the GGSN in the HPLMN via the SGSN of
+the VPLMN.
diff --git a/doc/manuals/chapters/gbproxy-running.adoc b/doc/manuals/chapters/gbproxy-running.adoc
new file mode 100644
index 000000000..9182b4867
--- /dev/null
+++ b/doc/manuals/chapters/gbproxy-running.adoc
@@ -0,0 +1,39 @@
+== Running OsmoGbPROXY
+
+The OsmoGbPROXY executable (`osmo-gbproxy`) offers the following command-line
+options:
+
+
+=== SYNOPSIS
+
+*osmo-gbproxy* [-h|-V] [-d 'DBGMASK'] [-D] [-c 'CONFIGFILE'] [-s] [-e 'LOGLEVEL'] [-T]
+
+
+=== OPTIONS
+
+*-h, --help*::
+ Print a short help message about the supported options
+*-V, --version*::
+ Print the compile-time version number of the program
+*-d, --debug 'DBGMASK','DBGLEVELS'*::
+ Set the log subsystems and levels for logging to stderr. This
+ has mostly been superseded by VTY-based logging configuration,
+ see <<logging>> for further information.
+*-D, --daemonize*::
+ Fork the process as a daemon into background.
+*-c, --config-file 'CONFIGFILE'*::
+ Specify the file and path name of the configuration file to be
+ used. If none is specified, use `osmo_sgsn.cfg` in the current
+ working directory.
+*-s, --disable-color*::
+ Disable colors for logging to stderr. This has mostly been
+ deprecated by VTY based logging configuration, see <<logging>>
+ for more information.
+*-e, --log-level 'LOGLEVEL'*::
+ Set the global log level for logging to stderr. This has mostly
+ been deprecated by VTY based logging configuration, see
+ <<logging>> for more information.
+*-T, --timestamp*::
+ Enable prefixing each log line on stderr with a timestamp. This
+ has mostly been deprecated by VTY based logging configuration, see
+ <<logging>> for more information.
diff --git a/doc/manuals/chapters/overview.adoc b/doc/manuals/chapters/overview.adoc
new file mode 100644
index 000000000..e2c010712
--- /dev/null
+++ b/doc/manuals/chapters/overview.adoc
@@ -0,0 +1,109 @@
+[[chapter_introduction]]
+== Overview
+
+[[intro_overview]]
+=== About OsmoSGSN
+
+OsmoSGSN is the Osmocom implementation of the GPRS SGSN (Serving Gprs
+Support Node) element inside the GPRS network. The SGSN plays a similar
+central function to the GPRS network as the MSC plays in the GSM
+network.
+
+The SGSN is connected on the downlink side to Gb interfaces of the BSS,
+specifically the PCU inside the BSS. The SGSN is further connected by
+the GTP protocol to the GGSN which terminates the tunnels towards the
+external packet data network (e.g. IPv4).
+
+OsmoSGSN supports both a PCU that is co-located with(in) the BTS, as
+well as a PCU that is co-located with(in) the BSC. In combination with
+OsmoNITB/OsmoBSC/OsmoBTS, the PCU is co-located within the BTS.
+
+[[fig-gprs-pcubts]]
+.GPRS network architecture with PCU in BTS
+[graphviz]
+----
+digraph G {
+ rankdir=LR;
+ MS0 [label="MS"];
+ MS1 [label="MS"];
+ MS0->BTS [label="Um"];
+ MS1->BTS [label="Um"];
+ BTS->BSC [label="Abis"];
+ BSC->MSC [label="A"];
+ BTS->PCU [label="pcu_sock"];
+ PCU->SGSN [label="Gb"];
+ SGSN->GGSN [label="GTP"];
+}
+----
+
+=== Software Components
+
+OsmoSGSN contains a variety of different software components, which
+we'll quickly describe in this section.
+
+==== Gb Implementation
+
+OsmoSGSN implements the ETSI/3GPP specified Gb interface, including TS
+08.16 (NS), TS 08.18 (BSSGP) and TS 08.64 (LLC) protocols. As transport
+layers for NS, it supports NS/IP (NS encapsulated in UDP/IP), as well as
+NS/FR/GRE/IP. The latter is provided in order to use a Router with
+Ethernet and Frame Relay interface to convert to actual physical Frame
+Relay medium, which is not directly supported by OsmoSGSN.
+
+The actual Gb Implementation is part of the libosmogb library, which is
+in turn part of the libosmocore software package. This allows the same
+Gb implementation to be used from osmo-pcu, osmo-gbproxy as well as
+OsmoSGSN.
+
+
+==== GTP Implementation
+
+OsmoSGSN uses the libgtp implementation originating from OsmoGGSN. It
+supports both GTPv0 and GTPv1.
+
+
+==== GMM Implementation
+
+The GPRS Mobility Management implementation is quite simplistic at this
+point. It supports the GPRS ATTACH and GPRS ROUTING AREA UPDATE
+procedures, as well as GPRS ATTACH and GPRS DETACH.
+
+==== LLC Implementation
+
+The LLC (Logical Link Control) implementation of OsmoSGSN only supports
+non-acknowledged mode, as this is the most common use case in real-world
+GPRS networks.
+
+It does support both TCP/IP header compression according to RFC1144 and
+payload compression according to V.42bis
+
+The LLC implementation does support LLC encryption with ciphers GEA3 and GEA4.
+For encryption to work the auth policy needs to be set to remote and the SGSN
+connected to an HLR containing the subscriber data including key material.
+Other auth policys will not work with encryption.
+
+==== Session Management Implementation
+
+The session management procedures ACTIVATE PDP CONTEXT and DEACTIVATE
+PDP CONTEXT are supported. However, no MODIFY PDP CONTEXT and no
+Network-initiated PDP context activation is possible. This is again
+covering the predominant use cases and configurations in GPRS real-world
+networks while skipping the more esoteric features.
+
+Multiple PDP contexts can be attached by a single MS.
+
+Multiple GGSNs can be configured and routing to a GGSN can be configured based
+on APN. Dynamic lookup of GGSNs though DNS-based APN resolving is also possible.
+
+=== Limitations
+
+At the time of writing, OsmoSGSN still has a number of limitations,
+which are a result of the demand-driven Open Source development model.
+If you require any of those features, please consider implementing and
+contributing them, or contracting the existing OsmoSGSN developers for
+performing that work.
+
+Known Limitations include:
+
+* No paging coordination between SGSN and MSC
+* No SMS over Ps support
diff --git a/doc/manuals/chapters/running.adoc b/doc/manuals/chapters/running.adoc
new file mode 100644
index 000000000..63c2b2781
--- /dev/null
+++ b/doc/manuals/chapters/running.adoc
@@ -0,0 +1,35 @@
+== Running OsmoSGSN
+
+The OsmoSGSN executable (`osmo-sgsn`) offers the following command-line
+options:
+
+
+=== SYNOPSIS
+
+*osmo-sgsn* [-h|-V] [-d 'DBGMASK'] [-D] [-c 'CONFIGFILE'] [-s] [-e 'LOGLEVEL']
+
+
+=== OPTIONS
+
+*-h, --help*::
+ Print a short help message about the supported options
+*-V, --version*::
+ Print the compile-time version number of the OsmoSGSN program
+*-d, --debug 'DBGMASK','DBGLEVELS'*::
+ Set the log subsystems and levels for logging to stderr. This
+ has mostly been superseded by VTY-based logging configuration,
+ see <<logging>> for further information.
+*-D, --daemonize*::
+ Fork the process as a daemon into background.
+*-c, --config-file 'CONFIGFILE'*::
+ Specify the file and path name of the configuration file to be
+ used. If none is specified, use `osmo_sgsn.cfg` in the current
+ working directory.
+*-s, --disable-color*::
+ Disable colors for logging to stderr. This has mostly been
+ deprecated by VTY based logging configuration, see <<logging>>
+ for more information.
+*-e, --log-level 'LOGLEVEL'*::
+ Set the global log level for logging to stderr. This has mostly
+ been deprecated by VTY based logging configuration, see
+ <<logging>> for more information.
diff --git a/doc/manuals/osmogbproxy-usermanual-docinfo.xml b/doc/manuals/osmogbproxy-usermanual-docinfo.xml
new file mode 100644
index 000000000..29bb2aa74
--- /dev/null
+++ b/doc/manuals/osmogbproxy-usermanual-docinfo.xml
@@ -0,0 +1,46 @@
+<revhistory>
+ <revision>
+ <revnumber>1</revnumber>
+ <date>March 21, 2019</date>
+ <authorinitials>HW</authorinitials>
+ <revremark>
+ Initial version.
+ </revremark>
+ </revision>
+</revhistory>
+
+<authorgroup>
+ <author>
+ <firstname>Harald</firstname>
+ <surname>Welte</surname>
+ <email>hwelte@sysmocom.de</email>
+ <authorinitials>HW</authorinitials>
+ <affiliation>
+ <shortaffil>sysmocom</shortaffil>
+ <orgname>sysmocom - s.f.m.c. GmbH</orgname>
+ <jobtitle>Managing Director</jobtitle>
+ </affiliation>
+ </author>
+</authorgroup>
+
+<copyright>
+ <year>2013-2019</year>
+ <holder>sysmocom - s.f.m.c. GmbH</holder>
+</copyright>
+
+<legalnotice>
+ <para>
+ Permission is granted to copy, distribute and/or modify this
+ document under the terms of the GNU Free Documentation License,
+ Version 1.3 or any later version published by the Free Software
+ Foundation; with no Invariant Sections, no Front-Cover Texts,
+ and no Back-Cover Texts. A copy of the license is included in
+ the section entitled "GNU Free Documentation License".
+ </para>
+ <para>
+ The Asciidoc source code of this manual can be found at
+ <ulink url="https://git.osmocom.org/osmo-sgsn/doc/">
+ https://git.osmocom.org/osmo-sgsn/doc/
+ </ulink>
+ </para>
+</legalnotice>
diff --git a/doc/manuals/osmogbproxy-usermanual.adoc b/doc/manuals/osmogbproxy-usermanual.adoc
new file mode 100644
index 000000000..c4e0b9d0b
--- /dev/null
+++ b/doc/manuals/osmogbproxy-usermanual.adoc
@@ -0,0 +1,34 @@
+:gfdl-enabled:
+
+OsmoGbPROXY User Manual
+=======================
+Harald Welte <hwelte@sysmocom.de>
+
+
+include::./common/chapters/preface.adoc[]
+
+include::{srcdir}/chapters/gbproxy-overview.adoc[]
+
+include::{srcdir}/chapters/gbproxy-running.adoc[]
+
+include::{srcdir}/chapters/gbproxy-control.adoc[]
+
+include::./common/chapters/vty.adoc[]
+
+include::./common/chapters/logging.adoc[]
+
+include::{srcdir}/chapters/gbproxy-configuration.adoc[]
+
+include::./common/chapters/gb.adoc[]
+
+include::./common/chapters/control_if.adoc[]
+
+//include::{srcdir}/chapters/counters.adoc[]
+
+include::./common/chapters/port_numbers.adoc[]
+
+include::./common/chapters/bibliography.adoc[]
+
+include::./common/chapters/glossary.adoc[]
+
+include::./common/chapters/gfdl.adoc[]
diff --git a/doc/manuals/osmogbproxy-vty-reference.xml b/doc/manuals/osmogbproxy-vty-reference.xml
new file mode 100644
index 000000000..ecf226808
--- /dev/null
+++ b/doc/manuals/osmogbproxy-vty-reference.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ex:ts=2:sw=42sts=2:et
+ -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
+-->
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML 5.0//EN"
+"http://docbook.org/xml/5.0/dtd/docbook.dtd" [
+<!ENTITY chapter-vty SYSTEM "./common/chapters/vty.xml" >
+<!ENTITY sections-vty SYSTEM "generated/docbook_osmogbproxy-vty-reference.xml" >
+]>
+
+<book>
+ <info>
+ <revhistory>
+ <revision>
+ <revnumber>v1</revnumber>
+ <date>2nd December 2019</date>
+ <authorinitials>hw</authorinitials>
+ <revremark>Initial</revremark>
+ </revision>
+ </revhistory>
+
+ <title>OsmoGbProxy VTY Reference</title>
+
+ <copyright>
+ <year>2019</year>
+ </copyright>
+
+ <legalnotice>
+ <para>This work is copyright by <orgname>sysmocom - s.f.m.c. GmbH</orgname>. All rights reserved.
+ </para>
+ </legalnotice>
+ </info>
+
+ <!-- Main chapters-->
+ &chapter-vty;
+</book>
+
diff --git a/doc/manuals/osmosgsn-usermanual-docinfo.xml b/doc/manuals/osmosgsn-usermanual-docinfo.xml
new file mode 100644
index 000000000..afbf1094e
--- /dev/null
+++ b/doc/manuals/osmosgsn-usermanual-docinfo.xml
@@ -0,0 +1,54 @@
+<revhistory>
+ <revision>
+ <revnumber>1</revnumber>
+ <date>January 13, 2013</date>
+ <authorinitials>HW</authorinitials>
+ <revremark>
+ Initial version.
+ </revremark>
+ </revision>
+ <revision>
+ <revnumber>2</revnumber>
+ <date>February 2016</date>
+ <authorinitials>HW</authorinitials>
+ <revremark>
+ Conversion to asciidoc, removal of sysmoBTS specific parts.
+ </revremark>
+ </revision>
+</revhistory>
+
+<authorgroup>
+ <author>
+ <firstname>Harald</firstname>
+ <surname>Welte</surname>
+ <email>hwelte@sysmocom.de</email>
+ <authorinitials>HW</authorinitials>
+ <affiliation>
+ <shortaffil>sysmocom</shortaffil>
+ <orgname>sysmocom - s.f.m.c. GmbH</orgname>
+ <jobtitle>Managing Director</jobtitle>
+ </affiliation>
+ </author>
+</authorgroup>
+
+<copyright>
+ <year>2013-2016</year>
+ <holder>sysmocom - s.f.m.c. GmbH</holder>
+</copyright>
+
+<legalnotice>
+ <para>
+ Permission is granted to copy, distribute and/or modify this
+ document under the terms of the GNU Free Documentation License,
+ Version 1.3 or any later version published by the Free Software
+ Foundation; with no Invariant Sections, no Front-Cover Texts,
+ and no Back-Cover Texts. A copy of the license is included in
+ the section entitled "GNU Free Documentation License".
+ </para>
+ <para>
+ The Asciidoc source code of this manual can be found at
+ <ulink url="http://git.osmocom.org/osmo-gsm-manuals/">
+ http://git.osmocom.org/osmo-gsm-manuals/
+ </ulink>
+ </para>
+</legalnotice>
diff --git a/doc/manuals/osmosgsn-usermanual.adoc b/doc/manuals/osmosgsn-usermanual.adoc
new file mode 100644
index 000000000..610704aeb
--- /dev/null
+++ b/doc/manuals/osmosgsn-usermanual.adoc
@@ -0,0 +1,40 @@
+:gfdl-enabled:
+
+OsmoSGSN User Manual
+====================
+Harald Welte <hwelte@sysmocom.de>
+
+
+include::./common/chapters/preface.adoc[]
+
+include::{srcdir}/chapters/overview.adoc[]
+
+include::{srcdir}/chapters/running.adoc[]
+
+include::{srcdir}/chapters/control.adoc[]
+
+include::./common/chapters/vty.adoc[]
+
+include::./common/chapters/logging.adoc[]
+
+include::{srcdir}/chapters/configuration.adoc[]
+
+include::./common/chapters/cs7-config.adoc[]
+
+include::./common/chapters/gb.adoc[]
+
+include::./common/chapters/control_if.adoc[]
+
+include::./common/chapters/oap.adoc[]
+
+include::./common/chapters/gsup.adoc[]
+
+include::{srcdir}/chapters/counters.adoc[]
+
+include::./common/chapters/port_numbers.adoc[]
+
+include::./common/chapters/bibliography.adoc[]
+
+include::./common/chapters/glossary.adoc[]
+
+include::./common/chapters/gfdl.adoc[]
diff --git a/doc/manuals/osmosgsn-vty-reference.xml b/doc/manuals/osmosgsn-vty-reference.xml
new file mode 100644
index 000000000..82b666a0c
--- /dev/null
+++ b/doc/manuals/osmosgsn-vty-reference.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ex:ts=2:sw=42sts=2:et
+ -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
+-->
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML 5.0//EN"
+"http://docbook.org/xml/5.0/dtd/docbook.dtd" [
+<!ENTITY chapter-vty SYSTEM "./common/chapters/vty.xml" >
+<!ENTITY sections-vty SYSTEM "generated/docbook_vty.xml" >
+]>
+
+<book>
+ <info>
+ <revhistory>
+ <revision>
+ <revnumber>v1</revnumber>
+ <date>13th January 2013</date>
+ <authorinitials>hw</authorinitials>
+ <revremark>Initial</revremark>
+ </revision>
+ <revision>
+ <revnumber>v2</revnumber>
+ <date>5th March 2014</date>
+ <authorinitials>hf</authorinitials>
+ <revremark>Update to match osmo-bsc version 0.13.0-305</revremark>
+ </revision>
+ </revhistory>
+
+ <title>OsmoSGSN VTY Reference</title>
+
+ <copyright>
+ <year>2013-2014</year>
+ </copyright>
+
+ <legalnotice>
+ <para>This work is copyright by <orgname>sysmocom - s.f.m.c. GmbH</orgname>. All rights reserved.
+ </para>
+ </legalnotice>
+ </info>
+
+ <!-- Main chapters-->
+ &chapter-vty;
+</book>
+
diff --git a/doc/manuals/regen_doc.sh b/doc/manuals/regen_doc.sh
new file mode 100755
index 000000000..847b764aa
--- /dev/null
+++ b/doc/manuals/regen_doc.sh
@@ -0,0 +1,77 @@
+#!/bin/sh -e
+
+require_osmo_interact_vty() {
+ if command -v osmo_interact_vty.py >/dev/null 2>&1; then
+ return
+ fi
+ echo "ERROR: osmo_interact_vty.py not found. Are osmo-python-tests in PATH?"
+ exit 1
+}
+
+# $1: "update_vty_reference" or "update_counters"
+# $2: output file
+# $3: port
+# $4-$n: command
+interact_vty() {
+ action="$1"
+ output="$2"
+ port="$3"
+ log="/tmp/$4.log"
+ shift 3
+
+ echo "Starting in background: $@"
+ "$@" > "$log" 2>&1 &
+ pid="$!"
+
+ sleep 0.5
+ if ! kill -0 "$pid" 2>/dev/null; then
+ echo "ERROR: start failed!"
+ cat "$log"
+ exit 1
+ fi
+
+ case "$action" in
+ "update_vty_reference")
+ echo "Updating VTY reference: $output"
+ osmo_interact_vty.py -X -p "$port" -H 127.0.0.1 -O "$output"
+ ;;
+ "update_counters")
+ echo "Updating asciidoc counters: $output"
+ osmo_interact_vty.py -c "enable;show asciidoc counters" -p "$port" -H 127.0.0.1 -O "$output"
+ ;;
+ *)
+ echo "ERROR: invalid argument: $action"
+ exit 1
+ ;;
+ esac
+
+ kill "$pid"
+ echo "Done (killed $1)"
+ echo
+}
+
+DIR="$(cd "$(dirname "$0")"; pwd)"
+cd "$DIR"
+
+require_osmo_interact_vty
+
+interact_vty \
+ "update_vty_reference" \
+ "vty/sgsn_vty_reference.xml" \
+ 4245 \
+ osmo-sgsn -c "../examples/osmo-sgsn/osmo-sgsn.cfg"
+
+interact_vty \
+ "update_vty_reference" \
+ "vty-osmogbproxy/gbproxy_vty_reference.xml" \
+ 4246 \
+ osmo-gbproxy -c "../examples/osmo-gbproxy/osmo-gbproxy.cfg"
+
+interact_vty \
+ "update_counters" \
+ "chapters/counters_generated.adoc" \
+ 4245 \
+ osmo-sgsn -c "../examples/osmo-sgsn/osmo-sgsn.cfg"
+
+
+echo "Done with all"
diff --git a/doc/manuals/vty-osmogbproxy/gbproxy_vty_additions.xml b/doc/manuals/vty-osmogbproxy/gbproxy_vty_additions.xml
new file mode 100644
index 000000000..6da2d2f2f
--- /dev/null
+++ b/doc/manuals/vty-osmogbproxy/gbproxy_vty_additions.xml
@@ -0,0 +1,5 @@
+<vtydoc xmlns='urn:osmocom:xml:libosmocore:vty:doc:1.0'>
+ <node id='config-gbproxy'>
+ <description>Configure the Gb proxy</description>
+ </node>
+</vtydoc>
diff --git a/doc/manuals/vty-osmogbproxy/gbproxy_vty_reference.xml b/doc/manuals/vty-osmogbproxy/gbproxy_vty_reference.xml
new file mode 100644
index 000000000..1db3c0d2f
--- /dev/null
+++ b/doc/manuals/vty-osmogbproxy/gbproxy_vty_reference.xml
@@ -0,0 +1,1627 @@
+<vtydoc xmlns='urn:osmocom:xml:libosmocore:vty:doc:1.0'>
+ <node id='_common_cmds_'>
+ <name>Common Commands</name>
+ <description>These commands are available on all VTY nodes. They are listed here only once, to unclutter the VTY reference.</description>
+ <command id='help'>
+ <params>
+ <param name='help' doc='Description of the interactive help system' />
+ </params>
+ </command>
+ <command id='list'>
+ <params>
+ <param name='list' doc='Print command list' />
+ </params>
+ </command>
+ <command id='write terminal'>
+ <params>
+ <param name='write' doc='Write running configuration to memory, network, or terminal' />
+ <param name='terminal' doc='Write to terminal' />
+ </params>
+ </command>
+ <command id='write file [PATH]'>
+ <params>
+ <param name='write' doc='Write running configuration to memory, network, or terminal' />
+ <param name='file' doc='Write to configuration file' />
+ <param name='[PATH]' doc='Set file path to store the config, or replace if already exists' />
+ </params>
+ </command>
+ <command id='write memory'>
+ <params>
+ <param name='write' doc='Write running configuration to memory, network, or terminal' />
+ <param name='memory' doc='Write configuration to the file (same as write file)' />
+ </params>
+ </command>
+ <command id='write'>
+ <params>
+ <param name='write' doc='Write running configuration to memory, network, or terminal' />
+ </params>
+ </command>
+ <command id='show running-config'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='running-config' doc='running configuration' />
+ </params>
+ </command>
+ <command id='exit'>
+ <params>
+ <param name='exit' doc='Exit current mode and down to previous mode' />
+ </params>
+ </command>
+ <command id='end'>
+ <params>
+ <param name='end' doc='End current mode and change to enable mode.' />
+ </params>
+ </command>
+ </node>
+ <node id='view'>
+ <name>view</name>
+ <command id='show version'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='version' doc='Displays program version' />
+ </params>
+ </command>
+ <command id='show online-help'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='online-help' doc='Online help' />
+ </params>
+ </command>
+ <command id='enable'>
+ <params>
+ <param name='enable' doc='Turn on privileged mode command' />
+ </params>
+ </command>
+ <command id='terminal length &lt;0-512&gt;'>
+ <params>
+ <param name='terminal' doc='Set terminal line parameters' />
+ <param name='length' doc='Set number of lines on a screen' />
+ <param name='&lt;0-512&gt;' doc='Number of lines on screen (0 for no pausing)' />
+ </params>
+ </command>
+ <command id='terminal no length'>
+ <params>
+ <param name='terminal' doc='Set terminal line parameters' />
+ <param name='no' doc='Negate a command or set its defaults' />
+ <param name='length' doc='Set number of lines on a screen' />
+ </params>
+ </command>
+ <command id='who'>
+ <params>
+ <param name='who' doc='Display who is on vty' />
+ </params>
+ </command>
+ <command id='show history'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='history' doc='Display the session command history' />
+ </params>
+ </command>
+ <command id='logging enable'>
+ <params>
+ <param name='logging' doc='Configure logging' />
+ <param name='enable' doc='Enables logging to this vty' />
+ </params>
+ </command>
+ <command id='logging disable'>
+ <params>
+ <param name='logging' doc='Configure logging' />
+ <param name='disable' doc='Disables logging to this vty' />
+ </params>
+ </command>
+ <command id='logging filter all (0|1)'>
+ <params>
+ <param name='logging' doc='Configure logging' />
+ <param name='filter' doc='Filter log messages' />
+ <param name='all' doc='Do you want to log all messages?' />
+ <param name='0' doc='Only print messages matched by other filters' />
+ <param name='1' doc='Bypass filter and print all messages' />
+ </params>
+ </command>
+ <command id='logging color (0|1)'>
+ <params>
+ <param name='logging' doc='Configure logging' />
+ <param name='color' doc='Configure color-printing for log messages' />
+ <param name='0' doc='Don&apos;t use color for printing messages' />
+ <param name='1' doc='Use color for printing messages' />
+ </params>
+ </command>
+ <command id='logging timestamp (0|1)'>
+ <params>
+ <param name='logging' doc='Configure logging' />
+ <param name='timestamp' doc='Configure log message timestamping' />
+ <param name='0' doc='Don&apos;t prefix each log message' />
+ <param name='1' doc='Prefix each log message with current timestamp' />
+ </params>
+ </command>
+ <command id='logging print extended-timestamp (0|1)'>
+ <params>
+ <param name='logging' doc='Configure logging' />
+ <param name='print' doc='Log output settings' />
+ <param name='extended-timestamp' doc='Configure log message timestamping' />
+ <param name='0' doc='Don&apos;t prefix each log message' />
+ <param name='1' doc='Prefix each log message with current timestamp with YYYYMMDDhhmmssnnn' />
+ </params>
+ </command>
+ <command id='logging print category (0|1)'>
+ <params>
+ <param name='logging' doc='Configure logging' />
+ <param name='print' doc='Log output settings' />
+ <param name='category' doc='Configure log message' />
+ <param name='0' doc='Don&apos;t prefix each log message' />
+ <param name='1' doc='Prefix each log message with category/subsystem name' />
+ </params>
+ </command>
+ <command id='logging print category-hex (0|1)'>
+ <params>
+ <param name='logging' doc='Configure logging' />
+ <param name='print' doc='Log output settings' />
+ <param name='category-hex' doc='Configure log message' />
+ <param name='0' doc='Don&apos;t prefix each log message' />
+ <param name='1' doc='Prefix each log message with category/subsystem nr in hex (&apos;&lt;000b&gt;&apos;)' />
+ </params>
+ </command>
+ <command id='logging print level (0|1)'>
+ <params>
+ <param name='logging' doc='Configure logging' />
+ <param name='print' doc='Log output settings' />
+ <param name='level' doc='Configure log message' />
+ <param name='0' doc='Don&apos;t prefix each log message' />
+ <param name='1' doc='Prefix each log message with the log level name' />
+ </params>
+ </command>
+ <command id='logging print file (0|1|basename) [last]'>
+ <params>
+ <param name='logging' doc='Configure logging' />
+ <param name='print' doc='Log output settings' />
+ <param name='file' doc='Configure log message' />
+ <param name='0' doc='Don&apos;t prefix each log message' />
+ <param name='1' doc='Prefix each log message with the source file and line' />
+ <param name='basename' doc='Prefix each log message with the source file&apos;s basename (strip leading paths) and line' />
+ <param name='[last]' doc='Log source file info at the end of a log line. If omitted, log source file info just before the log text.' />
+ </params>
+ </command>
+ <command id='logging set-log-mask MASK'>
+ <params>
+ <param name='logging' doc='Configure logging' />
+ <param name='set-log-mask' doc='Set the logmask of this logging target' />
+ <param name='MASK' doc='List of logging categories to log, e.g. &apos;abc:mno:xyz&apos;. Available log categories depend on the specific application, refer to the &apos;logging level&apos; command. Optionally add individual log levels like &apos;abc,1:mno,3:xyz,5&apos;, where the level numbers are LOGL_DEBUG=1 LOGL_INFO=3 LOGL_NOTICE=5 LOGL_ERROR=7 LOGL_FATAL=8' />
+ </params>
+ </command>
+ <command id='logging level (|gprs|ns|bssgp|lglobal|llapd|linp|lmux|lmi|lmib|lsms|lctrl|lgtp|lstats|lgsup|loap|lss7|lsccp|lsua|lm3ua|lmgcp|ljibuf|lrspro) (debug|info|notice|error|fatal)'>
+ <params>
+ <param name='logging' doc='Configure logging' />
+ <param name='level' doc='Set the log level for a specified category' />
+ <param name='gprs' doc='GPRS Packet Service' />
+ <param name='ns' doc='GPRS Network Service (NS)' />
+ <param name='bssgp' doc='GPRS BSS Gateway Protocol (BSSGP)' />
+ <param name='lglobal' doc='Library-internal global log family' />
+ <param name='llapd' doc='LAPD in libosmogsm' />
+ <param name='linp' doc='A-bis Intput Subsystem' />
+ <param name='lmux' doc='A-bis B-Subchannel TRAU Frame Multiplex' />
+ <param name='lmi' doc='A-bis Input Driver for Signalling' />
+ <param name='lmib' doc='A-bis Input Driver for B-Channels (voice)' />
+ <param name='lsms' doc='Layer3 Short Message Service (SMS)' />
+ <param name='lctrl' doc='Control Interface' />
+ <param name='lgtp' doc='GPRS GTP library' />
+ <param name='lstats' doc='Statistics messages and logging' />
+ <param name='lgsup' doc='Generic Subscriber Update Protocol' />
+ <param name='loap' doc='Osmocom Authentication Protocol' />
+ <param name='lss7' doc='libosmo-sigtran Signalling System 7' />
+ <param name='lsccp' doc='libosmo-sigtran SCCP Implementation' />
+ <param name='lsua' doc='libosmo-sigtran SCCP User Adaptation' />
+ <param name='lm3ua' doc='libosmo-sigtran MTP3 User Adaptation' />
+ <param name='lmgcp' doc='libosmo-mgcp Media Gateway Control Protocol' />
+ <param name='ljibuf' doc='libosmo-netif Jitter Buffer' />
+ <param name='lrspro' doc='Remote SIM protocol' />
+ <param name='debug' doc='Log debug messages and higher levels' />
+ <param name='info' doc='Log informational messages and higher levels' />
+ <param name='notice' doc='Log noticeable messages and higher levels' />
+ <param name='error' doc='Log error messages and higher levels' />
+ <param name='fatal' doc='Log only fatal messages' />
+ </params>
+ </command>
+ <command id='logging level set-all (debug|info|notice|error|fatal)'>
+ <params>
+ <param name='logging' doc='Configure logging' />
+ <param name='level' doc='Set the log level for a specified category' />
+ <param name='set-all' doc='Once-off set all categories to the given log level. There is no single command to take back these changes -- each category is set to the given level, period.' />
+ <param name='debug' doc='Log debug messages and higher levels' />
+ <param name='info' doc='Log informational messages and higher levels' />
+ <param name='notice' doc='Log noticeable messages and higher levels' />
+ <param name='error' doc='Log error messages and higher levels' />
+ <param name='fatal' doc='Log only fatal messages' />
+ </params>
+ </command>
+ <command id='logging level force-all (debug|info|notice|error|fatal)'>
+ <params>
+ <param name='logging' doc='Configure logging' />
+ <param name='level' doc='Set the log level for a specified category' />
+ <param name='force-all' doc='Globally force all logging categories to a specific level. This is released by the &apos;no logging level force-all&apos; command. Note: any &apos;logging level &lt;category&gt; &lt;level&gt;&apos; commands will have no visible effect after this, until the forced level is released.' />
+ <param name='debug' doc='Log debug messages and higher levels' />
+ <param name='info' doc='Log informational messages and higher levels' />
+ <param name='notice' doc='Log noticeable messages and higher levels' />
+ <param name='error' doc='Log error messages and higher levels' />
+ <param name='fatal' doc='Log only fatal messages' />
+ </params>
+ </command>
+ <command id='no logging level force-all'>
+ <params>
+ <param name='no' doc='Negate a command or set its defaults' />
+ <param name='logging' doc='Configure logging' />
+ <param name='level' doc='Set the log level for a specified category' />
+ <param name='force-all' doc='Release any globally forced log level set with &apos;logging level force-all &lt;level&gt;&apos;' />
+ </params>
+ </command>
+ <command id='logp (|gprs|ns|bssgp|lglobal|llapd|linp|lmux|lmi|lmib|lsms|lctrl|lgtp|lstats|lgsup|loap|lss7|lsccp|lsua|lm3ua|lmgcp|ljibuf|lrspro) (debug|info|notice|error|fatal) .LOGMESSAGE'>
+ <params>
+ <param name='logp' doc='Print a message on all log outputs; useful for placing markers in test logs' />
+ <param name='gprs' doc='GPRS Packet Service' />
+ <param name='ns' doc='GPRS Network Service (NS)' />
+ <param name='bssgp' doc='GPRS BSS Gateway Protocol (BSSGP)' />
+ <param name='lglobal' doc='Library-internal global log family' />
+ <param name='llapd' doc='LAPD in libosmogsm' />
+ <param name='linp' doc='A-bis Intput Subsystem' />
+ <param name='lmux' doc='A-bis B-Subchannel TRAU Frame Multiplex' />
+ <param name='lmi' doc='A-bis Input Driver for Signalling' />
+ <param name='lmib' doc='A-bis Input Driver for B-Channels (voice)' />
+ <param name='lsms' doc='Layer3 Short Message Service (SMS)' />
+ <param name='lctrl' doc='Control Interface' />
+ <param name='lgtp' doc='GPRS GTP library' />
+ <param name='lstats' doc='Statistics messages and logging' />
+ <param name='lgsup' doc='Generic Subscriber Update Protocol' />
+ <param name='loap' doc='Osmocom Authentication Protocol' />
+ <param name='lss7' doc='libosmo-sigtran Signalling System 7' />
+ <param name='lsccp' doc='libosmo-sigtran SCCP Implementation' />
+ <param name='lsua' doc='libosmo-sigtran SCCP User Adaptation' />
+ <param name='lm3ua' doc='libosmo-sigtran MTP3 User Adaptation' />
+ <param name='lmgcp' doc='libosmo-mgcp Media Gateway Control Protocol' />
+ <param name='ljibuf' doc='libosmo-netif Jitter Buffer' />
+ <param name='lrspro' doc='Remote SIM protocol' />
+ <param name='debug' doc='Log debug messages and higher levels' />
+ <param name='info' doc='Log informational messages and higher levels' />
+ <param name='notice' doc='Log noticeable messages and higher levels' />
+ <param name='error' doc='Log error messages and higher levels' />
+ <param name='fatal' doc='Log only fatal messages' />
+ <param name='.LOGMESSAGE' doc='Arbitrary message to log on given category and log level' />
+ </params>
+ </command>
+ <command id='show logging vty'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='logging' doc='Show current logging configuration' />
+ <param name='vty' doc='Show current logging configuration for this vty' />
+ </params>
+ </command>
+ <command id='show alarms'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='alarms' doc='Show current logging configuration' />
+ </params>
+ </command>
+ <command id='show talloc-context (application|all) (full|brief|DEPTH)'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='talloc-context' doc='Show talloc memory hierarchy' />
+ <param name='application' doc='Application&apos;s context' />
+ <param name='all' doc='All contexts, if NULL-context tracking is enabled' />
+ <param name='full' doc='Display a full talloc memory hierarchy' />
+ <param name='brief' doc='Display a brief talloc memory hierarchy' />
+ <param name='DEPTH' doc='Specify required maximal depth value' />
+ </params>
+ </command>
+ <command id='show talloc-context (application|all) (full|brief|DEPTH) tree ADDRESS'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='talloc-context' doc='Show talloc memory hierarchy' />
+ <param name='application' doc='Application&apos;s context' />
+ <param name='all' doc='All contexts, if NULL-context tracking is enabled' />
+ <param name='full' doc='Display a full talloc memory hierarchy' />
+ <param name='brief' doc='Display a brief talloc memory hierarchy' />
+ <param name='DEPTH' doc='Specify required maximal depth value' />
+ <param name='tree' doc='Display only a specific memory chunk' />
+ <param name='ADDRESS' doc='Chunk address (e.g. 0xdeadbeef)' />
+ </params>
+ </command>
+ <command id='show talloc-context (application|all) (full|brief|DEPTH) filter REGEXP'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='talloc-context' doc='Show talloc memory hierarchy' />
+ <param name='application' doc='Application&apos;s context' />
+ <param name='all' doc='All contexts, if NULL-context tracking is enabled' />
+ <param name='full' doc='Display a full talloc memory hierarchy' />
+ <param name='brief' doc='Display a brief talloc memory hierarchy' />
+ <param name='DEPTH' doc='Specify required maximal depth value' />
+ <param name='filter' doc='Filter chunks using regular expression' />
+ <param name='REGEXP' doc='Regular expression' />
+ </params>
+ </command>
+ <command id='show stats'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='stats' doc='Show statistical values' />
+ </params>
+ </command>
+ <command id='show stats level (global|peer|subscriber)'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='stats' doc='Show statistical values' />
+ <param name='level' doc='Set the maximum group level' />
+ <param name='global' doc='Show global groups only' />
+ <param name='peer' doc='Show global and network peer related groups' />
+ <param name='subscriber' doc='Show global, peer, and subscriber groups' />
+ </params>
+ </command>
+ <command id='show asciidoc counters'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='asciidoc' doc='Asciidoc generation' />
+ <param name='counters' doc='Generate table of all registered counters' />
+ </params>
+ </command>
+ <command id='show rate-counters'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='rate-counters' doc='Show all rate counters' />
+ </params>
+ </command>
+ <command id='show gbproxy [stats]'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='gbproxy' doc='Display information about the Gb proxy' />
+ <param name='[stats]' doc='Show statistics' />
+ </params>
+ </command>
+ <command id='show gbproxy links'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='gbproxy' doc='Display information about the Gb proxy' />
+ <param name='links' doc='Show logical links' />
+ </params>
+ </command>
+ <command id='show ns'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='ns' doc='Display information about the NS protocol' />
+ </params>
+ </command>
+ <command id='show ns stats'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='ns' doc='Display information about the NS protocol' />
+ <param name='stats' doc='Include statistics' />
+ </params>
+ </command>
+ <command id='show ns persistent'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='ns' doc='Display information about the NS protocol' />
+ <param name='persistent' doc='Show only persistent NS' />
+ </params>
+ </command>
+ <command id='show ns (nsei|nsvc) &lt;0-65535&gt; [stats]'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='ns' doc='Display information about the NS protocol' />
+ <param name='nsei' doc='Select one NSE by its NSE Identifier' />
+ <param name='nsvc' doc='Select one NSE by its NS-VC Identifier' />
+ <param name='&lt;0-65535&gt;' doc='The Identifier of selected type' />
+ <param name='[stats]' doc='Include Statistics' />
+ </params>
+ </command>
+ <command id='logging filter nsvc (nsei|nsvci) &lt;0-65535&gt;'>
+ <params>
+ <param name='logging' doc='Configure logging' />
+ <param name='filter' doc='Filter log messages' />
+ <param name='nsvc' doc='Filter based on NS Virtual Connection' />
+ <param name='nsei' doc='Identify NS-VC by NSEI' />
+ <param name='nsvci' doc='Identify NS-VC by NSVCI' />
+ <param name='&lt;0-65535&gt;' doc='Numeric identifier' />
+ </params>
+ </command>
+ </node>
+ <node id='enable'>
+ <name>enable</name>
+ <command id='disable'>
+ <params>
+ <param name='disable' doc='Turn off privileged mode command' />
+ </params>
+ </command>
+ <command id='configure terminal'>
+ <params>
+ <param name='configure' doc='Configuration from vty interface' />
+ <param name='terminal' doc='Configuration terminal' />
+ </params>
+ </command>
+ <command id='copy running-config startup-config'>
+ <params>
+ <param name='copy' doc='Copy configuration' />
+ <param name='running-config' doc='Copy running config to... ' />
+ <param name='startup-config' doc='Copy running config to startup config (same as write file)' />
+ </params>
+ </command>
+ <command id='show startup-config'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='startup-config' doc='Contentes of startup configuration' />
+ </params>
+ </command>
+ <command id='show version'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='version' doc='Displays program version' />
+ </params>
+ </command>
+ <command id='show online-help'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='online-help' doc='Online help' />
+ </params>
+ </command>
+ <command id='terminal length &lt;0-512&gt;'>
+ <params>
+ <param name='terminal' doc='Set terminal line parameters' />
+ <param name='length' doc='Set number of lines on a screen' />
+ <param name='&lt;0-512&gt;' doc='Number of lines on screen (0 for no pausing)' />
+ </params>
+ </command>
+ <command id='terminal no length'>
+ <params>
+ <param name='terminal' doc='Set terminal line parameters' />
+ <param name='no' doc='Negate a command or set its defaults' />
+ <param name='length' doc='Set number of lines on a screen' />
+ </params>
+ </command>
+ <command id='who'>
+ <params>
+ <param name='who' doc='Display who is on vty' />
+ </params>
+ </command>
+ <command id='show history'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='history' doc='Display the session command history' />
+ </params>
+ </command>
+ <command id='terminal monitor'>
+ <params>
+ <param name='terminal' doc='Set terminal line parameters' />
+ <param name='monitor' doc='Copy debug output to the current terminal line' />
+ </params>
+ </command>
+ <command id='terminal no monitor'>
+ <params>
+ <param name='terminal' doc='Set terminal line parameters' />
+ <param name='no' doc='Negate a command or set its defaults' />
+ <param name='monitor' doc='Copy debug output to the current terminal line' />
+ </params>
+ </command>
+ <command id='logging enable'>
+ <params>
+ <param name='logging' doc='Configure logging' />
+ <param name='enable' doc='Enables logging to this vty' />
+ </params>
+ </command>
+ <command id='logging disable'>
+ <params>
+ <param name='logging' doc='Configure logging' />
+ <param name='disable' doc='Disables logging to this vty' />
+ </params>
+ </command>
+ <command id='logging filter all (0|1)'>
+ <params>
+ <param name='logging' doc='Configure logging' />
+ <param name='filter' doc='Filter log messages' />
+ <param name='all' doc='Do you want to log all messages?' />
+ <param name='0' doc='Only print messages matched by other filters' />
+ <param name='1' doc='Bypass filter and print all messages' />
+ </params>
+ </command>
+ <command id='logging color (0|1)'>
+ <params>
+ <param name='logging' doc='Configure logging' />
+ <param name='color' doc='Configure color-printing for log messages' />
+ <param name='0' doc='Don&apos;t use color for printing messages' />
+ <param name='1' doc='Use color for printing messages' />
+ </params>
+ </command>
+ <command id='logging timestamp (0|1)'>
+ <params>
+ <param name='logging' doc='Configure logging' />
+ <param name='timestamp' doc='Configure log message timestamping' />
+ <param name='0' doc='Don&apos;t prefix each log message' />
+ <param name='1' doc='Prefix each log message with current timestamp' />
+ </params>
+ </command>
+ <command id='logging print extended-timestamp (0|1)'>
+ <params>
+ <param name='logging' doc='Configure logging' />
+ <param name='print' doc='Log output settings' />
+ <param name='extended-timestamp' doc='Configure log message timestamping' />
+ <param name='0' doc='Don&apos;t prefix each log message' />
+ <param name='1' doc='Prefix each log message with current timestamp with YYYYMMDDhhmmssnnn' />
+ </params>
+ </command>
+ <command id='logging print category (0|1)'>
+ <params>
+ <param name='logging' doc='Configure logging' />
+ <param name='print' doc='Log output settings' />
+ <param name='category' doc='Configure log message' />
+ <param name='0' doc='Don&apos;t prefix each log message' />
+ <param name='1' doc='Prefix each log message with category/subsystem name' />
+ </params>
+ </command>
+ <command id='logging print category-hex (0|1)'>
+ <params>
+ <param name='logging' doc='Configure logging' />
+ <param name='print' doc='Log output settings' />
+ <param name='category-hex' doc='Configure log message' />
+ <param name='0' doc='Don&apos;t prefix each log message' />
+ <param name='1' doc='Prefix each log message with category/subsystem nr in hex (&apos;&lt;000b&gt;&apos;)' />
+ </params>
+ </command>
+ <command id='logging print level (0|1)'>
+ <params>
+ <param name='logging' doc='Configure logging' />
+ <param name='print' doc='Log output settings' />
+ <param name='level' doc='Configure log message' />
+ <param name='0' doc='Don&apos;t prefix each log message' />
+ <param name='1' doc='Prefix each log message with the log level name' />
+ </params>
+ </command>
+ <command id='logging print file (0|1|basename) [last]'>
+ <params>
+ <param name='logging' doc='Configure logging' />
+ <param name='print' doc='Log output settings' />
+ <param name='file' doc='Configure log message' />
+ <param name='0' doc='Don&apos;t prefix each log message' />
+ <param name='1' doc='Prefix each log message with the source file and line' />
+ <param name='basename' doc='Prefix each log message with the source file&apos;s basename (strip leading paths) and line' />
+ <param name='[last]' doc='Log source file info at the end of a log line. If omitted, log source file info just before the log text.' />
+ </params>
+ </command>
+ <command id='logging set-log-mask MASK'>
+ <params>
+ <param name='logging' doc='Configure logging' />
+ <param name='set-log-mask' doc='Set the logmask of this logging target' />
+ <param name='MASK' doc='List of logging categories to log, e.g. &apos;abc:mno:xyz&apos;. Available log categories depend on the specific application, refer to the &apos;logging level&apos; command. Optionally add individual log levels like &apos;abc,1:mno,3:xyz,5&apos;, where the level numbers are LOGL_DEBUG=1 LOGL_INFO=3 LOGL_NOTICE=5 LOGL_ERROR=7 LOGL_FATAL=8' />
+ </params>
+ </command>
+ <command id='logging level (|gprs|ns|bssgp|lglobal|llapd|linp|lmux|lmi|lmib|lsms|lctrl|lgtp|lstats|lgsup|loap|lss7|lsccp|lsua|lm3ua|lmgcp|ljibuf|lrspro) (debug|info|notice|error|fatal)'>
+ <params>
+ <param name='logging' doc='Configure logging' />
+ <param name='level' doc='Set the log level for a specified category' />
+ <param name='gprs' doc='GPRS Packet Service' />
+ <param name='ns' doc='GPRS Network Service (NS)' />
+ <param name='bssgp' doc='GPRS BSS Gateway Protocol (BSSGP)' />
+ <param name='lglobal' doc='Library-internal global log family' />
+ <param name='llapd' doc='LAPD in libosmogsm' />
+ <param name='linp' doc='A-bis Intput Subsystem' />
+ <param name='lmux' doc='A-bis B-Subchannel TRAU Frame Multiplex' />
+ <param name='lmi' doc='A-bis Input Driver for Signalling' />
+ <param name='lmib' doc='A-bis Input Driver for B-Channels (voice)' />
+ <param name='lsms' doc='Layer3 Short Message Service (SMS)' />
+ <param name='lctrl' doc='Control Interface' />
+ <param name='lgtp' doc='GPRS GTP library' />
+ <param name='lstats' doc='Statistics messages and logging' />
+ <param name='lgsup' doc='Generic Subscriber Update Protocol' />
+ <param name='loap' doc='Osmocom Authentication Protocol' />
+ <param name='lss7' doc='libosmo-sigtran Signalling System 7' />
+ <param name='lsccp' doc='libosmo-sigtran SCCP Implementation' />
+ <param name='lsua' doc='libosmo-sigtran SCCP User Adaptation' />
+ <param name='lm3ua' doc='libosmo-sigtran MTP3 User Adaptation' />
+ <param name='lmgcp' doc='libosmo-mgcp Media Gateway Control Protocol' />
+ <param name='ljibuf' doc='libosmo-netif Jitter Buffer' />
+ <param name='lrspro' doc='Remote SIM protocol' />
+ <param name='debug' doc='Log debug messages and higher levels' />
+ <param name='info' doc='Log informational messages and higher levels' />
+ <param name='notice' doc='Log noticeable messages and higher levels' />
+ <param name='error' doc='Log error messages and higher levels' />
+ <param name='fatal' doc='Log only fatal messages' />
+ </params>
+ </command>
+ <command id='logging level set-all (debug|info|notice|error|fatal)'>
+ <params>
+ <param name='logging' doc='Configure logging' />
+ <param name='level' doc='Set the log level for a specified category' />
+ <param name='set-all' doc='Once-off set all categories to the given log level. There is no single command to take back these changes -- each category is set to the given level, period.' />
+ <param name='debug' doc='Log debug messages and higher levels' />
+ <param name='info' doc='Log informational messages and higher levels' />
+ <param name='notice' doc='Log noticeable messages and higher levels' />
+ <param name='error' doc='Log error messages and higher levels' />
+ <param name='fatal' doc='Log only fatal messages' />
+ </params>
+ </command>
+ <command id='logging level force-all (debug|info|notice|error|fatal)'>
+ <params>
+ <param name='logging' doc='Configure logging' />
+ <param name='level' doc='Set the log level for a specified category' />
+ <param name='force-all' doc='Globally force all logging categories to a specific level. This is released by the &apos;no logging level force-all&apos; command. Note: any &apos;logging level &lt;category&gt; &lt;level&gt;&apos; commands will have no visible effect after this, until the forced level is released.' />
+ <param name='debug' doc='Log debug messages and higher levels' />
+ <param name='info' doc='Log informational messages and higher levels' />
+ <param name='notice' doc='Log noticeable messages and higher levels' />
+ <param name='error' doc='Log error messages and higher levels' />
+ <param name='fatal' doc='Log only fatal messages' />
+ </params>
+ </command>
+ <command id='no logging level force-all'>
+ <params>
+ <param name='no' doc='Negate a command or set its defaults' />
+ <param name='logging' doc='Configure logging' />
+ <param name='level' doc='Set the log level for a specified category' />
+ <param name='force-all' doc='Release any globally forced log level set with &apos;logging level force-all &lt;level&gt;&apos;' />
+ </params>
+ </command>
+ <command id='logp (|gprs|ns|bssgp|lglobal|llapd|linp|lmux|lmi|lmib|lsms|lctrl|lgtp|lstats|lgsup|loap|lss7|lsccp|lsua|lm3ua|lmgcp|ljibuf|lrspro) (debug|info|notice|error|fatal) .LOGMESSAGE'>
+ <params>
+ <param name='logp' doc='Print a message on all log outputs; useful for placing markers in test logs' />
+ <param name='gprs' doc='GPRS Packet Service' />
+ <param name='ns' doc='GPRS Network Service (NS)' />
+ <param name='bssgp' doc='GPRS BSS Gateway Protocol (BSSGP)' />
+ <param name='lglobal' doc='Library-internal global log family' />
+ <param name='llapd' doc='LAPD in libosmogsm' />
+ <param name='linp' doc='A-bis Intput Subsystem' />
+ <param name='lmux' doc='A-bis B-Subchannel TRAU Frame Multiplex' />
+ <param name='lmi' doc='A-bis Input Driver for Signalling' />
+ <param name='lmib' doc='A-bis Input Driver for B-Channels (voice)' />
+ <param name='lsms' doc='Layer3 Short Message Service (SMS)' />
+ <param name='lctrl' doc='Control Interface' />
+ <param name='lgtp' doc='GPRS GTP library' />
+ <param name='lstats' doc='Statistics messages and logging' />
+ <param name='lgsup' doc='Generic Subscriber Update Protocol' />
+ <param name='loap' doc='Osmocom Authentication Protocol' />
+ <param name='lss7' doc='libosmo-sigtran Signalling System 7' />
+ <param name='lsccp' doc='libosmo-sigtran SCCP Implementation' />
+ <param name='lsua' doc='libosmo-sigtran SCCP User Adaptation' />
+ <param name='lm3ua' doc='libosmo-sigtran MTP3 User Adaptation' />
+ <param name='lmgcp' doc='libosmo-mgcp Media Gateway Control Protocol' />
+ <param name='ljibuf' doc='libosmo-netif Jitter Buffer' />
+ <param name='lrspro' doc='Remote SIM protocol' />
+ <param name='debug' doc='Log debug messages and higher levels' />
+ <param name='info' doc='Log informational messages and higher levels' />
+ <param name='notice' doc='Log noticeable messages and higher levels' />
+ <param name='error' doc='Log error messages and higher levels' />
+ <param name='fatal' doc='Log only fatal messages' />
+ <param name='.LOGMESSAGE' doc='Arbitrary message to log on given category and log level' />
+ </params>
+ </command>
+ <command id='show logging vty'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='logging' doc='Show current logging configuration' />
+ <param name='vty' doc='Show current logging configuration for this vty' />
+ </params>
+ </command>
+ <command id='show alarms'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='alarms' doc='Show current logging configuration' />
+ </params>
+ </command>
+ <command id='show talloc-context (application|all) (full|brief|DEPTH)'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='talloc-context' doc='Show talloc memory hierarchy' />
+ <param name='application' doc='Application&apos;s context' />
+ <param name='all' doc='All contexts, if NULL-context tracking is enabled' />
+ <param name='full' doc='Display a full talloc memory hierarchy' />
+ <param name='brief' doc='Display a brief talloc memory hierarchy' />
+ <param name='DEPTH' doc='Specify required maximal depth value' />
+ </params>
+ </command>
+ <command id='show talloc-context (application|all) (full|brief|DEPTH) tree ADDRESS'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='talloc-context' doc='Show talloc memory hierarchy' />
+ <param name='application' doc='Application&apos;s context' />
+ <param name='all' doc='All contexts, if NULL-context tracking is enabled' />
+ <param name='full' doc='Display a full talloc memory hierarchy' />
+ <param name='brief' doc='Display a brief talloc memory hierarchy' />
+ <param name='DEPTH' doc='Specify required maximal depth value' />
+ <param name='tree' doc='Display only a specific memory chunk' />
+ <param name='ADDRESS' doc='Chunk address (e.g. 0xdeadbeef)' />
+ </params>
+ </command>
+ <command id='show talloc-context (application|all) (full|brief|DEPTH) filter REGEXP'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='talloc-context' doc='Show talloc memory hierarchy' />
+ <param name='application' doc='Application&apos;s context' />
+ <param name='all' doc='All contexts, if NULL-context tracking is enabled' />
+ <param name='full' doc='Display a full talloc memory hierarchy' />
+ <param name='brief' doc='Display a brief talloc memory hierarchy' />
+ <param name='DEPTH' doc='Specify required maximal depth value' />
+ <param name='filter' doc='Filter chunks using regular expression' />
+ <param name='REGEXP' doc='Regular expression' />
+ </params>
+ </command>
+ <command id='show stats'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='stats' doc='Show statistical values' />
+ </params>
+ </command>
+ <command id='show stats level (global|peer|subscriber)'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='stats' doc='Show statistical values' />
+ <param name='level' doc='Set the maximum group level' />
+ <param name='global' doc='Show global groups only' />
+ <param name='peer' doc='Show global and network peer related groups' />
+ <param name='subscriber' doc='Show global, peer, and subscriber groups' />
+ </params>
+ </command>
+ <command id='show asciidoc counters'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='asciidoc' doc='Asciidoc generation' />
+ <param name='counters' doc='Generate table of all registered counters' />
+ </params>
+ </command>
+ <command id='show rate-counters'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='rate-counters' doc='Show all rate counters' />
+ </params>
+ </command>
+ <command id='show gbproxy [stats]'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='gbproxy' doc='Display information about the Gb proxy' />
+ <param name='[stats]' doc='Show statistics' />
+ </params>
+ </command>
+ <command id='show gbproxy links'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='gbproxy' doc='Display information about the Gb proxy' />
+ <param name='links' doc='Show logical links' />
+ </params>
+ </command>
+ <command id='delete-gbproxy-peer &lt;0-65534&gt; bvci &lt;2-65534&gt;'>
+ <params>
+ <param name='delete-gbproxy-peer' doc='Delete a GBProxy peer by NSEI and optionally BVCI' />
+ <param name='&lt;0-65534&gt;' doc='NSEI number' />
+ <param name='bvci' doc='Only delete peer with a matching BVCI' />
+ <param name='&lt;2-65534&gt;' doc='BVCI number' />
+ </params>
+ </command>
+ <command id='delete-gbproxy-peer &lt;0-65534&gt; (only-bvc|only-nsvc|all) [dry-run]'>
+ <params>
+ <param name='delete-gbproxy-peer' doc='Delete a GBProxy peer by NSEI and optionally BVCI' />
+ <param name='&lt;0-65534&gt;' doc='NSEI number' />
+ <param name='only-bvc' doc='Only delete BSSGP connections (BVC)' />
+ <param name='only-nsvc' doc='Only delete dynamic NS connections (NS-VC)' />
+ <param name='all' doc='Delete BVC and dynamic NS connections' />
+ <param name='[dry-run]' doc='Show what would be deleted instead of actually deleting' />
+ </params>
+ </command>
+ <command id='delete-gbproxy-link &lt;0-65534&gt; (tlli|imsi|sgsn-nsei) IDENT'>
+ <params>
+ <param name='delete-gbproxy-link' doc='Delete a GBProxy logical link entry by NSEI and identification' />
+ <param name='&lt;0-65534&gt;' doc='NSEI number' />
+ <param name='tlli' doc='Delete entries with a matching TLLI (hex)' />
+ <param name='imsi' doc='Delete entries with a matching IMSI' />
+ <param name='sgsn-nsei' doc='Delete entries with a matching SGSN NSEI' />
+ <param name='IDENT' doc='Identification to match' />
+ </params>
+ </command>
+ <command id='delete-gbproxy-link &lt;0-65534&gt; (stale|de-registered)'>
+ <params>
+ <param name='delete-gbproxy-link' doc='Delete a GBProxy logical link entry by NSEI and identification' />
+ <param name='&lt;0-65534&gt;' doc='NSEI number' />
+ <param name='stale' doc='Delete stale entries' />
+ <param name='de-registered' doc='Delete de-registered entries' />
+ </params>
+ </command>
+ <command id='show ns'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='ns' doc='Display information about the NS protocol' />
+ </params>
+ </command>
+ <command id='show ns stats'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='ns' doc='Display information about the NS protocol' />
+ <param name='stats' doc='Include statistics' />
+ </params>
+ </command>
+ <command id='show ns persistent'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='ns' doc='Display information about the NS protocol' />
+ <param name='persistent' doc='Show only persistent NS' />
+ </params>
+ </command>
+ <command id='show ns (nsei|nsvc) &lt;0-65535&gt; [stats]'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='ns' doc='Display information about the NS protocol' />
+ <param name='nsei' doc='Select one NSE by its NSE Identifier' />
+ <param name='nsvc' doc='Select one NSE by its NS-VC Identifier' />
+ <param name='&lt;0-65535&gt;' doc='The Identifier of selected type' />
+ <param name='[stats]' doc='Include Statistics' />
+ </params>
+ </command>
+ <command id='logging filter nsvc (nsei|nsvci) &lt;0-65535&gt;'>
+ <params>
+ <param name='logging' doc='Configure logging' />
+ <param name='filter' doc='Filter log messages' />
+ <param name='nsvc' doc='Filter based on NS Virtual Connection' />
+ <param name='nsei' doc='Identify NS-VC by NSEI' />
+ <param name='nsvci' doc='Identify NS-VC by NSVCI' />
+ <param name='&lt;0-65535&gt;' doc='Numeric identifier' />
+ </params>
+ </command>
+ <command id='nsvc (nsei|nsvci) &lt;0-65535&gt; (block|unblock|reset)'>
+ <params>
+ <param name='nsvc' doc='Perform an operation on a NSVC' />
+ <param name='nsei' doc='NSEI to identify NS-VC Identifier (NS-VCI)' />
+ <param name='nsvci' doc='NS-VC Identifier (NS-VCI)' />
+ <param name='&lt;0-65535&gt;' doc='The NSEI' />
+ <param name='block' doc='Initiate BLOCK procedure' />
+ <param name='unblock' doc='Initiate UNBLOCK procedure' />
+ <param name='reset' doc='Initiate RESET procedure' />
+ </params>
+ </command>
+ </node>
+ <node id='config'>
+ <name>config</name>
+ <command id='hostname WORD'>
+ <params>
+ <param name='hostname' doc='Set system&apos;s network name' />
+ <param name='WORD' doc='This system&apos;s network name' />
+ </params>
+ </command>
+ <command id='no hostname [HOSTNAME]'>
+ <params>
+ <param name='no' doc='Negate a command or set its defaults' />
+ <param name='hostname' doc='Reset system&apos;s network name' />
+ <param name='[HOSTNAME]' doc='Host name of this router' />
+ </params>
+ </command>
+ <command id='password (8|) WORD'>
+ <params>
+ <param name='password' doc='Assign the terminal connection password' />
+ <param name='8' doc='Specifies a HIDDEN password will follow' />
+ <param name='' doc='dummy string ' />
+ <param name='WORD' doc='The HIDDEN line password string' />
+ </params>
+ </command>
+ <command id='password LINE'>
+ <params>
+ <param name='password' doc='Assign the terminal connection password' />
+ <param name='LINE' doc='The UNENCRYPTED (cleartext) line password' />
+ </params>
+ </command>
+ <command id='enable password (8|) WORD'>
+ <params>
+ <param name='enable' doc='Modify enable password parameters' />
+ <param name='password' doc='Assign the privileged level password' />
+ <param name='8' doc='Specifies a HIDDEN password will follow' />
+ <param name='' doc='dummy string ' />
+ <param name='WORD' doc='The HIDDEN &apos;enable&apos; password string' />
+ </params>
+ </command>
+ <command id='enable password LINE'>
+ <params>
+ <param name='enable' doc='Modify enable password parameters' />
+ <param name='password' doc='Assign the privileged level password' />
+ <param name='LINE' doc='The UNENCRYPTED (cleartext) &apos;enable&apos; password' />
+ </params>
+ </command>
+ <command id='no enable password'>
+ <params>
+ <param name='no' doc='Negate a command or set its defaults' />
+ <param name='enable' doc='Modify enable password parameters' />
+ <param name='password' doc='Assign the privileged level password' />
+ </params>
+ </command>
+ <command id='banner motd default'>
+ <params>
+ <param name='banner' doc='Set banner string' />
+ <param name='motd' doc='Strings for motd' />
+ <param name='default' doc='Default string' />
+ </params>
+ </command>
+ <command id='banner motd file [FILE]'>
+ <params>
+ <param name='banner' doc='Set banner' />
+ <param name='motd' doc='Banner for motd' />
+ <param name='file' doc='Banner from a file' />
+ <param name='[FILE]' doc='Filename' />
+ </params>
+ </command>
+ <command id='no banner motd'>
+ <params>
+ <param name='no' doc='Negate a command or set its defaults' />
+ <param name='banner' doc='Set banner string' />
+ <param name='motd' doc='Strings for motd' />
+ </params>
+ </command>
+ <command id='service terminal-length &lt;0-512&gt;'>
+ <params>
+ <param name='service' doc='Set up miscellaneous service' />
+ <param name='terminal-length' doc='System wide terminal length configuration' />
+ <param name='&lt;0-512&gt;' doc='Number of lines of VTY (0 means no line control)' />
+ </params>
+ </command>
+ <command id='no service terminal-length [&lt;0-512&gt;]'>
+ <params>
+ <param name='no' doc='Negate a command or set its defaults' />
+ <param name='service' doc='Set up miscellaneous service' />
+ <param name='terminal-length' doc='System wide terminal length configuration' />
+ <param name='[&lt;0-512&gt;]' doc='Number of lines of VTY (0 means no line control)' />
+ </params>
+ </command>
+ <command id='line vty'>
+ <params>
+ <param name='line' doc='Configure a terminal line' />
+ <param name='vty' doc='Virtual terminal' />
+ </params>
+ </command>
+ <command id='service advanced-vty'>
+ <params>
+ <param name='service' doc='Set up miscellaneous service' />
+ <param name='advanced-vty' doc='Enable advanced mode vty interface' />
+ </params>
+ </command>
+ <command id='no service advanced-vty'>
+ <params>
+ <param name='no' doc='Negate a command or set its defaults' />
+ <param name='service' doc='Set up miscellaneous service' />
+ <param name='advanced-vty' doc='Enable advanced mode vty interface' />
+ </params>
+ </command>
+ <command id='show history'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='history' doc='Display the session command history' />
+ </params>
+ </command>
+ <command id='log stderr'>
+ <params>
+ <param name='log' doc='Configure logging sub-system' />
+ <param name='stderr' doc='Logging via STDERR of the process' />
+ </params>
+ </command>
+ <command id='no log stderr'>
+ <params>
+ <param name='no' doc='Negate a command or set its defaults' />
+ <param name='log' doc='Configure logging sub-system' />
+ <param name='stderr' doc='Logging via STDERR of the process' />
+ </params>
+ </command>
+ <command id='log file .FILENAME'>
+ <params>
+ <param name='log' doc='Configure logging sub-system' />
+ <param name='file' doc='Logging to text file' />
+ <param name='.FILENAME' doc='Filename' />
+ </params>
+ </command>
+ <command id='no log file .FILENAME'>
+ <params>
+ <param name='no' doc='Negate a command or set its defaults' />
+ <param name='log' doc='Configure logging sub-system' />
+ <param name='file' doc='Logging to text file' />
+ <param name='.FILENAME' doc='Filename' />
+ </params>
+ </command>
+ <command id='log alarms &lt;2-32700&gt;'>
+ <params>
+ <param name='log' doc='Configure logging sub-system' />
+ <param name='alarms' doc='Logging alarms to osmo_strrb' />
+ <param name='&lt;2-32700&gt;' doc='Maximum number of messages to log' />
+ </params>
+ </command>
+ <command id='no log alarms'>
+ <params>
+ <param name='no' doc='Negate a command or set its defaults' />
+ <param name='log' doc='Configure logging sub-system' />
+ <param name='alarms' doc='Logging alarms to osmo_strrb' />
+ </params>
+ </command>
+ <command id='log syslog (authpriv|cron|daemon|ftp|lpr|mail|news|user|uucp)'>
+ <params>
+ <param name='log' doc='Configure logging sub-system' />
+ <param name='syslog' doc='Logging via syslog' />
+ <param name='authpriv' doc='Security/authorization messages facility' />
+ <param name='cron' doc='Clock daemon (cron/at) facility' />
+ <param name='daemon' doc='General system daemon facility' />
+ <param name='ftp' doc='Ftp daemon facility' />
+ <param name='lpr' doc='Line printer facility' />
+ <param name='mail' doc='Mail facility' />
+ <param name='news' doc='News facility' />
+ <param name='user' doc='Generic facility' />
+ <param name='uucp' doc='UUCP facility' />
+ </params>
+ </command>
+ <command id='log syslog local &lt;0-7&gt;'>
+ <params>
+ <param name='log' doc='Configure logging sub-system' />
+ <param name='syslog' doc='Logging via syslog' />
+ <param name='local' doc='Syslog LOCAL facility' />
+ <param name='&lt;0-7&gt;' doc='Local facility number' />
+ </params>
+ </command>
+ <command id='no log syslog'>
+ <params>
+ <param name='no' doc='Negate a command or set its defaults' />
+ <param name='log' doc='Configure logging sub-system' />
+ <param name='syslog' doc='Logging via syslog' />
+ </params>
+ </command>
+ <command id='log gsmtap [HOSTNAME]'>
+ <params>
+ <param name='log' doc='Configure logging sub-system' />
+ <param name='gsmtap' doc='Logging via GSMTAP' />
+ <param name='[HOSTNAME]' doc='Host name to send the GSMTAP logging to (UDP port 4729)' />
+ </params>
+ </command>
+ <command id='stats reporter statsd'>
+ <params>
+ <param name='stats' doc='Configure stats sub-system' />
+ <param name='reporter' doc='Configure a stats reporter' />
+ <param name='statsd' doc='Report to a STATSD server' />
+ </params>
+ </command>
+ <command id='no stats reporter statsd'>
+ <params>
+ <param name='no' doc='Negate a command or set its defaults' />
+ <param name='stats' doc='Configure stats sub-system' />
+ <param name='reporter' doc='Configure a stats reporter' />
+ <param name='statsd' doc='Report to a STATSD server' />
+ </params>
+ </command>
+ <command id='stats reporter log'>
+ <params>
+ <param name='stats' doc='Configure stats sub-system' />
+ <param name='reporter' doc='Configure a stats reporter' />
+ <param name='log' doc='Report to the logger' />
+ </params>
+ </command>
+ <command id='no stats reporter log'>
+ <params>
+ <param name='no' doc='Negate a command or set its defaults' />
+ <param name='stats' doc='Configure stats sub-system' />
+ <param name='reporter' doc='Configure a stats reporter' />
+ <param name='log' doc='Report to the logger' />
+ </params>
+ </command>
+ <command id='stats interval &lt;1-65535&gt;'>
+ <params>
+ <param name='stats' doc='Configure stats sub-system' />
+ <param name='interval' doc='Set the reporting interval' />
+ <param name='&lt;1-65535&gt;' doc='Interval in seconds' />
+ </params>
+ </command>
+ <command id='gbproxy'>
+ <params>
+ <param name='gbproxy' doc='Configure the Gb proxy' />
+ </params>
+ </command>
+ <command id='ns'>
+ <params>
+ <param name='ns' doc='Configure the GPRS Network Service' />
+ </params>
+ </command>
+ </node>
+ <node id='config-log'>
+ <name>config-log</name>
+ <command id='logging filter all (0|1)'>
+ <params>
+ <param name='logging' doc='Configure logging' />
+ <param name='filter' doc='Filter log messages' />
+ <param name='all' doc='Do you want to log all messages?' />
+ <param name='0' doc='Only print messages matched by other filters' />
+ <param name='1' doc='Bypass filter and print all messages' />
+ </params>
+ </command>
+ <command id='logging color (0|1)'>
+ <params>
+ <param name='logging' doc='Configure logging' />
+ <param name='color' doc='Configure color-printing for log messages' />
+ <param name='0' doc='Don&apos;t use color for printing messages' />
+ <param name='1' doc='Use color for printing messages' />
+ </params>
+ </command>
+ <command id='logging timestamp (0|1)'>
+ <params>
+ <param name='logging' doc='Configure logging' />
+ <param name='timestamp' doc='Configure log message timestamping' />
+ <param name='0' doc='Don&apos;t prefix each log message' />
+ <param name='1' doc='Prefix each log message with current timestamp' />
+ </params>
+ </command>
+ <command id='logging print extended-timestamp (0|1)'>
+ <params>
+ <param name='logging' doc='Configure logging' />
+ <param name='print' doc='Log output settings' />
+ <param name='extended-timestamp' doc='Configure log message timestamping' />
+ <param name='0' doc='Don&apos;t prefix each log message' />
+ <param name='1' doc='Prefix each log message with current timestamp with YYYYMMDDhhmmssnnn' />
+ </params>
+ </command>
+ <command id='logging print category (0|1)'>
+ <params>
+ <param name='logging' doc='Configure logging' />
+ <param name='print' doc='Log output settings' />
+ <param name='category' doc='Configure log message' />
+ <param name='0' doc='Don&apos;t prefix each log message' />
+ <param name='1' doc='Prefix each log message with category/subsystem name' />
+ </params>
+ </command>
+ <command id='logging print category-hex (0|1)'>
+ <params>
+ <param name='logging' doc='Configure logging' />
+ <param name='print' doc='Log output settings' />
+ <param name='category-hex' doc='Configure log message' />
+ <param name='0' doc='Don&apos;t prefix each log message' />
+ <param name='1' doc='Prefix each log message with category/subsystem nr in hex (&apos;&lt;000b&gt;&apos;)' />
+ </params>
+ </command>
+ <command id='logging print level (0|1)'>
+ <params>
+ <param name='logging' doc='Configure logging' />
+ <param name='print' doc='Log output settings' />
+ <param name='level' doc='Configure log message' />
+ <param name='0' doc='Don&apos;t prefix each log message' />
+ <param name='1' doc='Prefix each log message with the log level name' />
+ </params>
+ </command>
+ <command id='logging print file (0|1|basename) [last]'>
+ <params>
+ <param name='logging' doc='Configure logging' />
+ <param name='print' doc='Log output settings' />
+ <param name='file' doc='Configure log message' />
+ <param name='0' doc='Don&apos;t prefix each log message' />
+ <param name='1' doc='Prefix each log message with the source file and line' />
+ <param name='basename' doc='Prefix each log message with the source file&apos;s basename (strip leading paths) and line' />
+ <param name='[last]' doc='Log source file info at the end of a log line. If omitted, log source file info just before the log text.' />
+ </params>
+ </command>
+ <command id='logging level (|gprs|ns|bssgp|lglobal|llapd|linp|lmux|lmi|lmib|lsms|lctrl|lgtp|lstats|lgsup|loap|lss7|lsccp|lsua|lm3ua|lmgcp|ljibuf|lrspro) (debug|info|notice|error|fatal)'>
+ <params>
+ <param name='logging' doc='Configure logging' />
+ <param name='level' doc='Set the log level for a specified category' />
+ <param name='gprs' doc='GPRS Packet Service' />
+ <param name='ns' doc='GPRS Network Service (NS)' />
+ <param name='bssgp' doc='GPRS BSS Gateway Protocol (BSSGP)' />
+ <param name='lglobal' doc='Library-internal global log family' />
+ <param name='llapd' doc='LAPD in libosmogsm' />
+ <param name='linp' doc='A-bis Intput Subsystem' />
+ <param name='lmux' doc='A-bis B-Subchannel TRAU Frame Multiplex' />
+ <param name='lmi' doc='A-bis Input Driver for Signalling' />
+ <param name='lmib' doc='A-bis Input Driver for B-Channels (voice)' />
+ <param name='lsms' doc='Layer3 Short Message Service (SMS)' />
+ <param name='lctrl' doc='Control Interface' />
+ <param name='lgtp' doc='GPRS GTP library' />
+ <param name='lstats' doc='Statistics messages and logging' />
+ <param name='lgsup' doc='Generic Subscriber Update Protocol' />
+ <param name='loap' doc='Osmocom Authentication Protocol' />
+ <param name='lss7' doc='libosmo-sigtran Signalling System 7' />
+ <param name='lsccp' doc='libosmo-sigtran SCCP Implementation' />
+ <param name='lsua' doc='libosmo-sigtran SCCP User Adaptation' />
+ <param name='lm3ua' doc='libosmo-sigtran MTP3 User Adaptation' />
+ <param name='lmgcp' doc='libosmo-mgcp Media Gateway Control Protocol' />
+ <param name='ljibuf' doc='libosmo-netif Jitter Buffer' />
+ <param name='lrspro' doc='Remote SIM protocol' />
+ <param name='debug' doc='Log debug messages and higher levels' />
+ <param name='info' doc='Log informational messages and higher levels' />
+ <param name='notice' doc='Log noticeable messages and higher levels' />
+ <param name='error' doc='Log error messages and higher levels' />
+ <param name='fatal' doc='Log only fatal messages' />
+ </params>
+ </command>
+ <command id='logging level set-all (debug|info|notice|error|fatal)'>
+ <params>
+ <param name='logging' doc='Configure logging' />
+ <param name='level' doc='Set the log level for a specified category' />
+ <param name='set-all' doc='Once-off set all categories to the given log level. There is no single command to take back these changes -- each category is set to the given level, period.' />
+ <param name='debug' doc='Log debug messages and higher levels' />
+ <param name='info' doc='Log informational messages and higher levels' />
+ <param name='notice' doc='Log noticeable messages and higher levels' />
+ <param name='error' doc='Log error messages and higher levels' />
+ <param name='fatal' doc='Log only fatal messages' />
+ </params>
+ </command>
+ <command id='logging level force-all (debug|info|notice|error|fatal)'>
+ <params>
+ <param name='logging' doc='Configure logging' />
+ <param name='level' doc='Set the log level for a specified category' />
+ <param name='force-all' doc='Globally force all logging categories to a specific level. This is released by the &apos;no logging level force-all&apos; command. Note: any &apos;logging level &lt;category&gt; &lt;level&gt;&apos; commands will have no visible effect after this, until the forced level is released.' />
+ <param name='debug' doc='Log debug messages and higher levels' />
+ <param name='info' doc='Log informational messages and higher levels' />
+ <param name='notice' doc='Log noticeable messages and higher levels' />
+ <param name='error' doc='Log error messages and higher levels' />
+ <param name='fatal' doc='Log only fatal messages' />
+ </params>
+ </command>
+ <command id='no logging level force-all'>
+ <params>
+ <param name='no' doc='Negate a command or set its defaults' />
+ <param name='logging' doc='Configure logging' />
+ <param name='level' doc='Set the log level for a specified category' />
+ <param name='force-all' doc='Release any globally forced log level set with &apos;logging level force-all &lt;level&gt;&apos;' />
+ </params>
+ </command>
+ <command id='logging filter nsvc (nsei|nsvci) &lt;0-65535&gt;'>
+ <params>
+ <param name='logging' doc='Configure logging' />
+ <param name='filter' doc='Filter log messages' />
+ <param name='nsvc' doc='Filter based on NS Virtual Connection' />
+ <param name='nsei' doc='Identify NS-VC by NSEI' />
+ <param name='nsvci' doc='Identify NS-VC by NSVCI' />
+ <param name='&lt;0-65535&gt;' doc='Numeric identifier' />
+ </params>
+ </command>
+ </node>
+ <node id='config-stats'>
+ <name>config-stats</name>
+ <command id='local-ip ADDR'>
+ <params>
+ <param name='local-ip' doc='Set the IP address to which we bind locally' />
+ <param name='ADDR' doc='IP Address' />
+ </params>
+ </command>
+ <command id='no local-ip'>
+ <params>
+ <param name='no' doc='Negate a command or set its defaults' />
+ <param name='local-ip' doc='Set the IP address to which we bind locally' />
+ </params>
+ </command>
+ <command id='remote-ip ADDR'>
+ <params>
+ <param name='remote-ip' doc='Set the remote IP address to which we connect' />
+ <param name='ADDR' doc='IP Address' />
+ </params>
+ </command>
+ <command id='remote-port &lt;1-65535&gt;'>
+ <params>
+ <param name='remote-port' doc='Set the remote port to which we connect' />
+ <param name='&lt;1-65535&gt;' doc='Remote port number' />
+ </params>
+ </command>
+ <command id='mtu &lt;100-65535&gt;'>
+ <params>
+ <param name='mtu' doc='Set the maximum packet size' />
+ <param name='&lt;100-65535&gt;' doc='Size in byte' />
+ </params>
+ </command>
+ <command id='no mtu'>
+ <params>
+ <param name='no' doc='Negate a command or set its defaults' />
+ <param name='mtu' doc='Set the maximum packet size' />
+ </params>
+ </command>
+ <command id='prefix PREFIX'>
+ <params>
+ <param name='prefix' doc='Set the item name prefix' />
+ <param name='PREFIX' doc='The prefix string' />
+ </params>
+ </command>
+ <command id='no prefix'>
+ <params>
+ <param name='no' doc='Negate a command or set its defaults' />
+ <param name='prefix' doc='Set the item name prefix' />
+ </params>
+ </command>
+ <command id='level (global|peer|subscriber)'>
+ <params>
+ <param name='level' doc='Set the maximum group level' />
+ <param name='global' doc='Report global groups only' />
+ <param name='peer' doc='Report global and network peer related groups' />
+ <param name='subscriber' doc='Report global, peer, and subscriber groups' />
+ </params>
+ </command>
+ <command id='enable'>
+ <params>
+ <param name='enable' doc='Enable the reporter' />
+ </params>
+ </command>
+ <command id='disable'>
+ <params>
+ <param name='disable' doc='Disable the reporter' />
+ </params>
+ </command>
+ </node>
+ <node id='config-line'>
+ <name>config-line</name>
+ <command id='login'>
+ <params>
+ <param name='login' doc='Enable password checking' />
+ </params>
+ </command>
+ <command id='no login'>
+ <params>
+ <param name='no' doc='Negate a command or set its defaults' />
+ <param name='login' doc='Enable password checking' />
+ </params>
+ </command>
+ <command id='bind A.B.C.D [&lt;0-65535&gt;]'>
+ <params>
+ <param name='bind' doc='Accept VTY telnet connections on local interface' />
+ <param name='A.B.C.D' doc='Local interface IP address (default: 127.0.0.1)' />
+ <param name='[&lt;0-65535&gt;]' doc='Local TCP port number' />
+ </params>
+ </command>
+ </node>
+ <node id='config-ns'>
+ <name>config-ns</name>
+ <command id='nse &lt;0-65535&gt; nsvci &lt;0-65534&gt;'>
+ <params>
+ <param name='nse' doc='Persistent NS Entity' />
+ <param name='&lt;0-65535&gt;' doc='NS Entity ID (NSEI)' />
+ <param name='nsvci' doc='NS Virtual Connection' />
+ <param name='&lt;0-65534&gt;' doc='NS Virtual Connection ID (NSVCI)' />
+ </params>
+ </command>
+ <command id='nse &lt;0-65535&gt; remote-ip A.B.C.D'>
+ <params>
+ <param name='nse' doc='Persistent NS Entity' />
+ <param name='&lt;0-65535&gt;' doc='NS Entity ID (NSEI)' />
+ <param name='remote-ip' doc='Remote IP Address' />
+ <param name='A.B.C.D' doc='Remote IP Address' />
+ </params>
+ </command>
+ <command id='nse &lt;0-65535&gt; remote-port &lt;0-65535&gt;'>
+ <params>
+ <param name='nse' doc='Persistent NS Entity' />
+ <param name='&lt;0-65535&gt;' doc='NS Entity ID (NSEI)' />
+ <param name='remote-port' doc='Remote UDP Port' />
+ <param name='&lt;0-65535&gt;' doc='Remote UDP Port Number' />
+ </params>
+ </command>
+ <command id='nse &lt;0-65535&gt; fr-dlci &lt;16-1007&gt;'>
+ <params>
+ <param name='nse' doc='Persistent NS Entity' />
+ <param name='&lt;0-65535&gt;' doc='NS Entity ID (NSEI)' />
+ <param name='fr-dlci' doc='Frame Relay DLCI' />
+ <param name='&lt;16-1007&gt;' doc='Frame Relay DLCI Number' />
+ </params>
+ </command>
+ <command id='nse &lt;0-65535&gt; encapsulation (udp|framerelay-gre)'>
+ <params>
+ <param name='nse' doc='Persistent NS Entity' />
+ <param name='&lt;0-65535&gt;' doc='NS Entity ID (NSEI)' />
+ <param name='encapsulation' doc='Encapsulation for NS' />
+ <param name='udp' doc='UDP/IP Encapsulation' />
+ <param name='framerelay-gre' doc='Frame-Relay/GRE/IP Encapsulation' />
+ </params>
+ </command>
+ <command id='nse &lt;0-65535&gt; remote-role (sgsn|bss)'>
+ <params>
+ <param name='nse' doc='Persistent NS Entity' />
+ <param name='&lt;0-65535&gt;' doc='NS Entity ID (NSEI)' />
+ <param name='remote-role' doc='Remote NSE Role' />
+ <param name='sgsn' doc='Remote Peer is SGSN' />
+ <param name='bss' doc='Remote Peer is BSS' />
+ </params>
+ </command>
+ <command id='no nse &lt;0-65535&gt;'>
+ <params>
+ <param name='no' doc='Delete Persistent NS Entity' />
+ <param name='nse' doc='Delete Persistent NS Entity' />
+ <param name='&lt;0-65535&gt;' doc='NS Entity ID (NSEI)' />
+ </params>
+ </command>
+ <command id='timer (tns-block|tns-block-retries|tns-reset|tns-reset-retries|tns-test|tns-alive|tns-alive-retries|tsns-prov) &lt;0-65535&gt;'>
+ <params>
+ <param name='timer' doc='Network Service Timer' />
+ <param name='tns-block' doc='(un)blocking Timer (Tns-block) timeout' />
+ <param name='tns-block-retries' doc='(un)blocking Timer (Tns-block) number of retries' />
+ <param name='tns-reset' doc='Reset Timer (Tns-reset) timeout' />
+ <param name='tns-reset-retries' doc='Reset Timer (Tns-reset) number of retries' />
+ <param name='tns-test' doc='Test Timer (Tns-test) timeout' />
+ <param name='tns-alive' doc='Alive Timer (Tns-alive) timeout' />
+ <param name='tns-alive-retries' doc='Alive Timer (Tns-alive) number of retries' />
+ <param name='tsns-prov' doc='SNS Provision Timer (Tsns-prov) timeout' />
+ <param name='&lt;0-65535&gt;' doc='Timer Value' />
+ </params>
+ </command>
+ <command id='encapsulation udp local-ip A.B.C.D'>
+ <params>
+ <param name='encapsulation' doc='NS encapsulation options' />
+ <param name='udp' doc='NS over UDP Encapsulation' />
+ <param name='local-ip' doc='Set the IP address on which we listen for NS/UDP' />
+ <param name='A.B.C.D' doc='IP Address' />
+ </params>
+ </command>
+ <command id='encapsulation udp local-port &lt;0-65535&gt;'>
+ <params>
+ <param name='encapsulation' doc='NS encapsulation options' />
+ <param name='udp' doc='NS over UDP Encapsulation' />
+ <param name='local-port' doc='Set the UDP port on which we listen for NS/UDP' />
+ <param name='&lt;0-65535&gt;' doc='UDP port number' />
+ </params>
+ </command>
+ <command id='encapsulation udp dscp &lt;0-255&gt;'>
+ <params>
+ <param name='encapsulation' doc='NS encapsulation options' />
+ <param name='udp' doc='NS over UDP Encapsulation' />
+ <param name='dscp' doc='Set DSCP/TOS on the UDP socket' />
+ <param name='&lt;0-255&gt;' doc='DSCP Value' />
+ </params>
+ </command>
+ <command id='encapsulation framerelay-gre enabled (1|0)'>
+ <params>
+ <param name='encapsulation' doc='NS encapsulation options' />
+ <param name='framerelay-gre' doc='NS over Frame Relay over GRE Encapsulation' />
+ <param name='enabled' doc='Enable or disable Frame Relay over GRE' />
+ <param name='1' doc='Enable' />
+ <param name='0' doc='Disable' />
+ </params>
+ </command>
+ <command id='encapsulation framerelay-gre local-ip A.B.C.D'>
+ <params>
+ <param name='encapsulation' doc='NS encapsulation options' />
+ <param name='framerelay-gre' doc='NS over Frame Relay over GRE Encapsulation' />
+ <param name='local-ip' doc='Set the IP address on which we listen for NS/FR/GRE' />
+ <param name='A.B.C.D' doc='IP Address' />
+ </params>
+ </command>
+ </node>
+ <node id='config-gbproxy'>
+ <name>config-gbproxy</name>
+ <command id='sgsn nsei &lt;0-65534&gt;'>
+ <params>
+ <param name='sgsn' doc='SGSN information' />
+ <param name='nsei' doc='NSEI to be used in the connection with the SGSN' />
+ <param name='&lt;0-65534&gt;' doc='The NSEI' />
+ </params>
+ </command>
+ <command id='core-mobile-country-code &lt;1-999&gt;'>
+ <params>
+ <param name='core-mobile-country-code' doc='Use this country code for the core network' />
+ <param name='&lt;1-999&gt;' doc='MCC value' />
+ </params>
+ </command>
+ <command id='core-mobile-network-code &lt;1-999&gt;'>
+ <params>
+ <param name='core-mobile-network-code' doc='Use this network code for the core network' />
+ <param name='&lt;1-999&gt;' doc='NCC value' />
+ </params>
+ </command>
+ <command id='match-imsi (patching|routing) .REGEXP'>
+ <params>
+ <param name='match-imsi' doc='Restrict actions to certain IMSIs' />
+ <param name='patching' doc='Patch MS related information elements on match only' />
+ <param name='routing' doc='Route to the secondary SGSN on match only' />
+ <param name='.REGEXP' doc='Regular expression for the IMSI match' />
+ </params>
+ </command>
+ <command id='core-access-point-name (APN|none)'>
+ <params>
+ <param name='core-access-point-name' doc='Use this access point name (APN) for the backbone' />
+ <param name='APN' doc='Replace APN by this string' />
+ <param name='none' doc='Remove APN' />
+ </params>
+ </command>
+ <command id='secondary-sgsn nsei &lt;0-65534&gt;'>
+ <params>
+ <param name='secondary-sgsn' doc='Route matching LLC connections to a second SGSN (Experimental)' />
+ <param name='nsei' doc='NSEI to be used in the connection with the SGSN' />
+ <param name='&lt;0-65534&gt;' doc='The NSEI' />
+ </params>
+ </command>
+ <command id='patch-ptmsi'>
+ <params>
+ <param name='patch-ptmsi' doc='Patch P-TMSI/TLLI' />
+ </params>
+ </command>
+ <command id='acquire-imsi'>
+ <params>
+ <param name='acquire-imsi' doc='Acquire the IMSI before establishing a LLC connection (Experimental)' />
+ </params>
+ </command>
+ <command id='link-list clean-stale-timer &lt;1-999999&gt;'>
+ <params>
+ <param name='link-list' doc='Set TLLI list parameters' />
+ <param name='clean-stale-timer' doc='Periodic timer to clean stale links' />
+ <param name='&lt;1-999999&gt;' doc='Frequency at which the periodic timer is fired (in seconds)' />
+ </params>
+ </command>
+ <command id='link-list max-age &lt;1-999999&gt;'>
+ <params>
+ <param name='link-list' doc='Set TLLI list parameters' />
+ <param name='max-age' doc='Limit maximum age' />
+ <param name='&lt;1-999999&gt;' doc='Maximum age in seconds' />
+ </params>
+ </command>
+ <command id='link-list max-length &lt;1-99999&gt;'>
+ <params>
+ <param name='link-list' doc='Set TLLI list parameters' />
+ <param name='max-length' doc='Limit list length' />
+ <param name='&lt;1-99999&gt;' doc='Maximum number of logical links in the list' />
+ </params>
+ </command>
+ <command id='link-list keep-mode (never|re-attach|identified|always)'>
+ <params>
+ <param name='link-list' doc='Set TLLI list parameters' />
+ <param name='keep-mode' doc='How to keep entries for detached logical links' />
+ <param name='never' doc='Discard entry immediately after detachment' />
+ <param name='re-attach' doc='Keep entry if a re-attachment has be requested' />
+ <param name='identified' doc='Keep entry if it associated with an IMSI' />
+ <param name='always' doc='Don&apos;t discard entries after detachment' />
+ </params>
+ </command>
+ <command id='link stored-msgs-max-length &lt;1-99999&gt;'>
+ <params>
+ <param name='link' doc='Set TLLI parameters' />
+ <param name='stored-msgs-max-length' doc='Limit list length' />
+ <param name='&lt;1-99999&gt;' doc='Maximum number of msgb stored in the logical link waiting to acquire its IMSI' />
+ </params>
+ </command>
+ <command id='no core-mobile-country-code'>
+ <params>
+ <param name='no' doc='Negate a command or set its defaults' />
+ <param name='core-mobile-country-code' doc='Use this country code for the core network' />
+ </params>
+ </command>
+ <command id='no core-mobile-network-code'>
+ <params>
+ <param name='no' doc='Negate a command or set its defaults' />
+ <param name='core-mobile-network-code' doc='Use this network code for the core network' />
+ </params>
+ </command>
+ <command id='no match-imsi'>
+ <params>
+ <param name='no' doc='Negate a command or set its defaults' />
+ <param name='match-imsi' doc='Restrict actions to certain IMSIs' />
+ </params>
+ </command>
+ <command id='no core-access-point-name'>
+ <params>
+ <param name='no' doc='Negate a command or set its defaults' />
+ <param name='core-access-point-name' doc='Use this access point name (APN) for the backbone' />
+ </params>
+ </command>
+ <command id='no secondary-sgsn'>
+ <params>
+ <param name='no' doc='Negate a command or set its defaults' />
+ <param name='secondary-sgsn' doc='Route matching LLC connections to a second SGSN (Experimental)' />
+ </params>
+ </command>
+ <command id='no patch-ptmsi'>
+ <params>
+ <param name='no' doc='Negate a command or set its defaults' />
+ <param name='patch-ptmsi' doc='Patch P-TMSI/TLLI' />
+ </params>
+ </command>
+ <command id='no acquire-imsi'>
+ <params>
+ <param name='no' doc='Negate a command or set its defaults' />
+ <param name='acquire-imsi' doc='Acquire the IMSI before establishing a LLC connection (Experimental)' />
+ </params>
+ </command>
+ <command id='no link-list clean-stale-timer'>
+ <params>
+ <param name='no' doc='Negate a command or set its defaults' />
+ <param name='link-list' doc='Set TLLI list parameters' />
+ <param name='clean-stale-timer' doc='Periodic timer to clean stale links' />
+ </params>
+ </command>
+ <command id='no link-list max-age'>
+ <params>
+ <param name='no' doc='Negate a command or set its defaults' />
+ <param name='link-list' doc='Set TLLI list parameters' />
+ <param name='max-age' doc='Limit maximum age' />
+ </params>
+ </command>
+ <command id='no link-list max-length'>
+ <params>
+ <param name='no' doc='Negate a command or set its defaults' />
+ <param name='link-list' doc='Set TLLI list parameters' />
+ <param name='max-length' doc='Limit list length' />
+ </params>
+ </command>
+ <command id='no link stored-msgs-max-length'>
+ <params>
+ <param name='no' doc='Negate a command or set its defaults' />
+ <param name='link' doc='Set TLLI parameters' />
+ <param name='stored-msgs-max-length' doc='Limit list length' />
+ </params>
+ </command>
+ </node>
+</vtydoc>
diff --git a/doc/manuals/vty/sgsn_vty_additions.xml b/doc/manuals/vty/sgsn_vty_additions.xml
new file mode 100644
index 000000000..660b695f7
--- /dev/null
+++ b/doc/manuals/vty/sgsn_vty_additions.xml
@@ -0,0 +1,6 @@
+<vtydoc xmlns='urn:osmocom:xml:libosmocore:vty:doc:1.0'>
+ <node id='config-sgsn'>
+ <description>Configure the remote GGSN, access-control and other
+ attributes of the SGSN</description>
+ </node>
+</vtydoc>
diff --git a/doc/manuals/vty/sgsn_vty_reference.xml b/doc/manuals/vty/sgsn_vty_reference.xml
new file mode 100644
index 000000000..38e21c2f1
--- /dev/null
+++ b/doc/manuals/vty/sgsn_vty_reference.xml
@@ -0,0 +1,2536 @@
+<vtydoc xmlns='urn:osmocom:xml:libosmocore:vty:doc:1.0'>
+ <node id='_common_cmds_'>
+ <name>Common Commands</name>
+ <description>These commands are available on all VTY nodes. They are listed here only once, to unclutter the VTY reference.</description>
+ <command id='help'>
+ <params>
+ <param name='help' doc='Description of the interactive help system' />
+ </params>
+ </command>
+ <command id='list'>
+ <params>
+ <param name='list' doc='Print command list' />
+ </params>
+ </command>
+ <command id='write terminal'>
+ <params>
+ <param name='write' doc='Write running configuration to memory, network, or terminal' />
+ <param name='terminal' doc='Write to terminal' />
+ </params>
+ </command>
+ <command id='write file'>
+ <params>
+ <param name='write' doc='Write running configuration to memory, network, or terminal' />
+ <param name='file' doc='Write to configuration file' />
+ </params>
+ </command>
+ <command id='write memory'>
+ <params>
+ <param name='write' doc='Write running configuration to memory, network, or terminal' />
+ <param name='memory' doc='Write configuration to the file (same as write file)' />
+ </params>
+ </command>
+ <command id='write'>
+ <params>
+ <param name='write' doc='Write running configuration to memory, network, or terminal' />
+ </params>
+ </command>
+ <command id='show running-config'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='running-config' doc='running configuration' />
+ </params>
+ </command>
+ <command id='exit'>
+ <params>
+ <param name='exit' doc='Exit current mode and down to previous mode' />
+ </params>
+ </command>
+ <command id='end'>
+ <params>
+ <param name='end' doc='End current mode and change to enable mode.' />
+ </params>
+ </command>
+ </node>
+ <node id='view'>
+ <name>view</name>
+ <command id='show version'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='version' doc='Displays program version' />
+ </params>
+ </command>
+ <command id='show online-help'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='online-help' doc='Online help' />
+ </params>
+ </command>
+ <command id='enable'>
+ <params>
+ <param name='enable' doc='Turn on privileged mode command' />
+ </params>
+ </command>
+ <command id='terminal length &lt;0-512&gt;'>
+ <params>
+ <param name='terminal' doc='Set terminal line parameters' />
+ <param name='length' doc='Set number of lines on a screen' />
+ <param name='&lt;0-512&gt;' doc='Number of lines on screen (0 for no pausing)' />
+ </params>
+ </command>
+ <command id='terminal no length'>
+ <params>
+ <param name='terminal' doc='Set terminal line parameters' />
+ <param name='no' doc='Negate a command or set its defaults' />
+ <param name='length' doc='Set number of lines on a screen' />
+ </params>
+ </command>
+ <command id='who'>
+ <params>
+ <param name='who' doc='Display who is on vty' />
+ </params>
+ </command>
+ <command id='show history'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='history' doc='Display the session command history' />
+ </params>
+ </command>
+ <command id='logging enable'>
+ <params>
+ <param name='logging' doc='Configure logging' />
+ <param name='enable' doc='Enables logging to this vty' />
+ </params>
+ </command>
+ <command id='logging disable'>
+ <params>
+ <param name='logging' doc='Configure logging' />
+ <param name='disable' doc='Disables logging to this vty' />
+ </params>
+ </command>
+ <command id='logging filter all (0|1)'>
+ <params>
+ <param name='logging' doc='Configure logging' />
+ <param name='filter' doc='Filter log messages' />
+ <param name='all' doc='Do you want to log all messages?' />
+ <param name='0' doc='Only print messages matched by other filters' />
+ <param name='1' doc='Bypass filter and print all messages' />
+ </params>
+ </command>
+ <command id='logging color (0|1)'>
+ <params>
+ <param name='logging' doc='Configure logging' />
+ <param name='color' doc='Configure color-printing for log messages' />
+ <param name='0' doc='Don&apos;t use color for printing messages' />
+ <param name='1' doc='Use color for printing messages' />
+ </params>
+ </command>
+ <command id='logging timestamp (0|1)'>
+ <params>
+ <param name='logging' doc='Configure logging' />
+ <param name='timestamp' doc='Configure log message timestamping' />
+ <param name='0' doc='Don&apos;t prefix each log message' />
+ <param name='1' doc='Prefix each log message with current timestamp' />
+ </params>
+ </command>
+ <command id='logging print extended-timestamp (0|1)'>
+ <params>
+ <param name='logging' doc='Configure logging' />
+ <param name='print' doc='Log output settings' />
+ <param name='extended-timestamp' doc='Configure log message timestamping' />
+ <param name='0' doc='Don&apos;t prefix each log message' />
+ <param name='1' doc='Prefix each log message with current timestamp with YYYYMMDDhhmmssnnn' />
+ </params>
+ </command>
+ <command id='logging print category (0|1)'>
+ <params>
+ <param name='logging' doc='Configure logging' />
+ <param name='print' doc='Log output settings' />
+ <param name='category' doc='Configure log message' />
+ <param name='0' doc='Don&apos;t prefix each log message' />
+ <param name='1' doc='Prefix each log message with category/subsystem name' />
+ </params>
+ </command>
+ <command id='logging print category-hex (0|1)'>
+ <params>
+ <param name='logging' doc='Configure logging' />
+ <param name='print' doc='Log output settings' />
+ <param name='category-hex' doc='Configure log message' />
+ <param name='0' doc='Don&apos;t prefix each log message' />
+ <param name='1' doc='Prefix each log message with category/subsystem nr in hex (&apos;&lt;000b&gt;&apos;)' />
+ </params>
+ </command>
+ <command id='logging print level (0|1)'>
+ <params>
+ <param name='logging' doc='Configure logging' />
+ <param name='print' doc='Log output settings' />
+ <param name='level' doc='Configure log message' />
+ <param name='0' doc='Don&apos;t prefix each log message' />
+ <param name='1' doc='Prefix each log message with the log level name' />
+ </params>
+ </command>
+ <command id='logging print file (0|1|basename) [last]'>
+ <params>
+ <param name='logging' doc='Configure logging' />
+ <param name='print' doc='Log output settings' />
+ <param name='file' doc='Configure log message' />
+ <param name='0' doc='Don&apos;t prefix each log message' />
+ <param name='1' doc='Prefix each log message with the source file and line' />
+ <param name='basename' doc='Prefix each log message with the source file&apos;s basename (strip leading paths) and line' />
+ <param name='[last]' doc='Log source file info at the end of a log line. If omitted, log source file info just before the log text.' />
+ </params>
+ </command>
+ <command id='logging set-log-mask MASK'>
+ <params>
+ <param name='logging' doc='Configure logging' />
+ <param name='set-log-mask' doc='Set the logmask of this logging target' />
+ <param name='MASK' doc='List of logging categories to log, e.g. &apos;abc:mno:xyz&apos;. Available log categories depend on the specific application, refer to the &apos;logging level&apos; command. Optionally add individual log levels like &apos;abc,1:mno,3:xyz,5&apos;, where the level numbers are LOGL_DEBUG=1 LOGL_INFO=3 LOGL_NOTICE=5 LOGL_ERROR=7 LOGL_FATAL=8' />
+ </params>
+ </command>
+ <command id='logging level (|mm|pag|meas|ref|gprs|ns|bssgp|llc|sndcp|slhc|ranap|sua|v42bis|lglobal|llapd|linp|lmux|lmi|lmib|lsms|lctrl|lgtp|lstats|lgsup|loap|lss7|lsccp|lsua|lm3ua|lmgcp|ljibuf|lrspro) (debug|info|notice|error|fatal)'>
+ <params>
+ <param name='logging' doc='Configure logging' />
+ <param name='level' doc='Set the log level for a specified category' />
+ <param name='mm' doc='Layer3 Mobility Management (MM)' />
+ <param name='pag' doc='Paging Subsystem' />
+ <param name='meas' doc='Radio Measurement Processing' />
+ <param name='ref' doc='Reference Counting' />
+ <param name='gprs' doc='GPRS Packet Service' />
+ <param name='ns' doc='GPRS Network Service (NS)' />
+ <param name='bssgp' doc='GPRS BSS Gateway Protocol (BSSGP)' />
+ <param name='llc' doc='GPRS Logical Link Control Protocol (LLC)' />
+ <param name='sndcp' doc='GPRS Sub-Network Dependent Control Protocol (SNDCP)' />
+ <param name='slhc' doc='RFC1144 TCP/IP Header compression (SLHC)' />
+ <param name='ranap' doc='RAN Application Part (RANAP)' />
+ <param name='sua' doc='SCCP User Adaptation (SUA)' />
+ <param name='v42bis' doc='V.42bis data compression (SNDCP)' />
+ <param name='lglobal' doc='Library-internal global log family' />
+ <param name='llapd' doc='LAPD in libosmogsm' />
+ <param name='linp' doc='A-bis Intput Subsystem' />
+ <param name='lmux' doc='A-bis B-Subchannel TRAU Frame Multiplex' />
+ <param name='lmi' doc='A-bis Input Driver for Signalling' />
+ <param name='lmib' doc='A-bis Input Driver for B-Channels (voice)' />
+ <param name='lsms' doc='Layer3 Short Message Service (SMS)' />
+ <param name='lctrl' doc='Control Interface' />
+ <param name='lgtp' doc='GPRS GTP library' />
+ <param name='lstats' doc='Statistics messages and logging' />
+ <param name='lgsup' doc='Generic Subscriber Update Protocol' />
+ <param name='loap' doc='Osmocom Authentication Protocol' />
+ <param name='lss7' doc='libosmo-sigtran Signalling System 7' />
+ <param name='lsccp' doc='libosmo-sigtran SCCP Implementation' />
+ <param name='lsua' doc='libosmo-sigtran SCCP User Adaptation' />
+ <param name='lm3ua' doc='libosmo-sigtran MTP3 User Adaptation' />
+ <param name='lmgcp' doc='libosmo-mgcp Media Gateway Control Protocol' />
+ <param name='ljibuf' doc='libosmo-netif Jitter Buffer' />
+ <param name='lrspro' doc='Remote SIM protocol' />
+ <param name='debug' doc='Log debug messages and higher levels' />
+ <param name='info' doc='Log informational messages and higher levels' />
+ <param name='notice' doc='Log noticeable messages and higher levels' />
+ <param name='error' doc='Log error messages and higher levels' />
+ <param name='fatal' doc='Log only fatal messages' />
+ </params>
+ </command>
+ <command id='logging level set-all (debug|info|notice|error|fatal)'>
+ <params>
+ <param name='logging' doc='Configure logging' />
+ <param name='level' doc='Set the log level for a specified category' />
+ <param name='set-all' doc='Once-off set all categories to the given log level. There is no single command to take back these changes -- each category is set to the given level, period.' />
+ <param name='debug' doc='Log debug messages and higher levels' />
+ <param name='info' doc='Log informational messages and higher levels' />
+ <param name='notice' doc='Log noticeable messages and higher levels' />
+ <param name='error' doc='Log error messages and higher levels' />
+ <param name='fatal' doc='Log only fatal messages' />
+ </params>
+ </command>
+ <command id='logging level force-all (debug|info|notice|error|fatal)'>
+ <params>
+ <param name='logging' doc='Configure logging' />
+ <param name='level' doc='Set the log level for a specified category' />
+ <param name='force-all' doc='Globally force all logging categories to a specific level. This is released by the &apos;no logging level force-all&apos; command. Note: any &apos;logging level &lt;category&gt; &lt;level&gt;&apos; commands will have no visible effect after this, until the forced level is released.' />
+ <param name='debug' doc='Log debug messages and higher levels' />
+ <param name='info' doc='Log informational messages and higher levels' />
+ <param name='notice' doc='Log noticeable messages and higher levels' />
+ <param name='error' doc='Log error messages and higher levels' />
+ <param name='fatal' doc='Log only fatal messages' />
+ </params>
+ </command>
+ <command id='no logging level force-all'>
+ <params>
+ <param name='no' doc='Negate a command or set its defaults' />
+ <param name='logging' doc='Configure logging' />
+ <param name='level' doc='Set the log level for a specified category' />
+ <param name='force-all' doc='Release any globally forced log level set with &apos;logging level force-all &lt;level&gt;&apos;' />
+ </params>
+ </command>
+ <command id='show logging vty'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='logging' doc='Show current logging configuration' />
+ <param name='vty' doc='Show current logging configuration for this vty' />
+ </params>
+ </command>
+ <command id='show alarms'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='alarms' doc='Show current logging configuration' />
+ </params>
+ </command>
+ <command id='show talloc-context (application|all) (full|brief|DEPTH)'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='talloc-context' doc='Show talloc memory hierarchy' />
+ <param name='application' doc='Application&apos;s context' />
+ <param name='all' doc='All contexts, if NULL-context tracking is enabled' />
+ <param name='full' doc='Display a full talloc memory hierarchy' />
+ <param name='brief' doc='Display a brief talloc memory hierarchy' />
+ <param name='DEPTH' doc='Specify required maximal depth value' />
+ </params>
+ </command>
+ <command id='show talloc-context (application|all) (full|brief|DEPTH) tree ADDRESS'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='talloc-context' doc='Show talloc memory hierarchy' />
+ <param name='application' doc='Application&apos;s context' />
+ <param name='all' doc='All contexts, if NULL-context tracking is enabled' />
+ <param name='full' doc='Display a full talloc memory hierarchy' />
+ <param name='brief' doc='Display a brief talloc memory hierarchy' />
+ <param name='DEPTH' doc='Specify required maximal depth value' />
+ <param name='tree' doc='Display only a specific memory chunk' />
+ <param name='ADDRESS' doc='Chunk address (e.g. 0xdeadbeef)' />
+ </params>
+ </command>
+ <command id='show talloc-context (application|all) (full|brief|DEPTH) filter REGEXP'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='talloc-context' doc='Show talloc memory hierarchy' />
+ <param name='application' doc='Application&apos;s context' />
+ <param name='all' doc='All contexts, if NULL-context tracking is enabled' />
+ <param name='full' doc='Display a full talloc memory hierarchy' />
+ <param name='brief' doc='Display a brief talloc memory hierarchy' />
+ <param name='DEPTH' doc='Specify required maximal depth value' />
+ <param name='filter' doc='Filter chunks using regular expression' />
+ <param name='REGEXP' doc='Regular expression' />
+ </params>
+ </command>
+ <command id='show stats'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='stats' doc='Show statistical values' />
+ </params>
+ </command>
+ <command id='show stats level (global|peer|subscriber)'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='stats' doc='Show statistical values' />
+ <param name='level' doc='Set the maximum group level' />
+ <param name='global' doc='Show global groups only' />
+ <param name='peer' doc='Show global and network peer related groups' />
+ <param name='subscriber' doc='Show global, peer, and subscriber groups' />
+ </params>
+ </command>
+ <command id='show asciidoc counters'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='asciidoc' doc='Asciidoc generation' />
+ <param name='counters' doc='Generate table of all registered counters' />
+ </params>
+ </command>
+ <command id='show rate-counters'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='rate-counters' doc='Show all rate counters' />
+ </params>
+ </command>
+ <command id='show sgsn'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='sgsn' doc='Display information about the SGSN' />
+ </params>
+ </command>
+ <command id='show mm-context imsi IMSI [pdp]'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='mm-context' doc='MM Context' />
+ <param name='imsi' doc='Identify by IMSI' />
+ <param name='IMSI' doc='IMSI of the MM Context' />
+ <param name='[pdp]' doc='Include PDP Context Information' />
+ </params>
+ </command>
+ <command id='show mm-context all [pdp]'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='mm-context' doc='MM Context' />
+ <param name='all' doc='All MM Contexts' />
+ <param name='[pdp]' doc='Include PDP Context Information' />
+ </params>
+ </command>
+ <command id='show pdp-context all'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='pdp-context' doc='Display information on PDP Context' />
+ <param name='all' doc='Show everything' />
+ </params>
+ </command>
+ <command id='show subscriber cache'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='subscriber' doc='Show information about subscribers' />
+ <param name='cache' doc='Display contents of subscriber cache' />
+ </params>
+ </command>
+ <command id='show cs7 instance &lt;0-15&gt; users'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='cs7' doc='ITU-T Signaling System 7' />
+ <param name='instance' doc='An instance of the SS7 stack' />
+ <param name='&lt;0-15&gt;' doc='An instance of the SS7 stack' />
+ <param name='users' doc='User Table' />
+ </params>
+ </command>
+ <command id='show cs7 (sua|m3ua|ipa) [&lt;0-65534&gt;]'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='cs7' doc='ITU-T Signaling System 7' />
+ <param name='sua' doc='SCCP User Adaptation' />
+ <param name='m3ua' doc='MTP3 User Adaptation' />
+ <param name='ipa' doc='IPA Multiplex (SCCP Lite)' />
+ <param name='[&lt;0-65534&gt;]' doc='Port Number' />
+ </params>
+ </command>
+ <command id='show cs7 instance &lt;0-15&gt; asp'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='cs7' doc='ITU-T Signaling System 7' />
+ <param name='instance' doc='An instance of the SS7 stack' />
+ <param name='&lt;0-15&gt;' doc='An instance of the SS7 stack' />
+ <param name='asp' doc='Application Server Process (ASP)' />
+ </params>
+ </command>
+ <command id='show cs7 instance &lt;0-15&gt; as (active|all|m3ua|sua)'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='cs7' doc='ITU-T Signaling System 7' />
+ <param name='instance' doc='An instance of the SS7 stack' />
+ <param name='&lt;0-15&gt;' doc='An instance of the SS7 stack' />
+ <param name='as' doc='Application Server (AS)' />
+ <param name='active' doc='Display all active ASs' />
+ <param name='all' doc='Display all ASs (default)' />
+ <param name='m3ua' doc='Display all m3ua ASs' />
+ <param name='sua' doc='Display all SUA ASs' />
+ </params>
+ </command>
+ <command id='show cs7 instance &lt;0-15&gt; sccp addressbook'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='cs7' doc='ITU-T Signaling System 7' />
+ <param name='instance' doc='An instance of the SS7 stack' />
+ <param name='&lt;0-15&gt;' doc='An instance of the SS7 stack' />
+ <param name='sccp' doc='Signalling Connection Control Part' />
+ <param name='addressbook' doc='List all SCCP addressbook entries' />
+ </params>
+ </command>
+ <command id='show cs7 instance &lt;0-15&gt; sccp users'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='cs7' doc='ITU-T Signaling System 7' />
+ <param name='instance' doc='An instance of the SS7 stack' />
+ <param name='&lt;0-15&gt;' doc='An instance of the SS7 stack' />
+ <param name='sccp' doc='Signalling Connection Control Part' />
+ <param name='users' doc='Show List of SCCP Users registered' />
+ </params>
+ </command>
+ <command id='show cs7 instance &lt;0-15&gt; sccp ssn &lt;0-65535&gt;'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='cs7' doc='ITU-T Signaling System 7' />
+ <param name='instance' doc='An instance of the SS7 stack' />
+ <param name='&lt;0-15&gt;' doc='An instance of the SS7 stack' />
+ <param name='sccp' doc='Signalling Connection Control Part' />
+ <param name='ssn' doc='Find an SCCP User registered for the given SSN' />
+ <param name='&lt;0-65535&gt;' doc='Subsystem Number (SSN)' />
+ </params>
+ </command>
+ <command id='show cs7 instance &lt;0-15&gt; sccp connections'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='cs7' doc='ITU-T Signaling System 7' />
+ <param name='instance' doc='An instance of the SS7 stack' />
+ <param name='&lt;0-15&gt;' doc='An instance of the SS7 stack' />
+ <param name='sccp' doc='Signalling Connection Control Part' />
+ <param name='connections' doc='Show List of active SCCP connections' />
+ </params>
+ </command>
+ <command id='show cs7 instance &lt;0-15&gt; sccp timers'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='cs7' doc='ITU-T Signaling System 7' />
+ <param name='instance' doc='An instance of the SS7 stack' />
+ <param name='&lt;0-15&gt;' doc='An instance of the SS7 stack' />
+ <param name='sccp' doc='Signaling Connection Control Part' />
+ <param name='timers' doc='Show List of SCCP timers' />
+ </params>
+ </command>
+ <command id='show ns'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='ns' doc='Display information about the NS protocol' />
+ </params>
+ </command>
+ <command id='show ns stats'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='ns' doc='Display information about the NS protocol' />
+ <param name='stats' doc='Include statistics' />
+ </params>
+ </command>
+ <command id='show ns persistent'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='ns' doc='Display information about the NS protocol' />
+ <param name='persistent' doc='Show only persistent NS' />
+ </params>
+ </command>
+ <command id='show ns (nsei|nsvc) &lt;0-65535&gt; [stats]'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='ns' doc='Display information about the NS protocol' />
+ <param name='nsei' doc='Select one NSE by its NSE Identifier' />
+ <param name='nsvc' doc='Select one NSE by its NS-VC Identifier' />
+ <param name='&lt;0-65535&gt;' doc='The Identifier of selected type' />
+ <param name='[stats]' doc='Include Statistics' />
+ </params>
+ </command>
+ <command id='logging filter nsvc (nsei|nsvci) &lt;0-65535&gt;'>
+ <params>
+ <param name='logging' doc='Configure logging' />
+ <param name='filter' doc='Filter log messages' />
+ <param name='nsvc' doc='Filter based on NS Virtual Connection' />
+ <param name='nsei' doc='Identify NS-VC by NSEI' />
+ <param name='nsvci' doc='Identify NS-VC by NSVCI' />
+ <param name='&lt;0-65535&gt;' doc='Numeric identifier' />
+ </params>
+ </command>
+ <command id='show bssgp'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='bssgp' doc='Show information about the BSSGP protocol' />
+ </params>
+ </command>
+ <command id='show bssgp stats'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='bssgp' doc='Show information about the BSSGP protocol' />
+ <param name='stats' doc='Include statistics' />
+ </params>
+ </command>
+ <command id='show bssgp nsei &lt;0-65535&gt; [stats]'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='bssgp' doc='Show information about the BSSGP protocol' />
+ <param name='nsei' doc='Show all BVCs on one NSE' />
+ <param name='&lt;0-65535&gt;' doc='The NSEI' />
+ <param name='[stats]' doc='Include Statistics' />
+ </params>
+ </command>
+ <command id='logging filter bvc nsei &lt;0-65535&gt; bvci &lt;0-65535&gt;'>
+ <params>
+ <param name='logging' doc='Configure logging' />
+ <param name='filter' doc='Filter log messages' />
+ <param name='bvc' doc='Filter based on BSSGP Virtual Connection' />
+ <param name='nsei' doc='NSEI of the BVC to be filtered' />
+ <param name='&lt;0-65535&gt;' doc='Network Service Entity Identifier (NSEI)' />
+ <param name='bvci' doc='BVCI of the BVC to be filtered' />
+ <param name='&lt;0-65535&gt;' doc='BSSGP Virtual Connection Identifier (BVCI)' />
+ </params>
+ </command>
+ <command id='bssgp bvc nsei &lt;0-65535&gt; bvci &lt;0-65535&gt; reset'>
+ <params>
+ <param name='bssgp' doc='Initiate BVC RESET procedure for a given NSEI and BVCI' />
+ <param name='bvc' doc='Filter based on BSSGP Virtual Connection' />
+ <param name='nsei' doc='NSEI of the BVC to be filtered' />
+ <param name='&lt;0-65535&gt;' doc='Network Service Entity Identifier (NSEI)' />
+ <param name='bvci' doc='BVCI of the BVC to be filtered' />
+ <param name='&lt;0-65535&gt;' doc='BSSGP Virtual Connection Identifier (BVCI)' />
+ <param name='reset' doc='Perform reset procedure' />
+ </params>
+ </command>
+ <command id='show llc'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='llc' doc='Display information about the LLC protocol' />
+ </params>
+ </command>
+ <command id='show sndcp'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='sndcp' doc='Display information about the SNDCP protocol' />
+ </params>
+ </command>
+ </node>
+ <node id='enable'>
+ <name>enable</name>
+ <command id='disable'>
+ <params>
+ <param name='disable' doc='Turn off privileged mode command' />
+ </params>
+ </command>
+ <command id='configure terminal'>
+ <params>
+ <param name='configure' doc='Configuration from vty interface' />
+ <param name='terminal' doc='Configuration terminal' />
+ </params>
+ </command>
+ <command id='copy running-config startup-config'>
+ <params>
+ <param name='copy' doc='Copy configuration' />
+ <param name='running-config' doc='Copy running config to... ' />
+ <param name='startup-config' doc='Copy running config to startup config (same as write file)' />
+ </params>
+ </command>
+ <command id='show startup-config'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='startup-config' doc='Contentes of startup configuration' />
+ </params>
+ </command>
+ <command id='show version'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='version' doc='Displays program version' />
+ </params>
+ </command>
+ <command id='show online-help'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='online-help' doc='Online help' />
+ </params>
+ </command>
+ <command id='terminal length &lt;0-512&gt;'>
+ <params>
+ <param name='terminal' doc='Set terminal line parameters' />
+ <param name='length' doc='Set number of lines on a screen' />
+ <param name='&lt;0-512&gt;' doc='Number of lines on screen (0 for no pausing)' />
+ </params>
+ </command>
+ <command id='terminal no length'>
+ <params>
+ <param name='terminal' doc='Set terminal line parameters' />
+ <param name='no' doc='Negate a command or set its defaults' />
+ <param name='length' doc='Set number of lines on a screen' />
+ </params>
+ </command>
+ <command id='who'>
+ <params>
+ <param name='who' doc='Display who is on vty' />
+ </params>
+ </command>
+ <command id='show history'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='history' doc='Display the session command history' />
+ </params>
+ </command>
+ <command id='terminal monitor'>
+ <params>
+ <param name='terminal' doc='Set terminal line parameters' />
+ <param name='monitor' doc='Copy debug output to the current terminal line' />
+ </params>
+ </command>
+ <command id='terminal no monitor'>
+ <params>
+ <param name='terminal' doc='Set terminal line parameters' />
+ <param name='no' doc='Negate a command or set its defaults' />
+ <param name='monitor' doc='Copy debug output to the current terminal line' />
+ </params>
+ </command>
+ <command id='logging enable'>
+ <params>
+ <param name='logging' doc='Configure logging' />
+ <param name='enable' doc='Enables logging to this vty' />
+ </params>
+ </command>
+ <command id='logging disable'>
+ <params>
+ <param name='logging' doc='Configure logging' />
+ <param name='disable' doc='Disables logging to this vty' />
+ </params>
+ </command>
+ <command id='logging filter all (0|1)'>
+ <params>
+ <param name='logging' doc='Configure logging' />
+ <param name='filter' doc='Filter log messages' />
+ <param name='all' doc='Do you want to log all messages?' />
+ <param name='0' doc='Only print messages matched by other filters' />
+ <param name='1' doc='Bypass filter and print all messages' />
+ </params>
+ </command>
+ <command id='logging color (0|1)'>
+ <params>
+ <param name='logging' doc='Configure logging' />
+ <param name='color' doc='Configure color-printing for log messages' />
+ <param name='0' doc='Don&apos;t use color for printing messages' />
+ <param name='1' doc='Use color for printing messages' />
+ </params>
+ </command>
+ <command id='logging timestamp (0|1)'>
+ <params>
+ <param name='logging' doc='Configure logging' />
+ <param name='timestamp' doc='Configure log message timestamping' />
+ <param name='0' doc='Don&apos;t prefix each log message' />
+ <param name='1' doc='Prefix each log message with current timestamp' />
+ </params>
+ </command>
+ <command id='logging print extended-timestamp (0|1)'>
+ <params>
+ <param name='logging' doc='Configure logging' />
+ <param name='print' doc='Log output settings' />
+ <param name='extended-timestamp' doc='Configure log message timestamping' />
+ <param name='0' doc='Don&apos;t prefix each log message' />
+ <param name='1' doc='Prefix each log message with current timestamp with YYYYMMDDhhmmssnnn' />
+ </params>
+ </command>
+ <command id='logging print category (0|1)'>
+ <params>
+ <param name='logging' doc='Configure logging' />
+ <param name='print' doc='Log output settings' />
+ <param name='category' doc='Configure log message' />
+ <param name='0' doc='Don&apos;t prefix each log message' />
+ <param name='1' doc='Prefix each log message with category/subsystem name' />
+ </params>
+ </command>
+ <command id='logging print category-hex (0|1)'>
+ <params>
+ <param name='logging' doc='Configure logging' />
+ <param name='print' doc='Log output settings' />
+ <param name='category-hex' doc='Configure log message' />
+ <param name='0' doc='Don&apos;t prefix each log message' />
+ <param name='1' doc='Prefix each log message with category/subsystem nr in hex (&apos;&lt;000b&gt;&apos;)' />
+ </params>
+ </command>
+ <command id='logging print level (0|1)'>
+ <params>
+ <param name='logging' doc='Configure logging' />
+ <param name='print' doc='Log output settings' />
+ <param name='level' doc='Configure log message' />
+ <param name='0' doc='Don&apos;t prefix each log message' />
+ <param name='1' doc='Prefix each log message with the log level name' />
+ </params>
+ </command>
+ <command id='logging print file (0|1|basename) [last]'>
+ <params>
+ <param name='logging' doc='Configure logging' />
+ <param name='print' doc='Log output settings' />
+ <param name='file' doc='Configure log message' />
+ <param name='0' doc='Don&apos;t prefix each log message' />
+ <param name='1' doc='Prefix each log message with the source file and line' />
+ <param name='basename' doc='Prefix each log message with the source file&apos;s basename (strip leading paths) and line' />
+ <param name='[last]' doc='Log source file info at the end of a log line. If omitted, log source file info just before the log text.' />
+ </params>
+ </command>
+ <command id='logging set-log-mask MASK'>
+ <params>
+ <param name='logging' doc='Configure logging' />
+ <param name='set-log-mask' doc='Set the logmask of this logging target' />
+ <param name='MASK' doc='List of logging categories to log, e.g. &apos;abc:mno:xyz&apos;. Available log categories depend on the specific application, refer to the &apos;logging level&apos; command. Optionally add individual log levels like &apos;abc,1:mno,3:xyz,5&apos;, where the level numbers are LOGL_DEBUG=1 LOGL_INFO=3 LOGL_NOTICE=5 LOGL_ERROR=7 LOGL_FATAL=8' />
+ </params>
+ </command>
+ <command id='logging level (|mm|pag|meas|ref|gprs|ns|bssgp|llc|sndcp|slhc|ranap|sua|v42bis|lglobal|llapd|linp|lmux|lmi|lmib|lsms|lctrl|lgtp|lstats|lgsup|loap|lss7|lsccp|lsua|lm3ua|lmgcp|ljibuf|lrspro) (debug|info|notice|error|fatal)'>
+ <params>
+ <param name='logging' doc='Configure logging' />
+ <param name='level' doc='Set the log level for a specified category' />
+ <param name='mm' doc='Layer3 Mobility Management (MM)' />
+ <param name='pag' doc='Paging Subsystem' />
+ <param name='meas' doc='Radio Measurement Processing' />
+ <param name='ref' doc='Reference Counting' />
+ <param name='gprs' doc='GPRS Packet Service' />
+ <param name='ns' doc='GPRS Network Service (NS)' />
+ <param name='bssgp' doc='GPRS BSS Gateway Protocol (BSSGP)' />
+ <param name='llc' doc='GPRS Logical Link Control Protocol (LLC)' />
+ <param name='sndcp' doc='GPRS Sub-Network Dependent Control Protocol (SNDCP)' />
+ <param name='slhc' doc='RFC1144 TCP/IP Header compression (SLHC)' />
+ <param name='ranap' doc='RAN Application Part (RANAP)' />
+ <param name='sua' doc='SCCP User Adaptation (SUA)' />
+ <param name='v42bis' doc='V.42bis data compression (SNDCP)' />
+ <param name='lglobal' doc='Library-internal global log family' />
+ <param name='llapd' doc='LAPD in libosmogsm' />
+ <param name='linp' doc='A-bis Intput Subsystem' />
+ <param name='lmux' doc='A-bis B-Subchannel TRAU Frame Multiplex' />
+ <param name='lmi' doc='A-bis Input Driver for Signalling' />
+ <param name='lmib' doc='A-bis Input Driver for B-Channels (voice)' />
+ <param name='lsms' doc='Layer3 Short Message Service (SMS)' />
+ <param name='lctrl' doc='Control Interface' />
+ <param name='lgtp' doc='GPRS GTP library' />
+ <param name='lstats' doc='Statistics messages and logging' />
+ <param name='lgsup' doc='Generic Subscriber Update Protocol' />
+ <param name='loap' doc='Osmocom Authentication Protocol' />
+ <param name='lss7' doc='libosmo-sigtran Signalling System 7' />
+ <param name='lsccp' doc='libosmo-sigtran SCCP Implementation' />
+ <param name='lsua' doc='libosmo-sigtran SCCP User Adaptation' />
+ <param name='lm3ua' doc='libosmo-sigtran MTP3 User Adaptation' />
+ <param name='lmgcp' doc='libosmo-mgcp Media Gateway Control Protocol' />
+ <param name='ljibuf' doc='libosmo-netif Jitter Buffer' />
+ <param name='lrspro' doc='Remote SIM protocol' />
+ <param name='debug' doc='Log debug messages and higher levels' />
+ <param name='info' doc='Log informational messages and higher levels' />
+ <param name='notice' doc='Log noticeable messages and higher levels' />
+ <param name='error' doc='Log error messages and higher levels' />
+ <param name='fatal' doc='Log only fatal messages' />
+ </params>
+ </command>
+ <command id='logging level set-all (debug|info|notice|error|fatal)'>
+ <params>
+ <param name='logging' doc='Configure logging' />
+ <param name='level' doc='Set the log level for a specified category' />
+ <param name='set-all' doc='Once-off set all categories to the given log level. There is no single command to take back these changes -- each category is set to the given level, period.' />
+ <param name='debug' doc='Log debug messages and higher levels' />
+ <param name='info' doc='Log informational messages and higher levels' />
+ <param name='notice' doc='Log noticeable messages and higher levels' />
+ <param name='error' doc='Log error messages and higher levels' />
+ <param name='fatal' doc='Log only fatal messages' />
+ </params>
+ </command>
+ <command id='logging level force-all (debug|info|notice|error|fatal)'>
+ <params>
+ <param name='logging' doc='Configure logging' />
+ <param name='level' doc='Set the log level for a specified category' />
+ <param name='force-all' doc='Globally force all logging categories to a specific level. This is released by the &apos;no logging level force-all&apos; command. Note: any &apos;logging level &lt;category&gt; &lt;level&gt;&apos; commands will have no visible effect after this, until the forced level is released.' />
+ <param name='debug' doc='Log debug messages and higher levels' />
+ <param name='info' doc='Log informational messages and higher levels' />
+ <param name='notice' doc='Log noticeable messages and higher levels' />
+ <param name='error' doc='Log error messages and higher levels' />
+ <param name='fatal' doc='Log only fatal messages' />
+ </params>
+ </command>
+ <command id='no logging level force-all'>
+ <params>
+ <param name='no' doc='Negate a command or set its defaults' />
+ <param name='logging' doc='Configure logging' />
+ <param name='level' doc='Set the log level for a specified category' />
+ <param name='force-all' doc='Release any globally forced log level set with &apos;logging level force-all &lt;level&gt;&apos;' />
+ </params>
+ </command>
+ <command id='show logging vty'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='logging' doc='Show current logging configuration' />
+ <param name='vty' doc='Show current logging configuration for this vty' />
+ </params>
+ </command>
+ <command id='show alarms'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='alarms' doc='Show current logging configuration' />
+ </params>
+ </command>
+ <command id='show talloc-context (application|all) (full|brief|DEPTH)'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='talloc-context' doc='Show talloc memory hierarchy' />
+ <param name='application' doc='Application&apos;s context' />
+ <param name='all' doc='All contexts, if NULL-context tracking is enabled' />
+ <param name='full' doc='Display a full talloc memory hierarchy' />
+ <param name='brief' doc='Display a brief talloc memory hierarchy' />
+ <param name='DEPTH' doc='Specify required maximal depth value' />
+ </params>
+ </command>
+ <command id='show talloc-context (application|all) (full|brief|DEPTH) tree ADDRESS'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='talloc-context' doc='Show talloc memory hierarchy' />
+ <param name='application' doc='Application&apos;s context' />
+ <param name='all' doc='All contexts, if NULL-context tracking is enabled' />
+ <param name='full' doc='Display a full talloc memory hierarchy' />
+ <param name='brief' doc='Display a brief talloc memory hierarchy' />
+ <param name='DEPTH' doc='Specify required maximal depth value' />
+ <param name='tree' doc='Display only a specific memory chunk' />
+ <param name='ADDRESS' doc='Chunk address (e.g. 0xdeadbeef)' />
+ </params>
+ </command>
+ <command id='show talloc-context (application|all) (full|brief|DEPTH) filter REGEXP'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='talloc-context' doc='Show talloc memory hierarchy' />
+ <param name='application' doc='Application&apos;s context' />
+ <param name='all' doc='All contexts, if NULL-context tracking is enabled' />
+ <param name='full' doc='Display a full talloc memory hierarchy' />
+ <param name='brief' doc='Display a brief talloc memory hierarchy' />
+ <param name='DEPTH' doc='Specify required maximal depth value' />
+ <param name='filter' doc='Filter chunks using regular expression' />
+ <param name='REGEXP' doc='Regular expression' />
+ </params>
+ </command>
+ <command id='show stats'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='stats' doc='Show statistical values' />
+ </params>
+ </command>
+ <command id='show stats level (global|peer|subscriber)'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='stats' doc='Show statistical values' />
+ <param name='level' doc='Set the maximum group level' />
+ <param name='global' doc='Show global groups only' />
+ <param name='peer' doc='Show global and network peer related groups' />
+ <param name='subscriber' doc='Show global, peer, and subscriber groups' />
+ </params>
+ </command>
+ <command id='show asciidoc counters'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='asciidoc' doc='Asciidoc generation' />
+ <param name='counters' doc='Generate table of all registered counters' />
+ </params>
+ </command>
+ <command id='show rate-counters'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='rate-counters' doc='Show all rate counters' />
+ </params>
+ </command>
+ <command id='show sgsn'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='sgsn' doc='Display information about the SGSN' />
+ </params>
+ </command>
+ <command id='show mm-context imsi IMSI [pdp]'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='mm-context' doc='MM Context' />
+ <param name='imsi' doc='Identify by IMSI' />
+ <param name='IMSI' doc='IMSI of the MM Context' />
+ <param name='[pdp]' doc='Include PDP Context Information' />
+ </params>
+ </command>
+ <command id='show mm-context all [pdp]'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='mm-context' doc='MM Context' />
+ <param name='all' doc='All MM Contexts' />
+ <param name='[pdp]' doc='Include PDP Context Information' />
+ </params>
+ </command>
+ <command id='show pdp-context all'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='pdp-context' doc='Display information on PDP Context' />
+ <param name='all' doc='Show everything' />
+ </params>
+ </command>
+ <command id='show subscriber cache'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='subscriber' doc='Show information about subscribers' />
+ <param name='cache' doc='Display contents of subscriber cache' />
+ </params>
+ </command>
+ <command id='update-subscriber imsi IMSI insert auth-triplet &lt;1-5&gt; sres SRES rand RAND kc KC'>
+ <params>
+ <param name='update-subscriber' doc='Update subscriber list' />
+ <param name='imsi' doc='Use the IMSI to select the subscriber' />
+ <param name='IMSI' doc='The IMSI' />
+ <param name='insert' doc='Insert data into the subscriber record' />
+ <param name='auth-triplet' doc='Update authentication triplet' />
+ <param name='&lt;1-5&gt;' doc='Triplet index' />
+ <param name='sres' doc='Set SRES value' />
+ <param name='SRES' doc='SRES value (4 byte) in hex' />
+ <param name='rand' doc='Set RAND value' />
+ <param name='RAND' doc='RAND value (16 byte) in hex' />
+ <param name='kc' doc='Set Kc value' />
+ <param name='KC' doc='Kc value (8 byte) in hex' />
+ </params>
+ </command>
+ <command id='update-subscriber imsi IMSI create'>
+ <params>
+ <param name='update-subscriber' doc='Update subscriber list' />
+ <param name='imsi' doc='Use the IMSI to select the subscriber' />
+ <param name='IMSI' doc='The IMSI' />
+ <param name='create' doc='Create a subscriber entry' />
+ </params>
+ </command>
+ <command id='update-subscriber imsi IMSI destroy'>
+ <params>
+ <param name='update-subscriber' doc='Update subscriber list' />
+ <param name='imsi' doc='Use the IMSI to select the subscriber' />
+ <param name='IMSI' doc='The IMSI' />
+ <param name='destroy' doc='Destroy a subscriber entry' />
+ </params>
+ </command>
+ <command id='update-subscriber imsi IMSI cancel (update-procedure|subscription-withdraw)'>
+ <params>
+ <param name='update-subscriber' doc='Update subscriber list' />
+ <param name='imsi' doc='Use the IMSI to select the subscriber' />
+ <param name='IMSI' doc='The IMSI' />
+ <param name='cancel' doc='Cancel (remove) subscriber record' />
+ <param name='update-procedure' doc='The MS moved to another SGSN' />
+ <param name='subscription-withdraw' doc='The subscription is no longer valid' />
+ </params>
+ </command>
+ <command id='update-subscriber imsi IMSI update-location-result (ok|system-failure|data-missing|unexpected-data-value|unknown-subscriber|roaming-not-allowed)'>
+ <params>
+ <param name='update-subscriber' doc='Update subscriber list' />
+ <param name='imsi' doc='Use the IMSI to select the subscriber' />
+ <param name='IMSI' doc='The IMSI' />
+ <param name='update-location-result' doc='Complete the update location procedure' />
+ <param name='ok' doc='The update location request succeeded' />
+ <param name='system-failure' doc='Force error code SystemFailure' />
+ <param name='data-missing' doc='Force error code DataMissing' />
+ <param name='unexpected-data-value' doc='Force error code UnexpectedDataValue' />
+ <param name='unknown-subscriber' doc='Force error code UnknownSubscriber' />
+ <param name='roaming-not-allowed' doc='Force error code RoamingNotAllowed' />
+ </params>
+ </command>
+ <command id='update-subscriber imsi IMSI update-auth-info'>
+ <params>
+ <param name='update-subscriber' doc='Update subscriber list' />
+ <param name='imsi' doc='Use the IMSI to select the subscriber' />
+ <param name='IMSI' doc='The IMSI' />
+ <param name='update-auth-info' doc='Complete the send authentication info procedure' />
+ </params>
+ </command>
+ <command id='show cs7 instance &lt;0-15&gt; users'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='cs7' doc='ITU-T Signaling System 7' />
+ <param name='instance' doc='An instance of the SS7 stack' />
+ <param name='&lt;0-15&gt;' doc='An instance of the SS7 stack' />
+ <param name='users' doc='User Table' />
+ </params>
+ </command>
+ <command id='show cs7 (sua|m3ua|ipa) [&lt;0-65534&gt;]'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='cs7' doc='ITU-T Signaling System 7' />
+ <param name='sua' doc='SCCP User Adaptation' />
+ <param name='m3ua' doc='MTP3 User Adaptation' />
+ <param name='ipa' doc='IPA Multiplex (SCCP Lite)' />
+ <param name='[&lt;0-65534&gt;]' doc='Port Number' />
+ </params>
+ </command>
+ <command id='show cs7 instance &lt;0-15&gt; asp'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='cs7' doc='ITU-T Signaling System 7' />
+ <param name='instance' doc='An instance of the SS7 stack' />
+ <param name='&lt;0-15&gt;' doc='An instance of the SS7 stack' />
+ <param name='asp' doc='Application Server Process (ASP)' />
+ </params>
+ </command>
+ <command id='show cs7 instance &lt;0-15&gt; as (active|all|m3ua|sua)'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='cs7' doc='ITU-T Signaling System 7' />
+ <param name='instance' doc='An instance of the SS7 stack' />
+ <param name='&lt;0-15&gt;' doc='An instance of the SS7 stack' />
+ <param name='as' doc='Application Server (AS)' />
+ <param name='active' doc='Display all active ASs' />
+ <param name='all' doc='Display all ASs (default)' />
+ <param name='m3ua' doc='Display all m3ua ASs' />
+ <param name='sua' doc='Display all SUA ASs' />
+ </params>
+ </command>
+ <command id='show cs7 instance &lt;0-15&gt; sccp addressbook'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='cs7' doc='ITU-T Signaling System 7' />
+ <param name='instance' doc='An instance of the SS7 stack' />
+ <param name='&lt;0-15&gt;' doc='An instance of the SS7 stack' />
+ <param name='sccp' doc='Signalling Connection Control Part' />
+ <param name='addressbook' doc='List all SCCP addressbook entries' />
+ </params>
+ </command>
+ <command id='show cs7 instance &lt;0-15&gt; sccp users'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='cs7' doc='ITU-T Signaling System 7' />
+ <param name='instance' doc='An instance of the SS7 stack' />
+ <param name='&lt;0-15&gt;' doc='An instance of the SS7 stack' />
+ <param name='sccp' doc='Signalling Connection Control Part' />
+ <param name='users' doc='Show List of SCCP Users registered' />
+ </params>
+ </command>
+ <command id='show cs7 instance &lt;0-15&gt; sccp ssn &lt;0-65535&gt;'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='cs7' doc='ITU-T Signaling System 7' />
+ <param name='instance' doc='An instance of the SS7 stack' />
+ <param name='&lt;0-15&gt;' doc='An instance of the SS7 stack' />
+ <param name='sccp' doc='Signalling Connection Control Part' />
+ <param name='ssn' doc='Find an SCCP User registered for the given SSN' />
+ <param name='&lt;0-65535&gt;' doc='Subsystem Number (SSN)' />
+ </params>
+ </command>
+ <command id='show cs7 instance &lt;0-15&gt; sccp connections'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='cs7' doc='ITU-T Signaling System 7' />
+ <param name='instance' doc='An instance of the SS7 stack' />
+ <param name='&lt;0-15&gt;' doc='An instance of the SS7 stack' />
+ <param name='sccp' doc='Signalling Connection Control Part' />
+ <param name='connections' doc='Show List of active SCCP connections' />
+ </params>
+ </command>
+ <command id='show cs7 instance &lt;0-15&gt; sccp timers'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='cs7' doc='ITU-T Signaling System 7' />
+ <param name='instance' doc='An instance of the SS7 stack' />
+ <param name='&lt;0-15&gt;' doc='An instance of the SS7 stack' />
+ <param name='sccp' doc='Signaling Connection Control Part' />
+ <param name='timers' doc='Show List of SCCP timers' />
+ </params>
+ </command>
+ <command id='show ns'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='ns' doc='Display information about the NS protocol' />
+ </params>
+ </command>
+ <command id='show ns stats'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='ns' doc='Display information about the NS protocol' />
+ <param name='stats' doc='Include statistics' />
+ </params>
+ </command>
+ <command id='show ns persistent'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='ns' doc='Display information about the NS protocol' />
+ <param name='persistent' doc='Show only persistent NS' />
+ </params>
+ </command>
+ <command id='show ns (nsei|nsvc) &lt;0-65535&gt; [stats]'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='ns' doc='Display information about the NS protocol' />
+ <param name='nsei' doc='Select one NSE by its NSE Identifier' />
+ <param name='nsvc' doc='Select one NSE by its NS-VC Identifier' />
+ <param name='&lt;0-65535&gt;' doc='The Identifier of selected type' />
+ <param name='[stats]' doc='Include Statistics' />
+ </params>
+ </command>
+ <command id='logging filter nsvc (nsei|nsvci) &lt;0-65535&gt;'>
+ <params>
+ <param name='logging' doc='Configure logging' />
+ <param name='filter' doc='Filter log messages' />
+ <param name='nsvc' doc='Filter based on NS Virtual Connection' />
+ <param name='nsei' doc='Identify NS-VC by NSEI' />
+ <param name='nsvci' doc='Identify NS-VC by NSVCI' />
+ <param name='&lt;0-65535&gt;' doc='Numeric identifier' />
+ </params>
+ </command>
+ <command id='nsvc (nsei|nsvci) &lt;0-65535&gt; (block|unblock|reset)'>
+ <params>
+ <param name='nsvc' doc='Perform an operation on a NSVC' />
+ <param name='nsei' doc='NSEI to identify NS-VC Identifier (NS-VCI)' />
+ <param name='nsvci' doc='NS-VC Identifier (NS-VCI)' />
+ <param name='&lt;0-65535&gt;' doc='The NSEI' />
+ <param name='block' doc='Initiate BLOCK procedure' />
+ <param name='unblock' doc='Initiate UNBLOCK procedure' />
+ <param name='reset' doc='Initiate RESET procedure' />
+ </params>
+ </command>
+ <command id='show bssgp'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='bssgp' doc='Show information about the BSSGP protocol' />
+ </params>
+ </command>
+ <command id='show bssgp stats'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='bssgp' doc='Show information about the BSSGP protocol' />
+ <param name='stats' doc='Include statistics' />
+ </params>
+ </command>
+ <command id='show bssgp nsei &lt;0-65535&gt; [stats]'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='bssgp' doc='Show information about the BSSGP protocol' />
+ <param name='nsei' doc='Show all BVCs on one NSE' />
+ <param name='&lt;0-65535&gt;' doc='The NSEI' />
+ <param name='[stats]' doc='Include Statistics' />
+ </params>
+ </command>
+ <command id='logging filter bvc nsei &lt;0-65535&gt; bvci &lt;0-65535&gt;'>
+ <params>
+ <param name='logging' doc='Configure logging' />
+ <param name='filter' doc='Filter log messages' />
+ <param name='bvc' doc='Filter based on BSSGP Virtual Connection' />
+ <param name='nsei' doc='NSEI of the BVC to be filtered' />
+ <param name='&lt;0-65535&gt;' doc='Network Service Entity Identifier (NSEI)' />
+ <param name='bvci' doc='BVCI of the BVC to be filtered' />
+ <param name='&lt;0-65535&gt;' doc='BSSGP Virtual Connection Identifier (BVCI)' />
+ </params>
+ </command>
+ <command id='bssgp bvc nsei &lt;0-65535&gt; bvci &lt;0-65535&gt; reset'>
+ <params>
+ <param name='bssgp' doc='Initiate BVC RESET procedure for a given NSEI and BVCI' />
+ <param name='bvc' doc='Filter based on BSSGP Virtual Connection' />
+ <param name='nsei' doc='NSEI of the BVC to be filtered' />
+ <param name='&lt;0-65535&gt;' doc='Network Service Entity Identifier (NSEI)' />
+ <param name='bvci' doc='BVCI of the BVC to be filtered' />
+ <param name='&lt;0-65535&gt;' doc='BSSGP Virtual Connection Identifier (BVCI)' />
+ <param name='reset' doc='Perform reset procedure' />
+ </params>
+ </command>
+ <command id='show llc'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='llc' doc='Display information about the LLC protocol' />
+ </params>
+ </command>
+ <command id='show sndcp'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='sndcp' doc='Display information about the SNDCP protocol' />
+ </params>
+ </command>
+ </node>
+ <node id='config'>
+ <name>config</name>
+ <command id='hostname WORD'>
+ <params>
+ <param name='hostname' doc='Set system&apos;s network name' />
+ <param name='WORD' doc='This system&apos;s network name' />
+ </params>
+ </command>
+ <command id='no hostname [HOSTNAME]'>
+ <params>
+ <param name='no' doc='Negate a command or set its defaults' />
+ <param name='hostname' doc='Reset system&apos;s network name' />
+ <param name='[HOSTNAME]' doc='Host name of this router' />
+ </params>
+ </command>
+ <command id='password (8|) WORD'>
+ <params>
+ <param name='password' doc='Assign the terminal connection password' />
+ <param name='8' doc='Specifies a HIDDEN password will follow' />
+ <param name='' doc='dummy string ' />
+ <param name='WORD' doc='The HIDDEN line password string' />
+ </params>
+ </command>
+ <command id='password LINE'>
+ <params>
+ <param name='password' doc='Assign the terminal connection password' />
+ <param name='LINE' doc='The UNENCRYPTED (cleartext) line password' />
+ </params>
+ </command>
+ <command id='enable password (8|) WORD'>
+ <params>
+ <param name='enable' doc='Modify enable password parameters' />
+ <param name='password' doc='Assign the privileged level password' />
+ <param name='8' doc='Specifies a HIDDEN password will follow' />
+ <param name='' doc='dummy string ' />
+ <param name='WORD' doc='The HIDDEN &apos;enable&apos; password string' />
+ </params>
+ </command>
+ <command id='enable password LINE'>
+ <params>
+ <param name='enable' doc='Modify enable password parameters' />
+ <param name='password' doc='Assign the privileged level password' />
+ <param name='LINE' doc='The UNENCRYPTED (cleartext) &apos;enable&apos; password' />
+ </params>
+ </command>
+ <command id='no enable password'>
+ <params>
+ <param name='no' doc='Negate a command or set its defaults' />
+ <param name='enable' doc='Modify enable password parameters' />
+ <param name='password' doc='Assign the privileged level password' />
+ </params>
+ </command>
+ <command id='banner motd default'>
+ <params>
+ <param name='banner' doc='Set banner string' />
+ <param name='motd' doc='Strings for motd' />
+ <param name='default' doc='Default string' />
+ </params>
+ </command>
+ <command id='banner motd file [FILE]'>
+ <params>
+ <param name='banner' doc='Set banner' />
+ <param name='motd' doc='Banner for motd' />
+ <param name='file' doc='Banner from a file' />
+ <param name='[FILE]' doc='Filename' />
+ </params>
+ </command>
+ <command id='no banner motd'>
+ <params>
+ <param name='no' doc='Negate a command or set its defaults' />
+ <param name='banner' doc='Set banner string' />
+ <param name='motd' doc='Strings for motd' />
+ </params>
+ </command>
+ <command id='service terminal-length &lt;0-512&gt;'>
+ <params>
+ <param name='service' doc='Set up miscellaneous service' />
+ <param name='terminal-length' doc='System wide terminal length configuration' />
+ <param name='&lt;0-512&gt;' doc='Number of lines of VTY (0 means no line control)' />
+ </params>
+ </command>
+ <command id='no service terminal-length [&lt;0-512&gt;]'>
+ <params>
+ <param name='no' doc='Negate a command or set its defaults' />
+ <param name='service' doc='Set up miscellaneous service' />
+ <param name='terminal-length' doc='System wide terminal length configuration' />
+ <param name='[&lt;0-512&gt;]' doc='Number of lines of VTY (0 means no line control)' />
+ </params>
+ </command>
+ <command id='line vty'>
+ <params>
+ <param name='line' doc='Configure a terminal line' />
+ <param name='vty' doc='Virtual terminal' />
+ </params>
+ </command>
+ <command id='service advanced-vty'>
+ <params>
+ <param name='service' doc='Set up miscellaneous service' />
+ <param name='advanced-vty' doc='Enable advanced mode vty interface' />
+ </params>
+ </command>
+ <command id='no service advanced-vty'>
+ <params>
+ <param name='no' doc='Negate a command or set its defaults' />
+ <param name='service' doc='Set up miscellaneous service' />
+ <param name='advanced-vty' doc='Enable advanced mode vty interface' />
+ </params>
+ </command>
+ <command id='show history'>
+ <params>
+ <param name='show' doc='Show running system information' />
+ <param name='history' doc='Display the session command history' />
+ </params>
+ </command>
+ <command id='log stderr'>
+ <params>
+ <param name='log' doc='Configure logging sub-system' />
+ <param name='stderr' doc='Logging via STDERR of the process' />
+ </params>
+ </command>
+ <command id='no log stderr'>
+ <params>
+ <param name='no' doc='Negate a command or set its defaults' />
+ <param name='log' doc='Configure logging sub-system' />
+ <param name='stderr' doc='Logging via STDERR of the process' />
+ </params>
+ </command>
+ <command id='log file .FILENAME'>
+ <params>
+ <param name='log' doc='Configure logging sub-system' />
+ <param name='file' doc='Logging to text file' />
+ <param name='.FILENAME' doc='Filename' />
+ </params>
+ </command>
+ <command id='no log file .FILENAME'>
+ <params>
+ <param name='no' doc='Negate a command or set its defaults' />
+ <param name='log' doc='Configure logging sub-system' />
+ <param name='file' doc='Logging to text file' />
+ <param name='.FILENAME' doc='Filename' />
+ </params>
+ </command>
+ <command id='log alarms &lt;2-32700&gt;'>
+ <params>
+ <param name='log' doc='Configure logging sub-system' />
+ <param name='alarms' doc='Logging alarms to osmo_strrb' />
+ <param name='&lt;2-32700&gt;' doc='Maximum number of messages to log' />
+ </params>
+ </command>
+ <command id='no log alarms'>
+ <params>
+ <param name='no' doc='Negate a command or set its defaults' />
+ <param name='log' doc='Configure logging sub-system' />
+ <param name='alarms' doc='Logging alarms to osmo_strrb' />
+ </params>
+ </command>
+ <command id='log syslog (authpriv|cron|daemon|ftp|lpr|mail|news|user|uucp)'>
+ <params>
+ <param name='log' doc='Configure logging sub-system' />
+ <param name='syslog' doc='Logging via syslog' />
+ <param name='authpriv' doc='Security/authorization messages facility' />
+ <param name='cron' doc='Clock daemon (cron/at) facility' />
+ <param name='daemon' doc='General system daemon facility' />
+ <param name='ftp' doc='Ftp daemon facility' />
+ <param name='lpr' doc='Line printer facility' />
+ <param name='mail' doc='Mail facility' />
+ <param name='news' doc='News facility' />
+ <param name='user' doc='Generic facility' />
+ <param name='uucp' doc='UUCP facility' />
+ </params>
+ </command>
+ <command id='log syslog local &lt;0-7&gt;'>
+ <params>
+ <param name='log' doc='Configure logging sub-system' />
+ <param name='syslog' doc='Logging via syslog' />
+ <param name='local' doc='Syslog LOCAL facility' />
+ <param name='&lt;0-7&gt;' doc='Local facility number' />
+ </params>
+ </command>
+ <command id='no log syslog'>
+ <params>
+ <param name='no' doc='Negate a command or set its defaults' />
+ <param name='log' doc='Configure logging sub-system' />
+ <param name='syslog' doc='Logging via syslog' />
+ </params>
+ </command>
+ <command id='log gsmtap [HOSTNAME]'>
+ <params>
+ <param name='log' doc='Configure logging sub-system' />
+ <param name='gsmtap' doc='Logging via GSMTAP' />
+ <param name='[HOSTNAME]' doc='Host name to send the GSMTAP logging to (UDP port 4729)' />
+ </params>
+ </command>
+ <command id='stats reporter statsd'>
+ <params>
+ <param name='stats' doc='Configure stats sub-system' />
+ <param name='reporter' doc='Configure a stats reporter' />
+ <param name='statsd' doc='Report to a STATSD server' />
+ </params>
+ </command>
+ <command id='no stats reporter statsd'>
+ <params>
+ <param name='no' doc='Negate a command or set its defaults' />
+ <param name='stats' doc='Configure stats sub-system' />
+ <param name='reporter' doc='Configure a stats reporter' />
+ <param name='statsd' doc='Report to a STATSD server' />
+ </params>
+ </command>
+ <command id='stats reporter log'>
+ <params>
+ <param name='stats' doc='Configure stats sub-system' />
+ <param name='reporter' doc='Configure a stats reporter' />
+ <param name='log' doc='Report to the logger' />
+ </params>
+ </command>
+ <command id='no stats reporter log'>
+ <params>
+ <param name='no' doc='Negate a command or set its defaults' />
+ <param name='stats' doc='Configure stats sub-system' />
+ <param name='reporter' doc='Configure a stats reporter' />
+ <param name='log' doc='Report to the logger' />
+ </params>
+ </command>
+ <command id='stats interval &lt;1-65535&gt;'>
+ <params>
+ <param name='stats' doc='Configure stats sub-system' />
+ <param name='interval' doc='Set the reporting interval' />
+ <param name='&lt;1-65535&gt;' doc='Interval in seconds' />
+ </params>
+ </command>
+ <command id='sgsn'>
+ <params>
+ <param name='sgsn' doc='Configure the SGSN' />
+ </params>
+ </command>
+ <command id='ctrl'>
+ <params>
+ <param name='ctrl' doc='Configure the Control Interface' />
+ </params>
+ </command>
+ <command id='cs7 instance &lt;0-15&gt;'>
+ <params>
+ <param name='cs7' doc='ITU-T Signaling System 7' />
+ <param name='instance' doc='Configure a SS7 Instance' />
+ <param name='&lt;0-15&gt;' doc='An instance of the SS7 stack' />
+ </params>
+ </command>
+ <command id='ns'>
+ <params>
+ <param name='ns' doc='Configure the GPRS Network Service' />
+ </params>
+ </command>
+ <command id='bssgp'>
+ <params>
+ <param name='bssgp' doc='Configure the GPRS BSS Gateway Protocol' />
+ </params>
+ </command>
+ </node>
+ <node id='config-log'>
+ <name>config-log</name>
+ <command id='logging filter all (0|1)'>
+ <params>
+ <param name='logging' doc='Configure logging' />
+ <param name='filter' doc='Filter log messages' />
+ <param name='all' doc='Do you want to log all messages?' />
+ <param name='0' doc='Only print messages matched by other filters' />
+ <param name='1' doc='Bypass filter and print all messages' />
+ </params>
+ </command>
+ <command id='logging color (0|1)'>
+ <params>
+ <param name='logging' doc='Configure logging' />
+ <param name='color' doc='Configure color-printing for log messages' />
+ <param name='0' doc='Don&apos;t use color for printing messages' />
+ <param name='1' doc='Use color for printing messages' />
+ </params>
+ </command>
+ <command id='logging timestamp (0|1)'>
+ <params>
+ <param name='logging' doc='Configure logging' />
+ <param name='timestamp' doc='Configure log message timestamping' />
+ <param name='0' doc='Don&apos;t prefix each log message' />
+ <param name='1' doc='Prefix each log message with current timestamp' />
+ </params>
+ </command>
+ <command id='logging print extended-timestamp (0|1)'>
+ <params>
+ <param name='logging' doc='Configure logging' />
+ <param name='print' doc='Log output settings' />
+ <param name='extended-timestamp' doc='Configure log message timestamping' />
+ <param name='0' doc='Don&apos;t prefix each log message' />
+ <param name='1' doc='Prefix each log message with current timestamp with YYYYMMDDhhmmssnnn' />
+ </params>
+ </command>
+ <command id='logging print category (0|1)'>
+ <params>
+ <param name='logging' doc='Configure logging' />
+ <param name='print' doc='Log output settings' />
+ <param name='category' doc='Configure log message' />
+ <param name='0' doc='Don&apos;t prefix each log message' />
+ <param name='1' doc='Prefix each log message with category/subsystem name' />
+ </params>
+ </command>
+ <command id='logging print category-hex (0|1)'>
+ <params>
+ <param name='logging' doc='Configure logging' />
+ <param name='print' doc='Log output settings' />
+ <param name='category-hex' doc='Configure log message' />
+ <param name='0' doc='Don&apos;t prefix each log message' />
+ <param name='1' doc='Prefix each log message with category/subsystem nr in hex (&apos;&lt;000b&gt;&apos;)' />
+ </params>
+ </command>
+ <command id='logging print level (0|1)'>
+ <params>
+ <param name='logging' doc='Configure logging' />
+ <param name='print' doc='Log output settings' />
+ <param name='level' doc='Configure log message' />
+ <param name='0' doc='Don&apos;t prefix each log message' />
+ <param name='1' doc='Prefix each log message with the log level name' />
+ </params>
+ </command>
+ <command id='logging print file (0|1|basename) [last]'>
+ <params>
+ <param name='logging' doc='Configure logging' />
+ <param name='print' doc='Log output settings' />
+ <param name='file' doc='Configure log message' />
+ <param name='0' doc='Don&apos;t prefix each log message' />
+ <param name='1' doc='Prefix each log message with the source file and line' />
+ <param name='basename' doc='Prefix each log message with the source file&apos;s basename (strip leading paths) and line' />
+ <param name='[last]' doc='Log source file info at the end of a log line. If omitted, log source file info just before the log text.' />
+ </params>
+ </command>
+ <command id='logging level (|mm|pag|meas|ref|gprs|ns|bssgp|llc|sndcp|slhc|ranap|sua|v42bis|lglobal|llapd|linp|lmux|lmi|lmib|lsms|lctrl|lgtp|lstats|lgsup|loap|lss7|lsccp|lsua|lm3ua|lmgcp|ljibuf|lrspro) (debug|info|notice|error|fatal)'>
+ <params>
+ <param name='logging' doc='Configure logging' />
+ <param name='level' doc='Set the log level for a specified category' />
+ <param name='mm' doc='Layer3 Mobility Management (MM)' />
+ <param name='pag' doc='Paging Subsystem' />
+ <param name='meas' doc='Radio Measurement Processing' />
+ <param name='ref' doc='Reference Counting' />
+ <param name='gprs' doc='GPRS Packet Service' />
+ <param name='ns' doc='GPRS Network Service (NS)' />
+ <param name='bssgp' doc='GPRS BSS Gateway Protocol (BSSGP)' />
+ <param name='llc' doc='GPRS Logical Link Control Protocol (LLC)' />
+ <param name='sndcp' doc='GPRS Sub-Network Dependent Control Protocol (SNDCP)' />
+ <param name='slhc' doc='RFC1144 TCP/IP Header compression (SLHC)' />
+ <param name='ranap' doc='RAN Application Part (RANAP)' />
+ <param name='sua' doc='SCCP User Adaptation (SUA)' />
+ <param name='v42bis' doc='V.42bis data compression (SNDCP)' />
+ <param name='lglobal' doc='Library-internal global log family' />
+ <param name='llapd' doc='LAPD in libosmogsm' />
+ <param name='linp' doc='A-bis Intput Subsystem' />
+ <param name='lmux' doc='A-bis B-Subchannel TRAU Frame Multiplex' />
+ <param name='lmi' doc='A-bis Input Driver for Signalling' />
+ <param name='lmib' doc='A-bis Input Driver for B-Channels (voice)' />
+ <param name='lsms' doc='Layer3 Short Message Service (SMS)' />
+ <param name='lctrl' doc='Control Interface' />
+ <param name='lgtp' doc='GPRS GTP library' />
+ <param name='lstats' doc='Statistics messages and logging' />
+ <param name='lgsup' doc='Generic Subscriber Update Protocol' />
+ <param name='loap' doc='Osmocom Authentication Protocol' />
+ <param name='lss7' doc='libosmo-sigtran Signalling System 7' />
+ <param name='lsccp' doc='libosmo-sigtran SCCP Implementation' />
+ <param name='lsua' doc='libosmo-sigtran SCCP User Adaptation' />
+ <param name='lm3ua' doc='libosmo-sigtran MTP3 User Adaptation' />
+ <param name='lmgcp' doc='libosmo-mgcp Media Gateway Control Protocol' />
+ <param name='ljibuf' doc='libosmo-netif Jitter Buffer' />
+ <param name='lrspro' doc='Remote SIM protocol' />
+ <param name='debug' doc='Log debug messages and higher levels' />
+ <param name='info' doc='Log informational messages and higher levels' />
+ <param name='notice' doc='Log noticeable messages and higher levels' />
+ <param name='error' doc='Log error messages and higher levels' />
+ <param name='fatal' doc='Log only fatal messages' />
+ </params>
+ </command>
+ <command id='logging level set-all (debug|info|notice|error|fatal)'>
+ <params>
+ <param name='logging' doc='Configure logging' />
+ <param name='level' doc='Set the log level for a specified category' />
+ <param name='set-all' doc='Once-off set all categories to the given log level. There is no single command to take back these changes -- each category is set to the given level, period.' />
+ <param name='debug' doc='Log debug messages and higher levels' />
+ <param name='info' doc='Log informational messages and higher levels' />
+ <param name='notice' doc='Log noticeable messages and higher levels' />
+ <param name='error' doc='Log error messages and higher levels' />
+ <param name='fatal' doc='Log only fatal messages' />
+ </params>
+ </command>
+ <command id='logging level force-all (debug|info|notice|error|fatal)'>
+ <params>
+ <param name='logging' doc='Configure logging' />
+ <param name='level' doc='Set the log level for a specified category' />
+ <param name='force-all' doc='Globally force all logging categories to a specific level. This is released by the &apos;no logging level force-all&apos; command. Note: any &apos;logging level &lt;category&gt; &lt;level&gt;&apos; commands will have no visible effect after this, until the forced level is released.' />
+ <param name='debug' doc='Log debug messages and higher levels' />
+ <param name='info' doc='Log informational messages and higher levels' />
+ <param name='notice' doc='Log noticeable messages and higher levels' />
+ <param name='error' doc='Log error messages and higher levels' />
+ <param name='fatal' doc='Log only fatal messages' />
+ </params>
+ </command>
+ <command id='no logging level force-all'>
+ <params>
+ <param name='no' doc='Negate a command or set its defaults' />
+ <param name='logging' doc='Configure logging' />
+ <param name='level' doc='Set the log level for a specified category' />
+ <param name='force-all' doc='Release any globally forced log level set with &apos;logging level force-all &lt;level&gt;&apos;' />
+ </params>
+ </command>
+ <command id='logging filter nsvc (nsei|nsvci) &lt;0-65535&gt;'>
+ <params>
+ <param name='logging' doc='Configure logging' />
+ <param name='filter' doc='Filter log messages' />
+ <param name='nsvc' doc='Filter based on NS Virtual Connection' />
+ <param name='nsei' doc='Identify NS-VC by NSEI' />
+ <param name='nsvci' doc='Identify NS-VC by NSVCI' />
+ <param name='&lt;0-65535&gt;' doc='Numeric identifier' />
+ </params>
+ </command>
+ <command id='logging filter bvc nsei &lt;0-65535&gt; bvci &lt;0-65535&gt;'>
+ <params>
+ <param name='logging' doc='Configure logging' />
+ <param name='filter' doc='Filter log messages' />
+ <param name='bvc' doc='Filter based on BSSGP Virtual Connection' />
+ <param name='nsei' doc='NSEI of the BVC to be filtered' />
+ <param name='&lt;0-65535&gt;' doc='Network Service Entity Identifier (NSEI)' />
+ <param name='bvci' doc='BVCI of the BVC to be filtered' />
+ <param name='&lt;0-65535&gt;' doc='BSSGP Virtual Connection Identifier (BVCI)' />
+ </params>
+ </command>
+ </node>
+ <node id='config-stats'>
+ <name>config-stats</name>
+ <command id='local-ip ADDR'>
+ <params>
+ <param name='local-ip' doc='Set the IP address to which we bind locally' />
+ <param name='ADDR' doc='IP Address' />
+ </params>
+ </command>
+ <command id='no local-ip'>
+ <params>
+ <param name='no' doc='Negate a command or set its defaults' />
+ <param name='local-ip' doc='Set the IP address to which we bind locally' />
+ </params>
+ </command>
+ <command id='remote-ip ADDR'>
+ <params>
+ <param name='remote-ip' doc='Set the remote IP address to which we connect' />
+ <param name='ADDR' doc='IP Address' />
+ </params>
+ </command>
+ <command id='remote-port &lt;1-65535&gt;'>
+ <params>
+ <param name='remote-port' doc='Set the remote port to which we connect' />
+ <param name='&lt;1-65535&gt;' doc='Remote port number' />
+ </params>
+ </command>
+ <command id='mtu &lt;100-65535&gt;'>
+ <params>
+ <param name='mtu' doc='Set the maximum packet size' />
+ <param name='&lt;100-65535&gt;' doc='Size in byte' />
+ </params>
+ </command>
+ <command id='no mtu'>
+ <params>
+ <param name='no' doc='Negate a command or set its defaults' />
+ <param name='mtu' doc='Set the maximum packet size' />
+ </params>
+ </command>
+ <command id='prefix PREFIX'>
+ <params>
+ <param name='prefix' doc='Set the item name prefix' />
+ <param name='PREFIX' doc='The prefix string' />
+ </params>
+ </command>
+ <command id='no prefix'>
+ <params>
+ <param name='no' doc='Negate a command or set its defaults' />
+ <param name='prefix' doc='Set the item name prefix' />
+ </params>
+ </command>
+ <command id='level (global|peer|subscriber)'>
+ <params>
+ <param name='level' doc='Set the maximum group level' />
+ <param name='global' doc='Report global groups only' />
+ <param name='peer' doc='Report global and network peer related groups' />
+ <param name='subscriber' doc='Report global, peer, and subscriber groups' />
+ </params>
+ </command>
+ <command id='enable'>
+ <params>
+ <param name='enable' doc='Enable the reporter' />
+ </params>
+ </command>
+ <command id='disable'>
+ <params>
+ <param name='disable' doc='Disable the reporter' />
+ </params>
+ </command>
+ </node>
+ <node id='config-line'>
+ <name>config-line</name>
+ <command id='login'>
+ <params>
+ <param name='login' doc='Enable password checking' />
+ </params>
+ </command>
+ <command id='no login'>
+ <params>
+ <param name='no' doc='Negate a command or set its defaults' />
+ <param name='login' doc='Enable password checking' />
+ </params>
+ </command>
+ <command id='bind A.B.C.D [&lt;0-65535&gt;]'>
+ <params>
+ <param name='bind' doc='Accept VTY telnet connections on local interface' />
+ <param name='A.B.C.D' doc='Local interface IP address (default: 127.0.0.1)' />
+ <param name='[&lt;0-65535&gt;]' doc='Local TCP port number' />
+ </params>
+ </command>
+ </node>
+ <node id='config-ns'>
+ <name>config-ns</name>
+ <command id='nse &lt;0-65535&gt; nsvci &lt;0-65534&gt;'>
+ <params>
+ <param name='nse' doc='Persistent NS Entity' />
+ <param name='&lt;0-65535&gt;' doc='NS Entity ID (NSEI)' />
+ <param name='nsvci' doc='NS Virtual Connection' />
+ <param name='&lt;0-65534&gt;' doc='NS Virtual Connection ID (NSVCI)' />
+ </params>
+ </command>
+ <command id='nse &lt;0-65535&gt; remote-ip A.B.C.D'>
+ <params>
+ <param name='nse' doc='Persistent NS Entity' />
+ <param name='&lt;0-65535&gt;' doc='NS Entity ID (NSEI)' />
+ <param name='remote-ip' doc='Remote IP Address' />
+ <param name='A.B.C.D' doc='Remote IP Address' />
+ </params>
+ </command>
+ <command id='nse &lt;0-65535&gt; remote-port &lt;0-65535&gt;'>
+ <params>
+ <param name='nse' doc='Persistent NS Entity' />
+ <param name='&lt;0-65535&gt;' doc='NS Entity ID (NSEI)' />
+ <param name='remote-port' doc='Remote UDP Port' />
+ <param name='&lt;0-65535&gt;' doc='Remote UDP Port Number' />
+ </params>
+ </command>
+ <command id='nse &lt;0-65535&gt; fr-dlci &lt;16-1007&gt;'>
+ <params>
+ <param name='nse' doc='Persistent NS Entity' />
+ <param name='&lt;0-65535&gt;' doc='NS Entity ID (NSEI)' />
+ <param name='fr-dlci' doc='Frame Relay DLCI' />
+ <param name='&lt;16-1007&gt;' doc='Frame Relay DLCI Number' />
+ </params>
+ </command>
+ <command id='nse &lt;0-65535&gt; encapsulation (udp|framerelay-gre)'>
+ <params>
+ <param name='nse' doc='Persistent NS Entity' />
+ <param name='&lt;0-65535&gt;' doc='NS Entity ID (NSEI)' />
+ <param name='encapsulation' doc='Encapsulation for NS' />
+ <param name='udp' doc='UDP/IP Encapsulation' />
+ <param name='framerelay-gre' doc='Frame-Relay/GRE/IP Encapsulation' />
+ </params>
+ </command>
+ <command id='nse &lt;0-65535&gt; remote-role (sgsn|bss)'>
+ <params>
+ <param name='nse' doc='Persistent NS Entity' />
+ <param name='&lt;0-65535&gt;' doc='NS Entity ID (NSEI)' />
+ <param name='remote-role' doc='Remote NSE Role' />
+ <param name='sgsn' doc='Remote Peer is SGSN' />
+ <param name='bss' doc='Remote Peer is BSS' />
+ </params>
+ </command>
+ <command id='no nse &lt;0-65535&gt;'>
+ <params>
+ <param name='no' doc='Delete Persistent NS Entity' />
+ <param name='nse' doc='Delete Persistent NS Entity' />
+ <param name='&lt;0-65535&gt;' doc='NS Entity ID (NSEI)' />
+ </params>
+ </command>
+ <command id='timer (tns-block|tns-block-retries|tns-reset|tns-reset-retries|tns-test|tns-alive|tns-alive-retries|tsns-prov) &lt;0-65535&gt;'>
+ <params>
+ <param name='timer' doc='Network Service Timer' />
+ <param name='tns-block' doc='(un)blocking Timer (Tns-block) timeout' />
+ <param name='tns-block-retries' doc='(un)blocking Timer (Tns-block) number of retries' />
+ <param name='tns-reset' doc='Reset Timer (Tns-reset) timeout' />
+ <param name='tns-reset-retries' doc='Reset Timer (Tns-reset) number of retries' />
+ <param name='tns-test' doc='Test Timer (Tns-test) timeout' />
+ <param name='tns-alive' doc='Alive Timer (Tns-alive) timeout' />
+ <param name='tns-alive-retries' doc='Alive Timer (Tns-alive) number of retries' />
+ <param name='tsns-prov' doc='SNS Provision Timer (Tsns-prov) timeout' />
+ <param name='&lt;0-65535&gt;' doc='Timer Value' />
+ </params>
+ </command>
+ <command id='encapsulation udp local-ip A.B.C.D'>
+ <params>
+ <param name='encapsulation' doc='NS encapsulation options' />
+ <param name='udp' doc='NS over UDP Encapsulation' />
+ <param name='local-ip' doc='Set the IP address on which we listen for NS/UDP' />
+ <param name='A.B.C.D' doc='IP Address' />
+ </params>
+ </command>
+ <command id='encapsulation udp local-port &lt;0-65535&gt;'>
+ <params>
+ <param name='encapsulation' doc='NS encapsulation options' />
+ <param name='udp' doc='NS over UDP Encapsulation' />
+ <param name='local-port' doc='Set the UDP port on which we listen for NS/UDP' />
+ <param name='&lt;0-65535&gt;' doc='UDP port number' />
+ </params>
+ </command>
+ <command id='encapsulation udp dscp &lt;0-255&gt;'>
+ <params>
+ <param name='encapsulation' doc='NS encapsulation options' />
+ <param name='udp' doc='NS over UDP Encapsulation' />
+ <param name='dscp' doc='Set DSCP/TOS on the UDP socket' />
+ <param name='&lt;0-255&gt;' doc='DSCP Value' />
+ </params>
+ </command>
+ <command id='encapsulation framerelay-gre enabled (1|0)'>
+ <params>
+ <param name='encapsulation' doc='NS encapsulation options' />
+ <param name='framerelay-gre' doc='NS over Frame Relay over GRE Encapsulation' />
+ <param name='enabled' doc='Enable or disable Frame Relay over GRE' />
+ <param name='1' doc='Enable' />
+ <param name='0' doc='Disable' />
+ </params>
+ </command>
+ <command id='encapsulation framerelay-gre local-ip A.B.C.D'>
+ <params>
+ <param name='encapsulation' doc='NS encapsulation options' />
+ <param name='framerelay-gre' doc='NS over Frame Relay over GRE Encapsulation' />
+ <param name='local-ip' doc='Set the IP address on which we listen for NS/FR/GRE' />
+ <param name='A.B.C.D' doc='IP Address' />
+ </params>
+ </command>
+ </node>
+ <node id='config-bssgp'>
+ <name>config-bssgp</name>
+ </node>
+ <node id='config-ctrl'>
+ <name>config-ctrl</name>
+ <command id='bind A.B.C.D'>
+ <params>
+ <param name='bind' doc='Set bind address to listen for Control connections' />
+ <param name='A.B.C.D' doc='Local IP address (default 127.0.0.1)' />
+ </params>
+ </command>
+ </node>
+ <node id='config-cs7'>
+ <name>config-cs7</name>
+ <command id='description .TEXT'>
+ <params>
+ <param name='description' doc='Save human-readable description of the object' />
+ <param name='.TEXT' doc='Text until the end of the line' />
+ </params>
+ </command>
+ <command id='network-indicator (international | national | reserved | spare)'>
+ <params>
+ <param name='network-indicator' doc='Configure the Network Indicator' />
+ <param name='international' doc='International Network' />
+ <param name='national' doc='National Network' />
+ <param name='reserved' doc='Reserved Network' />
+ <param name='spare' doc='Spare Network' />
+ </params>
+ </command>
+ <command id='point-code POINT_CODE'>
+ <params>
+ <param name='point-code' doc='Configure the local Point Code' />
+ <param name='POINT_CODE' doc='Point Code' />
+ </params>
+ </command>
+ <command id='point-code format &lt;1-24&gt; [&lt;1-23&gt;] [&lt;1-22&gt;]'>
+ <params>
+ <param name='point-code' doc='Point Code' />
+ <param name='format' doc='Configure Point Code Format' />
+ <param name='&lt;1-24&gt;' doc='Length of first PC component' />
+ <param name='[&lt;1-23&gt;]' doc='Length of second PC component' />
+ <param name='[&lt;1-22&gt;]' doc='Length of third PC component' />
+ </params>
+ </command>
+ <command id='point-code format default'>
+ <params>
+ <param name='point-code' doc='Point Code' />
+ <param name='format' doc='Configure Point Code Format' />
+ <param name='default' doc='Default Point Code Format (3.8.3)' />
+ </params>
+ </command>
+ <command id='point-code delimiter (default|dash)'>
+ <params>
+ <param name='point-code' doc='Point Code' />
+ <param name='delimiter' doc='Configure Point Code Delimiter' />
+ <param name='default' doc='Use dot as delimiter' />
+ <param name='dash' doc='User dash as delimiter' />
+ </params>
+ </command>
+ <command id='xua rkm routing-key-allocation (static-only|dynamic-permitted)'>
+ <params>
+ <param name='xua' doc='SIGTRAN xxxUA related' />
+ <param name='rkm' doc='Routing Key Management' />
+ <param name='routing-key-allocation' doc='Routing Key Management Allocation Policy' />
+ <param name='static-only' doc='Only static (pre-confgured) Routing Keys permitted' />
+ <param name='dynamic-permitted' doc='Dynamically allocate Routing Keys for what ASPs request' />
+ </params>
+ </command>
+ <command id='asp NAME &lt;0-65535&gt; &lt;0-65535&gt; (sua|m3ua|ipa)'>
+ <params>
+ <param name='asp' doc='Configure Application Server Process' />
+ <param name='NAME' doc='Name of ASP' />
+ <param name='&lt;0-65535&gt;' doc='Remote SCTP port number' />
+ <param name='&lt;0-65535&gt;' doc='Local SCTP port number' />
+ <param name='sua' doc='SCCP User Adaptation' />
+ <param name='m3ua' doc='MTP3 User Adaptation' />
+ <param name='ipa' doc='IPA Multiplex (SCCP Lite)' />
+ </params>
+ </command>
+ <command id='no asp NAME'>
+ <params>
+ <param name='no' doc='Negate a command or set its defaults' />
+ <param name='asp' doc='Disable Application Server Process' />
+ <param name='NAME' doc='Name of ASP' />
+ </params>
+ </command>
+ <command id='as NAME (sua|m3ua|ipa)'>
+ <params>
+ <param name='as' doc='Configure an Application Server' />
+ <param name='NAME' doc='Name of the Application Server' />
+ <param name='sua' doc='SCCP User Adaptation' />
+ <param name='m3ua' doc='MTP3 User Adaptation' />
+ <param name='ipa' doc='IPA Multiplex (SCCP Lite)' />
+ </params>
+ </command>
+ <command id='no as NAME'>
+ <params>
+ <param name='no' doc='Negate a command or set its defaults' />
+ <param name='as' doc='Disable Application Server' />
+ <param name='NAME' doc='Name of AS' />
+ </params>
+ </command>
+ <command id='sccp-address NAME'>
+ <params>
+ <param name='sccp-address' doc='Create/Modify an SCCP addressbook entry' />
+ <param name='NAME' doc='Name of the SCCP Address' />
+ </params>
+ </command>
+ <command id='no sccp-address NAME'>
+ <params>
+ <param name='no' doc='Negate a command or set its defaults' />
+ <param name='sccp-address' doc='Delete an SCCP addressbook entry' />
+ <param name='NAME' doc='Name of the SCCP Address' />
+ </params>
+ </command>
+ <command id='sccp-timer (conn_est|ias|iar|rel|repeat_rel|int|guard|reset|reassembly) &lt;1-999999&gt;'>
+ <params>
+ <param name='sccp-timer' doc='Configure SCCP timer values, see ITU-T Q.714' />
+ <param name='conn_est' doc='Waiting for connection confirm message, 1 to 2 minutes (default: 60)' />
+ <param name='ias' doc='Send keep-alive: on an idle connection, delay before sending an Idle Timer message, 5 to 10 minutes (default: 420)' />
+ <param name='iar' doc='Receive keep-alive: on an idle connection, delay until considering a connection as stale, 11 to 21 minutes (default: 900)' />
+ <param name='rel' doc='Waiting for release complete message, 10 to 20 seconds (default: 10)' />
+ <param name='repeat_rel' doc='Waiting for release complete message; or to repeat sending released message after the initial expiry, 10 to 20 seconds (default: 10)' />
+ <param name='int' doc='Waiting for release complete message; or to release connection resources, freeze the LRN and alert a maintenance function after the initial expiry, extending to 1 minute (default: 60)' />
+ <param name='guard' doc='Waiting to resume normal procedure for temporary connection sections during the restart procedure, 23 to 25 minutes (default: 1380)' />
+ <param name='reset' doc='Waiting to release temporary connection section or alert maintenance function after reset request message is sent, 10 to 20 seconds (default: 10)' />
+ <param name='reassembly' doc='Waiting to receive all the segments of the remaining segments, single segmented message after receiving the first segment, 10 to 20 seconds (default: 10)' />
+ <param name='&lt;1-999999&gt;' doc='Timer value, in seconds' />
+ </params>
+ </command>
+ </node>
+ <node id='config-cs7-as'>
+ <name>config-cs7-as</name>
+ <command id='description .TEXT'>
+ <params>
+ <param name='description' doc='Save human-readable description of the object' />
+ <param name='.TEXT' doc='Text until the end of the line' />
+ </params>
+ </command>
+ <command id='asp NAME'>
+ <params>
+ <param name='asp' doc='Specify that a given ASP is part of this AS' />
+ <param name='NAME' doc='Name of ASP to be added to AS' />
+ </params>
+ </command>
+ <command id='no asp NAME'>
+ <params>
+ <param name='no' doc='Negate a command or set its defaults' />
+ <param name='asp' doc='Specify ASP to be removed from this AS' />
+ <param name='NAME' doc='Name of ASP to be removed' />
+ </params>
+ </command>
+ <command id='traffic-mode (broadcast | loadshare | roundrobin | override)'>
+ <params>
+ <param name='traffic-mode' doc='Specifies traffic mode of operation of the ASP within the AS' />
+ <param name='broadcast' doc='Broadcast to all ASP within AS' />
+ <param name='loadshare' doc='Share Load among all ASP within AS' />
+ <param name='roundrobin' doc='Round-Robin between all ASP within AS' />
+ <param name='override' doc='Override' />
+ </params>
+ </command>
+ <command id='recovery-timeout &lt;1-2000&gt;'>
+ <params>
+ <param name='recovery-timeout' doc='Specifies the recovery timeout value in milliseconds' />
+ <param name='&lt;1-2000&gt;' doc='Recovery Timeout in Milliseconds' />
+ </params>
+ </command>
+ <command id='qos-class &lt;0-255&gt;'>
+ <params>
+ <param name='qos-class' doc='Specity QoS Class of AS' />
+ <param name='&lt;0-255&gt;' doc='QoS Class of AS' />
+ </params>
+ </command>
+ <command id='routing-key RCONTEXT DPC'>
+ <params>
+ <param name='routing-key' doc='Define a routing key' />
+ <param name='RCONTEXT' doc='Routing context number' />
+ <param name='DPC' doc='Destination Point Code' />
+ </params>
+ </command>
+ <command id='routing-key RCONTEXT DPC si (aal2|bicc|b-isup|h248|isup|sat-isup|sccp|tup)'>
+ <params>
+ <param name='routing-key' doc='Define a routing key' />
+ <param name='RCONTEXT' doc='Routing context number' />
+ <param name='DPC' doc='Destination Point Code' />
+ <param name='si' doc='Match on Service Indicator' />
+ <param name='aal2' doc='ATM Adaption Layer 2' />
+ <param name='bicc' doc='Bearer Independent Call Control' />
+ <param name='b-isup' doc='Broadband ISDN User Part' />
+ <param name='h248' doc='H.248' />
+ <param name='isup' doc='ISDN User Part' />
+ <param name='sat-isup' doc='Sattelite ISDN User Part' />
+ <param name='sccp' doc='Signalling Connection Control Part' />
+ <param name='tup' doc='Telephony User Part' />
+ </params>
+ </command>
+ <command id='routing-key RCONTEXT DPC ssn SSN'>
+ <params>
+ <param name='routing-key' doc='Define a routing key' />
+ <param name='RCONTEXT' doc='Routing context number' />
+ <param name='DPC' doc='Destination Point Code' />
+ <param name='ssn' doc='Match on Sub-System Number' />
+ <param name='SSN' doc='Sub-System Number to match on' />
+ </params>
+ </command>
+ <command id='routing-key RCONTEXT DPC si (aal2|bicc|b-isup|h248|isup|sat-isup|sccp|tup) ssn SSN'>
+ <params>
+ <param name='routing-key' doc='Define a routing key' />
+ <param name='RCONTEXT' doc='Routing context number' />
+ <param name='DPC' doc='Destination Point Code' />
+ <param name='si' doc='Match on Service Indicator' />
+ <param name='aal2' doc='ATM Adaption Layer 2' />
+ <param name='bicc' doc='Bearer Independent Call Control' />
+ <param name='b-isup' doc='Broadband ISDN User Part' />
+ <param name='h248' doc='H.248' />
+ <param name='isup' doc='ISDN User Part' />
+ <param name='sat-isup' doc='Sattelite ISDN User Part' />
+ <param name='sccp' doc='Signalling Connection Control Part' />
+ <param name='tup' doc='Telephony User Part' />
+ <param name='ssn' doc='Match on Sub-System Number' />
+ <param name='SSN' doc='Sub-System Number to match on' />
+ </params>
+ </command>
+ <command id='point-code override dpc PC'>
+ <params>
+ <param name='point-code' doc='Point Code Specific Features' />
+ <param name='override' doc='Override (force) a point-code to hard-coded value' />
+ <param name='dpc' doc='Override Source Point Code' />
+ <param name='PC' doc='Override Destination Point Code' />
+ </params>
+ </command>
+ </node>
+ <node id='config-cs7-asp'>
+ <name>config-cs7-asp</name>
+ <command id='description .TEXT'>
+ <params>
+ <param name='description' doc='Save human-readable description of the object' />
+ <param name='.TEXT' doc='Text until the end of the line' />
+ </params>
+ </command>
+ <command id='remote-ip A.B.C.D'>
+ <params>
+ <param name='remote-ip' doc='Specify Remote IP Address of ASP' />
+ <param name='A.B.C.D' doc='Remote IP Address of ASP' />
+ </params>
+ </command>
+ <command id='local-ip A.B.C.D'>
+ <params>
+ <param name='local-ip' doc='Specify Local IP Address from which to contact ASP' />
+ <param name='A.B.C.D' doc='Local IP Address from which to contact of ASP' />
+ </params>
+ </command>
+ <command id='qos-class &lt;0-255&gt;'>
+ <params>
+ <param name='qos-class' doc='Specify QoS Class of ASP' />
+ <param name='&lt;0-255&gt;' doc='QoS Class of ASP' />
+ </params>
+ </command>
+ <command id='block'>
+ <params>
+ <param name='block' doc='Allows a SCTP Association with ASP, but doesn&apos;t let it become active' />
+ </params>
+ </command>
+ <command id='shutdown'>
+ <params>
+ <param name='shutdown' doc='Terminates SCTP association; New associations will be rejected' />
+ </params>
+ </command>
+ </node>
+ <node id='config-cs7-sccpaddr'>
+ <name>config-cs7-sccpaddr</name>
+ <command id='no point-code'>
+ <params>
+ <param name='no' doc='Negate a command or set its defaults' />
+ <param name='point-code' doc='Remove point-code Number' />
+ </params>
+ </command>
+ <command id='no subsystem-number'>
+ <params>
+ <param name='no' doc='Negate a command or set its defaults' />
+ <param name='subsystem-number' doc='Remove Subsystem Number' />
+ </params>
+ </command>
+ <command id='no global-title'>
+ <params>
+ <param name='no' doc='Negate a command or set its defaults' />
+ <param name='global-title' doc='Remove Global Title' />
+ </params>
+ </command>
+ <command id='routing-indicator (GT|PC|IP)'>
+ <params>
+ <param name='routing-indicator' doc='Add Routing Indicator' />
+ <param name='GT' doc='by global-title' />
+ <param name='PC' doc='by point-code' />
+ <param name='IP' doc='by ip-address' />
+ </params>
+ </command>
+ <command id='point-code POINT_CODE'>
+ <params>
+ <param name='point-code' doc='Add point-code Number' />
+ <param name='POINT_CODE' doc='PC' />
+ </params>
+ </command>
+ <command id='subsystem-number &lt;0-4294967295&gt;'>
+ <params>
+ <param name='subsystem-number' doc='Add Subsystem Number' />
+ <param name='&lt;0-4294967295&gt;' doc='SSN' />
+ </params>
+ </command>
+ <command id='global-title'>
+ <params>
+ <param name='global-title' doc='Add/Modify Global Title' />
+ </params>
+ </command>
+ </node>
+ <node id='config-cs7-sccpaddr-gt'>
+ <name>config-cs7-sccpaddr-gt</name>
+ <command id='global-title-indicator &lt;0-15&gt;'>
+ <params>
+ <param name='global-title-indicator' doc='Set Global Title Indicator' />
+ <param name='&lt;0-15&gt;' doc='GTI' />
+ </params>
+ </command>
+ <command id='translation-type &lt;0-255&gt;'>
+ <params>
+ <param name='translation-type' doc='Set Global Title Translation Type' />
+ <param name='&lt;0-255&gt;' doc='TT' />
+ </params>
+ </command>
+ <command id='numbering-plan-indicator &lt;0-15&gt;'>
+ <params>
+ <param name='numbering-plan-indicator' doc='Set Global Title Numbering Plan Indicator' />
+ <param name='&lt;0-15&gt;' doc='NPI' />
+ </params>
+ </command>
+ <command id='nature-of-address-indicator &lt;0-127&gt;'>
+ <params>
+ <param name='nature-of-address-indicator' doc='Set Global Title Nature of Address Indicator' />
+ <param name='&lt;0-127&gt;' doc='NAI' />
+ </params>
+ </command>
+ <command id='digits DIGITS'>
+ <params>
+ <param name='digits' doc='Set Global Title Digits' />
+ <param name='DIGITS' doc='Number digits' />
+ </params>
+ </command>
+ </node>
+ <node id='config-sgsn'>
+ <name>config-sgsn</name>
+ <command id='gtp local-ip A.B.C.D'>
+ <params>
+ <param name='gtp' doc='GTP Parameters' />
+ <param name='local-ip' doc='Set the IP address for the local GTP bind for the Gp interface (towards the GGSNs). Note: in case you would like to run the GGSN on the same machine as the SGSN, you can not run both on the same IP address, since both sides are specified to use the same GTP port numbers (2123 and 2152). For example, you could use 127.0.0.1 for the SGSN and 127.0.0.2 for the GGSN in such situations.' />
+ <param name='A.B.C.D' doc='IPv4 Address' />
+ </params>
+ </command>
+ <command id='ggsn &lt;0-255&gt; remote-ip A.B.C.D'>
+ <params>
+ <param name='ggsn' doc='Configure the GGSN information' />
+ <param name='&lt;0-255&gt;' doc='GGSN Number' />
+ <param name='remote-ip' doc='Configure this static GGSN to use the specified remote IP address.' />
+ <param name='A.B.C.D' doc='IPv4 Address' />
+ </params>
+ </command>
+ <command id='ggsn &lt;0-255&gt; gtp-version (0|1)'>
+ <params>
+ <param name='ggsn' doc='Configure the GGSN information' />
+ <param name='&lt;0-255&gt;' doc='GGSN Number' />
+ <param name='gtp-version' doc='GTP Version' />
+ <param name='0' doc='Version 0' />
+ <param name='1' doc='Version 1' />
+ </params>
+ </command>
+ <command id='ggsn &lt;0-255&gt; echo-interval &lt;1-36000&gt;'>
+ <params>
+ <param name='ggsn' doc='Configure the GGSN information' />
+ <param name='&lt;0-255&gt;' doc='GGSN Number' />
+ <param name='echo-interval' doc='Send an echo request to this static GGSN every interval.' />
+ <param name='&lt;1-36000&gt;' doc='Interval between echo requests in seconds.' />
+ </params>
+ </command>
+ <command id='ggsn &lt;0-255&gt; no echo-interval'>
+ <params>
+ <param name='ggsn' doc='Configure the GGSN information' />
+ <param name='&lt;0-255&gt;' doc='GGSN Number' />
+ <param name='no' doc='Negate a command or set its defaults' />
+ <param name='echo-interval' doc='Send an echo request to this static GGSN every interval.' />
+ </params>
+ </command>
+ <command id='imsi-acl (add|del) IMSI'>
+ <params>
+ <param name='imsi-acl' doc='Access Control List of foreign IMSIs' />
+ <param name='add' doc='Add IMSI to ACL' />
+ <param name='del' doc='Remove IMSI from ACL' />
+ <param name='IMSI' doc='IMSI of subscriber' />
+ </params>
+ </command>
+ <command id='auth-policy (accept-all|closed|acl-only|remote)'>
+ <params>
+ <param name='auth-policy' doc='Configure the Authorization policy of the SGSN. This setting determines which subscribers are permitted to register to the network.' />
+ <param name='accept-all' doc='Accept all IMSIs (DANGEROUS)' />
+ <param name='closed' doc='Accept only home network subscribers or those in the ACL' />
+ <param name='acl-only' doc='Accept only subscribers in the ACL' />
+ <param name='remote' doc='Use remote subscription data only (HLR)' />
+ </params>
+ </command>
+ <command id='authentication (optional|required)'>
+ <params>
+ <param name='authentication' doc='Whether to enforce MS authentication in GERAN (only with auth-policy remote)' />
+ <param name='optional' doc='Allow MS to attach via GERAN without authentication (default and only possible value for non-remote auth-policy)' />
+ <param name='required' doc='Always require authentication (only available for auth-policy remote, default with that auth-policy)' />
+ </params>
+ </command>
+ <command id='encryption (GEA0|GEA1|GEA2|GEA3|GEA4)'>
+ <params>
+ <param name='encryption' doc='Set encryption algorithm for SGSN' />
+ <param name='GEA0' doc='Use GEA0 (no encryption)' />
+ <param name='GEA1' doc='Use GEA1' />
+ <param name='GEA2' doc='Use GEA2' />
+ <param name='GEA3' doc='Use GEA3' />
+ <param name='GEA4' doc='Use GEA4' />
+ </params>
+ </command>
+ <command id='gsup ipa-name NAME'>
+ <params>
+ <param name='gsup' doc='GSUP Parameters' />
+ <param name='ipa-name' doc='Set the IPA name of this SGSN' />
+ <param name='NAME' doc='A unique name for this SGSN. For example: PLMN + redundancy server number: SGSN-901-70-0. This name is used for GSUP routing and must be set if more than one SGSN is connected to the network. The default is &apos;SGSN-00-00-00-00-00-00&apos;.' />
+ </params>
+ </command>
+ <command id='gsup remote-ip A.B.C.D'>
+ <params>
+ <param name='gsup' doc='GSUP Parameters' />
+ <param name='remote-ip' doc='Set the IP address of the remote GSUP server (e.g. OsmoHLR). This setting only applies if &apos;auth-policy remote&apos; is used.' />
+ <param name='A.B.C.D' doc='IPv4 Address' />
+ </params>
+ </command>
+ <command id='gsup remote-port &lt;0-65535&gt;'>
+ <params>
+ <param name='gsup' doc='GSUP Parameters' />
+ <param name='remote-port' doc='Set the TCP port of the remote GSUP server, see also &apos;gsup remote-ip&apos;' />
+ <param name='&lt;0-65535&gt;' doc='Remote TCP port' />
+ </params>
+ </command>
+ <command id='gsup oap-id &lt;0-65535&gt;'>
+ <params>
+ <param name='gsup' doc='GSUP Parameters' />
+ <param name='oap-id' doc='Set the OAP client ID for authentication on the GSUP protocol. This setting only applies if &apos;auth-policy remote&apos; is used.' />
+ <param name='&lt;0-65535&gt;' doc='OAP client ID (0 == disabled)' />
+ </params>
+ </command>
+ <command id='gsup oap-k K'>
+ <params>
+ <param name='gsup' doc='GSUP Parameters' />
+ <param name='oap-k' doc='Set the OAP shared secret key K for authentication on the GSUP protocol. This setting only applies if auth-policy remote is used.' />
+ <param name='K' doc='K value (16 byte) hex' />
+ </params>
+ </command>
+ <command id='gsup oap-opc OPC'>
+ <params>
+ <param name='gsup' doc='GSUP Parameters' />
+ <param name='oap-opc' doc='Set the OAP shared secret OPC for authentication on the GSUP protocol. This setting only applies if auth-policy remote is used.' />
+ <param name='OPC' doc='OPC value (16 byte) hex' />
+ </params>
+ </command>
+ <command id='apn APNAME ggsn &lt;0-255&gt;'>
+ <params>
+ <param name='apn' doc='Configure the information per APN' />
+ <param name='APNAME' doc='The APN gateway name optionally prefixed by &apos;*&apos; (wildcard)' />
+ <param name='ggsn' doc='Select the GGSN to use for the given APN gateway prefix' />
+ <param name='&lt;0-255&gt;' doc='The GGSN id' />
+ </params>
+ </command>
+ <command id='apn APNAME imsi-prefix IMSIPRE ggsn &lt;0-255&gt;'>
+ <params>
+ <param name='apn' doc='Configure the information per APN' />
+ <param name='APNAME' doc='The APN gateway name optionally prefixed by &apos;*&apos; (wildcard)' />
+ <param name='imsi-prefix' doc='Select the GGSN to use for the given APN gateway prefix if and only if the IMSI matches the given prefix.' />
+ <param name='IMSIPRE' doc='An IMSI prefix' />
+ <param name='ggsn' doc='Select the GGSN to use when APN gateway and IMSI prefix match' />
+ <param name='&lt;0-255&gt;' doc='The GGSN id' />
+ </params>
+ </command>
+ <command id='access-point-name NAME'>
+ <params>
+ <param name='access-point-name' doc='Globally allow the given APN name for all subscribers.' />
+ <param name='NAME' doc='Add this NAME to the list' />
+ </params>
+ </command>
+ <command id='no access-point-name NAME'>
+ <params>
+ <param name='no' doc='Negate a command or set its defaults' />
+ <param name='access-point-name' doc='Configure a global list of allowed APNs' />
+ <param name='NAME' doc='Remove entry with NAME' />
+ </params>
+ </command>
+ <command id='cdr filename NAME'>
+ <params>
+ <param name='cdr' doc='CDR' />
+ <param name='filename' doc='Set the file name for the call-data-record file, logging the data usage of each subscriber.' />
+ <param name='NAME' doc='filename' />
+ </params>
+ </command>
+ <command id='no cdr filename'>
+ <params>
+ <param name='no' doc='Negate a command or set its defaults' />
+ <param name='cdr' doc='CDR' />
+ <param name='filename' doc='Disable saving CDR to file' />
+ </params>
+ </command>
+ <command id='cdr trap'>
+ <params>
+ <param name='cdr' doc='CDR' />
+ <param name='trap' doc='Enable sending CDR via TRAP CTRL messages' />
+ </params>
+ </command>
+ <command id='no cdr trap'>
+ <params>
+ <param name='no' doc='Negate a command or set its defaults' />
+ <param name='cdr' doc='CDR' />
+ <param name='trap' doc='Disable sending CDR via TRAP CTRL messages' />
+ </params>
+ </command>
+ <command id='cdr interval &lt;1-2147483647&gt;'>
+ <params>
+ <param name='cdr' doc='CDR' />
+ <param name='interval' doc='Set the interval for the call-data-record file' />
+ <param name='&lt;1-2147483647&gt;' doc='interval in seconds' />
+ </params>
+ </command>
+ <command id='ggsn dynamic'>
+ <params>
+ <param name='ggsn' doc='Configure the GGSN information' />
+ <param name='dynamic' doc='Enable dynamic resolving of GGSNs based on DNS resolving the APN name like in a GRX-style setup. Changing this setting requires a restart.' />
+ </params>
+ </command>
+ <command id='grx-dns-add A.B.C.D'>
+ <params>
+ <param name='grx-dns-add' doc='Use the specified IP address for DNS-resolving the AP names to GGSN IP addresses' />
+ <param name='A.B.C.D' doc='IPv4 address' />
+ </params>
+ </command>
+ <command id='timer t3312 &lt;0-65535&gt;'>
+ <params>
+ <param name='timer' doc='Configure GPRS Timers' />
+ <param name='t3312' doc='Periodic RA Update timer (s)' />
+ <param name='&lt;0-65535&gt;' doc='Timer Value in seconds' />
+ </params>
+ </command>
+ <command id='timer t3322 &lt;0-65535&gt;'>
+ <params>
+ <param name='timer' doc='Configure GPRS Timers' />
+ <param name='t3322' doc='Detach request -&gt; accept timer (s)' />
+ <param name='&lt;0-65535&gt;' doc='Timer Value in seconds' />
+ </params>
+ </command>
+ <command id='timer t3350 &lt;0-65535&gt;'>
+ <params>
+ <param name='timer' doc='Configure GPRS Timers' />
+ <param name='t3350' doc='Waiting for ATT/RAU/TMSI_COMPL timer (s)' />
+ <param name='&lt;0-65535&gt;' doc='Timer Value in seconds' />
+ </params>
+ </command>
+ <command id='timer t3360 &lt;0-65535&gt;'>
+ <params>
+ <param name='timer' doc='Configure GPRS Timers' />
+ <param name='t3360' doc='Waiting for AUTH/CIPH response timer (s)' />
+ <param name='&lt;0-65535&gt;' doc='Timer Value in seconds' />
+ </params>
+ </command>
+ <command id='timer t3370 &lt;0-65535&gt;'>
+ <params>
+ <param name='timer' doc='Configure GPRS Timers' />
+ <param name='t3370' doc='Waiting for IDENTITY response timer (s)' />
+ <param name='&lt;0-65535&gt;' doc='Timer Value in seconds' />
+ </params>
+ </command>
+ <command id='timer t3313 &lt;0-65535&gt;'>
+ <params>
+ <param name='timer' doc='Configure GPRS Timers' />
+ <param name='t3313' doc='Waiting for paging response timer (s)' />
+ <param name='&lt;0-65535&gt;' doc='Timer Value in seconds' />
+ </params>
+ </command>
+ <command id='timer t3314 &lt;0-65535&gt;'>
+ <params>
+ <param name='timer' doc='Configure GPRS Timers' />
+ <param name='t3314' doc='Force to STANDBY on expiry timer (s)' />
+ <param name='&lt;0-65535&gt;' doc='Timer Value in seconds' />
+ </params>
+ </command>
+ <command id='timer t3316 &lt;0-65535&gt;'>
+ <params>
+ <param name='timer' doc='Configure GPRS Timers' />
+ <param name='t3316' doc='AA-Ready timer (s)' />
+ <param name='&lt;0-65535&gt;' doc='Timer Value in seconds' />
+ </params>
+ </command>
+ <command id='timer t3385 &lt;0-65535&gt;'>
+ <params>
+ <param name='timer' doc='Configure GPRS Timers' />
+ <param name='t3385' doc='Wait for ACT PDP CTX REQ timer (s)' />
+ <param name='&lt;0-65535&gt;' doc='Timer Value in seconds' />
+ </params>
+ </command>
+ <command id='timer t3386 &lt;0-65535&gt;'>
+ <params>
+ <param name='timer' doc='Configure GPRS Timers' />
+ <param name='t3386' doc='Wait for MODIFY PDP CTX ACK timer (s)' />
+ <param name='&lt;0-65535&gt;' doc='Timer Value in seconds' />
+ </params>
+ </command>
+ <command id='timer t3395 &lt;0-65535&gt;'>
+ <params>
+ <param name='timer' doc='Configure GPRS Timers' />
+ <param name='t3395' doc='Wait for DEACT PDP CTX ACK timer (s)' />
+ <param name='&lt;0-65535&gt;' doc='Timer Value in seconds' />
+ </params>
+ </command>
+ <command id='timer t3397 &lt;0-65535&gt;'>
+ <params>
+ <param name='timer' doc='Configure GPRS Timers' />
+ <param name='t3397' doc='Wait for DEACT AA PDP CTX ACK timer (s)' />
+ <param name='&lt;0-65535&gt;' doc='Timer Value in seconds' />
+ </params>
+ </command>
+ <command id='no compression rfc1144'>
+ <params>
+ <param name='no' doc='Negate a command or set its defaults' />
+ <param name='compression' doc='Configure compression' />
+ <param name='rfc1144' doc='disable rfc1144 TCP/IP header compression' />
+ </params>
+ </command>
+ <command id='compression rfc1144 active slots &lt;1-256&gt;'>
+ <params>
+ <param name='compression' doc='Configure compression' />
+ <param name='rfc1144' doc='RFC1144 Header compression scheme' />
+ <param name='active' doc='Compression is actively proposed' />
+ <param name='slots' doc='Number of compression state slots' />
+ <param name='&lt;1-256&gt;' doc='Number of compression state slots' />
+ </params>
+ </command>
+ <command id='compression rfc1144 passive'>
+ <params>
+ <param name='compression' doc='Configure compression' />
+ <param name='rfc1144' doc='RFC1144 Header compression scheme' />
+ <param name='passive' doc='Compression is available on request' />
+ </params>
+ </command>
+ <command id='no compression v42bis'>
+ <params>
+ <param name='no' doc='Negate a command or set its defaults' />
+ <param name='compression' doc='Configure compression' />
+ <param name='v42bis' doc='disable V.42bis data compression' />
+ </params>
+ </command>
+ <command id='compression v42bis active direction (ms|sgsn|both) codewords &lt;512-65535&gt; strlen &lt;6-250&gt;'>
+ <params>
+ <param name='compression' doc='Configure compression' />
+ <param name='v42bis' doc='V.42bis data compression scheme' />
+ <param name='active' doc='Compression is actively proposed' />
+ <param name='direction' doc='Direction in which the compression shall be active (p0)' />
+ <param name='ms' doc='Compress ms-&gt;sgsn direction only' />
+ <param name='sgsn' doc='Compress sgsn-&gt;ms direction only' />
+ <param name='both' doc='Both directions' />
+ <param name='codewords' doc='Number of codewords (p1)' />
+ <param name='&lt;512-65535&gt;' doc='Number of codewords' />
+ <param name='strlen' doc='Maximum string length (p2)' />
+ <param name='&lt;6-250&gt;' doc='Maximum string length' />
+ </params>
+ </command>
+ <command id='compression v42bis passive'>
+ <params>
+ <param name='compression' doc='Configure compression' />
+ <param name='v42bis' doc='V.42bis data compression scheme' />
+ <param name='passive' doc='Compression is available on request' />
+ </params>
+ </command>
+ <command id='cs7-instance-iu &lt;0-15&gt;'>
+ <params>
+ <param name='cs7-instance-iu' doc='Set SS7 to be used by the Iu-Interface.' />
+ <param name='&lt;0-15&gt;' doc='SS7 instance reference number (default: 0)' />
+ </params>
+ </command>
+ <command id='iu rab-assign-addr-enc (x213|v4raw)'>
+ <params>
+ <param name='iu' doc='Iu interface protocol options' />
+ <param name='rab-assign-addr-enc' doc='Choose RAB Assignment&apos;s Transport Layer Address encoding' />
+ <param name='x213' doc='ITU-T X.213 compliant address encoding (default)' />
+ <param name='v4raw' doc='32bit length raw IPv4 address (for ip.access nano3G)' />
+ </params>
+ </command>
+ <command id='asn1 debug (1|0)'>
+ <params>
+ <param name='asn1' doc='ASN.1 settings' />
+ <param name='debug' doc='Enable ASN.1 debug messages' />
+ <param name='1' doc='Log ASN.1 debug messages to stderr' />
+ <param name='0' doc='Do not log ASN.1 debug messages to stderr' />
+ </params>
+ </command>
+ <command id='asn1 xer-print (1|0)'>
+ <params>
+ <param name='asn1' doc='ASN.1 settings' />
+ <param name='xer-print' doc='Log human readable representations of all ASN.1 messages to stderr' />
+ <param name='1' doc='Log XML representation of all ASN.1 messages to stderr' />
+ <param name='0' doc='Do not log decoded ASN.1 messages to stderr' />
+ </params>
+ </command>
+ </node>
+</vtydoc>
diff --git a/git-version-gen b/git-version-gen
index 8e59c5afa..42cf3d2bd 100755
--- a/git-version-gen
+++ b/git-version-gen
@@ -92,8 +92,8 @@ fi
if test -n "$v"
then
: # use $v
-elif test -d ./.git \
- && v=`git describe --abbrev=4 --match='v*' HEAD 2>/dev/null \
+elif
+ v=`git describe --abbrev=4 --match='v*' HEAD 2>/dev/null \
|| git describe --abbrev=4 HEAD 2>/dev/null` \
&& case $v in
[0-9]*) ;;
diff --git a/include/Makefile.am b/include/Makefile.am
index 677eec3aa..9d963a024 100644
--- a/include/Makefile.am
+++ b/include/Makefile.am
@@ -1,3 +1,3 @@
SUBDIRS = \
- openbsc \
+ osmocom \
$(NULL)
diff --git a/include/openbsc/gprs_gmm.h b/include/openbsc/gprs_gmm.h
deleted file mode 100644
index c38e49f0d..000000000
--- a/include/openbsc/gprs_gmm.h
+++ /dev/null
@@ -1,35 +0,0 @@
-#ifndef _GPRS_GMM_H
-#define _GPRS_GMM_H
-
-#include <osmocom/core/msgb.h>
-#include <openbsc/gprs_sgsn.h>
-
-#include <stdbool.h>
-
-int gsm48_tx_gsm_deact_pdp_req(struct sgsn_pdp_ctx *pdp, uint8_t sm_cause);
-int gsm48_tx_gsm_act_pdp_rej(struct sgsn_mm_ctx *mm, uint8_t tid,
- uint8_t cause, uint8_t pco_len, uint8_t *pco_v);
-int gsm48_tx_gsm_act_pdp_acc(struct sgsn_pdp_ctx *pdp);
-int gsm48_tx_gsm_deact_pdp_acc(struct sgsn_pdp_ctx *pdp);
-
-int gsm0408_gprs_rcvmsg_gb(struct msgb *msg, struct gprs_llc_llme *llme,
- bool drop_cipherable);
-int gsm0408_gprs_rcvmsg_iu(struct msgb *msg, struct gprs_ra_id *ra_id,
- uint16_t *sai);
-int gsm0408_gprs_force_reattach(struct sgsn_mm_ctx *mmctx);
-int gsm0408_gprs_force_reattach_oldmsg(struct msgb *msg,
- struct gprs_llc_llme *llme);
-void gsm0408_gprs_access_granted(struct sgsn_mm_ctx *mmctx);
-void gsm0408_gprs_access_denied(struct sgsn_mm_ctx *mmctx, int gmm_cause);
-void gsm0408_gprs_access_cancelled(struct sgsn_mm_ctx *mmctx, int gmm_cause);
-void gsm0408_gprs_authenticate(struct sgsn_mm_ctx *mmctx);
-
-int gprs_gmm_rx_suspend(struct gprs_ra_id *raid, uint32_t tlli);
-int gprs_gmm_rx_resume(struct gprs_ra_id *raid, uint32_t tlli,
- uint8_t suspend_ref);
-
-time_t gprs_max_time_to_idle(void);
-
-int iu_rab_act_ps(uint8_t rab_id, struct sgsn_pdp_ctx *pdp);
-
-#endif /* _GPRS_GMM_H */
diff --git a/include/openbsc/gsup_client.h b/include/openbsc/gsup_client.h
deleted file mode 100644
index 4a25490f6..000000000
--- a/include/openbsc/gsup_client.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/* GPRS Subscriber Update Protocol client */
-
-/* (C) 2014 by Sysmocom s.f.m.c. GmbH
- * All Rights Reserved
- *
- * Author: Jacob Erlbeck
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * 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 Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- */
-#pragma once
-
-#include <osmocom/core/timer.h>
-
-#include <openbsc/oap_client.h>
-
-#define GSUP_CLIENT_RECONNECT_INTERVAL 10
-#define GSUP_CLIENT_PING_INTERVAL 20
-
-struct msgb;
-struct ipa_client_conn;
-struct gsup_client;
-
-/* Expects message in msg->l2h */
-typedef int (*gsup_client_read_cb_t)(struct gsup_client *gsupc,
- struct msgb *msg);
-
-struct gsup_client {
- const char *unit_name;
-
- struct ipa_client_conn *link;
- gsup_client_read_cb_t read_cb;
- void *data;
-
- struct oap_client_state oap_state;
-
- struct osmo_timer_list ping_timer;
- struct osmo_timer_list connect_timer;
- int is_connected;
- int got_ipa_pong;
-};
-
-struct gsup_client *gsup_client_create(const char *unit_name,
- const char *ip_addr,
- unsigned int tcp_port,
- gsup_client_read_cb_t read_cb,
- struct oap_client_config *oapc_config);
-
-void gsup_client_destroy(struct gsup_client *gsupc);
-int gsup_client_send(struct gsup_client *gsupc, struct msgb *msg);
-struct msgb *gsup_client_msgb_alloc(void);
-
diff --git a/include/openbsc/oap_client.h b/include/openbsc/oap_client.h
deleted file mode 100644
index 80c86d5d6..000000000
--- a/include/openbsc/oap_client.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/* Osmocom Authentication Protocol API */
-
-/* (C) 2015 by Sysmocom s.f.m.c. GmbH
- * All Rights Reserved
- *
- * Author: Neels Hofmeyr
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * 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 Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#pragma once
-
-#include <stdint.h>
-
-struct msgb;
-struct osmo_oap_message;
-
-/* This is the config part for vty. It is essentially copied in
- * oap_client_state, where values are copied over once the config is
- * considered valid. */
-struct oap_client_config {
- uint16_t client_id;
- int secret_k_present;
- uint8_t secret_k[16];
- int secret_opc_present;
- uint8_t secret_opc[16];
-};
-
-/* The runtime state of the OAP client. client_id and the secrets are in fact
- * duplicated from oap_client_config, so that a separate validation of the
- * config data is possible, and so that only a struct oap_client_state* is
- * passed around. */
-struct oap_client_state {
- enum {
- OAP_UNINITIALIZED = 0, /* just allocated. */
- OAP_DISABLED, /* disabled by config. */
- OAP_INITIALIZED, /* enabled, config is valid. */
- OAP_REQUESTED_CHALLENGE,
- OAP_SENT_CHALLENGE_RESULT,
- OAP_REGISTERED
- } state;
- uint16_t client_id;
- uint8_t secret_k[16];
- uint8_t secret_opc[16];
- int registration_failures;
-};
-
-/* From config, initialize state. Return 0 on success. */
-int oap_client_init(struct oap_client_config *config,
- struct oap_client_state *state);
-
-/* Construct an OAP registration message and return in *msg_tx. Use
- * state->client_id and update state->state.
- * Return 0 on success, or a negative value on error.
- * If an error is returned, *msg_tx is guaranteed to be NULL. */
-int oap_client_register(struct oap_client_state *state, struct msgb **msg_tx);
-
-/* Decode and act on a received OAP message msg_rx. Update state->state. If a
- * non-NULL pointer is returned in *msg_tx, that msgb should be sent to the OAP
- * server (and freed) by the caller. The received msg_rx is not freed.
- * Return 0 on success, or a negative value on error.
- * If an error is returned, *msg_tx is guaranteed to be NULL. */
-int oap_client_handle(struct oap_client_state *state,
- const struct msgb *msg_rx, struct msgb **msg_tx);
-
-/* Allocate a msgb and in it, return the encoded oap_client_msg. Return
- * NULL on error. (Like oap_client_encode(), but also allocates a msgb.)
- * About the name: the idea is do_something(oap_client_encoded(my_struct))
- */
-struct msgb *oap_client_encoded(const struct osmo_oap_message *oap_client_msg);
diff --git a/include/openbsc/rest_octets.h b/include/openbsc/rest_octets.h
deleted file mode 100644
index 49a231296..000000000
--- a/include/openbsc/rest_octets.h
+++ /dev/null
@@ -1,139 +0,0 @@
-#ifndef _REST_OCTETS_H
-#define _REST_OCTETS_H
-
-#include <stdbool.h>
-#include <openbsc/gsm_04_08.h>
-#include <osmocom/gsm/sysinfo.h>
-
-/* generate SI1 rest octets */
-int rest_octets_si1(uint8_t *data, uint8_t *nch_pos, int is1800_net);
-int rest_octets_si2quater(uint8_t *data, struct gsm_bts *bts);
-int rest_octets_si6(uint8_t *data, bool is1800_net);
-
-struct gsm48_si_selection_params {
- uint16_t penalty_time:5,
- temp_offs:3,
- cell_resel_off:6,
- cbq:1,
- present:1;
-};
-
-struct gsm48_si_power_offset {
- uint8_t power_offset:2,
- present:1;
-};
-
-struct gsm48_si3_gprs_ind {
- uint8_t si13_position:1,
- ra_colour:3,
- present:1;
-};
-
-struct gsm48_lsa_params {
- uint32_t prio_thr:3,
- lsa_offset:3,
- mcc:12,
- mnc:12;
- unsigned int present;
-};
-
-struct gsm48_si_ro_info {
- struct gsm48_si_selection_params selection_params;
- struct gsm48_si_power_offset power_offset;
- uint8_t si2ter_indicator;
- uint8_t early_cm_ctrl;
- struct {
- uint8_t where:3,
- present:1;
- } scheduling;
- struct gsm48_si3_gprs_ind gprs_ind;
- /* SI 3 specific */
- uint8_t si2quater_indicator;
- /* SI 4 specific */
- struct gsm48_lsa_params lsa_params;
- uint16_t cell_id;
- uint8_t break_ind; /* do we have SI7 + SI8 ? */
-};
-
-
-/* Generate SI3 Rest Octests (Chapter 10.5.2.34 / Table 10.4.72) */
-int rest_octets_si3(uint8_t *data, const struct gsm48_si_ro_info *si3);
-
-/* Generate SI4 Rest Octets (Chapter 10.5.2.35) */
-int rest_octets_si4(uint8_t *data, const struct gsm48_si_ro_info *si4, int len);
-
-enum pbcch_carrier_type {
- PBCCH_BCCH,
- PBCCH_ARFCN,
- PBCCH_MAIO
-};
-
-/* TS 03.60 Chapter 6.3.3.1: Network Mode of Operation */
-enum gprs_nmo {
- GPRS_NMO_I = 0, /* CS pagin on GPRS paging or traffic channel */
- GPRS_NMO_II = 1, /* all paging on CCCH */
- GPRS_NMO_III = 2, /* no paging coordination */
-};
-
-/* TS 04.60 12.24 */
-struct gprs_cell_options {
- enum gprs_nmo nmo;
- /* T3168: wait for packet uplink assignment message */
- uint32_t t3168; /* in milliseconds */
- /* T3192: wait for release of the TBF after reception of the final block */
- uint32_t t3192; /* in milliseconds */
- uint32_t drx_timer_max;/* in seconds */
- uint32_t bs_cv_max;
- uint8_t supports_egprs_11bit_rach;
- bool ctrl_ack_type_use_block; /* use PACKET CONTROL ACKNOWLEDGMENT */
-
- uint8_t ext_info_present;
- struct {
- uint8_t egprs_supported;
- uint8_t use_egprs_p_ch_req;
- uint8_t bep_period;
- uint8_t pfc_supported;
- uint8_t dtm_supported;
- uint8_t bss_paging_coordination;
- } ext_info;
-};
-
-/* TS 04.60 Table 12.9.2 */
-struct gprs_power_ctrl_pars {
- uint8_t alpha;
- uint8_t t_avg_w;
- uint8_t t_avg_t;
- uint8_t pc_meas_chan;
- uint8_t n_avg_i;
-};
-
-struct gsm48_si13_info {
- struct gprs_cell_options cell_opts;
- struct gprs_power_ctrl_pars pwr_ctrl_pars;
- uint8_t bcch_change_mark;
- uint8_t si_change_field;
- uint8_t pbcch_present;
-
- union {
- struct {
- uint8_t rac;
- uint8_t spgc_ccch_sup;
- uint8_t net_ctrl_ord;
- uint8_t prio_acc_thr;
- } no_pbcch;
- struct {
- uint8_t psi1_rep_per;
- uint8_t pb;
- uint8_t tsc;
- uint8_t tn;
- enum pbcch_carrier_type carrier_type;
- uint16_t arfcn;
- uint8_t maio;
- } pbcch;
- };
-};
-
-/* Generate SI13 Rest Octests (Chapter 10.5.2.37b) */
-int rest_octets_si13(uint8_t *data, const struct gsm48_si13_info *si13);
-
-#endif /* _REST_OCTETS_H */
diff --git a/include/osmocom/Makefile.am b/include/osmocom/Makefile.am
new file mode 100644
index 000000000..09db97a95
--- /dev/null
+++ b/include/osmocom/Makefile.am
@@ -0,0 +1,3 @@
+SUBDIRS = \
+ sgsn \
+ $(NULL)
diff --git a/include/openbsc/Makefile.am b/include/osmocom/sgsn/Makefile.am
index 150212971..3fdb6b348 100644
--- a/include/openbsc/Makefile.am
+++ b/include/osmocom/sgsn/Makefile.am
@@ -3,11 +3,18 @@ noinst_HEADERS = \
crc24.h \
debug.h \
gb_proxy.h \
+ gprs_gb.h \
gprs_gb_parse.h \
gprs_gmm.h \
+ gprs_gmm_fsm.h \
+ gprs_gmm_attach.h \
+ gprs_mm_state_gb_fsm.h \
+ gprs_mm_state_iu_fsm.h \
gprs_llc.h \
gprs_llc_xid.h \
+ gprs_ranap.h \
gprs_sgsn.h \
+ gprs_sm.h \
gprs_sndcp_comp.h \
gprs_sndcp_dcomp.h \
gprs_sndcp.h \
@@ -15,10 +22,7 @@ noinst_HEADERS = \
gprs_sndcp_xid.h \
gprs_subscriber.h \
gprs_utils.h \
- gsup_client.h \
gtphub.h \
- oap_client.h \
- rest_octets.h \
sgsn.h \
signal.h \
slhc.h \
diff --git a/include/openbsc/common.h b/include/osmocom/sgsn/common.h
index d91b3d39e..d91b3d39e 100644
--- a/include/openbsc/common.h
+++ b/include/osmocom/sgsn/common.h
diff --git a/include/openbsc/crc24.h b/include/osmocom/sgsn/crc24.h
index 756638c03..756638c03 100644
--- a/include/openbsc/crc24.h
+++ b/include/osmocom/sgsn/crc24.h
diff --git a/include/openbsc/debug.h b/include/osmocom/sgsn/debug.h
index 65e197d52..29d500da7 100644
--- a/include/openbsc/debug.h
+++ b/include/osmocom/sgsn/debug.h
@@ -19,7 +19,6 @@ enum {
DMEAS,
DSCCP,
DMSC,
- DMGCP,
DHO,
DDB,
DREF,
@@ -31,7 +30,6 @@ enum {
DSLHC,
DNAT,
DCTRL,
- DSMPP,
DFILTER,
DGTPHUB,
DRANAP,
@@ -41,6 +39,7 @@ enum {
DVLR,
DIUCS,
DSIGTRAN,
+ DGTP,
Debug_LastEntry,
};
diff --git a/include/openbsc/gb_proxy.h b/include/osmocom/sgsn/gb_proxy.h
index e10894fc3..1e8fb253c 100644
--- a/include/openbsc/gb_proxy.h
+++ b/include/osmocom/sgsn/gb_proxy.h
@@ -3,12 +3,14 @@
#include <osmocom/core/msgb.h>
+#include <osmocom/gsm/gsm23003.h>
#include <osmocom/gprs/gprs_ns.h>
#include <osmocom/vty/command.h>
#include <sys/types.h>
#include <regex.h>
+#include <stdbool.h>
#define GBPROXY_INIT_VU_GEN_TX 256
@@ -69,29 +71,30 @@ enum gbproxy_peer_ctr {
};
enum gbproxy_keep_mode {
- GBPROX_KEEP_NEVER,
- GBPROX_KEEP_REATTACH,
- GBPROX_KEEP_IDENTIFIED,
- GBPROX_KEEP_ALWAYS,
+ GBPROX_KEEP_NEVER, /* don't ever keep TLLI/IMSI state of de-registered subscribers */
+ GBPROX_KEEP_REATTACH, /* keep if re-attach has been requested by SGSN */
+ GBPROX_KEEP_IDENTIFIED, /* keep if we had resolved an IMSI */
+ GBPROX_KEEP_ALWAYS, /* always keep */
};
enum gbproxy_match_id {
- GBPROX_MATCH_PATCHING,
- GBPROX_MATCH_ROUTING,
+ GBPROX_MATCH_PATCHING, /* match rule on whether or not we should patch */
+ GBPROX_MATCH_ROUTING, /* match rule on whether or not we should route (2-SGSN) */
GBPROX_MATCH_LAST
};
struct gbproxy_match {
- int enable;
- char *re_str;
- regex_t re_comp;
+ bool enable; /* is this match enabled? */
+ char *re_str; /* regular expression (for IMSI) in string format */
+ regex_t re_comp; /* compiled regular expression (for IMSI) */
};
+/* global gb-proxy configuration */
struct gbproxy_config {
/* parsed from config file */
uint16_t nsip_sgsn_nsei;
- /* misc */
+ /* NS instance of libosmogb */
struct gprs_ns_inst *nsi;
/* Linked list of all Gb peers (except SGSN) */
@@ -100,35 +103,48 @@ struct gbproxy_config {
/* Counter */
struct rate_ctr_group *ctrg;
- /* force mcc/mnc */
- int core_mnc;
- int core_mcc;
+ /* MCC/MNC to be patched into RA-ID on the way from BSS to SGSN? */
+ struct osmo_plmn_id core_plmn;
+
+ /* APN to be patched into PDP CTX ACT REQ on the way from BSS to SGSN */
uint8_t* core_apn;
size_t core_apn_size;
+
+ /* Frequency (sec) at which timer to clean stale links is fired (0 disabled) */
+ unsigned int clean_stale_timer_freq;
+ /* If !0, Max age to consider a struct gbproxy_link_info as stale */
int tlli_max_age;
+ /* If !0, Max len of gbproxy_peer->list (list of struct gbproxy_link_info) */
int tlli_max_len;
-
- /* Experimental config */
- int patch_ptmsi;
- int acquire_imsi;
- int route_to_sgsn2;
+ /* If !0, Max len of gbproxy_link_info->stored_msgs (list of msgb) */
+ uint32_t stored_msgs_max_len;
+
+ /* Should the P-TMSI be patched on the fly (required for 2-SGSN config) */
+ bool patch_ptmsi;
+ /* Should the IMSI be acquired by the proxy (required for 2-SGSN config) */
+ bool acquire_imsi;
+ /* Should we route subscribers to two different SGSNs? */
+ bool route_to_sgsn2;
+ /* NSEI of the second SGSN */
uint16_t nsip_sgsn2_nsei;
+ /* should we keep a cache of per-subscriber state even after de-registration? */
enum gbproxy_keep_mode keep_link_infos;
- /* IMSI checking/matching */
+ /* IMSI checking/matching for 2-SGSN routing and patching */
struct gbproxy_match matches[GBPROX_MATCH_LAST];
};
struct gbproxy_patch_state {
- int local_mnc;
- int local_mcc;
+ struct osmo_plmn_id local_plmn;
/* List of TLLIs for which patching is enabled */
struct llist_head logical_links;
int logical_link_count;
};
+/* one peer at NS level that we interact with (BSS/PCU) */
struct gbproxy_peer {
+ /* linked to gbproxy_config.bts_peers */
struct llist_head list;
/* point back to the config */
@@ -139,7 +155,7 @@ struct gbproxy_peer {
/* BVCI used for Point-to-Point to this peer */
uint16_t bvci;
- int blocked;
+ bool blocked;
/* Routeing Area that this peer is part of (raw 04.08 encoding) */
uint8_t ra[6];
@@ -147,36 +163,63 @@ struct gbproxy_peer {
/* Counter */
struct rate_ctr_group *ctrg;
+ /* State related to on-the-fly patching of certain messages */
struct gbproxy_patch_state patch_state;
+
+ /* Fired periodically to clean up stale links from list */
+ struct osmo_timer_list clean_stale_timer;
};
struct gbproxy_tlli_state {
+ /* currently active TLLI */
uint32_t current;
+ /* newly-assigned TLLI (e.g. during P-TMSI allocation procedure) */
uint32_t assigned;
- int bss_validated;
- int net_validated;
+ /* has the BSS side validated (confirmed) the new TLLI? */
+ bool bss_validated;
+ /* has the SGSN side validated (confirmed) the new TLLI? */
+ bool net_validated;
+ /* NOTE: once both are validated, we set current = assigned and assigned = 0 */
+ /* The P-TMSI for this subscriber */
uint32_t ptmsi;
};
+/* One TLLI (= UE, = Subscriber) served via this proxy */
struct gbproxy_link_info {
+ /* link to gbproxy_peer.patch_state.logical_links */
struct llist_head list;
+ /* TLLI on the BSS/PCU side */
struct gbproxy_tlli_state tlli;
+ /* TLLI on the SGSN side (can be different in case of P-TMSI patching) */
struct gbproxy_tlli_state sgsn_tlli;
+ /* NSEI of the SGSN serving this link */
uint32_t sgsn_nsei;
+ /* timestamp when we last had any contact with this UE */
time_t timestamp;
+
+ /* IMSI of the subscriber (if/once known) */
uint8_t *imsi;
size_t imsi_len;
- int imsi_acq_pending;
+ /* is the IMSI acquisition still pending? */
+ bool imsi_acq_pending;
+
+ /* queue of stored UL messages (until IMSI acquisition completes and we can
+ * determine which of the SGSNs we should route this to */
struct llist_head stored_msgs;
+ uint32_t stored_msgs_len;
+
+ /* generated N(U) we use (required due to IMSI acquisition */
unsigned vu_gen_tx_bss;
- int is_deregistered;
+ /* is this subscriber deregistered (TLLI invalidated)? */
+ bool is_deregistered;
- int is_matching[GBPROX_MATCH_LAST];
+ /* does this link match either the (2-SGSN) routing or the patching rule? */
+ bool is_matching[GBPROX_MATCH_LAST];
};
@@ -185,6 +228,9 @@ struct gbproxy_link_info {
int gbproxy_vty_init(void);
int gbproxy_parse_config(const char *config_file, struct gbproxy_config *cfg);
+/* gb_proxy_ctrl.c */
+int gb_ctrl_cmds_install(void);
+
/* gb_proxy.c */
int gbproxy_init_config(struct gbproxy_config *cfg);
diff --git a/include/osmocom/sgsn/gprs_gb.h b/include/osmocom/sgsn/gprs_gb.h
new file mode 100644
index 000000000..461eee319
--- /dev/null
+++ b/include/osmocom/sgsn/gprs_gb.h
@@ -0,0 +1,14 @@
+#pragma once
+
+#include <stdbool.h>
+
+#include <osmocom/core/msgb.h>
+#include <osmocom/sgsn/gprs_llc.h>
+
+int gsm0408_gprs_rcvmsg_gb(struct msgb *msg, struct gprs_llc_llme *llme,
+ bool drop_cipherable);
+/* Has to be called whenever any PDU (signaling, data, ...) has been received */
+void gprs_gb_recv_pdu(struct sgsn_mm_ctx *mmctx);
+
+/* page a MS in its routing area */
+int gprs_gb_page_ps_ra(struct sgsn_mm_ctx *mmctx);
diff --git a/include/openbsc/gprs_gb_parse.h b/include/osmocom/sgsn/gprs_gb_parse.h
index 246839286..9f43faed6 100644
--- a/include/openbsc/gprs_gb_parse.h
+++ b/include/osmocom/sgsn/gprs_gb_parse.h
@@ -1,6 +1,6 @@
#pragma once
-#include <openbsc/gprs_llc.h>
+#include <osmocom/sgsn/gprs_llc.h>
#include <sys/types.h>
diff --git a/include/osmocom/sgsn/gprs_gmm.h b/include/osmocom/sgsn/gprs_gmm.h
new file mode 100644
index 000000000..e2b17d217
--- /dev/null
+++ b/include/osmocom/sgsn/gprs_gmm.h
@@ -0,0 +1,47 @@
+#ifndef _GPRS_GMM_H
+#define _GPRS_GMM_H
+
+#include <osmocom/core/msgb.h>
+#include <osmocom/sgsn/gprs_sgsn.h>
+
+#include <stdbool.h>
+
+int gsm48_tx_gmm_auth_ciph_req(struct sgsn_mm_ctx *mm,
+ const struct osmo_auth_vector *vec,
+ uint8_t key_seq, bool force_standby);
+
+int gsm0408_gprs_rcvmsg_gb(struct msgb *msg, struct gprs_llc_llme *llme,
+ bool drop_cipherable);
+int gsm0408_rcv_gmm(struct sgsn_mm_ctx *mmctx, struct msgb *msg,
+ struct gprs_llc_llme *llme, bool drop_cipherable);
+int gsm48_gmm_sendmsg(struct msgb *msg, int command,
+ struct sgsn_mm_ctx *mm, bool encryptable);
+int gsm0408_gprs_force_reattach(struct sgsn_mm_ctx *mmctx);
+int gsm0408_gprs_force_reattach_oldmsg(struct msgb *msg,
+ struct gprs_llc_llme *llme);
+void gsm0408_gprs_access_granted(struct sgsn_mm_ctx *mmctx);
+void gsm0408_gprs_access_denied(struct sgsn_mm_ctx *mmctx, int gmm_cause);
+void gsm0408_gprs_access_cancelled(struct sgsn_mm_ctx *mmctx, int gmm_cause);
+void gsm0408_gprs_authenticate(struct sgsn_mm_ctx *mmctx);
+
+int gprs_gmm_rx_suspend(struct gprs_ra_id *raid, uint32_t tlli);
+int gprs_gmm_rx_resume(struct gprs_ra_id *raid, uint32_t tlli,
+ uint8_t suspend_ref);
+
+time_t gprs_max_time_to_idle(void);
+
+int gsm48_tx_gmm_id_req(struct sgsn_mm_ctx *mm, uint8_t id_type);
+int gsm48_tx_gmm_att_rej(struct sgsn_mm_ctx *mm,
+ uint8_t gmm_cause);
+int gsm48_tx_gmm_att_ack(struct sgsn_mm_ctx *mm);
+
+int gprs_gmm_attach_req_ies(struct msgb *a, struct msgb *b);
+
+int gsm48_gmm_authorize(struct sgsn_mm_ctx *ctx);
+/* TODO: move extract_subscr_* when gsm48_gmm_authorize() got removed */
+void extract_subscr_msisdn(struct sgsn_mm_ctx *ctx);
+void extract_subscr_hlr(struct sgsn_mm_ctx *ctx);
+
+void msgid2mmctx(struct sgsn_mm_ctx *mm, const struct msgb *msg);
+void mmctx2msgid(struct msgb *msg, const struct sgsn_mm_ctx *mm);
+#endif /* _GPRS_GMM_H */
diff --git a/include/osmocom/sgsn/gprs_gmm_attach.h b/include/osmocom/sgsn/gprs_gmm_attach.h
new file mode 100644
index 000000000..0aa2123a8
--- /dev/null
+++ b/include/osmocom/sgsn/gprs_gmm_attach.h
@@ -0,0 +1,39 @@
+#ifndef GPRS_GMM_ATTACH_H
+#define GPRS_GMM_ATTACH_H
+
+#include <osmocom/core/fsm.h>
+
+struct sgsn_mm_ctx;
+
+enum gmm_attach_req_fsm_states {
+ ST_INIT,
+ ST_IDENTIY,
+ ST_RETRIEVE_AUTH,
+ ST_AUTH,
+ ST_ASK_VLR,
+ ST_IU_SECURITY_CMD,
+ ST_ACCEPT,
+ ST_REJECT
+};
+
+enum gmm_attach_req_fsm_events {
+ E_ATTACH_REQ_RECV,
+ E_IDEN_RESP_RECV,
+ E_AUTH_RESP_RECV_SUCCESS,
+ E_AUTH_RESP_RECV_RESYNC,
+ E_IU_SECURITY_CMD_COMPLETE,
+ E_ATTACH_ACCEPTED,
+ E_ATTACH_ACCEPT_SENT,
+ E_ATTACH_COMPLETE_RECV,
+ E_REJECT,
+ E_VLR_ANSWERED,
+};
+
+#define GMM_DISCARD_MS_WITHOUT_REJECT -1
+
+extern const struct value_string gmm_attach_req_fsm_event_names[];
+extern struct osmo_fsm gmm_attach_req_fsm;
+
+void gmm_att_req_free(struct sgsn_mm_ctx *mm);
+
+#endif // GPRS_GMM_ATTACH_H
diff --git a/include/osmocom/sgsn/gprs_gmm_fsm.h b/include/osmocom/sgsn/gprs_gmm_fsm.h
new file mode 100644
index 000000000..f10851e5c
--- /dev/null
+++ b/include/osmocom/sgsn/gprs_gmm_fsm.h
@@ -0,0 +1,42 @@
+#pragma once
+
+#include <osmocom/core/fsm.h>
+#include <osmocom/sgsn/gprs_sgsn.h>
+
+
+/* 3GPP TS 24.008 § 4.1.3.3 GMM mobility management states on the network side */
+enum gmm_fsm_states {
+ ST_GMM_DEREGISTERED, /* 4.1.3.3.1.1 */
+ ST_GMM_COMMON_PROC_INIT, /* 4.1.3.3.1.2 */
+ ST_GMM_REGISTERED_NORMAL, /* 4.1.3.3.2.1 */
+ ST_GMM_REGISTERED_SUSPENDED, /* 4.1.3.3.2.2 */
+ ST_GMM_DEREGISTERED_INIT, /* 4.1.3.3.1.4 */
+};
+
+enum gmm_fsm_events {
+ E_GMM_COMMON_PROC_INIT_REQ,
+ /* E_GMM_COMMON_PROC_FAILED, NOT USED */
+ /* E_GMM_LOWER_LAYER_FAILED, NOT USED */
+ E_GMM_COMMON_PROC_SUCCESS,
+ E_GMM_ATTACH_SUCCESS,
+ /* E_GMM_NET_INIT_DETACH_REQ, NOT USED */
+ /* E_GMM_MS_INIT_DETACH_REQ, NOT USED */
+ /* E_GMM_DETACH_ACCEPTED, */
+ E_GMM_SUSPEND,
+ E_GMM_RESUME,
+ E_GMM_CLEANUP,
+ E_GMM_RAT_CHANGE,
+};
+
+struct gmm_rat_change_data {
+ enum sgsn_ran_type new_ran_type;
+ struct gprs_llc_llme *llme;
+};
+
+static inline bool gmm_fsm_is_registered(struct osmo_fsm_inst *fi)
+{
+ return fi->state == ST_GMM_REGISTERED_NORMAL ||
+ fi->state == ST_GMM_REGISTERED_SUSPENDED;
+}
+
+extern struct osmo_fsm gmm_fsm;
diff --git a/include/openbsc/gprs_llc.h b/include/osmocom/sgsn/gprs_llc.h
index 8bc226781..ce0e63c51 100644
--- a/include/openbsc/gprs_llc.h
+++ b/include/osmocom/sgsn/gprs_llc.h
@@ -3,8 +3,8 @@
#include <stdint.h>
#include <stdbool.h>
-#include <openbsc/gprs_sgsn.h>
-#include <openbsc/gprs_llc_xid.h>
+#include <osmocom/sgsn/gprs_sgsn.h>
+#include <osmocom/sgsn/gprs_llc_xid.h>
/* Section 4.7 LLC Layer Structure */
enum gprs_llc_sapi {
@@ -96,6 +96,7 @@ enum gprs_llc_llme_state {
GPRS_LLMS_UNASSIGNED = 1, /* No TLLI yet */
GPRS_LLMS_ASSIGNED = 2, /* TLLI assigned */
};
+extern const struct value_string gprs_llc_llme_state_names[];
/* Section 8.9.9 LLC layer parameter default values */
struct gprs_llc_params {
@@ -110,13 +111,13 @@ struct gprs_llc_params {
uint16_t kU;
};
-/* Section 4.7.1: Logical Link Entity: One per DLCI (TLLI + SAPI) */
+/* 3GPP TS 44.064 § 4.7.1: Logical Link Entity: One per DLCI (TLLI + SAPI) */
struct gprs_llc_lle {
struct llist_head list;
uint32_t sapi;
- struct gprs_llc_llme *llme;
+ struct gprs_llc_llme *llme; /* backpointer to the Logical Link Management Entity */
enum gprs_llc_lle_state state;
@@ -145,10 +146,18 @@ struct gprs_llc_lle {
unsigned int retrans_ctr;
struct gprs_llc_params params;
+
+ /* Copy of the XID fields we have sent with the last
+ * network originated XID-Request. Since the phone
+ * may strip the optional fields in the confirmation
+ * we need to remeber those fields in order to be
+ * able to create the compression entity. */
+ struct llist_head *xid;
};
#define NUM_SAPIS 16
+/* 3GPP TS 44.064 § 4.7.3: Logical Link Management Entity: One per TLLI */
struct gprs_llc_llme {
struct llist_head list;
@@ -169,13 +178,6 @@ struct gprs_llc_llme {
uint16_t nsei;
struct gprs_llc_lle lle[NUM_SAPIS];
- /* Copy of the XID fields we have sent with the last
- * network originated XID-Request. Since the phone
- * may strip the optional fields in the confirmation
- * we need to remeber those fields in order to be
- * able to create the compression entity. */
- struct llist_head *xid;
-
/* Compression entities */
struct {
/* In these two list_heads we will store the
@@ -191,6 +193,9 @@ struct gprs_llc_llme {
#define GPRS_LLME_RESET_AGE (0)
+/* 3GPP TS 44.064 § 8.3 TLLI assignment procedures */
+#define TLLI_UNASSIGNED (0xffffffff)
+
extern struct llist_head gprs_llc_llmes;
/* LLC low level types */
diff --git a/include/openbsc/gprs_llc_xid.h b/include/osmocom/sgsn/gprs_llc_xid.h
index d340d40b7..d340d40b7 100644
--- a/include/openbsc/gprs_llc_xid.h
+++ b/include/osmocom/sgsn/gprs_llc_xid.h
diff --git a/include/osmocom/sgsn/gprs_mm_state_gb_fsm.h b/include/osmocom/sgsn/gprs_mm_state_gb_fsm.h
new file mode 100644
index 000000000..e69e1e11c
--- /dev/null
+++ b/include/osmocom/sgsn/gprs_mm_state_gb_fsm.h
@@ -0,0 +1,26 @@
+#pragma once
+
+#include <osmocom/core/fsm.h>
+
+struct sgsn_mm_ctx;
+
+
+/* TS 23.060 6.1.1 Mobility Management States (A/Gb mode) */
+enum mm_state_gb_fsm_states {
+ ST_MM_IDLE,
+ ST_MM_READY,
+ ST_MM_STANDBY
+};
+
+enum mm_state_gb_fsm_events {
+ E_MM_GPRS_ATTACH,
+ /* E_GPRS_DETACH, TODO: not used */
+ E_MM_PDU_RECEPTION,
+ E_MM_IMPLICIT_DETACH, /* = E_MM_CANCEL_LOCATION */
+ E_MM_READY_TIMER_EXPIRY,
+ /* E_FORCE_TO_STANDBY, TODO: not used */
+ /* E_ABNSORMAL_RLC_CONDITION, TODO: not used */
+ E_MM_RA_UPDATE,
+};
+
+extern struct osmo_fsm mm_state_gb_fsm;
diff --git a/include/osmocom/sgsn/gprs_mm_state_iu_fsm.h b/include/osmocom/sgsn/gprs_mm_state_iu_fsm.h
new file mode 100644
index 000000000..05342f9fb
--- /dev/null
+++ b/include/osmocom/sgsn/gprs_mm_state_iu_fsm.h
@@ -0,0 +1,25 @@
+#pragma once
+
+#include <osmocom/core/fsm.h>
+
+struct sgsn_mm_ctx;
+
+
+/* TS 23.060 6.1.1 Mobility Management States (A/Gb mode) */
+enum mm_state_iu_fsm_states {
+ ST_PMM_DETACHED,
+ ST_PMM_CONNECTED,
+ ST_PMM_IDLE
+};
+
+enum mm_state_iu_fsm_events {
+ E_PMM_PS_ATTACH,
+ /* E_PS_DETACH, TODO: not used */
+ E_PMM_PS_CONN_RELEASE,
+ E_PMM_PS_CONN_ESTABLISH,
+ E_PMM_IMPLICIT_DETACH, /* = E_PS_ATTACH_REJECT, E_RAU_REJECT */
+ E_PMM_RA_UPDATE, /* = Serving RNC relocation */
+ E_PMM_USER_INACTIVITY, /* when the inactivity timer runs out */
+};
+
+extern struct osmo_fsm mm_state_iu_fsm;
diff --git a/include/osmocom/sgsn/gprs_ranap.h b/include/osmocom/sgsn/gprs_ranap.h
new file mode 100644
index 000000000..62fdf6f2d
--- /dev/null
+++ b/include/osmocom/sgsn/gprs_ranap.h
@@ -0,0 +1,34 @@
+#pragma once
+
+#include <osmocom/core/msgb.h>
+#include <osmocom/sgsn/gprs_sgsn.h>
+
+#ifdef BUILD_IU
+#include <osmocom/ranap/ranap_ies_defs.h>
+#include <osmocom/ranap/ranap_msg_factory.h>
+#include <osmocom/ranap/iu_client.h>
+
+void activate_pdp_rabs(struct sgsn_mm_ctx *ctx);
+int sgsn_ranap_iu_event(struct ranap_ue_conn_ctx *ctx, enum ranap_iu_event_type type, void *data);
+int iu_rab_act_ps(uint8_t rab_id, struct sgsn_pdp_ctx *pdp);
+
+/* free the Iu UE context */
+void sgsn_ranap_iu_free(struct sgsn_mm_ctx *ctx);
+
+/* send a Iu Release Command and free afterwards the UE context */
+void sgsn_ranap_iu_release_free(struct sgsn_mm_ctx *ctx,
+ const struct RANAP_Cause *cause);
+
+int gsm0408_gprs_rcvmsg_iu(struct msgb *msg, struct gprs_ra_id *ra_id, uint16_t *sai);
+
+#else /* ifndef BUILD_IU */
+inline static void sgsn_ranap_iu_free(void *ctx) {};
+inline static void sgsn_ranap_iu_release_free(void *ctx, void *cause) {};
+#endif /* BUILD_IU*/
+
+struct ranap_ue_conn_ctx;
+/* On RANAP, Returns pointer to he associated ranap_ue_conn_ctx in msg, filled
+ * in by osmo-iuh's iu_recv_cb().
+ * On Gb, returns NULL */
+#define MSG_IU_UE_CTX(msg) ((struct ranap_ue_conn_ctx *)(msg)->dst)
+#define MSG_IU_UE_CTX_SET(msg, val) (msg)->dst = (val)
diff --git a/include/openbsc/gprs_sgsn.h b/include/osmocom/sgsn/gprs_sgsn.h
index c47fb0905..289e0c474 100644
--- a/include/openbsc/gprs_sgsn.h
+++ b/include/osmocom/sgsn/gprs_sgsn.h
@@ -3,7 +3,9 @@
#include <stdint.h>
#include <netinet/in.h>
+#include <inttypes.h>
+#include <osmocom/core/fsm.h>
#include <osmocom/core/timer.h>
#include <osmocom/gsm/gsm48.h>
@@ -21,25 +23,6 @@ struct gprs_subscr;
enum gsm48_gsm_cause;
-/* TS 04.08 4.1.3.3 GMM mobility management states on the network side */
-enum gprs_gmm_state {
- GMM_DEREGISTERED, /* 4.1.3.3.1.1 */
- GMM_COMMON_PROC_INIT, /* 4.1.3.3.1.2 */
- GMM_REGISTERED_NORMAL, /* 4.1.3.3.2.1 */
- GMM_REGISTERED_SUSPENDED, /* 4.1.3.3.2.2 */
- GMM_DEREGISTERED_INIT, /* 4.1.3.3.1.4 */
-};
-
-/* TS 23.060 6.1.1 and 6.1.2 Mobility management states A/Gb and Iu mode */
-enum gprs_pmm_state {
- PMM_DETACHED,
- PMM_CONNECTED,
- PMM_IDLE,
- MM_IDLE,
- MM_READY,
- MM_STANDBY,
-};
-
enum gprs_mm_ctr {
GMM_CTR_PKTS_SIG_IN,
GMM_CTR_PKTS_SIG_OUT,
@@ -107,9 +90,12 @@ enum sgsn_ran_type {
MM_CTX_T_GERAN_Gb,
/* UMTS via Iu */
MM_CTX_T_UTRAN_Iu,
- /* GPRS/EDGE via Iu */
+#if 0
+ /* GPRS/EDGE via Iu, not supported */
MM_CTX_T_GERAN_Iu,
+#endif
};
+extern const struct value_string sgsn_ran_type_names[];
struct service_info {
uint8_t type;
@@ -133,8 +119,7 @@ struct sgsn_mm_ctx {
enum sgsn_ran_type ran_type;
char imsi[GSM23003_IMSI_MAX_DIGITS+1];
- enum gprs_gmm_state gmm_state;
- enum gprs_pmm_state pmm_state; /* Iu: page when in PMM-IDLE mode */
+ struct osmo_fsm_inst *gmm_fsm;
uint32_t p_tmsi;
uint32_t p_tmsi_old; /* old P-TMSI before new is confirmed */
uint32_t p_tmsi_sig;
@@ -153,6 +138,9 @@ struct sgsn_mm_ctx {
struct gprs_llc_llme *llme;
uint32_t tlli;
uint32_t tlli_new;
+
+ /* TS 23.060 6.1.1 Mobility Management States (A/Gb mode) */
+ struct osmo_fsm_inst *mm_state_fsm;
} gb;
struct {
int new_key;
@@ -167,7 +155,18 @@ struct sgsn_mm_ctx {
/* Voice Support Match Indicator */
struct ranap_ue_conn_ctx *ue_ctx;
struct service_info service;
+ /* TS 23.060 6.1.2 Mobility Management States (Iu mode) */
+ struct osmo_fsm_inst *mm_state_fsm;
} iu;
+ struct {
+ struct osmo_fsm_inst *fsm;
+
+ /* when a second attach req arrives while in this procedure,
+ * the fsm needs to compare it against old to decide what to do */
+ struct msgb *attach_req;
+ uint32_t id_type;
+ unsigned int auth_reattempt; /* tracking UMTS resync auth attempts */
+ } gmm_att_req;
/* VLR number */
uint32_t new_sgsn_addr;
/* Authentication Triplet */
@@ -224,7 +223,7 @@ struct sgsn_mm_ctx {
* whether one of them can be dropped. */
enum sgsn_auth_state auth_state;
- int is_authenticated;
+ enum osmo_sub_auth_type sec_ctx;
/* the string representation of the current hlr */
char hlr[GSM_EXTENSION_LENGTH];
@@ -235,10 +234,43 @@ struct sgsn_mm_ctx {
struct gprs_subscr *subscr;
};
+static inline bool sgsn_mm_ctx_is_authenticated(struct sgsn_mm_ctx *ctx)
+{
+ switch (ctx->sec_ctx) {
+ case OSMO_AUTH_TYPE_GSM:
+ case OSMO_AUTH_TYPE_UMTS:
+ return true;
+ default:
+ return false;
+ }
+}
+
#define LOGMMCTXP(level, mm, fmt, args...) \
LOGP(DMM, level, "MM(%s/%08x) " fmt, (mm) ? (mm)->imsi : "---", \
(mm) ? (mm)->p_tmsi : GSM_RESERVED_TMSI, ## args)
+#ifdef BUILD_IU
+#define LOGIUP(ue, level, fmt, args...) \
+ LOGP(DMM, level, "UE(0x%x){%s} " fmt, ue->conn_id, osmo_rai_name(&(ue)->ra_id), ## args)
+#else
+#define LOGIUP(ue, level, fmt, args...) \
+ LOGP(DMM, level, "UE(%p){NOTSUPPORTED} " fmt, ue, ## args)
+#endif
+
+#define LOGGBP(llme, category, level, fmt, args...) \
+ LOGP(category, level, "LLME(%08x/%08x){%s} " fmt, (llme)->old_tlli, \
+ (llme)->tlli, get_value_string_or_null(gprs_llc_llme_state_names, (llme)->state), ## args);
+
+#define LOGGBIUP(llme, msg, level, fmt, args...) \
+ do { \
+ struct ranap_ue_conn_ctx * _ue; \
+ if (llme) { \
+ LOGGBP(llme, DMM, level, fmt, ## args); \
+ } else if ((msg) && (_ue = MSG_IU_UE_CTX(msg))) { \
+ LOGIUP(_ue, level, fmt, ## args); \
+ } else { OSMO_ASSERT(0); } \
+ } while (0)
+
/* look-up a SGSN MM context based on TLLI + RAI */
struct sgsn_mm_ctx *sgsn_mm_ctx_by_tlli(uint32_t tlli,
const struct gprs_ra_id *raid);
@@ -285,6 +317,7 @@ struct sgsn_pdp_ctx {
struct sgsn_mm_ctx *mm; /* back pointer to MM CTX */
int destroy_ggsn; /* destroy it on destruction */
struct sgsn_ggsn_ctx *ggsn; /* which GGSN serves this PDP */
+ struct llist_head ggsn_list; /* list_head for ggsn->pdp_list */
struct rate_ctr_group *ctrg;
//unsigned int id;
@@ -327,6 +360,7 @@ struct sgsn_pdp_ctx *sgsn_pdp_ctx_by_tid(const struct sgsn_mm_ctx *mm,
uint8_t tid);
struct sgsn_pdp_ctx *sgsn_pdp_ctx_alloc(struct sgsn_mm_ctx *mm,
+ struct sgsn_ggsn_ctx *ggsn,
uint8_t nsapi);
void sgsn_pdp_ctx_terminate(struct sgsn_pdp_ctx *pdp);
void sgsn_pdp_ctx_free(struct sgsn_pdp_ctx *pdp);
@@ -339,12 +373,26 @@ struct sgsn_ggsn_ctx {
struct in_addr remote_addr;
int remote_restart_ctr;
struct gsn_t *gsn;
+ struct llist_head pdp_list; /* list of associated pdp ctx (struct sgsn_pdp_ctx*) */
+ struct osmo_timer_list echo_timer;
+ unsigned int echo_interval;
};
struct sgsn_ggsn_ctx *sgsn_ggsn_ctx_alloc(uint32_t id);
void sgsn_ggsn_ctx_free(struct sgsn_ggsn_ctx *ggc);
struct sgsn_ggsn_ctx *sgsn_ggsn_ctx_by_id(uint32_t id);
struct sgsn_ggsn_ctx *sgsn_ggsn_ctx_by_addr(struct in_addr *addr);
struct sgsn_ggsn_ctx *sgsn_ggsn_ctx_find_alloc(uint32_t id);
+void sgsn_ggsn_ctx_drop_pdp(struct sgsn_pdp_ctx *pctx);
+int sgsn_ggsn_ctx_drop_all_pdp_except(struct sgsn_ggsn_ctx *ggsn, struct sgsn_pdp_ctx *except);
+int sgsn_ggsn_ctx_drop_all_pdp(struct sgsn_ggsn_ctx *ggsn);
+void sgsn_ggsn_ctx_add_pdp(struct sgsn_ggsn_ctx *ggc, struct sgsn_pdp_ctx *pdp);
+void sgsn_ggsn_ctx_remove_pdp(struct sgsn_ggsn_ctx *ggc, struct sgsn_pdp_ctx *pdp);
+void sgsn_ggsn_ctx_check_echo_timer(struct sgsn_ggsn_ctx *ggc);
+
+#define LOGGGSN(ggc, level, fmt, args...) { \
+ char _buf[INET_ADDRSTRLEN]; \
+ LOGP(DGTP, level, "GGSN(%" PRIu32 ":%s): " fmt, (ggc)->id, inet_ntop(AF_INET, &(ggc)->remote_addr, _buf, sizeof(_buf)), ## args); \
+ } while (0)
struct apn_ctx {
struct llist_head list;
@@ -365,20 +413,14 @@ extern struct llist_head sgsn_apn_ctxts;
extern struct llist_head sgsn_pdp_ctxts;
uint32_t sgsn_alloc_ptmsi(void);
-void sgsn_inst_init(void);
-
-/* High-level function to be called in case a GGSN has disappeared or
- * ottherwise lost state (recovery procedure) */
-int drop_all_pdp_for_ggsn(struct sgsn_ggsn_ctx *ggsn);
+struct sgsn_instance *sgsn_instance_alloc(void *talloc_ctx);
+void sgsn_inst_init(struct sgsn_instance *sgsn);
char *gprs_pdpaddr2str(uint8_t *pdpa, uint8_t len);
/*
* ctrl interface related work
*/
-struct gsm_network;
-struct ctrl_handle *sgsn_controlif_setup(struct gsm_network *,
- const char *bind_addr, uint16_t port);
int sgsn_ctrl_cmds_install(void);
/*
@@ -386,7 +428,7 @@ int sgsn_ctrl_cmds_install(void);
*/
struct imsi_acl_entry {
struct llist_head list;
- char imsi[16+1];
+ char imsi[OSMO_IMSI_BUF_SIZE];
};
/* see GSM 09.02, 17.7.1, PDP-Context and GPRSSubscriptionData */
@@ -431,8 +473,8 @@ struct sgsn_config;
struct sgsn_instance;
extern const struct value_string *sgsn_auth_state_names;
-void sgsn_auth_init(void);
-struct imsi_acl_entry *sgsn_acl_lookup(const char *imsi, struct sgsn_config *cfg);
+void sgsn_auth_init(struct sgsn_instance *sgsn);
+struct imsi_acl_entry *sgsn_acl_lookup(const char *imsi, const struct sgsn_config *cfg);
int sgsn_acl_add(const char *imsi, struct sgsn_config *cfg);
int sgsn_acl_del(const char *imsi, struct sgsn_config *cfg);
/* Request authorization */
diff --git a/include/osmocom/sgsn/gprs_sm.h b/include/osmocom/sgsn/gprs_sm.h
new file mode 100644
index 000000000..55c95b89d
--- /dev/null
+++ b/include/osmocom/sgsn/gprs_sm.h
@@ -0,0 +1,15 @@
+#pragma once
+
+#include <osmocom/core/msgb.h>
+#include <osmocom/sgsn/gprs_sgsn.h>
+
+int gsm48_tx_gsm_deact_pdp_req(struct sgsn_pdp_ctx *pdp, uint8_t sm_cause, bool teardown);
+int gsm48_tx_gsm_act_pdp_rej(struct sgsn_mm_ctx *mm, uint8_t tid,
+ uint8_t cause, uint8_t pco_len, uint8_t *pco_v);
+int gsm48_tx_gsm_act_pdp_acc(struct sgsn_pdp_ctx *pdp);
+int gsm48_tx_gsm_deact_pdp_acc(struct sgsn_pdp_ctx *pdp);
+
+void pdp_ctx_detach_mm_ctx(struct sgsn_pdp_ctx *pdp);
+
+int gsm0408_rcv_gsm(struct sgsn_mm_ctx *mmctx, struct msgb *msg,
+ struct gprs_llc_llme *llme);
diff --git a/include/openbsc/gprs_sndcp.h b/include/osmocom/sgsn/gprs_sndcp.h
index d970240e4..d970240e4 100644
--- a/include/openbsc/gprs_sndcp.h
+++ b/include/osmocom/sgsn/gprs_sndcp.h
diff --git a/include/openbsc/gprs_sndcp_comp.h b/include/osmocom/sgsn/gprs_sndcp_comp.h
index 87ab6382a..e01a9d72f 100644
--- a/include/openbsc/gprs_sndcp_comp.h
+++ b/include/osmocom/sgsn/gprs_sndcp_comp.h
@@ -23,7 +23,7 @@
#include <stdint.h>
#include <osmocom/core/linuxlist.h>
-#include <openbsc/gprs_sndcp_xid.h>
+#include <osmocom/sgsn/gprs_sndcp_xid.h>
/* Header / Data compression entity */
struct gprs_sndcp_comp {
@@ -41,9 +41,9 @@ struct gprs_sndcp_comp {
uint8_t comp[MAX_COMP]; /* see also: 6.5.1.1.5 and 6.6.1.1.5 */
/* Algorithm parameters */
- int algo; /* Algorithm type (see gprs_sndcp_xid.h) */
- int compclass; /* See gprs_sndcp_xid.h/c */
- void *state; /* Algorithm status and parameters */
+ union gprs_sndcp_comp_algo algo;
+ enum gprs_sndcp_xid_param_types compclass; /* See gprs_sndcp_xid.h/c */
+ void *state; /* Algorithm status and parameters */
};
#define MAX_COMP 16 /* Maximum number of possible pcomp/dcomp values */
diff --git a/include/openbsc/gprs_sndcp_dcomp.h b/include/osmocom/sgsn/gprs_sndcp_dcomp.h
index a76b4a4b3..3e851421c 100644
--- a/include/openbsc/gprs_sndcp_dcomp.h
+++ b/include/osmocom/sgsn/gprs_sndcp_dcomp.h
@@ -23,7 +23,7 @@
#include <stdint.h>
#include <osmocom/core/linuxlist.h>
-#include <openbsc/gprs_sndcp_comp.h>
+#include <osmocom/sgsn/gprs_sndcp_comp.h>
/* Note: The decompressed packet may have a maximum size of:
* Return value * MAX_DATADECOMPR_FAC */
diff --git a/include/openbsc/gprs_sndcp_pcomp.h b/include/osmocom/sgsn/gprs_sndcp_pcomp.h
index 4e15b9be2..3e3131b52 100644
--- a/include/openbsc/gprs_sndcp_pcomp.h
+++ b/include/osmocom/sgsn/gprs_sndcp_pcomp.h
@@ -23,7 +23,7 @@
#include <stdint.h>
#include <osmocom/core/linuxlist.h>
-#include <openbsc/gprs_sndcp_comp.h>
+#include <osmocom/sgsn/gprs_sndcp_comp.h>
/* Note: The decompressed packet may have a maximum size of:
* Return value + MAX_DECOMPR_INCR */
diff --git a/include/openbsc/gprs_sndcp_xid.h b/include/osmocom/sgsn/gprs_sndcp_xid.h
index e64bc5237..0dce43e40 100644
--- a/include/openbsc/gprs_sndcp_xid.h
+++ b/include/osmocom/sgsn/gprs_sndcp_xid.h
@@ -32,6 +32,24 @@
#define MAX_NSAPI 11 /* Maximum number usable NSAPIs */
#define MAX_ROHC 16 /* Maximum number of ROHC compression profiles */
+/* According to: 3GPP TS 44.065, 6.5.1.1.4 Algorithm identifier */
+enum gprs_sndcp_hdr_comp_algo {
+ RFC_1144, /* TCP/IP header compression, see also 6.5.2 */
+ RFC_2507, /* TCP/UDP/IP header compression, see also: 6.5.3 */
+ ROHC /* Robust Header Compression, see also 6.5.4 */
+};
+
+/* According to: 3GPP TS 44.065, 6.5.1.1.4 Algorithm identifier */
+enum gprs_sndcp_data_comp_algo {
+ V42BIS, /* V.42bis data compression, see also 6.6.2 */
+ V44 /* V44 data compression, see also: 6.6.3 */
+};
+
+union gprs_sndcp_comp_algo {
+ enum gprs_sndcp_hdr_comp_algo pcomp;
+ enum gprs_sndcp_data_comp_algo dcomp;
+};
+
/* According to: 3GPP TS 44.065, 6.5.1.1 Format of the protocol control
* information compression field (Figure 7) and 3GPP TS 44.065,
* 6.6.1.1 Format of the data compression field (Figure 9) */
@@ -45,7 +63,7 @@ struct gprs_sndcp_comp_field {
unsigned int entity;
/* Algorithm identifier, see also: 6.5.1.1.4 and 6.6.1.1.4 */
- int algo;
+ union gprs_sndcp_comp_algo algo;
/* Number of contained PCOMP / DCOMP values */
uint8_t comp_len;
@@ -62,24 +80,12 @@ struct gprs_sndcp_comp_field {
struct gprs_sndcp_dcomp_v44_params *v44_params;
};
-/* According to: 3GPP TS 44.065, 6.5.1.1.4 Algorithm identifier */
-enum gprs_sndcp_hdr_comp_algo {
- RFC_1144, /* TCP/IP header compression, see also 6.5.2 */
- RFC_2507, /* TCP/UDP/IP header compression, see also: 6.5.3 */
- ROHC /* Robust Header Compression, see also 6.5.4 */
-};
-
-/* According to: 3GPP TS 44.065, 6.5.1.1.4 Algorithm identifier */
-enum gprs_sndcp_data_comp_algo {
- V42BIS, /* V.42bis data compression, see also 6.6.2 */
- V44 /* V44 data compression, see also: 6.6.3 */
-};
-
/* According to: 3GPP TS 44.065, 8 SNDCP XID parameters */
enum gprs_sndcp_xid_param_types {
SNDCP_XID_VERSION_NUMBER,
SNDCP_XID_DATA_COMPRESSION, /* See also: subclause 6.6.1 */
SNDCP_XID_PROTOCOL_COMPRESSION, /* See also: subclause 6.5.1 */
+ SNDCP_XID_INVALID_COMPRESSION /* Not part of the spec; this means we found an invalid value */
};
/* According to: 3GPP TS 44.065, 6.5.2.1 Parameters (Table 5) */
@@ -209,7 +215,7 @@ struct llist_head *gprs_sndcp_parse_xid(int *version,
/* Find out to which compression class the specified comp-field belongs
* (header compression or data compression?) */
-int gprs_sndcp_get_compression_class(
+enum gprs_sndcp_xid_param_types gprs_sndcp_get_compression_class(
const struct gprs_sndcp_comp_field *comp_field);
/* Dump a list with SNDCP-XID fields (Debug) */
diff --git a/include/openbsc/gprs_subscriber.h b/include/osmocom/sgsn/gprs_subscriber.h
index be78febff..d36db7500 100644
--- a/include/openbsc/gprs_subscriber.h
+++ b/include/osmocom/sgsn/gprs_subscriber.h
@@ -27,5 +27,5 @@ struct gprs_subscr *_gprs_subscr_get(struct gprs_subscr *gsub,
const char *file, int line);
struct gprs_subscr *_gprs_subscr_put(struct gprs_subscr *gsub,
const char *file, int line);
-#define gprs_subscr_get(gsub) _gprs_subscr_get(gsub, __BASE_FILE__, __LINE__)
-#define gprs_subscr_put(gsub) _gprs_subscr_put(gsub, __BASE_FILE__, __LINE__)
+#define gprs_subscr_get(gsub) _gprs_subscr_get(gsub, __FILE__, __LINE__)
+#define gprs_subscr_put(gsub) _gprs_subscr_put(gsub, __FILE__, __LINE__)
diff --git a/include/openbsc/gprs_utils.h b/include/osmocom/sgsn/gprs_utils.h
index e06364dad..eacaec7a2 100644
--- a/include/openbsc/gprs_utils.h
+++ b/include/osmocom/sgsn/gprs_utils.h
@@ -29,9 +29,6 @@
struct msgb;
struct gprs_ra_id;
-struct msgb *gprs_msgb_copy(const struct msgb *msg, const char *name);
-int gprs_msgb_resize_area(struct msgb *msg, uint8_t *area,
- size_t old_size, size_t new_size);
int gprs_str_to_apn(uint8_t *apn_enc, size_t max_len, const char *str);
/* GSM 04.08, 10.5.7.3 GPRS Timer */
diff --git a/include/openbsc/gtphub.h b/include/osmocom/sgsn/gtphub.h
index 9cb7605f8..8fd9f38cf 100644
--- a/include/openbsc/gtphub.h
+++ b/include/osmocom/sgsn/gtphub.h
@@ -28,7 +28,7 @@
#include <osmocom/core/timer.h>
#include <osmocom/core/rate_ctr.h>
-#include <openbsc/gprs_sgsn.h>
+#include <osmocom/sgsn/gprs_sgsn.h>
/* support */
diff --git a/include/openbsc/sgsn.h b/include/osmocom/sgsn/sgsn.h
index f371dc695..f5ff524da 100644
--- a/include/openbsc/sgsn.h
+++ b/include/osmocom/sgsn/sgsn.h
@@ -5,13 +5,20 @@
#include <osmocom/core/msgb.h>
#include <osmocom/crypt/gprs_cipher.h>
#include <osmocom/gprs/gprs_ns.h>
-#include <openbsc/gprs_sgsn.h>
-#include <openbsc/oap_client.h>
-#include <openbsc/common.h>
+#include <osmocom/sgsn/gprs_sgsn.h>
+#include <osmocom/gsm/oap_client.h>
+#include <osmocom/gsupclient/gsup_client.h>
+#include <osmocom/sgsn/common.h>
+
+#include "../../bscconfig.h"
+
+#if BUILD_IU
+#include <osmocom/ranap/iu_client.h>
+#endif
#include <ares.h>
+#include <gtp.h>
-struct gprs_gsup_client;
struct hostent;
enum sgsn_auth_policy {
@@ -51,6 +58,7 @@ enum sgsn_rate_ctr_keys {
struct sgsn_cdr {
char *filename;
+ bool trap;
int interval;
};
@@ -70,30 +78,20 @@ struct sgsn_config {
struct sockaddr_in gsup_server_addr;
int gsup_server_port;
+ /* Only meaningful if auth_policy is SGSN_AUTH_POLICY_REMOTE */
int require_authentication;
+
int require_update_location;
/* CDR configuration */
struct sgsn_cdr cdr;
- struct {
- int T3312;
- int T3322;
- int T3350;
- int T3360;
- int T3370;
- int T3313;
- int T3314;
- int T3316;
- int T3385;
- int T3386;
- int T3395;
- int T3397;
- } timers;
+ /* Timer defintions */
+ struct osmo_tdef *T_defs;
int dynamic_lookup;
- struct oap_client_config oap;
+ struct osmo_oap_client_config oap;
/* RFC1144 TCP/IP header compression */
struct {
@@ -111,9 +109,18 @@ struct sgsn_config {
int p2;
} dcomp_v42bis;
+#if BUILD_IU
struct {
- int rab_assign_addr_enc;
+ enum ranap_nsap_addr_enc rab_assign_addr_enc;
+ uint32_t cs7_instance;
} iu;
+#endif
+
+ /* This is transmitted as IPA Serial Number tag, which is used for GSUP routing (e.g. in OsmoHLR).
+ * This name must be set in a multi-SGSN network, and it must be unique to each SGSN.
+ * If no name is set, the IPA Serial Number will be the same as the Unit Name,
+ * and will be of the form 'SGSN-00-00-00-00-00-00' */
+ char *sgsn_ipa_name;
};
struct sgsn_instance {
@@ -123,12 +130,10 @@ struct sgsn_instance {
struct osmo_fd gtp_fd0;
struct osmo_fd gtp_fd1c;
struct osmo_fd gtp_fd1u;
- /* Timer for libGTP */
- struct osmo_timer_list gtp_timer;
/* GSN instance for libgtp */
struct gsn_t *gsn;
/* Subscriber */
- struct gsup_client *gsup_client;
+ struct osmo_gsup_client *gsup_client;
/* LLME inactivity timer */
struct osmo_timer_list llme_timer;
@@ -147,19 +152,22 @@ extern struct sgsn_instance *sgsn;
int sgsn_vty_init(struct sgsn_config *cfg);
int sgsn_parse_config(const char *config_file);
+char *sgsn_gtp_ntoa(struct ul16_t *ul);
/* sgsn.c */
/* Main input function for Gb proxy */
int sgsn_rcvmsg(struct msgb *msg, struct gprs_nsvc *nsvc, uint16_t ns_bvci);
-
+/* sgsn_libgtp.c */
struct sgsn_pdp_ctx *sgsn_create_pdp_ctx(struct sgsn_ggsn_ctx *ggsn,
struct sgsn_mm_ctx *mmctx,
uint16_t nsapi,
struct tlv_parsed *tp);
int sgsn_delete_pdp_ctx(struct sgsn_pdp_ctx *pctx);
void sgsn_pdp_upd_gtp_u(struct sgsn_pdp_ctx *pdp, void *addr, size_t alen);
+void sgsn_ggsn_echo_req(struct sgsn_ggsn_ctx *ggc);
+int send_act_pdp_cont_acc(struct sgsn_pdp_ctx *pctx);
/* gprs_sndcp.c */
diff --git a/include/openbsc/signal.h b/include/osmocom/sgsn/signal.h
index 4b6ba56f6..4b6ba56f6 100644
--- a/include/openbsc/signal.h
+++ b/include/osmocom/sgsn/signal.h
diff --git a/include/openbsc/slhc.h b/include/osmocom/sgsn/slhc.h
index cd5a47cf4..cd5a47cf4 100644
--- a/include/openbsc/slhc.h
+++ b/include/osmocom/sgsn/slhc.h
diff --git a/include/openbsc/v42bis.h b/include/osmocom/sgsn/v42bis.h
index 607a58e51..b64c43e69 100644
--- a/include/openbsc/v42bis.h
+++ b/include/osmocom/sgsn/v42bis.h
@@ -20,7 +20,7 @@
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/*! \page v42bis_page V.42bis modem data compression
diff --git a/include/openbsc/v42bis_private.h b/include/osmocom/sgsn/v42bis_private.h
index daa5ea315..c6b675a1b 100644
--- a/include/openbsc/v42bis_private.h
+++ b/include/osmocom/sgsn/v42bis_private.h
@@ -20,7 +20,7 @@
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#if !defined(_SPANDSP_PRIVATE_V42BIS_H_)
diff --git a/include/openbsc/vty.h b/include/osmocom/sgsn/vty.h
index d2e3d9a73..d2e3d9a73 100644
--- a/include/openbsc/vty.h
+++ b/include/osmocom/sgsn/vty.h
diff --git a/osmo-sgsn.pc.in b/osmo-sgsn.pc.in
deleted file mode 100644
index 45aef571b..000000000
--- a/osmo-sgsn.pc.in
+++ /dev/null
@@ -1,10 +0,0 @@
-prefix=@prefix@
-exec_prefix=@exec_prefix@
-libdir=@libdir@
-includedir=@includedir@/
-
-Name: OsmoSGSN
-Description: Osmocom's Serving GPRS Support Node for 2G and 3G packet-switched mobile networks
-Requires:
-Version: @VERSION@
-Cflags: -I${includedir}
diff --git a/osmoappdesc.py b/osmoappdesc.py
index f610e77b3..e91043f95 100644
--- a/osmoappdesc.py
+++ b/osmoappdesc.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
# (C) 2013 by Katerina Barone-Adesi <kat.obsc@gmail.com>
# This program is free software: you can redistribute it and/or modify
@@ -23,12 +23,12 @@ app_configs = {
}
-apps = [(4246, "src/gprs/osmo-gbproxy", "OsmoGbProxy", "gbproxy"),
- (4245, "src/gprs/osmo-sgsn", "OsmoSGSN", "sgsn"),
- (4253, "src/gprs/osmo-gtphub", "OsmoGTPhub", "gtphub")
+apps = [(4246, "src/gbproxy/osmo-gbproxy", "OsmoGbProxy", "gbproxy"),
+ (4245, "src/sgsn/osmo-sgsn", "OsmoSGSN", "sgsn"),
+ (4253, "src/gtphub/osmo-gtphub", "OsmoGTPhub", "gtphub")
]
-vty_command = ["./src/gprs/osmo-sgsn", "-c",
+vty_command = ["./src/sgsn/osmo-sgsn", "-c",
"doc/examples/osmo-sgsn/osmo-sgsn.cfg"]
vty_app = apps[1]
diff --git a/src/Makefile.am b/src/Makefile.am
index d2dcb9fba..c45d3ab46 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,3 +1,6 @@
SUBDIRS = \
gprs \
+ sgsn \
+ gbproxy \
+ gtphub \
$(NULL)
diff --git a/src/gbproxy/Makefile.am b/src/gbproxy/Makefile.am
new file mode 100644
index 000000000..6876f68a5
--- /dev/null
+++ b/src/gbproxy/Makefile.am
@@ -0,0 +1,46 @@
+AM_CPPFLAGS = \
+ $(all_includes) \
+ -I$(top_srcdir)/include \
+ -I$(top_builddir) \
+ $(NULL)
+
+AM_CFLAGS = \
+ -Wall \
+ -fno-strict-aliasing \
+ $(LIBOSMOCORE_CFLAGS) \
+ $(LIBOSMOGSM_CFLAGS) \
+ $(LIBOSMOVTY_CFLAGS) \
+ $(LIBOSMOCTRL_CFLAGS) \
+ $(LIBOSMOABIS_CFLAGS) \
+ $(LIBOSMOGB_CFLAGS) \
+ $(LIBOSMOGSUPCLIENT_CFLAGS) \
+ $(COVERAGE_CFLAGS) \
+ $(LIBGTP_CFLAGS) \
+ $(NULL)
+
+bin_PROGRAMS = \
+ osmo-gbproxy \
+ $(NULL)
+
+osmo_gbproxy_SOURCES = \
+ gb_proxy.c \
+ gb_proxy_main.c \
+ gb_proxy_vty.c \
+ gb_proxy_ctrl.c \
+ gb_proxy_patch.c \
+ gb_proxy_tlli.c \
+ gb_proxy_peer.c \
+ $(NULL)
+osmo_gbproxy_LDADD = \
+ $(top_builddir)/src/gprs/gprs_gb_parse.o \
+ $(top_builddir)/src/gprs/gprs_llc_parse.o \
+ $(top_builddir)/src/gprs/crc24.o \
+ $(top_builddir)/src/gprs/gprs_utils.o \
+ $(LIBOSMOCORE_LIBS) \
+ $(LIBOSMOGSM_LIBS) \
+ $(LIBOSMOVTY_LIBS) \
+ $(LIBOSMOCTRL_LIBS) \
+ $(LIBOSMOGB_LIBS) \
+ $(LIBGTP_LIBS) \
+ -lrt \
+ $(NULL)
diff --git a/src/gprs/gb_proxy.c b/src/gbproxy/gb_proxy.c
index d288cb314..3f471ff82 100644
--- a/src/gprs/gb_proxy.c
+++ b/src/gbproxy/gb_proxy.c
@@ -41,36 +41,34 @@
#include <osmocom/gsm/gsm_utils.h>
-#include <openbsc/signal.h>
-#include <openbsc/debug.h>
-#include <openbsc/gprs_gb_parse.h>
-#include <openbsc/gb_proxy.h>
+#include <osmocom/sgsn/signal.h>
+#include <osmocom/sgsn/debug.h>
+#include <osmocom/sgsn/gprs_gb_parse.h>
+#include <osmocom/sgsn/gb_proxy.h>
-#include <openbsc/gprs_llc.h>
+#include <osmocom/sgsn/gprs_llc.h>
#include <osmocom/gsm/protocol/gsm_04_08_gprs.h>
-#include <openbsc/gprs_utils.h>
+#include <osmocom/sgsn/gprs_utils.h>
-#include <openssl/rand.h>
-
-extern void *tall_bsc_ctx;
+extern void *tall_sgsn_ctx;
static const struct rate_ctr_desc global_ctr_description[] = {
{ "inv-bvci", "Invalid BVC Identifier " },
{ "inv-lai", "Invalid Location Area Identifier" },
{ "inv-rai", "Invalid Routing Area Identifier " },
{ "inv-nsei", "No BVC established for NSEI " },
- { "proto-err.bss", "BSSGP protocol error (BSS )" },
- { "proto-err.sgsn", "BSSGP protocol error (SGSN)" },
- { "not-supp.bss", "Feature not supported (BSS )" },
- { "not-supp.sgsn", "Feature not supported (SGSN)" },
- { "restart.sgsn", "Restarted RESET procedure (SGSN)" },
- { "tx-err.sgsn", "NS Transmission error (SGSN)" },
+ { "proto-err:bss", "BSSGP protocol error (BSS )" },
+ { "proto-err:sgsn", "BSSGP protocol error (SGSN)" },
+ { "not-supp:bss", "Feature not supported (BSS )" },
+ { "not-supp:sgsn", "Feature not supported (SGSN)" },
+ { "restart:sgsn", "Restarted RESET procedure (SGSN)" },
+ { "tx-err:sgsn", "NS Transmission error (SGSN)" },
{ "error", "Other error " },
{ "mod-peer-err", "Patch error: no peer " },
};
static const struct rate_ctr_group_desc global_ctrg_desc = {
- .group_name_prefix = "gbproxy.global",
+ .group_name_prefix = "gbproxy:global",
.group_description = "GBProxy Global Statistics",
.num_ctr = ARRAY_SIZE(global_ctr_description),
.ctr_desc = global_ctr_description,
@@ -194,8 +192,7 @@ static void gbprox_update_current_raid(uint8_t *raid_enc,
const char *log_text)
{
struct gbproxy_patch_state *state = &peer->patch_state;
- const int old_local_mcc = state->local_mcc;
- const int old_local_mnc = state->local_mnc;
+ const struct osmo_plmn_id old_plmn = state->local_plmn;
struct gprs_ra_id raid;
if (!raid_enc)
@@ -204,45 +201,49 @@ static void gbprox_update_current_raid(uint8_t *raid_enc,
gsm48_parse_ra(&raid, raid_enc);
/* save source side MCC/MNC */
- if (!peer->cfg->core_mcc || raid.mcc == peer->cfg->core_mcc) {
- state->local_mcc = 0;
+ if (!peer->cfg->core_plmn.mcc || raid.mcc == peer->cfg->core_plmn.mcc) {
+ state->local_plmn.mcc = 0;
} else {
- state->local_mcc = raid.mcc;
+ state->local_plmn.mcc = raid.mcc;
}
- if (!peer->cfg->core_mnc || raid.mnc == peer->cfg->core_mnc) {
- state->local_mnc = 0;
+ if (!peer->cfg->core_plmn.mnc
+ || !osmo_mnc_cmp(raid.mnc, raid.mnc_3_digits,
+ peer->cfg->core_plmn.mnc, peer->cfg->core_plmn.mnc_3_digits)) {
+ state->local_plmn.mnc = 0;
+ state->local_plmn.mnc_3_digits = false;
} else {
- state->local_mnc = raid.mnc;
+ state->local_plmn.mnc = raid.mnc;
+ state->local_plmn.mnc_3_digits = raid.mnc_3_digits;
}
- if (old_local_mcc != state->local_mcc ||
- old_local_mnc != state->local_mnc)
+ if (osmo_plmn_cmp(&old_plmn, &state->local_plmn))
LOGP(DGPRS, LOGL_NOTICE,
"Patching RAID %sactivated, msg: %s, "
- "local: %d-%d, core: %d-%d\n",
- state->local_mcc || state->local_mnc ?
+ "local: %s, core: %s\n",
+ state->local_plmn.mcc || state->local_plmn.mnc ?
"" : "de",
log_text,
- state->local_mcc, state->local_mnc,
- peer->cfg->core_mcc, peer->cfg->core_mnc);
+ osmo_plmn_name(&state->local_plmn),
+ osmo_plmn_name2(&peer->cfg->core_plmn));
}
uint32_t gbproxy_make_bss_ptmsi(struct gbproxy_peer *peer,
uint32_t sgsn_ptmsi)
{
uint32_t bss_ptmsi;
- int max_retries = 23;
+ int max_retries = 23, rc = 0;
if (!peer->cfg->patch_ptmsi) {
bss_ptmsi = sgsn_ptmsi;
} else {
do {
- if (RAND_bytes((uint8_t *) &bss_ptmsi, sizeof(bss_ptmsi)) != 1) {
+ rc = osmo_get_rand_id((uint8_t *) &bss_ptmsi, sizeof(bss_ptmsi));
+ if (rc < 0) {
bss_ptmsi = GSM_RESERVED_TMSI;
break;
}
- bss_ptmsi = bss_ptmsi | 0xC0000000;
+ bss_ptmsi = bss_ptmsi | GSM23003_TMSI_SGSN_MASK;
if (gbproxy_link_info_by_ptmsi(peer, bss_ptmsi))
bss_ptmsi = GSM_RESERVED_TMSI;
@@ -250,7 +251,7 @@ uint32_t gbproxy_make_bss_ptmsi(struct gbproxy_peer *peer,
}
if (bss_ptmsi == GSM_RESERVED_TMSI)
- LOGP(DGPRS, LOGL_ERROR, "Failed to allocate a BSS P-TMSI\n");
+ LOGP(DGPRS, LOGL_ERROR, "Failed to allocate a BSS P-TMSI: %d (%s)\n", rc, strerror(-rc));
return bss_ptmsi;
}
@@ -260,7 +261,7 @@ uint32_t gbproxy_make_sgsn_tlli(struct gbproxy_peer *peer,
uint32_t bss_tlli)
{
uint32_t sgsn_tlli;
- int max_retries = 23;
+ int max_retries = 23, rc = 0;
if (!peer->cfg->patch_ptmsi) {
sgsn_tlli = bss_tlli;
} else if (link_info->sgsn_tlli.ptmsi != GSM_RESERVED_TMSI &&
@@ -274,7 +275,8 @@ uint32_t gbproxy_make_sgsn_tlli(struct gbproxy_peer *peer,
} else {
do {
/* create random TLLI, 0b01111xxx... */
- if (RAND_bytes((uint8_t *) &sgsn_tlli, sizeof(sgsn_tlli)) != 1) {
+ rc = osmo_get_rand_id((uint8_t *) &sgsn_tlli, sizeof(sgsn_tlli));
+ if (rc < 0) {
sgsn_tlli = 0;
break;
}
@@ -287,7 +289,7 @@ uint32_t gbproxy_make_sgsn_tlli(struct gbproxy_peer *peer,
}
if (!sgsn_tlli)
- LOGP(DGPRS, LOGL_ERROR, "Failed to allocate an SGSN TLLI\n");
+ LOGP(DGPRS, LOGL_ERROR, "Failed to allocate an SGSN TLLI: %d (%s)\n", rc, strerror(-rc));
return sgsn_tlli;
}
@@ -308,7 +310,7 @@ static int gbproxy_restart_imsi_acquisition(struct gbproxy_link_info* link_info)
in_progress = 1;
gbproxy_link_info_discard_messages(link_info);
- link_info->imsi_acq_pending = 0;
+ link_info->imsi_acq_pending = false;
return in_progress;
}
@@ -319,24 +321,18 @@ static void gbproxy_reset_imsi_acquisition(struct gbproxy_link_info* link_info)
link_info->vu_gen_tx_bss = GBPROXY_INIT_VU_GEN_TX;
}
+/* Got identity response with IMSI, assuming the request had
+ * been generated by the gbproxy */
static int gbproxy_flush_stored_messages(struct gbproxy_peer *peer,
- struct msgb *msg,
time_t now,
- struct gbproxy_link_info* link_info,
- struct gprs_gb_parse_context *parse_ctx)
+ struct gbproxy_link_info* link_info)
{
int rc;
struct msgb *stored_msg;
- /* Got identity response with IMSI, assuming the request had
- * been generated by the gbproxy */
-
- LOGP(DLLC, LOGL_DEBUG,
- "NSEI=%d(BSS) IMSI acquisition succeeded, "
- "flushing stored messages\n",
- msgb_nsei(msg));
/* Patch and flush stored messages towards the SGSN */
- while ((stored_msg = msgb_dequeue(&link_info->stored_msgs))) {
+ while ((stored_msg = msgb_dequeue_count(&link_info->stored_msgs,
+ &link_info->stored_msgs_len))) {
struct gprs_gb_parse_context tmp_parse_ctx = {0};
tmp_parse_ctx.to_bss = 0;
tmp_parse_ctx.peer_nsei = msgb_nsei(stored_msg);
@@ -345,7 +341,7 @@ static int gbproxy_flush_stored_messages(struct gbproxy_peer *peer,
gprs_gb_parse_bssgp(msgb_bssgph(stored_msg),
msgb_bssgp_len(stored_msg),
&tmp_parse_ctx);
- gbproxy_patch_bssgp(msg, msgb_bssgph(stored_msg),
+ gbproxy_patch_bssgp(stored_msg, msgb_bssgph(stored_msg),
msgb_bssgp_len(stored_msg),
peer, link_info, &len_change,
&tmp_parse_ctx);
@@ -359,15 +355,15 @@ static int gbproxy_flush_stored_messages(struct gbproxy_peer *peer,
}
rc = gbprox_relay2sgsn(peer->cfg, stored_msg,
- msgb_bvci(msg), link_info->sgsn_nsei);
+ msgb_bvci(stored_msg), link_info->sgsn_nsei);
if (rc < 0)
LOGP(DLLC, LOGL_ERROR,
"NSEI=%d(BSS) failed to send stored message "
"(%s)\n",
- msgb_nsei(msg),
- parse_ctx->llc_msg_name ?
- parse_ctx->llc_msg_name : "BSSGP");
+ tmp_parse_ctx.peer_nsei,
+ tmp_parse_ctx.llc_msg_name ?
+ tmp_parse_ctx.llc_msg_name : "BSSGP");
msgb_free(stored_msg);
}
@@ -473,11 +469,14 @@ static int gbproxy_imsi_acquisition(struct gbproxy_peer *peer,
gsm48_hdr_pdisc(parse_ctx->g48_hdr) == GSM48_PDISC_MM_GPRS &&
gsm48_hdr_msg_type(parse_ctx->g48_hdr) == GSM48_MT_GMM_ID_RESP;
+ LOGP(DLLC, LOGL_DEBUG,
+ "NSEI=%d(BSS) IMSI acquisition succeeded, "
+ "flushing stored messages\n",
+ msgb_nsei(msg));
/* The IMSI is now available. If flushing the messages fails,
* then link_info has been deleted and we should return
* immediately. */
- if (gbproxy_flush_stored_messages(peer, msg, now, link_info,
- parse_ctx) < 0)
+ if (gbproxy_flush_stored_messages(peer, now, link_info) < 0)
return 0;
gbproxy_reset_imsi_acquisition(link_info);
@@ -490,6 +489,24 @@ static int gbproxy_imsi_acquisition(struct gbproxy_peer *peer,
/* The message cannot be processed since the IMSI is still missing */
+ /* If queue is getting too large, drop oldest msgb before adding new one */
+ if (peer->cfg->stored_msgs_max_len > 0) {
+ int exceeded_max_len = link_info->stored_msgs_len
+ + 1 - peer->cfg->stored_msgs_max_len;
+
+ for (; exceeded_max_len > 0; exceeded_max_len--) {
+ struct msgb *msgb_drop;
+ msgb_drop = msgb_dequeue_count(&link_info->stored_msgs,
+ &link_info->stored_msgs_len);
+ LOGP(DLLC, LOGL_INFO,
+ "NSEI=%d(BSS) Dropping stored msgb from list "
+ "(!acq imsi, length %d, max_len exceeded)\n",
+ msgb_nsei(msgb_drop), link_info->stored_msgs_len);
+
+ msgb_free(msgb_drop);
+ }
+ }
+
/* Enqueue unpatched messages */
LOGP(DLLC, LOGL_INFO,
"NSEI=%d(BSS) IMSI acquisition in progress, "
@@ -497,8 +514,9 @@ static int gbproxy_imsi_acquisition(struct gbproxy_peer *peer,
msgb_nsei(msg),
parse_ctx->llc_msg_name ? parse_ctx->llc_msg_name : "BSSGP");
- stored_msg = gprs_msgb_copy(msg, "process_bssgp_ul");
- msgb_enqueue(&link_info->stored_msgs, stored_msg);
+ stored_msg = bssgp_msgb_copy(msg, "process_bssgp_ul");
+ msgb_enqueue_count(&link_info->stored_msgs, stored_msg,
+ &link_info->stored_msgs_len);
if (!link_info->imsi_acq_pending) {
LOGP(DLLC, LOGL_INFO,
@@ -513,7 +531,7 @@ static int gbproxy_imsi_acquisition(struct gbproxy_peer *peer,
* implementation relies on the MS doing proper retransmissions
* of the triggering message instead */
- link_info->imsi_acq_pending = 1;
+ link_info->imsi_acq_pending = true;
}
return 0;
@@ -559,7 +577,7 @@ static int gbprox_process_bssgp_ul(struct gbproxy_config *cfg,
struct gbproxy_link_info *link_info = NULL;
uint32_t sgsn_nsei = cfg->nsip_sgsn_nsei;
- if (!cfg->core_mcc && !cfg->core_mnc && !cfg->core_apn &&
+ if (!cfg->core_plmn.mcc && !cfg->core_plmn.mnc && !cfg->core_apn &&
!cfg->acquire_imsi && !cfg->patch_ptmsi && !cfg->route_to_sgsn2)
return 1;
@@ -589,7 +607,7 @@ static int gbprox_process_bssgp_ul(struct gbproxy_config *cfg,
return 0;
- clock_gettime(CLOCK_MONOTONIC, &ts);
+ osmo_clock_gettime(CLOCK_MONOTONIC, &ts);
now = ts.tv_sec;
gbprox_update_current_raid(parse_ctx.bssgp_raid_enc, peer,
@@ -665,7 +683,7 @@ static int gbprox_process_bssgp_ul(struct gbproxy_config *cfg,
return 1;
}
-/* patch BSSGP message to use core_mcc/mnc on the SGSN side */
+/* patch BSSGP message to use core_plmn.mcc/mnc on the SGSN side */
static void gbprox_process_bssgp_dl(struct gbproxy_config *cfg,
struct msgb *msg,
struct gbproxy_peer *peer)
@@ -677,7 +695,7 @@ static void gbprox_process_bssgp_dl(struct gbproxy_config *cfg,
struct timespec ts = {0,};
struct gbproxy_link_info *link_info = NULL;
- if (!cfg->core_mcc && !cfg->core_mnc && !cfg->core_apn &&
+ if (!cfg->core_plmn.mcc && !cfg->core_plmn.mnc && !cfg->core_apn &&
!cfg->acquire_imsi && !cfg->patch_ptmsi && !cfg->route_to_sgsn2)
return;
@@ -705,7 +723,7 @@ static void gbprox_process_bssgp_dl(struct gbproxy_config *cfg,
if (!peer)
return;
- clock_gettime(CLOCK_MONOTONIC, &ts);
+ osmo_clock_gettime(CLOCK_MONOTONIC, &ts);
now = ts.tv_sec;
if (parse_ctx.g48_hdr) {
@@ -761,7 +779,7 @@ static int gbprox_relay2sgsn(struct gbproxy_config *cfg, struct msgb *old_msg,
{
/* create a copy of the message so the old one can
* be free()d safely when we return from gbprox_rcvmsg() */
- struct msgb *msg = gprs_msgb_copy(old_msg, "msgb_relay2sgsn");
+ struct msgb *msg = bssgp_msgb_copy(old_msg, "msgb_relay2sgsn");
int rc;
DEBUGP(DGPRS, "NSEI=%u proxying BTS->SGSN (NS_BVCI=%u, NSEI=%u)\n",
@@ -785,7 +803,7 @@ static int gbprox_relay2peer(struct msgb *old_msg, struct gbproxy_peer *peer,
{
/* create a copy of the message so the old one can
* be free()d safely when we return from gbprox_rcvmsg() */
- struct msgb *msg = gprs_msgb_copy(old_msg, "msgb_relay2peer");
+ struct msgb *msg = bssgp_msgb_copy(old_msg, "msgb_relay2peer");
int rc;
DEBUGP(DGPRS, "NSEI=%u proxying SGSN->BSS (NS_BVCI=%u, NSEI=%u)\n",
@@ -818,11 +836,11 @@ static int block_unblock_peer(struct gbproxy_config *cfg, uint16_t ptp_bvci, uin
switch (pdu_type) {
case BSSGP_PDUT_BVC_BLOCK_ACK:
- peer->blocked = 1;
+ peer->blocked = true;
rate_ctr_inc(&peer->ctrg->ctr[GBPROX_PEER_CTR_BLOCKED]);
break;
case BSSGP_PDUT_BVC_UNBLOCK_ACK:
- peer->blocked = 0;
+ peer->blocked = false;
rate_ctr_inc(&peer->ctrg->ctr[GBPROX_PEER_CTR_UNBLOCKED]);
break;
default:
@@ -994,9 +1012,8 @@ static int gbprox_rx_sig_from_bss(struct gbproxy_config *cfg,
sizeof(from_peer->ra));
gsm48_parse_ra(&raid, from_peer->ra);
LOGP(DGPRS, LOGL_INFO, "NSEI=%u BSSGP SUSPEND/RESUME "
- "RAI snooping: RAI %u-%u-%u-%u behind BVCI=%u\n",
- nsei, raid.mcc, raid.mnc, raid.lac,
- raid.rac , from_peer->bvci);
+ "RAI snooping: RAI %s behind BVCI=%u\n",
+ nsei, osmo_rai_name(&raid), from_peer->bvci);
/* FIXME: This only supports one BSS per RA */
break;
case BSSGP_PDUT_BVC_RESET:
@@ -1018,9 +1035,9 @@ static int gbprox_rx_sig_from_bss(struct gbproxy_config *cfg,
if (!from_peer) {
/* if a PTP-BVC is reset, and we don't know that
* PTP-BVCI yet, we should allocate a new peer */
- LOGP(DGPRS, LOGL_INFO, "Allocationg new peer for "
- "BVCI=%u via NSEI=%u\n", bvci, nsei);
+ LOGP(DGPRS, LOGL_INFO, "Allocationg new peer for BVCI=%u via NSEI=%u\n", bvci, nsei);
from_peer = gbproxy_peer_alloc(cfg, bvci);
+ OSMO_ASSERT(from_peer);
from_peer->nsei = nsei;
}
@@ -1037,10 +1054,8 @@ static int gbprox_rx_sig_from_bss(struct gbproxy_config *cfg,
TLVP_VAL(&tp, BSSGP_IE_CELL_ID),
sizeof(from_peer->ra));
gsm48_parse_ra(&raid, from_peer->ra);
- LOGP(DGPRS, LOGL_INFO, "NSEI=%u/BVCI=%u "
- "Cell ID %u-%u-%u-%u\n", nsei,
- bvci, raid.mcc, raid.mnc, raid.lac,
- raid.rac);
+ LOGP(DGPRS, LOGL_INFO, "NSEI=%u/BVCI=%u Cell ID %s\n",
+ nsei, bvci, osmo_rai_name(&raid));
}
if (cfg->route_to_sgsn2)
copy_to_sgsn2 = 1;
@@ -1180,7 +1195,7 @@ static int gbprox_rx_sig_from_sgsn(struct gbproxy_config *cfg,
return bssgp_tx_status(BSSGP_CAUSE_PROTO_ERR_UNSPEC, NULL, orig_msg);
}
- msg = gprs_msgb_copy(orig_msg, "rx_sig_from_sgsn");
+ msg = bssgp_msgb_copy(orig_msg, "rx_sig_from_sgsn");
gbprox_process_bssgp_dl(cfg, msg, NULL);
/* Update message info */
bgph = (struct bssgp_normal_hdr *) msgb_bssgph(msg);
@@ -1428,12 +1443,12 @@ int gbproxy_init_config(struct gbproxy_config *cfg)
struct timespec tp;
INIT_LLIST_HEAD(&cfg->bts_peers);
- cfg->ctrg = rate_ctr_group_alloc(tall_bsc_ctx, &global_ctrg_desc, 0);
+ cfg->ctrg = rate_ctr_group_alloc(tall_sgsn_ctx, &global_ctrg_desc, 0);
if (!cfg->ctrg) {
LOGP(DGPRS, LOGL_ERROR, "Cannot allocate global counter group!\n");
return -1;
}
- clock_gettime(CLOCK_REALTIME, &tp);
+ osmo_clock_gettime(CLOCK_REALTIME, &tp);
return 0;
}
diff --git a/src/gbproxy/gb_proxy_ctrl.c b/src/gbproxy/gb_proxy_ctrl.c
new file mode 100644
index 000000000..4b7c2f430
--- /dev/null
+++ b/src/gbproxy/gb_proxy_ctrl.c
@@ -0,0 +1,98 @@
+/* Control Interface Implementation for the Gb-proxy */
+/*
+ * (C) 2018 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>
+ * All Rights Reserved
+ *
+ * Author: Daniel Willmann
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <osmocom/core/talloc.h>
+
+
+#include <osmocom/gprs/gprs_bssgp.h>
+#include <osmocom/gprs/gprs_ns.h>
+
+#include <osmocom/ctrl/control_if.h>
+#include <osmocom/ctrl/control_cmd.h>
+#include <osmocom/sgsn/gb_proxy.h>
+#include <osmocom/sgsn/debug.h>
+
+extern vector ctrl_node_vec;
+
+static int get_nsvc_state(struct ctrl_cmd *cmd, void *data)
+{
+ struct gbproxy_config *cfg = data;
+ struct gprs_ns_inst *nsi = cfg->nsi;
+ struct gprs_nsvc *nsvc;
+
+ cmd->reply = talloc_strdup(cmd, "");
+
+ llist_for_each_entry(nsvc, &nsi->gprs_nsvcs, list) {
+ if (nsvc == nsi->unknown_nsvc)
+ continue;
+
+ cmd->reply = gprs_nsvc_state_append(cmd->reply, nsvc);
+ }
+
+ return CTRL_CMD_REPLY;
+}
+
+CTRL_CMD_DEFINE_RO(nsvc_state, "nsvc-state");
+
+static int get_gbproxy_state(struct ctrl_cmd *cmd, void *data)
+{
+ struct gbproxy_config *cfg = data;
+ struct gbproxy_peer *peer;
+
+ cmd->reply = talloc_strdup(cmd, "");
+
+ llist_for_each_entry(peer, &cfg->bts_peers, list) {
+ struct gprs_ra_id raid;
+ gsm48_parse_ra(&raid, peer->ra);
+
+ cmd->reply = talloc_asprintf_append(cmd->reply, "%u,%u,%u,%u,%u,%u,%s\n",
+ peer->nsei, peer->bvci,
+ raid.mcc, raid.mnc,
+ raid.lac, raid.rac,
+ peer->blocked ? "BLOCKED" : "UNBLOCKED");
+ }
+
+ return CTRL_CMD_REPLY;
+}
+
+CTRL_CMD_DEFINE_RO(gbproxy_state, "gbproxy-state");
+
+static int get_num_peers(struct ctrl_cmd *cmd, void *data)
+{
+ struct gbproxy_config *cfg = data;
+
+ cmd->reply = talloc_strdup(cmd, "");
+ cmd->reply = talloc_asprintf_append(cmd->reply, "%u", llist_count(&cfg->bts_peers));
+
+ return CTRL_CMD_REPLY;
+}
+CTRL_CMD_DEFINE_RO(num_peers, "number-of-peers");
+
+int gb_ctrl_cmds_install(void)
+{
+ int rc = 0;
+ rc |= ctrl_cmd_install(CTRL_NODE_ROOT, &cmd_nsvc_state);
+ rc |= ctrl_cmd_install(CTRL_NODE_ROOT, &cmd_gbproxy_state);
+ rc |= ctrl_cmd_install(CTRL_NODE_ROOT, &cmd_num_peers);
+
+ return rc;
+}
diff --git a/src/gprs/gb_proxy_main.c b/src/gbproxy/gb_proxy_main.c
index 853a763a2..8c8398043 100644
--- a/src/gprs/gb_proxy_main.c
+++ b/src/gbproxy/gb_proxy_main.c
@@ -41,23 +41,28 @@
#include <osmocom/gprs/gprs_ns.h>
#include <osmocom/gprs/gprs_bssgp.h>
-#include <openbsc/signal.h>
-#include <openbsc/debug.h>
-#include <openbsc/vty.h>
-#include <openbsc/gb_proxy.h>
+#include <osmocom/sgsn/signal.h>
+#include <osmocom/sgsn/debug.h>
+#include <osmocom/sgsn/vty.h>
+#include <osmocom/sgsn/gb_proxy.h>
+
+#include <osmocom/ctrl/control_vty.h>
+#include <osmocom/ctrl/control_if.h>
+#include <osmocom/ctrl/ports.h>
#include <osmocom/vty/command.h>
#include <osmocom/vty/telnet_interface.h>
#include <osmocom/vty/logging.h>
#include <osmocom/vty/stats.h>
#include <osmocom/vty/ports.h>
+#include <osmocom/vty/misc.h>
#include "../../bscconfig.h"
#define _GNU_SOURCE
#include <getopt.h>
-void *tall_bsc_ctx;
+void *tall_sgsn_ctx;
const char *openbsc_copyright =
"Copyright (C) 2010 Harald Welte and On-Waves\r\n"
@@ -65,8 +70,11 @@ const char *openbsc_copyright =
"This is free software: you are free to change and redistribute it.\r\n"
"There is NO WARRANTY, to the extent permitted by law.\r\n";
-static char *config_file = "osmo_gbproxy.cfg";
-struct gbproxy_config gbcfg = {0};
+#define CONFIG_FILE_DEFAULT "osmo-gbproxy.cfg"
+#define CONFIG_FILE_LEGACY "osmo_gbproxy.cfg"
+
+static char *config_file = NULL;
+struct gbproxy_config *gbcfg;
static int daemonize = 0;
/* Pointer to the SGSN peer */
@@ -80,7 +88,7 @@ static int proxy_ns_cb(enum gprs_ns_evt event, struct gprs_nsvc *nsvc,
switch (event) {
case GPRS_NS_EVT_UNIT_DATA:
- rc = gbprox_rcvmsg(&gbcfg, msg, nsvc->nsei, bvci, nsvc->nsvci);
+ rc = gbprox_rcvmsg(gbcfg, msg, nsvc->nsei, bvci, nsvc->nsvci);
break;
default:
LOGP(DGPRS, LOGL_ERROR, "SGSN: Unknown event %u from NS\n", event);
@@ -108,7 +116,7 @@ static void signal_handler(int signal)
* and then return to the caller, who will abort the process */
case SIGUSR1:
talloc_report(tall_vty_ctx, stderr);
- talloc_report_full(tall_bsc_ctx, stderr);
+ talloc_report_full(tall_sgsn_ctx, stderr);
break;
case SIGUSR2:
talloc_report_full(tall_vty_ctx, stderr);
@@ -129,10 +137,10 @@ static void print_help()
printf(" -h --help this text\n");
printf(" -d option --debug=DNS:DGPRS,0:0 enable debugging\n");
printf(" -D --daemonize Fork the process into a background daemon\n");
- printf(" -c --config-file filename The config file to use.\n");
+ printf(" -c --config-file filename The config file to use [%s]\n", CONFIG_FILE_DEFAULT);
printf(" -s --disable-color\n");
printf(" -T --timestamp Prefix every log line with a timestamp\n");
- printf(" -V --version. Print the version of OpenBSC.\n");
+ printf(" -V --version. Print the version.\n");
printf(" -e --log-level number. Set a global loglevel.\n");
}
@@ -188,6 +196,11 @@ static void handle_options(int argc, char **argv)
break;
}
}
+
+ if (argc > optind) {
+ fprintf(stderr, "Unsupported positional arguments on command line\n");
+ exit(2);
+ }
}
int gbproxy_vty_is_config_node(struct vty *vty, int node)
@@ -250,12 +263,20 @@ static const struct log_info gprs_log_info = {
.num_cat = ARRAY_SIZE(gprs_categories),
};
+static bool file_exists(const char *path)
+{
+ struct stat sb;
+ return stat(path, &sb) ? false : true;
+}
+
int main(int argc, char **argv)
{
int rc;
+ struct ctrl_handle *ctrl;
- tall_bsc_ctx = talloc_named_const(NULL, 0, "nsip_proxy");
- msgb_talloc_ctx_init(tall_bsc_ctx, 0);
+ tall_sgsn_ctx = talloc_named_const(NULL, 0, "nsip_proxy");
+ msgb_talloc_ctx_init(tall_sgsn_ctx, 0);
+ vty_info.tall_ctx = tall_sgsn_ctx;
signal(SIGINT, &signal_handler);
signal(SIGTERM, &signal_handler);
@@ -264,47 +285,82 @@ int main(int argc, char **argv)
signal(SIGUSR2, &signal_handler);
osmo_init_ignore_signals();
- osmo_init_logging(&gprs_log_info);
+ osmo_init_logging2(tall_sgsn_ctx, &gprs_log_info);
vty_info.copyright = openbsc_copyright;
vty_init(&vty_info);
- logging_vty_add_cmds(NULL);
- osmo_stats_vty_add_cmds(&gprs_log_info);
+ logging_vty_add_cmds();
+ osmo_talloc_vty_add_cmds();
+ osmo_stats_vty_add_cmds();
gbproxy_vty_init();
handle_options(argc, argv);
- rate_ctr_init(tall_bsc_ctx);
- osmo_stats_init(tall_bsc_ctx);
+ /* Backwards compatibility: for years, the default config file name was
+ * osmo_gbproxy.cfg. All other Osmocom programs use osmo-*.cfg with a
+ * dash. To be able to use the new config file name without breaking
+ * previous setups that might rely on the legacy default config file
+ * name, we need to look for the old config file if no -c option was
+ * passed AND no file exists with the new default file name. */
+ if (!config_file) {
+ /* No -c option was passed */
+ if (file_exists(CONFIG_FILE_LEGACY)
+ && !file_exists(CONFIG_FILE_DEFAULT))
+ config_file = CONFIG_FILE_LEGACY;
+ else
+ config_file = CONFIG_FILE_DEFAULT;
+ }
+
+ rate_ctr_init(tall_sgsn_ctx);
+ osmo_stats_init(tall_sgsn_ctx);
- bssgp_nsi = gprs_ns_instantiate(&proxy_ns_cb, tall_bsc_ctx);
+ bssgp_nsi = gprs_ns_instantiate(&proxy_ns_cb, tall_sgsn_ctx);
if (!bssgp_nsi) {
LOGP(DGPRS, LOGL_ERROR, "Unable to instantiate NS\n");
exit(1);
}
- gbproxy_init_config(&gbcfg);
- gbcfg.nsi = bssgp_nsi;
+
+ gbcfg = talloc_zero(tall_sgsn_ctx, struct gbproxy_config);
+ if (!gbcfg) {
+ LOGP(DGPRS, LOGL_FATAL, "Unable to allocate config\n");
+ exit(1);
+ }
+ gbproxy_init_config(gbcfg);
+ gbcfg->nsi = bssgp_nsi;
gprs_ns_vty_init(bssgp_nsi);
gprs_ns_set_log_ss(DNS);
bssgp_set_log_ss(DBSSGP);
- osmo_signal_register_handler(SS_L_NS, &gbprox_signal, &gbcfg);
+ osmo_signal_register_handler(SS_L_NS, &gbprox_signal, gbcfg);
- rc = gbproxy_parse_config(config_file, &gbcfg);
+ rc = gbproxy_parse_config(config_file, gbcfg);
if (rc < 0) {
- LOGP(DGPRS, LOGL_FATAL, "Cannot parse config file\n");
+ LOGP(DGPRS, LOGL_FATAL, "Cannot parse config file '%s'\n", config_file);
exit(2);
}
/* start telnet after reading config for vty_get_bind_addr() */
- rc = telnet_init_dynif(tall_bsc_ctx, NULL,
+ rc = telnet_init_dynif(tall_sgsn_ctx, NULL,
vty_get_bind_addr(), OSMO_VTY_PORT_GBPROXY);
if (rc < 0)
exit(1);
- if (!gprs_nsvc_by_nsei(gbcfg.nsi, gbcfg.nsip_sgsn_nsei)) {
+ /* Start control interface after getting config for
+ * ctrl_vty_get_bind_addr() */
+ ctrl = ctrl_interface_setup_dynip(gbcfg, ctrl_vty_get_bind_addr(), OSMO_CTRL_PORT_GBPROXY, NULL);
+ if (!ctrl) {
+ LOGP(DGPRS, LOGL_FATAL, "Failed to create CTRL interface.\n");
+ exit(1);
+ }
+
+ if (gb_ctrl_cmds_install() != 0) {
+ LOGP(DGPRS, LOGL_FATAL, "Failed to install CTRL commands.\n");
+ exit(1);
+ }
+
+ if (!gprs_nsvc_by_nsei(gbcfg->nsi, gbcfg->nsip_sgsn_nsei)) {
LOGP(DGPRS, LOGL_FATAL, "You cannot proxy to NSEI %u "
"without creating that NSEI before\n",
- gbcfg.nsip_sgsn_nsei);
+ gbcfg->nsip_sgsn_nsei);
exit(2);
}
diff --git a/src/gprs/gb_proxy_patch.c b/src/gbproxy/gb_proxy_patch.c
index bee315036..6235b04f4 100644
--- a/src/gprs/gb_proxy_patch.c
+++ b/src/gbproxy/gb_proxy_patch.c
@@ -18,65 +18,71 @@
*
*/
-#include <openbsc/gb_proxy.h>
+#include <osmocom/sgsn/gb_proxy.h>
-#include <openbsc/gprs_utils.h>
-#include <openbsc/gprs_gb_parse.h>
+#include <osmocom/sgsn/gprs_utils.h>
+#include <osmocom/sgsn/gprs_gb_parse.h>
-#include <openbsc/debug.h>
+#include <osmocom/sgsn/debug.h>
#include <osmocom/gprs/protocol/gsm_08_18.h>
#include <osmocom/core/rate_ctr.h>
#include <osmocom/gsm/apn.h>
-extern void *tall_bsc_ctx;
+extern void *tall_sgsn_ctx;
/* patch RA identifier in place */
-static void gbproxy_patch_raid(uint8_t *raid_enc, struct gbproxy_peer *peer,
+static void gbproxy_patch_raid(struct gsm48_ra_id *raid_enc, struct gbproxy_peer *peer,
int to_bss, const char *log_text)
{
struct gbproxy_patch_state *state = &peer->patch_state;
- int old_mcc;
- int old_mnc;
+ struct osmo_plmn_id old_plmn;
struct gprs_ra_id raid;
enum gbproxy_peer_ctr counter =
to_bss ?
GBPROX_PEER_CTR_RAID_PATCHED_SGSN :
GBPROX_PEER_CTR_RAID_PATCHED_BSS;
- if (!state->local_mcc || !state->local_mnc)
+ if (!state->local_plmn.mcc || !state->local_plmn.mnc)
return;
- gsm48_parse_ra(&raid, raid_enc);
+ gsm48_parse_ra(&raid, (uint8_t *)raid_enc);
- old_mcc = raid.mcc;
- old_mnc = raid.mnc;
+ old_plmn = (struct osmo_plmn_id){
+ .mcc = raid.mcc,
+ .mnc = raid.mnc,
+ .mnc_3_digits = raid.mnc_3_digits,
+ };
if (!to_bss) {
/* BSS -> SGSN */
- if (state->local_mcc)
- raid.mcc = peer->cfg->core_mcc;
+ if (state->local_plmn.mcc)
+ raid.mcc = peer->cfg->core_plmn.mcc;
- if (state->local_mnc)
- raid.mnc = peer->cfg->core_mnc;
+ if (state->local_plmn.mnc) {
+ raid.mnc = peer->cfg->core_plmn.mnc;
+ raid.mnc_3_digits = peer->cfg->core_plmn.mnc_3_digits;
+ }
} else {
/* SGSN -> BSS */
- if (state->local_mcc)
- raid.mcc = state->local_mcc;
+ if (state->local_plmn.mcc)
+ raid.mcc = state->local_plmn.mcc;
- if (state->local_mnc)
- raid.mnc = state->local_mnc;
+ if (state->local_plmn.mnc) {
+ raid.mnc = state->local_plmn.mnc;
+ raid.mnc_3_digits = state->local_plmn.mnc_3_digits;
+ }
}
LOGP(DGPRS, LOGL_DEBUG,
"Patching %s to %s: "
- "%d-%d-%d-%d -> %d-%d-%d-%d\n",
+ "%s-%d-%d -> %s\n",
log_text,
to_bss ? "BSS" : "SGSN",
- old_mcc, old_mnc, raid.lac, raid.rac,
- raid.mcc, raid.mnc, raid.lac, raid.rac);
+ osmo_plmn_name(&old_plmn), raid.lac, raid.rac,
+ osmo_rai_name(&raid));
- gsm48_construct_ra(raid_enc, &raid);
+ gsm48_encode_ra(raid_enc, &raid);
rate_ctr_inc(&peer->ctrg->ctr[counter]);
}
@@ -106,7 +112,7 @@ static void gbproxy_patch_apn_ie(struct msgb *msg,
osmo_apn_to_str(str1, apn, apn_len));
*new_apn_ie_len = 0;
- gprs_msgb_resize_area(msg, apn_ie, apn_ie_len, 0);
+ msgb_resize_area(msg, apn_ie, apn_ie_len, 0);
} else {
/* Resize the IE */
char str1[110];
@@ -123,7 +129,7 @@ static void gbproxy_patch_apn_ie(struct msgb *msg,
peer->cfg->core_apn_size));
*new_apn_ie_len = peer->cfg->core_apn_size + 2;
- gprs_msgb_resize_area(msg, apn, apn_len, peer->cfg->core_apn_size);
+ msgb_resize_area(msg, apn, apn_len, peer->cfg->core_apn_size);
memcpy(apn, peer->cfg->core_apn, peer->cfg->core_apn_size);
hdr->apn_len = peer->cfg->core_apn_size;
}
@@ -233,14 +239,14 @@ int gbproxy_patch_llc(struct msgb *msg, uint8_t *llc, size_t llc_len,
}
if (parse_ctx->raid_enc) {
- gbproxy_patch_raid(parse_ctx->raid_enc, peer, parse_ctx->to_bss,
+ gbproxy_patch_raid((struct gsm48_ra_id *)parse_ctx->raid_enc, peer, parse_ctx->to_bss,
parse_ctx->llc_msg_name);
have_patched = 1;
}
if (parse_ctx->old_raid_enc && !parse_ctx->old_raid_is_foreign) {
/* TODO: Patch to invalid if P-TMSI unknown. */
- gbproxy_patch_raid(parse_ctx->old_raid_enc, peer, parse_ctx->to_bss,
+ gbproxy_patch_raid((struct gsm48_ra_id *)parse_ctx->old_raid_enc, peer, parse_ctx->to_bss,
parse_ctx->llc_msg_name);
have_patched = 1;
}
@@ -276,7 +282,7 @@ int gbproxy_patch_llc(struct msgb *msg, uint8_t *llc, size_t llc_len,
return have_patched;
}
-/* patch BSSGP message to use core_mcc/mnc on the SGSN side */
+/* patch BSSGP message to use core_plmn.mcc/mnc on the SGSN side */
void gbproxy_patch_bssgp(struct msgb *msg, uint8_t *bssgp, size_t bssgp_len,
struct gbproxy_peer *peer,
struct gbproxy_link_info *link_info, int *len_change,
@@ -286,7 +292,7 @@ void gbproxy_patch_bssgp(struct msgb *msg, uint8_t *bssgp, size_t bssgp_len,
int err_ctr = -1;
if (parse_ctx->bssgp_raid_enc)
- gbproxy_patch_raid(parse_ctx->bssgp_raid_enc, peer,
+ gbproxy_patch_raid((struct gsm48_ra_id *)parse_ctx->bssgp_raid_enc, peer,
parse_ctx->to_bss, "BSSGP");
if (parse_ctx->need_decryption &&
@@ -392,7 +398,7 @@ void gbproxy_clear_patch_filter(struct gbproxy_match *match)
{
if (match->enable) {
regfree(&match->re_comp);
- match->enable = 0;
+ match->enable = false;
}
talloc_free(match->re_str);
match->re_str = NULL;
@@ -413,8 +419,8 @@ int gbproxy_set_patch_filter(struct gbproxy_match *match, const char *filter,
REG_EXTENDED | REG_NOSUB | REG_ICASE);
if (rc == 0) {
- match->enable = 1;
- match->re_str = talloc_strdup(tall_bsc_ctx, filter);
+ match->enable = true;
+ match->re_str = talloc_strdup(tall_sgsn_ctx, filter);
return 0;
}
@@ -457,4 +463,3 @@ int gbproxy_check_imsi(struct gbproxy_match *match,
return 1;
}
-
diff --git a/src/gprs/gb_proxy_peer.c b/src/gbproxy/gb_proxy_peer.c
index a83630bc1..48482b6a1 100644
--- a/src/gprs/gb_proxy_peer.c
+++ b/src/gbproxy/gb_proxy_peer.c
@@ -20,9 +20,9 @@
*
*/
-#include <openbsc/gb_proxy.h>
+#include <osmocom/sgsn/gb_proxy.h>
-#include <openbsc/debug.h>
+#include <osmocom/sgsn/debug.h>
#include <osmocom/gprs/protocol/gsm_08_18.h>
#include <osmocom/core/rate_ctr.h>
@@ -32,7 +32,7 @@
#include <string.h>
-extern void *tall_bsc_ctx;
+extern void *tall_sgsn_ctx;
static const struct rate_ctr_desc peer_ctr_description[] = {
{ "blocked", "BVC Block " },
@@ -40,13 +40,13 @@ static const struct rate_ctr_desc peer_ctr_description[] = {
{ "dropped", "BVC blocked, dropped packet " },
{ "inv-nsei", "NSEI mismatch " },
{ "tx-err", "NS Transmission error " },
- { "raid-mod.bss", "RAID patched (BSS )" },
- { "raid-mod.sgsn", "RAID patched (SGSN)" },
- { "apn-mod.sgsn", "APN patched " },
- { "tlli-mod.bss", "TLLI patched (BSS )" },
- { "tlli-mod.sgsn", "TLLI patched (SGSN)" },
- { "ptmsi-mod.bss", "P-TMSI patched (BSS )" },
- { "ptmsi-mod.sgsn","P-TMSI patched (SGSN)" },
+ { "raid-mod:bss", "RAID patched (BSS )" },
+ { "raid-mod:sgsn", "RAID patched (SGSN)" },
+ { "apn-mod:sgsn", "APN patched " },
+ { "tlli-mod:bss", "TLLI patched (BSS )" },
+ { "tlli-mod:sgsn", "TLLI patched (SGSN)" },
+ { "ptmsi-mod:bss", "P-TMSI patched (BSS )" },
+ { "ptmsi-mod:sgsn","P-TMSI patched (SGSN)" },
{ "mod-crypt-err", "Patch error: encrypted " },
{ "mod-err", "Patch error: other " },
{ "attach-reqs", "Attach Request count " },
@@ -73,7 +73,7 @@ static const struct rate_ctr_desc peer_ctr_description[] = {
osmo_static_assert(ARRAY_SIZE(peer_ctr_description) == GBPROX_PEER_CTR_LAST, everything_described);
static const struct rate_ctr_group_desc peer_ctrg_desc = {
- .group_name_prefix = "gbproxy.peer",
+ .group_name_prefix = "gbproxy:peer",
.group_description = "GBProxy Peer Statistics",
.num_ctr = ARRAY_SIZE(peer_ctr_description),
.ctr_desc = peer_ctr_description,
@@ -167,12 +167,25 @@ struct gbproxy_peer *gbproxy_peer_by_bssgp_tlv(struct gbproxy_config *cfg,
return NULL;
}
+static void clean_stale_timer_cb(void *data)
+{
+ time_t now;
+ struct timespec ts = {0,};
+ struct gbproxy_peer *peer = (struct gbproxy_peer *) data;
+
+ osmo_clock_gettime(CLOCK_MONOTONIC, &ts);
+ now = ts.tv_sec;
+ gbproxy_remove_stale_link_infos(peer, now);
+ if (peer->cfg->clean_stale_timer_freq != 0)
+ osmo_timer_schedule(&peer->clean_stale_timer,
+ peer->cfg->clean_stale_timer_freq, 0);
+}
struct gbproxy_peer *gbproxy_peer_alloc(struct gbproxy_config *cfg, uint16_t bvci)
{
struct gbproxy_peer *peer;
- peer = talloc_zero(tall_bsc_ctx, struct gbproxy_peer);
+ peer = talloc_zero(tall_sgsn_ctx, struct gbproxy_peer);
if (!peer)
return NULL;
@@ -188,13 +201,18 @@ struct gbproxy_peer *gbproxy_peer_alloc(struct gbproxy_config *cfg, uint16_t bvc
INIT_LLIST_HEAD(&peer->patch_state.logical_links);
+ osmo_timer_setup(&peer->clean_stale_timer, clean_stale_timer_cb, peer);
+ if (peer->cfg->clean_stale_timer_freq != 0)
+ osmo_timer_schedule(&peer->clean_stale_timer,
+ peer->cfg->clean_stale_timer_freq, 0);
+
return peer;
}
void gbproxy_peer_free(struct gbproxy_peer *peer)
{
llist_del(&peer->list);
-
+ osmo_timer_del(&peer->clean_stale_timer);
gbproxy_delete_link_infos(peer);
rate_ctr_group_free(peer->ctrg);
@@ -220,4 +238,3 @@ int gbproxy_cleanup_peers(struct gbproxy_config *cfg, uint16_t nsei, uint16_t bv
return counter;
}
-
diff --git a/src/gprs/gb_proxy_tlli.c b/src/gbproxy/gb_proxy_tlli.c
index 3b3b976a5..4e21ede86 100644
--- a/src/gprs/gb_proxy_tlli.c
+++ b/src/gbproxy/gb_proxy_tlli.c
@@ -20,12 +20,12 @@
#include <osmocom/gsm/gsm48.h>
-#include <openbsc/gb_proxy.h>
+#include <osmocom/sgsn/gb_proxy.h>
-#include <openbsc/gprs_utils.h>
-#include <openbsc/gprs_gb_parse.h>
+#include <osmocom/sgsn/gprs_utils.h>
+#include <osmocom/sgsn/gprs_gb_parse.h>
-#include <openbsc/debug.h>
+#include <osmocom/sgsn/debug.h>
#include <osmocom/gsm/gsm_utils.h>
@@ -284,8 +284,8 @@ void gbproxy_reassign_tlli(struct gbproxy_tlli_state *tlli_state,
/* Remember assigned TLLI */
tlli_state->assigned = new_tlli;
- tlli_state->bss_validated = 0;
- tlli_state->net_validated = 0;
+ tlli_state->bss_validated = false;
+ tlli_state->net_validated = false;
}
uint32_t gbproxy_map_tlli(uint32_t other_tlli,
@@ -325,9 +325,9 @@ static void gbproxy_validate_tlli(struct gbproxy_tlli_state *tlli_state,
/* See GSM 04.08, 4.7.1.5 */
if (to_bss)
- tlli_state->net_validated = 1;
+ tlli_state->net_validated = true;
else
- tlli_state->bss_validated = 1;
+ tlli_state->bss_validated = true;
if (!tlli_state->bss_validated || !tlli_state->net_validated)
return;
@@ -367,7 +367,7 @@ static int gbproxy_unregister_link_info(struct gbproxy_peer *peer,
link_info->sgsn_tlli.current = 0;
link_info->sgsn_tlli.assigned = 0;
- link_info->is_deregistered = 1;
+ link_info->is_deregistered = true;
gbproxy_reset_link(link_info);
@@ -388,7 +388,7 @@ int gbproxy_imsi_matches(struct gbproxy_config *cfg,
return link_info != NULL && link_info->is_matching[match_id];
}
-void gbproxy_assign_imsi(struct gbproxy_peer *peer,
+static void gbproxy_assign_imsi(struct gbproxy_peer *peer,
struct gbproxy_link_info *link_info,
struct gprs_gb_parse_context *parse_ctx)
{
@@ -424,7 +424,7 @@ void gbproxy_assign_imsi(struct gbproxy_peer *peer,
&peer->cfg->matches[match_id],
parse_ctx->imsi, parse_ctx->imsi_len);
if (imsi_matches >= 0)
- link_info->is_matching[match_id] = imsi_matches;
+ link_info->is_matching[match_id] = imsi_matches ? true : false;
}
}
@@ -498,7 +498,7 @@ static struct gbproxy_link_info *gbproxy_get_link_info_ul(
if (!link_info)
return NULL;
- link_info->is_deregistered = 0;
+ link_info->is_deregistered = false;
return link_info;
}
@@ -577,7 +577,7 @@ static struct gbproxy_link_info *gbproxy_get_link_info_dl(
peer, parse_ctx->imsi, parse_ctx->imsi_len);
if (link_info)
- link_info->is_deregistered = 0;
+ link_info->is_deregistered = false;
return link_info;
}
diff --git a/src/gprs/gb_proxy_vty.c b/src/gbproxy/gb_proxy_vty.c
index bd5bb1b5b..5c4f45420 100644
--- a/src/gprs/gb_proxy_vty.c
+++ b/src/gbproxy/gb_proxy_vty.c
@@ -23,6 +23,7 @@
#include <arpa/inet.h>
#include <string.h>
#include <time.h>
+#include <inttypes.h>
#include <osmocom/core/talloc.h>
#include <osmocom/core/rate_ctr.h>
@@ -31,10 +32,10 @@
#include <osmocom/gprs/gprs_ns.h>
#include <osmocom/gsm/apn.h>
-#include <openbsc/debug.h>
-#include <openbsc/gb_proxy.h>
-#include <openbsc/gprs_utils.h>
-#include <openbsc/vty.h>
+#include <osmocom/sgsn/debug.h>
+#include <osmocom/sgsn/gb_proxy.h>
+#include <osmocom/sgsn/gprs_utils.h>
+#include <osmocom/sgsn/vty.h>
#include <osmocom/vty/command.h>
#include <osmocom/vty/vty.h>
@@ -43,7 +44,7 @@
static struct gbproxy_config *g_cfg = NULL;
/*
- * vty code for mgcp below
+ * vty code for gbproxy below
*/
static struct cmd_node gbproxy_node = {
GBPROXY_NODE,
@@ -71,9 +72,7 @@ static void gbprox_vty_print_peer(struct vty *vty, struct gbproxy_peer *peer)
gsm48_parse_ra(&raid, peer->ra);
vty_out(vty, "NSEI %5u, PTP-BVCI %5u, "
- "RAI %u-%u-%u-%u",
- peer->nsei, peer->bvci,
- raid.mcc, raid.mnc, raid.lac, raid.rac);
+ "RAI %s", peer->nsei, peer->bvci, osmo_rai_name(&raid));
if (peer->blocked)
vty_out(vty, " [BVC-BLOCKED]");
@@ -89,12 +88,12 @@ static int config_write_gbproxy(struct vty *vty)
vty_out(vty, " sgsn nsei %u%s", g_cfg->nsip_sgsn_nsei,
VTY_NEWLINE);
- if (g_cfg->core_mcc > 0)
- vty_out(vty, " core-mobile-country-code %d%s",
- g_cfg->core_mcc, VTY_NEWLINE);
- if (g_cfg->core_mnc > 0)
- vty_out(vty, " core-mobile-network-code %d%s",
- g_cfg->core_mnc, VTY_NEWLINE);
+ if (g_cfg->core_plmn.mcc > 0)
+ vty_out(vty, " core-mobile-country-code %s%s",
+ osmo_mcc_name(g_cfg->core_plmn.mcc), VTY_NEWLINE);
+ if (g_cfg->core_plmn.mnc > 0)
+ vty_out(vty, " core-mobile-network-code %s%s",
+ osmo_mnc_name(g_cfg->core_plmn.mnc, g_cfg->core_plmn.mnc_3_digits), VTY_NEWLINE);
for (match_id = 0; match_id < ARRAY_SIZE(g_cfg->matches); ++match_id) {
struct gbproxy_match *match = &g_cfg->matches[match_id];
@@ -121,6 +120,9 @@ static int config_write_gbproxy(struct vty *vty)
vty_out(vty, " secondary-sgsn nsei %u%s", g_cfg->nsip_sgsn2_nsei,
VTY_NEWLINE);
+ if (g_cfg->clean_stale_timer_freq > 0)
+ vty_out(vty, " link-list clean-stale-timer %u%s",
+ g_cfg->clean_stale_timer_freq, VTY_NEWLINE);
if (g_cfg->tlli_max_age > 0)
vty_out(vty, " link-list max-age %d%s",
g_cfg->tlli_max_age, VTY_NEWLINE);
@@ -130,6 +132,9 @@ static int config_write_gbproxy(struct vty *vty)
vty_out(vty, " link-list keep-mode %s%s",
get_value_string(keep_modes, g_cfg->keep_link_infos),
VTY_NEWLINE);
+ if (g_cfg->stored_msgs_max_len > 0)
+ vty_out(vty, " link stored-msgs-max-length %"PRIu32"%s",
+ g_cfg->stored_msgs_max_len, VTY_NEWLINE);
return CMD_SUCCESS;
@@ -170,7 +175,14 @@ DEFUN(cfg_gbproxy_core_mnc,
"core-mobile-network-code <1-999>",
GBPROXY_CORE_MNC_STR "NCC value\n")
{
- g_cfg->core_mnc = atoi(argv[0]);
+ uint16_t mnc;
+ bool mnc_3_digits;
+ if (osmo_mnc_from_str(argv[0], &mnc, &mnc_3_digits)) {
+ vty_out(vty, "%% Invalid MNC: %s%s", argv[0], VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ g_cfg->core_plmn.mnc = mnc;
+ g_cfg->core_plmn.mnc_3_digits = mnc_3_digits;
return CMD_SUCCESS;
}
@@ -179,7 +191,8 @@ DEFUN(cfg_gbproxy_no_core_mnc,
"no core-mobile-network-code",
NO_STR GBPROXY_CORE_MNC_STR)
{
- g_cfg->core_mnc = 0;
+ g_cfg->core_plmn.mnc = 0;
+ g_cfg->core_plmn.mnc_3_digits = false;
return CMD_SUCCESS;
}
@@ -190,7 +203,7 @@ DEFUN(cfg_gbproxy_core_mcc,
"core-mobile-country-code <1-999>",
GBPROXY_CORE_MCC_STR "MCC value\n")
{
- g_cfg->core_mcc = atoi(argv[0]);
+ g_cfg->core_plmn.mcc = atoi(argv[0]);
return CMD_SUCCESS;
}
@@ -199,7 +212,7 @@ DEFUN(cfg_gbproxy_no_core_mcc,
"no core-mobile-country-code",
NO_STR GBPROXY_CORE_MCC_STR)
{
- g_cfg->core_mcc = 0;
+ g_cfg->core_plmn.mcc = 0;
return CMD_SUCCESS;
}
@@ -228,7 +241,7 @@ DEFUN(cfg_gbproxy_match_imsi,
return CMD_WARNING;
}
- g_cfg->acquire_imsi = 1;
+ g_cfg->acquire_imsi = true;
return CMD_SUCCESS;
}
@@ -243,7 +256,7 @@ DEFUN(cfg_gbproxy_no_match_imsi,
for (match_id = 0; match_id < ARRAY_SIZE(g_cfg->matches); ++match_id)
gbproxy_clear_patch_filter(&g_cfg->matches[match_id]);
- g_cfg->acquire_imsi = 0;
+ g_cfg->acquire_imsi = false;
return CMD_SUCCESS;
}
@@ -316,7 +329,7 @@ DEFUN(cfg_gbproxy_patch_ptmsi,
"patch-ptmsi",
GBPROXY_PATCH_PTMSI_STR)
{
- g_cfg->patch_ptmsi = 1;
+ g_cfg->patch_ptmsi = true;
return CMD_SUCCESS;
}
@@ -326,7 +339,7 @@ DEFUN(cfg_gbproxy_no_patch_ptmsi,
"no patch-ptmsi",
NO_STR GBPROXY_PATCH_PTMSI_STR)
{
- g_cfg->patch_ptmsi = 0;
+ g_cfg->patch_ptmsi = false;
return CMD_SUCCESS;
}
@@ -342,7 +355,7 @@ DEFUN(cfg_gbproxy_acquire_imsi,
"acquire-imsi",
GBPROXY_ACQUIRE_IMSI_STR)
{
- g_cfg->acquire_imsi = 1;
+ g_cfg->acquire_imsi = true;
return CMD_SUCCESS;
}
@@ -352,7 +365,7 @@ DEFUN(cfg_gbproxy_no_acquire_imsi,
"no acquire-imsi",
NO_STR GBPROXY_ACQUIRE_IMSI_STR)
{
- g_cfg->acquire_imsi = 0;
+ g_cfg->acquire_imsi = false;
return CMD_SUCCESS;
}
@@ -374,10 +387,10 @@ DEFUN(cfg_gbproxy_secondary_sgsn,
return CMD_WARNING;
}
- g_cfg->route_to_sgsn2 = 1;
+ g_cfg->route_to_sgsn2 = true;
g_cfg->nsip_sgsn2_nsei = nsei;
- g_cfg->patch_ptmsi = 1;
+ g_cfg->patch_ptmsi = true;
return CMD_SUCCESS;
}
@@ -387,15 +400,54 @@ DEFUN(cfg_gbproxy_no_secondary_sgsn,
"no secondary-sgsn",
NO_STR GBPROXY_SECOND_SGSN_STR)
{
- g_cfg->route_to_sgsn2 = 0;
+ g_cfg->route_to_sgsn2 = false;
g_cfg->nsip_sgsn2_nsei = 0xFFFF;
- g_cfg->patch_ptmsi = 0;
+ g_cfg->patch_ptmsi = false;
return CMD_SUCCESS;
}
#define GBPROXY_LINK_LIST_STR "Set TLLI list parameters\n"
+#define GBPROXY_LINK_STR "Set TLLI parameters\n"
+
+#define GBPROXY_CLEAN_STALE_TIMER_STR "Periodic timer to clean stale links\n"
+
+DEFUN(cfg_gbproxy_link_list_clean_stale_timer,
+ cfg_gbproxy_link_list_clean_stale_timer_cmd,
+ "link-list clean-stale-timer <1-999999>",
+ GBPROXY_LINK_LIST_STR GBPROXY_CLEAN_STALE_TIMER_STR
+ "Frequency at which the periodic timer is fired (in seconds)\n")
+{
+ struct gbproxy_peer *peer;
+ g_cfg->clean_stale_timer_freq = (unsigned int) atoi(argv[0]);
+
+ /* Re-schedule running timers soon in case prev frequency was really big
+ and new frequency is desired to be lower. After initial run, periodic
+ time is used. Use random() to avoid firing timers for all peers at
+ the same time */
+ llist_for_each_entry(peer, &g_cfg->bts_peers, list)
+ osmo_timer_schedule(&peer->clean_stale_timer,
+ random() % 5, random() % 1000000);
+
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_gbproxy_link_list_no_clean_stale_timer,
+ cfg_gbproxy_link_list_no_clean_stale_timer_cmd,
+ "no link-list clean-stale-timer",
+ NO_STR GBPROXY_LINK_LIST_STR GBPROXY_CLEAN_STALE_TIMER_STR)
+
+{
+ struct gbproxy_peer *peer;
+ g_cfg->clean_stale_timer_freq = 0;
+
+ llist_for_each_entry(peer, &g_cfg->bts_peers, list)
+ osmo_timer_del(&peer->clean_stale_timer);
+
+ return CMD_SUCCESS;
+}
+
#define GBPROXY_MAX_AGE_STR "Limit maximum age\n"
DEFUN(cfg_gbproxy_link_list_max_age,
@@ -458,6 +510,27 @@ DEFUN(cfg_gbproxy_link_list_keep_mode,
return CMD_SUCCESS;
}
+DEFUN(cfg_gbproxy_link_stored_msgs_max_len,
+ cfg_gbproxy_link_stored_msgs_max_len_cmd,
+ "link stored-msgs-max-length <1-99999>",
+ GBPROXY_LINK_STR GBPROXY_MAX_LEN_STR
+ "Maximum number of msgb stored in the logical link waiting to acquire its IMSI\n")
+{
+ g_cfg->stored_msgs_max_len = (uint32_t) atoi(argv[0]);
+
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_gbproxy_link_no_stored_msgs_max_len,
+ cfg_gbproxy_link_no_stored_msgs_max_len_cmd,
+ "no link stored-msgs-max-length",
+ NO_STR GBPROXY_LINK_STR GBPROXY_MAX_LEN_STR)
+{
+ g_cfg->stored_msgs_max_len = 0;
+
+ return CMD_SUCCESS;
+}
+
DEFUN(show_gbproxy, show_gbproxy_cmd, "show gbproxy [stats]",
SHOW_STR "Display information about the Gb proxy\n" "Show statistics\n")
@@ -485,7 +558,7 @@ DEFUN(show_gbproxy_links, show_gbproxy_links_cmd, "show gbproxy links",
time_t now;
struct timespec ts = {0,};
- clock_gettime(CLOCK_MONOTONIC, &ts);
+ osmo_clock_gettime(CLOCK_MONOTONIC, &ts);
now = ts.tv_sec;
llist_for_each_entry(peer, &g_cfg->bts_peers, list) {
@@ -496,10 +569,6 @@ DEFUN(show_gbproxy_links, show_gbproxy_links_cmd, "show gbproxy links",
llist_for_each_entry(link_info, &state->logical_links, list) {
time_t age = now - link_info->timestamp;
- int stored_msgs = 0;
- struct llist_head *iter;
- llist_for_each(iter, &link_info->stored_msgs)
- stored_msgs++;
if (link_info->imsi > 0) {
snprintf(mi_buf, sizeof(mi_buf), "(invalid)");
@@ -512,8 +581,10 @@ DEFUN(show_gbproxy_links, show_gbproxy_links_cmd, "show gbproxy links",
vty_out(vty, " TLLI %08x, IMSI %s, AGE %d",
link_info->tlli.current, mi_buf, (int)age);
- if (stored_msgs)
- vty_out(vty, ", STORED %d", stored_msgs);
+ if (link_info->stored_msgs_len)
+ vty_out(vty, ", STORED %"PRIu32"/%"PRIu32,
+ link_info->stored_msgs_len,
+ g_cfg->stored_msgs_max_len);
if (g_cfg->route_to_sgsn2)
vty_out(vty, ", SGSN NSEI %d",
@@ -721,7 +792,7 @@ DEFUN(delete_gb_link, delete_gb_link_cmd,
state = &peer->patch_state;
- clock_gettime(CLOCK_MONOTONIC, &ts);
+ osmo_clock_gettime(CLOCK_MONOTONIC, &ts);
now = ts.tv_sec;
if (match == MATCH_STALE) {
@@ -778,7 +849,7 @@ DEFUN_DEPRECATED(cfg_gbproxy_broken_apn_match,
return CMD_WARNING;
}
- g_cfg->acquire_imsi = 1;
+ g_cfg->acquire_imsi = true;
return CMD_SUCCESS;
}
@@ -808,7 +879,6 @@ int gbproxy_vty_init(void)
install_element(CONFIG_NODE, &cfg_gbproxy_cmd);
install_node(&gbproxy_node, config_write_gbproxy);
- vty_install_default(GBPROXY_NODE);
install_element(GBPROXY_NODE, &cfg_nsip_sgsn_nsei_cmd);
install_element(GBPROXY_NODE, &cfg_gbproxy_core_mcc_cmd);
install_element(GBPROXY_NODE, &cfg_gbproxy_core_mnc_cmd);
@@ -817,9 +887,11 @@ int gbproxy_vty_init(void)
install_element(GBPROXY_NODE, &cfg_gbproxy_secondary_sgsn_cmd);
install_element(GBPROXY_NODE, &cfg_gbproxy_patch_ptmsi_cmd);
install_element(GBPROXY_NODE, &cfg_gbproxy_acquire_imsi_cmd);
+ install_element(GBPROXY_NODE, &cfg_gbproxy_link_list_clean_stale_timer_cmd);
install_element(GBPROXY_NODE, &cfg_gbproxy_link_list_max_age_cmd);
install_element(GBPROXY_NODE, &cfg_gbproxy_link_list_max_len_cmd);
install_element(GBPROXY_NODE, &cfg_gbproxy_link_list_keep_mode_cmd);
+ install_element(GBPROXY_NODE, &cfg_gbproxy_link_stored_msgs_max_len_cmd);
install_element(GBPROXY_NODE, &cfg_gbproxy_no_core_mcc_cmd);
install_element(GBPROXY_NODE, &cfg_gbproxy_no_core_mnc_cmd);
install_element(GBPROXY_NODE, &cfg_gbproxy_no_match_imsi_cmd);
@@ -827,8 +899,10 @@ int gbproxy_vty_init(void)
install_element(GBPROXY_NODE, &cfg_gbproxy_no_secondary_sgsn_cmd);
install_element(GBPROXY_NODE, &cfg_gbproxy_no_patch_ptmsi_cmd);
install_element(GBPROXY_NODE, &cfg_gbproxy_no_acquire_imsi_cmd);
+ install_element(GBPROXY_NODE, &cfg_gbproxy_link_list_no_clean_stale_timer_cmd);
install_element(GBPROXY_NODE, &cfg_gbproxy_link_list_no_max_age_cmd);
install_element(GBPROXY_NODE, &cfg_gbproxy_link_list_no_max_len_cmd);
+ install_element(GBPROXY_NODE, &cfg_gbproxy_link_no_stored_msgs_max_len_cmd);
/* broken or deprecated to allow an upgrade path */
install_element(GBPROXY_NODE, &cfg_gbproxy_broken_apn_match_cmd);
@@ -850,4 +924,3 @@ int gbproxy_parse_config(const char *config_file, struct gbproxy_config *cfg)
return 0;
}
-
diff --git a/src/gprs/Makefile.am b/src/gprs/Makefile.am
index 654604b80..170ded8fc 100644
--- a/src/gprs/Makefile.am
+++ b/src/gprs/Makefile.am
@@ -13,9 +13,9 @@ AM_CFLAGS = \
$(LIBOSMOCTRL_CFLAGS) \
$(LIBOSMOABIS_CFLAGS) \
$(LIBOSMOGB_CFLAGS) \
+ $(LIBOSMOGSUPCLIENT_CFLAGS) \
$(COVERAGE_CFLAGS) \
$(LIBCARES_CFLAGS) \
- $(LIBCRYPTO_CFLAGS) \
$(LIBGTP_CFLAGS) \
$(NULL)
if BUILD_IU
@@ -26,107 +26,21 @@ AM_CFLAGS += \
$(NULL)
endif
-OSMO_LIBS = \
- $(LIBOSMOCORE_LIBS) \
- $(LIBOSMOABIS_LIBS) \
- $(LIBOSMOGSM_LIBS) \
- $(LIBOSMOVTY_LIBS) \
- $(LIBOSMOCTRL_LIBS) \
- $(LIBOSMOGB_LIBS) \
- $(LIBGTP_LIBS) \
- $(LIBOSMOSIGTRAN_LIBS) \
- $(NULL)
+noinst_LTLIBRARIES = libcommon.la
-bin_PROGRAMS = \
- osmo-gbproxy \
- $(NULL)
-if HAVE_LIBGTP
-if HAVE_LIBCARES
-bin_PROGRAMS += \
- osmo-sgsn \
- osmo-gtphub \
- $(NULL)
-endif
-endif
-
-osmo_gbproxy_SOURCES = \
- gb_proxy.c \
- gb_proxy_main.c \
- gb_proxy_vty.c \
- gb_proxy_patch.c \
- gb_proxy_tlli.c \
- gb_proxy_peer.c \
+libcommon_la_SOURCES = \
gprs_gb_parse.c \
gprs_llc_parse.c \
crc24.c \
gprs_utils.c \
- $(NULL)
-osmo_gbproxy_LDADD = \
- $(OSMO_LIBS) \
- $(LIBCRYPTO_LIBS) \
- -lrt \
- $(NULL)
-
-osmo_sgsn_SOURCES = \
- gprs_gmm.c \
- gprs_sgsn.c \
- gprs_sndcp.c \
- gprs_sndcp_comp.c \
- gprs_sndcp_dcomp.c \
- gprs_sndcp_pcomp.c \
- gprs_sndcp_vty.c \
- gprs_sndcp_xid.c \
- sgsn_main.c \
- sgsn_vty.c \
- sgsn_libgtp.c \
- gprs_llc.c \
- gprs_llc_parse.c \
- gprs_llc_vty.c \
- crc24.c \
- sgsn_ctrl.c \
- sgsn_auth.c \
- gprs_subscriber.c \
- gprs_utils.c \
- sgsn_cdr.c \
sgsn_ares.c \
- slhc.c \
- gprs_llc_xid.c \
- v42bis.c \
- gsup_client.c \
- oap_client.c \
- $(NULL)
-osmo_sgsn_LDADD = \
- $(OSMO_LIBS) \
- $(LIBOSMOABIS_LIBS) \
- $(LIBCARES_LIBS) \
- $(LIBCRYPTO_LIBS) \
- $(LIBGTP_LIBS) \
- -lrt \
- -lm \
- $(NULL)
-if BUILD_IU
-osmo_sgsn_LDADD += \
- $(LIBOSMOSIGTRAN_LIBS) \
- $(LIBOSMORANAP_LIBS) \
- $(LIBASN1C_LIBS) \
$(NULL)
-endif
-osmo_gtphub_SOURCES = \
- gtphub_main.c \
- gtphub.c \
- gtphub_sock.c \
- gtphub_ares.c \
- gtphub_vty.c \
- sgsn_ares.c \
- gprs_utils.c \
- $(NULL)
-osmo_gtphub_LDADD = \
+libcommon_la_LIBADD = \
$(LIBOSMOCORE_LIBS) \
$(LIBOSMOGSM_LIBS) \
$(LIBOSMOVTY_LIBS) \
- $(LIBCARES_LIBS) \
$(LIBGTP_LIBS) \
$(LIBOSMOSIGTRAN_LIBS) \
- -lrt \
+ $(LIBCARES_LIBS) \
$(NULL)
diff --git a/src/gprs/crc24.c b/src/gprs/crc24.c
index 1a420ed66..da269b375 100644
--- a/src/gprs/crc24.c
+++ b/src/gprs/crc24.c
@@ -19,7 +19,7 @@
*
*/
-#include <openbsc/crc24.h>
+#include <osmocom/sgsn/crc24.h>
/* CRC24 table - FCS */
static const uint32_t tbl_crc24[256] = {
diff --git a/src/gprs/gprs_gb_parse.c b/src/gprs/gprs_gb_parse.c
index d5a122bda..379674a91 100644
--- a/src/gprs/gprs_gb_parse.c
+++ b/src/gprs/gprs_gb_parse.c
@@ -21,11 +21,11 @@
#include <osmocom/gsm/gsm48.h>
#include <osmocom/gsm/protocol/gsm_04_08_gprs.h>
-#include <openbsc/gprs_gb_parse.h>
+#include <osmocom/sgsn/gprs_gb_parse.h>
-#include <openbsc/gprs_utils.h>
+#include <osmocom/sgsn/gprs_utils.h>
-#include <openbsc/debug.h>
+#include <osmocom/sgsn/debug.h>
#include <osmocom/gprs/gprs_bssgp.h>
@@ -46,7 +46,8 @@ static int gprs_gb_parse_gmm_attach_req(uint8_t *data, size_t data_len,
/* Skip Attach type */
/* Skip Ciphering key sequence number */
/* Skip DRX parameter */
- osmo_shift_v_fixed(&data, &data_len, 3, NULL);
+ if (osmo_shift_v_fixed(&data, &data_len, 3, NULL) < 3)
+ return 0;
/* Get Mobile identity */
if (osmo_shift_lv(&data, &data_len, &value, &value_len) <= 0 ||
@@ -82,7 +83,8 @@ static int gprs_gb_parse_gmm_attach_ack(uint8_t *data, size_t data_len,
/* Skip Periodic RA update timer */
/* Skip Radio priority for SMS */
/* Skip Spare half octet */
- osmo_shift_v_fixed(&data, &data_len, 3, NULL);
+ if (osmo_shift_v_fixed(&data, &data_len, 3, NULL) < 3)
+ return 0;
if (osmo_shift_v_fixed(&data, &data_len, 6, &value) <= 0)
return 0;
@@ -170,7 +172,8 @@ static int gprs_gb_parse_gmm_ra_upd_req(uint8_t *data, size_t data_len,
/* Skip Update type */
/* Skip GPRS ciphering key sequence number */
- osmo_shift_v_fixed(&data, &data_len, 1, NULL);
+ if (osmo_shift_v_fixed(&data, &data_len, 1, NULL) < 1)
+ return 0;
if (osmo_shift_v_fixed(&data, &data_len, 6, &value) <= 0)
return 0;
@@ -221,7 +224,8 @@ static int gprs_gb_parse_gmm_ra_upd_ack(uint8_t *data, size_t data_len,
/* Skip Force to standby */
/* Skip Update result */
/* Skip Periodic RA update timer */
- osmo_shift_v_fixed(&data, &data_len, 2, NULL);
+ if (osmo_shift_v_fixed(&data, &data_len, 2, NULL) < 2)
+ return 0;
if (osmo_shift_v_fixed(&data, &data_len, 6, &value) <= 0)
return 0;
@@ -299,7 +303,8 @@ static int gprs_gb_parse_gsm_act_pdp_req(uint8_t *data, size_t data_len,
/* Skip Requested NSAPI */
/* Skip Requested LLC SAPI */
- osmo_shift_v_fixed(&data, &data_len, 2, NULL);
+ if (osmo_shift_v_fixed(&data, &data_len, 2, NULL) < 2)
+ return 0;
/* Skip Requested QoS (support 04.08 and 24.008) */
if (osmo_shift_lv(&data, &data_len, NULL, &value_len) <= 0 ||
@@ -378,6 +383,14 @@ int gprs_gb_parse_dtap(uint8_t *data, size_t data_len,
parse_ctx->invalidate_tlli = 1;
break;
+ case GSM48_MT_GSM_DEACT_PDP_REQ:
+ parse_ctx->llc_msg_name = "DEACT_PDP_REQ";
+ break;
+
+ case GSM48_MT_GSM_DEACT_PDP_ACK:
+ parse_ctx->llc_msg_name = "DEACT_PDP_ACK";
+ break;
+
default:
LOGP(DLLC, LOGL_NOTICE,
"Unhandled GSM 04.08 message type %s for protocol discriminator %s.\n",
@@ -551,24 +564,21 @@ void gprs_gb_log_parse_context(int log_level,
if (parse_ctx->bssgp_raid_enc) {
struct gprs_ra_id raid;
gsm48_parse_ra(&raid, parse_ctx->bssgp_raid_enc);
- LOGPC(DGPRS, log_level, "%s BSSGP RAID %u-%u-%u-%u", sep,
- raid.mcc, raid.mnc, raid.lac, raid.rac);
+ LOGPC(DGPRS, log_level, "%s BSSGP RAID %s", sep, osmo_rai_name(&raid));
sep = ",";
}
if (parse_ctx->raid_enc) {
struct gprs_ra_id raid;
gsm48_parse_ra(&raid, parse_ctx->raid_enc);
- LOGPC(DGPRS, log_level, "%s RAID %u-%u-%u-%u", sep,
- raid.mcc, raid.mnc, raid.lac, raid.rac);
+ LOGPC(DGPRS, log_level, "%s RAID %s", sep, osmo_rai_name(&raid));
sep = ",";
}
if (parse_ctx->old_raid_enc) {
struct gprs_ra_id raid;
gsm48_parse_ra(&raid, parse_ctx->old_raid_enc);
- LOGPC(DGPRS, log_level, "%s old RAID %u-%u-%u-%u", sep,
- raid.mcc, raid.mnc, raid.lac, raid.rac);
+ LOGPC(DGPRS, log_level, "%s old RAID %s", sep, osmo_rai_name(&raid));
sep = ",";
}
diff --git a/src/gprs/gprs_llc_parse.c b/src/gprs/gprs_llc_parse.c
index be634974a..1d97004e0 100644
--- a/src/gprs/gprs_llc_parse.c
+++ b/src/gprs/gprs_llc_parse.c
@@ -28,11 +28,11 @@
#include <osmocom/core/talloc.h>
#include <osmocom/gprs/gprs_bssgp.h>
-#include <openbsc/debug.h>
-#include <openbsc/gprs_sgsn.h>
-#include <openbsc/gprs_gmm.h>
-#include <openbsc/gprs_llc.h>
-#include <openbsc/crc24.h>
+#include <osmocom/sgsn/debug.h>
+#include <osmocom/sgsn/gprs_sgsn.h>
+#include <osmocom/sgsn/gprs_gmm.h>
+#include <osmocom/sgsn/gprs_llc.h>
+#include <osmocom/sgsn/crc24.h>
static const struct value_string llc_cmd_strs[] = {
{ GPRS_LLC_NULL, "NULL" },
diff --git a/src/gprs/gprs_utils.c b/src/gprs/gprs_utils.c
index 91a09d2db..13641c1e1 100644
--- a/src/gprs/gprs_utils.c
+++ b/src/gprs/gprs_utils.c
@@ -19,7 +19,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
-#include <openbsc/gprs_utils.h>
+#include <osmocom/sgsn/gprs_utils.h>
#include <osmocom/core/msgb.h>
#include <osmocom/gprs/gprs_ns.h>
@@ -30,90 +30,6 @@
#include <string.h>
-/* FIXME: this needs to go to libosmocore/msgb.c */
-struct msgb *gprs_msgb_copy(const struct msgb *msg, const char *name)
-{
- struct libgb_msgb_cb *old_cb, *new_cb;
- struct msgb *new_msg;
-
- new_msg = msgb_alloc(msg->data_len, name);
- if (!new_msg)
- return NULL;
-
- /* copy data */
- memcpy(new_msg->_data, msg->_data, new_msg->data_len);
-
- /* copy header */
- new_msg->len = msg->len;
- new_msg->data += msg->data - msg->_data;
- new_msg->head += msg->head - msg->_data;
- new_msg->tail += msg->tail - msg->_data;
-
- if (msg->l1h)
- new_msg->l1h = new_msg->_data + (msg->l1h - msg->_data);
- if (msg->l2h)
- new_msg->l2h = new_msg->_data + (msg->l2h - msg->_data);
- if (msg->l3h)
- new_msg->l3h = new_msg->_data + (msg->l3h - msg->_data);
- if (msg->l4h)
- new_msg->l4h = new_msg->_data + (msg->l4h - msg->_data);
-
- /* copy GB specific data */
- old_cb = LIBGB_MSGB_CB(msg);
- new_cb = LIBGB_MSGB_CB(new_msg);
-
- if (old_cb->bssgph)
- new_cb->bssgph = new_msg->_data + (old_cb->bssgph - msg->_data);
- if (old_cb->llch)
- new_cb->llch = new_msg->_data + (old_cb->llch - msg->_data);
-
- /* bssgp_cell_id is a pointer into the old msgb, so we need to make
- * it a pointer into the new msgb */
- if (old_cb->bssgp_cell_id)
- new_cb->bssgp_cell_id = new_msg->_data +
- (old_cb->bssgp_cell_id - msg->_data);
- new_cb->nsei = old_cb->nsei;
- new_cb->bvci = old_cb->bvci;
- new_cb->tlli = old_cb->tlli;
-
- return new_msg;
-}
-
-/* TODO: Move this to libosmocore/msgb.c */
-int gprs_msgb_resize_area(struct msgb *msg, uint8_t *area,
- size_t old_size, size_t new_size)
-{
- int rc;
- uint8_t *rest = area + old_size;
- int rest_len = msg->len - old_size - (area - msg->data);
- int delta_size = (int)new_size - (int)old_size;
-
- if (delta_size == 0)
- return 0;
-
- if (delta_size > 0) {
- rc = msgb_trim(msg, msg->len + delta_size);
- if (rc < 0)
- return rc;
- }
-
- memmove(area + new_size, area + old_size, rest_len);
-
- if (msg->l1h >= rest)
- msg->l1h += delta_size;
- if (msg->l2h >= rest)
- msg->l2h += delta_size;
- if (msg->l3h >= rest)
- msg->l3h += delta_size;
- if (msg->l4h >= rest)
- msg->l4h += delta_size;
-
- if (delta_size < 0)
- msgb_trim(msg, msg->len + delta_size);
-
- return 0;
-}
-
int gprs_str_to_apn(uint8_t *apn_enc, size_t max_len, const char *str)
{
uint8_t *last_len_field;
@@ -239,8 +155,10 @@ void gprs_parse_tmsi(const uint8_t *value, uint32_t *tmsi)
}
int gprs_ra_id_equals(const struct gprs_ra_id *id1,
- const struct gprs_ra_id *id2)
+ const struct gprs_ra_id *id2)
{
- return (id1->mcc == id2->mcc && id1->mnc == id2->mnc &&
- id1->lac == id2->lac && id1->rac == id2->rac);
+ return (id1->mcc == id2->mcc
+ && !osmo_mnc_cmp(id1->mnc, id1->mnc_3_digits,
+ id2->mnc, id2->mnc_3_digits)
+ && id1->lac == id2->lac && id1->rac == id2->rac);
}
diff --git a/src/gprs/gsup_client.c b/src/gprs/gsup_client.c
deleted file mode 100644
index 258f230cb..000000000
--- a/src/gprs/gsup_client.c
+++ /dev/null
@@ -1,355 +0,0 @@
-/* Generic Subscriber Update Protocol client */
-
-/* (C) 2014-2016 by Sysmocom s.f.m.c. GmbH
- * All Rights Reserved
- *
- * Author: Jacob Erlbeck
- * Author: Neels Hofmeyr
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * 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 Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#include <openbsc/gsup_client.h>
-
-#include <osmocom/abis/ipa.h>
-#include <osmocom/gsm/protocol/ipaccess.h>
-#include <osmocom/core/msgb.h>
-#include <osmocom/core/logging.h>
-
-#include <openbsc/debug.h>
-
-#include <errno.h>
-#include <string.h>
-
-extern void *tall_bsc_ctx;
-
-static void start_test_procedure(struct gsup_client *gsupc);
-
-static void gsup_client_send_ping(struct gsup_client *gsupc)
-{
- struct msgb *msg = gsup_client_msgb_alloc();
-
- msg->l2h = msgb_put(msg, 1);
- msg->l2h[0] = IPAC_MSGT_PING;
- ipa_msg_push_header(msg, IPAC_PROTO_IPACCESS);
- ipa_client_conn_send(gsupc->link, msg);
-}
-
-static int gsup_client_connect(struct gsup_client *gsupc)
-{
- int rc;
-
- if (gsupc->is_connected)
- return 0;
-
- if (osmo_timer_pending(&gsupc->connect_timer)) {
- LOGP(DLGSUP, LOGL_DEBUG,
- "GSUP connect: connect timer already running\n");
- osmo_timer_del(&gsupc->connect_timer);
- }
-
- if (osmo_timer_pending(&gsupc->ping_timer)) {
- LOGP(DLGSUP, LOGL_DEBUG,
- "GSUP connect: ping timer already running\n");
- osmo_timer_del(&gsupc->ping_timer);
- }
-
- if (ipa_client_conn_clear_queue(gsupc->link) > 0)
- LOGP(DLGSUP, LOGL_DEBUG, "GSUP connect: discarded stored messages\n");
-
- rc = ipa_client_conn_open(gsupc->link);
-
- if (rc >= 0) {
- LOGP(DLGSUP, LOGL_NOTICE, "GSUP connecting to %s:%d\n",
- gsupc->link->addr, gsupc->link->port);
- return 0;
- }
-
- LOGP(DLGSUP, LOGL_ERROR, "GSUP failed to connect to %s:%d: %s\n",
- gsupc->link->addr, gsupc->link->port, strerror(-rc));
-
- if (rc == -EBADF || rc == -ENOTSOCK || rc == -EAFNOSUPPORT ||
- rc == -EINVAL)
- return rc;
-
- osmo_timer_schedule(&gsupc->connect_timer,
- GSUP_CLIENT_RECONNECT_INTERVAL, 0);
-
- LOGP(DLGSUP, LOGL_INFO, "Scheduled timer to retry GSUP connect to %s:%d\n",
- gsupc->link->addr, gsupc->link->port);
-
- return 0;
-}
-
-static void connect_timer_cb(void *gsupc_)
-{
- struct gsup_client *gsupc = gsupc_;
-
- if (gsupc->is_connected)
- return;
-
- gsup_client_connect(gsupc);
-}
-
-static void client_send(struct gsup_client *gsupc, int proto_ext,
- struct msgb *msg_tx)
-{
- ipa_prepend_header_ext(msg_tx, proto_ext);
- ipa_msg_push_header(msg_tx, IPAC_PROTO_OSMO);
- ipa_client_conn_send(gsupc->link, msg_tx);
- /* msg_tx is now queued and will be freed. */
-}
-
-static void gsup_client_oap_register(struct gsup_client *gsupc)
-{
- struct msgb *msg_tx;
- int rc;
- rc = oap_client_register(&gsupc->oap_state, &msg_tx);
-
- if ((rc < 0) || (!msg_tx)) {
- LOGP(DLGSUP, LOGL_ERROR, "GSUP OAP set up, but cannot register.\n");
- return;
- }
-
- client_send(gsupc, IPAC_PROTO_EXT_OAP, msg_tx);
-}
-
-static void gsup_client_updown_cb(struct ipa_client_conn *link, int up)
-{
- struct gsup_client *gsupc = link->data;
-
- LOGP(DLGSUP, LOGL_INFO, "GSUP link to %s:%d %s\n",
- link->addr, link->port, up ? "UP" : "DOWN");
-
- gsupc->is_connected = up;
-
- if (up) {
- start_test_procedure(gsupc);
-
- if (gsupc->oap_state.state == OAP_INITIALIZED)
- gsup_client_oap_register(gsupc);
-
- osmo_timer_del(&gsupc->connect_timer);
- } else {
- osmo_timer_del(&gsupc->ping_timer);
-
- osmo_timer_schedule(&gsupc->connect_timer,
- GSUP_CLIENT_RECONNECT_INTERVAL, 0);
- }
-}
-
-static int gsup_client_oap_handle(struct gsup_client *gsupc, struct msgb *msg_rx)
-{
- int rc;
- struct msgb *msg_tx;
-
- /* If the oap_state is disabled, this will reject the messages. */
- rc = oap_client_handle(&gsupc->oap_state, msg_rx, &msg_tx);
- msgb_free(msg_rx);
- if (rc < 0)
- return rc;
-
- if (msg_tx)
- client_send(gsupc, IPAC_PROTO_EXT_OAP, msg_tx);
-
- return 0;
-}
-
-static int gsup_client_read_cb(struct ipa_client_conn *link, struct msgb *msg)
-{
- struct ipaccess_head *hh = (struct ipaccess_head *) msg->data;
- struct ipaccess_head_ext *he = (struct ipaccess_head_ext *) msgb_l2(msg);
- struct gsup_client *gsupc = (struct gsup_client *)link->data;
- int rc;
- struct ipaccess_unit ipa_dev = {
- /* see gsup_client_create() on const vs non-const */
- .unit_name = (char*)gsupc->unit_name,
- };
-
- OSMO_ASSERT(ipa_dev.unit_name);
-
- msg->l2h = &hh->data[0];
-
- rc = ipaccess_bts_handle_ccm(link, &ipa_dev, msg);
-
- if (rc < 0) {
- LOGP(DLGSUP, LOGL_NOTICE,
- "GSUP received an invalid IPA/CCM message from %s:%d\n",
- link->addr, link->port);
- /* Link has been closed */
- gsupc->is_connected = 0;
- msgb_free(msg);
- return -1;
- }
-
- if (rc == 1) {
- uint8_t msg_type = *(msg->l2h);
- /* CCM message */
- if (msg_type == IPAC_MSGT_PONG) {
- LOGP(DLGSUP, LOGL_DEBUG, "GSUP receiving PONG\n");
- gsupc->got_ipa_pong = 1;
- }
-
- msgb_free(msg);
- return 0;
- }
-
- if (hh->proto != IPAC_PROTO_OSMO)
- goto invalid;
-
- if (!he || msgb_l2len(msg) < sizeof(*he))
- goto invalid;
-
- msg->l2h = &he->data[0];
-
- if (he->proto == IPAC_PROTO_EXT_GSUP) {
- OSMO_ASSERT(gsupc->read_cb != NULL);
- gsupc->read_cb(gsupc, msg);
- /* expecting read_cb() to free msg */
- } else if (he->proto == IPAC_PROTO_EXT_OAP) {
- return gsup_client_oap_handle(gsupc, msg);
- /* gsup_client_oap_handle frees msg */
- } else
- goto invalid;
-
- return 0;
-
-invalid:
- LOGP(DLGSUP, LOGL_NOTICE,
- "GSUP received an invalid IPA message from %s:%d, size = %d\n",
- link->addr, link->port, msgb_length(msg));
-
- msgb_free(msg);
- return -1;
-}
-
-static void ping_timer_cb(void *gsupc_)
-{
- struct gsup_client *gsupc = gsupc_;
-
- LOGP(DLGSUP, LOGL_INFO, "GSUP ping callback (%s, %s PONG)\n",
- gsupc->is_connected ? "connected" : "not connected",
- gsupc->got_ipa_pong ? "got" : "didn't get");
-
- if (gsupc->got_ipa_pong) {
- start_test_procedure(gsupc);
- return;
- }
-
- LOGP(DLGSUP, LOGL_NOTICE, "GSUP ping timed out, reconnecting\n");
- ipa_client_conn_close(gsupc->link);
- gsupc->is_connected = 0;
-
- gsup_client_connect(gsupc);
-}
-
-static void start_test_procedure(struct gsup_client *gsupc)
-{
- osmo_timer_setup(&gsupc->ping_timer, ping_timer_cb, gsupc);
-
- gsupc->got_ipa_pong = 0;
- osmo_timer_schedule(&gsupc->ping_timer, GSUP_CLIENT_PING_INTERVAL, 0);
- LOGP(DLGSUP, LOGL_DEBUG, "GSUP sending PING\n");
- gsup_client_send_ping(gsupc);
-}
-
-struct gsup_client *gsup_client_create(const char *unit_name,
- const char *ip_addr,
- unsigned int tcp_port,
- gsup_client_read_cb_t read_cb,
- struct oap_client_config *oapc_config)
-{
- struct gsup_client *gsupc;
- int rc;
-
- gsupc = talloc_zero(tall_bsc_ctx, struct gsup_client);
- OSMO_ASSERT(gsupc);
-
- /* struct ipaccess_unit has a non-const unit_name, so let's copy to be
- * able to have a non-const unit_name here as well. To not taint the
- * public gsup_client API, let's store it in a const char* anyway. */
- gsupc->unit_name = talloc_strdup(gsupc, unit_name);
- OSMO_ASSERT(gsupc->unit_name);
-
- /* a NULL oapc_config will mark oap_state disabled. */
- rc = oap_client_init(oapc_config, &gsupc->oap_state);
- if (rc != 0)
- goto failed;
-
- gsupc->link = ipa_client_conn_create(gsupc,
- /* no e1inp */ NULL,
- 0,
- ip_addr, tcp_port,
- gsup_client_updown_cb,
- gsup_client_read_cb,
- /* default write_cb */ NULL,
- gsupc);
- if (!gsupc->link)
- goto failed;
-
- osmo_timer_setup(&gsupc->connect_timer, connect_timer_cb, gsupc);
-
- rc = gsup_client_connect(gsupc);
-
- if (rc < 0)
- goto failed;
-
- gsupc->read_cb = read_cb;
-
- return gsupc;
-
-failed:
- gsup_client_destroy(gsupc);
- return NULL;
-}
-
-void gsup_client_destroy(struct gsup_client *gsupc)
-{
- osmo_timer_del(&gsupc->connect_timer);
- osmo_timer_del(&gsupc->ping_timer);
-
- if (gsupc->link) {
- ipa_client_conn_close(gsupc->link);
- ipa_client_conn_destroy(gsupc->link);
- gsupc->link = NULL;
- }
- talloc_free(gsupc);
-}
-
-int gsup_client_send(struct gsup_client *gsupc, struct msgb *msg)
-{
- if (!gsupc) {
- LOGP(DGPRS, LOGL_NOTICE, "No GSUP client, unable to "
- "send %s\n", msgb_hexdump(msg));
- msgb_free(msg);
- return -ENOTCONN;
- }
-
- if (!gsupc->is_connected) {
- LOGP(DGPRS, LOGL_NOTICE, "GSUP not connected, unable to "
- "send %s\n", msgb_hexdump(msg));
- msgb_free(msg);
- return -EAGAIN;
- }
-
- client_send(gsupc, IPAC_PROTO_EXT_GSUP, msg);
-
- return 0;
-}
-
-struct msgb *gsup_client_msgb_alloc(void)
-{
- return msgb_alloc_headroom(4000, 64, __func__);
-}
diff --git a/src/gprs/oap_client.c b/src/gprs/oap_client.c
deleted file mode 100644
index 5128ac119..000000000
--- a/src/gprs/oap_client.c
+++ /dev/null
@@ -1,280 +0,0 @@
-/* Osmocom Authentication Protocol API */
-
-/* (C) 2015 by Sysmocom s.f.m.c. GmbH
- * All Rights Reserved
- *
- * Author: Neels Hofmeyr
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * 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 Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#include <string.h>
-#include <errno.h>
-
-#include <osmocom/core/utils.h>
-#include <osmocom/crypt/auth.h>
-#include <osmocom/gsm/oap.h>
-
-#include <openbsc/oap_client.h>
-#include <openbsc/debug.h>
-
-int oap_client_init(struct oap_client_config *config,
- struct oap_client_state *state)
-{
- OSMO_ASSERT(state->state == OAP_UNINITIALIZED);
-
- if (!config)
- goto disable;
-
- if (config->client_id == 0)
- goto disable;
-
- if (config->secret_k_present == 0) {
- LOGP(DLOAP, LOGL_NOTICE, "OAP: client ID set, but secret K missing.\n");
- goto disable;
- }
-
- if (config->secret_opc_present == 0) {
- LOGP(DLOAP, LOGL_NOTICE, "OAP: client ID set, but secret OPC missing.\n");
- goto disable;
- }
-
- state->client_id = config->client_id;
- memcpy(state->secret_k, config->secret_k, sizeof(state->secret_k));
- memcpy(state->secret_opc, config->secret_opc, sizeof(state->secret_opc));
- state->state = OAP_INITIALIZED;
- return 0;
-
-disable:
- state->state = OAP_DISABLED;
- return 0;
-}
-
-/* From the given state and received RAND and AUTN octets, validate the
- * server's authenticity and formulate the matching milenage reply octets in
- * *tx_xres. The state is not modified.
- * On success, and if tx_res is not NULL, exactly 8 octets will be written to
- * *tx_res. If not NULL, tx_res must point at allocated memory of at least 8
- * octets. The caller will want to send XRES back to the server in a challenge
- * response message and update the state.
- * Return 0 on success; -1 if OAP is disabled; -2 if rx_random and rx_autn fail
- * the authentication check; -3 for any other errors. */
-static int oap_evaluate_challenge(const struct oap_client_state *state,
- const uint8_t *rx_random,
- const uint8_t *rx_autn,
- uint8_t *tx_xres)
-{
- struct osmo_auth_vector vec;
-
- struct osmo_sub_auth_data auth = {
- .type = OSMO_AUTH_TYPE_UMTS,
- .algo = OSMO_AUTH_ALG_MILENAGE,
- };
-
- osmo_static_assert(sizeof(((struct osmo_sub_auth_data*)0)->u.umts.k)
- == sizeof(state->secret_k), _secret_k_size_match);
- osmo_static_assert(sizeof(((struct osmo_sub_auth_data*)0)->u.umts.opc)
- == sizeof(state->secret_opc), _secret_opc_size_match);
-
- switch (state->state) {
- case OAP_UNINITIALIZED:
- case OAP_DISABLED:
- return -1;
- default:
- break;
- }
-
- memcpy(auth.u.umts.k, state->secret_k, sizeof(auth.u.umts.k));
- memcpy(auth.u.umts.opc, state->secret_opc, sizeof(auth.u.umts.opc));
- memset(auth.u.umts.amf, '\0', sizeof(auth.u.umts.amf));
- auth.u.umts.sqn = 41; /* TODO use incrementing sequence nr */
-
- memset(&vec, 0, sizeof(vec));
- osmo_auth_gen_vec(&vec, &auth, rx_random);
-
- if (vec.res_len != 8) {
- LOGP(DLOAP, LOGL_ERROR, "OAP: Expected XRES to be 8 octets, got %d\n",
- vec.res_len);
- return -3;
- }
-
- if (osmo_constant_time_cmp(vec.autn, rx_autn, sizeof(vec.autn)) != 0) {
- LOGP(DLOAP, LOGL_ERROR, "OAP: AUTN mismatch!\n");
- LOGP(DLOAP, LOGL_INFO, "OAP: AUTN from server: %s\n",
- osmo_hexdump_nospc(rx_autn, sizeof(vec.autn)));
- LOGP(DLOAP, LOGL_INFO, "OAP: AUTN expected: %s\n",
- osmo_hexdump_nospc(vec.autn, sizeof(vec.autn)));
- return -2;
- }
-
- if (tx_xres != NULL)
- memcpy(tx_xres, vec.res, 8);
- return 0;
-}
-
-struct msgb *oap_client_encoded(const struct osmo_oap_message *oap_msg)
-{
- struct msgb *msg = msgb_alloc_headroom(1000, 64, __func__);
- OSMO_ASSERT(msg);
- osmo_oap_encode(msg, oap_msg);
- return msg;
-}
-
-/* Create a new msgb containing an OAP registration message.
- * On error, return NULL. */
-static struct msgb* oap_msg_register(uint16_t client_id)
-{
- struct osmo_oap_message oap_msg = {0};
-
- if (client_id < 1) {
- LOGP(DLOAP, LOGL_ERROR, "OAP: Invalid client ID: %d\n", client_id);
- return NULL;
- }
-
- oap_msg.message_type = OAP_MSGT_REGISTER_REQUEST;
- oap_msg.client_id = client_id;
- return oap_client_encoded(&oap_msg);
-}
-
-int oap_client_register(struct oap_client_state *state, struct msgb **msg_tx)
-{
- *msg_tx = oap_msg_register(state->client_id);
- if (!(*msg_tx))
- return -1;
-
- state->state = OAP_REQUESTED_CHALLENGE;
- return 0;
-}
-
-/* Create a new msgb containing an OAP challenge response message.
- * xres must point at 8 octets to return as challenge response.
- * On error, return NULL. */
-static struct msgb* oap_msg_challenge_response(uint8_t *xres)
-{
- struct osmo_oap_message oap_reply = {0};
-
- oap_reply.message_type = OAP_MSGT_CHALLENGE_RESULT;
- memcpy(oap_reply.xres, xres, sizeof(oap_reply.xres));
- oap_reply.xres_present = 1;
- return oap_client_encoded(&oap_reply);
-}
-
-static int handle_challenge(struct oap_client_state *state,
- struct osmo_oap_message *oap_rx,
- struct msgb **msg_tx)
-{
- int rc;
- uint8_t xres[8];
-
- if (!(oap_rx->rand_present && oap_rx->autn_present)) {
- LOGP(DLOAP, LOGL_ERROR,
- "OAP challenge incomplete (rand_present: %d, autn_present: %d)\n",
- oap_rx->rand_present, oap_rx->autn_present);
- rc = -2;
- goto failure;
- }
-
- rc = oap_evaluate_challenge(state,
- oap_rx->rand,
- oap_rx->autn,
- xres);
- if (rc < 0)
- goto failure;
-
- *msg_tx = oap_msg_challenge_response(xres);
- if ((*msg_tx) == NULL) {
- rc = -1;
- goto failure;
- }
-
- state->state = OAP_SENT_CHALLENGE_RESULT;
- return 0;
-
-failure:
- OSMO_ASSERT(rc < 0);
- state->state = OAP_INITIALIZED;
- return rc;
-}
-
-int oap_client_handle(struct oap_client_state *state,
- const struct msgb *msg_rx, struct msgb **msg_tx)
-{
- uint8_t *data = msgb_l2(msg_rx);
- size_t data_len = msgb_l2len(msg_rx);
- struct osmo_oap_message oap_msg = {0};
- int rc = 0;
-
- *msg_tx = NULL;
-
- OSMO_ASSERT(data);
-
- rc = osmo_oap_decode(&oap_msg, data, data_len);
- if (rc < 0) {
- LOGP(DLOAP, LOGL_ERROR,
- "Decoding OAP message failed with error '%s' (%d)\n",
- get_value_string(gsm48_gmm_cause_names, -rc), -rc);
- return -10;
- }
-
- switch (state->state) {
- case OAP_UNINITIALIZED:
- LOGP(DLOAP, LOGL_ERROR,
- "Received OAP message %d, but the OAP client is"
- " not initialized\n", oap_msg.message_type);
- return -ENOTCONN;
- case OAP_DISABLED:
- LOGP(DLOAP, LOGL_ERROR,
- "Received OAP message %d, but the OAP client is"
- " disabled\n", oap_msg.message_type);
- return -ENOTCONN;
- default:
- break;
- }
-
- switch (oap_msg.message_type) {
- case OAP_MSGT_CHALLENGE_REQUEST:
- return handle_challenge(state, &oap_msg, msg_tx);
-
- case OAP_MSGT_REGISTER_RESULT:
- /* successfully registered */
- state->state = OAP_REGISTERED;
- break;
-
- case OAP_MSGT_REGISTER_ERROR:
- LOGP(DLOAP, LOGL_ERROR,
- "OAP registration failed\n");
- state->state = OAP_INITIALIZED;
- if (state->registration_failures < 3) {
- state->registration_failures ++;
- return oap_client_register(state, msg_tx);
- }
- return -11;
-
- case OAP_MSGT_REGISTER_REQUEST:
- case OAP_MSGT_CHALLENGE_RESULT:
- LOGP(DLOAP, LOGL_ERROR,
- "Received invalid OAP message type for OAP client side: %d\n",
- (int)oap_msg.message_type);
- return -12;
-
- default:
- LOGP(DLOAP, LOGL_ERROR,
- "Unknown OAP message type: %d\n",
- (int)oap_msg.message_type);
- return -13;
- }
-
- return 0;
-}
diff --git a/src/gprs/osmo_sgsn.cfg b/src/gprs/osmo_sgsn.cfg
deleted file mode 100644
index c4c9ec1cf..000000000
--- a/src/gprs/osmo_sgsn.cfg
+++ /dev/null
@@ -1,23 +0,0 @@
-!
-! Osmocom SGSN (0.9.0.474-0ede2) configuration saved from vty
-!!
-!
-line vty
- no login
-!
-sgsn
- gtp local-ip 192.168.100.11
- ggsn 0 remote-ip 192.168.100.239
- ggsn 0 gtp-version 1
-ns
- timer tns-block 3
- timer tns-block-retries 3
- timer tns-reset 3
- timer tns-reset-retries 3
- timer tns-test 30
- timer tns-alive 3
- timer tns-alive-retries 10
- encapsulation udp local-ip 192.168.100.11
- encapsulation udp local-port 23000
- encapsulation framerelay-gre enabled 0
-bssgp
diff --git a/src/gprs/sgsn_ares.c b/src/gprs/sgsn_ares.c
index 623809911..38e31e131 100644
--- a/src/gprs/sgsn_ares.c
+++ b/src/gprs/sgsn_ares.c
@@ -19,12 +19,12 @@
*
*/
-#include <openbsc/sgsn.h>
-#include <openbsc/debug.h>
+#include <osmocom/sgsn/sgsn.h>
+#include <osmocom/sgsn/debug.h>
#include <netdb.h>
-extern void *tall_bsc_ctx;
+extern void *tall_sgsn_ctx;
struct cares_event_fd {
struct llist_head head;
@@ -51,8 +51,8 @@ static int ares_osmo_fd_cb(struct osmo_fd *fd, unsigned int what)
LOGP(DGPRS, LOGL_DEBUG, "C-ares fd(%d) ready(%d)\n", fd->fd, what);
ares_process_fd(sgsn->ares_channel,
- (what & BSC_FD_READ) ? fd->fd : ARES_SOCKET_BAD,
- (what & BSC_FD_WRITE) ? fd->fd : ARES_SOCKET_BAD);
+ (what & OSMO_FD_READ) ? fd->fd : ARES_SOCKET_BAD,
+ (what & OSMO_FD_WRITE) ? fd->fd : ARES_SOCKET_BAD);
osmo_ares_reschedule(sgsn);
return 0;
}
@@ -110,7 +110,7 @@ static void setup_ares_osmo_fd(void *data, int fd, int read, int write)
}
LOGP(DGPRS, LOGL_DEBUG, "Registering C-ares fd (%d)\n", fd);
- ufd = talloc_zero(tall_bsc_ctx, struct cares_event_fd);
+ ufd = talloc_zero(tall_sgsn_ctx, struct cares_event_fd);
ufd->fd.fd = fd;
ufd->fd.cb = ares_osmo_fd_cb;
ufd->fd.data = data;
@@ -120,14 +120,14 @@ static void setup_ares_osmo_fd(void *data, int fd, int read, int write)
update_fd:
if (read)
- ufd->fd.when |= BSC_FD_READ;
+ ufd->fd.when |= OSMO_FD_READ;
else
- ufd->fd.when &= ~BSC_FD_READ;
+ ufd->fd.when &= ~OSMO_FD_READ;
if (write)
- ufd->fd.when |= BSC_FD_WRITE;
+ ufd->fd.when |= OSMO_FD_WRITE;
else
- ufd->fd.when &= ~BSC_FD_WRITE;
+ ufd->fd.when &= ~OSMO_FD_WRITE;
osmo_ares_reschedule(sgsn);
}
@@ -137,7 +137,7 @@ int sgsn_ares_query(struct sgsn_instance *sgsn, const char *name,
{
struct cares_cb_data *cb_data;
- cb_data = talloc_zero(tall_bsc_ctx, struct cares_cb_data);
+ cb_data = talloc_zero(tall_sgsn_ctx, struct cares_cb_data);
cb_data->cb = cb;
cb_data->data = data;
ares_gethostbyname(sgsn->ares_channel, name, AF_INET, ares_cb, cb_data);
diff --git a/src/gtphub/Makefile.am b/src/gtphub/Makefile.am
new file mode 100644
index 000000000..a242a0584
--- /dev/null
+++ b/src/gtphub/Makefile.am
@@ -0,0 +1,45 @@
+AM_CPPFLAGS = \
+ $(all_includes) \
+ -I$(top_srcdir)/include \
+ -I$(top_builddir) \
+ $(NULL)
+
+AM_CFLAGS = \
+ -Wall \
+ -fno-strict-aliasing \
+ $(LIBOSMOCORE_CFLAGS) \
+ $(LIBOSMOGSM_CFLAGS) \
+ $(LIBOSMOVTY_CFLAGS) \
+ $(LIBOSMOGSUPCLIENT_CFLAGS) \
+ $(COVERAGE_CFLAGS) \
+ $(LIBGTP_CFLAGS) \
+ $(NULL)
+if BUILD_IU
+AM_CFLAGS += \
+ $(LIBASN1C_CFLAGS) \
+ $(LIBOSMOSIGTRAN_CFLAGS) \
+ $(LIBOSMORANAP_CFLAGS) \
+ $(NULL)
+endif
+
+bin_PROGRAMS = osmo-gtphub
+
+osmo_gtphub_SOURCES = \
+ gtphub_main.c \
+ gtphub.c \
+ gtphub_sock.c \
+ gtphub_ares.c \
+ gtphub_vty.c \
+ $(NULL)
+
+osmo_gtphub_LDADD = \
+ $(top_builddir)/src/gprs/sgsn_ares.o \
+ $(top_builddir)/src/gprs/gprs_utils.o \
+ $(LIBOSMOCORE_LIBS) \
+ $(LIBOSMOGSM_LIBS) \
+ $(LIBOSMOVTY_LIBS) \
+ $(LIBCARES_LIBS) \
+ $(LIBGTP_LIBS) \
+ $(LIBOSMOSIGTRAN_LIBS) \
+ -lrt \
+ $(NULL)
diff --git a/src/gprs/gtphub.c b/src/gtphub/gtphub.c
index 0a8e375ab..7b355bf9c 100644
--- a/src/gprs/gtphub.c
+++ b/src/gtphub/gtphub.c
@@ -32,9 +32,9 @@
#include <gtp.h>
#include <gtpie.h>
-#include <openbsc/gtphub.h>
-#include <openbsc/debug.h>
-#include <openbsc/gprs_utils.h>
+#include <osmocom/sgsn/gtphub.h>
+#include <osmocom/sgsn/debug.h>
+#include <osmocom/sgsn/gprs_utils.h>
#include <osmocom/core/utils.h>
#include <osmocom/core/logging.h>
@@ -125,7 +125,7 @@ static const struct rate_ctr_desc gtphub_counters_io_desc[] = {
};
static const struct rate_ctr_group_desc gtphub_ctrg_io_desc = {
- .group_name_prefix = "gtphub.bind",
+ .group_name_prefix = "gtphub:bind",
.group_description = "I/O Statistics",
.num_ctr = ARRAY_SIZE(gtphub_counters_io_desc),
.ctr_desc = gtphub_counters_io_desc,
@@ -791,7 +791,7 @@ const char* const gtphub_side_idx_names[GTPH_SIDE_N] = {
time_t gtphub_now(void)
{
struct timespec now_tp;
- OSMO_ASSERT(clock_gettime(CLOCK_MONOTONIC, &now_tp) >= 0);
+ OSMO_ASSERT(osmo_clock_gettime(CLOCK_MONOTONIC, &now_tp) >= 0);
return now_tp.tv_sec;
}
@@ -853,7 +853,7 @@ static int gtphub_sock_init(struct osmo_fd *ofd,
return -1;
}
- ofd->when = BSC_FD_READ;
+ ofd->when = OSMO_FD_READ;
ofd->cb = cb;
ofd->data = data;
ofd->priv_nr = ofd_id;
@@ -879,14 +879,14 @@ static void gtphub_sock_close(struct osmo_fd *ofd)
ofd->cb = NULL;
}
-static void gtphub_bind_init(struct gtphub_bind *b)
+static void gtphub_bind_init(struct gtphub_bind *b, uint32_t idx)
{
ZERO_STRUCT(b);
INIT_LLIST_HEAD(&b->peers);
b->counters_io = rate_ctr_group_alloc(osmo_gtphub_ctx,
- &gtphub_ctrg_io_desc, 0);
+ &gtphub_ctrg_io_desc, idx);
OSMO_ASSERT(b->counters_io);
}
@@ -913,7 +913,8 @@ static int gtphub_bind_start(struct gtphub_bind *b,
static void gtphub_bind_free(struct gtphub_bind *b)
{
OSMO_ASSERT(llist_empty(&b->peers));
- rate_ctr_group_free(b->counters_io);
+ if (b->counters_io)
+ rate_ctr_group_free(b->counters_io);
}
static void gtphub_bind_stop(struct gtphub_bind *b) {
@@ -1107,6 +1108,14 @@ static void gtphub_tunnel_del_cb(struct expiring_item *expi)
talloc_free(tun);
}
+#define CTR_IDX(s, p, a, b) (a + s + (p + b) * 2)
+
+/* rate counter index for tunnels: [3; 6] */
+#define CTR_IDX_TUN(s, p) CTR_IDX(s, p, 1, 1)
+
+/* rate counter index for hubs: [7; 10] */
+#define CTR_IDX_HUB(s, p) CTR_IDX(s, p, 3, 2)
+
static struct gtphub_tunnel *gtphub_tunnel_new()
{
struct gtphub_tunnel *tun;
@@ -1121,8 +1130,9 @@ static struct gtphub_tunnel *gtphub_tunnel_new()
struct gtphub_tunnel_endpoint *te = &tun->endpoint[side_idx][plane_idx];
te->counters_io = rate_ctr_group_alloc(osmo_gtphub_ctx,
&gtphub_ctrg_io_desc,
- 0);
- OSMO_ASSERT(te->counters_io);
+ CTR_IDX_TUN(side_idx, plane_idx));
+ if (!te->counters_io)
+ return NULL;
}
tun->expiry_entry.del_cb = gtphub_tunnel_del_cb;
@@ -1486,7 +1496,13 @@ static int gtphub_handle_create_pdp_ctx(struct gtphub *hub,
}
/* A new tunnel. */
- p->tun = tun = gtphub_tunnel_new();
+ tun = gtphub_tunnel_new();
+ if (!tun) {
+ LOG(LOGL_ERROR, "Failed to allocate new tunnel %s <-> %s\n",
+ gtphub_port_str(from_ctrl), gtphub_port_str(to_ctrl));
+ return -1;
+ }
+ p->tun = tun;
/* Create TEI mapping */
tun->tei_repl = nr_pool_next(&hub->tei_pool);
@@ -1517,7 +1533,7 @@ static int gtphub_handle_create_pdp_ctx(struct gtphub *hub,
int ie_mandatory = (p->type == GTP_CREATE_PDP_REQ);
unsigned int side_idx = p->side_idx;
- for (plane_idx = 0; plane_idx < 2; plane_idx++) {
+ for_each_plane(plane_idx) {
int rc;
struct gsn_addr use_addr;
uint16_t use_port;
@@ -1567,7 +1583,9 @@ static int gtphub_handle_create_pdp_ctx(struct gtphub *hub,
* gtphub_handle_buf(), we'd be creating a peer port just to
* expire it right away. */
if (hub->sgsn_use_sender && (side_idx == GTPH_SIDE_SGSN)) {
- gsn_addr_from_sockaddr(&use_addr, &use_port, &from_ctrl->sa);
+ int rc = gsn_addr_from_sockaddr(&use_addr, &use_port, &from_ctrl->sa);
+ if (rc < 0)
+ LOG(LOGL_ERROR, "%s(): failed to obtain GSN address\n", __func__);
} else {
use_port = gtphub_plane_idx_default_port[plane_idx];
@@ -1930,7 +1948,7 @@ static int from_sgsns_read_cb(struct osmo_fd *from_sgsns_ofd, unsigned int what)
LOG(LOGL_DEBUG, "=== reading from SGSN (%s)\n",
gtphub_plane_idx_names[plane_idx]);
- if (!(what & BSC_FD_READ))
+ if (!(what & OSMO_FD_READ))
return 0;
struct gtphub *hub = from_sgsns_ofd->data;
@@ -1961,7 +1979,7 @@ static int from_ggsns_read_cb(struct osmo_fd *from_ggsns_ofd, unsigned int what)
OSMO_ASSERT(plane_idx < GTPH_PLANE_N);
LOG(LOGL_DEBUG, "=== reading from GGSN (%s)\n",
gtphub_plane_idx_names[plane_idx]);
- if (!(what & BSC_FD_READ))
+ if (!(what & OSMO_FD_READ))
return 0;
struct gtphub *hub = from_ggsns_ofd->data;
@@ -2460,7 +2478,7 @@ void gtphub_init(struct gtphub *hub)
int side_idx;
int plane_idx;
for_each_side_and_plane(side_idx, plane_idx) {
- gtphub_bind_init(&hub->to_gsns[side_idx][plane_idx]);
+ gtphub_bind_init(&hub->to_gsns[side_idx][plane_idx], CTR_IDX_HUB(side_idx, plane_idx));
}
hub->to_gsns[GTPH_SIDE_SGSN][GTPH_PLANE_CTRL].label = "SGSN Ctrl";
@@ -2631,7 +2649,9 @@ struct gtphub_peer_port *gtphub_port_find_sa(const struct gtphub_bind *bind,
{
struct gsn_addr gsna;
uint16_t port;
- gsn_addr_from_sockaddr(&gsna, &port, addr);
+ if (gsn_addr_from_sockaddr(&gsna, &port, addr) != 0)
+ return NULL;
+
return gtphub_port_find(bind, &gsna, port);
}
@@ -2709,8 +2729,9 @@ static struct gtphub_peer_port *gtphub_addr_add_port(struct gtphub_peer_addr *a,
}
pp->counters_io = rate_ctr_group_alloc(osmo_gtphub_ctx,
- &gtphub_ctrg_io_desc, 0);
+ &gtphub_ctrg_io_desc, port);
if (!pp->counters_io) {
+ LOG(LOGL_ERROR, "Failed to allocate rate counters for %s:%u\n", gsn_addr_to_str(&a->addr), port);
talloc_free(pp);
return NULL;
}
@@ -2748,7 +2769,9 @@ struct gtphub_peer_port *gtphub_known_addr_have_port(const struct gtphub_bind *b
struct gsn_addr gsna;
uint16_t port;
- gsn_addr_from_sockaddr(&gsna, &port, addr);
+ int rc = gsn_addr_from_sockaddr(&gsna, &port, addr);
+ if (rc < 0)
+ LOG(LOGL_ERROR, "%s(): failed to obtain GSN address\n", __func__);
pa = gtphub_addr_find(bind, &gsna);
if (!pa)
diff --git a/src/gprs/gtphub_ares.c b/src/gtphub/gtphub_ares.c
index afeeda657..87dc860c4 100644
--- a/src/gprs/gtphub_ares.c
+++ b/src/gtphub/gtphub_ares.c
@@ -28,15 +28,15 @@
#include <string.h>
#include <unistd.h>
-#include <openbsc/gtphub.h>
-#include <openbsc/debug.h>
+#include <osmocom/sgsn/gtphub.h>
+#include <osmocom/sgsn/debug.h>
#include <osmocom/core/utils.h>
#include <osmocom/gsm/apn.h>
/* TODO split GRX ares from sgsn into a separate struct and allow use without
* globals. */
-#include <openbsc/sgsn.h>
+#include <osmocom/sgsn/sgsn.h>
extern struct sgsn_instance *sgsn;
struct sgsn_instance sgsn_inst = { 0 };
diff --git a/src/gprs/gtphub_main.c b/src/gtphub/gtphub_main.c
index d7b3ba74b..664c801e8 100644
--- a/src/gprs/gtphub_main.c
+++ b/src/gtphub/gtphub_main.c
@@ -38,17 +38,20 @@
#include <osmocom/vty/logging.h>
#include <osmocom/vty/telnet_interface.h>
#include <osmocom/vty/ports.h>
+#include <osmocom/vty/misc.h>
-#include <osmocom/sigtran/osmo_ss7.h>
-
-#include <openbsc/debug.h>
-#include <openbsc/gtphub.h>
-#include <openbsc/vty.h>
+#include <osmocom/sgsn/debug.h>
+#include <osmocom/sgsn/gtphub.h>
+#include <osmocom/sgsn/vty.h>
#include "../../bscconfig.h"
+#if BUILD_IU
+#include <osmocom/sigtran/osmo_ss7.h>
+#endif
+
extern void *osmo_gtphub_ctx;
-void *tall_bsc_ctx;
+void *tall_sgsn_ctx;
const char *gtphub_copyright =
"Copyright (C) 2015 sysmocom s.f.m.c GmbH <info@sysmocom.de>\r\n"
@@ -115,6 +118,7 @@ static void signal_handler(int signal)
}
}
+#if BUILD_IU
int gtphub_vty_go_parent(struct vty *vty)
{
switch (vty->node) {
@@ -124,13 +128,16 @@ int gtphub_vty_go_parent(struct vty *vty)
return vty->node;
}
+#endif
int gtphub_vty_is_config_node(struct vty *vty, int node)
{
/* Check if libosmo-sccp declares the node in
* question as config node */
+#if BUILD_IU
if (osmo_ss7_is_config_node(vty, node))
return 1;
+#endif
switch (node) {
/* add items that are not config */
@@ -145,7 +152,9 @@ int gtphub_vty_is_config_node(struct vty *vty, int node)
static struct vty_app_info vty_info = {
.name = "OsmoGTPhub",
.version = PACKAGE_VERSION,
+#if BUILD_IU
.go_parent_cb = gtphub_vty_go_parent,
+#endif
.is_config_node = gtphub_vty_is_config_node,
};
@@ -229,11 +238,12 @@ static void print_help(struct cmdline_cfg *ccfg)
printf(" -e,--log-level <nr> Set a global log level.\n");
printf(" -r,--restart-file <path> File for counting restarts [%s].\n",
ccfg->restart_counter_file);
+ printf(" -V,--version Print the version.\n");
}
static void list_categories(void)
{
- printf("Avaliable debug categories:\n");
+ printf("Available debug categories:\n");
int i;
for (i = 0; i < gtphub_log_info.num_cat; ++i) {
if (!gtphub_log_info.cat[i].name)
@@ -256,10 +266,11 @@ static void handle_options(struct cmdline_cfg *ccfg, int argc, char **argv)
{"timestamp", 0, 0, 'T'},
{"log-level", 1, 0, 'e'},
{"restart-file", 1, 0, 'r'},
+ { "version", 0, 0, 'V' },
{NULL, 0, 0, 0}
};
- c = getopt_long(argc, argv, "hd:Dc:sTe:r:",
+ c = getopt_long(argc, argv, "hd:Dc:sTe:r:V",
long_options, &option_index);
if (c == -1) {
if (optind < argc) {
@@ -301,12 +312,21 @@ static void handle_options(struct cmdline_cfg *ccfg, int argc, char **argv)
case 'r':
ccfg->restart_counter_file = optarg;
break;
+ case 'V':
+ print_version(1);
+ exit(EXIT_SUCCESS);
+ break;
default:
LOGP(DGTPHUB, LOGL_FATAL, "Invalid command line argument, abort.\n");
exit(1);
break;
}
}
+
+ if (argc > optind) {
+ fprintf(stderr, "Unsupported positional arguments on command line\n");
+ exit(2);
+ }
}
int main(int argc, char **argv)
@@ -328,6 +348,7 @@ int main(int argc, char **argv)
osmo_gtphub_ctx = talloc_named_const(NULL, 0, "osmo_gtphub");
msgb_talloc_ctx_init(osmo_gtphub_ctx, 0);
+ vty_info.tall_ctx = osmo_gtphub_ctx;
signal(SIGINT, &signal_handler);
signal(SIGTERM, &signal_handler);
@@ -336,11 +357,12 @@ int main(int argc, char **argv)
signal(SIGUSR2, &signal_handler);
osmo_init_ignore_signals();
- osmo_init_logging(&gtphub_log_info);
+ osmo_init_logging2(osmo_gtphub_ctx, &gtphub_log_info);
vty_info.copyright = gtphub_copyright;
vty_init(&vty_info);
- logging_vty_add_cmds(NULL);
+ logging_vty_add_cmds();
+ osmo_talloc_vty_add_cmds();
gtphub_vty_init(hub, cfg);
rate_ctr_init(osmo_gtphub_ctx);
diff --git a/src/gprs/gtphub_sock.c b/src/gtphub/gtphub_sock.c
index 60bebaaeb..1acd5a624 100644
--- a/src/gprs/gtphub_sock.c
+++ b/src/gtphub/gtphub_sock.c
@@ -25,8 +25,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <openbsc/gtphub.h>
-#include <openbsc/debug.h>
+#include <osmocom/sgsn/gtphub.h>
+#include <osmocom/sgsn/debug.h>
/* Convenience makro, note: only within this C file. */
#define LOG(level, fmt, args...) \
diff --git a/src/gprs/gtphub_vty.c b/src/gtphub/gtphub_vty.c
index d611b1f9a..abc08fd69 100644
--- a/src/gprs/gtphub_vty.c
+++ b/src/gtphub/gtphub_vty.c
@@ -30,14 +30,14 @@
#include <osmocom/vty/command.h>
#include <osmocom/vty/misc.h>
-#include <openbsc/vty.h>
-#include <openbsc/gtphub.h>
+#include <osmocom/sgsn/vty.h>
+#include <osmocom/sgsn/gtphub.h>
/* TODO split GRX ares from sgsn into a separate struct and allow use without
* globals. */
-#include <openbsc/sgsn.h>
+#include <osmocom/sgsn/sgsn.h>
extern struct sgsn_instance *sgsn;
-extern void *tall_bsc_ctx;
+extern void *tall_sgsn_ctx;
static struct gtphub *g_hub = 0;
static struct gtphub_cfg *g_cfg = 0;
@@ -270,7 +270,7 @@ DEFUN(cfg_grx_ggsn, cfg_grx_ggsn_cmd,
"grx-dns-add A.B.C.D",
"Add DNS server\nIPv4 address\n")
{
- struct ares_addr_node *node = talloc_zero(tall_bsc_ctx, struct ares_addr_node);
+ struct ares_addr_node *node = talloc_zero(tall_sgsn_ctx, struct ares_addr_node);
node->family = AF_INET;
inet_aton(argv[0], &node->addr.addr4);
@@ -583,7 +583,6 @@ int gtphub_vty_init(struct gtphub *global_hub, struct gtphub_cfg *global_cfg)
install_element(CONFIG_NODE, &cfg_gtphub_cmd);
install_node(&gtphub_node, config_write_gtphub);
- vty_install_default(GTPHUB_NODE);
install_element(GTPHUB_NODE, &cfg_gtphub_bind_to_sgsns_short_cmd);
install_element(GTPHUB_NODE, &cfg_gtphub_bind_to_sgsns_cmd);
diff --git a/src/libcommon/Makefile.am b/src/libcommon/Makefile.am
deleted file mode 100644
index 0b258c08a..000000000
--- a/src/libcommon/Makefile.am
+++ /dev/null
@@ -1,47 +0,0 @@
-AM_CPPFLAGS = \
- $(all_includes) \
- -I$(top_srcdir)/include \
- -I$(top_builddir) \
- $(NULL)
-
-AM_CFLAGS = \
- -Wall \
- $(LIBOSMOCORE_CFLAGS) \
- $(LIBOSMOGSM_CFLAGS) \
- $(LIBOSMOVTY_CFLAGS) \
- $(LIBOSMOABIS_CFLAGS) \
- $(COVERAGE_CFLAGS) \
- $(NULL)
-
-noinst_LIBRARIES = \
- libcommon.a \
- $(NULL)
-
-libcommon_a_SOURCES = \
- bsc_version.c \
- common_vty.c \
- debug.c \
- gsm_data.c \
- gsm_data_shared.c \
- gsup_client.c \
- oap_client.c \
- socket.c \
- talloc_ctx.c \
- gsm_subscriber_base.c \
- $(NULL)
-
-noinst_PROGRAMS = \
- gsup_test_client \
- $(NULL)
-
-gsup_test_client_SOURCES = \
- gsup_test_client.c \
- $(NULL)
-gsup_test_client_LDADD = \
- libcommon.a \
- $(LIBOSMOCORE_LIBS) \
- $(LIBOSMOGSM_LIBS) \
- $(LIBOSMOVTY_LIBS) \
- $(LIBOSMOABIS_LIBS) \
- -lrt \
- $(NULL)
diff --git a/src/libcommon/bsc_version.c b/src/libcommon/bsc_version.c
deleted file mode 100644
index f0369bffe..000000000
--- a/src/libcommon/bsc_version.c
+++ /dev/null
@@ -1,30 +0,0 @@
-/* Hold the copyright and version string */
-/* (C) 2010-2016 by Harald Welte <laforge@gnumonks.org>
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * 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 Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#include "../../bscconfig.h"
-
-const char *openbsc_copyright =
- "Copyright (C) 2008-2016 Harald Welte, Holger Freyther\r\n"
- "Contributions by Daniel Willmann, Jan Lübbe, Stefan Schmidt\r\n"
- "Dieter Spaar, Andreas Eversberg, Sylvain Munaut, Neels Hofmeyr\r\n\r\n"
- "License AGPLv3+: GNU AGPL version 3 or later <http://gnu.org/licenses/agpl-3.0.html>\r\n"
- "This is free software: you are free to change and redistribute it.\r\n"
- "There is NO WARRANTY, to the extent permitted by law.\r\n";
-
-
diff --git a/src/libcommon/common_vty.c b/src/libcommon/common_vty.c
deleted file mode 100644
index 856583e0c..000000000
--- a/src/libcommon/common_vty.c
+++ /dev/null
@@ -1,152 +0,0 @@
-/* OpenBSC VTY common helpers */
-/* (C) 2009-2010 by Harald Welte <laforge@gnumonks.org>
- * (C) 2009-2010 by Holger Hans Peter Freyther
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * 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 Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#include <stdlib.h>
-#include <string.h>
-
-#include <osmocom/core/talloc.h>
-
-#include <openbsc/vty.h>
-#include <openbsc/debug.h>
-#include <openbsc/gsm_subscriber.h>
-#include <openbsc/bsc_nat.h>
-#include <openbsc/abis_om2000.h>
-
-#include <osmocom/vty/telnet_interface.h>
-#include <osmocom/vty/command.h>
-#include <osmocom/vty/buffer.h>
-#include <osmocom/vty/vty.h>
-#include <osmocom/sigtran/osmo_ss7.h>
-
-
-int bsc_vty_go_parent(struct vty *vty)
-{
- switch (vty->node) {
- case GSMNET_NODE:
- vty->node = CONFIG_NODE;
- vty->index = NULL;
- break;
- case BTS_NODE:
- vty->node = GSMNET_NODE;
- {
- /* set vty->index correctly ! */
- struct gsm_bts *bts = vty->index;
- vty->index = bts->network;
- vty->index_sub = NULL;
- }
- break;
- case TRX_NODE:
- vty->node = BTS_NODE;
- {
- /* set vty->index correctly ! */
- struct gsm_bts_trx *trx = vty->index;
- vty->index = trx->bts;
- vty->index_sub = &trx->bts->description;
- }
- break;
- case TS_NODE:
- vty->node = TRX_NODE;
- {
- /* set vty->index correctly ! */
- struct gsm_bts_trx_ts *ts = vty->index;
- vty->index = ts->trx;
- vty->index_sub = &ts->trx->description;
- }
- break;
- case OML_NODE:
- case OM2K_NODE:
- vty->node = ENABLE_NODE;
- /* NOTE: this only works because it's not part of the config
- * tree, where outer commands are searched via vty_go_parent()
- * and only (!) executed when a matching one is found.
- */
- talloc_free(vty->index);
- vty->index = NULL;
- break;
- case OM2K_CON_GROUP_NODE:
- vty->node = BTS_NODE;
- {
- struct con_group *cg = vty->index;
- struct gsm_bts *bts = cg->bts;
- vty->index = bts;
- vty->index_sub = &bts->description;
- }
- break;
- case NAT_BSC_NODE:
- vty->node = NAT_NODE;
- {
- struct bsc_config *bsc_config = vty->index;
- vty->index = bsc_config->nat;
- }
- break;
- case PGROUP_NODE:
- vty->node = NAT_NODE;
- vty->index = NULL;
- break;
- case TRUNK_NODE:
- vty->node = MGCP_NODE;
- vty->index = NULL;
- break;
- case SMPP_ESME_NODE:
- vty->node = SMPP_NODE;
- vty->index = NULL;
- break;
- case SMPP_NODE:
- case MGCP_NODE:
- case GBPROXY_NODE:
- case SGSN_NODE:
- case NAT_NODE:
- case BSC_NODE:
- case MSC_NODE:
- case MNCC_INT_NODE:
- case NITB_NODE:
- vty->node = CONFIG_NODE;
- vty->index = NULL;
- break;
- case SUBSCR_NODE:
- vty->node = ENABLE_NODE;
- vty->index = NULL;
- break;
- default:
- osmo_ss7_vty_go_parent(vty);
- }
-
- return vty->node;
-}
-
-int bsc_vty_is_config_node(struct vty *vty, int node)
-{
- /* Check if libosmo-sccp declares the node in
- * question as config node */
- if (osmo_ss7_is_config_node(vty, node))
- return 1;
-
- switch (node) {
- /* add items that are not config */
- case OML_NODE:
- case OM2K_NODE:
- case SUBSCR_NODE:
- case CONFIG_NODE:
- return 0;
-
- default:
- return 1;
- }
-}
diff --git a/src/libcommon/debug.c b/src/libcommon/debug.c
deleted file mode 100644
index 723641335..000000000
--- a/src/libcommon/debug.c
+++ /dev/null
@@ -1,232 +0,0 @@
-/* OpenBSC Debugging/Logging support code */
-
-/* (C) 2008-2010 by Harald Welte <laforge@gnumonks.org>
- * (C) 2008 by Holger Hans Peter Freyther <zecke@selfish.org>
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * 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 Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#include <stdarg.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <strings.h>
-#include <time.h>
-#include <errno.h>
-
-#include <osmocom/core/talloc.h>
-#include <osmocom/core/utils.h>
-#include <osmocom/core/logging.h>
-#include <osmocom/gprs/gprs_msgb.h>
-#include <openbsc/gsm_data.h>
-#include <openbsc/debug.h>
-
-/* default categories */
-static const struct log_info_cat default_categories[] = {
- [DRLL] = {
- .name = "DRLL",
- .description = "A-bis Radio Link Layer (RLL)",
- .color = "\033[1;31m",
- .enabled = 1, .loglevel = LOGL_NOTICE,
- },
- [DCC] = {
- .name = "DCC",
- .description = "Layer3 Call Control (CC)",
- .color = "\033[1;32m",
- .enabled = 1, .loglevel = LOGL_NOTICE,
- },
- [DMM] = {
- .name = "DMM",
- .description = "Layer3 Mobility Management (MM)",
- .color = "\033[1;33m",
- .enabled = 1, .loglevel = LOGL_NOTICE,
- },
- [DRR] = {
- .name = "DRR",
- .description = "Layer3 Radio Resource (RR)",
- .color = "\033[1;34m",
- .enabled = 1, .loglevel = LOGL_NOTICE,
- },
- [DRSL] = {
- .name = "DRSL",
- .description = "A-bis Radio Siganlling Link (RSL)",
- .color = "\033[1;35m",
- .enabled = 1, .loglevel = LOGL_NOTICE,
- },
- [DNM] = {
- .name = "DNM",
- .description = "A-bis Network Management / O&M (NM/OML)",
- .color = "\033[1;36m",
- .enabled = 1, .loglevel = LOGL_INFO,
- },
- [DMNCC] = {
- .name = "DMNCC",
- .description = "MNCC API for Call Control application",
- .color = "\033[1;39m",
- .enabled = 1, .loglevel = LOGL_NOTICE,
- },
- [DPAG] = {
- .name = "DPAG",
- .description = "Paging Subsystem",
- .color = "\033[1;38m",
- .enabled = 1, .loglevel = LOGL_NOTICE,
- },
- [DMEAS] = {
- .name = "DMEAS",
- .description = "Radio Measurement Processing",
- .enabled = 0, .loglevel = LOGL_NOTICE,
- },
- [DSCCP] = {
- .name = "DSCCP",
- .description = "SCCP Protocol",
- .enabled = 1, .loglevel = LOGL_NOTICE,
- },
- [DMSC] = {
- .name = "DMSC",
- .description = "Mobile Switching Center",
- .enabled = 1, .loglevel = LOGL_NOTICE,
- },
- [DMGCP] = {
- .name = "DMGCP",
- .description = "Media Gateway Control Protocol",
- .enabled = 1, .loglevel = LOGL_NOTICE,
- },
- [DHO] = {
- .name = "DHO",
- .description = "Hand-Over",
- .enabled = 1, .loglevel = LOGL_NOTICE,
- },
- [DDB] = {
- .name = "DDB",
- .description = "Database Layer",
- .enabled = 1, .loglevel = LOGL_NOTICE,
- },
- [DREF] = {
- .name = "DREF",
- .description = "Reference Counting",
- .enabled = 0, .loglevel = LOGL_NOTICE,
- },
- [DGPRS] = {
- .name = "DGPRS",
- .description = "GPRS Packet Service",
- .enabled = 1, .loglevel = LOGL_DEBUG,
- },
- [DNS] = {
- .name = "DNS",
- .description = "GPRS Network Service (NS)",
- .enabled = 1, .loglevel = LOGL_INFO,
- },
- [DBSSGP] = {
- .name = "DBSSGP",
- .description = "GPRS BSS Gateway Protocol (BSSGP)",
- .enabled = 1, .loglevel = LOGL_DEBUG,
- },
- [DLLC] = {
- .name = "DLLC",
- .description = "GPRS Logical Link Control Protocol (LLC)",
- .enabled = 1, .loglevel = LOGL_DEBUG,
- },
- [DSNDCP] = {
- .name = "DSNDCP",
- .description = "GPRS Sub-Network Dependent Control Protocol (SNDCP)",
- .enabled = 1, .loglevel = LOGL_DEBUG,
- },
- [DNAT] = {
- .name = "DNAT",
- .description = "GSM 08.08 NAT/Multiplexer",
- .enabled = 1, .loglevel = LOGL_NOTICE,
- },
- [DCTRL] = {
- .name = "DCTRL",
- .description = "Control interface",
- .enabled = 1, .loglevel = LOGL_NOTICE,
- },
- [DSMPP] = {
- .name = "DSMPP",
- .description = "SMPP interface for external SMS apps",
- .enabled = 1, .loglevel = LOGL_DEBUG,
- },
- [DFILTER] = {
- .name = "DFILTER",
- .description = "BSC/NAT IMSI based filtering",
- .enabled = 1, .loglevel = LOGL_DEBUG,
- },
- [DRANAP] = {
- .name = "DRANAP",
- .description = "Radio Access Network Application Part Protocol",
- .enabled = 1, .loglevel = LOGL_DEBUG,
- },
- [DSUA] = {
- .name = "DSUA",
- .description = "SCCP User Adaptation Protocol",
- .enabled = 1, .loglevel = LOGL_DEBUG,
- },
- [DPCU] = {
- .name = "DPCU",
- .description = "PCU Interface",
- .enabled = 1, .loglevel = LOGL_DEBUG,
- },
- [DVLR] = {
- .name = "DVLR",
- .description = "Visitor Location Register",
- .enabled = 1, .loglevel = LOGL_DEBUG,
- },
- [DIUCS] = {
- .name = "DIUCS",
- .description = "Iu-CS Protocol",
- .enabled = 1, .loglevel = LOGL_DEBUG,
- },
- [DSIGTRAN] = {
- .name = "DSIGTRAN",
- .description = "SIGTRAN Signalling Transport",
- .color = "\033[1;29m",
- .enabled = 1, .loglevel = LOGL_DEBUG,
- },
-};
-
-static int filter_fn(const struct log_context *ctx, struct log_target *tar)
-{
- const struct vlr_subscr *vsub = ctx->ctx[LOG_CTX_VLR_SUBSCR];
- const struct bsc_subscr *bsub = ctx->ctx[LOG_CTX_BSC_SUBSCR];
- const struct gprs_nsvc *nsvc = ctx->ctx[LOG_CTX_GB_NSVC];
- const struct gprs_nsvc *bvc = ctx->ctx[LOG_CTX_GB_BVC];
-
- if ((tar->filter_map & (1 << LOG_FLT_VLR_SUBSCR)) != 0
- && vsub && vsub == tar->filter_data[LOG_FLT_VLR_SUBSCR])
- return 1;
-
- if ((tar->filter_map & (1 << LOG_FLT_BSC_SUBSCR)) != 0
- && bsub && bsub == tar->filter_data[LOG_FLT_BSC_SUBSCR])
- return 1;
-
- /* Filter on the NS Virtual Connection */
- if ((tar->filter_map & (1 << LOG_FLT_GB_NSVC)) != 0
- && nsvc && (nsvc == tar->filter_data[LOG_FLT_GB_NSVC]))
- return 1;
-
- /* Filter on the NS Virtual Connection */
- if ((tar->filter_map & (1 << LOG_FLT_GB_BVC)) != 0
- && bvc && (bvc == tar->filter_data[LOG_FLT_GB_BVC]))
- return 1;
-
- return 0;
-}
-
-const struct log_info log_info = {
- .filter_fn = filter_fn,
- .cat = default_categories,
- .num_cat = ARRAY_SIZE(default_categories),
-};
diff --git a/src/libcommon/gsm_data.c b/src/libcommon/gsm_data.c
deleted file mode 100644
index 7be224082..000000000
--- a/src/libcommon/gsm_data.c
+++ /dev/null
@@ -1,459 +0,0 @@
-/* (C) 2008-2010 by Harald Welte <laforge@gnumonks.org>
- *
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * 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 Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <ctype.h>
-#include <stdbool.h>
-#include <netinet/in.h>
-
-#include <osmocom/core/linuxlist.h>
-#include <osmocom/core/talloc.h>
-#include <osmocom/gsm/gsm_utils.h>
-#include <osmocom/gsm/abis_nm.h>
-#include <osmocom/core/statistics.h>
-#include <osmocom/gsm/protocol/gsm_04_08.h>
-
-#include <openbsc/gsm_data.h>
-#include <openbsc/bsc_msc_data.h>
-#include <openbsc/abis_nm.h>
-
-void *tall_bsc_ctx;
-
-static LLIST_HEAD(bts_models);
-
-void set_ts_e1link(struct gsm_bts_trx_ts *ts, uint8_t e1_nr,
- uint8_t e1_ts, uint8_t e1_ts_ss)
-{
- ts->e1_link.e1_nr = e1_nr;
- ts->e1_link.e1_ts = e1_ts;
- ts->e1_link.e1_ts_ss = e1_ts_ss;
-}
-
-static struct gsm_bts_model *bts_model_find(enum gsm_bts_type type)
-{
- struct gsm_bts_model *model;
-
- llist_for_each_entry(model, &bts_models, list) {
- if (model->type == type)
- return model;
- }
-
- return NULL;
-}
-
-int gsm_bts_model_register(struct gsm_bts_model *model)
-{
- if (bts_model_find(model->type))
- return -EEXIST;
-
- tlv_def_patch(&model->nm_att_tlvdef, &abis_nm_att_tlvdef);
- llist_add_tail(&model->list, &bts_models);
- return 0;
-}
-
-const struct value_string bts_type_descs[_NUM_GSM_BTS_TYPE+1] = {
- { GSM_BTS_TYPE_UNKNOWN, "Unknown BTS Type" },
- { GSM_BTS_TYPE_BS11, "Siemens BTS (BS-11 or compatible)" },
- { GSM_BTS_TYPE_NANOBTS, "ip.access nanoBTS or compatible" },
- { GSM_BTS_TYPE_RBS2000, "Ericsson RBS2000 Series" },
- { GSM_BTS_TYPE_NOKIA_SITE, "Nokia {Metro,Ultra,In}Site" },
- { GSM_BTS_TYPE_OSMOBTS, "sysmocom sysmoBTS" },
- { 0, NULL }
-};
-
-struct gsm_bts_trx *gsm_bts_trx_by_nr(struct gsm_bts *bts, int nr)
-{
- struct gsm_bts_trx *trx;
-
- llist_for_each_entry(trx, &bts->trx_list, list) {
- if (trx->nr == nr)
- return trx;
- }
- return NULL;
-}
-
-/* Search for a BTS in the given Location Area; optionally start searching
- * with start_bts (for continuing to search after the first result) */
-struct gsm_bts *gsm_bts_by_lac(struct gsm_network *net, unsigned int lac,
- struct gsm_bts *start_bts)
-{
- int i;
- struct gsm_bts *bts;
- int skip = 0;
-
- if (start_bts)
- skip = 1;
-
- for (i = 0; i < net->num_bts; i++) {
- bts = gsm_bts_num(net, i);
-
- if (skip) {
- if (start_bts == bts)
- skip = 0;
- continue;
- }
-
- if (lac == GSM_LAC_RESERVED_ALL_BTS || bts->location_area_code == lac)
- return bts;
- }
- return NULL;
-}
-
-static const struct value_string auth_policy_names[] = {
- { GSM_AUTH_POLICY_CLOSED, "closed" },
- { GSM_AUTH_POLICY_ACCEPT_ALL, "accept-all" },
- { GSM_AUTH_POLICY_TOKEN, "token" },
- { GSM_AUTH_POLICY_REGEXP, "regexp" },
- { 0, NULL }
-};
-
-enum gsm_auth_policy gsm_auth_policy_parse(const char *arg)
-{
- return get_string_value(auth_policy_names, arg);
-}
-
-const char *gsm_auth_policy_name(enum gsm_auth_policy policy)
-{
- return get_value_string(auth_policy_names, policy);
-}
-
-static const struct value_string rrlp_mode_names[] = {
- { RRLP_MODE_NONE, "none" },
- { RRLP_MODE_MS_BASED, "ms-based" },
- { RRLP_MODE_MS_PREF, "ms-preferred" },
- { RRLP_MODE_ASS_PREF, "ass-preferred" },
- { 0, NULL }
-};
-
-enum rrlp_mode rrlp_mode_parse(const char *arg)
-{
- return get_string_value(rrlp_mode_names, arg);
-}
-
-const char *rrlp_mode_name(enum rrlp_mode mode)
-{
- return get_value_string(rrlp_mode_names, mode);
-}
-
-static const struct value_string bts_gprs_mode_names[] = {
- { BTS_GPRS_NONE, "none" },
- { BTS_GPRS_GPRS, "gprs" },
- { BTS_GPRS_EGPRS, "egprs" },
- { 0, NULL }
-};
-
-enum bts_gprs_mode bts_gprs_mode_parse(const char *arg, int *valid)
-{
- int rc;
-
- rc = get_string_value(bts_gprs_mode_names, arg);
- if (valid)
- *valid = rc != -EINVAL;
- return rc;
-}
-
-const char *bts_gprs_mode_name(enum bts_gprs_mode mode)
-{
- return get_value_string(bts_gprs_mode_names, mode);
-}
-
-int bts_gprs_mode_is_compat(struct gsm_bts *bts, enum bts_gprs_mode mode)
-{
- if (mode != BTS_GPRS_NONE &&
- !gsm_btsmodel_has_feature(bts->model, BTS_FEAT_GPRS)) {
- return 0;
- }
- if (mode == BTS_GPRS_EGPRS &&
- !gsm_btsmodel_has_feature(bts->model, BTS_FEAT_EGPRS)) {
- return 0;
- }
-
- return 1;
-}
-
-int gsm_btsmodel_set_feature(struct gsm_bts_model *model, enum gsm_bts_features feat)
-{
- OSMO_ASSERT(_NUM_BTS_FEAT < MAX_BTS_FEATURES);
- return bitvec_set_bit_pos(&model->features, feat, 1);
-}
-
-bool gsm_btsmodel_has_feature(struct gsm_bts_model *model, enum gsm_bts_features feat)
-{
- OSMO_ASSERT(_NUM_BTS_FEAT < MAX_BTS_FEATURES);
- return bitvec_get_bit_pos(&model->features, feat);
-}
-
-int gsm_set_bts_type(struct gsm_bts *bts, enum gsm_bts_type type)
-{
- struct gsm_bts_model *model;
-
- model = bts_model_find(type);
- if (!model)
- return -EINVAL;
-
- bts->type = type;
- bts->model = model;
-
- if (model->start && !model->started) {
- int ret = model->start(bts->network);
- if (ret < 0)
- return ret;
-
- model->started = true;
- }
-
- switch (bts->type) {
- case GSM_BTS_TYPE_NANOBTS:
- case GSM_BTS_TYPE_OSMOBTS:
- /* Set the default OML Stream ID to 0xff */
- bts->oml_tei = 0xff;
- bts->c0->nominal_power = 23;
- break;
- case GSM_BTS_TYPE_RBS2000:
- INIT_LLIST_HEAD(&bts->rbs2000.is.conn_groups);
- INIT_LLIST_HEAD(&bts->rbs2000.con.conn_groups);
- break;
- case GSM_BTS_TYPE_BS11:
- case GSM_BTS_TYPE_UNKNOWN:
- case GSM_BTS_TYPE_NOKIA_SITE:
- /* Set default BTS reset timer */
- bts->nokia.bts_reset_timer_cnf = 15;
- case _NUM_GSM_BTS_TYPE:
- break;
- }
-
- return 0;
-}
-
-struct gsm_bts *gsm_bts_alloc_register(struct gsm_network *net, enum gsm_bts_type type,
- uint8_t bsic)
-{
- struct gsm_bts_model *model = bts_model_find(type);
- struct gsm_bts *bts;
-
- if (!model && type != GSM_BTS_TYPE_UNKNOWN)
- return NULL;
-
- bts = gsm_bts_alloc(net, net->num_bts);
- if (!bts)
- return NULL;
-
- net->num_bts++;
-
- bts->network = net;
- bts->type = type;
- bts->model = model;
- bts->bsic = bsic;
- bts->dtxu = GSM48_DTX_SHALL_NOT_BE_USED;
- bts->dtxd = false;
- bts->gprs.ctrl_ack_type_use_block = true; /* use RLC/MAC control block */
- bts->neigh_list_manual_mode = 0;
- bts->si_common.cell_sel_par.cell_resel_hyst = 2; /* 4 dB */
- bts->si_common.cell_sel_par.rxlev_acc_min = 0;
- bts->si_common.si2quater_neigh_list.arfcn = bts->si_common.data.earfcn_list;
- bts->si_common.si2quater_neigh_list.meas_bw = bts->si_common.data.meas_bw_list;
- bts->si_common.si2quater_neigh_list.length = MAX_EARFCN_LIST;
- bts->si_common.si2quater_neigh_list.thresh_hi = 0;
- osmo_earfcn_init(&bts->si_common.si2quater_neigh_list);
- bts->si_common.neigh_list.data = bts->si_common.data.neigh_list;
- bts->si_common.neigh_list.data_len =
- sizeof(bts->si_common.data.neigh_list);
- bts->si_common.si5_neigh_list.data = bts->si_common.data.si5_neigh_list;
- bts->si_common.si5_neigh_list.data_len =
- sizeof(bts->si_common.data.si5_neigh_list);
- bts->si_common.cell_alloc.data = bts->si_common.data.cell_alloc;
- bts->si_common.cell_alloc.data_len =
- sizeof(bts->si_common.data.cell_alloc);
- bts->si_common.rach_control.re = 1; /* no re-establishment */
- bts->si_common.rach_control.tx_integer = 9; /* 12 slots spread - 217/115 slots delay */
- bts->si_common.rach_control.max_trans = 3; /* 7 retransmissions */
- bts->si_common.rach_control.t2 = 4; /* no emergency calls */
- bts->si_common.chan_desc.att = 1; /* attachment required */
- bts->si_common.chan_desc.bs_pa_mfrms = RSL_BS_PA_MFRMS_5; /* paging frames */
- bts->si_common.chan_desc.bs_ag_blks_res = 1; /* reserved AGCH blocks */
- bts->si_common.chan_desc.t3212 = net->t3212; /* Use network's current value */
- gsm_bts_set_radio_link_timeout(bts, 32); /* Use RADIO LINK TIMEOUT of 32 */
-
- llist_add_tail(&bts->list, &net->bts_list);
-
- INIT_LLIST_HEAD(&bts->abis_queue);
-
- INIT_LLIST_HEAD(&bts->loc_list);
-
- return bts;
-}
-
-void gprs_ra_id_by_bts(struct gprs_ra_id *raid, struct gsm_bts *bts)
-{
- raid->mcc = bts->network->country_code;
- raid->mnc = bts->network->network_code;
- raid->lac = bts->location_area_code;
- raid->rac = bts->gprs.rac;
-}
-
-int gsm48_ra_id_by_bts(uint8_t *buf, struct gsm_bts *bts)
-{
- struct gprs_ra_id raid;
-
- gprs_ra_id_by_bts(&raid, bts);
-
- return gsm48_construct_ra(buf, &raid);
-}
-
-int gsm_parse_reg(void *ctx, regex_t *reg, char **str, int argc, const char **argv)
-{
- int ret;
-
- ret = 0;
- if (*str) {
- talloc_free(*str);
- *str = NULL;
- }
- regfree(reg);
-
- if (argc > 0) {
- *str = talloc_strdup(ctx, argv[0]);
- ret = regcomp(reg, argv[0], 0);
-
- /* handle compilation failures */
- if (ret != 0) {
- talloc_free(*str);
- *str = NULL;
- }
- }
-
- return ret;
-}
-
-/* Assume there are only 256 possible bts */
-osmo_static_assert(sizeof(((struct gsm_bts *) 0)->nr) == 1, _bts_nr_is_256);
-static void depends_calc_index_bit(int bts_nr, int *idx, int *bit)
-{
- *idx = bts_nr / (8 * 4);
- *bit = bts_nr % (8 * 4);
-}
-
-void bts_depend_mark(struct gsm_bts *bts, int dep)
-{
- int idx, bit;
- depends_calc_index_bit(dep, &idx, &bit);
-
- bts->depends_on[idx] |= 1 << bit;
-}
-
-void bts_depend_clear(struct gsm_bts *bts, int dep)
-{
- int idx, bit;
- depends_calc_index_bit(dep, &idx, &bit);
-
- bts->depends_on[idx] &= ~(1 << bit);
-}
-
-int bts_depend_is_depedency(struct gsm_bts *base, struct gsm_bts *other)
-{
- int idx, bit;
- depends_calc_index_bit(other->nr, &idx, &bit);
-
- /* Check if there is a depends bit */
- return (base->depends_on[idx] & (1 << bit)) > 0;
-}
-
-static int bts_is_online(struct gsm_bts *bts)
-{
- /* TODO: support E1 BTS too */
- if (!is_ipaccess_bts(bts))
- return 1;
-
- if (!bts->oml_link)
- return 0;
-
- return bts->mo.nm_state.operational == NM_OPSTATE_ENABLED;
-}
-
-int bts_depend_check(struct gsm_bts *bts)
-{
- struct gsm_bts *other_bts;
-
- llist_for_each_entry(other_bts, &bts->network->bts_list, list) {
- if (!bts_depend_is_depedency(bts, other_bts))
- continue;
- if (bts_is_online(other_bts))
- continue;
- return 0;
- }
- return 1;
-}
-
-/* get the radio link timeout (based on SACCH decode errors, according
- * to algorithm specified in TS 05.08 section 5.2. A value of -1
- * indicates we should use an infinitely long timeout, which only works
- * with OsmoBTS as the BTS implementation */
-int gsm_bts_get_radio_link_timeout(const struct gsm_bts *bts)
-{
- const struct gsm48_cell_options *cell_options = &bts->si_common.cell_options;
-
- if (bts->infinite_radio_link_timeout)
- return -1;
- else {
- /* Encoding as per Table 10.5.21 of TS 04.08 */
- return (cell_options->radio_link_timeout + 1) << 2;
- }
-}
-
-/* set the radio link timeout (based on SACCH decode errors, according
- * to algorithm specified in TS 05.08 Section 5.2. A value of -1
- * indicates we should use an infinitely long timeout, which only works
- * with OsmoBTS as the BTS implementation */
-void gsm_bts_set_radio_link_timeout(struct gsm_bts *bts, int value)
-{
- struct gsm48_cell_options *cell_options = &bts->si_common.cell_options;
-
- if (value < 0)
- bts->infinite_radio_link_timeout = true;
- else {
- bts->infinite_radio_link_timeout = false;
- /* Encoding as per Table 10.5.21 of TS 04.08 */
- if (value < 4)
- value = 4;
- if (value > 64)
- value = 64;
- cell_options->radio_link_timeout = (value >> 2) - 1;
- }
-}
-
-bool classmark_is_r99(struct gsm_classmark *cm)
-{
- int rev_lev = 0;
- if (cm->classmark1_set)
- rev_lev = cm->classmark1.rev_lev;
- else if (cm->classmark2_len > 0)
- rev_lev = (cm->classmark2[0] >> 5) & 0x3;
- return rev_lev >= 2;
-}
-
-const struct value_string ran_type_names[] = {
- OSMO_VALUE_STRING(RAN_UNKNOWN),
- OSMO_VALUE_STRING(RAN_GERAN_A),
- OSMO_VALUE_STRING(RAN_UTRAN_IU),
- { 0, NULL }
-};
diff --git a/src/libcommon/gsm_data_shared.c b/src/libcommon/gsm_data_shared.c
deleted file mode 100644
index 26962730a..000000000
--- a/src/libcommon/gsm_data_shared.c
+++ /dev/null
@@ -1,853 +0,0 @@
-/* (C) 2008-2010 by Harald Welte <laforge@gnumonks.org>
- *
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * 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 Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <ctype.h>
-
-#include <netinet/in.h>
-
-#include <osmocom/core/linuxlist.h>
-#include <osmocom/core/talloc.h>
-#include <osmocom/gsm/gsm_utils.h>
-#include <osmocom/gsm/abis_nm.h>
-#include <osmocom/core/statistics.h>
-
-#include <openbsc/gsm_data.h>
-
-void gsm_abis_mo_reset(struct gsm_abis_mo *mo)
-{
- mo->nm_state.operational = NM_OPSTATE_NULL;
- mo->nm_state.availability = NM_AVSTATE_POWER_OFF;
-}
-
-static void gsm_mo_init(struct gsm_abis_mo *mo, struct gsm_bts *bts,
- uint8_t obj_class, uint8_t p1, uint8_t p2, uint8_t p3)
-{
- mo->bts = bts;
- mo->obj_class = obj_class;
- mo->obj_inst.bts_nr = p1;
- mo->obj_inst.trx_nr = p2;
- mo->obj_inst.ts_nr = p3;
- gsm_abis_mo_reset(mo);
-}
-
-const struct value_string bts_attribute_names[] = {
- OSMO_VALUE_STRING(BTS_TYPE_VARIANT),
- OSMO_VALUE_STRING(BTS_SUB_MODEL),
- OSMO_VALUE_STRING(TRX_PHY_VERSION),
- { 0, NULL }
-};
-
-enum bts_attribute str2btsattr(const char *s)
-{
- return get_string_value(bts_attribute_names, s);
-}
-
-const char *btsatttr2str(enum bts_attribute v)
-{
- return get_value_string(bts_attribute_names, v);
-}
-
-const struct value_string osmo_bts_variant_names[_NUM_BTS_VARIANT + 1] = {
- { BTS_UNKNOWN, "unknown" },
- { BTS_OSMO_LITECELL15, "osmo-bts-lc15" },
- { BTS_OSMO_OCTPHY, "osmo-bts-octphy" },
- { BTS_OSMO_SYSMO, "osmo-bts-sysmo" },
- { BTS_OSMO_TRX, "omso-bts-trx" },
- { 0, NULL }
-};
-
-enum gsm_bts_type_variant str2btsvariant(const char *arg)
-{
- return get_string_value(osmo_bts_variant_names, arg);
-}
-
-const char *btsvariant2str(enum gsm_bts_type_variant v)
-{
- return get_value_string(osmo_bts_variant_names, v);
-}
-
-const struct value_string bts_type_names[_NUM_GSM_BTS_TYPE + 1] = {
- { GSM_BTS_TYPE_UNKNOWN, "unknown" },
- { GSM_BTS_TYPE_BS11, "bs11" },
- { GSM_BTS_TYPE_NANOBTS, "nanobts" },
- { GSM_BTS_TYPE_RBS2000, "rbs2000" },
- { GSM_BTS_TYPE_NOKIA_SITE, "nokia_site" },
- { GSM_BTS_TYPE_OSMOBTS, "sysmobts" },
- { 0, NULL }
-};
-
-enum gsm_bts_type str2btstype(const char *arg)
-{
- return get_string_value(bts_type_names, arg);
-}
-
-const char *btstype2str(enum gsm_bts_type type)
-{
- return get_value_string(bts_type_names, type);
-}
-
-const struct value_string gsm_bts_features_descs[] = {
- { BTS_FEAT_HSCSD, "HSCSD" },
- { BTS_FEAT_GPRS, "GPRS" },
- { BTS_FEAT_EGPRS, "EGPRS" },
- { BTS_FEAT_ECSD, "ECSD" },
- { BTS_FEAT_HOPPING, "Frequency Hopping" },
- { BTS_FEAT_MULTI_TSC, "Multi-TSC" },
- { BTS_FEAT_OML_ALERTS, "OML Alerts" },
- { BTS_FEAT_AGCH_PCH_PROP, "AGCH/PCH proportional allocation" },
- { BTS_FEAT_CBCH, "CBCH" },
- { 0, NULL }
-};
-
-const struct value_string gsm_chreq_descs[] = {
- { GSM_CHREQ_REASON_EMERG, "emergency call" },
- { GSM_CHREQ_REASON_PAG, "answer to paging" },
- { GSM_CHREQ_REASON_CALL, "call re-establishment" },
- { GSM_CHREQ_REASON_LOCATION_UPD,"Location updating" },
- { GSM_CHREQ_REASON_PDCH, "one phase packet access" },
- { GSM_CHREQ_REASON_OTHER, "other" },
- { 0, NULL }
-};
-
-const struct value_string gsm_pchant_names[13] = {
- { GSM_PCHAN_NONE, "NONE" },
- { GSM_PCHAN_CCCH, "CCCH" },
- { GSM_PCHAN_CCCH_SDCCH4,"CCCH+SDCCH4" },
- { GSM_PCHAN_TCH_F, "TCH/F" },
- { GSM_PCHAN_TCH_H, "TCH/H" },
- { GSM_PCHAN_SDCCH8_SACCH8C, "SDCCH8" },
- { GSM_PCHAN_PDCH, "PDCH" },
- { GSM_PCHAN_TCH_F_PDCH, "TCH/F_PDCH" },
- { GSM_PCHAN_UNKNOWN, "UNKNOWN" },
- { GSM_PCHAN_CCCH_SDCCH4_CBCH, "CCCH+SDCCH4+CBCH" },
- { GSM_PCHAN_SDCCH8_SACCH8C_CBCH, "SDCCH8+CBCH" },
- { GSM_PCHAN_TCH_F_TCH_H_PDCH, "TCH/F_TCH/H_PDCH" },
- { 0, NULL }
-};
-
-const struct value_string gsm_pchant_descs[13] = {
- { GSM_PCHAN_NONE, "Physical Channel not configured" },
- { GSM_PCHAN_CCCH, "FCCH + SCH + BCCH + CCCH (Comb. IV)" },
- { GSM_PCHAN_CCCH_SDCCH4,
- "FCCH + SCH + BCCH + CCCH + 4 SDCCH + 2 SACCH (Comb. V)" },
- { GSM_PCHAN_TCH_F, "TCH/F + FACCH/F + SACCH (Comb. I)" },
- { GSM_PCHAN_TCH_H, "2 TCH/H + 2 FACCH/H + 2 SACCH (Comb. II)" },
- { GSM_PCHAN_SDCCH8_SACCH8C, "8 SDCCH + 4 SACCH (Comb. VII)" },
- { GSM_PCHAN_PDCH, "Packet Data Channel for GPRS/EDGE" },
- { GSM_PCHAN_TCH_F_PDCH, "Dynamic TCH/F or GPRS PDCH" },
- { GSM_PCHAN_UNKNOWN, "Unknown / Unsupported channel combination" },
- { GSM_PCHAN_CCCH_SDCCH4_CBCH, "FCCH + SCH + BCCH + CCCH + CBCH + 3 SDCCH + 2 SACCH (Comb. V)" },
- { GSM_PCHAN_SDCCH8_SACCH8C_CBCH, "7 SDCCH + 4 SACCH + CBCH (Comb. VII)" },
- { GSM_PCHAN_TCH_F_TCH_H_PDCH, "Dynamic TCH/F or TCH/H or GPRS PDCH" },
- { 0, NULL }
-};
-
-const char *gsm_pchan_name(enum gsm_phys_chan_config c)
-{
- return get_value_string(gsm_pchant_names, c);
-}
-
-enum gsm_phys_chan_config gsm_pchan_parse(const char *name)
-{
- return get_string_value(gsm_pchant_names, name);
-}
-
-/* TODO: move to libosmocore, next to gsm_chan_t_names? */
-const char *gsm_lchant_name(enum gsm_chan_t c)
-{
- return get_value_string(gsm_chan_t_names, c);
-}
-
-static const struct value_string lchan_s_names[] = {
- { LCHAN_S_NONE, "NONE" },
- { LCHAN_S_ACT_REQ, "ACTIVATION REQUESTED" },
- { LCHAN_S_ACTIVE, "ACTIVE" },
- { LCHAN_S_INACTIVE, "INACTIVE" },
- { LCHAN_S_REL_REQ, "RELEASE REQUESTED" },
- { LCHAN_S_REL_ERR, "RELEASE DUE ERROR" },
- { LCHAN_S_BROKEN, "BROKEN UNUSABLE" },
- { 0, NULL }
-};
-
-const char *gsm_lchans_name(enum gsm_lchan_state s)
-{
- return get_value_string(lchan_s_names, s);
-}
-
-static const struct value_string chreq_names[] = {
- { GSM_CHREQ_REASON_EMERG, "EMERGENCY" },
- { GSM_CHREQ_REASON_PAG, "PAGING" },
- { GSM_CHREQ_REASON_CALL, "CALL" },
- { GSM_CHREQ_REASON_LOCATION_UPD,"LOCATION_UPDATE" },
- { GSM_CHREQ_REASON_OTHER, "OTHER" },
- { 0, NULL }
-};
-
-const char *gsm_chreq_name(enum gsm_chreq_reason_t c)
-{
- return get_value_string(chreq_names, c);
-}
-
-struct gsm_bts *gsm_bts_num(struct gsm_network *net, int num)
-{
- struct gsm_bts *bts;
-
- if (num >= net->num_bts)
- return NULL;
-
- llist_for_each_entry(bts, &net->bts_list, list) {
- if (bts->nr == num)
- return bts;
- }
-
- return NULL;
-}
-
-struct gsm_bts_trx *gsm_bts_trx_alloc(struct gsm_bts *bts)
-{
- struct gsm_bts_trx *trx = talloc_zero(bts, struct gsm_bts_trx);
- int k;
-
- if (!trx)
- return NULL;
-
- trx->bts = bts;
- trx->nr = bts->num_trx++;
- trx->mo.nm_state.administrative = NM_STATE_UNLOCKED;
-
- gsm_mo_init(&trx->mo, bts, NM_OC_RADIO_CARRIER,
- bts->nr, trx->nr, 0xff);
- gsm_mo_init(&trx->bb_transc.mo, bts, NM_OC_BASEB_TRANSC,
- bts->nr, trx->nr, 0xff);
-
- for (k = 0; k < TRX_NR_TS; k++) {
- struct gsm_bts_trx_ts *ts = &trx->ts[k];
- int l;
-
- ts->trx = trx;
- ts->nr = k;
- ts->pchan = GSM_PCHAN_NONE;
- ts->dyn.pchan_is = GSM_PCHAN_NONE;
- ts->dyn.pchan_want = GSM_PCHAN_NONE;
- ts->tsc = -1;
-
- gsm_mo_init(&ts->mo, bts, NM_OC_CHANNEL,
- bts->nr, trx->nr, ts->nr);
-
- ts->hopping.arfcns.data_len = sizeof(ts->hopping.arfcns_data);
- ts->hopping.arfcns.data = ts->hopping.arfcns_data;
- ts->hopping.ma.data_len = sizeof(ts->hopping.ma_data);
- ts->hopping.ma.data = ts->hopping.ma_data;
-
- for (l = 0; l < TS_MAX_LCHAN; l++) {
- struct gsm_lchan *lchan;
- char *name;
- lchan = &ts->lchan[l];
-
- lchan->ts = ts;
- lchan->nr = l;
- lchan->type = GSM_LCHAN_NONE;
-
- name = gsm_lchan_name_compute(lchan);
- lchan->name = talloc_strdup(trx, name);
-#ifndef ROLE_BSC
- INIT_LLIST_HEAD(&lchan->sapi_cmds);
-#endif
- }
- }
-
- if (trx->nr != 0)
- trx->nominal_power = bts->c0->nominal_power;
-
- llist_add_tail(&trx->list, &bts->trx_list);
-
- return trx;
-}
-
-
-static const uint8_t bts_nse_timer_default[] = { 3, 3, 3, 3, 30, 3, 10 };
-static const uint8_t bts_cell_timer_default[] =
- { 3, 3, 3, 3, 3, 10, 3, 10, 3, 10, 3 };
-static const struct gprs_rlc_cfg rlc_cfg_default = {
- .parameter = {
- [RLC_T3142] = 20,
- [RLC_T3169] = 5,
- [RLC_T3191] = 5,
- [RLC_T3193] = 160, /* 10ms */
- [RLC_T3195] = 5,
- [RLC_N3101] = 10,
- [RLC_N3103] = 4,
- [RLC_N3105] = 8,
- [CV_COUNTDOWN] = 15,
- [T_DL_TBF_EXT] = 250 * 10, /* ms */
- [T_UL_TBF_EXT] = 250 * 10, /* ms */
- },
- .paging = {
- .repeat_time = 5 * 50, /* ms */
- .repeat_count = 3,
- },
- .cs_mask = 0x1fff,
- .initial_cs = 2,
- .initial_mcs = 6,
-};
-
-struct gsm_bts *gsm_bts_alloc(void *ctx, uint8_t bts_num)
-{
- struct gsm_bts *bts = talloc_zero(ctx, struct gsm_bts);
- int i;
-
- if (!bts)
- return NULL;
-
- bts->nr = bts_num;
- bts->num_trx = 0;
- INIT_LLIST_HEAD(&bts->trx_list);
- bts->ms_max_power = 15; /* dBm */
-
- gsm_mo_init(&bts->mo, bts, NM_OC_BTS,
- bts->nr, 0xff, 0xff);
- gsm_mo_init(&bts->site_mgr.mo, bts, NM_OC_SITE_MANAGER,
- 0xff, 0xff, 0xff);
-
- for (i = 0; i < ARRAY_SIZE(bts->gprs.nsvc); i++) {
- bts->gprs.nsvc[i].bts = bts;
- bts->gprs.nsvc[i].id = i;
- gsm_mo_init(&bts->gprs.nsvc[i].mo, bts, NM_OC_GPRS_NSVC,
- bts->nr, i, 0xff);
- }
- memcpy(&bts->gprs.nse.timer, bts_nse_timer_default,
- sizeof(bts->gprs.nse.timer));
- gsm_mo_init(&bts->gprs.nse.mo, bts, NM_OC_GPRS_NSE,
- bts->nr, 0xff, 0xff);
- memcpy(&bts->gprs.cell.timer, bts_cell_timer_default,
- sizeof(bts->gprs.cell.timer));
- gsm_mo_init(&bts->gprs.cell.mo, bts, NM_OC_GPRS_CELL,
- bts->nr, 0xff, 0xff);
- memcpy(&bts->gprs.cell.rlc_cfg, &rlc_cfg_default,
- sizeof(bts->gprs.cell.rlc_cfg));
-
- /* create our primary TRX */
- bts->c0 = gsm_bts_trx_alloc(bts);
- if (!bts->c0) {
- talloc_free(bts);
- return NULL;
- }
- bts->c0->ts[0].pchan = GSM_PCHAN_CCCH_SDCCH4;
-
- bts->rach_b_thresh = -1;
- bts->rach_ldavg_slots = -1;
- bts->paging.free_chans_need = -1;
- bts->features.data = &bts->_features_data[0];
- bts->features.data_len = sizeof(bts->_features_data);
-
- /* si handling */
- bts->bcch_change_mark = 1;
-
- return bts;
-}
-
-/* reset the state of all MO in the BTS */
-void gsm_bts_mo_reset(struct gsm_bts *bts)
-{
- struct gsm_bts_trx *trx;
- unsigned int i;
-
- gsm_abis_mo_reset(&bts->mo);
- gsm_abis_mo_reset(&bts->site_mgr.mo);
- for (i = 0; i < ARRAY_SIZE(bts->gprs.nsvc); i++)
- gsm_abis_mo_reset(&bts->gprs.nsvc[i].mo);
- gsm_abis_mo_reset(&bts->gprs.nse.mo);
- gsm_abis_mo_reset(&bts->gprs.cell.mo);
-
- llist_for_each_entry(trx, &bts->trx_list, list) {
- gsm_abis_mo_reset(&trx->mo);
- gsm_abis_mo_reset(&trx->bb_transc.mo);
-
- for (i = 0; i < ARRAY_SIZE(trx->ts); i++) {
- struct gsm_bts_trx_ts *ts = &trx->ts[i];
- gsm_abis_mo_reset(&ts->mo);
- }
- }
-}
-
-struct gsm_bts_trx *gsm_bts_trx_num(const struct gsm_bts *bts, int num)
-{
- struct gsm_bts_trx *trx;
-
- if (num >= bts->num_trx)
- return NULL;
-
- llist_for_each_entry(trx, &bts->trx_list, list) {
- if (trx->nr == num)
- return trx;
- }
-
- return NULL;
-}
-
-static char ts2str[255];
-
-char *gsm_trx_name(const struct gsm_bts_trx *trx)
-{
- if (!trx)
- snprintf(ts2str, sizeof(ts2str), "(trx=NULL)");
- else
- snprintf(ts2str, sizeof(ts2str), "(bts=%d,trx=%d)",
- trx->bts->nr, trx->nr);
-
- return ts2str;
-}
-
-
-char *gsm_ts_name(const struct gsm_bts_trx_ts *ts)
-{
- snprintf(ts2str, sizeof(ts2str), "(bts=%d,trx=%d,ts=%d)",
- ts->trx->bts->nr, ts->trx->nr, ts->nr);
-
- return ts2str;
-}
-
-/*! Log timeslot number with full pchan information */
-char *gsm_ts_and_pchan_name(const struct gsm_bts_trx_ts *ts)
-{
- switch (ts->pchan) {
- case GSM_PCHAN_TCH_F_TCH_H_PDCH:
- if (ts->dyn.pchan_is == ts->dyn.pchan_want)
- snprintf(ts2str, sizeof(ts2str),
- "(bts=%d,trx=%d,ts=%d,pchan=%s as %s)",
- ts->trx->bts->nr, ts->trx->nr, ts->nr,
- gsm_pchan_name(ts->pchan),
- gsm_pchan_name(ts->dyn.pchan_is));
- else
- snprintf(ts2str, sizeof(ts2str),
- "(bts=%d,trx=%d,ts=%d,pchan=%s"
- " switching %s -> %s)",
- ts->trx->bts->nr, ts->trx->nr, ts->nr,
- gsm_pchan_name(ts->pchan),
- gsm_pchan_name(ts->dyn.pchan_is),
- gsm_pchan_name(ts->dyn.pchan_want));
- break;
- case GSM_PCHAN_TCH_F_PDCH:
- if ((ts->flags & TS_F_PDCH_PENDING_MASK) == 0)
- snprintf(ts2str, sizeof(ts2str),
- "(bts=%d,trx=%d,ts=%d,pchan=%s as %s)",
- ts->trx->bts->nr, ts->trx->nr, ts->nr,
- gsm_pchan_name(ts->pchan),
- (ts->flags & TS_F_PDCH_ACTIVE)? "PDCH"
- : "TCH/F");
- else
- snprintf(ts2str, sizeof(ts2str),
- "(bts=%d,trx=%d,ts=%d,pchan=%s"
- " switching %s -> %s)",
- ts->trx->bts->nr, ts->trx->nr, ts->nr,
- gsm_pchan_name(ts->pchan),
- (ts->flags & TS_F_PDCH_ACTIVE)? "PDCH"
- : "TCH/F",
- (ts->flags & TS_F_PDCH_ACT_PENDING)? "PDCH"
- : "TCH/F");
- break;
- default:
- snprintf(ts2str, sizeof(ts2str), "(bts=%d,trx=%d,ts=%d,pchan=%s)",
- ts->trx->bts->nr, ts->trx->nr, ts->nr,
- gsm_pchan_name(ts->pchan));
- break;
- }
-
- return ts2str;
-}
-
-char *gsm_lchan_name_compute(const struct gsm_lchan *lchan)
-{
- struct gsm_bts_trx_ts *ts = lchan->ts;
-
- snprintf(ts2str, sizeof(ts2str), "(bts=%d,trx=%d,ts=%d,ss=%d)",
- ts->trx->bts->nr, ts->trx->nr, ts->nr, lchan->nr);
-
- return ts2str;
-}
-
-/* obtain the MO structure for a given object instance */
-struct gsm_abis_mo *
-gsm_objclass2mo(struct gsm_bts *bts, uint8_t obj_class,
- const struct abis_om_obj_inst *obj_inst)
-{
- struct gsm_bts_trx *trx;
- struct gsm_abis_mo *mo = NULL;
-
- switch (obj_class) {
- case NM_OC_BTS:
- mo = &bts->mo;
- break;
- case NM_OC_RADIO_CARRIER:
- if (obj_inst->trx_nr >= bts->num_trx) {
- return NULL;
- }
- trx = gsm_bts_trx_num(bts, obj_inst->trx_nr);
- mo = &trx->mo;
- break;
- case NM_OC_BASEB_TRANSC:
- if (obj_inst->trx_nr >= bts->num_trx) {
- return NULL;
- }
- trx = gsm_bts_trx_num(bts, obj_inst->trx_nr);
- mo = &trx->bb_transc.mo;
- break;
- case NM_OC_CHANNEL:
- if (obj_inst->trx_nr >= bts->num_trx) {
- return NULL;
- }
- trx = gsm_bts_trx_num(bts, obj_inst->trx_nr);
- if (obj_inst->ts_nr >= TRX_NR_TS)
- return NULL;
- mo = &trx->ts[obj_inst->ts_nr].mo;
- break;
- case NM_OC_SITE_MANAGER:
- mo = &bts->site_mgr.mo;
- break;
- case NM_OC_BS11:
- switch (obj_inst->bts_nr) {
- case BS11_OBJ_CCLK:
- mo = &bts->bs11.cclk.mo;
- break;
- case BS11_OBJ_BBSIG:
- if (obj_inst->ts_nr > bts->num_trx)
- return NULL;
- trx = gsm_bts_trx_num(bts, obj_inst->trx_nr);
- mo = &trx->bs11.bbsig.mo;
- break;
- case BS11_OBJ_PA:
- if (obj_inst->ts_nr > bts->num_trx)
- return NULL;
- trx = gsm_bts_trx_num(bts, obj_inst->trx_nr);
- mo = &trx->bs11.pa.mo;
- break;
- default:
- return NULL;
- }
- break;
- case NM_OC_BS11_RACK:
- mo = &bts->bs11.rack.mo;
- break;
- case NM_OC_BS11_ENVABTSE:
- if (obj_inst->trx_nr >= ARRAY_SIZE(bts->bs11.envabtse))
- return NULL;
- mo = &bts->bs11.envabtse[obj_inst->trx_nr].mo;
- break;
- case NM_OC_GPRS_NSE:
- mo = &bts->gprs.nse.mo;
- break;
- case NM_OC_GPRS_CELL:
- mo = &bts->gprs.cell.mo;
- break;
- case NM_OC_GPRS_NSVC:
- if (obj_inst->trx_nr >= ARRAY_SIZE(bts->gprs.nsvc))
- return NULL;
- mo = &bts->gprs.nsvc[obj_inst->trx_nr].mo;
- break;
- }
- return mo;
-}
-
-/* obtain the gsm_nm_state data structure for a given object instance */
-struct gsm_nm_state *
-gsm_objclass2nmstate(struct gsm_bts *bts, uint8_t obj_class,
- const struct abis_om_obj_inst *obj_inst)
-{
- struct gsm_abis_mo *mo;
-
- mo = gsm_objclass2mo(bts, obj_class, obj_inst);
- if (!mo)
- return NULL;
-
- return &mo->nm_state;
-}
-
-/* obtain the in-memory data structure of a given object instance */
-void *
-gsm_objclass2obj(struct gsm_bts *bts, uint8_t obj_class,
- const struct abis_om_obj_inst *obj_inst)
-{
- struct gsm_bts_trx *trx;
- void *obj = NULL;
-
- switch (obj_class) {
- case NM_OC_BTS:
- obj = bts;
- break;
- case NM_OC_RADIO_CARRIER:
- if (obj_inst->trx_nr >= bts->num_trx) {
- return NULL;
- }
- trx = gsm_bts_trx_num(bts, obj_inst->trx_nr);
- obj = trx;
- break;
- case NM_OC_BASEB_TRANSC:
- if (obj_inst->trx_nr >= bts->num_trx) {
- return NULL;
- }
- trx = gsm_bts_trx_num(bts, obj_inst->trx_nr);
- obj = &trx->bb_transc;
- break;
- case NM_OC_CHANNEL:
- if (obj_inst->trx_nr >= bts->num_trx) {
- return NULL;
- }
- trx = gsm_bts_trx_num(bts, obj_inst->trx_nr);
- if (obj_inst->ts_nr >= TRX_NR_TS)
- return NULL;
- obj = &trx->ts[obj_inst->ts_nr];
- break;
- case NM_OC_SITE_MANAGER:
- obj = &bts->site_mgr;
- break;
- case NM_OC_GPRS_NSE:
- obj = &bts->gprs.nse;
- break;
- case NM_OC_GPRS_CELL:
- obj = &bts->gprs.cell;
- break;
- case NM_OC_GPRS_NSVC:
- if (obj_inst->trx_nr >= ARRAY_SIZE(bts->gprs.nsvc))
- return NULL;
- obj = &bts->gprs.nsvc[obj_inst->trx_nr];
- break;
- }
- return obj;
-}
-
-/* See Table 10.5.25 of GSM04.08 */
-uint8_t gsm_pchan2chan_nr(enum gsm_phys_chan_config pchan,
- uint8_t ts_nr, uint8_t lchan_nr)
-{
- uint8_t cbits, chan_nr;
-
- switch (pchan) {
- case GSM_PCHAN_TCH_F:
- case GSM_PCHAN_TCH_F_PDCH:
- OSMO_ASSERT(lchan_nr == 0);
- cbits = 0x01;
- break;
- case GSM_PCHAN_PDCH:
- OSMO_ASSERT(lchan_nr == 0);
- cbits = RSL_CHAN_OSMO_PDCH >> 3;
- break;
- case GSM_PCHAN_TCH_H:
- OSMO_ASSERT(lchan_nr < 2);
- cbits = 0x02;
- cbits += lchan_nr;
- break;
- case GSM_PCHAN_CCCH_SDCCH4:
- case GSM_PCHAN_CCCH_SDCCH4_CBCH:
- /*
- * As a special hack for BCCH, lchan_nr == 4 may be passed
- * here. This should never be sent in an RSL message.
- * See osmo-bts-xxx/oml.c:opstart_compl().
- */
- if (lchan_nr == CCCH_LCHAN)
- chan_nr = 0;
- else
- OSMO_ASSERT(lchan_nr < 4);
- cbits = 0x04;
- cbits += lchan_nr;
- break;
- case GSM_PCHAN_SDCCH8_SACCH8C:
- case GSM_PCHAN_SDCCH8_SACCH8C_CBCH:
- OSMO_ASSERT(lchan_nr < 8);
- cbits = 0x08;
- cbits += lchan_nr;
- break;
- default:
- case GSM_PCHAN_CCCH:
-#ifdef ROLE_BSC
- OSMO_ASSERT(lchan_nr == 0);
-#else
- /*
- * FIXME: On octphy and litecell, we hit above assertion (see
- * Max's comment at https://gerrit.osmocom.org/589 ); disabled
- * for BTS until this is clarified; remove the #ifdef when it
- * is fixed.
- */
-#warning "fix caller that passes lchan_nr != 0"
-#endif
- cbits = 0x10;
- break;
- }
-
- chan_nr = (cbits << 3) | (ts_nr & 0x7);
-
- return chan_nr;
-}
-
-uint8_t gsm_lchan2chan_nr(const struct gsm_lchan *lchan)
-{
- enum gsm_phys_chan_config pchan = lchan->ts->pchan;
- if (pchan == GSM_PCHAN_TCH_F_TCH_H_PDCH)
- return gsm_lchan_as_pchan2chan_nr(lchan,
- lchan->ts->dyn.pchan_is);
- return gsm_pchan2chan_nr(lchan->ts->pchan, lchan->ts->nr, lchan->nr);
-}
-
-uint8_t gsm_lchan_as_pchan2chan_nr(const struct gsm_lchan *lchan,
- enum gsm_phys_chan_config as_pchan)
-{
- if (lchan->ts->pchan == GSM_PCHAN_TCH_F_TCH_H_PDCH
- && as_pchan == GSM_PCHAN_PDCH)
- return RSL_CHAN_OSMO_PDCH | (lchan->ts->nr & ~RSL_CHAN_NR_MASK);
- return gsm_pchan2chan_nr(as_pchan, lchan->ts->nr, lchan->nr);
-}
-
-/* return the gsm_lchan for the CBCH (if it exists at all) */
-struct gsm_lchan *gsm_bts_get_cbch(struct gsm_bts *bts)
-{
- struct gsm_lchan *lchan = NULL;
- struct gsm_bts_trx *trx = bts->c0;
-
- if (trx->ts[0].pchan == GSM_PCHAN_CCCH_SDCCH4_CBCH)
- lchan = &trx->ts[0].lchan[2];
- else {
- int i;
- for (i = 0; i < 8; i++) {
- if (trx->ts[i].pchan == GSM_PCHAN_SDCCH8_SACCH8C_CBCH) {
- lchan = &trx->ts[i].lchan[2];
- break;
- }
- }
- }
-
- return lchan;
-}
-
-/* determine logical channel based on TRX and channel number IE */
-struct gsm_lchan *rsl_lchan_lookup(struct gsm_bts_trx *trx, uint8_t chan_nr,
- int *rc)
-{
- uint8_t ts_nr = chan_nr & 0x07;
- uint8_t cbits = chan_nr >> 3;
- uint8_t lch_idx;
- struct gsm_bts_trx_ts *ts = &trx->ts[ts_nr];
- bool ok = true;
-
- if (rc)
- *rc = -EINVAL;
-
- if (cbits == 0x01) {
- lch_idx = 0; /* TCH/F */
- if (ts->pchan != GSM_PCHAN_TCH_F &&
- ts->pchan != GSM_PCHAN_PDCH &&
- ts->pchan != GSM_PCHAN_TCH_F_PDCH
- && !(ts->pchan == GSM_PCHAN_TCH_F_TCH_H_PDCH
- && (ts->dyn.pchan_is == GSM_PCHAN_TCH_F
- || ts->dyn.pchan_want == GSM_PCHAN_TCH_F)))
- ok = false;
- } else if ((cbits & 0x1e) == 0x02) {
- lch_idx = cbits & 0x1; /* TCH/H */
- if (ts->pchan != GSM_PCHAN_TCH_H
- && !(ts->pchan == GSM_PCHAN_TCH_F_TCH_H_PDCH
- && (ts->dyn.pchan_is == GSM_PCHAN_TCH_H
- || ts->dyn.pchan_want == GSM_PCHAN_TCH_H)))
- ok = false;
- } else if ((cbits & 0x1c) == 0x04) {
- lch_idx = cbits & 0x3; /* SDCCH/4 */
- if (ts->pchan != GSM_PCHAN_CCCH_SDCCH4 &&
- ts->pchan != GSM_PCHAN_CCCH_SDCCH4_CBCH)
- ok = false;
- } else if ((cbits & 0x18) == 0x08) {
- lch_idx = cbits & 0x7; /* SDCCH/8 */
- if (ts->pchan != GSM_PCHAN_SDCCH8_SACCH8C &&
- ts->pchan != GSM_PCHAN_SDCCH8_SACCH8C_CBCH)
- ok = false;
- } else if (cbits == 0x10 || cbits == 0x11 || cbits == 0x12) {
- lch_idx = 0;
- if (ts->pchan != GSM_PCHAN_CCCH &&
- ts->pchan != GSM_PCHAN_CCCH_SDCCH4 &&
- ts->pchan != GSM_PCHAN_CCCH_SDCCH4_CBCH)
- ok = false;
- /* FIXME: we should not return first sdcch4 !!! */
- } else if ((chan_nr & RSL_CHAN_NR_MASK) == RSL_CHAN_OSMO_PDCH) {
- lch_idx = 0;
- if (ts->pchan != GSM_PCHAN_TCH_F_TCH_H_PDCH)
- ok = false;
- } else
- return NULL;
-
- if (rc && ok)
- *rc = 0;
-
- return &ts->lchan[lch_idx];
-}
-
-static const uint8_t subslots_per_pchan[] = {
- [GSM_PCHAN_NONE] = 0,
- [GSM_PCHAN_CCCH] = 0,
- [GSM_PCHAN_PDCH] = 0,
- [GSM_PCHAN_CCCH_SDCCH4] = 4,
- [GSM_PCHAN_TCH_F] = 1,
- [GSM_PCHAN_TCH_H] = 2,
- [GSM_PCHAN_SDCCH8_SACCH8C] = 8,
- [GSM_PCHAN_CCCH_SDCCH4_CBCH] = 4,
- [GSM_PCHAN_SDCCH8_SACCH8C_CBCH] = 8,
- /*
- * GSM_PCHAN_TCH_F_PDCH and GSM_PCHAN_TCH_F_TCH_H_PDCH should not be
- * part of this, those TS are handled according to their dynamic state.
- */
-};
-
-/*! Return the actual pchan type, also heeding dynamic TS. */
-enum gsm_phys_chan_config ts_pchan(struct gsm_bts_trx_ts *ts)
-{
- switch (ts->pchan) {
- case GSM_PCHAN_TCH_F_TCH_H_PDCH:
- return ts->dyn.pchan_is;
- case GSM_PCHAN_TCH_F_PDCH:
- if (ts->flags & TS_F_PDCH_ACTIVE)
- return GSM_PCHAN_PDCH;
- else
- return GSM_PCHAN_TCH_F;
- default:
- return ts->pchan;
- }
-}
-
-/*! According to ts->pchan and possibly ts->dyn_pchan, return the number of
- * logical channels available in the timeslot. */
-uint8_t ts_subslots(struct gsm_bts_trx_ts *ts)
-{
- return subslots_per_pchan[ts_pchan(ts)];
-}
-
-static bool pchan_is_tch(enum gsm_phys_chan_config pchan)
-{
- switch (pchan) {
- case GSM_PCHAN_TCH_F:
- case GSM_PCHAN_TCH_H:
- return true;
- default:
- return false;
- }
-}
-
-bool ts_is_tch(struct gsm_bts_trx_ts *ts)
-{
- return pchan_is_tch(ts_pchan(ts));
-}
diff --git a/src/libcommon/gsm_subscriber_base.c b/src/libcommon/gsm_subscriber_base.c
deleted file mode 100644
index 018ed210c..000000000
--- a/src/libcommon/gsm_subscriber_base.c
+++ /dev/null
@@ -1,64 +0,0 @@
-/* The concept of a subscriber as seen by the BSC */
-
-/* (C) 2008 by Harald Welte <laforge@gnumonks.org>
- * (C) 2009-2010 by Holger Hans Peter Freyther <zecke@selfish.org>
- * (C) 2010 by On-Waves
- *
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * 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 Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <assert.h>
-
-#include <osmocom/core/talloc.h>
-#include <osmocom/core/utils.h>
-#include <openbsc/gsm_subscriber.h>
-#include <openbsc/debug.h>
-#include <openbsc/vlr.h>
-
-LLIST_HEAD(active_subscribers);
-void *tall_subscr_ctx;
-
-/* return static buffer with printable name of VLR subscriber */
-const char *vlr_subscr_name(struct vlr_subscr *vsub)
-{
- static char buf[32];
- if (!vsub)
- return "unknown";
- if (vsub->msisdn[0])
- snprintf(buf, sizeof(buf), "MSISDN:%s", vsub->msisdn);
- else if (vsub->imsi[0])
- snprintf(buf, sizeof(buf), "IMSI:%s", vsub->imsi);
- else if (vsub->tmsi != GSM_RESERVED_TMSI)
- snprintf(buf, sizeof(buf), "TMSI:0x%08x", vsub->tmsi);
- else if (vsub->tmsi_new != GSM_RESERVED_TMSI)
- snprintf(buf, sizeof(buf), "TMSI(new):0x%08x", vsub->tmsi_new);
- else
- return "unknown";
- buf[sizeof(buf)-1] = '\0';
- return buf;
-}
-
-const char *vlr_subscr_msisdn_or_name(struct vlr_subscr *vsub)
-{
- if (!vsub || !vsub->msisdn[0])
- return vlr_subscr_name(vsub);
- return vsub->msisdn;
-}
diff --git a/src/libcommon/gsup_client.c b/src/libcommon/gsup_client.c
deleted file mode 100644
index fd65e7b0b..000000000
--- a/src/libcommon/gsup_client.c
+++ /dev/null
@@ -1,347 +0,0 @@
-/* Generic Subscriber Update Protocol client */
-
-/* (C) 2014-2016 by Sysmocom s.f.m.c. GmbH
- * All Rights Reserved
- *
- * Author: Jacob Erlbeck
- * Author: Neels Hofmeyr
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * 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 Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#include <openbsc/gsup_client.h>
-
-#include <osmocom/abis/ipa.h>
-#include <osmocom/gsm/protocol/ipaccess.h>
-#include <osmocom/core/msgb.h>
-#include <osmocom/core/logging.h>
-
-#include <openbsc/debug.h>
-
-#include <errno.h>
-#include <string.h>
-
-extern void *tall_bsc_ctx;
-
-static void start_test_procedure(struct gsup_client *gsupc);
-
-static void gsup_client_send_ping(struct gsup_client *gsupc)
-{
- struct msgb *msg = gsup_client_msgb_alloc();
-
- msg->l2h = msgb_put(msg, 1);
- msg->l2h[0] = IPAC_MSGT_PING;
- ipa_msg_push_header(msg, IPAC_PROTO_IPACCESS);
- ipa_client_conn_send(gsupc->link, msg);
-}
-
-static int gsup_client_connect(struct gsup_client *gsupc)
-{
- int rc;
-
- if (gsupc->is_connected)
- return 0;
-
- if (osmo_timer_pending(&gsupc->connect_timer)) {
- LOGP(DLGSUP, LOGL_DEBUG,
- "GSUP connect: connect timer already running\n");
- osmo_timer_del(&gsupc->connect_timer);
- }
-
- if (osmo_timer_pending(&gsupc->ping_timer)) {
- LOGP(DLGSUP, LOGL_DEBUG,
- "GSUP connect: ping timer already running\n");
- osmo_timer_del(&gsupc->ping_timer);
- }
-
- if (ipa_client_conn_clear_queue(gsupc->link) > 0)
- LOGP(DLGSUP, LOGL_DEBUG, "GSUP connect: discarded stored messages\n");
-
- rc = ipa_client_conn_open(gsupc->link);
-
- if (rc >= 0) {
- LOGP(DLGSUP, LOGL_NOTICE, "GSUP connecting to %s:%d\n",
- gsupc->link->addr, gsupc->link->port);
- return 0;
- }
-
- LOGP(DLGSUP, LOGL_ERROR, "GSUP failed to connect to %s:%d: %s\n",
- gsupc->link->addr, gsupc->link->port, strerror(-rc));
-
- if (rc == -EBADF || rc == -ENOTSOCK || rc == -EAFNOSUPPORT ||
- rc == -EINVAL)
- return rc;
-
- osmo_timer_schedule(&gsupc->connect_timer,
- GSUP_CLIENT_RECONNECT_INTERVAL, 0);
-
- LOGP(DLGSUP, LOGL_INFO, "Scheduled timer to retry GSUP connect to %s:%d\n",
- gsupc->link->addr, gsupc->link->port);
-
- return 0;
-}
-
-static void connect_timer_cb(void *gsupc_)
-{
- struct gsup_client *gsupc = gsupc_;
-
- if (gsupc->is_connected)
- return;
-
- gsup_client_connect(gsupc);
-}
-
-static void client_send(struct gsup_client *gsupc, int proto_ext,
- struct msgb *msg_tx)
-{
- ipa_prepend_header_ext(msg_tx, proto_ext);
- ipa_msg_push_header(msg_tx, IPAC_PROTO_OSMO);
- ipa_client_conn_send(gsupc->link, msg_tx);
- /* msg_tx is now queued and will be freed. */
-}
-
-static void gsup_client_oap_register(struct gsup_client *gsupc)
-{
- struct msgb *msg_tx;
- int rc;
- rc = oap_client_register(&gsupc->oap_state, &msg_tx);
-
- if ((rc < 0) || (!msg_tx)) {
- LOGP(DLGSUP, LOGL_ERROR, "GSUP OAP set up, but cannot register.\n");
- return;
- }
-
- client_send(gsupc, IPAC_PROTO_EXT_OAP, msg_tx);
-}
-
-static void gsup_client_updown_cb(struct ipa_client_conn *link, int up)
-{
- struct gsup_client *gsupc = link->data;
-
- LOGP(DLGSUP, LOGL_INFO, "GSUP link to %s:%d %s\n",
- link->addr, link->port, up ? "UP" : "DOWN");
-
- gsupc->is_connected = up;
-
- if (up) {
- start_test_procedure(gsupc);
-
- if (gsupc->oap_state.state == OAP_INITIALIZED)
- gsup_client_oap_register(gsupc);
-
- osmo_timer_del(&gsupc->connect_timer);
- } else {
- osmo_timer_del(&gsupc->ping_timer);
-
- osmo_timer_schedule(&gsupc->connect_timer,
- GSUP_CLIENT_RECONNECT_INTERVAL, 0);
- }
-}
-
-static int gsup_client_oap_handle(struct gsup_client *gsupc, struct msgb *msg_rx)
-{
- int rc;
- struct msgb *msg_tx;
-
- /* If the oap_state is disabled, this will reject the messages. */
- rc = oap_client_handle(&gsupc->oap_state, msg_rx, &msg_tx);
- msgb_free(msg_rx);
- if (rc < 0)
- return rc;
-
- if (msg_tx)
- client_send(gsupc, IPAC_PROTO_EXT_OAP, msg_tx);
-
- return 0;
-}
-
-static int gsup_client_read_cb(struct ipa_client_conn *link, struct msgb *msg)
-{
- struct ipaccess_head *hh = (struct ipaccess_head *) msg->data;
- struct ipaccess_head_ext *he = (struct ipaccess_head_ext *) msgb_l2(msg);
- struct gsup_client *gsupc = (struct gsup_client *)link->data;
- int rc;
- struct ipaccess_unit ipa_dev = {
- /* see gsup_client_create() on const vs non-const */
- .unit_name = (char*)gsupc->unit_name,
- };
-
- OSMO_ASSERT(ipa_dev.unit_name);
-
- msg->l2h = &hh->data[0];
-
- rc = ipaccess_bts_handle_ccm(link, &ipa_dev, msg);
-
- if (rc < 0) {
- LOGP(DLGSUP, LOGL_NOTICE,
- "GSUP received an invalid IPA/CCM message from %s:%d\n",
- link->addr, link->port);
- /* Link has been closed */
- gsupc->is_connected = 0;
- msgb_free(msg);
- return -1;
- }
-
- if (rc == 1) {
- uint8_t msg_type = *(msg->l2h);
- /* CCM message */
- if (msg_type == IPAC_MSGT_PONG) {
- LOGP(DLGSUP, LOGL_DEBUG, "GSUP receiving PONG\n");
- gsupc->got_ipa_pong = 1;
- }
-
- msgb_free(msg);
- return 0;
- }
-
- if (hh->proto != IPAC_PROTO_OSMO)
- goto invalid;
-
- if (!he || msgb_l2len(msg) < sizeof(*he))
- goto invalid;
-
- msg->l2h = &he->data[0];
-
- if (he->proto == IPAC_PROTO_EXT_GSUP) {
- OSMO_ASSERT(gsupc->read_cb != NULL);
- gsupc->read_cb(gsupc, msg);
- /* expecting read_cb() to free msg */
- } else if (he->proto == IPAC_PROTO_EXT_OAP) {
- return gsup_client_oap_handle(gsupc, msg);
- /* gsup_client_oap_handle frees msg */
- } else
- goto invalid;
-
- return 0;
-
-invalid:
- LOGP(DLGSUP, LOGL_NOTICE,
- "GSUP received an invalid IPA message from %s:%d, size = %d\n",
- link->addr, link->port, msgb_length(msg));
-
- msgb_free(msg);
- return -1;
-}
-
-static void ping_timer_cb(void *gsupc_)
-{
- struct gsup_client *gsupc = gsupc_;
-
- LOGP(DLGSUP, LOGL_INFO, "GSUP ping callback (%s, %s PONG)\n",
- gsupc->is_connected ? "connected" : "not connected",
- gsupc->got_ipa_pong ? "got" : "didn't get");
-
- if (gsupc->got_ipa_pong) {
- start_test_procedure(gsupc);
- return;
- }
-
- LOGP(DLGSUP, LOGL_NOTICE, "GSUP ping timed out, reconnecting\n");
- ipa_client_conn_close(gsupc->link);
- gsupc->is_connected = 0;
-
- gsup_client_connect(gsupc);
-}
-
-static void start_test_procedure(struct gsup_client *gsupc)
-{
- osmo_timer_setup(&gsupc->ping_timer, ping_timer_cb, gsupc);
-
- gsupc->got_ipa_pong = 0;
- osmo_timer_schedule(&gsupc->ping_timer, GSUP_CLIENT_PING_INTERVAL, 0);
- LOGP(DLGSUP, LOGL_DEBUG, "GSUP sending PING\n");
- gsup_client_send_ping(gsupc);
-}
-
-struct gsup_client *gsup_client_create(const char *unit_name,
- const char *ip_addr,
- unsigned int tcp_port,
- gsup_client_read_cb_t read_cb,
- struct oap_client_config *oapc_config)
-{
- struct gsup_client *gsupc;
- int rc;
-
- gsupc = talloc_zero(tall_bsc_ctx, struct gsup_client);
- OSMO_ASSERT(gsupc);
-
- /* struct ipaccess_unit has a non-const unit_name, so let's copy to be
- * able to have a non-const unit_name here as well. To not taint the
- * public gsup_client API, let's store it in a const char* anyway. */
- gsupc->unit_name = talloc_strdup(gsupc, unit_name);
- OSMO_ASSERT(gsupc->unit_name);
-
- /* a NULL oapc_config will mark oap_state disabled. */
- rc = oap_client_init(oapc_config, &gsupc->oap_state);
- if (rc != 0)
- goto failed;
-
- gsupc->link = ipa_client_conn_create(gsupc,
- /* no e1inp */ NULL,
- 0,
- ip_addr, tcp_port,
- gsup_client_updown_cb,
- gsup_client_read_cb,
- /* default write_cb */ NULL,
- gsupc);
- if (!gsupc->link)
- goto failed;
-
- osmo_timer_setup(&gsupc->connect_timer, connect_timer_cb, gsupc);
-
- rc = gsup_client_connect(gsupc);
-
- if (rc < 0)
- goto failed;
-
- gsupc->read_cb = read_cb;
-
- return gsupc;
-
-failed:
- gsup_client_destroy(gsupc);
- return NULL;
-}
-
-void gsup_client_destroy(struct gsup_client *gsupc)
-{
- osmo_timer_del(&gsupc->connect_timer);
- osmo_timer_del(&gsupc->ping_timer);
-
- if (gsupc->link) {
- ipa_client_conn_close(gsupc->link);
- ipa_client_conn_destroy(gsupc->link);
- gsupc->link = NULL;
- }
- talloc_free(gsupc);
-}
-
-int gsup_client_send(struct gsup_client *gsupc, struct msgb *msg)
-{
- if (!gsupc || !gsupc->is_connected) {
- LOGP(DGPRS, LOGL_ERROR, "GSUP not connected, unable to send %s\n", msgb_hexdump(msg));
- msgb_free(msg);
- return -ENOTCONN;
- }
-
- client_send(gsupc, IPAC_PROTO_EXT_GSUP, msg);
-
- return 0;
-}
-
-struct msgb *gsup_client_msgb_alloc(void)
-{
- return msgb_alloc_headroom(4000, 64, __func__);
-}
diff --git a/src/libcommon/gsup_test_client.c b/src/libcommon/gsup_test_client.c
deleted file mode 100644
index b6a8d6b7d..000000000
--- a/src/libcommon/gsup_test_client.c
+++ /dev/null
@@ -1,298 +0,0 @@
-#include <string.h>
-#include <stdio.h>
-#include <errno.h>
-#include <signal.h>
-
-#include <osmocom/core/linuxlist.h>
-#include <osmocom/core/msgb.h>
-#include <osmocom/core/select.h>
-#include <osmocom/core/application.h>
-#include <osmocom/core/utils.h>
-#include <osmocom/gsm/gsup.h>
-
-#include <openbsc/gsup_client.h>
-#include <openbsc/debug.h>
-
-static struct gsup_client *g_gc;
-
-
-/***********************************************************************
- * IMSI Operation
- ***********************************************************************/
-static LLIST_HEAD(g_imsi_ops);
-
-struct imsi_op_stats {
- uint32_t num_alloc;
- uint32_t num_released;
- uint32_t num_rx_success;
- uint32_t num_rx_error;
- uint32_t num_timeout;
-};
-
-enum imsi_op_type {
- IMSI_OP_SAI,
- IMSI_OP_LU,
- IMSI_OP_ISD,
- _NUM_IMSI_OP
-};
-
-static const struct value_string imsi_op_names[] = {
- { IMSI_OP_SAI, "SAI" },
- { IMSI_OP_LU, "LU" },
- { IMSI_OP_ISD, "ISD" },
- { 0, NULL }
-};
-
-static struct imsi_op_stats imsi_op_stats[_NUM_IMSI_OP];
-
-struct imsi_op {
- struct llist_head list;
- char imsi[17];
- enum imsi_op_type type;
- struct osmo_timer_list timer;
-};
-
-static struct imsi_op *imsi_op_find(const char *imsi,
- enum imsi_op_type type)
-{
- struct imsi_op *io;
-
- llist_for_each_entry(io, &g_imsi_ops, list) {
- if (!strcmp(io->imsi, imsi) && io->type == type)
- return io;
- }
- return NULL;
-}
-
-static void imsi_op_timer_cb(void *data);
-
-static struct imsi_op *imsi_op_alloc(void *ctx, const char *imsi,
- enum imsi_op_type type)
-{
- struct imsi_op *io;
-
- if (imsi_op_find(imsi, type))
- return NULL;
-
- io = talloc_zero(ctx, struct imsi_op);
- osmo_strlcpy(io->imsi, imsi, sizeof(io->imsi));
- io->type = type;
- osmo_timer_setup(&io->timer, imsi_op_timer_cb, io);
- llist_add(&io->list, &g_imsi_ops);
- imsi_op_stats[type].num_alloc++;
-
- return io;
-}
-
-static void imsi_op_release(struct imsi_op *io)
-{
- osmo_timer_del(&io->timer);
- llist_del(&io->list);
- imsi_op_stats[io->type].num_released++;
- talloc_free(io);
-}
-
-static void imsi_op_timer_cb(void *data)
-{
- struct imsi_op *io = data;
- printf("%s: Timer expiration\n", io->imsi);
- imsi_op_stats[io->type].num_timeout++;
- imsi_op_release(io);
-}
-
-/* allocate + generate + send Send-Auth-Info */
-int req_auth_info(const char *imsi)
-{
- struct imsi_op *io = imsi_op_alloc(g_gc, imsi, IMSI_OP_SAI);
- struct osmo_gsup_message gsup = {0};
- struct msgb *msg = msgb_alloc_headroom(1200, 200, __func__);
-
- osmo_strlcpy(gsup.imsi, io->imsi, sizeof(gsup.imsi));
- gsup.message_type = OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST;
-
- osmo_gsup_encode(msg, &gsup);
-
- return gsup_client_send(g_gc, msg);
-}
-
-/* allocate + generate + send Send-Auth-Info */
-int req_loc_upd(const char *imsi)
-{
- struct imsi_op *io = imsi_op_alloc(g_gc, imsi, IMSI_OP_LU);
- struct osmo_gsup_message gsup = {0};
- struct msgb *msg = msgb_alloc_headroom(1200, 200, __func__);
-
- osmo_strlcpy(gsup.imsi, io->imsi, sizeof(gsup.imsi));
- gsup.message_type = OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST;
-
- osmo_gsup_encode(msg, &gsup);
-
- return gsup_client_send(g_gc, msg);
-}
-
-int resp_isd(struct imsi_op *io)
-{
- struct osmo_gsup_message gsup = {0};
- struct msgb *msg = msgb_alloc_headroom(1200, 200, __func__);
-
- osmo_strlcpy(gsup.imsi, io->imsi, sizeof(gsup.imsi));
- gsup.message_type = OSMO_GSUP_MSGT_INSERT_DATA_RESULT;
-
- osmo_gsup_encode(msg, &gsup);
-
- imsi_op_release(io);
-
- return gsup_client_send(g_gc, msg);
-}
-
-/* receive an incoming GSUP message */
-static void imsi_op_rx_gsup(struct imsi_op *io, const struct osmo_gsup_message *gsup)
-{
- int is_error = 0;
-
- if (OSMO_GSUP_IS_MSGT_ERROR(gsup->message_type)) {
- imsi_op_stats[io->type].num_rx_error++;
- is_error = 1;
- } else
- imsi_op_stats[io->type].num_rx_success++;
-
- switch (io->type) {
- case IMSI_OP_SAI:
- printf("%s; SAI Response%s\n", io->imsi, is_error ? ": ERROR" : "");
- /* now that we have auth tuples, request LU */
- req_loc_upd(io->imsi);
- imsi_op_release(io);
- break;
- case IMSI_OP_LU:
- printf("%s; LU Response%s\n", io->imsi, is_error ? ": ERROR" : "");
- imsi_op_release(io);
- break;
- case IMSI_OP_ISD:
- printf("%s; ISD Request%s\n", io->imsi, is_error ? ": ERROR" : "");
- resp_isd(io);
- break;
- default:
- printf("%s: Unknown\n", io->imsi);
- imsi_op_release(io);
- break;
- }
-}
-
-static int op_type_by_gsup_msgt(enum osmo_gsup_message_type msg_type)
-{
- switch (msg_type) {
- case OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT:
- case OSMO_GSUP_MSGT_SEND_AUTH_INFO_ERROR:
- return IMSI_OP_SAI;
- case OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT:
- case OSMO_GSUP_MSGT_UPDATE_LOCATION_ERROR:
- return IMSI_OP_LU;
- case OSMO_GSUP_MSGT_INSERT_DATA_REQUEST:
- return IMSI_OP_ISD;
- default:
- printf("Unknown GSUP msg_type %u\n", msg_type);
- return -1;
- }
-}
-
-static int gsupc_read_cb(struct gsup_client *gsupc, struct msgb *msg)
-{
- struct osmo_gsup_message gsup_msg = {0};
- struct imsi_op *io;
- int rc;
-
- DEBUGP(DGPRS, "Rx GSUP %s\n", osmo_hexdump(msgb_l2(msg), msgb_l2len(msg)));
-
- rc = osmo_gsup_decode(msgb_l2(msg), msgb_l2len(msg), &gsup_msg);
- if (rc < 0)
- return rc;
-
- if (!gsup_msg.imsi[0])
- return -1;
-
- rc = op_type_by_gsup_msgt(gsup_msg.message_type);
- if (rc < 0)
- return rc;
-
- switch (rc) {
- case IMSI_OP_SAI:
- case IMSI_OP_LU:
- io = imsi_op_find(gsup_msg.imsi, rc);
- if (!io)
- return -1;
- break;
- case IMSI_OP_ISD:
- /* ISD is an inbound transaction */
- io = imsi_op_alloc(g_gc, gsup_msg.imsi, IMSI_OP_ISD);
- break;
- }
-
- imsi_op_rx_gsup(io, &gsup_msg);
- msgb_free(msg);
-
- return 0;
-}
-
-static void print_report(void)
-{
- unsigned int i;
-
- for (i = 0; i < ARRAY_SIZE(imsi_op_stats); i++) {
- struct imsi_op_stats *st = &imsi_op_stats[i];
- const char *name = get_value_string(imsi_op_names, i);
- printf("%s: %u alloc, %u released, %u success, %u error , %u tout\n",
- name, st->num_alloc, st->num_released, st->num_rx_success,
- st->num_rx_error, st->num_timeout);
- }
-}
-
-static void sig_cb(int sig)
-{
- switch (sig) {
- case SIGINT:
- print_report();
- exit(0);
- break;
- }
-}
-
-void *tall_bsc_ctx = NULL;
-
-/* default categories */
-static struct log_info_cat default_categories[] = {
-};
-
-static const struct log_info gsup_test_client_log_info = {
- .cat = default_categories,
- .num_cat = ARRAY_SIZE(default_categories),
-};
-
-int main(int argc, char **argv)
-{
- unsigned long long i;
- char *server_host = "127.0.0.1";
- uint16_t server_port = OSMO_GSUP_PORT;
-
- osmo_init_logging(&gsup_test_client_log_info);
-
- g_gc = gsup_client_create("GSUPTEST", server_host, server_port,
- gsupc_read_cb, NULL);
-
-
- signal(SIGINT, sig_cb);
-
- for (i = 0; i < 10000; i++) {
- unsigned long long imsi = 901790000000000 + i;
- char imsi_buf[17];
- snprintf(imsi_buf, sizeof(imsi_buf), "%015llu", imsi);
- req_auth_info(imsi_buf);
- osmo_select_main(0);
- }
-
- while (1) {
- osmo_select_main(0);
- }
-
- print_report();
- exit(0);
-}
diff --git a/src/libcommon/oap_client.c b/src/libcommon/oap_client.c
deleted file mode 100644
index 5128ac119..000000000
--- a/src/libcommon/oap_client.c
+++ /dev/null
@@ -1,280 +0,0 @@
-/* Osmocom Authentication Protocol API */
-
-/* (C) 2015 by Sysmocom s.f.m.c. GmbH
- * All Rights Reserved
- *
- * Author: Neels Hofmeyr
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * 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 Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#include <string.h>
-#include <errno.h>
-
-#include <osmocom/core/utils.h>
-#include <osmocom/crypt/auth.h>
-#include <osmocom/gsm/oap.h>
-
-#include <openbsc/oap_client.h>
-#include <openbsc/debug.h>
-
-int oap_client_init(struct oap_client_config *config,
- struct oap_client_state *state)
-{
- OSMO_ASSERT(state->state == OAP_UNINITIALIZED);
-
- if (!config)
- goto disable;
-
- if (config->client_id == 0)
- goto disable;
-
- if (config->secret_k_present == 0) {
- LOGP(DLOAP, LOGL_NOTICE, "OAP: client ID set, but secret K missing.\n");
- goto disable;
- }
-
- if (config->secret_opc_present == 0) {
- LOGP(DLOAP, LOGL_NOTICE, "OAP: client ID set, but secret OPC missing.\n");
- goto disable;
- }
-
- state->client_id = config->client_id;
- memcpy(state->secret_k, config->secret_k, sizeof(state->secret_k));
- memcpy(state->secret_opc, config->secret_opc, sizeof(state->secret_opc));
- state->state = OAP_INITIALIZED;
- return 0;
-
-disable:
- state->state = OAP_DISABLED;
- return 0;
-}
-
-/* From the given state and received RAND and AUTN octets, validate the
- * server's authenticity and formulate the matching milenage reply octets in
- * *tx_xres. The state is not modified.
- * On success, and if tx_res is not NULL, exactly 8 octets will be written to
- * *tx_res. If not NULL, tx_res must point at allocated memory of at least 8
- * octets. The caller will want to send XRES back to the server in a challenge
- * response message and update the state.
- * Return 0 on success; -1 if OAP is disabled; -2 if rx_random and rx_autn fail
- * the authentication check; -3 for any other errors. */
-static int oap_evaluate_challenge(const struct oap_client_state *state,
- const uint8_t *rx_random,
- const uint8_t *rx_autn,
- uint8_t *tx_xres)
-{
- struct osmo_auth_vector vec;
-
- struct osmo_sub_auth_data auth = {
- .type = OSMO_AUTH_TYPE_UMTS,
- .algo = OSMO_AUTH_ALG_MILENAGE,
- };
-
- osmo_static_assert(sizeof(((struct osmo_sub_auth_data*)0)->u.umts.k)
- == sizeof(state->secret_k), _secret_k_size_match);
- osmo_static_assert(sizeof(((struct osmo_sub_auth_data*)0)->u.umts.opc)
- == sizeof(state->secret_opc), _secret_opc_size_match);
-
- switch (state->state) {
- case OAP_UNINITIALIZED:
- case OAP_DISABLED:
- return -1;
- default:
- break;
- }
-
- memcpy(auth.u.umts.k, state->secret_k, sizeof(auth.u.umts.k));
- memcpy(auth.u.umts.opc, state->secret_opc, sizeof(auth.u.umts.opc));
- memset(auth.u.umts.amf, '\0', sizeof(auth.u.umts.amf));
- auth.u.umts.sqn = 41; /* TODO use incrementing sequence nr */
-
- memset(&vec, 0, sizeof(vec));
- osmo_auth_gen_vec(&vec, &auth, rx_random);
-
- if (vec.res_len != 8) {
- LOGP(DLOAP, LOGL_ERROR, "OAP: Expected XRES to be 8 octets, got %d\n",
- vec.res_len);
- return -3;
- }
-
- if (osmo_constant_time_cmp(vec.autn, rx_autn, sizeof(vec.autn)) != 0) {
- LOGP(DLOAP, LOGL_ERROR, "OAP: AUTN mismatch!\n");
- LOGP(DLOAP, LOGL_INFO, "OAP: AUTN from server: %s\n",
- osmo_hexdump_nospc(rx_autn, sizeof(vec.autn)));
- LOGP(DLOAP, LOGL_INFO, "OAP: AUTN expected: %s\n",
- osmo_hexdump_nospc(vec.autn, sizeof(vec.autn)));
- return -2;
- }
-
- if (tx_xres != NULL)
- memcpy(tx_xres, vec.res, 8);
- return 0;
-}
-
-struct msgb *oap_client_encoded(const struct osmo_oap_message *oap_msg)
-{
- struct msgb *msg = msgb_alloc_headroom(1000, 64, __func__);
- OSMO_ASSERT(msg);
- osmo_oap_encode(msg, oap_msg);
- return msg;
-}
-
-/* Create a new msgb containing an OAP registration message.
- * On error, return NULL. */
-static struct msgb* oap_msg_register(uint16_t client_id)
-{
- struct osmo_oap_message oap_msg = {0};
-
- if (client_id < 1) {
- LOGP(DLOAP, LOGL_ERROR, "OAP: Invalid client ID: %d\n", client_id);
- return NULL;
- }
-
- oap_msg.message_type = OAP_MSGT_REGISTER_REQUEST;
- oap_msg.client_id = client_id;
- return oap_client_encoded(&oap_msg);
-}
-
-int oap_client_register(struct oap_client_state *state, struct msgb **msg_tx)
-{
- *msg_tx = oap_msg_register(state->client_id);
- if (!(*msg_tx))
- return -1;
-
- state->state = OAP_REQUESTED_CHALLENGE;
- return 0;
-}
-
-/* Create a new msgb containing an OAP challenge response message.
- * xres must point at 8 octets to return as challenge response.
- * On error, return NULL. */
-static struct msgb* oap_msg_challenge_response(uint8_t *xres)
-{
- struct osmo_oap_message oap_reply = {0};
-
- oap_reply.message_type = OAP_MSGT_CHALLENGE_RESULT;
- memcpy(oap_reply.xres, xres, sizeof(oap_reply.xres));
- oap_reply.xres_present = 1;
- return oap_client_encoded(&oap_reply);
-}
-
-static int handle_challenge(struct oap_client_state *state,
- struct osmo_oap_message *oap_rx,
- struct msgb **msg_tx)
-{
- int rc;
- uint8_t xres[8];
-
- if (!(oap_rx->rand_present && oap_rx->autn_present)) {
- LOGP(DLOAP, LOGL_ERROR,
- "OAP challenge incomplete (rand_present: %d, autn_present: %d)\n",
- oap_rx->rand_present, oap_rx->autn_present);
- rc = -2;
- goto failure;
- }
-
- rc = oap_evaluate_challenge(state,
- oap_rx->rand,
- oap_rx->autn,
- xres);
- if (rc < 0)
- goto failure;
-
- *msg_tx = oap_msg_challenge_response(xres);
- if ((*msg_tx) == NULL) {
- rc = -1;
- goto failure;
- }
-
- state->state = OAP_SENT_CHALLENGE_RESULT;
- return 0;
-
-failure:
- OSMO_ASSERT(rc < 0);
- state->state = OAP_INITIALIZED;
- return rc;
-}
-
-int oap_client_handle(struct oap_client_state *state,
- const struct msgb *msg_rx, struct msgb **msg_tx)
-{
- uint8_t *data = msgb_l2(msg_rx);
- size_t data_len = msgb_l2len(msg_rx);
- struct osmo_oap_message oap_msg = {0};
- int rc = 0;
-
- *msg_tx = NULL;
-
- OSMO_ASSERT(data);
-
- rc = osmo_oap_decode(&oap_msg, data, data_len);
- if (rc < 0) {
- LOGP(DLOAP, LOGL_ERROR,
- "Decoding OAP message failed with error '%s' (%d)\n",
- get_value_string(gsm48_gmm_cause_names, -rc), -rc);
- return -10;
- }
-
- switch (state->state) {
- case OAP_UNINITIALIZED:
- LOGP(DLOAP, LOGL_ERROR,
- "Received OAP message %d, but the OAP client is"
- " not initialized\n", oap_msg.message_type);
- return -ENOTCONN;
- case OAP_DISABLED:
- LOGP(DLOAP, LOGL_ERROR,
- "Received OAP message %d, but the OAP client is"
- " disabled\n", oap_msg.message_type);
- return -ENOTCONN;
- default:
- break;
- }
-
- switch (oap_msg.message_type) {
- case OAP_MSGT_CHALLENGE_REQUEST:
- return handle_challenge(state, &oap_msg, msg_tx);
-
- case OAP_MSGT_REGISTER_RESULT:
- /* successfully registered */
- state->state = OAP_REGISTERED;
- break;
-
- case OAP_MSGT_REGISTER_ERROR:
- LOGP(DLOAP, LOGL_ERROR,
- "OAP registration failed\n");
- state->state = OAP_INITIALIZED;
- if (state->registration_failures < 3) {
- state->registration_failures ++;
- return oap_client_register(state, msg_tx);
- }
- return -11;
-
- case OAP_MSGT_REGISTER_REQUEST:
- case OAP_MSGT_CHALLENGE_RESULT:
- LOGP(DLOAP, LOGL_ERROR,
- "Received invalid OAP message type for OAP client side: %d\n",
- (int)oap_msg.message_type);
- return -12;
-
- default:
- LOGP(DLOAP, LOGL_ERROR,
- "Unknown OAP message type: %d\n",
- (int)oap_msg.message_type);
- return -13;
- }
-
- return 0;
-}
diff --git a/src/libcommon/socket.c b/src/libcommon/socket.c
deleted file mode 100644
index 2a64767f8..000000000
--- a/src/libcommon/socket.c
+++ /dev/null
@@ -1,111 +0,0 @@
-/* OpenBSC sokcet code, taken from Abis input driver for ip.access */
-
-/* (C) 2009 by Harald Welte <laforge@gnumonks.org>
- * (C) 2010 by Holger Hans Peter Freyther
- * (C) 2010 by On-Waves
- *
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * 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 Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#include <stdio.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <string.h>
-#include <time.h>
-#include <sys/fcntl.h>
-#include <sys/socket.h>
-#include <sys/ioctl.h>
-#include <arpa/inet.h>
-
-#include <osmocom/core/select.h>
-#include <osmocom/gsm/tlv.h>
-#include <osmocom/core/msgb.h>
-#include <openbsc/debug.h>
-#include <openbsc/gsm_data.h>
-#include <osmocom/core/talloc.h>
-
-int make_sock(struct osmo_fd *bfd, int proto,
- uint32_t ip, uint16_t port, int priv_nr,
- int (*cb)(struct osmo_fd *fd, unsigned int what), void *data)
-{
- struct sockaddr_in addr;
- int ret, on = 1;
- int type = SOCK_STREAM;
-
- switch (proto) {
- case IPPROTO_TCP:
- type = SOCK_STREAM;
- break;
- case IPPROTO_UDP:
- type = SOCK_DGRAM;
- break;
-#ifdef IPPROTO_GRE
- case IPPROTO_GRE:
- type = SOCK_RAW;
- break;
-#endif
- default:
- return -EINVAL;
- }
-
- bfd->fd = socket(AF_INET, type, proto);
- bfd->cb = cb;
- bfd->when = BSC_FD_READ;
- bfd->data = data;
- bfd->priv_nr = priv_nr;
-
- if (bfd->fd < 0) {
- LOGP(DLINP, LOGL_ERROR, "could not create socket.\n");
- return -EIO;
- }
-
- memset(&addr, 0, sizeof(addr));
- addr.sin_family = AF_INET;
- addr.sin_port = htons(port);
- if (ip != INADDR_ANY)
- addr.sin_addr.s_addr = htonl(ip);
- else
- addr.sin_addr.s_addr = INADDR_ANY;
-
- setsockopt(bfd->fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
-
- ret = bind(bfd->fd, (struct sockaddr *) &addr, sizeof(addr));
- if (ret < 0) {
- LOGP(DLINP, LOGL_ERROR, "could not bind socket %s\n",
- strerror(errno));
- close(bfd->fd);
- return -EIO;
- }
-
- if (proto == IPPROTO_TCP) {
- ret = listen(bfd->fd, 1);
- if (ret < 0) {
- perror("listen");
- close(bfd->fd);
- return ret;
- }
- }
-
- ret = osmo_fd_register(bfd);
- if (ret < 0) {
- perror("register_listen_fd");
- close(bfd->fd);
- return ret;
- }
- return 0;
-}
diff --git a/src/libcommon/talloc_ctx.c b/src/libcommon/talloc_ctx.c
deleted file mode 100644
index c8e9cd31d..000000000
--- a/src/libcommon/talloc_ctx.c
+++ /dev/null
@@ -1,55 +0,0 @@
-/* OpenBSC allocation contexts initialization code */
-/* (C) 2011-2016 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * 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 Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#include <osmocom/core/talloc.h>
-#include <osmocom/core/msgb.h>
-
-extern void *tall_bsc_ctx;
-extern void *tall_fle_ctx;
-extern void *tall_locop_ctx;
-extern void *tall_authciphop_ctx;
-extern void *tall_gsms_ctx;
-extern void *tall_subscr_ctx;
-extern void *tall_sub_req_ctx;
-extern void *tall_call_ctx;
-extern void *tall_paging_ctx;
-extern void *tall_sigh_ctx;
-extern void *tall_tqe_ctx;
-extern void *tall_trans_ctx;
-extern void *tall_map_ctx;
-extern void *tall_upq_ctx;
-extern void *tall_ctr_ctx;
-
-void talloc_ctx_init(void *ctx_root)
-{
- msgb_talloc_ctx_init(ctx_root, 0);
- tall_fle_ctx = talloc_named_const(ctx_root, 0, "bs11_file_list_entry");
- tall_locop_ctx = talloc_named_const(ctx_root, 0, "loc_updating_oper");
- tall_authciphop_ctx = talloc_named_const(ctx_root, 0, "auth_ciph_oper");
- tall_gsms_ctx = talloc_named_const(ctx_root, 0, "sms");
- tall_subscr_ctx = talloc_named_const(ctx_root, 0, "subscriber");
- tall_call_ctx = talloc_named_const(ctx_root, 0, "gsm_call");
- tall_paging_ctx = talloc_named_const(ctx_root, 0, "paging_request");
- tall_sigh_ctx = talloc_named_const(ctx_root, 0, "signal_handler");
- tall_tqe_ctx = talloc_named_const(ctx_root, 0, "subch_txq_entry");
- tall_trans_ctx = talloc_named_const(ctx_root, 0, "transaction");
- tall_map_ctx = talloc_named_const(ctx_root, 0, "trau_map_entry");
- tall_upq_ctx = talloc_named_const(ctx_root, 0, "trau_upq_entry");
- tall_ctr_ctx = talloc_named_const(ctx_root, 0, "counter");
-}
diff --git a/src/sgsn/Makefile.am b/src/sgsn/Makefile.am
new file mode 100644
index 000000000..6a7392baf
--- /dev/null
+++ b/src/sgsn/Makefile.am
@@ -0,0 +1,93 @@
+AM_CPPFLAGS = \
+ $(all_includes) \
+ -I$(top_srcdir)/include \
+ -I$(top_builddir) \
+ $(NULL)
+
+AM_CFLAGS = \
+ -Wall \
+ -fno-strict-aliasing \
+ $(LIBOSMOCORE_CFLAGS) \
+ $(LIBOSMOGSM_CFLAGS) \
+ $(LIBOSMOVTY_CFLAGS) \
+ $(LIBOSMOCTRL_CFLAGS) \
+ $(LIBOSMOABIS_CFLAGS) \
+ $(LIBOSMOGB_CFLAGS) \
+ $(LIBOSMOGSUPCLIENT_CFLAGS) \
+ $(COVERAGE_CFLAGS) \
+ $(LIBCARES_CFLAGS) \
+ $(LIBGTP_CFLAGS) \
+ $(NULL)
+if BUILD_IU
+AM_CFLAGS += \
+ $(LIBASN1C_CFLAGS) \
+ $(LIBOSMOSIGTRAN_CFLAGS) \
+ $(LIBOSMORANAP_CFLAGS) \
+ $(NULL)
+endif
+
+OSMO_LIBS = \
+ $(LIBOSMOCORE_LIBS) \
+ $(LIBOSMOGSM_LIBS) \
+ $(LIBOSMOVTY_LIBS) \
+ $(LIBOSMOCTRL_LIBS) \
+ $(LIBOSMOGB_LIBS) \
+ $(LIBGTP_LIBS) \
+ $(NULL)
+
+bin_PROGRAMS = \
+ osmo-sgsn \
+ $(NULL)
+
+osmo_sgsn_SOURCES = \
+ gprs_gb.c \
+ gprs_gmm_attach.c \
+ gprs_gmm.c \
+ gprs_gmm_fsm.c \
+ gprs_mm_state_gb_fsm.c \
+ gprs_sgsn.c \
+ gprs_sm.c \
+ gprs_sndcp.c \
+ gprs_sndcp_comp.c \
+ gprs_sndcp_dcomp.c \
+ gprs_sndcp_pcomp.c \
+ gprs_sndcp_vty.c \
+ gprs_sndcp_xid.c \
+ sgsn_main.c \
+ sgsn_vty.c \
+ sgsn_libgtp.c \
+ gprs_llc.c \
+ gprs_llc_vty.c \
+ sgsn_ctrl.c \
+ sgsn_auth.c \
+ gprs_subscriber.c \
+ sgsn_cdr.c \
+ slhc.c \
+ gprs_llc_xid.c \
+ v42bis.c \
+ $(NULL)
+osmo_sgsn_LDADD = \
+ $(top_builddir)/src/gprs/gprs_llc_parse.o \
+ $(top_builddir)/src/gprs/crc24.o \
+ $(top_builddir)/src/gprs/gprs_utils.o \
+ $(top_builddir)/src/gprs/sgsn_ares.o \
+ $(OSMO_LIBS) \
+ $(LIBOSMOABIS_LIBS) \
+ $(LIBOSMOGSUPCLIENT_LIBS) \
+ $(LIBCARES_LIBS) \
+ $(LIBGTP_LIBS) \
+ -lrt \
+ -lm \
+ $(NULL)
+if BUILD_IU
+osmo_sgsn_LDADD += \
+ $(LIBOSMOSIGTRAN_LIBS) \
+ $(LIBOSMORANAP_LIBS) \
+ $(LIBASN1C_LIBS) \
+ $(NULL)
+
+osmo_sgsn_SOURCES += \
+ gprs_mm_state_iu_fsm.c \
+ gprs_ranap.c
+
+endif
diff --git a/src/sgsn/gprs_gb.c b/src/sgsn/gprs_gb.c
new file mode 100644
index 000000000..d470cfab9
--- /dev/null
+++ b/src/sgsn/gprs_gb.c
@@ -0,0 +1,105 @@
+/* Messages on the Gb interface (A/Gb mode) */
+
+/* (C) 2009-2015 by Harald Welte <laforge@gnumonks.org>
+ * (C) 2010 by On-Waves
+ * (C) 2019 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <osmocom/core/rate_ctr.h>
+
+#include <osmocom/gprs/gprs_msgb.h>
+#include <osmocom/gprs/gprs_bssgp.h>
+
+#include "bscconfig.h"
+
+#include <osmocom/sgsn/gprs_mm_state_gb_fsm.h>
+#include <osmocom/sgsn/gprs_sgsn.h>
+#include <osmocom/sgsn/gprs_gmm.h>
+#include <osmocom/sgsn/gprs_sm.h>
+#include <osmocom/sgsn/debug.h>
+
+/* Has to be called whenever any PDU (signaling, data, ...) has been received */
+void gprs_gb_recv_pdu(struct sgsn_mm_ctx *mmctx) {
+ if (mmctx->gb.llme)
+ osmo_fsm_inst_dispatch(mmctx->gb.mm_state_fsm, E_MM_PDU_RECEPTION, NULL);
+}
+
+/* Main entry point for incoming 04.08 GPRS messages from Gb */
+int gsm0408_gprs_rcvmsg_gb(struct msgb *msg, struct gprs_llc_llme *llme,
+ bool drop_cipherable)
+{
+ struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_gmmh(msg);
+ uint8_t pdisc = gsm48_hdr_pdisc(gh);
+ struct sgsn_mm_ctx *mmctx;
+ struct gprs_ra_id ra_id;
+ int rc = -EINVAL;
+
+ bssgp_parse_cell_id(&ra_id, msgb_bcid(msg));
+ mmctx = sgsn_mm_ctx_by_tlli(msgb_tlli(msg), &ra_id);
+ if (mmctx) {
+ msgid2mmctx(mmctx, msg);
+ rate_ctr_inc(&mmctx->ctrg->ctr[GMM_CTR_PKTS_SIG_IN]);
+ mmctx->gb.llme = llme;
+ gprs_gb_recv_pdu(mmctx);
+ }
+
+ /* MMCTX can be NULL */
+
+ switch (pdisc) {
+ case GSM48_PDISC_MM_GPRS:
+ rc = gsm0408_rcv_gmm(mmctx, msg, llme, drop_cipherable);
+ break;
+ case GSM48_PDISC_SM_GPRS:
+ rc = gsm0408_rcv_gsm(mmctx, msg, llme);
+ break;
+ default:
+ LOGMMCTXP(LOGL_NOTICE, mmctx,
+ "Unknown GSM 04.08 discriminator 0x%02x: %s\n",
+ pdisc, osmo_hexdump((uint8_t *)gh, msgb_l3len(msg)));
+ /* FIXME: return status message */
+ break;
+ }
+
+ /* MMCTX can be invalid */
+
+ return rc;
+}
+
+
+int gprs_gb_page_ps_ra(struct sgsn_mm_ctx *mmctx)
+{
+ struct bssgp_paging_info pinfo;
+ int rc;
+
+ /* FIXME: page whole routing area, not only the last known cell */
+
+ /* initiate PS PAGING procedure */
+ memset(&pinfo, 0, sizeof(pinfo));
+ pinfo.mode = BSSGP_PAGING_PS;
+ pinfo.scope = BSSGP_PAGING_BVCI;
+ pinfo.bvci = mmctx->gb.bvci;
+ pinfo.imsi = mmctx->imsi;
+ pinfo.ptmsi = &mmctx->p_tmsi;
+ pinfo.drx_params = mmctx->drx_parms;
+ pinfo.qos[0] = 0; // FIXME
+ rc = bssgp_tx_paging(mmctx->gb.nsei, 0, &pinfo);
+ rate_ctr_inc(&mmctx->ctrg->ctr[GMM_CTR_PAGING_PS]);
+
+ return rc;
+}
diff --git a/src/gprs/gprs_gmm.c b/src/sgsn/gprs_gmm.c
index 7301bf1c2..0391229eb 100644
--- a/src/gprs/gprs_gmm.c
+++ b/src/sgsn/gprs_gmm.c
@@ -29,9 +29,6 @@
#include <stdbool.h>
#include <netinet/in.h>
#include <arpa/inet.h>
-#include <netdb.h>
-
-#include <openssl/rand.h>
#include "bscconfig.h"
@@ -42,34 +39,33 @@
#include <osmocom/core/talloc.h>
#include <osmocom/core/rate_ctr.h>
#include <osmocom/core/utils.h>
+#include <osmocom/core/tdef.h>
#include <osmocom/crypt/auth.h>
-#include <osmocom/gsm/apn.h>
#include <osmocom/gsm/protocol/gsm_04_08_gprs.h>
#include <osmocom/gprs/gprs_bssgp.h>
-#ifdef BUILD_IU
-#include <osmocom/ranap/ranap_ies_defs.h>
-#include <osmocom/ranap/ranap_msg_factory.h>
-#include <osmocom/ranap/iu_client.h>
-#endif
-
-#include <openbsc/debug.h>
-#include <openbsc/gprs_llc.h>
-#include <openbsc/gprs_sgsn.h>
-#include <openbsc/gprs_gmm.h>
-#include <openbsc/gprs_utils.h>
-#include <openbsc/gprs_subscriber.h>
-#include <openbsc/sgsn.h>
-#include <openbsc/signal.h>
-#include <openbsc/gprs_sndcp.h>
+#include <osmocom/sgsn/debug.h>
+#include <osmocom/sgsn/gprs_llc.h>
+#include <osmocom/sgsn/gprs_sgsn.h>
+#include <osmocom/sgsn/gprs_gmm.h>
+#include <osmocom/sgsn/gprs_utils.h>
+#include <osmocom/sgsn/gprs_subscriber.h>
+#include <osmocom/sgsn/sgsn.h>
+#include <osmocom/sgsn/gprs_gmm_attach.h>
+#include <osmocom/sgsn/gprs_mm_state_gb_fsm.h>
+#include <osmocom/sgsn/gprs_mm_state_iu_fsm.h>
+#include <osmocom/sgsn/gprs_gmm_fsm.h>
+#include <osmocom/sgsn/signal.h>
+#include <osmocom/sgsn/gprs_sndcp.h>
+#include <osmocom/sgsn/gprs_ranap.h>
#include <pdp.h>
#define PTMSI_ALLOC
extern struct sgsn_instance *sgsn;
-extern void *tall_bsc_ctx;
+extern void *tall_sgsn_ctx;
static const struct tlv_definition gsm48_gmm_att_tlvdef = {
.def = {
@@ -90,142 +86,19 @@ static const struct tlv_definition gsm48_gmm_att_tlvdef = {
},
};
-static const struct tlv_definition gsm48_sm_att_tlvdef = {
- .def = {
- [GSM48_IE_GSM_APN] = { TLV_TYPE_TLV, 0 },
- [GSM48_IE_GSM_PROTO_CONF_OPT] = { TLV_TYPE_TLV, 0 },
- [GSM48_IE_GSM_PDP_ADDR] = { TLV_TYPE_TLV, 0 },
- [GSM48_IE_GSM_AA_TMR] = { TLV_TYPE_TV, 1 },
- [GSM48_IE_GSM_NAME_FULL] = { TLV_TYPE_TLV, 0 },
- [GSM48_IE_GSM_NAME_SHORT] = { TLV_TYPE_TLV, 0 },
- [GSM48_IE_GSM_TIMEZONE] = { TLV_TYPE_FIXED, 1 },
- [GSM48_IE_GSM_UTC_AND_TZ] = { TLV_TYPE_FIXED, 7 },
- [GSM48_IE_GSM_LSA_ID] = { TLV_TYPE_TLV, 0 },
- },
-};
-
-static const struct value_string gprs_pmm_state_names[] = {
- { PMM_DETACHED, "PMM DETACH" },
- { PMM_CONNECTED, "PMM CONNECTED" },
- { PMM_IDLE, "PMM IDLE" },
- { MM_IDLE, "MM IDLE" },
- { MM_READY, "MM READY" },
- { MM_STANDBY, "MM STANDBY" },
- { 0, NULL }
-};
-
-static int gsm48_gmm_authorize(struct sgsn_mm_ctx *ctx);
-
-static void mmctx_change_gtpu_endpoints_to_sgsn(struct sgsn_mm_ctx *mm_ctx)
-{
- struct sgsn_pdp_ctx *pdp;
- llist_for_each_entry(pdp, &mm_ctx->pdp_list, list) {
- sgsn_pdp_upd_gtp_u(pdp,
- &sgsn->cfg.gtp_listenaddr.sin_addr,
- sizeof(sgsn->cfg.gtp_listenaddr.sin_addr));
- }
-}
-
-void mmctx_set_pmm_state(struct sgsn_mm_ctx *ctx, enum gprs_pmm_state state)
-{
- if (ctx->ran_type != MM_CTX_T_UTRAN_Iu)
- return;
-
- if (ctx->pmm_state == state)
- return;
-
- LOGMMCTXP(LOGL_INFO, ctx, "Changing PMM state from %s to %s\n",
- get_value_string(gprs_pmm_state_names, ctx->pmm_state),
- get_value_string(gprs_pmm_state_names, state));
-
- switch (state) {
- case PMM_IDLE:
- /* TODO: start RA Upd timer */
- mmctx_change_gtpu_endpoints_to_sgsn(ctx);
- break;
- case PMM_CONNECTED:
- break;
- default:
- break;
- }
-
- ctx->pmm_state = state;
-}
-
-void mmctx_set_mm_state(struct sgsn_mm_ctx *ctx, enum gprs_pmm_state state)
-{
- if (ctx->ran_type != MM_CTX_T_GERAN_Gb)
- return;
-
- if (ctx->pmm_state == state)
- return;
-
- LOGMMCTXP(LOGL_INFO, ctx, "Changing MM state from %s to %s\n",
- get_value_string(gprs_pmm_state_names, ctx->pmm_state),
- get_value_string(gprs_pmm_state_names, state));
-
- ctx->pmm_state = state;
-}
-
-#ifdef BUILD_IU
-int sgsn_ranap_rab_ass_resp(struct sgsn_mm_ctx *ctx, RANAP_RAB_SetupOrModifiedItemIEs_t *setup_ies);
-int sgsn_ranap_iu_event(struct ranap_ue_conn_ctx *ctx, enum ranap_iu_event_type type, void *data)
-{
- struct sgsn_mm_ctx *mm;
- int rc = -1;
-
- mm = sgsn_mm_ctx_by_ue_ctx(ctx);
-
-#define REQUIRE_MM \
- if (!mm) { \
- LOGP(DRANAP, LOGL_NOTICE, "Cannot find mm ctx for IU event %d\n", type); \
- return rc; \
- }
-
- switch (type) {
- case RANAP_IU_EVENT_RAB_ASSIGN:
- REQUIRE_MM
- rc = sgsn_ranap_rab_ass_resp(mm, (RANAP_RAB_SetupOrModifiedItemIEs_t *)data);
- break;
- case RANAP_IU_EVENT_IU_RELEASE:
- /* fall thru */
- case RANAP_IU_EVENT_LINK_INVALIDATED:
- /* Clean up ranap_ue_conn_ctx here */
- if (mm)
- LOGMMCTXP(LOGL_INFO, mm, "IU release for imsi %s\n", mm->imsi);
- else
- LOGMMCTXP(LOGL_INFO, mm, "IU release for UE conn 0x%x\n",
- ctx->conn_id);
- if (mm && mm->pmm_state == PMM_CONNECTED)
- mmctx_set_pmm_state(mm, PMM_IDLE);
- rc = 0;
- break;
- case RANAP_IU_EVENT_SECURITY_MODE_COMPLETE:
- REQUIRE_MM
- /* Continue authentication here */
- mm->iu.ue_ctx->integrity_active = 1;
- rc = gsm48_gmm_authorize(mm);
- break;
- default:
- LOGP(DRANAP, LOGL_NOTICE, "Unknown event received: %i\n", type);
- rc = -1;
- break;
- }
- return rc;
-}
-#endif
-
-
/* Our implementation, should be kept in SGSN */
static void mmctx_timer_cb(void *_mm);
-static void mmctx_timer_start(struct sgsn_mm_ctx *mm, unsigned int T,
- unsigned int seconds)
+static void mmctx_timer_start(struct sgsn_mm_ctx *mm, unsigned int T)
{
+ unsigned long seconds;
if (osmo_timer_pending(&mm->timer))
LOGMMCTXP(LOGL_ERROR, mm, "Starting MM timer %u while old "
"timer %u pending\n", T, mm->T);
+
+ seconds = osmo_tdef_get(sgsn->cfg.T_defs, T, OSMO_TDEF_S, -1);
+
mm->T = T;
mm->num_T_exp = 0;
@@ -244,13 +117,17 @@ static void mmctx_timer_stop(struct sgsn_mm_ctx *mm, unsigned int T)
time_t gprs_max_time_to_idle(void)
{
- return sgsn->cfg.timers.T3314 + (sgsn->cfg.timers.T3312 + 4 * 60);
+ unsigned long T3314, T3312;
+
+ T3314 = osmo_tdef_get(sgsn->cfg.T_defs, 3314, OSMO_TDEF_S, -1);
+ T3312 = osmo_tdef_get(sgsn->cfg.T_defs, 3312, OSMO_TDEF_S, -1);
+ return T3314 + (T3312 + 4 * 60);
}
/* Send a message through the underlying layer.
* For param encryptable, see 3GPP TS 24.008 § 4.7.1.2 and
* gsm48_hdr_gmm_cipherable(). Pass false for not cipherable messages. */
-static int gsm48_gmm_sendmsg(struct msgb *msg, int command,
+int gsm48_gmm_sendmsg(struct msgb *msg, int command,
struct sgsn_mm_ctx *mm, bool encryptable)
{
if (mm) {
@@ -262,10 +139,7 @@ static int gsm48_gmm_sendmsg(struct msgb *msg, int command,
}
#ifdef BUILD_IU
- /* In Iu mode, msg->dst contains the ranap_ue_conn_ctx pointer, in Gb mode
- * dst is empty. */
- /* FIXME: have a more explicit indicator for Iu messages */
- if (msg->dst)
+ if (MSG_IU_UE_CTX(msg))
return ranap_iu_tx(msg, GPRS_SAPI_GMM);
#endif
@@ -280,32 +154,38 @@ static void gmm_copy_id(struct msgb *msg, const struct msgb *old)
msgb_tlli(msg) = msgb_tlli(old);
msgb_bvci(msg) = msgb_bvci(old);
msgb_nsei(msg) = msgb_nsei(old);
- msg->dst = old->dst;
+ MSG_IU_UE_CTX_SET(msg, MSG_IU_UE_CTX(old));
}
/* Store BVCI/NSEI in MM context */
-static void msgid2mmctx(struct sgsn_mm_ctx *mm, const struct msgb *msg)
+void msgid2mmctx(struct sgsn_mm_ctx *mm, const struct msgb *msg)
{
- mm->gb.bvci = msgb_bvci(msg);
- mm->gb.nsei = msgb_nsei(msg);
- /* In case a Iu connection is reconnected we need to update the ue ctx */
- mm->iu.ue_ctx = msg->dst;
- if (mm->ran_type == MM_CTX_T_UTRAN_Iu
- && mm->iu.ue_ctx) {
+ /* check for Iu or Gb */
+ if (!MSG_IU_UE_CTX(msg)) {
+ mm->gb.bvci = msgb_bvci(msg);
+ mm->gb.nsei = msgb_nsei(msg);
+ }
#ifdef BUILD_IU
- mm->iu.ue_ctx->rab_assign_addr_enc =
- sgsn->cfg.iu.rab_assign_addr_enc;
-#endif
+ else {
+ /* In case a Iu connection is reconnected we need to update the ue ctx */
+ /* FIXME: the old ue_ctx have to be freed/disconnected */
+ mm->iu.ue_ctx = MSG_IU_UE_CTX(msg);
+ if (mm->ran_type == MM_CTX_T_UTRAN_Iu
+ && mm->iu.ue_ctx) {
+ mm->iu.ue_ctx->rab_assign_addr_enc =
+ sgsn->cfg.iu.rab_assign_addr_enc;
+ }
}
+#endif
}
/* Store BVCI/NSEI in MM context */
-static void mmctx2msgid(struct msgb *msg, const struct sgsn_mm_ctx *mm)
+void mmctx2msgid(struct msgb *msg, const struct sgsn_mm_ctx *mm)
{
msgb_tlli(msg) = mm->gb.tlli;
msgb_bvci(msg) = mm->gb.bvci;
msgb_nsei(msg) = mm->gb.nsei;
- msg->dst = mm->iu.ue_ctx;
+ MSG_IU_UE_CTX_SET(msg, mm->iu.ue_ctx);
}
static void mm_ctx_cleanup_free(struct sgsn_mm_ctx *ctx, const char *log_text)
@@ -313,16 +193,23 @@ static void mm_ctx_cleanup_free(struct sgsn_mm_ctx *ctx, const char *log_text)
LOGMMCTXP(LOGL_INFO, ctx, "Cleaning MM context due to %s\n", log_text);
/* Mark MM state as deregistered */
- ctx->gmm_state = GMM_DEREGISTERED;
- mmctx_set_pmm_state(ctx, PMM_DETACHED);
- mmctx_set_pmm_state(ctx, MM_IDLE);
+ osmo_fsm_inst_dispatch(ctx->gmm_fsm, E_GMM_CLEANUP, NULL);
+
+ switch(ctx->ran_type) {
+ case MM_CTX_T_UTRAN_Iu:
+ osmo_fsm_inst_dispatch(ctx->iu.mm_state_fsm, E_PMM_IMPLICIT_DETACH, NULL);
+ break;
+ case MM_CTX_T_GERAN_Gb:
+ osmo_fsm_inst_dispatch(ctx->gb.mm_state_fsm, E_MM_IMPLICIT_DETACH, NULL);
+ break;
+ }
sgsn_mm_ctx_cleanup_free(ctx);
}
/* Chapter 9.4.18 */
static int _tx_status(struct msgb *msg, uint8_t cause,
- struct sgsn_mm_ctx *mmctx, int sm)
+ struct sgsn_mm_ctx *mmctx)
{
struct gsm48_hdr *gh;
@@ -332,13 +219,8 @@ static int _tx_status(struct msgb *msg, uint8_t cause,
get_value_string(gsm48_gmm_cause_names, cause));
gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh) + 1);
- if (sm) {
- gh->proto_discr = GSM48_PDISC_SM_GPRS;
- gh->msg_type = GSM48_MT_GSM_STATUS;
- } else {
- gh->proto_discr = GSM48_PDISC_MM_GPRS;
- gh->msg_type = GSM48_MT_GMM_STATUS;
- }
+ gh->proto_discr = GSM48_PDISC_MM_GPRS;
+ gh->msg_type = GSM48_MT_GMM_STATUS;
gh->data[0] = cause;
return gsm48_gmm_sendmsg(msg, 0, mmctx, true);
@@ -349,15 +231,7 @@ static int gsm48_tx_gmm_status(struct sgsn_mm_ctx *mmctx, uint8_t cause)
struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 GMM STATUS");
mmctx2msgid(msg, mmctx);
- return _tx_status(msg, cause, mmctx, 0);
-}
-
-static int gsm48_tx_sm_status(struct sgsn_mm_ctx *mmctx, uint8_t cause)
-{
- struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 SM STATUS");
-
- mmctx2msgid(msg, mmctx);
- return _tx_status(msg, cause, mmctx, 1);
+ return _tx_status(msg, cause, mmctx);
}
static int _tx_detach_req(struct msgb *msg, uint8_t detach_type, uint8_t cause,
@@ -400,36 +274,14 @@ static int gsm48_tx_gmm_detach_req_oldmsg(struct msgb *oldmsg,
return _tx_detach_req(msg, detach_type, cause, NULL);
}
-static struct gsm48_qos default_qos = {
- .delay_class = 4, /* best effort */
- .reliab_class = GSM48_QOS_RC_LLC_UN_RLC_ACK_DATA_PROT,
- .peak_tput = GSM48_QOS_PEAK_TPUT_32000bps,
- .preced_class = GSM48_QOS_PC_NORMAL,
- .mean_tput = GSM48_QOS_MEAN_TPUT_BEST_EFFORT,
- .traf_class = GSM48_QOS_TC_INTERACTIVE,
- .deliv_order = GSM48_QOS_DO_UNORDERED,
- .deliv_err_sdu = GSM48_QOS_ERRSDU_YES,
- .max_sdu_size = GSM48_QOS_MAXSDU_1520,
- .max_bitrate_up = GSM48_QOS_MBRATE_63k,
- .max_bitrate_down = GSM48_QOS_MBRATE_63k,
- .resid_ber = GSM48_QOS_RBER_5e_2,
- .sdu_err_ratio = GSM48_QOS_SERR_1e_2,
- .handling_prio = 3,
- .xfer_delay = 0x10, /* 200ms */
- .guar_bitrate_up = GSM48_QOS_MBRATE_0k,
- .guar_bitrate_down = GSM48_QOS_MBRATE_0k,
- .sig_ind = 0, /* not optimised for signalling */
- .max_bitrate_down_ext = 0, /* use octet 9 */
- .guar_bitrate_down_ext = 0, /* use octet 13 */
-};
-
/* Chapter 9.4.2: Attach accept */
-static int gsm48_tx_gmm_att_ack(struct sgsn_mm_ctx *mm)
+int gsm48_tx_gmm_att_ack(struct sgsn_mm_ctx *mm)
{
struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 ATT ACK");
struct gsm48_hdr *gh;
struct gsm48_attach_ack *aa;
uint8_t *mid;
+ unsigned long t;
#if 0
uint8_t *ptsig;
#endif
@@ -446,9 +298,10 @@ static int gsm48_tx_gmm_att_ack(struct sgsn_mm_ctx *mm)
aa = (struct gsm48_attach_ack *) msgb_put(msg, sizeof(*aa));
aa->force_stby = 0; /* not indicated */
aa->att_result = 1; /* GPRS only */
- aa->ra_upd_timer = gprs_secs_to_tmr_floor(sgsn->cfg.timers.T3312);
+ t = osmo_tdef_get(sgsn->cfg.T_defs, 3312, OSMO_TDEF_S, -1);
+ aa->ra_upd_timer = gprs_secs_to_tmr_floor(t);
aa->radio_prio = 4; /* lowest */
- gsm48_construct_ra(aa->ra_id.digits, &mm->ra);
+ gsm48_encode_ra(&aa->ra_id, &mm->ra);
#if 0
/* Optional: P-TMSI signature */
@@ -463,8 +316,8 @@ static int gsm48_tx_gmm_att_ack(struct sgsn_mm_ctx *mm)
* (fixed 44s, default value, GSM 04.08, table 11.4a) to safely limit
* the inactivity time READY->STANDBY.
*/
- msgb_tv_put(msg, GSM48_IE_GMM_TIMER_READY,
- gprs_secs_to_tmr_floor(sgsn->cfg.timers.T3314));
+ t = osmo_tdef_get(sgsn->cfg.T_defs, 3314, OSMO_TDEF_S, -1);
+ msgb_tv_put(msg, GSM48_IE_GMM_TIMER_READY, gprs_secs_to_tmr_floor(t));
#ifdef PTMSI_ALLOC
/* Optional: Allocated P-TMSI */
@@ -503,7 +356,7 @@ static int gsm48_tx_gmm_att_rej_oldmsg(const struct msgb *old_msg,
gmm_copy_id(msg, old_msg);
return _tx_gmm_att_rej(msg, gmm_cause, NULL);
}
-static int gsm48_tx_gmm_att_rej(struct sgsn_mm_ctx *mm,
+int gsm48_tx_gmm_att_rej(struct sgsn_mm_ctx *mm,
uint8_t gmm_cause)
{
struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 ATT REJ");
@@ -547,7 +400,7 @@ static int gsm48_tx_gmm_det_ack_oldmsg(struct msgb *oldmsg, uint8_t force_stby)
}
/* Transmit Chapter 9.4.12 Identity Request */
-static int gsm48_tx_gmm_id_req(struct sgsn_mm_ctx *mm, uint8_t id_type)
+int gsm48_tx_gmm_id_req(struct sgsn_mm_ctx *mm, uint8_t id_type)
{
struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 ID REQ");
struct gsm48_hdr *gh;
@@ -576,8 +429,8 @@ static bool mmctx_is_r99(const struct sgsn_mm_ctx *mm)
return false;
}
-/* 3GPP TS 24.008 Section 9.4.9: Authentication and Ciphering Request */
-static int gsm48_tx_gmm_auth_ciph_req(struct sgsn_mm_ctx *mm,
+/* 3GPP TS 24.008 § 9.4.9: Authentication and Ciphering Request */
+int gsm48_tx_gmm_auth_ciph_req(struct sgsn_mm_ctx *mm,
const struct osmo_auth_vector *vec,
uint8_t key_seq, bool force_standby)
{
@@ -585,9 +438,12 @@ static int gsm48_tx_gmm_auth_ciph_req(struct sgsn_mm_ctx *mm,
struct gsm48_hdr *gh;
struct gsm48_auth_ciph_req *acreq;
uint8_t *m_rand, *m_cksn, rbyte;
+ int rc;
- LOGMMCTXP(LOGL_INFO, mm, "<- GPRS AUTH AND CIPHERING REQ (rand = %s",
- osmo_hexdump(vec->rand, sizeof(vec->rand)));
+ LOGMMCTXP(LOGL_INFO, mm, "<- GPRS AUTH AND CIPHERING REQ (rand = %s,"
+ " mmctx_is_r99=%d, vec->auth_types=0x%x",
+ osmo_hexdump(vec->rand, sizeof(vec->rand)),
+ mmctx_is_r99(mm), vec->auth_types);
if (mmctx_is_r99(mm) && vec
&& (vec->auth_types & OSMO_AUTH_TYPE_UMTS)) {
LOGPC(DMM, LOGL_INFO, ", autn = %s)\n",
@@ -608,12 +464,13 @@ static int gsm48_tx_gmm_auth_ciph_req(struct sgsn_mm_ctx *mm,
/* § 10.5.5.7: */
acreq->force_stby = force_standby;
/* 3GPP TS 24.008 § 10.5.5.19: */
- if (RAND_bytes(&rbyte, 1) != 1) {
- LOGP(DMM, LOGL_NOTICE, "RAND_bytes failed for A&C ref, falling "
- "back to rand()\n");
- acreq->ac_ref_nr = rand();
- } else
- acreq->ac_ref_nr = rbyte;
+ rc = osmo_get_rand_id(&rbyte, 1);
+ if (rc < 0) {
+ LOGMMCTXP(LOGL_ERROR, mm, "osmo_get_rand_id() failed for A&C ref: %s\n", strerror(-rc));
+ return rc;
+ }
+
+ acreq->ac_ref_nr = rbyte;
mm->ac_ref_nr_used = acreq->ac_ref_nr;
/* Only if authentication is requested we need to set RAND + CKSN */
@@ -640,7 +497,7 @@ static int gsm48_tx_gmm_auth_ciph_req(struct sgsn_mm_ctx *mm,
return gsm48_gmm_sendmsg(msg, 1, mm, false);
}
-/* Section 9.4.11: Authentication and Ciphering Reject */
+/* 3GPP TS 24.008 § 9.4.11: Authentication and Ciphering Reject */
static int gsm48_tx_gmm_auth_ciph_rej(struct sgsn_mm_ctx *mm)
{
struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 AUTH CIPH REJ");
@@ -658,24 +515,24 @@ static int gsm48_tx_gmm_auth_ciph_rej(struct sgsn_mm_ctx *mm)
}
/* check if the received authentication response matches */
-static bool check_auth_resp(struct sgsn_mm_ctx *ctx,
- bool is_utran,
- const struct osmo_auth_vector *vec,
- const uint8_t *res, uint8_t res_len)
+static enum osmo_sub_auth_type check_auth_resp(struct sgsn_mm_ctx *ctx,
+ bool is_utran,
+ const struct osmo_auth_vector *vec,
+ const uint8_t *res, uint8_t res_len)
{
const uint8_t *expect_res;
uint8_t expect_res_len;
enum osmo_sub_auth_type expect_type;
const char *expect_str;
- if (!vec)
- return true; /* really!? */
-
/* On UTRAN (3G) we always expect UMTS AKA. On GERAN (2G) we sent AUTN
* and expect UMTS AKA if there is R99 capability and our vector
- * supports UMTS AKA, otherwise we expect GSM AKA. */
+ * supports UMTS AKA, otherwise we expect GSM AKA.
+ * However, on GERAN, even if we sent a UMTS AKA Authentication Request, the MS may decide to
+ * instead reply with a GSM AKA SRES response. */
if (is_utran
- || (mmctx_is_r99(ctx) && (vec->auth_types & OSMO_AUTH_TYPE_UMTS))) {
+ || (mmctx_is_r99(ctx) && (vec->auth_types & OSMO_AUTH_TYPE_UMTS)
+ && (res_len > sizeof(vec->sres)))) {
expect_type = OSMO_AUTH_TYPE_UMTS;
expect_str = "UMTS RES";
expect_res = vec->res;
@@ -686,13 +543,13 @@ static bool check_auth_resp(struct sgsn_mm_ctx *ctx,
expect_res = vec->sres;
expect_res_len = sizeof(vec->sres);
}
-
+
if (!(vec->auth_types & expect_type)) {
LOGMMCTXP(LOGL_ERROR, ctx, "Auth error: auth vector does"
" not provide the expected auth type:"
" expected %s = 0x%x, auth_types are 0x%x\n",
expect_str, expect_type, vec->auth_types);
- return false;
+ return OSMO_AUTH_TYPE_NONE;
}
if (!res)
@@ -705,15 +562,15 @@ static bool check_auth_resp(struct sgsn_mm_ctx *ctx,
goto auth_mismatch;
/* Authorized! */
- return true;
+ return expect_type;
auth_mismatch:
LOGMMCTXP(LOGL_ERROR, ctx, "Auth mismatch: expected %s = %s\n",
expect_str, osmo_hexdump_nospc(expect_res, expect_res_len));
- return false;
+ return OSMO_AUTH_TYPE_NONE;
}
-/* Section 9.4.10: Authentication and Ciphering Response */
+/* 3GPP TS 24.008 § 9.4.10: Authentication and Ciphering Response */
static int gsm48_rx_gmm_auth_ciph_resp(struct sgsn_mm_ctx *ctx,
struct msgb *msg)
{
@@ -774,25 +631,23 @@ static int gsm48_rx_gmm_auth_ciph_resp(struct sgsn_mm_ctx *ctx,
LOGMMCTXP(LOGL_DEBUG, ctx, "checking auth: received %s = %s\n",
res_name, osmo_hexdump(res, res_len));
- rc = check_auth_resp(ctx, false, &at->vec, res, res_len);
- if (!rc) {
+ ctx->sec_ctx = check_auth_resp(ctx, false, &at->vec, res, res_len);
+ if (!sgsn_mm_ctx_is_authenticated(ctx)) {
rc = gsm48_tx_gmm_auth_ciph_rej(ctx);
mm_ctx_cleanup_free(ctx, "GPRS AUTH AND CIPH REJECT");
return rc;
}
- ctx->is_authenticated = 1;
-
if (ctx->ran_type == MM_CTX_T_UTRAN_Iu)
ctx->iu.new_key = 1;
/* FIXME: enable LLC cipheirng */
/* Check if we can let the mobile station enter */
- return gsm48_gmm_authorize(ctx);
+ return osmo_fsm_inst_dispatch(ctx->gmm_att_req.fsm, E_AUTH_RESP_RECV_SUCCESS, NULL);
}
-/* Section 9.4.10: Authentication and Ciphering Failure */
+/* 3GPP TS 24.008 § 9.4.10: Authentication and Ciphering Failure */
static int gsm48_rx_gmm_auth_ciph_fail(struct sgsn_mm_ctx *ctx,
struct msgb *msg)
{
@@ -834,7 +689,7 @@ static int gsm48_rx_gmm_auth_ciph_fail(struct sgsn_mm_ctx *ctx,
rc = gprs_subscr_request_auth_info(ctx, auts,
ctx->auth_triplet.vec.rand);
if (!rc)
- return 0;
+ return osmo_fsm_inst_dispatch(ctx->gmm_att_req.fsm, E_AUTH_RESP_RECV_RESYNC, NULL);
/* on error, fall through to send a reject */
LOGMMCTXP(LOGL_ERROR, ctx,
"Sending AUTS to HLR failed (rc = %d)\n", rc);
@@ -846,7 +701,7 @@ static int gsm48_rx_gmm_auth_ciph_fail(struct sgsn_mm_ctx *ctx,
return rc;
}
-static void extract_subscr_msisdn(struct sgsn_mm_ctx *ctx)
+void extract_subscr_msisdn(struct sgsn_mm_ctx *ctx)
{
struct gsm_mncc_number called;
uint8_t msisdn[sizeof(ctx->subscr->sgsn_data->msisdn) + 1];
@@ -877,7 +732,7 @@ static void extract_subscr_msisdn(struct sgsn_mm_ctx *ctx)
}
}
-static void extract_subscr_hlr(struct sgsn_mm_ctx *ctx)
+void extract_subscr_hlr(struct sgsn_mm_ctx *ctx)
{
struct gsm_mncc_number called;
uint8_t hlr_number[sizeof(ctx->subscr->sgsn_data->hlr) + 1];
@@ -972,21 +827,8 @@ static int gsm48_tx_gmm_service_rej(struct sgsn_mm_ctx *mm,
static int gsm48_tx_gmm_ra_upd_ack(struct sgsn_mm_ctx *mm);
-#ifdef BUILD_IU
-/* Send RAB activation requests for all PDP contexts */
-void activate_pdp_rabs(struct sgsn_mm_ctx *ctx)
-{
- struct sgsn_pdp_ctx *pdp;
- if (ctx->ran_type != MM_CTX_T_UTRAN_Iu)
- return;
- llist_for_each_entry(pdp, &ctx->pdp_list, list) {
- iu_rab_act_ps(pdp->nsapi, pdp);
- }
-}
-#endif
-
/* Check if we can already authorize a subscriber */
-static int gsm48_gmm_authorize(struct sgsn_mm_ctx *ctx)
+int gsm48_gmm_authorize(struct sgsn_mm_ctx *ctx)
{
#ifdef BUILD_IU
int rc;
@@ -998,12 +840,12 @@ static int gsm48_gmm_authorize(struct sgsn_mm_ctx *ctx)
/* Request IMSI and IMEI from the MS if they are unknown */
if (!strlen(ctx->imei)) {
ctx->t3370_id_type = GSM_MI_TYPE_IMEI;
- mmctx_timer_start(ctx, 3370, sgsn->cfg.timers.T3370);
+ mmctx_timer_start(ctx, 3370);
return gsm48_tx_gmm_id_req(ctx, GSM_MI_TYPE_IMEI);
}
if (!strlen(ctx->imsi)) {
ctx->t3370_id_type = GSM_MI_TYPE_IMSI;
- mmctx_timer_start(ctx, 3370, sgsn->cfg.timers.T3370);
+ mmctx_timer_start(ctx, 3370);
return gsm48_tx_gmm_id_req(ctx, GSM_MI_TYPE_IMSI);
}
@@ -1022,15 +864,16 @@ static int gsm48_gmm_authorize(struct sgsn_mm_ctx *ctx)
return 0;
}
- if (ctx->auth_state == SGSN_AUTH_AUTHENTICATE && !ctx->is_authenticated) {
+ if (ctx->auth_state == SGSN_AUTH_AUTHENTICATE
+ && !sgsn_mm_ctx_is_authenticated(ctx)) {
struct gsm_auth_tuple *at = &ctx->auth_triplet;
- mmctx_timer_start(ctx, 3360, sgsn->cfg.timers.T3360);
+ mmctx_timer_start(ctx, 3360);
return gsm48_tx_gmm_auth_ciph_req(ctx, &at->vec, at->key_seq,
false);
}
- if (ctx->auth_state == SGSN_AUTH_AUTHENTICATE && ctx->is_authenticated &&
+ if (ctx->auth_state == SGSN_AUTH_AUTHENTICATE && sgsn_mm_ctx_is_authenticated(ctx) &&
ctx->auth_triplet.key_seq != GSM_KEY_SEQ_INVAL) {
/* Check again for authorization */
sgsn_auth_request(ctx);
@@ -1064,20 +907,20 @@ static int gsm48_gmm_authorize(struct sgsn_mm_ctx *ctx)
extract_subscr_hlr(ctx);
#ifdef PTMSI_ALLOC
/* Start T3350 and re-transmit up to 5 times until ATTACH COMPLETE */
- mmctx_timer_start(ctx, 3350, sgsn->cfg.timers.T3350);
+ mmctx_timer_start(ctx, 3350);
ctx->t3350_mode = GMM_T3350_MODE_ATT;
#else
memset(&sig_data, 0, sizeof(sig_data));
sig_data.mm = mmctx;
osmo_signal_dispatch(SS_SGSN, S_SGSN_ATTACH, &sig_data);
- ctx->gmm_state = GMM_REGISTERED_NORMAL;
+ osmo_fsm_inst_dispatch(mm->gmm_fsm, E_GMM_ATTACH_SUCCESS, NULL);
#endif
return gsm48_tx_gmm_att_ack(ctx);
#ifdef BUILD_IU
case GSM48_MT_GMM_SERVICE_REQ:
ctx->pending_req = 0;
- mmctx_set_pmm_state(ctx, PMM_CONNECTED);
+ osmo_fsm_inst_dispatch(ctx->iu.mm_state_fsm, E_PMM_PS_ATTACH, NULL);
rc = gsm48_tx_gmm_service_ack(ctx);
if (ctx->iu.service.type != GPRS_SERVICE_T_SIGNALLING)
@@ -1102,20 +945,24 @@ static int gsm48_gmm_authorize(struct sgsn_mm_ctx *ctx)
void gsm0408_gprs_authenticate(struct sgsn_mm_ctx *ctx)
{
- ctx->is_authenticated = 0;
+ ctx->sec_ctx = OSMO_AUTH_TYPE_NONE;
- gsm48_gmm_authorize(ctx);
+ if (ctx->gmm_att_req.fsm->state != ST_INIT)
+ osmo_fsm_inst_dispatch(ctx->gmm_att_req.fsm, E_VLR_ANSWERED, (void *) 0);
+ else
+ gsm48_gmm_authorize(ctx);
}
void gsm0408_gprs_access_granted(struct sgsn_mm_ctx *ctx)
{
- switch (ctx->gmm_state) {
- case GMM_COMMON_PROC_INIT:
+ switch (ctx->gmm_fsm->state) {
+ case ST_GMM_COMMON_PROC_INIT:
LOGMMCTXP(LOGL_NOTICE, ctx,
"Authorized, continuing procedure, IMSI=%s\n",
ctx->imsi);
/* Continue with the authorization */
- gsm48_gmm_authorize(ctx);
+ if (ctx->gmm_att_req.fsm->state != ST_INIT)
+ osmo_fsm_inst_dispatch(ctx->gmm_att_req.fsm, E_VLR_ANSWERED, (void *) 0);
break;
default:
LOGMMCTXP(LOGL_INFO, ctx,
@@ -1129,25 +976,25 @@ void gsm0408_gprs_access_denied(struct sgsn_mm_ctx *ctx, int gmm_cause)
if (gmm_cause == SGSN_ERROR_CAUSE_NONE)
gmm_cause = GMM_CAUSE_GPRS_NOTALLOWED;
- switch (ctx->gmm_state) {
- case GMM_COMMON_PROC_INIT:
+ switch (ctx->gmm_fsm->state) {
+ case ST_GMM_COMMON_PROC_INIT:
LOGMMCTXP(LOGL_NOTICE, ctx,
"Not authorized, rejecting ATTACH REQUEST "
"with cause '%s' (%d)\n",
get_value_string(gsm48_gmm_cause_names, gmm_cause),
gmm_cause);
- gsm48_tx_gmm_att_rej(ctx, gmm_cause);
- mm_ctx_cleanup_free(ctx, "GPRS ATTACH REJECT");
+ if (ctx->gmm_att_req.fsm->state != ST_INIT)
+ osmo_fsm_inst_dispatch(ctx->gmm_att_req.fsm, E_REJECT, (void *) (long) gmm_cause);
break;
- case GMM_REGISTERED_NORMAL:
- case GMM_REGISTERED_SUSPENDED:
+ case ST_GMM_REGISTERED_NORMAL:
+ case ST_GMM_REGISTERED_SUSPENDED:
LOGMMCTXP(LOGL_NOTICE, ctx,
"Authorization lost, detaching "
"with cause '%s' (%d)\n",
get_value_string(gsm48_gmm_cause_names, gmm_cause),
gmm_cause);
gsm48_tx_gmm_detach_req(
- ctx, GPRS_DET_T_MT_REATT_NOTREQ, gmm_cause);
+ ctx, GPRS_DET_T_MT_IMSI, gmm_cause);
mm_ctx_cleanup_free(ctx, "auth lost");
break;
@@ -1180,6 +1027,7 @@ static int gsm48_rx_gmm_id_resp(struct sgsn_mm_ctx *ctx, struct msgb *msg)
{
struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_gmmh(msg);
uint8_t mi_type = gh->data[1] & GSM_MI_TYPE_MASK;
+ long mi_typel = mi_type;
char mi_string[GSM48_MI_SIZE];
gsm48_mi_to_string(mi_string, sizeof(mi_string), &gh->data[1], gh->data[0]);
@@ -1232,10 +1080,53 @@ static int gsm48_rx_gmm_id_resp(struct sgsn_mm_ctx *ctx, struct msgb *msg)
}
/* Check if we can let the mobile station enter */
- return gsm48_gmm_authorize(ctx);
+ return osmo_fsm_inst_dispatch(ctx->gmm_att_req.fsm, E_IDEN_RESP_RECV, (void *)mi_typel);
+}
+
+/* Allocate a new P-TMSI and change context state */
+static inline void ptmsi_update(struct sgsn_mm_ctx *ctx)
+{
+ uint32_t ptmsi;
+ /* Don't change the P-TMSI if a P-TMSI re-assignment is under way */
+ if (ctx->gmm_fsm->state != ST_GMM_COMMON_PROC_INIT) {
+ ptmsi = sgsn_alloc_ptmsi();
+ if (ptmsi != GSM_RESERVED_TMSI) {
+ ctx->p_tmsi_old = ctx->p_tmsi;
+ ctx->p_tmsi = ptmsi;
+ } else
+ LOGMMCTXP(LOGL_ERROR, ctx, "P-TMSI allocation failure: using old one.\n");
+ }
+ osmo_fsm_inst_dispatch(ctx->gmm_fsm, E_GMM_COMMON_PROC_INIT_REQ, NULL);
}
-/* Section 9.4.1 Attach request */
+/* Detect if RAT has changed */
+static bool mmctx_did_rat_change(struct sgsn_mm_ctx *mmctx, struct msgb *msg)
+{
+ if (MSG_IU_UE_CTX(msg) && mmctx->ran_type != MM_CTX_T_UTRAN_Iu)
+ return true;
+ if (!MSG_IU_UE_CTX(msg) && mmctx->ran_type != MM_CTX_T_GERAN_Gb)
+ return true;
+ return false;
+}
+
+/* Notify the FSM of a RAT change */
+static void mmctx_handle_rat_change(struct sgsn_mm_ctx *mmctx, struct msgb *msg, struct gprs_llc_llme *llme)
+{
+ struct gmm_rat_change_data rat_chg = {
+ .llme = llme
+ };
+
+ rat_chg.new_ran_type = MSG_IU_UE_CTX(msg) ? MM_CTX_T_UTRAN_Iu : MM_CTX_T_GERAN_Gb;
+
+ if (rat_chg.new_ran_type != mmctx->ran_type)
+ osmo_fsm_inst_dispatch(mmctx->gmm_fsm, E_GMM_RAT_CHANGE, (void *) &rat_chg);
+ else
+ LOGMMCTXP(LOGL_ERROR, mmctx, "RAT didn't change or not implemented (ran_type=%u, "
+ "msg_iu_ue_ctx=%p\n", mmctx->ran_type, MSG_IU_UE_CTX(msg));
+
+}
+
+/* 3GPP TS 24.008 § 9.4.1 Attach request */
static int gsm48_rx_gmm_att_req(struct sgsn_mm_ctx *ctx, struct msgb *msg,
struct gprs_llc_llme *llme)
{
@@ -1257,15 +1148,12 @@ static int gsm48_rx_gmm_att_req(struct sgsn_mm_ctx *ctx, struct msgb *msg,
* with a foreign TLLI (P-TMSI that was allocated to the MS before),
* or with random TLLI. */
- /* In Iu mode, msg->dst contains the ranap_ue_conn_ctx pointer, in Gb mode
- * dst is empty. */
- /* FIXME: have a more explicit indicator for Iu messages */
- if (!msg->dst) {
+ if (!MSG_IU_UE_CTX(msg)) {
/* Gb mode */
cid = bssgp_parse_cell_id(&ra_id, msgb_bcid(msg));
} else {
#ifdef BUILD_IU
- ra_id = ((struct ranap_ue_conn_ctx*)msg->dst)->ra_id;
+ ra_id = MSG_IU_UE_CTX(msg)->ra_id;
#else
LOGMMCTXP(LOGL_ERROR, ctx, "Cannot handle Iu Attach Request, built without Iu support\n");
return -ENOTSUP;
@@ -1279,7 +1167,11 @@ static int gsm48_rx_gmm_att_req(struct sgsn_mm_ctx *ctx, struct msgb *msg,
goto err_inval;
cur += msnc_len;
- /* TODO: In iu mode - handle follow-on request */
+ /* TODO: In iu mode - handle follow-on request.
+ * The follow-on request can be signaled in an Attach Request on IuPS.
+ * This means the MS/UE asks to keep the PS connection open for further requests
+ * after the Attach Request succeed.
+ * The SGSN can decide if it close the connection or not. Both are spec conform. */
/* aTTACH Type 10.5.5.2 */
att_type = *cur++ & 0x07;
@@ -1321,11 +1213,8 @@ static int gsm48_rx_gmm_att_req(struct sgsn_mm_ctx *ctx, struct msgb *msg,
if (!ctx)
ctx = sgsn_mm_ctx_by_imsi(mi_string);
if (!ctx) {
-#if 0
- return gsm48_tx_gmm_att_rej(msg, GMM_CAUSE_IMSI_UNKNOWN);
-#else
- if (msg->dst)
- ctx = sgsn_mm_ctx_alloc_iu(msg->dst);
+ if (MSG_IU_UE_CTX(msg))
+ ctx = sgsn_mm_ctx_alloc_iu(MSG_IU_UE_CTX(msg));
else
ctx = sgsn_mm_ctx_alloc_gb(0, &ra_id);
if (!ctx) {
@@ -1333,13 +1222,7 @@ static int gsm48_rx_gmm_att_req(struct sgsn_mm_ctx *ctx, struct msgb *msg,
goto rejected;
}
osmo_strlcpy(ctx->imsi, mi_string, sizeof(ctx->imsi));
-#endif
}
- if (ctx->ran_type == MM_CTX_T_GERAN_Gb) {
- ctx->gb.tlli = msgb_tlli(msg);
- ctx->gb.llme = llme;
- }
- msgid2mmctx(ctx, msg);
break;
case GSM_MI_TYPE_TMSI:
memcpy(&tmsi, mi+1, 4);
@@ -1350,17 +1233,16 @@ static int gsm48_rx_gmm_att_req(struct sgsn_mm_ctx *ctx, struct msgb *msg,
if (!ctx) {
/* Allocate a context as most of our code expects one.
* Context will not have an IMSI ultil ID RESP is received */
- if (msg->dst)
- ctx = sgsn_mm_ctx_alloc_iu(msg->dst);
+ if (MSG_IU_UE_CTX(msg))
+ ctx = sgsn_mm_ctx_alloc_iu(MSG_IU_UE_CTX(msg));
else
ctx = sgsn_mm_ctx_alloc_gb(msgb_tlli(msg), &ra_id);
+ if (!ctx) {
+ reject_cause = GMM_CAUSE_NET_FAIL;
+ goto rejected;
+ }
ctx->p_tmsi = tmsi;
}
- if (ctx->ran_type == MM_CTX_T_GERAN_Gb) {
- ctx->gb.tlli = msgb_tlli(msg);
- ctx->gb.llme = llme;
- }
- msgid2mmctx(ctx, msg);
break;
default:
LOGMMCTXP(LOGL_NOTICE, ctx, "Rejecting ATTACH REQUEST with "
@@ -1368,6 +1250,15 @@ static int gsm48_rx_gmm_att_req(struct sgsn_mm_ctx *ctx, struct msgb *msg,
reject_cause = GMM_CAUSE_MS_ID_NOT_DERIVED;
goto rejected;
}
+
+ if (mmctx_did_rat_change(ctx, msg))
+ mmctx_handle_rat_change(ctx, msg, llme);
+
+ if (ctx->ran_type == MM_CTX_T_GERAN_Gb) {
+ ctx->gb.tlli = msgb_tlli(msg);
+ ctx->gb.llme = llme;
+ }
+ msgid2mmctx(ctx, msg);
/* Update MM Context with currient RA and Cell ID */
ctx->ra = ra_id;
if (ctx->ran_type == MM_CTX_T_GERAN_Gb)
@@ -1391,12 +1282,7 @@ static int gsm48_rx_gmm_att_req(struct sgsn_mm_ctx *ctx, struct msgb *msg,
}
#ifdef PTMSI_ALLOC
/* Allocate a new P-TMSI (+ P-TMSI signature) and update TLLI */
- /* Don't change the P-TMSI if a P-TMSI re-assignment is under way */
- if (ctx->gmm_state != GMM_COMMON_PROC_INIT) {
- ctx->p_tmsi_old = ctx->p_tmsi;
- ctx->p_tmsi = sgsn_alloc_ptmsi();
- }
- ctx->gmm_state = GMM_COMMON_PROC_INIT;
+ ptmsi_update(ctx);
#endif
if (ctx->ran_type == MM_CTX_T_GERAN_Gb) {
@@ -1405,14 +1291,14 @@ static int gsm48_rx_gmm_att_req(struct sgsn_mm_ctx *ctx, struct msgb *msg,
ctx->gb.tlli_new = gprs_tmsi2tlli(ctx->p_tmsi, TLLI_LOCAL);
/* Inform LLC layer about new TLLI but keep old active */
- if (ctx->is_authenticated)
+ if (sgsn_mm_ctx_is_authenticated(ctx))
gprs_llme_copy_key(ctx, ctx->gb.llme);
gprs_llgmm_assign(ctx->gb.llme, ctx->gb.tlli, ctx->gb.tlli_new);
}
- ctx->pending_req = GSM48_MT_GMM_ATTACH_REQ;
- return gsm48_gmm_authorize(ctx);
+ osmo_fsm_inst_dispatch(ctx->gmm_att_req.fsm, E_ATTACH_REQ_RECV, msg);
+ return 0;
err_inval:
LOGPC(DMM, LOGL_INFO, "\n");
@@ -1426,14 +1312,75 @@ rejected:
rc = gsm48_tx_gmm_att_rej_oldmsg(msg, reject_cause);
if (ctx)
mm_ctx_cleanup_free(ctx, "GPRS ATTACH REJ");
- else
+ else if (llme)
gprs_llgmm_unassign(llme);
return rc;
}
-/* Section 4.7.4.1 / 9.4.5.2 MO Detach request */
+/* 3GPP TS 24.008 § 9.4.3 Attach complete */
+static int gsm48_rx_gmm_att_compl(struct sgsn_mm_ctx *mmctx)
+{
+ struct sgsn_signal_data sig_data;
+ /* only in case SGSN offered new P-TMSI */
+ LOGMMCTXP(LOGL_INFO, mmctx, "-> ATTACH COMPLETE\n");
+
+ #ifdef BUILD_IU
+ if (mmctx->iu.ue_ctx) {
+ ranap_iu_tx_release(mmctx->iu.ue_ctx, NULL);
+ }
+ #endif
+
+ mmctx_timer_stop(mmctx, 3350);
+ mmctx->t3350_mode = GMM_T3350_MODE_NONE;
+ mmctx->p_tmsi_old = 0;
+ mmctx->pending_req = 0;
+ osmo_fsm_inst_dispatch(mmctx->gmm_fsm, E_GMM_ATTACH_SUCCESS, NULL);
+ switch(mmctx->ran_type) {
+ case MM_CTX_T_UTRAN_Iu:
+ osmo_fsm_inst_dispatch(mmctx->iu.mm_state_fsm, E_PMM_PS_ATTACH, NULL);
+ break;
+ case MM_CTX_T_GERAN_Gb:
+ /* Unassign the old TLLI */
+ mmctx->gb.tlli = mmctx->gb.tlli_new;
+ gprs_llme_copy_key(mmctx, mmctx->gb.llme);
+ gprs_llgmm_assign(mmctx->gb.llme, TLLI_UNASSIGNED,
+ mmctx->gb.tlli_new);
+ osmo_fsm_inst_dispatch(mmctx->gb.mm_state_fsm, E_MM_GPRS_ATTACH, NULL);
+ break;
+ }
+
+ osmo_fsm_inst_dispatch(mmctx->gmm_att_req.fsm, E_ATTACH_COMPLETE_RECV, 0);
+ memset(&sig_data, 0, sizeof(sig_data));
+ sig_data.mm = mmctx;
+ osmo_signal_dispatch(SS_SGSN, S_SGSN_ATTACH, &sig_data);
+
+ return 0;
+}
+
+/* Checks if two attach request contain the IEs and IE values
+ * return 0 if equal
+ * return -1 if error
+ * return 1 if unequal
+ *
+ * Only do a simple memcmp for now.
+ */
+int gprs_gmm_attach_req_ies(struct msgb *a, struct msgb *b)
+{
+ struct gsm48_hdr *gh_a = (struct gsm48_hdr *) msgb_gmmh(a);
+ struct gsm48_hdr *gh_b = (struct gsm48_hdr *) msgb_gmmh(b);
+
+#define GMM_ATTACH_REQ_LEN 26
+
+ /* there is the LLC FCS behind */
+ if (msgb_l3len(a) < GMM_ATTACH_REQ_LEN || msgb_l3len(b) < GMM_ATTACH_REQ_LEN)
+ return -1;
+
+ return !!memcmp(gh_a, gh_b, GMM_ATTACH_REQ_LEN);
+}
+
+/* 3GPP TS 24.008 § 4.7.4.1 / 9.4.5.2 MO Detach request */
static int gsm48_rx_gmm_det_req(struct sgsn_mm_ctx *ctx, struct msgb *msg)
{
struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_gmmh(msg);
@@ -1477,6 +1424,7 @@ static int gsm48_tx_gmm_ra_upd_ack(struct sgsn_mm_ctx *mm)
struct gsm48_hdr *gh;
struct gsm48_ra_upd_ack *rua;
uint8_t *mid;
+ unsigned long t;
rate_ctr_inc(&sgsn->rate_ctrs->ctr[CTR_GPRS_ROUTING_AREA_ACKED]);
LOGMMCTXP(LOGL_INFO, mm, "<- ROUTING AREA UPDATE ACCEPT\n");
@@ -1490,9 +1438,10 @@ static int gsm48_tx_gmm_ra_upd_ack(struct sgsn_mm_ctx *mm)
rua = (struct gsm48_ra_upd_ack *) msgb_put(msg, sizeof(*rua));
rua->force_stby = 0; /* not indicated */
rua->upd_result = 0; /* RA updated */
- rua->ra_upd_timer = gprs_secs_to_tmr_floor(sgsn->cfg.timers.T3312);
+ t = osmo_tdef_get(sgsn->cfg.T_defs, 3312, OSMO_TDEF_S, -1);
+ rua->ra_upd_timer = gprs_secs_to_tmr_floor(t);
- gsm48_construct_ra(rua->ra_id.digits, &mm->ra);
+ gsm48_encode_ra(&rua->ra_id, &mm->ra);
#if 0
/* Optional: P-TMSI signature */
@@ -1511,15 +1460,15 @@ static int gsm48_tx_gmm_ra_upd_ack(struct sgsn_mm_ctx *mm)
#endif
/* Optional: Negotiated READY timer value */
- msgb_tv_put(msg, GSM48_IE_GMM_TIMER_READY,
- gprs_secs_to_tmr_floor(sgsn->cfg.timers.T3314));
+ t = osmo_tdef_get(sgsn->cfg.T_defs, 3314, OSMO_TDEF_S, -1);
+ msgb_tv_put(msg, GSM48_IE_GMM_TIMER_READY, gprs_secs_to_tmr_floor(t));
/* Option: MS ID, ... */
return gsm48_gmm_sendmsg(msg, 0, mm, true);
}
/* Chapter 9.4.17: Routing area update reject */
-static int gsm48_tx_gmm_ra_upd_rej(struct msgb *old_msg, uint8_t cause)
+int gsm48_tx_gmm_ra_upd_rej(struct msgb *old_msg, uint8_t cause)
{
struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 RA UPD REJ");
struct gsm48_hdr *gh;
@@ -1569,6 +1518,19 @@ static void process_ms_ctx_status(struct sgsn_mm_ctx *mmctx,
}
}
+/* 3GPP TS 24.008 § 4.7.13.4 Service request procedure not accepted by the
+ * network. Returns true if MS has active PDP contexts in pdp_status */
+bool pdp_status_has_active_nsapis(const uint8_t *pdp_status, const size_t pdp_status_len)
+{
+ size_t i;
+
+ for (i = 0; i < pdp_status_len; i++)
+ if (pdp_status[i] != 0)
+ return true;
+
+ return false;
+}
+
/* Chapter 9.4.14: Routing area update request */
static int gsm48_rx_gmm_ra_upd_req(struct sgsn_mm_ctx *mmctx, struct msgb *msg,
struct gprs_llc_llme *llme)
@@ -1585,13 +1547,17 @@ static int gsm48_rx_gmm_ra_upd_req(struct sgsn_mm_ctx *mmctx, struct msgb *msg,
enum gsm48_gmm_cause reject_cause = GMM_CAUSE_PROTO_ERR_UNSPEC;
int rc;
- /* TODO: In iu mode - handle follow-on request */
+ /* TODO: In iu mode - handle follow-on request.
+ * The follow-on request can be signaled in an Attach Request on IuPS.
+ * This means the MS/UE asks to keep the PS connection open for further requests
+ * after the Attach Request succeed.
+ * The SGSN can decide if it close the connection or not. Both are spec conform. */
/* Update Type 10.5.5.18 */
upd_type = *cur++ & 0x07;
rate_ctr_inc(&sgsn->rate_ctrs->ctr[CTR_GPRS_ROUTING_AREA_REQUEST]);
- LOGP(DMM, LOGL_INFO, "-> GMM RA UPDATE REQUEST type=\"%s\"\n",
+ LOGMMCTXP(LOGL_INFO, mmctx, "-> GMM RA UPDATE REQUEST type=\"%s\"\n",
get_value_string(gprs_upd_t_strs, upd_type));
/* Old routing area identification 10.5.5.15 */
@@ -1601,6 +1567,9 @@ static int gsm48_rx_gmm_ra_upd_req(struct sgsn_mm_ctx *mmctx, struct msgb *msg,
/* MS Radio Access Capability 10.5.5.12a */
ms_ra_acc_cap_len = *cur++;
if (ms_ra_acc_cap_len > 52) {
+ LOGMMCTXP(LOGL_ERROR, mmctx,
+ "Rejecting GMM RA Update Request: MS Radio Access Capability too long"
+ " (ms_ra_acc_cap_len = %u > 52)\n", ms_ra_acc_cap_len);
reject_cause = GMM_CAUSE_PROTO_ERR_UNSPEC;
goto rejected;
}
@@ -1614,7 +1583,7 @@ static int gsm48_rx_gmm_ra_upd_req(struct sgsn_mm_ctx *mmctx, struct msgb *msg,
switch (upd_type) {
case GPRS_UPD_T_RA_LA:
case GPRS_UPD_T_RA_LA_IMSI_ATT:
- LOGP(DMM, LOGL_NOTICE, "Update type %i unsupported in Mode III, is your SI13 corrupt?\n", upd_type);
+ LOGMMCTXP(LOGL_NOTICE, mmctx, "Update type %i unsupported in Mode III, is your SI13 corrupt?\n", upd_type);
reject_cause = GMM_CAUSE_PROTO_ERR_UNSPEC;
goto rejected;
case GPRS_UPD_T_RA:
@@ -1631,17 +1600,15 @@ static int gsm48_rx_gmm_ra_upd_req(struct sgsn_mm_ctx *mmctx, struct msgb *msg,
* is an optimization to avoid the RA reject (impl detached)
* below, which will cause a new attach cycle. */
/* Look-up the MM context based on old RA-ID and TLLI */
- /* In Iu mode, msg->dst contains the ranap_ue_conn_ctx pointer, in Gb
- * mode dst is empty. */
- /* FIXME: have a more explicit indicator for Iu messages */
- if (!msg->dst) {
+ if (!MSG_IU_UE_CTX(msg)) {
+ /* Gb */
mmctx = sgsn_mm_ctx_by_tlli_and_ptmsi(msgb_tlli(msg), &old_ra_id);
} else if (TLVP_PRESENT(&tp, GSM48_IE_GMM_ALLOC_PTMSI)) {
#ifdef BUILD_IU
/* In Iu mode search only for ptmsi */
char mi_string[GSM48_MI_SIZE];
uint8_t mi_len = TLVP_LEN(&tp, GSM48_IE_GMM_ALLOC_PTMSI);
- uint8_t *mi = TLVP_VAL(&tp, GSM48_IE_GMM_ALLOC_PTMSI);
+ const uint8_t *mi = TLVP_VAL(&tp, GSM48_IE_GMM_ALLOC_PTMSI);
uint8_t mi_type = *mi & GSM_MI_TYPE_MASK;
uint32_t tmsi;
@@ -1653,6 +1620,8 @@ static int gsm48_rx_gmm_ra_upd_req(struct sgsn_mm_ctx *mmctx, struct msgb *msg,
mmctx = sgsn_mm_ctx_by_ptmsi(tmsi);
}
#else
+ LOGIUP(MSG_IU_UE_CTX(msg), LOGL_ERROR,
+ "Rejecting GMM RA Update Request: No Iu support\n");
goto rejected;
#endif
}
@@ -1660,23 +1629,30 @@ static int gsm48_rx_gmm_ra_upd_req(struct sgsn_mm_ctx *mmctx, struct msgb *msg,
LOGMMCTXP(LOGL_INFO, mmctx,
"Looked up by matching TLLI and P_TMSI. "
"BSSGP TLLI: %08x, P-TMSI: %08x (%08x), "
- "TLLI: %08x (%08x), RA: %d-%d-%d-%d\n",
+ "TLLI: %08x (%08x), RA: %s\n",
msgb_tlli(msg),
mmctx->p_tmsi, mmctx->p_tmsi_old,
mmctx->gb.tlli, mmctx->gb.tlli_new,
- mmctx->ra.mcc, mmctx->ra.mnc,
- mmctx->ra.lac, mmctx->ra.rac);
+ osmo_rai_name(&mmctx->ra));
+ /* A RAT change will trigger the common procedure
+ * below after handling the RAT change. Protect it
+ * here from being called twice */
+ if (!mmctx_did_rat_change(mmctx, msg))
+ osmo_fsm_inst_dispatch(mmctx->gmm_fsm, E_GMM_COMMON_PROC_INIT_REQ, NULL);
- mmctx->gmm_state = GMM_COMMON_PROC_INIT;
}
} else if (!gprs_ra_id_equals(&mmctx->ra, &old_ra_id) ||
- mmctx->gmm_state == GMM_DEREGISTERED)
+ mmctx->gmm_fsm->state == ST_GMM_DEREGISTERED)
{
/* We cannot use the mmctx */
LOGMMCTXP(LOGL_INFO, mmctx,
- "The MM context cannot be used, RA: %d-%d-%d-%d\n",
- mmctx->ra.mcc, mmctx->ra.mnc,
- mmctx->ra.lac, mmctx->ra.rac);
+ "The MM context cannot be used, RA: %s\n",
+ osmo_rai_name(&mmctx->ra));
+ /* mmctx is set to NULL and gprs_llgmm_unassign(llme) will be
+ called below, let's make sure we don't keep dangling llme
+ pointers in mmctx (OS#3957, OS#4245). */
+ if (mmctx->ran_type == MM_CTX_T_GERAN_Gb)
+ mmctx->gb.llme = NULL;
mmctx = NULL;
}
@@ -1684,23 +1660,29 @@ static int gsm48_rx_gmm_ra_upd_req(struct sgsn_mm_ctx *mmctx, struct msgb *msg,
if (llme) {
/* send a XID reset to re-set all LLC sequence numbers
* in the MS */
- LOGMMCTXP(LOGL_NOTICE, mmctx, "LLC XID RESET\n");
- gprs_llgmm_reset(llme);
+ LOGGBP(llme, DMM, LOGL_NOTICE, "LLC XID RESET\n");
+ gprs_llgmm_reset_oldmsg(msg, GPRS_SAPI_GMM, llme);
}
/* The MS has to perform GPRS attach */
/* Device is still IMSI attached for CS but initiate GPRS ATTACH,
* see GSM 04.08, 4.7.5.1.4 and G.6 */
+ LOGGBIUP(llme, msg, LOGL_ERROR, "Rejecting GMM RA Update Request: MS should GMM Attach first\n");
reject_cause = GMM_CAUSE_IMPL_DETACHED;
goto rejected;
}
+ if (mmctx_did_rat_change(mmctx, msg)) {
+ mmctx_handle_rat_change(mmctx, msg, llme);
+ osmo_fsm_inst_dispatch(mmctx->gmm_fsm, E_GMM_COMMON_PROC_INIT_REQ, NULL);
+ }
+
/* Store new BVCI/NSEI in MM context (FIXME: delay until we ack?) */
msgid2mmctx(mmctx, msg);
/* Bump the statistics of received signalling msgs for this MM context */
rate_ctr_inc(&mmctx->ctrg->ctr[GMM_CTR_PKTS_SIG_IN]);
/* Update the MM context with the new RA-ID */
- if (mmctx->ran_type == MM_CTX_T_GERAN_Gb) {
+ if (mmctx->ran_type == MM_CTX_T_GERAN_Gb && msgb_bcid(msg)) {
bssgp_parse_cell_id(&mmctx->ra, msgb_bcid(msg));
/* Update the MM context with the new (i.e. foreign) TLLI */
mmctx->gb.tlli = msgb_tlli(msg);
@@ -1711,19 +1693,14 @@ static int gsm48_rx_gmm_ra_upd_req(struct sgsn_mm_ctx *mmctx, struct msgb *msg,
rate_ctr_inc(&mmctx->ctrg->ctr[GMM_CTR_RA_UPDATE]);
#ifdef PTMSI_ALLOC
- /* Don't change the P-TMSI if a P-TMSI re-assignment is under way */
- if (mmctx->gmm_state != GMM_COMMON_PROC_INIT) {
- mmctx->p_tmsi_old = mmctx->p_tmsi;
- mmctx->p_tmsi = sgsn_alloc_ptmsi();
- }
+ ptmsi_update(mmctx);
+
/* Start T3350 and re-transmit up to 5 times until ATTACH COMPLETE */
mmctx->t3350_mode = GMM_T3350_MODE_RAU;
- mmctx_timer_start(mmctx, 3350, sgsn->cfg.timers.T3350);
-
- mmctx->gmm_state = GMM_COMMON_PROC_INIT;
+ mmctx_timer_start(mmctx, 3350);
#else
/* Make sure we are NORMAL (i.e. not SUSPENDED anymore) */
- mmctx->gmm_state = GMM_REGISTERED_NORMAL;
+ osmo_fsm_inst_dispatch(mm->gmm_fsm, E_GMM_ATTACH_SUCCESS, NULL);
memset(&sig_data, 0, sizeof(sig_data));
sig_data.mm = mmctx;
@@ -1734,7 +1711,7 @@ static int gsm48_rx_gmm_ra_upd_req(struct sgsn_mm_ctx *mmctx, struct msgb *msg,
* foreign TLLI to local TLLI */
mmctx->gb.tlli_new = gprs_tmsi2tlli(mmctx->p_tmsi, TLLI_LOCAL);
- /* Inform LLC layer about new TLLI but keep old active */
+ /* Inform LLC layer about new TLLI but keep accepting the old one during Rx */
gprs_llgmm_assign(mmctx->gb.llme, mmctx->gb.tlli,
mmctx->gb.tlli_new);
}
@@ -1760,22 +1737,73 @@ rejected:
rc = gsm48_tx_gmm_ra_upd_rej(msg, reject_cause);
if (mmctx)
mm_ctx_cleanup_free(mmctx, "GPRS RA UPDATE REJ");
- else {
- if (llme)
- gprs_llgmm_unassign(llme);
+ else if (llme)
+ gprs_llgmm_unassign(llme);
+#ifdef BUILD_IU
+ else if (MSG_IU_UE_CTX(msg)) {
+ unsigned long X1001 = osmo_tdef_get(sgsn->cfg.T_defs, -1001, OSMO_TDEF_S, -1);
+ ranap_iu_tx_release_free(MSG_IU_UE_CTX(msg), NULL, (int) X1001);
}
+#endif
return rc;
}
-/* 3GPP TS 24.008 Section 9.4.20 Service request.
+/* 3GPP TS 24.008 § 9.4.16: Routing area update complete */
+static int gsm48_rx_gmm_ra_upd_compl(struct sgsn_mm_ctx *mmctx)
+{
+ struct sgsn_signal_data sig_data;
+ /* only in case SGSN offered new P-TMSI */
+ LOGMMCTXP(LOGL_INFO, mmctx, "-> ROUTING AREA UPDATE COMPLETE\n");
+ mmctx_timer_stop(mmctx, 3350);
+ mmctx->t3350_mode = GMM_T3350_MODE_NONE;
+ mmctx->p_tmsi_old = 0;
+ mmctx->pending_req = 0;
+ osmo_fsm_inst_dispatch(mmctx->gmm_fsm, E_GMM_COMMON_PROC_SUCCESS, NULL);
+ switch(mmctx->ran_type) {
+ case MM_CTX_T_UTRAN_Iu:
+ osmo_fsm_inst_dispatch(mmctx->iu.mm_state_fsm, E_PMM_RA_UPDATE, NULL);
+ break;
+ case MM_CTX_T_GERAN_Gb:
+ /* Unassign the old TLLI */
+ mmctx->gb.tlli = mmctx->gb.tlli_new;
+ gprs_llgmm_assign(mmctx->gb.llme, TLLI_UNASSIGNED,
+ mmctx->gb.tlli_new);
+ osmo_fsm_inst_dispatch(mmctx->gb.mm_state_fsm, E_MM_RA_UPDATE, NULL);
+ break;
+ }
+
+ memset(&sig_data, 0, sizeof(sig_data));
+ sig_data.mm = mmctx;
+ osmo_signal_dispatch(SS_SGSN, S_SGSN_UPDATE, &sig_data);
+
+ return 0;
+}
+
+/* 3GPP TS 24.008 § 9.4.8: P-TMSI reallocation complete */
+static int gsm48_rx_gmm_ptmsi_reall_compl(struct sgsn_mm_ctx *mmctx)
+{
+ LOGMMCTXP(LOGL_INFO, mmctx, "-> PTMSI REALLOCATION COMPLETE\n");
+ mmctx_timer_stop(mmctx, 3350);
+ mmctx->t3350_mode = GMM_T3350_MODE_NONE;
+ mmctx->p_tmsi_old = 0;
+ mmctx->pending_req = 0;
+ if (mmctx->ran_type == MM_CTX_T_GERAN_Gb) {
+ /* Unassign the old TLLI */
+ mmctx->gb.tlli = mmctx->gb.tlli_new;
+ //gprs_llgmm_assign(mmctx->gb.llme, TLLI_UNASSIGNED, mmctx->gb.tlli_new, GPRS_ALGO_GEA0, NULL);
+ }
+ return 0;
+}
+
+/* 3GPP TS 24.008 § 9.4.20 Service request.
* In Iu, a UE in PMM-IDLE mode can use GSM48_MT_GMM_SERVICE_REQ to switch back
* to PMM-CONNECTED mode. */
static int gsm48_rx_gmm_service_req(struct sgsn_mm_ctx *ctx, struct msgb *msg)
{
struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_gmmh(msg);
uint8_t *cur = gh->data, *mi;
- uint8_t ciph_seq_nr, service_type, mi_len, mi_type;
+ uint8_t service_type, mi_len, mi_type;
uint32_t tmsi;
struct tlv_parsed tp;
char mi_string[GSM48_MI_SIZE];
@@ -1785,13 +1813,13 @@ static int gsm48_rx_gmm_service_req(struct sgsn_mm_ctx *ctx, struct msgb *msg)
LOGMMCTXP(LOGL_INFO, ctx, "-> GMM SERVICE REQUEST ");
/* This message is only valid in Iu mode */
- if (!msg->dst) {
+ if (!MSG_IU_UE_CTX(msg)) {
LOGPC(DMM, LOGL_INFO, "Invalid if not in Iu mode\n");
return -1;
}
/* Skip Ciphering key sequence number 10.5.1.2 */
- ciph_seq_nr = *cur & 0x07;
+ /* uint8_t ciph_seq_nr = *cur & 0x07; */
/* Service type 10.5.5.20 */
service_type = (*cur++ >> 4) & 0x07;
@@ -1821,7 +1849,7 @@ static int gsm48_rx_gmm_service_req(struct sgsn_mm_ctx *ctx, struct msgb *msg)
ctx = sgsn_mm_ctx_by_imsi(mi_string);
if (!ctx) {
/* FIXME: We need to have a context for service request? */
- reject_cause = GMM_CAUSE_NET_FAIL;
+ reject_cause = GMM_CAUSE_IMPL_DETACHED;
goto rejected;
}
msgid2mmctx(ctx, msg);
@@ -1834,7 +1862,7 @@ static int gsm48_rx_gmm_service_req(struct sgsn_mm_ctx *ctx, struct msgb *msg)
ctx = sgsn_mm_ctx_by_ptmsi(tmsi);
if (!ctx) {
/* FIXME: We need to have a context for service request? */
- reject_cause = GMM_CAUSE_NET_FAIL;
+ reject_cause = GMM_CAUSE_IMPL_DETACHED;
goto rejected;
}
msgid2mmctx(ctx, msg);
@@ -1846,16 +1874,27 @@ static int gsm48_rx_gmm_service_req(struct sgsn_mm_ctx *ctx, struct msgb *msg)
goto rejected;
}
- ctx->gmm_state = GMM_COMMON_PROC_INIT;
+ osmo_fsm_inst_dispatch(ctx->gmm_fsm, E_GMM_COMMON_PROC_INIT_REQ, NULL);
ctx->iu.service.type = service_type;
- /* TODO: Handle those only in case of accept? */
/* Look at PDP Context Status IE and see if MS's view of
* activated/deactivated NSAPIs agrees with our view */
if (TLVP_PRESENT(&tp, GSM48_IE_GMM_PDP_CTX_STATUS)) {
const uint8_t *pdp_status = TLVP_VAL(&tp, GSM48_IE_GMM_PDP_CTX_STATUS);
+ const size_t pdp_status_len = TLVP_LEN(&tp, GSM48_IE_GMM_PDP_CTX_STATUS);
+
process_ms_ctx_status(ctx, pdp_status);
+
+ /* 3GPP TS 24.008 § 4.7.13.4 Service request procedure not
+ * accepted by the network. Cause #40. If MS has PDP Contexts in
+ * Active state in pdp_status but there is no PDP contexts on
+ * SGSN side then Reject with the cause will force the mobile to
+ * reset PDP contexts */
+ if (llist_empty(&ctx->pdp_list) && pdp_status_has_active_nsapis(pdp_status, pdp_status_len)) {
+ reject_cause = GMM_CAUSE_NO_PDP_ACTIVATED;
+ goto rejected;
+ }
}
@@ -1888,15 +1927,13 @@ static int gsm48_rx_gmm_status(struct sgsn_mm_ctx *mmctx, struct msgb *msg)
return 0;
}
-/* GPRS Mobility Management */
-static int gsm0408_rcv_gmm(struct sgsn_mm_ctx *mmctx, struct msgb *msg,
+/* Rx GPRS Mobility Management. MMCTX can be NULL when called. On !Gb (Iu), llme is NULL */
+int gsm0408_rcv_gmm(struct sgsn_mm_ctx *mmctx, struct msgb *msg,
struct gprs_llc_llme *llme, bool drop_cipherable)
{
- struct sgsn_signal_data sig_data;
struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_gmmh(msg);
int rc;
- /* MMCTX can be NULL when called */
if (drop_cipherable && gsm48_hdr_gmm_cipherable(gh)) {
LOGMMCTXP(LOGL_NOTICE, mmctx, "Dropping cleartext GMM %s which "
"is expected to be encrypted for TLLI 0x%08x\n",
@@ -1908,7 +1945,7 @@ static int gsm0408_rcv_gmm(struct sgsn_mm_ctx *mmctx, struct msgb *msg,
if (llme && !mmctx &&
gh->msg_type != GSM48_MT_GMM_ATTACH_REQ &&
gh->msg_type != GSM48_MT_GMM_RA_UPD_REQ) {
- LOGP(DMM, LOGL_NOTICE, "Cannot handle GMM for unknown MM CTX\n");
+ LOGGBP(llme, DMM, LOGL_NOTICE, "Cannot handle GMM for unknown MM CTX\n");
/* 4.7.10 */
if (gh->msg_type == GSM48_MT_GMM_STATUS) {
/* TLLI unassignment */
@@ -1920,6 +1957,13 @@ static int gsm0408_rcv_gmm(struct sgsn_mm_ctx *mmctx, struct msgb *msg,
if (gh->msg_type == GSM48_MT_GMM_DETACH_ACK)
return gprs_llgmm_unassign(llme);
+ /* Don't reply to deatch requests, reason power off */
+ if (gh->msg_type == GSM48_MT_GMM_DETACH_REQ &&
+ gh->data[0] & 0x8) {
+ return 0;
+ }
+
+
gprs_llgmm_reset(llme);
/* Don't force it into re-attachment */
@@ -1940,6 +1984,23 @@ static int gsm0408_rcv_gmm(struct sgsn_mm_ctx *mmctx, struct msgb *msg,
return rc;
}
+ /* A RAT change is only expected/allowed for RAU/Attach Req */
+ if (mmctx && mmctx_did_rat_change(mmctx, msg)) {
+ switch (gh->msg_type) {
+ case GSM48_MT_GMM_RA_UPD_REQ:
+ case GSM48_MT_GMM_ATTACH_REQ:
+ break;
+ default:
+ /* This shouldn't happen with other message types and
+ * we need to error out to prevent a crash */
+ LOGMMCTXP(LOGL_NOTICE, mmctx, "Dropping GMM %s which was received on different "
+ "RAT (mmctx ran_type=%u, msg_iu_ue_ctx=%p\n",
+ get_value_string(gprs_msgt_gmm_names, gh->msg_type),
+ mmctx->ran_type, MSG_IU_UE_CTX(msg));
+ return -EINVAL;
+ }
+ }
+
/*
* For a few messages, mmctx may be NULL. For most, we want to ensure a
* non-NULL mmctx. At the same time, we want to keep the message
@@ -1985,66 +2046,17 @@ static int gsm0408_rcv_gmm(struct sgsn_mm_ctx *mmctx, struct msgb *msg,
case GSM48_MT_GMM_ATTACH_COMPL:
if (!mmctx)
goto null_mmctx;
- /* only in case SGSN offered new P-TMSI */
- LOGMMCTXP(LOGL_INFO, mmctx, "-> ATTACH COMPLETE\n");
- mmctx_timer_stop(mmctx, 3350);
- mmctx->t3350_mode = GMM_T3350_MODE_NONE;
- mmctx->p_tmsi_old = 0;
- mmctx->pending_req = 0;
- if (mmctx->ran_type == MM_CTX_T_GERAN_Gb) {
- /* Unassign the old TLLI */
- mmctx->gb.tlli = mmctx->gb.tlli_new;
- gprs_llme_copy_key(mmctx, mmctx->gb.llme);
- gprs_llgmm_assign(mmctx->gb.llme, 0xffffffff,
- mmctx->gb.tlli_new);
- }
- mmctx->gmm_state = GMM_REGISTERED_NORMAL;
- mmctx_set_pmm_state(mmctx, PMM_CONNECTED);
- mmctx_set_mm_state(mmctx, MM_READY);
- rc = 0;
-
- memset(&sig_data, 0, sizeof(sig_data));
- sig_data.mm = mmctx;
- osmo_signal_dispatch(SS_SGSN, S_SGSN_ATTACH, &sig_data);
+ rc = gsm48_rx_gmm_att_compl(mmctx);
break;
case GSM48_MT_GMM_RA_UPD_COMPL:
if (!mmctx)
goto null_mmctx;
- /* only in case SGSN offered new P-TMSI */
- LOGMMCTXP(LOGL_INFO, mmctx, "-> ROUTING AREA UPDATE COMPLETE\n");
- mmctx_timer_stop(mmctx, 3350);
- mmctx->t3350_mode = GMM_T3350_MODE_NONE;
- mmctx->p_tmsi_old = 0;
- mmctx->pending_req = 0;
- if (mmctx->ran_type == MM_CTX_T_GERAN_Gb) {
- /* Unassign the old TLLI */
- mmctx->gb.tlli = mmctx->gb.tlli_new;
- gprs_llgmm_assign(mmctx->gb.llme, 0xffffffff,
- mmctx->gb.tlli_new);
- }
- mmctx->gmm_state = GMM_REGISTERED_NORMAL;
- mmctx_set_pmm_state(mmctx, PMM_CONNECTED);
- mmctx_set_mm_state(mmctx, MM_READY);
- rc = 0;
-
- memset(&sig_data, 0, sizeof(sig_data));
- sig_data.mm = mmctx;
- osmo_signal_dispatch(SS_SGSN, S_SGSN_UPDATE, &sig_data);
+ rc = gsm48_rx_gmm_ra_upd_compl(mmctx);
break;
case GSM48_MT_GMM_PTMSI_REALL_COMPL:
if (!mmctx)
goto null_mmctx;
- LOGMMCTXP(LOGL_INFO, mmctx, "-> PTMSI REALLLICATION COMPLETE\n");
- mmctx_timer_stop(mmctx, 3350);
- mmctx->t3350_mode = GMM_T3350_MODE_NONE;
- mmctx->p_tmsi_old = 0;
- mmctx->pending_req = 0;
- if (mmctx->ran_type == MM_CTX_T_GERAN_Gb) {
- /* Unassign the old TLLI */
- mmctx->gb.tlli = mmctx->gb.tlli_new;
- //gprs_llgmm_assign(mmctx->gb.llme, 0xffffffff, mmctx->gb.tlli_new, GPRS_ALGO_GEA0, NULL);
- }
- rc = 0;
+ rc = gsm48_rx_gmm_ptmsi_reall_compl(mmctx);
break;
case GSM48_MT_GMM_AUTH_CIPH_RESP:
if (!mmctx)
@@ -2067,7 +2079,7 @@ static int gsm0408_rcv_gmm(struct sgsn_mm_ctx *mmctx, struct msgb *msg,
return rc;
null_mmctx:
- LOGP(DMM, LOGL_ERROR,
+ LOGGBIUP(llme, msg, LOGL_ERROR,
"Received GSM 04.08 message type 0x%02x,"
" but no MM context available\n",
gh->msg_type);
@@ -2078,6 +2090,8 @@ static void mmctx_timer_cb(void *_mm)
{
struct sgsn_mm_ctx *mm = _mm;
struct gsm_auth_tuple *at;
+ int rc;
+ unsigned long seconds;
mm->num_T_exp++;
@@ -2105,7 +2119,8 @@ static void mmctx_timer_cb(void *_mm)
"T3350 mode wasn't set, ignoring timeout\n");
break;
}
- osmo_timer_schedule(&mm->timer, sgsn->cfg.timers.T3350, 0);
+ seconds = osmo_tdef_get(sgsn->cfg.T_defs, 3350, OSMO_TDEF_S, -1);
+ osmo_timer_schedule(&mm->timer, seconds, 0);
break;
case 3360: /* waiting for AUTH AND CIPH RESP */
if (mm->num_T_exp >= 5) {
@@ -2122,8 +2137,13 @@ static void mmctx_timer_cb(void *_mm)
}
at = &mm->auth_triplet;
- gsm48_tx_gmm_auth_ciph_req(mm, &at->vec, at->key_seq, false);
- osmo_timer_schedule(&mm->timer, sgsn->cfg.timers.T3360, 0);
+ rc = gsm48_tx_gmm_auth_ciph_req(mm, &at->vec, at->key_seq, false);
+ if (rc < 0) {
+ LOGMMCTXP(LOGL_ERROR, mm, "failed sending Auth. & Ciph. Request: %s \n", strerror(-rc));
+ } else {
+ seconds = osmo_tdef_get(sgsn->cfg.T_defs, 3360, OSMO_TDEF_S, -1);
+ osmo_timer_schedule(&mm->timer, seconds, 0);
+ }
break;
case 3370: /* waiting for IDENTITY RESPONSE */
if (mm->num_T_exp >= 5) {
@@ -2134,7 +2154,8 @@ static void mmctx_timer_cb(void *_mm)
}
/* re-tranmit IDENTITY REQUEST and re-start timer */
gsm48_tx_gmm_id_req(mm, mm->t3370_id_type);
- osmo_timer_schedule(&mm->timer, sgsn->cfg.timers.T3370, 0);
+ seconds = osmo_tdef_get(sgsn->cfg.T_defs, 3370, OSMO_TDEF_S, -1);
+ osmo_timer_schedule(&mm->timer, seconds, 0);
break;
default:
LOGMMCTXP(LOGL_ERROR, mm, "timer expired in unknown mode %u\n",
@@ -2142,612 +2163,6 @@ static void mmctx_timer_cb(void *_mm)
}
}
-/* GPRS SESSION MANAGEMENT */
-
-static void pdpctx_timer_cb(void *_mm);
-
-static void pdpctx_timer_start(struct sgsn_pdp_ctx *pdp, unsigned int T,
- unsigned int seconds)
-{
- if (osmo_timer_pending(&pdp->timer))
- LOGPDPCTXP(LOGL_ERROR, pdp, "Starting PDP timer %u while old "
- "timer %u pending\n", T, pdp->T);
- pdp->T = T;
- pdp->num_T_exp = 0;
-
- /* FIXME: we should do this only once ? */
- osmo_timer_setup(&pdp->timer, pdpctx_timer_cb, pdp);
- osmo_timer_schedule(&pdp->timer, seconds, 0);
-}
-
-static void pdpctx_timer_stop(struct sgsn_pdp_ctx *pdp, unsigned int T)
-{
- if (pdp->T != T)
- LOGPDPCTXP(LOGL_ERROR, pdp, "Stopping PDP timer %u but "
- "%u is running\n", T, pdp->T);
- osmo_timer_del(&pdp->timer);
-}
-
-#if 0
-static void msgb_put_pdp_addr_ipv4(struct msgb *msg, uint32_t ipaddr)
-{
- uint8_t v[6];
-
- v[0] = PDP_TYPE_ORG_IETF;
- v[1] = PDP_TYPE_N_IETF_IPv4;
- *(uint32_t *)(v+2) = htonl(ipaddr);
-
- msgb_tlv_put(msg, GSM48_IE_GSM_PDP_ADDR, sizeof(v), v);
-}
-
-static void msgb_put_pdp_addr_ppp(struct msgb *msg)
-{
- uint8_t v[2];
-
- v[0] = PDP_TYPE_ORG_ETSI;
- v[1] = PDP_TYPE_N_ETSI_PPP;
-
- msgb_tlv_put(msg, GSM48_IE_GSM_PDP_ADDR, sizeof(v), v);
-}
-#endif
-
-/* Section 9.5.2: Activate PDP Context Accept */
-int gsm48_tx_gsm_act_pdp_acc(struct sgsn_pdp_ctx *pdp)
-{
- struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 PDP ACC");
- struct gsm48_hdr *gh;
- uint8_t transaction_id = pdp->ti ^ 0x8; /* flip */
-
- LOGPDPCTXP(LOGL_INFO, pdp, "<- ACTIVATE PDP CONTEXT ACK\n");
- rate_ctr_inc(&sgsn->rate_ctrs->ctr[CTR_PDP_ACTIVATE_ACCEPT]);
-
- mmctx2msgid(msg, pdp->mm);
-
- gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
- gh->proto_discr = GSM48_PDISC_SM_GPRS | (transaction_id << 4);
- gh->msg_type = GSM48_MT_GSM_ACT_PDP_ACK;
-
- /* Negotiated LLC SAPI */
- msgb_v_put(msg, pdp->sapi);
-
- /* FIXME: copy QoS parameters from original request */
- //msgb_lv_put(msg, pdp->lib->qos_neg.l, pdp->lib->qos_neg.v);
- msgb_lv_put(msg, sizeof(default_qos), (uint8_t *)&default_qos);
-
- /* Radio priority 10.5.7.2 */
- msgb_v_put(msg, pdp->lib->radio_pri);
-
- /* PDP address */
- /* Highest 4 bits of first byte need to be set to 1, otherwise
- * the IE is identical with the 04.08 PDP Address IE */
- pdp->lib->eua.v[0] &= ~0xf0;
- msgb_tlv_put(msg, GSM48_IE_GSM_PDP_ADDR,
- pdp->lib->eua.l, pdp->lib->eua.v);
- pdp->lib->eua.v[0] |= 0xf0;
-
- /* Optional: Protocol configuration options (FIXME: why 'req') */
- if (pdp->lib->pco_req.l)
- msgb_tlv_put(msg, GSM48_IE_GSM_PROTO_CONF_OPT,
- pdp->lib->pco_req.l, pdp->lib->pco_req.v);
-
- /* Optional: Packet Flow Identifier */
-
- return gsm48_gmm_sendmsg(msg, 0, pdp->mm, true);
-}
-
-/* Section 9.5.3: Activate PDP Context reject */
-int gsm48_tx_gsm_act_pdp_rej(struct sgsn_mm_ctx *mm, uint8_t tid,
- uint8_t cause, uint8_t pco_len, uint8_t *pco_v)
-{
- struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 PDP REJ");
- struct gsm48_hdr *gh;
- uint8_t transaction_id = tid ^ 0x8; /* flip */
-
- LOGMMCTXP(LOGL_NOTICE, mm, "<- ACTIVATE PDP CONTEXT REJ(cause=%u)\n", cause);
- rate_ctr_inc(&sgsn->rate_ctrs->ctr[CTR_PDP_ACTIVATE_REJECT]);
-
- mmctx2msgid(msg, mm);
-
- gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
- gh->proto_discr = GSM48_PDISC_SM_GPRS | (transaction_id << 4);
- gh->msg_type = GSM48_MT_GSM_ACT_PDP_REJ;
-
- msgb_v_put(msg, cause);
- if (pco_len && pco_v)
- msgb_tlv_put(msg, GSM48_IE_GSM_PROTO_CONF_OPT, pco_len, pco_v);
-
- return gsm48_gmm_sendmsg(msg, 0, mm, true);
-}
-
-/* Section 9.5.8: Deactivate PDP Context Request */
-static int _gsm48_tx_gsm_deact_pdp_req(struct sgsn_mm_ctx *mm, uint8_t tid,
- uint8_t sm_cause)
-{
- struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 PDP DET REQ");
- struct gsm48_hdr *gh;
- uint8_t transaction_id = tid ^ 0x8; /* flip */
-
- LOGMMCTXP(LOGL_INFO, mm, "<- DEACTIVATE PDP CONTEXT REQ\n");
- rate_ctr_inc(&sgsn->rate_ctrs->ctr[CTR_PDP_DL_DEACTIVATE_REQUEST]);
-
- mmctx2msgid(msg, mm);
-
- gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
- gh->proto_discr = GSM48_PDISC_SM_GPRS | (transaction_id << 4);
- gh->msg_type = GSM48_MT_GSM_DEACT_PDP_REQ;
-
- msgb_v_put(msg, sm_cause);
-
- return gsm48_gmm_sendmsg(msg, 0, mm, true);
-}
-int gsm48_tx_gsm_deact_pdp_req(struct sgsn_pdp_ctx *pdp, uint8_t sm_cause)
-{
- pdpctx_timer_start(pdp, 3395, sgsn->cfg.timers.T3395);
-
- return _gsm48_tx_gsm_deact_pdp_req(pdp->mm, pdp->ti, sm_cause);
-}
-
-/* Section 9.5.9: Deactivate PDP Context Accept */
-static int _gsm48_tx_gsm_deact_pdp_acc(struct sgsn_mm_ctx *mm, uint8_t tid)
-{
- struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 PDP DET ACC");
- struct gsm48_hdr *gh;
- uint8_t transaction_id = tid ^ 0x8; /* flip */
-
- LOGMMCTXP(LOGL_INFO, mm, "<- DEACTIVATE PDP CONTEXT ACK\n");
- rate_ctr_inc(&sgsn->rate_ctrs->ctr[CTR_PDP_DL_DEACTIVATE_ACCEPT]);
-
- mmctx2msgid(msg, mm);
-
- gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
- gh->proto_discr = GSM48_PDISC_SM_GPRS | (transaction_id << 4);
- gh->msg_type = GSM48_MT_GSM_DEACT_PDP_ACK;
-
- return gsm48_gmm_sendmsg(msg, 0, mm, true);
-}
-int gsm48_tx_gsm_deact_pdp_acc(struct sgsn_pdp_ctx *pdp)
-{
- return _gsm48_tx_gsm_deact_pdp_acc(pdp->mm, pdp->ti);
-}
-
-static int activate_ggsn(struct sgsn_mm_ctx *mmctx,
- struct sgsn_ggsn_ctx *ggsn, const uint8_t transaction_id,
- const uint8_t req_nsapi, const uint8_t req_llc_sapi,
- struct tlv_parsed *tp, int destroy_ggsn)
-{
- struct sgsn_pdp_ctx *pdp;
-
- LOGMMCTXP(LOGL_DEBUG, mmctx, "Using GGSN %u\n", ggsn->id);
- ggsn->gsn = sgsn->gsn;
- pdp = sgsn_create_pdp_ctx(ggsn, mmctx, req_nsapi, tp);
- if (!pdp)
- return -1;
-
- /* Store SAPI and Transaction Identifier */
- pdp->sapi = req_llc_sapi;
- pdp->ti = transaction_id;
- pdp->destroy_ggsn = destroy_ggsn;
-
- return 0;
-}
-
-static void ggsn_lookup_cb(void *arg, int status, int timeouts, struct hostent *hostent)
-{
- struct sgsn_ggsn_ctx *ggsn;
- struct sgsn_ggsn_lookup *lookup = arg;
- struct in_addr *addr = NULL;
-
- /* The context is gone while we made a request */
- if (!lookup->mmctx) {
- talloc_free(lookup->orig_msg);
- talloc_free(lookup);
- return;
- }
-
- if (status != ARES_SUCCESS) {
- struct sgsn_mm_ctx *mmctx = lookup->mmctx;
-
- LOGMMCTXP(LOGL_ERROR, mmctx, "DNS query failed.\n");
-
- /* Need to try with three digits now */
- if (lookup->state == SGSN_GGSN_2DIGIT) {
- char *hostname;
- int rc;
-
- lookup->state = SGSN_GGSN_3DIGIT;
- hostname = osmo_apn_qualify_from_imsi(mmctx->imsi,
- lookup->apn_str, 1);
- LOGMMCTXP(LOGL_DEBUG, mmctx,
- "Going to query %s\n", hostname);
- rc = sgsn_ares_query(sgsn, hostname,
- ggsn_lookup_cb, lookup);
- if (rc != 0) {
- LOGMMCTXP(LOGL_ERROR, mmctx, "Couldn't start GGSN\n");
- goto reject_due_failure;
- }
- return;
- }
-
- LOGMMCTXP(LOGL_ERROR, mmctx, "Couldn't resolve GGSN\n");
- goto reject_due_failure;
- }
-
- if (hostent->h_length != sizeof(struct in_addr)) {
- LOGMMCTXP(LOGL_ERROR, lookup->mmctx,
- "Wrong addr size(%zu)\n", sizeof(struct in_addr));
- goto reject_due_failure;
- }
-
- /* Get the first addr from the list */
- addr = (struct in_addr *) hostent->h_addr_list[0];
- if (!addr) {
- LOGMMCTXP(LOGL_ERROR, lookup->mmctx, "No host address.\n");
- goto reject_due_failure;
- }
-
- ggsn = sgsn_ggsn_ctx_alloc(UINT32_MAX);
- if (!ggsn) {
- LOGMMCTXP(LOGL_ERROR, lookup->mmctx, "Failed to create ggsn.\n");
- goto reject_due_failure;
- }
- ggsn->remote_addr = *addr;
- LOGMMCTXP(LOGL_NOTICE, lookup->mmctx,
- "Selected %s as GGSN.\n", inet_ntoa(*addr));
-
- /* forget about the ggsn look-up */
- lookup->mmctx->ggsn_lookup = NULL;
-
- activate_ggsn(lookup->mmctx, ggsn, lookup->ti, lookup->nsapi,
- lookup->sapi, &lookup->tp, 1);
-
- /* Now free it */
- talloc_free(lookup->orig_msg);
- talloc_free(lookup);
- return;
-
-reject_due_failure:
- gsm48_tx_gsm_act_pdp_rej(lookup->mmctx, lookup->ti,
- GMM_CAUSE_NET_FAIL, 0, NULL);
- lookup->mmctx->ggsn_lookup = NULL;
- talloc_free(lookup->orig_msg);
- talloc_free(lookup);
-}
-
-static int do_act_pdp_req(struct sgsn_mm_ctx *mmctx, struct msgb *msg, bool *delete)
-{
- struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_gmmh(msg);
- struct gsm48_act_pdp_ctx_req *act_req = (struct gsm48_act_pdp_ctx_req *) gh->data;
- uint8_t req_qos_len, req_pdpa_len;
- uint8_t *req_qos, *req_pdpa;
- struct tlv_parsed tp;
- uint8_t transaction_id = gsm48_hdr_trans_id(gh);
- struct sgsn_ggsn_ctx *ggsn;
- struct sgsn_pdp_ctx *pdp;
- enum gsm48_gsm_cause gsm_cause;
- char apn_str[GSM_APN_LENGTH] = { 0, };
- char *hostname;
- int rc;
- struct gprs_llc_lle *lle;
-
- LOGMMCTXP(LOGL_INFO, mmctx, "-> ACTIVATE PDP CONTEXT REQ: SAPI=%u NSAPI=%u ",
- act_req->req_llc_sapi, act_req->req_nsapi);
-
- /* FIXME: length checks! */
- req_qos_len = act_req->data[0];
- req_qos = act_req->data + 1; /* 10.5.6.5 */
- req_pdpa_len = act_req->data[1 + req_qos_len];
- req_pdpa = act_req->data + 1 + req_qos_len + 1; /* 10.5.6.4 */
-
- switch (req_pdpa[0] & 0xf) {
- case 0x0:
- DEBUGPC(DMM, "ETSI ");
- break;
- case 0x1:
- DEBUGPC(DMM, "IETF ");
- break;
- case 0xf:
- DEBUGPC(DMM, "Empty ");
- break;
- }
-
- switch (req_pdpa[1]) {
- case 0x21:
- DEBUGPC(DMM, "IPv4 ");
- if (req_pdpa_len >= 6) {
- struct in_addr ia;
- ia.s_addr = ntohl(*((uint32_t *) (req_pdpa+2)));
- DEBUGPC(DMM, "%s ", inet_ntoa(ia));
- }
- break;
- case 0x57:
- DEBUGPC(DMM, "IPv6 ");
- if (req_pdpa_len >= 18) {
- /* FIXME: print IPv6 address */
- }
- break;
- default:
- DEBUGPC(DMM, "0x%02x ", req_pdpa[1]);
- break;
- }
-
- LOGPC(DMM, LOGL_INFO, "\n");
-
- /* Check if NSAPI is out of range (TS 04.65 / 7.2) */
- if (act_req->req_nsapi < 5 || act_req->req_nsapi > 15) {
- /* Send reject with GSM_CAUSE_INV_MAND_INFO */
- return gsm48_tx_gsm_act_pdp_rej(mmctx, transaction_id,
- GSM_CAUSE_INV_MAND_INFO,
- 0, NULL);
- }
-
- /* Optional: Access Point Name, Protocol Config Options */
- if (req_pdpa + req_pdpa_len < msg->data + msg->len)
- tlv_parse(&tp, &gsm48_sm_att_tlvdef, req_pdpa + req_pdpa_len,
- (msg->data + msg->len) - (req_pdpa + req_pdpa_len), 0, 0);
- else
- memset(&tp, 0, sizeof(tp));
-
-
- /* put the non-TLV elements in the TLV parser structure to
- * pass them on to the SGSN / GTP code */
- tp.lv[OSMO_IE_GSM_REQ_QOS].len = req_qos_len;
- tp.lv[OSMO_IE_GSM_REQ_QOS].val = req_qos;
- tp.lv[OSMO_IE_GSM_REQ_PDP_ADDR].len = req_pdpa_len;
- tp.lv[OSMO_IE_GSM_REQ_PDP_ADDR].val = req_pdpa;
-
- /* Check if NSAPI is already in use */
- pdp = sgsn_pdp_ctx_by_nsapi(mmctx, act_req->req_nsapi);
- if (pdp) {
- /* We already have a PDP context for this TLLI + NSAPI tuple */
- if (pdp->sapi == act_req->req_llc_sapi &&
- pdp->ti == transaction_id) {
- /* This apparently is a re-transmission of a PDP CTX
- * ACT REQ (our ACT ACK must have got dropped) */
- rc = gsm48_tx_gsm_act_pdp_acc(pdp);
- if (rc < 0)
- return rc;
-
- if (pdp->mm->ran_type == MM_CTX_T_GERAN_Gb) {
- /* Also re-transmit the SNDCP XID message */
- lle = &pdp->mm->gb.llme->lle[pdp->sapi];
- rc = sndcp_sn_xid_req(lle,pdp->nsapi);
- if (rc < 0)
- return rc;
- }
-
- return 0;
- }
-
- /* Send reject with GSM_CAUSE_NSAPI_IN_USE */
- return gsm48_tx_gsm_act_pdp_rej(mmctx, transaction_id,
- GSM_CAUSE_NSAPI_IN_USE,
- 0, NULL);
- }
-
- if (mmctx->ggsn_lookup) {
- if (mmctx->ggsn_lookup->sapi == act_req->req_llc_sapi &&
- mmctx->ggsn_lookup->ti == transaction_id) {
- LOGMMCTXP(LOGL_NOTICE, mmctx,
- "Re-transmission while doing look-up. Ignoring.\n");
- return 0;
- }
- }
-
- /* Only increment counter for a real activation, after we checked
- * for re-transmissions */
- rate_ctr_inc(&mmctx->ctrg->ctr[GMM_CTR_PDP_CTX_ACT]);
-
- /* Determine GGSN based on APN and subscription options */
- ggsn = sgsn_mm_ctx_find_ggsn_ctx(mmctx, &tp, &gsm_cause, apn_str);
- if (ggsn)
- return activate_ggsn(mmctx, ggsn, transaction_id,
- act_req->req_nsapi, act_req->req_llc_sapi,
- &tp, 0);
-
- if (strlen(apn_str) == 0)
- goto no_context;
- if (!sgsn->cfg.dynamic_lookup)
- goto no_context;
-
- /* schedule a dynamic look-up */
- mmctx->ggsn_lookup = talloc_zero(tall_bsc_ctx, struct sgsn_ggsn_lookup);
- if (!mmctx->ggsn_lookup)
- goto no_context;
-
- mmctx->ggsn_lookup->state = SGSN_GGSN_2DIGIT;
- mmctx->ggsn_lookup->mmctx = mmctx;
- strcpy(mmctx->ggsn_lookup->apn_str, apn_str);
-
- mmctx->ggsn_lookup->orig_msg = msg;
- mmctx->ggsn_lookup->tp = tp;
-
- mmctx->ggsn_lookup->ti = transaction_id;
- mmctx->ggsn_lookup->nsapi = act_req->req_nsapi;
- mmctx->ggsn_lookup->sapi = act_req->req_llc_sapi;
-
- hostname = osmo_apn_qualify_from_imsi(mmctx->imsi,
- mmctx->ggsn_lookup->apn_str, 0);
-
- LOGMMCTXP(LOGL_DEBUG, mmctx, "Going to query %s\n", hostname);
- rc = sgsn_ares_query(sgsn, hostname,
- ggsn_lookup_cb, mmctx->ggsn_lookup);
- if (rc != 0) {
- LOGMMCTXP(LOGL_ERROR, mmctx, "Failed to start ares query.\n");
- goto no_context;
- }
- *delete = 0;
-
- return 0;
-
-no_context:
- LOGMMCTXP(LOGL_ERROR, mmctx, "No GGSN context found!\n");
- return gsm48_tx_gsm_act_pdp_rej(mmctx, transaction_id,
- gsm_cause, 0, NULL);
-}
-
-/* Section 9.5.1: Activate PDP Context Request */
-static int gsm48_rx_gsm_act_pdp_req(struct sgsn_mm_ctx *mmctx,
- struct msgb *_msg)
-{
- bool delete = 1;
- struct msgb *msg;
- int rc;
-
- rate_ctr_inc(&sgsn->rate_ctrs->ctr[CTR_PDP_ACTIVATE_REQUEST]);
-
- /*
- * This is painful. We might not have a static GGSN
- * configuration and then would need to copy the msg
- * and re-do most of this routine (or call it again
- * and make sure it only goes through the dynamic
- * resolving. The question is what to optimize for
- * and the dynamic resolution will be the right thing
- * in the long run.
- */
- msg = gprs_msgb_copy(_msg, __func__);
- if (!msg) {
- struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_gmmh(_msg);
- uint8_t transaction_id = gsm48_hdr_trans_id(gh);
-
- LOGMMCTXP(LOGL_ERROR, mmctx, "-> ACTIVATE PDP CONTEXT REQ failed copy.\n");
- /* Send reject with GSM_CAUSE_INV_MAND_INFO */
- return gsm48_tx_gsm_act_pdp_rej(mmctx, transaction_id,
- GSM_CAUSE_NET_FAIL,
- 0, NULL);
- }
-
- rc = do_act_pdp_req(mmctx, msg, &delete);
- if (delete)
- msgb_free(msg);
- return rc;
-}
-
-/* Section 9.5.8: Deactivate PDP Context Request */
-static int gsm48_rx_gsm_deact_pdp_req(struct sgsn_mm_ctx *mm, struct msgb *msg)
-{
- struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_gmmh(msg);
- uint8_t transaction_id = gsm48_hdr_trans_id(gh);
- struct sgsn_pdp_ctx *pdp;
-
- LOGMMCTXP(LOGL_INFO, mm, "-> DEACTIVATE PDP CONTEXT REQ (cause: %s)\n",
- get_value_string(gsm48_gsm_cause_names, gh->data[0]));
- rate_ctr_inc(&sgsn->rate_ctrs->ctr[CTR_PDP_UL_DEACTIVATE_REQUEST]);
-
- pdp = sgsn_pdp_ctx_by_tid(mm, transaction_id);
- if (!pdp) {
- LOGMMCTXP(LOGL_NOTICE, mm, "Deactivate PDP Context Request for "
- "non-existing PDP Context (IMSI=%s, TI=%u)\n",
- mm->imsi, transaction_id);
- return _gsm48_tx_gsm_deact_pdp_acc(mm, transaction_id);
- }
-
- return sgsn_delete_pdp_ctx(pdp);
-}
-
-/* Section 9.5.9: Deactivate PDP Context Accept */
-static int gsm48_rx_gsm_deact_pdp_ack(struct sgsn_mm_ctx *mm, struct msgb *msg)
-{
- struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_gmmh(msg);
- uint8_t transaction_id = gsm48_hdr_trans_id(gh);
- struct sgsn_pdp_ctx *pdp;
-
- LOGMMCTXP(LOGL_INFO, mm, "-> DEACTIVATE PDP CONTEXT ACK\n");
- rate_ctr_inc(&sgsn->rate_ctrs->ctr[CTR_PDP_UL_DEACTIVATE_ACCEPT]);
-
- pdp = sgsn_pdp_ctx_by_tid(mm, transaction_id);
- if (!pdp) {
- LOGMMCTXP(LOGL_NOTICE, mm, "Deactivate PDP Context Accept for "
- "non-existing PDP Context (IMSI=%s, TI=%u)\n",
- mm->imsi, transaction_id);
- return 0;
- }
- /* stop timer 3395 */
- pdpctx_timer_stop(pdp, 3395);
- return sgsn_delete_pdp_ctx(pdp);
-}
-
-static int gsm48_rx_gsm_status(struct sgsn_mm_ctx *ctx, struct msgb *msg)
-{
- struct gsm48_hdr *gh = msgb_l3(msg);
-
- LOGMMCTXP(LOGL_INFO, ctx, "-> GPRS SM STATUS (cause: %s)\n",
- get_value_string(gsm48_gsm_cause_names, gh->data[0]));
-
- return 0;
-}
-
-static void pdpctx_timer_cb(void *_pdp)
-{
- struct sgsn_pdp_ctx *pdp = _pdp;
-
- pdp->num_T_exp++;
-
- switch (pdp->T) {
- case 3395: /* waiting for PDP CTX DEACT ACK */
- if (pdp->num_T_exp >= 4) {
- LOGPDPCTXP(LOGL_NOTICE, pdp, "T3395 expired >= 5 times\n");
- pdp->state = PDP_STATE_INACTIVE;
- sgsn_delete_pdp_ctx(pdp);
- break;
- }
- gsm48_tx_gsm_deact_pdp_req(pdp, GSM_CAUSE_NET_FAIL);
- break;
- default:
- LOGPDPCTXP(LOGL_ERROR, pdp, "timer expired in unknown mode %u\n",
- pdp->T);
- }
-}
-
-
-/* GPRS Session Management */
-static int gsm0408_rcv_gsm(struct sgsn_mm_ctx *mmctx, struct msgb *msg,
- struct gprs_llc_llme *llme)
-{
- struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_gmmh(msg);
- int rc;
-
- /* MMCTX can be NULL when called */
-
- if (!mmctx) {
- LOGP(DMM, LOGL_NOTICE, "Cannot handle SM for unknown MM CTX\n");
- /* 6.1.3.6 */
- if (gh->msg_type == GSM48_MT_GSM_STATUS)
- return 0;
-
- return gsm0408_gprs_force_reattach_oldmsg(msg, llme);
- }
-
- switch (gh->msg_type) {
- case GSM48_MT_GSM_ACT_PDP_REQ:
- rc = gsm48_rx_gsm_act_pdp_req(mmctx, msg);
- break;
- case GSM48_MT_GSM_DEACT_PDP_REQ:
- rc = gsm48_rx_gsm_deact_pdp_req(mmctx, msg);
- break;
- case GSM48_MT_GSM_DEACT_PDP_ACK:
- rc = gsm48_rx_gsm_deact_pdp_ack(mmctx, msg);
- break;
- case GSM48_MT_GSM_STATUS:
- rc = gsm48_rx_gsm_status(mmctx, msg);
- break;
- case GSM48_MT_GSM_REQ_PDP_ACT_REJ:
- case GSM48_MT_GSM_ACT_AA_PDP_REQ:
- case GSM48_MT_GSM_DEACT_AA_PDP_REQ:
- LOGMMCTXP(LOGL_NOTICE, mmctx, "Unimplemented GSM 04.08 GSM msg type 0x%02x: %s\n",
- gh->msg_type, osmo_hexdump((uint8_t *)gh, msgb_l3len(msg)));
- rc = gsm48_tx_sm_status(mmctx, GSM_CAUSE_MSGT_NOTEXIST_NOTIMPL);
- break;
- default:
- LOGMMCTXP(LOGL_NOTICE, mmctx, "Unknown GSM 04.08 GSM msg type 0x%02x: %s\n",
- gh->msg_type, osmo_hexdump((uint8_t *)gh, msgb_l3len(msg)));
- rc = gsm48_tx_sm_status(mmctx, GSM_CAUSE_MSGT_NOTEXIST_NOTIMPL);
- break;
-
- }
-
- return rc;
-}
-
int gsm0408_gprs_force_reattach_oldmsg(struct msgb *msg,
struct gprs_llc_llme *llme)
{
@@ -2775,85 +2190,6 @@ int gsm0408_gprs_force_reattach(struct sgsn_mm_ctx *mmctx)
return rc;
}
-/* Main entry point for incoming 04.08 GPRS messages from Iu */
-int gsm0408_gprs_rcvmsg_iu(struct msgb *msg, struct gprs_ra_id *ra_id,
- uint16_t *sai)
-{
- struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_gmmh(msg);
- uint8_t pdisc = gsm48_hdr_pdisc(gh);
- struct sgsn_mm_ctx *mmctx;
- int rc = -EINVAL;
-
- mmctx = sgsn_mm_ctx_by_ue_ctx(msg->dst);
- if (mmctx) {
- rate_ctr_inc(&mmctx->ctrg->ctr[GMM_CTR_PKTS_SIG_IN]);
- if (ra_id)
- memcpy(&mmctx->ra, ra_id, sizeof(mmctx->ra));
- }
-
- /* MMCTX can be NULL */
-
- switch (pdisc) {
- case GSM48_PDISC_MM_GPRS:
- rc = gsm0408_rcv_gmm(mmctx, msg, NULL, false);
-#warning "set drop_cipherable arg for gsm0408_rcv_gmm() from IuPS?"
- break;
- case GSM48_PDISC_SM_GPRS:
- rc = gsm0408_rcv_gsm(mmctx, msg, NULL);
- break;
- default:
- LOGMMCTXP(LOGL_NOTICE, mmctx,
- "Unknown GSM 04.08 discriminator 0x%02x: %s\n",
- pdisc, osmo_hexdump((uint8_t *)gh, msgb_l3len(msg)));
- /* FIXME: return status message */
- break;
- }
-
- /* MMCTX can be invalid */
-
- return rc;
-}
-
-/* Main entry point for incoming 04.08 GPRS messages from Gb */
-int gsm0408_gprs_rcvmsg_gb(struct msgb *msg, struct gprs_llc_llme *llme,
- bool drop_cipherable)
-{
- struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_gmmh(msg);
- uint8_t pdisc = gsm48_hdr_pdisc(gh);
- struct sgsn_mm_ctx *mmctx;
- struct gprs_ra_id ra_id;
- int rc = -EINVAL;
-
- bssgp_parse_cell_id(&ra_id, msgb_bcid(msg));
- mmctx = sgsn_mm_ctx_by_tlli(msgb_tlli(msg), &ra_id);
- if (mmctx) {
- msgid2mmctx(mmctx, msg);
- rate_ctr_inc(&mmctx->ctrg->ctr[GMM_CTR_PKTS_SIG_IN]);
- mmctx->gb.llme = llme;
- }
-
- /* MMCTX can be NULL */
-
- switch (pdisc) {
- case GSM48_PDISC_MM_GPRS:
- rc = gsm0408_rcv_gmm(mmctx, msg, llme, drop_cipherable);
- break;
- case GSM48_PDISC_SM_GPRS:
- rc = gsm0408_rcv_gsm(mmctx, msg, llme);
- break;
- default:
- LOGMMCTXP(LOGL_NOTICE, mmctx,
- "Unknown GSM 04.08 discriminator 0x%02x: %s\n",
- pdisc, osmo_hexdump((uint8_t *)gh, msgb_l3len(msg)));
- /* FIXME: return status message */
- break;
- }
-
- /* MMCTX can be invalid */
-
- return rc;
-}
-
int gprs_gmm_rx_suspend(struct gprs_ra_id *raid, uint32_t tlli)
{
struct sgsn_mm_ctx *mmctx;
@@ -2865,15 +2201,14 @@ int gprs_gmm_rx_suspend(struct gprs_ra_id *raid, uint32_t tlli)
return -EINVAL;
}
- if (mmctx->gmm_state != GMM_REGISTERED_NORMAL &&
- mmctx->gmm_state != GMM_REGISTERED_SUSPENDED) {
+ if (!gmm_fsm_is_registered(mmctx->gmm_fsm)) {
LOGMMCTXP(LOGL_NOTICE, mmctx, "SUSPEND request while state "
"!= REGISTERED (TLLI=%08x)\n", tlli);
return -EINVAL;
}
/* Transition from REGISTERED_NORMAL to REGISTERED_SUSPENDED */
- mmctx->gmm_state = GMM_REGISTERED_SUSPENDED;
+ osmo_fsm_inst_dispatch(mmctx->gmm_fsm, E_GMM_SUSPEND, NULL);
return 0;
}
@@ -2891,8 +2226,7 @@ int gprs_gmm_rx_resume(struct gprs_ra_id *raid, uint32_t tlli,
return -EINVAL;
}
- if (mmctx->gmm_state != GMM_REGISTERED_NORMAL &&
- mmctx->gmm_state != GMM_REGISTERED_SUSPENDED) {
+ if (!gmm_fsm_is_registered(mmctx->gmm_fsm)) {
LOGMMCTXP(LOGL_NOTICE, mmctx, "RESUME request while state "
"!= SUSPENDED (TLLI=%08x)\n", tlli);
/* FIXME: should we not simply ignore it? */
@@ -2900,33 +2234,6 @@ int gprs_gmm_rx_resume(struct gprs_ra_id *raid, uint32_t tlli,
}
/* Transition from SUSPENDED to NORMAL */
- mmctx->gmm_state = GMM_REGISTERED_NORMAL;
+ osmo_fsm_inst_dispatch(mmctx->gmm_fsm, E_GMM_RESUME, NULL);
return 0;
}
-
-#ifdef BUILD_IU
-int iu_rab_act_ps(uint8_t rab_id, struct sgsn_pdp_ctx *pdp)
-{
- struct msgb *msg;
- struct sgsn_mm_ctx *mm = pdp->mm;
- struct ranap_ue_conn_ctx *uectx;
- uint32_t ggsn_ip;
- bool use_x213_nsap;
-
- uectx = mm->iu.ue_ctx;
- use_x213_nsap = (uectx->rab_assign_addr_enc == RANAP_NSAP_ADDR_ENC_X213);
-
- /* Get the IP address for ggsn user plane */
- memcpy(&ggsn_ip, pdp->lib->gsnru.v, pdp->lib->gsnru.l);
- ggsn_ip = htonl(ggsn_ip);
-
- LOGP(DRANAP, LOGL_DEBUG, "Assigning RAB: rab_id=%d, ggsn_ip=%x,"
- " teid_gn=%x, use_x213_nsap=%d\n",
- rab_id, ggsn_ip, pdp->lib->teid_gn, use_x213_nsap);
-
- msg = ranap_new_msg_rab_assign_data(rab_id, ggsn_ip,
- pdp->lib->teid_gn, use_x213_nsap);
- msg->l2h = msg->data;
- return ranap_iu_rab_act(uectx, msg);
-}
-#endif
diff --git a/src/sgsn/gprs_gmm_attach.c b/src/sgsn/gprs_gmm_attach.c
new file mode 100644
index 000000000..c903a016b
--- /dev/null
+++ b/src/sgsn/gprs_gmm_attach.c
@@ -0,0 +1,461 @@
+#include <osmocom/core/tdef.h>
+
+#include <osmocom/sgsn/gprs_gmm_attach.h>
+
+#include <osmocom/gsm/protocol/gsm_04_08_gprs.h>
+#include <osmocom/sgsn/debug.h>
+#include <osmocom/sgsn/gprs_gmm.h>
+#include <osmocom/sgsn/sgsn.h>
+
+#define X(s) (1 << (s))
+
+static int require_identity_imei = 1;
+static int require_auth = 1;
+
+static const struct osmo_tdef_state_timeout gmm_attach_fsm_timeouts[32] = {
+ [ST_IDENTIY] = { .T=3370 },
+ [ST_AUTH] = { .T=3360 },
+ [ST_ACCEPT] = { .T=3350 },
+ [ST_ASK_VLR] = { .T=3350 },
+ [ST_IU_SECURITY_CMD] = { .T=3350 },
+};
+
+#define gmm_attach_fsm_state_chg(fi, NEXT_STATE) \
+ osmo_tdef_fsm_inst_state_chg(fi, NEXT_STATE, gmm_attach_fsm_timeouts, sgsn->cfg.T_defs, -1)
+
+
+static void st_init(struct osmo_fsm_inst *fi, uint32_t event, void *data)
+{
+ struct sgsn_mm_ctx *ctx = fi->priv;
+ struct msgb *attach_req = data;
+
+ /* we can run st_init multiple times */
+ if (ctx->gmm_att_req.attach_req)
+ msgb_free(ctx->gmm_att_req.attach_req);
+
+ ctx->gmm_att_req.attach_req = msgb_copy(attach_req, "Attach Request");
+ ctx->auth_state = SGSN_AUTH_UNKNOWN;
+ ctx->gmm_att_req.auth_reattempt = 0;
+
+ /*
+ * TODO: remove pending_req as soon the sgsn_auth code doesn't depend
+ * on it.
+ * pending_req must be set, even this fsm doesn't use it, because
+ * the sgsn_auth code is using this too
+ */
+ ctx->pending_req = GSM48_MT_GMM_ATTACH_REQ;
+
+ if (require_identity_imei) {
+ ctx->gmm_att_req.id_type = GSM_MI_TYPE_IMEI;
+ gmm_attach_fsm_state_chg(fi, ST_IDENTIY);
+ } else if (!strlen(ctx->imsi)) {
+ ctx->gmm_att_req.id_type = GSM_MI_TYPE_IMSI;
+ gmm_attach_fsm_state_chg(fi, ST_IDENTIY);
+ } else if (require_auth)
+ gmm_attach_fsm_state_chg(fi, ST_AUTH);
+ else
+ gmm_attach_fsm_state_chg(fi, ST_ACCEPT);
+}
+
+static void st_identity_on_enter(struct osmo_fsm_inst *fi, uint32_t prev_state)
+{
+ struct sgsn_mm_ctx *ctx = fi->priv;
+ int ret = 0;
+
+ ctx->num_T_exp = 0;
+
+ switch (ctx->gmm_att_req.id_type) {
+ case GSM_MI_TYPE_IMEI:
+ case GSM_MI_TYPE_IMSI:
+ break;
+ default:
+ /* TODO logging */
+ osmo_fsm_inst_dispatch(fi, E_REJECT, NULL);
+ return;
+ }
+
+ ctx->t3370_id_type = ctx->gmm_att_req.id_type;
+ ret = gsm48_tx_gmm_id_req(ctx, ctx->gmm_att_req.id_type);
+ if (ret < 0) {
+ LOGPFSM(fi, "Can not send tx_gmm_id %d.\n", ret);
+ osmo_fsm_inst_dispatch(fi, E_REJECT, NULL);
+ }
+}
+
+static void st_identity(struct osmo_fsm_inst *fi, uint32_t event, void *data)
+{
+ struct sgsn_mm_ctx *ctx = fi->priv;
+
+ OSMO_ASSERT(event == E_IDEN_RESP_RECV);
+
+ /* check if we received a identity response */
+ long type = (long) data;
+ switch (type) {
+ case GSM_MI_TYPE_IMEI:
+ case GSM_MI_TYPE_IMSI:
+ break;
+ default:
+ LOGMMCTXP(LOGL_ERROR, ctx, "Unknown mi type: 0x%lx, rejecting MS.\n", type);
+ osmo_fsm_inst_dispatch(fi, E_REJECT, (void *) GMM_CAUSE_NET_FAIL);
+ return;
+ }
+
+ if (type != ctx->gmm_att_req.id_type) {
+ /* ignore wrong package */
+ /* TODO logging */
+ return;
+ }
+
+ if (type == GSM_MI_TYPE_IMEI && !strlen(ctx->imsi)) {
+ ctx->gmm_att_req.id_type = GSM_MI_TYPE_IMSI;
+ gmm_attach_fsm_state_chg(fi, ST_IDENTIY);
+ } else if (require_auth)
+ gmm_attach_fsm_state_chg(fi, ST_AUTH);
+ else
+ gmm_attach_fsm_state_chg(fi, ST_ACCEPT);
+}
+
+static void st_auth_on_enter(struct osmo_fsm_inst *fi, uint32_t prev_state)
+{
+ struct sgsn_mm_ctx *ctx = fi->priv;
+ enum sgsn_auth_state auth_state;
+
+ ctx->num_T_exp = 0;
+
+ /* TODO: remove this layer violation. Don't parse any auth_policy here
+ * The correct way would be to ask the SGSN is this mmctx has to be auth
+ * regardless of the state.
+ * Otherwise someone else could steal the TLLI and just use it without further
+ * auth.
+ */
+ if (sgsn->cfg.auth_policy != SGSN_AUTH_POLICY_REMOTE) {
+ /* we can "trust" sgsn_auth_state as long it's not remote */
+ auth_state = sgsn_auth_state(ctx);
+ } else {
+ auth_state = ctx->auth_state;
+ }
+
+ switch(auth_state) {
+ case SGSN_AUTH_UMTS_RESYNC: /* ask the vlr for a new vector to match the simcards seq */
+ case SGSN_AUTH_UNKNOWN: /* the SGSN doesn know this MS */
+ gmm_attach_fsm_state_chg(fi, ST_ASK_VLR);
+ break;
+ case SGSN_AUTH_REJECTED:
+ /* TODO: correct GMM cause */
+ osmo_fsm_inst_dispatch(fi, E_REJECT, (void *) GMM_CAUSE_GPRS_NOTALLOWED);
+ break;
+ case SGSN_AUTH_ACCEPTED:
+ gmm_attach_fsm_state_chg(fi, ST_ACCEPT);
+ break;
+ case SGSN_AUTH_AUTHENTICATE:
+ if (ctx->auth_triplet.key_seq == GSM_KEY_SEQ_INVAL) {
+ /* invalid key material */
+ gmm_attach_fsm_state_chg(fi, ST_ASK_VLR);
+ }
+
+ struct gsm_auth_tuple *at = &ctx->auth_triplet;
+ if (gsm48_tx_gmm_auth_ciph_req(ctx, &at->vec, at->key_seq,
+ false) < 0) {
+ /* network failure */
+ osmo_fsm_inst_dispatch(fi, E_REJECT, (void *) GMM_CAUSE_NET_FAIL);
+ }
+ ctx->gmm_att_req.auth_reattempt++;
+ break;
+ }
+}
+
+static void st_auth(struct osmo_fsm_inst *fi, uint32_t event, void *data)
+{
+ struct sgsn_mm_ctx *ctx = fi->priv;
+
+ switch (event) {
+ case E_AUTH_RESP_RECV_SUCCESS:
+ sgsn_auth_request(ctx);
+#ifdef BUILD_IU
+ if (ctx->ran_type == MM_CTX_T_UTRAN_Iu && !ctx->iu.ue_ctx->integrity_active)
+ gmm_attach_fsm_state_chg(fi, ST_IU_SECURITY_CMD);
+ else
+#endif /* BUILD_IU */
+ gmm_attach_fsm_state_chg(fi, ST_ACCEPT);
+ break;
+ case E_AUTH_RESP_RECV_RESYNC:
+ if (ctx->gmm_att_req.auth_reattempt <= 1)
+ gmm_attach_fsm_state_chg(fi, ST_ASK_VLR);
+ else
+ osmo_fsm_inst_dispatch(fi, E_REJECT, (void *) GMM_CAUSE_SYNC_FAIL);
+ break;
+ }
+}
+
+static void st_accept_on_enter(struct osmo_fsm_inst *fi, uint32_t prev_state)
+{
+ struct sgsn_mm_ctx *ctx = fi->priv;
+
+ ctx->num_T_exp = 0;
+
+ /* TODO: remove pending_req as soon the sgsn_auth code doesn't depend on it */
+ ctx->pending_req = 0;
+ gsm48_tx_gmm_att_ack(ctx);
+}
+
+static void st_accept(struct osmo_fsm_inst *fi, uint32_t event, void *data)
+{
+ struct sgsn_mm_ctx *ctx = fi->priv;
+
+ switch(event) {
+ case E_ATTACH_COMPLETE_RECV:
+ /* TODO: #ifdef ! PTMSI_ALLOC is not supported */
+ extract_subscr_msisdn(ctx);
+ extract_subscr_hlr(ctx);
+ osmo_fsm_inst_state_chg(fi, ST_INIT, 0, 0);
+ break;
+ case E_VLR_ANSWERED:
+ extract_subscr_msisdn(ctx);
+ extract_subscr_hlr(ctx);
+ LOGMMCTXP(LOGL_NOTICE, ctx,
+ "Unusual event: if MS got no data connection, check that it has APN configured.\n");
+ break;
+ }
+}
+
+static void st_reject(struct osmo_fsm_inst *fi, uint32_t event, void *data)
+{
+ struct sgsn_mm_ctx *ctx = fi->priv;
+ long reject_cause = (long) data;
+
+ if (reject_cause != GMM_DISCARD_MS_WITHOUT_REJECT)
+ gsm48_tx_gmm_att_rej(ctx, (uint8_t) reject_cause);
+
+ sgsn_mm_ctx_cleanup_free(ctx);
+}
+
+static void st_ask_vlr_on_enter(struct osmo_fsm_inst *fi, uint32_t prev_state)
+{
+ struct sgsn_mm_ctx *ctx = fi->priv;
+
+ /* FIXME: remove this layer violation.
+ * The VLR should send the message to the HLR and not the rx function
+ * gsm48_rx_gmm_auth_ciph_fail. Because gmm_auth_ciph_fail already send a
+ * message to the HLR, we don't send here a request. */
+ if (ctx->auth_state == SGSN_AUTH_UMTS_RESYNC)
+ return;
+
+ /* ask the auth layer for more data */
+ sgsn_auth_request(ctx);
+}
+
+static void st_ask_vlr(struct osmo_fsm_inst *fi, uint32_t event, void *data)
+{
+ switch(event) {
+ case E_VLR_ANSWERED:
+ gmm_attach_fsm_state_chg(fi, ST_AUTH);
+ break;
+ }
+}
+
+static void st_iu_security_cmd_on_enter(struct osmo_fsm_inst *fi, uint32_t prev_state)
+{
+#ifdef BUILD_IU
+ struct sgsn_mm_ctx *ctx = fi->priv;
+
+ /* TODO: shouldn't this set always? not only when the integrity_active? */
+ if (ctx->iu.ue_ctx->integrity_active) {
+ gmm_attach_fsm_state_chg(fi, ST_ACCEPT);
+ return;
+ }
+
+ ranap_iu_tx_sec_mode_cmd(ctx->iu.ue_ctx, &ctx->auth_triplet.vec, 0, ctx->iu.new_key);
+ ctx->iu.new_key = 0;
+#endif
+}
+
+static void st_iu_security_cmd(struct osmo_fsm_inst *fi, uint32_t event, void *data)
+{
+ switch(event) {
+ case E_IU_SECURITY_CMD_COMPLETE:
+ gmm_attach_fsm_state_chg(fi, ST_ACCEPT);
+ break;
+ }
+}
+
+static struct osmo_fsm_state gmm_attach_req_fsm_states[] = {
+ /* default state for non-DTX and DTX when SPEECH is in progress */
+ [ST_INIT] = {
+ .in_event_mask = X(E_ATTACH_REQ_RECV),
+ .out_state_mask = X(ST_INIT) | X(ST_IDENTIY) | X(ST_AUTH) | X(ST_ACCEPT),
+ .name = "Init",
+ .action = st_init,
+ },
+ [ST_ASK_VLR] = {
+ .in_event_mask = X(E_VLR_ANSWERED),
+ .out_state_mask = X(ST_INIT) | X(ST_AUTH) | X(ST_ACCEPT) | X(ST_REJECT),
+ .name = "AskVLR",
+ .onenter = st_ask_vlr_on_enter,
+ .action = st_ask_vlr,
+ },
+ [ST_IDENTIY] = {
+ .in_event_mask = X(E_IDEN_RESP_RECV),
+ .out_state_mask = X(ST_INIT) | X(ST_AUTH) | X(ST_ACCEPT) | X(ST_IDENTIY) | X(ST_REJECT),
+ .onenter = st_identity_on_enter,
+ .name = "CheckIdentity",
+ .action = st_identity,
+ },
+ [ST_AUTH] = {
+ .in_event_mask = X(E_AUTH_RESP_RECV_SUCCESS) | X(E_AUTH_RESP_RECV_RESYNC),
+ .out_state_mask = X(ST_INIT) | X(ST_AUTH) | X(ST_IU_SECURITY_CMD) | X(ST_ACCEPT) | X(ST_ASK_VLR) | X(ST_REJECT),
+ .name = "Authenticate",
+ .onenter = st_auth_on_enter,
+ .action = st_auth,
+ },
+ [ST_IU_SECURITY_CMD] = {
+ .in_event_mask = X(E_IU_SECURITY_CMD_COMPLETE),
+ .out_state_mask = X(ST_INIT) | X(ST_AUTH) | X(ST_ACCEPT) | X(ST_REJECT),
+ .name = "IuSecurityCommand",
+ .onenter = st_iu_security_cmd_on_enter,
+ .action = st_iu_security_cmd,
+ },
+ [ST_ACCEPT] = {
+ .in_event_mask = X(E_ATTACH_COMPLETE_RECV) | X(E_VLR_ANSWERED),
+ .out_state_mask = X(ST_INIT) | X(ST_REJECT),
+ .name = "WaitAttachComplete",
+ .onenter = st_accept_on_enter,
+ .action = st_accept,
+ },
+ [ST_REJECT] = {
+ .in_event_mask = X(E_REJECT),
+ .out_state_mask = X(ST_INIT),
+ .name = "Reject",
+ .action = st_reject,
+ },
+};
+
+const struct value_string gmm_attach_req_fsm_event_names[] = {
+ OSMO_VALUE_STRING(E_ATTACH_REQ_RECV),
+ OSMO_VALUE_STRING(E_IDEN_RESP_RECV),
+ OSMO_VALUE_STRING(E_AUTH_RESP_RECV_SUCCESS),
+ OSMO_VALUE_STRING(E_AUTH_RESP_RECV_RESYNC),
+ OSMO_VALUE_STRING(E_ATTACH_ACCEPTED),
+ OSMO_VALUE_STRING(E_ATTACH_ACCEPT_SENT),
+ OSMO_VALUE_STRING(E_ATTACH_COMPLETE_RECV),
+ OSMO_VALUE_STRING(E_IU_SECURITY_CMD_COMPLETE),
+ OSMO_VALUE_STRING(E_REJECT),
+ OSMO_VALUE_STRING(E_VLR_ANSWERED),
+ { 0, NULL }
+};
+
+void gmm_attach_allstate_action(struct osmo_fsm_inst *fi, uint32_t event, void *data) {
+ struct sgsn_mm_ctx *ctx = fi->priv;
+ struct msgb *new_attach_req = data;
+
+ switch (event) {
+ case E_ATTACH_REQ_RECV:
+ switch (fi->state) {
+ case ST_INIT:
+ case ST_REJECT:
+ st_init(fi, event, data);
+ break;
+
+ case ST_ACCEPT:
+ /* TODO: drop all state (e.g. PDP Ctx) and do this procedure */
+ osmo_fsm_inst_state_chg(fi, ST_INIT, 0, 0);
+ st_init(fi, event, data);
+ break;
+
+ case ST_ASK_VLR:
+ case ST_AUTH:
+ case ST_IDENTIY:
+ case ST_RETRIEVE_AUTH:
+ /* 04.08 4.7.3.1.6 d) Abnormal Case
+ * Only do action if Req IEs differs. */
+ if (ctx->gmm_att_req.attach_req &&
+ gprs_gmm_attach_req_ies(new_attach_req, ctx->gmm_att_req.attach_req)) {
+ osmo_fsm_inst_state_chg(fi, ST_INIT, 0, 0);
+ st_init(fi, event, data);
+ }
+ break;
+ }
+ break;
+ case E_REJECT:
+ if (fi->state != ST_REJECT)
+ osmo_fsm_inst_state_chg(fi, ST_REJECT, 0, 0);
+ st_reject(fi, event, data);
+ break;
+ }
+}
+
+int gmm_attach_timer_cb(struct osmo_fsm_inst *fi)
+{
+ struct sgsn_mm_ctx *ctx = fi->priv;
+ struct gsm_auth_tuple *at = &ctx->auth_triplet;
+ unsigned long t_secs;
+
+ ctx->num_T_exp++;
+
+ switch(fi->state) {
+ case ST_ASK_VLR:
+ /* TODO: replace T3350 by a better timer or it's own
+ * re-use T3350 - not defined by standard */
+ LOGMMCTXP(LOGL_ERROR, ctx, "HLR did not answer in time. Rejecting.\n");
+ osmo_fsm_inst_dispatch(fi, E_REJECT,
+ (void *) GMM_CAUSE_NET_FAIL);
+ break;
+ case ST_IDENTIY:
+ /* T3370 */
+ if (ctx->num_T_exp >= 5) {
+ osmo_fsm_inst_dispatch(fi, E_REJECT,
+ (void *) GMM_CAUSE_MS_ID_NOT_DERIVED);
+ break;
+ }
+ gsm48_tx_gmm_id_req(ctx, ctx->gmm_att_req.id_type);
+ t_secs = osmo_tdef_get(sgsn->cfg.T_defs, 3370, OSMO_TDEF_S, -1);
+ osmo_timer_schedule(&fi->timer, t_secs, 0);
+
+ break;
+ case ST_AUTH:
+ /* T3360 */
+ if (ctx->num_T_exp >= 5) {
+ osmo_fsm_inst_dispatch(fi, E_REJECT, (void *) GMM_DISCARD_MS_WITHOUT_REJECT);
+ break;
+ }
+ gsm48_tx_gmm_auth_ciph_req(ctx, &at->vec, at->key_seq, false);
+ t_secs = osmo_tdef_get(sgsn->cfg.T_defs, 3360, OSMO_TDEF_S, -1);
+ osmo_timer_schedule(&fi->timer, t_secs, 0);
+ break;
+ case ST_ACCEPT:
+ /* T3350 */
+ if (ctx->num_T_exp >= 5) {
+ osmo_fsm_inst_dispatch(fi, E_REJECT, (void *) GMM_DISCARD_MS_WITHOUT_REJECT);
+ break;
+ }
+ gsm48_tx_gmm_att_ack(ctx);
+ t_secs = osmo_tdef_get(sgsn->cfg.T_defs, 3350, OSMO_TDEF_S, -1);
+ osmo_timer_schedule(&fi->timer, t_secs, 0);
+ break;
+ }
+
+ return 0;
+}
+
+struct osmo_fsm gmm_attach_req_fsm = {
+ .name = "GMM_ATTACH_REQ_FSM",
+ .states = gmm_attach_req_fsm_states,
+ .num_states = ARRAY_SIZE(gmm_attach_req_fsm_states),
+ .event_names = gmm_attach_req_fsm_event_names,
+ .allstate_event_mask = X(E_REJECT) | X(E_ATTACH_REQ_RECV),
+ .allstate_action = gmm_attach_allstate_action,
+ .log_subsys = DMM,
+ .timer_cb = gmm_attach_timer_cb,
+};
+
+static __attribute__((constructor)) void gprs_gmm_fsm_init(void)
+{
+ OSMO_ASSERT(osmo_fsm_register(&gmm_attach_req_fsm) == 0);
+}
+
+void gmm_att_req_free(struct sgsn_mm_ctx *mm) {
+ if (mm->gmm_att_req.fsm)
+ osmo_fsm_inst_free(mm->gmm_att_req.fsm);
+
+ if (mm->gmm_att_req.attach_req)
+ msgb_free(mm->gmm_att_req.attach_req);
+}
diff --git a/src/sgsn/gprs_gmm_fsm.c b/src/sgsn/gprs_gmm_fsm.c
new file mode 100644
index 000000000..37ea90408
--- /dev/null
+++ b/src/sgsn/gprs_gmm_fsm.c
@@ -0,0 +1,210 @@
+#include <osmocom/core/tdef.h>
+
+#include <osmocom/sgsn/gprs_gmm_fsm.h>
+#include <osmocom/sgsn/gprs_mm_state_gb_fsm.h>
+#include <osmocom/sgsn/gprs_mm_state_iu_fsm.h>
+
+#include <osmocom/sgsn/debug.h>
+#include <osmocom/sgsn/sgsn.h>
+
+#define X(s) (1 << (s))
+
+static const struct osmo_tdef_state_timeout gmm_fsm_timeouts[32] = {
+ [ST_GMM_DEREGISTERED] = { },
+ [ST_GMM_COMMON_PROC_INIT] = { },
+ [ST_GMM_REGISTERED_NORMAL] = { },
+ [ST_GMM_REGISTERED_SUSPENDED] = { },
+ [ST_GMM_DEREGISTERED_INIT] = { },
+};
+
+#define gmm_fsm_state_chg(fi, NEXT_STATE) \
+ osmo_tdef_fsm_inst_state_chg(fi, NEXT_STATE, gmm_fsm_timeouts, sgsn->cfg.T_defs, -1)
+
+static void st_gmm_deregistered(struct osmo_fsm_inst *fi, uint32_t event, void *data)
+{
+ switch(event) {
+ case E_GMM_COMMON_PROC_INIT_REQ:
+ gmm_fsm_state_chg(fi, ST_GMM_COMMON_PROC_INIT);
+ break;
+ case E_GMM_ATTACH_SUCCESS:
+ gmm_fsm_state_chg(fi, ST_GMM_REGISTERED_NORMAL);
+ break;
+ }
+}
+
+static void st_gmm_common_proc_init(struct osmo_fsm_inst *fi, uint32_t event, void *data)
+{
+ switch(event) {
+ /* TODO: events not used
+ case E_GMM_LOWER_LAYER_FAILED:
+ case E_GMM_COMMON_PROC_FAILED:
+ gmm_fsm_state_chg(fi, ST_GMM_DEREGISTERED);
+ break;
+ */
+ case E_GMM_COMMON_PROC_SUCCESS:
+ case E_GMM_ATTACH_SUCCESS:
+ gmm_fsm_state_chg(fi, ST_GMM_REGISTERED_NORMAL);
+ break;
+ }
+}
+
+static void st_gmm_registered_normal(struct osmo_fsm_inst *fi, uint32_t event, void *data)
+{
+ switch(event) {
+ case E_GMM_COMMON_PROC_INIT_REQ:
+ gmm_fsm_state_chg(fi, ST_GMM_COMMON_PROC_INIT);
+ break;
+ /* case E_GMM_NET_INIT_DETACH_REQ:
+ gmm_fsm_state_chg(fi, ST_GMM_DEREGISTERED_INIT);
+ break; */
+ /* case E_GMM_MS_INIT_DETACH_REQ:
+ gmm_fsm_state_chg(fi, ST_GMM_DEREGISTERED);
+ break; */
+ case E_GMM_SUSPEND:
+ gmm_fsm_state_chg(fi, ST_GMM_REGISTERED_SUSPENDED);
+ break;
+ }
+}
+
+static void st_gmm_registered_suspended(struct osmo_fsm_inst *fi, uint32_t event, void *data)
+{
+ switch(event) {
+ case E_GMM_RESUME:
+ gmm_fsm_state_chg(fi, ST_GMM_REGISTERED_NORMAL);
+ break;
+ }
+}
+
+static void st_gmm_deregistered_init(struct osmo_fsm_inst *fi, uint32_t event, void *data)
+{
+ switch(event) {
+ /* TODO: events not used in osmo-sgsn code
+ case E_GMM_DETACH_ACCEPTED:
+ case E_GMM_LOWER_LAYER_FAILED:
+ gmm_fsm_state_chg(fi, ST_GMM_DEREGISTERED);
+ break;
+ */
+ }
+}
+
+static struct osmo_fsm_state gmm_fsm_states[] = {
+ [ST_GMM_DEREGISTERED] = {
+ .in_event_mask =
+ X(E_GMM_COMMON_PROC_INIT_REQ) |
+ X(E_GMM_ATTACH_SUCCESS),
+ .out_state_mask = X(ST_GMM_COMMON_PROC_INIT),
+ .name = "Deregistered",
+ .action = st_gmm_deregistered,
+ },
+ [ST_GMM_COMMON_PROC_INIT] = {
+ .in_event_mask =
+ /* X(E_GMM_LOWER_LAYER_FAILED) | */
+ /* X(E_GMM_COMMON_PROC_FAILED) | */
+ X(E_GMM_COMMON_PROC_SUCCESS) |
+ X(E_GMM_ATTACH_SUCCESS),
+ .out_state_mask =
+ X(ST_GMM_DEREGISTERED) |
+ X(ST_GMM_REGISTERED_NORMAL),
+ .name = "CommonProcedureInitiated",
+ .action = st_gmm_common_proc_init,
+ },
+ [ST_GMM_REGISTERED_NORMAL] = {
+ .in_event_mask =
+ X(E_GMM_COMMON_PROC_INIT_REQ) |
+ /* X(E_GMM_NET_INIT_DETACH_REQ) | */
+ /* X(E_GMM_MS_INIT_DETACH_REQ) | */
+ X(E_GMM_SUSPEND),
+ .out_state_mask =
+ X(ST_GMM_DEREGISTERED) |
+ X(ST_GMM_COMMON_PROC_INIT) |
+ X(ST_GMM_DEREGISTERED_INIT) |
+ X(ST_GMM_REGISTERED_SUSPENDED),
+ .name = "Registered.NORMAL",
+ .action = st_gmm_registered_normal,
+ },
+ [ST_GMM_REGISTERED_SUSPENDED] = {
+ .in_event_mask = X(E_GMM_RESUME),
+ .out_state_mask =
+ X(ST_GMM_DEREGISTERED) |
+ X(ST_GMM_REGISTERED_NORMAL),
+ .name = "Registered.SUSPENDED",
+ .action = st_gmm_registered_suspended,
+ },
+ [ST_GMM_DEREGISTERED_INIT] = {
+ .in_event_mask = 0
+ /* X(E_GMM_DETACH_ACCEPTED) | */
+ /* X(E_GMM_LOWER_LAYER_FAILED) */,
+ .out_state_mask = X(ST_GMM_DEREGISTERED),
+ .name = "DeregisteredInitiated",
+ .action = st_gmm_deregistered_init,
+ },
+};
+
+const struct value_string gmm_fsm_event_names[] = {
+ OSMO_VALUE_STRING(E_GMM_COMMON_PROC_INIT_REQ),
+ /* OSMO_VALUE_STRING(E_GMM_COMMON_PROC_FAILED), */
+ /* OSMO_VALUE_STRING(E_GMM_LOWER_LAYER_FAILED), */
+ OSMO_VALUE_STRING(E_GMM_COMMON_PROC_SUCCESS),
+ OSMO_VALUE_STRING(E_GMM_ATTACH_SUCCESS),
+ /* OSMO_VALUE_STRING(E_GMM_NET_INIT_DETACH_REQ), */
+ /* OSMO_VALUE_STRING(E_GMM_MS_INIT_DETACH_REQ), */
+ /* OSMO_VALUE_STRING(E_GMM_DETACH_ACCEPTED), */
+ OSMO_VALUE_STRING(E_GMM_SUSPEND),
+ OSMO_VALUE_STRING(E_GMM_CLEANUP),
+ OSMO_VALUE_STRING(E_GMM_RAT_CHANGE),
+ { 0, NULL }
+};
+
+void gmm_fsm_allstate_action(struct osmo_fsm_inst *fi, uint32_t event, void *data) {
+ struct sgsn_mm_ctx *mmctx = fi->priv;
+ struct gmm_rat_change_data *rat_chg = (struct gmm_rat_change_data *)data;
+
+ switch (event) {
+ case E_GMM_RAT_CHANGE:
+
+ switch (fi->state) {
+ case ST_GMM_COMMON_PROC_INIT:
+ gmm_fsm_state_chg(fi, ST_GMM_DEREGISTERED);
+ default:
+ if (mmctx->ran_type == MM_CTX_T_GERAN_Gb)
+ osmo_fsm_inst_dispatch(mmctx->gb.mm_state_fsm, E_MM_IMPLICIT_DETACH, NULL);
+ else if (mmctx->ran_type == MM_CTX_T_UTRAN_Iu) {
+ osmo_fsm_inst_dispatch(mmctx->iu.mm_state_fsm, E_PMM_IMPLICIT_DETACH, NULL);
+ mmctx->gb.llme = rat_chg->llme;
+ }
+
+ mmctx->ran_type = rat_chg->new_ran_type;
+ break;
+ }
+
+ case E_GMM_CLEANUP:
+ switch (fi->state) {
+ case ST_GMM_DEREGISTERED:
+ break;
+ default:
+ gmm_fsm_state_chg(fi, ST_GMM_DEREGISTERED);
+ break;
+ }
+ }
+}
+
+int gmm_fsm_timer_cb(struct osmo_fsm_inst *fi)
+{
+ return 0;
+}
+
+struct osmo_fsm gmm_fsm = {
+ .name = "GMM",
+ .states = gmm_fsm_states,
+ .num_states = ARRAY_SIZE(gmm_fsm_states),
+ .event_names = gmm_fsm_event_names,
+ .allstate_event_mask = X(E_GMM_CLEANUP) | X(E_GMM_RAT_CHANGE),
+ .allstate_action = gmm_fsm_allstate_action,
+ .log_subsys = DMM,
+ .timer_cb = gmm_fsm_timer_cb,
+};
+
+static __attribute__((constructor)) void gmm_fsm_init(void)
+{
+ OSMO_ASSERT(osmo_fsm_register(&gmm_fsm) == 0);
+}
diff --git a/src/gprs/gprs_llc.c b/src/sgsn/gprs_llc.c
index 904ec7e07..6e22e65c0 100644
--- a/src/gprs/gprs_llc.c
+++ b/src/sgsn/gprs_llc.c
@@ -22,8 +22,7 @@
#include <errno.h>
#include <stdint.h>
#include <stdbool.h>
-
-#include <openssl/rand.h>
+#include <inttypes.h>
#include <osmocom/core/msgb.h>
#include <osmocom/core/linuxlist.h>
@@ -33,19 +32,26 @@
#include <osmocom/gprs/gprs_bssgp.h>
#include <osmocom/gsm/gsm_utils.h>
-#include <openbsc/debug.h>
-#include <openbsc/gprs_sgsn.h>
-#include <openbsc/gprs_gmm.h>
-#include <openbsc/gprs_llc.h>
-#include <openbsc/crc24.h>
-#include <openbsc/sgsn.h>
-#include <openbsc/gprs_llc_xid.h>
-#include <openbsc/gprs_sndcp_comp.h>
-#include <openbsc/gprs_sndcp.h>
+#include <osmocom/sgsn/debug.h>
+#include <osmocom/sgsn/gprs_sgsn.h>
+#include <osmocom/sgsn/gprs_gmm.h>
+#include <osmocom/sgsn/gprs_llc.h>
+#include <osmocom/sgsn/crc24.h>
+#include <osmocom/sgsn/sgsn.h>
+#include <osmocom/sgsn/gprs_llc_xid.h>
+#include <osmocom/sgsn/gprs_sndcp_comp.h>
+#include <osmocom/sgsn/gprs_sndcp.h>
+
+const struct value_string gprs_llc_llme_state_names[] = {
+ { GPRS_LLMS_UNASSIGNED, "UNASSIGNED" },
+ { GPRS_LLMS_ASSIGNED, "ASSIGNED" },
+ { 0, NULL }
+};
static struct gprs_llc_llme *llme_alloc(uint32_t tlli);
static int gprs_llc_tx_xid(struct gprs_llc_lle *lle, struct msgb *msg,
int command);
+static int gprs_llc_tx_dm(struct gprs_llc_lle *lle);
static int gprs_llc_tx_u(struct msgb *msg, uint8_t sapi,
int command, enum gprs_llc_u_cmd u_cmd, int pf_bit);
@@ -54,7 +60,7 @@ static int gprs_llc_tx_u(struct msgb *msg, uint8_t sapi,
/* Generate XID message */
static int gprs_llc_generate_xid(uint8_t *bytes, int bytes_len,
struct gprs_llc_xid_field *l3_xid_field,
- struct gprs_llc_llme *llme)
+ struct gprs_llc_lle *lle)
{
/* Note: Called by gprs_ll_xid_req() */
@@ -63,17 +69,20 @@ static int gprs_llc_generate_xid(uint8_t *bytes, int bytes_len,
struct gprs_llc_xid_field xid_version;
struct gprs_llc_xid_field xid_n201u;
struct gprs_llc_xid_field xid_n201i;
+ uint16_t n201_u, n201_i;
xid_version.type = GPRS_LLC_XID_T_VERSION;
xid_version.data = (uint8_t *) "\x00";
xid_version.data_len = 1;
+ n201_u = htons(lle->params.n201_u);
xid_n201u.type = GPRS_LLC_XID_T_N201_U;
- xid_n201u.data = (uint8_t *) "\x05\xf0";
+ xid_n201u.data = (uint8_t *) &n201_u;
xid_n201u.data_len = 2;
+ n201_i = htons(lle->params.n201_i);
xid_n201i.type = GPRS_LLC_XID_T_N201_I;
- xid_n201i.data = (uint8_t *) "\x05\xf0";
+ xid_n201i.data = (uint8_t *) &n201_i;
xid_n201i.data_len = 2;
/* Add locally managed XID Fields */
@@ -91,8 +100,8 @@ static int gprs_llc_generate_xid(uint8_t *bytes, int bytes_len,
}
/* Store generated XID for later reference */
- talloc_free(llme->xid);
- llme->xid = gprs_llc_copy_xid(llme, &xid_fields);
+ talloc_free(lle->xid);
+ lle->xid = gprs_llc_copy_xid(lle->llme, &xid_fields);
return gprs_llc_compile_xid(bytes, bytes_len, &xid_fields);
}
@@ -100,7 +109,7 @@ static int gprs_llc_generate_xid(uint8_t *bytes, int bytes_len,
/* Generate XID message that will cause the GMM to reset */
static int gprs_llc_generate_xid_for_gmm_reset(uint8_t *bytes,
int bytes_len, uint32_t iov_ui,
- struct gprs_llc_llme *llme)
+ struct gprs_llc_lle *lle)
{
/* Called by gprs_llgmm_reset() and
* gprs_llgmm_reset_oldmsg() */
@@ -125,8 +134,8 @@ static int gprs_llc_generate_xid_for_gmm_reset(uint8_t *bytes,
llist_add(&xid_reset.list, &xid_fields);
/* Store generated XID for later reference */
- talloc_free(llme->xid);
- llme->xid = gprs_llc_copy_xid(llme, &xid_fields);
+ talloc_free(lle->xid);
+ lle->xid = gprs_llc_copy_xid(lle->llme, &xid_fields);
return gprs_llc_compile_xid(bytes, bytes_len, &xid_fields);
}
@@ -145,8 +154,8 @@ static int gprs_llc_process_xid_conf(uint8_t *bytes, int bytes_len,
struct gprs_llc_xid_field *xid_field_request_l3 = NULL;
/* Pick layer3 XID from the XID request we have sent last */
- if (lle->llme->xid) {
- llist_for_each_entry(xid_field_request, lle->llme->xid, list) {
+ if (lle->xid) {
+ llist_for_each_entry(xid_field_request, lle->xid, list) {
if (xid_field_request->type == GPRS_LLC_XID_T_L3_PAR)
xid_field_request_l3 = xid_field_request;
}
@@ -190,8 +199,8 @@ static int gprs_llc_process_xid_conf(uint8_t *bytes, int bytes_len,
}
/* Flush pending XID fields */
- talloc_free(lle->llme->xid);
- lle->llme->xid = NULL;
+ talloc_free(lle->xid);
+ lle->xid = NULL;
return 0;
}
@@ -326,8 +335,7 @@ int gprs_ll_xid_req(struct gprs_llc_lle *lle,
/* Generate XID */
xid_bytes_len =
- gprs_llc_generate_xid(xid_bytes, sizeof(xid_bytes),
- l3_xid_field, lle->llme);
+ gprs_llc_generate_xid(xid_bytes, sizeof(xid_bytes), l3_xid_field, lle);
/* Only perform XID sending if the XID message contains something */
if (xid_bytes_len > 0) {
@@ -374,8 +382,15 @@ static int _bssgp_tx_dl_ud(struct msgb *msg, struct sgsn_mm_ctx *mmctx)
dup.ms_ra_cap.v = mmctx->ms_radio_access_capa.buf;
/* make sure we only send it to the right llme */
- OSMO_ASSERT(msgb_tlli(msg) == mmctx->gb.llme->tlli
- || msgb_tlli(msg) == mmctx->gb.llme->old_tlli);
+ if (!(msgb_tlli(msg) == mmctx->gb.llme->tlli
+ || msgb_tlli(msg) == mmctx->gb.llme->old_tlli)) {
+ LOGP(DLLC, LOGL_ERROR,
+ "_bssgp_tx_dl_ud(): Attempt to send Downlink Unitdata to wrong LLME:"
+ " msgb_tlli=0x%x mmctx->gb.llme->tlli=0x%x ->old_tlli=0x%x\n",
+ msgb_tlli(msg), mmctx->gb.llme->tlli, mmctx->gb.llme->old_tlli);
+ msgb_free(msg);
+ return -EINVAL;
+ }
}
memcpy(&dup.qos_profile, qos_profile_default,
sizeof(qos_profile_default));
@@ -517,12 +532,12 @@ static struct gprs_llc_lle *lle_for_rx_by_tlli_sapi(const uint32_t tlli,
struct gprs_llc_llme *llme;
/* FIXME: don't use the TLLI but the 0xFFFF unassigned? */
llme = llme_alloc(tlli);
- LOGP(DLLC, LOGL_NOTICE, "LLC RX: unknown TLLI 0x%08x, "
+ LOGGBP(llme, DLLC, LOGL_NOTICE, "LLC RX: unknown TLLI 0x%08x, "
"creating LLME on the fly\n", tlli);
lle = &llme->lle[sapi];
return lle;
}
-
+
LOGP(DLLC, LOGL_NOTICE,
"unknown TLLI(0x%08x)/SAPI(%d): Silently dropping\n",
tlli, sapi);
@@ -551,7 +566,7 @@ static struct gprs_llc_llme *llme_alloc(uint32_t tlli)
return NULL;
llme->tlli = tlli;
- llme->old_tlli = 0xffffffff;
+ llme->old_tlli = TLLI_UNASSIGNED;
llme->state = GPRS_LLMS_UNASSIGNED;
llme->age_timestamp = GPRS_LLME_RESET_AGE;
llme->cksn = GSM_KEY_SEQ_INVAL;
@@ -571,7 +586,6 @@ static void llme_free(struct gprs_llc_llme *llme)
{
gprs_sndcp_comp_free(llme->comp.proto);
gprs_sndcp_comp_free(llme->comp.data);
- talloc_free(llme->xid);
llist_del(&llme->list);
talloc_free(llme);
}
@@ -671,6 +685,18 @@ static int gprs_llc_tx_xid(struct gprs_llc_lle *lle, struct msgb *msg,
return gprs_llc_tx_u(msg, lle->sapi, command, GPRS_LLC_U_XID, 1);
}
+static int gprs_llc_tx_dm(struct gprs_llc_lle *lle)
+{
+ struct msgb *msg = msgb_alloc_headroom(4096, 1024, "LLC_DM");
+
+ /* copy identifiers from LLE to ensure lower layers can route */
+ msgb_tlli(msg) = lle->llme->tlli;
+ msgb_bvci(msg) = lle->llme->bvci;
+ msgb_nsei(msg) = lle->llme->nsei;
+
+ return gprs_llc_tx_u(msg, lle->sapi, 0, GPRS_LLC_U_DM_RESP, 1);
+}
+
/* encrypt information field + FCS, if needed! */
static int apply_gea(struct gprs_llc_lle *lle, uint16_t crypt_len, uint16_t nu,
uint32_t oc, uint8_t sapi, uint8_t *fcs, uint8_t *data)
@@ -797,6 +823,8 @@ static int gprs_llc_hdr_rx(struct gprs_llc_hdr_parsed *gph,
struct gprs_llc_lle *lle)
{
switch (gph->cmd) {
+#if 0
+ /* we don't fully imoplement ABM, so refuse it properly (OS#3953) */
case GPRS_LLC_SABM: /* Section 6.4.1.1 */
lle->v_sent = lle->v_ack = lle->v_recv = 0;
if (lle->state == GPRS_LLES_ASSIGNED_ADM) {
@@ -822,6 +850,13 @@ static int gprs_llc_hdr_rx(struct gprs_llc_hdr_parsed *gph,
break;
case GPRS_LLC_FRMR: /* Section 6.4.1.5 */
break;
+#else
+ case GPRS_LLC_SABM:
+ case GPRS_LLC_DISC:
+ /* send DM to properly signal we don't do ABM */
+ gprs_llc_tx_dm(lle);
+ break;
+#endif
case GPRS_LLC_XID: /* Section 6.4.1.6 */
rx_llc_xid(lle, gph);
break;
@@ -855,6 +890,9 @@ static int gprs_llc_hdr_rx(struct gprs_llc_hdr_parsed *gph,
if ((gph->seq_tx + 1) / 512)
lle->oc_ui_recv += 512;
break;
+ case GPRS_LLC_NULL:
+ LOGP(DLLC, LOGL_DEBUG, "TLLI=%08x sends us LLC NULL\n", lle->llme ? lle->llme->tlli : -1);
+ break;
default:
LOGP(DLLC, LOGL_NOTICE, "Unhandled command: %d\n", gph->cmd);
break;
@@ -950,12 +988,19 @@ int gprs_llc_rcvmsg(struct msgb *msg, struct tlv_parsed *tv)
if (rc < 0)
return rc;
+ /* there are many frame types that don't carry user information
+ * and which hence have llhp.data = NULL */
+ if (llhp.data) {
+ /* set l3 layer & remove the fcs */
+ msg->l3h = llhp.data;
+ msgb_l3trim(msg, llhp.data_len);
+ }
+
rate_ctr_inc(&sgsn->rate_ctrs->ctr[CTR_LLC_UL_PACKETS]);
rate_ctr_add(&sgsn->rate_ctrs->ctr[CTR_LLC_UL_BYTES], msg->len);
/* llhp.data is only set when we need to send LL_[UNIT]DATA_IND up */
if (llhp.cmd == GPRS_LLC_UI && llhp.data && llhp.data_len) {
- msgb_gmmh(msg) = llhp.data;
switch (llhp.sapi) {
case GPRS_SAPI_GMM:
/* send LL_UNITDATA_IND to GMM */
@@ -1006,20 +1051,24 @@ int gprs_llgmm_assign(struct gprs_llc_llme *llme,
uint32_t old_tlli, uint32_t new_tlli)
{
unsigned int i;
+ bool free = false;
- if (old_tlli == 0xffffffff && new_tlli != 0xffffffff) {
+ LOGGBP(llme, DLLC, LOGL_NOTICE, "LLGM Assign pre (%08x => %08x)\n",
+ old_tlli, new_tlli);
+
+ if (old_tlli == TLLI_UNASSIGNED && new_tlli != TLLI_UNASSIGNED) {
/* TLLI Assignment 8.3.1 */
/* New TLLI shall be assigned and used when (re)transmitting LLC frames */
- /* If old TLLI != 0xffffffff was assigned to LLME, then TLLI
+ /* If old TLLI != TLLI_UNASSIGNED was assigned to LLME, then TLLI
* old is unassigned. Only TLLI new shall be accepted when
* received from peer. */
- if (llme->old_tlli != 0xffffffff) {
- llme->old_tlli = 0xffffffff;
+ if (llme->old_tlli != TLLI_UNASSIGNED) {
+ llme->old_tlli = TLLI_UNASSIGNED;
llme->tlli = new_tlli;
} else {
- /* If TLLI old == 0xffffffff was assigned to LLME, then this is
+ /* If TLLI old == TLLI_UNASSIGNED was assigned to LLME, then this is
* TLLI assignmemt according to 8.3.1 */
- llme->old_tlli = 0xffffffff;
+ llme->old_tlli = TLLI_UNASSIGNED;
llme->tlli = new_tlli;
llme->state = GPRS_LLMS_ASSIGNED;
/* 8.5.3.1 For all LLE's */
@@ -1031,14 +1080,14 @@ int gprs_llgmm_assign(struct gprs_llc_llme *llme,
/* FIXME Set parameters according to table 9 */
}
}
- } else if (old_tlli != 0xffffffff && new_tlli != 0xffffffff) {
+ } else if (old_tlli != TLLI_UNASSIGNED && new_tlli != TLLI_UNASSIGNED) {
/* TLLI Change 8.3.2 */
/* Both TLLI Old and TLLI New are assigned; use New when
* (re)transmitting. Accept both Old and New on Rx */
llme->old_tlli = old_tlli;
llme->tlli = new_tlli;
llme->state = GPRS_LLMS_ASSIGNED;
- } else if (old_tlli != 0xffffffff && new_tlli == 0xffffffff) {
+ } else if (old_tlli != TLLI_UNASSIGNED && new_tlli == TLLI_UNASSIGNED) {
/* TLLI Unassignment 8.3.3) */
llme->tlli = llme->old_tlli = 0;
llme->state = GPRS_LLMS_UNASSIGNED;
@@ -1046,38 +1095,47 @@ int gprs_llgmm_assign(struct gprs_llc_llme *llme,
struct gprs_llc_lle *l = &llme->lle[i];
l->state = GPRS_LLES_UNASSIGNED;
}
- llme_free(llme);
+ free = true;
} else
return -EINVAL;
+ LOGGBP(llme, DLLC, LOGL_NOTICE, "LLGM Assign post (%08x => %08x)\n",
+ old_tlli, new_tlli);
+
+ if (free)
+ llme_free(llme);
+
return 0;
}
/* TLLI unassignment */
int gprs_llgmm_unassign(struct gprs_llc_llme *llme)
{
- return gprs_llgmm_assign(llme, llme->tlli, 0xffffffff);
+ return gprs_llgmm_assign(llme, llme->tlli, TLLI_UNASSIGNED);
}
/* Chapter 7.2.1.2 LLGMM-RESET.req */
int gprs_llgmm_reset(struct gprs_llc_llme *llme)
{
struct msgb *msg = msgb_alloc_headroom(4096, 1024, "LLC_XID");
- struct gprs_llc_lle *lle = &llme->lle[1];
+ struct gprs_llc_lle *lle = &llme->lle[GPRS_SAPI_GMM];
uint8_t xid_bytes[1024];
- int xid_bytes_len;
+ int xid_bytes_len, rc;
uint8_t *xid;
- LOGP(DLLC, LOGL_NOTICE, "LLGM Reset\n");
- if (RAND_bytes((uint8_t *) &llme->iov_ui, 4) != 1) {
- LOGP(DLLC, LOGL_NOTICE, "RAND_bytes failed for LLC XID reset, "
- "falling back to rand()\n");
- llme->iov_ui = rand();
+ LOGGBP(llme, DLLC, LOGL_NOTICE, "LLGM Reset\n");
+
+ rc = osmo_get_rand_id((uint8_t *) &llme->iov_ui, 4);
+ if (rc < 0) {
+ LOGGBP(llme, DLLC, LOGL_ERROR,
+ "osmo_get_rand_id() failed for LLC XID reset: %s\n",
+ strerror(-rc));
+ return rc;
}
/* Generate XID message */
- xid_bytes_len = gprs_llc_generate_xid_for_gmm_reset(xid_bytes,
- sizeof(xid_bytes),llme->iov_ui,llme);
+ xid_bytes_len = gprs_llc_generate_xid_for_gmm_reset(xid_bytes, sizeof(xid_bytes),
+ llme->iov_ui, lle);
if (xid_bytes_len < 0)
return -EINVAL;
xid = msgb_put(msg, xid_bytes_len);
@@ -1097,20 +1155,24 @@ int gprs_llgmm_reset_oldmsg(struct msgb* oldmsg, uint8_t sapi,
struct gprs_llc_llme *llme)
{
struct msgb *msg = msgb_alloc_headroom(4096, 1024, "LLC_XID");
+ struct gprs_llc_lle *lle = &llme->lle[sapi];
uint8_t xid_bytes[1024];
- int xid_bytes_len;
+ int xid_bytes_len, rc;
uint8_t *xid;
- LOGP(DLLC, LOGL_NOTICE, "LLGM Reset\n");
- if (RAND_bytes((uint8_t *) &llme->iov_ui, 4) != 1) {
- LOGP(DLLC, LOGL_NOTICE, "RAND_bytes failed for LLC XID reset, "
- "falling back to rand()\n");
- llme->iov_ui = rand();
+ LOGGBP(llme, DLLC, LOGL_NOTICE, "LLGM Reset (SAPI=%" PRIu8 ")\n", sapi);
+
+ rc = osmo_get_rand_id((uint8_t *) &llme->iov_ui, 4);
+ if (rc < 0) {
+ LOGGBP(llme, DLLC, LOGL_ERROR,
+ "osmo_get_rand_id() failed for LLC XID reset: %s\n",
+ strerror(-rc));
+ return rc;
}
/* Generate XID message */
- xid_bytes_len = gprs_llc_generate_xid_for_gmm_reset(xid_bytes,
- sizeof(xid_bytes),llme->iov_ui,llme);
+ xid_bytes_len = gprs_llc_generate_xid_for_gmm_reset(xid_bytes, sizeof(xid_bytes),
+ llme->iov_ui, lle);
if (xid_bytes_len < 0)
return -EINVAL;
xid = msgb_put(msg, xid_bytes_len);
diff --git a/src/gprs/gprs_llc_vty.c b/src/sgsn/gprs_llc_vty.c
index 626d6ef1b..418be8348 100644
--- a/src/gprs/gprs_llc_vty.c
+++ b/src/sgsn/gprs_llc_vty.c
@@ -32,9 +32,9 @@
#include <osmocom/core/talloc.h>
#include <osmocom/core/select.h>
#include <osmocom/core/rate_ctr.h>
-#include <openbsc/debug.h>
-#include <openbsc/signal.h>
-#include <openbsc/gprs_llc.h>
+#include <osmocom/sgsn/debug.h>
+#include <osmocom/sgsn/signal.h>
+#include <osmocom/sgsn/gprs_llc.h>
#include <osmocom/vty/vty.h>
#include <osmocom/vty/command.h>
@@ -71,7 +71,7 @@ static void vty_dump_llme(struct vty *vty, struct gprs_llc_llme *llme)
{
unsigned int i;
struct timespec now_tp = {0};
- clock_gettime(CLOCK_MONOTONIC, &now_tp);
+ osmo_clock_gettime(CLOCK_MONOTONIC, &now_tp);
vty_out(vty, "TLLI %08x (Old TLLI %08x) BVCI=%u NSEI=%u %s: "
"IOV-UI=0x%06x CKSN=%d Age=%d: State %s%s", llme->tlli,
diff --git a/src/gprs/gprs_llc_xid.c b/src/sgsn/gprs_llc_xid.c
index fe631715a..b91fa6bfd 100644
--- a/src/gprs/gprs_llc_xid.c
+++ b/src/sgsn/gprs_llc_xid.c
@@ -30,10 +30,10 @@
#include <osmocom/core/msgb.h>
#include <osmocom/core/talloc.h>
-#include <openbsc/debug.h>
-#include <openbsc/gprs_llc.h>
-#include <openbsc/sgsn.h>
-#include <openbsc/gprs_llc_xid.h>
+#include <osmocom/sgsn/debug.h>
+#include <osmocom/sgsn/gprs_llc.h>
+#include <osmocom/sgsn/sgsn.h>
+#include <osmocom/sgsn/gprs_llc_xid.h>
const struct value_string gprs_llc_xid_type_names[] = {
{ GPRS_LLC_XID_T_VERSION, "VERSION"},
@@ -41,7 +41,7 @@ const struct value_string gprs_llc_xid_type_names[] = {
{ GPRS_LLC_XID_T_IOV_I, "IOV_I"},
{ GPRS_LLC_XID_T_T200, "T200"},
{ GPRS_LLC_XID_T_N200, "N200"},
- { GPRS_LLC_XID_T_N201_U, "N201_"},
+ { GPRS_LLC_XID_T_N201_U, "N201_U"},
{ GPRS_LLC_XID_T_N201_I, "N201_I"},
{ GPRS_LLC_XID_T_mD, "mD"},
{ GPRS_LLC_XID_T_mU, "mU"},
diff --git a/src/sgsn/gprs_mm_state_gb_fsm.c b/src/sgsn/gprs_mm_state_gb_fsm.c
new file mode 100644
index 000000000..811f0c2f4
--- /dev/null
+++ b/src/sgsn/gprs_mm_state_gb_fsm.c
@@ -0,0 +1,129 @@
+#include <osmocom/core/tdef.h>
+
+#include <osmocom/sgsn/gprs_mm_state_gb_fsm.h>
+#include <osmocom/sgsn/gprs_llc.h>
+
+#include <osmocom/sgsn/debug.h>
+#include <osmocom/sgsn/sgsn.h>
+
+#define X(s) (1 << (s))
+
+static const struct osmo_tdef_state_timeout mm_state_gb_fsm_timeouts[32] = {
+ [ST_MM_IDLE] = { },
+ [ST_MM_READY] = { .T=3314 },
+ [ST_MM_STANDBY] = { },
+};
+
+#define mm_state_gb_fsm_state_chg(fi, NEXT_STATE) \
+ osmo_tdef_fsm_inst_state_chg(fi, NEXT_STATE, mm_state_gb_fsm_timeouts, sgsn->cfg.T_defs, -1)
+
+static void st_mm_idle_on_enter(struct osmo_fsm_inst *fi, uint32_t prev_state) {
+ struct sgsn_mm_ctx *ctx = fi->priv;
+
+ /* FIXME: remove this timer when RAU has it's own fsm */
+ if (ctx->T == 3350 && osmo_timer_pending(&ctx->timer))
+ osmo_timer_del(&ctx->timer);
+
+ if (ctx->gb.llme) {
+ gprs_llgmm_unassign(ctx->gb.llme);
+ ctx->gb.llme = NULL;
+ }
+}
+
+static void st_mm_idle(struct osmo_fsm_inst *fi, uint32_t event, void *data)
+{
+ switch(event) {
+ case E_MM_GPRS_ATTACH:
+ mm_state_gb_fsm_state_chg(fi, ST_MM_READY);
+ break;
+ case E_MM_PDU_RECEPTION:
+ break;
+ }
+}
+
+static void st_mm_ready(struct osmo_fsm_inst *fi, uint32_t event, void *data)
+{
+ unsigned long t_secs;
+
+ switch(event) {
+ case E_MM_READY_TIMER_EXPIRY:
+ mm_state_gb_fsm_state_chg(fi, ST_MM_STANDBY);
+ break;
+ case E_MM_IMPLICIT_DETACH:
+ mm_state_gb_fsm_state_chg(fi, ST_MM_IDLE);
+ break;
+ case E_MM_PDU_RECEPTION:
+ /* RE-arm the READY timer upon receival of Gb PDUs */
+ t_secs = osmo_tdef_get(sgsn->cfg.T_defs, 3314, OSMO_TDEF_S, -1);
+ osmo_timer_schedule(&fi->timer, t_secs, 0);
+ break;
+ case E_MM_RA_UPDATE:
+ break;
+ }
+}
+
+static void st_mm_standby(struct osmo_fsm_inst *fi, uint32_t event, void *data)
+{
+ switch(event) {
+ case E_MM_PDU_RECEPTION:
+ mm_state_gb_fsm_state_chg(fi, ST_MM_READY);
+ break;
+ }
+}
+
+static struct osmo_fsm_state mm_state_gb_fsm_states[] = {
+ [ST_MM_IDLE] = {
+ .in_event_mask = X(E_MM_GPRS_ATTACH) | X(E_MM_PDU_RECEPTION),
+ .out_state_mask = X(ST_MM_READY),
+ .onenter = st_mm_idle_on_enter,
+ .name = "Idle",
+ .action = st_mm_idle,
+ },
+ [ST_MM_READY] = {
+ .in_event_mask = X(E_MM_READY_TIMER_EXPIRY) | X(E_MM_RA_UPDATE) | X(E_MM_IMPLICIT_DETACH) | X(E_MM_PDU_RECEPTION),
+ .out_state_mask = X(ST_MM_IDLE) | X(ST_MM_STANDBY),
+ .name = "Ready",
+ .action = st_mm_ready,
+ },
+ [ST_MM_STANDBY] = {
+ .in_event_mask = X(E_MM_PDU_RECEPTION),
+ .out_state_mask = X(ST_MM_IDLE) | X(ST_MM_READY),
+ .name = "Standby",
+ .action = st_mm_standby,
+ },
+};
+
+const struct value_string mm_state_gb_fsm_event_names[] = {
+ OSMO_VALUE_STRING(E_MM_GPRS_ATTACH),
+ OSMO_VALUE_STRING(E_MM_PDU_RECEPTION),
+ OSMO_VALUE_STRING(E_MM_IMPLICIT_DETACH),
+ OSMO_VALUE_STRING(E_MM_READY_TIMER_EXPIRY),
+ OSMO_VALUE_STRING(E_MM_RA_UPDATE),
+ { 0, NULL }
+};
+
+int mm_state_gb_fsm_timer_cb(struct osmo_fsm_inst *fi)
+{
+ switch(fi->state) {
+ case ST_MM_READY:
+ /* timer for mm state. state=READY: T3314 (aka TS 23.060 "READY timer") */
+ osmo_fsm_inst_dispatch(fi, E_MM_READY_TIMER_EXPIRY, NULL);
+ break;
+ }
+
+ return 0;
+}
+
+struct osmo_fsm mm_state_gb_fsm = {
+ .name = "MM_STATE_Gb",
+ .states = mm_state_gb_fsm_states,
+ .num_states = ARRAY_SIZE(mm_state_gb_fsm_states),
+ .event_names = mm_state_gb_fsm_event_names,
+ .log_subsys = DMM,
+ .timer_cb = mm_state_gb_fsm_timer_cb,
+};
+
+static __attribute__((constructor)) void mm_state_gb_fsm_init(void)
+{
+ OSMO_ASSERT(osmo_fsm_register(&mm_state_gb_fsm) == 0);
+}
diff --git a/src/sgsn/gprs_mm_state_iu_fsm.c b/src/sgsn/gprs_mm_state_iu_fsm.c
new file mode 100644
index 000000000..e571026c8
--- /dev/null
+++ b/src/sgsn/gprs_mm_state_iu_fsm.c
@@ -0,0 +1,150 @@
+#include <arpa/inet.h>
+
+#include <osmocom/core/tdef.h>
+
+#include <osmocom/sgsn/gprs_mm_state_iu_fsm.h>
+
+#include <osmocom/sgsn/debug.h>
+#include <osmocom/sgsn/sgsn.h>
+#include <osmocom/sgsn/gprs_ranap.h>
+
+#define X(s) (1 << (s))
+
+static const struct osmo_tdef_state_timeout mm_state_iu_fsm_timeouts[32] = {
+ [ST_PMM_DETACHED] = { },
+ /* non-spec -T3314 (User inactivity timer) */
+ [ST_PMM_CONNECTED] = { .T=-3314 },
+ [ST_PMM_IDLE] = { },
+};
+
+#define mm_state_iu_fsm_state_chg(fi, NEXT_STATE) \
+ osmo_tdef_fsm_inst_state_chg(fi, NEXT_STATE, mm_state_iu_fsm_timeouts, sgsn->cfg.T_defs, -1)
+
+static void mmctx_change_gtpu_endpoints_to_sgsn(struct sgsn_mm_ctx *mm_ctx)
+{
+ char buf[INET_ADDRSTRLEN];
+ struct sgsn_pdp_ctx *pdp;
+ llist_for_each_entry(pdp, &mm_ctx->pdp_list, list) {
+ LOGMMCTXP(LOGL_INFO, mm_ctx, "Changing GTP-U endpoints %s -> %s\n",
+ sgsn_gtp_ntoa(&pdp->lib->gsnlu),
+ inet_ntop(AF_INET, &sgsn->cfg.gtp_listenaddr.sin_addr, buf, sizeof(buf)));
+ sgsn_pdp_upd_gtp_u(pdp,
+ &sgsn->cfg.gtp_listenaddr.sin_addr,
+ sizeof(sgsn->cfg.gtp_listenaddr.sin_addr));
+ }
+}
+
+static void st_pmm_detached(struct osmo_fsm_inst *fi, uint32_t event, void *data)
+{
+ switch(event) {
+ case E_PMM_PS_ATTACH:
+ mm_state_iu_fsm_state_chg(fi, ST_PMM_CONNECTED);
+ break;
+ case E_PMM_IMPLICIT_DETACH:
+ break;
+ }
+}
+
+static void st_pmm_connected(struct osmo_fsm_inst *fi, uint32_t event, void *data)
+{
+ struct sgsn_mm_ctx *ctx = fi->priv;
+ const struct RANAP_Cause user_inactive_cause = {
+ .present = RANAP_Cause_PR_radioNetwork,
+ .choice.radioNetwork = RANAP_CauseRadioNetwork_user_inactivity,
+ };
+
+ switch(event) {
+ case E_PMM_PS_CONN_RELEASE:
+ sgsn_ranap_iu_free(ctx);
+ mm_state_iu_fsm_state_chg(fi, ST_PMM_IDLE);
+ break;
+ case E_PMM_IMPLICIT_DETACH:
+ sgsn_ranap_iu_release_free(ctx, NULL);
+ mm_state_iu_fsm_state_chg(fi, ST_PMM_DETACHED);
+ break;
+ case E_PMM_USER_INACTIVITY:
+ sgsn_ranap_iu_release_free(ctx, &user_inactive_cause);
+ mm_state_iu_fsm_state_chg(fi, ST_PMM_DETACHED);
+ break;
+ case E_PMM_RA_UPDATE:
+ break;
+ }
+}
+
+static void st_pmm_idle_on_enter(struct osmo_fsm_inst *fi, uint32_t prev_state)
+{
+ struct sgsn_mm_ctx *ctx = fi->priv;
+
+ mmctx_change_gtpu_endpoints_to_sgsn(ctx);
+}
+
+static void st_pmm_idle(struct osmo_fsm_inst *fi, uint32_t event, void *data)
+{
+ switch(event) {
+ case E_PMM_PS_CONN_ESTABLISH:
+ mm_state_iu_fsm_state_chg(fi, ST_PMM_CONNECTED);
+ break;
+ case E_PMM_IMPLICIT_DETACH:
+ mm_state_iu_fsm_state_chg(fi, ST_PMM_DETACHED);
+ break;
+ }
+}
+
+static int pmm_state_fsm_timer_cb(struct osmo_fsm_inst *fi)
+{
+ switch(fi->state) {
+ case ST_PMM_CONNECTED:
+ /* timer for pmm state. state=CONNECTED: -T3314 (User inactivity timer) */
+ osmo_fsm_inst_dispatch(fi, E_PMM_USER_INACTIVITY, NULL);
+ break;
+ }
+
+ return 0;
+}
+
+static struct osmo_fsm_state mm_state_iu_fsm_states[] = {
+ [ST_PMM_DETACHED] = {
+ .in_event_mask = X(E_PMM_PS_ATTACH) | X(E_PMM_IMPLICIT_DETACH),
+ .out_state_mask = X(ST_PMM_CONNECTED),
+ .name = "Detached",
+ .action = st_pmm_detached,
+ },
+ [ST_PMM_CONNECTED] = {
+ .in_event_mask = X(E_PMM_PS_CONN_RELEASE) | X(E_PMM_RA_UPDATE)
+ | X(E_PMM_IMPLICIT_DETACH) | X(E_PMM_USER_INACTIVITY),
+ .out_state_mask = X(ST_PMM_DETACHED) | X(ST_PMM_IDLE),
+ .name = "Connected",
+ .action = st_pmm_connected,
+ },
+ [ST_PMM_IDLE] = {
+ .in_event_mask = X(E_PMM_IMPLICIT_DETACH) | X(E_PMM_PS_CONN_ESTABLISH),
+ .out_state_mask = X(ST_PMM_DETACHED) | X(ST_PMM_CONNECTED),
+ .name = "Idle",
+ .onenter = st_pmm_idle_on_enter,
+ .action = st_pmm_idle,
+ },
+};
+
+const struct value_string mm_state_iu_fsm_event_names[] = {
+ OSMO_VALUE_STRING(E_PMM_PS_ATTACH),
+ OSMO_VALUE_STRING(E_PMM_PS_CONN_RELEASE),
+ OSMO_VALUE_STRING(E_PMM_PS_CONN_ESTABLISH),
+ OSMO_VALUE_STRING(E_PMM_IMPLICIT_DETACH),
+ OSMO_VALUE_STRING(E_PMM_RA_UPDATE),
+ OSMO_VALUE_STRING(E_PMM_USER_INACTIVITY),
+ { 0, NULL }
+};
+
+struct osmo_fsm mm_state_iu_fsm = {
+ .name = "MM_STATE_Iu",
+ .states = mm_state_iu_fsm_states,
+ .num_states = ARRAY_SIZE(mm_state_iu_fsm_states),
+ .event_names = mm_state_iu_fsm_event_names,
+ .timer_cb = pmm_state_fsm_timer_cb,
+ .log_subsys = DMM,
+};
+
+static __attribute__((constructor)) void mm_state_iu_fsm_init(void)
+{
+ OSMO_ASSERT(osmo_fsm_register(&mm_state_iu_fsm) == 0);
+}
diff --git a/src/sgsn/gprs_ranap.c b/src/sgsn/gprs_ranap.c
new file mode 100644
index 000000000..7a3349192
--- /dev/null
+++ b/src/sgsn/gprs_ranap.c
@@ -0,0 +1,260 @@
+/* Messages on the RANAP interface (Iu mode) */
+
+/* (C) 2009-2015 by Harald Welte <laforge@gnumonks.org>
+ * (C) 2015 by Holger Hans Peter Freyther
+ * (C) 2019 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "bscconfig.h"
+#include <gtp.h>
+
+#include <osmocom/core/rate_ctr.h>
+#include <osmocom/core/tdef.h>
+
+#include <osmocom/ranap/ranap_common.h>
+
+#include <osmocom/sgsn/gprs_gmm.h>
+#include <osmocom/sgsn/gprs_sm.h>
+#include <osmocom/sgsn/debug.h>
+#include <osmocom/sgsn/sgsn.h>
+#include <osmocom/sgsn/gprs_ranap.h>
+#include <osmocom/sgsn/gprs_gmm_attach.h>
+#include <osmocom/sgsn/gprs_mm_state_iu_fsm.h>
+
+/* Send RAB activation requests for all PDP contexts */
+void activate_pdp_rabs(struct sgsn_mm_ctx *ctx)
+{
+ struct sgsn_pdp_ctx *pdp;
+ if (ctx->ran_type != MM_CTX_T_UTRAN_Iu)
+ return;
+ llist_for_each_entry(pdp, &ctx->pdp_list, list) {
+ iu_rab_act_ps(pdp->nsapi, pdp);
+ }
+}
+
+/* Callback for RAB assignment response */
+static int sgsn_ranap_rab_ass_resp(struct sgsn_mm_ctx *ctx, RANAP_RAB_SetupOrModifiedItemIEs_t *setup_ies)
+{
+ uint8_t rab_id;
+ bool require_pdp_update = false;
+ struct sgsn_pdp_ctx *pdp = NULL;
+ RANAP_RAB_SetupOrModifiedItem_t *item = &setup_ies->raB_SetupOrModifiedItem;
+
+ rab_id = item->rAB_ID.buf[0];
+
+ pdp = sgsn_pdp_ctx_by_nsapi(ctx, rab_id);
+ if (!pdp) {
+ LOGP(DRANAP, LOGL_ERROR, "RAB Assignment Response for unknown RAB/NSAPI=%u\n", rab_id);
+ return -1;
+ }
+
+ if (item->transportLayerAddress) {
+ LOGPC(DRANAP, LOGL_INFO, " Setup: (%u/%s)", rab_id, osmo_hexdump(item->transportLayerAddress->buf,
+ item->transportLayerAddress->size));
+ switch (item->transportLayerAddress->size) {
+ case 7:
+ /* It must be IPv4 inside a X213 NSAP */
+ memcpy(pdp->lib->gsnlu.v, &item->transportLayerAddress->buf[3], 4);
+ break;
+ case 4:
+ /* It must be a raw IPv4 address */
+ memcpy(pdp->lib->gsnlu.v, item->transportLayerAddress->buf, 4);
+ break;
+ case 16:
+ /* TODO: It must be a raw IPv6 address */
+ case 19:
+ /* TODO: It must be IPv6 inside a X213 NSAP */
+ default:
+ LOGP(DRANAP, LOGL_ERROR, "RAB Assignment Resp: Unknown "
+ "transport layer address size %u\n",
+ item->transportLayerAddress->size);
+ return -1;
+ }
+ require_pdp_update = true;
+ }
+
+ /* The TEI on the RNC side might have changed, too */
+ if (item->iuTransportAssociation &&
+ item->iuTransportAssociation->present == RANAP_IuTransportAssociation_PR_gTP_TEI &&
+ item->iuTransportAssociation->choice.gTP_TEI.buf &&
+ item->iuTransportAssociation->choice.gTP_TEI.size >= 4) {
+ uint32_t tei = osmo_load32be(item->iuTransportAssociation->choice.gTP_TEI.buf);
+ LOGP(DRANAP, LOGL_DEBUG, "Updating TEID on RNC side from 0x%08x to 0x%08x\n",
+ pdp->lib->teid_own, tei);
+ pdp->lib->teid_own = tei;
+ require_pdp_update = true;
+ }
+
+ if (require_pdp_update)
+ gtp_update_context(pdp->ggsn->gsn, pdp->lib, pdp, &pdp->lib->hisaddr0);
+
+ if (pdp->state != PDP_STATE_CR_CONF) {
+ send_act_pdp_cont_acc(pdp);
+ pdp->state = PDP_STATE_CR_CONF;
+ }
+ return 0;
+
+}
+
+int sgsn_ranap_iu_event(struct ranap_ue_conn_ctx *ctx, enum ranap_iu_event_type type, void *data)
+{
+ struct sgsn_mm_ctx *mm;
+ int rc = -1;
+
+ mm = sgsn_mm_ctx_by_ue_ctx(ctx);
+ if (!mm) {
+ LOGIUP(ctx, LOGL_NOTICE, "Cannot find mm ctx for IU event %d\n", type);
+ ranap_iu_free_ue(ctx);
+ return rc;
+ }
+
+ switch (type) {
+ case RANAP_IU_EVENT_RAB_ASSIGN:
+ rc = sgsn_ranap_rab_ass_resp(mm, (RANAP_RAB_SetupOrModifiedItemIEs_t *)data);
+ break;
+ case RANAP_IU_EVENT_IU_RELEASE:
+ /* fall thru */
+ case RANAP_IU_EVENT_LINK_INVALIDATED:
+ /* Clean up ranap_ue_conn_ctx here */
+ LOGMMCTXP(LOGL_INFO, mm, "IU release for imsi %s\n", mm->imsi);
+ if (mm->iu.mm_state_fsm->state == ST_PMM_CONNECTED)
+ osmo_fsm_inst_dispatch(mm->iu.mm_state_fsm, E_PMM_PS_CONN_RELEASE, NULL);
+ else
+ sgsn_ranap_iu_free(mm);
+
+ /* TODO: move this into FSM */
+ if (mm->ran_type == MM_CTX_T_UTRAN_Iu && mm->gmm_att_req.fsm->state != ST_INIT)
+ osmo_fsm_inst_dispatch(mm->gmm_att_req.fsm, E_REJECT, (void *) GMM_DISCARD_MS_WITHOUT_REJECT);
+ rc = 0;
+ break;
+ case RANAP_IU_EVENT_SECURITY_MODE_COMPLETE:
+ /* Continue authentication here */
+ mm->iu.ue_ctx->integrity_active = 1;
+ ranap_iu_tx_common_id(mm->iu.ue_ctx, mm->imsi);
+
+ /* FIXME: remove gmm_authorize */
+ if (mm->pending_req != GSM48_MT_GMM_ATTACH_REQ)
+ gsm48_gmm_authorize(mm);
+ else
+ osmo_fsm_inst_dispatch(mm->gmm_att_req.fsm, E_IU_SECURITY_CMD_COMPLETE, NULL);
+ rc = 0;
+ break;
+ default:
+ LOGMMCTXP(LOGL_NOTICE, mm, "Unknown event received: %i\n", type);
+ rc = -1;
+ break;
+ }
+ return rc;
+}
+
+void sgsn_ranap_iu_free(struct sgsn_mm_ctx *ctx)
+{
+ if (!ctx)
+ return;
+
+ if (!ctx->iu.ue_ctx)
+ return;
+
+ ranap_iu_free_ue(ctx->iu.ue_ctx);
+ ctx->iu.ue_ctx = NULL;
+}
+
+void sgsn_ranap_iu_release_free(struct sgsn_mm_ctx *ctx,
+ const struct RANAP_Cause *cause)
+{
+ unsigned long X1001;
+
+ if (!ctx)
+ return;
+
+ if (!ctx->iu.ue_ctx)
+ return;
+
+ X1001 = osmo_tdef_get(sgsn->cfg.T_defs, -1001, OSMO_TDEF_S, -1);
+
+ ranap_iu_tx_release_free(ctx->iu.ue_ctx,
+ cause,
+ (int) X1001);
+ ctx->iu.ue_ctx = NULL;
+}
+
+int iu_rab_act_ps(uint8_t rab_id, struct sgsn_pdp_ctx *pdp)
+{
+ struct msgb *msg;
+ struct sgsn_mm_ctx *mm = pdp->mm;
+ struct ranap_ue_conn_ctx *uectx;
+ uint32_t ggsn_ip;
+ bool use_x213_nsap;
+
+ uectx = mm->iu.ue_ctx;
+ use_x213_nsap = (uectx->rab_assign_addr_enc == RANAP_NSAP_ADDR_ENC_X213);
+
+ /* Get the IP address for ggsn user plane */
+ memcpy(&ggsn_ip, pdp->lib->gsnru.v, pdp->lib->gsnru.l);
+ ggsn_ip = htonl(ggsn_ip);
+
+ LOGP(DRANAP, LOGL_DEBUG, "Assigning RAB: rab_id=%d, ggsn_ip=%x,"
+ " teid_gn=%x, use_x213_nsap=%d\n",
+ rab_id, ggsn_ip, pdp->lib->teid_gn, use_x213_nsap);
+
+ msg = ranap_new_msg_rab_assign_data(rab_id, ggsn_ip,
+ pdp->lib->teid_gn, use_x213_nsap);
+ msg->l2h = msg->data;
+ return ranap_iu_rab_act(uectx, msg);
+}
+
+
+/* Main entry point for incoming 04.08 GPRS messages from Iu */
+int gsm0408_gprs_rcvmsg_iu(struct msgb *msg, struct gprs_ra_id *ra_id,
+ uint16_t *sai)
+{
+ struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_gmmh(msg);
+ uint8_t pdisc = gsm48_hdr_pdisc(gh);
+ struct sgsn_mm_ctx *mmctx;
+ int rc = -EINVAL;
+
+ mmctx = sgsn_mm_ctx_by_ue_ctx(MSG_IU_UE_CTX(msg));
+ if (mmctx) {
+ rate_ctr_inc(&mmctx->ctrg->ctr[GMM_CTR_PKTS_SIG_IN]);
+ if (ra_id)
+ memcpy(&mmctx->ra, ra_id, sizeof(mmctx->ra));
+ }
+
+ /* MMCTX can be NULL */
+
+ switch (pdisc) {
+ case GSM48_PDISC_MM_GPRS:
+ rc = gsm0408_rcv_gmm(mmctx, msg, NULL, false);
+#pragma message "set drop_cipherable arg for gsm0408_rcv_gmm() from IuPS?"
+ break;
+ case GSM48_PDISC_SM_GPRS:
+ rc = gsm0408_rcv_gsm(mmctx, msg, NULL);
+ break;
+ default:
+ LOGMMCTXP(LOGL_NOTICE, mmctx,
+ "Unknown GSM 04.08 discriminator 0x%02x: %s\n",
+ pdisc, osmo_hexdump((uint8_t *)gh, msgb_l3len(msg)));
+ /* FIXME: return status message */
+ break;
+ }
+
+ /* MMCTX can be invalid */
+
+ return rc;
+}
diff --git a/src/gprs/gprs_sgsn.c b/src/sgsn/gprs_sgsn.c
index 560485de5..cb2c0fc25 100644
--- a/src/gprs/gprs_sgsn.c
+++ b/src/sgsn/gprs_sgsn.c
@@ -32,54 +32,63 @@
#include <osmocom/gsm/protocol/gsm_04_08_gprs.h>
#include <osmocom/gsm/apn.h>
#include <osmocom/gsm/gsm_utils.h>
-
-#include <openbsc/gprs_subscriber.h>
-#include <openbsc/debug.h>
-#include <openbsc/gprs_sgsn.h>
-#include <openbsc/sgsn.h>
-#include <openbsc/gprs_gmm.h>
-#include <openbsc/gprs_utils.h>
-#include <openbsc/signal.h>
-#include "openbsc/gprs_llc.h"
+#include <osmocom/gsm/gsup.h>
+
+#include <osmocom/sgsn/gprs_subscriber.h>
+#include <osmocom/sgsn/debug.h>
+#include <osmocom/sgsn/gprs_sgsn.h>
+#include <osmocom/sgsn/sgsn.h>
+#include <osmocom/sgsn/gprs_gmm.h>
+#include <osmocom/sgsn/gprs_sm.h>
+#include <osmocom/sgsn/gprs_utils.h>
+#include <osmocom/sgsn/signal.h>
+#include <osmocom/sgsn/gprs_gmm_attach.h>
+#include <osmocom/sgsn/gprs_mm_state_gb_fsm.h>
+#include <osmocom/sgsn/gprs_mm_state_iu_fsm.h>
+#include <osmocom/sgsn/gprs_gmm_fsm.h>
+#include <osmocom/sgsn/gprs_llc.h>
#include <pdp.h>
#include <time.h>
-#include <openssl/rand.h>
-
#include "../../bscconfig.h"
-#if BUILD_IU
-#include <osmocom/ranap/iu_client.h>
-#endif
-
#define GPRS_LLME_CHECK_TICK 30
extern struct sgsn_instance *sgsn;
-extern void *tall_bsc_ctx;
+extern void *tall_sgsn_ctx;
LLIST_HEAD(sgsn_mm_ctxts);
LLIST_HEAD(sgsn_ggsn_ctxts);
LLIST_HEAD(sgsn_apn_ctxts);
LLIST_HEAD(sgsn_pdp_ctxts);
+const struct value_string sgsn_ran_type_names[] = {
+ { MM_CTX_T_GERAN_Gb, "GPRS/EDGE via Gb" },
+ { MM_CTX_T_UTRAN_Iu, "UMTS via Iu" },
+#if 0
+ { MM_CTX_T_GERAN_Iu, "GPRS/EDGE via Iu" },
+#endif
+ { 0, NULL }
+};
+
static const struct rate_ctr_desc mmctx_ctr_description[] = {
- { "sign.packets.in", "Signalling Messages ( In)" },
- { "sign.packets.out", "Signalling Messages (Out)" },
- { "udata.packets.in", "User Data Messages ( In)" },
- { "udata.packets.out", "User Data Messages (Out)" },
- { "udata.bytes.in", "User Data Bytes ( In)" },
- { "udata.bytes.out", "User Data Bytes (Out)" },
+ { "sign:packets:in", "Signalling Messages ( In)" },
+ { "sign:packets:out", "Signalling Messages (Out)" },
+ { "udata:packets:in", "User Data Messages ( In)" },
+ { "udata:packets:out", "User Data Messages (Out)" },
+ { "udata:bytes:in", "User Data Bytes ( In)" },
+ { "udata:bytes:out", "User Data Bytes (Out)" },
{ "pdp_ctx_act", "PDP Context Activations " },
{ "suspend", "SUSPEND Count " },
- { "paging.ps", "Paging Packet Switched " },
- { "paging.cs", "Paging Circuit Switched " },
+ { "paging:ps", "Paging Packet Switched " },
+ { "paging:cs", "Paging Circuit Switched " },
{ "ra_update", "Routing Area Update " },
};
static const struct rate_ctr_group_desc mmctx_ctrg_desc = {
- .group_name_prefix = "sgsn.mmctx",
+ .group_name_prefix = "sgsn:mmctx",
.group_description = "SGSN MM Context Statistics",
.num_ctr = ARRAY_SIZE(mmctx_ctr_description),
.ctr_desc = mmctx_ctr_description,
@@ -87,14 +96,14 @@ static const struct rate_ctr_group_desc mmctx_ctrg_desc = {
};
static const struct rate_ctr_desc pdpctx_ctr_description[] = {
- { "udata.packets.in", "User Data Messages ( In)" },
- { "udata.packets.out", "User Data Messages (Out)" },
- { "udata.bytes.in", "User Data Bytes ( In)" },
- { "udata.bytes.out", "User Data Bytes (Out)" },
+ { "udata:packets:in", "User Data Messages ( In)" },
+ { "udata:packets:out", "User Data Messages (Out)" },
+ { "udata:bytes:in", "User Data Bytes ( In)" },
+ { "udata:bytes:out", "User Data Bytes (Out)" },
};
static const struct rate_ctr_group_desc pdpctx_ctrg_desc = {
- .group_name_prefix = "sgsn.pdpctx",
+ .group_name_prefix = "sgsn:pdpctx",
.group_description = "SGSN PDP Context Statistics",
.num_ctr = ARRAY_SIZE(pdpctx_ctr_description),
.ctr_desc = pdpctx_ctr_description,
@@ -102,29 +111,29 @@ static const struct rate_ctr_group_desc pdpctx_ctrg_desc = {
};
static const struct rate_ctr_desc sgsn_ctr_description[] = {
- { "llc.dl_bytes", "Count sent LLC bytes before giving it to the bssgp layer" },
- { "llc.ul_bytes", "Count sucessful received LLC bytes (encrypt & fcs correct)" },
- { "llc.dl_packets", "Count sucessful sent LLC packets before giving it to the bssgp layer" },
- { "llc.ul_packets", "Count sucessful received LLC packets (encrypt & fcs correct)" },
- { "gprs.attach_requested", "Received attach requests" },
- { "gprs.attach_accepted", "Sent attach accepts" },
- { "gprs.attach_rejected", "Sent attach rejects" },
- { "gprs.detach_requested", "Received detach requests" },
- { "gprs.detach_acked", "Sent detach acks" },
- { "gprs.routing_area_requested", "Received routing area requests" },
- { "gprs.routing_area_requested", "Sent routing area acks" },
- { "gprs.routing_area_requested", "Sent routing area rejects" },
- { "pdp.activate_requested", "Received activate requests" },
- { "pdp.activate_rejected", "Sent activate rejects" },
- { "pdp.activate_accepted", "Sent activate accepts" },
- { "pdp.request_activated", "unused" },
- { "pdp.request_activate_rejected", "unused" },
- { "pdp.modify_requested", "unused" },
- { "pdp.modify_accepted", "unused" },
- { "pdp.dl_deactivate_requested", "Sent deactivate requests" },
- { "pdp.dl_deactivate_accepted", "Sent deactivate accepted" },
- { "pdp.ul_deactivate_requested", "Received deactivate requests" },
- { "pdp.ul_deactivate_accepted", "Received deactivate accepts" },
+ { "llc:dl_bytes", "Count sent LLC bytes before giving it to the bssgp layer" },
+ { "llc:ul_bytes", "Count successful received LLC bytes (encrypt & fcs correct)" },
+ { "llc:dl_packets", "Count successful sent LLC packets before giving it to the bssgp layer" },
+ { "llc:ul_packets", "Count successful received LLC packets (encrypt & fcs correct)" },
+ { "gprs:attach_requested", "Received attach requests" },
+ { "gprs:attach_accepted", "Sent attach accepts" },
+ { "gprs:attach_rejected", "Sent attach rejects" },
+ { "gprs:detach_requested", "Received detach requests" },
+ { "gprs:detach_acked", "Sent detach acks" },
+ { "gprs:routing_area_requested", "Received routing area requests" },
+ { "gprs:routing_area_requested", "Sent routing area acks" },
+ { "gprs:routing_area_requested", "Sent routing area rejects" },
+ { "pdp:activate_requested", "Received activate requests" },
+ { "pdp:activate_rejected", "Sent activate rejects" },
+ { "pdp:activate_accepted", "Sent activate accepts" },
+ { "pdp:request_activated", "unused" },
+ { "pdp:request_activate_rejected", "unused" },
+ { "pdp:modify_requested", "unused" },
+ { "pdp:modify_accepted", "unused" },
+ { "pdp:dl_deactivate_requested", "Sent deactivate requests" },
+ { "pdp:dl_deactivate_accepted", "Sent deactivate accepted" },
+ { "pdp:ul_deactivate_requested", "Received deactivate requests" },
+ { "pdp:ul_deactivate_accepted", "Received deactivate accepts" },
};
static const struct rate_ctr_group_desc sgsn_ctrg_desc = {
@@ -136,7 +145,7 @@ static const struct rate_ctr_group_desc sgsn_ctrg_desc = {
};
void sgsn_rate_ctr_init() {
- sgsn->rate_ctrs = rate_ctr_group_alloc(tall_bsc_ctx, &sgsn_ctrg_desc, 0);
+ sgsn->rate_ctrs = rate_ctr_group_alloc(tall_sgsn_ctx, &sgsn_ctrg_desc, 0);
OSMO_ASSERT(sgsn->rate_ctrs);
}
@@ -218,68 +227,99 @@ struct sgsn_mm_ctx *sgsn_mm_ctx_by_imsi(const char *imsi)
}
-/* Allocate a new SGSN MM context for GERAN_Gb */
-struct sgsn_mm_ctx *sgsn_mm_ctx_alloc_gb(uint32_t tlli,
- const struct gprs_ra_id *raid)
+/* Allocate a new SGSN MM context, generic part */
+struct sgsn_mm_ctx *sgsn_mm_ctx_alloc(uint32_t rate_ctr_id)
{
struct sgsn_mm_ctx *ctx;
- ctx = talloc_zero(tall_bsc_ctx, struct sgsn_mm_ctx);
+ ctx = talloc_zero(tall_sgsn_ctx, struct sgsn_mm_ctx);
if (!ctx)
return NULL;
- memcpy(&ctx->ra, raid, sizeof(ctx->ra));
- ctx->ran_type = MM_CTX_T_GERAN_Gb;
- ctx->gb.tlli = tlli;
- ctx->gmm_state = GMM_DEREGISTERED;
- ctx->pmm_state = MM_IDLE;
ctx->auth_triplet.key_seq = GSM_KEY_SEQ_INVAL;
- ctx->ciph_algo = sgsn->cfg.cipher;
- LOGMMCTXP(LOGL_DEBUG, ctx, "Allocated with %s cipher.\n",
- get_value_string(gprs_cipher_names, ctx->ciph_algo));
- ctx->ctrg = rate_ctr_group_alloc(ctx, &mmctx_ctrg_desc, tlli);
+ ctx->ctrg = rate_ctr_group_alloc(ctx, &mmctx_ctrg_desc, rate_ctr_id);
if (!ctx->ctrg) {
LOGMMCTXP(LOGL_ERROR, ctx, "Cannot allocate counter group\n");
talloc_free(ctx);
return NULL;
}
+
+ ctx->gmm_fsm = osmo_fsm_inst_alloc(&gmm_fsm, ctx, ctx, LOGL_DEBUG, "gmm_fsm");
+ if (!ctx->gmm_fsm)
+ goto out;
+ ctx->gmm_att_req.fsm = osmo_fsm_inst_alloc(&gmm_attach_req_fsm, ctx, ctx, LOGL_DEBUG, "gb_gmm_req");
+ if (!ctx->gmm_att_req.fsm)
+ goto out;
+ ctx->gb.mm_state_fsm = osmo_fsm_inst_alloc(&mm_state_gb_fsm, ctx, ctx, LOGL_DEBUG, NULL);
+ if (!ctx->gb.mm_state_fsm)
+ goto out;
+#ifdef BUILD_IU
+ ctx->iu.mm_state_fsm = osmo_fsm_inst_alloc(&mm_state_iu_fsm, ctx, ctx, LOGL_DEBUG, NULL);
+ if (!ctx->iu.mm_state_fsm)
+ goto out;
+#endif
+
INIT_LLIST_HEAD(&ctx->pdp_list);
llist_add(&ctx->list, &sgsn_mm_ctxts);
return ctx;
+
+out:
+ if (ctx->iu.mm_state_fsm)
+ osmo_fsm_inst_free(ctx->iu.mm_state_fsm);
+ if (ctx->gb.mm_state_fsm)
+ osmo_fsm_inst_free(ctx->gb.mm_state_fsm);
+ if (ctx->gmm_att_req.fsm)
+ osmo_fsm_inst_free(ctx->gmm_att_req.fsm);
+ if (ctx->gmm_fsm)
+ osmo_fsm_inst_free(ctx->gmm_fsm);
+
+ rate_ctr_group_free(ctx->ctrg);
+ talloc_free(ctx);
+
+ return NULL;
+}
+/* Allocate a new SGSN MM context for GERAN_Gb */
+struct sgsn_mm_ctx *sgsn_mm_ctx_alloc_gb(uint32_t tlli,
+ const struct gprs_ra_id *raid)
+{
+ struct sgsn_mm_ctx *ctx;
+
+ ctx = sgsn_mm_ctx_alloc(tlli);
+ if (!ctx)
+ return NULL;
+
+ memcpy(&ctx->ra, raid, sizeof(ctx->ra));
+ ctx->ran_type = MM_CTX_T_GERAN_Gb;
+ ctx->gb.tlli = tlli;
+ ctx->ciph_algo = sgsn->cfg.cipher;
+ osmo_fsm_inst_update_id_f(ctx->gb.mm_state_fsm, "%" PRIu32, tlli);
+
+ LOGMMCTXP(LOGL_DEBUG, ctx, "Allocated with %s cipher.\n",
+ get_value_string(gprs_cipher_names, ctx->ciph_algo));
+ return ctx;
}
-/* Allocate a new SGSN MM context */
+/* Allocate a new SGSN MM context for UTRAN_Iu */
struct sgsn_mm_ctx *sgsn_mm_ctx_alloc_iu(void *uectx)
{
#if BUILD_IU
struct sgsn_mm_ctx *ctx;
+ struct ranap_ue_conn_ctx *ue_ctx = uectx;
- ctx = talloc_zero(tall_bsc_ctx, struct sgsn_mm_ctx);
+ ctx = sgsn_mm_ctx_alloc(ue_ctx->conn_id);
if (!ctx)
return NULL;
+ /* Need to get RAID from IU conn */
+ ctx->ra = ue_ctx->ra_id;
ctx->ran_type = MM_CTX_T_UTRAN_Iu;
- ctx->iu.ue_ctx = uectx;
+ ctx->iu.ue_ctx = ue_ctx;
ctx->iu.ue_ctx->rab_assign_addr_enc = sgsn->cfg.iu.rab_assign_addr_enc;
ctx->iu.new_key = 1;
- ctx->gmm_state = GMM_DEREGISTERED;
- ctx->pmm_state = PMM_DETACHED;
- ctx->auth_triplet.key_seq = GSM_KEY_SEQ_INVAL;
- ctx->ctrg = rate_ctr_group_alloc(ctx, &mmctx_ctrg_desc, 0);
- if (!ctx->ctrg) {
- LOGMMCTXP(LOGL_ERROR, ctx, "Cannot allocate counter group\n");
- talloc_free(ctx);
- return NULL;
- }
+ osmo_fsm_inst_update_id_f(ctx->iu.mm_state_fsm, "%" PRIu32, ue_ctx->conn_id);
- /* Need to get RAID from IU conn */
- ctx->ra = ctx->iu.ue_ctx->ra_id;
-
- INIT_LLIST_HEAD(&ctx->pdp_list);
-
- llist_add(&ctx->list, &sgsn_mm_ctxts);
return ctx;
#else
@@ -309,7 +349,6 @@ static void sgsn_mm_ctx_free(struct sgsn_mm_ctx *mm)
void sgsn_mm_ctx_cleanup_free(struct sgsn_mm_ctx *mm)
{
struct gprs_llc_llme *llme = NULL;
- uint32_t tlli = mm->gb.tlli;
struct sgsn_pdp_ctx *pdp, *pdp2;
struct sgsn_signal_data sig_data;
@@ -350,12 +389,22 @@ void sgsn_mm_ctx_cleanup_free(struct sgsn_mm_ctx *mm)
gprs_subscr_put(subscr);
}
+ if (mm->gmm_att_req.fsm)
+ gmm_att_req_free(mm);
+ if (mm->gb.mm_state_fsm)
+ osmo_fsm_inst_free(mm->gb.mm_state_fsm);
+ if (mm->iu.mm_state_fsm)
+ osmo_fsm_inst_free(mm->iu.mm_state_fsm);
+ if (mm->gmm_fsm)
+ osmo_fsm_inst_free(mm->gmm_fsm);
+
sgsn_mm_ctx_free(mm);
mm = NULL;
if (llme) {
/* TLLI unassignment, must be called after sgsn_mm_ctx_free */
- gprs_llgmm_assign(llme, tlli, 0xffffffff);
+ if (gprs_llgmm_unassign(llme) < 0)
+ LOGMMCTXP(LOGL_ERROR, mm, "gprs_llgmm_unassign failed, llme not freed!\n");
}
}
@@ -388,6 +437,7 @@ struct sgsn_pdp_ctx *sgsn_pdp_ctx_by_tid(const struct sgsn_mm_ctx *mm,
/* you don't want to use this directly, call sgsn_create_pdp_ctx() */
struct sgsn_pdp_ctx *sgsn_pdp_ctx_alloc(struct sgsn_mm_ctx *mm,
+ struct sgsn_ggsn_ctx *ggsn,
uint8_t nsapi)
{
struct sgsn_pdp_ctx *pdp;
@@ -396,11 +446,12 @@ struct sgsn_pdp_ctx *sgsn_pdp_ctx_alloc(struct sgsn_mm_ctx *mm,
if (pdp)
return NULL;
- pdp = talloc_zero(tall_bsc_ctx, struct sgsn_pdp_ctx);
+ pdp = talloc_zero(tall_sgsn_ctx, struct sgsn_pdp_ctx);
if (!pdp)
return NULL;
pdp->mm = mm;
+ pdp->ggsn = ggsn;
pdp->nsapi = nsapi;
pdp->ctrg = rate_ctr_group_alloc(pdp, &pdpctx_ctrg_desc, nsapi);
if (!pdp->ctrg) {
@@ -409,6 +460,7 @@ struct sgsn_pdp_ctx *sgsn_pdp_ctx_alloc(struct sgsn_mm_ctx *mm,
return NULL;
}
llist_add(&pdp->list, &mm->pdp_list);
+ sgsn_ggsn_ctx_add_pdp(pdp->ggsn, pdp);
llist_add(&pdp->g_list, &sgsn_pdp_ctxts);
return pdp;
@@ -432,7 +484,8 @@ void sgsn_pdp_ctx_terminate(struct sgsn_pdp_ctx *pdp)
if (pdp->mm->ran_type == MM_CTX_T_GERAN_Gb) {
/* Force the deactivation of the SNDCP layer */
- sndcp_sm_deactivate_ind(&pdp->mm->gb.llme->lle[pdp->sapi], pdp->nsapi);
+ if (pdp->mm->gb.llme)
+ sndcp_sm_deactivate_ind(&pdp->mm->gb.llme->lle[pdp->sapi], pdp->nsapi);
}
memset(&sig_data, 0, sizeof(sig_data));
@@ -440,10 +493,9 @@ void sgsn_pdp_ctx_terminate(struct sgsn_pdp_ctx *pdp)
osmo_signal_dispatch(SS_SGSN, S_SGSN_PDP_TERMINATE, &sig_data);
/* Detach from MM context */
- llist_del(&pdp->list);
- pdp->mm = NULL;
-
- sgsn_delete_pdp_ctx(pdp);
+ pdp_ctx_detach_mm_ctx(pdp);
+ if (pdp->ggsn)
+ sgsn_delete_pdp_ctx(pdp);
}
/*
@@ -462,6 +514,8 @@ void sgsn_pdp_ctx_free(struct sgsn_pdp_ctx *pdp)
rate_ctr_group_free(pdp->ctrg);
if (pdp->mm)
llist_del(&pdp->list);
+ if (pdp->ggsn)
+ sgsn_ggsn_ctx_remove_pdp(pdp->ggsn, pdp);
llist_del(&pdp->g_list);
/* _if_ we still have a library handle, at least set it to NULL
@@ -476,18 +530,36 @@ void sgsn_pdp_ctx_free(struct sgsn_pdp_ctx *pdp)
lib->priv = NULL;
}
- if (pdp->destroy_ggsn)
- sgsn_ggsn_ctx_free(pdp->ggsn);
talloc_free(pdp);
}
+void sgsn_ggsn_ctx_check_echo_timer(struct sgsn_ggsn_ctx *ggc)
+{
+ bool pending = osmo_timer_pending(&ggc->echo_timer);
+
+ /* Only enable if allowed by policy and at least 1 pdp ctx exists against ggsn */
+ if (!llist_empty(&ggc->pdp_list) && ggc->echo_interval) {
+ if (!pending)
+ osmo_timer_schedule(&ggc->echo_timer, ggc->echo_interval, 0);
+ } else {
+ if (pending)
+ osmo_timer_del(&ggc->echo_timer);
+ }
+}
+
/* GGSN contexts */
+static void echo_timer_cb(void *data)
+{
+ struct sgsn_ggsn_ctx *ggc = (struct sgsn_ggsn_ctx *) data;
+ sgsn_ggsn_echo_req(ggc);
+ osmo_timer_schedule(&ggc->echo_timer, ggc->echo_interval, 0);
+}
struct sgsn_ggsn_ctx *sgsn_ggsn_ctx_alloc(uint32_t id)
{
struct sgsn_ggsn_ctx *ggc;
- ggc = talloc_zero(tall_bsc_ctx, struct sgsn_ggsn_ctx);
+ ggc = talloc_zero(tall_sgsn_ctx, struct sgsn_ggsn_ctx);
if (!ggc)
return NULL;
@@ -496,6 +568,8 @@ struct sgsn_ggsn_ctx *sgsn_ggsn_ctx_alloc(uint32_t id)
ggc->remote_restart_ctr = -1;
/* if we are called from config file parse, this gsn doesn't exist yet */
ggc->gsn = sgsn->gsn;
+ INIT_LLIST_HEAD(&ggc->pdp_list);
+ osmo_timer_setup(&ggc->echo_timer, echo_timer_cb, ggc);
llist_add(&ggc->list, &sgsn_ggsn_ctxts);
return ggc;
@@ -503,6 +577,7 @@ struct sgsn_ggsn_ctx *sgsn_ggsn_ctx_alloc(uint32_t id)
void sgsn_ggsn_ctx_free(struct sgsn_ggsn_ctx *ggc)
{
+ OSMO_ASSERT(llist_empty(&ggc->pdp_list));
llist_del(&ggc->list);
talloc_free(ggc);
}
@@ -546,7 +621,7 @@ static struct apn_ctx *sgsn_apn_ctx_alloc(const char *ap_name, const char *imsi_
{
struct apn_ctx *actx;
- actx = talloc_zero(tall_bsc_ctx, struct apn_ctx);
+ actx = talloc_zero(tall_sgsn_ctx, struct apn_ctx);
if (!actx)
return NULL;
actx->name = talloc_strdup(actx, ap_name);
@@ -641,10 +716,11 @@ uint32_t sgsn_alloc_ptmsi(void)
{
struct sgsn_mm_ctx *mm;
uint32_t ptmsi = 0xdeadbeef;
- int max_retries = 100;
+ int max_retries = 100, rc = 0;
restart:
- if (RAND_bytes((uint8_t *) &ptmsi, sizeof(ptmsi)) != 1)
+ rc = osmo_get_rand_id((uint8_t *) &ptmsi, sizeof(ptmsi));
+ if (rc < 0)
goto failed;
/* Enforce that the 2 MSB are set without loosing the distance between
@@ -658,12 +734,12 @@ restart:
* Alternatively, a freeze list could be used if another PRNG is used
* or when this approach proves to be not sufficient.
*/
- if (ptmsi >= 0xC0000000) {
+ if (ptmsi >= GSM23003_TMSI_SGSN_MASK) {
if (!max_retries--)
goto failed;
goto restart;
}
- ptmsi |= 0xC0000000;
+ ptmsi |= GSM23003_TMSI_SGSN_MASK;
if (ptmsi == GSM_RESERVED_TMSI) {
if (!max_retries--)
@@ -682,43 +758,68 @@ restart:
return ptmsi;
failed:
- LOGP(DGPRS, LOGL_ERROR, "Failed to allocate a P-TMSI\n");
+ LOGP(DGPRS, LOGL_ERROR, "Failed to allocate a P-TMSI: %d (%s)\n", rc, strerror(-rc));
return GSM_RESERVED_TMSI;
}
-static void drop_one_pdp(struct sgsn_pdp_ctx *pdp)
+void sgsn_ggsn_ctx_drop_pdp(struct sgsn_pdp_ctx *pctx)
{
- if (pdp->mm->gmm_state == GMM_REGISTERED_NORMAL)
- gsm48_tx_gsm_deact_pdp_req(pdp, GSM_CAUSE_NET_FAIL);
- else {
+ /* the MM context can be deleted while the GGSN is not reachable or
+ * if has been crashed. */
+ if (pctx->mm && pctx->mm->gmm_fsm->state == ST_GMM_REGISTERED_NORMAL) {
+ gsm48_tx_gsm_deact_pdp_req(pctx, GSM_CAUSE_NET_FAIL, true);
+ sgsn_ggsn_ctx_remove_pdp(pctx->ggsn, pctx);
+ } else {
/* FIXME: GPRS paging in case MS is SUSPENDED */
- LOGPDPCTXP(LOGL_NOTICE, pdp, "Hard-dropping PDP ctx due to GGSN "
+ LOGPDPCTXP(LOGL_NOTICE, pctx, "Hard-dropping PDP ctx due to GGSN "
"recovery\n");
/* FIXME: how to tell this to libgtp? */
- sgsn_pdp_ctx_free(pdp);
+ sgsn_pdp_ctx_free(pctx);
}
}
/* High-level function to be called in case a GGSN has disappeared or
- * otherwise lost state (recovery procedure) */
-int drop_all_pdp_for_ggsn(struct sgsn_ggsn_ctx *ggsn)
+ * otherwise lost state (recovery procedure). It will detach all related pdp ctx
+ * from a ggsn and communicate deact to MS. Optionally (!NULL), one pdp ctx can
+ * be kept alive to allow handling later message which contained the Recovery IE. */
+int sgsn_ggsn_ctx_drop_all_pdp_except(struct sgsn_ggsn_ctx *ggsn, struct sgsn_pdp_ctx *except)
{
- struct sgsn_mm_ctx *mm;
int num = 0;
- llist_for_each_entry(mm, &sgsn_mm_ctxts, list) {
- struct sgsn_pdp_ctx *pdp;
- llist_for_each_entry(pdp, &mm->pdp_list, list) {
- if (pdp->ggsn == ggsn) {
- drop_one_pdp(pdp);
- num++;
- }
- }
+ struct sgsn_pdp_ctx *pdp, *pdp2;
+ llist_for_each_entry_safe(pdp, pdp2, &ggsn->pdp_list, ggsn_list) {
+ if (pdp == except)
+ continue;
+ sgsn_ggsn_ctx_drop_pdp(pdp);
+ num++;
}
return num;
}
+int sgsn_ggsn_ctx_drop_all_pdp(struct sgsn_ggsn_ctx *ggsn)
+{
+ return sgsn_ggsn_ctx_drop_all_pdp_except(ggsn, NULL);
+}
+
+void sgsn_ggsn_ctx_add_pdp(struct sgsn_ggsn_ctx *ggc, struct sgsn_pdp_ctx *pdp)
+{
+ llist_add(&pdp->ggsn_list, &ggc->pdp_list);
+ sgsn_ggsn_ctx_check_echo_timer(ggc);
+}
+void sgsn_ggsn_ctx_remove_pdp(struct sgsn_ggsn_ctx *ggc, struct sgsn_pdp_ctx *pdp)
+{
+ llist_del(&pdp->ggsn_list);
+ sgsn_ggsn_ctx_check_echo_timer(ggc);
+ if (pdp->destroy_ggsn)
+ sgsn_ggsn_ctx_free(pdp->ggsn);
+ pdp->ggsn = NULL;
+ /* Drop references to libgtp since the conn is down */
+ if (pdp->lib)
+ pdp_freepdp(pdp->lib);
+ pdp->lib = NULL;
+}
+
void sgsn_update_subscriber_data(struct sgsn_mm_ctx *mmctx)
{
OSMO_ASSERT(mmctx != NULL);
@@ -866,7 +967,8 @@ struct sgsn_ggsn_ctx *sgsn_mm_ctx_find_ggsn_ctx(struct sgsn_mm_ctx *mmctx,
LOGMMCTXP(LOGL_NOTICE, mmctx,
"No static GGSN configured. Selected APN '%s'\n",
selected_apn_str);
- return NULL;
+ *gsm_cause = GSM_CAUSE_MISSING_APN;
+ return NULL;
}
LOGMMCTXP(LOGL_INFO, mmctx,
@@ -903,7 +1005,7 @@ static void sgsn_llme_check_cb(void *data_)
int rc;
- rc = clock_gettime(CLOCK_MONOTONIC, &now_tp);
+ rc = osmo_clock_gettime(CLOCK_MONOTONIC, &now_tp);
OSMO_ASSERT(rc >= 0);
now = now_tp.tv_sec;
@@ -927,9 +1029,19 @@ static void sgsn_llme_check_cb(void *data_)
osmo_timer_schedule(&sgsn->llme_timer, GPRS_LLME_CHECK_TICK, 0);
}
-void sgsn_inst_init()
+struct sgsn_instance *sgsn_instance_alloc(void *talloc_ctx)
+{
+ struct sgsn_instance *inst;
+ inst = talloc_zero(talloc_ctx, struct sgsn_instance);
+ inst->cfg.gtp_statedir = talloc_strdup(inst, "./");
+ inst->cfg.auth_policy = SGSN_AUTH_POLICY_CLOSED;
+ inst->cfg.require_authentication = true; /* only applies if auth_policy is REMOTE */
+ inst->cfg.gsup_server_port = OSMO_GSUP_PORT;
+ return inst;
+}
+
+void sgsn_inst_init(struct sgsn_instance *sgsn)
{
osmo_timer_setup(&sgsn->llme_timer, sgsn_llme_check_cb, NULL);
osmo_timer_schedule(&sgsn->llme_timer, GPRS_LLME_CHECK_TICK, 0);
}
-
diff --git a/src/sgsn/gprs_sm.c b/src/sgsn/gprs_sm.c
new file mode 100644
index 000000000..f8019ab6a
--- /dev/null
+++ b/src/sgsn/gprs_sm.c
@@ -0,0 +1,754 @@
+/* Section "9.5 GPRS Session Management Messages"
+ * 3GPP TS 04.08 version 7.21.0 Release 1998 / ETSI TS 100 940 V7.21.0 */
+
+/* (C) 2009-2015 by Harald Welte <laforge@gnumonks.org>
+ * (C) 2010 by On-Waves
+ * (C) 2019 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+
+#include "bscconfig.h"
+
+#include <osmocom/core/rate_ctr.h>
+#include <osmocom/core/tdef.h>
+#include <osmocom/gsm/apn.h>
+#include <osmocom/gprs/gprs_bssgp.h>
+
+#include <osmocom/sgsn/gprs_sm.h>
+#include <osmocom/sgsn/gprs_gmm.h>
+#include <osmocom/sgsn/gprs_utils.h>
+#include <osmocom/sgsn/sgsn.h>
+#include <osmocom/sgsn/debug.h>
+#include <osmocom/sgsn/gprs_llc.h>
+#include <osmocom/sgsn/gprs_sndcp.h>
+#include <osmocom/sgsn/gprs_ranap.h>
+
+extern void *tall_sgsn_ctx;
+
+/* 3GPP TS 04.08 sec 6.1.3.4.3(.a) "Abnormal cases" */
+#define T339X_MAX_RETRANS 4
+
+static const struct tlv_definition gsm48_sm_att_tlvdef = {
+ .def = {
+ [GSM48_IE_GSM_APN] = { TLV_TYPE_TLV, 0 },
+ [GSM48_IE_GSM_PROTO_CONF_OPT] = { TLV_TYPE_TLV, 0 },
+ [GSM48_IE_GSM_PDP_ADDR] = { TLV_TYPE_TLV, 0 },
+ [GSM48_IE_GSM_AA_TMR] = { TLV_TYPE_TV, 1 },
+ [GSM48_IE_GSM_NAME_FULL] = { TLV_TYPE_TLV, 0 },
+ [GSM48_IE_GSM_NAME_SHORT] = { TLV_TYPE_TLV, 0 },
+ [GSM48_IE_GSM_TIMEZONE] = { TLV_TYPE_FIXED, 1 },
+ [GSM48_IE_GSM_UTC_AND_TZ] = { TLV_TYPE_FIXED, 7 },
+ [GSM48_IE_GSM_LSA_ID] = { TLV_TYPE_TLV, 0 },
+ },
+};
+
+static struct gsm48_qos default_qos = {
+ .delay_class = 4, /* best effort */
+ .reliab_class = GSM48_QOS_RC_LLC_UN_RLC_ACK_DATA_PROT,
+ .peak_tput = GSM48_QOS_PEAK_TPUT_32000bps,
+ .preced_class = GSM48_QOS_PC_NORMAL,
+ .mean_tput = GSM48_QOS_MEAN_TPUT_BEST_EFFORT,
+ .traf_class = GSM48_QOS_TC_INTERACTIVE,
+ .deliv_order = GSM48_QOS_DO_UNORDERED,
+ .deliv_err_sdu = GSM48_QOS_ERRSDU_YES,
+ .max_sdu_size = GSM48_QOS_MAXSDU_1520,
+ .max_bitrate_up = GSM48_QOS_MBRATE_63k,
+ .max_bitrate_down = GSM48_QOS_MBRATE_63k,
+ .resid_ber = GSM48_QOS_RBER_5e_2,
+ .sdu_err_ratio = GSM48_QOS_SERR_1e_2,
+ .handling_prio = 3,
+ .xfer_delay = 0x10, /* 200ms */
+ .guar_bitrate_up = GSM48_QOS_MBRATE_0k,
+ .guar_bitrate_down = GSM48_QOS_MBRATE_0k,
+ .sig_ind = 0, /* not optimised for signalling */
+ .max_bitrate_down_ext = 0, /* use octet 9 */
+ .guar_bitrate_down_ext = 0, /* use octet 13 */
+};
+
+/* GPRS SESSION MANAGEMENT */
+
+static void pdpctx_timer_cb(void *_mm);
+
+static void pdpctx_timer_rearm(struct sgsn_pdp_ctx *pdp, unsigned int T)
+{
+ unsigned long seconds;
+ if (osmo_timer_pending(&pdp->timer))
+ LOGPDPCTXP(LOGL_ERROR, pdp, "Scheduling PDP timer %u while old "
+ "timer %u pending\n", T, pdp->T);
+ seconds = osmo_tdef_get(sgsn->cfg.T_defs, T, OSMO_TDEF_S, -1);
+ osmo_timer_schedule(&pdp->timer, seconds, 0);
+}
+
+static void pdpctx_timer_start(struct sgsn_pdp_ctx *pdp, unsigned int T)
+{
+ if (osmo_timer_pending(&pdp->timer))
+ LOGPDPCTXP(LOGL_ERROR, pdp, "Starting PDP timer %u while old "
+ "timer %u pending\n", T, pdp->T);
+ pdp->T = T;
+ pdp->num_T_exp = 0;
+
+ osmo_timer_setup(&pdp->timer, pdpctx_timer_cb, pdp);
+ pdpctx_timer_rearm(pdp, pdp->T);
+}
+
+static void pdpctx_timer_stop(struct sgsn_pdp_ctx *pdp, unsigned int T)
+{
+ if (pdp->T != T)
+ LOGPDPCTXP(LOGL_ERROR, pdp, "Stopping PDP timer %u but "
+ "%u is running\n", T, pdp->T);
+ osmo_timer_del(&pdp->timer);
+}
+
+void pdp_ctx_detach_mm_ctx(struct sgsn_pdp_ctx *pdp)
+{
+ /* Detach from MM context */
+ llist_del(&pdp->list);
+ pdp->mm = NULL;
+
+ /* stop timer 3395 */
+ pdpctx_timer_stop(pdp, 3395);
+}
+
+#if 0
+static void msgb_put_pdp_addr_ipv4(struct msgb *msg, uint32_t ipaddr)
+{
+ uint8_t v[6];
+
+ v[0] = PDP_TYPE_ORG_IETF;
+ v[1] = PDP_TYPE_N_IETF_IPv4;
+ *(uint32_t *)(v+2) = htonl(ipaddr);
+
+ msgb_tlv_put(msg, GSM48_IE_GSM_PDP_ADDR, sizeof(v), v);
+}
+
+static void msgb_put_pdp_addr_ppp(struct msgb *msg)
+{
+ uint8_t v[2];
+
+ v[0] = PDP_TYPE_ORG_ETSI;
+ v[1] = PDP_TYPE_N_ETSI_PPP;
+
+ msgb_tlv_put(msg, GSM48_IE_GSM_PDP_ADDR, sizeof(v), v);
+}
+#endif
+
+/* Chapter 9.4.18 */
+static int _tx_status(struct msgb *msg, uint8_t cause,
+ struct sgsn_mm_ctx *mmctx)
+{
+ struct gsm48_hdr *gh;
+
+ /* MMCTX might be NULL! */
+
+ DEBUGP(DMM, "<- GPRS MM STATUS (cause: %s)\n",
+ get_value_string(gsm48_gmm_cause_names, cause));
+
+ gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh) + 1);
+ gh->proto_discr = GSM48_PDISC_SM_GPRS;
+ gh->msg_type = GSM48_MT_GSM_STATUS;
+ gh->data[0] = cause;
+
+ return gsm48_gmm_sendmsg(msg, 0, mmctx, true);
+}
+
+static int gsm48_tx_sm_status(struct sgsn_mm_ctx *mmctx, uint8_t cause)
+{
+ struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 SM STATUS");
+
+ mmctx2msgid(msg, mmctx);
+ return _tx_status(msg, cause, mmctx);
+}
+
+/* 3GPP TS 24.008 § 9.5.2: Activate PDP Context Accept */
+int gsm48_tx_gsm_act_pdp_acc(struct sgsn_pdp_ctx *pdp)
+{
+ struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 PDP ACC");
+ struct gsm48_hdr *gh;
+ uint8_t transaction_id = pdp->ti ^ 0x8; /* flip */
+
+ LOGPDPCTXP(LOGL_INFO, pdp, "<- ACTIVATE PDP CONTEXT ACK\n");
+ rate_ctr_inc(&sgsn->rate_ctrs->ctr[CTR_PDP_ACTIVATE_ACCEPT]);
+
+ mmctx2msgid(msg, pdp->mm);
+
+ gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
+ gh->proto_discr = GSM48_PDISC_SM_GPRS | (transaction_id << 4);
+ gh->msg_type = GSM48_MT_GSM_ACT_PDP_ACK;
+
+ /* Negotiated LLC SAPI */
+ msgb_v_put(msg, pdp->sapi);
+
+ /* FIXME: copy QoS parameters from original request */
+ //msgb_lv_put(msg, pdp->lib->qos_neg.l, pdp->lib->qos_neg.v);
+ msgb_lv_put(msg, sizeof(default_qos), (uint8_t *)&default_qos);
+
+ /* Radio priority 10.5.7.2 */
+ msgb_v_put(msg, pdp->lib->radio_pri);
+
+ /* PDP address */
+ /* Highest 4 bits of first byte need to be set to 1, otherwise
+ * the IE is identical with the 04.08 PDP Address IE */
+ pdp->lib->eua.v[0] &= ~0xf0;
+ msgb_tlv_put(msg, GSM48_IE_GSM_PDP_ADDR,
+ pdp->lib->eua.l, pdp->lib->eua.v);
+ pdp->lib->eua.v[0] |= 0xf0;
+
+ /* Optional: Protocol configuration options (FIXME: why 'req') */
+ if (pdp->lib->pco_req.l)
+ msgb_tlv_put(msg, GSM48_IE_GSM_PROTO_CONF_OPT,
+ pdp->lib->pco_req.l, pdp->lib->pco_req.v);
+
+ /* Optional: Packet Flow Identifier */
+
+ return gsm48_gmm_sendmsg(msg, 0, pdp->mm, true);
+}
+
+/* 3GPP TS 24.008 § 9.5.3: Activate PDP Context reject */
+int gsm48_tx_gsm_act_pdp_rej(struct sgsn_mm_ctx *mm, uint8_t tid,
+ uint8_t cause, uint8_t pco_len, uint8_t *pco_v)
+{
+ struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 PDP REJ");
+ struct gsm48_hdr *gh;
+ uint8_t transaction_id = tid ^ 0x8; /* flip */
+
+ LOGMMCTXP(LOGL_NOTICE, mm, "<- ACTIVATE PDP CONTEXT REJ: %s\n",
+ get_value_string(gsm48_gsm_cause_names, cause));
+ rate_ctr_inc(&sgsn->rate_ctrs->ctr[CTR_PDP_ACTIVATE_REJECT]);
+
+ mmctx2msgid(msg, mm);
+
+ gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
+ gh->proto_discr = GSM48_PDISC_SM_GPRS | (transaction_id << 4);
+ gh->msg_type = GSM48_MT_GSM_ACT_PDP_REJ;
+
+ msgb_v_put(msg, cause);
+ if (pco_len && pco_v)
+ msgb_tlv_put(msg, GSM48_IE_GSM_PROTO_CONF_OPT, pco_len, pco_v);
+
+ return gsm48_gmm_sendmsg(msg, 0, mm, true);
+}
+
+/* 3GPP TS 24.008 § 9.5.8: Deactivate PDP Context Request */
+static int _gsm48_tx_gsm_deact_pdp_req(struct sgsn_mm_ctx *mm, uint8_t tid,
+ uint8_t sm_cause, bool teardown)
+{
+ struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 PDP DET REQ");
+ struct gsm48_hdr *gh;
+ uint8_t transaction_id = tid ^ 0x8; /* flip */
+ uint8_t tear_down_ind = (0x9 << 4) | (!!teardown);
+
+ LOGMMCTXP(LOGL_INFO, mm, "<- DEACTIVATE PDP CONTEXT REQ\n");
+ rate_ctr_inc(&sgsn->rate_ctrs->ctr[CTR_PDP_DL_DEACTIVATE_REQUEST]);
+
+ mmctx2msgid(msg, mm);
+
+ gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
+ gh->proto_discr = GSM48_PDISC_SM_GPRS | (transaction_id << 4);
+ gh->msg_type = GSM48_MT_GSM_DEACT_PDP_REQ;
+
+ msgb_v_put(msg, sm_cause);
+ msgb_v_put(msg, tear_down_ind);
+
+ return gsm48_gmm_sendmsg(msg, 0, mm, true);
+}
+int gsm48_tx_gsm_deact_pdp_req(struct sgsn_pdp_ctx *pdp, uint8_t sm_cause, bool teardown)
+{
+ pdpctx_timer_start(pdp, 3395);
+
+ return _gsm48_tx_gsm_deact_pdp_req(pdp->mm, pdp->ti, sm_cause, teardown);
+}
+
+/* 3GPP TS 24.008 § 9.5.9: Deactivate PDP Context Accept */
+static int _gsm48_tx_gsm_deact_pdp_acc(struct sgsn_mm_ctx *mm, uint8_t tid)
+{
+ struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 PDP DET ACC");
+ struct gsm48_hdr *gh;
+ uint8_t transaction_id = tid ^ 0x8; /* flip */
+
+ LOGMMCTXP(LOGL_INFO, mm, "<- DEACTIVATE PDP CONTEXT ACK\n");
+ rate_ctr_inc(&sgsn->rate_ctrs->ctr[CTR_PDP_DL_DEACTIVATE_ACCEPT]);
+
+ mmctx2msgid(msg, mm);
+
+ gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
+ gh->proto_discr = GSM48_PDISC_SM_GPRS | (transaction_id << 4);
+ gh->msg_type = GSM48_MT_GSM_DEACT_PDP_ACK;
+
+ return gsm48_gmm_sendmsg(msg, 0, mm, true);
+}
+int gsm48_tx_gsm_deact_pdp_acc(struct sgsn_pdp_ctx *pdp)
+{
+ return _gsm48_tx_gsm_deact_pdp_acc(pdp->mm, pdp->ti);
+}
+
+static int activate_ggsn(struct sgsn_mm_ctx *mmctx,
+ struct sgsn_ggsn_ctx *ggsn, const uint8_t transaction_id,
+ const uint8_t req_nsapi, const uint8_t req_llc_sapi,
+ struct tlv_parsed *tp, int destroy_ggsn)
+{
+ struct sgsn_pdp_ctx *pdp;
+
+ LOGMMCTXP(LOGL_DEBUG, mmctx, "Using GGSN %u\n", ggsn->id);
+ ggsn->gsn = sgsn->gsn;
+ pdp = sgsn_create_pdp_ctx(ggsn, mmctx, req_nsapi, tp);
+ if (!pdp)
+ return -1;
+
+ /* Store SAPI and Transaction Identifier */
+ pdp->sapi = req_llc_sapi;
+ pdp->ti = transaction_id;
+ pdp->destroy_ggsn = destroy_ggsn;
+
+ return 0;
+}
+
+static void ggsn_lookup_cb(void *arg, int status, int timeouts, struct hostent *hostent)
+{
+ struct sgsn_ggsn_ctx *ggsn;
+ struct sgsn_ggsn_lookup *lookup = arg;
+ struct in_addr *addr = NULL;
+ char buf[INET_ADDRSTRLEN];
+
+ /* The context is gone while we made a request */
+ if (!lookup->mmctx) {
+ talloc_free(lookup->orig_msg);
+ talloc_free(lookup);
+ return;
+ }
+
+ if (status != ARES_SUCCESS) {
+ struct sgsn_mm_ctx *mmctx = lookup->mmctx;
+
+ LOGMMCTXP(LOGL_ERROR, mmctx, "DNS query failed.\n");
+
+ /* Need to try with three digits now */
+ if (lookup->state == SGSN_GGSN_2DIGIT) {
+ char *hostname;
+ int rc;
+
+ lookup->state = SGSN_GGSN_3DIGIT;
+ hostname = osmo_apn_qualify_from_imsi(mmctx->imsi,
+ lookup->apn_str, 1);
+ LOGMMCTXP(LOGL_DEBUG, mmctx,
+ "Going to query %s\n", hostname);
+ rc = sgsn_ares_query(sgsn, hostname,
+ ggsn_lookup_cb, lookup);
+ if (rc != 0) {
+ LOGMMCTXP(LOGL_ERROR, mmctx, "Couldn't start GGSN\n");
+ goto reject_due_failure;
+ }
+ return;
+ }
+
+ LOGMMCTXP(LOGL_ERROR, mmctx, "Couldn't resolve GGSN\n");
+ goto reject_due_failure;
+ }
+
+ if (hostent->h_length != sizeof(struct in_addr)) {
+ LOGMMCTXP(LOGL_ERROR, lookup->mmctx,
+ "Wrong addr size(%zu)\n", sizeof(struct in_addr));
+ goto reject_due_failure;
+ }
+
+ /* Get the first addr from the list */
+ addr = (struct in_addr *) hostent->h_addr_list[0];
+ if (!addr) {
+ LOGMMCTXP(LOGL_ERROR, lookup->mmctx, "No host address.\n");
+ goto reject_due_failure;
+ }
+
+ ggsn = sgsn_ggsn_ctx_alloc(UINT32_MAX);
+ if (!ggsn) {
+ LOGMMCTXP(LOGL_ERROR, lookup->mmctx, "Failed to create ggsn.\n");
+ goto reject_due_failure;
+ }
+ ggsn->remote_addr = *addr;
+ LOGMMCTXP(LOGL_NOTICE, lookup->mmctx,
+ "Selected %s as GGSN.\n",
+ inet_ntop(AF_INET, addr, buf, sizeof(buf)));
+
+ /* forget about the ggsn look-up */
+ lookup->mmctx->ggsn_lookup = NULL;
+
+ activate_ggsn(lookup->mmctx, ggsn, lookup->ti, lookup->nsapi,
+ lookup->sapi, &lookup->tp, 1);
+
+ /* Now free it */
+ talloc_free(lookup->orig_msg);
+ talloc_free(lookup);
+ return;
+
+reject_due_failure:
+ gsm48_tx_gsm_act_pdp_rej(lookup->mmctx, lookup->ti,
+ GMM_CAUSE_NET_FAIL, 0, NULL);
+ lookup->mmctx->ggsn_lookup = NULL;
+ talloc_free(lookup->orig_msg);
+ talloc_free(lookup);
+}
+
+static int do_act_pdp_req(struct sgsn_mm_ctx *mmctx, struct msgb *msg, bool *delete)
+{
+ struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_gmmh(msg);
+ struct gsm48_act_pdp_ctx_req *act_req = (struct gsm48_act_pdp_ctx_req *) gh->data;
+ uint8_t req_qos_len, req_pdpa_len;
+ uint8_t *req_qos, *req_pdpa;
+ struct tlv_parsed tp;
+ uint8_t transaction_id = gsm48_hdr_trans_id(gh);
+ struct sgsn_ggsn_ctx *ggsn;
+ struct sgsn_pdp_ctx *pdp;
+ enum gsm48_gsm_cause gsm_cause;
+ char apn_str[GSM_APN_LENGTH] = { 0, };
+ char *hostname;
+ int rc;
+ struct gprs_llc_lle *lle;
+ char buf[INET_ADDRSTRLEN];
+
+ LOGMMCTXP(LOGL_INFO, mmctx, "-> ACTIVATE PDP CONTEXT REQ: SAPI=%u NSAPI=%u ",
+ act_req->req_llc_sapi, act_req->req_nsapi);
+
+ /* FIXME: length checks! */
+ req_qos_len = act_req->data[0];
+ req_qos = act_req->data + 1; /* 10.5.6.5 */
+ req_pdpa_len = act_req->data[1 + req_qos_len];
+ req_pdpa = act_req->data + 1 + req_qos_len + 1; /* 10.5.6.4 */
+
+ switch (req_pdpa[0] & 0xf) {
+ case 0x0:
+ DEBUGPC(DMM, "ETSI ");
+ break;
+ case 0x1:
+ DEBUGPC(DMM, "IETF ");
+ break;
+ case 0xf:
+ DEBUGPC(DMM, "Empty ");
+ break;
+ }
+
+ switch (req_pdpa[1]) {
+ case 0x21:
+ DEBUGPC(DMM, "IPv4 ");
+ if (req_pdpa_len >= 6) {
+ struct in_addr ia;
+ ia.s_addr = ntohl(*((uint32_t *) (req_pdpa+2)));
+ DEBUGPC(DMM, "%s ", inet_ntop(AF_INET, &ia, buf, sizeof(buf)));
+ }
+ break;
+ case 0x57:
+ DEBUGPC(DMM, "IPv6 ");
+ if (req_pdpa_len >= 18) {
+ /* FIXME: print IPv6 address */
+ }
+ break;
+ default:
+ DEBUGPC(DMM, "0x%02x ", req_pdpa[1]);
+ break;
+ }
+
+ LOGPC(DMM, LOGL_INFO, "\n");
+
+ /* Check if NSAPI is out of range (TS 04.65 / 7.2) */
+ if (act_req->req_nsapi < 5 || act_req->req_nsapi > 15) {
+ /* Send reject with GSM_CAUSE_INV_MAND_INFO */
+ return gsm48_tx_gsm_act_pdp_rej(mmctx, transaction_id,
+ GSM_CAUSE_INV_MAND_INFO,
+ 0, NULL);
+ }
+
+ /* Optional: Access Point Name, Protocol Config Options */
+ if (req_pdpa + req_pdpa_len < msg->data + msg->len)
+ tlv_parse(&tp, &gsm48_sm_att_tlvdef, req_pdpa + req_pdpa_len,
+ (msg->data + msg->len) - (req_pdpa + req_pdpa_len), 0, 0);
+ else
+ memset(&tp, 0, sizeof(tp));
+
+
+ /* put the non-TLV elements in the TLV parser structure to
+ * pass them on to the SGSN / GTP code */
+ tp.lv[OSMO_IE_GSM_REQ_QOS].len = req_qos_len;
+ tp.lv[OSMO_IE_GSM_REQ_QOS].val = req_qos;
+ tp.lv[OSMO_IE_GSM_REQ_PDP_ADDR].len = req_pdpa_len;
+ tp.lv[OSMO_IE_GSM_REQ_PDP_ADDR].val = req_pdpa;
+
+ /* Check if NSAPI is already in use */
+ pdp = sgsn_pdp_ctx_by_nsapi(mmctx, act_req->req_nsapi);
+ if (pdp) {
+ /* Make sure pdp ctx was not already torn down on GTP side */
+ if (!pdp->lib) {
+ gsm_cause = GSM_CAUSE_REACT_RQD;
+ goto no_context;
+ }
+ /* We already have a PDP context for this TLLI + NSAPI tuple */
+ if (pdp->sapi == act_req->req_llc_sapi &&
+ pdp->ti == transaction_id) {
+ /* This apparently is a re-transmission of a PDP CTX
+ * ACT REQ (our ACT ACK must have got dropped) */
+ rc = gsm48_tx_gsm_act_pdp_acc(pdp);
+ if (rc < 0)
+ return rc;
+
+ if (pdp->mm->ran_type == MM_CTX_T_GERAN_Gb) {
+ /* Also re-transmit the SNDCP XID message */
+ lle = &pdp->mm->gb.llme->lle[pdp->sapi];
+ rc = sndcp_sn_xid_req(lle,pdp->nsapi);
+ if (rc < 0)
+ return rc;
+ }
+
+ return 0;
+ }
+
+ /* Send reject with GSM_CAUSE_NSAPI_IN_USE */
+ return gsm48_tx_gsm_act_pdp_rej(mmctx, transaction_id,
+ GSM_CAUSE_NSAPI_IN_USE,
+ 0, NULL);
+ }
+
+ if (mmctx->ggsn_lookup) {
+ if (mmctx->ggsn_lookup->sapi == act_req->req_llc_sapi &&
+ mmctx->ggsn_lookup->ti == transaction_id) {
+ LOGMMCTXP(LOGL_NOTICE, mmctx,
+ "Re-transmission while doing look-up. Ignoring.\n");
+ return 0;
+ }
+ }
+
+ /* Only increment counter for a real activation, after we checked
+ * for re-transmissions */
+ rate_ctr_inc(&mmctx->ctrg->ctr[GMM_CTR_PDP_CTX_ACT]);
+
+ /* Determine GGSN based on APN and subscription options */
+ ggsn = sgsn_mm_ctx_find_ggsn_ctx(mmctx, &tp, &gsm_cause, apn_str);
+ if (ggsn)
+ return activate_ggsn(mmctx, ggsn, transaction_id,
+ act_req->req_nsapi, act_req->req_llc_sapi,
+ &tp, 0);
+
+ if (strlen(apn_str) == 0)
+ goto no_context;
+ if (!sgsn->cfg.dynamic_lookup)
+ goto no_context;
+
+ /* schedule a dynamic look-up */
+ mmctx->ggsn_lookup = talloc_zero(tall_sgsn_ctx, struct sgsn_ggsn_lookup);
+ if (!mmctx->ggsn_lookup)
+ goto no_context;
+
+ mmctx->ggsn_lookup->state = SGSN_GGSN_2DIGIT;
+ mmctx->ggsn_lookup->mmctx = mmctx;
+ strcpy(mmctx->ggsn_lookup->apn_str, apn_str);
+
+ mmctx->ggsn_lookup->orig_msg = msg;
+ mmctx->ggsn_lookup->tp = tp;
+
+ mmctx->ggsn_lookup->ti = transaction_id;
+ mmctx->ggsn_lookup->nsapi = act_req->req_nsapi;
+ mmctx->ggsn_lookup->sapi = act_req->req_llc_sapi;
+
+ hostname = osmo_apn_qualify_from_imsi(mmctx->imsi,
+ mmctx->ggsn_lookup->apn_str, 0);
+
+ LOGMMCTXP(LOGL_DEBUG, mmctx, "Going to query %s\n", hostname);
+ rc = sgsn_ares_query(sgsn, hostname,
+ ggsn_lookup_cb, mmctx->ggsn_lookup);
+ if (rc != 0) {
+ LOGMMCTXP(LOGL_ERROR, mmctx, "Failed to start ares query.\n");
+ goto no_context;
+ }
+ *delete = 0;
+
+ return 0;
+
+no_context:
+ LOGMMCTXP(LOGL_ERROR, mmctx, "No GGSN context found!\n");
+ return gsm48_tx_gsm_act_pdp_rej(mmctx, transaction_id,
+ gsm_cause, 0, NULL);
+}
+
+/* 3GPP TS 24.008 § 9.5.1: Activate PDP Context Request */
+static int gsm48_rx_gsm_act_pdp_req(struct sgsn_mm_ctx *mmctx,
+ struct msgb *_msg)
+{
+ bool delete = 1;
+ struct msgb *msg;
+ int rc;
+
+ rate_ctr_inc(&sgsn->rate_ctrs->ctr[CTR_PDP_ACTIVATE_REQUEST]);
+
+ /*
+ * This is painful. We might not have a static GGSN
+ * configuration and then would need to copy the msg
+ * and re-do most of this routine (or call it again
+ * and make sure it only goes through the dynamic
+ * resolving. The question is what to optimize for
+ * and the dynamic resolution will be the right thing
+ * in the long run.
+ */
+ msg = bssgp_msgb_copy(_msg, __func__);
+ if (!msg) {
+ struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_gmmh(_msg);
+ uint8_t transaction_id = gsm48_hdr_trans_id(gh);
+
+ LOGMMCTXP(LOGL_ERROR, mmctx, "-> ACTIVATE PDP CONTEXT REQ failed copy.\n");
+ /* Send reject with GSM_CAUSE_INV_MAND_INFO */
+ return gsm48_tx_gsm_act_pdp_rej(mmctx, transaction_id,
+ GSM_CAUSE_NET_FAIL,
+ 0, NULL);
+ }
+
+ rc = do_act_pdp_req(mmctx, msg, &delete);
+ if (delete)
+ msgb_free(msg);
+ return rc;
+}
+
+/* 3GPP TS 24.008 § 9.5.8: Deactivate PDP Context Request */
+static int gsm48_rx_gsm_deact_pdp_req(struct sgsn_mm_ctx *mm, struct msgb *msg)
+{
+ struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_gmmh(msg);
+ uint8_t transaction_id = gsm48_hdr_trans_id(gh);
+ struct sgsn_pdp_ctx *pdp;
+
+ LOGMMCTXP(LOGL_INFO, mm, "-> DEACTIVATE PDP CONTEXT REQ (cause: %s)\n",
+ get_value_string(gsm48_gsm_cause_names, gh->data[0]));
+ rate_ctr_inc(&sgsn->rate_ctrs->ctr[CTR_PDP_UL_DEACTIVATE_REQUEST]);
+
+ pdp = sgsn_pdp_ctx_by_tid(mm, transaction_id);
+ if (!pdp) {
+ LOGMMCTXP(LOGL_NOTICE, mm, "Deactivate PDP Context Request for "
+ "non-existing PDP Context (IMSI=%s, TI=%u)\n",
+ mm->imsi, transaction_id);
+ return _gsm48_tx_gsm_deact_pdp_acc(mm, transaction_id);
+ }
+
+ return sgsn_delete_pdp_ctx(pdp);
+}
+
+/* 3GPP TS 24.008 § 9.5.9: Deactivate PDP Context Accept */
+static int gsm48_rx_gsm_deact_pdp_ack(struct sgsn_mm_ctx *mm, struct msgb *msg)
+{
+ struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_gmmh(msg);
+ uint8_t transaction_id = gsm48_hdr_trans_id(gh);
+ struct sgsn_pdp_ctx *pdp;
+
+ LOGMMCTXP(LOGL_INFO, mm, "-> DEACTIVATE PDP CONTEXT ACK\n");
+ rate_ctr_inc(&sgsn->rate_ctrs->ctr[CTR_PDP_UL_DEACTIVATE_ACCEPT]);
+
+ pdp = sgsn_pdp_ctx_by_tid(mm, transaction_id);
+ if (!pdp) {
+ LOGMMCTXP(LOGL_NOTICE, mm, "Deactivate PDP Context Accept for "
+ "non-existing PDP Context (IMSI=%s, TI=%u)\n",
+ mm->imsi, transaction_id);
+ return 0;
+ }
+ /* stop timer 3395 */
+ pdpctx_timer_stop(pdp, 3395);
+ if (pdp->ggsn)
+ return sgsn_delete_pdp_ctx(pdp);
+ /* GTP side already detached, freeing */
+ sgsn_pdp_ctx_free(pdp);
+ return 0;
+}
+
+static int gsm48_rx_gsm_status(struct sgsn_mm_ctx *ctx, struct msgb *msg)
+{
+ struct gsm48_hdr *gh = msgb_l3(msg);
+
+ LOGMMCTXP(LOGL_INFO, ctx, "-> GPRS SM STATUS (cause: %s)\n",
+ get_value_string(gsm48_gsm_cause_names, gh->data[0]));
+
+ return 0;
+}
+
+static void pdpctx_timer_cb(void *_pdp)
+{
+ struct sgsn_pdp_ctx *pdp = _pdp;
+
+ pdp->num_T_exp++;
+
+ switch (pdp->T) {
+ case 3395: /* waiting for PDP CTX DEACT ACK */
+ if (pdp->num_T_exp > T339X_MAX_RETRANS) {
+ LOGPDPCTXP(LOGL_NOTICE, pdp, "T3395 expired > %d times\n", T339X_MAX_RETRANS);
+ pdp->state = PDP_STATE_INACTIVE;
+ if (pdp->ggsn)
+ sgsn_delete_pdp_ctx(pdp);
+ else
+ sgsn_pdp_ctx_free(pdp);
+ break;
+ }
+ _gsm48_tx_gsm_deact_pdp_req(pdp->mm, pdp->ti, GSM_CAUSE_NET_FAIL, true);
+ pdpctx_timer_rearm(pdp, 3395);
+ break;
+ default:
+ LOGPDPCTXP(LOGL_ERROR, pdp, "timer expired in unknown mode %u\n",
+ pdp->T);
+ }
+}
+
+/* GPRS Session Management */
+int gsm0408_rcv_gsm(struct sgsn_mm_ctx *mmctx, struct msgb *msg,
+ struct gprs_llc_llme *llme)
+{
+ struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_gmmh(msg);
+ int rc;
+
+ /* MMCTX can be NULL when called */
+
+ if (!mmctx) {
+ LOGGBIUP(llme, msg, LOGL_NOTICE, "Cannot handle SM for unknown MM CTX\n");
+ /* 6.1.3.6 */
+ if (gh->msg_type == GSM48_MT_GSM_STATUS)
+ return 0;
+
+ return gsm0408_gprs_force_reattach_oldmsg(msg, llme);
+ }
+
+ switch (gh->msg_type) {
+ case GSM48_MT_GSM_ACT_PDP_REQ:
+ rc = gsm48_rx_gsm_act_pdp_req(mmctx, msg);
+ break;
+ case GSM48_MT_GSM_DEACT_PDP_REQ:
+ rc = gsm48_rx_gsm_deact_pdp_req(mmctx, msg);
+ break;
+ case GSM48_MT_GSM_DEACT_PDP_ACK:
+ rc = gsm48_rx_gsm_deact_pdp_ack(mmctx, msg);
+ break;
+ case GSM48_MT_GSM_STATUS:
+ rc = gsm48_rx_gsm_status(mmctx, msg);
+ break;
+ case GSM48_MT_GSM_REQ_PDP_ACT_REJ:
+ case GSM48_MT_GSM_ACT_AA_PDP_REQ:
+ case GSM48_MT_GSM_DEACT_AA_PDP_REQ:
+ LOGMMCTXP(LOGL_NOTICE, mmctx, "Unimplemented GSM 04.08 GSM msg type 0x%02x: %s\n",
+ gh->msg_type, osmo_hexdump((uint8_t *)gh, msgb_l3len(msg)));
+ rc = gsm48_tx_sm_status(mmctx, GSM_CAUSE_MSGT_NOTEXIST_NOTIMPL);
+ break;
+ default:
+ LOGMMCTXP(LOGL_NOTICE, mmctx, "Unknown GSM 04.08 GSM msg type 0x%02x: %s\n",
+ gh->msg_type, osmo_hexdump((uint8_t *)gh, msgb_l3len(msg)));
+ rc = gsm48_tx_sm_status(mmctx, GSM_CAUSE_MSGT_NOTEXIST_NOTIMPL);
+ break;
+
+ }
+
+ return rc;
+}
diff --git a/src/gprs/gprs_sndcp.c b/src/sgsn/gprs_sndcp.c
index 05dad6603..01be57ef2 100644
--- a/src/gprs/gprs_sndcp.c
+++ b/src/sgsn/gprs_sndcp.c
@@ -30,15 +30,16 @@
#include <osmocom/core/talloc.h>
#include <osmocom/gprs/gprs_bssgp.h>
-#include <openbsc/debug.h>
-#include <openbsc/gprs_llc.h>
-#include <openbsc/sgsn.h>
-#include <openbsc/gprs_sndcp.h>
-#include <openbsc/gprs_llc_xid.h>
-#include <openbsc/gprs_sndcp_xid.h>
-#include <openbsc/gprs_sndcp_pcomp.h>
-#include <openbsc/gprs_sndcp_dcomp.h>
-#include <openbsc/gprs_sndcp_comp.h>
+#include <osmocom/sgsn/debug.h>
+#include <osmocom/sgsn/gprs_gb.h>
+#include <osmocom/sgsn/gprs_llc.h>
+#include <osmocom/sgsn/sgsn.h>
+#include <osmocom/sgsn/gprs_sndcp.h>
+#include <osmocom/sgsn/gprs_llc_xid.h>
+#include <osmocom/sgsn/gprs_sndcp_xid.h>
+#include <osmocom/sgsn/gprs_sndcp_pcomp.h>
+#include <osmocom/sgsn/gprs_sndcp_dcomp.h>
+#include <osmocom/sgsn/gprs_sndcp_comp.h>
#define DEBUG_IP_PACKETS 0 /* 0=Disabled, 1=Enabled */
@@ -745,6 +746,7 @@ int sndcp_llunitdata_ind(struct msgb *msg, struct gprs_llc_lle *lle,
struct sndcp_common_hdr *sch = (struct sndcp_common_hdr *)hdr;
struct sndcp_comp_hdr *scomph = NULL;
struct sndcp_udata_hdr *suh;
+ struct sgsn_mm_ctx *mmctx;
uint8_t *npdu;
uint16_t npdu_num __attribute__((unused));
int npdu_len;
@@ -778,6 +780,15 @@ int sndcp_llunitdata_ind(struct msgb *msg, struct gprs_llc_lle *lle,
/* FIXME: move this RA_ID up to the LLME or even higher */
bssgp_parse_cell_id(&sne->ra_id, msgb_bcid(msg));
+ mmctx = sgsn_mm_ctx_by_tlli(msgb_tlli(msg), &sne->ra_id);
+ if (!mmctx) {
+ LOGP(DSNDCP, LOGL_ERROR, "Message for non-existing MM ctx "
+ "(lle=%p, TLLI=%08x, SAPI=%u, NSAPI=%u)\n",
+ lle, lle->llme->tlli, lle->sapi, sch->nsapi);
+ return -EIO;
+ }
+ gprs_gb_recv_pdu(mmctx);
+
if (scomph) {
sne->defrag.pcomp = scomph->pcomp;
sne->defrag.dcomp = scomph->dcomp;
@@ -792,7 +803,7 @@ int sndcp_llunitdata_ind(struct msgb *msg, struct gprs_llc_lle *lle,
npdu_num = (suh->npdu_high << 8) | suh->npdu_low;
npdu = (uint8_t *)suh + sizeof(*suh);
- npdu_len = (msg->data + msg->len) - npdu - 3; /* -3 'removes' the FCS */
+ npdu_len = (msg->data + msg->len) - npdu;
if (npdu_len <= 0) {
LOGP(DSNDCP, LOGL_ERROR, "Short SNDCP N-PDU: %d\n", npdu_len);
@@ -934,7 +945,7 @@ static int gprs_llc_gen_sndcp_xid(uint8_t *bytes, int bytes_len, uint8_t nsapi)
rfc1144_params.s01 = sgsn->cfg.pcomp_rfc1144.s01;
rfc1144_comp_field.p = 1;
rfc1144_comp_field.entity = entity;
- rfc1144_comp_field.algo = RFC_1144;
+ rfc1144_comp_field.algo.pcomp = RFC_1144;
rfc1144_comp_field.comp[RFC1144_PCOMP1] = 1;
rfc1144_comp_field.comp[RFC1144_PCOMP2] = 2;
rfc1144_comp_field.comp_len = RFC1144_PCOMP_NUM;
@@ -952,7 +963,7 @@ static int gprs_llc_gen_sndcp_xid(uint8_t *bytes, int bytes_len, uint8_t nsapi)
v42bis_params.p2 = sgsn->cfg.dcomp_v42bis.p2;
v42bis_comp_field.p = 1;
v42bis_comp_field.entity = entity;
- v42bis_comp_field.algo = V42BIS;
+ v42bis_comp_field.algo.dcomp = V42BIS;
v42bis_comp_field.comp[V42BIS_DCOMP1] = 1;
v42bis_comp_field.comp_len = V42BIS_DCOMP_NUM;
v42bis_comp_field.v42bis_params = &v42bis_params;
@@ -989,8 +1000,8 @@ int sndcp_sn_xid_req(struct gprs_llc_lle *lle, uint8_t nsapi)
gprs_sndcp_comp_free(lle->llme->comp.data);
lle->llme->comp.proto = gprs_sndcp_comp_alloc(lle->llme);
lle->llme->comp.data = gprs_sndcp_comp_alloc(lle->llme);
- talloc_free(lle->llme->xid);
- lle->llme->xid = NULL;
+ talloc_free(lle->xid);
+ lle->xid = NULL;
/* Generate compression parameter bytestream */
xid_len = gprs_llc_gen_sndcp_xid(l3params, sizeof(l3params), nsapi);
@@ -1021,7 +1032,7 @@ static int handle_pcomp_entities(struct gprs_sndcp_comp_field *comp_field,
comp_field->p = 0;
/* Process proposed parameters */
- switch (comp_field->algo) {
+ switch (comp_field->algo.pcomp) {
case RFC_1144:
if (sgsn->cfg.pcomp_rfc1144.passive
&& comp_field->rfc1144_params->nsapi_len > 0) {
@@ -1068,7 +1079,7 @@ static int handle_dcomp_entities(struct gprs_sndcp_comp_field *comp_field,
comp_field->p = 0;
/* Process proposed parameters */
- switch (comp_field->algo) {
+ switch (comp_field->algo.dcomp) {
case V42BIS:
if (sgsn->cfg.dcomp_v42bis.passive &&
comp_field->v42bis_params->nsapi_len > 0) {
@@ -1120,6 +1131,14 @@ int sndcp_sn_xid_ind(struct gprs_llc_xid_field *xid_field_indication,
OSMO_ASSERT(xid_field_response);
OSMO_ASSERT(lle);
+ /* Some phones send zero byte length SNDCP frames
+ * and do require a confirmation response. */
+ if (xid_field_indication->data_len == 0) {
+ xid_field_response->type = GPRS_LLC_XID_T_L3_PAR;
+ xid_field_response->data_len = 0;
+ return 0;
+ }
+
/* Parse SNDCP-CID XID-Field */
comp_fields = gprs_sndcp_parse_xid(&version, lle->llme,
xid_field_indication->data,
diff --git a/src/gprs/gprs_sndcp_comp.c b/src/sgsn/gprs_sndcp_comp.c
index a12c39aa6..c71cc8982 100644
--- a/src/gprs/gprs_sndcp_comp.c
+++ b/src/sgsn/gprs_sndcp_comp.c
@@ -30,11 +30,11 @@
#include <osmocom/core/talloc.h>
#include <osmocom/core/utils.h>
-#include <openbsc/debug.h>
-#include <openbsc/gprs_sndcp_xid.h>
-#include <openbsc/gprs_sndcp_comp.h>
-#include <openbsc/gprs_sndcp_pcomp.h>
-#include <openbsc/gprs_sndcp_dcomp.h>
+#include <osmocom/sgsn/debug.h>
+#include <osmocom/sgsn/gprs_sndcp_xid.h>
+#include <osmocom/sgsn/gprs_sndcp_comp.h>
+#include <osmocom/sgsn/gprs_sndcp_pcomp.h>
+#include <osmocom/sgsn/gprs_sndcp_dcomp.h>
/* Create a new compression entity from a XID-Field */
static struct gprs_sndcp_comp *gprs_sndcp_comp_create(const void *ctx,
@@ -55,32 +55,36 @@ static struct gprs_sndcp_comp *gprs_sndcp_comp_create(const void *ctx,
memcpy(comp_entity->nsapi,
comp_field->rfc1144_params->nsapi,
sizeof(comp_entity->nsapi));
+ comp_entity->algo.pcomp = comp_field->algo.pcomp;
} else if (comp_field->rfc2507_params) {
comp_entity->nsapi_len = comp_field->rfc2507_params->nsapi_len;
memcpy(comp_entity->nsapi,
comp_field->rfc2507_params->nsapi,
sizeof(comp_entity->nsapi));
+ comp_entity->algo.pcomp = comp_field->algo.pcomp;
} else if (comp_field->rohc_params) {
comp_entity->nsapi_len = comp_field->rohc_params->nsapi_len;
memcpy(comp_entity->nsapi, comp_field->rohc_params->nsapi,
sizeof(comp_entity->nsapi));
+ comp_entity->algo.pcomp = comp_field->algo.pcomp;
} else if (comp_field->v42bis_params) {
comp_entity->nsapi_len = comp_field->v42bis_params->nsapi_len;
memcpy(comp_entity->nsapi,
comp_field->v42bis_params->nsapi,
sizeof(comp_entity->nsapi));
+ comp_entity->algo.dcomp = comp_field->algo.dcomp;
} else if (comp_field->v44_params) {
comp_entity->nsapi_len = comp_field->v44_params->nsapi_len;
memcpy(comp_entity->nsapi,
comp_field->v44_params->nsapi,
sizeof(comp_entity->nsapi));
+ comp_entity->algo.dcomp = comp_field->algo.dcomp;
} else {
/* The caller is expected to check carefully if the all
* data fields required for compression entity creation
* are present. Otherwise we blow an assertion here */
OSMO_ASSERT(false);
}
- comp_entity->algo = comp_field->algo;
/* Check if an NSAPI is selected, if not, it does not make sense
* to create the compression entity, since the caller should
@@ -92,19 +96,23 @@ static struct gprs_sndcp_comp *gprs_sndcp_comp_create(const void *ctx,
* (Protocol or Data compresson ?) */
comp_entity->compclass = gprs_sndcp_get_compression_class(comp_field);
- OSMO_ASSERT(comp_entity->compclass != -1);
-
/* Create an algorithm specific compression context */
- if (comp_entity->compclass == SNDCP_XID_PROTOCOL_COMPRESSION) {
+ switch (comp_entity->compclass) {
+ case SNDCP_XID_PROTOCOL_COMPRESSION:
if (gprs_sndcp_pcomp_init(ctx, comp_entity, comp_field) != 0) {
talloc_free(comp_entity);
comp_entity = NULL;
}
- } else {
+ break;
+ case SNDCP_XID_DATA_COMPRESSION:
if (gprs_sndcp_dcomp_init(ctx, comp_entity, comp_field) != 0) {
talloc_free(comp_entity);
comp_entity = NULL;
}
+ break;
+ default:
+ /* comp_field is somehow invalid */
+ OSMO_ASSERT(false);
}
/* Bail on failure */
@@ -152,16 +160,23 @@ void gprs_sndcp_comp_free(struct llist_head *comp_entities)
llist_for_each_entry(comp_entity, comp_entities, list) {
/* Free compression entity */
- if (comp_entity->compclass == SNDCP_XID_PROTOCOL_COMPRESSION) {
+ switch (comp_entity->compclass) {
+ case SNDCP_XID_PROTOCOL_COMPRESSION:
LOGP(DSNDCP, LOGL_INFO,
"Deleting header compression entity %d ...\n",
comp_entity->entity);
gprs_sndcp_pcomp_term(comp_entity);
- } else {
+ break;
+ case SNDCP_XID_DATA_COMPRESSION:
LOGP(DSNDCP, LOGL_INFO,
"Deleting data compression entity %d ...\n",
comp_entity->entity);
gprs_sndcp_dcomp_term(comp_entity);
+ break;
+ default:
+ LOGP(DSNDCP, LOGL_INFO,
+ "Invalid compression class %d!\n", comp_entity->compclass);
+ OSMO_ASSERT(false);
}
}
diff --git a/src/gprs/gprs_sndcp_dcomp.c b/src/sgsn/gprs_sndcp_dcomp.c
index b0f95b486..c0da84d47 100644
--- a/src/gprs/gprs_sndcp_dcomp.c
+++ b/src/sgsn/gprs_sndcp_dcomp.c
@@ -33,14 +33,14 @@
#include <osmocom/core/talloc.h>
#include <osmocom/gsm/tlv.h>
-#include <openbsc/gprs_llc.h>
-#include <openbsc/sgsn.h>
-#include <openbsc/gprs_sndcp_xid.h>
-#include <openbsc/v42bis.h>
-#include <openbsc/v42bis_private.h>
-#include <openbsc/debug.h>
-#include <openbsc/gprs_sndcp_comp.h>
-#include <openbsc/gprs_sndcp_dcomp.h>
+#include <osmocom/sgsn/gprs_llc.h>
+#include <osmocom/sgsn/sgsn.h>
+#include <osmocom/sgsn/gprs_sndcp_xid.h>
+#include <osmocom/sgsn/v42bis.h>
+#include <osmocom/sgsn/v42bis_private.h>
+#include <osmocom/sgsn/debug.h>
+#include <osmocom/sgsn/gprs_sndcp_comp.h>
+#include <osmocom/sgsn/gprs_sndcp_dcomp.h>
/* A struct to capture the output data of compressor and decompressor */
struct v42bis_output_buffer {
@@ -83,7 +83,7 @@ int gprs_sndcp_dcomp_init(const void *ctx, struct gprs_sndcp_comp *comp_entity,
OSMO_ASSERT(comp_field);
if (comp_entity->compclass == SNDCP_XID_DATA_COMPRESSION
- && comp_entity->algo == V42BIS) {
+ && comp_entity->algo.dcomp == V42BIS) {
OSMO_ASSERT(comp_field->v42bis_params);
comp_entity->state =
v42bis_init(ctx, NULL, comp_field->v42bis_params->p0,
@@ -94,7 +94,7 @@ int gprs_sndcp_dcomp_init(const void *ctx, struct gprs_sndcp_comp *comp_entity,
&rx_v42bis_data_handler, NULL,
V42BIS_MAX_OUTPUT_LENGTH);
LOGP(DSNDCP, LOGL_INFO,
- "V.42bis data compression initalized.\n");
+ "V.42bis data compression initialized.\n");
return 0;
}
@@ -114,7 +114,7 @@ void gprs_sndcp_dcomp_term(struct gprs_sndcp_comp *comp_entity)
OSMO_ASSERT(comp_entity);
if (comp_entity->compclass == SNDCP_XID_DATA_COMPRESSION
- && comp_entity->algo == V42BIS) {
+ && comp_entity->algo.dcomp == V42BIS) {
if (comp_entity->state) {
v42bis_free((v42bis_state_t *) comp_entity->state);
comp_entity->state = NULL;
@@ -293,7 +293,7 @@ int gprs_sndcp_dcomp_expand(uint8_t *data, unsigned int len, uint8_t pcomp,
/* Note: Currently V42BIS is the only compression method we
* support, so the only allowed algorithm is V42BIS */
- OSMO_ASSERT(comp_entity->algo == V42BIS);
+ OSMO_ASSERT(comp_entity->algo.dcomp == V42BIS);
/* Find pcomp_index */
pcomp_index = gprs_sndcp_comp_get_idx(comp_entity, pcomp);
@@ -339,7 +339,7 @@ int gprs_sndcp_dcomp_compress(uint8_t *data, unsigned int len, uint8_t *pcomp,
/* Note: Currently V42BIS is the only compression method we
* support, so the only allowed algorithm is V42BIS */
- OSMO_ASSERT(comp_entity->algo == V42BIS);
+ OSMO_ASSERT(comp_entity->algo.dcomp == V42BIS);
/* Run compression algo */
rc = v42bis_compress_unitdata(&pcomp_index, data, len,
diff --git a/src/gprs/gprs_sndcp_pcomp.c b/src/sgsn/gprs_sndcp_pcomp.c
index a2236c3b1..8c2fc974d 100644
--- a/src/gprs/gprs_sndcp_pcomp.c
+++ b/src/sgsn/gprs_sndcp_pcomp.c
@@ -33,13 +33,13 @@
#include <osmocom/core/talloc.h>
#include <osmocom/gsm/tlv.h>
-#include <openbsc/gprs_llc.h>
-#include <openbsc/sgsn.h>
-#include <openbsc/gprs_sndcp_xid.h>
-#include <openbsc/slhc.h>
-#include <openbsc/debug.h>
-#include <openbsc/gprs_sndcp_comp.h>
-#include <openbsc/gprs_sndcp_pcomp.h>
+#include <osmocom/sgsn/gprs_llc.h>
+#include <osmocom/sgsn/sgsn.h>
+#include <osmocom/sgsn/gprs_sndcp_xid.h>
+#include <osmocom/sgsn/slhc.h>
+#include <osmocom/sgsn/debug.h>
+#include <osmocom/sgsn/gprs_sndcp_comp.h>
+#include <osmocom/sgsn/gprs_sndcp_pcomp.h>
/* Initalize header compression */
int gprs_sndcp_pcomp_init(const void *ctx, struct gprs_sndcp_comp *comp_entity,
@@ -53,13 +53,13 @@ int gprs_sndcp_pcomp_init(const void *ctx, struct gprs_sndcp_comp *comp_entity,
OSMO_ASSERT(comp_field);
if (comp_entity->compclass == SNDCP_XID_PROTOCOL_COMPRESSION
- && comp_entity->algo == RFC_1144) {
+ && comp_entity->algo.pcomp == RFC_1144) {
OSMO_ASSERT(comp_field->rfc1144_params);
comp_entity->state =
slhc_init(ctx, comp_field->rfc1144_params->s01 + 1,
comp_field->rfc1144_params->s01 + 1);
LOGP(DSNDCP, LOGL_INFO,
- "RFC1144 header compression initalized.\n");
+ "RFC1144 header compression initialized.\n");
return 0;
}
@@ -79,7 +79,7 @@ void gprs_sndcp_pcomp_term(struct gprs_sndcp_comp *comp_entity)
OSMO_ASSERT(comp_entity);
if (comp_entity->compclass == SNDCP_XID_PROTOCOL_COMPRESSION
- && comp_entity->algo == RFC_1144) {
+ && comp_entity->algo.pcomp == RFC_1144) {
if (comp_entity->state) {
slhc_free((struct slcompress *)comp_entity->state);
comp_entity->state = NULL;
@@ -214,7 +214,7 @@ int gprs_sndcp_pcomp_expand(uint8_t *data, unsigned int len, uint8_t pcomp,
/* Note: Currently RFC1144 is the only compression method we
* support, so the only allowed algorithm is RFC1144 */
- OSMO_ASSERT(comp_entity->algo == RFC_1144);
+ OSMO_ASSERT(comp_entity->algo.pcomp == RFC_1144);
/* Find pcomp_index */
pcomp_index = gprs_sndcp_comp_get_idx(comp_entity, pcomp);
@@ -263,7 +263,7 @@ int gprs_sndcp_pcomp_compress(uint8_t *data, unsigned int len, uint8_t *pcomp,
/* Note: Currently RFC1144 is the only compression method we
* support, so the only allowed algorithm is RFC1144 */
- OSMO_ASSERT(comp_entity->algo == RFC_1144);
+ OSMO_ASSERT(comp_entity->algo.pcomp == RFC_1144);
/* Run compression algo */
rc = rfc1144_compress(&pcomp_index, data, len, comp_entity->state);
diff --git a/src/gprs/gprs_sndcp_vty.c b/src/sgsn/gprs_sndcp_vty.c
index 4bad8b040..0994a4cd2 100644
--- a/src/gprs/gprs_sndcp_vty.c
+++ b/src/sgsn/gprs_sndcp_vty.c
@@ -31,10 +31,10 @@
#include <osmocom/core/talloc.h>
#include <osmocom/core/select.h>
#include <osmocom/core/rate_ctr.h>
-#include <openbsc/debug.h>
-#include <openbsc/signal.h>
-#include <openbsc/gprs_llc.h>
-#include <openbsc/gprs_sndcp.h>
+#include <osmocom/sgsn/debug.h>
+#include <osmocom/sgsn/signal.h>
+#include <osmocom/sgsn/gprs_llc.h>
+#include <osmocom/sgsn/gprs_sndcp.h>
#include <osmocom/vty/vty.h>
#include <osmocom/vty/command.h>
diff --git a/src/gprs/gprs_sndcp_xid.c b/src/sgsn/gprs_sndcp_xid.c
index dfea5febc..a19f64514 100644
--- a/src/gprs/gprs_sndcp_xid.c
+++ b/src/sgsn/gprs_sndcp_xid.c
@@ -31,10 +31,10 @@
#include <osmocom/core/talloc.h>
#include <osmocom/gsm/tlv.h>
-#include <openbsc/debug.h>
-#include <openbsc/gprs_llc.h>
-#include <openbsc/sgsn.h>
-#include <openbsc/gprs_sndcp_xid.h>
+#include <osmocom/sgsn/debug.h>
+#include <osmocom/sgsn/gprs_llc.h>
+#include <osmocom/sgsn/sgsn.h>
+#include <osmocom/sgsn/gprs_sndcp_xid.h>
/* When the propose bit in an SNDCP-XID compression field is set to zero,
* the algorithm identifier is stripped. The algoritm parameters are specific
@@ -42,9 +42,8 @@
* about the referenced algorithm to the parser. */
struct entity_algo_table {
unsigned int entity; /* see also: 6.5.1.1.3 and 6.6.1.1.3 */
- unsigned int algo; /* see also: 6.5.1.1.4 and 6.6.1.1.4 */
- unsigned int compclass; /* Can be either SNDCP_XID_DATA_COMPRESSION or
- SNDCP_XID_PROTOCOL_COMPRESSION */
+ union gprs_sndcp_comp_algo algo;
+ enum gprs_sndcp_xid_param_types compclass;
};
/* FUNCTIONS RELATED TO SNDCP-XID ENCODING */
@@ -386,6 +385,7 @@ static int encode_comp_field(uint8_t *dst, unsigned int dst_maxlen,
int len;
int expected_length;
int i;
+ enum gprs_sndcp_xid_param_types compclass;
uint8_t payload_bytes[256];
int payload_bytes_len = -1;
@@ -443,7 +443,17 @@ static int encode_comp_field(uint8_t *dst, unsigned int dst_maxlen,
OSMO_ASSERT(comp_field->entity <= 0x1f);
/* Check if the algorithm number is within bounds */
- OSMO_ASSERT(comp_field->algo >= 0 || comp_field->algo <= 0x1f);
+ compclass = gprs_sndcp_get_compression_class(comp_field);
+ switch (compclass) {
+ case SNDCP_XID_PROTOCOL_COMPRESSION:
+ OSMO_ASSERT(comp_field->algo.pcomp >= 0 && comp_field->algo.pcomp <= 0x1f);
+ break;
+ case SNDCP_XID_DATA_COMPRESSION:
+ OSMO_ASSERT(comp_field->algo.dcomp >= 0 && comp_field->algo.dcomp <= 0x1f);
+ break;
+ default:
+ OSMO_ASSERT(false);
+ }
/* Zero out buffer */
memset(dst, 0, dst_maxlen);
@@ -459,7 +469,10 @@ static int encode_comp_field(uint8_t *dst, unsigned int dst_maxlen,
/* Encode algorithm number */
if (comp_field->p) {
- *dst |= comp_field->algo & 0x1F;
+ if (compclass == SNDCP_XID_PROTOCOL_COMPRESSION)
+ *dst |= comp_field->algo.pcomp & 0x1F;
+ else
+ *dst |= comp_field->algo.dcomp & 0x1F;
dst++;
dst_counter++;
}
@@ -501,7 +514,7 @@ static int encode_comp_field(uint8_t *dst, unsigned int dst_maxlen,
/* Find out to which compression class the specified comp-field belongs
* (header compression or data compression?) */
-int gprs_sndcp_get_compression_class(const struct gprs_sndcp_comp_field
+enum gprs_sndcp_xid_param_types gprs_sndcp_get_compression_class(const struct gprs_sndcp_comp_field
*comp_field)
{
OSMO_ASSERT(comp_field);
@@ -517,7 +530,7 @@ int gprs_sndcp_get_compression_class(const struct gprs_sndcp_comp_field
else if (comp_field->v44_params)
return SNDCP_XID_DATA_COMPRESSION;
else
- return -EINVAL;
+ return SNDCP_XID_INVALID_COMPRESSION;
}
/* Convert all compression fields to bytstreams */
@@ -1005,10 +1018,29 @@ static int decode_dcomp_v44_params(struct gprs_sndcp_dcomp_v44_params *params,
return byte_counter;
}
-/* Lookup algorithm identfier by entity ID */
-static int lookup_algorithm_identifier(int entity, const struct
- entity_algo_table
- *lt, unsigned int lt_len, int compclass)
+/* Lookup protocol compression algorithm identfier by entity ID */
+static enum gprs_sndcp_hdr_comp_algo lookup_algorithm_identifier_pcomp(int entity,
+ const struct entity_algo_table *lt,
+ unsigned int lt_len)
+{
+ int i;
+
+ if (!lt)
+ return -1;
+
+ for (i = 0; i < lt_len; i++) {
+ if ((lt[i].entity == entity)
+ && (lt[i].compclass == SNDCP_XID_PROTOCOL_COMPRESSION))
+ return lt[i].algo.pcomp;
+ }
+
+ return SNDCP_XID_INVALID_COMPRESSION;
+}
+
+/* Lookup a data compression algorithm identfier by entity ID */
+static enum gprs_sndcp_data_comp_algo lookup_algorithm_identifier_dcomp(int entity,
+ const struct entity_algo_table *lt,
+ unsigned int lt_len)
{
int i;
@@ -1017,26 +1049,27 @@ static int lookup_algorithm_identifier(int entity, const struct
for (i = 0; i < lt_len; i++) {
if ((lt[i].entity == entity)
- && (lt[i].compclass == compclass))
- return lt[i].algo;
+ && (lt[i].compclass == SNDCP_XID_DATA_COMPRESSION))
+ return lt[i].algo.dcomp;
}
- return -1;
+ return SNDCP_XID_INVALID_COMPRESSION;
}
/* Helper function for decode_comp_field(), decodes
* numeric pcomp/dcomp values */
static int decode_comp_values(struct gprs_sndcp_comp_field *comp_field,
- const uint8_t *src, int compclass)
+ const uint8_t *src, enum gprs_sndcp_xid_param_types compclass)
{
int src_counter = 0;
int i;
if (comp_field->p) {
/* Determine the number of expected PCOMP/DCOMP values */
- if (compclass == SNDCP_XID_PROTOCOL_COMPRESSION) {
+ switch (compclass) {
+ case SNDCP_XID_PROTOCOL_COMPRESSION:
/* For protocol compression */
- switch (comp_field->algo) {
+ switch (comp_field->algo.pcomp) {
case RFC_1144:
comp_field->comp_len = RFC1144_PCOMP_NUM;
break;
@@ -1052,9 +1085,10 @@ static int decode_comp_values(struct gprs_sndcp_comp_field *comp_field,
default:
return -EINVAL;
}
- } else {
+ break;
+ case SNDCP_XID_DATA_COMPRESSION:
/* For data compression */
- switch (comp_field->algo) {
+ switch (comp_field->algo.dcomp) {
case V42BIS:
comp_field->comp_len = V42BIS_DCOMP_NUM;
break;
@@ -1067,6 +1101,9 @@ static int decode_comp_values(struct gprs_sndcp_comp_field *comp_field,
default:
return -EINVAL;
}
+ break;
+ default:
+ return -EINVAL;
}
for (i = 0; i < comp_field->comp_len; i++) {
@@ -1094,7 +1131,7 @@ static int decode_pcomp_params(struct gprs_sndcp_comp_field *comp_field,
{
int rc;
- switch (comp_field->algo) {
+ switch (comp_field->algo.pcomp) {
case RFC_1144:
comp_field->rfc1144_params = talloc_zero(comp_field, struct
gprs_sndcp_pcomp_rfc1144_params);
@@ -1142,7 +1179,7 @@ static int decode_dcomp_params(struct gprs_sndcp_comp_field *comp_field,
{
int rc;
- switch (comp_field->algo) {
+ switch (comp_field->algo.dcomp) {
case V42BIS:
comp_field->v42bis_params = talloc_zero(comp_field, struct
gprs_sndcp_dcomp_v42bis_params);
@@ -1180,7 +1217,8 @@ static int decode_dcomp_params(struct gprs_sndcp_comp_field *comp_field,
static int decode_comp_field(struct gprs_sndcp_comp_field *comp_field,
const uint8_t *src, unsigned int src_len,
const struct entity_algo_table *lt,
- unsigned int lt_len, int compclass)
+ unsigned int lt_len,
+ enum gprs_sndcp_xid_param_types compclass)
{
int src_counter = 0;
unsigned int len;
@@ -1205,15 +1243,34 @@ static int decode_comp_field(struct gprs_sndcp_comp_field *comp_field,
/* Decode algorithm number (if present) */
if (comp_field->p) {
- comp_field->algo = (*src) & 0x1F;
+ switch (compclass) {
+ case SNDCP_XID_PROTOCOL_COMPRESSION:
+ comp_field->algo.pcomp = (*src) & 0x1F;
+ break;
+ case SNDCP_XID_DATA_COMPRESSION:
+ comp_field->algo.dcomp = (*src) & 0x1F;
+ break;
+ default:
+ return -EINVAL;
+ }
src_counter++;
src++;
}
/* Alternatively take the information from the lookup table */
- else
- comp_field->algo =
- lookup_algorithm_identifier(comp_field->entity, lt,
- lt_len, compclass);
+ else {
+ switch (compclass) {
+ case SNDCP_XID_PROTOCOL_COMPRESSION:
+ comp_field->algo.pcomp =
+ lookup_algorithm_identifier_pcomp(comp_field->entity, lt, lt_len);
+ break;
+ case SNDCP_XID_DATA_COMPRESSION:
+ comp_field->algo.dcomp =
+ lookup_algorithm_identifier_dcomp(comp_field->entity, lt, lt_len);
+ break;
+ default:
+ return -EINVAL;
+ }
+ }
/* Decode length field */
len = *src;
@@ -1368,7 +1425,7 @@ static int gprs_sndcp_fill_table(struct
{
struct gprs_sndcp_comp_field *comp_field;
int i = 0;
- int rc;
+ enum gprs_sndcp_xid_param_types compclass;
if (!comp_fields)
return -EINVAL;
@@ -1378,19 +1435,23 @@ static int gprs_sndcp_fill_table(struct
memset(lt, 0, sizeof(*lt));
llist_for_each_entry(comp_field, comp_fields, list) {
- if (comp_field->algo >= 0) {
- lt[i].entity = comp_field->entity;
- lt[i].algo = comp_field->algo;
- rc = gprs_sndcp_get_compression_class(comp_field);
-
- if (rc < 0) {
- memset(lt, 0, sizeof(*lt));
- return -EINVAL;
- }
-
- lt[i].compclass = rc;
- i++;
+ compclass = gprs_sndcp_get_compression_class(comp_field);
+ switch (compclass) {
+ case SNDCP_XID_PROTOCOL_COMPRESSION:
+ lt[i].algo.pcomp = comp_field->algo.pcomp;
+ break;
+ case SNDCP_XID_DATA_COMPRESSION:
+ lt[i].algo.dcomp = comp_field->algo.dcomp;
+ break;
+ case SNDCP_XID_INVALID_COMPRESSION:
+ continue;
+ default:
+ memset(lt, 0, sizeof(*lt));
+ return -EINVAL;
}
+ lt[i].compclass = compclass;
+ lt[i].entity = comp_field->entity;
+ i++;
}
return i;
@@ -1402,7 +1463,10 @@ static int complete_comp_field_params(struct gprs_sndcp_comp_field
*comp_field_dst, const struct
gprs_sndcp_comp_field *comp_field_src)
{
- if (comp_field_dst->algo < 0)
+ enum gprs_sndcp_xid_param_types compclass;
+
+ compclass = gprs_sndcp_get_compression_class(comp_field_dst);
+ if (compclass == SNDCP_XID_INVALID_COMPRESSION)
return -EINVAL;
if (comp_field_dst->rfc1144_params && comp_field_src->rfc1144_params) {
@@ -1626,7 +1690,7 @@ static void dump_pcomp_params(const struct gprs_sndcp_comp_field
{
int i;
- switch (comp_field->algo) {
+ switch (comp_field->algo.pcomp) {
case RFC_1144:
if (comp_field->rfc1144_params == NULL) {
LOGP(DSNDCP, logl,
@@ -1726,7 +1790,7 @@ static void dump_dcomp_params(const struct gprs_sndcp_comp_field
{
int i;
- switch (comp_field->algo) {
+ switch (comp_field->algo.dcomp) {
case V42BIS:
if (comp_field->v42bis_params == NULL) {
LOGP(DSNDCP, logl,
@@ -1791,15 +1855,26 @@ void gprs_sndcp_dump_comp_fields(const struct llist_head *comp_fields,
{
struct gprs_sndcp_comp_field *comp_field;
int i;
- int compclass;
+ enum gprs_sndcp_xid_param_types compclass;
OSMO_ASSERT(comp_fields);
llist_for_each_entry(comp_field, comp_fields, list) {
+ compclass = gprs_sndcp_get_compression_class(comp_field);
LOGP(DSNDCP, logl, "SNDCP-XID:\n");
LOGP(DSNDCP, logl, "struct gprs_sndcp_comp_field {\n");
LOGP(DSNDCP, logl, " entity=%d;\n", comp_field->entity);
- LOGP(DSNDCP, logl, " algo=%d;\n", comp_field->algo);
+ switch (compclass) {
+ case SNDCP_XID_PROTOCOL_COMPRESSION:
+ LOGP(DSNDCP, logl, " algo=%d;\n", comp_field->algo.pcomp);
+ break;
+ case SNDCP_XID_DATA_COMPRESSION:
+ LOGP(DSNDCP, logl, " algo=%d;\n", comp_field->algo.dcomp);
+ break;
+ default:
+ LOGP(DSNDCP, logl, " algo invalid!\n");
+ break;
+ }
LOGP(DSNDCP, logl, " comp_len=%d;\n", comp_field->comp_len);
if (comp_field->comp_len == 0)
LOGP(DSNDCP, logl, " comp[] = NULL;\n");
@@ -1808,12 +1883,16 @@ void gprs_sndcp_dump_comp_fields(const struct llist_head *comp_fields,
comp_field->comp[i]);
}
- compclass = gprs_sndcp_get_compression_class(comp_field);
-
- if (compclass == SNDCP_XID_PROTOCOL_COMPRESSION) {
+ switch (compclass) {
+ case SNDCP_XID_PROTOCOL_COMPRESSION:
dump_pcomp_params(comp_field, logl);
- } else if (compclass == SNDCP_XID_DATA_COMPRESSION) {
+ break;
+ case SNDCP_XID_DATA_COMPRESSION:
dump_dcomp_params(comp_field, logl);
+ break;
+ default:
+ LOGP(DSNDCP, logl, " compression algorithm invalid!\n");
+ break;
}
LOGP(DSNDCP, logl, "}\n");
diff --git a/src/gprs/gprs_subscriber.c b/src/sgsn/gprs_subscriber.c
index 94297d0d6..c23b332f3 100644
--- a/src/gprs/gprs_subscriber.c
+++ b/src/sgsn/gprs_subscriber.c
@@ -23,17 +23,18 @@
#include <osmocom/gsm/protocol/gsm_04_08_gprs.h>
#include <osmocom/gsm/gsup.h>
#include <osmocom/gsm/apn.h>
+#include <osmocom/gsm/ipa.h>
#include <osmocom/core/utils.h>
#include <osmocom/core/logging.h>
-#include <openbsc/gprs_subscriber.h>
-#include <openbsc/gsup_client.h>
+#include <osmocom/sgsn/gprs_subscriber.h>
+#include <osmocom/gsupclient/gsup_client.h>
-#include <openbsc/sgsn.h>
-#include <openbsc/gprs_sgsn.h>
-#include <openbsc/gprs_gmm.h>
-#include <openbsc/gprs_utils.h>
+#include <osmocom/sgsn/sgsn.h>
+#include <osmocom/sgsn/gprs_sgsn.h>
+#include <osmocom/sgsn/gprs_gmm.h>
+#include <osmocom/sgsn/gprs_utils.h>
-#include <openbsc/debug.h>
+#include <osmocom/sgsn/debug.h>
#include <netinet/in.h>
#include <arpa/inet.h>
@@ -47,12 +48,12 @@
(gsup)->imsi, \
## args)
-extern void *tall_bsc_ctx;
+extern void *tall_sgsn_ctx;
LLIST_HEAD(_gprs_subscribers);
struct llist_head * const gprs_subscribers = &_gprs_subscribers;
-static int gsup_read_cb(struct gsup_client *gsupc, struct msgb *msg);
+static int gsup_read_cb(struct osmo_gsup_client *gsupc, struct msgb *msg);
/* TODO: Some functions are specific to the SGSN, but this file is more general
* (it has gprs_* name). Either move these functions elsewhere, split them and
@@ -63,14 +64,20 @@ static int gsup_read_cb(struct gsup_client *gsupc, struct msgb *msg);
int gprs_subscr_init(struct sgsn_instance *sgi)
{
const char *addr_str;
+ struct ipaccess_unit *ipa_dev;
if (!sgi->cfg.gsup_server_addr.sin_addr.s_addr)
return 0;
addr_str = inet_ntoa(sgi->cfg.gsup_server_addr.sin_addr);
- sgi->gsup_client = gsup_client_create(
- "SGSN",
+ ipa_dev = talloc_zero(sgi, struct ipaccess_unit);
+ ipa_dev->unit_name = "SGSN";
+ ipa_dev->serno = sgi->cfg.sgsn_ipa_name; /* NULL unless configured via VTY */
+
+ sgi->gsup_client = osmo_gsup_client_create2(
+ sgi,
+ ipa_dev,
addr_str, sgi->cfg.gsup_server_port,
&gsup_read_cb,
&sgi->cfg.oap);
@@ -81,7 +88,7 @@ int gprs_subscr_init(struct sgsn_instance *sgi)
return 1;
}
-static int gsup_read_cb(struct gsup_client *gsupc, struct msgb *msg)
+static int gsup_read_cb(struct osmo_gsup_client *gsupc, struct msgb *msg)
{
int rc;
@@ -141,7 +148,7 @@ struct gprs_subscr *gprs_subscr_get_by_imsi(const char *imsi)
static struct gprs_subscr *gprs_subscr_alloc(void)
{
struct gprs_subscr *gsub;
- gsub = talloc_zero(tall_bsc_ctx, struct gprs_subscr);
+ gsub = talloc_zero(tall_sgsn_ctx, struct gprs_subscr);
if (!gsub)
return NULL;
llist_add_tail(&gsub->entry, gprs_subscribers);
@@ -194,7 +201,7 @@ void gprs_subscr_cancel(struct gprs_subscr *subscr)
static int gprs_subscr_tx_gsup_message(struct gprs_subscr *subscr,
struct osmo_gsup_message *gsup_msg)
{
- struct msgb *msg = gsup_client_msgb_alloc();
+ struct msgb *msg = osmo_gsup_client_msgb_alloc();
if (strlen(gsup_msg->imsi) == 0 && subscr)
osmo_strlcpy(gsup_msg->imsi, subscr->imsi,
@@ -210,7 +217,7 @@ static int gprs_subscr_tx_gsup_message(struct gprs_subscr *subscr,
return -ENOTSUP;
}
- return gsup_client_send(sgsn->gsup_client, msg);
+ return osmo_gsup_client_send(sgsn->gsup_client, msg);
}
static int gprs_subscr_tx_gsup_error_reply(struct gprs_subscr *subscr,
@@ -374,7 +381,11 @@ static void gprs_subscr_gsup_insert_data(struct gprs_subscr *subscr,
pdp_data->pdp_type = pdp_info->pdp_type;
osmo_apn_to_str(pdp_data->apn_str,
pdp_info->apn_enc, pdp_info->apn_enc_len);
- memcpy(pdp_data->qos_subscribed, pdp_info->qos_enc, pdp_info->qos_enc_len);
+
+ if (pdp_info->qos_enc) {
+ memcpy(&pdp_data->qos_subscribed[0], pdp_info->qos_enc,
+ pdp_info->qos_enc_len);
+ }
pdp_data->qos_subscribed_len = pdp_info->qos_enc_len;
if (pdp_info->pdp_charg_enc && pdp_info->pdp_charg_enc_len >= sizeof(pdp_data->pdp_charg)) {
@@ -502,6 +513,7 @@ static int gprs_subscr_handle_gsup_auth_err(struct gprs_subscr *subscr,
"GSUP protocol remote error, GMM cause = '%s' (%d)\n",
get_value_string(gsm48_gmm_cause_names, gsup_msg->cause),
gsup_msg->cause);
+ sdata->error_cause = gsup_msg->cause;
break;
}
@@ -800,7 +812,7 @@ static int gprs_subscr_query_auth_info(struct gprs_subscr *subscr,
return gprs_subscr_tx_gsup_message(subscr, &gsup_msg);
}
-int gprs_subscr_location_update(struct gprs_subscr *subscr)
+int gprs_subscr_location_update(struct gprs_subscr *subscr, enum sgsn_ran_type ran_type)
{
struct osmo_gsup_message gsup_msg = {0};
@@ -808,6 +820,18 @@ int gprs_subscr_location_update(struct gprs_subscr *subscr)
"subscriber data is not available\n");
gsup_msg.message_type = OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST;
+
+ switch (ran_type) {
+ case MM_CTX_T_GERAN_Gb:
+ gsup_msg.current_rat_type = OSMO_RAT_GERAN_A;
+ break;
+ case MM_CTX_T_UTRAN_Iu:
+ gsup_msg.current_rat_type = OSMO_RAT_UTRAN_IU;
+ break;
+ default:
+ break;
+ }
+
return gprs_subscr_tx_gsup_message(subscr, &gsup_msg);
}
@@ -872,7 +896,7 @@ int gprs_subscr_request_update_location(struct sgsn_mm_ctx *mmctx)
subscr->flags |= GPRS_SUBSCRIBER_UPDATE_LOCATION_PENDING;
- rc = gprs_subscr_location_update(subscr);
+ rc = gprs_subscr_location_update(subscr, mmctx->ran_type);
gprs_subscr_put(subscr);
return rc;
}
diff --git a/src/gprs/sgsn_auth.c b/src/sgsn/sgsn_auth.c
index a64339c3e..b8d803590 100644
--- a/src/gprs/sgsn_auth.c
+++ b/src/sgsn/sgsn_auth.c
@@ -21,11 +21,11 @@
#include <osmocom/gsm/protocol/gsm_04_08_gprs.h>
#include <osmocom/core/utils.h>
-#include <openbsc/sgsn.h>
-#include <openbsc/gprs_sgsn.h>
-#include <openbsc/gprs_gmm.h>
-#include <openbsc/gprs_subscriber.h>
-#include <openbsc/debug.h>
+#include <osmocom/sgsn/sgsn.h>
+#include <osmocom/sgsn/gprs_sgsn.h>
+#include <osmocom/sgsn/gprs_gmm.h>
+#include <osmocom/sgsn/gprs_subscriber.h>
+#include <osmocom/sgsn/debug.h>
const struct value_string auth_state_names[] = {
{ SGSN_AUTH_ACCEPTED, "accepted"},
@@ -38,13 +38,12 @@ const struct value_string auth_state_names[] = {
const struct value_string *sgsn_auth_state_names = auth_state_names;
-void sgsn_auth_init(void)
+void sgsn_auth_init(struct sgsn_instance *sgsn)
{
INIT_LLIST_HEAD(&sgsn->cfg.imsi_acl);
}
-/* temporary IMSI ACL hack */
-struct imsi_acl_entry *sgsn_acl_lookup(const char *imsi, struct sgsn_config *cfg)
+struct imsi_acl_entry *sgsn_acl_lookup(const char *imsi, const struct sgsn_config *cfg)
{
struct imsi_acl_entry *acl;
llist_for_each_entry(acl, &cfg->imsi_acl, list) {
@@ -114,7 +113,7 @@ enum sgsn_auth_state sgsn_auth_state(struct sgsn_mm_ctx *mmctx)
return mmctx->auth_state;
if (sgsn->cfg.require_authentication &&
- (!mmctx->is_authenticated ||
+ (!sgsn_mm_ctx_is_authenticated(mmctx) ||
mmctx->subscr->sgsn_data->auth_triplets_updated))
return SGSN_AUTH_AUTHENTICATE;
@@ -133,9 +132,10 @@ enum sgsn_auth_state sgsn_auth_state(struct sgsn_mm_ctx *mmctx)
if (check_net) {
/* We simply assume that the IMSI exists, as long as it is part
* of 'our' network */
- snprintf(mccmnc, sizeof(mccmnc), "%03d%02d",
- mmctx->ra.mcc, mmctx->ra.mnc);
- if (strncmp(mccmnc, mmctx->imsi, 5) == 0)
+ snprintf(mccmnc, sizeof(mccmnc), "%s%s",
+ osmo_mcc_name(mmctx->ra.mcc),
+ osmo_mnc_name(mmctx->ra.mnc, mmctx->ra.mnc_3_digits));
+ if (strncmp(mccmnc, mmctx->imsi, mmctx->ra.mnc_3_digits ? 6 : 5) == 0)
return SGSN_AUTH_ACCEPTED;
}
@@ -174,7 +174,7 @@ int sgsn_auth_request(struct sgsn_mm_ctx *mmctx)
OSMO_ASSERT(mmctx->subscr != NULL);
- if (sgsn->cfg.require_authentication && !mmctx->is_authenticated) {
+ if (sgsn->cfg.require_authentication && !sgsn_mm_ctx_is_authenticated(mmctx)) {
/* Find next tuple */
at = sgsn_auth_get_tuple(mmctx, mmctx->auth_triplet.key_seq);
diff --git a/src/gprs/sgsn_cdr.c b/src/sgsn/sgsn_cdr.c
index 16ea9d47a..a50b4dfdd 100644
--- a/src/gprs/sgsn_cdr.c
+++ b/src/sgsn/sgsn_cdr.c
@@ -18,13 +18,15 @@
*
*/
-#include <openbsc/sgsn.h>
-#include <openbsc/signal.h>
-#include <openbsc/gprs_utils.h>
-#include <openbsc/debug.h>
+#include <osmocom/ctrl/control_if.h>
+
+#include <osmocom/sgsn/sgsn.h>
+#include <osmocom/sgsn/signal.h>
+#include <osmocom/sgsn/gprs_utils.h>
+#include <osmocom/sgsn/debug.h>
#include <osmocom/gsm/apn.h>
-#include <openbsc/vty.h>
+#include <osmocom/sgsn/vty.h>
#include <gtp.h>
#include <pdp.h>
@@ -38,6 +40,7 @@
/* TODO...avoid going through a global */
extern struct sgsn_instance *sgsn;
+extern struct ctrl_handle *g_ctrlh;
/**
* The CDR module will generate an entry like:
@@ -59,6 +62,11 @@ extern struct sgsn_instance *sgsn;
* CAUSE_FOR_TERM, # CAUSE_FOR_TERM
*/
+static void send_cdr_trap(char *value)
+{
+ if (ctrl_cmd_send_trap(g_ctrlh, "cdr-v1", value) < 0)
+ LOGP(DGPRS, LOGL_ERROR, "Failed to create and send TRAP cdr-v1\n");
+}
static void maybe_print_header(FILE *cdr_file)
{
@@ -68,27 +76,16 @@ static void maybe_print_header(FILE *cdr_file)
fprintf(cdr_file, "timestamp,imsi,imei,msisdn,cell_id,lac,hlr,event,pdp_duration,ggsn_addr,sgsn_addr,apni,eua_addr,vol_in,vol_out,charging_id\n");
}
-static void cdr_log_mm(struct sgsn_instance *inst, const char *ev,
+static int cdr_snprintf_mm(char *buf, size_t size, const char *ev,
struct sgsn_mm_ctx *mmctx)
{
- FILE *cdr_file;
struct tm tm;
struct timeval tv;
+ int ret;
- if (!inst->cfg.cdr.filename)
- return;
-
- cdr_file = fopen(inst->cfg.cdr.filename, "a");
- if (!cdr_file) {
- LOGP(DGPRS, LOGL_ERROR, "Failed to open %s\n",
- inst->cfg.cdr.filename);
- return;
- }
-
- maybe_print_header(cdr_file);
gettimeofday(&tv, NULL);
gmtime_r(&tv.tv_sec, &tm);
- fprintf(cdr_file, "%04d%02d%02d%02d%02d%02d%03d,%s,%s,%s,%d,%d,%s,%s\n",
+ ret = snprintf(buf, size, "%04d%02d%02d%02d%02d%02d%03d,%s,%s,%s,%d,%d,%s,%s",
tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
tm.tm_hour, tm.tm_min, tm.tm_sec,
(int)(tv.tv_usec / 1000),
@@ -99,8 +96,36 @@ static void cdr_log_mm(struct sgsn_instance *inst, const char *ev,
mmctx->ra.lac,
mmctx->hlr,
ev);
+ return ret;
+}
+
+static void cdr_log_mm(struct sgsn_instance *inst, const char *ev,
+ struct sgsn_mm_ctx *mmctx)
+{
+ FILE *cdr_file;
+ char buf[1024];
+
+ if (!inst->cfg.cdr.filename && !inst->cfg.cdr.trap)
+ return;
+
+ cdr_snprintf_mm(buf, sizeof(buf), ev, mmctx);
+
+ if (inst->cfg.cdr.trap)
+ send_cdr_trap(buf);
+
+ if (inst->cfg.cdr.filename) {
+ cdr_file = fopen(inst->cfg.cdr.filename, "a");
+ if (!cdr_file) {
+ LOGP(DGPRS, LOGL_ERROR, "Failed to open %s\n",
+ inst->cfg.cdr.filename);
+ return;
+ }
+
+ maybe_print_header(cdr_file);
+ fprintf(cdr_file, "%s\n", buf);
- fclose(cdr_file);
+ fclose(cdr_file);
+ }
}
static void extract_eua(struct ul66_t *eua, char *eua_addr)
@@ -124,24 +149,22 @@ static void extract_eua(struct ul66_t *eua, char *eua_addr)
}
}
-static void cdr_log_pdp(struct sgsn_instance *inst, const char *ev,
+static int cdr_snprintf_pdp(char *buf, size_t size, const char *ev,
struct sgsn_pdp_ctx *pdp)
{
- FILE *cdr_file;
char apni[(pdp->lib ? pdp->lib->apn_use.l : 0) + 1];
- char ggsn_addr[INET_ADDRSTRLEN + 1];
- char sgsn_addr[INET_ADDRSTRLEN + 1];
- char eua_addr[INET6_ADDRSTRLEN + 1];
+ char ggsn_addr[INET_ADDRSTRLEN];
+ char sgsn_addr[INET_ADDRSTRLEN];
+ char eua_addr[INET6_ADDRSTRLEN];
struct tm tm;
struct timeval tv;
time_t duration;
struct timespec tp;
-
- if (!inst->cfg.cdr.filename)
- return;
+ int ret;
memset(apni, 0, sizeof(apni));
memset(ggsn_addr, 0, sizeof(ggsn_addr));
+ memset(sgsn_addr, 0, sizeof(sgsn_addr));
memset(eua_addr, 0, sizeof(eua_addr));
@@ -154,16 +177,7 @@ static void cdr_log_pdp(struct sgsn_instance *inst, const char *ev,
if (pdp->ggsn)
inet_ntop(AF_INET, &pdp->ggsn->gsn->gsnc.s_addr, sgsn_addr, sizeof(sgsn_addr));
- cdr_file = fopen(inst->cfg.cdr.filename, "a");
- if (!cdr_file) {
- LOGP(DGPRS, LOGL_ERROR, "Failed to open %s\n",
- inst->cfg.cdr.filename);
- return;
- }
-
- maybe_print_header(cdr_file);
-
- clock_gettime(CLOCK_MONOTONIC, &tp);
+ osmo_clock_gettime(CLOCK_MONOTONIC, &tp);
gettimeofday(&tv, NULL);
/* convert the timestamp to UTC */
@@ -172,8 +186,8 @@ static void cdr_log_pdp(struct sgsn_instance *inst, const char *ev,
/* Check the duration of the PDP context */
duration = tp.tv_sec - pdp->cdr_start.tv_sec;
- fprintf(cdr_file,
- "%04d%02d%02d%02d%02d%02d%03d,%s,%s,%s,%d,%d,%s,%s,%ld,%s,%s,%s,%s,%" PRIu64 ",%" PRIu64 ",%u\n",
+ ret = snprintf(buf, size,
+ "%04d%02d%02d%02d%02d%02d%03d,%s,%s,%s,%d,%d,%s,%s,%ld,%s,%s,%s,%s,%" PRIu64 ",%" PRIu64 ",%u",
tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
tm.tm_hour, tm.tm_min, tm.tm_sec,
(int)(tv.tv_usec / 1000),
@@ -192,7 +206,35 @@ static void cdr_log_pdp(struct sgsn_instance *inst, const char *ev,
pdp->cdr_bytes_in,
pdp->cdr_bytes_out,
pdp->cdr_charging_id);
- fclose(cdr_file);
+ return ret;
+}
+
+static void cdr_log_pdp(struct sgsn_instance *inst, const char *ev,
+ struct sgsn_pdp_ctx *pdp)
+{
+ FILE *cdr_file;
+ char buf[1024];
+
+ if (!inst->cfg.cdr.filename && !inst->cfg.cdr.trap)
+ return;
+
+ cdr_snprintf_pdp(buf, sizeof(buf), ev, pdp);
+
+ if (inst->cfg.cdr.trap)
+ send_cdr_trap(buf);
+
+ if (inst->cfg.cdr.filename) {
+ cdr_file = fopen(inst->cfg.cdr.filename, "a");
+ if (!cdr_file) {
+ LOGP(DGPRS, LOGL_ERROR, "Failed to open %s\n",
+ inst->cfg.cdr.filename);
+ return;
+ }
+
+ maybe_print_header(cdr_file);
+ fprintf(cdr_file, "%s\n", buf);
+ fclose(cdr_file);
+ }
}
static void cdr_pdp_timeout(void *_data)
@@ -225,7 +267,7 @@ static int handle_sgsn_sig(unsigned int subsys, unsigned int signal,
cdr_log_mm(inst, "free", signal_data->mm);
break;
case S_SGSN_PDP_ACT:
- clock_gettime(CLOCK_MONOTONIC, &signal_data->pdp->cdr_start);
+ osmo_clock_gettime(CLOCK_MONOTONIC, &signal_data->pdp->cdr_start);
signal_data->pdp->cdr_charging_id = signal_data->pdp->lib->cid;
cdr_log_pdp(inst, "pdp-act", signal_data->pdp);
osmo_timer_setup(&signal_data->pdp->cdr_timer, cdr_pdp_timeout,
diff --git a/src/gprs/sgsn_ctrl.c b/src/sgsn/sgsn_ctrl.c
index f7b1180be..ad91d25a5 100644
--- a/src/gprs/sgsn_ctrl.c
+++ b/src/sgsn/sgsn_ctrl.c
@@ -21,9 +21,9 @@
#include <osmocom/ctrl/control_if.h>
#include <osmocom/ctrl/control_cmd.h>
-#include <openbsc/gprs_sgsn.h>
-#include <openbsc/sgsn.h>
-#include <openbsc/debug.h>
+#include <osmocom/sgsn/gprs_sgsn.h>
+#include <osmocom/sgsn/sgsn.h>
+#include <osmocom/sgsn/debug.h>
#include <pdp.h>
@@ -60,9 +60,3 @@ int sgsn_ctrl_cmds_install(void)
rc |= ctrl_cmd_install(CTRL_NODE_ROOT, &cmd_subscriber_list);
return rc;
}
-
-struct ctrl_handle *sgsn_controlif_setup(struct gsm_network *net,
- const char *bind_addr, uint16_t port)
-{
- return ctrl_interface_setup_dynip(net, bind_addr, port, NULL);
-}
diff --git a/src/gprs/sgsn_libgtp.c b/src/sgsn/sgsn_libgtp.c
index 90b4d1636..7b46476b0 100644
--- a/src/gprs/sgsn_libgtp.c
+++ b/src/sgsn/sgsn_libgtp.c
@@ -42,19 +42,19 @@
#include <osmocom/gprs/gprs_bssgp.h>
#include <osmocom/gsm/protocol/gsm_04_08_gprs.h>
-#include <openbsc/signal.h>
-#include <openbsc/debug.h>
-#include <openbsc/sgsn.h>
-#include <openbsc/gprs_llc.h>
-#include <openbsc/gprs_sgsn.h>
-#include <openbsc/gprs_gmm.h>
-#include <openbsc/gprs_subscriber.h>
-#include <openbsc/gprs_sndcp.h>
-
-#ifdef BUILD_IU
-#include <osmocom/ranap/iu_client.h>
-#include <osmocom/ranap/ranap_ies_defs.h>
-#endif
+#include <osmocom/sgsn/signal.h>
+#include <osmocom/sgsn/debug.h>
+#include <osmocom/sgsn/sgsn.h>
+#include <osmocom/sgsn/gprs_gb.h>
+#include <osmocom/sgsn/gprs_llc.h>
+#include <osmocom/sgsn/gprs_sgsn.h>
+#include <osmocom/sgsn/gprs_gmm.h>
+#include <osmocom/sgsn/gprs_sm.h>
+#include <osmocom/sgsn/gprs_subscriber.h>
+#include <osmocom/sgsn/gprs_sndcp.h>
+#include <osmocom/sgsn/gprs_ranap.h>
+#include <osmocom/sgsn/gprs_gmm_fsm.h>
+#include <osmocom/sgsn/gprs_mm_state_gb_fsm.h>
#include <gtp.h>
#include <pdp.h>
@@ -145,8 +145,7 @@ struct sgsn_pdp_ctx *sgsn_create_pdp_ctx(struct sgsn_ggsn_ctx *ggsn,
const uint8_t *qos;
int rc;
- LOGP(DGPRS, LOGL_ERROR, "Create PDP Context\n");
- pctx = sgsn_pdp_ctx_alloc(mmctx, nsapi);
+ pctx = sgsn_pdp_ctx_alloc(mmctx, ggsn, nsapi);
if (!pctx) {
LOGP(DGPRS, LOGL_ERROR, "Couldn't allocate PDP Ctx\n");
return NULL;
@@ -154,14 +153,13 @@ struct sgsn_pdp_ctx *sgsn_create_pdp_ctx(struct sgsn_ggsn_ctx *ggsn,
imsi_ui64 = imsi_str2gtp(mmctx->imsi);
- rc = pdp_newpdp(&pdp, imsi_ui64, nsapi, NULL);
+ rc = gtp_pdp_newpdp(ggsn->gsn, &pdp, imsi_ui64, nsapi, NULL);
if (rc) {
LOGP(DGPRS, LOGL_ERROR, "Out of libgtp PDP Contexts\n");
return NULL;
}
pdp->priv = pctx;
pctx->lib = pdp;
- pctx->ggsn = ggsn;
//pdp->peer = /* sockaddr_in of GGSN (receive) */
//pdp->ipif = /* not used by library */
@@ -174,12 +172,11 @@ struct sgsn_pdp_ctx *sgsn_create_pdp_ctx(struct sgsn_ggsn_ctx *ggsn,
pdp->selmode = 0xFC | 0x00;
/* IMSI, TEID/TEIC, FLLU/FLLC, TID, NSAPI set in pdp_newpdp */
+ LOGPDPCTXP(LOGL_NOTICE, pctx, "Create PDP Context\n");
/* Put the MSISDN in case we have it */
if (mmctx->subscr && mmctx->subscr->sgsn_data->msisdn_len) {
- pdp->msisdn.l = mmctx->subscr->sgsn_data->msisdn_len;
- if (pdp->msisdn.l > sizeof(pdp->msisdn.v))
- pdp->msisdn.l = sizeof(pdp->msisdn.v);
+ pdp->msisdn.l = OSMO_MIN(mmctx->subscr->sgsn_data->msisdn_len, sizeof(pdp->msisdn.v));
memcpy(pdp->msisdn.v, mmctx->subscr->sgsn_data->msisdn,
pdp->msisdn.l);
} else {
@@ -199,18 +196,25 @@ struct sgsn_pdp_ctx *sgsn_create_pdp_ctx(struct sgsn_ggsn_ctx *ggsn,
pdp->eua.v[0] |= 0xf0;
/* APN name from GMM */
- pdp->apn_use.l = TLVP_LEN(tp, GSM48_IE_GSM_APN);
- if (pdp->apn_use.l > sizeof(pdp->apn_use.v))
- pdp->apn_use.l = sizeof(pdp->apn_use.v);
- memcpy(pdp->apn_use.v, TLVP_VAL(tp, GSM48_IE_GSM_APN),
- pdp->apn_use.l);
+ if (TLVP_PRESENT(tp, GSM48_IE_GSM_APN)) {
+ pdp->apn_use.l = TLVP_LEN(tp, GSM48_IE_GSM_APN);
+ if (pdp->apn_use.l > sizeof(pdp->apn_use.v))
+ pdp->apn_use.l = sizeof(pdp->apn_use.v);
+ memcpy(pdp->apn_use.v, TLVP_VAL(tp, GSM48_IE_GSM_APN), pdp->apn_use.l);
+ } else {
+ pdp->apn_use.l = 0;
+ }
/* Protocol Configuration Options from GMM */
- pdp->pco_req.l = TLVP_LEN(tp, GSM48_IE_GSM_PROTO_CONF_OPT);
- if (pdp->pco_req.l > sizeof(pdp->pco_req.v))
- pdp->pco_req.l = sizeof(pdp->pco_req.v);
- memcpy(pdp->pco_req.v, TLVP_VAL(tp, GSM48_IE_GSM_PROTO_CONF_OPT),
- pdp->pco_req.l);
+ if (TLVP_PRESENT(tp, GSM48_IE_GSM_PROTO_CONF_OPT)) {
+ pdp->pco_req.l = TLVP_LEN(tp, GSM48_IE_GSM_PROTO_CONF_OPT);
+ if (pdp->pco_req.l > sizeof(pdp->pco_req.v))
+ pdp->pco_req.l = sizeof(pdp->pco_req.v);
+ memcpy(pdp->pco_req.v, TLVP_VAL(tp, GSM48_IE_GSM_PROTO_CONF_OPT),
+ pdp->pco_req.l);
+ } else {
+ pdp->pco_req.l = 0;
+ }
/* QoS options from GMM or remote */
if (TLVP_LEN(tp, OSMO_IE_GSM_SUB_QOS) > 0) {
@@ -268,14 +272,16 @@ struct sgsn_pdp_ctx *sgsn_create_pdp_ctx(struct sgsn_ggsn_ctx *ggsn,
raid = mmctx->ra;
raid.lac = 0xFFFE;
raid.rac = 0xFF;
- gsm48_construct_ra(pdp->rai.v, &raid);
+ gsm48_encode_ra((struct gsm48_ra_id *)pdp->rai.v, &raid);
/* Encode User Location Information accordint to TS 29.060 7.7.51 */
pdp->userloc_given = 1;
pdp->userloc.l = 8;
switch (mmctx->ran_type) {
case MM_CTX_T_GERAN_Gb:
+#if 0
case MM_CTX_T_GERAN_Iu:
+#endif
pdp->rattype.v[0] = 2;
/* User Location Information */
pdp->userloc_given = 1;
@@ -308,10 +314,10 @@ struct sgsn_pdp_ctx *sgsn_create_pdp_ctx(struct sgsn_ggsn_ctx *ggsn,
/* SGSN wants to delete a PDP context */
int sgsn_delete_pdp_ctx(struct sgsn_pdp_ctx *pctx)
{
- LOGPDPCTXP(LOGL_ERROR, pctx, "Delete PDP Context\n");
+ LOGPDPCTXP(LOGL_INFO, pctx, "Delete PDP Context\n");
/* FIXME: decide if we need teardown or not ! */
- return gtp_delete_context_req(pctx->ggsn->gsn, pctx->lib, pctx, 1);
+ return gtp_delete_context_req2(pctx->ggsn->gsn, pctx->lib, pctx, 1);
}
struct cause_map {
@@ -353,7 +359,7 @@ static const struct cause_map gtp2sm_cause_map[] = {
{ 0, 0 }
};
-static int send_act_pdp_cont_acc(struct sgsn_pdp_ctx *pctx)
+int send_act_pdp_cont_acc(struct sgsn_pdp_ctx *pctx)
{
struct sgsn_signal_data sig_data;
int rc;
@@ -384,15 +390,13 @@ static int send_act_pdp_cont_acc(struct sgsn_pdp_ctx *pctx)
static int create_pdp_conf(struct pdp_t *pdp, void *cbp, int cause)
{
struct sgsn_pdp_ctx *pctx = cbp;
- uint8_t reject_cause;
+ uint8_t reject_cause = 0;
LOGPDPCTXP(LOGL_INFO, pctx, "Received CREATE PDP CTX CONF, cause=%d(%s)\n",
cause, get_value_string(gtp_cause_strs, cause));
if (!pctx->mm) {
- LOGP(DGPRS, LOGL_INFO,
- "No MM context, aborting CREATE PDP CTX CONF\n");
- return -EIO;
+ goto reject;
}
/* Check for cause value if it was really successful */
@@ -446,9 +450,11 @@ reject:
if (pdp)
pdp_freepdp(pdp);
+
/* Send PDP CTX ACT REJ to MS */
- gsm48_tx_gsm_act_pdp_rej(pctx->mm, pctx->ti, reject_cause,
- 0, NULL);
+ if (pctx->mm)
+ gsm48_tx_gsm_act_pdp_rej(pctx->mm, pctx->ti, reject_cause,
+ 0, NULL);
sgsn_pdp_ctx_free(pctx);
return EOF;
@@ -461,71 +467,11 @@ void sgsn_pdp_upd_gtp_u(struct sgsn_pdp_ctx *pdp, void *addr, size_t alen)
gtp_update_context(pdp->ggsn->gsn, pdp->lib, pdp, &pdp->lib->hisaddr0);
}
-#ifdef BUILD_IU
-/* Callback for RAB assignment response */
-int sgsn_ranap_rab_ass_resp(struct sgsn_mm_ctx *ctx, RANAP_RAB_SetupOrModifiedItemIEs_t *setup_ies)
+void sgsn_ggsn_echo_req(struct sgsn_ggsn_ctx *ggc)
{
- uint8_t rab_id;
- bool require_pdp_update = false;
- struct sgsn_pdp_ctx *pdp = NULL;
- RANAP_RAB_SetupOrModifiedItem_t *item = &setup_ies->raB_SetupOrModifiedItem;
-
- rab_id = item->rAB_ID.buf[0];
-
- pdp = sgsn_pdp_ctx_by_nsapi(ctx, rab_id);
- if (!pdp) {
- LOGP(DRANAP, LOGL_ERROR, "RAB Assignment Response for unknown RAB/NSAPI=%u\n", rab_id);
- return -1;
- }
-
- if (item->transportLayerAddress) {
- LOGPC(DRANAP, LOGL_INFO, " Setup: (%u/%s)", rab_id, osmo_hexdump(item->transportLayerAddress->buf,
- item->transportLayerAddress->size));
- switch (item->transportLayerAddress->size) {
- case 7:
- /* It must be IPv4 inside a X213 NSAP */
- memcpy(pdp->lib->gsnlu.v, &item->transportLayerAddress->buf[3], 4);
- break;
- case 4:
- /* It must be a raw IPv4 address */
- memcpy(pdp->lib->gsnlu.v, item->transportLayerAddress->buf, 4);
- break;
- case 16:
- /* TODO: It must be a raw IPv6 address */
- case 19:
- /* TODO: It must be IPv6 inside a X213 NSAP */
- default:
- LOGP(DRANAP, LOGL_ERROR, "RAB Assignment Resp: Unknown "
- "transport layer address size %u\n",
- item->transportLayerAddress->size);
- return -1;
- }
- require_pdp_update = true;
- }
-
- /* The TEI on the RNC side might have changed, too */
- if (item->iuTransportAssociation &&
- item->iuTransportAssociation->present == RANAP_IuTransportAssociation_PR_gTP_TEI &&
- item->iuTransportAssociation->choice.gTP_TEI.buf &&
- item->iuTransportAssociation->choice.gTP_TEI.size >= 4) {
- uint32_t tei = osmo_load32be(item->iuTransportAssociation->choice.gTP_TEI.buf);
- LOGP(DRANAP, LOGL_DEBUG, "Updating TEID on RNC side from 0x%08x to 0x%08x\n",
- pdp->lib->teid_own, tei);
- pdp->lib->teid_own = tei;
- require_pdp_update = true;
- }
-
- if (require_pdp_update)
- gtp_update_context(pdp->ggsn->gsn, pdp->lib, pdp, &pdp->lib->hisaddr0);
-
- if (pdp->state != PDP_STATE_CR_CONF) {
- send_act_pdp_cont_acc(pdp);
- pdp->state = PDP_STATE_CR_CONF;
- }
- return 0;
-
+ LOGGGSN(ggc, LOGL_INFO, "GTP Tx Echo Request\n");
+ gtp_echo_req(ggc->gsn, ggc->gtp_version, ggc, &ggc->remote_addr);
}
-#endif
/* Confirmation of a PDP Context Delete */
static int delete_pdp_conf(struct pdp_t *pdp, void *cbp, int cause)
@@ -562,32 +508,31 @@ static int delete_pdp_conf(struct pdp_t *pdp, void *cbp, int cause)
"is not available\n");
}
- /* unlink the now non-existing library handle from the pdp
- * context */
- pctx->lib = NULL;
-
sgsn_pdp_ctx_free(pctx);
return rc;
}
/* Confirmation of an GTP ECHO request */
-static int echo_conf(struct pdp_t *pdp, void *cbp, int recovery)
+static int echo_conf(void *cbp, bool timeout)
{
- if (recovery < 0) {
- LOGP(DGPRS, LOGL_NOTICE, "GTP Echo Request timed out\n");
+ struct sgsn_ggsn_ctx *ggc = (struct sgsn_ggsn_ctx *)cbp;
+ if (timeout) {
+ LOGGGSN(ggc, LOGL_NOTICE, "GTP Echo Request timed out\n");
/* FIXME: if version == 1, retry with version 0 */
+ sgsn_ggsn_ctx_drop_all_pdp(ggc);
} else {
- DEBUGP(DGPRS, "GTP Rx Echo Response\n");
+ LOGGGSN(ggc, LOGL_INFO, "GTP Rx Echo Response\n");
}
return 0;
}
/* Any message received by GGSN contains a recovery IE */
-static int cb_recovery(struct sockaddr_in *peer, uint8_t recovery)
+static int cb_recovery2(struct sockaddr_in *peer, struct pdp_t *pdp, uint8_t recovery)
{
struct sgsn_ggsn_ctx *ggsn;
-
+ struct sgsn_pdp_ctx *pctx = NULL;
+
ggsn = sgsn_ggsn_ctx_by_addr(&peer->sin_addr);
if (!ggsn) {
LOGP(DGPRS, LOGL_NOTICE, "Received Recovery IE for unknown GGSN\n");
@@ -599,11 +544,13 @@ static int cb_recovery(struct sockaddr_in *peer, uint8_t recovery)
ggsn->remote_restart_ctr = recovery;
} else if (ggsn->remote_restart_ctr != recovery) {
/* counter has changed (GGSN restart): release all PDP */
- LOGP(DGPRS, LOGL_NOTICE, "GGSN recovery (%u->%u), "
- "releasing all PDP contexts\n",
- ggsn->remote_restart_ctr, recovery);
+ LOGP(DGPRS, LOGL_NOTICE, "GGSN recovery (%u->%u) pdp=%p, "
+ "releasing all%s PDP contexts\n",
+ ggsn->remote_restart_ctr, recovery, pdp, pdp ? " other" : "");
ggsn->remote_restart_ctr = recovery;
- drop_all_pdp_for_ggsn(ggsn);
+ if (pdp)
+ pctx = pdp->priv;
+ sgsn_ggsn_ctx_drop_all_pdp_except(ggsn, pctx);
}
return 0;
}
@@ -620,8 +567,8 @@ static int cb_conf(int type, int cause, struct pdp_t *pdp, void *cbp)
switch (type) {
case GTP_ECHO_REQ:
- /* libgtp hands us the RECOVERY number instead of a cause */
- return echo_conf(pdp, cbp, cause);
+ /* libgtp hands us the RECOVERY number instead of a cause (EOF on timeout) */
+ return echo_conf(cbp, cause == EOF);
case GTP_CREATE_PDP_REQ:
return create_pdp_conf(pdp, cbp, cause);
case GTP_DELETE_PDP_REQ:
@@ -635,7 +582,16 @@ static int cb_conf(int type, int cause, struct pdp_t *pdp, void *cbp)
/* Called whenever a PDP context is deleted for any reason */
static int cb_delete_context(struct pdp_t *pdp)
{
- LOGP(DGPRS, LOGL_INFO, "PDP Context was deleted\n");
+ struct sgsn_pdp_ctx *pctx = pdp->priv;
+
+ LOGPDPX(DGPRS, LOGL_INFO, pdp, "Context %p was deleted\n", pdp);
+
+ /* unlink the now non-existing library handle from the pdp context.
+ This way we avoid calling pdp_freepdp() on it, since after returning
+ from cb_delete_context callback, libgtp is already doing so. */
+ pctx->lib = NULL;
+
+ sgsn_ggsn_ctx_drop_pdp(pctx);
return 0;
}
@@ -651,16 +607,15 @@ static int cb_unsup_ind(struct sockaddr_in *peer)
/* Called when we receive a Supported Ext Headers Notification */
static int cb_extheader_ind(struct sockaddr_in *peer)
{
- LOGP(DGPRS, LOGL_INFO, "GTP Supported Ext Headers Noficiation "
+ LOGP(DGPRS, LOGL_INFO, "GTP Supported Ext Headers Notification "
"from %s:%u\n", inet_ntoa(peer->sin_addr),
ntohs(peer->sin_port));
return 0;
}
-/* Called whenever we recive a DATA packet */
+/* Called whenever we receive a DATA packet */
static int cb_data_ind(struct pdp_t *lib, void *packet, unsigned int len)
{
- struct bssgp_paging_info pinfo;
struct sgsn_pdp_ctx *pdp;
struct sgsn_mm_ctx *mm;
struct msgb *msg;
@@ -703,26 +658,22 @@ static int cb_data_ind(struct pdp_t *lib, void *packet, unsigned int len)
msgb_bvci(msg) = mm->gb.bvci;
msgb_nsei(msg) = mm->gb.nsei;
- switch (mm->gmm_state) {
- case GMM_REGISTERED_SUSPENDED:
+ switch (mm->gmm_fsm->state) {
+ case ST_GMM_REGISTERED_SUSPENDED:
/* initiate PS PAGING procedure */
- memset(&pinfo, 0, sizeof(pinfo));
- pinfo.mode = BSSGP_PAGING_PS;
- pinfo.scope = BSSGP_PAGING_BVCI;
- pinfo.bvci = mm->gb.bvci;
- pinfo.imsi = mm->imsi;
- pinfo.ptmsi = &mm->p_tmsi;
- pinfo.drx_params = mm->drx_parms;
- pinfo.qos[0] = 0; // FIXME
- bssgp_tx_paging(mm->gb.nsei, 0, &pinfo);
- rate_ctr_inc(&mm->ctrg->ctr[GMM_CTR_PAGING_PS]);
+ gprs_gb_page_ps_ra(mm);
/* FIXME: queue the packet we received from GTP */
break;
- case GMM_REGISTERED_NORMAL:
+ case ST_GMM_REGISTERED_NORMAL:
+ OSMO_ASSERT(mm->gb.mm_state_fsm->state != ST_MM_IDLE);
+ if (mm->gb.mm_state_fsm->state == ST_MM_STANDBY)
+ gprs_gb_page_ps_ra(mm);
+
+ /* FIXME: queue the packet we received from GTP */
break;
default:
LOGP(DGPRS, LOGL_ERROR, "GTP DATA IND for TLLI %08X in state "
- "%u\n", mm->gb.tlli, mm->gmm_state);
+ "%s\n", mm->gb.tlli, osmo_fsm_inst_state_name(mm->gmm_fsm));
msgb_free(msg);
return -1;
}
@@ -782,7 +733,7 @@ static int sgsn_gtp_fd_cb(struct osmo_fd *fd, unsigned int what)
struct sgsn_instance *sgi = fd->data;
int rc;
- if (!(what & BSC_FD_READ))
+ if (!(what & OSMO_FD_READ))
return 0;
switch (fd->priv_nr) {
@@ -802,28 +753,6 @@ static int sgsn_gtp_fd_cb(struct osmo_fd *fd, unsigned int what)
return rc;
}
-static void sgsn_gtp_tmr_start(struct sgsn_instance *sgi)
-{
- struct timeval next;
-
- /* Retrieve next retransmission as struct timeval */
- gtp_retranstimeout(sgi->gsn, &next);
-
- /* re-schedule the timer */
- osmo_timer_schedule(&sgi->gtp_timer, next.tv_sec, next.tv_usec/1000);
-}
-
-/* timer callback for libgtp retransmissions and ping */
-static void sgsn_gtp_tmr_cb(void *data)
-{
- struct sgsn_instance *sgi = data;
-
- /* Do all the retransmissions as needed */
- gtp_retrans(sgi->gsn);
-
- sgsn_gtp_tmr_start(sgi);
-}
-
int sgsn_gtp_init(struct sgsn_instance *sgi)
{
int rc;
@@ -835,12 +764,17 @@ int sgsn_gtp_init(struct sgsn_instance *sgi)
LOGP(DGPRS, LOGL_ERROR, "Failed to create GTP: %d\n", rc);
return rc;
}
+ LOGP(DGPRS, LOGL_NOTICE, "Created GTP on %s\n", inet_ntoa(sgi->cfg.gtp_listenaddr.sin_addr));
+
gsn = sgi->gsn;
+ if (gsn->mode != GTP_MODE_SGSN)
+ return -EINVAL;
+
sgi->gtp_fd0.fd = gsn->fd0;
sgi->gtp_fd0.priv_nr = 0;
sgi->gtp_fd0.data = sgi;
- sgi->gtp_fd0.when = BSC_FD_READ;
+ sgi->gtp_fd0.when = OSMO_FD_READ;
sgi->gtp_fd0.cb = sgsn_gtp_fd_cb;
rc = osmo_fd_register(&sgi->gtp_fd0);
if (rc < 0)
@@ -849,7 +783,7 @@ int sgsn_gtp_init(struct sgsn_instance *sgi)
sgi->gtp_fd1c.fd = gsn->fd1c;
sgi->gtp_fd1c.priv_nr = 1;
sgi->gtp_fd1c.data = sgi;
- sgi->gtp_fd1c.when = BSC_FD_READ;
+ sgi->gtp_fd1c.when = OSMO_FD_READ;
sgi->gtp_fd1c.cb = sgsn_gtp_fd_cb;
rc = osmo_fd_register(&sgi->gtp_fd1c);
if (rc < 0) {
@@ -860,7 +794,7 @@ int sgsn_gtp_init(struct sgsn_instance *sgi)
sgi->gtp_fd1u.fd = gsn->fd1u;
sgi->gtp_fd1u.priv_nr = 2;
sgi->gtp_fd1u.data = sgi;
- sgi->gtp_fd1u.when = BSC_FD_READ;
+ sgi->gtp_fd1u.when = OSMO_FD_READ;
sgi->gtp_fd1u.cb = sgsn_gtp_fd_cb;
rc = osmo_fd_register(&sgi->gtp_fd1u);
if (rc < 0) {
@@ -869,14 +803,10 @@ int sgsn_gtp_init(struct sgsn_instance *sgi)
return rc;
}
- /* Start GTP re-transmission timer */
- osmo_timer_setup(&sgi->gtp_timer, sgsn_gtp_tmr_cb, sgi);
- sgsn_gtp_tmr_start(sgi);
-
/* Register callbackcs with libgtp */
gtp_set_cb_delete_context(gsn, cb_delete_context);
gtp_set_cb_conf(gsn, cb_conf);
- gtp_set_cb_recovery(gsn, cb_recovery);
+ gtp_set_cb_recovery2(gsn, cb_recovery2);
gtp_set_cb_data_ind(gsn, cb_data_ind);
gtp_set_cb_unsup_ind(gsn, cb_unsup_ind);
gtp_set_cb_extheader_ind(gsn, cb_extheader_ind);
diff --git a/src/gprs/sgsn_main.c b/src/sgsn/sgsn_main.c
index 8ffc6c83d..3b18b051c 100644
--- a/src/gprs/sgsn_main.c
+++ b/src/sgsn/sgsn_main.c
@@ -40,8 +40,6 @@
#include <osmocom/core/logging.h>
#include <osmocom/core/stats.h>
-#include <osmocom/gsm/gsup.h>
-
#include <osmocom/gprs/gprs_ns.h>
#include <osmocom/gprs/gprs_bssgp.h>
@@ -49,15 +47,17 @@
#include <osmocom/vty/logging.h>
#include <osmocom/vty/stats.h>
#include <osmocom/vty/ports.h>
+#include <osmocom/vty/misc.h>
#include <osmocom/ctrl/control_vty.h>
-#include <openbsc/signal.h>
-#include <openbsc/debug.h>
-#include <openbsc/vty.h>
-#include <openbsc/sgsn.h>
-#include <openbsc/gprs_llc.h>
-#include <openbsc/gprs_gmm.h>
+#include <osmocom/sgsn/signal.h>
+#include <osmocom/sgsn/debug.h>
+#include <osmocom/sgsn/vty.h>
+#include <osmocom/sgsn/sgsn.h>
+#include <osmocom/sgsn/gprs_llc.h>
+#include <osmocom/sgsn/gprs_gmm.h>
+#include <osmocom/sgsn/gprs_ranap.h>
#include <osmocom/ctrl/control_if.h>
#include <osmocom/ctrl/ports.h>
@@ -75,7 +75,8 @@
#define _GNU_SOURCE
#include <getopt.h>
-void *tall_bsc_ctx;
+void *tall_sgsn_ctx;
+struct ctrl_handle *g_ctrlh;
struct gprs_ns_inst *sgsn_nsi;
static int daemonize = 0;
@@ -85,15 +86,11 @@ const char *openbsc_copyright =
"This is free software: you are free to change and redistribute it.\r\n"
"There is NO WARRANTY, to the extent permitted by law.\r\n";
-static struct sgsn_instance sgsn_inst = {
- .config_file = "osmo_sgsn.cfg",
- .cfg = {
- .gtp_statedir = "./",
- .auth_policy = SGSN_AUTH_POLICY_CLOSED,
- .gsup_server_port = OSMO_GSUP_PORT,
- },
-};
-struct sgsn_instance *sgsn = &sgsn_inst;
+#define CONFIG_FILE_DEFAULT "osmo-sgsn.cfg"
+#define CONFIG_FILE_LEGACY "osmo_sgsn.cfg"
+
+
+struct sgsn_instance *sgsn;
/* call-back function for the NS protocol */
static int sgsn_ns_cb(enum gprs_ns_evt event, struct gprs_nsvc *nsvc,
@@ -160,7 +157,7 @@ static void signal_handler(int signal)
* and then return to the caller, who will abort the process */
case SIGUSR1:
talloc_report(tall_vty_ctx, stderr);
- talloc_report_full(tall_bsc_ctx, stderr);
+ talloc_report_full(tall_sgsn_ctx, stderr);
break;
case SIGUSR2:
talloc_report_full(tall_vty_ctx, stderr);
@@ -213,10 +210,11 @@ static void print_help(void)
{
printf("Some useful help...\n");
printf(" -h --help\tthis text\n");
+ printf(" -V --version\tPrint the version\n");
printf(" -D --daemonize\tFork the process into a background daemon\n");
printf(" -d option --debug\tenable Debugging\n");
printf(" -s --disable-color\n");
- printf(" -c --config-file\tThe config file to use [%s]\n", sgsn->config_file);
+ printf(" -c --config-file\tThe config file to use [%s]\n", CONFIG_FILE_DEFAULT);
printf(" -e --log-level number\tSet a global log level\n");
}
@@ -256,7 +254,7 @@ static void handle_options(int argc, char **argv)
daemonize = 1;
break;
case 'c':
- sgsn_inst.config_file = strdup(optarg);
+ osmo_talloc_replace_string(sgsn, &sgsn->config_file, optarg);
break;
case 'T':
log_set_print_timestamp(osmo_stderr_target, 1);
@@ -273,6 +271,11 @@ static void handle_options(int argc, char **argv)
break;
}
}
+
+ if (argc > optind) {
+ fprintf(stderr, "Unsupported positional arguments on command line\n");
+ exit(2);
+ }
}
/* default categories */
@@ -302,48 +305,53 @@ static struct log_info_cat gprs_categories[] = {
[DGPRS] = {
.name = "DGPRS",
.description = "GPRS Packet Service",
- .enabled = 1, .loglevel = LOGL_DEBUG,
+ .enabled = 1, .loglevel = LOGL_NOTICE,
},
[DNS] = {
.name = "DNS",
.description = "GPRS Network Service (NS)",
- .enabled = 1, .loglevel = LOGL_INFO,
+ .enabled = 1, .loglevel = LOGL_NOTICE,
},
[DBSSGP] = {
.name = "DBSSGP",
.description = "GPRS BSS Gateway Protocol (BSSGP)",
- .enabled = 1, .loglevel = LOGL_DEBUG,
+ .enabled = 1, .loglevel = LOGL_NOTICE,
},
[DLLC] = {
.name = "DLLC",
.description = "GPRS Logical Link Control Protocol (LLC)",
- .enabled = 1, .loglevel = LOGL_DEBUG,
+ .enabled = 1, .loglevel = LOGL_NOTICE,
},
[DSNDCP] = {
.name = "DSNDCP",
.description = "GPRS Sub-Network Dependent Control Protocol (SNDCP)",
- .enabled = 1, .loglevel = LOGL_DEBUG,
+ .enabled = 1, .loglevel = LOGL_NOTICE,
},
[DRANAP] = {
.name = "DRANAP",
.description = "RAN Application Part (RANAP)",
- .enabled = 1, .loglevel = LOGL_DEBUG,
+ .enabled = 1, .loglevel = LOGL_NOTICE,
},
[DSUA] = {
.name = "DSUA",
.description = "SCCP User Adaptation (SUA)",
- .enabled = 1, .loglevel = LOGL_DEBUG,
+ .enabled = 1, .loglevel = LOGL_NOTICE,
},
[DSLHC] = {
.name = "DSLHC",
.description = "RFC1144 TCP/IP Header compression (SLHC)",
- .enabled = 1, .loglevel = LOGL_DEBUG,
+ .enabled = 1, .loglevel = LOGL_NOTICE,
},
[DV42BIS] = {
.name = "DV42BIS",
.description = "V.42bis data compression (SNDCP)",
- .enabled = 1, .loglevel = LOGL_DEBUG,
- }
+ .enabled = 1, .loglevel = LOGL_NOTICE,
+ },
+ [DGTP] = {
+ .name = "DGTP",
+ .description = "GPRS Tunnelling Protocol (GTP)",
+ .enabled = 1, .loglevel = LOGL_NOTICE,
+ },
};
static const struct log_info gprs_log_info = {
@@ -352,21 +360,24 @@ static const struct log_info gprs_log_info = {
.num_cat = ARRAY_SIZE(gprs_categories),
};
-#if BUILD_IU
-int sgsn_ranap_iu_event(struct ranap_ue_conn_ctx *ctx, enum ranap_iu_event_type type, void *data);
-#endif
+static bool file_exists(const char *path)
+{
+ struct stat sb;
+ return stat(path, &sb) ? false : true;
+}
int main(int argc, char **argv)
{
- struct ctrl_handle *ctrl;
int rc;
#if BUILD_IU
struct osmo_sccp_instance *sccp;
#endif
srand(time(NULL));
- tall_bsc_ctx = talloc_named_const(NULL, 0, "osmo_sgsn");
- msgb_talloc_ctx_init(tall_bsc_ctx, 0);
+ tall_sgsn_ctx = talloc_named_const(NULL, 0, "osmo_sgsn");
+ sgsn = sgsn_instance_alloc(tall_sgsn_ctx);
+ msgb_talloc_ctx_init(tall_sgsn_ctx, 0);
+ vty_info.tall_ctx = tall_sgsn_ctx;
signal(SIGINT, &signal_handler);
signal(SIGTERM, &signal_handler);
@@ -375,64 +386,81 @@ int main(int argc, char **argv)
signal(SIGUSR2, &signal_handler);
osmo_init_ignore_signals();
- osmo_init_logging(&gprs_log_info);
- osmo_stats_init(tall_bsc_ctx);
+ osmo_init_logging2(tall_sgsn_ctx, &gprs_log_info);
+ osmo_stats_init(tall_sgsn_ctx);
vty_info.copyright = openbsc_copyright;
vty_init(&vty_info);
- logging_vty_add_cmds(NULL);
- osmo_stats_vty_add_cmds(&gprs_log_info);
- sgsn_vty_init(&sgsn_inst.cfg);
- ctrl_vty_init(tall_bsc_ctx);
+ logging_vty_add_cmds();
+ osmo_talloc_vty_add_cmds();
+ osmo_stats_vty_add_cmds();
+ sgsn_vty_init(&sgsn->cfg);
+ ctrl_vty_init(tall_sgsn_ctx);
#if BUILD_IU
- osmo_ss7_init();
- osmo_ss7_vty_init_asp(tall_bsc_ctx);
+ OSMO_ASSERT(osmo_ss7_init() == 0);
+ osmo_ss7_vty_init_asp(tall_sgsn_ctx);
+ osmo_sccp_vty_init();
#endif
handle_options(argc, argv);
- rate_ctr_init(tall_bsc_ctx);
+ /* Backwards compatibility: for years, the default config file name was
+ * osmo_sgsn.cfg. All other Osmocom programs use osmo-*.cfg with a
+ * dash. To be able to use the new config file name without breaking
+ * previous setups that might rely on the legacy default config file
+ * name, we need to look for the old config file if no -c option was
+ * passed AND no file exists with the new default file name. */
+ if (!sgsn->config_file) {
+ /* No -c option was passed */
+ if (file_exists(CONFIG_FILE_LEGACY)
+ && !file_exists(CONFIG_FILE_DEFAULT))
+ osmo_talloc_replace_string(sgsn, &sgsn->config_file, CONFIG_FILE_LEGACY);
+ else
+ osmo_talloc_replace_string(sgsn, &sgsn->config_file, CONFIG_FILE_DEFAULT);
+ }
+
+ rate_ctr_init(tall_sgsn_ctx);
gprs_ns_set_log_ss(DNS);
bssgp_set_log_ss(DBSSGP);
- sgsn_nsi = gprs_ns_instantiate(&sgsn_ns_cb, tall_bsc_ctx);
+ sgsn_nsi = gprs_ns_instantiate(&sgsn_ns_cb, tall_sgsn_ctx);
if (!sgsn_nsi) {
LOGP(DGPRS, LOGL_ERROR, "Unable to instantiate NS\n");
exit(1);
}
- bssgp_nsi = sgsn_inst.cfg.nsi = sgsn_nsi;
+ bssgp_nsi = sgsn->cfg.nsi = sgsn_nsi;
gprs_llc_init("/usr/local/lib/osmocom/crypt/");
sgsn_rate_ctr_init();
- sgsn_inst_init();
+ sgsn_inst_init(sgsn);
gprs_ns_vty_init(bssgp_nsi);
bssgp_vty_init();
gprs_llc_vty_init();
gprs_sndcp_vty_init();
- sgsn_auth_init();
- sgsn_cdr_init(&sgsn_inst);
+ sgsn_auth_init(sgsn);
+ sgsn_cdr_init(sgsn);
/* FIXME: register signal handler for SS_L_NS */
- rc = sgsn_parse_config(sgsn_inst.config_file);
+ rc = sgsn_parse_config(sgsn->config_file);
if (rc < 0) {
LOGP(DGPRS, LOGL_FATAL, "Error in config file\n");
exit(2);
}
/* start telnet after reading config for vty_get_bind_addr() */
- rc = telnet_init_dynif(tall_bsc_ctx, NULL,
+ rc = telnet_init_dynif(tall_sgsn_ctx, NULL,
vty_get_bind_addr(), OSMO_VTY_PORT_SGSN);
if (rc < 0)
exit(1);
/* start control interface after reading config for
* ctrl_vty_get_bind_addr() */
- ctrl = sgsn_controlif_setup(NULL, ctrl_vty_get_bind_addr(),
- OSMO_CTRL_PORT_SGSN);
- if (!ctrl) {
+ g_ctrlh = ctrl_interface_setup_dynip(NULL, ctrl_vty_get_bind_addr(),
+ OSMO_CTRL_PORT_SGSN, NULL);
+ if (!g_ctrlh) {
LOGP(DGPRS, LOGL_ERROR, "Failed to create CTRL interface.\n");
exit(1);
}
@@ -443,13 +471,14 @@ int main(int argc, char **argv)
}
- rc = sgsn_gtp_init(&sgsn_inst);
+ rc = sgsn_gtp_init(sgsn);
if (rc) {
LOGP(DGPRS, LOGL_FATAL, "Cannot bind/listen on GTP socket\n");
exit(2);
- }
+ } else
+ LOGP(DGPRS, LOGL_NOTICE, "libGTP v%s initialized\n", gtp_version());
- rc = gprs_subscr_init(&sgsn_inst);
+ rc = gprs_subscr_init(sgsn);
if (rc < 0) {
LOGP(DGPRS, LOGL_FATAL, "Cannot set up subscriber management\n");
exit(2);
@@ -477,17 +506,20 @@ int main(int argc, char **argv)
}
#if BUILD_IU
- sccp = osmo_sccp_simple_client(tall_bsc_ctx, "OsmoSGSN",
- 2 /* FIXME: configurable */,
- OSMO_SS7_ASP_PROT_M3UA,
- 0, NULL,
- 0, "127.0.0.1");
+ /* Note that these are mostly defaults and can be overriden from the VTY */
+ sccp = osmo_sccp_simple_client_on_ss7_id(tall_sgsn_ctx,
+ sgsn->cfg.iu.cs7_instance,
+ "OsmoSGSN",
+ (23 << 3) + 4,
+ OSMO_SS7_ASP_PROT_M3UA,
+ 0, NULL,
+ 0, "127.0.0.1");
if (!sccp) {
printf("Setting up SCCP client failed.\n");
return 8;
}
- ranap_iu_init(tall_bsc_ctx, DRANAP, "OsmoSGSN-IuPS", sccp, gsm0408_gprs_rcvmsg_iu, sgsn_ranap_iu_event);
+ ranap_iu_init(tall_sgsn_ctx, DRANAP, "OsmoSGSN-IuPS", sccp, gsm0408_gprs_rcvmsg_iu, sgsn_ranap_iu_event);
#endif
if (daemonize) {
diff --git a/src/gprs/sgsn_vty.c b/src/sgsn/sgsn_vty.c
index fce251885..14248d1d8 100644
--- a/src/gprs/sgsn_vty.c
+++ b/src/sgsn/sgsn_vty.c
@@ -23,27 +23,34 @@
#include <netinet/in.h>
#include <arpa/inet.h>
#include <time.h>
+#include <inttypes.h>
#include <osmocom/core/talloc.h>
#include <osmocom/core/utils.h>
#include <osmocom/core/rate_ctr.h>
+#include <osmocom/core/tdef.h>
#include <osmocom/gsm/protocol/gsm_04_08_gprs.h>
#include <osmocom/gsm/apn.h>
-#include <openbsc/debug.h>
-#include <openbsc/sgsn.h>
+#include <osmocom/sgsn/debug.h>
+#include <osmocom/sgsn/sgsn.h>
#include <osmocom/gprs/gprs_ns.h>
-#include <openbsc/gprs_sgsn.h>
-#include <openbsc/vty.h>
-#include <openbsc/gsup_client.h>
+#include <osmocom/sgsn/gprs_gmm.h>
+#include <osmocom/sgsn/gprs_sgsn.h>
+#include <osmocom/sgsn/vty.h>
+#include <osmocom/gsupclient/gsup_client.h>
+#include <osmocom/vty/tdef_vty.h>
#include <osmocom/vty/command.h>
#include <osmocom/vty/vty.h>
#include <osmocom/vty/misc.h>
#include <osmocom/crypt/gprs_cipher.h>
#include <osmocom/abis/ipa.h>
+#include <osmocom/gprs/gprs_bssgp.h>
+
#include <pdp.h>
+#include <gtp.h>
#include "../../bscconfig.h"
@@ -51,7 +58,7 @@
#include <osmocom/ranap/iu_client.h>
#endif
-extern void *tall_bsc_ctx;
+extern void *tall_sgsn_ctx;
static struct sgsn_config *g_cfg = NULL;
@@ -83,55 +90,48 @@ const struct value_string sgsn_auth_pol_strs[] = {
#define GSM0408_T3395_SECS 8 /* wait for DEACT PDP CTX ACK */
#define GSM0408_T3397_SECS 8 /* wait for DEACT AA PDP CTX ACK */
-#define DECLARE_TIMER(number, doc) \
- DEFUN(cfg_sgsn_T##number, \
- cfg_sgsn_T##number##_cmd, \
- "timer t" #number " <0-65535>", \
- "Configure GPRS Timers\n" \
- doc "\nTimer Value in seconds\n") \
-{ \
- int value = atoi(argv[0]); \
- \
- if (value < 0 || value > 65535) { \
- vty_out(vty, "Timer value %s out of range.%s", \
- argv[0], VTY_NEWLINE); \
- return CMD_WARNING; \
- } \
- \
- g_cfg->timers.T##number = value; \
- return CMD_SUCCESS; \
-}
-
-DECLARE_TIMER(3312, "Periodic RA Update timer (s)")
-DECLARE_TIMER(3322, "Detach request -> accept timer (s)")
-DECLARE_TIMER(3350, "Waiting for ATT/RAU/TMSI_COMPL timer (s)")
-DECLARE_TIMER(3360, "Waiting for AUTH/CIPH response timer (s)")
-DECLARE_TIMER(3370, "Waiting for IDENTITY response timer (s)")
-
-DECLARE_TIMER(3313, "Waiting for paging response timer (s)")
-DECLARE_TIMER(3314, "Force to STANDBY on expiry timer (s)")
-DECLARE_TIMER(3316, "AA-Ready timer (s)")
-
-DECLARE_TIMER(3385, "Wait for ACT PDP CTX REQ timer (s)")
-DECLARE_TIMER(3386, "Wait for MODIFY PDP CTX ACK timer (s)")
-DECLARE_TIMER(3395, "Wait for DEACT PDP CTX ACK timer (s)")
-DECLARE_TIMER(3397, "Wait for DEACT AA PDP CTX ACK timer (s)")
-
+/* Non spec timer */
+#define NONSPEC_X1001_SECS 5 /* wait for a RANAP Release Complete */
+
+
+static struct osmo_tdef sgsn_T_defs[] = {
+ { .T=3312, .default_val=GSM0408_T3312_SECS, .desc="Periodic RA Update timer (s)" },
+ { .T=3313, .default_val=GSM0408_T3313_SECS, .desc="Waiting for paging response timer (s)" },
+ { .T=3314, .default_val=GSM0408_T3314_SECS, .desc="READY timer. Force to STANDBY on expiry timer (s)" },
+ { .T=3316, .default_val=GSM0408_T3316_SECS, .desc="AA-Ready timer (s)" },
+ { .T=3322, .default_val=GSM0408_T3322_SECS, .desc="Detach request -> accept timer (s)" },
+ { .T=3350, .default_val=GSM0408_T3350_SECS, .desc="Waiting for ATT/RAU/TMSI_COMPL timer (s)" },
+ { .T=3360, .default_val=GSM0408_T3360_SECS, .desc="Waiting for AUTH/CIPH response timer (s)" },
+ { .T=3370, .default_val=GSM0408_T3370_SECS, .desc="Waiting for IDENTITY response timer (s)" },
+ { .T=3385, .default_val=GSM0408_T3385_SECS, .desc="Wait for ACT PDP CTX REQ timer (s)" },
+ { .T=3386, .default_val=GSM0408_T3386_SECS, .desc="Wait for MODIFY PDP CTX ACK timer (s)" },
+ { .T=3395, .default_val=GSM0408_T3395_SECS, .desc="Wait for DEACT PDP CTX ACK timer (s)" },
+ { .T=3397, .default_val=GSM0408_T3397_SECS, .desc="Wait for DEACT AA PDP CTX ACK timer (s)" },
+ /* non spec timers */
+ { .T=-1001, .default_val=NONSPEC_X1001_SECS, .desc="RANAP Release timeout. Wait for RANAP Release Complete."
+ "On expiry release Iu connection (s)" },
+ { .T=-3314, .default_val=GSM0408_T3314_SECS, .desc="Iu User inactivity timer. On expiry release Iu connection (s)" },
+ {}
+};
-#define GSM48_MAX_APN_LEN 102 /* 10.5.6.1 */
-/** Copy apn to a static buffer, replacing the length octets in apn_enc with '.'
- * and terminating with a '\0'. Return the static buffer.
- * len: the length of the encoded APN (which has no terminating zero).
- */
-static char *gprs_apn2str(uint8_t *apn, unsigned int len)
+DEFUN(show_timer, show_timer_cmd,
+ "show timer " OSMO_TDEF_VTY_ARG_T_OPTIONAL,
+ SHOW_STR "Show timers\n"
+ OSMO_TDEF_VTY_DOC_T)
{
- static char apnbuf[GSM48_MAX_APN_LEN+1];
-
- if (!apn)
- return "";
- osmo_apn_to_str(apnbuf, apn, len);
+ const char *T_arg = argc > 0 ? argv[0] : NULL;
+ return osmo_tdef_vty_show_cmd(vty, g_cfg->T_defs, T_arg, NULL);
+}
- return apnbuf+1;
+DEFUN(cfg_sgsn_timer, cfg_sgsn_timer_cmd,
+ "timer " OSMO_TDEF_VTY_ARG_SET_OPTIONAL,
+ "Configure or show timers\n"
+ OSMO_TDEF_VTY_DOC_SET)
+{
+ /* If any arguments are missing, redirect to 'show' */
+ if (argc < 2)
+ return show_timer(self, vty, argc, argv);
+ return osmo_tdef_vty_set_cmd(vty, g_cfg->T_defs, argv);
}
char *gprs_pdpaddr2str(uint8_t *pdpa, uint8_t len)
@@ -197,6 +197,12 @@ static int config_write_sgsn(struct vty *vty)
inet_ntoa(gctx->remote_addr), VTY_NEWLINE);
vty_out(vty, " ggsn %u gtp-version %u%s", gctx->id,
gctx->gtp_version, VTY_NEWLINE);
+ if (gctx->echo_interval)
+ vty_out(vty, " ggsn %u echo-interval %u%s",
+ gctx->id, gctx->echo_interval, VTY_NEWLINE);
+ else
+ vty_out(vty, " ggsn %u no echo-interval%s",
+ gctx->id, VTY_NEWLINE);
}
if (sgsn->cfg.dynamic_lookup)
@@ -209,12 +215,16 @@ static int config_write_sgsn(struct vty *vty)
vty_out(vty, " encryption %s%s",
get_value_string(gprs_cipher_names, g_cfg->cipher),
VTY_NEWLINE);
+ if (g_cfg->sgsn_ipa_name)
+ vty_out(vty, " gsup ipa-name %s%s", g_cfg->sgsn_ipa_name, VTY_NEWLINE);
if (g_cfg->gsup_server_addr.sin_addr.s_addr)
vty_out(vty, " gsup remote-ip %s%s",
inet_ntoa(g_cfg->gsup_server_addr.sin_addr), VTY_NEWLINE);
if (g_cfg->gsup_server_port)
vty_out(vty, " gsup remote-port %d%s",
g_cfg->gsup_server_port, VTY_NEWLINE);
+ if (g_cfg->auth_policy == SGSN_AUTH_POLICY_REMOTE && !g_cfg->require_authentication)
+ vty_out(vty, " authentication optional%s", VTY_NEWLINE);
vty_out(vty, " auth-policy %s%s",
get_value_string(sgsn_auth_pol_strs, g_cfg->auth_policy),
VTY_NEWLINE);
@@ -249,20 +259,13 @@ static int config_write_sgsn(struct vty *vty)
vty_out(vty, " cdr filename %s%s", g_cfg->cdr.filename, VTY_NEWLINE);
else
vty_out(vty, " no cdr filename%s", VTY_NEWLINE);
+ if (g_cfg->cdr.trap)
+ vty_out(vty, " cdr trap%s", VTY_NEWLINE);
+ else
+ vty_out(vty, " no cdr trap%s", VTY_NEWLINE);
vty_out(vty, " cdr interval %d%s", g_cfg->cdr.interval, VTY_NEWLINE);
- vty_out(vty, " timer t3312 %d%s", g_cfg->timers.T3312, VTY_NEWLINE);
- vty_out(vty, " timer t3322 %d%s", g_cfg->timers.T3322, VTY_NEWLINE);
- vty_out(vty, " timer t3350 %d%s", g_cfg->timers.T3350, VTY_NEWLINE);
- vty_out(vty, " timer t3360 %d%s", g_cfg->timers.T3360, VTY_NEWLINE);
- vty_out(vty, " timer t3370 %d%s", g_cfg->timers.T3370, VTY_NEWLINE);
- vty_out(vty, " timer t3313 %d%s", g_cfg->timers.T3313, VTY_NEWLINE);
- vty_out(vty, " timer t3314 %d%s", g_cfg->timers.T3314, VTY_NEWLINE);
- vty_out(vty, " timer t3316 %d%s", g_cfg->timers.T3316, VTY_NEWLINE);
- vty_out(vty, " timer t3385 %d%s", g_cfg->timers.T3385, VTY_NEWLINE);
- vty_out(vty, " timer t3386 %d%s", g_cfg->timers.T3386, VTY_NEWLINE);
- vty_out(vty, " timer t3395 %d%s", g_cfg->timers.T3395, VTY_NEWLINE);
- vty_out(vty, " timer t3397 %d%s", g_cfg->timers.T3397, VTY_NEWLINE);
+ osmo_tdef_vty_write(vty, g_cfg->T_defs, " timer ");
if (g_cfg->pcomp_rfc1144.active) {
vty_out(vty, " compression rfc1144 active slots %d%s",
@@ -293,6 +296,8 @@ static int config_write_sgsn(struct vty *vty)
vty_out(vty, " no compression v42bis%s", VTY_NEWLINE);
#ifdef BUILD_IU
+ vty_out(vty, " cs7-instance-iu %u%s", g_cfg->iu.cs7_instance,
+ VTY_NEWLINE);
ranap_iu_vty_config_write(vty, " ");
#endif
@@ -313,7 +318,12 @@ DEFUN(cfg_sgsn, cfg_sgsn_cmd,
DEFUN(cfg_sgsn_bind_addr, cfg_sgsn_bind_addr_cmd,
"gtp local-ip A.B.C.D",
"GTP Parameters\n"
- "Set the IP address for the local GTP bind\n"
+ "Set the IP address for the local GTP bind for the Gp interface (towards the GGSNs)."
+ " Note: in case you would like to run the GGSN on the same machine as the SGSN, you can not run"
+ " both on the same IP address, since both sides are specified to use the same GTP port numbers"
+ " (" OSMO_STRINGIFY_VAL(GTP1C_PORT) " and " OSMO_STRINGIFY_VAL(GTP1U_PORT) ")."
+ " For example, you could use 127.0.0.1 for the SGSN and 127.0.0.2 for the GGSN in such"
+ " situations.\n"
"IPv4 Address\n")
{
inet_aton(argv[0], &g_cfg->gtp_listenaddr.sin_addr);
@@ -323,7 +333,9 @@ DEFUN(cfg_sgsn_bind_addr, cfg_sgsn_bind_addr_cmd,
DEFUN(cfg_ggsn_remote_ip, cfg_ggsn_remote_ip_cmd,
"ggsn <0-255> remote-ip A.B.C.D",
- GGSN_STR "GGSN Number\n" IP_STR "IPv4 Address\n")
+ GGSN_STR "GGSN Number\n"
+ "Configure this static GGSN to use the specified remote IP address.\n"
+ "IPv4 Address\n")
{
uint32_t id = atoi(argv[0]);
struct sgsn_ggsn_ctx *ggc = sgsn_ggsn_ctx_find_alloc(id);
@@ -361,9 +373,46 @@ DEFUN(cfg_ggsn_gtp_version, cfg_ggsn_gtp_version_cmd,
return CMD_SUCCESS;
}
+/* Seee 3GPP TS 29.060 section 7.2.1 */
+DEFUN(cfg_ggsn_echo_interval, cfg_ggsn_echo_interval_cmd,
+ "ggsn <0-255> echo-interval <1-36000>",
+ GGSN_STR "GGSN Number\n"
+ "Send an echo request to this static GGSN every interval.\n"
+ "Interval between echo requests in seconds.\n")
+{
+ uint32_t id = atoi(argv[0]);
+ struct sgsn_ggsn_ctx *ggc = sgsn_ggsn_ctx_find_alloc(id);
+
+ ggc->echo_interval = atoi(argv[1]);
+
+ if (ggc->echo_interval < 60)
+ vty_out(vty, "%% 3GPP TS 29.060 section 7.2.1 states interval should " \
+ "not be lower than 60 seconds, use this value for " \
+ "testing purposes only!%s", VTY_NEWLINE);
+
+ sgsn_ggsn_ctx_check_echo_timer(ggc);
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_ggsn_no_echo_interval, cfg_ggsn_no_echo_interval_cmd,
+ "ggsn <0-255> no echo-interval",
+ GGSN_STR "GGSN Number\n"
+ NO_STR "Send an echo request to this static GGSN every interval.\n")
+{
+ uint32_t id = atoi(argv[0]);
+ struct sgsn_ggsn_ctx *ggc = sgsn_ggsn_ctx_find_alloc(id);
+
+ ggc->echo_interval = 0;
+ sgsn_ggsn_ctx_check_echo_timer(ggc);
+
+ return CMD_SUCCESS;
+}
+
DEFUN(cfg_ggsn_dynamic_lookup, cfg_ggsn_dynamic_lookup_cmd,
"ggsn dynamic",
- GGSN_STR "Enable dynamic GRX based look-up (requires restart)\n")
+ GGSN_STR
+ "Enable dynamic resolving of GGSNs based on DNS resolving the APN name like in a GRX-style setup."
+ " Changing this setting requires a restart.\n")
{
sgsn->cfg.dynamic_lookup = 1;
return CMD_SUCCESS;
@@ -371,9 +420,10 @@ DEFUN(cfg_ggsn_dynamic_lookup, cfg_ggsn_dynamic_lookup_cmd,
DEFUN(cfg_grx_ggsn, cfg_grx_ggsn_cmd,
"grx-dns-add A.B.C.D",
- "Add DNS server\nIPv4 address\n")
+ "Use the specified IP address for DNS-resolving the AP names to GGSN IP addresses\n"
+ "IPv4 address\n")
{
- struct ares_addr_node *node = talloc_zero(tall_bsc_ctx, struct ares_addr_node);
+ struct ares_addr_node *node = talloc_zero(tall_sgsn_ctx, struct ares_addr_node);
node->family = AF_INET;
inet_aton(argv[0], &node->addr.addr4);
@@ -413,7 +463,7 @@ static int add_apn_ggsn_mapping(struct vty *vty, const char *apn_str,
DEFUN(cfg_apn_ggsn, cfg_apn_ggsn_cmd,
"apn APNAME ggsn <0-255>",
APN_STR APN_GW_STR
- "Select the GGSN to use when the APN gateway prefix matches\n"
+ "Select the GGSN to use for the given APN gateway prefix\n"
"The GGSN id")
{
@@ -423,7 +473,8 @@ DEFUN(cfg_apn_ggsn, cfg_apn_ggsn_cmd,
DEFUN(cfg_apn_imsi_ggsn, cfg_apn_imsi_ggsn_cmd,
"apn APNAME imsi-prefix IMSIPRE ggsn <0-255>",
APN_STR APN_GW_STR
- "Restrict rule to a certain IMSI prefix\n"
+ "Select the GGSN to use for the given APN gateway prefix if and only if the IMSI matches the"
+ " given prefix.\n"
"An IMSI prefix\n"
"Select the GGSN to use when APN gateway and IMSI prefix match\n"
"The GGSN id")
@@ -432,23 +483,14 @@ DEFUN(cfg_apn_imsi_ggsn, cfg_apn_imsi_ggsn_cmd,
return add_apn_ggsn_mapping(vty, argv[0], argv[1], atoi(argv[2]));
}
-const struct value_string gprs_mm_st_strs[] = {
- { GMM_DEREGISTERED, "DEREGISTERED" },
- { GMM_COMMON_PROC_INIT, "COMMON PROCEDURE (INIT)" },
- { GMM_REGISTERED_NORMAL, "REGISTERED (NORMAL)" },
- { GMM_REGISTERED_SUSPENDED, "REGISTERED (SUSPENDED)" },
- { GMM_DEREGISTERED_INIT, "DEREGISTERED (INIT)" },
- { 0, NULL }
-};
-
-static char *gtp_ntoa(struct ul16_t *ul)
+char *sgsn_gtp_ntoa(struct ul16_t *ul)
{
- if (ul->l == 4) {
- struct in_addr *ia = (struct in_addr *) ul;
- return inet_ntoa(*ia);
- } else {
+ struct in_addr ia;
+
+ if (gsna2in_addr(&ia, ul) != 0)
return "UNKNOWN";
- }
+
+ return inet_ntoa(ia);
}
static void vty_dump_pdp(struct vty *vty, const char *pfx,
@@ -458,20 +500,21 @@ static void vty_dump_pdp(struct vty *vty, const char *pfx,
vty_out(vty, "%sPDP Context IMSI: %s, SAPI: %u, NSAPI: %u, TI: %u%s",
pfx, imsi, pdp->sapi, pdp->nsapi, pdp->ti, VTY_NEWLINE);
if (pdp->lib) {
+ char apnbuf[APN_MAXLEN + 1];
vty_out(vty, "%s APN: %s%s", pfx,
- gprs_apn2str(pdp->lib->apn_use.v, pdp->lib->apn_use.l),
+ osmo_apn_to_str(apnbuf, pdp->lib->apn_use.v, pdp->lib->apn_use.l),
VTY_NEWLINE);
vty_out(vty, "%s PDP Address: %s%s", pfx,
gprs_pdpaddr2str(pdp->lib->eua.v, pdp->lib->eua.l),
VTY_NEWLINE);
- vty_out(vty, "%s GTP Local Control(%s / TEIC: 0x%08x) ", pfx,
- gtp_ntoa(&pdp->lib->gsnlc), pdp->lib->teic_own);
+ vty_out(vty, "%s GTPv%d Local Control(%s / TEIC: 0x%08x) ", pfx, pdp->lib->version,
+ sgsn_gtp_ntoa(&pdp->lib->gsnlc), pdp->lib->teic_own);
vty_out(vty, "Data(%s / TEID: 0x%08x)%s",
- gtp_ntoa(&pdp->lib->gsnlu), pdp->lib->teid_own, VTY_NEWLINE);
- vty_out(vty, "%s GTP Remote Control(%s / TEIC: 0x%08x) ", pfx,
- gtp_ntoa(&pdp->lib->gsnrc), pdp->lib->teic_gn);
+ sgsn_gtp_ntoa(&pdp->lib->gsnlu), pdp->lib->teid_own, VTY_NEWLINE);
+ vty_out(vty, "%s GTPv%d Remote Control(%s / TEIC: 0x%08x) ", pfx, pdp->lib->version,
+ sgsn_gtp_ntoa(&pdp->lib->gsnrc), pdp->lib->teic_gn);
vty_out(vty, "Data(%s / TEID: 0x%08x)%s",
- gtp_ntoa(&pdp->lib->gsnru), pdp->lib->teid_gn, VTY_NEWLINE);
+ sgsn_gtp_ntoa(&pdp->lib->gsnru), pdp->lib->teid_gn, VTY_NEWLINE);
}
vty_out_rate_ctr_group(vty, " ", pdp->ctrg);
@@ -480,17 +523,33 @@ static void vty_dump_pdp(struct vty *vty, const char *pfx,
static void vty_dump_mmctx(struct vty *vty, const char *pfx,
struct sgsn_mm_ctx *mm, int pdp)
{
+ uint32_t id = 0;
+ const char *mm_state_name = NULL;
+
+ switch(mm->ran_type) {
+ case MM_CTX_T_UTRAN_Iu:
+#if BUILD_IU
+ id = mm->iu.ue_ctx->conn_id;
+ mm_state_name = osmo_fsm_inst_state_name(mm->iu.mm_state_fsm);
+#endif
+ break;
+ case MM_CTX_T_GERAN_Gb:
+ id = mm->gb.tlli;
+ mm_state_name = osmo_fsm_inst_state_name(mm->gb.mm_state_fsm);
+ break;
+ }
+
vty_out(vty, "%sMM Context for IMSI %s, IMEI %s, P-TMSI %08x%s",
pfx, mm->imsi, mm->imei, mm->p_tmsi, VTY_NEWLINE);
vty_out(vty, "%s MSISDN: %s, TLLI: %08x%s HLR: %s",
- pfx, mm->msisdn, mm->gb.tlli, mm->hlr, VTY_NEWLINE);
- vty_out(vty, "%s MM State: %s, Routeing Area: %u-%u-%u-%u, "
- "Cell ID: %u%s", pfx,
- get_value_string(gprs_mm_st_strs, mm->gmm_state),
- mm->ra.mcc, mm->ra.mnc, mm->ra.lac, mm->ra.rac,
- mm->gb.cell_id, VTY_NEWLINE);
+ pfx, mm->msisdn, id, mm->hlr, VTY_NEWLINE);
+ vty_out(vty, "%s GMM State: %s, Routeing Area: %s, Cell ID: %u%s",
+ pfx, osmo_fsm_inst_state_name(mm->gmm_fsm),
+ osmo_rai_name(&mm->ra), mm->gb.cell_id, VTY_NEWLINE);
+ vty_out(vty, "%s MM State: %s, RAN Type: %s%s", pfx, mm_state_name,
+ get_value_string(sgsn_ran_type_names, mm->ran_type), VTY_NEWLINE);
- vty_out_rate_ctr_group(vty, " ", mm->ctrg);
+ vty_out_rate_ctr_group(vty, " ", mm->ctrg);
if (pdp) {
struct sgsn_pdp_ctx *pdp;
@@ -511,6 +570,10 @@ DEFUN(show_sgsn, show_sgsn_cmd, "show sgsn",
link->addr, link->port,
VTY_NEWLINE);
}
+ if (sgsn->gsn)
+ vty_out(vty, " GSN: signalling %s, user traffic %s%s",
+ inet_ntoa(sgsn->gsn->gsnc), inet_ntoa(sgsn->gsn->gsnu), VTY_NEWLINE);
+
/* FIXME: statistics */
return CMD_SUCCESS;
}
@@ -587,19 +650,24 @@ DEFUN(imsi_acl, cfg_imsi_acl_cmd,
"Remove IMSI from ACL\n"
"IMSI of subscriber\n")
{
- char imsi_sanitized[GSM23003_IMSI_MAX_DIGITS+1];
+ char imsi_sanitized[GSM23003_IMSI_MAX_DIGITS + 1];
const char *op = argv[0];
const char *imsi = imsi_sanitized;
+ size_t len = strnlen(argv[1], GSM23003_IMSI_MAX_DIGITS + 1);
int rc;
+ memset(imsi_sanitized, '0', GSM23003_IMSI_MAX_DIGITS);
+ imsi_sanitized[GSM23003_IMSI_MAX_DIGITS] = '\0';
+
/* Sanitize IMSI */
- if (strlen(argv[1]) > GSM23003_IMSI_MAX_DIGITS) {
- vty_out(vty, "%% IMSI (%s) too long -- ignored!%s",
- argv[1], VTY_NEWLINE);
+ if (len > GSM23003_IMSI_MAX_DIGITS) {
+ vty_out(vty, "%% IMSI (%s) too long (max %u digits) -- ignored!%s",
+ argv[1], GSM23003_IMSI_MAX_DIGITS, VTY_NEWLINE);
return CMD_WARNING;
}
- memset(imsi_sanitized, '0', sizeof(imsi_sanitized));
- strcpy(imsi_sanitized+GSM23003_IMSI_MAX_DIGITS-strlen(argv[1]),argv[1]);
+
+ osmo_strlcpy(imsi_sanitized + GSM23003_IMSI_MAX_DIGITS - len, argv[1],
+ sizeof(imsi_sanitized) - (GSM23003_IMSI_MAX_DIGITS - len));
if (!strcmp(op, "add"))
rc = sgsn_acl_add(imsi, g_cfg);
@@ -639,9 +707,31 @@ DEFUN(cfg_encrypt, cfg_encrypt_cmd,
return CMD_SUCCESS;
}
+DEFUN(cfg_authentication, cfg_authentication_cmd,
+ "authentication (optional|required)",
+ "Whether to enforce MS authentication in GERAN (only with auth-policy remote)\n"
+ "Allow MS to attach via GERAN without authentication (default and only possible value for non-remote auth-policy)\n"
+ "Always require authentication (only available for auth-policy remote, default with that auth-policy)\n")
+{
+ int required = (argv[0][0] == 'r');
+
+ if (vty->type != VTY_FILE) {
+ if (g_cfg->auth_policy != SGSN_AUTH_POLICY_REMOTE && required) {
+ vty_out(vty, "%% Authentication is not possible without HLR, "
+ "consider setting 'auth-policy' to 'remote'%s",
+ VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ }
+
+ g_cfg->require_authentication = required;
+ return CMD_SUCCESS;
+}
+
DEFUN(cfg_auth_policy, cfg_auth_policy_cmd,
"auth-policy (accept-all|closed|acl-only|remote)",
- "Autorization Policy of SGSN\n"
+ "Configure the Authorization policy of the SGSN. This setting determines which subscribers are"
+ " permitted to register to the network.\n"
"Accept all IMSIs (DANGEROUS)\n"
"Accept only home network subscribers or those in the ACL\n"
"Accept only subscribers in the ACL\n"
@@ -650,14 +740,13 @@ DEFUN(cfg_auth_policy, cfg_auth_policy_cmd,
int val = get_string_value(sgsn_auth_pol_strs, argv[0]);
OSMO_ASSERT(val >= SGSN_AUTH_POLICY_OPEN && val <= SGSN_AUTH_POLICY_REMOTE);
g_cfg->auth_policy = val;
- g_cfg->require_authentication = (val == SGSN_AUTH_POLICY_REMOTE);
g_cfg->require_update_location = (val == SGSN_AUTH_POLICY_REMOTE);
return CMD_SUCCESS;
}
/* Subscriber */
-#include <openbsc/gprs_subscriber.h>
+#include <osmocom/sgsn/gprs_subscriber.h>
static void subscr_dump_full_vty(struct vty *vty, struct gprs_subscr *gsub, int pending)
{
@@ -697,13 +786,13 @@ static void subscr_dump_full_vty(struct vty *vty, struct gprs_subscr *gsub, int
at->key_seq);
if (at->vec.auth_types & OSMO_AUTH_TYPE_GSM) {
vty_out(vty, "RAND: %s, ",
- osmo_hexdump(at->vec.rand,
+ osmo_hexdump_nospc(at->vec.rand,
sizeof(at->vec.rand)));
vty_out(vty, "SRES: %s, ",
- osmo_hexdump(at->vec.sres,
+ osmo_hexdump_nospc(at->vec.sres,
sizeof(at->vec.sres)));
vty_out(vty, "Kc: %s%s",
- osmo_hexdump(at->vec.kc,
+ osmo_hexdump_nospc(at->vec.kc,
sizeof(at->vec.kc)), VTY_NEWLINE);
}
if (at->vec.auth_types & OSMO_AUTH_TYPE_UMTS) {
@@ -711,19 +800,22 @@ static void subscr_dump_full_vty(struct vty *vty, struct gprs_subscr *gsub, int
osmo_hexdump(at->vec.autn,
sizeof(at->vec.autn)));
vty_out(vty, "RES: %s, ",
- osmo_hexdump(at->vec.res, at->vec.res_len));
+ osmo_hexdump_nospc(at->vec.res, at->vec.res_len));
vty_out(vty, "IK: %s, ",
- osmo_hexdump(at->vec.ik, sizeof(at->vec.ik)));
+ osmo_hexdump_nospc(at->vec.ik, sizeof(at->vec.ik)));
vty_out(vty, "CK: %s, ",
- osmo_hexdump(at->vec.ck, sizeof(at->vec.ck)));
+ osmo_hexdump_nospc(at->vec.ck, sizeof(at->vec.ck)));
}
}
llist_for_each_entry(pdp, &gsub->sgsn_data->pdp_list, list) {
- vty_out(vty, " PDP info: Id: %d, Type: 0x%04x, APN: '%s' QoS: %s%s",
- pdp->context_id, pdp->pdp_type, pdp->apn_str,
- osmo_hexdump(pdp->qos_subscribed, pdp->qos_subscribed_len),
- VTY_NEWLINE);
+ vty_out(vty, " PDP info: Id: %d, Type: 0x%04x, APN: '%s'",
+ pdp->context_id, pdp->pdp_type, pdp->apn_str);
+
+ if (pdp->qos_subscribed_len)
+ vty_out(vty, " QoS: %s", osmo_hexdump(pdp->qos_subscribed, pdp->qos_subscribed_len));
+
+ vty_out(vty, "%s", VTY_NEWLINE);
}
#if 0
@@ -753,6 +845,41 @@ static void subscr_dump_full_vty(struct vty *vty, struct gprs_subscr *gsub, int
vty_out(vty, " Use count: %u%s", gsub->use_count, VTY_NEWLINE);
}
+#define RESET_SGSN_STATE_STR \
+ "Remove all known subscribers, MM contexts and flush BSSGP queues." \
+ " Useful only when running tests against the SGSN\n"
+
+DEFUN_HIDDEN(reset_sgsn_state,
+ reset_sgsn_state_cmd,
+ "reset sgsn state",
+ RESET_SGSN_STATE_STR RESET_SGSN_STATE_STR RESET_SGSN_STATE_STR)
+{
+ struct gprs_subscr *subscr, *tmp_subscr;
+ struct sgsn_mm_ctx *mm, *tmp_mm;
+
+ llist_for_each_entry_safe(mm, tmp_mm, &sgsn_mm_ctxts, list)
+ {
+ gsm0408_gprs_access_cancelled(mm, SGSN_ERROR_CAUSE_NONE);
+ }
+ vty_out(vty, "Cancelled MM Ctx. %s", VTY_NEWLINE);
+
+ llist_for_each_entry_safe(subscr, tmp_subscr, gprs_subscribers, entry) {
+ gprs_subscr_get(subscr);
+ gprs_subscr_cancel(subscr);
+ gprs_subscr_put(subscr);
+ }
+ vty_out(vty, "Removed all gprs subscribers.%s", VTY_NEWLINE);
+
+ bssgp_flush_all_queues();
+ vty_out(vty, "Flushed all BSSGPs queues.%s", VTY_NEWLINE);
+
+ gtp_clear_queues(sgsn->gsn);
+ vty_out(vty, "Flushed rx & tx queus towards the GGSN.%s", VTY_NEWLINE);
+
+ /* remove all queues to bssgp */
+ return CMD_SUCCESS;
+}
+
DEFUN(show_subscr_cache,
show_subscr_cache_cmd,
"show subscriber cache",
@@ -990,10 +1117,30 @@ DEFUN(update_subscr_update_auth_info, update_subscr_update_auth_info_cmd,
return CMD_SUCCESS;
}
+DEFUN(cfg_gsup_ipa_name,
+ cfg_gsup_ipa_name_cmd,
+ "gsup ipa-name NAME",
+ "GSUP Parameters\n"
+ "Set the IPA name of this SGSN\n"
+ "A unique name for this SGSN. For example: PLMN + redundancy server number: SGSN-901-70-0. "
+ "This name is used for GSUP routing and must be set if more than one SGSN is connected to the network. "
+ "The default is 'SGSN-00-00-00-00-00-00'.\n")
+{
+ if (vty->type != VTY_FILE) {
+ vty_out(vty, "The IPA name cannot be changed at run-time; "
+ "It can only be set in the configuraton file.%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ g_cfg->sgsn_ipa_name = talloc_strdup(tall_vty_ctx, argv[0]);
+ return CMD_SUCCESS;
+}
+
DEFUN(cfg_gsup_remote_ip, cfg_gsup_remote_ip_cmd,
"gsup remote-ip A.B.C.D",
"GSUP Parameters\n"
- "Set the IP address of the remote GSUP server\n"
+ "Set the IP address of the remote GSUP server (e.g. OsmoHLR)."
+ " This setting only applies if 'auth-policy remote' is used.\n"
"IPv4 Address\n")
{
inet_aton(argv[0], &g_cfg->gsup_server_addr.sin_addr);
@@ -1004,7 +1151,7 @@ DEFUN(cfg_gsup_remote_ip, cfg_gsup_remote_ip_cmd,
DEFUN(cfg_gsup_remote_port, cfg_gsup_remote_port_cmd,
"gsup remote-port <0-65535>",
"GSUP Parameters\n"
- "Set the TCP port of the remote GSUP server\n"
+ "Set the TCP port of the remote GSUP server, see also 'gsup remote-ip'\n"
"Remote TCP port\n")
{
g_cfg->gsup_server_port = atoi(argv[0]);
@@ -1015,7 +1162,9 @@ DEFUN(cfg_gsup_remote_port, cfg_gsup_remote_port_cmd,
DEFUN(cfg_gsup_oap_id, cfg_gsup_oap_id_cmd,
"gsup oap-id <0-65535>",
"GSUP Parameters\n"
- "Set the SGSN's OAP client ID\nOAP client ID (0 == disabled)\n")
+ "Set the OAP client ID for authentication on the GSUP protocol."
+ " This setting only applies if 'auth-policy remote' is used.\n"
+ "OAP client ID (0 == disabled)\n")
{
/* VTY ensures range */
g_cfg->oap.client_id = (uint16_t)atoi(argv[0]);
@@ -1025,7 +1174,9 @@ DEFUN(cfg_gsup_oap_id, cfg_gsup_oap_id_cmd,
DEFUN(cfg_gsup_oap_k, cfg_gsup_oap_k_cmd,
"gsup oap-k K",
"GSUP Parameters\n"
- "Set the OAP shared secret K\nK value (16 byte) hex\n")
+ "Set the OAP shared secret key K for authentication on the GSUP protocol."
+ " This setting only applies if auth-policy remote is used.\n"
+ "K value (16 byte) hex\n")
{
const char *k = argv[0];
@@ -1058,7 +1209,9 @@ disable:
DEFUN(cfg_gsup_oap_opc, cfg_gsup_oap_opc_cmd,
"gsup oap-opc OPC",
"GSUP Parameters\n"
- "Set the OAP shared secret OPC\nOPC value (16 byte) hex\n")
+ "Set the OAP shared secret OPC for authentication on the GSUP protocol."
+ " This setting only applies if auth-policy remote is used.\n"
+ "OPC value (16 byte) hex\n")
{
const char *opc = argv[0];
@@ -1090,7 +1243,7 @@ disable:
DEFUN(cfg_apn_name, cfg_apn_name_cmd,
"access-point-name NAME",
- "Configure a global list of allowed APNs\n"
+ "Globally allow the given APN name for all subscribers.\n"
"Add this NAME to the list\n")
{
return add_apn_ggsn_mapping(vty, argv[0], "", 0);
@@ -1111,7 +1264,9 @@ DEFUN(cfg_no_apn_name, cfg_no_apn_name_cmd,
DEFUN(cfg_cdr_filename, cfg_cdr_filename_cmd,
"cdr filename NAME",
- "CDR\nSet filename\nname\n")
+ "CDR\n"
+ "Set the file name for the call-data-record file, logging the data usage of each subscriber.\n"
+ "filename\n")
{
talloc_free(g_cfg->cdr.filename);
g_cfg->cdr.filename = talloc_strdup(tall_vty_ctx, argv[0]);
@@ -1120,16 +1275,34 @@ DEFUN(cfg_cdr_filename, cfg_cdr_filename_cmd,
DEFUN(cfg_no_cdr_filename, cfg_no_cdr_filename_cmd,
"no cdr filename",
- NO_STR "CDR\nDisable CDR generation\n")
+ NO_STR "CDR\nDisable saving CDR to file\n")
{
talloc_free(g_cfg->cdr.filename);
g_cfg->cdr.filename = NULL;
return CMD_SUCCESS;
}
+DEFUN(cfg_cdr_trap, cfg_cdr_trap_cmd,
+ "cdr trap",
+ "CDR\nEnable sending CDR via TRAP CTRL messages\n")
+{
+ g_cfg->cdr.trap = true;
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_no_cdr_trap, cfg_no_cdr_trap_cmd,
+ "no cdr trap",
+ NO_STR "CDR\nDisable sending CDR via TRAP CTRL messages\n")
+{
+ g_cfg->cdr.trap = false;
+ return CMD_SUCCESS;
+}
+
DEFUN(cfg_cdr_interval, cfg_cdr_interval_cmd,
"cdr interval <1-2147483647>",
- "CDR\nPDP periodic log interval\nSeconds\n")
+ "CDR\n"
+ "Set the interval for the call-data-record file\n"
+ "interval in seconds\n")
{
g_cfg->cdr.interval = atoi(argv[0]);
return CMD_SUCCESS;
@@ -1148,7 +1321,7 @@ DEFUN(cfg_no_comp_rfc1144, cfg_no_comp_rfc1144_cmd,
DEFUN(cfg_comp_rfc1144, cfg_comp_rfc1144_cmd,
"compression rfc1144 active slots <1-256>",
COMPRESSION_STR
- "RFC1144 Header compresion scheme\n"
+ "RFC1144 Header compression scheme\n"
"Compression is actively proposed\n"
"Number of compression state slots\n"
"Number of compression state slots\n")
@@ -1162,7 +1335,7 @@ DEFUN(cfg_comp_rfc1144, cfg_comp_rfc1144_cmd,
DEFUN(cfg_comp_rfc1144p, cfg_comp_rfc1144p_cmd,
"compression rfc1144 passive",
COMPRESSION_STR
- "RFC1144 Header compresion scheme\n"
+ "RFC1144 Header compression scheme\n"
"Compression is available on request\n")
{
g_cfg->pcomp_rfc1144.active = 0;
@@ -1182,7 +1355,7 @@ DEFUN(cfg_no_comp_v42bis, cfg_no_comp_v42bis_cmd,
DEFUN(cfg_comp_v42bis, cfg_comp_v42bis_cmd,
"compression v42bis active direction (ms|sgsn|both) codewords <512-65535> strlen <6-250>",
COMPRESSION_STR
- "V.42bis data compresion scheme\n"
+ "V.42bis data compression scheme\n"
"Compression is actively proposed\n"
"Direction in which the compression shall be active (p0)\n"
"Compress ms->sgsn direction only\n"
@@ -1215,7 +1388,7 @@ DEFUN(cfg_comp_v42bis, cfg_comp_v42bis_cmd,
DEFUN(cfg_comp_v42bisp, cfg_comp_v42bisp_cmd,
"compression v42bis passive",
COMPRESSION_STR
- "V.42bis data compresion scheme\n"
+ "V.42bis data compression scheme\n"
"Compression is available on request\n")
{
g_cfg->dcomp_v42bis.active = 0;
@@ -1223,16 +1396,31 @@ DEFUN(cfg_comp_v42bisp, cfg_comp_v42bisp_cmd,
return CMD_SUCCESS;
}
+#if BUILD_IU
+DEFUN(cfg_sgsn_cs7_instance_iu,
+ cfg_sgsn_cs7_instance_iu_cmd,
+ "cs7-instance-iu <0-15>",
+ "Set SS7 to be used by the Iu-Interface.\n" "SS7 instance reference number (default: 0)\n")
+{
+ g_cfg->iu.cs7_instance = atoi(argv[0]);
+ return CMD_SUCCESS;
+}
+#endif
+
int sgsn_vty_init(struct sgsn_config *cfg)
{
g_cfg = cfg;
+ g_cfg->T_defs = sgsn_T_defs;
+ osmo_tdefs_reset(g_cfg->T_defs);
+
install_element_ve(&show_sgsn_cmd);
//install_element_ve(&show_mmctx_tlli_cmd);
install_element_ve(&show_mmctx_imsi_cmd);
install_element_ve(&show_mmctx_all_cmd);
install_element_ve(&show_pdpctx_all_cmd);
install_element_ve(&show_subscr_cache_cmd);
+ install_element_ve(&show_timer_cmd);
install_element(ENABLE_NODE, &update_subscr_insert_auth_triplet_cmd);
install_element(ENABLE_NODE, &update_subscr_create_cmd);
@@ -1240,17 +1428,21 @@ int sgsn_vty_init(struct sgsn_config *cfg)
install_element(ENABLE_NODE, &update_subscr_cancel_cmd);
install_element(ENABLE_NODE, &update_subscr_update_location_result_cmd);
install_element(ENABLE_NODE, &update_subscr_update_auth_info_cmd);
+ install_element(ENABLE_NODE, &reset_sgsn_state_cmd);
install_element(CONFIG_NODE, &cfg_sgsn_cmd);
install_node(&sgsn_node, config_write_sgsn);
- vty_install_default(SGSN_NODE);
install_element(SGSN_NODE, &cfg_sgsn_bind_addr_cmd);
install_element(SGSN_NODE, &cfg_ggsn_remote_ip_cmd);
//install_element(SGSN_NODE, &cfg_ggsn_remote_port_cmd);
install_element(SGSN_NODE, &cfg_ggsn_gtp_version_cmd);
+ install_element(SGSN_NODE, &cfg_ggsn_echo_interval_cmd);
+ install_element(SGSN_NODE, &cfg_ggsn_no_echo_interval_cmd);
install_element(SGSN_NODE, &cfg_imsi_acl_cmd);
install_element(SGSN_NODE, &cfg_auth_policy_cmd);
+ install_element(SGSN_NODE, &cfg_authentication_cmd);
install_element(SGSN_NODE, &cfg_encrypt_cmd);
+ install_element(SGSN_NODE, &cfg_gsup_ipa_name_cmd);
install_element(SGSN_NODE, &cfg_gsup_remote_ip_cmd);
install_element(SGSN_NODE, &cfg_gsup_remote_port_cmd);
install_element(SGSN_NODE, &cfg_gsup_oap_id_cmd);
@@ -1262,22 +1454,13 @@ int sgsn_vty_init(struct sgsn_config *cfg)
install_element(SGSN_NODE, &cfg_no_apn_name_cmd);
install_element(SGSN_NODE, &cfg_cdr_filename_cmd);
install_element(SGSN_NODE, &cfg_no_cdr_filename_cmd);
+ install_element(SGSN_NODE, &cfg_cdr_trap_cmd);
+ install_element(SGSN_NODE, &cfg_no_cdr_trap_cmd);
install_element(SGSN_NODE, &cfg_cdr_interval_cmd);
install_element(SGSN_NODE, &cfg_ggsn_dynamic_lookup_cmd);
install_element(SGSN_NODE, &cfg_grx_ggsn_cmd);
- install_element(SGSN_NODE, &cfg_sgsn_T3312_cmd);
- install_element(SGSN_NODE, &cfg_sgsn_T3322_cmd);
- install_element(SGSN_NODE, &cfg_sgsn_T3350_cmd);
- install_element(SGSN_NODE, &cfg_sgsn_T3360_cmd);
- install_element(SGSN_NODE, &cfg_sgsn_T3370_cmd);
- install_element(SGSN_NODE, &cfg_sgsn_T3313_cmd);
- install_element(SGSN_NODE, &cfg_sgsn_T3314_cmd);
- install_element(SGSN_NODE, &cfg_sgsn_T3316_cmd);
- install_element(SGSN_NODE, &cfg_sgsn_T3385_cmd);
- install_element(SGSN_NODE, &cfg_sgsn_T3386_cmd);
- install_element(SGSN_NODE, &cfg_sgsn_T3395_cmd);
- install_element(SGSN_NODE, &cfg_sgsn_T3397_cmd);
+ install_element(SGSN_NODE, &cfg_sgsn_timer_cmd);
install_element(SGSN_NODE, &cfg_no_comp_rfc1144_cmd);
install_element(SGSN_NODE, &cfg_comp_rfc1144_cmd);
@@ -1287,6 +1470,7 @@ int sgsn_vty_init(struct sgsn_config *cfg)
install_element(SGSN_NODE, &cfg_comp_v42bisp_cmd);
#ifdef BUILD_IU
+ install_element(SGSN_NODE, &cfg_sgsn_cs7_instance_iu_cmd);
ranap_iu_vty_init(SGSN_NODE, &g_cfg->iu.rab_assign_addr_enc);
#endif
return 0;
@@ -1299,19 +1483,6 @@ int sgsn_parse_config(const char *config_file)
/* make sure sgsn_vty_init() was called before this */
OSMO_ASSERT(g_cfg);
- g_cfg->timers.T3312 = GSM0408_T3312_SECS;
- g_cfg->timers.T3322 = GSM0408_T3322_SECS;
- g_cfg->timers.T3350 = GSM0408_T3350_SECS;
- g_cfg->timers.T3360 = GSM0408_T3360_SECS;
- g_cfg->timers.T3370 = GSM0408_T3370_SECS;
- g_cfg->timers.T3313 = GSM0408_T3313_SECS;
- g_cfg->timers.T3314 = GSM0408_T3314_SECS;
- g_cfg->timers.T3316 = GSM0408_T3316_SECS;
- g_cfg->timers.T3385 = GSM0408_T3385_SECS;
- g_cfg->timers.T3386 = GSM0408_T3386_SECS;
- g_cfg->timers.T3395 = GSM0408_T3395_SECS;
- g_cfg->timers.T3397 = GSM0408_T3397_SECS;
-
rc = vty_read_config_file(config_file, NULL);
if (rc < 0) {
fprintf(stderr, "Failed to parse the config file: '%s'\n", config_file);
diff --git a/src/gprs/slhc.c b/src/sgsn/slhc.c
index cbdf8dbd8..20e571d48 100644
--- a/src/gprs/slhc.c
+++ b/src/sgsn/slhc.c
@@ -57,8 +57,8 @@
#include <arpa/inet.h>
#include <osmocom/core/utils.h>
#include <osmocom/core/talloc.h>
-#include <openbsc/slhc.h>
-#include <openbsc/debug.h>
+#include <osmocom/sgsn/slhc.h>
+#include <osmocom/sgsn/debug.h>
#define ERR_PTR(x) x
diff --git a/src/gprs/v42bis.c b/src/sgsn/v42bis.c
index a04b0af5c..0759cdf1c 100644
--- a/src/gprs/v42bis.c
+++ b/src/sgsn/v42bis.c
@@ -20,7 +20,7 @@
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/* THIS IS A WORK IN PROGRESS. IT IS NOT FINISHED.
@@ -38,9 +38,9 @@
#include <ctype.h>
#include <assert.h>
-#include <openbsc/v42bis.h>
-#include <openbsc/v42bis_private.h>
-#include <openbsc/debug.h>
+#include <osmocom/sgsn/v42bis.h>
+#include <osmocom/sgsn/v42bis_private.h>
+#include <osmocom/sgsn/debug.h>
#include <osmocom/core/talloc.h>
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 10bb916ff..a23d9317a 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -1,24 +1,13 @@
SUBDIRS = \
gprs \
gbproxy \
- $(NULL)
-
-if HAVE_LIBGTP
-SUBDIRS += \
gtphub \
- $(NULL)
-
-if HAVE_LIBCARES
-SUBDIRS += \
sgsn \
- oap \
xid \
sndcp_xid \
slhc \
v42bis \
$(NULL)
-endif
-endif
# The `:;' works around a Bash 3.2 bug when the output is not writeable.
$(srcdir)/package.m4: $(top_srcdir)/configure.ac
@@ -44,6 +33,7 @@ EXTRA_DIST = \
$(TESTSUITE) \
vty_test_runner.py \
ctrl_test_runner.py \
+ test_nodes.vty \
$(NULL)
TESTSUITE = $(srcdir)/testsuite
@@ -54,16 +44,38 @@ DISTCLEANFILES = \
if ENABLE_EXT_TESTS
python-tests: $(BUILT_SOURCES)
- osmotestvty.py -p $(abs_top_srcdir) -w $(abs_top_builddir) -v
- osmotestconfig.py -p $(abs_top_srcdir) -w $(abs_top_builddir) -v
- $(PYTHON) $(srcdir)/vty_test_runner.py -w $(abs_top_builddir) -v
- $(PYTHON) $(srcdir)/ctrl_test_runner.py -w $(abs_top_builddir) -v
- rm -f $(top_builddir)/sms.db $(top_builddir)/gsn_restart $(top_builddir)/gtphub_restart_count
+ $(MAKE) vty-test
+ $(MAKE) ctrl-python-test
else
python-tests: $(BUILT_SOURCES)
echo "Not running python-based tests (determined at configure-time)"
endif
+vty-python-test: $(BUILT_SOURCES)
+ osmotestvty.py -p $(abs_top_srcdir) -w $(abs_top_builddir) -v
+ osmotestconfig.py -p $(abs_top_srcdir) -w $(abs_top_builddir) -v
+ $(srcdir)/vty_test_runner.py -w $(abs_top_builddir) -v
+ rm -f $(top_builddir)/sms.db $(top_builddir)/gsn_restart $(top_builddir)/gtphub_restart_count
+
+# To update the VTY script from current application behavior,
+# pass -u to vty_script_runner.py by doing:
+# make vty-transcript-test U=-u
+vty-transcript-test:
+ osmo_verify_transcript_vty.py -v \
+ -n OsmoSGSN -p 4245 \
+ -r "$(top_builddir)/src/sgsn/osmo-sgsn -c $(top_srcdir)/doc/examples/osmo-sgsn/osmo-sgsn.cfg" \
+ $(U) $${T:-$(srcdir)/*.vty}
+ rm -f $(builddir)/sms.db $(builddir)/gsn_restart
+
+# don't run multiple tests concurrently so that the ports don't conflict
+vty-test:
+ $(MAKE) vty-python-test
+ $(MAKE) vty-transcript-test
+
+ctrl-python-test: $(BUILT_SOURCES)
+ $(srcdir)/ctrl_test_runner.py -w $(abs_top_builddir) -v
+ rm -f $(top_builddir)/sms.db $(top_builddir)/gsn_restart $(top_builddir)/gtphub_restart_count
+
check-local: atconfig $(TESTSUITE)
$(SHELL) '$(TESTSUITE)' $(TESTSUITEFLAGS)
$(MAKE) $(AM_MAKEFLAGS) python-tests
diff --git a/tests/atlocal.in b/tests/atlocal.in
index 362bfa9df..c85448765 100644
--- a/tests/atlocal.in
+++ b/tests/atlocal.in
@@ -1,7 +1,3 @@
-enable_nat_test='@osmo_ac_build_nat@'
-enable_smpp_test='@osmo_ac_build_smpp@'
-enable_bsc_test='@osmo_ac_build_bsc@'
-enable_mgcp_transcoding_test='@osmo_ac_mgcp_transcoding@'
enable_sgsn_test='@found_libgtp_and_libcares@'
enable_oap_test='@found_libgtp_and_libcares@'
enable_gtphub_test='@found_libgtp_and_libcares@'
diff --git a/tests/ctrl_test_runner.py b/tests/ctrl_test_runner.py
index 2e59e13d2..69b247819 100644..100755
--- a/tests/ctrl_test_runner.py
+++ b/tests/ctrl_test_runner.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
# (C) 2013 by Jacob Erlbeck <jerlbeck@sysmocom.de>
# (C) 2014 by Holger Hans Peter Freyther
@@ -29,11 +29,7 @@ import struct
import osmopy.obscvty as obscvty
import osmopy.osmoutil as osmoutil
-
-# add $top_srcdir/contrib to find ipa.py
-sys.path.append(os.path.join(sys.path[0], '..', 'contrib'))
-
-from ipa import Ctrl, IPA
+from osmopy.osmo_ipa import Ctrl, IPA
# to be able to find $top_srcdir/doc/...
confpath = os.path.join(sys.path[0], '..')
@@ -57,8 +53,8 @@ class TestCtrlBase(unittest.TestCase):
try:
self.proc = osmoutil.popen_devnull(osmo_ctrl_cmd)
except OSError:
- print >> sys.stderr, "Current directory: %s" % os.getcwd()
- print >> sys.stderr, "Consider setting -b"
+ print("Current directory: %s" % os.getcwd(), file=sys.stderr)
+ print("Consider setting -b", file=sys.stderr)
time.sleep(2)
appstring = self.ctrl_app()[2]
@@ -76,7 +72,7 @@ class TestCtrlBase(unittest.TestCase):
def connect(self, host, port):
if verbose:
- print "Connecting to host %s:%i" % (host, port)
+ print("Connecting to host %s:%i" % (host, port))
retries = 30
while True:
@@ -96,7 +92,7 @@ class TestCtrlBase(unittest.TestCase):
def send(self, data):
if verbose:
- print "Sending \"%s\"" %(data)
+ print("Sending \"%s\"" %(data))
data = Ctrl().add_header(data)
return self.sock.send(data) == len(data)
@@ -125,9 +121,9 @@ class TestCtrlBase(unittest.TestCase):
data = self.sock.recv(4096)
while (len(data)>0):
(head, data) = IPA().split_combined(data)
- answer = Ctrl().rem_header(head)
+ answer = Ctrl().rem_header(head).decode()
if verbose:
- print "Got message:", answer
+ print("Got message:", answer)
(mtype, id, msg) = answer.split(None, 2)
id = int(id)
rsp = {'mtype': mtype, 'id': id}
@@ -143,396 +139,27 @@ class TestCtrlBase(unittest.TestCase):
responses[id] = rsp
if verbose:
- print "Decoded replies: ", responses
+ print("Decoded replies: ", responses)
return responses
-
-class TestCtrlBSC(TestCtrlBase):
-
- def tearDown(self):
- TestCtrlBase.tearDown(self)
- os.unlink("tmp_dummy_sock")
-
- def ctrl_command(self):
- return ["./src/osmo-bsc/osmo-bsc", "-r", "tmp_dummy_sock", "-c",
- "doc/examples/osmo-bsc/osmo-bsc.cfg"]
-
- def ctrl_app(self):
- return (4249, "./src/osmo-bsc/osmo-bsc", "OsmoBSC", "bsc")
-
- def testCtrlErrs(self):
- r = self.do_get('invalid')
- self.assertEquals(r['mtype'], 'ERROR')
- self.assertEquals(r['error'], 'Command not found')
-
- r = self.do_set('rf_locked', '999')
- self.assertEquals(r['mtype'], 'ERROR')
- self.assertEquals(r['error'], 'Value failed verification.')
-
- r = self.do_get('bts')
- self.assertEquals(r['mtype'], 'ERROR')
- self.assertEquals(r['error'], 'Error while parsing the index.')
-
- r = self.do_get('bts.999')
- self.assertEquals(r['mtype'], 'ERROR')
- self.assertEquals(r['error'], 'Error while resolving object')
-
- def testBtsLac(self):
- r = self.do_get('bts.0.location-area-code')
- self.assertEquals(r['mtype'], 'GET_REPLY')
- self.assertEquals(r['var'], 'bts.0.location-area-code')
- self.assertEquals(r['value'], '1')
-
- r = self.do_set('bts.0.location-area-code', '23')
- self.assertEquals(r['mtype'], 'SET_REPLY')
- self.assertEquals(r['var'], 'bts.0.location-area-code')
- self.assertEquals(r['value'], '23')
-
- r = self.do_get('bts.0.location-area-code')
- self.assertEquals(r['mtype'], 'GET_REPLY')
- self.assertEquals(r['var'], 'bts.0.location-area-code')
- self.assertEquals(r['value'], '23')
-
- r = self.do_set('bts.0.location-area-code', '-1')
- self.assertEquals(r['mtype'], 'ERROR')
- self.assertEquals(r['error'], 'Input not within the range')
-
- def testBtsCi(self):
- r = self.do_get('bts.0.cell-identity')
- self.assertEquals(r['mtype'], 'GET_REPLY')
- self.assertEquals(r['var'], 'bts.0.cell-identity')
- self.assertEquals(r['value'], '0')
-
- r = self.do_set('bts.0.cell-identity', '23')
- self.assertEquals(r['mtype'], 'SET_REPLY')
- self.assertEquals(r['var'], 'bts.0.cell-identity')
- self.assertEquals(r['value'], '23')
-
- r = self.do_get('bts.0.cell-identity')
- self.assertEquals(r['mtype'], 'GET_REPLY')
- self.assertEquals(r['var'], 'bts.0.cell-identity')
- self.assertEquals(r['value'], '23')
-
- r = self.do_set('bts.0.cell-identity', '-1')
- self.assertEquals(r['mtype'], 'ERROR')
- self.assertEquals(r['error'], 'Input not within the range')
-
- def testBtsGenerateSystemInformation(self):
- r = self.do_get('bts.0.send-new-system-informations')
- self.assertEquals(r['mtype'], 'ERROR')
- self.assertEquals(r['error'], 'Write Only attribute')
-
- # No RSL links so it will fail
- r = self.do_set('bts.0.send-new-system-informations', '1')
- self.assertEquals(r['mtype'], 'ERROR')
- self.assertEquals(r['error'], 'Failed to generate SI')
-
- def testBtsChannelLoad(self):
- r = self.do_set('bts.0.channel-load', '1')
- self.assertEquals(r['mtype'], 'ERROR')
- self.assertEquals(r['error'], 'Read Only attribute')
-
- # No RSL link so everything is 0
- r = self.do_get('bts.0.channel-load')
- self.assertEquals(r['mtype'], 'GET_REPLY')
- self.assertEquals(r['value'],
- 'CCCH+SDCCH4,0,0 TCH/F,0,0 TCH/H,0,0 SDCCH8,0,0'
- + ' TCH/F_PDCH,0,0 CCCH+SDCCH4+CBCH,0,0'
- + ' SDCCH8+CBCH,0,0 TCH/F_TCH/H_PDCH,0,0')
-
- def testBtsOmlConnectionState(self):
- """Check OML state. It will not be connected"""
- r = self.do_set('bts.0.oml-connection-state', '1')
- self.assertEquals(r['mtype'], 'ERROR')
- self.assertEquals(r['error'], 'Read Only attribute')
-
- # No RSL link so everything is 0
- r = self.do_get('bts.0.oml-connection-state')
- self.assertEquals(r['mtype'], 'GET_REPLY')
- self.assertEquals(r['value'], 'disconnected')
-
- def testTrxPowerRed(self):
- r = self.do_get('bts.0.trx.0.max-power-reduction')
- self.assertEquals(r['mtype'], 'GET_REPLY')
- self.assertEquals(r['var'], 'bts.0.trx.0.max-power-reduction')
- self.assertEquals(r['value'], '20')
-
- r = self.do_set('bts.0.trx.0.max-power-reduction', '22')
- self.assertEquals(r['mtype'], 'SET_REPLY')
- self.assertEquals(r['var'], 'bts.0.trx.0.max-power-reduction')
- self.assertEquals(r['value'], '22')
-
- r = self.do_get('bts.0.trx.0.max-power-reduction')
- self.assertEquals(r['mtype'], 'GET_REPLY')
- self.assertEquals(r['var'], 'bts.0.trx.0.max-power-reduction')
- self.assertEquals(r['value'], '22')
-
- r = self.do_set('bts.0.trx.0.max-power-reduction', '1')
- self.assertEquals(r['mtype'], 'ERROR')
- self.assertEquals(r['error'], 'Value must be even')
-
- def testTrxArfcn(self):
- r = self.do_get('bts.0.trx.0.arfcn')
- self.assertEquals(r['mtype'], 'GET_REPLY')
- self.assertEquals(r['var'], 'bts.0.trx.0.arfcn')
- self.assertEquals(r['value'], '871')
-
- r = self.do_set('bts.0.trx.0.arfcn', '873')
- self.assertEquals(r['mtype'], 'SET_REPLY')
- self.assertEquals(r['var'], 'bts.0.trx.0.arfcn')
- self.assertEquals(r['value'], '873')
-
- r = self.do_get('bts.0.trx.0.arfcn')
- self.assertEquals(r['mtype'], 'GET_REPLY')
- self.assertEquals(r['var'], 'bts.0.trx.0.arfcn')
- self.assertEquals(r['value'], '873')
-
- r = self.do_set('bts.0.trx.0.arfcn', '2000')
- self.assertEquals(r['mtype'], 'ERROR')
- self.assertEquals(r['error'], 'Input not within the range')
-
- def testRfLock(self):
- r = self.do_get('bts.0.rf_state')
- self.assertEquals(r['mtype'], 'GET_REPLY')
- self.assertEquals(r['var'], 'bts.0.rf_state')
- self.assertEquals(r['value'], 'inoperational,unlocked,on')
-
- r = self.do_set('rf_locked', '1')
- self.assertEquals(r['mtype'], 'SET_REPLY')
- self.assertEquals(r['var'], 'rf_locked')
- self.assertEquals(r['value'], '1')
-
- time.sleep(1.5)
-
- r = self.do_get('bts.0.rf_state')
- self.assertEquals(r['mtype'], 'GET_REPLY')
- self.assertEquals(r['var'], 'bts.0.rf_state')
- self.assertEquals(r['value'], 'inoperational,locked,off')
-
- r = self.do_get('rf_locked')
- self.assertEquals(r['mtype'], 'GET_REPLY')
- self.assertEquals(r['var'], 'rf_locked')
- self.assertEquals(r['value'], 'state=off,policy=off')
-
- r = self.do_set('rf_locked', '0')
- self.assertEquals(r['mtype'], 'SET_REPLY')
- self.assertEquals(r['var'], 'rf_locked')
- self.assertEquals(r['value'], '0')
-
- time.sleep(1.5)
-
- r = self.do_get('bts.0.rf_state')
- self.assertEquals(r['mtype'], 'GET_REPLY')
- self.assertEquals(r['var'], 'bts.0.rf_state')
- self.assertEquals(r['value'], 'inoperational,unlocked,on')
-
- r = self.do_get('rf_locked')
- self.assertEquals(r['mtype'], 'GET_REPLY')
- self.assertEquals(r['var'], 'rf_locked')
- self.assertEquals(r['value'], 'state=off,policy=on')
-
- def testTimezone(self):
- r = self.do_get('timezone')
- self.assertEquals(r['mtype'], 'GET_REPLY')
- self.assertEquals(r['var'], 'timezone')
- self.assertEquals(r['value'], 'off')
-
- r = self.do_set('timezone', '-2,15,2')
- self.assertEquals(r['mtype'], 'SET_REPLY')
- self.assertEquals(r['var'], 'timezone')
- self.assertEquals(r['value'], '-2,15,2')
-
- r = self.do_get('timezone')
- self.assertEquals(r['mtype'], 'GET_REPLY')
- self.assertEquals(r['var'], 'timezone')
- self.assertEquals(r['value'], '-2,15,2')
-
- # Test invalid input
- r = self.do_set('timezone', '-2,15,2,5,6,7')
- self.assertEquals(r['mtype'], 'SET_REPLY')
- self.assertEquals(r['var'], 'timezone')
- self.assertEquals(r['value'], '-2,15,2')
-
- r = self.do_set('timezone', '-2,15')
- self.assertEquals(r['mtype'], 'ERROR')
- r = self.do_set('timezone', '-2')
- self.assertEquals(r['mtype'], 'ERROR')
- r = self.do_set('timezone', '1')
-
- r = self.do_set('timezone', 'off')
- self.assertEquals(r['mtype'], 'SET_REPLY')
- self.assertEquals(r['var'], 'timezone')
- self.assertEquals(r['value'], 'off')
-
- r = self.do_get('timezone')
- self.assertEquals(r['mtype'], 'GET_REPLY')
- self.assertEquals(r['var'], 'timezone')
- self.assertEquals(r['value'], 'off')
-
- def testMcc(self):
- r = self.do_set('mcc', '23')
- r = self.do_get('mcc')
- self.assertEquals(r['mtype'], 'GET_REPLY')
- self.assertEquals(r['var'], 'mcc')
- self.assertEquals(r['value'], '23')
-
- r = self.do_set('mcc', '023')
- r = self.do_get('mcc')
- self.assertEquals(r['mtype'], 'GET_REPLY')
- self.assertEquals(r['var'], 'mcc')
- self.assertEquals(r['value'], '23')
-
- def testMnc(self):
- r = self.do_set('mnc', '9')
- r = self.do_get('mnc')
- self.assertEquals(r['mtype'], 'GET_REPLY')
- self.assertEquals(r['var'], 'mnc')
- self.assertEquals(r['value'], '9')
-
- r = self.do_set('mnc', '09')
- r = self.do_get('mnc')
- self.assertEquals(r['mtype'], 'GET_REPLY')
- self.assertEquals(r['var'], 'mnc')
- self.assertEquals(r['value'], '9')
-
-
- def testMccMncApply(self):
- # Test some invalid input
- r = self.do_set('mcc-mnc-apply', 'WRONG')
- self.assertEquals(r['mtype'], 'ERROR')
-
- r = self.do_set('mcc-mnc-apply', '1,')
- self.assertEquals(r['mtype'], 'ERROR')
-
- r = self.do_set('mcc-mnc-apply', '200,3')
- self.assertEquals(r['mtype'], 'SET_REPLY')
- self.assertEquals(r['var'], 'mcc-mnc-apply')
- self.assertEquals(r['value'], 'Tried to drop the BTS')
-
- # Set it again
- r = self.do_set('mcc-mnc-apply', '200,3')
- self.assertEquals(r['mtype'], 'SET_REPLY')
- self.assertEquals(r['var'], 'mcc-mnc-apply')
- self.assertEquals(r['value'], 'Nothing changed')
-
- # Change it
- r = self.do_set('mcc-mnc-apply', '200,4')
- self.assertEquals(r['mtype'], 'SET_REPLY')
- self.assertEquals(r['var'], 'mcc-mnc-apply')
- self.assertEquals(r['value'], 'Tried to drop the BTS')
-
- # Change it
- r = self.do_set('mcc-mnc-apply', '201,4')
- self.assertEquals(r['mtype'], 'SET_REPLY')
- self.assertEquals(r['var'], 'mcc-mnc-apply')
- self.assertEquals(r['value'], 'Tried to drop the BTS')
-
- # Verify
- r = self.do_get('mnc')
- self.assertEquals(r['mtype'], 'GET_REPLY')
- self.assertEquals(r['var'], 'mnc')
- self.assertEquals(r['value'], '4')
-
- r = self.do_get('mcc')
- self.assertEquals(r['mtype'], 'GET_REPLY')
- self.assertEquals(r['var'], 'mcc')
- self.assertEquals(r['value'], '201')
-
- # Change it
- r = self.do_set('mcc-mnc-apply', '202,03')
- self.assertEquals(r['mtype'], 'SET_REPLY')
- self.assertEquals(r['var'], 'mcc-mnc-apply')
- self.assertEquals(r['value'], 'Tried to drop the BTS')
-
- r = self.do_get('mnc')
- self.assertEquals(r['mtype'], 'GET_REPLY')
- self.assertEquals(r['var'], 'mnc')
- self.assertEquals(r['value'], '3')
-
- r = self.do_get('mcc')
- self.assertEquals(r['mtype'], 'GET_REPLY')
- self.assertEquals(r['var'], 'mcc')
- self.assertEquals(r['value'], '202')
-
-class TestCtrlNAT(TestCtrlBase):
-
- def ctrl_command(self):
- return ["./src/osmo-bsc_nat/osmo-bsc_nat", "-c",
- "doc/examples/osmo-bsc_nat/osmo-bsc_nat.cfg"]
-
- def ctrl_app(self):
- return (4250, "./src/osmo-bsc_nat/osmo-bsc_nat", "OsmoNAT", "nat")
-
- def testAccessList(self):
- r = self.do_get('net.0.bsc_cfg.0.access-list-name')
- self.assertEquals(r['mtype'], 'GET_REPLY')
- self.assertEquals(r['var'], 'net')
- self.assertEquals(r['value'], None)
-
- r = self.do_set('net.0.bsc_cfg.0.access-list-name', 'bla')
- self.assertEquals(r['mtype'], 'SET_REPLY')
- self.assertEquals(r['var'], 'net')
- self.assertEquals(r['value'], 'bla')
-
- r = self.do_get('net.0.bsc_cfg.0.access-list-name')
- self.assertEquals(r['mtype'], 'GET_REPLY')
- self.assertEquals(r['var'], 'net')
- self.assertEquals(r['value'], 'bla')
-
- r = self.do_set('net.0.bsc_cfg.0.no-access-list-name', '1')
- self.assertEquals(r['mtype'], 'SET_REPLY')
- self.assertEquals(r['var'], 'net')
- self.assertEquals(r['value'], None)
-
- r = self.do_get('net.0.bsc_cfg.0.access-list-name')
- self.assertEquals(r['mtype'], 'GET_REPLY')
- self.assertEquals(r['var'], 'net')
- self.assertEquals(r['value'], None)
-
- def testAccessListManagement(self):
- r = self.do_set("net.0.add.allow.access-list.404", "abc")
- self.assertEquals(r['mtype'], 'ERROR')
-
- r = self.do_set("net.0.add.allow.access-list.bla", "^234$")
- self.assertEquals(r['mtype'], 'SET_REPLY')
- self.assertEquals(r['var'], 'net.0.add.allow.access-list.bla')
- self.assertEquals(r['value'], 'IMSI allow added to access list')
-
- # TODO.. find a way to actually see if this rule has been
- # added. e.g. by implementing a get for the list.
-
class TestCtrlSGSN(TestCtrlBase):
def ctrl_command(self):
- return ["./src/gprs/osmo-sgsn", "-c",
+ return ["./src/sgsn/osmo-sgsn", "-c",
"doc/examples/osmo-sgsn/osmo-sgsn.cfg"]
def ctrl_app(self):
- return (4251, "./src/gprs/osmo-sgsn", "OsmoSGSN", "sgsn")
+ return (4251, "./src/sgsn/osmo-sgsn", "OsmoSGSN", "sgsn")
def testListSubscribers(self):
# TODO. Add command to mark a subscriber as active
r = self.do_get('subscriber-list-active-v1')
- self.assertEquals(r['mtype'], 'GET_REPLY')
- self.assertEquals(r['var'], 'subscriber-list-active-v1')
- self.assertEquals(r['value'], None)
-
-def add_bsc_test(suite, workdir):
- if not os.path.isfile(os.path.join(workdir, "src/osmo-bsc/osmo-bsc")):
- print("Skipping the BSC test")
- return
- test = unittest.TestLoader().loadTestsFromTestCase(TestCtrlBSC)
- suite.addTest(test)
-
-def add_nat_test(suite, workdir):
- if not os.path.isfile(os.path.join(workdir, "src/osmo-bsc_nat/osmo-bsc_nat")):
- print("Skipping the NAT test")
- return
- test = unittest.TestLoader().loadTestsFromTestCase(TestCtrlNAT)
- suite.addTest(test)
+ self.assertEqual(r['mtype'], 'GET_REPLY')
+ self.assertEqual(r['var'], 'subscriber-list-active-v1')
+ self.assertEqual(r['value'], None)
def add_sgsn_test(suite, workdir):
- if not os.path.isfile(os.path.join(workdir, "src/gprs/osmo-sgsn")):
+ if not os.path.isfile(os.path.join(workdir, "src/sgsn/osmo-sgsn")):
print("Skipping the SGSN test")
return
test = unittest.TestLoader().loadTestsFromTestCase(TestCtrlSGSN)
@@ -564,12 +191,10 @@ if __name__ == '__main__':
if args.p:
confpath = args.p
- print "confpath %s, workdir %s" % (confpath, workdir)
+ print("confpath %s, workdir %s" % (confpath, workdir))
os.chdir(workdir)
- print "Running tests for specific control commands"
+ print("Running tests for specific control commands")
suite = unittest.TestSuite()
- add_bsc_test(suite, workdir)
- add_nat_test(suite, workdir)
add_sgsn_test(suite, workdir)
res = unittest.TextTestRunner(verbosity=verbose_level).run(suite)
sys.exit(len(res.errors) + len(res.failures))
diff --git a/tests/gbproxy/Makefile.am b/tests/gbproxy/Makefile.am
index 3291839b6..b9585acc8 100644
--- a/tests/gbproxy/Makefile.am
+++ b/tests/gbproxy/Makefile.am
@@ -28,14 +28,14 @@ gbproxy_test_SOURCES = \
$(NULL)
gbproxy_test_LDFLAGS = \
- -Wl,--wrap=RAND_bytes \
+ -Wl,--wrap=osmo_get_rand_id \
$(NULL)
gbproxy_test_LDADD = \
- $(top_builddir)/src/gprs/gb_proxy.o \
- $(top_builddir)/src/gprs/gb_proxy_patch.o \
- $(top_builddir)/src/gprs/gb_proxy_peer.o \
- $(top_builddir)/src/gprs/gb_proxy_tlli.o \
+ $(top_builddir)/src/gbproxy/gb_proxy.o \
+ $(top_builddir)/src/gbproxy/gb_proxy_patch.o \
+ $(top_builddir)/src/gbproxy/gb_proxy_peer.o \
+ $(top_builddir)/src/gbproxy/gb_proxy_tlli.o \
$(top_builddir)/src/gprs/gprs_gb_parse.o \
$(top_builddir)/src/gprs/gprs_llc_parse.o \
$(top_builddir)/src/gprs/crc24.o \
@@ -46,6 +46,6 @@ gbproxy_test_LDADD = \
$(LIBOSMOVTY_LIBS) \
$(LIBOSMOABIS_LIBS) \
$(LIBRARY_DL) \
- $(LIBCRYPTO_LIBS) \
+ $(LIBRARY_DLSYM) \
-lrt \
$(NULL)
diff --git a/tests/gbproxy/gbproxy_test.c b/tests/gbproxy/gbproxy_test.c
index 9672dcba6..f5c730db9 100644
--- a/tests/gbproxy/gbproxy_test.c
+++ b/tests/gbproxy/gbproxy_test.c
@@ -31,13 +31,11 @@
#include <osmocom/gprs/gprs_ns.h>
#include <osmocom/gprs/gprs_bssgp.h>
-#include <openbsc/gb_proxy.h>
-#include <openbsc/gprs_utils.h>
-#include <openbsc/gprs_llc.h>
-#include <openbsc/gprs_gb_parse.h>
-#include <openbsc/debug.h>
-
-#include <openssl/rand.h>
+#include <osmocom/sgsn/gb_proxy.h>
+#include <osmocom/sgsn/gprs_utils.h>
+#include <osmocom/sgsn/gprs_llc.h>
+#include <osmocom/sgsn/gprs_gb_parse.h>
+#include <osmocom/sgsn/debug.h>
#define REMOTE_BSS_ADDR 0x01020304
#define REMOTE_SGSN_ADDR 0x05060708
@@ -49,30 +47,29 @@
#define MATCH_ANY (-1)
-void *tall_bsc_ctx;
+void *tall_sgsn_ctx = NULL;
struct gbproxy_config gbcfg = {0};
struct llist_head *received_messages = NULL;
-/* override, requires '-Wl,--wrap=RAND_bytes' */
-int __real_RAND_bytes(unsigned char *buf, int num);
-int mock_RAND_bytes(unsigned char *buf, int num);
-int (*RAND_bytes_cb)(unsigned char *, int) =
- &mock_RAND_bytes;
+/* override, requires '-Wl,--wrap=osmo_get_rand_id' */
+int __real_osmo_get_rand_id(uint8_t *data, size_t len);
+int mock_osmo_get_rand_id(uint8_t *data, size_t len);
+int (*osmo_get_rand_id_cb)(uint8_t *, size_t) =
+ &mock_osmo_get_rand_id;
-int __wrap_RAND_bytes(unsigned char *buf, int num)
+int __wrap_osmo_get_rand_id(uint8_t *buf, size_t num)
{
- return (*RAND_bytes_cb)(buf, num);
+ return (*osmo_get_rand_id_cb)(buf, num);
}
static int rand_seq_num = 0;
-int mock_RAND_bytes(unsigned char *buf, int num)
+int mock_osmo_get_rand_id(uint8_t *buf, size_t num)
{
uint32_t val;
OSMO_ASSERT(num == sizeof(val));
- OSMO_ASSERT(__real_RAND_bytes(buf, num) == 1);
val = 0x00dead00 + rand_seq_num;
@@ -134,12 +131,11 @@ static int dump_peers(FILE *stream, int indent, time_t now,
struct gbproxy_patch_state *state = &peer->patch_state;
gsm48_parse_ra(&raid, peer->ra);
- rc = fprintf(stream, "%*s NSEI %u, BVCI %u, %sblocked, "
- "RAI %u-%u-%u-%u\n",
+ rc = fprintf(stream, "%*s NSEI %u, BVCI %u, %sblocked, RAI %s\n",
indent, "",
peer->nsei, peer->bvci,
peer->blocked ? "" : "not ",
- raid.mcc, raid.mnc, raid.lac, raid.rac);
+ osmo_rai_name(&raid));
if (rc < 0)
return rc;
@@ -225,9 +221,9 @@ static int dump_peers(FILE *stream, int indent, time_t now,
const uint8_t *convert_ra(struct gprs_ra_id *raid)
{
- static uint8_t buf[6];
- gsm48_construct_ra(buf, raid);
- return buf;
+ static struct gsm48_ra_id r;
+ gsm48_encode_ra(&r, raid);
+ return (const uint8_t *)&r;
}
/* DTAP - Attach Request */
@@ -585,7 +581,7 @@ static void send_bssgp_ul_unitdata(
OSMO_ASSERT(bssgp_msg_size <= sizeof(msg));
- gsm48_construct_ra(msg + 10, raid);
+ gsm48_encode_ra((struct gsm48_ra_id *)(msg + 10), raid);
msg[1] = (uint8_t)(tlli >> 24);
msg[2] = (uint8_t)(tlli >> 16);
msg[3] = (uint8_t)(tlli >> 8);
@@ -716,7 +712,7 @@ static void send_bssgp_suspend(struct gprs_ns_inst *nsi,
msg[5] = (uint8_t)(tlli >> 8);
msg[6] = (uint8_t)(tlli >> 0);
- gsm48_construct_ra(msg + 9, raid);
+ gsm48_encode_ra((struct gsm48_ra_id *)(msg + 9), raid);
send_ns_unitdata(nsi, "BVC_SUSPEND", src_addr, 0, msg, sizeof(msg));
}
@@ -738,7 +734,7 @@ static void send_bssgp_suspend_ack(struct gprs_ns_inst *nsi,
msg[5] = (uint8_t)(tlli >> 8);
msg[6] = (uint8_t)(tlli >> 0);
- gsm48_construct_ra(msg + 9, raid);
+ gsm48_encode_ra((struct gsm48_ra_id *)(msg + 9), raid);
send_ns_unitdata(nsi, "BVC_SUSPEND_ACK", src_addr, 0, msg, sizeof(msg));
}
@@ -798,7 +794,7 @@ static void send_bssgp_paging(struct gprs_ns_inst *nsi,
if (raid) {
msg[bssgp_msg_size] = BSSGP_IE_ROUTEING_AREA;
msg[bssgp_msg_size+1] = 0x86;
- gsm48_construct_ra(msg + bssgp_msg_size + 2, raid);
+ gsm48_encode_ra((struct gsm48_ra_id *)(msg + bssgp_msg_size + 2), raid);
bssgp_msg_size += 8;
}
@@ -1065,7 +1061,7 @@ int gprs_ns_sendmsg(struct gprs_ns_inst *nsi, struct msgb *msg)
if (received_messages) {
struct msgb *msg_copy;
- msg_copy = gprs_msgb_copy(msg, "received_messages");
+ msg_copy = bssgp_msgb_copy(msg, "received_messages");
llist_add_tail(&msg_copy->list, received_messages);
}
@@ -1306,7 +1302,13 @@ static int gprs_process_message(struct gprs_ns_inst *nsi, const char *text, stru
ret = gprs_ns_rcvmsg(nsi, msg, peer, GPRS_NS_LL_UDP);
- printf("result (%s) = %d\n\n", text, ret);
+ /* gprs_ns_rcvmsg() in old libosmocore returns "number of bytes
+ * transmitted by any response PDU we sent as a result of the
+ * received message", while modern libosmocore simply retunrs '0'
+ * for any successfully received message. Let's make sure any
+ * non-negative responses lead to a reproducible test output
+ * with both old and new libosmocore. */
+ printf("result (%s) = %d\n\n", text, ret < 0 ? ret : 0);
msgb_free(msg);
@@ -1333,7 +1335,7 @@ static void gprs_dump_nsi(struct gprs_ns_inst *nsi)
static void test_gbproxy()
{
- struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
+ struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, tall_sgsn_ctx);
struct sockaddr_in bss_peer[4] = {{0},};
struct sockaddr_in sgsn_peer= {0};
@@ -1501,7 +1503,7 @@ static void test_gbproxy()
static void test_gbproxy_ident_changes()
{
- struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
+ struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, tall_sgsn_ctx);
struct sockaddr_in bss_peer[1] = {{0},};
struct sockaddr_in sgsn_peer= {0};
uint16_t nsei[2] = {0x1000, 0x2000};
@@ -1633,7 +1635,7 @@ static void test_gbproxy_ident_changes()
static void test_gbproxy_ra_patching()
{
- struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
+ struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, tall_sgsn_ctx);
struct sockaddr_in bss_peer[1] = {{0},};
struct sockaddr_in sgsn_peer= {0};
struct gprs_ra_id rai_bss =
@@ -1660,9 +1662,8 @@ static void test_gbproxy_ra_patching()
bssgp_nsi = nsi;
gbcfg.nsi = bssgp_nsi;
gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
- gbcfg.core_mcc = 123;
- gbcfg.core_mnc = 456;
- gbcfg.core_apn = talloc_zero_size(NULL, 100);
+ gbcfg.core_plmn = (struct osmo_plmn_id){ .mcc = 123, .mnc = 456 };
+ gbcfg.core_apn = talloc_zero_size(tall_sgsn_ctx, 100);
gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
gbcfg.patch_ptmsi = 0;
@@ -1965,6 +1966,9 @@ static void test_gbproxy_ra_patching()
OSMO_ASSERT(!expect_msg());
received_messages = NULL;
+ talloc_free(gbcfg.core_apn);
+ gbcfg.core_apn = NULL;
+
gbproxy_clear_patch_filter(&gbcfg.matches[GBPROX_MATCH_PATCHING]);
gbprox_reset(&gbcfg);
gprs_ns_destroy(nsi);
@@ -1973,7 +1977,7 @@ static void test_gbproxy_ra_patching()
static void test_gbproxy_ptmsi_assignment()
{
- struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
+ struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, tall_sgsn_ctx);
struct sockaddr_in bss_peer[1] = {{0},};
struct sockaddr_in sgsn_peer= {0};
struct gprs_ra_id rai_bss =
@@ -2001,9 +2005,8 @@ static void test_gbproxy_ptmsi_assignment()
bssgp_nsi = nsi;
gbcfg.nsi = bssgp_nsi;
gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
- gbcfg.core_mcc = 0;
- gbcfg.core_mnc = 0;
- gbcfg.core_apn = talloc_zero_size(NULL, 100);
+ gbcfg.core_plmn = (struct osmo_plmn_id){};
+ gbcfg.core_apn = talloc_zero_size(tall_sgsn_ctx, 100);
gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
gbcfg.patch_ptmsi = 0;
@@ -2178,6 +2181,9 @@ static void test_gbproxy_ptmsi_assignment()
dump_global(stdout, 0);
+ talloc_free(gbcfg.core_apn);
+ gbcfg.core_apn = NULL;
+
gbprox_reset(&gbcfg);
gprs_ns_destroy(nsi);
nsi = NULL;
@@ -2187,7 +2193,7 @@ static void test_gbproxy_ptmsi_assignment()
static void test_gbproxy_ptmsi_patching()
{
- struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
+ struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, tall_sgsn_ctx);
struct sockaddr_in bss_peer[1] = {{0},};
struct sockaddr_in sgsn_peer= {0};
struct gprs_ra_id rai_bss =
@@ -2235,9 +2241,8 @@ static void test_gbproxy_ptmsi_patching()
bssgp_nsi = nsi;
gbcfg.nsi = bssgp_nsi;
gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
- gbcfg.core_mcc = 123;
- gbcfg.core_mnc = 456;
- gbcfg.core_apn = talloc_zero_size(NULL, 100);
+ gbcfg.core_plmn = (struct osmo_plmn_id){ .mcc = 123, .mnc = 456 };
+ gbcfg.core_apn = talloc_zero_size(tall_sgsn_ctx, 100);
gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
gbcfg.patch_ptmsi = 1;
@@ -2515,6 +2520,9 @@ static void test_gbproxy_ptmsi_patching()
dump_global(stdout, 0);
+ talloc_free(gbcfg.core_apn);
+ gbcfg.core_apn = NULL;
+
gbprox_reset(&gbcfg);
gprs_ns_destroy(nsi);
nsi = NULL;
@@ -2524,7 +2532,7 @@ static void test_gbproxy_ptmsi_patching()
static void test_gbproxy_ptmsi_patching_bad_cases()
{
- struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
+ struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, tall_sgsn_ctx);
struct sockaddr_in bss_peer[1] = {{0},};
struct sockaddr_in sgsn_peer= {0};
struct gprs_ra_id rai_bss =
@@ -2554,9 +2562,8 @@ static void test_gbproxy_ptmsi_patching_bad_cases()
bssgp_nsi = nsi;
gbcfg.nsi = bssgp_nsi;
gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
- gbcfg.core_mcc = 123;
- gbcfg.core_mnc = 456;
- gbcfg.core_apn = talloc_zero_size(NULL, 100);
+ gbcfg.core_plmn = (struct osmo_plmn_id){ .mcc = 123, .mnc = 456 };
+ gbcfg.core_apn = talloc_zero_size(tall_sgsn_ctx, 100);
gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
gbcfg.patch_ptmsi = 1;
@@ -2694,6 +2701,9 @@ static void test_gbproxy_ptmsi_patching_bad_cases()
dump_global(stdout, 0);
+ talloc_free(gbcfg.core_apn);
+ gbcfg.core_apn = NULL;
+
gbprox_reset(&gbcfg);
gprs_ns_destroy(nsi);
nsi = NULL;
@@ -2704,7 +2714,7 @@ static void test_gbproxy_ptmsi_patching_bad_cases()
static void test_gbproxy_imsi_acquisition()
{
- struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
+ struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, tall_sgsn_ctx);
struct sockaddr_in bss_peer[1] = {{0},};
struct sockaddr_in sgsn_peer= {0};
struct gprs_ra_id rai_bss =
@@ -2738,9 +2748,8 @@ static void test_gbproxy_imsi_acquisition()
bssgp_nsi = nsi;
gbcfg.nsi = bssgp_nsi;
gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
- gbcfg.core_mcc = 123;
- gbcfg.core_mnc = 456;
- gbcfg.core_apn = talloc_zero_size(NULL, 100);
+ gbcfg.core_plmn = (struct osmo_plmn_id){ .mcc = 123, .mnc = 456 };
+ gbcfg.core_apn = talloc_zero_size(tall_sgsn_ctx, 100);
gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
gbcfg.patch_ptmsi = 1;
gbcfg.acquire_imsi = 1;
@@ -3006,6 +3015,9 @@ static void test_gbproxy_imsi_acquisition()
dump_global(stdout, 0);
+ talloc_free(gbcfg.core_apn);
+ gbcfg.core_apn = NULL;
+
gbprox_reset(&gbcfg);
gprs_ns_destroy(nsi);
nsi = NULL;
@@ -3015,7 +3027,7 @@ static void test_gbproxy_imsi_acquisition()
static void test_gbproxy_secondary_sgsn()
{
- struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
+ struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, tall_sgsn_ctx);
struct sockaddr_in bss_peer[1] = {{0},};
struct sockaddr_in sgsn_peer[2]= {{0},};
struct gprs_ra_id rai_bss =
@@ -3064,9 +3076,8 @@ static void test_gbproxy_secondary_sgsn()
bssgp_nsi = nsi;
gbcfg.nsi = bssgp_nsi;
gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
- gbcfg.core_mcc = 123;
- gbcfg.core_mnc = 456;
- gbcfg.core_apn = talloc_zero_size(NULL, 100);
+ gbcfg.core_plmn = (struct osmo_plmn_id){ .mcc = 123, .mnc = 456 };
+ gbcfg.core_apn = talloc_zero_size(tall_sgsn_ctx, 100);
gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
gbcfg.patch_ptmsi = 1;
gbcfg.acquire_imsi = 1;
@@ -3507,6 +3518,9 @@ static void test_gbproxy_secondary_sgsn()
dump_global(stdout, 0);
+ talloc_free(gbcfg.core_apn);
+ gbcfg.core_apn = NULL;
+
gbproxy_clear_patch_filter(&gbcfg.matches[GBPROX_MATCH_ROUTING]);
gbprox_reset(&gbcfg);
gprs_ns_destroy(nsi);
@@ -3517,7 +3531,7 @@ static void test_gbproxy_secondary_sgsn()
static void test_gbproxy_keep_info()
{
- struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
+ struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, tall_sgsn_ctx);
struct sockaddr_in bss_peer[1] = {{0},};
struct sockaddr_in sgsn_peer= {0};
struct gprs_ra_id rai_bss =
@@ -3543,8 +3557,7 @@ static void test_gbproxy_keep_info()
gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
gbcfg.patch_ptmsi = 0;
gbcfg.acquire_imsi = 1;
- gbcfg.core_mcc = 0;
- gbcfg.core_mnc = 0;
+ gbcfg.core_plmn = (struct osmo_plmn_id){};
gbcfg.core_apn = NULL;
gbcfg.core_apn_size = 0;
gbcfg.route_to_sgsn2 = 0;
@@ -4451,6 +4464,9 @@ static void test_gbproxy_keep_info()
dump_global(stdout, 0);
+ talloc_free(gbcfg.core_apn);
+ gbcfg.core_apn = NULL;
+
gbprox_reset(&gbcfg);
gprs_ns_destroy(nsi);
nsi = NULL;
@@ -4739,6 +4755,8 @@ static void test_gbproxy_tlli_expire(void)
}
gbproxy_clear_patch_filter(&cfg.matches[GBPROX_MATCH_PATCHING]);
gbprox_reset(&cfg);
+ /* gbprox_reset() frees the rate_ctr, but re-allocates it again. */
+ rate_ctr_group_free(cfg.ctrg);
cleanup_test();
}
@@ -4821,7 +4839,7 @@ static void test_gbproxy_imsi_matching(void)
static void test_gbproxy_stored_messages()
{
- struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
+ struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, tall_sgsn_ctx);
struct sockaddr_in bss_peer[1] = {{0},};
struct sockaddr_in sgsn_peer= {0};
struct gprs_ra_id rai_bss =
@@ -4844,9 +4862,8 @@ static void test_gbproxy_stored_messages()
bssgp_nsi = nsi;
gbcfg.nsi = bssgp_nsi;
gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
- gbcfg.core_mcc = 0;
- gbcfg.core_mnc = 0;
- gbcfg.core_apn = talloc_zero_size(NULL, 100);
+ gbcfg.core_plmn = (struct osmo_plmn_id){};
+ gbcfg.core_apn = talloc_zero_size(tall_sgsn_ctx, 100);
gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
gbcfg.patch_ptmsi = 0;
gbcfg.acquire_imsi = 1;
@@ -4906,6 +4923,9 @@ static void test_gbproxy_stored_messages()
dump_global(stdout, 0);
+ talloc_free(gbcfg.core_apn);
+ gbcfg.core_apn = NULL;
+
gbprox_reset(&gbcfg);
gprs_ns_destroy(nsi);
nsi = NULL;
@@ -4913,6 +4933,83 @@ static void test_gbproxy_stored_messages()
cleanup_test();
}
+/* See OS#3178 "gbproxy: failed to parse invalid BSSGP-UNITDATA message" */
+static void test_gbproxy_parse_bssgp_unitdata()
+{
+ const char *hex = "0000239401e155cfea000004088872f4801018009c4000800e000601c0416c4338";
+ struct msgb *msg = msgb_alloc(1034, "bssgp_unitdata");
+ struct gprs_gb_parse_context parse_ctx;
+ int rc;
+
+ memset(&parse_ctx, 0, sizeof(parse_ctx));
+
+ OSMO_ASSERT(msg);
+ msgb_bssgph(msg) = msg->head;
+ msgb_put(msg, osmo_hexparse(hex, msg->head, msgb_tailroom(msg)));
+
+ parse_ctx.to_bss = 0;
+ parse_ctx.peer_nsei = msgb_nsei(msg);
+
+ rc = gprs_gb_parse_bssgp(msg->data, msg->len, &parse_ctx);
+ if (!rc)
+ fprintf(stderr, "%s: Test passed; Failed to parse invalid message %s\n", __func__, msgb_hexdump(msg));
+ else
+ fprintf(stderr, "%s: Test failed; invalid message was accepted by parser: %s\n", __func__, msgb_hexdump(msg));
+
+ OSMO_ASSERT(!rc);
+
+ /* Manually decoded message according to:
+ ETSI TS 148 018 V10.6.0 (2012 07) 96
+ 3GPP TS 48.018 version 10.6.0 Release 10
+ Table 10.2.2: UL-UNITDATA PDU content
+
+ 00 - PDU type UL-UNITDATA (ok)
+
+ 11.3.35 Temporary logical link Identity (TLLI)
+ 00 - TLLI[0]
+ 23 - TLLI[1]
+ 94 - TLLI[2]
+ 01 - TLLI[3]
+ TLLI == "00239401"
+
+ e1 - QOS[0] (bit rate MSB)
+ 55 - QOS[1] (bit rate LSB)
+ bit rate = "57685" (57685*100000 bit/s per PBRG)
+ cf - QOS[2] PBRG = 11 (bit rate is expressed in 100000 bit/s increments),
+ C/R 0 (contains LLC ACK/SACK),
+ T 0 (contains signalling),
+ A 1 (radio if uses MAC/UNITDATA,
+ Precedence 111 (reserved value)
+
+ ea - CELL_ID[0] (TLV IEI: wrong, should be 0x08)
+ 00 - CELL_ID[1] (length 1)
+ 00 - CELL_ID[2] (length 2)
+ lenth == 0
+ 04 -- CELL_ID[3]
+ 08 -- CELL_ID[4]
+ 88 -- CELL_ID[5]
+ 72 -- CELL_ID[6]
+ f4 -- CELL_ID[7]
+ 80 -- CELL_ID[8]
+ 10 -- CELL_DI[9]
+
+ 18 -- QOSP[0] OoS Profile IEI
+ not allowed in BSSGP Userdata
+ 00 -- QOSP[1]
+ 9c -- QOSP[2]
+ 40 -- QOSP[3]
+ 00 -- QOSP[4]
+
+ 80 -- IEI for "E-UTRAN Inter RAT Handover Info"
+ not allowed in BSSGP Userdata
+ 0e -- length (14 bytes -- only 8 bytes remain)
+ 00 06 01 c0 41 6c 43 38 */
+
+ msgb_free(msg);
+
+ cleanup_test();
+}
+
static struct log_info_cat gprs_categories[] = {
[DGPRS] = {
.name = "DGPRS",
@@ -4938,9 +5035,13 @@ static struct log_info info = {
int main(int argc, char **argv)
{
- msgb_talloc_ctx_init(NULL, 0);
+ talloc_enable_leak_report();
+ tall_sgsn_ctx = talloc_named_const(NULL, 0, "gbproxy_test");
+ void *log_ctx = talloc_named_const(tall_sgsn_ctx, 0, "log");
- osmo_init_logging(&info);
+ msgb_talloc_ctx_init(tall_sgsn_ctx, 0);
+
+ osmo_init_logging2(log_ctx, &info);
log_set_use_color(osmo_stderr_target, 0);
log_set_print_filename(osmo_stderr_target, 0);
osmo_signal_register_handler(SS_L_NS, &test_signal, &gbcfg);
@@ -4949,7 +5050,7 @@ int main(int argc, char **argv)
log_set_log_level(osmo_stderr_target, LOGL_DEBUG);
log_set_all_filter(osmo_stderr_target, 1);
- rate_ctr_init(NULL);
+ rate_ctr_init(tall_sgsn_ctx);
setlinebuf(stdout);
@@ -4967,7 +5068,16 @@ int main(int argc, char **argv)
test_gbproxy_keep_info();
test_gbproxy_tlli_expire();
test_gbproxy_stored_messages();
+ test_gbproxy_parse_bssgp_unitdata();
+ gbprox_reset(&gbcfg);
+ /* gbprox_reset() frees the rate_ctr, but re-allocates it again. */
+ rate_ctr_group_free(gbcfg.ctrg);
printf("===== GbProxy test END\n\n");
- exit(EXIT_SUCCESS);
+ talloc_free(log_ctx);
+ /* expecting root and msgb ctx, empty */
+ OSMO_ASSERT(talloc_total_blocks(tall_sgsn_ctx) == 2);
+ talloc_free(tall_sgsn_ctx);
+
+ return 0;
}
diff --git a/tests/gbproxy/gbproxy_test.ok b/tests/gbproxy/gbproxy_test.ok
index 737aec0ba..75f31ab9e 100644
--- a/tests/gbproxy/gbproxy_test.ok
+++ b/tests/gbproxy/gbproxy_test.ok
@@ -11,7 +11,7 @@ PROCESSING RESET_ACK from 0x05060708:32000
MESSAGE to SGSN at 0x05060708:32000, msg length 1
0a
-result (RESET_ACK) = 1
+result (RESET_ACK) = 0
PROCESSING ALIVE_ACK from 0x05060708:32000
0b
@@ -19,7 +19,7 @@ PROCESSING ALIVE_ACK from 0x05060708:32000
MESSAGE to SGSN at 0x05060708:32000, msg length 1
06
-result (ALIVE_ACK) = 1
+result (ALIVE_ACK) = 0
PROCESSING UNBLOCK_ACK from 0x05060708:32000
07
@@ -34,10 +34,14 @@ PROCESSING ALIVE from 0x05060708:32000
MESSAGE to SGSN at 0x05060708:32000, msg length 1
0b
-result (ALIVE) = 1
+result (ALIVE) = 0
Current NS-VCIs:
VCI 0x0101, NSEI 0x0100, peer 0x05060708:32000
+ Packets at NS Level ( In): 4
+ Packets at NS Level (Out): 4
+ Bytes at NS Level ( In): 12
+ Bytes at NS Level (Out): 15
NS-VC Block count : 1
--- Initialise BSS 1 ---
@@ -55,7 +59,7 @@ MESSAGE to BSS at 0x01020304:1111, msg length 9
MESSAGE to BSS at 0x01020304:1111, msg length 1
0a
-result (RESET) = 9
+result (RESET) = 0
PROCESSING ALIVE from 0x01020304:1111
0a
@@ -63,17 +67,17 @@ PROCESSING ALIVE from 0x01020304:1111
MESSAGE to BSS at 0x01020304:1111, msg length 1
0b
-result (ALIVE) = 1
+result (ALIVE) = 0
PROCESSING UNBLOCK from 0x01020304:1111
06
-==> got signal NS_UNBLOCK, NS-VC 0x1001/1.2.3.4:1111
-
MESSAGE to BSS at 0x01020304:1111, msg length 1
07
-result (UNBLOCK) = 1
+==> got signal NS_UNBLOCK, NS-VC 0x1001/1.2.3.4:1111
+
+result (UNBLOCK) = 0
PROCESSING ALIVE_ACK from 0x01020304:1111
0b
@@ -92,11 +96,19 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x0000, msg length 18 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 22
00 00 00 00 22 04 82 10 02 07 81 08 08 88 11 22 33 40 50 60 10 00
-result (BVC_RESET) = 22
+result (BVC_RESET) = 0
Current NS-VCIs:
VCI 0x1001, NSEI 0x1000, peer 0x01020304:1111
+ Packets at NS Level ( In): 5
+ Packets at NS Level (Out): 4
+ Bytes at NS Level ( In): 37
+ Bytes at NS Level (Out): 12
VCI 0x0101, NSEI 0x0100, peer 0x05060708:32000
+ Packets at NS Level ( In): 4
+ Packets at NS Level (Out): 5
+ Bytes at NS Level ( In): 12
+ Bytes at NS Level (Out): 37
NS-VC Block count : 1
Peers:
@@ -112,7 +124,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x0000, msg length 5 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 9
00 00 00 00 23 04 82 10 02
-result (BVC_RESET_ACK) = 9
+result (BVC_RESET_ACK) = 0
--- Initialise BSS 2 ---
@@ -129,7 +141,7 @@ MESSAGE to BSS at 0x01020304:2222, msg length 9
MESSAGE to BSS at 0x01020304:2222, msg length 1
0a
-result (RESET) = 9
+result (RESET) = 0
PROCESSING ALIVE from 0x01020304:2222
0a
@@ -137,17 +149,17 @@ PROCESSING ALIVE from 0x01020304:2222
MESSAGE to BSS at 0x01020304:2222, msg length 1
0b
-result (ALIVE) = 1
+result (ALIVE) = 0
PROCESSING UNBLOCK from 0x01020304:2222
06
-==> got signal NS_UNBLOCK, NS-VC 0x2001/1.2.3.4:2222
-
MESSAGE to BSS at 0x01020304:2222, msg length 1
07
-result (UNBLOCK) = 1
+==> got signal NS_UNBLOCK, NS-VC 0x2001/1.2.3.4:2222
+
+result (UNBLOCK) = 0
PROCESSING ALIVE_ACK from 0x01020304:2222
0b
@@ -166,12 +178,24 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x0000, msg length 18 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 22
00 00 00 00 22 04 82 20 02 07 81 08 08 88 11 22 33 40 50 60 10 00
-result (BVC_RESET) = 22
+result (BVC_RESET) = 0
Current NS-VCIs:
VCI 0x2001, NSEI 0x2000, peer 0x01020304:2222
+ Packets at NS Level ( In): 5
+ Packets at NS Level (Out): 4
+ Bytes at NS Level ( In): 37
+ Bytes at NS Level (Out): 12
VCI 0x1001, NSEI 0x1000, peer 0x01020304:1111
+ Packets at NS Level ( In): 5
+ Packets at NS Level (Out): 5
+ Bytes at NS Level ( In): 37
+ Bytes at NS Level (Out): 21
VCI 0x0101, NSEI 0x0100, peer 0x05060708:32000
+ Packets at NS Level ( In): 5
+ Packets at NS Level (Out): 6
+ Bytes at NS Level ( In): 21
+ Bytes at NS Level (Out): 59
NS-VC Block count : 1
Peers:
@@ -189,7 +213,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x0000, msg length 5 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:2222, msg length 9
00 00 00 00 23 04 82 20 02
-result (BVC_RESET_ACK) = 9
+result (BVC_RESET_ACK) = 0
--- Move BSS 1 to new port ---
@@ -206,7 +230,7 @@ MESSAGE to BSS at 0x01020304:3333, msg length 9
MESSAGE to BSS at 0x01020304:3333, msg length 1
0a
-result (RESET) = 9
+result (RESET) = 0
PROCESSING ALIVE from 0x01020304:3333
0a
@@ -214,17 +238,17 @@ PROCESSING ALIVE from 0x01020304:3333
MESSAGE to BSS at 0x01020304:3333, msg length 1
0b
-result (ALIVE) = 1
+result (ALIVE) = 0
PROCESSING UNBLOCK from 0x01020304:3333
06
-==> got signal NS_UNBLOCK, NS-VC 0x1001/1.2.3.4:3333
-
MESSAGE to BSS at 0x01020304:3333, msg length 1
07
-result (UNBLOCK) = 1
+==> got signal NS_UNBLOCK, NS-VC 0x1001/1.2.3.4:3333
+
+result (UNBLOCK) = 0
PROCESSING ALIVE_ACK from 0x01020304:3333
0b
@@ -233,8 +257,20 @@ result (ALIVE_ACK) = 0
Current NS-VCIs:
VCI 0x2001, NSEI 0x2000, peer 0x01020304:2222
+ Packets at NS Level ( In): 5
+ Packets at NS Level (Out): 5
+ Bytes at NS Level ( In): 37
+ Bytes at NS Level (Out): 21
VCI 0x1001, NSEI 0x1000, peer 0x01020304:3333
+ Packets at NS Level ( In): 9
+ Packets at NS Level (Out): 9
+ Bytes at NS Level ( In): 52
+ Bytes at NS Level (Out): 33
VCI 0x0101, NSEI 0x0100, peer 0x05060708:32000
+ Packets at NS Level ( In): 6
+ Packets at NS Level (Out): 6
+ Bytes at NS Level ( In): 30
+ Bytes at NS Level (Out): 59
NS-VC Block count : 1
Peers:
@@ -257,7 +293,7 @@ MESSAGE to BSS at 0x01020304:1111, msg length 9
MESSAGE to BSS at 0x01020304:1111, msg length 1
0a
-result (RESET) = 9
+result (RESET) = 0
PROCESSING ALIVE from 0x01020304:1111
0a
@@ -265,17 +301,17 @@ PROCESSING ALIVE from 0x01020304:1111
MESSAGE to BSS at 0x01020304:1111, msg length 1
0b
-result (ALIVE) = 1
+result (ALIVE) = 0
PROCESSING UNBLOCK from 0x01020304:1111
06
-==> got signal NS_UNBLOCK, NS-VC 0x2001/1.2.3.4:1111
-
MESSAGE to BSS at 0x01020304:1111, msg length 1
07
-result (UNBLOCK) = 1
+==> got signal NS_UNBLOCK, NS-VC 0x2001/1.2.3.4:1111
+
+result (UNBLOCK) = 0
PROCESSING ALIVE_ACK from 0x01020304:1111
0b
@@ -284,8 +320,20 @@ result (ALIVE_ACK) = 0
Current NS-VCIs:
VCI 0x2001, NSEI 0x2000, peer 0x01020304:1111
+ Packets at NS Level ( In): 9
+ Packets at NS Level (Out): 9
+ Bytes at NS Level ( In): 52
+ Bytes at NS Level (Out): 33
VCI 0x1001, NSEI 0x1000, peer 0x01020304:3333
+ Packets at NS Level ( In): 9
+ Packets at NS Level (Out): 9
+ Bytes at NS Level ( In): 52
+ Bytes at NS Level (Out): 33
VCI 0x0101, NSEI 0x0100, peer 0x05060708:32000
+ Packets at NS Level ( In): 6
+ Packets at NS Level (Out): 6
+ Bytes at NS Level ( In): 30
+ Bytes at NS Level (Out): 59
NS-VC Block count : 1
Peers:
@@ -308,7 +356,7 @@ MESSAGE to BSS at 0x01020304:1111, msg length 9
MESSAGE to BSS at 0x01020304:1111, msg length 1
0a
-result (RESET) = 9
+result (RESET) = 0
PROCESSING ALIVE from 0x01020304:1111
0a
@@ -316,17 +364,17 @@ PROCESSING ALIVE from 0x01020304:1111
MESSAGE to BSS at 0x01020304:1111, msg length 1
0b
-result (ALIVE) = 1
+result (ALIVE) = 0
PROCESSING UNBLOCK from 0x01020304:1111
06
-==> got signal NS_UNBLOCK, NS-VC 0x2001/1.2.3.4:1111
-
MESSAGE to BSS at 0x01020304:1111, msg length 1
07
-result (UNBLOCK) = 1
+==> got signal NS_UNBLOCK, NS-VC 0x2001/1.2.3.4:1111
+
+result (UNBLOCK) = 0
PROCESSING ALIVE_ACK from 0x01020304:1111
0b
@@ -335,8 +383,20 @@ result (ALIVE_ACK) = 0
Current NS-VCIs:
VCI 0x2001, NSEI 0x2000, peer 0x01020304:1111
+ Packets at NS Level ( In): 13
+ Packets at NS Level (Out): 13
+ Bytes at NS Level ( In): 67
+ Bytes at NS Level (Out): 45
VCI 0x1001, NSEI 0x1000, peer 0x01020304:3333
+ Packets at NS Level ( In): 9
+ Packets at NS Level (Out): 9
+ Bytes at NS Level ( In): 52
+ Bytes at NS Level (Out): 33
VCI 0x0101, NSEI 0x0100, peer 0x05060708:32000
+ Packets at NS Level ( In): 6
+ Packets at NS Level (Out): 6
+ Bytes at NS Level ( In): 30
+ Bytes at NS Level (Out): 59
NS-VC Block count : 1
Peers:
@@ -359,7 +419,7 @@ MESSAGE to BSS at 0x01020304:4444, msg length 9
MESSAGE to BSS at 0x01020304:4444, msg length 1
0a
-result (RESET) = 9
+result (RESET) = 0
PROCESSING ALIVE from 0x01020304:4444
0a
@@ -367,17 +427,17 @@ PROCESSING ALIVE from 0x01020304:4444
MESSAGE to BSS at 0x01020304:4444, msg length 1
0b
-result (ALIVE) = 1
+result (ALIVE) = 0
PROCESSING UNBLOCK from 0x01020304:4444
06
-==> got signal NS_UNBLOCK, NS-VC 0x2001/1.2.3.4:4444
-
MESSAGE to BSS at 0x01020304:4444, msg length 1
07
-result (UNBLOCK) = 1
+==> got signal NS_UNBLOCK, NS-VC 0x2001/1.2.3.4:4444
+
+result (UNBLOCK) = 0
PROCESSING ALIVE_ACK from 0x01020304:4444
0b
@@ -386,8 +446,20 @@ result (ALIVE_ACK) = 0
Current NS-VCIs:
VCI 0x2001, NSEI 0x2000, peer 0x01020304:4444
+ Packets at NS Level ( In): 17
+ Packets at NS Level (Out): 17
+ Bytes at NS Level ( In): 82
+ Bytes at NS Level (Out): 57
VCI 0x1001, NSEI 0x1000, peer 0x01020304:3333
+ Packets at NS Level ( In): 9
+ Packets at NS Level (Out): 9
+ Bytes at NS Level ( In): 52
+ Bytes at NS Level (Out): 33
VCI 0x0101, NSEI 0x0100, peer 0x05060708:32000
+ Packets at NS Level ( In): 6
+ Packets at NS Level (Out): 6
+ Bytes at NS Level ( In): 30
+ Bytes at NS Level (Out): 59
NS-VC Block count : 1
Peers:
@@ -412,7 +484,7 @@ MESSAGE to BSS at 0x01020304:3333, msg length 9
MESSAGE to BSS at 0x01020304:3333, msg length 1
0a
-result (RESET) = 9
+result (RESET) = 0
PROCESSING ALIVE from 0x01020304:3333
0a
@@ -420,17 +492,17 @@ PROCESSING ALIVE from 0x01020304:3333
MESSAGE to BSS at 0x01020304:3333, msg length 1
0b
-result (ALIVE) = 1
+result (ALIVE) = 0
PROCESSING UNBLOCK from 0x01020304:3333
06
-==> got signal NS_UNBLOCK, NS-VC 0x2001/1.2.3.4:3333
-
MESSAGE to BSS at 0x01020304:3333, msg length 1
07
-result (UNBLOCK) = 1
+==> got signal NS_UNBLOCK, NS-VC 0x2001/1.2.3.4:3333
+
+result (UNBLOCK) = 0
PROCESSING ALIVE_ACK from 0x01020304:3333
0b
@@ -439,9 +511,21 @@ result (ALIVE_ACK) = 0
Current NS-VCIs:
VCI 0x2001, NSEI 0x2000, peer 0x01020304:3333
+ Packets at NS Level ( In): 20
+ Packets at NS Level (Out): 21
+ Bytes at NS Level ( In): 85
+ Bytes at NS Level (Out): 69
NS-VC replaced other count: 1
VCI 0x1001, NSEI 0x1000, peer 0x00000000:0
+ Packets at NS Level ( In): 10
+ Packets at NS Level (Out): 9
+ Bytes at NS Level ( In): 64
+ Bytes at NS Level (Out): 33
VCI 0x0101, NSEI 0x0100, peer 0x05060708:32000
+ Packets at NS Level ( In): 6
+ Packets at NS Level (Out): 6
+ Bytes at NS Level ( In): 30
+ Bytes at NS Level (Out): 59
NS-VC Block count : 1
Peers:
@@ -464,7 +548,7 @@ MESSAGE to BSS at 0x01020304:1111, msg length 9
MESSAGE to BSS at 0x01020304:1111, msg length 1
0a
-result (RESET) = 9
+result (RESET) = 0
PROCESSING ALIVE from 0x01020304:1111
0a
@@ -472,17 +556,17 @@ PROCESSING ALIVE from 0x01020304:1111
MESSAGE to BSS at 0x01020304:1111, msg length 1
0b
-result (ALIVE) = 1
+result (ALIVE) = 0
PROCESSING UNBLOCK from 0x01020304:1111
06
-==> got signal NS_UNBLOCK, NS-VC 0x1001/1.2.3.4:1111
-
MESSAGE to BSS at 0x01020304:1111, msg length 1
07
-result (UNBLOCK) = 1
+==> got signal NS_UNBLOCK, NS-VC 0x1001/1.2.3.4:1111
+
+result (UNBLOCK) = 0
PROCESSING ALIVE_ACK from 0x01020304:1111
0b
@@ -491,9 +575,21 @@ result (ALIVE_ACK) = 0
Current NS-VCIs:
VCI 0x2001, NSEI 0x2000, peer 0x01020304:3333
+ Packets at NS Level ( In): 20
+ Packets at NS Level (Out): 21
+ Bytes at NS Level ( In): 85
+ Bytes at NS Level (Out): 69
NS-VC replaced other count: 1
VCI 0x1001, NSEI 0x1000, peer 0x01020304:1111
+ Packets at NS Level ( In): 14
+ Packets at NS Level (Out): 13
+ Bytes at NS Level ( In): 79
+ Bytes at NS Level (Out): 45
VCI 0x0101, NSEI 0x0100, peer 0x05060708:32000
+ Packets at NS Level ( In): 6
+ Packets at NS Level (Out): 6
+ Bytes at NS Level ( In): 30
+ Bytes at NS Level (Out): 59
NS-VC Block count : 1
Peers:
@@ -515,13 +611,25 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x0000, msg length 18 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 22
00 00 00 00 22 04 82 10 12 07 81 08 08 88 11 22 33 40 50 60 10 00
-result (BVC_RESET) = 22
+result (BVC_RESET) = 0
Current NS-VCIs:
VCI 0x2001, NSEI 0x2000, peer 0x01020304:3333
+ Packets at NS Level ( In): 20
+ Packets at NS Level (Out): 21
+ Bytes at NS Level ( In): 85
+ Bytes at NS Level (Out): 69
NS-VC replaced other count: 1
VCI 0x1001, NSEI 0x1000, peer 0x01020304:1111
+ Packets at NS Level ( In): 15
+ Packets at NS Level (Out): 13
+ Bytes at NS Level ( In): 101
+ Bytes at NS Level (Out): 45
VCI 0x0101, NSEI 0x0100, peer 0x05060708:32000
+ Packets at NS Level ( In): 6
+ Packets at NS Level (Out): 7
+ Bytes at NS Level ( In): 30
+ Bytes at NS Level (Out): 81
NS-VC Block count : 1
Peers:
@@ -541,7 +649,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x0000, msg length 5 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 9
00 00 00 00 23 04 82 10 12
-result (BVC_RESET_ACK) = 9
+result (BVC_RESET_ACK) = 0
--- Reset BSS 1 with the old BVCI ---
@@ -557,13 +665,25 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x0000, msg length 18 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 22
00 00 00 00 22 04 82 10 02 07 81 08 08 88 11 22 33 40 50 60 10 00
-result (BVC_RESET) = 22
+result (BVC_RESET) = 0
Current NS-VCIs:
VCI 0x2001, NSEI 0x2000, peer 0x01020304:3333
+ Packets at NS Level ( In): 20
+ Packets at NS Level (Out): 21
+ Bytes at NS Level ( In): 85
+ Bytes at NS Level (Out): 69
NS-VC replaced other count: 1
VCI 0x1001, NSEI 0x1000, peer 0x01020304:1111
+ Packets at NS Level ( In): 16
+ Packets at NS Level (Out): 14
+ Bytes at NS Level ( In): 123
+ Bytes at NS Level (Out): 54
VCI 0x0101, NSEI 0x0100, peer 0x05060708:32000
+ Packets at NS Level ( In): 7
+ Packets at NS Level (Out): 8
+ Bytes at NS Level ( In): 39
+ Bytes at NS Level (Out): 103
NS-VC Block count : 1
Peers:
@@ -583,7 +703,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x0000, msg length 5 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 9
00 00 00 00 23 04 82 10 02
-result (BVC_RESET_ACK) = 9
+result (BVC_RESET_ACK) = 0
--- Reset BSS 1 with the old BVCI again ---
@@ -599,13 +719,25 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x0000, msg length 18 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 22
00 00 00 00 22 04 82 10 02 07 81 08 08 88 11 22 33 40 50 60 10 00
-result (BVC_RESET) = 22
+result (BVC_RESET) = 0
Current NS-VCIs:
VCI 0x2001, NSEI 0x2000, peer 0x01020304:3333
+ Packets at NS Level ( In): 20
+ Packets at NS Level (Out): 21
+ Bytes at NS Level ( In): 85
+ Bytes at NS Level (Out): 69
NS-VC replaced other count: 1
VCI 0x1001, NSEI 0x1000, peer 0x01020304:1111
+ Packets at NS Level ( In): 17
+ Packets at NS Level (Out): 15
+ Bytes at NS Level ( In): 145
+ Bytes at NS Level (Out): 63
VCI 0x0101, NSEI 0x0100, peer 0x05060708:32000
+ Packets at NS Level ( In): 8
+ Packets at NS Level (Out): 9
+ Bytes at NS Level ( In): 48
+ Bytes at NS Level (Out): 125
NS-VC Block count : 1
Peers:
@@ -625,7 +757,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x0000, msg length 5 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 9
00 00 00 00 23 04 82 10 02
-result (BVC_RESET_ACK) = 9
+result (BVC_RESET_ACK) = 0
--- Send message from BSS 1 to SGSN, BVCI 0x1012 ---
@@ -639,7 +771,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x1012, msg length 0 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 4
00 00 10 12
-result (UNITDATA) = 4
+result (UNITDATA) = 0
--- Send message from SGSN to BSS 1, BVCI 0x1012 ---
@@ -653,7 +785,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x1012, msg length 0 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 4
00 00 10 12
-result (UNITDATA) = 4
+result (UNITDATA) = 0
--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---
@@ -667,7 +799,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x1012, msg length 0 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 4
00 00 10 12
-result (UNITDATA) = 4
+result (UNITDATA) = 0
--- Send message from SGSN to BSS 1, BVCI 0x1002 ---
@@ -681,7 +813,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x1012, msg length 0 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 4
00 00 10 12
-result (UNITDATA) = 4
+result (UNITDATA) = 0
--- Send message from BSS 2 to SGSN, BVCI 0x2002 ---
@@ -695,7 +827,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x2002, msg length 0 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 4
00 00 20 02
-result (UNITDATA) = 4
+result (UNITDATA) = 0
--- Send message from SGSN to BSS 2, BVCI 0x2002 ---
@@ -709,7 +841,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x2002, msg length 0 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:3333, msg length 4
00 00 20 02
-result (UNITDATA) = 4
+result (UNITDATA) = 0
--- Reset BSS 1 with the old BVCI on BSS2's link ---
@@ -725,13 +857,25 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x0000, msg length 18 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 22
00 00 00 00 22 04 82 10 02 07 81 08 08 88 11 22 33 40 50 60 10 00
-result (BVC_RESET) = 22
+result (BVC_RESET) = 0
Current NS-VCIs:
VCI 0x2001, NSEI 0x2000, peer 0x01020304:3333
+ Packets at NS Level ( In): 21
+ Packets at NS Level (Out): 22
+ Bytes at NS Level ( In): 107
+ Bytes at NS Level (Out): 73
NS-VC replaced other count: 1
VCI 0x1001, NSEI 0x1000, peer 0x01020304:1111
+ Packets at NS Level ( In): 20
+ Packets at NS Level (Out): 18
+ Bytes at NS Level ( In): 157
+ Bytes at NS Level (Out): 80
VCI 0x0101, NSEI 0x0100, peer 0x05060708:32000
+ Packets at NS Level ( In): 12
+ Packets at NS Level (Out): 13
+ Bytes at NS Level ( In): 69
+ Bytes at NS Level (Out): 159
NS-VC Block count : 1
Peers:
@@ -754,7 +898,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x0000, msg length 5 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:3333, msg length 9
00 00 00 00 23 04 82 10 02
-result (BVC_RESET_ACK) = 9
+result (BVC_RESET_ACK) = 0
--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---
@@ -768,7 +912,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x1012, msg length 0 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 4
00 00 10 12
-result (UNITDATA) = 4
+result (UNITDATA) = 0
--- Send message from SGSN to BSS 1, BVCI 0x1002 ---
@@ -782,7 +926,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x1012, msg length 0 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 4
00 00 10 12
-result (UNITDATA) = 4
+result (UNITDATA) = 0
--- Send message from SGSN to BSS 1, BVCI 0x10ff (invalid) ---
@@ -796,7 +940,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x0000, msg length 10 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 14
00 00 00 00 41 07 81 05 04 82 10 ff 15 80
-result (UNITDATA) = 14
+result (UNITDATA) = 0
Peers:
NSEI 8192, BVCI 8194, not blocked, RAI 112-332-16464-96
@@ -819,7 +963,7 @@ PROCESSING RESET_ACK from 0x05060708:32000
MESSAGE to SGSN at 0x05060708:32000, msg length 1
0a
-result (RESET_ACK) = 1
+result (RESET_ACK) = 0
PROCESSING ALIVE_ACK from 0x05060708:32000
0b
@@ -827,7 +971,7 @@ PROCESSING ALIVE_ACK from 0x05060708:32000
MESSAGE to SGSN at 0x05060708:32000, msg length 1
06
-result (ALIVE_ACK) = 1
+result (ALIVE_ACK) = 0
PROCESSING UNBLOCK_ACK from 0x05060708:32000
07
@@ -842,10 +986,14 @@ PROCESSING ALIVE from 0x05060708:32000
MESSAGE to SGSN at 0x05060708:32000, msg length 1
0b
-result (ALIVE) = 1
+result (ALIVE) = 0
Current NS-VCIs:
VCI 0x0101, NSEI 0x0100, peer 0x05060708:32000
+ Packets at NS Level ( In): 4
+ Packets at NS Level (Out): 4
+ Bytes at NS Level ( In): 12
+ Bytes at NS Level (Out): 15
NS-VC Block count : 1
--- Initialise BSS 1 ---
@@ -863,7 +1011,7 @@ MESSAGE to BSS at 0x01020304:1111, msg length 9
MESSAGE to BSS at 0x01020304:1111, msg length 1
0a
-result (RESET) = 9
+result (RESET) = 0
PROCESSING ALIVE from 0x01020304:1111
0a
@@ -871,17 +1019,17 @@ PROCESSING ALIVE from 0x01020304:1111
MESSAGE to BSS at 0x01020304:1111, msg length 1
0b
-result (ALIVE) = 1
+result (ALIVE) = 0
PROCESSING UNBLOCK from 0x01020304:1111
06
-==> got signal NS_UNBLOCK, NS-VC 0x1001/1.2.3.4:1111
-
MESSAGE to BSS at 0x01020304:1111, msg length 1
07
-result (UNBLOCK) = 1
+==> got signal NS_UNBLOCK, NS-VC 0x1001/1.2.3.4:1111
+
+result (UNBLOCK) = 0
PROCESSING ALIVE_ACK from 0x01020304:1111
0b
@@ -890,7 +1038,15 @@ result (ALIVE_ACK) = 0
Current NS-VCIs:
VCI 0x1001, NSEI 0x1000, peer 0x01020304:1111
+ Packets at NS Level ( In): 4
+ Packets at NS Level (Out): 4
+ Bytes at NS Level ( In): 15
+ Bytes at NS Level (Out): 12
VCI 0x0101, NSEI 0x0100, peer 0x05060708:32000
+ Packets at NS Level ( In): 4
+ Packets at NS Level (Out): 4
+ Bytes at NS Level ( In): 12
+ Bytes at NS Level (Out): 15
NS-VC Block count : 1
--- Setup BVCI 1 ---
@@ -907,7 +1063,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x0000, msg length 18 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 22
00 00 00 00 22 04 82 10 02 07 81 08 08 88 11 22 33 40 50 60 10 00
-result (BVC_RESET) = 22
+result (BVC_RESET) = 0
PROCESSING BVC_RESET_ACK from 0x05060708:32000
00 00 00 00 23 04 82 10 02
@@ -919,7 +1075,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x0000, msg length 5 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 9
00 00 00 00 23 04 82 10 02
-result (BVC_RESET_ACK) = 9
+result (BVC_RESET_ACK) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -938,7 +1094,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x0000, msg length 18 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 22
00 00 00 00 22 04 82 20 02 07 81 08 08 88 11 22 33 40 50 60 10 00
-result (BVC_RESET) = 22
+result (BVC_RESET) = 0
PROCESSING BVC_RESET_ACK from 0x05060708:32000
00 00 00 00 23 04 82 20 02
@@ -950,7 +1106,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x0000, msg length 5 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 9
00 00 00 00 23 04 82 20 02
-result (BVC_RESET_ACK) = 9
+result (BVC_RESET_ACK) = 0
Peers:
NSEI 4096, BVCI 8194, not blocked, RAI 112-332-16464-96
@@ -969,7 +1125,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 0 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 4
00 00 10 02
-result (UNITDATA) = 4
+result (UNITDATA) = 0
PROCESSING UNITDATA from 0x05060708:32000
00 00 10 02
@@ -981,7 +1137,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 0 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 4
00 00 10 02
-result (UNITDATA) = 4
+result (UNITDATA) = 0
--- Send message from BSS 1 to SGSN and back, BVCI 2 ---
@@ -995,7 +1151,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x2002, msg length 0 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 4
00 00 20 02
-result (UNITDATA) = 4
+result (UNITDATA) = 0
PROCESSING UNITDATA from 0x05060708:32000
00 00 20 02
@@ -1007,7 +1163,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x2002, msg length 0 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 4
00 00 20 02
-result (UNITDATA) = 4
+result (UNITDATA) = 0
--- Change NSEI ---
@@ -1024,7 +1180,7 @@ MESSAGE to BSS at 0x01020304:1111, msg length 9
MESSAGE to BSS at 0x01020304:1111, msg length 1
0a
-result (RESET) = 9
+result (RESET) = 0
PROCESSING ALIVE from 0x01020304:1111
0a
@@ -1032,17 +1188,17 @@ PROCESSING ALIVE from 0x01020304:1111
MESSAGE to BSS at 0x01020304:1111, msg length 1
0b
-result (ALIVE) = 1
+result (ALIVE) = 0
PROCESSING UNBLOCK from 0x01020304:1111
06
-==> got signal NS_UNBLOCK, NS-VC 0x1001/1.2.3.4:1111
-
MESSAGE to BSS at 0x01020304:1111, msg length 1
07
-result (UNBLOCK) = 1
+==> got signal NS_UNBLOCK, NS-VC 0x1001/1.2.3.4:1111
+
+result (UNBLOCK) = 0
PROCESSING ALIVE_ACK from 0x01020304:1111
0b
@@ -1051,8 +1207,16 @@ result (ALIVE_ACK) = 0
Current NS-VCIs:
VCI 0x1001, NSEI 0x2000, peer 0x01020304:1111
+ Packets at NS Level ( In): 12
+ Packets at NS Level (Out): 12
+ Bytes at NS Level ( In): 82
+ Bytes at NS Level (Out): 50
NS-VC changed NSEI count : 1
VCI 0x0101, NSEI 0x0100, peer 0x05060708:32000
+ Packets at NS Level ( In): 8
+ Packets at NS Level (Out): 8
+ Bytes at NS Level ( In): 38
+ Bytes at NS Level (Out): 67
NS-VC Block count : 1
--- Setup BVCI 1 ---
@@ -1069,7 +1233,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x0000, msg length 18 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 22
00 00 00 00 22 04 82 10 02 07 81 08 08 88 11 22 33 40 50 60 10 00
-result (BVC_RESET) = 22
+result (BVC_RESET) = 0
PROCESSING BVC_RESET_ACK from 0x05060708:32000
00 00 00 00 23 04 82 10 02
@@ -1081,7 +1245,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x0000, msg length 5 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 9
00 00 00 00 23 04 82 10 02
-result (BVC_RESET_ACK) = 9
+result (BVC_RESET_ACK) = 0
Peers:
NSEI 4096, BVCI 8194, not blocked, RAI 112-332-16464-96
@@ -1103,7 +1267,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x0000, msg length 18 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 22
00 00 00 00 22 04 82 30 02 07 81 08 08 88 11 22 33 40 50 60 10 00
-result (BVC_RESET) = 22
+result (BVC_RESET) = 0
PROCESSING BVC_RESET_ACK from 0x05060708:32000
00 00 00 00 23 04 82 30 02
@@ -1115,7 +1279,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x0000, msg length 5 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 9
00 00 00 00 23 04 82 30 02
-result (BVC_RESET_ACK) = 9
+result (BVC_RESET_ACK) = 0
Peers:
NSEI 8192, BVCI 12290, not blocked, RAI 112-332-16464-96
@@ -1137,7 +1301,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 0 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 4
00 00 10 02
-result (UNITDATA) = 4
+result (UNITDATA) = 0
PROCESSING UNITDATA from 0x05060708:32000
00 00 10 02
@@ -1149,7 +1313,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 0 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 4
00 00 10 02
-result (UNITDATA) = 4
+result (UNITDATA) = 0
--- Send message from BSS 1 to SGSN and back, BVCI 2 (should fail) ---
@@ -1163,7 +1327,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x2002, msg length 0 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 4
00 00 20 02
-result (UNITDATA) = 4
+result (UNITDATA) = 0
Peers:
NSEI 8192, BVCI 12290, not blocked, RAI 112-332-16464-96
@@ -1205,7 +1369,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x3002, msg length 0 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 4
00 00 30 02
-result (UNITDATA) = 4
+result (UNITDATA) = 0
PROCESSING UNITDATA from 0x05060708:32000
00 00 30 02
@@ -1217,7 +1381,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x3002, msg length 0 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 4
00 00 30 02
-result (UNITDATA) = 4
+result (UNITDATA) = 0
--- Change NSVCI ---
@@ -1236,7 +1400,7 @@ MESSAGE to BSS at 0x01020304:1111, msg length 9
MESSAGE to BSS at 0x01020304:1111, msg length 1
0a
-result (RESET) = 9
+result (RESET) = 0
PROCESSING ALIVE from 0x01020304:1111
0a
@@ -1244,17 +1408,17 @@ PROCESSING ALIVE from 0x01020304:1111
MESSAGE to BSS at 0x01020304:1111, msg length 1
0b
-result (ALIVE) = 1
+result (ALIVE) = 0
PROCESSING UNBLOCK from 0x01020304:1111
06
-==> got signal NS_UNBLOCK, NS-VC 0x2001/1.2.3.4:1111
-
MESSAGE to BSS at 0x01020304:1111, msg length 1
07
-result (UNBLOCK) = 1
+==> got signal NS_UNBLOCK, NS-VC 0x2001/1.2.3.4:1111
+
+result (UNBLOCK) = 0
PROCESSING ALIVE_ACK from 0x01020304:1111
0b
@@ -1263,10 +1427,22 @@ result (ALIVE_ACK) = 0
Current NS-VCIs:
VCI 0x2001, NSEI 0x2000, peer 0x01020304:1111
+ Packets at NS Level ( In): 3
+ Packets at NS Level (Out): 4
+ Bytes at NS Level ( In): 3
+ Bytes at NS Level (Out): 12
NS-VC replaced other count: 1
VCI 0x1001, NSEI 0x2000, peer 0x00000000:0
+ Packets at NS Level ( In): 18
+ Packets at NS Level (Out): 16
+ Bytes at NS Level ( In): 150
+ Bytes at NS Level (Out): 76
NS-VC changed NSEI count : 1
VCI 0x0101, NSEI 0x0100, peer 0x05060708:32000
+ Packets at NS Level ( In): 13
+ Packets at NS Level (Out): 13
+ Bytes at NS Level ( In): 68
+ Bytes at NS Level (Out): 123
NS-VC Block count : 1
--- Setup BVCI 1 ---
@@ -1283,7 +1459,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x0000, msg length 18 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 22
00 00 00 00 22 04 82 10 02 07 81 08 08 88 11 22 33 40 50 60 10 00
-result (BVC_RESET) = 22
+result (BVC_RESET) = 0
PROCESSING BVC_RESET_ACK from 0x05060708:32000
00 00 00 00 23 04 82 10 02
@@ -1295,7 +1471,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x0000, msg length 5 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 9
00 00 00 00 23 04 82 10 02
-result (BVC_RESET_ACK) = 9
+result (BVC_RESET_ACK) = 0
Peers:
NSEI 8192, BVCI 12290, not blocked, RAI 112-332-16464-96
@@ -1321,7 +1497,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x0000, msg length 18 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 22
00 00 00 00 22 04 82 40 02 07 81 08 08 88 11 22 33 40 50 60 10 00
-result (BVC_RESET) = 22
+result (BVC_RESET) = 0
PROCESSING BVC_RESET_ACK from 0x05060708:32000
00 00 00 00 23 04 82 40 02
@@ -1333,7 +1509,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x0000, msg length 5 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 9
00 00 00 00 23 04 82 40 02
-result (BVC_RESET_ACK) = 9
+result (BVC_RESET_ACK) = 0
Peers:
NSEI 8192, BVCI 16386, not blocked, RAI 112-332-16464-96
@@ -1359,7 +1535,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 0 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 4
00 00 10 02
-result (UNITDATA) = 4
+result (UNITDATA) = 0
PROCESSING UNITDATA from 0x05060708:32000
00 00 10 02
@@ -1371,7 +1547,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 0 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 4
00 00 10 02
-result (UNITDATA) = 4
+result (UNITDATA) = 0
--- Send message from BSS 1 to SGSN and back, BVCI 2 (should fail) ---
@@ -1385,7 +1561,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x2002, msg length 0 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 4
00 00 20 02
-result (UNITDATA) = 4
+result (UNITDATA) = 0
Peers:
NSEI 8192, BVCI 16386, not blocked, RAI 112-332-16464-96
@@ -1432,7 +1608,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x3002, msg length 0 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 4
00 00 30 02
-result (UNITDATA) = 4
+result (UNITDATA) = 0
PROCESSING UNITDATA from 0x05060708:32000
00 00 30 02
@@ -1444,7 +1620,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x3002, msg length 0 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 4
00 00 30 02
-result (UNITDATA) = 4
+result (UNITDATA) = 0
--- Send message from BSS 1 to SGSN and back, BVCI 4 ---
@@ -1458,7 +1634,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x4002, msg length 0 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 4
00 00 40 02
-result (UNITDATA) = 4
+result (UNITDATA) = 0
PROCESSING UNITDATA from 0x05060708:32000
00 00 40 02
@@ -1470,7 +1646,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x4002, msg length 0 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 4
00 00 40 02
-result (UNITDATA) = 4
+result (UNITDATA) = 0
Gbproxy global:
Peers:
@@ -1499,7 +1675,7 @@ PROCESSING RESET_ACK from 0x05060708:32000
MESSAGE to SGSN at 0x05060708:32000, msg length 1
0a
-result (RESET_ACK) = 1
+result (RESET_ACK) = 0
PROCESSING ALIVE_ACK from 0x05060708:32000
0b
@@ -1507,7 +1683,7 @@ PROCESSING ALIVE_ACK from 0x05060708:32000
MESSAGE to SGSN at 0x05060708:32000, msg length 1
06
-result (ALIVE_ACK) = 1
+result (ALIVE_ACK) = 0
PROCESSING UNBLOCK_ACK from 0x05060708:32000
07
@@ -1522,7 +1698,7 @@ PROCESSING ALIVE from 0x05060708:32000
MESSAGE to SGSN at 0x05060708:32000, msg length 1
0b
-result (ALIVE) = 1
+result (ALIVE) = 0
--- Initialise BSS 1 ---
@@ -1539,7 +1715,7 @@ MESSAGE to BSS at 0x01020304:1111, msg length 9
MESSAGE to BSS at 0x01020304:1111, msg length 1
0a
-result (RESET) = 9
+result (RESET) = 0
PROCESSING ALIVE from 0x01020304:1111
0a
@@ -1547,17 +1723,17 @@ PROCESSING ALIVE from 0x01020304:1111
MESSAGE to BSS at 0x01020304:1111, msg length 1
0b
-result (ALIVE) = 1
+result (ALIVE) = 0
PROCESSING UNBLOCK from 0x01020304:1111
06
-==> got signal NS_UNBLOCK, NS-VC 0x1001/1.2.3.4:1111
-
MESSAGE to BSS at 0x01020304:1111, msg length 1
07
-result (UNBLOCK) = 1
+==> got signal NS_UNBLOCK, NS-VC 0x1001/1.2.3.4:1111
+
+result (UNBLOCK) = 0
PROCESSING ALIVE_ACK from 0x01020304:1111
0b
@@ -1576,7 +1752,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x0000, msg length 18 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 22
00 00 00 00 22 04 82 10 02 07 81 08 08 88 11 22 33 40 50 60 10 00
-result (BVC_RESET) = 22
+result (BVC_RESET) = 0
PROCESSING BVC_RESET_ACK from 0x05060708:32000
00 00 00 00 23 04 82 10 02
@@ -1588,11 +1764,19 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x0000, msg length 5 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 9
00 00 00 00 23 04 82 10 02
-result (BVC_RESET_ACK) = 9
+result (BVC_RESET_ACK) = 0
Current NS-VCIs:
VCI 0x1001, NSEI 0x1000, peer 0x01020304:1111
+ Packets at NS Level ( In): 5
+ Packets at NS Level (Out): 5
+ Bytes at NS Level ( In): 37
+ Bytes at NS Level (Out): 21
VCI 0x0101, NSEI 0x0100, peer 0x05060708:32000
+ Packets at NS Level ( In): 5
+ Packets at NS Level (Out): 5
+ Bytes at NS Level ( In): 21
+ Bytes at NS Level (Out): 37
NS-VC Block count : 1
Gbproxy global:
@@ -1611,7 +1795,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 75 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 79
00 00 10 02 01 80 00 de ad 00 00 04 08 88 00 f1 99 00 63 60 12 34 00 80 0e 00 34 01 c0 01 08 01 02 f5 e0 21 08 02 05 f4 fb c5 46 79 11 22 33 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 16 6d 01
-result (ATTACH REQUEST) = 79
+result (ATTACH REQUEST) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -1629,7 +1813,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 23 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 27
00 00 10 02 00 80 00 de ad 00 50 20 16 82 02 58 0e 89 41 c0 01 08 15 01 ff 6c ba
-result (IDENT REQUEST) = 27
+result (IDENT REQUEST) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -1647,7 +1831,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 40 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 44
00 00 10 02 01 80 00 de ad 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 11 01 c0 05 08 16 08 11 12 13 14 15 16 17 18 ad 05 28
-result (IDENT RESPONSE) = 44
+result (IDENT RESPONSE) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -1665,7 +1849,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 88 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 92
00 00 10 02 00 80 00 de ad 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 9e 41 c0 05 08 02 01 49 04 21 63 54 40 50 60 19 cd d7 08 17 16 18 05 f4 ef e2 b7 00 53 62 f1
-result (ATTACH ACCEPT) = 92
+result (ATTACH ACCEPT) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -1684,7 +1868,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 31 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 35
00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 09 08 03 39 d7 bc
-result (ATTACH COMPLETE) = 35
+result (ATTACH COMPLETE) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -1704,7 +1888,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 66 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 70
00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 88 41 c0 09 08 21 04 ba 3d
-result (GMM INFO) = 70
+result (GMM INFO) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -1726,7 +1910,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 75 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 79
00 00 10 02 01 80 00 be ef 00 00 04 08 88 00 f1 99 00 63 60 12 34 00 80 0e 00 34 01 c0 0d 08 01 02 f5 e0 21 08 02 05 f4 fb c5 46 79 11 22 33 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 46 42 6e
-result (ATTACH REQUEST) = 79
+result (ATTACH REQUEST) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -1747,7 +1931,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 23 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 27
00 00 10 02 00 80 00 be ef 00 50 20 16 82 02 58 0e 89 41 c0 0d 08 15 01 0c a6 18
-result (IDENT REQUEST) = 27
+result (IDENT REQUEST) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -1768,7 +1952,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 40 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 44
00 00 10 02 01 80 00 be ef 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 11 01 c0 11 08 16 08 11 12 99 99 99 16 17 18 bf d2 01
-result (IDENT RESPONSE) = 44
+result (IDENT RESPONSE) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -1789,7 +1973,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 88 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 92
00 00 10 02 00 80 00 be ef 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 99 99 99 16 17 18 00 81 00 0e 9e 41 c0 11 08 02 01 49 04 21 63 54 40 50 60 19 cd d7 08 17 16 18 05 f4 ef e2 b7 00 3a 6d d4
-result (ATTACH ACCEPT) = 92
+result (ATTACH ACCEPT) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -1809,7 +1993,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 31 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 35
00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 15 08 03 86 ac 47
-result (ATTACH COMPLETE) = 35
+result (ATTACH COMPLETE) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -1829,7 +2013,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 66 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 70
00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 99 99 99 16 17 18 00 81 00 0e 88 41 c0 15 08 21 bb c1 c6
-result (GMM INFO) = 70
+result (GMM INFO) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -1852,7 +2036,7 @@ PROCESSING RESET_ACK from 0x05060708:32000
MESSAGE to SGSN at 0x05060708:32000, msg length 1
0a
-result (RESET_ACK) = 1
+result (RESET_ACK) = 0
PROCESSING ALIVE_ACK from 0x05060708:32000
0b
@@ -1860,7 +2044,7 @@ PROCESSING ALIVE_ACK from 0x05060708:32000
MESSAGE to SGSN at 0x05060708:32000, msg length 1
06
-result (ALIVE_ACK) = 1
+result (ALIVE_ACK) = 0
PROCESSING UNBLOCK_ACK from 0x05060708:32000
07
@@ -1875,10 +2059,14 @@ PROCESSING ALIVE from 0x05060708:32000
MESSAGE to SGSN at 0x05060708:32000, msg length 1
0b
-result (ALIVE) = 1
+result (ALIVE) = 0
Current NS-VCIs:
VCI 0x0101, NSEI 0x0100, peer 0x05060708:32000
+ Packets at NS Level ( In): 4
+ Packets at NS Level (Out): 4
+ Bytes at NS Level ( In): 12
+ Bytes at NS Level (Out): 15
NS-VC Block count : 1
--- Initialise BSS 1 ---
@@ -1896,7 +2084,7 @@ MESSAGE to BSS at 0x01020304:1111, msg length 9
MESSAGE to BSS at 0x01020304:1111, msg length 1
0a
-result (RESET) = 9
+result (RESET) = 0
PROCESSING ALIVE from 0x01020304:1111
0a
@@ -1904,17 +2092,17 @@ PROCESSING ALIVE from 0x01020304:1111
MESSAGE to BSS at 0x01020304:1111, msg length 1
0b
-result (ALIVE) = 1
+result (ALIVE) = 0
PROCESSING UNBLOCK from 0x01020304:1111
06
-==> got signal NS_UNBLOCK, NS-VC 0x1001/1.2.3.4:1111
-
MESSAGE to BSS at 0x01020304:1111, msg length 1
07
-result (UNBLOCK) = 1
+==> got signal NS_UNBLOCK, NS-VC 0x1001/1.2.3.4:1111
+
+result (UNBLOCK) = 0
PROCESSING ALIVE_ACK from 0x01020304:1111
0b
@@ -1933,11 +2121,19 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x0000, msg length 18 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 22
00 00 00 00 22 04 82 10 02 07 81 08 08 88 21 63 54 40 50 60 10 00
-result (BVC_RESET) = 22
+result (BVC_RESET) = 0
Current NS-VCIs:
VCI 0x1001, NSEI 0x1000, peer 0x01020304:1111
+ Packets at NS Level ( In): 5
+ Packets at NS Level (Out): 4
+ Bytes at NS Level ( In): 37
+ Bytes at NS Level (Out): 12
VCI 0x0101, NSEI 0x0100, peer 0x05060708:32000
+ Packets at NS Level ( In): 4
+ Packets at NS Level (Out): 5
+ Bytes at NS Level ( In): 12
+ Bytes at NS Level (Out): 37
NS-VC Block count : 1
Peers:
@@ -1954,7 +2150,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x0000, msg length 5 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 9
00 00 00 00 23 04 82 10 02
-result (BVC_RESET_ACK) = 9
+result (BVC_RESET_ACK) = 0
PROCESSING BVC_SUSPEND from 0x01020304:1111
00 00 00 00 0b 1f 84 cc d1 75 8b 1b 86 11 22 33 40 50 60
@@ -1966,7 +2162,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x0000, msg length 15 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 19
00 00 00 00 0b 1f 84 cc d1 75 8b 1b 86 21 63 54 40 50 60
-result (BVC_SUSPEND) = 19
+result (BVC_SUSPEND) = 0
PROCESSING BVC_SUSPEND_ACK from 0x05060708:32000
00 00 00 00 0c 1f 84 cc d1 75 8b 1b 86 21 63 54 40 50 60 1d 81 01
@@ -1978,7 +2174,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x0000, msg length 18 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 22
00 00 00 00 0c 1f 84 cc d1 75 8b 1b 86 11 22 33 40 50 60 1d 81 01
-result (BVC_SUSPEND_ACK) = 22
+result (BVC_SUSPEND_ACK) = 0
Gbproxy global:
Peers:
@@ -1999,7 +2195,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 75 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 79
00 00 10 02 01 bb c5 46 79 00 00 04 08 88 21 63 54 40 50 60 75 30 00 80 0e 00 34 01 c0 01 08 01 02 f5 e0 21 08 02 05 f4 fb c5 46 79 21 63 54 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 8e cd 32
-result (ATTACH REQUEST) = 79
+result (ATTACH REQUEST) = 0
PROCESSING IDENT REQUEST from 0x05060708:32000
00 00 10 02 00 bb c5 46 79 00 50 20 16 82 02 58 0e 89 41 c0 01 08 15 01 ff 6c ba
@@ -2011,7 +2207,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 23 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 27
00 00 10 02 00 bb c5 46 79 00 50 20 16 82 02 58 0e 89 41 c0 01 08 15 01 ff 6c ba
-result (IDENT REQUEST) = 27
+result (IDENT REQUEST) = 0
PROCESSING IDENT RESPONSE from 0x01020304:1111
00 00 10 02 01 bb c5 46 79 00 00 04 08 88 11 22 33 40 50 60 75 30 00 80 0e 00 11 01 c0 0d 08 16 08 11 12 13 14 15 16 17 18 b7 1b 9a
@@ -2023,7 +2219,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 40 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 44
00 00 10 02 01 bb c5 46 79 00 00 04 08 88 21 63 54 40 50 60 75 30 00 80 0e 00 11 01 c0 0d 08 16 08 11 12 13 14 15 16 17 18 b7 1b 9a
-result (IDENT RESPONSE) = 44
+result (IDENT RESPONSE) = 0
PROCESSING ATTACH ACCEPT from 0x05060708:32000
00 00 10 02 00 bb c5 46 79 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 9e 41 c0 05 08 02 01 49 04 21 63 54 40 50 60 19 cd d7 08 17 16 18 05 f4 ef e2 b7 00 53 62 f1
@@ -2035,7 +2231,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 88 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 92
00 00 10 02 00 bb c5 46 79 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 9e 41 c0 05 08 02 01 49 04 11 22 33 40 50 60 19 cd d7 08 17 16 18 05 f4 ef e2 b7 00 be 38 c0
-result (ATTACH ACCEPT) = 92
+result (ATTACH ACCEPT) = 0
PROCESSING ATTACH COMPLETE from 0x01020304:1111
00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 75 30 00 80 0e 00 08 01 c0 11 08 03 ea 67 11
@@ -2047,7 +2243,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 31 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 35
00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 21 63 54 40 50 60 75 30 00 80 0e 00 08 01 c0 11 08 03 ea 67 11
-result (ATTACH COMPLETE) = 35
+result (ATTACH COMPLETE) = 0
PROCESSING ACT PDP CTX REQ (REPLACE APN) from 0x01020304:1111
00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 75 30 00 80 0e 00 35 01 c0 0d 0a 41 05 03 0c 00 00 1f 10 00 00 00 00 00 00 00 00 02 01 21 28 03 02 61 62 27 14 80 80 21 10 01 00 00 10 81 06 00 00 00 00 83 06 00 00 00 00 5a ff 02
@@ -2059,7 +2255,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 81 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 85
00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 21 63 54 40 50 60 75 30 00 80 0e 00 3a 01 c0 0d 0a 41 05 03 0c 00 00 1f 10 00 00 00 00 00 00 00 00 02 01 21 28 08 03 66 6f 6f 03 62 61 72 27 14 80 80 21 10 01 00 00 10 81 06 00 00 00 00 83 06 00 00 00 00 24 9d 75
-result (ACT PDP CTX REQ (REPLACE APN)) = 85
+result (ACT PDP CTX REQ (REPLACE APN)) = 0
PROCESSING GMM INFO from 0x05060708:32000
00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 88 41 c0 09 08 21 04 ba 3d
@@ -2071,7 +2267,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 66 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 70
00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 88 41 c0 09 08 21 04 ba 3d
-result (GMM INFO) = 70
+result (GMM INFO) = 0
PROCESSING ACT PDP CTX REQ (REPLACE APN) from 0x01020304:1111
00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 75 30 00 80 0e 00 35 01 c0 0d 0a 41 05 03 0c 00 00 1f 10 00 00 00 00 00 00 00 00 02 01 21 28 03 02 61 62 27 14 80 80 21 10 01 00 00 10 81 06 00 00 00 00 83 06 00 00 00 00 5a ff 02
@@ -2083,7 +2279,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 81 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 85
00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 21 63 54 40 50 60 75 30 00 80 0e 00 3a 01 c0 0d 0a 41 05 03 0c 00 00 1f 10 00 00 00 00 00 00 00 00 02 01 21 28 08 03 66 6f 6f 03 62 61 72 27 14 80 80 21 10 01 00 00 10 81 06 00 00 00 00 83 06 00 00 00 00 24 9d 75
-result (ACT PDP CTX REQ (REPLACE APN)) = 85
+result (ACT PDP CTX REQ (REPLACE APN)) = 0
PROCESSING ACT PDP CTX REQ (REMOVE APN) from 0x01020304:1111
00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 75 30 00 80 0e 00 35 01 c0 0d 0a 41 05 03 0c 00 00 1f 10 00 00 00 00 00 00 00 00 02 01 21 28 03 02 61 62 27 14 80 80 21 10 01 00 00 10 81 06 00 00 00 00 83 06 00 00 00 00 5a ff 02
@@ -2095,7 +2291,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 71 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 75
00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 21 63 54 40 50 60 75 30 00 80 0e 00 30 01 c0 0d 0a 41 05 03 0c 00 00 1f 10 00 00 00 00 00 00 00 00 02 01 21 27 14 80 80 21 10 01 00 00 10 81 06 00 00 00 00 83 06 00 00 00 00 85 fa 60
-result (ACT PDP CTX REQ (REMOVE APN)) = 75
+result (ACT PDP CTX REQ (REMOVE APN)) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -2120,7 +2316,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 44 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 48
00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 21 63 54 40 50 60 75 30 00 80 0e 00 15 01 c0 19 08 05 01 18 05 f4 ef e2 b7 00 19 03 b9 97 cb 7e e1 41
-result (DETACH REQ) = 48
+result (DETACH REQ) = 0
PROCESSING DETACH ACC from 0x05060708:32000
00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 89 41 c0 15 08 06 00 f7 35 f0
@@ -2132,7 +2328,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 67 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 71
00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 89 41 c0 15 08 06 00 f7 35 f0
-result (DETACH ACC) = 71
+result (DETACH ACC) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -2159,7 +2355,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 85 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 89
00 00 10 02 01 bb c5 46 79 00 00 04 08 88 21 63 54 40 50 60 70 80 00 80 0e 00 3e 01 c0 15 08 08 10 21 63 54 40 50 60 1d 19 13 42 33 57 2b f7 c8 48 02 13 48 50 c8 48 02 14 48 50 c8 48 02 17 49 10 c8 48 02 00 19 8b b2 92 17 16 27 07 04 31 02 e5 e0 32 02 20 00 1d f0 41
-result (RA UPD REQ) = 89
+result (RA UPD REQ) = 0
PROCESSING RA UPD ACC from 0x05060708:32000
00 00 10 02 00 bb c5 46 79 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 9d 41 c0 19 08 09 00 49 21 63 54 40 50 60 19 54 ab b3 18 05 f4 ef e2 b7 00 17 16 d7 59 65
@@ -2171,7 +2367,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 87 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 91
00 00 10 02 00 bb c5 46 79 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 9d 41 c0 19 08 09 00 49 11 22 33 40 50 60 19 54 ab b3 18 05 f4 ef e2 b7 00 17 16 3a 03 54
-result (RA UPD ACC) = 91
+result (RA UPD ACC) = 0
PROCESSING ACT PDP CTX REQ (REMOVE APN) from 0x01020304:1111
00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 75 30 00 80 0e 00 35 01 c0 0d 0a 41 05 03 0c 00 00 1f 10 00 00 00 00 00 00 00 00 02 01 21 28 03 02 61 62 27 14 80 80 21 10 01 00 00 10 81 06 00 00 00 00 83 06 00 00 00 00 5a ff 02
@@ -2183,7 +2379,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 71 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 75
00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 21 63 54 40 50 60 75 30 00 80 0e 00 30 01 c0 0d 0a 41 05 03 0c 00 00 1f 10 00 00 00 00 00 00 00 00 02 01 21 27 14 80 80 21 10 01 00 00 10 81 06 00 00 00 00 83 06 00 00 00 00 85 fa 60
-result (ACT PDP CTX REQ (REMOVE APN)) = 75
+result (ACT PDP CTX REQ (REMOVE APN)) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -2212,7 +2408,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 44 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 48
00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 21 63 54 40 50 60 75 30 00 80 0e 00 15 01 c0 19 08 05 09 18 05 f4 ef e2 b7 00 19 03 b9 97 cb 84 0c eb
-result (DETACH REQ (PWR OFF)) = 48
+result (DETACH REQ (PWR OFF)) = 0
Gbproxy global:
Peers:
@@ -2242,7 +2438,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 75 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 79
00 00 10 02 01 bb 00 be ef 00 00 04 08 88 21 63 54 40 50 60 75 30 00 80 0e 00 34 01 c0 01 08 01 02 f5 e0 21 08 02 05 f4 fb 00 be ef 99 99 99 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 2d c7 df
-result (ATTACH REQUEST (foreign RAI)) = 79
+result (ATTACH REQUEST (foreign RAI)) = 0
TLLI is already detached, shouldn't patch
PROCESSING ACT PDP CTX REQ from 0x01020304:1111
@@ -2255,7 +2451,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 76 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 80
00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 21 63 54 40 50 60 75 30 00 80 0e 00 35 01 c0 0d 0a 41 05 03 0c 00 00 1f 10 00 00 00 00 00 00 00 00 02 01 21 28 03 02 61 62 27 14 80 80 21 10 01 00 00 10 81 06 00 00 00 00 83 06 00 00 00 00 5a ff 02
-result (ACT PDP CTX REQ) = 80
+result (ACT PDP CTX REQ) = 0
Invalid RAI, shouldn't patch
PROCESSING BVC_SUSPEND_ACK from 0x05060708:32000
@@ -2268,7 +2464,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x0000, msg length 24 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 28
00 00 00 00 41 07 81 21 15 92 0c 1f 84 cc d1 75 8b 1b 86 00 f1 99 00 63 60 1d 81 01
-result (BVC_SUSPEND_ACK) = 28
+result (BVC_SUSPEND_ACK) = 0
Gbproxy global:
Invalid Routing Area Identifier : 1
@@ -2303,7 +2499,7 @@ PROCESSING RESET_ACK from 0x05060708:32000
MESSAGE to SGSN at 0x05060708:32000, msg length 1
0a
-result (RESET_ACK) = 1
+result (RESET_ACK) = 0
PROCESSING ALIVE_ACK from 0x05060708:32000
0b
@@ -2311,7 +2507,7 @@ PROCESSING ALIVE_ACK from 0x05060708:32000
MESSAGE to SGSN at 0x05060708:32000, msg length 1
06
-result (ALIVE_ACK) = 1
+result (ALIVE_ACK) = 0
PROCESSING UNBLOCK_ACK from 0x05060708:32000
07
@@ -2326,7 +2522,7 @@ PROCESSING ALIVE from 0x05060708:32000
MESSAGE to SGSN at 0x05060708:32000, msg length 1
0b
-result (ALIVE) = 1
+result (ALIVE) = 0
--- Initialise BSS 1 ---
@@ -2343,7 +2539,7 @@ MESSAGE to BSS at 0x01020304:1111, msg length 9
MESSAGE to BSS at 0x01020304:1111, msg length 1
0a
-result (RESET) = 9
+result (RESET) = 0
PROCESSING ALIVE from 0x01020304:1111
0a
@@ -2351,17 +2547,17 @@ PROCESSING ALIVE from 0x01020304:1111
MESSAGE to BSS at 0x01020304:1111, msg length 1
0b
-result (ALIVE) = 1
+result (ALIVE) = 0
PROCESSING UNBLOCK from 0x01020304:1111
06
-==> got signal NS_UNBLOCK, NS-VC 0x1001/1.2.3.4:1111
-
MESSAGE to BSS at 0x01020304:1111, msg length 1
07
-result (UNBLOCK) = 1
+==> got signal NS_UNBLOCK, NS-VC 0x1001/1.2.3.4:1111
+
+result (UNBLOCK) = 0
PROCESSING ALIVE_ACK from 0x01020304:1111
0b
@@ -2380,7 +2576,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x0000, msg length 18 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 22
00 00 00 00 22 04 82 10 02 07 81 08 08 88 21 63 54 40 50 60 10 00
-result (BVC_RESET) = 22
+result (BVC_RESET) = 0
PROCESSING BVC_RESET_ACK from 0x05060708:32000
00 00 00 00 23 04 82 10 02
@@ -2392,11 +2588,19 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x0000, msg length 5 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 9
00 00 00 00 23 04 82 10 02
-result (BVC_RESET_ACK) = 9
+result (BVC_RESET_ACK) = 0
Current NS-VCIs:
VCI 0x1001, NSEI 0x1000, peer 0x01020304:1111
+ Packets at NS Level ( In): 5
+ Packets at NS Level (Out): 5
+ Bytes at NS Level ( In): 37
+ Bytes at NS Level (Out): 21
VCI 0x0101, NSEI 0x0100, peer 0x05060708:32000
+ Packets at NS Level ( In): 5
+ Packets at NS Level (Out): 5
+ Bytes at NS Level ( In): 21
+ Bytes at NS Level (Out): 37
NS-VC Block count : 1
Gbproxy global:
@@ -2416,7 +2620,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 75 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 79
00 00 10 02 01 78 de ad 00 00 00 04 08 88 21 63 54 00 63 60 12 34 00 80 0e 00 34 01 c0 01 08 01 02 f5 e0 21 08 02 05 f4 fb c5 46 79 11 22 33 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 16 6d 01
-result (ATTACH REQUEST) = 79
+result (ATTACH REQUEST) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -2436,7 +2640,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 23 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 27
00 00 10 02 00 80 00 de ad 00 50 20 16 82 02 58 0e 89 41 c0 01 08 15 01 ff 6c ba
-result (IDENT REQUEST) = 27
+result (IDENT REQUEST) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -2457,7 +2661,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 40 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 44
00 00 10 02 01 78 de ad 00 00 00 04 08 88 21 63 54 40 50 60 12 34 00 80 0e 00 11 01 c0 05 08 16 08 11 12 13 14 15 16 17 18 ad 05 28
-result (IDENT RESPONSE) = 44
+result (IDENT RESPONSE) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -2478,7 +2682,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 88 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 92
00 00 10 02 00 80 00 de ad 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 9e 41 c0 05 08 02 01 49 04 11 22 33 40 50 60 19 cd d7 08 17 16 18 05 f4 c0 de ad 01 0c 0a 29
-result (ATTACH ACCEPT) = 92
+result (ATTACH ACCEPT) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -2502,7 +2706,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 31 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 35
00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 21 63 54 40 50 60 12 34 00 80 0e 00 08 01 c0 09 08 03 39 d7 bc
-result (ATTACH COMPLETE) = 35
+result (ATTACH COMPLETE) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -2527,7 +2731,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 66 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 70
00 00 10 02 00 c0 de ad 01 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 88 41 c0 09 08 21 04 ba 3d
-result (GMM INFO) = 70
+result (GMM INFO) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -2552,7 +2756,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 81 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 85
00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 21 63 54 40 50 60 12 34 00 80 0e 00 3a 01 c0 0d 0a 41 05 03 0c 00 00 1f 10 00 00 00 00 00 00 00 00 02 01 21 28 08 03 66 6f 6f 03 62 61 72 27 14 80 80 21 10 01 00 00 10 81 06 00 00 00 00 83 06 00 00 00 00 24 9d 75
-result (ACT PDP CTX REQ (REPLACE APN)) = 85
+result (ACT PDP CTX REQ (REPLACE APN)) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -2579,7 +2783,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 38 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 42
00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 21 63 54 40 50 60 12 34 00 80 0e 00 0f 41 fb 01 00 0e 00 64 11 05 16 01 90 66 b3 28
-result (XID (UL)) = 42
+result (XID (UL)) = 0
PROCESSING XID (DL) from 0x05060708:32000
00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 8c 41 fb 30 84 10 61 b6 64 e4 a9 1a 9e
@@ -2591,7 +2795,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 70 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 74
00 00 10 02 00 c0 de ad 01 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 8c 41 fb 30 84 10 61 b6 64 e4 a9 1a 9e
-result (XID (DL)) = 74
+result (XID (DL)) = 0
PROCESSING LL11 DNS QUERY (UL) from 0x01020304:1111
00 00 10 02 01 c0 de ad 01 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 42 0b c0 01 65 00 00 00 45 00 00 38 95 72 00 00 45 11 20 85 0a c0 07 e4 ac 10 01 0a ad ab 00 35 00 24 0e 1c 3b e0 01 00 00 01 00 00 00 00 00 00 01 6d 05 68 65 69 73 65 02 64 65 00 00 01 00 01 47 8f 07
@@ -2603,7 +2807,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 89 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 93
00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 21 63 54 40 50 60 12 34 00 80 0e 00 42 0b c0 01 65 00 00 00 45 00 00 38 95 72 00 00 45 11 20 85 0a c0 07 e4 ac 10 01 0a ad ab 00 35 00 24 0e 1c 3b e0 01 00 00 01 00 00 00 00 00 00 01 6d 05 68 65 69 73 65 02 64 65 00 00 01 00 01 47 8f 07
-result (LL11 DNS QUERY (UL)) = 93
+result (LL11 DNS QUERY (UL)) = 0
PROCESSING LL11 DNS RESP (DL) from 0x05060708:32000
00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 00 d0 4b c0 01 65 00 00 00 45 00 00 c6 00 00 40 00 3e 11 7c 69 ac 10 01 0a 0a c0 07 e4 00 35 ad ab 00 b2 74 4e 3b e0 81 80 00 01 00 01 00 05 00 00 01 6d 05 68 65 69 73 65 02 64 65 00 00 01 00 01 c0 0c 00 01 00 01 00 00 0e 10 00 04 c1 63 90 58 c0 0e 00 02 00 01 00 00 0e 10 00 16 03 6e 73 32 0c 70 6f 70 2d 68 61 6e 6e 6f 76 65 72 03 6e 65 74 00 c0 0e 00 02 00 01 00 00 0e 10 00 10 02 6e 73 01 73 08 70 6c 75 73 6c 69 6e 65 c0 14 c0 0e 00 02 00 01 00 00 0e 10 00 05 02 6e 73 c0 0e c0 0e 00 02 00 01 00 00 0e 10 00 05 02 6e 73 c0 5f c0 0e 00 02 00 01 00 00 0e 10 00 12 02 6e 73 0c 70 6f 70 2d 68 61 6e 6e 6f 76 65 72 c0 14 aa df 31
@@ -2615,7 +2819,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 267 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 271
00 00 10 02 00 c0 de ad 01 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 00 d0 4b c0 01 65 00 00 00 45 00 00 c6 00 00 40 00 3e 11 7c 69 ac 10 01 0a 0a c0 07 e4 00 35 ad ab 00 b2 74 4e 3b e0 81 80 00 01 00 01 00 05 00 00 01 6d 05 68 65 69 73 65 02 64 65 00 00 01 00 01 c0 0c 00 01 00 01 00 00 0e 10 00 04 c1 63 90 58 c0 0e 00 02 00 01 00 00 0e 10 00 16 03 6e 73 32 0c 70 6f 70 2d 68 61 6e 6e 6f 76 65 72 03 6e 65 74 00 c0 0e 00 02 00 01 00 00 0e 10 00 10 02 6e 73 01 73 08 70 6c 75 73 6c 69 6e 65 c0 14 c0 0e 00 02 00 01 00 00 0e 10 00 05 02 6e 73 c0 0e c0 0e 00 02 00 01 00 00 0e 10 00 05 02 6e 73 c0 5f c0 0e 00 02 00 01 00 00 0e 10 00 12 02 6e 73 0c 70 6f 70 2d 68 61 6e 6e 6f 76 65 72 c0 14 aa df 31
-result (LL11 DNS RESP (DL)) = 271
+result (LL11 DNS RESP (DL)) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -2642,7 +2846,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 85 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 89
00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 21 63 54 40 50 60 70 80 00 80 0e 00 3e 01 c0 11 08 08 10 21 63 54 40 50 60 1d 19 13 42 33 57 2b f7 c8 48 02 13 48 50 c8 48 02 14 48 50 c8 48 02 17 49 10 c8 48 02 00 19 8b b2 92 17 16 27 07 04 31 02 e5 e0 32 02 20 00 69 a3 ae
-result (RA UPD REQ (P-TMSI 2)) = 89
+result (RA UPD REQ (P-TMSI 2)) = 0
PROCESSING RA UDP ACC (P-TMSI 2) from 0x05060708:32000
00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 9d 41 c0 0d 08 09 00 49 21 63 54 40 50 60 19 54 ab b3 18 05 f4 e0 98 76 54 17 16 9f e8 ea
@@ -2654,7 +2858,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 87 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 91
00 00 10 02 00 c0 de ad 01 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 9d 41 c0 0d 08 09 00 49 11 22 33 40 50 60 19 54 ab b3 18 05 f4 c0 de ad 02 17 16 bb 4d a0
-result (RA UDP ACC (P-TMSI 2)) = 91
+result (RA UDP ACC (P-TMSI 2)) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -2683,7 +2887,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 85 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 89
00 00 10 02 01 e0 98 76 54 00 00 04 08 88 21 63 54 40 50 60 70 80 00 80 0e 00 3e 01 c0 15 08 08 10 21 63 54 40 50 60 1d 19 13 42 33 57 2b f7 c8 48 02 13 48 50 c8 48 02 14 48 50 c8 48 02 17 49 10 c8 48 02 00 19 8b b2 92 17 16 27 07 04 31 02 e5 e0 32 02 20 00 1d f0 41
-result (RA UPD REQ (P-TMSI 3)) = 89
+result (RA UPD REQ (P-TMSI 3)) = 0
PROCESSING RA UDP ACC (P-TMSI 3) from 0x05060708:32000
00 00 10 02 00 e0 98 76 54 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 9d 41 c0 11 08 09 00 49 21 63 54 40 50 60 19 54 ab b3 18 05 f4 e0 54 32 10 17 16 1b a3 a8
@@ -2695,7 +2899,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 87 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 91
00 00 10 02 00 c0 de ad 02 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 9d 41 c0 11 08 09 00 49 11 22 33 40 50 60 19 54 ab b3 18 05 f4 c0 de ad 03 17 16 6e 58 26
-result (RA UDP ACC (P-TMSI 3)) = 91
+result (RA UDP ACC (P-TMSI 3)) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -2724,7 +2928,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 31 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 35
00 00 10 02 01 e0 54 32 10 00 00 04 08 88 21 63 54 40 50 60 70 80 00 80 0e 00 08 01 c0 19 08 0a d5 5f 5e
-result (RA UPD COMPLETE) = 35
+result (RA UPD COMPLETE) = 0
PROCESSING GMM INFO from 0x05060708:32000
00 00 10 02 00 e0 54 32 10 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 88 41 c0 15 08 21 bb c1 c6
@@ -2736,7 +2940,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 66 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 70
00 00 10 02 00 c0 de ad 03 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 88 41 c0 15 08 21 bb c1 c6
-result (GMM INFO) = 70
+result (GMM INFO) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -2766,7 +2970,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x0000, msg length 19 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 23
00 00 00 00 2c 1f 84 e0 54 32 10 0f 81 01 04 82 10 02 25 83 00 00 0c
-result (LLC_DISCARDED) = 23
+result (LLC_DISCARDED) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -2796,7 +3000,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x0000, msg length 15 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 19
00 00 00 00 0b 1f 84 e0 54 32 10 1b 86 21 63 54 40 50 60
-result (BVC_SUSPEND) = 19
+result (BVC_SUSPEND) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -2826,7 +3030,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x0000, msg length 18 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 22
00 00 00 00 0c 1f 84 c0 de ad 03 1b 86 11 22 33 40 50 60 1d 81 01
-result (BVC_SUSPEND_ACK) = 22
+result (BVC_SUSPEND_ACK) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -2856,7 +3060,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x0000, msg length 34 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 38
00 00 00 00 06 0d 88 11 12 13 14 15 16 17 18 0a 82 07 04 1b 86 11 22 33 40 50 60 18 83 00 00 00 20 84 c0 de ad 03
-result (PAGING_PS) = 38
+result (PAGING_PS) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -2886,7 +3090,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x0000, msg length 19 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 23
00 00 00 00 2c 1f 84 e0 54 32 10 0f 81 01 04 82 ee e1 25 83 00 00 0c
-result (LLC_DISCARDED) = 23
+result (LLC_DISCARDED) = 0
Gbproxy global:
PROCESSING BVC_SUSPEND_ACK from 0x05060708:32000
@@ -2899,7 +3103,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x0000, msg length 24 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 28
00 00 00 00 41 07 81 21 15 92 0c 1f 84 e0 54 32 10 1b 86 00 f1 99 00 63 60 1d 81 01
-result (BVC_SUSPEND_ACK) = 28
+result (BVC_SUSPEND_ACK) = 0
Gbproxy global:
Invalid Routing Area Identifier : 1
@@ -2914,7 +3118,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x0000, msg length 18 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 22
00 00 00 00 0c 1f 84 c0 de ad 03 1b 86 11 22 33 40 50 60 1d 81 01
-result (BVC_SUSPEND_ACK) = 22
+result (BVC_SUSPEND_ACK) = 0
Gbproxy global:
Invalid Routing Area Identifier : 1
@@ -2929,7 +3133,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 58 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 62
00 00 10 02 00 ee ba db ad 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 00 83 00 00 00 0e 88 41 c0 09 08 21 04 ba 3d
-result (GMM INFO) = 62
+result (GMM INFO) = 0
PROCESSING GMM INFO from 0x05060708:32000
00 00 10 02 00 ee ba db ad 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 88 41 c0 0d 08 21 68 71 6b
@@ -2941,7 +3145,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 66 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 70
00 00 10 02 00 ee ba db ad 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 88 41 c0 0d 08 21 68 71 6b
-result (GMM INFO) = 70
+result (GMM INFO) = 0
PROCESSING DETACH REQ from 0x01020304:1111
00 00 10 02 01 c0 de ad 03 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 15 01 c0 1d 08 05 01 18 05 f4 ef e2 b7 00 19 03 b9 97 cb aa cc a3
@@ -2953,7 +3157,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 44 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 48
00 00 10 02 01 e0 54 32 10 00 00 04 08 88 21 63 54 40 50 60 12 34 00 80 0e 00 15 01 c0 1d 08 05 01 18 05 f4 e0 54 32 10 19 03 b9 97 cb ea 6d af
-result (DETACH REQ) = 48
+result (DETACH REQ) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -2986,7 +3190,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 67 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 71
00 00 10 02 00 c0 de ad 03 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 89 41 c0 19 08 06 00 04 ff 52
-result (DETACH ACC) = 71
+result (DETACH ACC) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -3023,7 +3227,7 @@ PROCESSING RESET_ACK from 0x05060708:32000
MESSAGE to SGSN at 0x05060708:32000, msg length 1
0a
-result (RESET_ACK) = 1
+result (RESET_ACK) = 0
PROCESSING ALIVE_ACK from 0x05060708:32000
0b
@@ -3031,7 +3235,7 @@ PROCESSING ALIVE_ACK from 0x05060708:32000
MESSAGE to SGSN at 0x05060708:32000, msg length 1
06
-result (ALIVE_ACK) = 1
+result (ALIVE_ACK) = 0
PROCESSING UNBLOCK_ACK from 0x05060708:32000
07
@@ -3046,7 +3250,7 @@ PROCESSING ALIVE from 0x05060708:32000
MESSAGE to SGSN at 0x05060708:32000, msg length 1
0b
-result (ALIVE) = 1
+result (ALIVE) = 0
--- Initialise BSS 1 ---
@@ -3063,7 +3267,7 @@ MESSAGE to BSS at 0x01020304:1111, msg length 9
MESSAGE to BSS at 0x01020304:1111, msg length 1
0a
-result (RESET) = 9
+result (RESET) = 0
PROCESSING ALIVE from 0x01020304:1111
0a
@@ -3071,17 +3275,17 @@ PROCESSING ALIVE from 0x01020304:1111
MESSAGE to BSS at 0x01020304:1111, msg length 1
0b
-result (ALIVE) = 1
+result (ALIVE) = 0
PROCESSING UNBLOCK from 0x01020304:1111
06
-==> got signal NS_UNBLOCK, NS-VC 0x1001/1.2.3.4:1111
-
MESSAGE to BSS at 0x01020304:1111, msg length 1
07
-result (UNBLOCK) = 1
+==> got signal NS_UNBLOCK, NS-VC 0x1001/1.2.3.4:1111
+
+result (UNBLOCK) = 0
PROCESSING ALIVE_ACK from 0x01020304:1111
0b
@@ -3100,7 +3304,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x0000, msg length 18 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 22
00 00 00 00 22 04 82 10 02 07 81 08 08 88 21 63 54 40 50 60 10 00
-result (BVC_RESET) = 22
+result (BVC_RESET) = 0
PROCESSING BVC_RESET_ACK from 0x05060708:32000
00 00 00 00 23 04 82 10 02
@@ -3112,11 +3316,19 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x0000, msg length 5 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 9
00 00 00 00 23 04 82 10 02
-result (BVC_RESET_ACK) = 9
+result (BVC_RESET_ACK) = 0
Current NS-VCIs:
VCI 0x1001, NSEI 0x1000, peer 0x01020304:1111
+ Packets at NS Level ( In): 5
+ Packets at NS Level (Out): 5
+ Bytes at NS Level ( In): 37
+ Bytes at NS Level (Out): 21
VCI 0x0101, NSEI 0x0100, peer 0x05060708:32000
+ Packets at NS Level ( In): 5
+ Packets at NS Level (Out): 5
+ Bytes at NS Level ( In): 21
+ Bytes at NS Level (Out): 37
NS-VC Block count : 1
Gbproxy global:
@@ -3136,7 +3348,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 75 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 79
00 00 10 02 01 78 de ad 00 00 00 04 08 88 21 63 54 00 63 60 12 34 00 80 0e 00 34 01 c0 01 08 01 02 f5 e0 21 08 02 05 f4 fb c5 46 79 11 22 33 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 16 6d 01
-result (ATTACH REQUEST) = 79
+result (ATTACH REQUEST) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -3156,7 +3368,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 23 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 27
00 00 10 02 00 80 00 de ad 00 50 20 16 82 02 58 0e 89 41 c0 01 08 15 01 ff 6c ba
-result (IDENT REQUEST) = 27
+result (IDENT REQUEST) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -3177,7 +3389,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 40 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 44
00 00 10 02 01 78 de ad 00 00 00 04 08 88 21 63 54 40 50 60 12 34 00 80 0e 00 11 01 c0 05 08 16 08 11 12 13 14 15 16 17 18 ad 05 28
-result (IDENT RESPONSE) = 44
+result (IDENT RESPONSE) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -3198,7 +3410,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 88 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 92
00 00 10 02 00 80 00 de ad 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 9e 41 c0 05 08 02 01 49 04 11 22 33 40 50 60 19 cd d7 08 17 16 18 05 f4 c0 de ad 01 0c 0a 29
-result (ATTACH ACCEPT) = 92
+result (ATTACH ACCEPT) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -3222,7 +3434,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 88 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 92
00 00 10 02 00 80 00 de ad 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 9e 41 c0 09 08 02 01 49 04 11 22 33 40 50 60 19 cd d7 08 17 16 18 05 f4 c0 de ad 01 42 f6 fc
-result (ATTACH ACCEPT (duplicated)) = 92
+result (ATTACH ACCEPT (duplicated)) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -3246,7 +3458,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 31 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 35
00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 21 63 54 40 50 60 12 34 00 80 0e 00 08 01 c0 09 08 03 39 d7 bc
-result (ATTACH COMPLETE) = 35
+result (ATTACH COMPLETE) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -3271,7 +3483,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 66 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 70
00 00 10 02 00 c0 de ad 01 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 88 41 c0 0d 08 21 68 71 6b
-result (GMM INFO) = 70
+result (GMM INFO) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -3296,7 +3508,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 44 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 48
00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 21 63 54 40 50 60 12 34 00 80 0e 00 15 01 c0 0d 08 05 01 18 05 f4 ef e2 b7 00 19 03 b9 97 cb 37 67 c6
-result (DETACH REQ) = 48
+result (DETACH REQ) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -3322,7 +3534,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 67 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 71
00 00 10 02 00 c0 de ad 01 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 89 41 c0 11 08 06 00 cf 8a 58
-result (DETACH ACC) = 71
+result (DETACH ACC) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -3350,7 +3562,7 @@ PROCESSING RESET_ACK from 0x05060708:32000
MESSAGE to SGSN at 0x05060708:32000, msg length 1
0a
-result (RESET_ACK) = 1
+result (RESET_ACK) = 0
PROCESSING ALIVE_ACK from 0x05060708:32000
0b
@@ -3358,7 +3570,7 @@ PROCESSING ALIVE_ACK from 0x05060708:32000
MESSAGE to SGSN at 0x05060708:32000, msg length 1
06
-result (ALIVE_ACK) = 1
+result (ALIVE_ACK) = 0
PROCESSING UNBLOCK_ACK from 0x05060708:32000
07
@@ -3373,7 +3585,7 @@ PROCESSING ALIVE from 0x05060708:32000
MESSAGE to SGSN at 0x05060708:32000, msg length 1
0b
-result (ALIVE) = 1
+result (ALIVE) = 0
--- Initialise BSS 1 ---
@@ -3390,7 +3602,7 @@ MESSAGE to BSS at 0x01020304:1111, msg length 9
MESSAGE to BSS at 0x01020304:1111, msg length 1
0a
-result (RESET) = 9
+result (RESET) = 0
PROCESSING ALIVE from 0x01020304:1111
0a
@@ -3398,17 +3610,17 @@ PROCESSING ALIVE from 0x01020304:1111
MESSAGE to BSS at 0x01020304:1111, msg length 1
0b
-result (ALIVE) = 1
+result (ALIVE) = 0
PROCESSING UNBLOCK from 0x01020304:1111
06
-==> got signal NS_UNBLOCK, NS-VC 0x1001/1.2.3.4:1111
-
MESSAGE to BSS at 0x01020304:1111, msg length 1
07
-result (UNBLOCK) = 1
+==> got signal NS_UNBLOCK, NS-VC 0x1001/1.2.3.4:1111
+
+result (UNBLOCK) = 0
PROCESSING ALIVE_ACK from 0x01020304:1111
0b
@@ -3427,7 +3639,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x0000, msg length 18 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 22
00 00 00 00 22 04 82 10 02 07 81 08 08 88 21 63 54 40 50 60 10 00
-result (BVC_RESET) = 22
+result (BVC_RESET) = 0
PROCESSING BVC_RESET_ACK from 0x05060708:32000
00 00 00 00 23 04 82 10 02
@@ -3439,11 +3651,19 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x0000, msg length 5 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 9
00 00 00 00 23 04 82 10 02
-result (BVC_RESET_ACK) = 9
+result (BVC_RESET_ACK) = 0
Current NS-VCIs:
VCI 0x1001, NSEI 0x1000, peer 0x01020304:1111
+ Packets at NS Level ( In): 5
+ Packets at NS Level (Out): 5
+ Bytes at NS Level ( In): 37
+ Bytes at NS Level (Out): 21
VCI 0x0101, NSEI 0x0100, peer 0x05060708:32000
+ Packets at NS Level ( In): 5
+ Packets at NS Level (Out): 5
+ Bytes at NS Level ( In): 21
+ Bytes at NS Level (Out): 37
NS-VC Block count : 1
Gbproxy global:
@@ -3502,7 +3722,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 23 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 27
00 00 10 02 00 80 00 de ad 00 50 20 16 82 02 58 0e 89 41 c0 01 08 15 01 ff 6c ba
-result (IDENT REQUEST) = 27
+result (IDENT REQUEST) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -3523,7 +3743,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 40 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 44
00 00 10 02 01 78 de ad 00 00 00 04 08 88 21 63 54 40 50 60 12 34 00 80 0e 00 11 01 c0 09 08 16 08 11 12 13 14 15 16 17 18 ba 14 c3
-result (IDENT RESPONSE) = 44
+result (IDENT RESPONSE) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -3544,7 +3764,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 88 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 92
00 00 10 02 00 80 00 de ad 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 9e 41 c0 05 08 02 01 49 04 11 22 33 40 50 60 19 cd d7 08 17 16 18 05 f4 c0 de ad 01 0c 0a 29
-result (ATTACH ACCEPT) = 92
+result (ATTACH ACCEPT) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -3568,7 +3788,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 31 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 35
00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 21 63 54 40 50 60 12 34 00 80 0e 00 08 01 c0 0d 08 03 55 1c ea
-result (ATTACH COMPLETE) = 35
+result (ATTACH COMPLETE) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -3593,7 +3813,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 66 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 70
00 00 10 02 00 c0 de ad 01 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 88 41 c0 09 08 21 04 ba 3d
-result (GMM INFO) = 70
+result (GMM INFO) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -3618,7 +3838,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 38 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 42
00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 21 63 54 40 50 60 12 34 00 80 0e 00 0f 41 fb 01 00 0e 00 64 11 05 16 01 90 66 b3 28
-result (XID (UL)) = 42
+result (XID (UL)) = 0
PROCESSING XID (DL) from 0x05060708:32000
00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 8c 41 fb 30 84 10 61 b6 64 e4 a9 1a 9e
@@ -3630,7 +3850,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 70 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 74
00 00 10 02 00 c0 de ad 01 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 8c 41 fb 30 84 10 61 b6 64 e4 a9 1a 9e
-result (XID (DL)) = 74
+result (XID (DL)) = 0
PROCESSING LL11 DNS QUERY (UL) from 0x01020304:1111
00 00 10 02 01 c0 de ad 01 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 42 0b c0 01 65 00 00 00 45 00 00 38 95 72 00 00 45 11 20 85 0a c0 07 e4 ac 10 01 0a ad ab 00 35 00 24 0e 1c 3b e0 01 00 00 01 00 00 00 00 00 00 01 6d 05 68 65 69 73 65 02 64 65 00 00 01 00 01 47 8f 07
@@ -3642,7 +3862,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 89 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 93
00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 21 63 54 40 50 60 12 34 00 80 0e 00 42 0b c0 01 65 00 00 00 45 00 00 38 95 72 00 00 45 11 20 85 0a c0 07 e4 ac 10 01 0a ad ab 00 35 00 24 0e 1c 3b e0 01 00 00 01 00 00 00 00 00 00 01 6d 05 68 65 69 73 65 02 64 65 00 00 01 00 01 47 8f 07
-result (LL11 DNS QUERY (UL)) = 93
+result (LL11 DNS QUERY (UL)) = 0
PROCESSING LL11 DNS RESP (DL) from 0x05060708:32000
00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 00 d0 4b c0 01 65 00 00 00 45 00 00 c6 00 00 40 00 3e 11 7c 69 ac 10 01 0a 0a c0 07 e4 00 35 ad ab 00 b2 74 4e 3b e0 81 80 00 01 00 01 00 05 00 00 01 6d 05 68 65 69 73 65 02 64 65 00 00 01 00 01 c0 0c 00 01 00 01 00 00 0e 10 00 04 c1 63 90 58 c0 0e 00 02 00 01 00 00 0e 10 00 16 03 6e 73 32 0c 70 6f 70 2d 68 61 6e 6e 6f 76 65 72 03 6e 65 74 00 c0 0e 00 02 00 01 00 00 0e 10 00 10 02 6e 73 01 73 08 70 6c 75 73 6c 69 6e 65 c0 14 c0 0e 00 02 00 01 00 00 0e 10 00 05 02 6e 73 c0 0e c0 0e 00 02 00 01 00 00 0e 10 00 05 02 6e 73 c0 5f c0 0e 00 02 00 01 00 00 0e 10 00 12 02 6e 73 0c 70 6f 70 2d 68 61 6e 6e 6f 76 65 72 c0 14 aa df 31
@@ -3654,7 +3874,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 267 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 271
00 00 10 02 00 c0 de ad 01 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 00 d0 4b c0 01 65 00 00 00 45 00 00 c6 00 00 40 00 3e 11 7c 69 ac 10 01 0a 0a c0 07 e4 00 35 ad ab 00 b2 74 4e 3b e0 81 80 00 01 00 01 00 05 00 00 01 6d 05 68 65 69 73 65 02 64 65 00 00 01 00 01 c0 0c 00 01 00 01 00 00 0e 10 00 04 c1 63 90 58 c0 0e 00 02 00 01 00 00 0e 10 00 16 03 6e 73 32 0c 70 6f 70 2d 68 61 6e 6e 6f 76 65 72 03 6e 65 74 00 c0 0e 00 02 00 01 00 00 0e 10 00 10 02 6e 73 01 73 08 70 6c 75 73 6c 69 6e 65 c0 14 c0 0e 00 02 00 01 00 00 0e 10 00 05 02 6e 73 c0 0e c0 0e 00 02 00 01 00 00 0e 10 00 05 02 6e 73 c0 5f c0 0e 00 02 00 01 00 00 0e 10 00 12 02 6e 73 0c 70 6f 70 2d 68 61 6e 6e 6f 76 65 72 c0 14 aa df 31
-result (LL11 DNS RESP (DL)) = 271
+result (LL11 DNS RESP (DL)) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -3679,7 +3899,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x0000, msg length 19 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 23
00 00 00 00 2c 1f 84 ef e2 b7 00 0f 81 01 04 82 10 02 25 83 00 00 0c
-result (LLC_DISCARDED) = 23
+result (LLC_DISCARDED) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -3704,7 +3924,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x0000, msg length 25 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 29
00 00 00 00 41 07 81 27 15 93 2c 1f 84 ef e2 b7 00 0f 81 01 04 82 10 02 25 83 00 00 0c
-result (LLC_DISCARDED) = 29
+result (LLC_DISCARDED) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -3729,7 +3949,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x0000, msg length 15 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 19
00 00 00 00 0b 1f 84 ef e2 b7 00 1b 86 21 63 54 40 50 60
-result (BVC_SUSPEND) = 19
+result (BVC_SUSPEND) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -3754,7 +3974,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x0000, msg length 18 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 22
00 00 00 00 0c 1f 84 c0 de ad 01 1b 86 11 22 33 40 50 60 1d 81 01
-result (BVC_SUSPEND_ACK) = 22
+result (BVC_SUSPEND_ACK) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -3779,7 +3999,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x0000, msg length 19 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 23
00 00 00 00 2c 1f 84 ef e2 b7 00 0f 81 01 04 82 ee e1 25 83 00 00 0c
-result (LLC_DISCARDED) = 23
+result (LLC_DISCARDED) = 0
Gbproxy global:
BSSGP protocol error (SGSN): 1
@@ -3793,7 +4013,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x0000, msg length 24 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 28
00 00 00 00 41 07 81 21 15 92 0c 1f 84 ef e2 b7 00 1b 86 00 f1 99 00 63 60 1d 81 01
-result (BVC_SUSPEND_ACK) = 28
+result (BVC_SUSPEND_ACK) = 0
Gbproxy global:
Invalid Routing Area Identifier : 1
@@ -3809,7 +4029,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x0000, msg length 18 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 22
00 00 00 00 0c 1f 84 c0 de ad 01 1b 86 11 22 33 40 50 60 1d 81 01
-result (BVC_SUSPEND_ACK) = 22
+result (BVC_SUSPEND_ACK) = 0
Gbproxy global:
Invalid Routing Area Identifier : 1
@@ -3825,7 +4045,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 44 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 48
00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 21 63 54 40 50 60 12 34 00 80 0e 00 15 01 c0 11 08 05 01 18 05 f4 ef e2 b7 00 19 03 b9 97 cb 6d b1 de
-result (DETACH REQ) = 48
+result (DETACH REQ) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -3851,7 +4071,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 67 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 71
00 00 10 02 00 c0 de ad 01 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 89 41 c0 0d 08 06 00 aa ab ee
-result (DETACH ACC) = 71
+result (DETACH ACC) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -3916,7 +4136,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 87 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 91
00 00 10 02 00 80 00 de ad 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 9d 41 c0 11 08 09 00 49 11 22 33 40 50 60 19 54 ab b3 18 05 f4 c0 de ad 03 17 16 6e 58 26
-result (RA UDP ACC) = 91
+result (RA UDP ACC) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -3974,7 +4194,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 67 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 71
00 00 10 02 00 c0 de ad 03 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 89 41 c0 15 08 06 00 f7 35 f0
-result (DETACH ACC) = 71
+result (DETACH ACC) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -4136,7 +4356,7 @@ PROCESSING RESET_ACK from 0x05060708:32000
MESSAGE to SGSN at 0x05060708:32000, msg length 1
0a
-result (RESET_ACK) = 1
+result (RESET_ACK) = 0
PROCESSING ALIVE_ACK from 0x05060708:32000
0b
@@ -4144,7 +4364,7 @@ PROCESSING ALIVE_ACK from 0x05060708:32000
MESSAGE to SGSN at 0x05060708:32000, msg length 1
06
-result (ALIVE_ACK) = 1
+result (ALIVE_ACK) = 0
PROCESSING UNBLOCK_ACK from 0x05060708:32000
07
@@ -4159,7 +4379,7 @@ PROCESSING ALIVE from 0x05060708:32000
MESSAGE to SGSN at 0x05060708:32000, msg length 1
0b
-result (ALIVE) = 1
+result (ALIVE) = 0
--- Initialise SGSN 2 ---
@@ -4172,7 +4392,7 @@ PROCESSING RESET_ACK from 0x15161718:32001
MESSAGE to SGSN 2 at 0x15161718:32001, msg length 1
0a
-result (RESET_ACK) = 1
+result (RESET_ACK) = 0
PROCESSING ALIVE_ACK from 0x15161718:32001
0b
@@ -4180,7 +4400,7 @@ PROCESSING ALIVE_ACK from 0x15161718:32001
MESSAGE to SGSN 2 at 0x15161718:32001, msg length 1
06
-result (ALIVE_ACK) = 1
+result (ALIVE_ACK) = 0
PROCESSING UNBLOCK_ACK from 0x15161718:32001
07
@@ -4195,7 +4415,7 @@ PROCESSING ALIVE from 0x15161718:32001
MESSAGE to SGSN 2 at 0x15161718:32001, msg length 1
0b
-result (ALIVE) = 1
+result (ALIVE) = 0
--- Initialise BSS 1 ---
@@ -4212,7 +4432,7 @@ MESSAGE to BSS at 0x01020304:1111, msg length 9
MESSAGE to BSS at 0x01020304:1111, msg length 1
0a
-result (RESET) = 9
+result (RESET) = 0
PROCESSING ALIVE from 0x01020304:1111
0a
@@ -4220,17 +4440,17 @@ PROCESSING ALIVE from 0x01020304:1111
MESSAGE to BSS at 0x01020304:1111, msg length 1
0b
-result (ALIVE) = 1
+result (ALIVE) = 0
PROCESSING UNBLOCK from 0x01020304:1111
06
-==> got signal NS_UNBLOCK, NS-VC 0x1001/1.2.3.4:1111
-
MESSAGE to BSS at 0x01020304:1111, msg length 1
07
-result (UNBLOCK) = 1
+==> got signal NS_UNBLOCK, NS-VC 0x1001/1.2.3.4:1111
+
+result (UNBLOCK) = 0
PROCESSING ALIVE_ACK from 0x01020304:1111
0b
@@ -4249,7 +4469,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x0000, msg length 5 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 9
00 00 00 00 23 04 82 00 00
-result (BVC_RESET) = 9
+result (BVC_RESET) = 0
PROCESSING BVC_RESET_ACK from 0x05060708:32000
00 00 00 00 23 04 82 00 00
@@ -4275,7 +4495,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x0000, msg length 18 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 22
00 00 00 00 22 04 82 10 02 07 81 08 08 88 21 63 54 40 50 60 10 00
-result (BVC_RESET) = 22
+result (BVC_RESET) = 0
PROCESSING BVC_RESET_ACK from 0x05060708:32000
00 00 00 00 23 04 82 10 02
@@ -4287,7 +4507,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x0000, msg length 5 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 9
00 00 00 00 23 04 82 10 02
-result (BVC_RESET_ACK) = 9
+result (BVC_RESET_ACK) = 0
PROCESSING BVC_RESET_ACK from 0x15161718:32001
00 00 00 00 23 04 82 10 02
@@ -4295,13 +4515,25 @@ PROCESSING BVC_RESET_ACK from 0x15161718:32001
CALLBACK, event 0, msg length 5, bvci 0x0000
00 00 00 00 23 04 82 10 02
-result (BVC_RESET_ACK) = 1
+result (BVC_RESET_ACK) = 0
Current NS-VCIs:
VCI 0x1001, NSEI 0x1000, peer 0x01020304:1111
+ Packets at NS Level ( In): 6
+ Packets at NS Level (Out): 6
+ Bytes at NS Level ( In): 59
+ Bytes at NS Level (Out): 30
VCI 0x0103, NSEI 0x0102, peer 0x15161718:32001
+ Packets at NS Level ( In): 5
+ Packets at NS Level (Out): 5
+ Bytes at NS Level ( In): 21
+ Bytes at NS Level (Out): 37
NS-VC Block count : 1
VCI 0x0101, NSEI 0x0100, peer 0x05060708:32000
+ Packets at NS Level ( In): 6
+ Packets at NS Level (Out): 5
+ Bytes at NS Level ( In): 30
+ Bytes at NS Level (Out): 37
NS-VC Block count : 1
Gbproxy global:
@@ -4327,7 +4559,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 24 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 28
00 00 10 02 26 1e 81 01 05 82 01 dc 03 82 02 76 01 82 00 50 1c 82 02 58 06 82 00 03
-result (FLOW_CONTROL_BVC) = 28
+result (FLOW_CONTROL_BVC) = 0
PROCESSING FLOW_CONTROL_BVC_ACK from 0x05060708:32000
00 00 10 02 27 1e 81 01
@@ -4339,7 +4571,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 4 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 8
00 00 10 02 27 1e 81 01
-result (FLOW_CONTROL_BVC_ACK) = 8
+result (FLOW_CONTROL_BVC_ACK) = 0
PROCESSING FLOW_CONTROL_BVC_ACK from 0x15161718:32001
00 00 10 02 27 1e 81 01
@@ -4400,7 +4632,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 23 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 27
00 00 10 02 00 80 00 de ad 00 50 20 16 82 02 58 0e 89 41 c0 01 08 15 01 ff 6c ba
-result (IDENT REQUEST) = 27
+result (IDENT REQUEST) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -4421,7 +4653,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 40 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 44
00 00 10 02 01 78 de ad 00 00 00 04 08 88 21 63 54 40 50 60 12 34 00 80 0e 00 11 01 c0 09 08 16 08 11 12 13 14 15 16 17 18 ba 14 c3
-result (IDENT RESPONSE) = 44
+result (IDENT RESPONSE) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -4442,7 +4674,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 88 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 92
00 00 10 02 00 80 00 de ad 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 9e 41 c0 05 08 02 01 49 04 11 22 33 40 50 60 19 cd d7 08 17 16 18 05 f4 c0 de ad 01 0c 0a 29
-result (ATTACH ACCEPT) = 92
+result (ATTACH ACCEPT) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -4466,7 +4698,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 31 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 35
00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 21 63 54 40 50 60 12 34 00 80 0e 00 08 01 c0 0d 08 03 55 1c ea
-result (ATTACH COMPLETE) = 35
+result (ATTACH COMPLETE) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -4491,7 +4723,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 66 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 70
00 00 10 02 00 c0 de ad 01 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 88 41 c0 09 08 21 04 ba 3d
-result (GMM INFO) = 70
+result (GMM INFO) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -4516,7 +4748,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 38 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 42
00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 21 63 54 40 50 60 12 34 00 80 0e 00 0f 41 fb 01 00 0e 00 64 11 05 16 01 90 66 b3 28
-result (XID (UL)) = 42
+result (XID (UL)) = 0
PROCESSING XID (DL) from 0x05060708:32000
00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 8c 41 fb 30 84 10 61 b6 64 e4 a9 1a 9e
@@ -4528,7 +4760,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 70 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 74
00 00 10 02 00 c0 de ad 01 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 8c 41 fb 30 84 10 61 b6 64 e4 a9 1a 9e
-result (XID (DL)) = 74
+result (XID (DL)) = 0
PROCESSING LL11 DNS QUERY (UL) from 0x01020304:1111
00 00 10 02 01 c0 de ad 01 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 42 0b c0 01 65 00 00 00 45 00 00 38 95 72 00 00 45 11 20 85 0a c0 07 e4 ac 10 01 0a ad ab 00 35 00 24 0e 1c 3b e0 01 00 00 01 00 00 00 00 00 00 01 6d 05 68 65 69 73 65 02 64 65 00 00 01 00 01 47 8f 07
@@ -4540,7 +4772,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 89 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 93
00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 21 63 54 40 50 60 12 34 00 80 0e 00 42 0b c0 01 65 00 00 00 45 00 00 38 95 72 00 00 45 11 20 85 0a c0 07 e4 ac 10 01 0a ad ab 00 35 00 24 0e 1c 3b e0 01 00 00 01 00 00 00 00 00 00 01 6d 05 68 65 69 73 65 02 64 65 00 00 01 00 01 47 8f 07
-result (LL11 DNS QUERY (UL)) = 93
+result (LL11 DNS QUERY (UL)) = 0
PROCESSING LL11 DNS RESP (DL) from 0x05060708:32000
00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 00 d0 4b c0 01 65 00 00 00 45 00 00 c6 00 00 40 00 3e 11 7c 69 ac 10 01 0a 0a c0 07 e4 00 35 ad ab 00 b2 74 4e 3b e0 81 80 00 01 00 01 00 05 00 00 01 6d 05 68 65 69 73 65 02 64 65 00 00 01 00 01 c0 0c 00 01 00 01 00 00 0e 10 00 04 c1 63 90 58 c0 0e 00 02 00 01 00 00 0e 10 00 16 03 6e 73 32 0c 70 6f 70 2d 68 61 6e 6e 6f 76 65 72 03 6e 65 74 00 c0 0e 00 02 00 01 00 00 0e 10 00 10 02 6e 73 01 73 08 70 6c 75 73 6c 69 6e 65 c0 14 c0 0e 00 02 00 01 00 00 0e 10 00 05 02 6e 73 c0 0e c0 0e 00 02 00 01 00 00 0e 10 00 05 02 6e 73 c0 5f c0 0e 00 02 00 01 00 00 0e 10 00 12 02 6e 73 0c 70 6f 70 2d 68 61 6e 6e 6f 76 65 72 c0 14 aa df 31
@@ -4552,7 +4784,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 267 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 271
00 00 10 02 00 c0 de ad 01 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 00 d0 4b c0 01 65 00 00 00 45 00 00 c6 00 00 40 00 3e 11 7c 69 ac 10 01 0a 0a c0 07 e4 00 35 ad ab 00 b2 74 4e 3b e0 81 80 00 01 00 01 00 05 00 00 01 6d 05 68 65 69 73 65 02 64 65 00 00 01 00 01 c0 0c 00 01 00 01 00 00 0e 10 00 04 c1 63 90 58 c0 0e 00 02 00 01 00 00 0e 10 00 16 03 6e 73 32 0c 70 6f 70 2d 68 61 6e 6e 6f 76 65 72 03 6e 65 74 00 c0 0e 00 02 00 01 00 00 0e 10 00 10 02 6e 73 01 73 08 70 6c 75 73 6c 69 6e 65 c0 14 c0 0e 00 02 00 01 00 00 0e 10 00 05 02 6e 73 c0 0e c0 0e 00 02 00 01 00 00 0e 10 00 05 02 6e 73 c0 5f c0 0e 00 02 00 01 00 00 0e 10 00 12 02 6e 73 0c 70 6f 70 2d 68 61 6e 6e 6f 76 65 72 c0 14 aa df 31
-result (LL11 DNS RESP (DL)) = 271
+result (LL11 DNS RESP (DL)) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -4577,7 +4809,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x0000, msg length 19 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 23
00 00 00 00 2c 1f 84 ef e2 b7 00 0f 81 01 04 82 10 02 25 83 00 00 0c
-result (LLC_DISCARDED) = 23
+result (LLC_DISCARDED) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -4602,7 +4834,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x0000, msg length 25 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 29
00 00 00 00 41 07 81 27 15 93 2c 1f 84 ef e2 b7 00 0f 81 01 04 82 10 02 25 83 00 00 0c
-result (LLC_DISCARDED) = 29
+result (LLC_DISCARDED) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -4627,7 +4859,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x0000, msg length 15 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 19
00 00 00 00 0b 1f 84 ef e2 b7 00 1b 86 21 63 54 40 50 60
-result (BVC_SUSPEND) = 19
+result (BVC_SUSPEND) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -4652,7 +4884,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x0000, msg length 18 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 22
00 00 00 00 0c 1f 84 c0 de ad 01 1b 86 11 22 33 40 50 60 1d 81 01
-result (BVC_SUSPEND_ACK) = 22
+result (BVC_SUSPEND_ACK) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -4731,7 +4963,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 23 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 27
00 00 10 02 00 80 00 be ef 00 50 20 16 82 02 58 0e 89 41 c0 0d 08 15 01 0c a6 18
-result (IDENT REQUEST) = 27
+result (IDENT REQUEST) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -4783,7 +5015,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 88 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 92
00 00 10 02 00 80 00 be ef 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 99 99 99 16 17 18 00 81 00 0e 9e 41 c0 11 08 02 01 49 04 11 22 33 40 50 60 19 cd d7 08 17 16 18 05 f4 c0 de ad 03 32 40 fa
-result (ATTACH ACCEPT) = 92
+result (ATTACH ACCEPT) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -4835,7 +5067,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 66 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 70
00 00 10 02 00 c0 de ad 03 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 99 99 99 16 17 18 00 81 00 0e 88 41 c0 15 08 21 bb c1 c6
-result (GMM INFO) = 70
+result (GMM INFO) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -4873,7 +5105,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 70 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 74
00 00 10 02 00 c0 de ad 03 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 99 99 99 16 17 18 00 81 00 0e 8c 41 fb 30 84 10 61 b6 64 e4 a9 1a 9e
-result (XID (DL)) = 74
+result (XID (DL)) = 0
PROCESSING LL11 DNS QUERY (UL) from 0x01020304:1111
00 00 10 02 01 c0 de ad 03 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 42 0b c0 01 65 00 00 00 45 00 00 38 95 72 00 00 45 11 20 85 0a c0 07 e4 ac 10 01 0a ad ab 00 35 00 24 0e 1c 3b e0 01 00 00 01 00 00 00 00 00 00 01 6d 05 68 65 69 73 65 02 64 65 00 00 01 00 01 47 8f 07
@@ -4897,7 +5129,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 267 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 271
00 00 10 02 00 c0 de ad 03 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 99 99 99 16 17 18 00 81 00 0e 00 d0 4b c0 01 65 00 00 00 45 00 00 c6 00 00 40 00 3e 11 7c 69 ac 10 01 0a 0a c0 07 e4 00 35 ad ab 00 b2 74 4e 3b e0 81 80 00 01 00 01 00 05 00 00 01 6d 05 68 65 69 73 65 02 64 65 00 00 01 00 01 c0 0c 00 01 00 01 00 00 0e 10 00 04 c1 63 90 58 c0 0e 00 02 00 01 00 00 0e 10 00 16 03 6e 73 32 0c 70 6f 70 2d 68 61 6e 6e 6f 76 65 72 03 6e 65 74 00 c0 0e 00 02 00 01 00 00 0e 10 00 10 02 6e 73 01 73 08 70 6c 75 73 6c 69 6e 65 c0 14 c0 0e 00 02 00 01 00 00 0e 10 00 05 02 6e 73 c0 0e c0 0e 00 02 00 01 00 00 0e 10 00 05 02 6e 73 c0 5f c0 0e 00 02 00 01 00 00 0e 10 00 12 02 6e 73 0c 70 6f 70 2d 68 61 6e 6e 6f 76 65 72 c0 14 aa df 31
-result (LL11 DNS RESP (DL)) = 271
+result (LL11 DNS RESP (DL)) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -4949,7 +5181,7 @@ NS UNITDATA MESSAGE to SGSN 2, BVCI 0x0000, msg length 25 (gprs_ns_sendmsg)
MESSAGE to SGSN 2 at 0x15161718:32001, msg length 29
00 00 00 00 41 07 81 27 15 93 2c 1f 84 e0 98 76 54 0f 81 01 04 82 10 02 25 83 00 00 0c
-result (LLC_DISCARDED) = 29
+result (LLC_DISCARDED) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -5001,7 +5233,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x0000, msg length 18 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 22
00 00 00 00 0c 1f 84 c0 de ad 03 1b 86 11 22 33 40 50 60 1d 81 01
-result (BVC_SUSPEND_ACK) = 22
+result (BVC_SUSPEND_ACK) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -5083,7 +5315,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 23 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 27
00 00 10 02 00 80 00 fe ed 00 50 20 16 82 02 58 0e 89 41 c0 19 08 15 01 a2 f2 a4
-result (IDENT REQUEST) = 27
+result (IDENT REQUEST) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -5137,7 +5369,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 88 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 92
00 00 10 02 00 80 00 fe ed 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 99 99 99 26 27 28 00 81 00 0e 9e 41 c0 1d 08 02 01 49 04 11 22 33 40 50 60 19 cd d7 08 17 16 18 05 f4 c0 de ad 05 3e 78 6e
-result (ATTACH ACCEPT (P-TMSI 1)) = 92
+result (ATTACH ACCEPT (P-TMSI 1)) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -5191,7 +5423,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 66 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 70
00 00 10 02 00 c0 de ad 05 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 99 99 99 26 27 28 00 81 00 0e 88 41 c0 21 08 21 ca 60 90
-result (GMM INFO) = 70
+result (GMM INFO) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -5220,7 +5452,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 44 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 48
00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 21 63 54 40 50 60 12 34 00 80 0e 00 15 01 c0 31 08 05 01 18 05 f4 ef e2 b7 00 19 03 b9 97 cb 57 e6 15
-result (DETACH REQ) = 48
+result (DETACH REQ) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -5248,7 +5480,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 67 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 71
00 00 10 02 00 c0 de ad 01 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 89 41 c0 25 08 06 00 4d 09 cd
-result (DETACH ACC) = 71
+result (DETACH ACC) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -5307,7 +5539,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 67 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 71
00 00 10 02 00 c0 de ad 03 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 99 99 99 16 17 18 00 81 00 0e 89 41 c0 29 08 06 00 be c3 6f
-result (DETACH ACC) = 71
+result (DETACH ACC) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -5365,7 +5597,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 67 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 71
00 00 10 02 00 c0 de ad 05 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 99 99 99 26 27 28 00 81 00 0e 89 41 c0 2d 08 06 00 86 7c c7
-result (DETACH ACC) = 71
+result (DETACH ACC) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -5397,7 +5629,7 @@ PROCESSING RESET_ACK from 0x05060708:32000
MESSAGE to SGSN at 0x05060708:32000, msg length 1
0a
-result (RESET_ACK) = 1
+result (RESET_ACK) = 0
PROCESSING ALIVE_ACK from 0x05060708:32000
0b
@@ -5405,7 +5637,7 @@ PROCESSING ALIVE_ACK from 0x05060708:32000
MESSAGE to SGSN at 0x05060708:32000, msg length 1
06
-result (ALIVE_ACK) = 1
+result (ALIVE_ACK) = 0
PROCESSING UNBLOCK_ACK from 0x05060708:32000
07
@@ -5420,7 +5652,7 @@ PROCESSING ALIVE from 0x05060708:32000
MESSAGE to SGSN at 0x05060708:32000, msg length 1
0b
-result (ALIVE) = 1
+result (ALIVE) = 0
--- Initialise BSS 1 ---
@@ -5437,7 +5669,7 @@ MESSAGE to BSS at 0x01020304:1111, msg length 9
MESSAGE to BSS at 0x01020304:1111, msg length 1
0a
-result (RESET) = 9
+result (RESET) = 0
PROCESSING ALIVE from 0x01020304:1111
0a
@@ -5445,17 +5677,17 @@ PROCESSING ALIVE from 0x01020304:1111
MESSAGE to BSS at 0x01020304:1111, msg length 1
0b
-result (ALIVE) = 1
+result (ALIVE) = 0
PROCESSING UNBLOCK from 0x01020304:1111
06
-==> got signal NS_UNBLOCK, NS-VC 0x1001/1.2.3.4:1111
-
MESSAGE to BSS at 0x01020304:1111, msg length 1
07
-result (UNBLOCK) = 1
+==> got signal NS_UNBLOCK, NS-VC 0x1001/1.2.3.4:1111
+
+result (UNBLOCK) = 0
PROCESSING ALIVE_ACK from 0x01020304:1111
0b
@@ -5474,7 +5706,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x0000, msg length 18 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 22
00 00 00 00 22 04 82 10 02 07 81 08 08 88 11 22 33 40 50 60 10 00
-result (BVC_RESET) = 22
+result (BVC_RESET) = 0
PROCESSING BVC_RESET_ACK from 0x05060708:32000
00 00 00 00 23 04 82 10 02
@@ -5486,11 +5718,19 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x0000, msg length 5 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 9
00 00 00 00 23 04 82 10 02
-result (BVC_RESET_ACK) = 9
+result (BVC_RESET_ACK) = 0
Current NS-VCIs:
VCI 0x1001, NSEI 0x1000, peer 0x01020304:1111
+ Packets at NS Level ( In): 5
+ Packets at NS Level (Out): 5
+ Bytes at NS Level ( In): 37
+ Bytes at NS Level (Out): 21
VCI 0x0101, NSEI 0x0100, peer 0x05060708:32000
+ Packets at NS Level ( In): 5
+ Packets at NS Level (Out): 5
+ Bytes at NS Level ( In): 21
+ Bytes at NS Level (Out): 37
NS-VC Block count : 1
Gbproxy global:
@@ -5545,7 +5785,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 23 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 27
00 00 10 02 00 af e2 b7 00 00 50 20 16 82 02 58 0e 89 41 c0 01 08 15 01 ff 6c ba
-result (IDENT REQUEST) = 27
+result (IDENT REQUEST) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -5563,7 +5803,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 40 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 44
00 00 10 02 01 af e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 11 01 c0 09 08 16 08 11 12 13 14 15 16 17 18 ba 14 c3
-result (IDENT RESPONSE) = 44
+result (IDENT RESPONSE) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -5581,7 +5821,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 88 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 92
00 00 10 02 00 af e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 9e 41 c0 05 08 02 01 49 04 21 63 54 40 50 60 19 cd d7 08 17 16 18 05 f4 ef e2 b7 00 53 62 f1
-result (ATTACH ACCEPT) = 92
+result (ATTACH ACCEPT) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -5600,7 +5840,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 31 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 35
00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 0d 08 03 55 1c ea
-result (ATTACH COMPLETE) = 35
+result (ATTACH COMPLETE) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -5620,7 +5860,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 66 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 70
00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 88 41 c0 09 08 21 04 ba 3d
-result (GMM INFO) = 70
+result (GMM INFO) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -5640,7 +5880,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 44 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 48
00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 15 01 c0 11 08 05 01 18 05 f4 ef e2 b7 00 19 03 b9 97 cb 6d b1 de
-result (DETACH REQ) = 48
+result (DETACH REQ) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -5661,7 +5901,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 67 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 71
00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 89 41 c0 0d 08 06 00 aa ab ee
-result (DETACH ACC) = 71
+result (DETACH ACC) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -5683,7 +5923,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 75 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 79
00 00 10 02 01 af e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 34 01 c0 15 08 01 02 f5 e0 21 08 02 05 f4 ef e2 b7 00 11 22 33 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 e6 71 c7
-result (ATTACH REQUEST) = 79
+result (ATTACH REQUEST) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -5705,7 +5945,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 88 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 92
00 00 10 02 00 af e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 9e 41 c0 11 08 02 01 49 04 21 63 54 40 50 60 19 cd d7 08 17 16 18 05 f4 ef e2 b7 00 3a 6d d4
-result (ATTACH ACCEPT) = 92
+result (ATTACH ACCEPT) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -5727,7 +5967,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 31 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 35
00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 19 08 03 32 f1 bc
-result (ATTACH COMPLETE) = 35
+result (ATTACH COMPLETE) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -5749,7 +5989,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 69 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 73
00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 8b 41 c0 15 08 05 01 25 0a 67 0e 96
-result (DETACH REQ (re-attach)) = 73
+result (DETACH REQ (re-attach)) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -5771,7 +6011,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 31 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 35
00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 1d 08 06 3d 1c 8b
-result (DETACH ACC) = 35
+result (DETACH ACC) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -5793,7 +6033,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 75 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 79
00 00 10 02 01 af e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 34 01 c0 21 08 01 02 f5 e0 21 08 02 05 f4 ef e2 b7 00 11 22 33 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 44 db cc
-result (ATTACH REQUEST) = 79
+result (ATTACH REQUEST) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -5815,7 +6055,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 88 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 92
00 00 10 02 00 af e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 9e 41 c0 19 08 02 01 49 04 21 63 54 40 50 60 19 cd d7 08 17 16 18 05 f4 ef e2 b7 00 27 3c 84
-result (ATTACH ACCEPT) = 92
+result (ATTACH ACCEPT) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -5837,7 +6077,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 31 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 35
00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 25 08 03 9b c6 47
-result (ATTACH COMPLETE) = 35
+result (ATTACH COMPLETE) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -5859,7 +6099,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 69 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 73
00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 8b 41 c0 1d 08 05 02 25 0a dd 56 6c
-result (DETACH REQ) = 73
+result (DETACH REQ) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -5881,7 +6121,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 31 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 35
00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 29 08 06 4c bd dd
-result (DETACH ACC) = 35
+result (DETACH ACC) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -5903,7 +6143,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 78 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 82
00 00 10 02 01 af e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 37 01 c0 2d 08 01 02 f5 e0 21 08 02 08 11 12 13 14 15 16 17 18 11 22 33 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 a5 85 76
-result (ATTACH REQUEST (IMSI)) = 82
+result (ATTACH REQUEST (IMSI)) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -5925,7 +6165,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 88 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 92
00 00 10 02 00 af e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 9e 41 c0 21 08 02 01 49 04 21 63 54 40 50 60 19 cd d7 08 17 16 18 05 f4 ef e2 b7 00 cf 80 6e
-result (ATTACH ACCEPT) = 92
+result (ATTACH ACCEPT) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -5947,7 +6187,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 31 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 35
00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 31 08 03 fc 2b 11
-result (ATTACH COMPLETE) = 35
+result (ATTACH COMPLETE) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -5969,7 +6209,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 69 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 73
00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 8b 41 c0 25 08 05 02 25 0a 8e ee 85
-result (DETACH REQ) = 73
+result (DETACH REQ) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -5991,7 +6231,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 31 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 35
00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 35 08 06 f3 c6 26
-result (DETACH ACC) = 35
+result (DETACH ACC) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -6013,7 +6253,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 75 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 79
00 00 10 02 01 af e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 34 01 c0 39 08 01 02 f5 e0 21 08 02 05 f4 ef e2 b7 00 11 22 33 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 e4 85 12
-result (ATTACH REQUEST) = 79
+result (ATTACH REQUEST) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -6035,7 +6275,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 88 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 92
00 00 10 02 00 af e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 9e 41 c0 29 08 02 01 49 04 21 63 54 40 50 60 19 cd d7 08 17 16 18 05 f4 ef e2 b7 00 d2 d1 3e
-result (ATTACH ACCEPT) = 92
+result (ATTACH ACCEPT) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -6057,7 +6297,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 31 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 35
00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 3d 08 03 48 76 ea
-result (ATTACH COMPLETE) = 35
+result (ATTACH COMPLETE) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -6079,7 +6319,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 85 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 89
00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 70 80 00 80 0e 00 3e 01 c0 41 08 08 10 11 22 33 40 50 60 1d 19 13 42 33 57 2b f7 c8 48 02 13 48 50 c8 48 02 14 48 50 c8 48 02 17 49 10 c8 48 02 00 19 8b b2 92 17 16 27 07 04 31 02 e5 e0 32 02 20 00 30 73 32
-result (RA UPD REQ) = 89
+result (RA UPD REQ) = 0
PROCESSING RA UDP REJ from 0x05060708:32000
00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 8a 41 c0 2d 08 0b 0a 00 41 30 a7
@@ -6091,7 +6331,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 68 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 72
00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 8a 41 c0 2d 08 0b 0a 00 41 30 a7
-result (RA UDP REJ) = 72
+result (RA UDP REJ) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -6164,7 +6404,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 88 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 92
00 00 10 02 00 af e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 9e 41 c0 31 08 02 01 49 04 21 63 54 40 50 60 19 cd d7 08 17 16 18 05 f4 ef e2 b7 00 f5 22 ce
-result (ATTACH ACCEPT) = 92
+result (ATTACH ACCEPT) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -6188,7 +6428,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 31 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 35
00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 4d 08 03 79 84 ea
-result (ATTACH COMPLETE) = 35
+result (ATTACH COMPLETE) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -6212,7 +6452,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 69 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 73
00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 8b 41 c0 35 08 05 02 25 0a 9b fa 57
-result (DETACH REQ) = 73
+result (DETACH REQ) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -6236,7 +6476,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 31 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 35
00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 51 08 06 a5 d9 70
-result (DETACH ACC) = 35
+result (DETACH ACC) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -6260,7 +6500,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 75 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 79
00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 34 01 c0 55 08 01 02 f5 e0 21 08 02 05 f4 ef e2 b7 00 11 22 33 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 f9 cc e9
-result (ATTACH REQUEST (local TLLI)) = 79
+result (ATTACH REQUEST (local TLLI)) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -6284,7 +6524,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 88 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 92
00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 9e 41 c0 39 08 02 01 49 04 21 63 54 40 50 60 19 cd d7 08 17 16 18 05 f4 ef e2 b7 00 e8 73 9e
-result (ATTACH ACCEPT) = 92
+result (ATTACH ACCEPT) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -6308,7 +6548,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 31 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 35
00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 59 08 03 1e 69 bc
-result (ATTACH COMPLETE) = 35
+result (ATTACH COMPLETE) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -6332,7 +6572,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 69 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 73
00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 8b 41 c0 3d 08 05 01 25 0a 21 a2 ad
-result (DETACH REQ (re-attach)) = 73
+result (DETACH REQ (re-attach)) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -6356,7 +6596,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 31 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 35
00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 5d 08 06 11 84 8b
-result (DETACH ACC) = 35
+result (DETACH ACC) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -6380,7 +6620,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 75 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 79
00 00 10 02 01 af e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 34 01 c0 61 08 01 02 f5 e0 21 08 02 05 f4 ef e2 b7 00 11 22 33 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 5b 66 e2
-result (ATTACH REQUEST) = 79
+result (ATTACH REQUEST) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -6404,7 +6644,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 88 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 92
00 00 10 02 00 af e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 9e 41 c0 41 08 02 01 49 04 21 63 54 40 50 60 19 cd d7 08 17 16 18 05 f4 ef e2 b7 00 9e 50 40
-result (ATTACH ACCEPT) = 92
+result (ATTACH ACCEPT) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -6428,7 +6668,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 31 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 35
00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 65 08 03 b7 5e 47
-result (ATTACH COMPLETE) = 35
+result (ATTACH COMPLETE) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -6452,7 +6692,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 66 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 70
00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 88 41 c0 45 08 21 9c 7f c6
-result (GMM INFO) = 70
+result (GMM INFO) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -6476,7 +6716,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 78 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 82
00 00 10 02 01 af e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 37 01 c0 69 08 01 02 f5 e0 21 08 02 08 11 12 13 14 15 16 17 18 11 22 33 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 e1 11 8e
-result (ATTACH REQUEST (unexpected, IMSI)) = 82
+result (ATTACH REQUEST (unexpected, IMSI)) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -6500,7 +6740,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 88 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 92
00 00 10 02 00 af e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 9e 41 c0 49 08 02 01 49 04 21 63 54 40 50 60 19 cd d7 08 17 16 18 05 f4 ef e2 b7 00 83 01 10
-result (ATTACH ACCEPT) = 92
+result (ATTACH ACCEPT) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -6524,7 +6764,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 31 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 35
00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 6d 08 03 6f c8 ea
-result (ATTACH COMPLETE) = 35
+result (ATTACH COMPLETE) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -6548,7 +6788,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 69 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 73
00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 8b 41 c0 4d 08 05 02 25 0a 51 0e 1b
-result (DETACH REQ) = 73
+result (DETACH REQ) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -6572,7 +6812,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 31 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 35
00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 71 08 06 b3 95 70
-result (DETACH ACC) = 35
+result (DETACH ACC) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -6596,7 +6836,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 75 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 79
00 00 10 02 01 af e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 34 01 c0 75 08 01 02 f5 e0 21 08 02 05 f4 ef e2 b7 00 11 22 33 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 ab 17 53
-result (ATTACH REQUEST) = 79
+result (ATTACH REQUEST) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -6620,7 +6860,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 88 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 92
00 00 10 02 00 af e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 9e 41 c0 51 08 02 01 49 04 21 63 54 40 50 60 19 cd d7 08 17 16 18 05 f4 ef e2 b7 00 a4 f2 e0
-result (ATTACH ACCEPT) = 92
+result (ATTACH ACCEPT) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -6644,7 +6884,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 31 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 35
00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 79 08 03 08 25 bc
-result (ATTACH COMPLETE) = 35
+result (ATTACH COMPLETE) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -6668,7 +6908,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 66 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 70
00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 88 41 c0 55 08 21 97 59 c6
-result (GMM INFO) = 70
+result (GMM INFO) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -6692,7 +6932,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 75 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 79
00 00 10 02 01 af e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 34 01 c0 7d 08 01 02 f5 e0 21 08 02 05 f4 ef e2 b7 00 11 22 33 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 a2 24 d0
-result (ATTACH REQUEST (unexpected)) = 79
+result (ATTACH REQUEST (unexpected)) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -6716,7 +6956,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 88 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 92
00 00 10 02 00 af e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 9e 41 c0 59 08 02 01 49 04 21 63 54 40 50 60 19 cd d7 08 17 16 18 05 f4 ef e2 b7 00 b9 a3 b0
-result (ATTACH ACCEPT) = 92
+result (ATTACH ACCEPT) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -6740,7 +6980,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 31 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 35
00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 81 08 03 b9 71 10
-result (ATTACH COMPLETE) = 35
+result (ATTACH COMPLETE) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -6764,7 +7004,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 69 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 73
00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 8b 41 c0 5d 08 05 02 25 0a 44 1a c9
-result (DETACH REQ) = 73
+result (DETACH REQ) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -6788,7 +7028,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 31 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 35
00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 85 08 06 b6 9c 27
-result (DETACH ACC) = 35
+result (DETACH ACC) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -6860,7 +7100,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 67 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 71
00 00 10 02 00 af e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 89 41 c0 61 08 04 07 79 ba a5
-result (ATTACH REJECT) = 71
+result (ATTACH REJECT) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -6958,7 +7198,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 69 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 73
00 00 10 02 00 af e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 8b 41 c0 65 08 05 02 25 0a 17 a2 20
-result (DETACH REQ (MT)) = 73
+result (DETACH REQ (MT)) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -6987,7 +7227,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 31 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 35
00 00 10 02 01 af e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 12 34 00 80 0e 00 08 01 c0 9d 08 06 65 2c 8a
-result (DETACH ACC) = 35
+result (DETACH ACC) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
@@ -7009,7 +7249,7 @@ Test TLLI replacement:
Add TLLI 1, IMSI 1
Add TLLI 2, IMSI 1 (should replace TLLI 1)
Peers:
- NSEI 0, BVCI 20, not blocked, RAI 0-0-0-0
+ NSEI 0, BVCI 20, not blocked, RAI 000-000-0-0
TLLI cache size : 1
TLLI-Cache: 1
TLLI c000162e, IMSI 03242526, AGE 0, IMSI matches
@@ -7018,7 +7258,7 @@ Test IMSI replacement:
Add TLLI 1, IMSI 1
Add TLLI 1, IMSI 2 (should replace IMSI 1)
Peers:
- NSEI 0, BVCI 20, not blocked, RAI 0-0-0-0
+ NSEI 0, BVCI 20, not blocked, RAI 000-000-0-0
TLLI cache size : 1
TLLI-Cache: 1
TLLI c00004d2, IMSI 06272829, AGE 0, IMSI matches
@@ -7027,7 +7267,7 @@ Test TLLI expiry, max_len == 1:
Add TLLI 1, IMSI 1
Add TLLI 2, IMSI 2 (should replace IMSI 1)
Peers:
- NSEI 0, BVCI 20, not blocked, RAI 0-0-0-0
+ NSEI 0, BVCI 20, not blocked, RAI 000-000-0-0
TLLI cache size : 1
TLLI-Cache: 1
TLLI c000162e, IMSI 06272829, AGE 0, IMSI matches
@@ -7036,7 +7276,7 @@ Test TLLI expiry, max_age == 1:
Add TLLI 1, IMSI 1 (should expire after timeout)
Add TLLI 2, IMSI 2 (should not expire after timeout)
Peers:
- NSEI 0, BVCI 20, not blocked, RAI 0-0-0-0
+ NSEI 0, BVCI 20, not blocked, RAI 000-000-0-0
TLLI cache size : 1
TLLI-Cache: 1
TLLI c000162e, IMSI 06272829, AGE 1, IMSI matches
@@ -7046,7 +7286,7 @@ Test TLLI expiry, max_len == 2, max_age == 1:
Add TLLI 2, IMSI 2 (should expire after timeout)
Add TLLI 3, IMSI 3 (should not expire after timeout)
Peers:
- NSEI 0, BVCI 20, not blocked, RAI 0-0-0-0
+ NSEI 0, BVCI 20, not blocked, RAI 000-000-0-0
TLLI cache size : 3
TLLI-Cache: 3
TLLI c0000d80, IMSI 12345678, AGE 0, IMSI matches
@@ -7054,7 +7294,7 @@ Test TLLI expiry, max_len == 2, max_age == 1:
TLLI c00004d2, IMSI 03242526, AGE 2, IMSI matches
Remove stale TLLIs
Peers:
- NSEI 0, BVCI 20, not blocked, RAI 0-0-0-0
+ NSEI 0, BVCI 20, not blocked, RAI 000-000-0-0
TLLI cache size : 1
TLLI-Cache: 1
TLLI c0000d80, IMSI 12345678, AGE 0, IMSI matches
@@ -7071,7 +7311,7 @@ PROCESSING RESET_ACK from 0x05060708:32000
MESSAGE to SGSN at 0x05060708:32000, msg length 1
0a
-result (RESET_ACK) = 1
+result (RESET_ACK) = 0
PROCESSING ALIVE_ACK from 0x05060708:32000
0b
@@ -7079,7 +7319,7 @@ PROCESSING ALIVE_ACK from 0x05060708:32000
MESSAGE to SGSN at 0x05060708:32000, msg length 1
06
-result (ALIVE_ACK) = 1
+result (ALIVE_ACK) = 0
PROCESSING UNBLOCK_ACK from 0x05060708:32000
07
@@ -7094,7 +7334,7 @@ PROCESSING ALIVE from 0x05060708:32000
MESSAGE to SGSN at 0x05060708:32000, msg length 1
0b
-result (ALIVE) = 1
+result (ALIVE) = 0
--- Initialise BSS 1 ---
@@ -7111,7 +7351,7 @@ MESSAGE to BSS at 0x01020304:1111, msg length 9
MESSAGE to BSS at 0x01020304:1111, msg length 1
0a
-result (RESET) = 9
+result (RESET) = 0
PROCESSING ALIVE from 0x01020304:1111
0a
@@ -7119,17 +7359,17 @@ PROCESSING ALIVE from 0x01020304:1111
MESSAGE to BSS at 0x01020304:1111, msg length 1
0b
-result (ALIVE) = 1
+result (ALIVE) = 0
PROCESSING UNBLOCK from 0x01020304:1111
06
-==> got signal NS_UNBLOCK, NS-VC 0x1001/1.2.3.4:1111
-
MESSAGE to BSS at 0x01020304:1111, msg length 1
07
-result (UNBLOCK) = 1
+==> got signal NS_UNBLOCK, NS-VC 0x1001/1.2.3.4:1111
+
+result (UNBLOCK) = 0
PROCESSING ALIVE_ACK from 0x01020304:1111
0b
@@ -7148,7 +7388,7 @@ NS UNITDATA MESSAGE to SGSN, BVCI 0x0000, msg length 18 (gprs_ns_sendmsg)
MESSAGE to SGSN at 0x05060708:32000, msg length 22
00 00 00 00 22 04 82 10 02 07 81 08 08 88 11 22 33 40 50 60 10 00
-result (BVC_RESET) = 22
+result (BVC_RESET) = 0
PROCESSING BVC_RESET_ACK from 0x05060708:32000
00 00 00 00 23 04 82 10 02
@@ -7160,11 +7400,19 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x0000, msg length 5 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 9
00 00 00 00 23 04 82 10 02
-result (BVC_RESET_ACK) = 9
+result (BVC_RESET_ACK) = 0
Current NS-VCIs:
VCI 0x1001, NSEI 0x1000, peer 0x01020304:1111
+ Packets at NS Level ( In): 5
+ Packets at NS Level (Out): 5
+ Bytes at NS Level ( In): 37
+ Bytes at NS Level (Out): 21
VCI 0x0101, NSEI 0x0100, peer 0x05060708:32000
+ Packets at NS Level ( In): 5
+ Packets at NS Level (Out): 5
+ Bytes at NS Level ( In): 21
+ Bytes at NS Level (Out): 37
NS-VC Block count : 1
Gbproxy global:
@@ -7201,7 +7449,7 @@ NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 23 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 27
00 00 10 02 00 80 00 de ad 00 50 20 16 82 02 58 0e 89 41 c0 01 08 15 01 ff 6c ba
-result (IDENT REQUEST) = 27
+result (IDENT REQUEST) = 0
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
diff --git a/tests/gprs/gprs_test.c b/tests/gprs/gprs_test.c
index aac9bb896..99e3ea519 100644
--- a/tests/gprs/gprs_test.c
+++ b/tests/gprs/gprs_test.c
@@ -2,10 +2,10 @@
#include <stdlib.h>
#include <inttypes.h>
-#include <openbsc/gprs_llc.h>
-#include <openbsc/gprs_utils.h>
+#include <osmocom/sgsn/gprs_llc.h>
+#include <osmocom/sgsn/gprs_utils.h>
-#include <openbsc/debug.h>
+#include <osmocom/sgsn/debug.h>
#include <osmocom/core/application.h>
#include <osmocom/gsm/gsup.h>
@@ -130,7 +130,8 @@ static struct log_info info = {
int main(int argc, char **argv)
{
- osmo_init_logging(&info);
+ void *ctx = talloc_named_const(NULL, 0, "gprs_test");
+ osmo_init_logging2(ctx, &info);
test_8_4_2();
test_gprs_timer_enc_dec();
diff --git a/tests/gtphub/Makefile.am b/tests/gtphub/Makefile.am
index f2a6b888e..fea01e0d1 100644
--- a/tests/gtphub/Makefile.am
+++ b/tests/gtphub/Makefile.am
@@ -16,13 +16,9 @@ EXTRA_DIST = \
gtphub_test.ok \
$(NULL)
-if HAVE_LIBGTP
-if HAVE_LIBCARES
noinst_PROGRAMS = \
gtphub_test \
$(NULL)
-endif
-endif
gtphub_test_SOURCES = \
gtphub_test.c \
@@ -35,7 +31,7 @@ gtphub_test_LDFLAGS = \
$(NULL)
gtphub_test_LDADD = \
- $(top_builddir)/src/gprs/gtphub.o \
+ $(top_builddir)/src/gtphub/gtphub.o \
$(top_builddir)/src/gprs/gprs_utils.o \
$(LIBOSMOCORE_LIBS) \
$(LIBOSMOGSM_LIBS) \
diff --git a/tests/gtphub/gtphub_test.c b/tests/gtphub/gtphub_test.c
index e7c27d2cb..ed4617624 100644
--- a/tests/gtphub/gtphub_test.c
+++ b/tests/gtphub/gtphub_test.c
@@ -28,9 +28,9 @@
#include <osmocom/core/utils.h>
#include <osmocom/core/application.h>
-#include <openbsc/debug.h>
+#include <osmocom/sgsn/debug.h>
-#include <openbsc/gtphub.h>
+#include <osmocom/sgsn/gtphub.h>
#include <gtp.h>
#include <gtpie.h>
@@ -54,7 +54,7 @@
void gtphub_init(struct gtphub *hub);
void gtphub_free(struct gtphub *hub);
-void *osmo_gtphub_ctx;
+extern void *osmo_gtphub_ctx;
static void nr_mapping_free(struct expiring_item *e)
{
@@ -1762,8 +1762,9 @@ static struct log_info info = {
int main(int argc, char **argv)
{
- osmo_init_logging(&info);
osmo_gtphub_ctx = talloc_named_const(NULL, 0, "osmo_gtphub");
+ void *log_ctx = talloc_named_const(osmo_gtphub_ctx, 0, "log");
+ osmo_init_logging2(log_ctx, &info);
test_nr_map_basic();
test_nr_map_wrap();
@@ -1780,7 +1781,9 @@ int main(int argc, char **argv)
printf("Done\n");
talloc_report_full(osmo_gtphub_ctx, stderr);
+ talloc_free(log_ctx);
OSMO_ASSERT(talloc_total_blocks(osmo_gtphub_ctx) == 1);
+ talloc_free(osmo_gtphub_ctx);
return 0;
}
diff --git a/tests/oap/Makefile.am b/tests/oap/Makefile.am
deleted file mode 100644
index 5f8bbc5c2..000000000
--- a/tests/oap/Makefile.am
+++ /dev/null
@@ -1,36 +0,0 @@
-AM_CPPFLAGS = \
- $(all_includes) \
- -I$(top_srcdir)/include \
- $(NULL)
-
-AM_CFLAGS = \
- -Wall \
- -ggdb3 \
- $(LIBOSMOCORE_CFLAGS) \
- $(LIBOSMOGSM_CFLAGS) \
- $(NULL)
-
-EXTRA_DIST = \
- oap_client_test.ok \
- oap_client_test.err \
- $(NULL)
-
-if HAVE_LIBGTP
-if HAVE_LIBCARES
-noinst_PROGRAMS = \
- oap_client_test \
- $(NULL)
-endif
-endif
-
-oap_client_test_SOURCES = \
- oap_client_test.c \
- $(NULL)
-
-oap_client_test_LDADD = \
- $(top_builddir)/src/gprs/gprs_utils.o \
- $(top_builddir)/src/gprs/oap_client.o \
- $(LIBOSMOCORE_LIBS) \
- $(LIBOSMOGSM_LIBS) \
- -lrt
-
diff --git a/tests/oap/oap_client_test.c b/tests/oap/oap_client_test.c
deleted file mode 100644
index e6501cb6d..000000000
--- a/tests/oap/oap_client_test.c
+++ /dev/null
@@ -1,270 +0,0 @@
-/* Test Osmocom Authentication Protocol */
-/*
- * (C) 2015 by sysmocom s.f.m.c. GmbH
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * 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 Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#include <osmocom/core/application.h>
-#include <osmocom/gsm/oap.h>
-
-#include <openbsc/debug.h>
-#include <openbsc/oap_client.h>
-
-#include <stdio.h>
-#include <string.h>
-
-static void test_oap_api(void)
-{
- printf("Testing OAP API\n");
-
- struct oap_client_config _config;
- struct oap_client_config *config = &_config;
-
- struct oap_client_state _state;
- struct oap_client_state *state = &_state;
-
- struct osmo_oap_message oap_rx;
- struct msgb *msg_rx;
-
- struct osmo_oap_message oap_tx;
- struct msgb *msg_tx;
-
- memset(config, 0, sizeof(*config));
- memset(state, 0, sizeof(*state));
-
- OSMO_ASSERT(osmo_hexparse("0102030405060708090a0b0c0d0e0f10", config->secret_k, 16) == 16);
- OSMO_ASSERT(osmo_hexparse("1112131415161718191a1b1c1d1e1f20", config->secret_opc, 16) == 16);
-
- fprintf(stderr, "- make sure filling with zeros means uninitialized\n");
- OSMO_ASSERT(state->state == OAP_UNINITIALIZED);
-
- fprintf(stderr, "- reject messages in uninitialized state\n");
- memset(&oap_rx, 0, sizeof(oap_rx));
- state->client_id = 1;
- oap_rx.message_type = OAP_MSGT_REGISTER_ERROR;
- msg_rx = oap_client_encoded(&oap_rx);
- OSMO_ASSERT(oap_client_handle(state, msg_rx, &msg_tx) < 0);
- OSMO_ASSERT(state->state == OAP_UNINITIALIZED);
- msgb_free(msg_rx);
- OSMO_ASSERT(!msg_tx);
-
- fprintf(stderr, "- NULL config should disable\n");
- OSMO_ASSERT( oap_client_init(NULL, state) == 0 );
- OSMO_ASSERT(state->state == OAP_DISABLED);
-
- fprintf(stderr, "- reject messages in disabled state\n");
- memset(state, 0, sizeof(*state));
- memset(&oap_rx, 0, sizeof(oap_rx));
- state->state = OAP_DISABLED;
- state->client_id = 1;
- oap_rx.message_type = OAP_MSGT_REGISTER_ERROR;
- msg_rx = oap_client_encoded(&oap_rx);
- OSMO_ASSERT(oap_client_handle(state, msg_rx, &msg_tx) < 0);
- OSMO_ASSERT(state->state == OAP_DISABLED);
- msgb_free(msg_rx);
- OSMO_ASSERT(!msg_tx);
-
- fprintf(stderr, "- invalid client_id and shared secret\n");
- memset(state, 0, sizeof(*state));
- config->client_id = 0;
- config->secret_k_present = 0;
- config->secret_opc_present = 0;
- OSMO_ASSERT( oap_client_init(config, state) == 0 );
- OSMO_ASSERT(state->state == OAP_DISABLED);
-
- fprintf(stderr, "- reset state\n");
- memset(state, 0, sizeof(*state));
-
- fprintf(stderr, "- only client_id is invalid\n");
- config->client_id = 0;
- config->secret_k_present = 1;
- config->secret_opc_present = 1;
- OSMO_ASSERT( oap_client_init(config, state) == 0 );
- OSMO_ASSERT(state->state == OAP_DISABLED);
-
- memset(state, 0, sizeof(*state));
-
- fprintf(stderr, "- valid id, but omitted shared_secret (1/2)\n");
- config->client_id = 12345;
- config->secret_k_present = 0;
- config->secret_opc_present = 1;
- OSMO_ASSERT( oap_client_init(config, state) == 0 );
- OSMO_ASSERT(state->state == OAP_DISABLED);
-
- memset(state, 0, sizeof(*state));
-
- fprintf(stderr, "- valid id, but omitted shared_secret (2/2)\n");
- config->client_id = 12345;
- config->secret_k_present = 1;
- config->secret_opc_present = 0;
- OSMO_ASSERT( oap_client_init(config, state) == 0 );
- OSMO_ASSERT(state->state == OAP_DISABLED);
-
- memset(state, 0, sizeof(*state));
-
-
- fprintf(stderr, "- mint configuration\n");
- config->client_id = 12345;
- config->secret_k_present = 1;
- config->secret_opc_present = 1;
- /*config->secret_* buffers are still set from the top */
- OSMO_ASSERT( oap_client_init(config, state) == 0 );
- OSMO_ASSERT(state->state == OAP_INITIALIZED);
-
-
- fprintf(stderr, "- Missing challenge data\n");
- memset(&oap_rx, 0, sizeof(oap_rx));
- oap_rx.message_type = OAP_MSGT_CHALLENGE_REQUEST;
- oap_rx.rand_present = 0;
- oap_rx.autn_present = 0;
- msg_rx = oap_client_encoded(&oap_rx);
- OSMO_ASSERT(oap_client_handle(state, msg_rx, &msg_tx) == -2);
- msgb_free(msg_rx);
- OSMO_ASSERT(!msg_tx);
-
- fprintf(stderr, "- AUTN missing\n");
- osmo_hexparse("0102030405060708090a0b0c0d0e0f10",
- oap_rx.rand, 16);
- oap_rx.rand_present = 1;
- msg_rx = oap_client_encoded(&oap_rx);
- OSMO_ASSERT(oap_client_handle(state, msg_rx, &msg_tx) == -2);
- msgb_free(msg_rx);
- OSMO_ASSERT(!msg_tx);
-
- fprintf(stderr, "- RAND missing\n");
- oap_rx.rand_present = 0;
- osmo_hexparse("cec4e3848a33000086781158ca40f136",
- oap_rx.autn, 16);
- oap_rx.autn_present = 1;
- msg_rx = oap_client_encoded(&oap_rx);
- OSMO_ASSERT(oap_client_handle(state, msg_rx, &msg_tx) == -2);
- msgb_free(msg_rx);
- OSMO_ASSERT(!msg_tx);
-
- fprintf(stderr, "- wrong autn (by one bit)\n");
- osmo_hexparse("0102030405060708090a0b0c0d0e0f10",
- oap_rx.rand, 16);
- osmo_hexparse("dec4e3848a33000086781158ca40f136",
- oap_rx.autn, 16);
- oap_rx.rand_present = 1;
- oap_rx.autn_present = 1;
- msg_rx = oap_client_encoded(&oap_rx);
- OSMO_ASSERT(oap_client_handle(state, msg_rx, &msg_tx) == -2);
- msgb_free(msg_rx);
- OSMO_ASSERT(!msg_tx);
-
- fprintf(stderr, "- all data correct\n");
- osmo_hexparse("cec4e3848a33000086781158ca40f136",
- oap_rx.autn, 16);
- msg_rx = oap_client_encoded(&oap_rx);
-
- fprintf(stderr, "- but refuse to evaluate in uninitialized state\n");
- OSMO_ASSERT(state->state == OAP_INITIALIZED);
-
- state->state = OAP_UNINITIALIZED;
- OSMO_ASSERT(oap_client_handle(state, msg_rx, &msg_tx) < 0);
- OSMO_ASSERT(!msg_tx);
-
- state->state = OAP_DISABLED;
- OSMO_ASSERT(oap_client_handle(state, msg_rx, &msg_tx) < 0);
- OSMO_ASSERT(!msg_tx);
-
- state->state = OAP_INITIALIZED;
-
- fprintf(stderr, "- now everything is correct\n");
- /* a successful return value here indicates correct autn */
- OSMO_ASSERT(oap_client_handle(state, msg_rx, &msg_tx) == 0);
- msgb_free(msg_rx);
-
- fprintf(stderr, "- Expect the challenge response in msg_tx\n");
- OSMO_ASSERT(msg_tx);
- OSMO_ASSERT(osmo_oap_decode(&oap_tx, msg_tx->data, msg_tx->len) == 0);
- OSMO_ASSERT(oap_tx.message_type == OAP_MSGT_CHALLENGE_RESULT);
- OSMO_ASSERT(strcmp("e2d05b598c61d9ba",
- osmo_hexdump_nospc(oap_tx.xres, sizeof(oap_tx.xres)))
- == 0);
- OSMO_ASSERT(state->state == OAP_SENT_CHALLENGE_RESULT);
- msgb_free(msg_tx);
- msg_tx = 0;
-
- struct oap_client_state saved_state = _state;
-
- fprintf(stderr, "- Receive registration error for the first time.\n");
-
- memset(&oap_rx, 0, sizeof(oap_rx));
- oap_rx.message_type = OAP_MSGT_REGISTER_ERROR;
- oap_rx.cause = GMM_CAUSE_PROTO_ERR_UNSPEC;
- msg_rx = oap_client_encoded(&oap_rx);
-
- OSMO_ASSERT(state->registration_failures == 0);
- OSMO_ASSERT(oap_client_handle(state, msg_rx, &msg_tx) == 0);
- OSMO_ASSERT(state->registration_failures == 1);
- OSMO_ASSERT(msg_tx);
- OSMO_ASSERT(osmo_oap_decode(&oap_tx, msg_tx->data, msg_tx->len) == 0);
- OSMO_ASSERT(oap_tx.message_type == OAP_MSGT_REGISTER_REQUEST);
- OSMO_ASSERT(state->state == OAP_REQUESTED_CHALLENGE);
- msgb_free(msg_tx);
- msg_tx = 0;
-
- fprintf(stderr, "- Receive registration error for the Nth time.\n");
- state->registration_failures = 999;
- OSMO_ASSERT(oap_client_handle(state, msg_rx, &msg_tx) == -11);
- OSMO_ASSERT(!msg_tx);
- OSMO_ASSERT(state->state == OAP_INITIALIZED);
- msgb_free(msg_tx);
- msg_tx = 0;
-
- msgb_free(msg_rx);
-
- fprintf(stderr, "- Registration success\n");
-
- _state = saved_state;
- memset(&oap_rx, 0, sizeof(oap_rx));
- oap_rx.message_type = OAP_MSGT_REGISTER_RESULT;
- msg_rx = oap_client_encoded(&oap_rx);
- OSMO_ASSERT(oap_client_handle(state, msg_rx, &msg_tx) == 0);
- OSMO_ASSERT(!msg_tx);
- OSMO_ASSERT(state->state == OAP_REGISTERED);
- msgb_free(msg_rx);
-}
-
-static struct log_info_cat oap_client_test_categories[] = {
-};
-
-static struct log_info info = {
- .cat = oap_client_test_categories,
- .num_cat = ARRAY_SIZE(oap_client_test_categories),
-};
-
-int main(int argc, char **argv)
-{
- msgb_talloc_ctx_init(NULL, 0);
- osmo_init_logging(&info);
-
- OSMO_ASSERT(osmo_stderr_target);
- log_set_use_color(osmo_stderr_target, 0);
- log_set_print_timestamp(osmo_stderr_target, 0);
- log_set_print_filename(osmo_stderr_target, 0);
- log_set_print_category(osmo_stderr_target, 1);
- log_parse_category_mask(osmo_stderr_target, "DLOAP,1");
-
- test_oap_api();
- printf("Done\n");
-
- return 0;
-}
-
diff --git a/tests/oap/oap_client_test.err b/tests/oap/oap_client_test.err
deleted file mode 100644
index 62ddc9efa..000000000
--- a/tests/oap/oap_client_test.err
+++ /dev/null
@@ -1,35 +0,0 @@
-- make sure filling with zeros means uninitialized
-- reject messages in uninitialized state
-DLOAP Received OAP message 5, but the OAP client is not initialized
-- NULL config should disable
-- reject messages in disabled state
-DLOAP Received OAP message 5, but the OAP client is disabled
-- invalid client_id and shared secret
-- reset state
-- only client_id is invalid
-- valid id, but omitted shared_secret (1/2)
-DLOAP OAP: client ID set, but secret K missing.
-- valid id, but omitted shared_secret (2/2)
-DLOAP OAP: client ID set, but secret OPC missing.
-- mint configuration
-- Missing challenge data
-DLOAP OAP challenge incomplete (rand_present: 0, autn_present: 0)
-- AUTN missing
-DLOAP OAP challenge incomplete (rand_present: 1, autn_present: 0)
-- RAND missing
-DLOAP OAP challenge incomplete (rand_present: 0, autn_present: 1)
-- wrong autn (by one bit)
-DLOAP OAP: AUTN mismatch!
-DLOAP OAP: AUTN from server: dec4e3848a33000086781158ca40f136
-DLOAP OAP: AUTN expected: cec4e3848a33000086781158ca40f136
-- all data correct
-- but refuse to evaluate in uninitialized state
-DLOAP Received OAP message 8, but the OAP client is not initialized
-DLOAP Received OAP message 8, but the OAP client is disabled
-- now everything is correct
-- Expect the challenge response in msg_tx
-- Receive registration error for the first time.
-DLOAP OAP registration failed
-- Receive registration error for the Nth time.
-DLOAP OAP registration failed
-- Registration success
diff --git a/tests/oap/oap_client_test.ok b/tests/oap/oap_client_test.ok
deleted file mode 100644
index 59108a792..000000000
--- a/tests/oap/oap_client_test.ok
+++ /dev/null
@@ -1,2 +0,0 @@
-Testing OAP API
-Done
diff --git a/tests/sgsn/Makefile.am b/tests/sgsn/Makefile.am
index 36026dd56..b72c44634 100644
--- a/tests/sgsn/Makefile.am
+++ b/tests/sgsn/Makefile.am
@@ -9,7 +9,9 @@ AM_CFLAGS = \
$(LIBOSMOCORE_CFLAGS) \
$(LIBOSMOABIS_CFLAGS) \
$(LIBOSMOGSM_CFLAGS) \
+ $(LIBOSMOGSUPCLIENT_CFLAGS) \
$(LIBCARES_CFLAGS) \
+ $(LIBGTP_CFLAGS) \
$(NULL)
if BUILD_IU
AM_CFLAGS += \
@@ -32,42 +34,45 @@ sgsn_test_SOURCES = \
$(NULL)
sgsn_test_LDFLAGS = \
- -Wl,--wrap=RAND_bytes \
+ -Wl,--wrap=osmo_get_rand_id \
-Wl,--wrap=sgsn_update_subscriber_data \
-Wl,--wrap=gprs_subscr_request_update_location \
-Wl,--wrap=gprs_subscr_request_auth_info \
- -Wl,--wrap=gsup_client_send \
+ -Wl,--wrap=osmo_gsup_client_send \
$(NULL)
sgsn_test_LDADD = \
+ $(top_builddir)/src/sgsn/gprs_llc.o \
+ $(top_builddir)/src/sgsn/gprs_gb.o \
+ $(top_builddir)/src/sgsn/gprs_sndcp.o \
+ $(top_builddir)/src/sgsn/gprs_gmm_attach.o \
+ $(top_builddir)/src/sgsn/gprs_gmm.o \
+ $(top_builddir)/src/sgsn/gprs_gmm_fsm.o \
+ $(top_builddir)/src/sgsn/gprs_mm_state_gb_fsm.o \
+ $(top_builddir)/src/sgsn/gprs_sgsn.o \
+ $(top_builddir)/src/sgsn/sgsn_vty.o \
+ $(top_builddir)/src/sgsn/sgsn_libgtp.o \
+ $(top_builddir)/src/sgsn/sgsn_auth.o \
+ $(top_builddir)/src/sgsn/gprs_subscriber.o \
+ $(top_builddir)/src/sgsn/gprs_llc_xid.o \
+ $(top_builddir)/src/sgsn/gprs_sndcp_xid.o \
+ $(top_builddir)/src/sgsn/slhc.o \
+ $(top_builddir)/src/sgsn/gprs_sm.o \
+ $(top_builddir)/src/sgsn/gprs_sndcp_comp.o \
+ $(top_builddir)/src/sgsn/gprs_sndcp_pcomp.o \
+ $(top_builddir)/src/sgsn/v42bis.o \
+ $(top_builddir)/src/sgsn/gprs_sndcp_dcomp.o \
+ $(top_builddir)/src/gprs/gprs_utils.o \
$(top_builddir)/src/gprs/gprs_llc_parse.o \
- $(top_builddir)/src/gprs/gprs_llc.o \
+ $(top_builddir)/src/gprs/gprs_gb_parse.o \
$(top_builddir)/src/gprs/crc24.o \
- $(top_builddir)/src/gprs/gprs_sndcp.o \
- $(top_builddir)/src/gprs/gprs_gmm.o \
- $(top_builddir)/src/gprs/gprs_sgsn.o \
- $(top_builddir)/src/gprs/sgsn_vty.o \
- $(top_builddir)/src/gprs/sgsn_libgtp.o \
- $(top_builddir)/src/gprs/sgsn_auth.o \
$(top_builddir)/src/gprs/sgsn_ares.o \
- $(top_builddir)/src/gprs/gprs_utils.o \
- $(top_builddir)/src/gprs/gprs_subscriber.o \
- $(top_builddir)/src/gprs/gprs_gb_parse.o \
- $(top_builddir)/src/gprs/gprs_llc_xid.o \
- $(top_builddir)/src/gprs/gprs_sndcp_xid.o \
- $(top_builddir)/src/gprs/slhc.o \
- $(top_builddir)/src/gprs/gprs_sndcp_comp.o \
- $(top_builddir)/src/gprs/gprs_sndcp_pcomp.o \
- $(top_builddir)/src/gprs/v42bis.o \
- $(top_builddir)/src/gprs/gprs_sndcp_dcomp.o \
- $(top_builddir)/src/gprs/gsup_client.o \
- $(top_builddir)/src/gprs/oap_client.o \
$(LIBOSMOABIS_LIBS) \
$(LIBOSMOCORE_LIBS) \
$(LIBOSMOGSM_LIBS) \
$(LIBOSMOGB_LIBS) \
+ $(LIBOSMOGSUPCLIENT_LIBS) \
$(LIBCARES_LIBS) \
- $(LIBCRYPTO_LIBS) \
$(LIBGTP_LIBS) \
-lrt \
-lm \
@@ -75,6 +80,8 @@ sgsn_test_LDADD = \
if BUILD_IU
sgsn_test_LDADD += \
+ $(top_builddir)/src/sgsn/gprs_ranap.o \
+ $(top_builddir)/src/sgsn/gprs_mm_state_iu_fsm.o \
$(LIBOSMORANAP_LIBS) \
$(LIBOSMOSIGTRAN_LIBS) \
$(LIBASN1C_LIBS) \
diff --git a/tests/sgsn/sgsn_test.c b/tests/sgsn/sgsn_test.c
index d66c5dd84..7399573fc 100644
--- a/tests/sgsn/sgsn_test.c
+++ b/tests/sgsn/sgsn_test.c
@@ -19,15 +19,16 @@
*
*/
-#include <openbsc/gprs_llc.h>
-#include <openbsc/sgsn.h>
-#include <openbsc/gprs_gmm.h>
-#include <openbsc/debug.h>
-#include <openbsc/gprs_subscriber.h>
+#include <osmocom/sgsn/gprs_llc.h>
+#include <osmocom/sgsn/sgsn.h>
+#include <osmocom/sgsn/gprs_gmm.h>
+#include <osmocom/sgsn/debug.h>
+#include <osmocom/sgsn/gprs_subscriber.h>
#include <osmocom/gsm/gsup.h>
-#include <openbsc/gsup_client.h>
-#include <openbsc/gprs_utils.h>
-#include <openbsc/gprs_gb_parse.h>
+#include <osmocom/gsupclient/gsup_client.h>
+#include <osmocom/sgsn/gprs_utils.h>
+#include <osmocom/sgsn/gprs_gb_parse.h>
+#include <osmocom/sgsn/gprs_gmm_fsm.h>
#include <osmocom/gprs/gprs_bssgp.h>
@@ -37,10 +38,11 @@
#include <osmocom/core/msgb.h>
#include <osmocom/core/rate_ctr.h>
#include <osmocom/core/utils.h>
+#include <osmocom/vty/vty.h>
#include <stdio.h>
-void *tall_bsc_ctx;
+void *tall_sgsn_ctx;
static struct sgsn_instance sgsn_inst = {
.config_file = "osmo_sgsn.cfg",
.cfg = {
@@ -100,21 +102,21 @@ int bssgp_tx_dl_ud(struct msgb *msg, uint16_t pdu_lifetime,
return 0;
}
-/* override, requires '-Wl,--wrap=RAND_bytes' */
-int __real_RAND_bytes(unsigned char *buf, int num);
-int mock_RAND_bytes(unsigned char *buf, int num);
-int (*RAND_bytes_cb)(unsigned char *, int) =
- &mock_RAND_bytes;
+/* override, requires '-Wl,--wrap=osmo_get_rand_id' */
+int __real_osmo_get_rand_id(uint8_t *data, size_t len);
+int mock_osmo_get_rand_id(uint8_t *data, size_t len);
+int (*osmo_get_rand_id_cb)(uint8_t *, size_t) =
+ &mock_osmo_get_rand_id;
-int __wrap_RAND_bytes(unsigned char *buf, int num)
+int __wrap_osmo_get_rand_id(uint8_t *buf, size_t num)
{
- return (*RAND_bytes_cb)(buf, num);
+ return (*osmo_get_rand_id_cb)(buf, num);
}
/* make results of A&C ref predictable */
-int mock_RAND_bytes(unsigned char *buf, int num)
+int mock_osmo_get_rand_id(uint8_t *buf, size_t num)
{
if (num > 1)
- return __real_RAND_bytes(buf, num);
+ return __real_osmo_get_rand_id(buf, num);
buf[0] = 0;
return 1;
}
@@ -148,13 +150,13 @@ int __wrap_gprs_subscr_request_auth_info(struct sgsn_mm_ctx *mmctx, const uint8_
};
/* override, requires '-Wl,--wrap=gsup_client_send' */
-int __real_gsup_client_send(struct gsup_client *gsupc, struct msgb *msg);
-int (*gsup_client_send_cb)(struct gsup_client *gsupc, struct msgb *msg) =
- &__real_gsup_client_send;
+int __real_osmo_gsup_client_send(struct osmo_gsup_client *gsupc, struct msgb *msg);
+int (*osmo_gsup_client_send_cb)(struct osmo_gsup_client *gsupc, struct msgb *msg) =
+ &__real_osmo_gsup_client_send;
-int __wrap_gsup_client_send(struct gsup_client *gsupc, struct msgb *msg)
+int __wrap_osmo_gsup_client_send(struct osmo_gsup_client *gsupc, struct msgb *msg)
{
- return (*gsup_client_send_cb)(gsupc, msg);
+ return (*osmo_gsup_client_send_cb)(gsupc, msg);
};
static int count(struct llist_head *head)
@@ -165,7 +167,7 @@ static int count(struct llist_head *head)
llist_for_each(cur, head)
count += 1;
- return count;
+ return count;
}
static struct msgb *create_msg(const uint8_t *data, size_t len)
@@ -191,7 +193,6 @@ static struct sgsn_mm_ctx *alloc_mm_ctx(uint32_t tlli, struct gprs_ra_id *raid)
lle = gprs_lle_get_or_create(tlli, 3);
ctx = sgsn_mm_ctx_alloc_gb(tlli, raid);
- ctx->gmm_state = GMM_REGISTERED_NORMAL;
ctx->gb.llme = lle->llme;
ictx = sgsn_mm_ctx_by_tlli(tlli, raid);
@@ -729,7 +730,7 @@ static void test_subscriber_gsup(void)
cleanup_test();
}
-int my_gsup_client_send_dummy(struct gsup_client *gsupc, struct msgb *msg)
+int my_gsup_client_send_dummy(struct osmo_gsup_client *gsupc, struct msgb *msg)
{
msgb_free(msg);
return 0;
@@ -925,167 +926,8 @@ static void test_gmm_status_no_mmctx(void)
cleanup_test();
}
-/*
- * Test the GMM Attach procedure
- */
-static void test_gmm_attach(int retry)
+int my_subscr_request_update_location(struct sgsn_mm_ctx *mmctx)
{
- struct gprs_ra_id raid = { 0, };
- struct sgsn_mm_ctx *ctx = NULL;
- struct sgsn_mm_ctx *ictx;
- uint32_t ptmsi1;
- uint32_t foreign_tlli;
- uint32_t local_tlli = 0;
- struct gprs_llc_lle *lle;
-
- /* DTAP - Attach Request */
- /* The P-TMSI is not known by the SGSN */
- static const unsigned char attach_req[] = {
- 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x05, 0xf4,
- 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
- 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60,
- 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
- 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
- };
-
- /* DTAP - Identity Response IMEI */
- static const unsigned char ident_resp_imei[] = {
- 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
- 0x56
- };
-
- /* DTAP - Identity Response IMSI */
- static const unsigned char ident_resp_imsi[] = {
- 0x08, 0x16, 0x08, 0x19, 0x32, 0x54, 0x76, 0x98, 0x10, 0x32,
- 0x54
- };
-
- /* DTAP - Authentication and Ciphering Resp */
- static const unsigned char auth_ciph_resp[] = {
- 0x08, 0x13, 0x00, 0x22, 0x51, 0xe5, 0x51, 0xe5, 0x23, 0x09,
- 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x01
- };
-
- /* DTAP - Attach Complete */
- static const unsigned char attach_compl[] = {
- 0x08, 0x03
- };
-
- /* DTAP - Detach Request (MO) */
- /* normal detach, power_off = 0 */
- static const unsigned char detach_req[] = {
- 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xeb, 0x8b,
- 0x45, 0x67, 0x19, 0x03, 0xb9, 0x97, 0xcb
- };
-
- printf("Testing GMM attach%s\n", retry ? " with retry" : "");
-
- foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
-
- /* Create a LLE/LLME */
- OSMO_ASSERT(count(gprs_llme_list()) == 0);
- lle = gprs_lle_get_or_create(foreign_tlli, 3);
- OSMO_ASSERT(count(gprs_llme_list()) == 1);
-
- /* inject the attach request */
- send_0408_message(lle->llme, foreign_tlli, &raid,
- attach_req, ARRAY_SIZE(attach_req));
-
- ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
- OSMO_ASSERT(ctx != NULL);
- OSMO_ASSERT(ctx->gmm_state == GMM_COMMON_PROC_INIT);
-
- /* we expect an identity request (IMEI) */
- OSMO_ASSERT(sgsn_tx_counter == 1);
-
- /* inject the identity response (IMEI) */
- send_0408_message(ctx->gb.llme, foreign_tlli, &raid,
- ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
-
- /* we expect an identity request (IMSI) */
- OSMO_ASSERT(sgsn_tx_counter == 1);
-
- /* inject the identity response (IMSI) */
- send_0408_message(ctx->gb.llme, foreign_tlli, &raid,
- ident_resp_imsi, ARRAY_SIZE(ident_resp_imsi));
-
- /* check that the MM context has not been removed due to a failed
- * authorization */
- OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
-
- OSMO_ASSERT(ctx->gmm_state == GMM_COMMON_PROC_INIT);
-
-retry_attach_req:
-
- if (retry && sgsn_tx_counter == 0) {
- fprintf(stderr, "Retrying attach request\n");
- /* re-inject the attach request */
- send_0408_message(lle->llme, foreign_tlli, &raid,
- attach_req, ARRAY_SIZE(attach_req));
- }
-
- if (ctx->auth_state == SGSN_AUTH_AUTHENTICATE && sgsn_tx_counter == 1) {
- /* we got an auth & ciph request */
-
- /* inject the auth & ciph response */
- send_0408_message(ctx->gb.llme, foreign_tlli, &raid,
- auth_ciph_resp, ARRAY_SIZE(auth_ciph_resp));
-
- /* check that the MM context has not been removed due to a
- * failed authorization */
- OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
- if (ctx->subscr && ctx->subscr->sgsn_data->msisdn_len > 0)
- OSMO_ASSERT(strcmp(ctx->msisdn, "+49166213323") == 0);
- }
-
- if (retry && sgsn_tx_counter == 0)
- goto retry_attach_req;
-
- /* we expect an attach accept/reject */
- OSMO_ASSERT(sgsn_tx_counter == 1);
- ptmsi1 = get_new_ptmsi(&last_dl_parse_ctx);
- OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
-
- /* this has been randomly assigned by the SGSN */
- local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
-
- /* inject the attach complete */
- send_0408_message(ctx->gb.llme, local_tlli, &raid,
- attach_compl, ARRAY_SIZE(attach_compl));
-
- OSMO_ASSERT(ctx->gmm_state == GMM_REGISTERED_NORMAL);
-
- /* we don't expect a response */
- OSMO_ASSERT(sgsn_tx_counter == 0);
-
- /* inject the detach */
- send_0408_message(ctx->gb.llme, local_tlli, &raid,
- detach_req, ARRAY_SIZE(detach_req));
-
- /* verify that things are gone */
- OSMO_ASSERT(count(gprs_llme_list()) == 0);
- ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
- OSMO_ASSERT(!ictx);
-
- cleanup_test();
-}
-
-static void test_gmm_attach_acl(void)
-{
- const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
-
- sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_CLOSED;
- sgsn_acl_add("123456789012345", &sgsn->cfg);
- printf("Auth policy 'closed': ");
- test_gmm_attach(0);
- sgsn_acl_del("123456789012345", &sgsn->cfg);
-
- sgsn->cfg.auth_policy = saved_auth_policy;
-
- cleanup_test();
-}
-
-int my_subscr_request_update_location(struct sgsn_mm_ctx *mmctx) {
int rc;
rc = __real_gprs_subscr_request_update_location(mmctx);
if (rc == -ENOTSUP) {
@@ -1093,71 +935,24 @@ int my_subscr_request_update_location(struct sgsn_mm_ctx *mmctx) {
gprs_subscr_update(mmctx->subscr);
}
return rc;
-};
+}
-int my_subscr_request_auth_info(struct sgsn_mm_ctx *mmctx) {
+int my_subscr_request_auth_info(struct sgsn_mm_ctx *mmctx, const uint8_t *auts,
+ const uint8_t *auts_rand)
+{
gprs_subscr_update(mmctx->subscr);
return 0;
-};
-
-static void test_gmm_attach_subscr(void)
-{
- const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
- struct gprs_subscr *subscr;
-
- sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
- subscr_request_update_location_cb = my_subscr_request_update_location;
- subscr_request_auth_info_cb = my_subscr_request_auth_info;
-
- subscr = gprs_subscr_get_or_create("123456789012345");
- subscr->authorized = 1;
-
- printf("Auth policy 'remote': ");
- test_gmm_attach(0);
- gprs_subscr_put(subscr);
- assert_no_subscrs();
-
- sgsn->cfg.auth_policy = saved_auth_policy;
- subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
- subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
-
- cleanup_test();
}
-int my_subscr_request_auth_info_fake_auth(struct sgsn_mm_ctx *mmctx)
+int my_subscr_request_auth_info_fake_auth(struct sgsn_mm_ctx *mmctx, const uint8_t *auts,
+ const uint8_t *auts_rand)
{
/* Fake an authentication */
OSMO_ASSERT(mmctx->subscr);
- mmctx->is_authenticated = 1;
+ mmctx->sec_ctx = OSMO_AUTH_TYPE_GSM;
gprs_subscr_update_auth_info(mmctx->subscr);
return 0;
-};
-
-static void test_gmm_attach_subscr_fake_auth(void)
-{
- const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
- struct gprs_subscr *subscr;
-
- sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
- subscr_request_update_location_cb = my_subscr_request_update_location;
- subscr_request_auth_info_cb = my_subscr_request_auth_info_fake_auth;
-
- subscr = gprs_subscr_get_or_create("123456789012345");
- subscr->authorized = 1;
- sgsn->cfg.require_authentication = 1;
- sgsn->cfg.require_update_location = 1;
-
- printf("Auth policy 'remote', auth faked: ");
- test_gmm_attach(0);
- gprs_subscr_put(subscr);
- assert_no_subscrs();
-
- sgsn->cfg.auth_policy = saved_auth_policy;
- subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
- subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
-
- cleanup_test();
}
int my_subscr_request_auth_info_real_auth(struct sgsn_mm_ctx *mmctx, const uint8_t *auts, const uint8_t *auts_rand)
@@ -1175,33 +970,6 @@ int my_subscr_request_auth_info_real_auth(struct sgsn_mm_ctx *mmctx, const uint8
gprs_subscr_update_auth_info(mmctx->subscr);
return 0;
-};
-
-static void test_gmm_attach_subscr_real_auth(void)
-{
- const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
- struct gprs_subscr *subscr;
-
- sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
- subscr_request_update_location_cb = my_subscr_request_update_location;
- subscr_request_auth_info_cb = my_subscr_request_auth_info_real_auth;
-
- subscr = gprs_subscr_get_or_create("123456789012345");
- subscr->authorized = 1;
- sgsn->cfg.require_authentication = 1;
- sgsn->cfg.require_update_location = 1;
-
- printf("Auth policy 'remote', triplet based auth: ");
-
- test_gmm_attach(0);
- gprs_subscr_put(subscr);
- assert_no_subscrs();
-
- sgsn->cfg.auth_policy = saved_auth_policy;
- subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
- subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
-
- cleanup_test();
}
#define TEST_GSUP_IMSI_LONG_IE 0x01, 0x08, \
@@ -1210,7 +978,8 @@ static void test_gmm_attach_subscr_real_auth(void)
static int auth_info_skip = 0;
static int upd_loc_skip = 0;
-int my_subscr_request_auth_info_gsup_auth(struct sgsn_mm_ctx *mmctx)
+int my_subscr_request_auth_info_gsup_auth(struct sgsn_mm_ctx *mmctx, const uint8_t *auts,
+ const uint8_t *auts_rand)
{
static const uint8_t send_auth_info_res[] = {
0x0a,
@@ -1264,40 +1033,7 @@ int my_subscr_request_update_gsup_auth(struct sgsn_mm_ctx *mmctx) {
return rx_gsup_message(update_location_res, sizeof(update_location_res));
};
-
-static void test_gmm_attach_subscr_gsup_auth(int retry)
-{
- const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
- struct gprs_subscr *subscr;
-
- sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
- subscr_request_update_location_cb = my_subscr_request_update_gsup_auth;
- subscr_request_auth_info_cb = my_subscr_request_auth_info_gsup_auth;
- if (retry) {
- upd_loc_skip = 3;
- auth_info_skip = 3;
- }
-
- subscr = gprs_subscr_get_or_create("123456789012345");
- subscr->authorized = 1;
- sgsn->cfg.require_authentication = 1;
- sgsn->cfg.require_update_location = 1;
- gprs_subscr_put(subscr);
-
- printf("Auth policy 'remote', GSUP based auth: ");
- test_gmm_attach(retry);
- assert_no_subscrs();
-
- sgsn->cfg.auth_policy = saved_auth_policy;
- subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
- subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
- upd_loc_skip = 0;
- auth_info_skip = 0;
-
- cleanup_test();
-}
-
-int my_gsup_client_send(struct gsup_client *gsupc, struct msgb *msg)
+int my_gsup_client_send(struct osmo_gsup_client *gsupc, struct msgb *msg)
{
struct osmo_gsup_message to_peer = {0};
struct osmo_gsup_message from_peer = {0};
@@ -1320,7 +1056,7 @@ int my_gsup_client_send(struct gsup_client *gsupc, struct msgb *msg)
case OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST:
/* Send SEND_AUTH_INFO_RESULT */
- return my_subscr_request_auth_info_gsup_auth(NULL);
+ return my_subscr_request_auth_info_gsup_auth(NULL, NULL, NULL);
case OSMO_GSUP_MSGT_PURGE_MS_REQUEST:
from_peer.message_type = OSMO_GSUP_MSGT_PURGE_MS_RESULT;
@@ -1339,7 +1075,7 @@ int my_gsup_client_send(struct gsup_client *gsupc, struct msgb *msg)
return 0;
}
- reply_msg = gsup_client_msgb_alloc();
+ reply_msg = osmo_gsup_client_msgb_alloc();
reply_msg->l2h = reply_msg->data;
osmo_gsup_encode(reply_msg, &from_peer);
gprs_subscr_rx_gsup_message(reply_msg);
@@ -1348,38 +1084,6 @@ int my_gsup_client_send(struct gsup_client *gsupc, struct msgb *msg)
return 0;
};
-static void test_gmm_attach_subscr_real_gsup_auth(int retry)
-{
- const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
- struct gprs_subscr *subscr;
-
- sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
- gsup_client_send_cb = my_gsup_client_send;
-
- sgsn->gsup_client = talloc_zero(tall_bsc_ctx, struct gsup_client);
-
- if (retry) {
- upd_loc_skip = 3;
- auth_info_skip = 3;
- }
-
- printf("Auth policy 'remote', real GSUP based auth: ");
- test_gmm_attach(retry);
-
- subscr = gprs_subscr_get_by_imsi("123456789012345");
- OSMO_ASSERT(subscr == NULL);
- assert_no_subscrs();
-
- sgsn->cfg.auth_policy = saved_auth_policy;
- gsup_client_send_cb = __real_gsup_client_send;
- upd_loc_skip = 0;
- auth_info_skip = 0;
- talloc_free(sgsn->gsup_client);
- sgsn->gsup_client = NULL;
-
- cleanup_test();
-}
-
/*
* Test the GMM Rejects
*/
@@ -1582,7 +1286,7 @@ static void test_gmm_cancel(void)
ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
OSMO_ASSERT(ctx != NULL);
- OSMO_ASSERT(ctx->gmm_state == GMM_COMMON_PROC_INIT);
+ OSMO_ASSERT(ctx->gmm_fsm->state == ST_GMM_COMMON_PROC_INIT);
/* we expect an identity request (IMEI) */
OSMO_ASSERT(sgsn_tx_counter == 1);
@@ -1602,7 +1306,7 @@ static void test_gmm_cancel(void)
* authorization */
OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
- OSMO_ASSERT(ctx->gmm_state == GMM_COMMON_PROC_INIT);
+ OSMO_ASSERT(ctx->gmm_fsm->state == ST_GMM_COMMON_PROC_INIT);
/* we expect an attach accept/reject */
OSMO_ASSERT(sgsn_tx_counter == 1);
@@ -1616,7 +1320,7 @@ static void test_gmm_cancel(void)
send_0408_message(ctx->gb.llme, foreign_tlli, &raid,
attach_compl, ARRAY_SIZE(attach_compl));
- OSMO_ASSERT(ctx->gmm_state == GMM_REGISTERED_NORMAL);
+ OSMO_ASSERT(ctx->gmm_fsm->state == ST_GMM_REGISTERED_NORMAL);
/* we don't expect a response */
OSMO_ASSERT(sgsn_tx_counter == 0);
@@ -1634,513 +1338,6 @@ static void test_gmm_cancel(void)
cleanup_test();
}
-/*
- * Test the dynamic allocation of P-TMSIs
- */
-static void test_gmm_ptmsi_allocation(void)
-{
- struct gprs_ra_id raid = {332, 112, 16464, 96};
- struct sgsn_mm_ctx *ctx = NULL;
- struct sgsn_mm_ctx *ictx;
- uint32_t foreign_tlli;
- uint32_t ptmsi1;
- uint32_t ptmsi2;
- uint32_t received_ptmsi;
- uint32_t old_ptmsi;
- uint32_t local_tlli = 0;
- struct gprs_llc_lle *lle;
- const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
-
- /* DTAP - Attach Request (IMSI 12131415161718) */
- static const unsigned char attach_req[] = {
- 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02,
- 0x08, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
- 0x18, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60, 0x19,
- 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00,
- 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60,
- 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80,
- 0x00,
- };
-
- /* DTAP - Identity Response IMEI */
- static const unsigned char ident_resp_imei[] = {
- 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
- 0x56
- };
-
- /* DTAP - Attach Complete */
- static const unsigned char attach_compl[] = {
- 0x08, 0x03
- };
-
- /* DTAP - Routing Area Update Request */
- static const unsigned char ra_upd_req[] = {
- 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
- 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
- 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
- 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
- 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
- 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
- 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
- };
-
- /* DTAP - Routing Area Update Complete */
- static const unsigned char ra_upd_complete[] = {
- 0x08, 0x0a
- };
-
- /* DTAP - Detach Request (MO) */
- /* normal detach, power_off = 1 */
- static const unsigned char detach_req[] = {
- 0x08, 0x05, 0x09, 0x18, 0x05, 0xf4, 0xef, 0xe2,
- 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
- };
-
- sgsn->cfg.auth_policy = SGSN_AUTH_POLICY_OPEN;
-
- printf("Testing P-TMSI allocation\n");
-
- printf(" - sgsn_alloc_ptmsi\n");
-
- /* reset the PRNG used by sgsn_alloc_ptmsi */
- srand(1);
-
- ptmsi1 = sgsn_alloc_ptmsi();
- OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
-
- ptmsi2 = sgsn_alloc_ptmsi();
- OSMO_ASSERT(ptmsi2 != GSM_RESERVED_TMSI);
-
- OSMO_ASSERT(ptmsi1 != ptmsi2);
-
- ptmsi1 = ptmsi2 = GSM_RESERVED_TMSI;
-
- printf(" - Repeated Attach Request\n");
-
- foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
-
- /* Create a LLE/LLME */
- OSMO_ASSERT(count(gprs_llme_list()) == 0);
- lle = gprs_lle_get_or_create(foreign_tlli, 3);
- OSMO_ASSERT(count(gprs_llme_list()) == 1);
-
- /* inject the attach request */
- send_0408_message(lle->llme, foreign_tlli, &raid,
- attach_req, ARRAY_SIZE(attach_req));
-
- ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
- OSMO_ASSERT(ctx != NULL);
- OSMO_ASSERT(ctx->gmm_state == GMM_COMMON_PROC_INIT);
- OSMO_ASSERT(ctx->p_tmsi != GSM_RESERVED_TMSI);
- ptmsi1 = ctx->p_tmsi;
-
- old_ptmsi = ctx->p_tmsi_old;
-
- /* we expect an identity request (IMEI) */
- OSMO_ASSERT(sgsn_tx_counter == 1);
-
- /* inject the identity response (IMEI) */
- send_0408_message(ctx->gb.llme, foreign_tlli, &raid,
- ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
-
- /* check that the MM context has not been removed due to a failed
- * authorization */
- OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
-
- OSMO_ASSERT(ctx->gmm_state == GMM_COMMON_PROC_INIT);
- OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
-
- /* we expect an attach accept */
- OSMO_ASSERT(sgsn_tx_counter == 1);
- received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx);
- OSMO_ASSERT(received_ptmsi == ptmsi1);
-
- /* we ignore this and send the attach again */
- send_0408_message(lle->llme, foreign_tlli, &raid,
- attach_req, ARRAY_SIZE(attach_req));
-
- /* the allocated P-TMSI should be the same */
- ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
- OSMO_ASSERT(ctx != NULL);
- OSMO_ASSERT(ctx->gmm_state == GMM_COMMON_PROC_INIT);
- OSMO_ASSERT(ctx->p_tmsi_old == old_ptmsi);
- OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
-
- /* we expect an attach accept */
- OSMO_ASSERT(sgsn_tx_counter == 1);
- received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx);
- OSMO_ASSERT(received_ptmsi == ptmsi1);
-
- /* inject the attach complete */
- local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
- send_0408_message(ctx->gb.llme, local_tlli, &raid,
- attach_compl, ARRAY_SIZE(attach_compl));
-
- /* we don't expect a response */
- OSMO_ASSERT(sgsn_tx_counter == 0);
-
- OSMO_ASSERT(ctx->gmm_state == GMM_REGISTERED_NORMAL);
- OSMO_ASSERT(ctx->p_tmsi_old == 0);
- OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
-
- printf(" - Repeated RA Update Request\n");
-
- /* inject the RA update request */
- send_0408_message(ctx->gb.llme, local_tlli, &raid,
- ra_upd_req, ARRAY_SIZE(ra_upd_req));
-
- /* we expect an RA update accept */
- OSMO_ASSERT(sgsn_tx_counter == 1);
-
- OSMO_ASSERT(ctx->gmm_state == GMM_COMMON_PROC_INIT);
- OSMO_ASSERT(ctx->p_tmsi_old == ptmsi1);
- OSMO_ASSERT(ctx->p_tmsi != GSM_RESERVED_TMSI);
- OSMO_ASSERT(ctx->p_tmsi != ptmsi1);
- ptmsi2 = ctx->p_tmsi;
-
- /* repeat the RA update request */
- send_0408_message(ctx->gb.llme, local_tlli, &raid,
- ra_upd_req, ARRAY_SIZE(ra_upd_req));
-
- /* we expect an RA update accept */
- OSMO_ASSERT(sgsn_tx_counter == 1);
- received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx);
- OSMO_ASSERT(received_ptmsi == ptmsi2);
-
- OSMO_ASSERT(ctx->gmm_state == GMM_COMMON_PROC_INIT);
- OSMO_ASSERT(ctx->p_tmsi_old == ptmsi1);
- OSMO_ASSERT(ctx->p_tmsi == ptmsi2);
-
- /* inject the RA update complete */
- local_tlli = gprs_tmsi2tlli(ptmsi2, TLLI_LOCAL);
- send_0408_message(ctx->gb.llme, local_tlli, &raid,
- ra_upd_complete, ARRAY_SIZE(ra_upd_complete));
-
- /* we don't expect a response */
- OSMO_ASSERT(sgsn_tx_counter == 0);
-
- OSMO_ASSERT(ctx->gmm_state == GMM_REGISTERED_NORMAL);
- OSMO_ASSERT(ctx->p_tmsi_old == 0);
- OSMO_ASSERT(ctx->p_tmsi == ptmsi2);
-
- /* inject the detach */
- send_0408_message(ctx->gb.llme, local_tlli, &raid,
- detach_req, ARRAY_SIZE(detach_req));
-
- /* verify that things are gone */
- OSMO_ASSERT(count(gprs_llme_list()) == 0);
- ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
- OSMO_ASSERT(!ictx);
-
- sgsn->cfg.auth_policy = saved_auth_policy;
-
- cleanup_test();
-}
-
-/*
- * Test changing of routing areas
- */
-static void test_gmm_routing_areas(void)
-{
- struct gprs_ra_id raid1 = {332, 112, 16464, 96};
- struct gprs_ra_id raid2 = {332, 112, 16464, 97};
- struct sgsn_mm_ctx *ctx = NULL;
- struct sgsn_mm_ctx *ictx;
- uint32_t ptmsi1;
- uint32_t received_ptmsi;
- uint32_t ms_tlli = 0;
- struct gprs_llc_lle *lle;
- const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
-
- /* DTAP - Attach Request (IMSI 12131415161718) */
- static const unsigned char attach_req[] = {
- 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02,
- 0x08, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
- 0x18, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60, 0x19,
- 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00,
- 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60,
- 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80,
- 0x00,
- };
-
- /* DTAP - Attach Request (IMSI 12131415161718) (RA 2) */
- static const unsigned char attach_req2[] = {
- 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02,
- 0x08, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
- 0x18, 0x11, 0x22, 0x33, 0x40, 0x50, 0x61, 0x19,
- 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00,
- 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60,
- 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80,
- 0x00,
- };
-
- /* DTAP - Identity Response IMEI */
- static const unsigned char ident_resp_imei[] = {
- 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
- 0x56
- };
-
- /* DTAP - Attach Complete */
- static const unsigned char attach_compl[] = {
- 0x08, 0x03
- };
-
- /* DTAP - Routing Area Update Request (coming from RA 1) */
- static const unsigned char ra_upd_req1[] = {
- 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
- 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
- 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
- 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
- 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
- 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
- 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
- };
-
- /* DTAP - Routing Area Update Request (coming from RA 2) */
- static const unsigned char ra_upd_req2[] = {
- 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
- 0x61, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
- 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
- 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
- 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
- 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
- 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
- };
-
- /* DTAP - Routing Area Update Request (coming from RA other) */
- /* raid_other = {443, 223, 16464, 98}; */
- static const unsigned char ra_upd_req_other[] = {
- 0x08, 0x08, 0x10, 0x22, 0x33, 0x44, 0x40, 0x50,
- 0x62, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
- 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
- 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
- 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
- 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
- 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
- };
-
- /* DTAP - Routing Area Update Complete */
- static const unsigned char ra_upd_complete[] = {
- 0x08, 0x0a
- };
-
- /* DTAP - Detach Request (MO) */
- /* normal detach, power_off = 1 */
- static const unsigned char detach_req[] = {
- 0x08, 0x05, 0x09, 0x18, 0x05, 0xf4, 0xef, 0xe2,
- 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
- };
-
- sgsn->cfg.auth_policy = SGSN_AUTH_POLICY_OPEN;
-
- printf("Testing routing area changes\n");
-
- /* reset the PRNG used by sgsn_alloc_ptmsi */
- srand(1);
-
- ptmsi1 = GSM_RESERVED_TMSI;
-
- printf(" - Attach Request (RA 1)\n");
-
- ms_tlli = gprs_tmsi2tlli(0x00000023, TLLI_RANDOM);
-
- /* Create a LLE/LLME */
- OSMO_ASSERT(count(gprs_llme_list()) == 0);
- lle = gprs_lle_get_or_create(ms_tlli, 3);
- OSMO_ASSERT(count(gprs_llme_list()) == 1);
-
- /* inject the attach request */
- send_0408_message(lle->llme, ms_tlli, &raid1,
- attach_req, ARRAY_SIZE(attach_req));
-
- ctx = sgsn_mm_ctx_by_tlli(ms_tlli, &raid1);
- OSMO_ASSERT(ctx != NULL);
- OSMO_ASSERT(ctx->gmm_state == GMM_COMMON_PROC_INIT);
- OSMO_ASSERT(ctx->p_tmsi != GSM_RESERVED_TMSI);
-
- /* we expect an identity request (IMEI) */
- OSMO_ASSERT(sgsn_tx_counter == 1);
- OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_ID_REQ);
- OSMO_ASSERT(last_dl_parse_ctx.tlli == ms_tlli);
-
- /* inject the identity response (IMEI) */
- send_0408_message(ctx->gb.llme, ms_tlli, &raid1,
- ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
-
- /* check that the MM context has not been removed due to a failed
- * authorization */
- OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(ms_tlli, &raid1));
-
- OSMO_ASSERT(ctx->gmm_state == GMM_COMMON_PROC_INIT);
-
- /* we expect an attach accept */
- OSMO_ASSERT(sgsn_tx_counter == 1);
- OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_ATTACH_ACK);
- OSMO_ASSERT(last_dl_parse_ctx.tlli == ms_tlli);
-
- received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx);
- OSMO_ASSERT(received_ptmsi == ctx->p_tmsi);
- ptmsi1 = received_ptmsi;
-
- /* inject the attach complete */
- ms_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
- send_0408_message(ctx->gb.llme, ms_tlli, &raid1,
- attach_compl, ARRAY_SIZE(attach_compl));
-
- /* we don't expect a response */
- OSMO_ASSERT(sgsn_tx_counter == 0);
-
- OSMO_ASSERT(ctx->gmm_state == GMM_REGISTERED_NORMAL);
- OSMO_ASSERT(ctx->p_tmsi_old == 0);
- OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
-
- printf(" - RA Update Request (RA 1 -> RA 1)\n");
-
- /* inject the RA update request */
- send_0408_message(ctx->gb.llme, ms_tlli, &raid1,
- ra_upd_req1, ARRAY_SIZE(ra_upd_req1));
-
- /* we expect an RA update accept */
- OSMO_ASSERT(sgsn_tx_counter == 1);
- OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_RA_UPD_ACK);
- // OSMO_ASSERT(last_dl_parse_ctx.tlli == ms_tlli);
-
- OSMO_ASSERT(ctx->gmm_state == GMM_COMMON_PROC_INIT);
- OSMO_ASSERT(ctx->p_tmsi_old == ptmsi1);
- OSMO_ASSERT(ctx->p_tmsi != GSM_RESERVED_TMSI);
- OSMO_ASSERT(ctx->p_tmsi != ptmsi1);
-
- received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx);
- OSMO_ASSERT(received_ptmsi == ctx->p_tmsi);
- ptmsi1 = received_ptmsi;
-
- /* inject the RA update complete */
- ms_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
- send_0408_message(ctx->gb.llme, ms_tlli, &raid1,
- ra_upd_complete, ARRAY_SIZE(ra_upd_complete));
-
- /* we don't expect a response */
- OSMO_ASSERT(sgsn_tx_counter == 0);
-
- OSMO_ASSERT(ctx->gmm_state == GMM_REGISTERED_NORMAL);
- OSMO_ASSERT(ctx->p_tmsi_old == 0);
- OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
- OSMO_ASSERT(ctx->gb.tlli == ms_tlli);
-
- printf(" - RA Update Request (RA 1 -> RA 2)\n");
-
- /* inject the RA update request */
- ms_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_FOREIGN);
-
- /* It is coming from RA 1 => ra_upd_req1 */
- send_0408_message(ctx->gb.llme, ms_tlli, &raid2,
- ra_upd_req1, ARRAY_SIZE(ra_upd_req1));
-
- /* we expect an RA update accept */
- OSMO_ASSERT(sgsn_tx_counter == 1);
- OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_RA_UPD_ACK);
-
- printf(" - RA Update Request (RA other -> RA 2)\n");
-
- /* inject the RA update request */
- ms_tlli = gprs_tmsi2tlli(0x12345678, TLLI_FOREIGN);
-
- /* It is coming from RA 1 => ra_upd_req1 */
- send_0408_message(ctx->gb.llme, ms_tlli, &raid2,
- ra_upd_req_other, ARRAY_SIZE(ra_upd_req_other));
-
- /* we expect an RA update reject (and a LLC XID RESET) */
- OSMO_ASSERT(sgsn_tx_counter == 2);
- OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_RA_UPD_REJ);
- /* this has killed the LLE/LLME */
-
- printf(" - Attach Request (RA 2)\n");
-
- /* Create a LLE/LLME */
- OSMO_ASSERT(count(gprs_llme_list()) == 1);
- lle = gprs_lle_get_or_create(ms_tlli, 3);
- OSMO_ASSERT(count(gprs_llme_list()) == 1);
-
- /* inject the attach request */
- send_0408_message(lle->llme, ms_tlli, &raid2,
- attach_req2, ARRAY_SIZE(attach_req2));
-
- ctx = sgsn_mm_ctx_by_tlli(ms_tlli, &raid2);
- OSMO_ASSERT(ctx != NULL);
- OSMO_ASSERT(ctx->gmm_state == GMM_COMMON_PROC_INIT);
- OSMO_ASSERT(ctx->p_tmsi != GSM_RESERVED_TMSI);
-
- /* we expect an attach accept */
- OSMO_ASSERT(sgsn_tx_counter == 1);
- OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_ATTACH_ACK);
-
- received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx);
- OSMO_ASSERT(received_ptmsi == ctx->p_tmsi);
- ptmsi1 = received_ptmsi;
-
- /* inject the attach complete */
- ms_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
- ictx = sgsn_mm_ctx_by_tlli(ms_tlli, &raid2);
- OSMO_ASSERT(ictx != NULL);
- OSMO_ASSERT(ictx == ctx);
-
- send_0408_message(ctx->gb.llme, ms_tlli, &raid2,
- attach_compl, ARRAY_SIZE(attach_compl));
-
- /* we don't expect a response */
- OSMO_ASSERT(sgsn_tx_counter == 0);
-
- OSMO_ASSERT(ctx->gmm_state == GMM_REGISTERED_NORMAL);
- OSMO_ASSERT(ctx->p_tmsi_old == 0);
- OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
-
- printf(" - RA Update Request (RA 2 -> RA 2)\n");
-
- /* inject the RA update request */
- send_0408_message(ctx->gb.llme, ms_tlli, &raid2,
- ra_upd_req2, ARRAY_SIZE(ra_upd_req2));
-
- /* we expect an RA update accept */
- OSMO_ASSERT(sgsn_tx_counter == 1);
- OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_RA_UPD_ACK);
-
- OSMO_ASSERT(ctx->gmm_state == GMM_COMMON_PROC_INIT);
- OSMO_ASSERT(ctx->p_tmsi_old == ptmsi1);
- OSMO_ASSERT(ctx->p_tmsi != GSM_RESERVED_TMSI);
- OSMO_ASSERT(ctx->p_tmsi != ptmsi1);
-
- received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx);
- OSMO_ASSERT(received_ptmsi == ctx->p_tmsi);
- ptmsi1 = received_ptmsi;
-
- /* inject the RA update complete */
- ms_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
- send_0408_message(ctx->gb.llme, ms_tlli, &raid2,
- ra_upd_complete, ARRAY_SIZE(ra_upd_complete));
-
- /* we don't expect a response */
- OSMO_ASSERT(sgsn_tx_counter == 0);
-
- OSMO_ASSERT(ctx->gmm_state == GMM_REGISTERED_NORMAL);
- OSMO_ASSERT(ctx->p_tmsi_old == 0);
- OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
- OSMO_ASSERT(ctx->gb.tlli == ms_tlli);
-
-
- /* inject the detach */
- send_0408_message(ctx->gb.llme, ms_tlli, &raid2,
- detach_req, ARRAY_SIZE(detach_req));
-
- /* verify that things are gone */
- OSMO_ASSERT(count(gprs_llme_list()) == 0);
- ictx = sgsn_mm_ctx_by_tlli(ms_tlli, &raid2);
- OSMO_ASSERT(!ictx);
-
- sgsn->cfg.auth_policy = saved_auth_policy;
-
- cleanup_test();
-}
-
static void test_apn_matching(void)
{
struct apn_ctx *actx, *actxs[9];
@@ -2255,7 +1452,7 @@ static void test_ggsn_selection(void)
printf("Testing GGSN selection\n");
- gsup_client_send_cb = my_gsup_client_send_dummy;
+ osmo_gsup_client_send_cb = my_gsup_client_send_dummy;
/* Check for emptiness */
OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
@@ -2374,11 +1571,27 @@ static void test_ggsn_selection(void)
sgsn_ggsn_ctx_free(ggcs[1]);
sgsn_ggsn_ctx_free(ggcs[2]);
- gsup_client_send_cb = __real_gsup_client_send;
+ osmo_gsup_client_send_cb = __real_osmo_gsup_client_send;
cleanup_test();
}
+bool pdp_status_has_active_nsapis(const uint8_t *pdp_status, const size_t pdp_status_len);
+
+static void test_pdp_status_has_active_nsapis(void)
+{
+ const size_t pdp_status_len = 2;
+ const uint8_t pdp_status1[] = { 0b00100000, 0b00000000 }; /* PDP NSAPI 5 active */
+ const uint8_t pdp_status2[] = { 0b00000000, 0b00000000 }; /* no active PDP NSAPI */
+ const uint8_t pdp_status3[] = { 0b00000000, 0b00000001 }; /* PDP NSAPI 8 active */
+
+ printf("Testing pdp_status_has_active_nsapis\n");
+
+ OSMO_ASSERT(pdp_status_has_active_nsapis(pdp_status1, pdp_status_len));
+ OSMO_ASSERT(!pdp_status_has_active_nsapis(pdp_status2, pdp_status_len));
+ OSMO_ASSERT(pdp_status_has_active_nsapis(pdp_status3, pdp_status_len));
+}
+
static struct log_info_cat gprs_categories[] = {
[DMM] = {
.name = "DMM",
@@ -2434,19 +1647,25 @@ static struct log_info info = {
.num_cat = ARRAY_SIZE(gprs_categories),
};
+static struct vty_app_info vty_info = {
+ .name = "testSGSN",
+};
+
int main(int argc, char **argv)
{
void *osmo_sgsn_ctx;
void *msgb_ctx;
- osmo_init_logging(&info);
osmo_sgsn_ctx = talloc_named_const(NULL, 0, "osmo_sgsn");
- tall_bsc_ctx = talloc_named_const(osmo_sgsn_ctx, 0, "bsc");
+ osmo_init_logging2(osmo_sgsn_ctx, &info);
+ tall_sgsn_ctx = talloc_named_const(osmo_sgsn_ctx, 0, "sgsn");
msgb_ctx = msgb_talloc_ctx_init(osmo_sgsn_ctx, 0);
sgsn_rate_ctr_init();
- sgsn_auth_init();
+ sgsn_auth_init(sgsn);
gprs_subscr_init(sgsn);
+ vty_init(&vty_info);
+ sgsn_vty_init(&sgsn->cfg);
test_llme();
test_subscriber();
@@ -2457,24 +1676,16 @@ int main(int argc, char **argv)
test_gmm_detach_no_mmctx();
test_gmm_detach_accept_unexpected();
test_gmm_status_no_mmctx();
- test_gmm_attach_acl();
- test_gmm_attach_subscr();
- test_gmm_attach_subscr_fake_auth();
- test_gmm_attach_subscr_real_auth();
- test_gmm_attach_subscr_gsup_auth(0);
- test_gmm_attach_subscr_gsup_auth(1);
- test_gmm_attach_subscr_real_gsup_auth(0);
test_gmm_reject();
test_gmm_cancel();
- test_gmm_ptmsi_allocation();
- test_gmm_routing_areas();
test_apn_matching();
test_ggsn_selection();
+ test_pdp_status_has_active_nsapis();
printf("Done\n");
talloc_report_full(osmo_sgsn_ctx, stderr);
OSMO_ASSERT(talloc_total_blocks(msgb_ctx) == 1);
- OSMO_ASSERT(talloc_total_blocks(tall_bsc_ctx) == 2);
+ OSMO_ASSERT(talloc_total_blocks(tall_sgsn_ctx) == 2);
return 0;
}
diff --git a/tests/sgsn/sgsn_test.ok b/tests/sgsn/sgsn_test.ok
index f38d7309d..35b1d7bb7 100644
--- a/tests/sgsn/sgsn_test.ok
+++ b/tests/sgsn/sgsn_test.ok
@@ -15,13 +15,6 @@ Testing GMM detach (power off)
Testing GMM detach (no MMCTX)
Testing GMM detach accept (unexpected)
Testing GMM Status (no MMCTX)
-Auth policy 'closed': Testing GMM attach
-Auth policy 'remote': Testing GMM attach
-Auth policy 'remote', auth faked: Testing GMM attach
-Auth policy 'remote', triplet based auth: Testing GMM attach
-Auth policy 'remote', GSUP based auth: Testing GMM attach
-Auth policy 'remote', GSUP based auth: Testing GMM attach with retry
-Auth policy 'remote', real GSUP based auth: Testing GMM attach
Testing GMM reject
- Attach Request (invalid MI length)
- Attach Request (invalid MI type)
@@ -29,17 +22,7 @@ Testing GMM reject
- Routing Area Update Request (invalid type)
- Routing Area Update Request (invalid CAP length)
Testing cancellation
-Testing P-TMSI allocation
- - sgsn_alloc_ptmsi
- - Repeated Attach Request
- - Repeated RA Update Request
-Testing routing area changes
- - Attach Request (RA 1)
- - RA Update Request (RA 1 -> RA 1)
- - RA Update Request (RA 1 -> RA 2)
- - RA Update Request (RA other -> RA 2)
- - Attach Request (RA 2)
- - RA Update Request (RA 2 -> RA 2)
Testing APN matching
Testing GGSN selection
+Testing pdp_status_has_active_nsapis
Done
diff --git a/tests/slhc/Makefile.am b/tests/slhc/Makefile.am
index 818ae2ef3..b6738c25d 100644
--- a/tests/slhc/Makefile.am
+++ b/tests/slhc/Makefile.am
@@ -8,7 +8,7 @@ noinst_PROGRAMS = slhc_test
slhc_test_SOURCES = slhc_test.c
slhc_test_LDADD = \
- $(top_builddir)/src/gprs/slhc.o \
+ $(top_builddir)/src/sgsn/slhc.o \
$(LIBOSMOCORE_LIBS)
diff --git a/tests/slhc/slhc_test.c b/tests/slhc/slhc_test.c
index d2e1cd9dc..5c1331355 100644
--- a/tests/slhc/slhc_test.c
+++ b/tests/slhc/slhc_test.c
@@ -19,8 +19,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <openbsc/slhc.h>
-#include <openbsc/debug.h>
+#include <osmocom/sgsn/slhc.h>
+#include <osmocom/sgsn/debug.h>
#include <osmocom/core/talloc.h>
#include <osmocom/core/utils.h>
@@ -250,17 +250,20 @@ static struct log_info info = {
int main(int argc, char **argv)
{
void *ctx;
-
- osmo_init_logging(&info);
+ void *log_ctx;
ctx = talloc_named_const(NULL, 0, "slhc_ctx");
+ log_ctx = talloc_named_const(ctx, 0, "log");
+ osmo_init_logging2(log_ctx, &info);
test_slhc(ctx);
printf("Done\n");
talloc_report_full(ctx, stderr);
+ talloc_free(log_ctx);
OSMO_ASSERT(talloc_total_blocks(ctx) == 1);
+ talloc_free(ctx);
return 0;
}
diff --git a/tests/sndcp_xid/Makefile.am b/tests/sndcp_xid/Makefile.am
index d09c41b28..24626b32e 100644
--- a/tests/sndcp_xid/Makefile.am
+++ b/tests/sndcp_xid/Makefile.am
@@ -8,13 +8,12 @@ noinst_PROGRAMS = sndcp_xid_test
sndcp_xid_test_SOURCES = sndcp_xid_test.c
sndcp_xid_test_LDADD = \
- $(top_builddir)/src/gprs/gprs_sndcp_xid.o \
+ $(top_builddir)/src/sgsn/gprs_sndcp_xid.o \
$(LIBOSMOABIS_LIBS) \
$(LIBOSMOCORE_LIBS) \
$(LIBOSMOGSM_LIBS) \
$(LIBOSMOGB_LIBS) \
$(LIBCARES_LIBS) \
- $(LIBCRYPTO_LIBS) \
$(LIBGTP_LIBS) \
-lrt -lm
diff --git a/tests/sndcp_xid/sndcp_xid_test.c b/tests/sndcp_xid/sndcp_xid_test.c
index 151dd2bb5..56b97e336 100644
--- a/tests/sndcp_xid/sndcp_xid_test.c
+++ b/tests/sndcp_xid/sndcp_xid_test.c
@@ -19,8 +19,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <openbsc/gprs_sndcp_xid.h>
-#include <openbsc/debug.h>
+#include <osmocom/sgsn/gprs_sndcp_xid.h>
+#include <osmocom/sgsn/debug.h>
#include <osmocom/core/talloc.h>
#include <osmocom/core/utils.h>
@@ -106,7 +106,7 @@ static void test_xid_encode_decode(const void *ctx)
/* Setup rfc1144 compression field */
rfc1144_comp_field.p = 1;
rfc1144_comp_field.entity = 0;
- rfc1144_comp_field.algo = RFC_1144;
+ rfc1144_comp_field.algo.pcomp = RFC_1144;
rfc1144_comp_field.comp[RFC1144_PCOMP1] = 1;
rfc1144_comp_field.comp[RFC1144_PCOMP2] = 2;
rfc1144_comp_field.comp_len = RFC1144_PCOMP_NUM;
@@ -126,7 +126,7 @@ static void test_xid_encode_decode(const void *ctx)
/* Setup rfc2507 compression field */
rfc2507_comp_field.p = 1;
rfc2507_comp_field.entity = 1;
- rfc2507_comp_field.algo = RFC_2507;
+ rfc2507_comp_field.algo.pcomp = RFC_2507;
rfc2507_comp_field.comp[RFC2507_PCOMP1] = 3;
rfc2507_comp_field.comp[RFC2507_PCOMP2] = 4;
rfc2507_comp_field.comp[RFC2507_PCOMP3] = 5;
@@ -173,7 +173,7 @@ static void test_xid_encode_decode(const void *ctx)
/* Setup ROHC compression field */
rohc_comp_field.p = 1;
rohc_comp_field.entity = 2;
- rohc_comp_field.algo = ROHC;
+ rohc_comp_field.algo.pcomp = ROHC;
rohc_comp_field.comp[ROHC_PCOMP1] = 8;
rohc_comp_field.comp[ROHC_PCOMP2] = 9;
rohc_comp_field.comp_len = ROHC_PCOMP_NUM;
@@ -191,7 +191,7 @@ static void test_xid_encode_decode(const void *ctx)
/* Setup v42bis compression field */
v42bis_comp_field.p = 1;
v42bis_comp_field.entity = 3;
- v42bis_comp_field.algo = V42BIS;
+ v42bis_comp_field.algo.dcomp = V42BIS;
v42bis_comp_field.comp[V42BIS_DCOMP1] = 10;
v42bis_comp_field.comp_len = V42BIS_DCOMP_NUM;
v42bis_comp_field.v42bis_params = &v42bis_params;
@@ -211,7 +211,7 @@ static void test_xid_encode_decode(const void *ctx)
/* Setup v44 compression field */
v44_comp_field.p = 1;
v44_comp_field.entity = 3;
- v44_comp_field.algo = V44;
+ v44_comp_field.algo.dcomp = V44;
v44_comp_field.comp[V44_DCOMP1] = 10;
v44_comp_field.comp[V44_DCOMP2] = 11;
v44_comp_field.comp_len = V44_DCOMP_NUM;
@@ -261,10 +261,11 @@ static struct log_info info = {
int main(int argc, char **argv)
{
void *xid_ctx;
-
- osmo_init_logging(&info);
+ void *log_ctx;
xid_ctx = talloc_named_const(NULL, 0, "xid_ctx");
+ log_ctx = talloc_named_const(xid_ctx, 0, "log");
+ osmo_init_logging2(log_ctx, &info);
test_xid_decode_realworld(xid_ctx);
test_xid_encode_decode(xid_ctx);
@@ -272,7 +273,9 @@ int main(int argc, char **argv)
printf("Done\n");
talloc_report_full(xid_ctx, stderr);
+ talloc_free(log_ctx);
OSMO_ASSERT(talloc_total_blocks(xid_ctx) == 1);
+ talloc_free(xid_ctx);
return 0;
}
diff --git a/tests/test_nodes.vty b/tests/test_nodes.vty
new file mode 100644
index 000000000..18bccc8f2
--- /dev/null
+++ b/tests/test_nodes.vty
@@ -0,0 +1,63 @@
+OsmoSGSN> enable
+OsmoSGSN# show timer
+T3312 = 600 s Periodic RA Update timer (s) (default: 600 s)
+T3313 = 30 s Waiting for paging response timer (s) (default: 30 s)
+T3314 = 44 s READY timer. Force to STANDBY on expiry timer (s) (default: 44 s)
+T3316 = 44 s AA-Ready timer (s) (default: 44 s)
+T3322 = 6 s Detach request -> accept timer (s) (default: 6 s)
+T3350 = 6 s Waiting for ATT/RAU/TMSI_COMPL timer (s) (default: 6 s)
+T3360 = 6 s Waiting for AUTH/CIPH response timer (s) (default: 6 s)
+T3370 = 6 s Waiting for IDENTITY response timer (s) (default: 6 s)
+T3385 = 8 s Wait for ACT PDP CTX REQ timer (s) (default: 8 s)
+T3386 = 8 s Wait for MODIFY PDP CTX ACK timer (s) (default: 8 s)
+T3395 = 8 s Wait for DEACT PDP CTX ACK timer (s) (default: 8 s)
+T3397 = 8 s Wait for DEACT AA PDP CTX ACK timer (s) (default: 8 s)
+X1001 = 5 s RANAP Release timeout. Wait for RANAP Release Complete.On expiry release Iu connection (s) (default: 5 s)
+X3314 = 44 s Iu User inactivity timer. On expiry release Iu connection (s) (default: 44 s)
+OsmoSGSN# configure terminal
+OsmoSGSN(config)# list
+...
+ sgsn
+ ctrl
+...
+ ns
+ bssgp
+...
+
+OsmoSGSN(config)# sgsn
+OsmoSGSN(config-sgsn)# list
+...
+ gtp local-ip A.B.C.D
+ ggsn <0-255> remote-ip A.B.C.D
+ ggsn <0-255> gtp-version (0|1)
+ ggsn <0-255> echo-interval <1-36000>
+ ggsn <0-255> no echo-interval
+ imsi-acl (add|del) IMSI
+ auth-policy (accept-all|closed|acl-only|remote)
+ authentication (optional|required)
+ encryption (GEA0|GEA1|GEA2|GEA3|GEA4)
+ gsup ipa-name NAME
+ gsup remote-ip A.B.C.D
+ gsup remote-port <0-65535>
+ gsup oap-id <0-65535>
+ gsup oap-k K
+ gsup oap-opc OPC
+ apn APNAME ggsn <0-255>
+ apn APNAME imsi-prefix IMSIPRE ggsn <0-255>
+ access-point-name NAME
+ no access-point-name NAME
+ cdr filename NAME
+ no cdr filename
+ cdr trap
+ no cdr trap
+ cdr interval <1-2147483647>
+ ggsn dynamic
+ grx-dns-add A.B.C.D
+ timer [TNNNN] [(<0-2147483647>|default)]
+ no compression rfc1144
+ compression rfc1144 active slots <1-256>
+ compression rfc1144 passive
+ no compression v42bis
+ compression v42bis active direction (ms|sgsn|both) codewords <512-65535> strlen <6-250>
+ compression v42bis passive
+...
diff --git a/tests/testsuite.at b/tests/testsuite.at
index 81cd713f3..d30115e01 100644
--- a/tests/testsuite.at
+++ b/tests/testsuite.at
@@ -20,14 +20,6 @@ cat $abs_srcdir/sgsn/sgsn_test.ok > expout
AT_CHECK([$abs_top_builddir/tests/sgsn/sgsn_test], [], [expout], [ignore])
AT_CLEANUP
-AT_SETUP([oap])
-AT_KEYWORDS([oap])
-AT_CHECK([test "$enable_oap_test" != no || exit 77])
-cat $abs_srcdir/oap/oap_client_test.ok > expout
-cat $abs_srcdir/oap/oap_client_test.err > experr
-AT_CHECK([$abs_top_builddir/tests/oap/oap_client_test], [], [expout], [experr])
-AT_CLEANUP
-
AT_SETUP([gtphub])
AT_KEYWORDS([gtphub])
AT_CHECK([test "$enable_gtphub_test" != no || exit 77])
diff --git a/tests/v42bis/Makefile.am b/tests/v42bis/Makefile.am
index 8e17b4afd..744239279 100644
--- a/tests/v42bis/Makefile.am
+++ b/tests/v42bis/Makefile.am
@@ -8,7 +8,7 @@ noinst_PROGRAMS = v42bis_test
v42bis_test_SOURCES = v42bis_test.c
v42bis_test_LDADD = \
- $(top_builddir)/src/gprs/v42bis.o \
+ $(top_builddir)/src/sgsn/v42bis.o \
$(LIBOSMOCORE_LIBS)
diff --git a/tests/v42bis/v42bis_test.c b/tests/v42bis/v42bis_test.c
index 7e907858d..e9c506926 100644
--- a/tests/v42bis/v42bis_test.c
+++ b/tests/v42bis/v42bis_test.c
@@ -19,9 +19,9 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <openbsc/v42bis.h>
-#include <openbsc/v42bis_private.h>
-#include <openbsc/debug.h>
+#include <osmocom/sgsn/v42bis.h>
+#include <osmocom/sgsn/v42bis_private.h>
+#include <osmocom/sgsn/debug.h>
#include <osmocom/core/talloc.h>
#include <osmocom/core/utils.h>
@@ -407,11 +407,12 @@ static struct log_info info = {
int main(int argc, char **argv)
{
void *v42bis_ctx;
+ void *log_ctx;
int i;
- osmo_init_logging(&info);
-
v42bis_ctx = talloc_named_const(NULL, 0, "v42bis_ctx");
+ log_ctx = talloc_named_const(v42bis_ctx, 0, "log");
+ osmo_init_logging2(log_ctx, &info);
test_v42bis(v42bis_ctx);
@@ -423,7 +424,9 @@ int main(int argc, char **argv)
printf("Done\n");
talloc_report_full(v42bis_ctx, stderr);
+ talloc_free(log_ctx);
OSMO_ASSERT(talloc_total_blocks(v42bis_ctx) == 1);
+ talloc_free(v42bis_ctx);
return 0;
}
diff --git a/tests/vty_test_runner.py b/tests/vty_test_runner.py
index 9be8d03cc..ed52d5f9b 100644..100755
--- a/tests/vty_test_runner.py
+++ b/tests/vty_test_runner.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
# (C) 2013 by Katerina Barone-Adesi <kat.obsc@gmail.com>
# (C) 2013 by Holger Hans Peter Freyther
@@ -23,11 +23,7 @@ import subprocess
import osmopy.obscvty as obscvty
import osmopy.osmoutil as osmoutil
-
-# add $top_srcdir/contrib to find ipa.py
-sys.path.append(os.path.join(sys.path[0], '..', 'contrib'))
-
-from ipa import IPA
+from osmopy.osmo_ipa import IPA
# to be able to find $top_srcdir/doc/...
confpath = os.path.join(sys.path[0], '..')
@@ -37,9 +33,9 @@ class TestVTYBase(unittest.TestCase):
def checkForEndAndExit(self):
res = self.vty.command("list")
#print ('looking for "exit"\n')
- self.assert_(res.find(' exit\r') > 0)
+ self.assertTrue(res.find(' exit\r') > 0)
#print 'found "exit"\nlooking for "end"\n'
- self.assert_(res.find(' end\r') > 0)
+ self.assertTrue(res.find(' end\r') > 0)
#print 'found "end"\n'
def vty_command(self):
@@ -58,8 +54,8 @@ class TestVTYBase(unittest.TestCase):
try:
self.proc = osmoutil.popen_devnull(osmo_vty_cmd)
except OSError:
- print >> sys.stderr, "Current directory: %s" % os.getcwd()
- print >> sys.stderr, "Consider setting -b"
+ print("Current directory: %s" % os.getcwd(), file=sys.stderr)
+ print("Consider setting -b", file=sys.stderr)
appstring = self.vty_app()[2]
appport = self.vty_app()[0]
@@ -75,142 +71,140 @@ class TestVTYBase(unittest.TestCase):
class TestVTYGbproxy(TestVTYBase):
def vty_command(self):
- return ["./src/gprs/osmo-gbproxy", "-c",
+ return ["./src/gbproxy/osmo-gbproxy", "-c",
"doc/examples/osmo-gbproxy/osmo-gbproxy.cfg"]
def vty_app(self):
- return (4246, "./src/gprs/osmo-gbproxy", "OsmoGbProxy", "bsc")
+ return (4246, "./src/gbproxy/osmo-gbproxy", "OsmoGbProxy", "gbproxy")
def testVtyTree(self):
self.vty.enable()
self.assertTrue(self.vty.verify('configure terminal', ['']))
- self.assertEquals(self.vty.node(), 'config')
+ self.assertEqual(self.vty.node(), 'config')
self.checkForEndAndExit()
self.assertTrue(self.vty.verify('ns', ['']))
- self.assertEquals(self.vty.node(), 'config-ns')
+ self.assertEqual(self.vty.node(), 'config-ns')
self.checkForEndAndExit()
self.assertTrue(self.vty.verify('exit', ['']))
- self.assertEquals(self.vty.node(), 'config')
+ self.assertEqual(self.vty.node(), 'config')
self.assertTrue(self.vty.verify('gbproxy', ['']))
- self.assertEquals(self.vty.node(), 'config-gbproxy')
+ self.assertEqual(self.vty.node(), 'config-gbproxy')
self.checkForEndAndExit()
self.assertTrue(self.vty.verify('exit', ['']))
- self.assertEquals(self.vty.node(), 'config')
+ self.assertEqual(self.vty.node(), 'config')
def testVtyShow(self):
res = self.vty.command("show ns")
- self.assert_(res.find('Encapsulation NS-UDP-IP') >= 0)
+ self.assertTrue(res.find('Encapsulation NS-UDP-IP') >= 0)
res = self.vty.command("show gbproxy stats")
- self.assert_(res.find('GBProxy Global Statistics') >= 0)
+ self.assertTrue(res.find('GBProxy Global Statistics') >= 0)
def testVtyDeletePeer(self):
self.vty.enable()
self.assertTrue(self.vty.verify('delete-gbproxy-peer 9999 bvci 7777', ['BVC not found']))
res = self.vty.command("delete-gbproxy-peer 9999 all dry-run")
- self.assert_(res.find('Not Deleted 0 BVC') >= 0)
- self.assert_(res.find('Not Deleted 0 NS-VC') >= 0)
+ self.assertTrue(res.find('Not Deleted 0 BVC') >= 0)
+ self.assertTrue(res.find('Not Deleted 0 NS-VC') >= 0)
res = self.vty.command("delete-gbproxy-peer 9999 only-bvc dry-run")
- self.assert_(res.find('Not Deleted 0 BVC') >= 0)
- self.assert_(res.find('Not Deleted 0 NS-VC') < 0)
+ self.assertTrue(res.find('Not Deleted 0 BVC') >= 0)
+ self.assertTrue(res.find('Not Deleted 0 NS-VC') < 0)
res = self.vty.command("delete-gbproxy-peer 9999 only-nsvc dry-run")
- self.assert_(res.find('Not Deleted 0 BVC') < 0)
- self.assert_(res.find('Not Deleted 0 NS-VC') >= 0)
+ self.assertTrue(res.find('Not Deleted 0 BVC') < 0)
+ self.assertTrue(res.find('Not Deleted 0 NS-VC') >= 0)
res = self.vty.command("delete-gbproxy-peer 9999 all")
- self.assert_(res.find('Deleted 0 BVC') >= 0)
- self.assert_(res.find('Deleted 0 NS-VC') >= 0)
+ self.assertTrue(res.find('Deleted 0 BVC') >= 0)
+ self.assertTrue(res.find('Deleted 0 NS-VC') >= 0)
class TestVTYSGSN(TestVTYBase):
def vty_command(self):
- return ["./src/gprs/osmo-sgsn", "-c",
+ return ["./src/sgsn/osmo-sgsn", "-c",
"doc/examples/osmo-sgsn/osmo-sgsn-accept-all.cfg"]
def vty_app(self):
- return (4245, "./src/gprs/osmo-sgsn", "OsmoSGSN", "sgsn")
+ return (4245, "./src/sgsn/osmo-sgsn", "OsmoSGSN", "sgsn")
def testVtyTree(self):
self.vty.enable()
self.assertTrue(self.vty.verify('configure terminal', ['']))
- self.assertEquals(self.vty.node(), 'config')
+ self.assertEqual(self.vty.node(), 'config')
self.checkForEndAndExit()
self.assertTrue(self.vty.verify('ns', ['']))
- self.assertEquals(self.vty.node(), 'config-ns')
+ self.assertEqual(self.vty.node(), 'config-ns')
self.checkForEndAndExit()
self.assertTrue(self.vty.verify('exit', ['']))
- self.assertEquals(self.vty.node(), 'config')
+ self.assertEqual(self.vty.node(), 'config')
self.assertTrue(self.vty.verify('sgsn', ['']))
- self.assertEquals(self.vty.node(), 'config-sgsn')
+ self.assertEqual(self.vty.node(), 'config-sgsn')
self.checkForEndAndExit()
self.assertTrue(self.vty.verify('exit', ['']))
- self.assertEquals(self.vty.node(), 'config')
+ self.assertEqual(self.vty.node(), 'config')
def testVtyShow(self):
res = self.vty.command("show ns")
- self.assert_(res.find('Encapsulation NS-UDP-IP') >= 0)
+ self.assertTrue(res.find('Encapsulation NS-UDP-IP') >= 0)
self.assertTrue(self.vty.verify('show bssgp', ['']))
self.assertTrue(self.vty.verify('show bssgp stats', ['']))
- # TODO: uncomment when the command does not segfault anymore
- # self.assertTrue(self.vty.verify('show bssgp nsei 123', ['']))
- # self.assertTrue(self.vty.verify('show bssgp nsei 123 stats', ['']))
-
- self.assertTrue(self.vty.verify('show sgsn', ['']))
+ self.assertTrue(self.vty.verify('show bssgp nsei 123', ['']))
+ self.assertTrue(self.vty.verify('show bssgp nsei 123 stats', ['']))
+ self.assertTrue(self.vty.verify('show sgsn', [' GSN: signalling 127.0.0.1, user traffic 127.0.0.1']))
self.assertTrue(self.vty.verify('show mm-context all', ['']))
self.assertTrue(self.vty.verify('show mm-context imsi 000001234567', ['No MM context for IMSI 000001234567']))
self.assertTrue(self.vty.verify('show pdp-context all', ['']))
res = self.vty.command("show sndcp")
- self.assert_(res.find('State of SNDCP Entities') >= 0)
+ self.assertTrue(res.find('State of SNDCP Entities') >= 0)
res = self.vty.command("show llc")
- self.assert_(res.find('State of LLC Entities') >= 0)
+ self.assertTrue(res.find('State of LLC Entities') >= 0)
def testVtyAuth(self):
self.vty.enable()
self.assertTrue(self.vty.verify('configure terminal', ['']))
- self.assertEquals(self.vty.node(), 'config')
+ self.assertEqual(self.vty.node(), 'config')
self.assertTrue(self.vty.verify('sgsn', ['']))
- self.assertEquals(self.vty.node(), 'config-sgsn')
+ self.assertEqual(self.vty.node(), 'config-sgsn')
self.assertTrue(self.vty.verify('auth-policy accept-all', ['']))
res = self.vty.command("show running-config")
- self.assert_(res.find('auth-policy accept-all') > 0)
+ self.assertTrue(res.find('auth-policy accept-all') > 0)
self.assertTrue(self.vty.verify('auth-policy acl-only', ['']))
res = self.vty.command("show running-config")
- self.assert_(res.find('auth-policy acl-only') > 0)
+ self.assertTrue(res.find('auth-policy acl-only') > 0)
self.assertTrue(self.vty.verify('auth-policy closed', ['']))
res = self.vty.command("show running-config")
- self.assert_(res.find('auth-policy closed') > 0)
+ self.assertTrue(res.find('auth-policy closed') > 0)
self.assertTrue(self.vty.verify('gsup remote-ip 127.0.0.4', ['']))
self.assertTrue(self.vty.verify('gsup remote-port 2222', ['']))
self.assertTrue(self.vty.verify('auth-policy remote', ['']))
res = self.vty.command("show running-config")
- self.assert_(res.find('auth-policy remote') > 0)
+ self.assertTrue(res.find('auth-policy remote') > 0)
def testVtySubscriber(self):
self.vty.enable()
res = self.vty.command('show subscriber cache')
- self.assert_(res.find('1234567890') < 0)
+ self.assertTrue(res.find('1234567890') < 0)
self.assertTrue(self.vty.verify('update-subscriber imsi 1234567890 create', ['']))
res = self.vty.command('show subscriber cache')
- self.assert_(res.find('1234567890') >= 0)
- self.assert_(res.find('Authorized: 0') >= 0)
+ self.assertTrue(res.find('1234567890') >= 0)
+ self.assertTrue(res.find('Authorized: 0') >= 0)
self.assertTrue(self.vty.verify('update-subscriber imsi 1234567890 update-location-result ok', ['']))
res = self.vty.command('show subscriber cache')
- self.assert_(res.find('1234567890') >= 0)
- self.assert_(res.find('Authorized: 1') >= 0)
+ self.assertTrue(res.find('1234567890') >= 0)
+ self.assertTrue(res.find('Authorized: 1') >= 0)
self.assertTrue(self.vty.verify('update-subscriber imsi 1234567890 cancel update-procedure', ['']))
res = self.vty.command('show subscriber cache')
- self.assert_(res.find('1234567890') >= 0)
+ self.assertTrue(res.find('1234567890') >= 0)
self.assertTrue(self.vty.verify('update-subscriber imsi 1234567890 destroy', ['']))
res = self.vty.command('show subscriber cache')
- self.assert_(res.find('1234567890') < 0)
+ self.assertTrue(res.find('1234567890') < 0)
def testVtyGgsn(self):
self.vty.enable()
self.assertTrue(self.vty.verify('configure terminal', ['']))
- self.assertEquals(self.vty.node(), 'config')
+ self.assertEqual(self.vty.node(), 'config')
self.assertTrue(self.vty.verify('sgsn', ['']))
- self.assertEquals(self.vty.node(), 'config-sgsn')
+ self.assertEqual(self.vty.node(), 'config-sgsn')
self.assertTrue(self.vty.verify('ggsn 0 remote-ip 127.99.99.99', ['']))
self.assertTrue(self.vty.verify('ggsn 0 gtp-version 1', ['']))
self.assertTrue(self.vty.verify('apn * ggsn 0', ['']))
@@ -219,69 +213,78 @@ class TestVTYSGSN(TestVTYBase):
self.assertTrue(self.vty.verify('apn apn1.test imsi-prefix 123456 ggsn 0', ['']))
self.assertTrue(self.vty.verify('apn apn2.test imsi-prefix 123456 ggsn 0', ['']))
res = self.vty.command("show running-config")
- self.assert_(res.find('ggsn 0 remote-ip 127.99.99.99') >= 0)
- self.assert_(res.find('ggsn 0 gtp-version 1') >= 0)
- self.assert_(res.find('apn * ggsn 0') >= 0)
- self.assert_(res.find('apn apn1.test ggsn 0') >= 0)
- self.assert_(res.find('apn apn1.test imsi-prefix 123456 ggsn 0') >= 0)
- self.assert_(res.find('apn apn2.test imsi-prefix 123456 ggsn 0') >= 0)
+ self.assertTrue(res.find('ggsn 0 remote-ip 127.99.99.99') >= 0)
+ self.assertTrue(res.find('ggsn 0 gtp-version 1') >= 0)
+ self.assertTrue(res.find('apn * ggsn 0') >= 0)
+ self.assertTrue(res.find('apn apn1.test ggsn 0') >= 0)
+ self.assertTrue(res.find('apn apn1.test imsi-prefix 123456 ggsn 0') >= 0)
+ self.assertTrue(res.find('apn apn2.test imsi-prefix 123456 ggsn 0') >= 0)
def testVtyEasyAPN(self):
self.vty.enable()
self.assertTrue(self.vty.verify('configure terminal', ['']))
- self.assertEquals(self.vty.node(), 'config')
+ self.assertEqual(self.vty.node(), 'config')
self.assertTrue(self.vty.verify('sgsn', ['']))
- self.assertEquals(self.vty.node(), 'config-sgsn')
+ self.assertEqual(self.vty.node(), 'config-sgsn')
res = self.vty.command("show running-config")
- self.assertEquals(res.find("apn internet"), -1)
+ self.assertEqual(res.find("apn internet"), -1)
self.assertTrue(self.vty.verify("access-point-name internet.apn", ['']))
res = self.vty.command("show running-config")
- self.assert_(res.find("apn internet.apn ggsn 0") >= 0)
+ self.assertTrue(res.find("apn internet.apn ggsn 0") >= 0)
self.assertTrue(self.vty.verify("no access-point-name internet.apn", ['']))
res = self.vty.command("show running-config")
- self.assertEquals(res.find("apn internet"), -1)
+ self.assertEqual(res.find("apn internet"), -1)
def testVtyCDR(self):
self.vty.enable()
self.assertTrue(self.vty.verify('configure terminal', ['']))
- self.assertEquals(self.vty.node(), 'config')
+ self.assertEqual(self.vty.node(), 'config')
self.assertTrue(self.vty.verify('sgsn', ['']))
- self.assertEquals(self.vty.node(), 'config-sgsn')
+ self.assertEqual(self.vty.node(), 'config-sgsn')
res = self.vty.command("show running-config")
- self.assert_(res.find("no cdr filename") > 0)
+ self.assertTrue(res.find("no cdr filename") > 0)
self.vty.command("cdr filename bla.cdr")
res = self.vty.command("show running-config")
- self.assertEquals(res.find("no cdr filename"), -1)
- self.assert_(res.find(" cdr filename bla.cdr") > 0)
+ self.assertEqual(res.find("no cdr filename"), -1)
+ self.assertTrue(res.find(" cdr filename bla.cdr") > 0)
self.vty.command("no cdr filename")
res = self.vty.command("show running-config")
- self.assert_(res.find("no cdr filename") > 0)
- self.assertEquals(res.find(" cdr filename bla.cdr"), -1)
+ self.assertTrue(res.find("no cdr filename") > 0)
+ self.assertEqual(res.find(" cdr filename bla.cdr"), -1)
res = self.vty.command("show running-config")
- self.assert_(res.find(" cdr interval 600") > 0)
+ self.assertTrue(res.find(" cdr interval 600") > 0)
self.vty.command("cdr interval 900")
res = self.vty.command("show running-config")
- self.assert_(res.find(" cdr interval 900") > 0)
- self.assertEquals(res.find(" cdr interval 600"), -1)
+ self.assertTrue(res.find(" cdr interval 900") > 0)
+ self.assertEqual(res.find(" cdr interval 600"), -1)
+
+ def testVtyTimers(self):
+ self.vty.enable()
+ self.assertTrue(self.vty.verify('configure terminal', ['']))
+ self.assertEqual(self.vty.node(), 'config')
+ self.assertTrue(self.vty.verify('sgsn', ['']))
+ self.assertEqual(self.vty.node(), 'config-sgsn')
+ for t in [3312, 3322, 3350, 3360, 3370, 3313, 3314, 3316, 3385, 3395, 3397]:
+ self.assertTrue(self.vty.verify('timer t%d 10' % t, ['']))
def add_gbproxy_test(suite, workdir):
- if not os.path.isfile(os.path.join(workdir, "src/gprs/osmo-gbproxy")):
+ if not os.path.isfile(os.path.join(workdir, "src/gbproxy/osmo-gbproxy")):
print("Skipping the Gb-Proxy test")
return
test = unittest.TestLoader().loadTestsFromTestCase(TestVTYGbproxy)
suite.addTest(test)
def add_sgsn_test(suite, workdir):
- if not os.path.isfile(os.path.join(workdir, "src/gprs/osmo-sgsn")):
+ if not os.path.isfile(os.path.join(workdir, "src/sgsn/osmo-sgsn")):
print("Skipping the SGSN test")
return
test = unittest.TestLoader().loadTestsFromTestCase(TestVTYSGSN)
@@ -313,9 +316,9 @@ if __name__ == '__main__':
if args.p:
confpath = args.p
- print "confpath %s, workdir %s" % (confpath, workdir)
+ print("confpath %s, workdir %s" % (confpath, workdir))
os.chdir(workdir)
- print "Running tests for specific VTY commands"
+ print("Running tests for specific VTY commands")
suite = unittest.TestSuite()
add_gbproxy_test(suite, workdir)
add_sgsn_test(suite, workdir)
diff --git a/tests/xid/Makefile.am b/tests/xid/Makefile.am
index 6c3689f19..6f058f5a6 100644
--- a/tests/xid/Makefile.am
+++ b/tests/xid/Makefile.am
@@ -24,13 +24,12 @@ xid_test_SOURCES = \
$(NULL)
xid_test_LDADD = \
- $(top_builddir)/src/gprs/gprs_llc_xid.o \
+ $(top_builddir)/src/sgsn/gprs_llc_xid.o \
$(LIBOSMOABIS_LIBS) \
$(LIBOSMOCORE_LIBS) \
$(LIBOSMOGSM_LIBS) \
$(LIBOSMOGB_LIBS) \
$(LIBCARES_LIBS) \
- $(LIBCRYPTO_LIBS) \
$(LIBGTP_LIBS) \
-lrt \
-lm \
diff --git a/tests/xid/xid_test.c b/tests/xid/xid_test.c
index b77a4ae85..89d82e999 100644
--- a/tests/xid/xid_test.c
+++ b/tests/xid/xid_test.c
@@ -19,8 +19,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <openbsc/gprs_llc_xid.h>
-#include <openbsc/debug.h>
+#include <osmocom/sgsn/gprs_llc_xid.h>
+#include <osmocom/sgsn/debug.h>
#include <osmocom/core/talloc.h>
#include <osmocom/core/utils.h>
@@ -142,17 +142,20 @@ static struct log_info info = {
int main(int argc, char **argv)
{
void *xid_ctx;
-
- osmo_init_logging(&info);
+ void *log_ctx;
xid_ctx = talloc_named_const(NULL, 0, "xid_ctx");
+ log_ctx = talloc_named_const(xid_ctx, 0, "log");
+ osmo_init_logging2(log_ctx, &info);
test_xid_decode(xid_ctx);
test_xid_encode(xid_ctx);
printf("Done\n");
talloc_report_full(xid_ctx, stderr);
+ talloc_free(log_ctx);
OSMO_ASSERT(talloc_total_blocks(xid_ctx) == 1);
+ talloc_free(xid_ctx);
return 0;
}