diff options
209 files changed, 26581 insertions, 7161 deletions
diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 000000000..7592debf9 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1 @@ +open_collective: osmocom diff --git a/.gitignore b/.gitignore index bcd684787..412e5f164 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,11 @@ debian/*.log +debian/autoreconf.* +debian/*.substvars +debian/tmp +debian/files +debian/.debhelper +debian/osmo-msc*/ + *.o *.lo *.a @@ -15,6 +22,7 @@ config.h.in *.pyc *.gcda *.gcno +*~ #configure aclocal.m4 @@ -72,3 +80,6 @@ doc/manuals/generated/ doc/manuals/osmomsc-usermanual.xml doc/manuals/common doc/manuals/build +doc/manuals/vty/msc_vty_reference.xml + +contrib/osmo-msc.spec diff --git a/Makefile.am b/Makefile.am index 3f89896a3..13a7313f4 100644 --- a/Makefile.am +++ b/Makefile.am @@ -9,15 +9,22 @@ AM_CPPFLAGS = \ $(NULL) SUBDIRS = \ - doc \ include \ src \ + doc \ contrib \ tests \ $(NULL) BUILT_SOURCES = $(top_srcdir)/.version -EXTRA_DIST = git-version-gen osmoappdesc.py .version +EXTRA_DIST = \ + .version \ + README.md \ + contrib/osmo-msc.spec.in \ + debian \ + git-version-gen \ + osmoappdesc.py \ + $(NULL) AM_DISTCHECK_CONFIGURE_FLAGS = \ --with-systemdsystemunitdir=$$dc_install_base/$(systemdsystemunitdir) diff --git a/README b/README deleted file mode 100644 index a45ef951e..000000000 --- a/README +++ /dev/null @@ -1,24 +0,0 @@ -About OsmoMSC -============= - -OsmoMSC originated from the OpenBSC project, which started as a minimalistic -all-in-one implementation of the GSM Network. In 2017, OpenBSC had reached -maturity and diversity (including M3UA SIGTRAN and 3G support in the form of -IuCS and IuPS interfaces) that naturally lead to a separation of the all-in-one -approach to fully independent separate programs as in typical GSM networks. - -OsmoMSC was one of the parts split off from the old openbsc.git. Before, it was -the libmsc part of the old OsmoNITB. Since a true A interface and IuCS for 3G -support is available, OsmoMSC exists only as a separate standalone entity. - -OsmoMSC exposes -- GSUP towards OsmoHLR (or a MAP proxy); -- A over IP towards a BSC (e.g. OsmoBSC); -- IuCS towards an RNC or HNB-GW (e.g. OsmoHNBGW) for 3G voice; -- MNCC (Mobile Network Call Control derived from GSM TS 04.07); -- SMPP 3.4 (Short Message Peer-to-Peer); -- The Osmocom typical telnet VTY and CTRL interfaces. - -Find OsmoMSC issue tracker and wiki online at -https://osmocom.org/projects/osmomsc -https://osmocom.org/projects/osmomsc/wiki diff --git a/README.md b/README.md new file mode 100644 index 000000000..df1cb5fc0 --- /dev/null +++ b/README.md @@ -0,0 +1,110 @@ +osmo-msc - Osmocom MSC Implementation +===================================== + +This repository contains a C-language implementation of a GSM **Mobile Switching +Centre (MSC)** for 2G (GSM) and 3G (UMTS). It is part of the +[Osmocom](https://osmocom.org/) Open Source Mobile Communications +project. + +OsmoMSC exposes + + * *A over IP* towards BSCs (e.g. [osmo-bsc](https://osmocom.org/projects/osmobsc/wiki): 3GPP AoIP or SCCPlite + * *IuCS over IP* towards RNCs / HNBGW (e.g. [osmo-hnbgw](https://osmocom.org/projects/osmohnbgw/wiki)) + * *MGCP* towards a co-located [osmo-mgw](https://osmocom.org/projects/osmo-mgw/wiki) for the RTP streams + * *[GSUP](https://osmocom.org/projects/cellular-infrastructure/wiki/GSUP)* (instead of 3GPP MAP) towards [osmo-hlr](https://osmocom.org/projects/osmo-hlr/wiki) + * *SMPP* towards any external SMS sending/receiving applications + * *[MNCC](https://osmocom.org/projects/osmomsc/wiki/MNCC)* as external call-control interface towards e.g. + [osmo-sip-connectr](https://osmocom.org/projects/osmo-sip-conector/wiki) + * The Osmocom typical telnet *VTY* and *CTRL* interfaces. + * The Osmocom typical *statsd* exporter. + +OsmoMSC implements + + * mobility management + * call control (either via built-in MNCC handler or external osmo-sip-connector) + * voice group call ([VGCS](https://osmocom.org/projects/cellular-infrastructure/wiki/Voice_Group_Call)) and + voice broadcast calls ([VBS](https://osmocom.org/projects/cellular-infrastructure/wiki/Voice_Broadcast_Call)) as used in GSM-R + * USSD (exposed via GSUP) + * SMS (either via built-in SMSC or external via GSUP) + +Homepage +-------- + +You can find the OsmoMSC home page and wiki online at +<https://osmocom.org/projects/osmomsc/wiki>. + + +GIT Repository +-------------- + +You can clone from the official osmo-msc.git repository using + + git clone https://gitea.osmocom.org/cellular-infrastructure/osmo-msc + +There is a web interface at <https://gitea.osmocom.org/cellular-infrastructure/osmo-msc> + + +Documentation +------------- + +User Manuals and VTY reference manuals are [optionally] built in PDF form +as part of the build process. + +Pre-rendered PDF version of the current "master" can be found at +[User Manual](https://ftp.osmocom.org/docs/latest/osmomsc-usermanual.pdf) +as well as the [VTY Reference Manual](https://ftp.osmocom.org/docs/latest/osmomsc-vty-reference.pdf) + + +Forum +----- + +We welcome any osmo-msc related discussions in the +[Cellular Network Infrastructure -> 2G/3G CN](https://discourse.osmocom.org/c/cni/2g-3g-cn) +section of the osmocom discourse (web based Forum). + + +Mailing List +------------ + +Discussions related to osmo-msc are happening on the +openbsc@lists.osmocom.org mailing list, please see +<https://lists.osmocom.org/mailman/listinfo/openbsc> for subscription +options and the list archive. + +Please observe the [Osmocom Mailing List +Rules](https://osmocom.org/projects/cellular-infrastructure/wiki/Mailing_List_Rules) +when posting. + +Issue Tracker +------------- + +We use the [issue tracker of the osmo-msc project on osmocom.org](https://osmocom.org/projects/osmomsc/issues) for +tracking the state of bug reports and feature requests. Feel free to submit any issues you may find, or help +us out by resolving existing issues. + + +Contributing +------------ + +Our coding standards are described at +<https://osmocom.org/projects/cellular-infrastructure/wiki/Coding_standards> + +We us a gerrit based patch submission/review process for managing +contributions. Please see +<https://osmocom.org/projects/cellular-infrastructure/wiki/Gerrit> for +more details + +The current patch queue for osmo-msc can be seen at +<https://gerrit.osmocom.org/#/q/project:osmo-msc+status:open> + + +History +------- + +OsmoMSC originated from the [OsmoNITB](https://osmocom.org/projects/osmonitb/wiki/OsmoNITB) +project, which started as a minimalistic all-in-one implementation of the GSM Network. In 2017, OsmoNITB had +reached maturity and diversity (including M3UA SIGTRAN and 3G support in the form of IuCS and IuPS interfaces) +that naturally lead to a separation of the all-in-one approach to fully independent separate programs as in +typical GSM networks. + +OsmoMSC was one of the parts split off from the old openbsc.git. diff --git a/README.vty-tests b/README.vty-tests index 0669ea8e8..dc34916ee 100644 --- a/README.vty-tests +++ b/README.vty-tests @@ -1,6 +1,6 @@ To run the configuration parsing and output (VTY) test suite, first install - git://git.osmocom.org/python/osmo-python-tests + https://gitea.osmocom.org/cellular-infrastructure/osmo-python-tests and pass the following configure options here: diff --git a/TODO-RELEASE b/TODO-RELEASE new file mode 100644 index 000000000..8b07972f3 --- /dev/null +++ b/TODO-RELEASE @@ -0,0 +1,10 @@ +# When cleaning up this file: bump API version in corresponding Makefile.am and rename corresponding debian/lib*.install +# according to https://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html#Updating-version-info +# In short: +# LIBVERSION=c:r:a +# If the library source code has changed at all since the last update, then increment revision: c:r + 1:a. +# If any interfaces have been added, removed, or changed since the last update: c + 1:0:0. +# If any interfaces have been added since the last public release: c:r:a + 1. +# If any interfaces have been removed or changed since the last public release: c:r:0. +#library what description / commit summary line +libosmogsm >1.9.0 ABI breakage in struct osmo_gsup_pdp_info, use new fields pdp_type_* and pdp_address.
\ No newline at end of file diff --git a/configure.ac b/configure.ac index 36ff99e3c..89d37c2e6 100644 --- a/configure.ac +++ b/configure.ac @@ -9,6 +9,8 @@ AC_CONFIG_AUX_DIR([.]) AM_INIT_AUTOMAKE([dist-bzip2]) AC_CONFIG_TESTDIR(tests) +CFLAGS="$CFLAGS -std=gnu11" + dnl kernel style compile messages m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) @@ -22,6 +24,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 @@ -29,22 +36,19 @@ if test "x$PKG_CONFIG_INSTALLED" = "xno"; then fi PKG_PROG_PKG_CONFIG([0.20]) -dnl check for AX_CHECK_COMPILE_FLAG -m4_ifdef([AX_CHECK_COMPILE_FLAG], [], [ - AC_MSG_ERROR([Please install autoconf-archive; re-run 'autoreconf -fi' for it to take effect.]) - ]) - +PKG_CHECK_MODULES(LIBSQLITE3, sqlite3) +PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore >= 1.9.0) +PKG_CHECK_MODULES(LIBOSMOVTY, libosmovty >= 1.9.0) +PKG_CHECK_MODULES(LIBOSMOCTRL, libosmoctrl >= 1.9.0) +PKG_CHECK_MODULES(LIBOSMOGSM, libosmogsm >= 1.9.0) +PKG_CHECK_MODULES(LIBOSMOABIS, libosmoabis >= 1.5.0) +PKG_CHECK_MODULES(LIBOSMONETIF, libosmo-netif >= 1.4.0) +PKG_CHECK_MODULES(LIBOSMOSIGTRAN, libosmo-sigtran >= 1.8.0) +PKG_CHECK_MODULES(LIBOSMOSCCP, libosmo-sccp >= 1.8.0) +PKG_CHECK_MODULES(LIBOSMOMGCPCLIENT, libosmo-mgcp-client >= 1.12.0) +PKG_CHECK_MODULES(LIBOSMOGSUPCLIENT, libosmo-gsup-client >= 1.7.0) -PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore >= 1.0.0) -PKG_CHECK_MODULES(LIBOSMOVTY, libosmovty >= 1.0.0) -PKG_CHECK_MODULES(LIBOSMOCTRL, libosmoctrl >= 1.0.0) -PKG_CHECK_MODULES(LIBOSMOGSM, libosmogsm >= 1.0.0) -PKG_CHECK_MODULES(LIBOSMOABIS, libosmoabis >= 0.6.0) -PKG_CHECK_MODULES(LIBOSMONETIF, libosmo-netif >= 0.4.0) -PKG_CHECK_MODULES(LIBOSMOSIGTRAN, libosmo-sigtran >= 1.0.0) -PKG_CHECK_MODULES(LIBOSMOSCCP, libosmo-sccp >= 1.0.0) -PKG_CHECK_MODULES(LIBOSMOMGCPCLIENT, libosmo-mgcp-client >= 1.5.0) -PKG_CHECK_MODULES(LIBOSMOGSUPCLIENT, libosmo-gsup-client >= 1.0.0) +AC_CHECK_FUNC([timegm], [AC_DEFINE(HAVE_TIMEGM, 1, Define if libc implements timegm)]) old_LIBS=$LIBS AC_SEARCH_LIBS([sctp_send], [sctp], [ @@ -91,7 +95,7 @@ fi AC_ARG_ENABLE([smpp], [AS_HELP_STRING([--enable-smpp], [Build the SMPP interface])], [osmo_ac_build_smpp="$enableval"],[osmo_ac_build_smpp="no"]) if test "$osmo_ac_build_smpp" = "yes" ; then - PKG_CHECK_MODULES(LIBSMPP34, libsmpp34 >= 1.13.0) + PKG_CHECK_MODULES(LIBSMPP34, libsmpp34 >= 1.14.0) AC_DEFINE(BUILD_SMPP, 1, [Define if we want to build SMPP]) fi AM_CONDITIONAL(BUILD_SMPP, test "x$osmo_ac_build_smpp" = "xyes") @@ -102,25 +106,12 @@ AC_ARG_ENABLE([iu], [AS_HELP_STRING([--enable-iu], [Build 3G support, aka IuPS a [osmo_ac_iu="$enableval"],[osmo_ac_iu="no"]) if test "x$osmo_ac_iu" = "xyes" ; then PKG_CHECK_MODULES(LIBASN1C, libasn1c >= 0.9.30) - PKG_CHECK_MODULES(LIBOSMORANAP, libosmo-ranap >= 0.3.0) + PKG_CHECK_MODULES(LIBOSMORANAP, libosmo-ranap >= 1.5.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) -dnl checks for header files -AC_HEADER_STDC -AC_CHECK_HEADERS(dbi/dbd.h,,AC_MSG_ERROR(DBI library is not installed)) - - -dnl Checks for typedefs, structures and compiler characteristics -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([-Werror=sizeof-array-argument], [CFLAGS="$CFLAGS -Werror=sizeof-array-argument"]) -AX_CHECK_COMPILE_FLAG([-Werror=sizeof-pointer-memaccess], [CFLAGS="$CFLAGS -Werror=sizeof-pointer-memaccess"]) - # Coverage build taken from WebKit's configure.in AC_MSG_CHECKING([whether to enable code coverage support]) AC_ARG_ENABLE(coverage, @@ -168,7 +159,7 @@ if test "x$enable_ext_tests" = "xyes" ; then AM_PATH_PYTHON 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.]) + AC_MSG_ERROR([Please install https://gitea.osmocom.org/cellular-infrastructure/osmo-python-tests to run the VTY/CTRL tests.]) fi fi AC_MSG_CHECKING([whether to enable VTY/CTRL tests]) @@ -243,20 +234,27 @@ AC_OUTPUT( include/Makefile include/osmocom/Makefile include/osmocom/msc/Makefile + include/osmocom/smpp/Makefile src/Makefile src/libmsc/Makefile src/libvlr/Makefile + src/libsmpputil/Makefile src/osmo-msc/Makefile src/utils/Makefile tests/Makefile tests/atlocal tests/smpp/Makefile + tests/db_sms/Makefile tests/sms_queue/Makefile tests/msc_vlr/Makefile + tests/sdp_msg/Makefile + tests/mncc/Makefile + tests/csd/Makefile doc/Makefile doc/examples/Makefile doc/manuals/Makefile doc/sequence_charts/Makefile contrib/Makefile contrib/systemd/Makefile + contrib/osmo-msc.spec Makefile) diff --git a/contrib/jenkins.sh b/contrib/jenkins.sh index be8dadcf7..c5161eff6 100755 --- a/contrib/jenkins.sh +++ b/contrib/jenkins.sh @@ -5,6 +5,7 @@ # * 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") +# * IS_MASTER_BUILD: set to 1 when running from master-builds (not gerrit-verifications) # if ! [ -x "$(command -v osmo-build-dep.sh)" ]; then @@ -12,6 +13,14 @@ if ! [ -x "$(command -v osmo-build-dep.sh)" ]; then exit 2 fi +exit_tar_workspace() { + if [ "$IS_MASTER_BUILD" = "1" ]; then + tar -cJf "/tmp/workspace.tar.xz" "$base" + mv /tmp/workspace.tar.xz "$base" + fi + + cat-testlogs.sh +} set -ex @@ -35,23 +44,19 @@ export PATH="$inst/bin:$PATH" osmo-build-dep.sh libosmo-abis osmo-build-dep.sh libosmo-netif osmo-build-dep.sh libosmo-sccp -PARALLEL_MAKE="" osmo-build-dep.sh libsmpp34 +osmo-build-dep.sh libsmpp34 osmo-build-dep.sh osmo-mgw osmo-build-dep.sh osmo-hlr -enable_werror="" if [ "x$IU" = "x--enable-iu" ]; then 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 @@ -65,17 +70,18 @@ set -x cd "$base" autoreconf --install --force -./configure --enable-sanitize $enable_werror --enable-smpp $IU --enable-external-tests $CONFIG +./configure --enable-sanitize --enable-werror --enable-smpp $IU --enable-external-tests $CONFIG $MAKE $PARALLEL_MAKE LD_LIBRARY_PATH="$inst/lib" $MAKE check \ - || cat-testlogs.sh + || exit_tar_workspace LD_LIBRARY_PATH="$inst/lib" \ - DISTCHECK_CONFIGURE_FLAGS="$enable_werror --enable-smpp $IU --enable-external-tests $CONFIG" \ - $MAKE distcheck \ - || cat-testlogs.sh + DISTCHECK_CONFIGURE_FLAGS="--enable-werror --enable-smpp $IU --enable-external-tests $CONFIG" \ + $MAKE $PARALLEL_MAKE distcheck \ + || exit_tar_workspace if [ "$WITH_MANUALS" = "1" ] && [ "$PUBLISH" = "1" ]; then make -C "$base/doc/manuals" publish fi +$MAKE $PARALLEL_MAKE maintainer-clean osmo-clean-workspace.sh diff --git a/contrib/osmo-msc.spec.in b/contrib/osmo-msc.spec.in new file mode 100644 index 000000000..de9314926 --- /dev/null +++ b/contrib/osmo-msc.spec.in @@ -0,0 +1,118 @@ +# +# spec file for package osmo-msc +# +# Copyright (c) 2017, Martin Hauke <mardnh@gmx.de> +# +# All modifications and additions to the file contributed by third parties +# remain the property of their copyright owners, unless otherwise agreed +# upon. The license for this file, and modifications and additions to the +# file, is the same license as for the pristine package itself (unless the +# license for the pristine package is not an Open Source License, in which +# case the license is the MIT License). An "Open Source License" is a +# license that conforms to the Open Source Definition (Version 1.9) +# published by the Open Source Initiative. + +## Disable LTO for now since it breaks compilation of the tests +## https://osmocom.org/issues/4115 +%define _lto_cflags %{nil} + +%define with_iu 1 +Name: osmo-msc +Version: @VERSION@ +Release: 0 +Summary: Osmocom's MSC for 2G and 3G circuit-switched mobile networks +License: AGPL-3.0-or-later AND GPL-2.0-only +Group: Productivity/Telephony/Servers +URL: https://osmocom.org/projects/osmomsc +Source: %{name}-%{version}.tar.xz +BuildRequires: autoconf +BuildRequires: automake +BuildRequires: libtool +%if 0%{?suse_version} +BuildRequires: systemd-rpm-macros +%endif +BuildRequires: pkgconfig >= 0.20 +BuildRequires: pkgconfig(sqlite3) +BuildRequires: pkgconfig(libcrypto) >= 0.9.5 +BuildRequires: pkgconfig(libosmo-gsup-client) >= 1.7.0 +BuildRequires: pkgconfig(libosmo-mgcp-client) >= 1.12.0 +BuildRequires: pkgconfig(libosmo-netif) >= 1.4.0 +BuildRequires: pkgconfig(libosmo-sccp) >= 1.8.0 +BuildRequires: pkgconfig(libosmo-sigtran) >= 1.8.0 +BuildRequires: pkgconfig(libosmoabis) >= 1.5.0 +BuildRequires: pkgconfig(libosmocore) >= 1.9.0 +BuildRequires: pkgconfig(libosmoctrl) >= 1.9.0 +BuildRequires: pkgconfig(libosmogsm) >= 1.9.0 +BuildRequires: pkgconfig(libosmovty) >= 1.9.0 +BuildRequires: pkgconfig(libsmpp34) >= 1.14.0 +#### +BuildRequires: lksctp-tools-devel +#### +%{?systemd_requires} +%if %{with_iu} +BuildRequires: pkgconfig(libasn1c) >= 0.9.30 +BuildRequires: pkgconfig(libosmo-ranap) >= 1.5.0 +%endif + +%description +The Mobile Switching Center (MSC) is the heart of 2G/3G +circuit-switched services. It terminates the A-interface links from the +Base Station Controllers (BSC) and handles the MM and CC sub-layers of +the Layer 3 protocol from the phones (MS). + +This Osmocom implementation of the MSC handles A interfaces via 3GPP +AoIP in an ASP role. It furthermore implements IETF MGCP against an +external media gateway, such as OsmoMGW. It does *not* implement MAP +towards a HLR, but the much simpler Osmocom GSUP protocol, which can +be translated to MAP if needed. + +%prep +%setup -q + +%build +echo "%{version}" >.tarball-version +autoreconf -fi +%configure \ +%if %{with_iu} + --enable-iu \ +%endif + --enable-smpp \ + --docdir=%{_docdir}/%{name} \ + --with-systemdsystemunitdir=%{_unitdir} + +make %{?_smp_mflags} + +%install +%make_install + +%if 0%{?suse_version} +%preun +%service_del_preun %{name}.service + +%postun +%service_del_postun %{name}.service + +%pre +%service_add_pre %{name}.service + +%post +%service_add_post %{name}.service +%endif + +%check +make %{?_smp_mflags} check || (find . -name testsuite.log -exec cat {} +) + +%files +%license COPYING +%doc AUTHORS README.md +%dir %{_docdir}/%{name}/examples +%dir %{_docdir}/%{name}/examples/osmo-msc +%{_docdir}/%{name}/examples/osmo-msc/osmo-msc.cfg +%{_docdir}/%{name}/examples/osmo-msc/osmo-msc_custom-sccp.cfg +%{_docdir}/%{name}/examples/osmo-msc/osmo-msc_multi-cs7.cfg +%{_bindir}/osmo-msc +%{_unitdir}/%{name}.service +%dir %{_sysconfdir}/osmocom +%config(noreplace) %{_sysconfdir}/osmocom/osmo-msc.cfg + +%changelog diff --git a/contrib/systemd/osmo-msc.service b/contrib/systemd/osmo-msc.service index 343639cf3..f21aec7b5 100644 --- a/contrib/systemd/osmo-msc.service +++ b/contrib/systemd/osmo-msc.service @@ -4,10 +4,14 @@ Wants=osmo-hlr.service Wants=osmo-mgw.service After=osmo-hlr.service After=osmo-hnbgw.service +After=network-online.target +Wants=network-online.target [Service] Type=simple Restart=always +StateDirectory=osmocom +WorkingDirectory=%S/osmocom ExecStart=/usr/bin/osmo-msc -c /etc/osmocom/osmo-msc.cfg RestartSec=2 diff --git a/debian/changelog b/debian/changelog index 8aec381ed..debce4e80 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,815 @@ +osmo-msc (1.11.1) unstable; urgency=medium + + [ Neels Hofmeyr ] + * fix codecs in internal call bridge + * make two functions static + + [ Mychaela N. Falconia ] + * CC: don't start guard timer on mid-call MNCC messages + * gsup_client_mux: set destination_name in error reply function + * SMS over GSUP: correctly route GSUP responses to MT SMS + * SMS over GSUP: set source_name in GSUP reply messages + + [ Andreas Eversberg ] + * ASCI: Remove duplicated CLEAR COMMAND from VGCS/VBS channel handling + + -- Oliver Smith <osmith@sysmocom.de> Thu, 28 Sep 2023 13:53:07 +0200 + +osmo-msc (1.11.0) unstable; urgency=medium + + [ arehbein ] + * Transition to use of 'telnet_init_default' + + [ Neels Hofmeyr ] + * sdp_msg.c: fix missing rate in sdp_audio_codecs_add() + * comment: clarify L3 Info processing + * IuCS: remove IuUP LOOPBACK hack + * make: doc/sequence_charts: use wildcards for EXTRA_DIST and CLEANFILES + * tweak MNCC logging, add RTP info + * msc_log_to_ladder.py: various tweaks + * charts: Rename voice_call_full.msc to voice_call_external_mncc.msc + * update doc/sequence_charts/voice_call_external_mncc.msc + * add voice_call_internal_mncc.msc + * add codec_mapping.h,c + * MNCC: use codec_mapping, drop mgcp_codec_to_mncc_payload_msg_type() + * [codecs filter] add codec_filter.h,c + * [codecs filter] add trans.cc.codecs + * [codecs filter] store BSS codec list from Compl L3 + * [codecs filter] MO call: apply BSS codec list + * [codecs filter] MT call: apply BSS codec list + * [codecs filter] MT call: apply remote call leg codecs + * [codecs filter] MT call: store MS Bearer Cap from CC Call Conf + * msc_vlr_test_call: include RAN RTP addr in ass compl + * [codecs filter] apply BSS codecs from Assignment Complete + * add ran_infra.force_mgw_codecs_to_ran + * rtp_stream: allow multiple codecs / use codec filter from Assignment + * in ran_msg, return gsm0808_speech_codec (intra-MSC) + * in ran_msg, return gsm0808_speech_codec (inter-MSC) + * [codecs filter] use filter result in MT DTAP CC Setup + * [codecs filter] use filter result in Assignment + * [codecs filter] send + receive SDP via MNCC + * msc_vlr_tests: confirm crcx by RAN/CN side separately + * [codecs filter] use codecs filter on crcx ok + * do CN CRCX first + * mncc_recvmsg(): log caller file,line + * [codecs filter] msc_vlr_test_call: test codecs resolution + * codecs: compose HO Req Ch Type from cc.codecs + * HO Req: include IE Codec List (MSC Preferred) + * fix msc_vlr_test_call SDP mncc_rtp + * coverity: sdp_msg_test.c: check rc of sdp_msg_from_sdp_str() + * 3G: decapsulate IuUP to AMR at the MGW; allow 3G<-AMR->2G + * TODO-RELEASE: add note on osmo-sip-connector and SDP + + [ Vadim Yanitskiy ] + * src/Makefile.am: remove unneeded AM_LDFLAGS with LIBS + * tests: use -no-install libtool flag to avoid ./lt-* scripts + * tests: $(BUILT_SOURCES) is not defined, depend on osmo-msc + * copyright: fix typo: sysmocom s/s.m.f.c./s.f.m.c./ GmbH + * fixup: contrib/jenkins: create workspace.tar.xz on error + * tests/{ctrl,vty}_test_runner.py: raise an exception if proc's rc != 0 + * msc_vty: support spaces in short/long network name + * ran_a_mgcp_codec_from_sc(): cosmetic: remove unneeded breaks + * ran_a_mgcp_codec_from_sc(): map GSM0808_SCT_CSD to CODEC_CLEARMODE + * ran_a_channel_type_to_speech_codec_list(): set PI/PT for CSD + * codec_mapping: codec_map[]: add missing speech codec for CLEARMODE + * csd_bs_list_to_bearer_cap(): properly initialize bcap fields + * csd_bs_list_to_bearer_cap(): add default branch for safety + + [ Pau Espin Pedrol ] + * mncc_sock: Call osmo_fd_unregister() before closing and changing bfd->fd + * rtp_stream: Update id after modifying fields upon Tx of MGCP msg + * rtp_stream: Fix remote_osmux_cid_sent_to_mgw never set to true + * UserManual: Include sigtran*.adoc from osmo-gsm-manuals.git + * Write explicit role & sctp-role fields in ASP configurations + * Use new mgcp_client_conf_alloc() API to alloc mgcp_client_conf + * Tx Loc UPD ACC: Use PLMN provided by subscr + * trans_lcls_compose(): Set PLMN fron cell currently in use + + [ Oliver Smith ] + * msc_mgw_setup: use mgcp_client_pool_empty() + * msc_main: close SMS db on startup error + * debian: set compat level to 10 + * contrib/jenkins: create workspace.tar.xz on error + * systemd: depend on networking-online.target + * codec_mapping: add clearmode + * ran_a_channel_type_to_speech_codec_list: add CSD + * codec_filter_set_ms_from_bc: prepare for CSD + * Cosmetic: gsm48_cc_tx_setup: tweak comment + * Cosmetic: gsm48_cc_tx_setup: remove TODO comment + * codec_filter_init: prepare for CSD + * codec_filter_set_ran: prepare for CSD + * codec_filter_set_bss: prepare for CSD + * codec_filter_run: prepare for CSD + * transaction: move cc.codecs.remote -> cc.remote + * transaction: move cc.codecs.result -> cc.local + * msc: add trans_cc_set_remote_from_bc + * gsm48_cc_tx_setup: set trans->bearer_cap.transfer early + * Add initial CSD support with external MNCC + * smpp_handle_bind_tx: initialize tlv + * sdp_msg_test: fix dereference after null check + * smpp_msc: submit_to_sms: check ud_len > sms_msg_len + * msc_ho_send_handover_request: fix check_after_deref + * csd_bs_list_to_gsm0808_channel_type: fix rc check + * gsm48_cc_tx_alerting: check rc of sdp_msg_from_sdp_str + * mncc_test: fix talloc_named_const + * gsm48_cc_tx_setup: use MNCC bcaps for CSD + * test: add csd_test + * csd_bs_list_remove: fix removal logic + * mncc_builtin: permit data bearer types + * csd_bs_to_gsm0808: add T 300 / proper ch_rate_type + * Cosmetic: fix typo + * csd_bs_list_to_gsm0808_ct: assert -> ret -EINVAL + * msc_ho_send_handover_request: support CSD + * msc_a_up_call_assignment_complete: check CSD codec + * gsm48_cc_tx_call_proc_…: verify bcap.transfer + + [ Andreas Eversberg ] + * ASCI: Add log categories for GCC/BCC (call control) + * ASCI: Add log category for VGCS/VBS call and channel FSM + * ASCI: Use a unique call-id for RTP streams + * ASCI: rtp_stream_commit(): Also update MGW on conn mode change + * ASCI: Allow usage of rtp_stream with other FSM + * ASCI: Add transaction type to trans_find_by_callref() + * ASCI: Add two new transaction types for VGCS and VBS + * ASCI: Allow transaction without subscriber associated + * ASCI: Add simple implementation of Group Call Register + * ASCI: Add functions to transcode VGCS/VBS messages on A-interface + * ASCI: Add callref to assignment command + * ASCI: Add call control for VGCS/VBS + * ASCI: Add decoder for VGCS/VBS messages to msc_a.c + * ASCI: Add function to receive VGCS/VBS messages from BSS + * ASCI: Add option to switch on or off ASCI support + * ASCI: Check return code of osmo_mobile_identity_decode() + * ASCI: Remove check for trans->msc_a to be set in _assign_complete() + * ASCI: Add VTY to configure GCR (Group Call Register) + * ASCI: Add reception of UPLINK RELEASE on dedicated channel + * ASCI: Clear VGCS call and channel on BSSMAP reset message + * ASCI: Receive messages from MSC-A role related to VGCS/VBS + * ASCI: Null pointer bug fix in trans_create_bcc_gcc + * ASCI: Fix wrong check for Null pointer in vgcs_cell_fsm_null() + * ASCI: Check if codec mapping exists for given codec + * ASCI: Fix Null pointer dereference bug in gsm44068_bcc_gcc_trans_free() + * ASCI: Point to correct state machine when calling ran_encode_and_send() + * ASCI: Add debugging and error logging to VGCS/VBS call control + * ASCI: Add missing transaction ID to SET PARAMETER message + + [ Keith Whyte ] + * SMPP: Fix Memory leaks + + -- Pau Espin Pedrol <pespin@sysmocom.de> Tue, 12 Sep 2023 16:46:11 +0200 + +osmo-msc (1.10.0) unstable; urgency=medium + + [ Keith Whyte ] + * Don't let this osmo-msc operate on a libdbi database + * Turn off secure_delete in sqlite + * Update MNCC field validation mask. + * Change CC_CAUSE returned on unanswered MT Call + * LCLS: Fix Global Call Reference generation + + [ Neels Hofmeyr ] + * fix typo in msgb name for CC SETUP + * missing whitespace in gsm_04_08_cc.c + * err log: fix reverse statement in msc_a call handling + * cosmetic: log actual MNCC msg in tch_rtp_connect() + * sdp_msg: s/_name_/_to_str_/g + * in sdp logging: add payload type number like 'AMR#111' + * sdp_msg: add sdp_audio_codecs_cmp(), add compare flags + * sdp_msg: s/sdp_audio_codec_/sdp_audio_codecs_ + * msc_a,vlr: rename ciphering_required to is_ciphering_to_be_attempted + * msc_a,vlr: add is_ciphering_required (accurately named) + * vlr_lu_fsm: clarify naming of static functions + * vlr: auth_fsm: clarify success/failure result + * vlr: auth_fsm: rename AUTH_RES to AUTH_SUCCESS + * vlr_auth_fsm: add result no_auth_info_event + * vlr: implement fallback to no-auth + * sdp_msg: when NULL, do not crash but return empty SDP str + * log CC timeouts + * add sdp_audio_codec_is_set + * add some comments to sdp_msg.c,h + * sdp_msg.c: parse send/recv mode + * fix sdp_msg_to_sdp_str(), never add fmtp for unset codec + * rtp_stream_commit: check missing MGW ep only when ready for RTP + * rtp_stream: set_remote_addr: do nothing when unchanged + + [ Max ] + * SMPP: clarify (re)start logic + * Ignore .deb build byproducts + * ESME: use osmo_sock_get_name() for logging + * tests: use common stubs for SMS queue test + * Introduce libsmpputil + * Add ESME-specific logging + * Set working directory in systemd service file + * Make esme struct shared + * Use libsmpputil functions in smpp_mirror tool + * cosmetic: use proper name for SMPP handlers + * SMPP: remove duplicate g_smsc definition + * smpp_mirror: fix compiler warning + * SMPP: use default port from libsmpp34 + * SMPP: fix possible NULL pointer dereference + * SMPP: make smpp_smsc_stop() static + * ctrl: take both address and port from vty config + * SMPP: use proper type for boolean variables + + [ Vadim Yanitskiy ] + * contrib/jenkins.sh: do not override parallel make for libsmpp34 + * mncc: move MNCC_F_ALL from mncc.c to mncc.h + * mncc: cosmetic: fix coding style in mncc_prim_check_sign() + * libmsc: check return value of gsm0808_create_ass2() + * msc_main: fix wrong comment: HLR is a separate project + * fix msc_vty_go_parent(): add missing case for MGW_NODE + + [ Pau Espin Pedrol ] + * tests/test_nodes.vty: Avoid listing commands provided by lib + * Introduce support for libosmo-mgcp-client MGW pooling + * vty: Make use of new mgcp_client_pool_config_write() API + * Use new mgcp-client VTY commands under mgw node + * call_leg: Fix EV_MGW_ENDPOINT_GONE not processed in RELEASE state + * doc: Include mgwpool.adoc from osmo-gsm-manuals + + [ Oliver Smith ] + * contrib/jenkins.sh: use enable-werror with IU too + + -- Pau Espin Pedrol <pespin@sysmocom.de> Tue, 07 Feb 2023 17:28:16 +0100 + +osmo-msc (1.9.0) unstable; urgency=medium + + [ Alexander Couzens ] + * utran: use new UTRAN encryption enum + * libmsc/gsm_04_08: refactor require ciphering into an own function + * ran_msg_iu: do not pass UEA0 to ranap_new_msg_sec_mod_cmd2() + + [ Vadim Yanitskiy ] + * VTY: clarify deprecation message for cfg_net_per_loc_upd_cmd + * libmsc: fix memory leak (struct gsm_sms) in gsm340_rx_tpdu() + * libmsc: fix another memleak (struct gsm_sms) in gsm340_rx_tpdu() + * libvlr: vlr_set_ciph_mode(): avoid redundant check + * libvlr: fix is_ciph_required(): always send SecModeCmd for UTRAN + * libmsc: ran_iu_make_security_mode_command(): improve readability + * libmsc: ran_iu_make_security_mode_command(): clarify UIA mask + * libmsc: fix memory leak (struct msgb) in msc_i_ran_enc() + * tests: use 'check_PROGRAMS' instead of 'noinst_PROGRAMS' + + [ Oliver Smith ] + * treewide: remove FSF address + * tests/msc_vlr/Makefile.am: drop -ldbi + + [ Pau Espin Pedrol ] + * Announce IuFP audio codec for UTRAN conns in CRCX towards MGW + * Avoid setting audio codec if not available during assignment_complete (MDCX) + * ran_msg_iu.c: Set proper codec in Assignment Complete + * Drop unneeded ax_check_compile_flag.m4 + * call_leg: local_bridge: Avoid null pointer access if CN-side not ready + + [ Neels Hofmeyr ] + * fix crash on CM Serv Rej: fix use count mismatch + + [ Harald Welte ] + * call rate_ctr_init() to make rate counters work properly + * switch sqlite3 to single-threaded mode + * sms_queue: Annotate each function with some comment + * vlr: Split vlr_subscr_rx_imsi_detach() + * vlr: Add rate counters and stat items + * sms_queue: Introduce rate_ctr / stat_item + * smpp: Fix use-after-free bug when ESME disconnects but has write pending + * smpp: don't enqueue write messages if ESME is disconnected + * sms_queue: refactor sms_pending add/remove code + * sms_queue: merge sms_pending_add into sms_pending_from + * tests: Remove sms.db{-wal,-shm} files, not just sms.db + * switch from libdbi to lbsqlite3 + * db: Switch from 'synchronous = FULL' to 'synchronous = NORMAL' + * sms: Encapsulate SMS queue related config parameters + * sms: Give smsc its own VTY config node + * sms_queue: Use local variable rather than 9x pointer de-ref in function + * sms_queue: Make deletion of messages from DB VTY-configurable + * smpp: Parse and use SMPP-provided validity period + * sms: Make default SMS validity period configurable via VTY + * sms: Introduce VTY-configurable minimum SMS validity period + * update git URLs (git -> https; gitea) + * Convert + Expand README file + * fix RPM build failures due to README -> README.md rename + + -- Pau Espin Pedrol <pespin@sysmocom.de> Wed, 29 Jun 2022 11:32:11 +0200 + +osmo-msc (1.8.0) unstable; urgency=medium + + [ Pau Espin Pedrol ] + * configure.ac: Depend on newer libosmo-ranap + * Fill Last Used E-UTRAN PLMN Id when in CSFB + * Use new osmo stat items/ctr APIs + * sgs: Use available API to set vlr subscr LastUsedEutranPLMNId + * vlr_sgs: Drop recorded LastEutranPlmnId when UE no longer associated + * sgs_iface.c: Improve logging when paging over SGs + * msc_a.c: Allow MSC_A_EV_CN_CLOSE in state MSC_A_ST_RELEASING + * cosmetic: fix typos in comments + * vlr_sgs.h: Set proper logic order of items in enum sgs_ue_fsm_state + * vlr_auth_fsm.c: Simplify function auth_fsm_wait_ai_resync + * vlr_sgs.c: Fix missing use_count decrease in vlr_sgs_imsi_detach + * vlr_sgs: Balance use_count incremented in vlr_sgs_loc_update + * cosmetic: Fix typo in comment + + [ Oliver Smith ] + * contrib/osmo-msc.spec.in: depend on dbd-sqlite3 + * contrib/osmo-msc.spec.in: require libosmo-ranap >= 0.7.0 + * Revert "Turn some compiler warnings into errors" + + [ Vadim Yanitskiy ] + * SMS-over-GSUP: notify sender if no transaction found + * msc_tx_common_id(): fix potential NULL pointer dereference + * libmsc: fix NULL pointer dereference in trans_lcls_compose() + * libmsc: struct smsc: drop 'const' qualifier from bind_addr + * smpp_smsc: use osmo_talloc_replace_string() in smpp_smsc_conf() + * mncc: rework passing GCR over the MNCC interface + * manuals: remove deprecated -C / --no-dbcounter options + * Do not mention deprecated -M / --mncc-sock-path options + * Do not mention deprecated -l / --database options + + [ Neels Hofmeyr ] + * osmo-msc main: use osmo_select_shutdown() + * ran_msg_a.c: use gsm0808_create_cipher2() + * support A5/4 in Cipher Mode Command + * support A5/4 in inter-BSC handover + * improve logging on encryption, for Ciphering and HO + * add sequence_charts/call_reestablishment.msc + * add vlr_subscr_find_by_mi + * implement CM Re-Establish for voice calls + + [ Eric Wild ] + * vty: allow A5/4 encryption in config + + [ Philipp Maier ] + * running.adoc: add section about MGCP configuration + * msc_vlr_test: remove DLMGCP log messages from unit test output + + [ Harald Welte ] + * smpp: Fix help string in vty for "alert-notifications" + * smpp_mirror: Factor-out reset of SMPP read state + * smpp_mirror: Don't allocate msgb's for unrealistic amounts of memory + * Fix enabling of UMTS UEA encryption + * Make UTRAN encryption algorithms configurable + + [ Keith Whyte ] + * Add support for LCLS to the MSC + + [ Alexander Couzens ] + * Validate the choosen UTRAN encryption algorithm + + -- Pau Espin Pedrol <pespin@sysmocom.de> Tue, 16 Nov 2021 17:44:54 +0100 + +osmo-msc (1.7.0) unstable; urgency=medium + + [ Keith Whyte ] + * Use GSM411_RP_* and not GSM48_CC_* + * Trivial: code simplification, return early + * vty: allow configuring db path from cfg file + * Don't Store an SMS in the database when the ESME is not Bound + + [ Pablo Neira Ayuso ] + * libmsc: SMS, Avoid premature RP-ACK to MS + + [ Vadim Yanitskiy ] + * manuals/vty: update the VTY reference to reflect recent changes + * libvlr: remove unused 'periodic_lu_timer' from struct vlr_subscr + * osmo-msc: fix: properly initialize default values for MGW timers + * msc/signal.h: remove unused (since the NiTB split up) signals + * VTY: mark 'subscriber create imsi' command as deprecated + * VTY: add osmo_tdef introspection and configuration commands + * libvlr: use generic osmo_tdef API for T3250, T3260, and T3270 + * libmsc: move subscriber expiration timer T3212 to libvlr + * vlr: remove unused parameter 'log_level' of auth_fsm_start() + * vlr_sgs_fsm: add missing break, do not call to_null() twice + * msc/sccp_ran.h: fix: do not pass -1 to osmo_rat_type_name() + * VTY: cosmetic: make struct cmd_node for GSMNET_NODE static + * libmsc/gsm_04_08: make use of msc_a in gsm48_rx_rr_app_info() + * libmsc/gsm_04_08: use DRR in gsm48_rx_rr_pag_resp(), not DMM + * libmsc/gsm_04_11.h: remove unused sms_deliver definition + * osmo-msc: use stderr to print error messages, not stdout + * libmsc/sdp: cosmetic: fix less-than-zero comparison of an unsigned value + * SMS-over-GSUP: clarify error message about unexpected MO/MT SMS + * SMS-over-GSUP: move net->sms_over_gsup check to gsm411_gsup_rx() + * SMS-over-GSUP: respond with error if net->sms_over_gsup is false + * SMS-over-GSUP: notify sender about unhandled GSUP messages + * SMS-over-GSUP: notify sender about malformed GSUP messages + * SMS-over-GSUP: notify sender in case of RPL delivery failure + * gsm_04_14: fix off-by-one error in create_gsm0414_msg() + * vty: fix vsub reference counting: call vlr_subscr_put() + * debian/control: change maintainer to the Osmocom team / mailing list + * mncc_builtin: cosmetic: fix coding style in int_mncc_recv() + * mncc_builtin: log type of unhandled message in int_mncc_recv() + * main: add --vty-ref-mode, use vty_dump_xml_ref_mode() + * submit_to_sms(): fix the use of deprecated gsm_septets2octets() + * ran_a_decode_cipher_mode_reject(): use gsm0808_get_cause() + * fix _gsm48_cc_trans_free(): send MNCC REL.ind on Clear Request + + [ Neels Hofmeyr ] + * fix segfault: unsolicited Paging Response + * manual: add missing mention of MGCP in "Multiple instances" + * manual: Multiple Instances: tweak MNCC, add missing SGs doc + * manual: link to new common cs7-config.adoc, remove some dup of that + * vlr_subscr_rx_id_resp(): dont assert on received MI type + * msc_vlr_test_gsm_ciph.c: fix IMEISV MI: even number of digits, clear odd bit + * use new osmo_mobile_identity API everywhere + * add rudimentary NRI support for MSC pooling + * add osmo-msc --vty-ref-xml: dump VTY ref XML to stdout + * add comments to clarify some complete l3 details + * vty 'show connection': show msc_a->via_cell instead of vsub->cgi + * propagate Compl L3 Info Cell ID to the VLR subscriber record + * make vty-transcrip-test: use $VTY_TEST var like osmo-bsc + * refactor: move RESET Osmux TLV parsing to ran_msg_a.c + * sgs_tx_loc_upd_resp_cb(): fix error handling for MI encoding + * is_reset_msg: use proper enum for rc value + * manuals: generate vty reference xml at build time + * Clear Command: set cause value to "Call Control" + * fix crash for unknown MI during Paging Response + * fix MGCP timeout timer + * drop duplicate ran_peer_find() vs ran_peer_find_by_addr() + * fix comment in ran_peer.h + * msc_vlr_tests: make independent of libosmocore talloc + * gsm_network: drop unused neighbor_list member + + [ Eric ] + * configure.ac: fix libtool issue with clang and sanitizer + + [ Philipp Maier ] + * doc: do not use random ip-address for MGW + * msc_vty: remove emergency-call command from network + * msc_a: add callref as call id to ASSIGNMENT REQ. + * msc_ho: fix CALL IDENTIFIER in HANDOVER REQUEST + * mncc_call: fix memory overrun + * gsm_04_08: check return code of osmo_mobile_identity_decode_from_l3() + + [ Harald Welte ] + * vlr_auth_fsm: Fix compilation with gcc-10 + * contrib/osmo-msc.spec.in: Enable SMPP in RPM builds + * remove empty + unused ran_up_l2.c + * osmo-msc.spec.in: Use %config(noreplace) to retain current config file + * Send "BSSMAP CommonID" to tell BSC about the IMSI + * Use osmo_fd_setup() whenever applicable + * debian/control: Recommend installation of osmo-mgw + * Use osmo_fd_*_{disable,enable} + * README update. Explain more what it is than just the history + + [ Pau Espin Pedrol ] + * Use OSMO_FD_* instead of deprecated BSC_FD_* + * ran_msg_iu.c: Avoid redefining osmo-iuh global variables + * configure.ac: Drop trailing whitespace + * Support setting rt-prio and cpu-affinity mask through VTY + * Change default SCTP conn NULL->127.0.0.1 to localhost->localhost + * Support sending IPv6 Transport Address in Assignment Command + * Support handling IPv6 Transport Address in Assignment Complete + * tests: Fix VTY results after switch to newer libosmo-mgcp-client + * Support handling IPv6 Transport Address in Handover Request (Ack) + * mncc: Support IPv6 addresses (new version mncc 7) + * contrib/jenkins: Enable parallel make in make distcheck + * main: generate coredump and exit upon SIGABRT received + * .gitignore: Ignore new autofoo tmp files + * tests: Explicitly drop category from log + * tests: Replace deprecated API log_set_print_filename + + [ Oliver Smith ] + * contrib: import RPM spec + * contrib: integrate RPM spec + * Makefile.am: EXTRA_DIST: debian, contrib/*.spec.in + * contrib/jenkins: don't build osmo-gsm-manuals + * configure.ac: set -std=gnu11 + + [ Alexander Couzens ] + * Convert paging response timer into an osmocom own X4 timer + + -- Pau Espin Pedrol <pespin@sysmocom.de> Tue, 23 Feb 2021 20:22:34 +0100 + +osmo-msc (1.6.1) unstable; urgency=medium + + [ Vadim Yanitskiy ] + * libmsc/gsm_04_08.c: fix: verify MI before calling vlr_subscr_rx_id_resp() + + [ Neels Hofmeyr ] + * vlr_gsup_rx: fix uninitialized rc + * vlr.c: fix condition to check MSISDN presence + + -- Pau Espin Pedrol <pespin@sysmocom.de> Thu, 09 Jan 2020 12:29:08 +0100 + +osmo-msc (1.6.0) unstable; urgency=medium + + [ Philipp Maier ] + * cosmetic: make function mncc_tx_to_gsm_cc static + * sgs_iface: do not use SGsAP-MO-CSFB-INDICATION for CSFB return + * msc_a: switch RAN type back to SGs when a CSFB-Call is cleared + * sgs_iface: Accept messages with unknown TLV elements + * paging: Send SGsAP-SERVICE-ABORT-REQUEST on paging timeout + + [ Neels Hofmeyr ] + * add 'encryption uea 1 2' cfg / fix ttcn3 iu tests + * mncc: send payload type matching chosen codec + * memleak on cc setup errors + * cc trans: make sure bearer cap is empty + * fix segfault: don't send CC REL on NULL msc_a + * vlr_lu_fsm: ignore ID_IMEISV during VLR_ULA_S_WAIT_HLR_UPD + * tweak CC cause for incoming call to unattached nr + * log, cosmetic: add "RR" to "Ciphering Mode Complete" + * msc_vlr_tests: GSUP: don't care about extra IEs + * gsm48_tch_rtp_create(): check against NULL mgcp_info + * msc_a.c, CC trans: change a comment to a debug log + * cosmetic: fix call_leg_ensure_ci() decl. arg name to match impl. + * vlr: don't log about "gratuitous ID RESPONSE" + * ran_dec logging: log message sizes on errors + * msc_a fsm: ignore state chg to same state + * fix error on BSSMAP Cipher Mode Complete L3 msg IE + * catch GSUP auth result without auth_fsm + * LOG_TRANS for CC: always log CC state + * log which DTAP messages are sent to RAN + * log: drop duplicate MNCC log + * also log MNCC_SETUP_REQ + * BSSMAP log tweak + * log: RANAP encode: use RANAP message names instead of BSSAP + * log: ran_msg_a: tweak a message name + * send MNCC REL only if MNCC has actually started + * fsm: use deferred deallocation + * rtp_stream: sanely cancel MGW endpoint FSM notify + * use osmo_sockaddr_str_is_nonzero() + * CC: add error handling for CRCX responses + * add msc_log_to_ladder.py + * charts: add full MO and MT voice call diagram + * cc trans: remove unused tch_rtp_create + * fix msc_vlr_test_call.c + * BSSMAP: decode Codec List (BSS Supported) + * fail on invalid RTP address from MGW + * msc_a CC: add some basic sanity tests + * fix incoming call while Paging + * add sdp_msg API: SDP parsing/composition + * MNCC v6: add optional SDP to the socket protocol + * msc_vlr_tests: better err logging for dtap msgs + * msc_vlr_test_call.c: add MNCC logging + * msc_vlr_tests: log descriptions in color with -v + * msc_vlr_test_call: rename lu_utran_tmsi + * gsup: indicate CN-Domain in SendAuthInfo Requests + * sms db: when storing an SMS, retrieve the ID + * sms log tweak + + [ Vadim Yanitskiy ] + * libvlr/vlr.c: cosmetic: move message_type assignment + * counters: clarify documentation for MSC_CTR_SMS_* entries + * counters: clarify documentation for MSC_CTR_LOC_UPDATE_* entries + * counters: clarify documentation for MSC_CTR_CALL_* entries + * counters: polish documentation of cm_service_request / paging_resp + * libmsc: fix potential NULL-pointer dereferences detected by GCC's LTO + * libmsc/gsm_04_11_gsup.c: do not init a buffer in gsm411_gsup_mo_fwd_sm_req() + * libmsc/gsm_04_11_gsup.c: fix SM-RP-OA encoding for MO SMS over GSUP + + [ Alexander Couzens ] + * smpp_openbsc.c: check acl before deref it + * vlr: gmm_cause_to_fsm_and_mm_cause() drop fsm_cause_p argument + * make vlr_gmm_cause_to_mm_cause public + * vlr_auth_fsm: on SAI use the GSUP provided GMM cause code + + [ Keith Whyte ] + * Implement a global switch on the network to disable call waiting. + + [ Pau Espin Pedrol ] + * vty: fix access to wrong argv in paging response-timer + + [ Oliver Smith ] + * tests: only check IU configs if IU is enabled + * osmoappdesc.py, tests: switch to python 3 + + [ Martin Hauke ] + * Fix some typos + + [ Harald Welte ] + * check for osmo_ss7_init() error return value + * manual: Fix copy+paste error + * Check for osmo_fsm_register() error return value + * msc: exit(2) on unsupported positional arguments on command line + + -- Pau Espin Pedrol <pespin@sysmocom.de> Fri, 03 Jan 2020 18:51:37 +0100 + +osmo-msc (1.5.0) unstable; urgency=medium + + [ Max ] + * Handle LCLS-NOTIFICATION message from BSS + * Various logging fixes + * VLR tests: use msgb_eq_data_print() for comparison + * transaction: drop meaningless ti_flag of trans_assign_trans_id() + * transaction: clarify magic 0xff transaction ID + + [ Vadim Yanitskiy ] + * transaction.c: cosmetic: use 'default' branch in trans_free() + * libmsc/ran_conn.c: cosmetic: use tabs instead of N * 8 spaces + * transaction: change arguments of trans_find_by_sm_rp_mr() + * libmsc/gsm_04_11.c: also assign SM-RP-MR to MO transactions + * libmsc/gsm_04_11.c: introduce and use gsm411_assign_sm_rp_mr() + * libmsc/gsm_04_80.c: use gsm0480_create_release_complete() + * libmsc/gsm_04_80.c: add msc_send_ussd_release_complete_cause() + * libmsc/osmo_msc.c: move connection ref-counting code to 'ran_conn.c' + * transaction: fix description of trans_assign_trans_id() + * transaction.h: use #pragma once as include guard + * libmsc/gsm_09_11.c: implement guard timer for NCSS sessions + * libmsc/ran_conn.c: add missing 'break' to OSMO_RAT_EUTRAN_SGS + * libmsc/sgs_iface.c: fix SGS_STATE_NS11 counter reference + * libmsc/sgs_vty.c: always write server address and VLR name + * libmsc/msc_vty.c: drop dead comparison against null + * libmsc/sgs_iface.c: fix copy-paste error + * libmsc/sgs_iface.c: register sgs_vlr_reset_fsm on DSO load + * libmsc/sgs_vty.c: don't print SGs socket error twice + * libmsc: fix: properly initialize the SGs server + * libmsc/sms_queue.c: fix memleak in smsq_take_next_sms() + * tests/sms_queue: track the use of NULL talloc memory contexts + * msc/gsm_data.h: drop unused SMS_HDR_SIZE macro + * configure.ac: drop rudimentary check for -fvisibility=hidden + * configure.ac: drop useless SQLite3 dependency + * libmsc/db.c: print info about database name and libdbi version + * libmsc/gsm_04_11.c: clarify implicit CP-ACK handling + * libmsc/ran_peer.c: fix msgb memleak in ran_peer_rx_reset() + * libmsc/gsm_04_11.c: properly handle TP-User-Data-Length + * libmsc/gsm_04_11.c: fix double init of both SMR and SMC FSMs + * libmsc/gsm_04_11.c: cosmetic: restructure gsm411_mm_send() + * libmsc/gsm_04_08.c: fix: print proper length value + * libmsc/gsm_04_08.c: refactor CM Service Request parsing + * libmsc/gsm_04_08.c: clarify IMEI rejection in gsm48_rx_mm_serv_req() + * libmsc/gsm_04_11_gsup.c: cosmetic: drop useless variable + * tests/.../Makefile.am avoid redundant linkage with librt + * libmsc/sgs_server.c: do not override rc in case of SCTP_SHUTDOWN_EVENT + * libmsc/msc_ho.c: fix unreacheable check of MSC-T role allocation + * libmsc/msc_a.c: fix possible NULL-pointer dereferences + * sms_queue_test: assert return value of osmo_use_count_get_put() + * libmsc/gsm_04_11.c: fix NULL-pointer dereference in gsm340_rx_tpdu() + * libmsc/ran_msg_a.c: avoid ternary operator in struct initialization + * libmsc/ran_msg_a.c: refactor ran_a_decode_lcls_notification() + * libmsc/ran_msg_a.c: prevent chosen_encryption->key buffer overrun + * libmsc/mncc_call.c: fix uninitialized access of stack memory + * libmsc/ran_peer.c: fix msgb memleaks in ran_peer_down_paging() + * libmsc/ran_peer.c: avoid unreasonable use of goto in ran_peer_down_paging() + * libmsc/msc_vty.c: fix: use msub_for_vsub() in subscr_dump_full_vty() + * libmsc/msc_vty.c: fix documentation of 'show subscriber id' + * libmsc/msc_vty.c: use llist_count() in subscr_dump_full_vty() + * libmsc/rtp_stream.c: prevent NULL-pointer dereference + * libmsc/gsm_04_11.c: properly handle MMTS indication + * transaction: accept trans_type enum in trans_log_subsys() + * Use GSM23003_MSISDN_MAX_DIGITS from libosmogsm + * libmsc/msc_vty.c: refactor 'show subscr / conn / trans' commands + * libmsc/msc_vty.c: do not abuse strlen() to check char buffers + * tests: share stubs.h from msc_vlr_test as stubs.c + * Introduce initial unit test for db_sms_* API + * libmsc/db.c: fix storing SMS with empty TP-User-Data + * debian/control: add missing libdbd-sqlite3 to Build-Depends + * libmsc/db.c: fix potential integer overflow + * libmsc/db.c: introduce and use parse_sm_ud_from_result() + * libmsc/db.c: warn user about SMS text truncation + * libmsc/db.c: get rid of hard-coded SMS expiry threshold + * libmsc/mncc_builtin.c: drop dummy switch in int_mncc_recv() + * libmsc/gsm_0(4|9)_11_gsup.c: print error message if subscr is not known + * gsup_client_mux_tx_error_reply(): fix: do not override IMSI + * gsup_client_mux_tx_error_reply(): fix: do not omit session IEs + * gsup_client_mux_tx_error_reply(): fix: do not omit message class IE + * gsup_client_mux_tx_error_reply(): fix: do not omit SM-RP-MR IE + * libmsc/gsm_09_11.c: fix: return trans from establish_nc_ss_trans() + * libmsc/gsm_09_11.c: send GSUP PROS_SS ERROR message when needed + * libmsc/gsm_04_08.c: clean up unused leftover includes + * libmsc/msc_a.c: fix: remove dummy allstate_action of msc_a_fsm + * libmsc/paging.c: avoid double zero-initialization + * libmsc/paging.c: cosmetic: actually use default branch of switch + * libmsc/paging.c: cosmetic: remove leading space in log line + * libmsc/gsm_09_11.c: do not abuse LOG_TRANS() and early trans allocation + * libmsc/gsm_09_11.c: log network-originated session establishment error + * libmsc/gsm_09_11.c: drop rudimentary vsub->cgi.lai.lac check + * libmsc/gsm_09_11.c: drop meaningless check for concurrent paging + * libmsc/msc_net_init.c: pass pointer to gsm_network directly + * libmsc/gsm_09_11.c: inform HLR/EUSE if Paging has failed + * libmsc/gsm_09_11.c: properly handle OSMO_GSUP_MSGT_PROC_SS_ERROR + * libmsc/gsm_09_11.c: avoid double zero-initialization of gsup_msg + * libmsc/gsm_09_11.c: fix broken reference counting for vsub + * libmsc/gsm_09_11.c: do not abuse LOG_TRANS() in gsm0911_rcv_nc_ss() + * libmsc/gsm_09_11.c: do not suppress rc of gsup_client_mux_tx() + * tests/msc_vlr: fix: do not pass RAT type to expect_bssap_clear() + * libvlr/vlr.c: do not expire subscribers if periodic LU is disabled + * gsm_04_11_gsup.c: fix broken reference counting for vsub + * libmsc/gsm_04_11.c: do not abuse LOG_TRANS() in gsm411_alloc_mt_trans() + * libmsc/ran_msg_iu.c: fix: properly handle SAPI IE of RANAP_DirectTransfer + * Fix: add missing semicolons to OSMO_ASSERT statements + * libmsc/msc_vty.c: print subscriber expiration time + + [ Harald Welte ] + * Add SGs Interface + * debian: depend on libsctp-dev + * configure.ac: Check for libsctp + * a_iface: Centralize/wrap BSSAP / N-DATA transmission + * a_iface: use 'const' qualifier for ran_conn whenever possible + * a_iface: Fix hexdumping of N-DATA.req + * a_iface: OSMO_ASSERT() if we ever want to send BSSAP with invalid length + * smpp_smsc: Call destroy_tlv() when using build_tlv() + * smpp: Make libsmpp34 use talloc for its allocations + * msub_check_for_release(): Initialize msc_role_a_c + * SMPP: Don't accept password or system-id exceeding spec length + * Iu: Send SMS over SAPI-3 + + [ Philipp Maier ] + * a_iface: Include CSFB Indication into BSSMAP CLEAR COMMAND + * silent_call: use osmo_strlcpy() instead of strncpy() + * msc_vty: add missing header file + * vlr_sgs: fix SGs IMSI detech from non EPS services + * vlr_sgs: start lu expiration timer on sgs eps detach + * sgs_iface: fix nullpointer dereference + * vlr_sgs_fsm: make sure vsub is marked used when LA is present + * sgs_iface: detect and react to VLR/HLR failure + + [ Oliver Smith ] + * debian: depend on libdbd-sqlite3 + * vlr_lu_fsm.c: assert for invalid events + * vty: make retrieve-imeisv-early configurable + * vlr: fix IMEI length + * vlr: when setting IMEISV, also set IMEI + * vlr: optionally send IMEI early to HLR + * debian: create -doc subpackage with pdf manuals + * contrib/jenkins.sh: run "make maintainer-clean" + * vlr_lu_fsm.c: don't send LU reject twice + + [ Keith ] + * Don't deliver alert notifications to ESME not yet bound. + * Write configuration correctly from vty (alert notifications) + + [ Neels Hofmeyr ] + * use only accepted ran_conns for new transactions + * gsm_04_11_gsup.c: drop unused conn lookup + * SMS queue: properly log failed attempts number + * vty: add cmd subscriber ID sms delete-all + * vlr_subscr_name(): use OSMO_STRBUF + * enable osmo_fsm_term_safely(), apply logging changes + * sms queue: avoid repeated Paging for a failed SMS + * vlr_subscr: use osmo_use_count + * add LOG_TRANS, proper context for all transactions + * gsm_04_08_cc: improve logging for CC trans + * smpp: fix vlr_subscr use count bugs + * vlr subscr get/put: also check against NULL + * fix various missing line endings in logging + * gsm_04_11: use gsm48_decode_bcd_number2(), evaluate rc + * large refactoring: support inter-BSC and inter-MSC Handover + * GSUP: include terminating nul in inter-MSC source/destination name + * rename bscconfig.h to config.h, cleanup + * fix regression: fix internal MNCC operation + * vty/cfg: add missing write-back of inter-BSC and inter-MSC HO config + * comment: apply function renames to message cycle explanation + * ran_a_make_handover_request(): allow no encryption + * make msc_a_vsub() and others NULL-safe + * no HO call forwarding if no RTP stream + * LOG_TRANS: store subsys in trans, unify USSD logging back to DMM + * call_leg: remove unused event MSC_EV_CALL_LEG_RTP_RELEASED + * call_leg: document the parent_event_* items + * add DSS logging category + * silence error messages about HANDOVER_END not permitted + * build osmo-msc: add "missing" LIBASN1C_LIBS + * minor comments in msc_vty.c + * manual: adjust and fix auth and ciph docs + * do not force encryption on UTRAN + * add msc_vlr tests for UMTS without ciphering + * doc/sequence_charts/mncc_fsm.msc: add SIP messages, tweak + * doc/sequence_charts: fix naming of mncc_fsm to mncc_call + * vlr_lu_fsm: fix missing event for IMEISV + + [ Sylvain Munaut ] + * libmsc: Allow different channel types to be requested as silent calls + * libvlr: Allow 2G auth tuples to be re-used without going through AUTH + * make LOG_TRANS() NULL-safe again + + [ Pau Espin Pedrol ] + * debian/control: Fix typo + * sms_queue: Print dest msisdn instead of unknown subscriber + * ran_peer: Move rx_reset_ack logic into its own func + * vty: Add option to enable osmux towards BSCs + * bssap: Detect BSC Osmux support on RESET (ACK) recv + * a_iface: Announce Osmux support on RESET (ACK) send + * Request Osmux CID and forward it in Assign Req and Assign Compl + * db: Fix call to mempcy with NULL src ptr + * db_sms_test: Do not print exact memcmp result + * db_sms_test: Remove libdbi expected driver load errors + * sms_queue.c: Improve misleading log line + * doc: Add Osmux documentation to User Manual + * Remove undefined param passed to logging_vty_add_cmds + * Fix dependency version requirements + + [ Omar Ramadan ] + * Allow MME name preformatted as FQDN in SGsAP + + [ Alexander Couzens ] + * remove msc specific db counters + * replace osmo_counter with stat_items + + [ Eric Wild ] + * libvlr: fix sgsn tmsi creation, replace constant with define + * turn -Werror=null-dereference into a warning + + [ Daniel Willmann ] + * manuals: Add script to update vty/counter documentation from docker + * manuals: Update counter/vty documentation + * manuals: Include overview chapter about counters + + [ Thorsten Alteholz ] + * fix spelling detected by lintian + + [ Keith Whyte ] + * Set coding in mncc_set_cause() + + -- Pau Espin Pedrol <pespin@sysmocom.de> Thu, 08 Aug 2019 16:01:38 +0200 + osmo-msc (1.3.1) unstable; urgency=medium [ Neels Hofmeyr ] diff --git a/debian/compat b/debian/compat index ec635144f..f599e28b8 100644 --- a/debian/compat +++ b/debian/compat @@ -1 +1 @@ -9 +10 diff --git a/debian/control b/debian/control index 54a35469c..64bb73c90 100644 --- a/debian/control +++ b/debian/control @@ -1,36 +1,38 @@ Source: osmo-msc Section: net Priority: extra -Maintainer: Alexander Couzens <lynxis@fe80.eu> -Build-Depends: debhelper (>=9), +Maintainer: Osmocom team <openbsc@lists.osmocom.org> +Build-Depends: debhelper (>= 10), dh-autoreconf, autotools-dev, autoconf, automake, libtool, pkg-config, - libdbi-dev, + libsqlite3-dev, libsctp-dev, libtalloc-dev, - libsmpp34-dev (>= 1.12), - libasn1c-dev (>= 0.9.28), - libosmocore-dev (>= 0.10.0), - libosmo-sccp-dev, - libosmo-sigtran-dev (>= 0.8.0), - libosmo-abis-dev, - libosmo-mgcp-client-dev (>= 1.1.0), - libosmo-gsup-client-dev (>= 0.2.1), - libosmo-netif-dev (>= 0.1.0), - libosmo-ranap-dev (>= 0.2.0) + libsmpp34-dev (>= 1.14.0), + libasn1c-dev (>= 0.9.30), + libosmocore-dev (>= 1.9.0), + libosmo-sccp-dev (>= 1.8.0), + libosmo-sigtran-dev (>= 1.8.0), + libosmo-abis-dev (>= 1.5.0), + libosmo-mgcp-client-dev (>= 1.12.0), + libosmo-gsup-client-dev (>= 1.7.0), + libosmo-netif-dev (>= 1.4.0), + libosmo-ranap-dev (>= 1.5.0), + osmo-gsm-manuals-dev (>= 1.5.0) Standards-Version: 3.9.8 -Vcs-Git: git://git.osmocom.org/osmo-msc.git -Vcs-Browser: https://git.osmocom.org/osmo-msc/ +Vcs-Git: https://gitea.osmocom.org/cellular-infrastructure/osmo-msc +Vcs-Browser: https://gitea.osmocom.org/cellular-infrastructure/osmo-msc Homepage: https://osmocom.org/projects/osmomsc Package: osmo-msc Architecture: any Multi-Arch: foreign -Depends: ${misc:Depends}, ${shlibs:Depends}, libdbd-sqlite3 +Depends: ${misc:Depends}, ${shlibs:Depends} +Recommends: osmo-mgw Description: OsmoMSC: Osmocom's Mobile Switching Center for 2G and 3G circuit-switched mobile networks The Mobile Switching Center (MSC) is the heart of 2G/3G circuit-switched services. It terminates the A-interface links from the @@ -62,3 +64,12 @@ Description: OsmoMSC: Osmocom's Mobile Switching Center for 2G and 3G circuit-sw . This package contains the debug symbols for osmo-msc in order to generate meaningful backtraces in bug-reports. + +Package: osmo-msc-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 e3cd9b3cb..ac8ed52d2 100644 --- a/debian/copyright +++ b/debian/copyright @@ -1,6 +1,6 @@ Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Upstream-Name: osmo-msc -Source: git://git.osmocom.org/osmo-msc +Source: https://gitea.osmocom.org/cellular-infrastructure/osmo-msc Files: * Copyright: 2008 Daniel Willmann <daniel@totalueberwachung.de> diff --git a/debian/osmo-msc-doc.install b/debian/osmo-msc-doc.install new file mode 100644 index 000000000..ee15cf912 --- /dev/null +++ b/debian/osmo-msc-doc.install @@ -0,0 +1 @@ +usr/share/doc/osmo-msc-doc/*.pdf diff --git a/debian/rules b/debian/rules index 1cf3a355e..5925ca976 100755 --- a/debian/rules +++ b/debian/rules @@ -46,7 +46,7 @@ # debmake generated override targets # Set options for ./configure -CONFIGURE_FLAGS += --enable-iu --enable-smpp --with-systemdsystemunitdir=/lib/systemd/system +CONFIGURE_FLAGS += --enable-iu --enable-smpp --with-systemdsystemunitdir=/lib/systemd/system --enable-manuals override_dh_auto_configure: dh_auto_configure -- $(CONFIGURE_FLAGS) # @@ -61,3 +61,7 @@ override_dh_strip: # 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/examples/osmo-msc/osmo-msc.cfg b/doc/examples/osmo-msc/osmo-msc.cfg index f80143d21..7c5fe2d55 100644 --- a/doc/examples/osmo-msc/osmo-msc.cfg +++ b/doc/examples/osmo-msc/osmo-msc.cfg @@ -1,21 +1,30 @@ ! ! OsmoMSC configuration saved from vty ! +log stderr + logging color 1 + logging print category-hex 0 + logging print category 1 + logging timestamp 0 + logging print file basename last + logging print level 1 + line vty no login ! network - network country code 1 - mobile network code 1 + network country code 001 + mobile network code 01 short name OsmoMSC long name OsmoMSC encryption a5 0 rrlp mode none mm info 1 + mgw 0 + remote-ip 127.0.0.1 + remote-port 2427 + local-port 2728 msc - mgw remote-ip 10.23.24.1 - mgw remote-port 2427 - mgw local-port 2728 assign-tmsi auth-tuple-max-reuse-count 3 auth-tuple-reuse-on-error 1 diff --git a/doc/examples/osmo-msc/osmo-msc_custom-sccp.cfg b/doc/examples/osmo-msc/osmo-msc_custom-sccp.cfg index 39ca9d496..503359899 100644 --- a/doc/examples/osmo-msc/osmo-msc_custom-sccp.cfg +++ b/doc/examples/osmo-msc/osmo-msc_custom-sccp.cfg @@ -1,6 +1,14 @@ ! ! OsmoMSC configuration saved from vty ! +log stderr + logging color 1 + logging print category-hex 0 + logging print category 1 + logging timestamp 0 + logging print file basename last + logging print level 1 + line vty no login ! @@ -12,16 +20,19 @@ network encryption a5 0 rrlp mode none mm info 1 + mgw 0 + remote-ip 127.0.0.1 + remote-port 2427 + local-port 2728 cs7 instance 0 point-code 0.23.1 asp asp-clnt-OsmoMSC-A-Iu 2905 0 m3ua ! where to reach the STP: remote-ip 127.0.0.5 -! local-ip 10.23.24.1 + !local-ip 10.23.24.1 + role asp + sctp-role client msc cs7-instance-a 0 cs7-instance-iu 0 - mgw remote-ip 10.23.24.1 - mgw remote-port 2427 - mgw local-port 2728 assign-tmsi diff --git a/doc/examples/osmo-msc/osmo-msc_multi-cs7.cfg b/doc/examples/osmo-msc/osmo-msc_multi-cs7.cfg index 2af17261d..22f8734de 100644 --- a/doc/examples/osmo-msc/osmo-msc_multi-cs7.cfg +++ b/doc/examples/osmo-msc/osmo-msc_multi-cs7.cfg @@ -1,6 +1,14 @@ ! ! OsmoMSC configuration saved from vty ! +log stderr + logging color 1 + logging print category-hex 0 + logging print category 1 + logging timestamp 0 + logging print file basename last + logging print level 1 + line vty no login ! @@ -12,18 +20,23 @@ network encryption a5 0 rrlp mode none mm info 1 + mgw 0 + remote-ip 127.0.0.1 + remote-port 2427 + local-port 2728 cs7 instance 0 point-code 0.23.1 asp asp-clnt-OsmoMSC-A 2905 0 m3ua remote-ip 127.0.0.5 + role asp + sctp-role client cs7 instance 1 point-code 0.23.2 asp asp-clnt-OsmoMSC-Iu 2905 0 m3ua remote-ip 127.0.0.6 + role asp + sctp-role client msc cs7-instance-a 0 cs7-instance-iu 1 - mgw remote-ip 10.23.24.1 - mgw remote-port 2427 - mgw local-port 2728 assign-tmsi diff --git a/doc/manuals/Makefile.am b/doc/manuals/Makefile.am index 42e353d03..14d142da3 100644 --- a/doc/manuals/Makefile.am +++ b/doc/manuals/Makefile.am @@ -1,6 +1,7 @@ EXTRA_DIST = osmomsc-usermanual.adoc \ osmomsc-usermanual-docinfo.xml \ osmomsc-vty-reference.xml \ + regen_doc.sh \ chapters \ images \ vty @@ -13,5 +14,11 @@ if BUILD_MANUALS VTY_REFERENCE = osmomsc-vty-reference.xml include $(OSMO_GSM_MANUALS_DIR)/build/Makefile.vty-reference.inc + BUILT_REFERENCE_XML = $(builddir)/vty/msc_vty_reference.xml + $(builddir)/vty/msc_vty_reference.xml: $(top_builddir)/src/osmo-msc/osmo-msc + mkdir -p $(builddir)/vty + $(top_builddir)/src/osmo-msc/osmo-msc --vty-ref-xml > $@ + + OSMO_REPOSITORY = osmo-msc include $(OSMO_GSM_MANUALS_DIR)/build/Makefile.common.inc endif diff --git a/doc/manuals/chapters/counters_generated.adoc b/doc/manuals/chapters/counters_generated.adoc index afeb8ffe5..f55be27ac 100644 --- a/doc/manuals/chapters/counters_generated.adoc +++ b/doc/manuals/chapters/counters_generated.adoc @@ -1,5 +1,8 @@ + // autogenerated by show asciidoc counters -These counters and their description based on OsmoMSC UNKNOWN (OsmoMSC). +These counters and their description based on OsmoMSC 1.4.0 (OsmoMSC). + +=== Rate Counters // generating tables for rate_ctr_group // rate_ctr_group table mobile switching center @@ -7,27 +10,41 @@ These counters and their description based on OsmoMSC UNKNOWN (OsmoMSC). [options="header"] |=== | Name | Reference | Description -| loc_update_type:attach | <<msc_loc_update_type:attach>> | Received location update imsi attach requests. -| loc_update_type:normal | <<msc_loc_update_type:normal>> | Received location update normal requests. -| loc_update_type:periodic | <<msc_loc_update_type:periodic>> | Received location update periodic requests. -| loc_update_type:detach | <<msc_loc_update_type:detach>> | Received location update detach indication. -| loc_update_resp:failed | <<msc_loc_update_resp:failed>> | Rejected location updates. -| loc_update_resp:completed | <<msc_loc_update_resp:completed>> | Successful location updates. -| sms:submitted | <<msc_sms:submitted>> | Received a RPDU from a MS (MO). -| sms:no_receiver | <<msc_sms:no_receiver>> | Counts SMS which couldn't routed because no receiver found. -| sms:delivered | <<msc_sms:delivered>> | Global SMS Deliver attempts. -| sms:rp_err_mem | <<msc_sms:rp_err_mem>> | CAUSE_MT_MEM_EXCEEDED errors of MS responses on a sms deliver attempt. -| sms:rp_err_other | <<msc_sms:rp_err_other>> | Other error of MS responses on a sms delive attempt. -| sms:deliver_unknown_error | <<msc_sms:deliver_unknown_error>> | Unknown error occured during sms delivery. -| call:mo_setup | <<msc_call:mo_setup>> | Received setup requests from a MS to init a MO call. -| call:mo_connect_ack | <<msc_call:mo_connect_ack>> | Received a connect ack from MS of a MO call. Call is now succesful connected up. -| call:mt_setup | <<msc_call:mt_setup>> | Sent setup requests to the MS (MT). -| call:mt_connect | <<msc_call:mt_connect>> | Sent a connect to the MS (MT). -| call:active | <<msc_call:active>> | Count total amount of calls that ever reached active state. -| call:complete | <<msc_call:complete>> | Count total amount of calls which got terminated by disconnect req or ind after reaching active state. -| call:incomplete | <<msc_call:incomplete>> | Count total amount of call which got terminated by any other reason after reaching active state. +| loc_update_type:attach | <<msc_loc_update_type:attach>> | Received Location Update (IMSI Attach) requests. +| loc_update_type:normal | <<msc_loc_update_type:normal>> | Received Location Update (LAC change) requests. +| loc_update_type:periodic | <<msc_loc_update_type:periodic>> | Received (periodic) Location Update requests. +| loc_update_type:detach | <<msc_loc_update_type:detach>> | Received IMSI Detach indications. +| loc_update_resp:failed | <<msc_loc_update_resp:failed>> | Rejected Location Updates requests. +| loc_update_resp:completed | <<msc_loc_update_resp:completed>> | Successful Location Update procedures. +| cm_service_request:rejected | <<msc_cm_service_request:rejected>> | Rejected CM Service Requests. +| cm_service_request:accepted | <<msc_cm_service_request:accepted>> | Accepted CM Service Requests. +| paging_resp:rejected | <<msc_paging_resp:rejected>> | Rejected Paging Responses. +| paging_resp:accepted | <<msc_paging_resp:accepted>> | Accepted Paging Responses. +| sms:submitted | <<msc_sms:submitted>> | Total MO SMS received from the MS. +| sms:no_receiver | <<msc_sms:no_receiver>> | Failed MO SMS delivery attempts (no receiver found). +| sms:deliver_unknown_error | <<msc_sms:deliver_unknown_error>> | Failed MO SMS delivery attempts (other reason). +| sms:delivered | <<msc_sms:delivered>> | Total MT SMS delivery attempts. +| sms:rp_err_mem | <<msc_sms:rp_err_mem>> | Failed MT SMS delivery attempts (no memory). +| sms:rp_err_other | <<msc_sms:rp_err_other>> | Failed MT SMS delivery attempts (other reason). +| call:mo_setup | <<msc_call:mo_setup>> | Received MO SETUP messages (MO call establishment). +| call:mo_connect_ack | <<msc_call:mo_connect_ack>> | Received MO CONNECT messages (MO call establishment). +| call:mt_setup | <<msc_call:mt_setup>> | Sent MT SETUP messages (MT call establishment). +| call:mt_connect | <<msc_call:mt_connect>> | Sent MT CONNECT messages (MT call establishment). +| call:active | <<msc_call:active>> | Calls that ever reached the active state. +| call:complete | <<msc_call:complete>> | Calls terminated by DISCONNECT message after reaching the active state. +| call:incomplete | <<msc_call:incomplete>> | Calls terminated by any other reason after reaching the active state. +| nc_ss:mo_requests | <<msc_nc_ss:mo_requests>> | Received MS-initiated call independent SS/USSD requests. +| nc_ss:mo_established | <<msc_nc_ss:mo_established>> | Established MS-initiated call independent SS/USSD sessions. +| nc_ss:mt_requests | <<msc_nc_ss:mt_requests>> | Received network-initiated call independent SS/USSD requests. +| nc_ss:mt_established | <<msc_nc_ss:mt_established>> | Established network-initiated call independent SS/USSD sessions. +| bssmap:cipher_mode_reject | <<msc_bssmap:cipher_mode_reject>> | Number of CIPHER MODE REJECT messages processed by BSSMAP layer +| bssmap:cipher_mode_complete | <<msc_bssmap:cipher_mode_complete>> | Number of CIPHER MODE COMPLETE messages processed by BSSMAP layer |=== +== Osmo Stat Items + // generating tables for osmo_stat_items +== Osmo Counters + // generating tables for osmo_counters // ungrouped osmo_counters .ungrouped osmo counters @@ -35,6 +52,5 @@ These counters and their description based on OsmoMSC UNKNOWN (OsmoMSC). |=== | Name | Reference | Description | msc.active_calls | <<ungroup_counter_msc.active_calls>> | +| msc.active_nc_ss | <<ungroup_counter_msc.active_nc_ss>> | |=== - - diff --git a/doc/manuals/chapters/net.adoc b/doc/manuals/chapters/net.adoc index 06be4bad2..6edb9ee3a 100644 --- a/doc/manuals/chapters/net.adoc +++ b/doc/manuals/chapters/net.adoc @@ -101,32 +101,56 @@ operating system on which OsmoMSC is running. === Authentication -Authorized subscribers must be entered in the HLR database, see the _OsmoHLR -reference manual_ <<userman-osmohlr>>. If authentication tokens (such as KI for -2G, or K and OP/OPC for UMTS) are present in the HLR, OsmoMSC will only attach -a subscriber after successful authentication. +A subscriber's IMSI must be entered in the HLR database to be able to attach. A +subscriber-create-on-demand feature is also available, see the _OsmoHLR +reference manual_ <<userman-osmohlr>>. -If no authentication keys are present in the HLR for a given subscriber, -OsmoMSC will attach the subscriber _without_ authentication. You can reject -subscribers that lack authentication info in the HLR with this setting: +A known IMSI in the HLR may or may not have authentication keys associated, +which profoundly affects the ability to attach and the algorithms used to +negotiate authentication, as the following sections explain for 2G and 3G. + +==== Authentication on 2G + +If authentication tokens (such as KI for 2G, or K and OP/OPC for UMTS) are +present in the HLR, OsmoMSC will only attach a subscriber after successful +authentication. Note that the 3G authentication keys are also used on 2G when +the MS indicates UMTS AKA capability, in which case the full UMTS style mutual +authentication may indeed take place on 2G (GERAN). + +On 2G, if no authentication keys are present in the HLR for a given subscriber, +OsmoMSC will attach the subscriber _without_ authentication. Subscribers that +lack authentication keys can always be rejected with this setting: ---- network authentication required ---- +==== Authentication on 3G + +3G (UTRAN) always requires authentication (a.k.a. Integrity Protection) by +specification, and hence authentication keys must be present in the HLR for a +subscriber to be able to attach on 3G. + +OsmoMSC always indicates UIA1 and UIA2 as permitted Integrity Protection +algorithms on 3G. + === Ciphering To enable ciphering on the radio link, authentication must take place first: -the Kc resulting from authentication is the key used for ciphering. Hence, all -subscribers must have authentication tokens available in the HLR for ciphering. +the Kc resulting from authentication is the key used for ciphering. Hence, to +be able to use ciphering, a subscriber must have authentication tokens +available in the HLR. + +==== Ciphering on 2G The MS, BTS and MSC must agree on a ciphering algorithm to use. - The MS sends its supported ciphering algorithms via Classmark IEs during Location Updating. - Typically the BSC needs to know which A5 ciphers are supported by connected - BTSes. + BTSes, see the `network / encryption a5` configuration item for OsmoBSC + <<vty-ref-osmobsc>>. - Finally, OsmoMSC may impose that specific A5 ciphers shall not be considered. It is the responsibility of the BSC to then pick an A5 cipher that satisfies @@ -143,12 +167,43 @@ network + ---- network - encryption a5 3 + encryption a5 1 3 ---- - Never use A5/2: it is an "export grade cipher" and has been deprecated for its low ciphering strength. -NOTE: At the time of writing, OsmoMSC supports setting only a single A5 cipher, -while it should be able to allow a set of ciphers. This is subject to ongoing -development. +- To allow either no encryption or any of A5/1 or A5/3 based on the presence of + authentication keys and abilities of the MS, SIM and BSC configuration, it is + recommended to enable all ciphers in OsmoMSC. The highest available A5 cipher + will be used; the order in which the A5 options are configured does not + affect the choice. ++ +---- +network + encryption a5 0 1 3 +---- + +==== Ciphering on 3G + +While authentication is always required on 3G, ciphering is optional. + +So far OsmoMSC allows switching ciphering on 3G either on or off -- the default +behavior is to enable ciphering. (Individual choice of algorithms may be added +in the future.) + +Disable 3G ciphering: + +---- +network + encryption uea 0 +---- + +Enable 3G ciphering (default): + +---- +network + encryption uea 1 2 +---- + +OsmoMSC indicates UEA1 and UEA2 as permitted encryption algorithms on 3G. diff --git a/doc/manuals/chapters/osmux_msc.adoc b/doc/manuals/chapters/osmux_msc.adoc new file mode 100644 index 000000000..ed722f2a0 --- /dev/null +++ b/doc/manuals/chapters/osmux_msc.adoc @@ -0,0 +1,65 @@ +include::{commondir}/chapters/osmux/osmux.adoc[] + +=== Osmux Support in {program-name} + +==== {program-name} in a A/IP with IPA/SCCPlite network setup + +In this kind of setup, the CN side of BSC co-located MGW is managed by the MSC, +meaning the use of Osmux is transparent to BSC since MSC takes care of both peer +MGW connections. Moreover, in this case the MSC has no dynamic information on +Osmux support in the BSC co-located MGW until `CRCX` time, which means +configuration on both nodes need to be carefully set up so they can work +together. + +Osmux usage in {program-name} in managed through the VTY command `osmux +(on|off|only)`. Since there's no dynamic information on Osmux support, it may be +required in the future to have an extra VTY command which can be set per BSC to +fine-tune which ones should use Osmux and which shouldn't. + +{program-name} will behave differently during call set up based on the VTY +command presented above: + +* `off`: {program-name} won't include an `X-Osmux` extension to `CRCX` sent to + the BSC co-located MGW when configuring the CN side of the MGW endpoint. If + the MGW answers with a `CRCX ACK` containing an `X-Osmux`, {program-name} will + cancel the call establishment. +* `on`: {program-name} will initially configure its co-located MGW to use Osmux, then + similarly send a `CRCX` with an `X-Osmux` extension towards the BSC co-located + MGW. Under this configuration, if the BSC co-located MGW didn't support Osmux, + it could send a `CRCX ACK` without `X-Osmux` extension or fail (depending on + its own configuration), and {program-name} could choose to re-create its local + connection as non-Osmux (RTP) (and possibly try again against BSC co-located + MGW), but this behavior is currently not implemented. As a result, currently + `on` behaves the same as `only`. +* `only`: {program-name} will configure its co-located MGW as well as the BSC + co-located MGW to use Osmux by including the `X-Osmux` MGCP extension. If MGW + rejects to use Osmux, {program-name} will reject the call and the call + establishment will fail. + +==== {program-name} in a 3GPP AoIP network setup + +Osmux usage in {program-name} in managed through the VTY command `osmux +(on|off|only)`. Once enabled (`on` or `only`), {program-name} will start +appending the vendor specific _Osmux Support_ IE in _BSSMAP RESET_ and _BSSMAP +RESET-ACK_ message towards the BSC in order to announce it supports Osmux, and +BSC will do the same. This way, {program-name} can decide whether to use Osmux +or not based on this information when setting up a call (this time using _Osmux +CID_ IE). It should be noted that this option should not be enabled unless BSCs +managed by {program-name} support handling this extension IE (like OsmoBSC), +3rd-party BSCs might otherwise refuse the related _RESET_/_RESET-ACK_ messages. + +{program-name} will behave differently during call set up based on the VTY +command presented above: + +* `off`: {program-name} won't use Osmux. That is, it will send a _BSSMAP Assign + Request_ without the _Osmux CID_ IE, and will send a `CRCX` without `X-Osmux` + extension towards its co-located MGW. +* `on`: If BSC announced Osmux support to {program-name} during _BSSMAP RESET_ + time, then {program-name} will set up the call to use Osmux (by adding + `X-Osmux` to MGCP `CRCX` and _Osmux CID_ IE to _BSSMAP Assign Request_). If + the BSC didn't announce Osmux support to {program-name}, then {program-name} + will use RTP to set up the call (by avoiding addition of previously described + bits). +* `only`: Same as per `on`, except that {program-name} will allow to set up only + Osmux calls on the CN-side, this is, it will reject to set up voice calls for + BSC which didn't announce Osmux support. diff --git a/doc/manuals/chapters/running.adoc b/doc/manuals/chapters/running.adoc index 9d56f1fcd..3041145dc 100644 --- a/doc/manuals/chapters/running.adoc +++ b/doc/manuals/chapters/running.adoc @@ -5,14 +5,14 @@ arguments: === SYNOPSIS -*osmo-msc* [-h|-V] [-d 'DBGMASK'] [-D] [-c 'CONFIGFILE'] [-s] [-T] [-e 'LOGLEVEL'] [-l 'DATABASE'] [-M 'SOCKETPATH'] [-C] +*osmo-msc* [-h|-V] [-d 'DBGMASK'] [-D] [-c 'CONFIGFILE'] [-s] [-T] [-e 'LOGLEVEL'] === OPTIONS *-h, --help*:: Print a short help message about the supported options *-V, --version*:: - Print the compile-time version number of the OsmoBTS program + 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, @@ -35,16 +35,6 @@ arguments: Set the global log level for logging to stderr. This has mostly been deprecated by VTY based logging configuration, see <<logging>> for more information. -*-l, --database 'DATABASE'*:: - Specify the file name of the SQLite3 database to use as SMS storage -*-M, --mncc-sock-path*:: - Enable the MNCC socket for an external MNCC handler. See - <<mncc>> for further information. -*-m, --mncc-sock*:: - Same as option -M (deprecated). -*-C, --no-dbcounter*:: - Deprecated. DB statistics and counter has been removed. - This option is only valid for compatiblity and does nothing. === Multiple instances @@ -74,9 +64,18 @@ smpp More on SMPP configuration in <<smpp-config-global>>. -The external MNCC handler is configured by the `--mncc-sock` commandline -argument. Choose a different such socket path for each OsmoMSC instance running -on the same file system. See more in <<mncc-external>>. +The external MNCC handler is a UNIX domain socket that is created when external MNCC handling is configured. A separate +path must be used per osmo-msc instance: + +---- +msc + mncc external /tmp/mncc_socket +---- + +More on MNCC in <<mncc-external>>. + +The SGs interface by default listens on 0.0.0.0:29118 (SCTP). Each instance of OsmoMSC must use a different IP address +and/or port. For details about the configuration of the SGs interface, see section <<sgs>>. For the following links, OsmoMSC acts as a client and does not listen/bind to a specific interface, and will hence not encounter conflicts for multiple instances @@ -84,55 +83,47 @@ running on the same interface: - The SCCP/M3UA links are established by OsmoMSC contacting an STP. - The GSUP link is established by OsmoMSC contacting an HLR. +- The MGCP link is established by OsmoMSC contacting an MGW. === Configure primary links ==== Configure SCCP/M3UA to accept _A_ and _IuCS_ links -OsmoMSC will contact an STP instance to establish an SCCP/M3UA link. BSC and -HNBGW will then reach the MSC via this link. By default, an STP instance is -assumed to listen on the default M3UA port (2905) on the local host. +OsmoMSC acts as client to contact an STP instance and establish an SCCP/M3UA +link. -Establishing an SCCP/M3UA link towards an STP instance not on the local host -can be configured as follows: +An example configuration of OsmoMSC's SCCP link: ---- cs7 instance 0 - asp my-OsmoMSC 2905 0 m3ua - ! IP address of the remote STP: - remote-ip 10.23.24.1 + point-code 0.23.1 + asp asp-clnt-OsmoMSC-A-Iu 2905 0 m3ua + remote-ip 127.0.0.1 + role asp + sctp-role client ---- +This configuration is explained in detail in <<cs7_config>>. + Note that _A_ and _IuCS_ may use different SCCP instances, if so desired: ---- cs7 instance 0 asp my-OsmoMSC-A 2905 0 m3ua remote-ip 10.23.42.1 + role asp + sctp-role client cs7 instance 1 asp my-OsmoMSC-Iu 2905 0 m3ua remote-ip 10.23.42.2 + role asp + sctp-role client msc cs7-instance-a 0 cs7-instance-iu 1 ---- -A full configuration needs an `asp` on an `as` -- an Application Server Process -running on an Application Server -- as well as a local point code and routing -configuration. The SCCP VTY automatically creates those parts that are missing, -by assuming sane defaults. A complete configuration would look like this: - ----- -cs7 instance 0 - point-code 0.23.1 - asp my-OsmoMSC-A-Iu 2905 0 m3ua - remote-ip 127.0.0.1 - as my-as-for-OsmoMSC-A-Iu m3ua - asp my-OsmoMSC-A-Iu - routing-key 0 0.23.1 ----- - ==== Configure GSUP to reach the HLR OsmoMSC will assume a GSUP server (OsmoHLR) to run on the local host and the @@ -146,3 +137,36 @@ hlr ! default port is 4222, optionally configurable by: remote-port 1234 ---- + +==== Configure MGCP to connect to an MGW + +OsmoMSC uses a media gateway (typically OsmoMGW) to direct RTP streams. By +default, an MGW is expected to receive MGCP requests on the IANA-registered +default port for MGCP (2427) on local host (127.0.0.1). + +Here is an example configuration for a remote MGW: + +---- +network + mgw 0 + remote-ip 10.9.8.7 + remote-port 2427 + reset-endpoint rtpbridge/* <1> +---- +<1> The 'reset-endpoint' setting instructs the OsmoMGW to send a wildcarded +DLCX to the media gateway. This helps to clear lingering calls from the +media gateway when the OsmoMSC is restarted. + +OsmoMSC is also able to handle a pool of media gateways for load +distribution. See also <<mgw_pooling>>. + +[NOTE] +==== +Previous versions of OsmoMSC (1.9.0 and below) didn't have the 'mgw' VTY node and +hence didn't support the MGW pooling feature. Therefore, historically the MGW +related commands where placed under the `msc` VTY node. The MGW related commands +under the `msc` VTY are still parsed and used but its use is deprecated and +hence discouraged in favour of the new `mgw` node. Writing the config to a file +from within OsmoMSC will automatically convert the config to use the new `mgw` +node. +==== diff --git a/doc/manuals/chapters/sgs.adoc b/doc/manuals/chapters/sgs.adoc new file mode 100644 index 000000000..1f0240bed --- /dev/null +++ b/doc/manuals/chapters/sgs.adoc @@ -0,0 +1,55 @@ +[[sgs]] +== SGs interface + +OsmoMSC offers an SGs interface using the SGsAP protocol. The SGs interface is an +optional interface between a 2G (GERAN) / 3G (UTRAN) MSC and an 4G (EUTRAN) MME. +Its purpose is to facilitate both CSFB (Circuit-Switched Fall Back) and SMSoS +(SMS over SGs). It is used for Mobility management (MM) and paging procedures +between the EPS (Evolved Packet Services) and CS (Circuit Switched) domain. + +=== VTY configuration + +The SGs interface implementation in OsmoMSC is automatically active and requires +only minimal configuration. When no specific configuration is provided OsmoMSC +will listen on 0.0.0.0:29118 (SCTP) for incoming connections. + +This is sufficient in the most configurations, but in larger installations, +where services are either tied to specific interfaces and/or more instances of +OsmoMSC run in parallel, a custom configuration is necessary. + +The user has the option to configure the IP address (`local-ip`) and the SCTP +port (`local-port`) and also the `vlr-name` that OsmoMSC uses to identify itself +towards the MME. It should be noted that the `vlr-name` is usually the DNS name +for the IP address of the VLR/MSC, so IP address used and the `vlr-name` should +match the DNS server entry. + +---- +sgs + local-ip 127.0.0.1 + local-port 29118 + vlr-name vlr.example.net +---- + +In order to fine tune the behavior of the SGs interface the user also has +control over the relevant timers (`ts5`, `ts6-2`, `ts7`, `ts11`, `ts14`, `ts15`) +and counters (`ns7`, `ns11`). Each timer and counter has to be configured +separately. In the following example we change the value of ts and ns11. + +---- +sgs + timer ts7 23 + counter ns11 100 +---- + + +[NOTE] +==== +In case multiple instances of OsmoMSC run in parallel, it is advised to use a +different `vlr-name` for each instance. In any case it must be ensured that the +SGs interface of each instance is bound to a different IP address and/or port. +==== + +=== Connection monitoring + +The user can use the VTY command `show sgs-connections` to list the MMEs that +are currently connected to OsmoMSC. diff --git a/doc/manuals/osmomsc-usermanual.adoc b/doc/manuals/osmomsc-usermanual.adoc index 4fd0cc71e..45be140f5 100644 --- a/doc/manuals/osmomsc-usermanual.adoc +++ b/doc/manuals/osmomsc-usermanual.adoc @@ -14,22 +14,38 @@ include::{srcdir}/chapters/running.adoc[] include::{srcdir}/chapters/control.adoc[] +include::./common/chapters/counters-overview.adoc[] + include::{srcdir}/chapters/counters.adoc[] include::./common/chapters/vty.adoc[] include::./common/chapters/logging.adoc[] +include::./common/chapters/sigtran-osmocom.adoc[] + +include::./common/chapters/cs7-config.adoc[] + +include::./common/chapters/cs7-config.adoc[] + include::{srcdir}/chapters/net.adoc[] include::./common/chapters/smpp.adoc[] include::./common/chapters/mncc.adoc[] +include::{srcdir}/chapters/osmux_msc.adoc[] + +include::./common/chapters/mgwpool.adoc[] + +include::{srcdir}/chapters/sgs.adoc[] + include::./common/chapters/control_if.adoc[] include::./common/chapters/gsup.adoc[] +include::./common/chapters/vty_cpu_sched.adoc[] + include::./common/chapters/port_numbers.adoc[] include::./common/chapters/bibliography.adoc[] @@ -37,4 +53,3 @@ include::./common/chapters/bibliography.adoc[] include::./common/chapters/glossary.adoc[] include::./common/chapters/gfdl.adoc[] - diff --git a/doc/manuals/regen_doc.sh b/doc/manuals/regen_doc.sh new file mode 100755 index 000000000..55cda5c4c --- /dev/null +++ b/doc/manuals/regen_doc.sh @@ -0,0 +1,17 @@ +#!/bin/sh -x + +if [ -z "$DOCKER_PLAYGROUND" ]; then + echo "You need to set DOCKER_PLAYGROUND" + exit 1 +fi + +SCRIPT=$(realpath "$0") +MANUAL_DIR=$(dirname "$SCRIPT") + +COMMIT=${COMMIT:-$(git log -1 --format=format:%H)} + +cd "$DOCKER_PLAYGROUND/scripts" || exit 1 + +OSMO_MSC_BRANCH=$COMMIT ./regen_doc.sh osmo-msc 4254 \ + "$MANUAL_DIR/chapters/counters_generated.adoc" \ + "$MANUAL_DIR/vty/msc_vty_reference.xml" diff --git a/doc/manuals/vty/msc_vty_reference.xml b/doc/manuals/vty/msc_vty_reference.xml deleted file mode 100644 index bb7e958b2..000000000 --- a/doc/manuals/vty/msc_vty_reference.xml +++ /dev/null @@ -1,2686 +0,0 @@ -<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 <0-512>'> - <params> - <param name='terminal' doc='Set terminal line parameters' /> - <param name='length' doc='Set number of lines on a screen' /> - <param name='<0-512>' 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='show cs7 instance <0-15> 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='<0-15>' doc='An instance of the SS7 stack' /> - <param name='users' doc='User Table' /> - </params> - </command> - <command id='show cs7 (sua|m3ua|ipa) [<0-65534>]'> - <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='[<0-65534>]' doc='Port Number' /> - </params> - </command> - <command id='show cs7 instance <0-15> 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='<0-15>' doc='An instance of the SS7 stack' /> - <param name='asp' doc='Application Server Process (ASP)' /> - </params> - </command> - <command id='show cs7 instance <0-15> 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='<0-15>' 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 <0-15> 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='<0-15>' 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 <0-15> 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='<0-15>' 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 <0-15> sccp ssn <0-65535>'> - <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='<0-15>' 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='<0-65535>' doc='Subsystem Number (SSN)' /> - </params> - </command> - <command id='show cs7 instance <0-15> 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='<0-15>' 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 <0-15> 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='<0-15>' 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='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'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'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'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'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't prefix each log message' /> - <param name='1' doc='Prefix each log message with category/subsystem nr in hex ('<000b>')' /> - </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'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'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'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. 'abc:mno:xyz'. Available log categories depend on the specific application, refer to the 'logging level' command. Optionally add individual log levels like 'abc,1:mno,3:xyz,5', 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 (rll|cc|mm|rr|mncc|pag|msc|mgcp|ho|db|ref|ctrl|smpp|ranap|vlr|iucs|bssap|lglobal|llapd|linp|lmux|lmi|lmib|lsms|lctrl|lgtp|lstats|lgsup|loap|lss7|lsccp|lsua|lm3ua|lmgcp|ljibuf) (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='rll' doc='A-bis Radio Link Layer (RLL)' /> - <param name='cc' doc='Layer3 Call Control (CC)' /> - <param name='mm' doc='Layer3 Mobility Management (MM)' /> - <param name='rr' doc='Layer3 Radio Resource (RR)' /> - <param name='mncc' doc='MNCC API for Call Control application' /> - <param name='pag' doc='Paging Subsystem' /> - <param name='msc' doc='Mobile Switching Center' /> - <param name='mgcp' doc='Media Gateway Control Protocol' /> - <param name='ho' doc='Hand-Over' /> - <param name='db' doc='Database Layer' /> - <param name='ref' doc='Reference Counting' /> - <param name='ctrl' doc='Control interface' /> - <param name='smpp' doc='SMPP interface for external SMS apps' /> - <param name='ranap' doc='Radio Access Network Application Part Protocol' /> - <param name='vlr' doc='Visitor Location Register' /> - <param name='iucs' doc='Iu-CS Protocol' /> - <param name='bssap' doc='BSSAP Protocol (A Interface)' /> - <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='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 'no logging level force-all' command. Note: any 'logging level <category> <level>' 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 'logging level force-all <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'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'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'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 fsm NAME'> - <params> - <param name='show' doc='Show running system information' /> - <param name='fsm' doc='Show information about finite state machines' /> - <param name='NAME' doc='Display information about a single named finite state machine' /> - </params> - </command> - <command id='show fsm all'> - <params> - <param name='show' doc='Show running system information' /> - <param name='fsm' doc='Show information about finite state machines' /> - <param name='all' doc='Display a list of all registered finite state machines' /> - </params> - </command> - <command id='show fsm-instances NAME'> - <params> - <param name='show' doc='Show running system information' /> - <param name='fsm-instances' doc='Show information about finite state machine instances' /> - <param name='NAME' doc='Display a list of all FSM instances of the named finite state machine' /> - </params> - </command> - <command id='show fsm-instances all'> - <params> - <param name='show' doc='Show running system information' /> - <param name='fsm-instances' doc='Show information about finite state machine instances' /> - <param name='all' doc='Display a list of all FSM instances of all finite state machine' /> - </params> - </command> - <command id='show subscriber (msisdn|extension|imsi|tmsi|id) ID'> - <params> - <param name='show' doc='Show running system information' /> - <param name='subscriber' doc='Operations on a Subscriber' /> - <param name='msisdn' doc='Identify subscriber by MSISDN (phone number)' /> - <param name='extension' doc='Legacy alias for 'msisdn'' /> - <param name='imsi' doc='Identify subscriber by IMSI' /> - <param name='tmsi' doc='Identify subscriber by TMSI' /> - <param name='id' doc='Identify subscriber by database ID' /> - <param name='ID' doc='Identifier for the subscriber' /> - </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 connection'> - <params> - <param name='show' doc='Show running system information' /> - <param name='connection' doc='Subscriber Connections' /> - </params> - </command> - <command id='show transaction'> - <params> - <param name='show' doc='Show running system information' /> - <param name='transaction' doc='Transactions' /> - </params> - </command> - <command id='sms send pending'> - <params> - <param name='sms' doc='SMS related commands' /> - <param name='send' doc='SMS Sending related commands' /> - <param name='pending' doc='Send all pending SMS' /> - </params> - </command> - <command id='sms delete expired'> - <params> - <param name='sms' doc='SMS related commands' /> - <param name='delete' doc='SMS Database related commands' /> - <param name='expired' doc='Delete all expired SMS' /> - </params> - </command> - <command id='subscriber create imsi ID'> - <params> - <param name='subscriber' doc='Operations on a Subscriber' /> - <param name='create' doc='Create new subscriber' /> - <param name='imsi' doc='Identify the subscriber by his IMSI' /> - <param name='ID' doc='Identifier for the subscriber' /> - </params> - </command> - <command id='subscriber (msisdn|extension|imsi|tmsi|id) ID sms sender (msisdn|extension|imsi|tmsi|id) SENDER_ID send .LINE'> - <params> - <param name='subscriber' doc='Operations on a Subscriber' /> - <param name='msisdn' doc='Identify subscriber by MSISDN (phone number)' /> - <param name='extension' doc='Legacy alias for 'msisdn'' /> - <param name='imsi' doc='Identify subscriber by IMSI' /> - <param name='tmsi' doc='Identify subscriber by TMSI' /> - <param name='id' doc='Identify subscriber by database ID' /> - <param name='ID' doc='Identifier for the subscriber' /> - <param name='sms' doc='SMS Operations' /> - <param name='sender' doc='Operations on a Subscriber' /> - <param name='msisdn' doc='Identify subscriber by MSISDN (phone number)' /> - <param name='extension' doc='Legacy alias for 'msisdn'' /> - <param name='imsi' doc='Identify subscriber by IMSI' /> - <param name='tmsi' doc='Identify subscriber by TMSI' /> - <param name='id' doc='Identify subscriber by database ID' /> - <param name='SENDER_ID' doc='Identifier for the subscriber' /> - <param name='send' doc='Send SMS' /> - <param name='.LINE' doc='Actual SMS Text' /> - </params> - </command> - <command id='subscriber (msisdn|extension|imsi|tmsi|id) ID silent-sms sender (msisdn|extension|imsi|tmsi|id) SENDER_ID send .LINE'> - <params> - <param name='subscriber' doc='Operations on a Subscriber' /> - <param name='msisdn' doc='Identify subscriber by MSISDN (phone number)' /> - <param name='extension' doc='Legacy alias for 'msisdn'' /> - <param name='imsi' doc='Identify subscriber by IMSI' /> - <param name='tmsi' doc='Identify subscriber by TMSI' /> - <param name='id' doc='Identify subscriber by database ID' /> - <param name='ID' doc='Identifier for the subscriber' /> - <param name='silent-sms' doc='Silent SMS Operations' /> - <param name='sender' doc='Operations on a Subscriber' /> - <param name='msisdn' doc='Identify subscriber by MSISDN (phone number)' /> - <param name='extension' doc='Legacy alias for 'msisdn'' /> - <param name='imsi' doc='Identify subscriber by IMSI' /> - <param name='tmsi' doc='Identify subscriber by TMSI' /> - <param name='id' doc='Identify subscriber by database ID' /> - <param name='SENDER_ID' doc='Identifier for the subscriber' /> - <param name='send' doc='Send SMS' /> - <param name='.LINE' doc='Actual SMS Text' /> - </params> - </command> - <command id='subscriber (msisdn|extension|imsi|tmsi|id) ID silent-call start (any|tch/f|tch/any|sdcch)'> - <params> - <param name='subscriber' doc='Operations on a Subscriber' /> - <param name='msisdn' doc='Identify subscriber by MSISDN (phone number)' /> - <param name='extension' doc='Legacy alias for 'msisdn'' /> - <param name='imsi' doc='Identify subscriber by IMSI' /> - <param name='tmsi' doc='Identify subscriber by TMSI' /> - <param name='id' doc='Identify subscriber by database ID' /> - <param name='ID' doc='Identifier for the subscriber' /> - <param name='silent-call' doc='Silent call operation' /> - <param name='start' doc='Start silent call' /> - <param name='any' doc='Any channel' /> - <param name='tch/f' doc='TCH/F channel' /> - <param name='tch/any' doc='Any TCH channel' /> - <param name='sdcch' doc='SDCCH channel' /> - </params> - </command> - <command id='subscriber (msisdn|extension|imsi|tmsi|id) ID silent-call stop'> - <params> - <param name='subscriber' doc='Operations on a Subscriber' /> - <param name='msisdn' doc='Identify subscriber by MSISDN (phone number)' /> - <param name='extension' doc='Legacy alias for 'msisdn'' /> - <param name='imsi' doc='Identify subscriber by IMSI' /> - <param name='tmsi' doc='Identify subscriber by TMSI' /> - <param name='id' doc='Identify subscriber by database ID' /> - <param name='ID' doc='Identifier for the subscriber' /> - <param name='silent-call' doc='Silent call operation' /> - <param name='stop' doc='Stop silent call' /> - </params> - </command> - <command id='subscriber (msisdn|extension|imsi|tmsi|id) ID ussd-notify (0|1|2) .TEXT'> - <params> - <param name='subscriber' doc='Operations on a Subscriber' /> - <param name='msisdn' doc='Identify subscriber by MSISDN (phone number)' /> - <param name='extension' doc='Legacy alias for 'msisdn'' /> - <param name='imsi' doc='Identify subscriber by IMSI' /> - <param name='tmsi' doc='Identify subscriber by TMSI' /> - <param name='id' doc='Identify subscriber by database ID' /> - <param name='ID' doc='Identifier for the subscriber' /> - <param name='ussd-notify' doc='Send a USSD notify to the subscriber' /> - <param name='0' doc='Alerting Level 0' /> - <param name='1' doc='Alerting Level 1' /> - <param name='2' doc='Alerting Level 2' /> - <param name='.TEXT' doc='Text of USSD message to send' /> - </params> - </command> - <command id='subscriber (msisdn|extension|imsi|tmsi|id) ID ms-test close-loop (a|b|c|d|e|f|i)'> - <params> - <param name='subscriber' doc='Operations on a Subscriber' /> - <param name='msisdn' doc='Identify subscriber by MSISDN (phone number)' /> - <param name='extension' doc='Legacy alias for 'msisdn'' /> - <param name='imsi' doc='Identify subscriber by IMSI' /> - <param name='tmsi' doc='Identify subscriber by TMSI' /> - <param name='id' doc='Identify subscriber by database ID' /> - <param name='ID' doc='Identifier for the subscriber' /> - <param name='ms-test' doc='Send a TS 04.14 MS Test Command to subscriber' /> - <param name='close-loop' doc='Close a TCH Loop inside the MS' /> - <param name='a' doc='Loop Type A' /> - <param name='b' doc='Loop Type B' /> - <param name='c' doc='Loop Type C' /> - <param name='d' doc='Loop Type D' /> - <param name='e' doc='Loop Type E' /> - <param name='f' doc='Loop Type F' /> - <param name='i' doc='Loop Type I' /> - </params> - </command> - <command id='subscriber (msisdn|extension|imsi|tmsi|id) ID ms-test open-loop'> - <params> - <param name='subscriber' doc='Operations on a Subscriber' /> - <param name='msisdn' doc='Identify subscriber by MSISDN (phone number)' /> - <param name='extension' doc='Legacy alias for 'msisdn'' /> - <param name='imsi' doc='Identify subscriber by IMSI' /> - <param name='tmsi' doc='Identify subscriber by TMSI' /> - <param name='id' doc='Identify subscriber by database ID' /> - <param name='ID' doc='Identifier for the subscriber' /> - <param name='ms-test' doc='Send a TS 04.14 MS Test Command to subscriber' /> - <param name='open-loop' doc='Open a TCH Loop inside the MS' /> - </params> - </command> - <command id='subscriber (msisdn|extension|imsi|tmsi|id) ID paging'> - <params> - <param name='subscriber' doc='Operations on a Subscriber' /> - <param name='msisdn' doc='Identify subscriber by MSISDN (phone number)' /> - <param name='extension' doc='Legacy alias for 'msisdn'' /> - <param name='imsi' doc='Identify subscriber by IMSI' /> - <param name='tmsi' doc='Identify subscriber by TMSI' /> - <param name='id' doc='Identify subscriber by database ID' /> - <param name='ID' doc='Identifier for the subscriber' /> - <param name='paging' doc='Issue an empty Paging for the subscriber (for debugging)' /> - </params> - </command> - <command id='show statistics'> - <params> - <param name='show' doc='Show running system information' /> - <param name='statistics' doc='Display network statistics' /> - </params> - </command> - <command id='show sms-queue'> - <params> - <param name='show' doc='Show running system information' /> - <param name='sms-queue' doc='Display SMSqueue statistics' /> - </params> - </command> - <command id='logging filter imsi IMSI'> - <params> - <param name='logging' doc='Configure logging' /> - <param name='filter' doc='Filter log messages' /> - <param name='imsi' doc='Filter log messages by IMSI' /> - <param name='IMSI' doc='IMSI to be used as filter' /> - </params> - </command> - <command id='show smpp esme'> - <params> - <param name='show' doc='Show running system information' /> - <param name='smpp' doc='SMPP Interface' /> - <param name='esme' doc='SMPP Extrenal SMS Entity' /> - </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 <0-512>'> - <params> - <param name='terminal' doc='Set terminal line parameters' /> - <param name='length' doc='Set number of lines on a screen' /> - <param name='<0-512>' 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='show cs7 instance <0-15> 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='<0-15>' doc='An instance of the SS7 stack' /> - <param name='users' doc='User Table' /> - </params> - </command> - <command id='show cs7 (sua|m3ua|ipa) [<0-65534>]'> - <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='[<0-65534>]' doc='Port Number' /> - </params> - </command> - <command id='show cs7 instance <0-15> 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='<0-15>' doc='An instance of the SS7 stack' /> - <param name='asp' doc='Application Server Process (ASP)' /> - </params> - </command> - <command id='show cs7 instance <0-15> 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='<0-15>' 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 <0-15> 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='<0-15>' 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 <0-15> 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='<0-15>' 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 <0-15> sccp ssn <0-65535>'> - <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='<0-15>' 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='<0-65535>' doc='Subsystem Number (SSN)' /> - </params> - </command> - <command id='show cs7 instance <0-15> 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='<0-15>' 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 <0-15> 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='<0-15>' 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='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'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'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'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'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't prefix each log message' /> - <param name='1' doc='Prefix each log message with category/subsystem nr in hex ('<000b>')' /> - </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'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'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'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. 'abc:mno:xyz'. Available log categories depend on the specific application, refer to the 'logging level' command. Optionally add individual log levels like 'abc,1:mno,3:xyz,5', 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 (rll|cc|mm|rr|mncc|pag|msc|mgcp|ho|db|ref|ctrl|smpp|ranap|vlr|iucs|bssap|lglobal|llapd|linp|lmux|lmi|lmib|lsms|lctrl|lgtp|lstats|lgsup|loap|lss7|lsccp|lsua|lm3ua|lmgcp|ljibuf) (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='rll' doc='A-bis Radio Link Layer (RLL)' /> - <param name='cc' doc='Layer3 Call Control (CC)' /> - <param name='mm' doc='Layer3 Mobility Management (MM)' /> - <param name='rr' doc='Layer3 Radio Resource (RR)' /> - <param name='mncc' doc='MNCC API for Call Control application' /> - <param name='pag' doc='Paging Subsystem' /> - <param name='msc' doc='Mobile Switching Center' /> - <param name='mgcp' doc='Media Gateway Control Protocol' /> - <param name='ho' doc='Hand-Over' /> - <param name='db' doc='Database Layer' /> - <param name='ref' doc='Reference Counting' /> - <param name='ctrl' doc='Control interface' /> - <param name='smpp' doc='SMPP interface for external SMS apps' /> - <param name='ranap' doc='Radio Access Network Application Part Protocol' /> - <param name='vlr' doc='Visitor Location Register' /> - <param name='iucs' doc='Iu-CS Protocol' /> - <param name='bssap' doc='BSSAP Protocol (A Interface)' /> - <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='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 'no logging level force-all' command. Note: any 'logging level <category> <level>' 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 'logging level force-all <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'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'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'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 fsm NAME'> - <params> - <param name='show' doc='Show running system information' /> - <param name='fsm' doc='Show information about finite state machines' /> - <param name='NAME' doc='Display information about a single named finite state machine' /> - </params> - </command> - <command id='show fsm all'> - <params> - <param name='show' doc='Show running system information' /> - <param name='fsm' doc='Show information about finite state machines' /> - <param name='all' doc='Display a list of all registered finite state machines' /> - </params> - </command> - <command id='show fsm-instances NAME'> - <params> - <param name='show' doc='Show running system information' /> - <param name='fsm-instances' doc='Show information about finite state machine instances' /> - <param name='NAME' doc='Display a list of all FSM instances of the named finite state machine' /> - </params> - </command> - <command id='show fsm-instances all'> - <params> - <param name='show' doc='Show running system information' /> - <param name='fsm-instances' doc='Show information about finite state machine instances' /> - <param name='all' doc='Display a list of all FSM instances of all finite state machine' /> - </params> - </command> - <command id='show subscriber (msisdn|extension|imsi|tmsi|id) ID'> - <params> - <param name='show' doc='Show running system information' /> - <param name='subscriber' doc='Operations on a Subscriber' /> - <param name='msisdn' doc='Identify subscriber by MSISDN (phone number)' /> - <param name='extension' doc='Legacy alias for 'msisdn'' /> - <param name='imsi' doc='Identify subscriber by IMSI' /> - <param name='tmsi' doc='Identify subscriber by TMSI' /> - <param name='id' doc='Identify subscriber by database ID' /> - <param name='ID' doc='Identifier for the subscriber' /> - </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 connection'> - <params> - <param name='show' doc='Show running system information' /> - <param name='connection' doc='Subscriber Connections' /> - </params> - </command> - <command id='show transaction'> - <params> - <param name='show' doc='Show running system information' /> - <param name='transaction' doc='Transactions' /> - </params> - </command> - <command id='sms send pending'> - <params> - <param name='sms' doc='SMS related commands' /> - <param name='send' doc='SMS Sending related commands' /> - <param name='pending' doc='Send all pending SMS' /> - </params> - </command> - <command id='sms delete expired'> - <params> - <param name='sms' doc='SMS related commands' /> - <param name='delete' doc='SMS Database related commands' /> - <param name='expired' doc='Delete all expired SMS' /> - </params> - </command> - <command id='subscriber create imsi ID'> - <params> - <param name='subscriber' doc='Operations on a Subscriber' /> - <param name='create' doc='Create new subscriber' /> - <param name='imsi' doc='Identify the subscriber by his IMSI' /> - <param name='ID' doc='Identifier for the subscriber' /> - </params> - </command> - <command id='subscriber (msisdn|extension|imsi|tmsi|id) ID sms sender (msisdn|extension|imsi|tmsi|id) SENDER_ID send .LINE'> - <params> - <param name='subscriber' doc='Operations on a Subscriber' /> - <param name='msisdn' doc='Identify subscriber by MSISDN (phone number)' /> - <param name='extension' doc='Legacy alias for 'msisdn'' /> - <param name='imsi' doc='Identify subscriber by IMSI' /> - <param name='tmsi' doc='Identify subscriber by TMSI' /> - <param name='id' doc='Identify subscriber by database ID' /> - <param name='ID' doc='Identifier for the subscriber' /> - <param name='sms' doc='SMS Operations' /> - <param name='sender' doc='Operations on a Subscriber' /> - <param name='msisdn' doc='Identify subscriber by MSISDN (phone number)' /> - <param name='extension' doc='Legacy alias for 'msisdn'' /> - <param name='imsi' doc='Identify subscriber by IMSI' /> - <param name='tmsi' doc='Identify subscriber by TMSI' /> - <param name='id' doc='Identify subscriber by database ID' /> - <param name='SENDER_ID' doc='Identifier for the subscriber' /> - <param name='send' doc='Send SMS' /> - <param name='.LINE' doc='Actual SMS Text' /> - </params> - </command> - <command id='subscriber (msisdn|extension|imsi|tmsi|id) ID silent-sms sender (msisdn|extension|imsi|tmsi|id) SENDER_ID send .LINE'> - <params> - <param name='subscriber' doc='Operations on a Subscriber' /> - <param name='msisdn' doc='Identify subscriber by MSISDN (phone number)' /> - <param name='extension' doc='Legacy alias for 'msisdn'' /> - <param name='imsi' doc='Identify subscriber by IMSI' /> - <param name='tmsi' doc='Identify subscriber by TMSI' /> - <param name='id' doc='Identify subscriber by database ID' /> - <param name='ID' doc='Identifier for the subscriber' /> - <param name='silent-sms' doc='Silent SMS Operations' /> - <param name='sender' doc='Operations on a Subscriber' /> - <param name='msisdn' doc='Identify subscriber by MSISDN (phone number)' /> - <param name='extension' doc='Legacy alias for 'msisdn'' /> - <param name='imsi' doc='Identify subscriber by IMSI' /> - <param name='tmsi' doc='Identify subscriber by TMSI' /> - <param name='id' doc='Identify subscriber by database ID' /> - <param name='SENDER_ID' doc='Identifier for the subscriber' /> - <param name='send' doc='Send SMS' /> - <param name='.LINE' doc='Actual SMS Text' /> - </params> - </command> - <command id='subscriber (msisdn|extension|imsi|tmsi|id) ID silent-call start (any|tch/f|tch/any|sdcch)'> - <params> - <param name='subscriber' doc='Operations on a Subscriber' /> - <param name='msisdn' doc='Identify subscriber by MSISDN (phone number)' /> - <param name='extension' doc='Legacy alias for 'msisdn'' /> - <param name='imsi' doc='Identify subscriber by IMSI' /> - <param name='tmsi' doc='Identify subscriber by TMSI' /> - <param name='id' doc='Identify subscriber by database ID' /> - <param name='ID' doc='Identifier for the subscriber' /> - <param name='silent-call' doc='Silent call operation' /> - <param name='start' doc='Start silent call' /> - <param name='any' doc='Any channel' /> - <param name='tch/f' doc='TCH/F channel' /> - <param name='tch/any' doc='Any TCH channel' /> - <param name='sdcch' doc='SDCCH channel' /> - </params> - </command> - <command id='subscriber (msisdn|extension|imsi|tmsi|id) ID silent-call stop'> - <params> - <param name='subscriber' doc='Operations on a Subscriber' /> - <param name='msisdn' doc='Identify subscriber by MSISDN (phone number)' /> - <param name='extension' doc='Legacy alias for 'msisdn'' /> - <param name='imsi' doc='Identify subscriber by IMSI' /> - <param name='tmsi' doc='Identify subscriber by TMSI' /> - <param name='id' doc='Identify subscriber by database ID' /> - <param name='ID' doc='Identifier for the subscriber' /> - <param name='silent-call' doc='Silent call operation' /> - <param name='stop' doc='Stop silent call' /> - </params> - </command> - <command id='subscriber (msisdn|extension|imsi|tmsi|id) ID ussd-notify (0|1|2) .TEXT'> - <params> - <param name='subscriber' doc='Operations on a Subscriber' /> - <param name='msisdn' doc='Identify subscriber by MSISDN (phone number)' /> - <param name='extension' doc='Legacy alias for 'msisdn'' /> - <param name='imsi' doc='Identify subscriber by IMSI' /> - <param name='tmsi' doc='Identify subscriber by TMSI' /> - <param name='id' doc='Identify subscriber by database ID' /> - <param name='ID' doc='Identifier for the subscriber' /> - <param name='ussd-notify' doc='Send a USSD notify to the subscriber' /> - <param name='0' doc='Alerting Level 0' /> - <param name='1' doc='Alerting Level 1' /> - <param name='2' doc='Alerting Level 2' /> - <param name='.TEXT' doc='Text of USSD message to send' /> - </params> - </command> - <command id='subscriber (msisdn|extension|imsi|tmsi|id) ID ms-test close-loop (a|b|c|d|e|f|i)'> - <params> - <param name='subscriber' doc='Operations on a Subscriber' /> - <param name='msisdn' doc='Identify subscriber by MSISDN (phone number)' /> - <param name='extension' doc='Legacy alias for 'msisdn'' /> - <param name='imsi' doc='Identify subscriber by IMSI' /> - <param name='tmsi' doc='Identify subscriber by TMSI' /> - <param name='id' doc='Identify subscriber by database ID' /> - <param name='ID' doc='Identifier for the subscriber' /> - <param name='ms-test' doc='Send a TS 04.14 MS Test Command to subscriber' /> - <param name='close-loop' doc='Close a TCH Loop inside the MS' /> - <param name='a' doc='Loop Type A' /> - <param name='b' doc='Loop Type B' /> - <param name='c' doc='Loop Type C' /> - <param name='d' doc='Loop Type D' /> - <param name='e' doc='Loop Type E' /> - <param name='f' doc='Loop Type F' /> - <param name='i' doc='Loop Type I' /> - </params> - </command> - <command id='subscriber (msisdn|extension|imsi|tmsi|id) ID ms-test open-loop'> - <params> - <param name='subscriber' doc='Operations on a Subscriber' /> - <param name='msisdn' doc='Identify subscriber by MSISDN (phone number)' /> - <param name='extension' doc='Legacy alias for 'msisdn'' /> - <param name='imsi' doc='Identify subscriber by IMSI' /> - <param name='tmsi' doc='Identify subscriber by TMSI' /> - <param name='id' doc='Identify subscriber by database ID' /> - <param name='ID' doc='Identifier for the subscriber' /> - <param name='ms-test' doc='Send a TS 04.14 MS Test Command to subscriber' /> - <param name='open-loop' doc='Open a TCH Loop inside the MS' /> - </params> - </command> - <command id='subscriber (msisdn|extension|imsi|tmsi|id) ID paging'> - <params> - <param name='subscriber' doc='Operations on a Subscriber' /> - <param name='msisdn' doc='Identify subscriber by MSISDN (phone number)' /> - <param name='extension' doc='Legacy alias for 'msisdn'' /> - <param name='imsi' doc='Identify subscriber by IMSI' /> - <param name='tmsi' doc='Identify subscriber by TMSI' /> - <param name='id' doc='Identify subscriber by database ID' /> - <param name='ID' doc='Identifier for the subscriber' /> - <param name='paging' doc='Issue an empty Paging for the subscriber (for debugging)' /> - </params> - </command> - <command id='show statistics'> - <params> - <param name='show' doc='Show running system information' /> - <param name='statistics' doc='Display network statistics' /> - </params> - </command> - <command id='show sms-queue'> - <params> - <param name='show' doc='Show running system information' /> - <param name='sms-queue' doc='Display SMSqueue statistics' /> - </params> - </command> - <command id='logging filter imsi IMSI'> - <params> - <param name='logging' doc='Configure logging' /> - <param name='filter' doc='Filter log messages' /> - <param name='imsi' doc='Filter log messages by IMSI' /> - <param name='IMSI' doc='IMSI to be used as filter' /> - </params> - </command> - <command id='subscriber (msisdn|extension|imsi|tmsi|id) ID expire'> - <params> - <param name='subscriber' doc='Operations on a Subscriber' /> - <param name='msisdn' doc='Identify subscriber by MSISDN (phone number)' /> - <param name='extension' doc='Legacy alias for 'msisdn'' /> - <param name='imsi' doc='Identify subscriber by IMSI' /> - <param name='tmsi' doc='Identify subscriber by TMSI' /> - <param name='id' doc='Identify subscriber by database ID' /> - <param name='ID' doc='Identifier for the subscriber' /> - <param name='expire' doc='Expire the subscriber Now' /> - </params> - </command> - <command id='sms-queue trigger'> - <params> - <param name='sms-queue' doc='SMS Queue' /> - <param name='trigger' doc='Trigger sending messages' /> - </params> - </command> - <command id='sms-queue max-pending <1-500>'> - <params> - <param name='sms-queue' doc='SMS Queue' /> - <param name='max-pending' doc='SMS to deliver in parallel' /> - <param name='<1-500>' doc='Amount' /> - </params> - </command> - <command id='sms-queue clear'> - <params> - <param name='sms-queue' doc='SMS Queue' /> - <param name='clear' doc='Clear the queue of pending SMS' /> - </params> - </command> - <command id='sms-queue max-failure <1-500>'> - <params> - <param name='sms-queue' doc='SMS Queue' /> - <param name='max-failure' doc='Maximum amount of delivery failures' /> - <param name='<1-500>' doc='Amount' /> - </params> - </command> - <command id='subscriber (msisdn|extension|imsi|tmsi|id) ID sms pending-send'> - <params> - <param name='subscriber' doc='Operations on a Subscriber' /> - <param name='msisdn' doc='Identify subscriber by MSISDN (phone number)' /> - <param name='extension' doc='Legacy alias for 'msisdn'' /> - <param name='imsi' doc='Identify subscriber by IMSI' /> - <param name='tmsi' doc='Identify subscriber by TMSI' /> - <param name='id' doc='Identify subscriber by database ID' /> - <param name='ID' doc='Identifier for the subscriber' /> - <param name='sms' doc='SMS Operations' /> - <param name='pending-send' doc='Send pending SMS' /> - </params> - </command> - <command id='show smpp esme'> - <params> - <param name='show' doc='Show running system information' /> - <param name='smpp' doc='SMPP Interface' /> - <param name='esme' doc='SMPP Extrenal SMS Entity' /> - </params> - </command> - </node> - <node id='config'> - <name>config</name> - <command id='hostname WORD'> - <params> - <param name='hostname' doc='Set system's network name' /> - <param name='WORD' doc='This system'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'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 'enable' 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) 'enable' 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 <0-512>'> - <params> - <param name='service' doc='Set up miscellaneous service' /> - <param name='terminal-length' doc='System wide terminal length configuration' /> - <param name='<0-512>' doc='Number of lines of VTY (0 means no line control)' /> - </params> - </command> - <command id='no service terminal-length [<0-512>]'> - <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='[<0-512>]' 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='cs7 instance <0-15>'> - <params> - <param name='cs7' doc='ITU-T Signaling System 7' /> - <param name='instance' doc='Configure a SS7 Instance' /> - <param name='<0-15>' doc='An instance of the SS7 stack' /> - </params> - </command> - <command id='ctrl'> - <params> - <param name='ctrl' doc='Configure the Control Interface' /> - </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 <2-32700>'> - <params> - <param name='log' doc='Configure logging sub-system' /> - <param name='alarms' doc='Logging alarms to osmo_strrb' /> - <param name='<2-32700>' 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 <0-7>'> - <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='<0-7>' 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 <1-65535>'> - <params> - <param name='stats' doc='Configure stats sub-system' /> - <param name='interval' doc='Set the reporting interval' /> - <param name='<1-65535>' doc='Interval in seconds' /> - </params> - </command> - <command id='network'> - <params> - <param name='network' doc='Configure the GSM network' /> - </params> - </command> - <command id='msc'> - <params> - <param name='msc' doc='Configure MSC options' /> - </params> - </command> - <command id='mncc-int'> - <params> - <param name='mncc-int' doc='Configure internal MNCC handler' /> - </params> - </command> - <command id='hlr'> - <params> - <param name='hlr' doc='Configure connection to the HLR' /> - </params> - </command> - <command id='smpp'> - <params> - <param name='smpp' doc='Configure SMPP SMS Interface' /> - </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'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'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'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'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't prefix each log message' /> - <param name='1' doc='Prefix each log message with category/subsystem nr in hex ('<000b>')' /> - </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'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'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'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 (rll|cc|mm|rr|mncc|pag|msc|mgcp|ho|db|ref|ctrl|smpp|ranap|vlr|iucs|bssap|lglobal|llapd|linp|lmux|lmi|lmib|lsms|lctrl|lgtp|lstats|lgsup|loap|lss7|lsccp|lsua|lm3ua|lmgcp|ljibuf) (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='rll' doc='A-bis Radio Link Layer (RLL)' /> - <param name='cc' doc='Layer3 Call Control (CC)' /> - <param name='mm' doc='Layer3 Mobility Management (MM)' /> - <param name='rr' doc='Layer3 Radio Resource (RR)' /> - <param name='mncc' doc='MNCC API for Call Control application' /> - <param name='pag' doc='Paging Subsystem' /> - <param name='msc' doc='Mobile Switching Center' /> - <param name='mgcp' doc='Media Gateway Control Protocol' /> - <param name='ho' doc='Hand-Over' /> - <param name='db' doc='Database Layer' /> - <param name='ref' doc='Reference Counting' /> - <param name='ctrl' doc='Control interface' /> - <param name='smpp' doc='SMPP interface for external SMS apps' /> - <param name='ranap' doc='Radio Access Network Application Part Protocol' /> - <param name='vlr' doc='Visitor Location Register' /> - <param name='iucs' doc='Iu-CS Protocol' /> - <param name='bssap' doc='BSSAP Protocol (A Interface)' /> - <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='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 'no logging level force-all' command. Note: any 'logging level <category> <level>' 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 'logging level force-all <level>'' /> - </params> - </command> - <command id='logging filter imsi IMSI'> - <params> - <param name='logging' doc='Configure logging' /> - <param name='filter' doc='Filter log messages' /> - <param name='imsi' doc='Filter log messages by IMSI' /> - <param name='IMSI' doc='IMSI to be used as filter' /> - </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 <1-65535>'> - <params> - <param name='remote-port' doc='Set the remote port to which we connect' /> - <param name='<1-65535>' doc='Remote port number' /> - </params> - </command> - <command id='mtu <100-65535>'> - <params> - <param name='mtu' doc='Set the maximum packet size' /> - <param name='<100-65535>' 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'> - <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)' /> - </params> - </command> - </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 <1-24> [<1-23>] [<1-22>]'> - <params> - <param name='point-code' doc='Point Code' /> - <param name='format' doc='Configure Point Code Format' /> - <param name='<1-24>' doc='Length of first PC component' /> - <param name='[<1-23>]' doc='Length of second PC component' /> - <param name='[<1-22>]' 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 <0-65535> <0-65535> (sua|m3ua|ipa)'> - <params> - <param name='asp' doc='Configure Application Server Process' /> - <param name='NAME' doc='Name of ASP' /> - <param name='<0-65535>' doc='Remote SCTP port number' /> - <param name='<0-65535>' 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) <1-999999>'> - <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='<1-999999>' 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 <1-2000>'> - <params> - <param name='recovery-timeout' doc='Specifies the recovery timeout value in milliseconds' /> - <param name='<1-2000>' doc='Recovery Timeout in Milliseconds' /> - </params> - </command> - <command id='qos-class <0-255>'> - <params> - <param name='qos-class' doc='Specity QoS Class of AS' /> - <param name='<0-255>' 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 <0-255>'> - <params> - <param name='qos-class' doc='Specify QoS Class of ASP' /> - <param name='<0-255>' doc='QoS Class of ASP' /> - </params> - </command> - <command id='block'> - <params> - <param name='block' doc='Allows a SCTP Association with ASP, but doesn'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 <0-4294967295>'> - <params> - <param name='subsystem-number' doc='Add Subsystem Number' /> - <param name='<0-4294967295>' 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 <0-15>'> - <params> - <param name='global-title-indicator' doc='Set Global Title Indicator' /> - <param name='<0-15>' doc='GTI' /> - </params> - </command> - <command id='translation-type <0-255>'> - <params> - <param name='translation-type' doc='Set Global Title Translation Type' /> - <param name='<0-255>' doc='TT' /> - </params> - </command> - <command id='numbering-plan-indicator <0-15>'> - <params> - <param name='numbering-plan-indicator' doc='Set Global Title Numbering Plan Indicator' /> - <param name='<0-15>' doc='NPI' /> - </params> - </command> - <command id='nature-of-address-indicator <0-127>'> - <params> - <param name='nature-of-address-indicator' doc='Set Global Title Nature of Address Indicator' /> - <param name='<0-127>' 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-net'> - <name>config-net</name> - <command id='network country code <1-999>'> - <params> - <param name='network' doc='Set the GSM network country code' /> - <param name='country' doc='Country commands' /> - <param name='code' doc='Code commands' /> - <param name='<1-999>' doc='Network Country Code to use' /> - </params> - </command> - <command id='mobile network code <0-999>'> - <params> - <param name='mobile' doc='Set the GSM mobile network code' /> - <param name='network' doc='Network Commands' /> - <param name='code' doc='Code commands' /> - <param name='<0-999>' doc='Mobile Network Code to use' /> - </params> - </command> - <command id='short name NAME'> - <params> - <param name='short' doc='Set the short GSM network name' /> - <param name='name' doc='Name Commands' /> - <param name='NAME' doc='Name to use' /> - </params> - </command> - <command id='long name NAME'> - <params> - <param name='long' doc='Set the long GSM network name' /> - <param name='name' doc='Name Commands' /> - <param name='NAME' doc='Name to use' /> - </params> - </command> - <command id='encryption a5 <0-3> [<0-3>] [<0-3>] [<0-3>]'> - <params> - <param name='encryption' doc='Encryption options' /> - <param name='a5' doc='GSM A5 Air Interface Encryption' /> - <param name='<0-3>' doc='A5/n Algorithm Number' /> - <param name='[<0-3>]' doc='A5/n Algorithm Number' /> - <param name='[<0-3>]' doc='A5/n Algorithm Number' /> - <param name='[<0-3>]' doc='A5/n Algorithm Number' /> - </params> - </command> - <command id='authentication (optional|required)'> - <params> - <param name='authentication' doc='Whether to enforce MS authentication in 2G' /> - <param name='optional' doc='Allow MS to attach via 2G BSC without authentication' /> - <param name='required' doc='Always do authentication' /> - </params> - </command> - <command id='rrlp mode (none|ms-based|ms-preferred|ass-preferred)'> - <params> - <param name='rrlp' doc='Radio Resource Location Protocol' /> - <param name='mode' doc='Set the Radio Resource Location Protocol Mode' /> - <param name='none' doc='Don't send RRLP request' /> - <param name='ms-based' doc='Request MS-based location' /> - <param name='ms-preferred' doc='Request any location, prefer MS-based' /> - <param name='ass-preferred' doc='Request any location, prefer MS-assisted' /> - </params> - </command> - <command id='mm info (0|1)'> - <params> - <param name='mm' doc='Mobility Management' /> - <param name='info' doc='Send MM INFO after LOC UPD ACCEPT' /> - <param name='0' doc='Disable' /> - <param name='1' doc='Enable' /> - </params> - </command> - <command id='timezone <-19-19> (0|15|30|45)'> - <params> - <param name='timezone' doc='Set the Timezone Offset of the network' /> - <param name='<-19-19>' doc='Timezone offset (hours)' /> - <param name='0' doc='Timezone offset (00 minutes)' /> - <param name='15' doc='Timezone offset (15 minutes)' /> - <param name='30' doc='Timezone offset (30 minutes)' /> - <param name='45' doc='Timezone offset (45 minutes)' /> - </params> - </command> - <command id='timezone <-19-19> (0|15|30|45) <0-2>'> - <params> - <param name='timezone' doc='Set the Timezone Offset of the network' /> - <param name='<-19-19>' doc='Timezone offset (hours)' /> - <param name='0' doc='Timezone offset (00 minutes)' /> - <param name='15' doc='Timezone offset (15 minutes)' /> - <param name='30' doc='Timezone offset (30 minutes)' /> - <param name='45' doc='Timezone offset (45 minutes)' /> - <param name='<0-2>' doc='DST offset (hours)' /> - </params> - </command> - <command id='no timezone'> - <params> - <param name='no' doc='Negate a command or set its defaults' /> - <param name='timezone' doc='Disable network timezone override, use system tz' /> - </params> - </command> - <command id='periodic location update <6-1530>'> - <params> - <param name='periodic' doc='Periodic Location Updating Interval' /> - <param name='location' doc='Periodic Location Updating Interval' /> - <param name='update' doc='Periodic Location Updating Interval' /> - <param name='<6-1530>' doc='Periodic Location Updating Interval in Minutes' /> - </params> - </command> - <command id='no periodic location update'> - <params> - <param name='no' doc='Negate a command or set its defaults' /> - <param name='periodic' doc='Periodic Location Updating Interval' /> - <param name='location' doc='Periodic Location Updating Interval' /> - <param name='update' doc='Periodic Location Updating Interval' /> - </params> - </command> - </node> - <node id='config-msc'> - <name>config-msc</name> - <command id='assign-tmsi'> - <params> - <param name='assign-tmsi' doc='Assign TMSI during Location Updating.' /> - </params> - </command> - <command id='mncc-guard-timeout <0-255>'> - <params> - <param name='mncc-guard-timeout' doc='Set global guard timer for mncc interface activity' /> - <param name='<0-255>' doc='guard timer value (sec.)' /> - </params> - </command> - <command id='no assign-tmsi'> - <params> - <param name='no' doc='Negate a command or set its defaults' /> - <param name='assign-tmsi' doc='Assign TMSI during Location Updating.' /> - </params> - </command> - <command id='auth-tuple-max-reuse-count <-1-2147483647>'> - <params> - <param name='auth-tuple-max-reuse-count' doc='Configure authentication tuple re-use' /> - <param name='<-1-2147483647>' doc='0 to use each auth tuple at most once (default), >0 to limit re-use, -1 to re-use infinitely (vulnerable!).' /> - </params> - </command> - <command id='auth-tuple-reuse-on-error (0|1)'> - <params> - <param name='auth-tuple-reuse-on-error' doc='Configure authentication tuple re-use when HLR is not responsive' /> - <param name='0' doc='0 = never re-use auth tuples beyond auth-tuple-max-reuse-count (default)' /> - <param name='1' doc='1 = if the HLR does not deliver new tuples, do re-use already available old ones.' /> - </params> - </command> - <command id='cs7-instance-a <0-15>'> - <params> - <param name='cs7-instance-a' doc='Set SS7 to be used by the A-Interface.' /> - <param name='<0-15>' doc='SS7 instance reference number' /> - </params> - </command> - <command id='cs7-instance-iu <0-15>'> - <params> - <param name='cs7-instance-iu' doc='Set SS7 to be used by the Iu-Interface.' /> - <param name='<0-15>' doc='SS7 instance reference number' /> - </params> - </command> - <command id='paging response-timer (default|<1-65535>)'> - <params> - <param name='paging' doc='Configure Paging' /> - <param name='response-timer' doc='Set Paging timeout, the minimum time to pass between (unsuccessful) Pagings sent towards BSS or RNC' /> - <param name='default' doc='Set to default timeout (10 seconds)' /> - <param name='<1-65535>' doc='Set paging timeout in seconds' /> - </params> - </command> - <command id='emergency-call route-to-msisdn MSISDN'> - <params> - <param name='emergency-call' doc='Configure Emergency Call Behaviour' /> - <param name='route-to-msisdn' doc='MSISDN to which Emergency Calls are Dispatched' /> - <param name='MSISDN' doc='MSISDN (E.164 Phone Number)' /> - </params> - </command> - <command id='mgw local-ip A.B.C.D'> - <params> - <param name='mgw' doc='Configure MGCP connection to Media Gateway' /> - <param name='local-ip' doc='local bind to connect to MGW from' /> - <param name='A.B.C.D' doc='local bind IP address' /> - </params> - </command> - <command id='mgw local-port <0-65535>'> - <params> - <param name='mgw' doc='Configure MGCP connection to Media Gateway' /> - <param name='local-port' doc='local port to connect to MGW from' /> - <param name='<0-65535>' doc='local bind port' /> - </params> - </command> - <command id='mgw remote-ip A.B.C.D'> - <params> - <param name='mgw' doc='Configure MGCP connection to Media Gateway' /> - <param name='remote-ip' doc='remote IP address to reach the MGW at' /> - <param name='A.B.C.D' doc='remote IP address' /> - </params> - </command> - <command id='mgw remote-port <0-65535>'> - <params> - <param name='mgw' doc='Configure MGCP connection to Media Gateway' /> - <param name='remote-port' doc='remote port to reach the MGW at' /> - <param name='<0-65535>' doc='remote port' /> - </params> - </command> - <command id='mgw endpoint-range <1-65534> <1-65534>'> - <params> - <param name='mgw' doc='Configure MGCP connection to Media Gateway' /> - <param name='endpoint-range' doc='usable range of endpoint identifiers' /> - <param name='<1-65534>' doc='set first usable endpoint identifier' /> - <param name='<1-65534>' doc='set last usable endpoint identifier' /> - </params> - </command> - <command id='mgw bts-base <0-65534>'> - <params> - <param name='mgw' doc='Configure MGCP connection to Media Gateway' /> - <param name='bts-base' doc='First UDP port allocated for the BTS side' /> - <param name='<0-65534>' doc='UDP Port number' /> - </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'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> - <node id='config-mncc-int'> - <name>config-mncc-int</name> - <command id='default-codec tch-f (fr|efr|amr)'> - <params> - <param name='default-codec' doc='Set default codec' /> - <param name='tch-f' doc='Codec for TCH/F' /> - <param name='fr' doc='Full-Rate' /> - <param name='efr' doc='Enhanced Full-Rate' /> - <param name='amr' doc='Adaptive Multi-Rate' /> - </params> - </command> - <command id='default-codec tch-h (hr|amr)'> - <params> - <param name='default-codec' doc='Set default codec' /> - <param name='tch-h' doc='Codec for TCH/H' /> - <param name='hr' doc='Half-Rate' /> - <param name='amr' doc='Adaptive Multi-Rate' /> - </params> - </command> - </node> - <node id='config-smpp'> - <name>config-smpp</name> - <command id='smpp-first'> - <params> - <param name='smpp-first' doc='Try SMPP routes before the subscriber DB' /> - </params> - </command> - <command id='no smpp-first'> - <params> - <param name='no' doc='Negate a command or set its defaults' /> - <param name='smpp-first' doc='Try SMPP before routes before the subscriber DB' /> - </params> - </command> - <command id='local-tcp-port <1-65535>'> - <params> - <param name='local-tcp-port' doc='Set the local TCP port on which we listen for SMPP' /> - <param name='<1-65535>' doc='TCP port number' /> - </params> - </command> - <command id='local-tcp-ip A.B.C.D <1-65535>'> - <params> - <param name='local-tcp-ip' doc='Set the local IP address and TCP port on which we listen for SMPP' /> - <param name='A.B.C.D' doc='Local IP address' /> - <param name='<1-65535>' doc='TCP port number' /> - </params> - </command> - <command id='system-id ID'> - <params> - <param name='system-id' doc='Set the System ID of this SMSC' /> - <param name='ID' doc='Alphanumeric SMSC System ID' /> - </params> - </command> - <command id='policy (accept-all|closed)'> - <params> - <param name='policy' doc='Set the authentication policy of this SMSC' /> - <param name='accept-all' doc='Accept all SMPP connections independeint of system ID / passwd' /> - <param name='closed' doc='Accept only SMPP connections from ESMEs explicitly configured' /> - </params> - </command> - <command id='esme NAME'> - <params> - <param name='esme' doc='Configure a particular ESME' /> - <param name='NAME' doc='Alphanumeric System ID of the ESME to be configured' /> - </params> - </command> - <command id='no esme NAME'> - <params> - <param name='no' doc='Negate a command or set its defaults' /> - <param name='esme' doc='Remove ESME configuration' /> - <param name='NAME' doc='Alphanumeric System ID of the ESME to be removed' /> - </params> - </command> - </node> - <node id='config-smpp-esme'> - <name>config-smpp-esme</name> - <command id='password PASSWORD'> - <params> - <param name='password' doc='Set the password for this ESME' /> - <param name='PASSWORD' doc='Alphanumeric password string' /> - </params> - </command> <command id='no password'> - <params> - <param name='no' doc='Negate a command or set its defaults' /> - <param name='password' doc='Remove the password for this ESME' /> - </params> - </command> - <command id='route prefix (unknown|international|national|network|subscriber|alpha|abbrev) (unknown|isdn|x121|f69|e212|national|private|ermes|ip|wap) PREFIX'> - <params> - <param name='route' doc='Configure a route for MO-SMS to be sent to this ESME' /> - <param name='prefix' doc='Prefix-match route' /> - <param name='unknown' doc='Unknown type-of-number' /> - <param name='international' doc='International type-of-number' /> - <param name='national' doc='National type-of-number' /> - <param name='network' doc='Network specific type-of-number' /> - <param name='subscriber' doc='Subscriber type-of-number' /> - <param name='alpha' doc='Alphanumeric type-of-number' /> - <param name='abbrev' doc='Abbreviated type-of-number' /> - <param name='unknown' doc='Unknown numbering plan' /> - <param name='isdn' doc='ISDN (E.164) numbering plan' /> - <param name='x121' doc='X.121 numbering plan' /> - <param name='f69' doc='F.69 numbering plan' /> - <param name='e212' doc='E.212 numbering plan' /> - <param name='national' doc='National numbering plan' /> - <param name='private' doc='Private numbering plan' /> - <param name='ermes' doc='ERMES numbering plan' /> - <param name='ip' doc='IP numbering plan' /> - <param name='wap' doc='WAP numbeing plan' /> - <param name='PREFIX' doc='Destination number prefix' /> - </params> - </command> - <command id='no route prefix (unknown|international|national|network|subscriber|alpha|abbrev) (unknown|isdn|x121|f69|e212|national|private|ermes|ip|wap) PREFIX'> - <params> - <param name='no' doc='Negate a command or set its defaults' /> - <param name='route' doc='Configure a route for MO-SMS to be sent to this ESME' /> - <param name='prefix' doc='Prefix-match route' /> - <param name='unknown' doc='Unknown type-of-number' /> - <param name='international' doc='International type-of-number' /> - <param name='national' doc='National type-of-number' /> - <param name='network' doc='Network specific type-of-number' /> - <param name='subscriber' doc='Subscriber type-of-number' /> - <param name='alpha' doc='Alphanumeric type-of-number' /> - <param name='abbrev' doc='Abbreviated type-of-number' /> - <param name='unknown' doc='Unknown numbering plan' /> - <param name='isdn' doc='ISDN (E.164) numbering plan' /> - <param name='x121' doc='X.121 numbering plan' /> - <param name='f69' doc='F.69 numbering plan' /> - <param name='e212' doc='E.212 numbering plan' /> - <param name='national' doc='National numbering plan' /> - <param name='private' doc='Private numbering plan' /> - <param name='ermes' doc='ERMES numbering plan' /> - <param name='ip' doc='IP numbering plan' /> - <param name='wap' doc='WAP numbeing plan' /> - <param name='PREFIX' doc='Destination number prefix' /> - </params> - </command> - <command id='default-route'> - <params> - <param name='default-route' doc='Set this ESME as default-route for all SMS to unknown destinations' /> - </params> - </command> - <command id='no default-route'> - <params> - <param name='no' doc='Negate a command or set its defaults' /> - <param name='default-route' doc='Remove this ESME as default-route for all SMS to unknown destinations' /> - </params> - </command> - <command id='deliver-src-imsi'> - <params> - <param name='deliver-src-imsi' doc='Enable the use of IMSI as source address in DELIVER' /> - </params> - </command> - <command id='no deliver-src-imsi'> - <params> - <param name='no' doc='Negate a command or set its defaults' /> - <param name='deliver-src-imsi' doc='Disable the use of IMSI as source address in DELIVER' /> - </params> - </command> - <command id='osmocom-extensions'> - <params> - <param name='osmocom-extensions' doc='Enable the use of Osmocom SMPP Extensions for this ESME' /> - </params> - </command> - <command id='no osmocom-extensions'> - <params> - <param name='no' doc='Negate a command or set its defaults' /> - <param name='osmocom-extensions' doc='Disable the use of Osmocom SMPP Extensions for this ESME' /> - </params> - </command> - <command id='dcs-transparent'> - <params> - <param name='dcs-transparent' doc='Enable the transparent pass-through of TP-DCS to SMPP DataCoding' /> - </params> - </command> - <command id='no dcs-transparent'> - <params> - <param name='no' doc='Negate a command or set its defaults' /> - <param name='dcs-transparent' doc='Disable the transparent pass-through of TP-DCS to SMPP DataCoding' /> - </params> - </command> - </node> - <node id='config-hlr'> - <name>config-hlr</name> - <command id='remote-ip A.B.C.D'> - <params> - <param name='remote-ip' doc='Remote GSUP address of the HLR' /> - <param name='A.B.C.D' doc='Remote GSUP address (default: 127.0.0.1)' /> - </params> - </command> - <command id='remote-port <1-65535>'> - <params> - <param name='remote-port' doc='Remote GSUP port of the HLR' /> - <param name='<1-65535>' doc='Remote GSUP port (default: MSC_HLR_REMOTE_PORT_DEFAULT)' /> - </params> - </command> - </node> -</vtydoc> diff --git a/doc/sequence_charts/Makefile.am b/doc/sequence_charts/Makefile.am index b667a6f5e..7a5277643 100644 --- a/doc/sequence_charts/Makefile.am +++ b/doc/sequence_charts/Makefile.am @@ -4,27 +4,26 @@ all: charts: msc dot EXTRA_DIST = \ - inter_bsc_ho.msc \ - inter_msc_ho.msc \ - mncc_fsm.msc \ + $(srcdir)/*.msc \ $(NULL) CLEANFILES = \ - inter_bsc_ho.png \ - inter_msc_ho.png \ - mncc_fsm.png \ + $(builddir)/*.png \ $(NULL) msc: \ - $(builddir)/mncc_fsm.png \ + $(builddir)/mncc_call_fsm.png \ $(builddir)/inter_bsc_ho.png \ $(builddir)/inter_msc_ho.png \ + $(builddir)/voice_call_external_mncc.png \ + $(builddir)/voice_call_internal_mncc.png \ + $(builddir)/call_reestablishment.png \ $(NULL) dot: \ $(NULL) -$(builddir)/%.png: $(srcdir)/%.msc +$(builddir)/%.png: %.msc mscgen -T png -o $@ $< $(builddir)/%.png: $(srcdir)/%.dot diff --git a/doc/sequence_charts/call_reestablishment.msc b/doc/sequence_charts/call_reestablishment.msc new file mode 100644 index 000000000..b4d081ca2 --- /dev/null +++ b/doc/sequence_charts/call_reestablishment.msc @@ -0,0 +1,33 @@ +msc { + hscale="2"; + ms[label="MS"],cell1[label="Cell 1 (BTS+BSC)"],cell0[label="Cell 0 (BTS+BSC)"],__msc[label="MSC"]; + + ms rbox __msc [label="Call Re-Establishment"]; + ms note __msc [label="Ongoing voice call: MM is established"]; + + ...; + + ms -x cell0 [label="radio link fails"]; + ms x- cell0; + + __msc abox __msc [label="Keep MM until timeout"]; + + ms => cell1 [label="Channel Required"]; + ms <= cell1 [label="Immediate Assignment"]; + ms => cell1 [label="Complete Layer3"]; + cell1 => __msc [label="Complete Layer3:\nCM Re-Establishment Request"]; + + cell0 <= __msc [label="Clear Command"]; + cell0 => __msc [label="Clear Complete"]; + + cell1 <= __msc [label="Authentication Request"]; + cell1 => __msc [label="Authentication Response"]; + + cell1 <= __msc [label="Cipher Mode Commad"]; + cell1 => __msc [label="Cipher Mode Complete"]; + + cell1 <= __msc [label="Assignment Request\nthis Assignment ACKs the CM Re-Establishment"]; + ms <= cell1 [label="RR Assignment Command"]; + ms => cell1 [label="RR Assignment Complete"]; + cell1 => __msc [label="Assignment Complete"]; +} diff --git a/doc/sequence_charts/mncc_call_fsm.msc b/doc/sequence_charts/mncc_call_fsm.msc new file mode 100644 index 000000000..4a14ff738 --- /dev/null +++ b/doc/sequence_charts/mncc_call_fsm.msc @@ -0,0 +1,104 @@ +msc { + hscale=3; + msc1[label="osmo-msc"], mncc1[label="MNCC FSM\n(osmo-msc mncc_call.c)"], sipcon1[label="osmo-sip-connector"], sip[label="PBX"], sipcon2[label="osmo-sip-connector"], mncc2[label="MNCC FSM\n(osmo-msc mncc_call.c)"], msc2[label="osmo-msc"]; + + msc1 note sipcon1 [label="MO call"]; + sipcon2 note msc2 [label="MT call"]; + + mncc1 abox mncc1 [label="MNCC_CALL_ST_NOT_STARTED"]; + msc1 rbox msc1 [label="mncc_outgoing_start()"]; + msc1 -> mncc1 [label="MNCC_CALL_EV_OUTGOING_START"]; + + mncc1 abox mncc1 [label="MNCC_CALL_ST_OUTGOING_WAIT_PROCEEDING"]; + mncc1 => sipcon1 [label="MNCC_SETUP_IND + \n callref, IMSI, called and calling number, SDP"]; + sipcon1 => sip [label="SIP INVITE + \n from, to, SDP"]; + sipcon1 <= sip [label="SIP 100 Trying"]; + mncc1 <= sipcon1 [label="MNCC_RTP_CREATE + \n callref"]; + mncc1 rbox mncc1 [label="mncc_rx_rtp_create()"]; + mncc1 => sipcon1 [label="MNCC_RTP_CREATE + \n callref, RTP IP address and port"]; + mncc1 <= sipcon1 [label="MNCC_CALL_PROC_REQ + \n callref, RTP IP address and port"]; + mncc1 abox mncc1 [label="MNCC_CALL_ST_OUTGOING_WAIT_COMPLETE"]; + + sip => sipcon2 [label="SIP INVITE + \n from, to, SDP"]; + sipcon2 => sip [label="SIP 100 Trying"]; + msc2 <= sipcon2 [label="MNCC_SETUP_REQ + \n callref, called and calling number + \n SDP"]; + mncc2 abox mncc2 [label="MNCC_CALL_ST_NOT_STARTED"]; + msc2 rbox msc2 [label="mncc_incoming_start()"]; + msc2 -> mncc2 [label="MNCC_CALL_EV_INCOMING_START"]; + mncc2 abox mncc2 [label="MNCC_CALL_ST_INCOMING_WAIT_COMPLETE"]; + mncc2 => sipcon2 [label="MNCC_CALL_CONF_IND + \n callref, bearer capabilities, cccap and IMSI, SDP?"]; + mncc2 <= sipcon2 [label="MNCC_RTP_CREATE + \n callref"]; + mncc2 rbox mncc2 [label="mncc_rx_rtp_create()"]; + mncc2 => sipcon2 [label="MNCC_RTP_CREATE + \n callref, RTP IP address and port, SDP?"]; + mncc2 => sipcon2 [label="MNCC_ALERT_IND + \n callref"]; + sipcon2 => sip [label="SIP 180 Ringing + \n SDP"]; + + sipcon1 <= sip [label="SIP 180 Ringing + \n SDP"]; + mncc1 <= sipcon1 [label="MNCC_ALERT_REQ + \n callref and progress"]; + sipcon1 => sip [label="SIP PRACK 180 Ringing"]; + sipcon1 <= sip [label="SIP PRACK 200"]; + + mncc1 <= sipcon1 [label="MNCC_RTP_CONNECT + \n callref, RTP IP and port"]; + mncc1 rbox mncc1 [label="mncc_rx_rtp_connect()"]; + msc1 <- mncc1 [label="rtp_stream_set_remote_addr()"]; + + mncc2 => sipcon2 [label="MNCC_SETUP_CNF + \n callref, imsi and connected number, SDP?"]; + sipcon2 => sip [label="SIP 200 OK + \n SDP"]; + mncc2 <= sipcon2 [label="MNCC_RTP_CONNECT + \n callref, RTP IP and port"]; + mncc2 rbox mncc2 [label="mncc_rx_rtp_connect()"]; + mncc2 <= sipcon2 [label="MNCC_SETUP_COMPL_REQ + \n callref"]; + mncc2 abox mncc2 [label="MNCC_CALL_ST_TALKING"]; + + sipcon1 <= sip [label="SIP 200 OK INVITE"]; + mncc1 <= sipcon1 [label="MNCC_SETUP_RSP + \n callref"]; + mncc1 => sipcon1 [label="MNCC_SETUP_COMPL_IND + \n callref"]; + mncc1 abox mncc1 [label="MNCC_CALL_ST_TALKING"]; + sipcon1 => sip [label="SIP ACK"]; + + ...; + ... [label="Call goes on for a while..."]; + ...; + + mncc1 rbox mncc1 [label="mncc_release()"]; + mncc1 => sipcon1 [label="MNCC_DISC_IND + \n callref and cause"]; + mncc1 abox mncc1 [label="MNCC_CALL_ST_WAIT_RELEASE_ACK"]; + sipcon1 => sip [label="SIP BYE"]; + sipcon1 <= sip [label="SIP 200 OK"]; + mncc1 <= sipcon1 [label="MNCC_REL_REQ + \n callref and cause"]; + + sip => sipcon2 [label="SIP BYE"]; + sip <= sipcon2 [label="SIP 200 OK"]; + mncc2 <= sipcon2 [label="MNCC_DISC_REQ + \n callref and cause"]; + mncc2 => sipcon2 [label="MNCC_REL_IND + \n callref and cause"]; + mncc2 abox mncc2 [label="terminated"]; + + mncc1 => sipcon1 [label="MNCC_REL_CNF + \n callref"]; + mncc1 abox mncc1 [label="terminated"]; +} diff --git a/doc/sequence_charts/mncc_fsm.msc b/doc/sequence_charts/mncc_fsm.msc deleted file mode 100644 index ae5e0a211..000000000 --- a/doc/sequence_charts/mncc_fsm.msc +++ /dev/null @@ -1,84 +0,0 @@ -msc { - hscale=2; - msc1[label="osmo-msc"], mncc1[label="MNCC FSM"], pbx[label="MNCC server (osmo-sip-connector)"], mncc2[label="MNCC FSM"], msc2[label="osmo-msc"]; - - mncc1 note mncc1 [label="The typical progression of an outgoing call, i.e. a call initiated by osmo-msc, as - implemented in mncc_fsm.h, mncc_fsm.c"]; - mncc2 note mncc2 [label="The typical progression of an incoming call, i.e. a call initiated by the PBX, as - implemented in mncc_fsm.h, mncc_fsm.c"]; - - mncc1 abox mncc1 [label="MNCC_ST_NOT_STARTED"]; - msc1 rbox msc1 [label="mncc_outgoing_start()"]; - msc1 -> mncc1 [label="MNCC_EV_OUTGOING_START"]; - - mncc1 abox mncc1 [label="MNCC_ST_OUTGOING_WAIT_PROCEEDING"]; - mncc1 => pbx [label="MNCC_SETUP_IND - \n callref, IMSI, called and calling number"]; - mncc1 <= pbx [label="MNCC_RTP_CREATE - \n callref"]; - mncc1 rbox mncc1 [label="mncc_rx_rtp_create()"]; - mncc1 => pbx [label="MNCC_RTP_CREATE - \n callref, RTP IP address and port"]; - mncc1 <= pbx [label="MNCC_CALL_PROC_REQ - \n callref, RTP IP address and port"]; - mncc1 abox mncc1 [label="MNCC_ST_OUTGOING_WAIT_COMPLETE"]; - - msc2 <= pbx [label="MNCC_SETUP_REQ - \n callref, called and calling number"]; - mncc2 abox mncc2 [label="MNCC_ST_NOT_STARTED"]; - msc2 rbox msc2 [label="mncc_incoming_start()"]; - msc2 -> mncc2 [label="MNCC_EV_INCOMING_START"]; - mncc2 abox mncc2 [label="MNCC_ST_INCOMING_WAIT_COMPLETE"]; - mncc2 => pbx [label="MNCC_CALL_CONF_IND - \n callref, bearer capabilities, cccap and IMSI"]; - mncc2 <= pbx [label="MNCC_RTP_CREATE - \n callref"]; - mncc2 rbox mncc2 [label="mncc_rx_rtp_create()"]; - mncc2 => pbx [label="MNCC_RTP_CREATE - \n callref, RTP IP address and port"]; - mncc2 => pbx [label="MNCC_ALERT_IND - \n callref"]; - - mncc1 <= pbx [label="MNCC_ALERT_REQ - \n callref and progress"]; - - mncc2 => pbx [label="MNCC_SETUP_CNF - \n callref, imsi and connected number"]; - mncc2 <= pbx [label="MNCC_RTP_CONNECT - \n callref, RTP IP and port"]; - mncc2 rbox mncc2 [label="mncc_rx_rtp_connect()"]; - mncc2 <= pbx [label="MNCC_SETUP_COMPL_REQ - \n callref"]; - mncc2 abox mncc2 [label="MNCC_ST_TALKING"]; - - mncc1 <= pbx [label="MNCC_RTP_CONNECT - \n callref, RTP IP and port"]; - mncc1 rbox mncc1 [label="mncc_rx_rtp_connect()"]; - msc1 <- mncc1 [label="rtp_stream_set_remote_addr()"]; - mncc1 <= pbx [label="MNCC_SETUP_RSP - \n callref"]; - mncc1 => pbx [label="MNCC_SETUP_COMPL_IND - \n callref"]; - mncc1 abox mncc1 [label="MNCC_ST_TALKING"]; - - ...; - ... [label="Call goes on for a while..."]; - ...; - - mncc1 rbox mncc1 [label="mncc_release()"]; - mncc1 => pbx [label="MNCC_DISC_IND - \n callref and cause"]; - mncc1 abox mncc1 [label="MNCC_ST_WAIT_RELEASE_ACK"]; - mncc1 <= pbx [label="MNCC_REL_REQ - \n callref and cause"]; - - mncc2 <= pbx [label="MNCC_DISC_REQ - \n callref and cause"]; - mncc2 => pbx [label="MNCC_REL_IND - \n callref and cause"]; - mncc2 abox mncc2 [label="terminated"]; - - mncc1 => pbx [label="MNCC_REL_CNF - \n callref"]; - mncc1 abox mncc1 [label="terminated"]; -} diff --git a/doc/sequence_charts/msc_log_to_ladder.py b/doc/sequence_charts/msc_log_to_ladder.py new file mode 100755 index 000000000..9bfb9c9c2 --- /dev/null +++ b/doc/sequence_charts/msc_log_to_ladder.py @@ -0,0 +1,753 @@ +#!/usr/bin/env python3 +doc=r''' +Reading a log, it can be hard to figure out what is the important bit going on. +This is a tool that reads an osmo-msc log and tries to compose a ladder diagram from it automatically. +''' + +import argparse +import sys +import re +import tempfile +import os + +def error(*msg): + sys.stderr.write('%s\n' % (''.join(msg))) + exit(1) + +def quote(msg, quote='"'): + return '"%s"' % (msg.replace('"', r'\"')) + +class Entity: + def __init__(self, name, descr=None, attrs={}): + self.name = name + self.descr = descr + self.attrs = attrs + +class Arrow: + def __init__(self, mo_mt, left, arrow, right, descr=None, attrs={}, ran_conn=None, imsi=None, tmsi=None): + self.mo_mt = mo_mt + self.left = left + self.arrow = arrow + self.right = right + self.descr = descr + self.attrs = attrs + self.ran_conn = ran_conn + self.imsi = imsi + self.tmsi = tmsi + + def __repr__(self): + return 'Arrow(%s %s %s %s: %s IMSI=%s)' % (self.mo_mt, self.left, self.arrow, self.right, self.descr, self.imsi) + +class Separator: + def __init__(self): + self.separator = None + self.descr = None + self.attrs = {} + +class EmptyLine: + def __init__(self): + self.count = 1 + +MS = 'ms' +UE = 'ms' #'ue' +MS_UE_UNKNOWN = 'ms' #None +MSC = 'msc' +MGW = 'mgw' +MNCC = 'mncc' + +MO = 'mo' +MT = 'mt' +MO_MT_UNKNOWN = None + + +class OutputBase: + def __init__(self, write_to, start_with_re=None): + self._write_to = write_to + + self.start_with_re = None + if start_with_re is not None: + self.start_with_re = re.compile(start_with_re) + + def head(self): + self.writeln('# Generated by osmo-msc.git/doc/sequence_charts/msc_log_to_ladder.py') + + def tail(self): + pass + + def render(self, diagram): + self.head() + if diagram.root_attrs: + self.root_attrs(diagram.root_attrs) + self.entities(diagram.entities) + + started = (self.start_with_re is None) + + for line in diagram.lines: + if not started: + if hasattr(line, 'descr') and self.start_with_re.match(line.descr): + started = True + else: + continue + self.add(line) + self.tail() + + def entities(self, entities): + for entity in entities: + self.entity(entity) + + def write(self, line): + self._write_to.write(line) + + def writeln(self, line): + self.write('%s\n' % line) + + def emptyline(self, emptyline): + self.write('\n' * emptyline.count); + + def add(self, thing): + func = getattr(self, thing.__class__.__name__.lower()) + func(thing) + + +class OutputLadder(OutputBase): + + def indent_multiline(self, s): + return s.replace('\n', '\n\t') + + def attrs_str(self, attrs, prefix=' '): + if not attrs: + return '' + return '%s{%s}' % (prefix or '', ','.join('%s=%s' % (k,v) for k,v in attrs.items())) + + def root_attrs(self, attrs): + self.writeln(self.attrs_str(attrs, prefix=None)) + + def entity(self, entity): + self.writeln('%s = %s%s' % (entity.name, self.indent_multiline(entity.descr), self.attrs_str(entity.attrs))) + + def arrow(self, arrow): + mo_mt = arrow.mo_mt or MO + + def prepend_mo_mt(name): + if name in ('.', MNCC): + return name + return '%s%s' % (mo_mt, name) + + self.writeln('%s %s %s%s%s%s' + % (prepend_mo_mt(arrow.left), + arrow.arrow, + prepend_mo_mt(arrow.right), + '\t' if arrow.descr else '', + self.indent_multiline(arrow.descr or ''), + self.attrs_str(arrow.attrs))) + + def separator(self, sep_str, descr, attrs): + self.writeln('%s%s%s%s' + % (separator.separator, + ' ' if separator.descr else '', + self.indent_multiline(separator.descr or ''), + self.attrs_str(separator.attrs))) + +class OutputMscgen(OutputBase): + ARROWS = { + '>' : '=>>', + '->' : '=>', + '-->' : '>>', + '~>' : '->', + '=>' : ':>', + '-><' : '-x', + + '<' : '<<=', + '<-' : '<=', + '<--' : '<<', + '<~' : '<-', + '<=' : '<:', + '><-' : 'x-', + + '<>' : 'abox', + '()' : 'rbox', + '[]' : 'note', + } + + def head(self): + super().head() + self.writeln('msc {') + + def tail(self): + self.writeln('}') + + def entities(self, entities): + estr = [] + for entity in entities: + estr.append('%s%s' % (entity.name, self.attrs_str(self.all_attrs(entity.descr, entity.attrs), prefix=''))) + if not estr: + return + self.writeln('%s;' % (','.join(estr))) + + def attrs_list_str(self, attrs): + if not attrs: + return '' + def escape(s): + return s.replace('\n', r'\n').replace('\r', '').replace('\t', r'\t') + return ','.join('%s="%s"' % (k,escape(v)) for k,v in attrs.items()) + + def attrs_str(self, attrs, prefix=' '): + attrs_list_str = self.attrs_list_str(attrs) + if not attrs_list_str: + return '' + return '%s[%s]' % (prefix or '', attrs_list_str) + + def root_attrs(self, attrs): + if not attrs: + return + self.writeln('%s;' % self.attrs_list_str(attrs)) + + def all_attrs(self, descr, attrs): + a = {} + if descr: + a['label'] = descr + a.update(attrs) + return a + + def entity(self, entity): + error('OutputMscgen.entity() should not be called') + + def arrow_txlate(self, arrow): + txlate = OutputMscgen.ARROWS.get(arrow) + if not txlate: + error('Unknown arrow: %r' % arrow) + return txlate + + def arrow(self, arrow): + mo_mt = arrow.mo_mt or MO + + def prepend_mo_mt(name): + if name in ('.', MNCC): + return name + return '%s%s' % (mo_mt, name) + + l = prepend_mo_mt(arrow.left) + r = arrow.right + if r == '.': + r = l + else: + r = prepend_mo_mt(r) + + a = {'label': arrow.descr} + a.update(arrow.attrs) + attrs = self.attrs_str(a) + + self.writeln('%s %s %s%s;' + % (l, self.arrow_txlate(arrow.arrow), r, + self.attrs_str(self.all_attrs(arrow.descr, arrow.attrs), prefix='\t'))) + + def separator(self, sep_str, descr, attrs): + self.writeln('%s%s%s%s;' + % (separator.separator, + self.attrs_str(self.all_attrs(descr, attrs), prefix='\t'))) + + def emptyline(self, emptyline): + self.write('\n' * emptyline.count); + + +def ms_from_ran(ran_type_or_conn): + if ran_type_or_conn.startswith('UTRAN-Iu'): + return UE + if ran_type_or_conn.startswith('RANAP'): + return UE + if ran_type_or_conn.startswith('GERAN-A'): + return MS + if ran_type_or_conn.startswith('BSS'): + return MS + return MS_UE_UNKNOWN + +class Diagram: + def __init__(self): + self.root_attrs = {} + self.entities = [] + self.lines = [] + self.mo_mt_unknown_lines = [] + + def add_line(self, line): + self.lines.append(line) + + def resolve_unknown_mo_mt(self): + + def try_match(a, b): + if a < 0 or a >= len(self.lines): + return False + if b < 0 or b >= len(self.lines): + return False + la = self.lines[a] + lb = self.lines[b] + + if not hasattr(lb, 'mo_mt'): + return False + if lb.mo_mt == MO_MT_UNKNOWN: + return False + + for match_attr in ('imsi', 'tmsi', 'ran_conn'): + if not hasattr(la, match_attr): + continue + if not hasattr(lb, match_attr): + continue + la_attr = getattr(la, match_attr) + if la_attr is None: + continue + lb_attr = getattr(lb, match_attr) + if la_attr == lb_attr: + la.mo_mt = lb.mo_mt + return True + return False + + + while True: + changes = 0 + for i in range(len(self.lines)): + line = self.lines[i] + + if not hasattr(line, 'mo_mt'): + continue + if line.mo_mt is not MO_MT_UNKNOWN: + continue + + # don't know MO/MT, try to resolve from near messages + for j in range(1,100): + if try_match(i, i-j): + break + if try_match(i, i+j): + break + if line.mo_mt is not MO_MT_UNKNOWN: + changes += 1 + if not changes: + break + + +re_source_file_last = re.compile(r'(.*) \(([^):]+:[0-9]+)\)$') + +class Rule: + def __init__(self, name, re_str, handler): + self.name = name + self.re = re.compile(re_str) + self.handler = handler + + def match(self, line): + m = self.re.match(line) + if not m: + return False + return self.handler(m) + + +def mo_mt_from_l3type(l3type): + if l3type == 'PAGING_RESP': + return MT + elif l3type == 'CM_SERVICE_REQ': + return MO + else: + return MO_MT_UNKNOWN + +def int_to_hex(val, bits): + return hex((int(val) + (1 << bits)) % (1 << bits)) + +class Callref: + MAX = 0x7fffffff + MIN = -0x80000000 + BITS = 32 + + def int_to_hex(val): + return int_to_hex(val, Callref.BITS) + + def hex_to_int(hexstr): + val = int(hexstr, 16) + if val > Callref.MAX: + val = Callref.MIN + (val & Callref.MAX) + return val + +class Parse: + + def __init__(self, output, mask_values=False): + + self.diagram = Diagram() + self.output = output + self.linenr = 0 + self.rules = [] + self.rules_hit = {} + self.seen_udtrace_mncc = False + + self.callrefs_mo_mt = {} + self.mask_values = mask_values + self.masked_values = {} + + for member in dir(self): + if not member.startswith('rule_'): + continue + func = getattr(self, member) + if not callable(func): + continue + + docstr = func.__doc__ + if not docstr: + continue + re_str = docstr.splitlines()[0] + + self.rules.append(Rule(name=member, re_str=re_str, handler=func)) + self.rules_hit[member] = 0 + + + + def error(self, *msg): + error('line %d: ' % self.linenr, *msg) + + def start(self): + self.diagram.root_attrs = {'hscale': '3'} + for name, descr in ( + ('moms', 'MS,BSS (MO)\\nUE,hNodeB (MO)'), + #('moue', 'UE,hNodeB (MO)'), + ('momgw', 'MGW for MSC (MO)'), + ('momsc', 'MSC (MO)'), + ('mncc', 'MNCC'), + ('mtmsc', 'MSC (MT)'), + ('mtmgw', 'MGW for MSC (MT)'), + ('mtms', 'BSS,MS (MT)\\nhNodeB,UE (MT)'), + #('mtue', 'hNodeB,UE (MT)'), + ): + self.diagram.entities.append(Entity(name, descr)) + + def end(self): + self.diagram.resolve_unknown_mo_mt() + self.output.render(self.diagram) + + def mask_value(self, name, val): + if not self.mask_values: + return val + if not val: + return val + name_dict = self.masked_values.get(name) + if not name_dict: + name_dict = {} + self.masked_values[name] = name_dict + + masked_val = name_dict.get(val) + if masked_val is None: + masked_val = '%s-%d' % (name, len(name_dict) + 1) + name_dict[val] = masked_val + return masked_val + + def add_line(self, line): + self.linenr += 1 + if line.endswith('\n'): + line = line[:-1] + if line.endswith('\r'): + line = line[:-1] + + self.interpret(line) + + def interpret(self, line): + + m = re_source_file_last.match(line) + if m: + line = m.group(1) + + for rule in self.rules: + if rule.match(line): + self.rules_hit[rule.name] = self.rules_hit.get(rule.name, 0) + 1 + break + + RE_DTAP_NAME = re.compile('.*GSM48_MT_([^_]+)_(.+)') + + def rule_paging(self, m): + r'.*ran_peer\(([^:]+):.* Paging for ([^ ]+) on ([^ ]+)' + ran_type, subscr, cell = m.groups() + + self.diagram.add_line(Arrow(MT, ms_from_ran(ran_type), '<', MSC, 'Paging')) + return True + + RE_IMSI = re.compile('IMSI-([0-9]+)') + RE_TMSI = re.compile('TMSI-0x([0-9a-fA-F]+)') + + def rule_dtap(self, m): + r'.*msc_a\(([^)]*):([^:]+):([^:]+)\).* (Dispatching 04.08 message|Sending DTAP): (.+)$' + + subscr, ran_conn, l3type, rx_tx, dtap = m.groups() + tx = (rx_tx == 'Sending DTAP') + + m = self.RE_DTAP_NAME.match(dtap) + if m: + dtap = '%s %s' % m.groups() + + if 'IMSI_DETACH_IND' in dtap: + # detecting IMSI Detach separately, because this log line does not contain the IMSI. + # By using the rule_imsi_detach(), we can accurately put it on the MO/MT side. + return True + + if l3type == 'NONE' and not tx and dtap.endswith('PAG_RESP'): + e = MT + else: + e = mo_mt_from_l3type(l3type) + + imsi = None + for m in Parse.RE_IMSI.finditer(subscr): + imsi = m.group(1) + tmsi = None + for m in Parse.RE_TMSI.finditer(subscr): + tmsi = m.group(1) + + self.diagram.add_line(Arrow(e, ms_from_ran(ran_conn), '<' if tx else '>', MSC, dtap, + ran_conn=ran_conn, imsi=imsi, tmsi=tmsi)) + return True + + def rule_imsi_detach(self, m): + r'.*IMSI DETACH for IMSI-([0-9]+):.*' + imsi = m.group(1) + e = MO_MT_UNKNOWN + self.diagram.add_line(Arrow(e, MS_UE_UNKNOWN, '>', MSC, 'IMSI Detach', imsi=imsi)) + return True + + def rule_mgcp_tx(self, m): + r'.*mgw-endp\([^)]*:([^:]+):([^:]+)\).* (rtpbridge[^ ]+) .* RTP_TO_(RAN|CN)( CI=([^:]+)|): ([^ :]+).*: Sending' + ran, l3type, endp, rtp_to, cond_ci, ci, verb = m.groups() + e = mo_mt_from_l3type(l3type) + if '*' not in endp: + endp = self.mask_value('EP', endp) + ci = self.mask_value('CI', ci) + ci_str = '' + if ci: + ci_str = ' %s' % ci + self.diagram.add_line(Arrow(e, MGW, '<', MSC, 'for %s: %s\\n%s%s' % (rtp_to, verb, endp, ci_str))) + return True + + def rule_mgcp_rx(self, m): + r'.*mgw-endp\(([^)]+):([^:)]+):([^:)]+)\).* (rtpbridge[^ ]+) .* RTP_TO_(RAN|CN)( CI=([^:]+)|).*: received successful response to ([^:]+): RTP=[^:]+:([0-9.:]+)' + subscr, ran_conn, l3type, endp, rtp_to, cond_ci, ci, verb, rtp = m.groups() + e = mo_mt_from_l3type(l3type) + endp = self.mask_value('EP', endp) + ci = self.mask_value('CI', ci) + ci_str = '' + if ci: + ci_str = ' %s' % ci + rtp = self.mask_value('IP:port', rtp) + self.diagram.add_line(Arrow(e, MGW, '>', MSC, 'for %s: %s OK\\n%s%s %s' % (rtp_to, verb, endp, ci_str, rtp))) + return True + + def rule_ran_tx(self, m): + r'.*msc_a\(([^)]+):([^:)]+):([^:)]+)\).* RAN encode: ([^: ]+): (.+)$' + + subscr, ran_conn, l3type, ran_type, msg_type = m.groups() + + if msg_type in ('DTAP', 'DirectTransfer'): + # will get DTAP details from rule_dtap() instead, not from BSSMAP logging + return True + if msg_type.startswith('Tx'): + # skip 'Tx RANAP SECURITY MODE COMMAND to RNC, ik 47...' + return True + if '=' in msg_type: + # skip 'RAB Assignment: rab_id=1, rtp=192.168.178.66:50008, use_x213_nsap=1' + return True + + + e = mo_mt_from_l3type(l3type) + + imsi = None + for m in Parse.RE_IMSI.finditer(subscr): + imsi = m.group(1) + tmsi = None + for m in Parse.RE_TMSI.finditer(subscr): + tmsi = m.group(1) + + self.diagram.add_line(Arrow(e, ms_from_ran(ran_conn), '<', MSC, '(%s) %s' % (ran_type, msg_type), + ran_conn=ran_conn, imsi=imsi, tmsi=tmsi)) + return True + + def rule_ran_rx(self, m): + r'.*msc_a\(([^)]+):([^:)]+):([^:)]+)\).* RAN decode: ([^: ]+) (.+)$' + + subscr, ran_conn, l3type, ran_type, msg_type = m.groups() + + if msg_type in ('DTAP', 'DirectTransfer', 'DirectTransfer RAN PDU'): + # will get DTAP details from rule_dtap() instead, not from BSSMAP logging + return True + + + e = mo_mt_from_l3type(l3type) + + imsi = None + for m in Parse.RE_IMSI.finditer(subscr): + imsi = m.group(1) + tmsi = None + for m in Parse.RE_TMSI.finditer(subscr): + tmsi = m.group(1) + + self.diagram.add_line(Arrow(e, ms_from_ran(ran_type), '>', MSC, '(%s) %s' % (ran_type, msg_type), + ran_conn=ran_conn, imsi=imsi, tmsi=tmsi)) + return True + + def rule_cc_state(self, m): + r'.*trans\(CC[^) ]* [^ )]+:([^:)]+) callref-([^ ]+) [^)]+\) new state ([^ ]+) -> ([^ ]+)' + l3type, callref_hex, from_state, to_state = m.groups() + + e = mo_mt_from_l3type(l3type) + self.callrefs_mo_mt[callref_hex] = e + + self.diagram.add_line(Arrow(e, MSC, '<>', '.', 'CC state:\\n%s' % to_state)) + return True + + def rule_log_mncc_no_rtp(self, m): + r'.*trans\(CC[^) ]* [^ )]+:([^:)]+) callref-([^ ]+) [^)]+\) (tx|rx) (MNCC_[^ ]*)$' + l3type, callref_hex, tx_rx, mncc_msg = m.groups() + + if self.seen_udtrace_mncc: + # If no udtrace is present, take the MNCC logging. + # But if there is udtrace logging available, we should not duplicate those MNCC lines. + return True + + tx = (tx_rx == 'tx') + + try: + e = self.callrefs_mo_mt.get(callref_hex, MT) + except: + e = MT + + self.diagram.add_line(Arrow(e, MSC, '>' if tx else '<', 'mncc', mncc_msg)) + return True + + def rule_log_mncc_with_rtp(self, m): + r'.*trans\(CC[^) ]* [^ )]+:([^:)]+) callref-([^ ]+) [^)]+\) (tx|rx) (MNCC_[^ ]*) \(RTP=([^){]+)(|{.*})\)$' + l3type, callref_hex, tx_rx, mncc_msg, rtp, codec = m.groups() + + if self.seen_udtrace_mncc: + # If no udtrace is present, take the MNCC logging. + # But if there is udtrace logging available, we should not duplicate those MNCC lines. + return True + + tx = (tx_rx == 'tx') + + try: + e = self.callrefs_mo_mt.get(callref_hex, MT) + except: + e = MT + + rtp = self.mask_value('IP:port', rtp) + self.diagram.add_line(Arrow(e, MSC, '>' if tx else '<', 'mncc', f'{mncc_msg}\\n{rtp}')) + return True + + RE_MNCC_RTP = re.compile(' ip := ([^, ]+), rtp_port := ([0-9]+),') + RE_MNCC_CALLREF = re.compile(' callref := ([^ ,]+), ') + + # detecting MNCC with udtrace has the advantage that we also get an indication whether RTP information is + # present + def rule_udtrace_mncc(self, m): + r'.*(write|recv).* (Tx|Rx): \{ msg_type := ([^ ]+) .* u := \{ (.*) \} \}$' + write_recv, tx_rx, msg_type, u = m.groups() + + self.seen_udtrace_mncc = True + + tx = (tx_rx == 'Tx') + + callref_intstr = None + for m in Parse.RE_MNCC_CALLREF.finditer(u): + callref_intstr = m.group(1) + if not callref_intstr: + # log only MNCC that has a callref + return True + + try: + e = self.callrefs_mo_mt.get(Callref.int_to_hex(callref_intstr), MT) + except: + e = MT + + descr = msg_type + + for m in Parse.RE_MNCC_RTP.finditer(u): + ip_str, port_str = m.groups() + try: + if int(ip_str) == 0 or int(port_str) == 0: + break + except: + break + ip_hex = int_to_hex(ip_str, 32) + ip = [] + ip_val = int(ip_hex, 16) + for byte in range(4): + ip.insert(0, (ip_val & (0xff << (8*byte))) >> (8*byte)) + rtp_info = '%s:%s' % ('.'.join(str(b) for b in ip), port_str) + rtp_info = self.mask_value('IP:port', rtp_info) + descr = '%s\\n%s' % (descr, rtp_info) + break + + self.diagram.add_line(Arrow(e, MSC, '>' if tx else '<', 'mncc', descr)) + return True + + def rule_cc_timer(self, m): + r'.*trans\(CC.*IMSI-([0-9]+):.*\) (starting|stopping pending) (guard timer|timer T[0-9]+)( with ([0-9]+) seconds|)' + imsi, start_stop, t, with_cond, s = m.groups() + start = (start_stop == 'starting') + e = MO_MT_UNKNOWN + if start: + self.diagram.add_line(Arrow(e, MSC, '[]', '.', 'CC starts %s (%ss)' % (t, s), imsi=imsi)) + else: + self.diagram.add_line(Arrow(e, MSC, '[]', '.', 'CC stops %s' % (t), imsi=imsi)) + return True + + +def translate(inf, outf, cmdline): + if cmdline.output_format == 'mscgen': + output = OutputMscgen(outf, cmdline.start_with_re) + else: + output = OutputLadder(outf, cmdline.start_with_re) + parse = Parse(output, cmdline.mask_values) + + parse.start() + + while inf.readable(): + line = inf.readline() + if not line: + break; + parse.add_line(line) + parse.end() + if cmdline.verbose: + for name, count in parse.rules_hit.items(): + print(f" {name}: {count}") + +def open_output(inf, cmdline): + if cmdline.output_file == '-': + translate(inf, sys.stdout, cmdline) + else: + with tempfile.NamedTemporaryFile(dir=os.path.dirname(cmdline.output_file), mode='w', encoding='utf-8') as tmp_out: + translate(inf, tmp_out, cmdline) + if os.path.exists(cmdline.output_file): + os.unlink(cmdline.output_file) + os.link(tmp_out.name, cmdline.output_file) + +def open_input(cmdline): + if cmdline.input_file == '-': + open_output(sys.stdin, cmdline) + else: + with open(cmdline.input_file, 'r') as f: + open_output(f, cmdline) + +def main(cmdline): + open_input(cmdline) + + +if __name__ == '__main__': + parser = argparse.ArgumentParser(description=doc) + parser.add_argument('-i', '--input-file', dest='input_file', default="-", + help='Read from this file, or stdin if "-"') + parser.add_argument('-o', '--output-file', dest='output_file', default="-", + help='Write to this file, or stdout if "-"') + parser.add_argument('-t', '--output-format', dest='output_format', default="mscgen", + choices=('mscgen','ladder'), + help='Pick output format: mscgen format or libosmocore/contrib/ladder_to_msc.py format') + parser.add_argument('-m', '--mask-values', dest='mask_values', action='store_true', + help='Do not output specific values like IP address, port, endpoint CI, instead just indicate that a value is' + ' present. This makes the output reproducible across various logs.') + parser.add_argument('-s', '--start-with', dest='start_with_re', default=None, + help='Skip until the first message with this label (regex), e.g. -s "CC SETUP"') + parser.add_argument('-v', '--verbose', dest='verbose', action='store_true', + help='show some debug info, like which regex rules were hit and which were not.') + + cmdline = parser.parse_args() + + main(cmdline) + +# vim: shiftwidth=8 noexpandtab tabstop=8 autoindent nocindent diff --git a/doc/sequence_charts/voice_call_external_mncc.msc b/doc/sequence_charts/voice_call_external_mncc.msc new file mode 100644 index 000000000..94cedee67 --- /dev/null +++ b/doc/sequence_charts/voice_call_external_mncc.msc @@ -0,0 +1,124 @@ +# Generated by osmo-msc.git/doc/sequence_charts/msc_log_to_ladder.py +msc { +hscale="3"; +moms[label="MS,BSS (MO)\nUE,hNodeB (MO)"],momgw[label="MGW for MSC (MO)"],momsc[label="MSC (MO)"],mncc[label="MNCC"],mtmsc[label="MSC (MT)"],mtmgw[label="MGW for MSC (MT)"],mtms[label="BSS,MS (MT)\nhNodeB,UE (MT)"]; +moms =>> momsc [label="(BSSMAP) Complete Layer 3 Information"]; +moms =>> momsc [label="MM CM_SERV_REQ"]; +moms <<= momsc [label="MM AUTH_REQ"]; +moms =>> momsc [label="MM AUTH_RESP"]; +moms <<= momsc [label="(BSSMAP) CIPHER_MODE_COMMAND"]; +moms =>> momsc [label="(BSSMAP) Ciphering Mode Complete"]; +moms <<= momsc [label="(BSSMAP) COMMON_ID"]; +moms =>> momsc [label="RR CIPH_M_COMPL"]; +moms =>> momsc [label="CC SETUP"]; +momsc note momsc [label="CC starts guard timer (180s)"]; +momsc abox momsc [label="CC state:\nINITIATED"]; +momgw <<= momsc [label="for CN: CRCX\nrtpbridge/*@msc"]; +momgw =>> momsc [label="for CN: CRCX OK\nEP-1 CI-1 IP:port-1"]; +momsc =>> mncc [label="MNCC_SETUP_IND\nIP:port-1"]; +momgw <<= momsc [label="for RAN: CRCX\nEP-1"]; +momsc <<= mncc [label="MNCC_RTP_CREATE"]; +momgw =>> momsc [label="for RAN: CRCX OK\nEP-1 CI-2 IP:port-2"]; +moms <<= momsc [label="(BSSMAP) ASSIGNMENT_COMMAND"]; +moms =>> momsc [label="(BSSMAP) Assignment Complete"]; +momgw <<= momsc [label="for RAN: MDCX\nEP-1 CI-2"]; +momsc =>> mncc [label="MNCC_RTP_CREATE\nIP:port-1"]; +momsc <<= mncc [label="MNCC_CALL_PROC_REQ"]; +momsc note momsc [label="CC stops guard timer"]; +momsc note momsc [label="CC starts guard timer (180s)"]; +momsc abox momsc [label="CC state:\nMO_CALL_PROC"]; +moms <<= momsc [label="CC CALL_PROC"]; +mtmsc <<= mncc [label="MNCC_SETUP_REQ\nIP:port-1"]; +mtms <<= mtmsc [label="Paging"]; +momgw =>> momsc [label="for RAN: MDCX OK\nEP-1 CI-2 IP:port-2"]; +mtms =>> mtmsc [label="(BSSMAP) Complete Layer 3 Information"]; +mtms =>> mtmsc [label="RR PAG_RESP"]; +mtms <<= mtmsc [label="MM AUTH_REQ"]; +mtms =>> mtmsc [label="MM AUTH_RESP"]; +mtms <<= mtmsc [label="(BSSMAP) CIPHER_MODE_COMMAND"]; +mtms =>> mtmsc [label="(BSSMAP) Ciphering Mode Complete"]; +mtms <<= mtmsc [label="(BSSMAP) COMMON_ID"]; +mtmsc note mtmsc [label="CC starts timer T303 (30s)"]; +mtmsc abox mtmsc [label="CC state:\nCALL_PRESENT"]; +mtms <<= mtmsc [label="CC SETUP"]; +mtms =>> mtmsc [label="RR CIPH_M_COMPL"]; +mtms =>> mtmsc [label="CC CALL_CONF"]; +mtmsc note mtmsc [label="CC stops timer T303"]; +mtmsc note mtmsc [label="CC starts timer T310 (30s)"]; +mtmgw <<= mtmsc [label="for CN: CRCX\nrtpbridge/*@msc"]; +mtmsc abox mtmsc [label="CC state:\nMO_TERM_CALL_CONF"]; +mtmsc =>> mncc [label="MNCC_CALL_CONF_IND"]; +mtmsc <<= mncc [label="MNCC_RTP_CREATE"]; +mtmgw =>> mtmsc [label="for CN: CRCX OK\nEP-2 CI-3 IP:port-3"]; +mtmgw <<= mtmsc [label="for RAN: CRCX\nEP-2"]; +mtmgw =>> mtmsc [label="for RAN: CRCX OK\nEP-2 CI-4 IP:port-4"]; +mtms <<= mtmsc [label="(BSSMAP) ASSIGNMENT_COMMAND"]; +mtms =>> mtmsc [label="(BSSMAP) Assignment Complete"]; +mtmgw <<= mtmsc [label="for RAN: MDCX\nEP-2 CI-4"]; +mtmsc =>> mncc [label="MNCC_RTP_CREATE\nIP:port-3"]; +mtmgw =>> mtmsc [label="for RAN: MDCX OK\nEP-2 CI-4 IP:port-4"]; +mtms =>> mtmsc [label="CC ALERTING"]; +mtmsc note mtmsc [label="CC stops timer T310"]; +mtmsc note mtmsc [label="CC starts timer T301 (180s)"]; +mtmsc abox mtmsc [label="CC state:\nCALL_RECEIVED"]; +mtmsc =>> mncc [label="MNCC_ALERT_IND\nIP:port-3"]; +momsc <<= mncc [label="MNCC_ALERT_REQ"]; +momsc note momsc [label="CC stops guard timer"]; +momsc note momsc [label="CC starts guard timer (180s)"]; +momsc abox momsc [label="CC state:\nCALL_DELIVERED"]; +moms <<= momsc [label="CC ALERTING"]; +mtms =>> mtmsc [label="CC CONNECT"]; +mtmsc note mtmsc [label="CC stops timer T301"]; +mtmsc abox mtmsc [label="CC state:\nCONNECT_REQUEST"]; +mtmsc =>> mncc [label="MNCC_SETUP_CNF\nIP:port-3"]; +mtmsc <<= mncc [label="MNCC_RTP_CONNECT\nIP:port-1"]; +mtmgw <<= mtmsc [label="for CN: MDCX\nEP-2 CI-3"]; +mtmsc <<= mncc [label="MNCC_SETUP_COMPL_REQ"]; +mtmsc note mtmsc [label="CC starts guard timer (180s)"]; +mtmsc abox mtmsc [label="CC state:\nACTIVE"]; +mtmsc note mtmsc [label="CC stops guard timer"]; +mtms <<= mtmsc [label="CC CONNECT_ACK"]; +momsc <<= mncc [label="MNCC_RTP_CONNECT\nIP:port-3"]; +momgw <<= momsc [label="for CN: MDCX\nEP-1 CI-1"]; +momsc <<= mncc [label="MNCC_SETUP_RSP"]; +momsc note momsc [label="CC stops guard timer"]; +momsc note momsc [label="CC starts guard timer (180s)"]; +momsc note momsc [label="CC starts timer T313 (30s)"]; +momsc abox momsc [label="CC state:\nCONNECT_IND"]; +moms <<= momsc [label="CC CONNECT"]; +mtmgw =>> mtmsc [label="for CN: MDCX OK\nEP-2 CI-3 IP:port-3"]; +momgw =>> momsc [label="for CN: MDCX OK\nEP-1 CI-1 IP:port-1"]; +moms =>> momsc [label="CC CONNECT_ACK"]; +momsc note momsc [label="CC stops timer T313"]; +momsc abox momsc [label="CC state:\nACTIVE"]; +momsc note momsc [label="CC stops guard timer"]; +momsc =>> mncc [label="MNCC_SETUP_COMPL_IND"]; +moms =>> momsc [label="CC DISCONNECT"]; +momsc abox momsc [label="CC state:\nDISCONNECT_IND"]; +momsc =>> mncc [label="MNCC_DISC_IND"]; +momsc <<= mncc [label="MNCC_REL_REQ"]; +momsc note momsc [label="CC starts guard timer (180s)"]; +momsc note momsc [label="CC starts timer T308 (10s)"]; +momsc abox momsc [label="CC state:\nRELEASE_REQ"]; +moms <<= momsc [label="CC RELEASE"]; +mtmsc <<= mncc [label="MNCC_DISC_REQ"]; +mtmsc note mtmsc [label="CC starts guard timer (180s)"]; +mtmsc note mtmsc [label="CC starts timer T306 (30s)"]; +mtmsc abox mtmsc [label="CC state:\nDISCONNECT_IND"]; +mtms <<= mtmsc [label="CC DISCONNECT"]; +mtms =>> mtmsc [label="CC RELEASE"]; +mtmsc note mtmsc [label="CC stops timer T306"]; +mtms <<= mtmsc [label="CC RELEASE_COMPL"]; +mtmsc =>> mncc [label="MNCC_REL_IND"]; +mtmsc abox mtmsc [label="CC state:\nNULL"]; +mtmsc note mtmsc [label="CC stops guard timer"]; +mtms <<= mtmsc [label="(BSSMAP) CLEAR_COMMAND"]; +mtms =>> mtmsc [label="(BSSMAP) Clear Complete"]; +moms =>> momsc [label="CC RELEASE_COMPL"]; +momsc note momsc [label="CC stops timer T308"]; +momsc =>> mncc [label="MNCC_REL_CNF"]; +momsc abox momsc [label="CC state:\nNULL"]; +momsc note momsc [label="CC stops guard timer"]; +moms <<= momsc [label="(BSSMAP) CLEAR_COMMAND"]; +moms =>> momsc [label="(BSSMAP) Clear Complete"]; +} diff --git a/doc/sequence_charts/voice_call_internal_mncc.msc b/doc/sequence_charts/voice_call_internal_mncc.msc new file mode 100644 index 000000000..898c1ff9a --- /dev/null +++ b/doc/sequence_charts/voice_call_internal_mncc.msc @@ -0,0 +1,129 @@ +# Generated by osmo-msc.git/doc/sequence_charts/msc_log_to_ladder.py +msc { +hscale="3"; +moms[label="MS,BSS (MO)\nUE,hNodeB (MO)"],momgw[label="MGW for MSC (MO)"],momsc[label="MSC (MO)"],mncc[label="MNCC"],mtmsc[label="MSC (MT)"],mtmgw[label="MGW for MSC (MT)"],mtms[label="BSS,MS (MT)\nhNodeB,UE (MT)"]; +moms =>> momsc [label="(BSSMAP) Complete Layer 3 Information"]; +moms =>> momsc [label="MM CM_SERV_REQ"]; +moms <<= momsc [label="MM AUTH_REQ"]; +moms =>> momsc [label="MM AUTH_RESP"]; +moms <<= momsc [label="(BSSMAP) CIPHER_MODE_COMMAND"]; +moms =>> momsc [label="(BSSMAP) Ciphering Mode Complete"]; +moms <<= momsc [label="(BSSMAP) COMMON_ID"]; +moms =>> momsc [label="RR CIPH_M_COMPL"]; +moms =>> momsc [label="CC SETUP"]; +momsc note momsc [label="CC starts guard timer (180s)"]; +momsc abox momsc [label="CC state:\nINITIATED"]; +momgw <<= momsc [label="for CN: CRCX\nrtpbridge/*@msc"]; +momgw =>> momsc [label="for CN: CRCX OK\nEP-1 CI-1 IP:port-1"]; +momsc =>> mncc [label="MNCC_SETUP_IND\nIP:port-1"]; +momsc <<= mncc [label="MNCC_CALL_PROC_REQ"]; +momsc note momsc [label="CC stops guard timer"]; +momsc note momsc [label="CC starts guard timer (180s)"]; +momsc abox momsc [label="CC state:\nMO_CALL_PROC"]; +moms <<= momsc [label="CC CALL_PROC"]; +momsc <<= mncc [label="MNCC_LCHAN_MODIFY"]; +momsc note momsc [label="CC stops guard timer"]; +momsc note momsc [label="CC starts guard timer (180s)"]; +mtmsc <<= mncc [label="MNCC_SETUP_REQ\nIP:port-1"]; +mtms <<= mtmsc [label="Paging"]; +momgw <<= momsc [label="for RAN: CRCX\nEP-1"]; +momgw =>> momsc [label="for RAN: CRCX OK\nEP-1 CI-2 IP:port-2"]; +moms <<= momsc [label="(BSSMAP) ASSIGNMENT_COMMAND"]; +mtms =>> mtmsc [label="(BSSMAP) Complete Layer 3 Information"]; +mtms =>> mtmsc [label="RR PAG_RESP"]; +mtms <<= mtmsc [label="MM AUTH_REQ"]; +moms =>> momsc [label="(BSSMAP) Assignment Complete"]; +momgw <<= momsc [label="for RAN: MDCX\nEP-1 CI-2"]; +momsc =>> mncc [label="MNCC_RTP_CREATE\nIP:port-1"]; +momgw =>> momsc [label="for RAN: MDCX OK\nEP-1 CI-2 IP:port-2"]; +mtms =>> mtmsc [label="MM AUTH_RESP"]; +mtms <<= mtmsc [label="(BSSMAP) CIPHER_MODE_COMMAND"]; +mtms =>> mtmsc [label="(BSSMAP) Ciphering Mode Complete"]; +mtms <<= mtmsc [label="(BSSMAP) COMMON_ID"]; +mtmsc note mtmsc [label="CC starts timer T303 (30s)"]; +mtmsc abox mtmsc [label="CC state:\nCALL_PRESENT"]; +mtms <<= mtmsc [label="CC SETUP"]; +mtms =>> mtmsc [label="RR CIPH_M_COMPL"]; +mtms =>> mtmsc [label="CC CALL_CONF"]; +mtmsc note mtmsc [label="CC stops timer T303"]; +mtmsc note mtmsc [label="CC starts timer T310 (30s)"]; +mtmgw <<= mtmsc [label="for CN: CRCX\nrtpbridge/*@msc"]; +mtmsc abox mtmsc [label="CC state:\nMO_TERM_CALL_CONF"]; +mtmsc =>> mncc [label="MNCC_CALL_CONF_IND"]; +mtmsc <<= mncc [label="MNCC_LCHAN_MODIFY"]; +mtmsc note mtmsc [label="CC starts guard timer (180s)"]; +mtmgw =>> mtmsc [label="for CN: CRCX OK\nEP-2 CI-3 IP:port-3"]; +mtmgw <<= mtmsc [label="for RAN: CRCX\nEP-2"]; +mtmgw =>> mtmsc [label="for RAN: CRCX OK\nEP-2 CI-4 IP:port-4"]; +mtms <<= mtmsc [label="(BSSMAP) ASSIGNMENT_COMMAND"]; +mtms =>> mtmsc [label="(BSSMAP) Assignment Complete"]; +mtmgw <<= mtmsc [label="for RAN: MDCX\nEP-2 CI-4"]; +mtmsc =>> mncc [label="MNCC_RTP_CREATE\nIP:port-3"]; +mtmgw =>> mtmsc [label="for RAN: MDCX OK\nEP-2 CI-4 IP:port-4"]; +mtms =>> mtmsc [label="CC ALERTING"]; +mtmsc note mtmsc [label="CC stops timer T310"]; +mtmsc note mtmsc [label="CC starts timer T301 (180s)"]; +mtmsc abox mtmsc [label="CC state:\nCALL_RECEIVED"]; +mtmsc =>> mncc [label="MNCC_ALERT_IND\nIP:port-3"]; +momsc <<= mncc [label="MNCC_ALERT_REQ\nIP:port-3"]; +momsc note momsc [label="CC stops guard timer"]; +momsc note momsc [label="CC starts guard timer (180s)"]; +momsc abox momsc [label="CC state:\nCALL_DELIVERED"]; +momgw <<= momsc [label="for CN: MDCX\nEP-1 CI-1"]; +moms <<= momsc [label="CC ALERTING"]; +momgw =>> momsc [label="for CN: MDCX OK\nEP-1 CI-1 IP:port-1"]; +mtms =>> mtmsc [label="CC CONNECT"]; +mtmsc note mtmsc [label="CC stops timer T301"]; +mtmsc abox mtmsc [label="CC state:\nCONNECT_REQUEST"]; +mtmsc =>> mncc [label="MNCC_SETUP_CNF\nIP:port-3"]; +mtmsc <<= mncc [label="MNCC_SETUP_COMPL_REQ"]; +mtmsc note mtmsc [label="CC stops guard timer"]; +mtmsc note mtmsc [label="CC starts guard timer (180s)"]; +mtmsc abox mtmsc [label="CC state:\nACTIVE"]; +mtmsc note mtmsc [label="CC stops guard timer"]; +mtms <<= mtmsc [label="CC CONNECT_ACK"]; +momsc <<= mncc [label="MNCC_SETUP_RSP\nIP:port-3"]; +momsc note momsc [label="CC stops guard timer"]; +momsc note momsc [label="CC starts guard timer (180s)"]; +momsc note momsc [label="CC starts timer T313 (30s)"]; +momsc abox momsc [label="CC state:\nCONNECT_IND"]; +moms <<= momsc [label="CC CONNECT"]; +mtmgw <<= mtmsc [label="for CN: MDCX\nEP-2 CI-3"]; +mtmgw =>> mtmsc [label="for CN: MDCX OK\nEP-2 CI-3 IP:port-3"]; +moms =>> momsc [label="CC CONNECT_ACK"]; +momsc note momsc [label="CC stops timer T313"]; +momsc abox momsc [label="CC state:\nACTIVE"]; +momsc note momsc [label="CC stops guard timer"]; +momsc =>> mncc [label="MNCC_SETUP_COMPL_IND"]; +moms =>> momsc [label="CC DISCONNECT"]; +momsc abox momsc [label="CC state:\nDISCONNECT_IND"]; +momsc =>> mncc [label="MNCC_DISC_IND"]; +momsc <<= mncc [label="MNCC_REL_REQ"]; +momsc note momsc [label="CC starts guard timer (180s)"]; +momsc note momsc [label="CC starts timer T308 (10s)"]; +momsc abox momsc [label="CC state:\nRELEASE_REQ"]; +moms <<= momsc [label="CC RELEASE"]; +mtmsc <<= mncc [label="MNCC_DISC_REQ"]; +mtmsc note mtmsc [label="CC starts guard timer (180s)"]; +mtmsc note mtmsc [label="CC starts timer T306 (30s)"]; +mtmsc abox mtmsc [label="CC state:\nDISCONNECT_IND"]; +mtms <<= mtmsc [label="CC DISCONNECT"]; +mtms =>> mtmsc [label="CC RELEASE"]; +mtmsc note mtmsc [label="CC stops timer T306"]; +mtms <<= mtmsc [label="CC RELEASE_COMPL"]; +mtmsc =>> mncc [label="MNCC_REL_IND"]; +momsc <<= mncc [label="MNCC_REL_REQ"]; +momsc note momsc [label="CC stops guard timer"]; +momsc note momsc [label="CC starts guard timer (180s)"]; +mtmsc abox mtmsc [label="CC state:\nNULL"]; +mtmsc note mtmsc [label="CC stops guard timer"]; +mtms <<= mtmsc [label="(BSSMAP) CLEAR_COMMAND"]; +mtms =>> mtmsc [label="(BSSMAP) Clear Complete"]; +moms =>> momsc [label="CC RELEASE_COMPL"]; +momsc note momsc [label="CC stops timer T308"]; +momsc =>> mncc [label="MNCC_REL_CNF"]; +momsc abox momsc [label="CC state:\nNULL"]; +momsc note momsc [label="CC stops guard timer"]; +moms <<= momsc [label="(BSSMAP) CLEAR_COMMAND"]; +moms =>> momsc [label="(BSSMAP) Clear Complete"]; +} diff --git a/include/osmocom/Makefile.am b/include/osmocom/Makefile.am index 4d8063711..b07a00459 100644 --- a/include/osmocom/Makefile.am +++ b/include/osmocom/Makefile.am @@ -1,3 +1,4 @@ SUBDIRS = \ msc \ + smpp \ $(NULL) diff --git a/include/osmocom/msc/Makefile.am b/include/osmocom/msc/Makefile.am index 0d7d45ce9..a940056fc 100644 --- a/include/osmocom/msc/Makefile.am +++ b/include/osmocom/msc/Makefile.am @@ -1,6 +1,10 @@ noinst_HEADERS = \ call_leg.h \ cell_id_list.h \ + codec_filter.h \ + codec_mapping.h \ + csd_bs.h \ + csd_filter.h \ db.h \ debug.h \ e_link.h \ @@ -21,6 +25,7 @@ noinst_HEADERS = \ msc_a_remote.h \ msc_common.h \ msc_ho.h \ + msc_vgcs.h \ msc_i.h \ msc_i_remote.h \ msc_roles.h \ @@ -39,15 +44,18 @@ noinst_HEADERS = \ rrlp.h \ rtp_stream.h \ sccp_ran.h \ + sdp_msg.h \ sgs_iface.h \ sgs_server.h \ sgs_vty.h \ signal.h \ silent_call.h \ - smpp.h \ sms_queue.h \ transaction.h \ + transaction_cc.h \ vlr.h \ vlr_sgs.h \ vty.h \ + asci_gcr.h \ + asci_vty.h \ $(NULL) diff --git a/include/osmocom/msc/asci_gcr.h b/include/osmocom/msc/asci_gcr.h new file mode 100644 index 000000000..f2160c1e0 --- /dev/null +++ b/include/osmocom/msc/asci_gcr.h @@ -0,0 +1,55 @@ +/* Group Call Register (GCR) */ +/* + * (C) 2023 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de> + * All Rights Reserved + * + * SPDX-License-Identifier: AGPL-3.0+ + * + * Author: Andreas Eversberg + * + * 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 + +/* Group Call Register */ +struct gcr { + struct llist_head list; + enum trans_type trans_type; + char group_id[9]; + uint16_t timeout; + bool mute_talker; + struct llist_head bss_list; +}; + +struct gcr_bss { + struct llist_head list; + int pc; + struct llist_head cell_list; +}; + +struct gcr_cell { + struct llist_head list; + uint16_t cell_id; +}; + +struct gcr_cell *gcr_add_cell(struct gcr_bss *bss, uint16_t cell_id); +struct gcr_cell *gcr_find_cell(struct gcr_bss *bss, uint16_t cell_id); +void gcr_rm_cell(struct gcr_bss *bss, uint16_t cell_id); +struct gcr_bss *gcr_add_bss(struct gcr *gcr, int pc); +struct gcr_bss *gcr_find_bss(struct gcr *gcr, int pc); +void gcr_rm_bss(struct gcr *gcr, int pc); +struct gcr *gcr_create(struct gsm_network *gsmnet, enum trans_type trans_type, const char *group_id); +void gcr_destroy(struct gcr *gcr); +struct gcr *gcr_by_group_id(struct gsm_network *gsmnet, enum trans_type trans_type, const char *group_id); +struct gcr *gcr_by_callref(struct gsm_network *gsmnet, enum trans_type trans_type, uint32_t callref); diff --git a/include/osmocom/msc/asci_vty.h b/include/osmocom/msc/asci_vty.h new file mode 100644 index 000000000..5fe11f6f5 --- /dev/null +++ b/include/osmocom/msc/asci_vty.h @@ -0,0 +1,25 @@ +/* + * (C) 2023 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de> + * All Rights Reserved + * + * SPDX-License-Identifier: AGPL-3.0+ + * + * Author: Andreas Eversberg + * + * 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 + +void asci_vty_init(struct gsm_network *msc_network); diff --git a/include/osmocom/msc/call_leg.h b/include/osmocom/msc/call_leg.h index d8380f52b..c7d3b9739 100644 --- a/include/osmocom/msc/call_leg.h +++ b/include/osmocom/msc/call_leg.h @@ -12,6 +12,7 @@ struct gsm_network; struct gsm_trans; struct rtp_stream; enum rtp_direction; +struct sdp_audio_codecs; extern struct osmo_tdef g_mgw_tdefs[]; @@ -44,6 +45,8 @@ struct call_leg { /* Prevent events from deallocating for certain release code paths, to prevent use-after-free problems. */ bool deallocating; + + bool ran_peer_supports_osmux; }; enum call_leg_event { @@ -72,7 +75,8 @@ int call_leg_local_bridge(struct call_leg *cl1, uint32_t call_id1, struct gsm_tr int call_leg_ensure_rtp_alloc(struct call_leg *cl, enum rtp_direction dir, uint32_t call_id, struct gsm_trans *for_trans); int call_leg_ensure_ci(struct call_leg *cl, enum rtp_direction dir, uint32_t call_id, struct gsm_trans *for_trans, - const enum mgcp_codecs *codec_if_known, const struct osmo_sockaddr_str *remote_port_if_known); + const struct sdp_audio_codecs *codecs_if_known, + const struct osmo_sockaddr_str *remote_addr_if_known); struct osmo_sockaddr_str *call_leg_local_ip(struct call_leg *cl, enum rtp_direction dir); void call_leg_rtp_stream_gone(struct call_leg *cl, struct rtp_stream *rtps); diff --git a/include/osmocom/msc/cell_id_list.h b/include/osmocom/msc/cell_id_list.h index 83d05f5da..4c0c6eac4 100644 --- a/include/osmocom/msc/cell_id_list.h +++ b/include/osmocom/msc/cell_id_list.h @@ -1,6 +1,6 @@ /* Manage a list of struct gsm0808_cell_id */ /* - * (C) 2019 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de> + * (C) 2019 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de> * All Rights Reserved * * Author: Neels Hofmeyr @@ -16,10 +16,6 @@ * 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. */ #pragma once diff --git a/include/osmocom/msc/codec_filter.h b/include/osmocom/msc/codec_filter.h new file mode 100644 index 000000000..da4a67e04 --- /dev/null +++ b/include/osmocom/msc/codec_filter.h @@ -0,0 +1,57 @@ +/* Filter/overlay codec selections for a voice call, across MS, RAN and CN limitations */ +/* + * (C) 2019-2022 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de> + * All Rights Reserved + * + * Author: Neels Hofmeyr + * + * SPDX-License-Identifier: GPL-2.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 2 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. + */ +#pragma once + +#include <osmocom/gsm/gsm_utils.h> +#include <osmocom/gsm/mncc.h> +#include <osmocom/mgcp_client/mgcp_client.h> + +#include <osmocom/msc/sdp_msg.h> + +struct gsm0808_speech_codec_list; + +/* Combine various codec selections to obtain a resulting set of codecs allowed by all of them. + * Members reflect the different entities/stages that select codecs in a voice call. + * Call codec_filter_run() and obtain the resulting set of codecs in codec_filter.result. */ +struct codec_filter { + /* The fixed set of codecs available on the RAN type, per definition. */ + struct sdp_audio_codecs ran; + /* The codecs advertised by the MS Bearer Capabilities */ + struct sdp_audio_codecs ms; + /* If known, the set of codecs the current RAN cell allows / has available. + * This may not be available if the BSC does not issue this information early enough. + * Should be ignored if empty. */ + struct sdp_audio_codecs bss; + + /* After a channel was assigned, this reflects the chosen codec. */ + struct sdp_audio_codec assignment; +}; + +void codec_filter_set_ran(struct codec_filter *codec_filter, enum osmo_rat_type ran_type); +void codec_filter_set_bss(struct codec_filter *codec_filter, + const struct gsm0808_speech_codec_list *codec_list_bss_supported); +int codec_filter_run(struct codec_filter *codec_filter, struct sdp_msg *result, const struct sdp_msg *remote); + +int codec_filter_to_str_buf(char *buf, size_t buflen, const struct codec_filter *codec_filter, + const struct sdp_msg *result, const struct sdp_msg *remote); +char *codec_filter_to_str_c(void *ctx, const struct codec_filter *codec_filter, const struct sdp_msg *result, + const struct sdp_msg *remote); +const char *codec_filter_to_str(const struct codec_filter *codec_filter, const struct sdp_msg *result, + const struct sdp_msg *remote); diff --git a/include/osmocom/msc/codec_mapping.h b/include/osmocom/msc/codec_mapping.h new file mode 100644 index 000000000..3b502a913 --- /dev/null +++ b/include/osmocom/msc/codec_mapping.h @@ -0,0 +1,65 @@ +/* Routines for translation between codec representations: SDP, CC/BSSMAP variants, MGCP, MNCC */ +#pragma once + +#include <osmocom/gsm/protocol/gsm_04_08.h> +#include <osmocom/gsm/protocol/gsm_08_08.h> +#include <osmocom/mgcp_client/mgcp_client.h> +#include <osmocom/msc/sdp_msg.h> +#include <osmocom/gsm/mncc.h> + +#define NO_MGCP_CODEC 0xffffffff + +extern const struct gsm_mncc_bearer_cap bearer_cap_empty; + +enum codec_frhr { + CODEC_FRHR_NONE = 0, + CODEC_FRHR_FR, + CODEC_FRHR_HR, +}; + +struct codec_mapping { + /* The sdp.payload_type number in a mapping is not necessarily imperative, but may just reflect the usual + * payload type number for a given codec. */ + struct sdp_audio_codec sdp; + /* The id that mgcp_client.h uses for this codec. Must be set in each mapping, because 0 means PCMU. */ + enum mgcp_codecs mgcp; + /* Nr of used entries in speech_ver[] below. */ + unsigned int speech_ver_count; + /* Entries to add to Speech Version lists when this codec is present, if any. */ + enum gsm48_bcap_speech_ver speech_ver[8]; + /* If applicable, one of GSM_TCHF_FRAME, GSM_TCHF_FRAME_EFR, GSM_TCHH_FRAME, GSM_TCH_FRAME_AMR; or zero. */ + uint32_t mncc_payload_msg_type; + /* Set to true if gsm0808_speech_codec below reflects a meaningful value. */ + bool has_gsm0808_speech_codec; + struct gsm0808_speech_codec gsm0808_speech_codec; + /* If applicable, entries to add to Permitted Speech lists when this codec is present; or zero. */ + enum gsm0808_permitted_speech perm_speech; + /* If applicable, indicator whether this codec can work on a GERAN half-rate lchan, or whether full-rate is + * required. Leave zero when this codec does not apply to GERAN. */ + enum codec_frhr frhr; +}; + +const struct codec_mapping *codec_mapping_by_speech_ver(enum gsm48_bcap_speech_ver speech_ver); +const struct codec_mapping *codec_mapping_by_gsm0808_speech_codec_type(enum gsm0808_speech_codec_type sct); +const struct codec_mapping *codec_mapping_by_gsm0808_speech_codec(const struct gsm0808_speech_codec *sc); +const struct codec_mapping *codec_mapping_by_perm_speech(enum gsm0808_permitted_speech perm_speech); +const struct codec_mapping *codec_mapping_by_subtype_name(const char *subtype_name); +const struct codec_mapping *codec_mapping_by_mgcp_codec(enum mgcp_codecs mgcp); + +int bearer_cap_add_speech_ver(struct gsm_mncc_bearer_cap *bearer_cap, enum gsm48_bcap_speech_ver speech_ver); +int sdp_audio_codec_add_to_bearer_cap(struct gsm_mncc_bearer_cap *bearer_cap, const struct sdp_audio_codec *codec); +int sdp_audio_codecs_to_bearer_cap(struct gsm_mncc_bearer_cap *bearer_cap, const struct sdp_audio_codecs *ac); +int bearer_cap_set_radio(struct gsm_mncc_bearer_cap *bearer_cap); + +struct sdp_audio_codec *sdp_audio_codecs_add_speech_ver(struct sdp_audio_codecs *ac, + enum gsm48_bcap_speech_ver speech_ver); +struct sdp_audio_codec *sdp_audio_codecs_add_mgcp_codec(struct sdp_audio_codecs *ac, enum mgcp_codecs mgcp_codec); +void sdp_audio_codecs_from_bearer_cap(struct sdp_audio_codecs *ac, const struct gsm_mncc_bearer_cap *bc); + +int sdp_audio_codec_to_speech_codec_list(struct gsm0808_speech_codec_list *scl, const struct sdp_audio_codec *codec); +void sdp_audio_codecs_to_speech_codec_list(struct gsm0808_speech_codec_list *cl, const struct sdp_audio_codecs *ac); +void sdp_audio_codecs_from_speech_codec_list(struct sdp_audio_codecs *ac, const struct gsm0808_speech_codec_list *cl); + +int sdp_audio_codecs_to_gsm0808_channel_type(struct gsm0808_channel_type *ct, const struct sdp_audio_codecs *ac); + +enum mgcp_codecs sdp_audio_codec_to_mgcp_codec(const struct sdp_audio_codec *codec); diff --git a/include/osmocom/msc/csd_bs.h b/include/osmocom/msc/csd_bs.h new file mode 100644 index 000000000..eee869266 --- /dev/null +++ b/include/osmocom/msc/csd_bs.h @@ -0,0 +1,54 @@ +/* 3GPP TS 122.002 Bearer Services */ +#pragma once + +#include <osmocom/gsm/mncc.h> +#include <osmocom/gsm/protocol/gsm_08_08.h> + +enum csd_bs { + CSD_BS_NONE, + + /* 3.1.1.1.2 */ + CSD_BS_21_T_V110_0k3, + CSD_BS_22_T_V110_1k2, + CSD_BS_24_T_V110_2k4, + CSD_BS_25_T_V110_4k8, + CSD_BS_26_T_V110_9k6, + + /* 3.1.1.2.2 */ + CSD_BS_21_NT_V110_0k3, + CSD_BS_22_NT_V110_1k2, + CSD_BS_24_NT_V110_2k4, + CSD_BS_25_NT_V110_4k8, + CSD_BS_26_NT_V110_9k6, + + /* 3.1.2.1.2 */ + CSD_BS_31_T_V110_1k2, + CSD_BS_32_T_V110_2k4, + CSD_BS_33_T_V110_4k8, + CSD_BS_34_T_V110_9k6, + + CSD_BS_MAX, +}; + +struct csd_bs_list { + unsigned int count; + enum csd_bs bs[CSD_BS_MAX]; +}; + +void csd_bs_list_add_bs(struct csd_bs_list *list, enum csd_bs bs); +int csd_bs_list_to_bearer_cap(struct gsm_mncc_bearer_cap *cap, const struct csd_bs_list *list); +void csd_bs_list_from_bearer_cap(struct csd_bs_list *list, const struct gsm_mncc_bearer_cap *cap); + +int csd_bs_to_str_buf(char *buf, size_t buflen, enum csd_bs bs); +char *csd_bs_to_str_c(void *ctx, enum csd_bs bs); +const char *csd_bs_to_str(enum csd_bs bs); + +int csd_bs_list_to_str_buf(char *buf, size_t buflen, const struct csd_bs_list *list); +char *csd_bs_list_to_str_c(void *ctx, const struct csd_bs_list *list); +const char *csd_bs_list_to_str(const struct csd_bs_list *list); + +void csd_bs_list_add_bs(struct csd_bs_list *list, enum csd_bs bs); +void csd_bs_list_remove(struct csd_bs_list *list, enum csd_bs bs); +void csd_bs_list_intersection(struct csd_bs_list *dest, const struct csd_bs_list *other); + +int csd_bs_list_to_gsm0808_channel_type(struct gsm0808_channel_type *ct, const struct csd_bs_list *list); diff --git a/include/osmocom/msc/csd_filter.h b/include/osmocom/msc/csd_filter.h new file mode 100644 index 000000000..51ffff706 --- /dev/null +++ b/include/osmocom/msc/csd_filter.h @@ -0,0 +1,53 @@ +/* Filter/overlay data rates for CSD, across MS, RAN and CN limitations */ +/* + * (C) 2023 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de> + * All Rights Reserved + * + * Author: Oliver Smith + * + * SPDX-License-Identifier: GPL-2.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 2 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. + */ +#pragma once + +#include <osmocom/gsm/gsm_utils.h> +#include <osmocom/gsm/mncc.h> +#include <osmocom/mgcp_client/mgcp_client.h> + +#include <osmocom/msc/csd_bs.h> +#include <osmocom/msc/sdp_msg.h> + +/* Combine various data rate selections to obtain a resulting set allowed by + * all of them. Members reflect the different entities/stages that select data + * rates in CSD. Call csd_filter_run() and obtain the resulting set in + * csd_filter.result. */ +struct csd_filter { + /* The fixed set available on the RAN type, per definition. */ + struct csd_bs_list ran; + /* The services advertised by the MS Bearer Capabilities */ + struct csd_bs_list ms; + /* If known, the set the current RAN cell allows / has available. This + * may not be available if the BSC does not issue this information + * early enough. Should be ignored if empty. */ + struct csd_bs_list bss; + + /* After a channel was assigned, this reflects the chosen BS. */ + enum csd_bs assignment; +}; + +void csd_filter_set_ran(struct csd_filter *filter, enum osmo_rat_type ran_type); +int csd_filter_run(struct csd_filter *filter, struct sdp_msg *result, const struct sdp_msg *remote); + +int csd_filter_to_str_buf(char *buf, size_t buflen, const struct csd_filter *filter, + const struct sdp_msg *result, const struct sdp_msg *remote); +char *csd_filter_to_str_c(void *ctx, const struct csd_filter *filter, const struct sdp_msg *result, const struct sdp_msg *remote); +const char *csd_filter_to_str(const struct csd_filter *filter, const struct sdp_msg *result, const struct sdp_msg *remote); diff --git a/include/osmocom/msc/db.h b/include/osmocom/msc/db.h index d9463a684..fc1781bd6 100644 --- a/include/osmocom/msc/db.h +++ b/include/osmocom/msc/db.h @@ -1,5 +1,6 @@ /* (C) 2008 by Jan Luebbe <jluebbe@debian.org> * (C) 2009 by Holger Hans Peter Freyther <zecke@selfish.org> + * (C) 2022 by Harald Welte <laforge@osmocom.org> * All Rights Reserved * * This program is free software; you can redistribute it and/or modify @@ -30,7 +31,7 @@ struct gsm_network; struct gsm_sms; /* one time initialisation */ -int db_init(const char *name); +int db_init(void *ctx, const char *fname, bool enable_sqlite_logging); int db_prepare(void); int db_fini(void); @@ -39,12 +40,12 @@ int db_sms_store(struct gsm_sms *sms); struct gsm_sms *db_sms_get(struct gsm_network *net, unsigned long long id); struct gsm_sms *db_sms_get_next_unsent(struct gsm_network *net, unsigned long long min_sms_id, - unsigned int max_failed); + int max_failed); struct gsm_sms *db_sms_get_next_unsent_rr_msisdn(struct gsm_network *net, const char *last_msisdn, - unsigned int max_failed); + int max_failed); struct gsm_sms *db_sms_get_unsent_for_subscr(struct vlr_subscr *vsub, - unsigned int max_failed); + int max_failed); int db_sms_mark_delivered(struct gsm_sms *sms); int db_sms_inc_deliver_attempts(struct gsm_sms *sms); int db_sms_delete_by_msisdn(const char *msisdn); diff --git a/include/osmocom/msc/debug.h b/include/osmocom/msc/debug.h index 3347e20d4..9925a3cb0 100644 --- a/include/osmocom/msc/debug.h +++ b/include/osmocom/msc/debug.h @@ -6,8 +6,11 @@ enum { DRLL, DCC, + DBCC, + DGCC, DMM, DRR, + DLCLS, DMNCC, DPAG, DMSC, @@ -23,5 +26,6 @@ enum { DBSSAP, DSGS, DSS, + DASCI, Debug_LastEntry, }; diff --git a/include/osmocom/msc/gsm_04_08.h b/include/osmocom/msc/gsm_04_08.h index 661da42b3..cd5074eb6 100644 --- a/include/osmocom/msc/gsm_04_08.h +++ b/include/osmocom/msc/gsm_04_08.h @@ -45,6 +45,11 @@ int gsm48_send_rr_app_info(struct msc_a *msc_a, uint8_t apdu_id, uint8_t apdu_le int gsm48_send_rr_ass_cmd(struct gsm_lchan *dest_lchan, struct gsm_lchan *lchan, uint8_t power_class); int gsm48_send_ho_cmd(struct gsm_lchan *old_lchan, struct gsm_lchan *new_lchan, uint8_t power_command, uint8_t ho_ref); +void gsm48_cc_rx_setup_cn_local_rtp_port_known(struct gsm_trans *trans); +void gsm48_cc_rx_call_conf_cn_local_rtp_port_known(struct gsm_trans *trans); +int cc_on_cn_local_rtp_port_known(struct gsm_trans *trans); +int cc_on_assignment_done(struct gsm_trans *trans); + int mncc_tx_to_cc(struct gsm_network *net, void *arg); /* convert a ASCII phone number to call-control BCD */ @@ -54,8 +59,6 @@ int decode_bcd_number(char *output, int output_len, const uint8_t *bcd_lv, int h_len); int send_siemens_mrpci(struct gsm_lchan *lchan, uint8_t *classmark2_lv); -int gsm48_extract_mi(uint8_t *classmark2, int length, char *mi_string, uint8_t *mi_type); -int gsm48_paging_extract_mi(struct gsm48_pag_resp *pag, int length, char *mi_string, uint8_t *mi_type); int gsm48_lchan_modify(struct gsm_lchan *lchan, uint8_t lchan_mode); int gsm48_rx_rr_modif_ack(struct msgb *msg); diff --git a/include/osmocom/msc/gsm_04_11.h b/include/osmocom/msc/gsm_04_11.h index be8bff3c3..17a31ecdd 100644 --- a/include/osmocom/msc/gsm_04_11.h +++ b/include/osmocom/msc/gsm_04_11.h @@ -11,24 +11,6 @@ struct msc_a; #define UM_SAPI_SMS 3 /* See GSM 04.05/04.06 */ -/* SMS deliver PDU */ -struct sms_deliver { - uint8_t mti:2; /* message type indicator */ - uint8_t mms:1; /* more messages to send */ - uint8_t rp:1; /* reply path */ - uint8_t udhi:1; /* user data header indicator */ - uint8_t sri:1; /* status report indication */ - uint8_t *orig_addr; /* originating address */ - uint8_t pid; /* protocol identifier */ - uint8_t dcs; /* data coding scheme */ - /* service centre time stamp */ - uint8_t ud_len; /* user data length */ - uint8_t *user_data; /* user data */ - - uint8_t msg_ref; /* message reference */ - uint8_t *smsc; -}; - struct gsm_network; struct msgb; @@ -45,7 +27,9 @@ int gsm411_send_sms(struct gsm_network *net, struct gsm_sms *sms); int gsm411_send_rp_data(struct gsm_network *net, struct vlr_subscr *vsub, size_t sm_rp_oa_len, const uint8_t *sm_rp_oa, - size_t sm_rp_ud_len, const uint8_t *sm_rp_ud); + size_t sm_rp_ud_len, const uint8_t *sm_rp_ud, + bool sm_rp_mmts_ind, const uint8_t *gsup_source_name, + size_t gsup_source_name_len); void gsm411_sapi_n_reject(struct msc_a *msc_a); diff --git a/include/osmocom/msc/gsm_data.h b/include/osmocom/msc/gsm_data.h index f6e3ed99f..119f093db 100644 --- a/include/osmocom/msc/gsm_data.h +++ b/include/osmocom/msc/gsm_data.h @@ -10,13 +10,17 @@ #include <osmocom/core/rate_ctr.h> #include <osmocom/core/select.h> #include <osmocom/core/stats.h> +#include <osmocom/core/stat_item.h> #include <osmocom/gsm/gsm48.h> #include <osmocom/crypt/auth.h> +#include <osmocom/crypt/utran_cipher.h> #include <osmocom/mgcp_client/mgcp_client.h> +#include <osmocom/mgcp_client/mgcp_client_pool.h> #include <osmocom/msc/msc_common.h> #include <osmocom/msc/neighbor_ident.h> +#include <osmocom/msc/sms_queue.h> #include "gsm_data_shared.h" #include "osmux.h" @@ -29,6 +33,7 @@ struct vlr_instance; struct vlr_subscr; struct gsup_client_mux; +#define SMS_DEFAULT_DB_FILE_PATH "sms.db" #define tmsi_from_string(str) strtoul(str, NULL, 10) enum { @@ -42,6 +47,8 @@ enum { MSC_CTR_CM_SERVICE_REQUEST_ACCEPTED, MSC_CTR_PAGING_RESP_REJECTED, MSC_CTR_PAGING_RESP_ACCEPTED, + MSC_CTR_CM_RE_ESTABLISH_REQ_REJECTED, + MSC_CTR_CM_RE_ESTABLISH_REQ_ACCEPTED, MSC_CTR_SMS_SUBMITTED, MSC_CTR_SMS_NO_RECEIVER, MSC_CTR_SMS_DELIVERED, @@ -64,30 +71,33 @@ enum { }; static const struct rate_ctr_desc msc_ctr_description[] = { - [MSC_CTR_LOC_UPDATE_TYPE_ATTACH] = {"loc_update_type:attach", "Received location update imsi attach requests."}, - [MSC_CTR_LOC_UPDATE_TYPE_NORMAL] = {"loc_update_type:normal", "Received location update normal requests."}, - [MSC_CTR_LOC_UPDATE_TYPE_PERIODIC] = {"loc_update_type:periodic", "Received location update periodic requests."}, - [MSC_CTR_LOC_UPDATE_TYPE_DETACH] = {"loc_update_type:detach", "Received location update detach indication."}, - [MSC_CTR_LOC_UPDATE_FAILED] = {"loc_update_resp:failed", "Rejected location updates."}, - [MSC_CTR_LOC_UPDATE_COMPLETED] = {"loc_update_resp:completed", "Successful location updates."}, - [MSC_CTR_CM_SERVICE_REQUEST_REJECTED] = {"cm_service_request:rejected", "Rejected CM Service Request."}, - [MSC_CTR_CM_SERVICE_REQUEST_ACCEPTED] = {"cm_service_request:accepted", "Accepted CM Service Request."}, - [MSC_CTR_PAGING_RESP_REJECTED] = {"paging_resp:rejected", "Rejected Paging Response."}, - [MSC_CTR_PAGING_RESP_ACCEPTED] = {"paging_resp:accepted", "Accepted Paging Response."}, - [MSC_CTR_SMS_SUBMITTED] = {"sms:submitted", "Received a RPDU from a MS (MO)."}, - [MSC_CTR_SMS_NO_RECEIVER] = {"sms:no_receiver", "Counts SMS which couldn't routed because no receiver found."}, - [MSC_CTR_SMS_DELIVERED] = {"sms:delivered", "Global SMS Deliver attempts."}, - [MSC_CTR_SMS_RP_ERR_MEM] = {"sms:rp_err_mem", "CAUSE_MT_MEM_EXCEEDED errors of MS responses on a sms deliver attempt."}, - [MSC_CTR_SMS_RP_ERR_OTHER] = {"sms:rp_err_other", "Other error of MS responses on a sms delive attempt."}, - [MSC_CTR_SMS_DELIVER_UNKNOWN_ERROR] = {"sms:deliver_unknown_error", "Unknown error occured during sms delivery."}, - /* FIXME: count also sms delivered */ - [MSC_CTR_CALL_MO_SETUP] = {"call:mo_setup", "Received setup requests from a MS to init a MO call."}, - [MSC_CTR_CALL_MO_CONNECT_ACK] = {"call:mo_connect_ack", "Received a connect ack from MS of a MO call. Call is now succesful connected up."}, - [MSC_CTR_CALL_MT_SETUP] = {"call:mt_setup", "Sent setup requests to the MS (MT)."}, - [MSC_CTR_CALL_MT_CONNECT] = {"call:mt_connect", "Sent a connect to the MS (MT)."}, - [MSC_CTR_CALL_ACTIVE] = {"call:active", "Count total amount of calls that ever reached active state."}, - [MSC_CTR_CALL_COMPLETE] = {"call:complete", "Count total amount of calls which got terminated by disconnect req or ind after reaching active state."}, - [MSC_CTR_CALL_INCOMPLETE] = {"call:incomplete", "Count total amount of call which got terminated by any other reason after reaching active state."}, + [MSC_CTR_LOC_UPDATE_TYPE_ATTACH] = {"loc_update_type:attach", "Received Location Update (IMSI Attach) requests."}, + [MSC_CTR_LOC_UPDATE_TYPE_NORMAL] = {"loc_update_type:normal", "Received Location Update (LAC change) requests."}, + [MSC_CTR_LOC_UPDATE_TYPE_PERIODIC] = {"loc_update_type:periodic", "Received (periodic) Location Update requests."}, + [MSC_CTR_LOC_UPDATE_TYPE_DETACH] = {"loc_update_type:detach", "Received IMSI Detach indications."}, + [MSC_CTR_LOC_UPDATE_FAILED] = {"loc_update_resp:failed", "Rejected Location Update requests."}, + [MSC_CTR_LOC_UPDATE_COMPLETED] = {"loc_update_resp:completed", "Successful Location Update procedures."}, + [MSC_CTR_CM_SERVICE_REQUEST_REJECTED] = {"cm_service_request:rejected", "Rejected CM Service Requests."}, + [MSC_CTR_CM_SERVICE_REQUEST_ACCEPTED] = {"cm_service_request:accepted", "Accepted CM Service Requests."}, + [MSC_CTR_PAGING_RESP_REJECTED] = {"paging_resp:rejected", "Rejected Paging Responses."}, + [MSC_CTR_PAGING_RESP_ACCEPTED] = {"paging_resp:accepted", "Accepted Paging Responses."}, + [MSC_CTR_CM_RE_ESTABLISH_REQ_REJECTED] = {"cm_re_establish_request:rejected", "Rejected CM Re-Establishing Requests."}, + [MSC_CTR_CM_RE_ESTABLISH_REQ_ACCEPTED] = {"cm_re_establish_request:accepted", "Accepted CM Re-Establishing Requests."}, + [MSC_CTR_SMS_SUBMITTED] = {"sms:submitted", "Total MO SMS received from the MS."}, + [MSC_CTR_SMS_NO_RECEIVER] = {"sms:no_receiver", "Failed MO SMS delivery attempts (no receiver found)."}, + [MSC_CTR_SMS_DELIVER_UNKNOWN_ERROR] = {"sms:deliver_unknown_error", "Failed MO SMS delivery attempts (other reason)."}, + /* FIXME: "sms:delivered" should actually count number of _successfully_ delivered MT SMS. + * The current description reflects its current (errorneous) behaviour. */ + [MSC_CTR_SMS_DELIVERED] = {"sms:delivered", "Total MT SMS delivery attempts."}, + [MSC_CTR_SMS_RP_ERR_MEM] = {"sms:rp_err_mem", "Failed MT SMS delivery attempts (no memory)."}, + [MSC_CTR_SMS_RP_ERR_OTHER] = {"sms:rp_err_other", "Failed MT SMS delivery attempts (other reason)."}, + [MSC_CTR_CALL_MO_SETUP] = {"call:mo_setup", "Received MO SETUP messages (MO call establishment)."}, + [MSC_CTR_CALL_MO_CONNECT_ACK] = {"call:mo_connect_ack", "Received MO CONNECT messages (MO call establishment)."}, + [MSC_CTR_CALL_MT_SETUP] = {"call:mt_setup", "Sent MT SETUP messages (MT call establishment)."}, + [MSC_CTR_CALL_MT_CONNECT] = {"call:mt_connect", "Sent MT CONNECT messages (MT call establishment)."}, + [MSC_CTR_CALL_ACTIVE] = {"call:active", "Calls that ever reached the active state."}, + [MSC_CTR_CALL_COMPLETE] = {"call:complete", "Calls terminated by DISCONNECT message after reaching the active state."}, + [MSC_CTR_CALL_INCOMPLETE] = {"call:incomplete", "Calls terminated by any other reason after reaching the active state."}, [MSC_CTR_NC_SS_MO_REQUESTS] = {"nc_ss:mo_requests", "Received MS-initiated call independent SS/USSD requests."}, [MSC_CTR_NC_SS_MO_ESTABLISHED] = {"nc_ss:mo_established", "Established MS-initiated call independent SS/USSD sessions."}, [MSC_CTR_NC_SS_MT_REQUESTS] = {"nc_ss:mt_requests", "Received network-initiated call independent SS/USSD requests."}, @@ -96,6 +106,11 @@ static const struct rate_ctr_desc msc_ctr_description[] = { [MSC_CTR_BSSMAP_CIPHER_MODE_COMPLETE] = {"bssmap:cipher_mode_complete", "Number of CIPHER MODE COMPLETE messages processed by BSSMAP layer"}, }; +enum { + MSC_STAT_ACTIVE_CALLS, + MSC_STAT_ACTIVE_NC_SS, +}; + static const struct rate_ctr_group_desc msc_ctrg_desc = { "msc", "mobile switching center", @@ -104,6 +119,19 @@ static const struct rate_ctr_group_desc msc_ctrg_desc = { msc_ctr_description, }; +static const struct osmo_stat_item_desc msc_stat_item_description[] = { + [MSC_STAT_ACTIVE_CALLS] = { "msc.active_calls", "Currently active calls " , OSMO_STAT_ITEM_NO_UNIT, 4, 0}, + [MSC_STAT_ACTIVE_NC_SS] = { "msc.active_nc_ss", "Currently active SS/USSD sessions", OSMO_STAT_ITEM_NO_UNIT, 4, 0}, +}; + +static const struct osmo_stat_item_group_desc msc_statg_desc = { + "net", + "network statistics", + OSMO_STATS_CLASS_GLOBAL, + ARRAY_SIZE(msc_stat_item_description), + msc_stat_item_description, +}; + #define MSC_PAGING_RESPONSE_TIMER_DEFAULT 10 struct gsm_tz { @@ -130,9 +158,11 @@ struct gsm_network { bool authentication_required; int send_mm_info; + /* bit-mask of permitted encryption algorithms. LSB=UEA0, MSB=UEA7 */ + uint8_t uea_encryption_mask; + struct rate_ctr_group *msc_ctrs; - struct osmo_counter *active_calls; - struct osmo_counter *active_nc_ss; + struct osmo_stat_item_group *statg; /* layer 4 */ char *mncc_sock_path; @@ -147,8 +177,6 @@ struct gsm_network { */ struct llist_head trans_list; - unsigned int paging_response_timer; - /* Radio Resource Location Protocol (TS 04.31) */ struct { enum rrlp_mode mode; @@ -181,9 +209,6 @@ struct gsm_network { struct vlr_instance *vlr; - /* Periodic location update default value */ - uint8_t t3212; - /* Global MNCC guard timer value */ int mncc_guard_timeout; /* Global guard timer value for NCSS sessions */ @@ -191,8 +216,10 @@ struct gsm_network { struct { struct osmo_tdef *tdefs; - struct mgcp_client_conf conf; - struct mgcp_client *client; + struct mgcp_client_conf *conf; + /* MGW pool, also includes the single MGCP client as fallback if no + * pool is configured. */ + struct mgcp_client_pool *mgw_pool; } mgw; struct { @@ -210,10 +237,6 @@ struct gsm_network { struct sccp_ran_inst *sri; } a; - /* A list of neighbor BSCs. This list is defined statically via VTY and does not - * necessarily correspond to BSCs attached to the A interface at a given moment. */ - struct neighbor_ident_list *neighbor_list; - struct { /* MSISDN to which to route MO emergency calls */ char *route_to_msisdn; @@ -225,6 +248,8 @@ struct gsm_network { * and will be of the form 'MSC-00-00-00-00-00-00' */ char *msc_ipa_name; + /* A list of neighbor BSCs. This list is defined statically via VTY and does not + * necessarily correspond to BSCs attached to the A interface at a given moment. */ struct llist_head neighbor_ident_list; struct { @@ -235,9 +260,24 @@ struct gsm_network { /* Whether we want to use Osmux against BSCs. Controlled via VTY */ enum osmux_usage use_osmux; + + /* Whether to use call waiting on the network */ + bool call_waiting; + + /* Whether to use lcls on the network */ + bool lcls_permitted; + + /* SMS queue config parameters */ + struct sms_queue_config *sms_queue_cfg; + + /* ASCI feature support */ + struct { + bool enable; + struct llist_head gcr_lists; + } asci; }; -struct osmo_esme; +struct smpp_esme; enum gsm_sms_source_id { SMS_SOURCE_UNKNOWN = 0, @@ -266,7 +306,7 @@ struct gsm_sms { } gsm411; struct { - struct osmo_esme *esme; + struct smpp_esme *esme; uint32_t sequence_nr; int transaction_mode; char msg_id[16]; diff --git a/include/osmocom/msc/gsup_client_mux.h b/include/osmocom/msc/gsup_client_mux.h index 07f17c260..501b81dbe 100644 --- a/include/osmocom/msc/gsup_client_mux.h +++ b/include/osmocom/msc/gsup_client_mux.h @@ -28,6 +28,7 @@ int gsup_client_mux_start(struct gsup_client_mux *gcm, const char *gsup_server_a struct ipaccess_unit *ipa_dev); int gsup_client_mux_tx(struct gsup_client_mux *gcm, const struct osmo_gsup_message *gsup_msg); +void gsup_client_mux_tx_set_source(const struct gsup_client_mux *gcm, struct osmo_gsup_message *gsup_msg); void gsup_client_mux_tx_error_reply(struct gsup_client_mux *gcm, const struct osmo_gsup_message *gsup_orig, enum gsm48_gmm_cause cause); diff --git a/include/osmocom/msc/mncc.h b/include/osmocom/msc/mncc.h index 28ee9b339..d258630c5 100644 --- a/include/osmocom/msc/mncc.h +++ b/include/osmocom/msc/mncc.h @@ -28,6 +28,7 @@ #include <osmocom/gsm/mncc.h> #include <stdint.h> +#include <netinet/in.h> struct gsm_network; struct msgb; @@ -53,7 +54,7 @@ struct gsm_call { #define MNCC_SETUP_CNF 0x0104 #define MNCC_SETUP_COMPL_REQ 0x0105 #define MNCC_SETUP_COMPL_IND 0x0106 -/* MNCC_REJ_* is perfomed via MNCC_REL_* */ +/* MNCC_REJ_* is performed via MNCC_REL_* */ #define MNCC_CALL_CONF_IND 0x0107 #define MNCC_CALL_PROC_REQ 0x0108 #define MNCC_PROGRESS_REQ 0x0109 @@ -123,6 +124,15 @@ struct gsm_call { #define MNCC_F_CCCAP 0x0800 #define MNCC_F_KEYPAD 0x1000 #define MNCC_F_SIGNAL 0x2000 +#define MNCC_F_GCR 0x4000 +#define MNCC_F_HIGHL_COMPAT 0x8000 +#define MNCC_F_LOWL_COMPAT 0x10000 + +/* UPDATEME when adding new MNCC_F_* entries above */ +#define MNCC_F_ALL 0x1ffff + +#define GSM_MAX_LOWL_COMPAT 16 /* (18 with TLV) */ +#define GSM_MAX_HIGHL_COMPAT 3 /* (5 with TLV) */ struct gsm_mncc { /* context based information */ @@ -132,7 +142,7 @@ struct gsm_mncc { /* which fields are present */ uint32_t fields; - /* data derived informations (MNCC_F_ based) */ + /* data derived information (MNCC_F_ based) */ struct gsm_mncc_bearer_cap bearer_cap; struct gsm_mncc_number called; struct gsm_mncc_number calling; @@ -159,6 +169,26 @@ struct gsm_mncc { unsigned char lchan_type; unsigned char lchan_mode; + + /* Global Call Reference (encoded as per 3GPP TS 29.205) */ + uint8_t gcr[16]; + + /* A buffer to contain SDP ('\0' terminated) */ + char sdp[1024]; + + /* Additional information that extends current socket interface version. */ + + /* The content requals of Low Layer compatibility IE, described in 3GPP TS 24.008 §10.5.4.18. */ + struct gsm_mncc_lowl_compat { + uint8_t len; + uint8_t compat[GSM_MAX_LOWL_COMPAT]; + } llc; + + /* The content requals of High Layer compatibility IE, described in 3GPP TS 24.008 §10.5.4.16. */ + struct gsm_mncc_highl_compat { + uint8_t len; + uint8_t compat[GSM_MAX_HIGHL_COMPAT]; + } hlc; }; struct gsm_data_frame { @@ -167,7 +197,7 @@ struct gsm_data_frame { unsigned char data[0]; }; -#define MNCC_SOCK_VERSION 5 +#define MNCC_SOCK_VERSION 8 struct gsm_mncc_hello { uint32_t msg_type; uint32_t version; @@ -186,10 +216,10 @@ struct gsm_mncc_hello { struct gsm_mncc_rtp { uint32_t msg_type; uint32_t callref; - uint32_t ip; - uint16_t port; + struct sockaddr_storage addr; uint32_t payload_type; uint32_t payload_msg_type; + char sdp[1024]; }; struct gsm_mncc_bridge { @@ -208,7 +238,6 @@ union mncc_msg { const char *get_mncc_name(int value); void mncc_set_cause(struct gsm_mncc *data, int loc, int val); -void cc_tx_to_mncc(struct gsm_network *net, struct msgb *msg); /* input from CC code into mncc_builtin */ int int_mncc_recv(struct gsm_network *net, struct msgb *msg); @@ -226,6 +255,7 @@ int mncc_sock_init(struct gsm_network *net, const char *sock_path); || msg_type == GSM_BAD_FRAME) int mncc_prim_check(const struct gsm_mncc *mncc_prim, unsigned int len); +int mncc_check_sdp_termination(const char *label, const struct gsm_mncc *mncc, unsigned int len, const char *sdp); int mncc_bearer_cap_to_channel_type(struct gsm0808_channel_type *ct, const struct gsm_mncc_bearer_cap *bc); diff --git a/include/osmocom/msc/mncc_call.h b/include/osmocom/msc/mncc_call.h index ad0f0f841..084edd5e1 100644 --- a/include/osmocom/msc/mncc_call.h +++ b/include/osmocom/msc/mncc_call.h @@ -1,6 +1,6 @@ /* Handle an MNCC managed call (external MNCC). */ /* - * (C) 2019 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de> + * (C) 2019 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de> * All Rights Reserved * * SPDX-License-Identifier: AGPL-3.0+ @@ -22,6 +22,7 @@ */ #pragma once +#include <osmocom/mgcp_client/mgcp_client.h> #include <osmocom/msc/mncc.h> #include <osmocom/msc/mncc_call.h> @@ -138,3 +139,5 @@ int mncc_call_tx_msgt(struct mncc_call *mncc_call, uint32_t msg_type); struct mncc_call *mncc_call_find_by_callref(uint32_t callref); void mncc_call_release(struct mncc_call *mncc_call); + +uint32_t mgcp_codec_to_mncc_payload_msg_type(enum mgcp_codecs codec); diff --git a/include/osmocom/msc/msc_a.h b/include/osmocom/msc/msc_a.h index c732695a1..4099d4cd2 100644 --- a/include/osmocom/msc/msc_a.h +++ b/include/osmocom/msc/msc_a.h @@ -1,6 +1,6 @@ /* MSC-A role: main subscriber management */ /* - * (C) 2019 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de> + * (C) 2019 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de> * All Rights Reserved * * SPDX-License-Identifier: AGPL-3.0+ @@ -37,14 +37,21 @@ #include <osmocom/msc/neighbor_ident.h> struct ran_infra; +struct vgcs_bss; +struct vgcs_bss_cell; #define MSC_A_USE_LOCATION_UPDATING "lu" #define MSC_A_USE_CM_SERVICE_CC "cm_service_cc" +#define MSC_A_USE_CM_SERVICE_GCC "cm_service_gcc" +#define MSC_A_USE_CM_SERVICE_BCC "cm_service_bcc" #define MSC_A_USE_CM_SERVICE_SMS "cm_service_sms" #define MSC_A_USE_CM_SERVICE_SS "cm_service_ss" #define MSC_A_USE_PAGING_RESPONSE "paging-response" +#define MSC_A_USE_GCC "gcc" +#define MSC_A_USE_BCC "bcc" #define MSC_A_USE_CC "cc" #define MSC_A_USE_SMS "sms" +#define MSC_A_USE_SMS_MMTS "sms_mmts" #define MSC_A_USE_NC_SS "nc_ss" #define MSC_A_USE_SILENT_CALL "silent_call" @@ -98,6 +105,9 @@ struct msc_a { /* After Ciphering Mode Complete on GERAN, this reflects the chosen ciphering algorithm and key */ struct geran_encr geran_encr; + /* Type of MI requested in MM Identity Request */ + uint8_t mm_id_req_type; + /* N(SD) expected in the received frame, per flow (TS 24.007 11.2.3.2.3.2.2) */ uint8_t n_sd_next[4]; @@ -117,6 +127,9 @@ struct msc_a { * \-------RTP--> (ISUP) <--RTP--> <--RTP--> */ struct { + /* Codec List (BSS Supported) as received during Complete Layer 3 Information */ + struct gsm0808_speech_codec_list compl_l3_codec_list_bss_supported; + /* All of the RTP stream handling */ struct call_leg *call_leg; struct mncc_call *mncc_forwarding_to_remote_ran; @@ -176,6 +189,8 @@ struct msc_a *msc_a_for_vsub(const struct vlr_subscr *vsub, bool valid_conn_only void msc_a_pending_cm_service_req_add(struct msc_a *msc_a, enum osmo_cm_service_type type); unsigned int msc_a_pending_cm_service_req_count(struct msc_a *msc_a, enum osmo_cm_service_type type); void msc_a_pending_cm_service_req_del(struct msc_a *msc_a, enum osmo_cm_service_type type); +bool msc_a_is_ciphering_to_be_attempted(const struct msc_a *msc_a); +bool msc_a_is_ciphering_required(const struct msc_a *msc_a); #define msc_a_ran_down(A,B,C) \ _msc_a_ran_down(A,B,C, __FILE__, __LINE__) @@ -199,13 +214,18 @@ void msc_a_up_ciph_res(struct msc_a *msc_a, bool success, const char *imeisv); bool msc_a_is_accepted(const struct msc_a *msc_a); bool msc_a_is_establishing_auth_ciph(const struct msc_a *msc_a); +int msc_a_ensure_cn_local_rtp(struct msc_a *msc_a, struct gsm_trans *cc_trans); int msc_a_try_call_assignment(struct gsm_trans *cc_trans); +void msc_a_tx_assignment_cmd(struct msc_a *msc_a); -const char *msc_a_cm_service_type_to_use(enum osmo_cm_service_type cm_service_type); +const char *msc_a_cm_service_type_to_use(struct msc_a *msc_a, enum osmo_cm_service_type cm_service_type); void msc_a_release_cn(struct msc_a *msc_a); void msc_a_release_mo(struct msc_a *msc_a, enum gsm48_gsm_cause gsm_cause); +int msc_a_rx_vgcs_bss(struct vgcs_bss *bss, struct ran_conn *from_conn, struct msgb *msg); +int msc_a_rx_vgcs_cell(struct vgcs_bss_cell *cell, struct ran_conn *from_conn, struct msgb *msg); + int msc_a_ran_decode_cb(struct osmo_fsm_inst *msc_a_fi, void *data, const struct ran_msg *msg); int msc_a_vlr_set_cipher_mode(void *_msc_a, bool umts_aka, bool retrieve_imeisv); diff --git a/include/osmocom/msc/msc_common.h b/include/osmocom/msc/msc_common.h index 78337f764..f3fb0e07a 100644 --- a/include/osmocom/msc/msc_common.h +++ b/include/osmocom/msc/msc_common.h @@ -1,5 +1,7 @@ #pragma once +#include <osmocom/core/tdef.h> + #include <osmocom/gsm/protocol/gsm_04_08.h> #include <osmocom/gsm/gsm0808.h> @@ -7,6 +9,9 @@ struct msgb; struct gsm_network; struct vlr_subscr; +extern struct osmo_tdef_group msc_tdef_group[]; +extern struct osmo_tdef msc_tdefs_vlr[]; + #define MSC_HLR_REMOTE_IP_DEFAULT "127.0.0.1" #define MSC_HLR_REMOTE_PORT_DEFAULT OSMO_GSUP_PORT @@ -27,6 +32,8 @@ struct geran_encr { uint8_t alg_id; uint8_t key_len; uint8_t key[MAX_A5_KEY_LEN]; + bool kc128_present; + uint8_t kc128[MAX_A5_KEY_LEN]; }; enum complete_layer3_type { @@ -34,6 +41,7 @@ enum complete_layer3_type { COMPLETE_LAYER3_LU, COMPLETE_LAYER3_CM_SERVICE_REQ, COMPLETE_LAYER3_PAGING_RESP, + COMPLETE_LAYER3_CM_RE_ESTABLISH_REQ, }; extern const struct value_string complete_layer3_type_names[]; diff --git a/include/osmocom/msc/msc_ho.h b/include/osmocom/msc/msc_ho.h index 99956f1e6..aedb622dc 100644 --- a/include/osmocom/msc/msc_ho.h +++ b/include/osmocom/msc/msc_ho.h @@ -1,6 +1,6 @@ /* MSC Handover API */ /* - * (C) 2019 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de> + * (C) 2019 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de> * All Rights Reserved * * SPDX-License-Identifier: AGPL-3.0+ @@ -31,7 +31,7 @@ #include <osmocom/msc/neighbor_ident.h> #include <osmocom/msc/ran_msg.h> #include <osmocom/msc/mncc_call.h> - +#include <osmocom/msc/sdp_msg.h> struct gsm0808_handover_required; @@ -81,7 +81,7 @@ struct msc_ho_state { struct osmo_sockaddr_str ran_remote_rtp; /* The codec from Handover Request Acknowledge. */ bool codec_present; - enum mgcp_codecs codec; + struct gsm0808_speech_codec codec; /* Inter-MSC voice forwarding via MNCC, to the remote MSC. The Prepare Handover Response sent us the * Handover Number the remote MSC assigned. This is a call to that Handover Number, via PBX. @@ -92,7 +92,7 @@ struct msc_ho_state { struct { /* Saved RTP IP:port and codec in case we need to roll back */ struct osmo_sockaddr_str ran_remote_rtp; - enum mgcp_codecs codec; + struct sdp_audio_codecs codecs; } old_cell; }; diff --git a/include/osmocom/msc/msc_roles.h b/include/osmocom/msc/msc_roles.h index b22bc7b85..495717576 100644 --- a/include/osmocom/msc/msc_roles.h +++ b/include/osmocom/msc/msc_roles.h @@ -236,7 +236,7 @@ enum msc_a_events { MSC_A_EV_FROM_T_SEND_END_SIGNAL_REQUEST, /* gsm_04_08.c has successfully received a valid Complete Layer 3 message, i.e. Location Updating, CM Service - * Request, Paging Reponse or IMSI Detach. */ + * Request, Paging Response or IMSI Detach. */ MSC_A_EV_COMPLETE_LAYER_3_OK, /* Received a Classmark Update -- during GERAN ciphering, msc_a may have to wait for Classmark information to diff --git a/include/osmocom/msc/msc_t.h b/include/osmocom/msc/msc_t.h index 39b3abca0..876c11d5e 100644 --- a/include/osmocom/msc/msc_t.h +++ b/include/osmocom/msc/msc_t.h @@ -30,7 +30,7 @@ struct msc_t { struct { struct an_apdu ho_request; struct gsm0808_cell_id cell_id_target; - uint32_t callref; + uint32_t call_id; char handover_number[16]; /* No libosmocore definition for MSISDN_MAXLEN? */ struct call_leg *call_leg; struct mncc_call *mncc_forwarding_to_remote_cn; diff --git a/include/osmocom/msc/msc_vgcs.h b/include/osmocom/msc/msc_vgcs.h new file mode 100644 index 000000000..2b2f45d31 --- /dev/null +++ b/include/osmocom/msc/msc_vgcs.h @@ -0,0 +1,228 @@ +/* Handle a call via VGCS/VBCS (Voice Group/Broadcast Call Service). */ +/* + * (C) 2023 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de> + * All Rights Reserved + * + * SPDX-License-Identifier: AGPL-3.0+ + * + * Author: Andreas Eversberg + * + * 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/msc/transaction.h> + +#define GSM44068_ALLOC_SIZE 2048 +#define GSM44068_ALLOC_HEADROOM 256 + +static inline struct msgb *gsm44068_msgb_alloc_name(const char *name) +{ + return msgb_alloc_headroom(GSM44068_ALLOC_SIZE, GSM44068_ALLOC_HEADROOM, name); +} + +/* VGCS/VBS "call control" connection to each BSS */ +struct vgcs_bss { + struct llist_head list; /* List entry */ + struct llist_head cell_list; /* List of cells */ + struct gsm_trans *trans; /* Back pointer to transaction */ + struct osmo_fsm_inst *fi; /* State machine of each BSS */ + struct ran_conn *conn; /* RAN ("SCCP") connection */ + enum trans_type trans_type; /* Transaction type */ + uint32_t callref; /* Callref */ + int pc; /* Point code for debug purpose */ +}; + +/* VGCS/VBS "resource control" connection to each cell in BSS */ +struct vgcs_bss_cell { + struct llist_head list_bss; /* List entry in vgcs_bss */ + struct llist_head list_mgw; /* List entry in MGW endpoint */ + struct vgcs_bss *bss; /* Back pointer to vgcs_bss */ + struct vgcs_mgw_ep *mgw; /* Back pointer to vgcs_mgw_ep */ + struct osmo_fsm_inst *fi; /* State machine of each cell */ + int cell_id; /* Id of cell (BTS) to use */ + struct ran_conn *conn; /* RAN ("SCCP") connection */ + enum trans_type trans_type; /* Transaction type */ + uint32_t callref; /* Callref */ + int call_id; /* Id of call (used for MGW connections) */ + int pc; /* Point code for debug purpose */ + bool assigned; /* Flags if assignment is complete */ + struct rtp_stream *rtps; /* MGW connection process */ +}; + +/* VGCS/VBS MGW endpoint for each call */ +struct vgcs_mgw_ep { + struct llist_head cell_list; /* List of cells with connections */ + struct llist_head list; /* List entry */ + struct osmo_fsm_inst *fi; /* State machine of each cell */ + struct osmo_mgcpc_ep *mgw_ep; /* MGW endpoint */ +}; + +/* Events for the GCC/BCC state machine. + * There is no primitive definition like MNGCC-* oder MNBCC-* in the standard. */ +enum vgcs_gcc_fsm_event { + /* The network sets up a call. */ + VGCS_GCC_EV_NET_SETUP, + /* The network requests termination. */ + VGCS_GCC_EV_NET_TERM, + /* The user sets up a call. */ + VGCS_GCC_EV_USER_SETUP, + /* The user requests termination. */ + VGCS_GCC_EV_USER_TERM, + /* BSS completed call establishment (all BSCs) */ + VGCS_GCC_EV_BSS_ESTABLISHED, + /* Assignment was completed. */ + VGCS_GCC_EV_BSS_ASSIGN_CPL, + /* Assignment failed. */ + VGCS_GCC_EV_BSS_ASSIGN_FAIL, + /* BSS released call establishment (all BSCs) */ + VGCS_GCC_EV_BSS_RELEASED, + /* Inactivity timeout */ + VGCS_GCC_EV_TIMEOUT, +}; + +/* 3GPP TS 44.068 6.1.2.2 States of GCC/BCC */ +enum vgcs_gcc_fsm_state { + /* No call. Initial state when instance is created. */ + VGCS_GCC_ST_N0_NULL = 0, + /* An MS wants to establish a call. */ + VGCS_GCC_ST_N1_CALL_INITIATED, + /* Call established in at least one cell. */ + VGCS_GCC_ST_N2_CALL_ACTIVE, + /* Channel activation is requested, CONNECT already sent to MS. */ + VGCS_GCC_ST_N3_CALL_EST_PROC, + /* Call termination is requested, waiting for all cells to confirm. */ + VGCS_GCC_ST_N4_TERMINATION_REQ, +}; + +const char *vgcs_bcc_gcc_state_name(struct osmo_fsm_inst *fi); + +/* Events for the VGCS/VBS "call control" state machine */ +enum vgcs_bss_fsm_event { + /* Start a VGCS/VBS call using VGCS/VBS SETUP message */ + VGCS_BSS_EV_SETUP, + /* VGCS/VBS SETUP ACK is received */ + VGCS_BSS_EV_SETUP_ACK, + /* VGCS/VBS SETUP REFUSE is received */ + VGCS_BSS_EV_SETUP_REFUSE, + /* VGCS/VBS ASSIGNMENT complete or failed */ + VGCS_BSS_EV_ACTIVE_OR_FAIL, + /* Talker request */ + VGCS_BSS_EV_UL_REQUEST, + /* Talker established uplink */ + VGCS_BSS_EV_UL_REQUEST_CNF, + /* Talker send app data */ + VGCS_BSS_EV_UL_APP_DATA, + /* Talker send signaling data */ + VGCS_BSS_EV_BSS_DTAP, + /* Talker becomes listener */ + VGCS_BSS_EV_UL_RELEASE, + /* Release channel towards BSS */ + VGCS_BSS_EV_CLEAR, + /* Channel closed from BSS */ + VGCS_BSS_EV_CLOSE, + /* Release is complete */ + VGCS_BSS_EV_RELEASED, +}; + +/* States of the VGCS/VBS "call control" state machine */ +enum vgcs_bss_fsm_state { + /* No call. Initial state when instance is created. */ + VGCS_BSS_ST_NULL = 0, + /* VGCS/VBS SETUP is sent towards BSC */ + VGCS_BSS_ST_SETUP, + /* VGCS/VBS ASSIGNMENT REQUEST is sent towards BSC */ + VGCS_BSS_ST_ASSIGNMENT, + /* VGCS/VBS is establised */ + VGCS_BSS_ST_ACTIVE, + /* CLEAR COMMAND was sent */ + VGCS_BSS_ST_RELEASE, +}; + +/* Events for the VGCS/VBS "resource control" state machine */ +enum vgcs_cell_fsm_event { + /* RTP stream gone */ + VGCS_CELL_EV_RTP_STREAM_GONE, + /* RTP stream remote addr available */ + VGCS_CELL_EV_RTP_STREAM_ADDR_AVAILABLE, + /* RTP stream established */ + VGCS_CELL_EV_RTP_STREAM_ESTABLISHED, + /* Start a VGCS/VBS channel using VGCS/VBS ASSIGNMENT message */ + VGCS_CELL_EV_ASSIGN, + /* VGCS/VBS ASSIGNMENT RESULT is received */ + VGCS_CELL_EV_ASSIGN_RES, + /* VGCS/VBS ASSIGNMENT FAILURE is received */ + VGCS_CELL_EV_ASSIGN_FAIL, + /* Release channel towards BSS */ + VGCS_CELL_EV_CLEAR, + /* Channel closed from BSS */ + VGCS_CELL_EV_CLOSE, + /* Release is complete */ + VGCS_CELL_EV_RELEASED, +}; + +/* States of the VGCS/VBS "resource control" state machine */ +enum vgcs_cell_fsm_state { + /* No call. Initial state when instance is created. */ + VGCS_CELL_ST_NULL = 0, + /* VGCS/VBS ASSIGNMENT REQUEST is sent towards BSC */ + VGCS_CELL_ST_ASSIGNMENT, + /* Channel is establised */ + VGCS_CELL_ST_ACTIVE, + /* CLEAR COMMAND was sent */ + VGCS_CELL_ST_RELEASE, +}; + +/* Events for the VGCS/VBS MGW endpoint state machine */ +enum vgcs_mgw_ep_fsm_event { + /* MGW endpoint gone */ + VGCS_MGW_EP_EV_FREE, + /* Destroy MGW endpoint */ + VGCS_MGW_EP_EV_CLEAR, +}; + +/* States of the VGCS/VBS MGW endpoint state machine */ +enum vgcs_mgw_ep_fsm_state { + VGCS_MGW_EP_ST_NULL = 0, + /* MGW endpoint allocated */ + VGCS_MGW_EP_ST_ACTIVE, +}; + +const char *gsm44068_group_id_string(uint32_t callref); + +struct gcr; + +int gsm44068_rcv_rr(struct msc_a *msc_a, struct msgb *msg); +int gsm44068_rcv_bcc_gcc(struct msc_a *msc_a, struct gsm_trans *trans, struct msgb *msg); +const char *vgcs_vty_initiate(struct gsm_network *gsmnet, struct gcr *gcr); +const char *vgcs_vty_terminate(struct gsm_network *gsmnet, struct gcr *gcr); +void gsm44068_bcc_gcc_trans_free(struct gsm_trans *trans); + +void vgcs_vbs_setup_ack(struct vgcs_bss *bss, const struct ran_msg *ran_msg); +void vgcs_vbs_setup_refuse(struct vgcs_bss *bss, const struct ran_msg *ran_msg); +void vgcs_vbs_assign_result(struct vgcs_bss_cell *cell, const struct ran_msg *ran_msg); +void vgcs_vbs_assign_fail(struct vgcs_bss_cell *cell, const struct ran_msg *ran_msg); +void vgcs_vbs_queuing_ind(struct vgcs_bss_cell *cell); +void vgcs_uplink_request(struct vgcs_bss *bss, const struct ran_msg *ran_msg); +void vgcs_uplink_request_cnf(struct vgcs_bss *bss, const struct ran_msg *ran_msg); +void vgcs_app_data(struct vgcs_bss *bss, const struct ran_msg *ran_msg); +void vgcs_bss_dtap(struct vgcs_bss *bss, const struct ran_msg *ran_msg); +void vgcs_uplink_release_ind(struct vgcs_bss *bss, const struct ran_msg *ran_msg); +void vgcs_vbs_assign_status(struct vgcs_bss_cell *cell, const struct ran_msg *ran_msg); +void vgcs_vbs_clear_req_channel(struct vgcs_bss_cell *cell, const struct ran_msg *ran_msg); +void vgcs_vbs_clear_cpl_channel(struct vgcs_bss_cell *cell, const struct ran_msg *ran_msg); +void vgcs_vbs_clear_req(struct vgcs_bss *bss, const struct ran_msg *ran_msg); +void vgcs_vbs_clear_cpl(struct vgcs_bss *bss, const struct ran_msg *ran_msg); +void vgcs_vbs_caller_assign_cpl(struct gsm_trans *trans); +void vgcs_vbs_caller_assign_fail(struct gsm_trans *trans); diff --git a/include/osmocom/msc/msub.h b/include/osmocom/msc/msub.h index 2418febcf..14f3e76ce 100644 --- a/include/osmocom/msc/msub.h +++ b/include/osmocom/msc/msub.h @@ -1,5 +1,7 @@ #pragma once +#include <osmocom/gsm/gsm48.h> + #include <osmocom/msc/debug.h> #include <osmocom/msc/msc_roles.h> @@ -64,7 +66,7 @@ int _msub_role_dispatch(struct msub *msub, enum msc_role to_role, uint32_t to_ro const char *file, int line); int msub_tx_an_apdu(struct msub *msub, enum msc_role from_role, enum msc_role to_role, struct an_apdu *an_apdu); -void msub_update_id_from_mi(struct msub *msub, const uint8_t mi[], uint8_t mi_len); +void msub_update_id_from_mi(struct msub *msub, const struct osmo_mobile_identity *mi); void msub_update_id(struct msub *msub); void msub_update_id_for_vsub(struct vlr_subscr *for_vsub); diff --git a/include/osmocom/msc/paging.h b/include/osmocom/msc/paging.h index 4de679df7..f8ebf9e3b 100644 --- a/include/osmocom/msc/paging.h +++ b/include/osmocom/msc/paging.h @@ -40,6 +40,7 @@ struct paging_request { struct paging_request *paging_request_start(struct vlr_subscr *vsub, enum paging_cause cause, paging_cb_t paging_cb, struct gsm_trans *trans, const char *label); +void paging_request_join_vsub(struct vlr_subscr *keep_vsub, struct vlr_subscr *discarding_vsub); void paging_request_remove(struct paging_request *pr); void paging_response(struct msc_a *msc_a); diff --git a/include/osmocom/msc/ran_conn.h b/include/osmocom/msc/ran_conn.h index 7aa50df07..cdaa02652 100644 --- a/include/osmocom/msc/ran_conn.h +++ b/include/osmocom/msc/ran_conn.h @@ -18,9 +18,17 @@ struct ran_conn { uint32_t sccp_conn_id; /* MSC role that this RAN connection belongs to. This will be either an msc_i (currently active - * connection) or an msc_t (transitory new connection during Handover). */ + * connection) or an msc_t (transitory new connection during Handover). + * Used for usual L3 ran_conn to a subscriber. */ struct osmo_fsm_inst *msc_role; + /* For VGCS/VBS, we have additional N connections to BSS. When receiving messages for a group call peer, + * dispatch to the VGCS management. */ + struct { + void *bss; + void *cell; + } vgcs; + bool closing; }; diff --git a/include/osmocom/msc/ran_infra.h b/include/osmocom/msc/ran_infra.h index 38c424f09..262a9c82e 100644 --- a/include/osmocom/msc/ran_infra.h +++ b/include/osmocom/msc/ran_infra.h @@ -4,6 +4,7 @@ #include <osmocom/gsm/gsup.h> #include <osmocom/msc/sccp_ran.h> #include <osmocom/msc/ran_msg.h> +#include <osmocom/msc/sdp_msg.h> struct osmo_tdef; @@ -25,6 +26,10 @@ struct ran_infra { const ran_dec_l2_t ran_dec_l2; const ran_encode_t ran_encode; struct sccp_ran_inst *sri; + /* To always set up the MGW endpoint facing the RAN side with specific codecs, list those here. Otherwise leave + * empty (to use the result of codecs filtering). This exists for IuCS, to always set the MGW endpoint facing + * RAN to IUFP, to decapsulate the IuUP headers. */ + struct sdp_audio_codecs force_mgw_codecs_to_ran; }; extern struct ran_infra msc_ran_infra[]; diff --git a/include/osmocom/msc/ran_msg.h b/include/osmocom/msc/ran_msg.h index 4d0485d43..dc1483cb5 100644 --- a/include/osmocom/msc/ran_msg.h +++ b/include/osmocom/msc/ran_msg.h @@ -69,6 +69,26 @@ enum ran_msg_type { RAN_MSG_HANDOVER_SUCCEEDED, RAN_MSG_HANDOVER_COMPLETE, RAN_MSG_HANDOVER_FAILURE, + RAN_MSG_VGCS_VBS_SETUP, + RAN_MSG_VGCS_VBS_SETUP_ACK, + RAN_MSG_VGCS_VBS_SETUP_REFUSE, + RAN_MSG_VGCS_VBS_ASSIGN_REQ, + RAN_MSG_VGCS_VBS_ASSIGN_RES, + RAN_MSG_VGCS_VBS_ASSIGN_FAIL, + RAN_MSG_VGCS_VBS_QUEUING_IND, + RAN_MSG_UPLINK_REQUEST, + RAN_MSG_UPLINK_REQUEST_ACK, + RAN_MSG_UPLINK_REQUEST_CNF, + RAN_MSG_UPLINK_APPLICATION_DATA, + RAN_MSG_UPLINK_RELEASE_IND, + RAN_MSG_UPLINK_REJECT_CMD, + RAN_MSG_UPLINK_RELEASE_CMD, + RAN_MSG_UPLINK_SEIZED_CMD, + RAN_MSG_VGCS_ADDITIONAL_INFO, + RAN_MSG_VGCS_VBS_AREA_CELL_INFO, + RAN_MSG_VGCS_VBS_ASSIGN_STATUS, + RAN_MSG_VGCS_SMS, + RAN_MSG_NOTIFICATION_DATA, }; extern const struct value_string ran_msg_type_names[]; @@ -84,6 +104,13 @@ struct ran_assignment_command { const struct osmo_sockaddr_str *cn_rtp; const struct gsm0808_channel_type *channel_type; enum nsap_addr_enc rab_assign_addr_enc; + bool osmux_present; + uint8_t osmux_cid; + bool call_id_present; + uint32_t call_id; + struct osmo_lcls *lcls; + bool callref_present; + struct gsm0808_group_callref callref; }; struct ran_cipher_mode_command { @@ -97,6 +124,9 @@ struct ran_cipher_mode_command { /* out-argument to return the key to the caller, pass NULL if not needed. */ struct geran_encr *chosen_key; } geran; + struct { + uint8_t uea_encryption_mask; + } utran; }; struct ran_handover_request { @@ -154,7 +184,8 @@ struct ran_handover_request_ack { struct osmo_sockaddr_str remote_rtp; bool codec_present; - enum mgcp_codecs codec; + struct gsm0808_speech_codec codec; + bool codec_with_iuup; }; struct ran_handover_command { @@ -190,6 +221,7 @@ struct ran_msg { union { struct { const struct gsm0808_cell_id *cell_id; + const struct gsm0808_speech_codec_list *codec_list_bss_supported; struct msgb *msg; } compl_l3; struct msgb *dtap; @@ -207,13 +239,22 @@ struct ran_msg { * alg_id == 1 means A5/0 i.e. no encryption, alg_id == 4 means A5/3. * alg_id == 0 means no such IE was present. */ uint8_t alg_id; + /*! utran integrity protection. 0..15 */ + int16_t utran_integrity; + /*! utran_integrity is in encoded format: + * utran_integrity == -1 means no such IE was present + * utran_integrity == 0 means no encryption. */ + int16_t utran_encryption; const char *imeisv; + const struct tlv_p_entry *l3_msg; } cipher_mode_complete; struct { enum gsm0808_cause bssap_cause; } cipher_mode_reject; struct { const char *imsi; + bool last_eutran_plmn_present; + struct osmo_plmn_id last_eutran_plmn; } common_id; struct { enum gsm48_reject_value cause; @@ -222,7 +263,11 @@ struct ran_msg { struct { struct osmo_sockaddr_str remote_rtp; bool codec_present; - enum mgcp_codecs codec; + struct gsm0808_speech_codec codec; + bool codec_with_iuup; + const struct gsm0808_speech_codec_list *codec_list_bss_supported; + bool osmux_present; + uint8_t osmux_cid; } assignment_complete; struct { enum gsm0808_cause bssap_cause; @@ -247,6 +292,33 @@ struct ran_msg { } handover_failure; struct ran_handover_request handover_request; struct ran_handover_request_ack handover_request_ack; + struct gsm0808_vgcs_vbs_setup vgcs_vbs_setup; + struct gsm0808_vgcs_vbs_setup_ack vgcs_vbs_setup_ack; + struct { + enum gsm0808_cause cause; + } vgcs_vbs_setup_refuse; + struct gsm0808_vgcs_vbs_assign_req vgcs_vbs_assign_req; + struct gsm0808_vgcs_vbs_assign_res vgcs_vbs_assign_res; + struct gsm0808_vgcs_vbs_assign_fail vgcs_vbs_assign_fail; + struct gsm0808_uplink_request uplink_request; + struct gsm0808_uplink_request_ack uplink_request_ack; + struct gsm0808_uplink_request_cnf uplink_request_cnf; + struct gsm0808_uplink_app_data uplink_app_data; + struct gsm0808_uplink_release_ind uplink_release_ind; + struct gsm0808_uplink_seized_cmd uplink_seized_cmd; + struct gsm0808_uplink_reject_cmd uplink_reject_cmd; + struct { + enum gsm0808_cause cause; + } uplink_release_cmd; + struct { + struct gsm0808_talker_identity talker_identity; + } vgcs_additional_info; + struct gsm0808_vgcs_vbs_area_cell_info vgcs_vbs_area_cell_info; + struct gsm0808_vgcs_vbs_assign_stat vgcs_vbs_assign_stat; + struct { + struct gsm0808_sms_to_vgcs sms_to_vgcs; + } vgcs_sms; + struct gsm0808_notification_data notification_data; }; }; diff --git a/include/osmocom/msc/ran_msg_a.h b/include/osmocom/msc/ran_msg_a.h index 3ba081de2..2d045b96e 100644 --- a/include/osmocom/msc/ran_msg_a.h +++ b/include/osmocom/msc/ran_msg_a.h @@ -35,7 +35,8 @@ struct gsm_mncc_bearer_cap; int ran_a_decode_l2(struct ran_dec *ran_a, struct msgb *bssap); struct msgb *ran_a_encode(struct osmo_fsm_inst *caller_fi, const struct ran_msg *ran_enc_msg); -enum reset_msg_type bssmap_is_reset_msg(const struct sccp_ran_inst *sri, const struct msgb *l2); +enum reset_msg_type bssmap_is_reset_msg(const struct sccp_ran_inst *sri, struct osmo_fsm_inst *log_fi, + struct msgb *l2, int *supports_osmux); struct msgb *bssmap_make_reset_msg(const struct sccp_ran_inst *sri, enum reset_msg_type type); struct msgb *bssmap_make_paging_msg(const struct sccp_ran_inst *sri, const struct gsm0808_cell_id *page_cell_id, const char *imsi, uint32_t tmsi, enum paging_cause cause); diff --git a/include/osmocom/msc/ran_msg_iu.h b/include/osmocom/msc/ran_msg_iu.h index 316a91cdb..3f3d61e4a 100644 --- a/include/osmocom/msc/ran_msg_iu.h +++ b/include/osmocom/msc/ran_msg_iu.h @@ -28,7 +28,8 @@ int ran_iu_decode_l2(struct ran_dec *ran_dec_iu, struct msgb *ranap); struct msgb *ran_iu_encode(struct osmo_fsm_inst *caller_fi, const struct ran_msg *ran_enc_msg); -enum reset_msg_type ranap_is_reset_msg(const struct sccp_ran_inst *sri, const struct msgb *l2); +enum reset_msg_type ranap_is_reset_msg(const struct sccp_ran_inst *sri, struct osmo_fsm_inst *log_fi, + struct msgb *l2, int *supports_osmux); struct msgb *ranap_make_reset_msg(const struct sccp_ran_inst *sri, enum reset_msg_type type); struct msgb *ranap_make_paging_msg(const struct sccp_ran_inst *sri, const struct gsm0808_cell_id *page_cell_id, const char *imsi, uint32_t tmsi, enum paging_cause cause); diff --git a/include/osmocom/msc/ran_peer.h b/include/osmocom/msc/ran_peer.h index 06ab50090..c936d5c5d 100644 --- a/include/osmocom/msc/ran_peer.h +++ b/include/osmocom/msc/ran_peer.h @@ -42,7 +42,7 @@ struct neighbor_ident_entry; * list is kept in sccp_ran_inst. For convenience, see ran_peer_for_each_ran_conn(). */ struct ran_peer { - /* Entry in sccp_ran_inst->ran_conns */ + /* Entry in sccp_ran_inst->ran_peers */ struct llist_head entry; struct sccp_ran_inst *sri; @@ -91,7 +91,7 @@ struct ran_peer_ev_ctx { }; struct ran_peer *ran_peer_find_or_create(struct sccp_ran_inst *sri, const struct osmo_sccp_addr *peer_addr); -struct ran_peer *ran_peer_find(struct sccp_ran_inst *sri, const struct osmo_sccp_addr *peer_addr); +struct ran_peer *ran_peer_find_by_addr(struct sccp_ran_inst *sri, const struct osmo_sccp_addr *peer_addr); void ran_peer_cells_seen_add(struct ran_peer *ran_peer, const struct gsm0808_cell_id *id); @@ -106,4 +106,3 @@ int ran_peer_down_paging(struct ran_peer *rp, const struct gsm0808_cell_id *page struct ran_peer *ran_peer_find_by_cell_id(struct sccp_ran_inst *sri, const struct gsm0808_cell_id *cid, bool expecting_single_match); -struct ran_peer *ran_peer_find_by_addr(struct sccp_ran_inst *sri, const struct osmo_sccp_addr *addr); diff --git a/include/osmocom/msc/rtp_stream.h b/include/osmocom/msc/rtp_stream.h index 794e8066f..5bc01440f 100644 --- a/include/osmocom/msc/rtp_stream.h +++ b/include/osmocom/msc/rtp_stream.h @@ -5,6 +5,7 @@ #include <osmocom/core/sockaddr_str.h> #include <osmocom/mgcp_client/mgcp_client.h> +#include <osmocom/msc/sdp_msg.h> struct gsm_trans; @@ -25,7 +26,8 @@ static inline const char *rtp_direction_name(enum rtp_direction val) /* A single bidirectional RTP hop between remote and MGW's local RTP port. */ struct rtp_stream { struct osmo_fsm_inst *fi; - struct call_leg *parent_call_leg; + uint32_t event_avail; + uint32_t event_estab; enum rtp_direction dir; uint32_t call_id; @@ -37,26 +39,42 @@ struct rtp_stream { struct osmo_sockaddr_str remote; bool remote_sent_to_mgw; - bool codec_known; - enum mgcp_codecs codec; - bool codec_sent_to_mgw; + bool codecs_known; + struct sdp_audio_codecs codecs; + bool codecs_sent_to_mgw; struct osmo_mgcpc_ep_ci *ci; enum mgcp_connection_mode crcx_conn_mode; + bool mode_sent_to_mgw; + + /* configured to use Osmux */ + bool use_osmux; + /* Allocated by our MGW, negative means invalid, not yet known */ + int local_osmux_cid; + /* Allocated by BSC MGW, negative means invalid, not yet known */ + int remote_osmux_cid; + /* Whether remote_osmux_cid has been communicated to MGW */ + bool remote_osmux_cid_sent_to_mgw; }; #define RTP_STREAM_FMT "local=" RTP_IP_PORT_FMT ",remote=" RTP_IP_PORT_FMT #define RTP_STREAM_ARGS(RS) RTP_IP_PORT_ARGS(&(RS)->local), RTP_IP_PORT_ARGS(&(RS)->remote), -struct rtp_stream *rtp_stream_alloc(struct call_leg *parent_call_leg, enum rtp_direction dir, - uint32_t call_id, struct gsm_trans *for_trans); +struct rtp_stream *rtp_stream_alloc(struct osmo_fsm_inst *parent_fi, uint32_t event_gone, uint32_t event_avail, + uint32_t event_estab, enum rtp_direction dir, uint32_t call_id, + struct gsm_trans *for_trans); int rtp_stream_ensure_ci(struct rtp_stream *rtps, struct osmo_mgcpc_ep *at_endpoint); int rtp_stream_do_mdcx(struct rtp_stream *rtps); -void rtp_stream_set_codec(struct rtp_stream *rtps, enum mgcp_codecs codec); +bool rtp_stream_set_codecs_from_mgcp_codec(struct rtp_stream *rtps, enum mgcp_codecs codec); +void rtp_stream_set_one_codec(struct rtp_stream *rtps, const struct sdp_audio_codec *codec); +void rtp_stream_set_codecs(struct rtp_stream *rtps, const struct sdp_audio_codecs *codecs); +void rtp_stream_set_mode(struct rtp_stream *rtps, enum mgcp_connection_mode mode); void rtp_stream_set_remote_addr(struct rtp_stream *rtps, const struct osmo_sockaddr_str *r); +void rtp_stream_set_remote_addr_and_codecs(struct rtp_stream *rtps, const struct sdp_msg *sdp); +void rtp_stream_set_remote_osmux_cid(struct rtp_stream *rtps, uint8_t osmux_cid); int rtp_stream_commit(struct rtp_stream *rtps); void rtp_stream_release(struct rtp_stream *rtps); diff --git a/include/osmocom/msc/sccp_ran.h b/include/osmocom/msc/sccp_ran.h index f190d91e3..a4bd4ca61 100644 --- a/include/osmocom/msc/sccp_ran.h +++ b/include/osmocom/msc/sccp_ran.h @@ -189,14 +189,14 @@ struct sccp_ran_inst; #define LOG_SCCP_RAN_CO(sri, peer_addr, conn_id, level, fmt, args...) \ LOGP((sri) && (sri)->ran? (sri)->ran->log_subsys : DMSC, level, "(%s-%u%s%s) " fmt, \ - osmo_rat_type_name((sri) && (sri)->ran? (sri)->ran->type : -1), conn_id, \ + osmo_rat_type_name((sri) && (sri)->ran ? (sri)->ran->type : OSMO_RAT_UNKNOWN), conn_id, \ peer_addr ? " from " : "", \ peer_addr ? osmo_sccp_inst_addr_name((sri)->sccp, peer_addr) : "", \ ## args) #define LOG_SCCP_RAN_CL_CAT(sri, peer_addr, subsys, level, fmt, args...) \ LOGP(subsys, level, "(%s%s%s) " fmt, \ - osmo_rat_type_name((sri) && (sri)->ran? (sri)->ran->type : -1), \ + osmo_rat_type_name((sri) && (sri)->ran ? (sri)->ran->type : OSMO_RAT_UNKNOWN), \ peer_addr ? " from " : "", \ peer_addr ? osmo_sccp_inst_addr_name((sri)->sccp, peer_addr) : "", \ ## args) @@ -233,8 +233,11 @@ struct sccp_ran_ops { /* Return whether the given l2_cl message is a RESET, RESET ACKNOWLEDGE, or RESET-unrelated message. * This callback is stored in struct sccp_ran_inst to provide RESET handling to the caller (ran_peer), - * it is not used in sccp_ran.c. */ - enum reset_msg_type (* is_reset_msg )(const struct sccp_ran_inst *sri, const struct msgb *l2_cl); + * it is not used in sccp_ran.c. + * In supports_osmux, return 0 for no information, 1 for support detected, -1 for non-support detected. + */ + enum reset_msg_type (* is_reset_msg )(const struct sccp_ran_inst *sri, struct osmo_fsm_inst *log_fi, + struct msgb *l2_cl, int *supports_osmux); /* Return a RESET or RESET ACK message for this RAN type. * This callback is stored in struct sccp_ran_inst to provide RESET handling to the caller (ran_peer), diff --git a/include/osmocom/msc/sdp_msg.h b/include/osmocom/msc/sdp_msg.h new file mode 100644 index 000000000..e3879f6af --- /dev/null +++ b/include/osmocom/msc/sdp_msg.h @@ -0,0 +1,87 @@ +/* Minimalistic SDP parse/compose API, focused on GSM audio codecs */ +#pragma once + +#include <osmocom/core/utils.h> +#include <osmocom/core/sockaddr_str.h> + +#include <osmocom/msc/csd_bs.h> + +extern const struct value_string sdp_msg_payload_type_names[]; +static inline const char *sdp_msg_payload_type_name(unsigned int payload_type) +{ return get_value_string(sdp_msg_payload_type_names, payload_type); } +int sdp_subtype_name_to_payload_type(const char *subtype_name); + +enum sdp_mode_e { + SDP_MODE_UNSET = 0, + SDP_MODE_SENDONLY = 1, + SDP_MODE_RECVONLY = 2, + SDP_MODE_SENDRECV = 3, + SDP_MODE_INACTIVE = 4, +}; + +struct sdp_audio_codec { + /* Payload type number, like 3 for GSM-FR. */ + unsigned int payload_type; + /* Like "GSM", "AMR", "EFR", ... */ + char subtype_name[16]; + unsigned int rate; + char fmtp[256]; +}; + +struct sdp_audio_codecs { + unsigned int count; + struct sdp_audio_codec codec[16]; +}; + +struct sdp_msg { + struct osmo_sockaddr_str rtp; + unsigned int ptime; + enum sdp_mode_e mode; + struct sdp_audio_codecs audio_codecs; + struct csd_bs_list bearer_services; +}; + +#define sdp_audio_codecs_foreach(/* struct sdp_audio_codec* */ CODEC, \ + /* struct sdp_audio_codecs* */ AC) \ + for (CODEC = (AC)->codec; \ + (CODEC - (AC)->codec) < OSMO_MIN((AC)->count, ARRAY_SIZE((AC)->codec)); \ + CODEC++) + +const char *sdp_msg_line_end(const char *src); + +bool sdp_audio_codec_is_set(const struct sdp_audio_codec *a); +int sdp_audio_codec_cmp(const struct sdp_audio_codec *a, const struct sdp_audio_codec *b, + bool cmp_fmtp, bool cmp_payload_type); +int sdp_audio_codecs_cmp(const struct sdp_audio_codecs *a, const struct sdp_audio_codecs *b, + bool cmp_fmtp, bool cmp_payload_type); + +struct sdp_audio_codec *sdp_audio_codecs_add(struct sdp_audio_codecs *ac, unsigned int payload_type, + const char *subtype_name, unsigned int rate, const char *fmtp); +struct sdp_audio_codec *sdp_audio_codecs_add_copy(struct sdp_audio_codecs *ac, + const struct sdp_audio_codec *codec); +int sdp_audio_codecs_remove(struct sdp_audio_codecs *ac, const struct sdp_audio_codec *codec); +struct sdp_audio_codec *sdp_audio_codecs_by_payload_type(struct sdp_audio_codecs *ac, + unsigned int payload_type, bool create); +struct sdp_audio_codec *sdp_audio_codecs_by_descr(struct sdp_audio_codecs *ac, + const struct sdp_audio_codec *codec); + +void sdp_audio_codecs_intersection(struct sdp_audio_codecs *ac_dest, const struct sdp_audio_codecs *ac_other, + bool translate_payload_type_numbers); +void sdp_audio_codecs_select(struct sdp_audio_codecs *ac, struct sdp_audio_codec *codec); + +int sdp_msg_to_sdp_str_buf(char *dst, size_t dst_size, const struct sdp_msg *sdp); +int sdp_msg_from_sdp_str(struct sdp_msg *sdp, const char *src); + +int sdp_audio_codec_to_str_buf(char *buf, size_t buflen, const struct sdp_audio_codec *codec); +char *sdp_audio_codec_to_str_c(void *ctx, const struct sdp_audio_codec *codec); +const char *sdp_audio_codec_to_str(const struct sdp_audio_codec *codec); + +int sdp_audio_codecs_to_str_buf(char *buf, size_t buflen, const struct sdp_audio_codecs *ac); +char *sdp_audio_codecs_to_str_c(void *ctx, const struct sdp_audio_codecs *ac); +const char *sdp_audio_codecs_to_str(const struct sdp_audio_codecs *ac); + +int sdp_msg_to_str_buf(char *buf, size_t buflen, const struct sdp_msg *sdp); +char *sdp_msg_to_str_c(void *ctx, const struct sdp_msg *sdp); +const char *sdp_msg_to_str(const struct sdp_msg *sdp); + +void sdp_audio_codecs_set_csd(struct sdp_audio_codecs *ac); diff --git a/include/osmocom/msc/sgs_iface.h b/include/osmocom/msc/sgs_iface.h index 575468e10..a31966370 100644 --- a/include/osmocom/msc/sgs_iface.h +++ b/include/osmocom/msc/sgs_iface.h @@ -89,4 +89,5 @@ enum sgsap_service_ind sgs_serv_ind_from_paging_cause(enum paging_cause); int sgs_iface_tx_paging(struct vlr_subscr *vsub, enum sgsap_service_ind serv_ind); int sgs_iface_tx_dtap_ud(struct msc_a *msc_a, struct msgb *msg); void sgs_iface_tx_release(struct vlr_subscr *vsub); +void sgs_iface_tx_serv_abrt(struct vlr_subscr *vsub); diff --git a/include/osmocom/msc/sgs_server.h b/include/osmocom/msc/sgs_server.h index a89022d9e..400bd9e80 100644 --- a/include/osmocom/msc/sgs_server.h +++ b/include/osmocom/msc/sgs_server.h @@ -44,7 +44,7 @@ struct sgs_state { char vlr_name[SGS_VLR_NAME_MAXLEN]; /* timers on VLR side */ unsigned int timer[_NUM_SGS_STATE_TIMERS]; - /* countrs on VLR side */ + /* counters on VLR side */ unsigned int counter[_NUM_SGS_STATE_COUNTERS]; } cfg; }; diff --git a/include/osmocom/msc/signal.h b/include/osmocom/msc/signal.h index 16b5678db..915313131 100644 --- a/include/osmocom/msc/signal.h +++ b/include/osmocom/msc/signal.h @@ -70,15 +70,6 @@ enum signal_scall { S_SCALL_DETACHED, }; -/* SS_IPAC_NWL signals */ -enum signal_ipaccess { - S_IPAC_NWL_COMPLETE, -}; - -enum signal_global { - S_GLOBAL_BTS_CLOSE_OM, -}; - struct paging_signal_data { struct vlr_subscr *vsub; struct msc_a *msc_a; @@ -89,7 +80,7 @@ struct scall_signal_data { struct vty *vty; }; struct sms_signal_data { - /* The transaction where this occured */ + /* The transaction where this occurred */ struct gsm_trans *trans; /* Can be NULL for SMMA */ struct gsm_sms *sms; diff --git a/include/osmocom/msc/smpp.h b/include/osmocom/msc/smpp.h deleted file mode 100644 index bcdac8f0b..000000000 --- a/include/osmocom/msc/smpp.h +++ /dev/null @@ -1,4 +0,0 @@ -#pragma once - -int smpp_openbsc_alloc_init(void *ctx); -int smpp_openbsc_start(struct gsm_network *net); diff --git a/include/osmocom/msc/sms_queue.h b/include/osmocom/msc/sms_queue.h index ef73baf04..a6e6aebd3 100644 --- a/include/osmocom/msc/sms_queue.h +++ b/include/osmocom/msc/sms_queue.h @@ -1,20 +1,32 @@ #ifndef SMS_QUEUE_H #define SMS_QUEUE_H +#include <stdbool.h> + struct gsm_network; struct gsm_sms_queue; struct vty; +struct sms_queue_config { + char *db_file_path; /* SMS database file path */ + int max_fail; /* maximum number of delivery failures */ + int max_pending; /* maximum number of gsm_sms_pending in RAM */ + bool delete_delivered; /* delete delivered SMS from DB? */ + bool delete_expired; /* delete expired SMS from DB? */ + unsigned int minimum_validity_mins; /* minimum validity period in minutes */ + unsigned int default_validity_mins; /* default validity period in minutes */ +}; + +struct sms_queue_config *sms_queue_cfg_alloc(void *ctx); + #define VSUB_USE_SMS_PENDING "SMS-pending" #define MSC_A_USE_SMS_PENDING "SMS-pending" -int sms_queue_start(struct gsm_network *, int in_flight); +int sms_queue_start(struct gsm_network *net); int sms_queue_trigger(struct gsm_sms_queue *); /* vty helper functions */ int sms_queue_stats(struct gsm_sms_queue *, struct vty* vty); -int sms_queue_set_max_pending(struct gsm_sms_queue *, int max); -int sms_queue_set_max_failure(struct gsm_sms_queue *, int fail); int sms_queue_clear(struct gsm_sms_queue *); int sms_queue_sms_is_pending(struct gsm_sms_queue *smsq, unsigned long long sms_id); diff --git a/include/osmocom/msc/transaction.h b/include/osmocom/msc/transaction.h index 9278b6400..aa529e494 100644 --- a/include/osmocom/msc/transaction.h +++ b/include/osmocom/msc/transaction.h @@ -8,6 +8,8 @@ #include <osmocom/msc/mncc.h> #include <osmocom/msc/msc_a.h> #include <osmocom/msc/debug.h> +#include <osmocom/msc/codec_filter.h> +#include <osmocom/msc/csd_filter.h> #include <osmocom/gsm/gsm0411_smc.h> #include <osmocom/gsm/gsm0411_smr.h> @@ -16,15 +18,18 @@ struct vty; /* Used for late TID assignment */ #define TRANS_ID_UNASSIGNED 0xff +#define LOG_TRANS_CAT_SRC(trans, subsys, level, file, line, fmt, args...) \ + LOGPSRC(subsys, level, file, line, \ + "trans(%s %s callref-0x%x tid-%u%s) " fmt, \ + (trans) ? trans_name(trans) : "NULL", \ + (trans) ? ((trans)->msc_a ? (trans)->msc_a->c.fi->id : vlr_subscr_name((trans)->vsub)) : "NULL", \ + (trans) ? (trans)->callref : 0, \ + (trans) ? (trans)->transaction_id : 0, \ + (trans) && (trans)->paging_request ? ",PAGING" : "", \ + ##args) + #define LOG_TRANS_CAT(trans, subsys, level, fmt, args...) \ - LOGP(subsys, level, \ - "trans(%s %s callref-0x%x tid-%u%s) " fmt, \ - (trans) ? trans_type_name((trans)->type) : "NULL", \ - (trans) ? ((trans)->msc_a ? (trans)->msc_a->c.fi->id : vlr_subscr_name((trans)->vsub)) : "NULL", \ - (trans) ? (trans)->callref : 0, \ - (trans) ? (trans)->transaction_id : 0, \ - (trans) && (trans)->paging_request ? ",PAGING" : "", \ - ##args) + LOG_TRANS_CAT_SRC(trans, subsys, level, __FILE__, __LINE__, fmt, ##args) #define LOG_TRANS(trans, level, fmt, args...) \ LOG_TRANS_CAT(trans, (trans) ? (trans)->log_subsys : DMSC, level, fmt, ##args) @@ -38,6 +43,8 @@ enum bridge_state { }; enum trans_type { + TRANS_GCC = GSM48_PDISC_GROUP_CC, + TRANS_BCC = GSM48_PDISC_BCAST_CC, TRANS_CC = GSM48_PDISC_CC, TRANS_SMS = GSM48_PDISC_SMS, TRANS_USSD = GSM48_PDISC_NC_SS, @@ -78,6 +85,9 @@ struct gsm_trans { /* reference from MNCC or other application */ uint32_t callref; + /* reference that may be used by MGW to identify a call */ + uint32_t call_id; + /* if traffic channel receive was requested */ int tch_recv; @@ -87,12 +97,27 @@ struct gsm_trans { /* bearer capabilities (rate and codec) */ struct gsm_mncc_bearer_cap bearer_cap; - /* if true, TCH_RTP_CREATE is sent after the - * assignment is done */ - bool tch_rtp_create; - union { struct { + /* State machine of setup process towards BSS */ + struct osmo_fsm_inst *fi; + /* BSS list with all VGCS/VBS calls */ + struct llist_head bss_list; + /* Inactivity timeout and timer */ + int inactivity_to; + struct osmo_timer_list timer_inactivity; + /* If talker's downlink shall be muted */ + bool mute_talker; + /* Indicator, if Uplink is used in one cell */ + bool uplink_busy; + /* BSS that uses the uplink */ + struct vgcs_bss *uplink_bss; + /* Cell that uses the uplink */ + struct vgcs_bss_cell *uplink_cell; + /* If uplink is used by the originator */ + bool uplink_originator; + } gcc; + struct { /* current call state */ int state; @@ -103,6 +128,16 @@ struct gsm_trans { struct osmo_timer_list timer; struct osmo_timer_list timer_guard; struct gsm_mncc msg; /* stores setup/disconnect/release message */ + bool mncc_initiated; /* Whether an MNCC Release is necessary on failure */ + struct osmo_lcls *lcls; + /* SDP as last received from the remote call leg. */ + struct sdp_msg remote; + /* Track codec/CSD choices from BSS and remote call leg */ + struct codec_filter codecs; + struct csd_filter csd; + /* Resulting choice from codecs/bearer services and the + * local RTP address to be sent to the remote call leg. */ + struct sdp_msg local; } cc; struct { struct gsm411_smc_inst smc_inst; @@ -110,8 +145,13 @@ struct gsm_trans { /* SM-RP-MR, Message Reference (see GSM TS 04.11, section 8.2.3) */ uint8_t sm_rp_mr; + /* More Messages to Send (see 3GPP TS 29.002, section 7.6.8.7) */ + bool sm_rp_mmts_ind; struct gsm_sms *sms; + + uint8_t *gsup_source_name; + size_t gsup_source_name_len; } sms; struct { /** @@ -140,12 +180,14 @@ struct gsm_trans { struct gsm_trans *trans_find_by_type(const struct msc_a *msc_a, enum trans_type type); struct gsm_trans *trans_find_by_id(const struct msc_a *msc_a, enum trans_type type, uint8_t trans_id); -struct gsm_trans *trans_find_by_callref(const struct gsm_network *net, +struct gsm_trans *trans_find_by_callref(const struct gsm_network *net, enum trans_type type, uint32_t callref); struct gsm_trans *trans_find_by_sm_rp_mr(const struct gsm_network *net, const struct vlr_subscr *vsub, uint8_t sm_rp_mr); +struct osmo_lcls *trans_lcls_compose(const struct gsm_trans *trans, bool use_lac); + struct gsm_trans *trans_alloc(struct gsm_network *net, struct vlr_subscr *vsub, enum trans_type type, uint8_t trans_id, @@ -157,11 +199,13 @@ int trans_assign_trans_id(const struct gsm_network *net, const struct vlr_subscr struct gsm_trans *trans_has_conn(const struct msc_a *msc_a); void trans_conn_closed(const struct msc_a *msc_a); -static inline int trans_log_subsys(const struct gsm_trans *trans) +static inline int trans_log_subsys(enum trans_type type) { - if (!trans) - return DMSC; - switch (trans->type) { + switch (type) { + case TRANS_GCC: + return DGCC; + case TRANS_BCC: + return DBCC; case TRANS_CC: case TRANS_SILENT_CALL: return DCC; @@ -174,3 +218,5 @@ static inline int trans_log_subsys(const struct gsm_trans *trans) } return DMSC; } + +const char *trans_name(const struct gsm_trans *trans); diff --git a/include/osmocom/msc/transaction_cc.h b/include/osmocom/msc/transaction_cc.h new file mode 100644 index 000000000..963cb457a --- /dev/null +++ b/include/osmocom/msc/transaction_cc.h @@ -0,0 +1,39 @@ +/* Filter/overlay codec and CSD bearer service selections for voice calls/CSD, + * across MS, RAN and CN limitations + * + * (C) 2023 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de> + * All Rights Reserved + * + * Author: Oliver Smith + * + * SPDX-License-Identifier: AGPL-3.0+ + * + * 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/gsm/mncc.h> + +#include <osmocom/msc/codec_mapping.h> +#include <osmocom/msc/transaction.h> +#include <osmocom/msc/vlr.h> + +void trans_cc_filter_init(struct gsm_trans *trans); +void trans_cc_filter_set_ran(struct gsm_trans *trans, enum osmo_rat_type ran_type); +void trans_cc_filter_set_bss(struct gsm_trans *trans, struct msc_a *msc_a); +#define trans_cc_filter_run(TRANS_CC) _trans_cc_filter_run(__FILE__, __LINE__, TRANS_CC) +void _trans_cc_filter_run(const char *file, int line, struct gsm_trans *trans); +void trans_cc_filter_set_ms_from_bc(struct gsm_trans *trans, const struct gsm_mncc_bearer_cap *bcap); +void trans_cc_set_remote_from_bc(struct gsm_trans *trans, const struct gsm_mncc_bearer_cap *bcap); diff --git a/include/osmocom/msc/vlr.h b/include/osmocom/msc/vlr.h index b1c0d5dde..a7707fd01 100644 --- a/include/osmocom/msc/vlr.h +++ b/include/osmocom/msc/vlr.h @@ -5,6 +5,8 @@ #include <osmocom/core/fsm.h> #include <osmocom/core/logging.h> #include <osmocom/core/use_count.h> +#include <osmocom/core/stat_item.h> +#include <osmocom/core/rate_ctr.h> #include <osmocom/gsm/protocol/gsm_23_003.h> #include <osmocom/gsm/protocol/gsm_04_08_gprs.h> #include <osmocom/gsm/gsm23003.h> @@ -23,6 +25,7 @@ LOGP(DVLR, level, "SUBSCR(%s) " fmt, vlr_subscr_name(vsub), ## args) struct log_target; +struct osmo_mobile_identity; #define VLR_SUBSCRIBER_NO_EXPIRATION 0 #define VLR_SUBSCRIBER_LU_EXPIRATION_INTERVAL 60 /* in seconds */ @@ -40,7 +43,7 @@ struct log_target; /* VLR subscriber authentication state */ enum vlr_subscr_auth_state { - /* subscriber needs to be autenticated */ + /* subscriber needs to be authenticated */ VLR_SUB_AS_NEEDS_AUTH, /* waiting for AuthInfo from HLR/AUC */ VLR_SUB_AS_NEEDS_AUTH_WAIT_AI, @@ -64,9 +67,11 @@ enum vlr_lu_event { VLR_ULA_E_UPDATE_LA, /* Initial trigger (LU from MS) */ VLR_ULA_E_SEND_ID_ACK, /* Result of Send-ID from PVLR */ VLR_ULA_E_SEND_ID_NACK, /* Result of Send-ID from PVLR */ - VLR_ULA_E_AUTH_RES, /* Result of auth procedure */ + VLR_ULA_E_AUTH_SUCCESS, /* Successful result of auth procedure */ + VLR_ULA_E_AUTH_NO_INFO, /* HLR returned SAI NACK, possibly continue without auth */ + VLR_ULA_E_AUTH_FAILURE, /* Auth procedure failed */ VLR_ULA_E_CIPH_RES, /* Result of Ciphering Mode Command */ - VLR_ULA_E_ID_IMSI, /* IMSI recieved from MS */ + VLR_ULA_E_ID_IMSI, /* IMSI received from MS */ VLR_ULA_E_ID_IMEI, /* IMEI received from MS */ VLR_ULA_E_ID_IMEISV, /* IMEISV received from MS */ VLR_ULA_E_HLR_IMEI_ACK, /* Check_IMEI_VLR result from HLR */ @@ -113,7 +118,6 @@ struct sgsn_mm_ctx; struct vlr_instance; #define VLR_NAME_LENGTH 160 -#define VLR_MSISDN_LENGTH 15 /* The VLR subscriber is the part of the GSM subscriber state in VLR (CS) or * SGSN (PS), particularly while interacting with the HLR via GSUP */ @@ -127,10 +131,9 @@ struct vlr_subscr { /* Data from HLR */ /* 3GPP TS 23.008 */ /* Always use vlr_subscr_set_imsi() to write to imsi[] */ char imsi[GSM23003_IMSI_MAX_DIGITS+1]; /* 2.1.1.1 */ - char msisdn[VLR_MSISDN_LENGTH+1]; /* 2.1.2 */ + char msisdn[GSM23003_MSISDN_MAX_DIGITS+1]; /* 2.1.2 */ char name[VLR_NAME_LENGTH+1]; /* proprietary */ OSMO_LBUF_DECL(hlr, 16); /* 2.4.7 */ - uint32_t periodic_lu_timer; /* 2.4.24 */ uint32_t age_indicator; /* 2.17.1 */ /* Authentication Data */ @@ -194,6 +197,8 @@ struct vlr_subscr { vlr_sgs_lu_mminfo_cb_t mminfo_cb; enum sgsap_service_ind paging_serv_ind; struct osmo_timer_list Ts5; + bool last_eutran_plmn_present; + struct osmo_plmn_id last_eutran_plmn; } sgs; struct osmo_gsm48_classmark classmark; @@ -252,13 +257,8 @@ struct vlr_ops { /* notify MSC/SGSN that the given subscriber has been associated * with this msc_conn_ref */ int (*subscr_assoc)(void *msc_conn_ref, struct vlr_subscr *vsub); -}; - -enum vlr_timer { - VLR_T_3250, - VLR_T_3260, - VLR_T_3270, - _NUM_VLR_TIMERS + /* notify MSC that the given subscriber is no longer valid */ + void (*subscr_inval)(void *msc_conn_ref, struct vlr_subscr *vsub); }; /* An instance of the VLR codebase */ @@ -277,8 +277,11 @@ struct vlr_instance { bool auth_reuse_old_sets_on_error; bool parq_retrieve_imsi; bool is_ps; - uint32_t timer[_NUM_VLR_TIMERS]; + uint8_t nri_bitlen; + struct osmo_nri_ranges *nri_ranges; } cfg; + struct osmo_stat_item_group *statg; + struct rate_ctr_group *ctrg; /* A free-form pointer for use by the caller */ void *user_ctx; }; @@ -300,7 +303,8 @@ vlr_loc_update(struct osmo_fsm_inst *parent, const struct osmo_location_area_id *old_lai, const struct osmo_location_area_id *new_lai, bool authentication_required, - bool ciphering_required, + bool is_ciphering_to_be_attempted, + bool is_ciphering_required, uint8_t key_seq, bool is_r99, bool is_utran, bool assign_tmsi); @@ -312,7 +316,7 @@ void vlr_loc_update_cancel(struct osmo_fsm_inst *fi, /* tell the VLR that the RAN connection is gone */ int vlr_subscr_disconnected(struct vlr_subscr *vsub); bool vlr_subscr_expire(struct vlr_subscr *vsub); -int vlr_subscr_rx_id_resp(struct vlr_subscr *vsub, const uint8_t *mi, size_t mi_len); +int vlr_subscr_rx_id_resp(struct vlr_subscr *vsub, const struct osmo_mobile_identity *mi); int vlr_subscr_rx_auth_resp(struct vlr_subscr *vsub, bool is_r99, bool is_utran, const uint8_t *res, uint8_t res_len); int vlr_subscr_rx_auth_fail(struct vlr_subscr *vsub, const uint8_t *auts); @@ -363,6 +367,9 @@ const char *vlr_subscr_msisdn_or_name(const struct vlr_subscr *vsub); #define vlr_subscr_find_by_msisdn(vlr, msisdn, USE) \ _vlr_subscr_find_by_msisdn(vlr, msisdn, USE, __FILE__, __LINE__) +#define vlr_subscr_find_by_mi(vlr, mi, USE) \ + _vlr_subscr_find_by_mi(vlr, mi, USE, __FILE__, __LINE__) + struct vlr_subscr *_vlr_subscr_find_by_imsi(struct vlr_instance *vlr, const char *imsi, const char *use, @@ -390,6 +397,11 @@ struct vlr_subscr *_vlr_subscr_find_by_msisdn(struct vlr_instance *vlr, const char *use, const char *file, int line); +struct vlr_subscr *_vlr_subscr_find_by_mi(struct vlr_instance *vlr, + const struct osmo_mobile_identity *mi, + const char *use, + const char *file, int line); + #define vlr_subscr_get(VSUB, USE) vlr_subscr_get_src(VSUB, USE, __FILE__, __LINE__) #define vlr_subscr_put(VSUB, USE) vlr_subscr_put_src(VSUB, USE, __FILE__, __LINE__) @@ -405,6 +417,8 @@ void vlr_subscr_set_imsi(struct vlr_subscr *vsub, const char *imsi); void vlr_subscr_set_imei(struct vlr_subscr *vsub, const char *imei); void vlr_subscr_set_imeisv(struct vlr_subscr *vsub, const char *imeisv); void vlr_subscr_set_msisdn(struct vlr_subscr *vsub, const char *msisdn); +void vlr_subscr_set_last_used_eutran_plmn_id(struct vlr_subscr *vsub, + const struct osmo_plmn_id *last_eutran_plmn); bool vlr_subscr_matches_imsi(struct vlr_subscr *vsub, const char *imsi); bool vlr_subscr_matches_tmsi(struct vlr_subscr *vsub, uint32_t tmsi); @@ -421,12 +435,14 @@ void vlr_subscr_cancel_attach_fsm(struct vlr_subscr *vsub, void vlr_subscr_enable_expire_lu(struct vlr_subscr *vsub); -/* Process Acccess Request FSM */ +/* Process Access Request FSM */ enum proc_arq_vlr_event { PR_ARQ_E_START, PR_ARQ_E_ID_IMSI, PR_ARQ_E_AUTH_RES, + PR_ARQ_E_AUTH_NO_INFO, + PR_ARQ_E_AUTH_FAILURE, PR_ARQ_E_CIPH_RES, PR_ARQ_E_UPD_LOC_RES, PR_ARQ_E_TRACE_RES, @@ -439,6 +455,7 @@ enum vlr_parq_type { VLR_PR_ARQ_T_INVALID = 0, /* to guard against unset vars */ VLR_PR_ARQ_T_CM_SERV_REQ, VLR_PR_ARQ_T_PAGING_RESP, + VLR_PR_ARQ_T_CM_RE_ESTABLISH_REQ, /* FIXME: differentiate between services of 24.008 10.5.3.3 */ }; @@ -450,10 +467,11 @@ vlr_proc_acc_req(struct osmo_fsm_inst *parent, void *parent_event_data, struct vlr_instance *vlr, void *msc_conn_ref, enum vlr_parq_type type, enum osmo_cm_service_type cm_service_type, - const uint8_t *mi_lv, + const struct osmo_mobile_identity *mi, const struct osmo_location_area_id *lai, bool authentication_required, - bool ciphering_required, + bool is_ciphering_to_be_attempted, + bool is_ciphering_required, uint8_t key_seq, bool is_r99, bool is_utran); @@ -466,7 +484,6 @@ void vlr_parq_fsm_init(void); int vlr_set_ciph_mode(struct vlr_instance *vlr, struct osmo_fsm_inst *fi, void *msc_conn_ref, - bool ciph_required, bool umts_aka, bool retrieve_imeisv); @@ -474,3 +491,6 @@ bool vlr_use_umts_aka(struct osmo_auth_vector *vec, bool is_r99); void log_set_filter_vlr_subscr(struct log_target *target, struct vlr_subscr *vlr_subscr); + +void vlr_gmm_cause_to_mm_cause(enum gsm48_gmm_cause gmm_cause, + enum gsm48_reject_value *gsm48_rej_p); diff --git a/include/osmocom/msc/vlr_sgs.h b/include/osmocom/msc/vlr_sgs.h index 00d52f7b4..aade5d342 100644 --- a/include/osmocom/msc/vlr_sgs.h +++ b/include/osmocom/msc/vlr_sgs.h @@ -26,14 +26,14 @@ enum vlr_lu_type; struct vlr_subscr; struct vlr_instance; -#define VSUB_USE_SGS "SGs" +#define VSUB_USE_SGS_LU "SGs-lu" #define VSUB_USE_SGS_PAGING_REQ "SGs-paging-req" /* See also 3GPP TS 29.118, chapter 4.2.2 States at the VLR */ enum sgs_ue_fsm_state { SGS_UE_ST_NULL, - SGS_UE_ST_ASSOCIATED, SGS_UE_ST_LA_UPD_PRES, + SGS_UE_ST_ASSOCIATED, }; enum vlr_sgs_state_tmr { @@ -69,12 +69,13 @@ static inline const char *vlr_sgs_state_timer_name(enum vlr_sgs_state_tmr Ts) extern const struct value_string sgs_state_counter_names[]; static inline const char *vlr_sgs_state_counter_name(enum vlr_sgs_state_ctr Ns) { - return get_value_string(sgs_state_timer_names, Ns); + return get_value_string(sgs_state_counter_names, Ns); } /* This callback function is called when an SGs location update is complete */ struct sgs_lu_response { bool accepted; + bool error; struct vlr_subscr *vsub; }; typedef void (*vlr_sgs_lu_response_cb_t) (struct sgs_lu_response *response); @@ -96,7 +97,7 @@ void vlr_sgs_reset(struct vlr_instance *vlr); int vlr_sgs_loc_update(struct vlr_instance *vlr, struct vlr_sgs_cfg *cfg, vlr_sgs_lu_response_cb_t response_cb, vlr_sgs_lu_paging_cb_t paging_cb, vlr_sgs_lu_mminfo_cb_t mminfo_cb, char *mme_name, enum vlr_lu_type type, const char *imsi, - struct osmo_location_area_id *new_lai); + struct osmo_location_area_id *new_lai, struct osmo_plmn_id *last_eutran_plmn); void vlr_sgs_loc_update_acc_sent(struct vlr_subscr *vsub); void vlr_sgs_loc_update_rej_sent(struct vlr_subscr *vsub); void vlr_sgs_detach(struct vlr_instance *vlr, const char *imsi, bool eps); diff --git a/include/osmocom/msc/vty.h b/include/osmocom/msc/vty.h index 2a3b18bdf..a7f1db7ca 100644 --- a/include/osmocom/msc/vty.h +++ b/include/osmocom/msc/vty.h @@ -17,6 +17,7 @@ extern struct cmd_element cfg_no_description_cmd; enum bsc_vty_node { GSMNET_NODE = _LAST_OSMOVTY_NODE + 1, + MGW_NODE, SUBSCR_NODE, MSC_NODE, MNCC_INT_NODE, @@ -24,11 +25,17 @@ enum bsc_vty_node { SMPP_ESME_NODE, HLR_NODE, CFG_SGS_NODE, + SMSC_NODE, + ASCI_NODE, + GCR_NODE, + VGC_NODE, + VBC_NODE, }; int bsc_vty_init_extra(void); void msc_vty_init(struct gsm_network *msc_network); +void smsc_vty_init(struct gsm_network *msc_network); struct gsm_network *gsmnet_from_vty(struct vty *vty); diff --git a/include/osmocom/smpp/Makefile.am b/include/osmocom/smpp/Makefile.am new file mode 100644 index 000000000..5ad34ad0d --- /dev/null +++ b/include/osmocom/smpp/Makefile.am @@ -0,0 +1,4 @@ +noinst_HEADERS = \ + smpp.h \ + smpp_smsc.h \ + $(NULL) diff --git a/include/osmocom/smpp/smpp.h b/include/osmocom/smpp/smpp.h new file mode 100644 index 000000000..a2832d304 --- /dev/null +++ b/include/osmocom/smpp/smpp.h @@ -0,0 +1,55 @@ +#pragma once + +#include <osmocom/msc/gsm_data.h> + +/* Length limits according to SMPP 3.4 spec including NUL-byte: */ +#define SMPP_SYS_ID_LEN 15 +#define SMPP_PASSWD_LEN 8 + +enum esme_read_state { + READ_ST_IN_LEN = 0, + READ_ST_IN_MSG = 1, +}; + +/* struct representing SMPP's External Short Messaging Entity */ +struct esme { + uint32_t own_seq_nr; + + struct osmo_wqueue wqueue; + enum esme_read_state read_state; + uint32_t read_len; + uint32_t read_idx; + struct msgb *read_msg; + + uint8_t smpp_version; + char system_id[SMPP_SYS_ID_LEN + 1]; + char password[SMPP_SYS_ID_LEN + 1]; +}; + +#define LOGPESME(ESME, LEVEL, FMT, ARGS...) \ + LOGP(DSMPP, LEVEL, "[%s] " FMT, (ESME)->system_id, ##ARGS) + +#define LOGPESMERR(ESME, FMT, ARGS...) \ + LOGPESME(ESME, LOGL_ERROR, "Error (%s) " FMT, smpp34_strerror, ##ARGS) + +/*! \brief Ugly wrapper. libsmpp34 should do this itself! */ +#define SMPP34_UNPACK(rc, type, str, data, len) { \ + memset(str, 0, sizeof(*str)); \ + rc = smpp34_unpack(type, str, data, len); } + +#define PACK_AND_SEND(esme, ptr) pack_and_send(esme, (ptr)->command_id, ptr) + +/*! \brief initialize the libsmpp34 data structure for a response */ +#define INIT_RESP(type, resp, req) { \ + memset((resp), 0, sizeof(*(resp))); \ + (resp)->command_length = 0; \ + (resp)->command_id = type; \ + (resp)->command_status = ESME_ROK; \ + (resp)->sequence_number = (req)->sequence_number; } + +struct esme *esme_alloc(void *ctx); +uint32_t smpp_msgb_cmdid(struct msgb *msg); +uint32_t esme_inc_seq_nr(struct esme *esme); +int pack_and_send(struct esme *esme, uint32_t type, void *ptr); +int smpp_msc_alloc_init(void *ctx); +int smpp_msc_start(struct gsm_network *net); diff --git a/src/libmsc/smpp_smsc.h b/include/osmocom/smpp/smpp_smsc.h index b26d01126..6d7647589 100644 --- a/src/libmsc/smpp_smsc.h +++ b/include/osmocom/smpp/smpp_smsc.h @@ -1,5 +1,4 @@ -#ifndef _SMPP_SMSC_H -#define _SMPP_SMSC_H +#pragma once #include <sys/socket.h> #include <netinet/in.h> @@ -8,24 +7,17 @@ #include <osmocom/core/msgb.h> #include <osmocom/core/write_queue.h> #include <osmocom/core/timer.h> +#include <osmocom/smpp/smpp.h> #include <smpp34.h> #include <smpp34_structs.h> #include <smpp34_params.h> -#define SMPP_SYS_ID_LEN 15 -#define SMPP_PASSWD_LEN 8 - #define MODE_7BIT 7 #define MODE_8BIT 8 struct msc_a; -enum esme_read_state { - READ_ST_IN_LEN = 0, - READ_ST_IN_MSG = 1, -}; - struct osmo_smpp_acl; struct osmo_smpp_addr { @@ -34,35 +26,24 @@ struct osmo_smpp_addr { char addr[21+1]; }; -struct osmo_esme { +/* struct wrapping ESME struct with additional SMSC-specific things like ACL, command list etc */ +struct smpp_esme { struct llist_head list; struct smsc *smsc; + struct esme *esme; struct osmo_smpp_acl *acl; int use; struct llist_head smpp_cmd_list; - uint32_t own_seq_nr; - - struct osmo_wqueue wqueue; - struct sockaddr_storage sa; - socklen_t sa_len; - - enum esme_read_state read_state; - uint32_t read_len; - uint32_t read_idx; - struct msgb *read_msg; - uint8_t smpp_version; - char system_id[SMPP_SYS_ID_LEN+1]; - uint8_t bind_flags; }; struct osmo_smpp_acl { struct llist_head list; struct smsc *smsc; - struct osmo_esme *esme; + struct smpp_esme *esme; char *description; char system_id[SMPP_SYS_ID_LEN+1]; char passwd[SMPP_PASSWD_LEN+1]; @@ -99,18 +80,18 @@ struct osmo_smpp_cmd { struct osmo_timer_list response_timer; }; -struct osmo_smpp_cmd *smpp_cmd_find_by_seqnum(struct osmo_esme *esme, +struct osmo_smpp_cmd *smpp_cmd_find_by_seqnum(struct smpp_esme *esme, uint32_t sequence_number); void smpp_cmd_ack(struct osmo_smpp_cmd *cmd); void smpp_cmd_err(struct osmo_smpp_cmd *cmd, uint32_t status); -void smpp_cmd_flush_pending(struct osmo_esme *esme); +void smpp_cmd_flush_pending(struct smpp_esme *esme); struct smsc { struct osmo_fd listen_ofd; struct llist_head esme_list; struct llist_head acl_list; struct llist_head route_list; - const char *bind_addr; + char *bind_addr; uint16_t listen_port; char system_id[SMPP_SYS_ID_LEN+1]; int accept_all; @@ -126,27 +107,26 @@ struct smsc *smpp_smsc_alloc_init(void *ctx); int smpp_smsc_conf(struct smsc *smsc, const char *bind_addr, uint16_t port); int smpp_smsc_start(struct smsc *smsc, const char *bind_addr, uint16_t port); int smpp_smsc_restart(struct smsc *smsc, const char *bind_addr, uint16_t port); -void smpp_smsc_stop(struct smsc *smsc); -void smpp_esme_get(struct osmo_esme *esme); -void smpp_esme_put(struct osmo_esme *esme); +void smpp_esme_get(struct smpp_esme *esme); +void smpp_esme_put(struct smpp_esme *esme); -int smpp_route(const struct smsc *smsc, const struct osmo_smpp_addr *dest, struct osmo_esme **emse); +int smpp_route(const struct smsc *smsc, const struct osmo_smpp_addr *dest, struct smpp_esme **emse); struct osmo_smpp_acl *smpp_acl_alloc(struct smsc *smsc, const char *sys_id); struct osmo_smpp_acl *smpp_acl_by_system_id(struct smsc *smsc, const char *sys_id); void smpp_acl_delete(struct osmo_smpp_acl *acl); -int smpp_tx_submit_r(struct osmo_esme *esme, uint32_t sequence_nr, +int smpp_tx_submit_r(struct smpp_esme *esme, uint32_t sequence_nr, uint32_t command_status, char *msg_id); -int smpp_tx_alert(struct osmo_esme *esme, uint8_t ton, uint8_t npi, +int smpp_tx_alert(struct smpp_esme *esme, uint8_t ton, uint8_t npi, const char *addr, uint8_t avail_status); -int smpp_tx_deliver(struct osmo_esme *esme, struct deliver_sm_t *deliver); +int smpp_tx_deliver(struct smpp_esme *esme, struct deliver_sm_t *deliver); -int handle_smpp_submit(struct osmo_esme *esme, struct submit_sm_t *submit, +int handle_smpp_submit(struct smpp_esme *esme, struct submit_sm_t *submit, struct submit_sm_resp_t *submit_r); int smpp_route_pfx_add(struct osmo_smpp_acl *acl, @@ -158,6 +138,7 @@ int smpp_vty_init(void); int smpp_determine_scheme(uint8_t dcs, uint8_t *data_coding, int *mode); +time_t smpp_parse_time_format(const char *vp, time_t *t_now); struct gsm_sms; @@ -165,4 +146,3 @@ struct ran_conn; bool smpp_route_smpp_first(); int smpp_try_deliver(struct gsm_sms *sms, struct msc_a *msc_a); -#endif diff --git a/m4/ax_check_compile_flag.m4 b/m4/ax_check_compile_flag.m4 deleted file mode 100644 index ca3639715..000000000 --- a/m4/ax_check_compile_flag.m4 +++ /dev/null @@ -1,74 +0,0 @@ -# =========================================================================== -# http://www.gnu.org/software/autoconf-archive/ax_check_compile_flag.html -# =========================================================================== -# -# SYNOPSIS -# -# AX_CHECK_COMPILE_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS], [INPUT]) -# -# DESCRIPTION -# -# Check whether the given FLAG works with the current language's compiler -# or gives an error. (Warnings, however, are ignored) -# -# ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on -# success/failure. -# -# If EXTRA-FLAGS is defined, it is added to the current language's default -# flags (e.g. CFLAGS) when the check is done. The check is thus made with -# the flags: "CFLAGS EXTRA-FLAGS FLAG". This can for example be used to -# force the compiler to issue an error when a bad flag is given. -# -# INPUT gives an alternative input source to AC_COMPILE_IFELSE. -# -# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this -# macro in sync with AX_CHECK_{PREPROC,LINK}_FLAG. -# -# LICENSE -# -# Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de> -# Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.com> -# -# 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/>. -# -# As a special exception, the respective Autoconf Macro's copyright owner -# gives unlimited permission to copy, distribute and modify the configure -# scripts that are the output of Autoconf when processing the Macro. You -# need not follow the terms of the GNU General Public License when using -# or distributing such scripts, even though portions of the text of the -# Macro appear in them. The GNU General Public License (GPL) does govern -# all other use of the material that constitutes the Autoconf Macro. -# -# This special exception to the GPL applies to versions of the Autoconf -# Macro released by the Autoconf Archive. When you make and distribute a -# modified version of the Autoconf Macro, you may extend this special -# exception to the GPL to apply to your modified version as well. - -#serial 4 - -AC_DEFUN([AX_CHECK_COMPILE_FLAG], -[AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_IF -AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_[]_AC_LANG_ABBREV[]flags_$4_$1])dnl -AC_CACHE_CHECK([whether _AC_LANG compiler accepts $1], CACHEVAR, [ - ax_check_save_flags=$[]_AC_LANG_PREFIX[]FLAGS - _AC_LANG_PREFIX[]FLAGS="$[]_AC_LANG_PREFIX[]FLAGS $4 $1" - AC_COMPILE_IFELSE([m4_default([$5],[AC_LANG_PROGRAM()])], - [AS_VAR_SET(CACHEVAR,[yes])], - [AS_VAR_SET(CACHEVAR,[no])]) - _AC_LANG_PREFIX[]FLAGS=$ax_check_save_flags]) -AS_VAR_IF(CACHEVAR,yes, - [m4_default([$2], :)], - [m4_default([$3], :)]) -AS_VAR_POPDEF([CACHEVAR])dnl -])dnl AX_CHECK_COMPILE_FLAGS diff --git a/osmoappdesc.py b/osmoappdesc.py index 886c682a7..b7a274c92 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 @@ -14,13 +14,16 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/> +import os + app_configs = { - "msc": ["doc/examples/osmo-msc/osmo-msc.cfg", - "doc/examples/osmo-msc/osmo-msc_custom-sccp.cfg", - "doc/examples/osmo-msc/osmo-msc_multi-cs7.cfg", - ], + "msc": ["doc/examples/osmo-msc/osmo-msc.cfg"], } +if os.environ["IU"] == "1": + app_configs["msc"] += ["doc/examples/osmo-msc/osmo-msc_custom-sccp.cfg", + "doc/examples/osmo-msc/osmo-msc_multi-cs7.cfg"] + apps = [(4254, "src/osmo-msc/osmo-msc", "OsmoMSC", "msc"), ] diff --git a/src/Makefile.am b/src/Makefile.am index 4e7cea19b..746c80d0f 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -13,20 +13,22 @@ AM_CFLAGS = \ $(COVERAGE_CFLAGS) \ $(NULL) -AM_LDFLAGS = \ - $(LIBOSMOCORE_LIBS) \ - $(LIBOSMOGSM_LIBS) \ - $(COVERAGE_LDFLAGS) \ - $(NULL) - # Libraries SUBDIRS = \ libvlr \ libmsc \ $(NULL) +if BUILD_SMPP + +SUBDIRS += \ + libsmpputil \ + utils \ + $(NULL) + +endif + # Programs SUBDIRS += \ osmo-msc \ - utils \ $(NULL) diff --git a/src/libmsc/Makefile.am b/src/libmsc/Makefile.am index d83489680..dff4b2db0 100644 --- a/src/libmsc/Makefile.am +++ b/src/libmsc/Makefile.am @@ -20,9 +20,6 @@ AM_CFLAGS = \ $(LIBOSMONETIF_CFLAGS) \ $(NULL) -noinst_HEADERS = \ - $(NULL) - noinst_LIBRARIES = \ libmsc.a \ $(NULL) @@ -30,6 +27,10 @@ noinst_LIBRARIES = \ libmsc_a_SOURCES = \ call_leg.c \ cell_id_list.c \ + codec_filter.c \ + codec_mapping.c \ + csd_bs.c \ + csd_filter.c \ sccp_ran.c \ msc_vty.c \ db.c \ @@ -54,6 +55,7 @@ libmsc_a_SOURCES = \ msc_t.c \ msc_t_remote.c \ msc_ho.c \ + msc_vgcs.c \ neighbor_ident.c \ neighbor_ident_vty.c \ paging.c \ @@ -64,14 +66,19 @@ libmsc_a_SOURCES = \ ran_peer.c \ rrlp.c \ rtp_stream.c \ + sdp_msg.c \ silent_call.c \ sms_queue.c \ + smsc_vty.c \ transaction.c \ + transaction_cc.c \ msc_net_init.c \ ctrl_commands.c \ sgs_iface.c \ sgs_server.c \ sgs_vty.c \ + asci_gcr.c \ + asci_vty.c \ $(NULL) if BUILD_IU @@ -79,16 +86,3 @@ libmsc_a_SOURCES += \ ran_msg_iu.c \ $(NULL) endif - -if BUILD_SMPP -noinst_HEADERS += \ - smpp_smsc.h \ - $(NULL) - -libmsc_a_SOURCES += \ - smpp_smsc.c \ - smpp_openbsc.c \ - smpp_vty.c \ - smpp_utils.c \ - $(NULL) -endif diff --git a/src/libmsc/asci_gcr.c b/src/libmsc/asci_gcr.c new file mode 100644 index 000000000..220815136 --- /dev/null +++ b/src/libmsc/asci_gcr.c @@ -0,0 +1,175 @@ +/* Group Call Register (GCR) */ +/* + * (C) 2023 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de> + * All Rights Reserved + * + * SPDX-License-Identifier: AGPL-3.0+ + * + * Author: Andreas Eversberg + * + * 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/msc/gsm_data.h> +#include <osmocom/msc/transaction.h> + +#include <osmocom/msc/asci_gcr.h> + +#define GCR_DEFAULT_TIMEOUT 60 + +static uint32_t pow10[9] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000 }; + +/* Add cell to BSS list. */ +struct gcr_cell *gcr_add_cell(struct gcr_bss *bss, uint16_t cell_id) +{ + struct gcr_cell *c; + + c = talloc_zero(bss, struct gcr_cell); + if (!c) + return NULL; + c->cell_id = cell_id; + llist_add_tail(&c->list, &bss->cell_list); + + return c; +} + +/* Find cell entry in BSS list. */ +struct gcr_cell *gcr_find_cell(struct gcr_bss *bss, uint16_t cell_id) +{ + struct gcr_cell *c; + + llist_for_each_entry(c, &bss->cell_list, list) { + if (c->cell_id == cell_id) + return c; + } + + return NULL; +} + +/* Remove cell entry from BSS list. */ +void gcr_rm_cell(struct gcr_bss *bss, uint16_t cell_id) +{ + struct gcr_cell *c = gcr_find_cell(bss, cell_id); + + if (c) { + llist_del(&c->list); + talloc_free(c); + } +} + +/* Add BSS to GCR list. */ +struct gcr_bss *gcr_add_bss(struct gcr *gcr, int pc) +{ + struct gcr_bss *b; + + b = talloc_zero(gcr, struct gcr_bss); + if (!b) + return NULL; + INIT_LLIST_HEAD(&b->cell_list); + b->pc = pc; + llist_add_tail(&b->list, &gcr->bss_list); + + return b; +} + +/* Find BSS entry in GCR list. */ +struct gcr_bss *gcr_find_bss(struct gcr *gcr, int pc) +{ + struct gcr_bss *b; + + llist_for_each_entry(b, &gcr->bss_list, list) { + if (b->pc == pc) + return b; + } + + return NULL; +} + +/* Remove BSS entry from GCR list. */ +void gcr_rm_bss(struct gcr *gcr, int pc) +{ + struct gcr_bss *b = gcr_find_bss(gcr, pc); + + if (b) { + /* All cell definitons will be removed, as they are attached to BSS. */ + llist_del(&b->list); + talloc_free(b); + } +} + +/* Create a new (empty) GCR list. */ +struct gcr *gcr_create(struct gsm_network *gsmnet, enum trans_type trans_type, const char *group_id) +{ + struct gcr *gcr; + + gcr = talloc_zero(gsmnet, struct gcr); + if (!gcr) + return NULL; + + INIT_LLIST_HEAD(&gcr->bss_list); + gcr->trans_type = trans_type; + gcr->timeout = GCR_DEFAULT_TIMEOUT; + gcr->mute_talker = true; + osmo_strlcpy(gcr->group_id, group_id, sizeof(gcr->group_id)); + llist_add_tail(&gcr->list, &gsmnet->asci.gcr_lists); + + return gcr; +} + +/* Destroy a GCR list. */ +void gcr_destroy(struct gcr *gcr) +{ + /* All BSS definitons will be removed, as they are attached to GCR. */ + llist_del(&gcr->list); + talloc_free(gcr); +} + +/* Find GCR list by group ID. */ +struct gcr *gcr_by_group_id(struct gsm_network *gsmnet, enum trans_type trans_type, const char *group_id) +{ + struct gcr *gcr; + + llist_for_each_entry(gcr, &gsmnet->asci.gcr_lists, list) { + if (gcr->trans_type == trans_type && !strcmp(gcr->group_id, group_id)) + return gcr; + } + + return NULL; +} + +/* Find GCR list by callref. */ +struct gcr *gcr_by_callref(struct gsm_network *gsmnet, enum trans_type trans_type, uint32_t callref) +{ + struct gcr *most_specific_gcr = NULL, *gcr; + int a, b; + size_t most_specific_len = 0, l; + + llist_for_each_entry(gcr, &gsmnet->asci.gcr_lists, list) { + /* Compare only the digits in Group ID with the digits in callref. + * callref is an integer. Only the remainder, based on Group ID length, is checked. */ + l = strlen(gcr->group_id); + a = atoi(gcr->group_id); + OSMO_ASSERT(l < ARRAY_SIZE(pow10)); + b = callref % pow10[l]; + if (gcr->trans_type == trans_type && a == b) { + /* Get most specific GROUP ID, no matter what order they are stored. */ + if (l > most_specific_len) { + most_specific_gcr = gcr; + most_specific_len = l; + } + } + } + + return most_specific_gcr; +} diff --git a/src/libmsc/asci_vty.c b/src/libmsc/asci_vty.c new file mode 100644 index 000000000..a138eda51 --- /dev/null +++ b/src/libmsc/asci_vty.c @@ -0,0 +1,434 @@ +/* GCR interface to VTY */ +/* + * (C) 2023 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de> + * All Rights Reserved + * + * SPDX-License-Identifier: AGPL-3.0+ + * + * Author: Andreas Eversberg + * + * 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/msc/vty.h> +#include <osmocom/msc/transaction.h> +#include <osmocom/msc/msc_vgcs.h> +#include <osmocom/msc/asci_vty.h> +#include <osmocom/msc/asci_gcr.h> + +static struct gsm_network *gsmnet; + +/*********************************************************************** + * ASCI Node + ***********************************************************************/ + +#define ASCI_STR "Advanced Speech Call Items\n" + +static void asci_disabled(struct vty *vty) +{ + vty_out(vty, "%%Advanced Speech Call Items are disabled.%s", VTY_NEWLINE); +} + +DEFUN(asci_call, asci_call_cmd, + "asci (initiate|terminate) (vgc|vbc) CALLREF", + ASCI_STR "Initiate a call\nTerminate a call\nVoice Group Call\nVoice Broadcast Call\nCall reference") +{ + struct gcr *gcr; + const char *error; + + if (!gsmnet->asci.enable) { + asci_disabled(vty); + return CMD_WARNING; + } + + gcr = gcr_by_group_id(gsmnet, (argv[1][1] == 'g') ? TRANS_GCC : TRANS_BCC, argv[2]); + if (!gcr) { + vty_out(vty, "%%Given call ref does not exist in GCR.%s", VTY_NEWLINE); + return CMD_WARNING; + } + if (argv[0][0] == 'i') + error = vgcs_vty_initiate(gsmnet, gcr); + else + error = vgcs_vty_terminate(gsmnet, gcr); + if (error) { + vty_out(vty, "%%%s%s", error, VTY_NEWLINE); + return CMD_WARNING; + } + return CMD_SUCCESS; +} + +DEFUN(asci_show, asci_show_cmd, + "show asci calls", + SHOW_STR ASCI_STR "Show all Voice Group/Broadcast Calls") +{ + struct gsm_trans *trans; + const char *typestr; + struct vgcs_bss *bss; + struct vgcs_bss_cell *cell; + + if (!gsmnet->asci.enable) { + asci_disabled(vty); + return CMD_WARNING; + } + + llist_for_each_entry(trans, &gsmnet->trans_list, entry) { + if (trans->type == TRANS_GCC) + typestr = "Group"; + else if (trans->type == TRANS_BCC) + typestr = "Broadcast"; + else + continue; + vty_out(vty, "Call Reference %s (Voice %s Call).%s", gsm44068_group_id_string(trans->callref), + typestr, VTY_NEWLINE); + vty_out(vty, " Call state : %s%s", vgcs_bcc_gcc_state_name(trans->gcc.fi), VTY_NEWLINE); + vty_out(vty, " Uplink state: %s%s", (trans->gcc.uplink_busy) ? "busy" : "free", VTY_NEWLINE); + if (trans->gcc.uplink_busy) + vty_out(vty, " Talker : %s subscriber%s", + (trans->gcc.uplink_originator) ? "calling" : "other", VTY_NEWLINE); + llist_for_each_entry(bss, &trans->gcc.bss_list, list) { + vty_out(vty, " BSS %8s: listening%s%s", osmo_ss7_pointcode_print(NULL, bss->pc), + (trans->gcc.uplink_busy && bss == trans->gcc.uplink_bss) ? "+talking" : "", + VTY_NEWLINE); + llist_for_each_entry(cell, &bss->cell_list, list_bss) { + vty_out(vty, " Cell %6d: listening%s%s", cell->cell_id, + (trans->gcc.uplink_busy && cell == trans->gcc.uplink_cell) ? "+talking" : "", + VTY_NEWLINE); + } + } + } + + return CMD_SUCCESS; +} + +/*********************************************************************** + * GCR Config Node + ***********************************************************************/ + +static struct cmd_node asci_node = { + ASCI_NODE, + "%s(config-asci)# ", + 1, +}; + +static struct cmd_node gcr_node = { + GCR_NODE, + "%s(config-gcr)# ", + 1, +}; + +char conf_prompt[64]; + +static struct cmd_node vgc_node = { + VGC_NODE, + conf_prompt, + 1, +}; + +static struct cmd_node vbc_node = { + VBC_NODE, + conf_prompt, + 1, +}; + +DEFUN(cfg_asci, cfg_asci_cmd, + "asci", "Enable and configure " ASCI_STR) +{ + vty->node = ASCI_NODE; + return CMD_SUCCESS; +} + +DEFUN(cfg_enable_disable, cfg_enable_disable_cmd, + "(enable|disable)", "Enable " ASCI_STR "Disable " ASCI_STR) +{ + gsmnet->asci.enable = (argv[0][0] == 'e'); + return CMD_SUCCESS; +} + +DEFUN(cfg_gcr, cfg_gcr_cmd, + "gcr", "Configure Group Call Register") +{ + vty->node = GCR_NODE; + return CMD_SUCCESS; +} + +static bool valid_group_id(const char *id, struct vty *vty) +{ + int i; + + if (strlen(id) < 1 || strlen(id) > 8) { + vty_out(vty, "%%Given group ID is not valid. Use up to 8 numeric digits!%s", VTY_NEWLINE); + return false; + } + for (i = 0; i < strlen(id); i++) { + if (id[i] < '0' || id[i] > '9') { + vty_out(vty, "%%Given group ID is not valid. Use numeric digits only!%s", VTY_NEWLINE); + return false; + } + } + + return true; +} + +DEFUN(cfg_vgc, cfg_vgc_cmd, + "vgc ID", "Configure Voice Group Call\n" "Group ID") +{ + struct gcr *gcr; + + if (!valid_group_id(argv[0], vty)) + return CMD_WARNING; + + gcr = gcr_by_group_id(gsmnet, TRANS_GCC, argv[0]); + if (!gcr) + gcr = gcr_create(gsmnet, TRANS_GCC, argv[0]); + if (!gcr) + return CMD_WARNING; + + sprintf(conf_prompt, "%%s(vgc-%s)# ", gcr->group_id); + vty->node = VGC_NODE; + vty->index = gcr; + return CMD_SUCCESS; +} + +DEFUN(cfg_no_vgc, cfg_no_vgc_cmd, + "no vgc ID", NO_STR "Configure Voice Group Call\n" "Group ID") +{ + struct gcr *gcr; + + if (!valid_group_id(argv[0], vty)) + return CMD_WARNING; + + gcr = gcr_by_group_id(gsmnet, TRANS_GCC, argv[0]); + if (!gcr) { + vty_out(vty, "%%Voice group call with given group ID does not exit!%s", VTY_NEWLINE); + return CMD_WARNING; + } + gcr_destroy(gcr); + + return CMD_SUCCESS; +} + +DEFUN(cfg_vbc, cfg_vbc_cmd, + "vbc ID", "Configure Voice Broadcast Call\n" "Group ID") +{ + struct gcr *gcr; + + if (!valid_group_id(argv[0], vty)) + return CMD_WARNING; + + gcr = gcr_by_group_id(gsmnet, TRANS_BCC, argv[0]); + if (!gcr) + gcr = gcr_create(gsmnet, TRANS_BCC, argv[0]); + if (!gcr) + return CMD_WARNING; + + sprintf(conf_prompt, "%%s(vbc-%s)# ", gcr->group_id); + vty->node = VBC_NODE; + vty->index = gcr; + return CMD_SUCCESS; +} + +DEFUN(cfg_no_vbc, cfg_no_vbc_cmd, + "no vbc ID", NO_STR "Configure Voice Broadcast Call\n" "Group ID") +{ + struct gcr *gcr; + + if (!valid_group_id(argv[0], vty)) + return CMD_WARNING; + + gcr = gcr_by_group_id(gsmnet, TRANS_BCC, argv[0]); + if (!gcr) { + vty_out(vty, "%%Voice broadcast call with given group ID does not exit!%s", VTY_NEWLINE); + return CMD_WARNING; + } + gcr_destroy(gcr); + + return CMD_SUCCESS; +} + +DEFUN(cfg_mute, cfg_mute_cmd, + "mute-talker", "Mute talker's downlink") +{ + struct gcr *gcr = vty->index; + + gcr->mute_talker = true; + + return CMD_SUCCESS; +} + +DEFUN(cfg_unmute, cfg_unmute_cmd, + "unmute-talker", "Unmute talker's downlink") +{ + struct gcr *gcr = vty->index; + + gcr->mute_talker = false; + + return CMD_SUCCESS; +} + +DEFUN(cfg_timeout, cfg_timeout_cmd, + "timeout <1-65535>", "Set inactivity timer\n" "Timeout in seconds") +{ + struct gcr *gcr = vty->index; + + gcr->timeout = atoi(argv[0]); + + return CMD_SUCCESS; +} + +DEFUN(cfg_no_timeout, cfg_no_timeout_cmd, + "no timeout", NO_STR "Unset inactivity timer") +{ + struct gcr *gcr = vty->index; + + gcr->timeout = 0; + + return CMD_SUCCESS; +} + +#define PC_ID_STR "Point code of MSC\nCell ID of BTS" + +DEFUN(cfg_no_cell, cfg_no_cell_cmd, + "no cell POINT_CODE [<0-65535>]", NO_STR "Remove BSS/cell from current group\n" PC_ID_STR) +{ + struct osmo_ss7_instance *ss7 = osmo_ss7_instance_find(0); + struct gcr *gcr = vty->index; + struct gcr_bss *bss; + int pc = osmo_ss7_pointcode_parse(ss7, argv[0]); + uint16_t cell_id; + + if (pc < 0 || !osmo_ss7_pc_is_valid((uint32_t)pc)) { + vty_out(vty, "Invalid point code (%s)%s", argv[0], VTY_NEWLINE); + return CMD_WARNING; + } + + bss = gcr_find_bss(gcr, pc); + if (!bss) { + vty_out(vty, "%%Given BSS point code does not exit in list!%s", VTY_NEWLINE); + return CMD_WARNING; + } + + if (argc > 1) { + cell_id = atoi(argv[1]); + if (!gcr_find_cell(bss, cell_id)) { + vty_out(vty, "%%Given cell does not exit in list!%s", VTY_NEWLINE); + return CMD_WARNING; + } + + /* Remove cell only. Exit if there are still cells for this BSS. */ + gcr_rm_cell(bss, cell_id); + if (!llist_empty(&bss->cell_list)) + return CMD_SUCCESS; + } + + gcr_rm_bss(gcr, pc); + + return CMD_SUCCESS; +} + +DEFUN(cfg_cell, cfg_cell_cmd, + "cell POINT_CODE <0-65535>", "Add cell to current group\n" PC_ID_STR) +{ + struct osmo_ss7_instance *ss7 = osmo_ss7_instance_find(0); + struct gcr *gcr = vty->index; + struct gcr_bss *bss; + int pc = osmo_ss7_pointcode_parse(ss7, argv[0]); + uint16_t cell_id = atoi(argv[1]); + + if (pc < 0 || !osmo_ss7_pc_is_valid((uint32_t)pc)) { + vty_out(vty, "Invalid point code (%s)%s", argv[0], VTY_NEWLINE); + return CMD_WARNING; + } + + bss = gcr_find_bss(gcr, pc); + if (!bss) + bss = gcr_add_bss(gcr, pc); + if (!bss) + return CMD_WARNING; + + if (gcr_find_cell(bss, cell_id)) + return CMD_SUCCESS; + + gcr_add_cell(bss, cell_id); + + return CMD_SUCCESS; +} + +static int config_write_asci(struct vty *vty) +{ + struct osmo_ss7_instance *ss7 = osmo_ss7_instance_find(0); + struct gcr *gcr; + struct gcr_bss *b; + struct gcr_cell *c; + + vty_out(vty, "asci%s", VTY_NEWLINE); + + vty_out(vty, " %s%s", (gsmnet->asci.enable) ? "enable" : "disable", VTY_NEWLINE); + + vty_out(vty, " gcr%s", VTY_NEWLINE); + + llist_for_each_entry(gcr, &gsmnet->asci.gcr_lists, list) { + vty_out(vty, " %s %s%s", (gcr->trans_type == TRANS_GCC) ? "vgc" : "vbc", gcr->group_id, VTY_NEWLINE); + if (gcr->trans_type == TRANS_GCC) { + if (gcr->timeout) + vty_out(vty, " timeout %d%s", gcr->timeout, VTY_NEWLINE); + else + vty_out(vty, " no timeout%s", VTY_NEWLINE); + } + if (gcr->mute_talker) + vty_out(vty, " mute-talker%s", VTY_NEWLINE); + else + vty_out(vty, " unmute-talker%s", VTY_NEWLINE); + if (llist_empty(&gcr->bss_list)) + vty_out(vty, " ! Please add cell(s) here!%s", VTY_NEWLINE); + llist_for_each_entry(b, &gcr->bss_list, list) { + llist_for_each_entry(c, &b->cell_list, list) + vty_out(vty, " cell %s %d%s", osmo_ss7_pointcode_print(ss7, b->pc), c->cell_id, VTY_NEWLINE); + } + } + + return CMD_SUCCESS; +} + +void asci_vty_init(struct gsm_network *msc_network) +{ + OSMO_ASSERT(gsmnet == NULL); + gsmnet = msc_network; + + install_element_ve(&asci_show_cmd); + /* enable node */ + install_element(ENABLE_NODE, &asci_call_cmd); + /* Config node */ + install_element(CONFIG_NODE, &cfg_asci_cmd); + install_node(&asci_node, config_write_asci); + install_element(ASCI_NODE, &cfg_enable_disable_cmd); + install_element(ASCI_NODE, &cfg_gcr_cmd); + install_node(&gcr_node, NULL); + install_element(GCR_NODE, &cfg_vgc_cmd); + install_element(GCR_NODE, &cfg_no_vgc_cmd); + install_node(&vgc_node, NULL); + install_element(GCR_NODE, &cfg_vbc_cmd); + install_element(GCR_NODE, &cfg_no_vbc_cmd); + install_node(&vbc_node, NULL); + install_element(VGC_NODE, &cfg_mute_cmd); + install_element(VGC_NODE, &cfg_unmute_cmd); + install_element(VGC_NODE, &cfg_timeout_cmd); + install_element(VGC_NODE, &cfg_no_timeout_cmd); + install_element(VGC_NODE, &cfg_cell_cmd); + install_element(VGC_NODE, &cfg_no_cell_cmd); + /* Add all VGC_NODEs again for VBC_NODEs. */ + install_element(VBC_NODE, &cfg_mute_cmd); + install_element(VBC_NODE, &cfg_unmute_cmd); + install_element(VBC_NODE, &cfg_cell_cmd); + install_element(VBC_NODE, &cfg_no_cell_cmd); +} diff --git a/src/libmsc/call_leg.c b/src/libmsc/call_leg.c index 46405bcaa..59f2f636d 100644 --- a/src/libmsc/call_leg.c +++ b/src/libmsc/call_leg.c @@ -1,25 +1,21 @@ /* Implementation to manage two RTP streams that make up an MO or MT call leg's RTP forwarding. */ /* - * (C) 2019 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de> + * (C) 2019 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de> * All Rights Reserved * * Author: Neels Hofmeyr * - * SPDX-License-Identifier: GPL-2.0+ + * SPDX-License-Identifier: AGPL-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 2 of the License, or + * 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 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. + * GNU Affero General Public License for more details. */ #include <osmocom/core/fsm.h> #include <osmocom/mgcp_client/mgcp_client_endpoint_fsm.h> @@ -43,7 +39,7 @@ enum call_leg_state { }; struct osmo_tdef g_mgw_tdefs[] = { - { .T=-1, .default_val=4, .desc="MGCP response timeout" }, + { .T=-2427, .default_val=4, .desc="MGCP response timeout" }, { .T=-2, .default_val=30, .desc="RTP stream establishing timeout" }, {} }; @@ -126,7 +122,13 @@ void call_leg_release(struct call_leg *cl) static void call_leg_mgw_endpoint_gone(struct call_leg *cl) { + struct mgcp_client *mgcp_client; int i; + + /* Put MGCP client back into MGW pool */ + mgcp_client = osmo_mgcpc_ep_client(cl->mgw_endpoint); + mgcp_client_pool_put(mgcp_client); + cl->mgw_endpoint = NULL; for (i = 0; i < ARRAY_SIZE(cl->rtp); i++) { if (!cl->rtp[i]) @@ -156,7 +158,8 @@ static void call_leg_fsm_establishing_established(struct osmo_fsm_inst *fi, uint } if (!established) break; - call_leg_state_chg(cl, CALL_LEG_ST_ESTABLISHED); + if (cl->fi->state != CALL_LEG_ST_ESTABLISHED) + call_leg_state_chg(cl, CALL_LEG_ST_ESTABLISHED); break; case CALL_LEG_EV_RTP_STREAM_ADDR_AVAILABLE: @@ -186,6 +189,12 @@ void call_leg_fsm_established_onenter(struct osmo_fsm_inst *fi, uint32_t prev_st void call_leg_fsm_releasing_onenter(struct osmo_fsm_inst *fi, uint32_t prev_state) { + /* Trigger termination of children FSMs (rtp_stream(s)) before + * terminating ourselves, otherwise we are not able to receive + * CALL_LEG_EV_MGW_ENDPOINT_GONE from cl->mgw_endpoint (call_leg => + * rtp_stream => mgw_endpoint), because osmo_fsm disabled dispatching + * events to an FSM in process of terminating. */ + osmo_fsm_inst_term_children(fi, OSMO_FSM_TERM_PARENT, NULL); osmo_fsm_inst_term(fi, OSMO_FSM_TERM_REGULAR, NULL); } @@ -279,16 +288,24 @@ int call_leg_ensure_rtp_alloc(struct call_leg *cl, enum rtp_direction dir, uint3 if (cl->rtp[dir]) return 0; - if (!cl->mgw_endpoint) + if (!cl->mgw_endpoint) { + struct mgcp_client *mgcp_client = mgcp_client_pool_get(gsmnet->mgw.mgw_pool); + if (!mgcp_client) { + LOG_CALL_LEG(cl, LOGL_ERROR, + "cannot ensure MGW endpoint -- no MGW configured, check configuration!\n"); + return -ENODEV; + } cl->mgw_endpoint = osmo_mgcpc_ep_alloc(cl->fi, CALL_LEG_EV_MGW_ENDPOINT_GONE, - gsmnet->mgw.client, gsmnet->mgw.tdefs, cl->fi->id, - "%s", mgcp_client_rtpbridge_wildcard(gsmnet->mgw.client)); + mgcp_client, gsmnet->mgw.tdefs, cl->fi->id, + "%s", mgcp_client_rtpbridge_wildcard(mgcp_client)); + } if (!cl->mgw_endpoint) { LOG_CALL_LEG(cl, LOGL_ERROR, "failed to setup MGW endpoint\n"); return -EIO; } - cl->rtp[dir] = rtp_stream_alloc(cl, dir, call_id, for_trans); + cl->rtp[dir] = rtp_stream_alloc(cl->fi, CALL_LEG_EV_RTP_STREAM_GONE, CALL_LEG_EV_RTP_STREAM_ADDR_AVAILABLE, + CALL_LEG_EV_RTP_STREAM_ESTABLISHED, dir, call_id, for_trans); OSMO_ASSERT(cl->rtp[dir]); return 0; } @@ -301,7 +318,7 @@ struct osmo_sockaddr_str *call_leg_local_ip(struct call_leg *cl, enum rtp_direct rtps = cl->rtp[dir]; if (!rtps) return NULL; - if (!osmo_sockaddr_str_is_set(&rtps->local)) + if (!osmo_sockaddr_str_is_nonzero(&rtps->local)) return NULL; return &rtps->local; } @@ -309,21 +326,26 @@ struct osmo_sockaddr_str *call_leg_local_ip(struct call_leg *cl, enum rtp_direct /* Make sure an MGW endpoint CI is set up for an RTP connection. * This is the one-stop for all to either completely set up a new endpoint connection, or to modify an existing one. * If not yet present, allocate the rtp_stream for the given direction. - * Then, call rtp_stream_set_codec() if codec_if_known is non-NULL, and/or rtp_stream_set_remote_addr() if + * Then, call rtp_stream_set_codecs() if codecs_if_known is non-NULL, and/or rtp_stream_set_remote_addr() if * remote_addr_if_known is non-NULL. * Finally make sure that a CRCX is sent out for this direction, if this has not already happened. * If the CRCX has already happened but new codec / remote_addr data was passed, call rtp_stream_commit() to trigger an * MDCX. */ int call_leg_ensure_ci(struct call_leg *cl, enum rtp_direction dir, uint32_t call_id, struct gsm_trans *for_trans, - const enum mgcp_codecs *codec_if_known, const struct osmo_sockaddr_str *remote_addr_if_known) + const struct sdp_audio_codecs *codecs_if_known, + const struct osmo_sockaddr_str *remote_addr_if_known) { if (call_leg_ensure_rtp_alloc(cl, dir, call_id, for_trans)) return -EIO; - cl->rtp[dir]->crcx_conn_mode = cl->crcx_conn_mode[dir]; - if (codec_if_known) - rtp_stream_set_codec(cl->rtp[dir], *codec_if_known); - if (remote_addr_if_known && osmo_sockaddr_str_is_set(remote_addr_if_known)) + rtp_stream_set_mode(cl->rtp[dir], cl->crcx_conn_mode[dir]); + if (dir == RTP_TO_RAN && cl->ran_peer_supports_osmux) { + cl->rtp[dir]->use_osmux = true; + cl->rtp[dir]->remote_osmux_cid = -1; /* wildcard */ + } + if (codecs_if_known) + rtp_stream_set_codecs(cl->rtp[dir], codecs_if_known); + if (remote_addr_if_known && osmo_sockaddr_str_is_nonzero(remote_addr_if_known)) rtp_stream_set_remote_addr(cl->rtp[dir], remote_addr_if_known); return rtp_stream_ensure_ci(cl->rtp[dir], cl->mgw_endpoint); } @@ -331,22 +353,46 @@ int call_leg_ensure_ci(struct call_leg *cl, enum rtp_direction dir, uint32_t cal int call_leg_local_bridge(struct call_leg *cl1, uint32_t call_id1, struct gsm_trans *trans1, struct call_leg *cl2, uint32_t call_id2, struct gsm_trans *trans2) { - enum mgcp_codecs codec; + struct sdp_audio_codecs *cn_codecs = NULL; cl1->local_bridge = cl2; cl2->local_bridge = cl1; - /* We may just copy the codec info we have for the RAN side of the first leg to the CN side of both legs. This - * also means that if both legs use different codecs the MGW must perform transcoding on the second leg. */ - if (!cl1->rtp[RTP_TO_RAN] || !cl1->rtp[RTP_TO_RAN]->codec_known) { - LOG_CALL_LEG(cl1, LOGL_ERROR, "RAN-side RTP stream codec is not known, not ready for bridging\n"); + /* Marry the two CN sides of the call legs. Call establishment should have made all efforts for these to be + * compatible. However, for local bridging, the codecs and payload type numbers must be exactly identical on + * both sides. Both sides may so far have different payload type numbers or slightly differing codecs, but it + * will only work when the SDP on the RTP_TO_CN sides of the call legs talk the same payload type numbers. + * So, simply take the SDP from one RTP_TO_CN side, and overwrite the other RTP_TO_CN side's SDP with it. + * If all goes to plan, the codecs will be identical, or possibly the MGW will do a conversion like AMR-BE to + * AMR-OA. In the worst case, the other call leg cannot transcode, and the call fails -- because codec + * negotiation did not do a good enough job. + * + * Copy one call leg's CN config to the other: + * + * call leg 1 call leg 2 + * ---MGW-ep------- ---MGW-ep------- + * RAN CN CN RAN + * AMR:112 AMR:112 AMR:96 AMR:96 + * | + * +-------+ + * | + * V + * AMR:112 AMR:112 AMR:112 AMR:96 + * ^MGW-endpoint converts payload type numbers between 112 and 96. + */ + if (cl1->rtp[RTP_TO_CN] && cl1->rtp[RTP_TO_CN]->codecs_known) + cn_codecs = &cl1->rtp[RTP_TO_CN]->codecs; + else if (cl2->rtp[RTP_TO_CN] && cl2->rtp[RTP_TO_CN]->codecs_known) + cn_codecs = &cl2->rtp[RTP_TO_CN]->codecs; + if (!cn_codecs) { + LOG_CALL_LEG(cl1, LOGL_ERROR, "RAN-side CN stream codec is not known, not ready for bridging\n"); + LOG_CALL_LEG(cl2, LOGL_ERROR, "RAN-side CN stream codec is not known, not ready for bridging\n"); return -EINVAL; } - codec = cl1->rtp[RTP_TO_RAN]->codec; call_leg_ensure_ci(cl1, RTP_TO_CN, call_id1, trans1, - &codec, &cl2->rtp[RTP_TO_CN]->local); + cn_codecs, &cl2->rtp[RTP_TO_CN]->local); call_leg_ensure_ci(cl2, RTP_TO_CN, call_id2, trans2, - &codec, &cl1->rtp[RTP_TO_CN]->local); + cn_codecs, &cl1->rtp[RTP_TO_CN]->local); return 0; } diff --git a/src/libmsc/cell_id_list.c b/src/libmsc/cell_id_list.c index ca7a6d43b..4bf3a76de 100644 --- a/src/libmsc/cell_id_list.c +++ b/src/libmsc/cell_id_list.c @@ -1,25 +1,21 @@ /* Manage a list of struct gsm0808_cell_id */ /* - * (C) 2019 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de> + * (C) 2019 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de> * All Rights Reserved * * Author: Neels Hofmeyr * - * SPDX-License-Identifier: GPL-2.0+ + * SPDX-License-Identifier: AGPL-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 2 of the License, or + * 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 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. + * GNU Affero General Public License for more details. */ #include <osmocom/msc/cell_id_list.h> diff --git a/src/libmsc/codec_filter.c b/src/libmsc/codec_filter.c new file mode 100644 index 000000000..7511f9026 --- /dev/null +++ b/src/libmsc/codec_filter.c @@ -0,0 +1,163 @@ +/* Filter/overlay codec selections for a voice call, across MS, RAN and CN limitations */ +/* + * (C) 2019-2023 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de> + * All Rights Reserved + * + * Author: Neels Hofmeyr + * + * SPDX-License-Identifier: AGPL-3.0+ + * + * 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/gsm/protocol/gsm_08_08.h> + +#include <osmocom/msc/codec_filter.h> +#include <osmocom/msc/codec_mapping.h> +#include <osmocom/msc/debug.h> + +/* Add all known payload types encountered in GSM networks */ +static void sdp_add_all_geran_codecs(struct sdp_audio_codecs *ac) +{ + /* In order of preference. TODO: make configurable */ + static const enum gsm48_bcap_speech_ver mobile_codecs[] = { + GSM48_BCAP_SV_AMR_F /*!< 4 GSM FR V3 (FR AMR) */, + GSM48_BCAP_SV_AMR_H /*!< 5 GSM HR V3 (HR_AMR) */, + GSM48_BCAP_SV_EFR /*!< 2 GSM FR V2 (GSM EFR) */, + GSM48_BCAP_SV_FR /*!< 0 GSM FR V1 (GSM FR) */, + GSM48_BCAP_SV_HR /*!< 1 GSM HR V1 (GSM HR) */, + }; + int i; + for (i = 0; i < ARRAY_SIZE(mobile_codecs); i++) + sdp_audio_codecs_add_speech_ver(ac, mobile_codecs[i]); +} + +/* Add all known AMR payload types encountered in UTRAN networks */ +static void sdp_add_all_utran_codecs(struct sdp_audio_codecs *ac) +{ + /* In order of preference. TODO: make configurable */ + static const enum gsm48_bcap_speech_ver utran_codecs[] = { + GSM48_BCAP_SV_AMR_F /*!< 4 GSM FR V3 (FR AMR) */, + GSM48_BCAP_SV_AMR_H /*!< 5 GSM HR V3 (HR_AMR) */, + GSM48_BCAP_SV_AMR_OH /*!< 11 GSM HR V6 (OHR AMR) */, + GSM48_BCAP_SV_AMR_FW /*!< 8 GSM FR V5 (FR AMR-WB) */, + GSM48_BCAP_SV_AMR_OFW /*!< 6 GSM FR V4 (OFR AMR-WB) */, + GSM48_BCAP_SV_AMR_OHW /*!< 7 GSM HR V4 (OHR AMR-WB) */, + }; + int i; + for (i = 0; i < ARRAY_SIZE(utran_codecs); i++) + sdp_audio_codecs_add_speech_ver(ac, utran_codecs[i]); +} + +void codec_filter_set_ran(struct codec_filter *codec_filter, enum osmo_rat_type ran_type) +{ + codec_filter->ran = (struct sdp_audio_codecs){}; + + switch (ran_type) { + default: + case OSMO_RAT_GERAN_A: + sdp_add_all_geran_codecs(&codec_filter->ran); + break; + + case OSMO_RAT_UTRAN_IU: + sdp_add_all_utran_codecs(&codec_filter->ran); + break; + } +} + +void codec_filter_set_bss(struct codec_filter *codec_filter, + const struct gsm0808_speech_codec_list *codec_list_bss_supported) +{ + codec_filter->bss = (struct sdp_audio_codecs){}; + if (codec_list_bss_supported) + sdp_audio_codecs_from_speech_codec_list(&codec_filter->bss, codec_list_bss_supported); +} + +/* Render intersections of all known audio codec constraints to reach a resulting choice of favorite audio codec, plus + * possible set of alternative audio codecs, in codec_filter->result. (The result.rtp address remains unchanged.) */ +int codec_filter_run(struct codec_filter *codec_filter, struct sdp_msg *result, const struct sdp_msg *remote) +{ + struct sdp_audio_codecs *r = &result->audio_codecs; + struct sdp_audio_codec *a = &codec_filter->assignment; + *r = codec_filter->ran; + if (codec_filter->ms.count) + sdp_audio_codecs_intersection(r, &codec_filter->ms, false); + if (codec_filter->bss.count) + sdp_audio_codecs_intersection(r, &codec_filter->bss, false); + if (remote->audio_codecs.count) + sdp_audio_codecs_intersection(r, &remote->audio_codecs, true); + + if (sdp_audio_codec_is_set(a)) { + /* Assignment has completed, the chosen codec should be the first of the resulting SDP. + * If present, make sure this is listed in first place. + * If 'select' is NULL, the assigned codec is not present in the intersection of possible choices for + * TFO. Just omit the assigned codec from the filter result, and it is the CC code's responsibility to + * detect this and assign a working codec instead. */ + struct sdp_audio_codec *select = sdp_audio_codecs_by_descr(r, a); + if (select) + sdp_audio_codecs_select(r, select); + } + return 0; +} + +int codec_filter_to_str_buf(char *buf, size_t buflen, const struct codec_filter *codec_filter, + const struct sdp_msg *result, const struct sdp_msg *remote) +{ + struct osmo_strbuf sb = { .buf = buf, .len = buflen }; + OSMO_STRBUF_APPEND(sb, sdp_msg_to_str_buf, result); + OSMO_STRBUF_PRINTF(sb, " (from:"); + + if (sdp_audio_codec_is_set(&codec_filter->assignment)) { + OSMO_STRBUF_PRINTF(sb, " assigned="); + OSMO_STRBUF_APPEND(sb, sdp_audio_codec_to_str_buf, &codec_filter->assignment); + } + + if (remote->audio_codecs.count + || osmo_sockaddr_str_is_nonzero(&remote->rtp)) { + OSMO_STRBUF_PRINTF(sb, " remote="); + OSMO_STRBUF_APPEND(sb, sdp_msg_to_str_buf, remote); + } + + if (codec_filter->ms.count) { + OSMO_STRBUF_PRINTF(sb, " MS={"); + OSMO_STRBUF_APPEND(sb, sdp_audio_codecs_to_str_buf, &codec_filter->ms); + OSMO_STRBUF_PRINTF(sb, "}"); + } + + if (codec_filter->bss.count) { + OSMO_STRBUF_PRINTF(sb, " bss={"); + OSMO_STRBUF_APPEND(sb, sdp_audio_codecs_to_str_buf, &codec_filter->bss); + OSMO_STRBUF_PRINTF(sb, "}"); + } + + OSMO_STRBUF_PRINTF(sb, " RAN={"); + OSMO_STRBUF_APPEND(sb, sdp_audio_codecs_to_str_buf, &codec_filter->ran); + OSMO_STRBUF_PRINTF(sb, "}"); + + OSMO_STRBUF_PRINTF(sb, ")"); + + return sb.chars_needed; +} + +char *codec_filter_to_str_c(void *ctx, const struct codec_filter *codec_filter, const struct sdp_msg *result, + const struct sdp_msg *remote) +{ + OSMO_NAME_C_IMPL(ctx, 128, "codec_filter_to_str_c-ERROR", codec_filter_to_str_buf, codec_filter, result, remote) +} + +const char *codec_filter_to_str(const struct codec_filter *codec_filter, const struct sdp_msg *result, + const struct sdp_msg *remote) +{ + return codec_filter_to_str_c(OTC_SELECT, codec_filter, result, remote); +} diff --git a/src/libmsc/codec_mapping.c b/src/libmsc/codec_mapping.c new file mode 100644 index 000000000..bb5968f0e --- /dev/null +++ b/src/libmsc/codec_mapping.c @@ -0,0 +1,547 @@ +/* Routines for translation between codec representations: SDP, CC/BSSMAP variants, MGCP, MNCC */ +/* + * (C) 2019-2023 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de> + * All Rights Reserved + * + * Author: Neels Hofmeyr + * + * SPDX-License-Identifier: AGPL-3.0+ + * + * 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 <osmocom/gsm/mncc.h> + +#include <osmocom/msc/sdp_msg.h> +#include <osmocom/msc/codec_mapping.h> +#include <osmocom/msc/mncc.h> + +const struct codec_mapping codec_map[] = { + /* FIXME: sdp.fmtp handling is not done properly yet, proper mode-set and octet-align handling will follow in + * separate patches. */ + { + .sdp = { + .payload_type = 0, + .subtype_name = "PCMU", + .rate = 8000, + }, + .mgcp = CODEC_PCMU_8000_1, + }, + { + .sdp = { + .payload_type = 3, + .subtype_name = "GSM", + .rate = 8000, + }, + .mgcp = CODEC_GSM_8000_1, + .speech_ver_count = 1, + .speech_ver = { GSM48_BCAP_SV_FR }, + .mncc_payload_msg_type = GSM_TCHF_FRAME, + .has_gsm0808_speech_codec = true, + .gsm0808_speech_codec = { + .fi = true, + .type = GSM0808_SCT_FR1, + }, + .perm_speech = GSM0808_PERM_FR1, + .frhr = CODEC_FRHR_FR, + }, + { + .sdp = { + .payload_type = 8, + .subtype_name = "PCMA", + .rate = 8000, + }, + .mgcp = CODEC_PCMA_8000_1, + }, + { + .sdp = { + .payload_type = 18, + .subtype_name = "G729", + .rate = 8000, + }, + .mgcp = CODEC_G729_8000_1, + }, + { + .sdp = { + .payload_type = 110, + .subtype_name = "GSM-EFR", + .rate = 8000, + }, + .mgcp = CODEC_GSMEFR_8000_1, + .speech_ver_count = 1, + .speech_ver = { GSM48_BCAP_SV_EFR }, + .mncc_payload_msg_type = GSM_TCHF_FRAME_EFR, + .has_gsm0808_speech_codec = true, + .gsm0808_speech_codec = { + .fi = true, + .type = GSM0808_SCT_FR2, + }, + .perm_speech = GSM0808_PERM_FR2, + .frhr = CODEC_FRHR_FR, + }, + { + .sdp = { + .payload_type = 111, + .subtype_name = "GSM-HR-08", + .rate = 8000, + }, + .mgcp = CODEC_GSMHR_8000_1, + .speech_ver_count = 1, + .speech_ver = { GSM48_BCAP_SV_HR }, + .mncc_payload_msg_type = GSM_TCHH_FRAME, + .has_gsm0808_speech_codec = true, + .gsm0808_speech_codec = { + .fi = true, + .type = GSM0808_SCT_HR1, + }, + .perm_speech = GSM0808_PERM_HR1, + .frhr = CODEC_FRHR_HR, + }, + { + .sdp = { + /* 112 is just what we use by default. The other call leg may impose a different number. */ + .payload_type = 112, + .subtype_name = "AMR", + .rate = 8000, + /* AMR is always octet-aligned in 2G and 3G RAN, so this fmtp is signalled to remote call legs. + * So far, fmtp is ignored in incoming SIP SDP, so an incoming SDP without 'octet-align=1' will + * match with this entry; we will still reply with 'octet-align=1', which often works out. */ + .fmtp = "octet-align=1", + }, + .mgcp = CODEC_AMR_8000_1, + .speech_ver_count = 1, + .speech_ver = { GSM48_BCAP_SV_AMR_F }, + .mncc_payload_msg_type = GSM_TCH_FRAME_AMR, + .has_gsm0808_speech_codec = true, + .gsm0808_speech_codec = { + .fi = true, + .type = GSM0808_SCT_FR3, + .cfg = GSM0808_SC_CFG_DEFAULT_FR_AMR, + }, + .perm_speech = GSM0808_PERM_FR3, + .frhr = CODEC_FRHR_FR, + }, + { + /* Another entry like the above, to map HR3 to AMR, too. */ + .sdp = { + .payload_type = 112, + .subtype_name = "AMR", + .rate = 8000, + .fmtp = "octet-align=1", + }, + .mgcp = CODEC_AMR_8000_1, + .speech_ver_count = 2, + .speech_ver = { GSM48_BCAP_SV_AMR_H, GSM48_BCAP_SV_AMR_OH }, + .mncc_payload_msg_type = GSM_TCH_FRAME_AMR, + .has_gsm0808_speech_codec = true, + .gsm0808_speech_codec = { + .fi = true, + .type = GSM0808_SCT_HR3, + .cfg = GSM0808_SC_CFG_DEFAULT_HR_AMR, + }, + .perm_speech = GSM0808_PERM_HR3, + .frhr = CODEC_FRHR_HR, + }, + { + .sdp = { + .payload_type = 113, + .subtype_name = "AMR-WB", + .rate = 16000, + .fmtp = "octet-align=1", + }, + .mgcp = CODEC_AMRWB_16000_1, + .speech_ver_count = 2, + .speech_ver = { GSM48_BCAP_SV_AMR_OFW, GSM48_BCAP_SV_AMR_FW }, + .mncc_payload_msg_type = GSM_TCH_FRAME_AMR, + .has_gsm0808_speech_codec = true, + .gsm0808_speech_codec = { + .fi = true, + .type = GSM0808_SCT_FR5, + .cfg = GSM0808_SC_CFG_DEFAULT_FR_AMR_WB, + }, + .perm_speech = GSM0808_PERM_FR5, + .frhr = CODEC_FRHR_FR, + }, + { + /* Another entry like the above, to map HR4 to AMR-WB, too. */ + .sdp = { + .payload_type = 113, + .subtype_name = "AMR-WB", + .rate = 16000, + .fmtp = "octet-align=1", + }, + .mgcp = CODEC_AMRWB_16000_1, + .speech_ver_count = 1, + .speech_ver = { GSM48_BCAP_SV_AMR_OHW }, + .mncc_payload_msg_type = GSM_TCH_FRAME_AMR, + .has_gsm0808_speech_codec = true, + .gsm0808_speech_codec = { + .fi = true, + .type = GSM0808_SCT_HR4, + .cfg = GSM0808_SC_CFG_DEFAULT_OHR_AMR_WB, + }, + .perm_speech = GSM0808_PERM_HR4, + .frhr = CODEC_FRHR_HR, + }, + { + .sdp = { + .payload_type = 96, + .subtype_name = "VND.3GPP.IUFP", + .rate = 16000, + }, + .mgcp = CODEC_IUFP, + }, + { + .sdp = { + .payload_type = 120, + .subtype_name = "CLEARMODE", + .rate = 8000, + }, + .has_gsm0808_speech_codec = true, + .gsm0808_speech_codec = { + .pi = true, /* PI indicates CSDoIP is supported */ + .pt = false, /* PT indicates CSDoTDM is not supported */ + .type = GSM0808_SCT_CSD, + .cfg = 0, /* R2/R3 not set (redundancy not supported) */ + }, + .mgcp = CODEC_CLEARMODE, + }, +}; + +#define foreach_codec_mapping(CODEC_MAPPING) \ + for ((CODEC_MAPPING) = codec_map; (CODEC_MAPPING) < codec_map + ARRAY_SIZE(codec_map); (CODEC_MAPPING)++) + +const struct gsm_mncc_bearer_cap bearer_cap_empty = { + .speech_ver = { -1 }, + }; + +const struct codec_mapping *codec_mapping_by_speech_ver(enum gsm48_bcap_speech_ver speech_ver) +{ + const struct codec_mapping *m; + foreach_codec_mapping(m) { + int i; + for (i = 0; i < m->speech_ver_count; i++) + if (m->speech_ver[i] == speech_ver) + return m; + } + return NULL; +} + +const struct codec_mapping *codec_mapping_by_gsm0808_speech_codec_type(enum gsm0808_speech_codec_type sct) +{ + const struct codec_mapping *m; + foreach_codec_mapping(m) { + if (!m->has_gsm0808_speech_codec) + continue; + if (m->gsm0808_speech_codec.type == sct) + return m; + } + return NULL; +} + +const struct codec_mapping *codec_mapping_by_gsm0808_speech_codec(const struct gsm0808_speech_codec *sc) +{ + const struct codec_mapping *m; + foreach_codec_mapping(m) { + if (!m->has_gsm0808_speech_codec) + continue; + if (m->gsm0808_speech_codec.type != sc->type) + continue; + /* Return only those where sc->cfg is a subset of m->gsm0808_speech_codec.cfg. */ + if ((m->gsm0808_speech_codec.cfg & sc->cfg) != sc->cfg) + continue; + return m; + } + return NULL; +} + +const struct codec_mapping *codec_mapping_by_perm_speech(enum gsm0808_permitted_speech perm_speech) +{ + const struct codec_mapping *m; + foreach_codec_mapping(m) { + if (m->perm_speech == perm_speech) + return m; + } + return NULL; +} + +const struct codec_mapping *codec_mapping_by_subtype_name(const char *subtype_name) +{ + const struct codec_mapping *m; + foreach_codec_mapping(m) { + if (!strcmp(m->sdp.subtype_name, subtype_name)) + return m; + } + return NULL; +} + +const struct codec_mapping *codec_mapping_by_mgcp_codec(enum mgcp_codecs mgcp) +{ + const struct codec_mapping *m; + foreach_codec_mapping(m) { + if (m->mgcp == mgcp) + return m; + } + return NULL; +} + +/* Append given Speech Version to the end of the Bearer Capabilities Speech Version array. Return 1 if added, zero + * otherwise (as in, return the number of items added). */ +int bearer_cap_add_speech_ver(struct gsm_mncc_bearer_cap *bearer_cap, enum gsm48_bcap_speech_ver speech_ver) +{ + int i; + for (i = 0; i < ARRAY_SIZE(bearer_cap->speech_ver) - 1; i++) { + if (bearer_cap->speech_ver[i] == speech_ver) + return 0; + if (bearer_cap->speech_ver[i] == -1) { + bearer_cap->speech_ver[i] = speech_ver; + bearer_cap->speech_ver[i+1] = -1; + return 1; + } + } + return 0; +} + +/* From the current speech_ver list present in the bearer_cap, set the bearer_cap.radio. + * If a HR speech_ver is present, set to GSM48_BCAP_RRQ_DUAL_FR, otherwise set to GSM48_BCAP_RRQ_FR_ONLY. */ +int bearer_cap_set_radio(struct gsm_mncc_bearer_cap *bearer_cap) +{ + bool hr_present = false; + int i; + for (i = 0; i < ARRAY_SIZE(bearer_cap->speech_ver) - 1; i++) { + const struct codec_mapping *m; + + if (bearer_cap->speech_ver[i] == -1) + break; + + m = codec_mapping_by_speech_ver(bearer_cap->speech_ver[i]); + + if (!m) + continue; + + if (m->frhr == CODEC_FRHR_HR) + hr_present = true; + } + + if (hr_present) + bearer_cap->radio = GSM48_BCAP_RRQ_DUAL_FR; + else + bearer_cap->radio = GSM48_BCAP_RRQ_FR_ONLY; + + return 0; +} + +/* Try to convert the SDP audio codec name to Speech Versions to append to Bearer Capabilities. + * Return the number of Speech Version entries added (some may add more than one, others may be unknown/unapplicable and + * return 0). */ +int sdp_audio_codec_add_to_bearer_cap(struct gsm_mncc_bearer_cap *bearer_cap, const struct sdp_audio_codec *codec) +{ + const struct codec_mapping *m; + int added = 0; + foreach_codec_mapping(m) { + int i; + if (strcmp(m->sdp.subtype_name, codec->subtype_name)) + continue; + /* TODO also match rate and fmtp? */ + for (i = 0; i < m->speech_ver_count; i++) + added += bearer_cap_add_speech_ver(bearer_cap, m->speech_ver[i]); + } + return added; +} + +/* Append all audio codecs found in given sdp_msg to Bearer Capability, by traversing all codec entries with + * sdp_audio_codec_add_to_bearer_cap(). Return the number of Speech Version entries added. + * Note that Speech Version entries are only appended, no previous entries are removed. + * Note that only the Speech Version entries are modified; to make a valid Bearer Capabiliy, at least bearer_cap->radio + * must also be set (before or after this function); see also bearer_cap_set_radio(). */ +int sdp_audio_codecs_to_bearer_cap(struct gsm_mncc_bearer_cap *bearer_cap, const struct sdp_audio_codecs *ac) +{ + const struct sdp_audio_codec *codec; + int added = 0; + + sdp_audio_codecs_foreach(codec, ac) { + added += sdp_audio_codec_add_to_bearer_cap(bearer_cap, codec); + } + + return added; +} + +/* Convert Speech Version to SDP audio codec and append to SDP message struct. */ +struct sdp_audio_codec *sdp_audio_codecs_add_speech_ver(struct sdp_audio_codecs *ac, + enum gsm48_bcap_speech_ver speech_ver) +{ + const struct codec_mapping *m; + struct sdp_audio_codec *ret = NULL; + foreach_codec_mapping(m) { + int i; + for (i = 0; i < m->speech_ver_count; i++) { + if (m->speech_ver[i] == speech_ver) { + ret = sdp_audio_codecs_add_copy(ac, &m->sdp); + break; + } + } + } + return ret; +} + +struct sdp_audio_codec *sdp_audio_codecs_add_mgcp_codec(struct sdp_audio_codecs *ac, enum mgcp_codecs mgcp_codec) +{ + const struct codec_mapping *m = codec_mapping_by_mgcp_codec(mgcp_codec); + if (!m) + return NULL; + return sdp_audio_codecs_add_copy(ac, &m->sdp); +} + +void sdp_audio_codecs_from_bearer_cap(struct sdp_audio_codecs *ac, const struct gsm_mncc_bearer_cap *bc) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(bc->speech_ver); i++) { + if (bc->speech_ver[i] == -1) + break; + sdp_audio_codecs_add_speech_ver(ac, bc->speech_ver[i]); + } +} + +/* Append an entry for the given sdp_audio_codec to the gsm0808_speech_codec_list. + * Return 0 if an entry was added, -ENOENT when there is no mapping to gsm0808_speech_codec for the given + * sdp_audio_codec, and -ENOSPC when scl is full and nothing could be added. */ +int sdp_audio_codec_to_speech_codec_list(struct gsm0808_speech_codec_list *scl, const struct sdp_audio_codec *codec) +{ + const struct codec_mapping *m = codec_mapping_by_subtype_name(codec->subtype_name); + if (!m) + return -ENOENT; + if (!m->has_gsm0808_speech_codec) + return -ENOENT; + if (scl->len >= ARRAY_SIZE(scl->codec)) + return -ENOSPC; + scl->codec[scl->len] = m->gsm0808_speech_codec; + /* FIXME: apply AMR configuration according to codec->fmtp */ + scl->len++; + return 0; +} + +void sdp_audio_codecs_to_speech_codec_list(struct gsm0808_speech_codec_list *scl, const struct sdp_audio_codecs *ac) +{ + const struct sdp_audio_codec *codec; + + *scl = (struct gsm0808_speech_codec_list){}; + + sdp_audio_codecs_foreach(codec, ac) { + int rc = sdp_audio_codec_to_speech_codec_list(scl, codec); + if (rc == -ENOSPC) + break; + } +} + +void sdp_audio_codecs_from_speech_codec_list(struct sdp_audio_codecs *ac, const struct gsm0808_speech_codec_list *cl) +{ + int i; + for (i = 0; i < cl->len; i++) { + const struct gsm0808_speech_codec *sc = &cl->codec[i]; + const struct codec_mapping *m = codec_mapping_by_gsm0808_speech_codec(sc); + if (!m) + continue; + sdp_audio_codecs_add_copy(ac, &m->sdp); + /* FIXME: for AMR, apply sc->cfg to the added codec's fmtp */ + } +} + +int sdp_audio_codecs_to_gsm0808_channel_type(struct gsm0808_channel_type *ct, const struct sdp_audio_codecs *ac) +{ + const struct sdp_audio_codec *codec; + bool fr_present = false; + int first_fr_idx = -1; + bool hr_present = false; + int first_hr_idx = -1; + int idx = -1; + + *ct = (struct gsm0808_channel_type){ + .ch_indctr = GSM0808_CHAN_SPEECH, + }; + + sdp_audio_codecs_foreach(codec, ac) { + const struct codec_mapping *m; + int i; + bool dup; + idx++; + foreach_codec_mapping(m) { + if (strcmp(m->sdp.subtype_name, codec->subtype_name)) + continue; + + switch (m->perm_speech) { + default: + continue; + + case GSM0808_PERM_FR1: + case GSM0808_PERM_FR2: + case GSM0808_PERM_FR3: + case GSM0808_PERM_FR4: + case GSM0808_PERM_FR5: + fr_present = true; + if (first_fr_idx < 0) + first_fr_idx = idx; + break; + + case GSM0808_PERM_HR1: + case GSM0808_PERM_HR2: + case GSM0808_PERM_HR3: + case GSM0808_PERM_HR4: + case GSM0808_PERM_HR6: + hr_present = true; + if (first_hr_idx < 0) + first_hr_idx = idx; + break; + } + + /* Avoid duplicates */ + dup = false; + for (i = 0; i < ct->perm_spch_len; i++) { + if (ct->perm_spch[i] == m->perm_speech) { + dup = true; + break; + } + } + if (dup) + continue; + + ct->perm_spch[ct->perm_spch_len] = m->perm_speech; + ct->perm_spch_len++; + } + } + + if (fr_present && hr_present) { + if (first_fr_idx <= first_hr_idx) + ct->ch_rate_type = GSM0808_SPEECH_FULL_PREF; + else + ct->ch_rate_type = GSM0808_SPEECH_HALF_PREF; + } else if (fr_present && !hr_present) + ct->ch_rate_type = GSM0808_SPEECH_FULL_BM; + else if (!fr_present && hr_present) + ct->ch_rate_type = GSM0808_SPEECH_HALF_LM; + else + return -EINVAL; + return 0; +} + +enum mgcp_codecs sdp_audio_codec_to_mgcp_codec(const struct sdp_audio_codec *codec) +{ + const struct codec_mapping *m; + foreach_codec_mapping(m) { + if (!sdp_audio_codec_cmp(&m->sdp, codec, false, false)) + return m->mgcp; + } + return NO_MGCP_CODEC; +} diff --git a/src/libmsc/csd_bs.c b/src/libmsc/csd_bs.c new file mode 100644 index 000000000..ab0b64309 --- /dev/null +++ b/src/libmsc/csd_bs.c @@ -0,0 +1,517 @@ +/* 3GPP TS 122.002 Bearer Services */ +/* + * (C) 2023 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de> + * All Rights Reserved + * + * Author: Oliver Smith + * + * SPDX-License-Identifier: AGPL-3.0+ + * + * 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 <errno.h> + +#include <osmocom/msc/csd_bs.h> +#include <osmocom/msc/debug.h> + +/* csd_bs related below */ + +struct csd_bs_map { + /* BS number (20, 21, ...) */ + unsigned int num; + /* Access Structure (1: asynchronous, 0: synchronous) */ + bool async; + /* QoS Attribute (1: transparent, 0: non-transparent) */ + bool transp; + /* Rate Adaption (V110, V120 etc.) */ + enum gsm48_bcap_ra ra; + /* Fixed Network User Rate */ + unsigned int rate; +}; + +static const struct csd_bs_map bs_map[] = { + /* 3.1.1.1.2 */ + [CSD_BS_21_T_V110_0k3] = { + .num = 21, + .async = true, + .transp = true, + .ra = GSM48_BCAP_RA_V110_X30, + .rate = 300, + }, + [CSD_BS_22_T_V110_1k2] = { + .num = 22, + .async = true, + .transp = true, + .ra = GSM48_BCAP_RA_V110_X30, + .rate = 1200, + }, + [CSD_BS_24_T_V110_2k4] = { + .num = 24, + .async = true, + .transp = true, + .ra = GSM48_BCAP_RA_V110_X30, + .rate = 2400, + }, + [CSD_BS_25_T_V110_4k8] = { + .num = 25, + .async = true, + .transp = true, + .ra = GSM48_BCAP_RA_V110_X30, + .rate = 4800, + }, + [CSD_BS_26_T_V110_9k6] = { + .num = 26, + .async = true, + .transp = true, + .ra = GSM48_BCAP_RA_V110_X30, + .rate = 9600, + }, + + /* 3.1.1.2.2 */ + [CSD_BS_21_NT_V110_0k3] = { + .num = 21, + .async = true, + .transp = false, + .ra = GSM48_BCAP_RA_V110_X30, + .rate = 300, + }, + [CSD_BS_22_NT_V110_1k2] = { + .num = 22, + .async = true, + .transp = false, + .ra = GSM48_BCAP_RA_V110_X30, + .rate = 1200, + }, + [CSD_BS_24_NT_V110_2k4] = { + .num = 24, + .async = true, + .transp = false, + .ra = GSM48_BCAP_RA_V110_X30, + .rate = 2400, + }, + [CSD_BS_25_NT_V110_4k8] = { + .num = 25, + .async = true, + .transp = false, + .ra = GSM48_BCAP_RA_V110_X30, + .rate = 4800, + }, + [CSD_BS_26_NT_V110_9k6] = { + .num = 26, + .async = true, + .transp = false, + .ra = GSM48_BCAP_RA_V110_X30, + .rate = 9600, + }, + + /* 3.1.2.1.2 */ + [CSD_BS_31_T_V110_1k2] = { + .num = 31, + .async = false, + .transp = true, + .ra = GSM48_BCAP_RA_V110_X30, + .rate = 1200, + }, + [CSD_BS_32_T_V110_2k4] = { + .num = 32, + .async = false, + .transp = true, + .ra = GSM48_BCAP_RA_V110_X30, + .rate = 2400, + }, + [CSD_BS_33_T_V110_4k8] = { + .num = 33, + .async = false, + .transp = true, + .ra = GSM48_BCAP_RA_V110_X30, + .rate = 4800, + }, + [CSD_BS_34_T_V110_9k6] = { + .num = 34, + .async = false, + .transp = true, + .ra = GSM48_BCAP_RA_V110_X30, + .rate = 9600, + }, +}; + +osmo_static_assert(ARRAY_SIZE(bs_map) == CSD_BS_MAX, _invalid_size_bs_map); + +bool csd_bs_is_transp(enum csd_bs bs) +{ + return bs_map[bs].transp; +} + +/* Short single-line representation, convenient for logging. + * Like "BS25NT" */ +int csd_bs_to_str_buf(char *buf, size_t buflen, enum csd_bs bs) +{ + struct osmo_strbuf sb = { .buf = buf, .len = buflen }; + const struct csd_bs_map *map = &bs_map[bs]; + + OSMO_STRBUF_PRINTF(sb, "BS%u%s", + map->num, + map->transp ? "T" : "NT"); + + if (map->ra != GSM48_BCAP_RA_V110_X30) + OSMO_STRBUF_PRINTF(sb, "-RA=%d", map->ra); + + return sb.chars_needed; +} + +char *csd_bs_to_str_c(void *ctx, enum csd_bs bs) +{ + OSMO_NAME_C_IMPL(ctx, 32, "csd_bs_to_str_c-ERROR", csd_bs_to_str_buf, bs) +} + +const char *csd_bs_to_str(enum csd_bs bs) +{ + return csd_bs_to_str_c(OTC_SELECT, bs); +} + +static int csd_bs_to_gsm0808_data_rate_transp(enum csd_bs bs, uint8_t *ch_rate_type) +{ + switch (bs_map[bs].rate) { + case 300: + *ch_rate_type = GSM0808_DATA_FULL_PREF; + return GSM0808_DATA_RATE_TRANSP_600; + case 1200: + *ch_rate_type = GSM0808_DATA_FULL_PREF; + return GSM0808_DATA_RATE_TRANSP_1k2; + case 2400: + *ch_rate_type = GSM0808_DATA_FULL_PREF; + return GSM0808_DATA_RATE_TRANSP_2k4; + case 4800: + *ch_rate_type = GSM0808_DATA_FULL_PREF; + return GSM0808_DATA_RATE_TRANSP_4k8; + case 9600: + *ch_rate_type = GSM0808_DATA_FULL_BM; + return GSM0808_DATA_RATE_TRANSP_9k6; + } + return -EINVAL; +} + +static int csd_bs_to_gsm0808_data_rate_non_transp(enum csd_bs bs, uint8_t *ch_rate_type) +{ + uint16_t rate = bs_map[bs].rate; + + if (rate < 6000) { + *ch_rate_type = GSM0808_DATA_FULL_PREF; + return GSM0808_DATA_RATE_NON_TRANSP_6k0; + } + if (rate < 12000) { + *ch_rate_type = GSM0808_DATA_FULL_BM; + return GSM0808_DATA_RATE_NON_TRANSP_12k0; + } + + return -EINVAL; +} + +static int csd_bs_to_gsm0808_data_rate_non_transp_allowed(enum csd_bs bs) +{ + uint16_t rate = bs_map[bs].rate; + + if (rate < 6000) + return GSM0808_DATA_RATE_NON_TRANSP_ALLOWED_6k0; + if (rate < 12000) + return GSM0808_DATA_RATE_NON_TRANSP_ALLOWED_12k0; + + return -EINVAL; +} + +enum csd_bs csd_bs_from_bearer_cap(const struct gsm_mncc_bearer_cap *cap, bool transp) +{ + enum gsm48_bcap_ra ra = cap->data.rate_adaption; + enum gsm48_bcap_user_rate rate = cap->data.user_rate; + bool async = cap->data.async; + + /* 3.1kHz CSD calls won't have the rate adaptation field set + but do require rate adaptation. */ + if (cap->data.interm_rate && !ra) + ra = GSM48_BCAP_RA_V110_X30; + + if (ra == GSM48_BCAP_RA_V110_X30 && async && transp) { + switch (rate) { + case GSM48_BCAP_UR_300: + return CSD_BS_21_T_V110_0k3; + case GSM48_BCAP_UR_1200: + return CSD_BS_22_T_V110_1k2; + case GSM48_BCAP_UR_2400: + return CSD_BS_24_T_V110_2k4; + case GSM48_BCAP_UR_4800: + return CSD_BS_25_T_V110_4k8; + case GSM48_BCAP_UR_9600: + return CSD_BS_26_T_V110_9k6; + default: + return CSD_BS_NONE; + } + } + + if (ra == GSM48_BCAP_RA_V110_X30 && async && !transp) { + switch (rate) { + case GSM48_BCAP_UR_300: + return CSD_BS_21_NT_V110_0k3; + case GSM48_BCAP_UR_1200: + return CSD_BS_22_NT_V110_1k2; + case GSM48_BCAP_UR_2400: + return CSD_BS_24_NT_V110_2k4; + case GSM48_BCAP_UR_4800: + return CSD_BS_25_NT_V110_4k8; + case GSM48_BCAP_UR_9600: + return CSD_BS_26_NT_V110_9k6; + default: + return CSD_BS_NONE; + } + } + + if (ra == GSM48_BCAP_RA_V110_X30 && !async && transp) { + switch (rate) { + case GSM48_BCAP_UR_1200: + return CSD_BS_31_T_V110_1k2; + case GSM48_BCAP_UR_2400: + return CSD_BS_32_T_V110_2k4; + case GSM48_BCAP_UR_4800: + return CSD_BS_33_T_V110_4k8; + case GSM48_BCAP_UR_9600: + return CSD_BS_34_T_V110_9k6; + default: + return CSD_BS_NONE; + } + } + + return CSD_BS_NONE; +} + +/* csd_bs_list related below */ + +int csd_bs_list_to_str_buf(char *buf, size_t buflen, const struct csd_bs_list *list) +{ + struct osmo_strbuf sb = { .buf = buf, .len = buflen }; + int i; + + if (!list->count) + OSMO_STRBUF_PRINTF(sb, "(no-bearer-services)"); + + for (i = 0; i < list->count; i++) { + if (i) + OSMO_STRBUF_PRINTF(sb, ","); + + OSMO_STRBUF_APPEND(sb, csd_bs_to_str_buf, list->bs[i]); + } + return sb.chars_needed; +} + +char *csd_bs_list_to_str_c(void *ctx, const struct csd_bs_list *list) +{ + OSMO_NAME_C_IMPL(ctx, 128, "csd_bs_list_to_str_c-ERROR", csd_bs_list_to_str_buf, list) +} + +const char *csd_bs_list_to_str(const struct csd_bs_list *list) +{ + return csd_bs_list_to_str_c(OTC_SELECT, list); +} + +bool csd_bs_list_has_bs(const struct csd_bs_list *list, enum csd_bs bs) +{ + int i; + + for (i = 0; i < list->count; i++) { + if (list->bs[i] == bs) + return true; + } + + return false; +} + +void csd_bs_list_add_bs(struct csd_bs_list *list, enum csd_bs bs) +{ + int i; + + if (!bs) + return; + + for (i = 0; i < list->count; i++) { + if (list->bs[i] == bs) + return; + } + + list->bs[i] = bs; + list->count++; +} + +void csd_bs_list_remove(struct csd_bs_list *list, enum csd_bs bs) +{ + int i; + bool found = false; + + for (i = 0; i < list->count; i++) { + if (list->bs[i] == bs) + found = true; + if (found && i + 1 < list->count) + list->bs[i] = list->bs[i + 1]; + } + + if (found) + list->count--; +} + +void csd_bs_list_intersection(struct csd_bs_list *dest, const struct csd_bs_list *other) +{ + int i; + + for (i = 0; i < dest->count; i++) { + if (csd_bs_list_has_bs(other, dest->bs[i])) + continue; + csd_bs_list_remove(dest, dest->bs[i]); + i--; + } +} + +int csd_bs_list_to_gsm0808_channel_type(struct gsm0808_channel_type *ct, const struct csd_bs_list *list) +{ + int i; + int rc; + + *ct = (struct gsm0808_channel_type){ + .ch_indctr = GSM0808_CHAN_DATA, + }; + + if (!list->count) + return -EINVAL; + + if (csd_bs_is_transp(list->bs[0])) { + ct->data_transparent = true; + rc = csd_bs_to_gsm0808_data_rate_transp(list->bs[0], &ct->ch_rate_type); + } else { + rc = csd_bs_to_gsm0808_data_rate_non_transp(list->bs[0], &ct->ch_rate_type); + } + + if (rc < 0) + return -EINVAL; + + ct->data_rate = rc; + + /* Other possible data rates allowed (3GPP TS 48.008 § 3.2.2.11, 5a) */ + if (!ct->data_transparent && list->count > 1) { + for (i = 1; i < list->count; i++) { + if (!csd_bs_is_transp(list->bs[i])) + continue; + + rc = csd_bs_to_gsm0808_data_rate_non_transp_allowed(list->bs[i]); + if (rc < 0) { + LOGP(DMSC, LOGL_DEBUG, "Failed to convert %s to allowed r i/f rate\n", + csd_bs_to_str(list->bs[i])); + continue; + } + + ct->data_rate_allowed |= rc; + } + if (ct->data_rate_allowed) + ct->data_rate_allowed_is_set = true; + } + + return 0; +} + +int csd_bs_list_to_bearer_cap(struct gsm_mncc_bearer_cap *cap, const struct csd_bs_list *list) +{ + *cap = (struct gsm_mncc_bearer_cap){ + .transfer = GSM_MNCC_BCAP_UNR_DIG, + .mode = GSM48_BCAP_TMOD_CIRCUIT, + .coding = GSM48_BCAP_CODING_GSM_STD, + .radio = GSM48_BCAP_RRQ_FR_ONLY, + }; + enum csd_bs bs; + int i; + + for (i = 0; i < list->count; i++) { + bs = list->bs[i]; + + cap->data.rate_adaption = GSM48_BCAP_RA_V110_X30; + cap->data.sig_access = GSM48_BCAP_SA_I440_I450; + cap->data.async = bs_map[bs].async; + if (bs_map[bs].transp) + cap->data.transp = GSM48_BCAP_TR_TRANSP; + else + cap->data.transp = GSM48_BCAP_TR_RLP; + + /* FIXME: proper values for sync/async (current: 8N1) */ + cap->data.nr_data_bits = 8; + cap->data.parity = GSM48_BCAP_PAR_NONE; + cap->data.nr_stop_bits = 1; + cap->data.modem_type = GSM48_BCAP_MT_NONE; + + switch (bs_map[bs].rate) { + case 300: + cap->data.user_rate = GSM48_BCAP_UR_300; + cap->data.interm_rate = GSM48_BCAP_IR_8k; + break; + case 1200: + cap->data.user_rate = GSM48_BCAP_UR_1200; + cap->data.interm_rate = GSM48_BCAP_IR_8k; + break; + case 2400: + cap->data.user_rate = GSM48_BCAP_UR_2400; + cap->data.interm_rate = GSM48_BCAP_IR_8k; + break; + case 4800: + cap->data.user_rate = GSM48_BCAP_UR_4800; + cap->data.interm_rate = GSM48_BCAP_IR_8k; + break; + case 9600: + cap->data.user_rate = GSM48_BCAP_UR_9600; + cap->data.interm_rate = GSM48_BCAP_IR_16k; + break; + default: + LOGP(DMSC, LOGL_ERROR, + "%s(): bs=%d (rate=%u) is not implemented\n", + __func__, bs, bs_map[bs].rate); + continue; + } + + /* FIXME: handle more than one list entry */ + return 1; + } + + return 0; +} + +void csd_bs_list_from_bearer_cap(struct csd_bs_list *list, const struct gsm_mncc_bearer_cap *cap) +{ + *list = (struct csd_bs_list){}; + + switch (cap->data.transp) { + case GSM48_BCAP_TR_TRANSP: + csd_bs_list_add_bs(list, csd_bs_from_bearer_cap(cap, true)); + break; + case GSM48_BCAP_TR_RLP: /* NT */ + csd_bs_list_add_bs(list, csd_bs_from_bearer_cap(cap, false)); + break; + case GSM48_BCAP_TR_TR_PREF: + csd_bs_list_add_bs(list, csd_bs_from_bearer_cap(cap, true)); + csd_bs_list_add_bs(list, csd_bs_from_bearer_cap(cap, false)); + break; + case GSM48_BCAP_TR_RLP_PREF: + csd_bs_list_add_bs(list, csd_bs_from_bearer_cap(cap, false)); + csd_bs_list_add_bs(list, csd_bs_from_bearer_cap(cap, true)); + break; + } + + if (!list->count) { + LOGP(DMSC, LOGL_ERROR, "Failed to get bearer service from bearer capabilities ra=%d, async=%d," + " transp=%d, user_rate=%d\n", cap->data.rate_adaption, cap->data.async, cap->data.transp, + cap->data.user_rate); + return; + } +} diff --git a/src/libmsc/csd_filter.c b/src/libmsc/csd_filter.c new file mode 100644 index 000000000..0f428cffe --- /dev/null +++ b/src/libmsc/csd_filter.c @@ -0,0 +1,157 @@ +/* Filter/overlay bearer service selections across MS, RAN and CN limitations */ +/* + * (C) 2023 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de> + * All Rights Reserved + * + * Author: Oliver Smith + * + * SPDX-License-Identifier: AGPL-3.0+ + * + * 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/mgcp_client/mgcp_client.h> + +#include <osmocom/msc/csd_filter.h> + +static void add_all_geran_bs(struct csd_bs_list *list) +{ + /* See 3GPP TS 122.002 Bearer Services */ + /* In order of preference. TODO: make configurable */ + + /* GSM-R */ + csd_bs_list_add_bs(list, CSD_BS_24_T_V110_2k4); + csd_bs_list_add_bs(list, CSD_BS_25_T_V110_4k8); + csd_bs_list_add_bs(list, CSD_BS_26_T_V110_9k6); + + /* Other */ + csd_bs_list_add_bs(list, CSD_BS_21_T_V110_0k3); + csd_bs_list_add_bs(list, CSD_BS_22_T_V110_1k2); + csd_bs_list_add_bs(list, CSD_BS_21_NT_V110_0k3); + csd_bs_list_add_bs(list, CSD_BS_22_NT_V110_1k2); + csd_bs_list_add_bs(list, CSD_BS_24_NT_V110_2k4); + csd_bs_list_add_bs(list, CSD_BS_25_NT_V110_4k8); + csd_bs_list_add_bs(list, CSD_BS_26_NT_V110_9k6); + csd_bs_list_add_bs(list, CSD_BS_31_T_V110_1k2); + csd_bs_list_add_bs(list, CSD_BS_32_T_V110_2k4); + csd_bs_list_add_bs(list, CSD_BS_33_T_V110_4k8); + csd_bs_list_add_bs(list, CSD_BS_34_T_V110_9k6); +} + +static void add_all_utran_bs(struct csd_bs_list *list) +{ + /* See 3GPP TS 122.002 Bearer Services */ + /* In order of preference. TODO: make configurable */ + csd_bs_list_add_bs(list, CSD_BS_21_NT_V110_0k3); + csd_bs_list_add_bs(list, CSD_BS_22_NT_V110_1k2); + csd_bs_list_add_bs(list, CSD_BS_24_NT_V110_2k4); + csd_bs_list_add_bs(list, CSD_BS_25_NT_V110_4k8); + csd_bs_list_add_bs(list, CSD_BS_26_NT_V110_9k6); +} + +void csd_filter_set_ran(struct csd_filter *filter, enum osmo_rat_type ran_type) +{ + filter->ran = (struct csd_bs_list){}; + + switch (ran_type) { + default: + case OSMO_RAT_GERAN_A: + add_all_geran_bs(&filter->ran); + break; + case OSMO_RAT_UTRAN_IU: + add_all_utran_bs(&filter->ran); + break; + } +} + +int csd_filter_run(struct csd_filter *filter, struct sdp_msg *result, const struct sdp_msg *remote) +{ + struct csd_bs_list *r = &result->bearer_services; + enum csd_bs a = filter->assignment; + + *r = filter->ran; + + if (filter->ms.count) + csd_bs_list_intersection(r, &filter->ms); + if (filter->bss.count) + csd_bs_list_intersection(r, &filter->bss); + if (remote->bearer_services.count) + csd_bs_list_intersection(r, &remote->bearer_services); + + /* Future: If osmo-msc were able to trigger a re-assignment [...] see + * comment in codec_filter_run(). */ + + if (a) { + *r = (struct csd_bs_list){}; + csd_bs_list_add_bs(r, a); + } + + result->audio_codecs.count = 1; + result->audio_codecs.codec[0] = (struct sdp_audio_codec){ + .payload_type = CODEC_CLEARMODE, + .subtype_name = "CLEARMODE", + .rate = 8000, + }; + + return 0; +} + + +int csd_filter_to_str_buf(char *buf, size_t buflen, const struct csd_filter *filter, + const struct sdp_msg *result, const struct sdp_msg *remote) +{ + struct osmo_strbuf sb = { .buf = buf, .len = buflen }; + OSMO_STRBUF_APPEND(sb, sdp_msg_to_str_buf, result); + OSMO_STRBUF_PRINTF(sb, " (from:"); + + if (filter->assignment) { + OSMO_STRBUF_PRINTF(sb, " assigned="); + OSMO_STRBUF_APPEND(sb, csd_bs_to_str_buf, filter->assignment); + } + + if (remote->bearer_services.count || osmo_sockaddr_str_is_nonzero(&remote->rtp)) { + OSMO_STRBUF_PRINTF(sb, " remote="); + OSMO_STRBUF_APPEND(sb, sdp_msg_to_str_buf, remote); + } + + if (filter->ms.count) { + OSMO_STRBUF_PRINTF(sb, " MS={"); + OSMO_STRBUF_APPEND(sb, csd_bs_list_to_str_buf, &filter->ms); + OSMO_STRBUF_PRINTF(sb, "}"); + } + + if (filter->bss.count) { + OSMO_STRBUF_PRINTF(sb, " bss={"); + OSMO_STRBUF_APPEND(sb, csd_bs_list_to_str_buf, &filter->bss); + OSMO_STRBUF_PRINTF(sb, "}"); + } + + OSMO_STRBUF_PRINTF(sb, " RAN={"); + OSMO_STRBUF_APPEND(sb, csd_bs_list_to_str_buf, &filter->ran); + OSMO_STRBUF_PRINTF(sb, "}"); + + OSMO_STRBUF_PRINTF(sb, ")"); + + return sb.chars_needed; +} + +char *csd_filter_to_str_c(void *ctx, const struct csd_filter *filter, const struct sdp_msg *result, const struct sdp_msg *remote) +{ + OSMO_NAME_C_IMPL(ctx, 128, "csd_filter_to_str_c-ERROR", csd_filter_to_str_buf, filter, result, remote) +} + +const char *csd_filter_to_str(const struct csd_filter *filter, const struct sdp_msg *result, const struct sdp_msg *remote) +{ + return csd_filter_to_str_c(OTC_SELECT, filter, result, remote); +} diff --git a/src/libmsc/db.c b/src/libmsc/db.c index c2d833939..d12f04c13 100644 --- a/src/libmsc/db.c +++ b/src/libmsc/db.c @@ -1,7 +1,7 @@ -/* Simple HLR/VLR database backend using dbi */ +/* Simple HLR/VLR database backend using sqlite3 */ /* (C) 2008 by Jan Luebbe <jluebbe@debian.org> * (C) 2009 by Holger Hans Peter Freyther <zecke@selfish.org> - * (C) 2009 by Harald Welte <laforge@gnumonks.org> + * (C) 2009,2022 by Harald Welte <laforge@gnumonks.org> * All Rights Reserved * * This program is free software; you can redistribute it and/or modify @@ -28,7 +28,7 @@ #include <string.h> #include <errno.h> #include <time.h> -#include <dbi/dbi.h> +#include <sqlite3.h> #include <osmocom/msc/gsm_data.h> #include <osmocom/msc/gsm_subscriber.h> @@ -43,12 +43,36 @@ #include <osmocom/core/rate_ctr.h> #include <osmocom/core/utils.h> -static char *db_basename = NULL; -static char *db_dirname = NULL; -static dbi_conn conn; -static dbi_inst inst; +enum stmt_idx { + DB_STMT_SMS_STORE, + DB_STMT_SMS_GET, + DB_STMT_SMS_GET_NEXT_UNSENT, + DB_STMT_SMS_GET_UNSENT_FOR_SUBSCR, + DB_STMT_SMS_GET_NEXT_UNSENT_RR_MSISDN, + DB_STMT_SMS_MARK_DELIVERED, + DB_STMT_SMS_INC_DELIVER_ATTEMPTS, + DB_STMT_SMS_DEL_BY_MSISDN, + DB_STMT_SMS_DEL_BY_ID, + DB_STMT_SMS_DEL_EXPIRED, + DB_STMT_SMS_GET_VALID_UNTIL_BY_ID, + DB_STMT_SMS_GET_OLDEST_EXPIRED, + _NUM_DB_STMT +}; + +struct db_context { + char *fname; + sqlite3 *db; + sqlite3_stmt *stmt[_NUM_DB_STMT]; +}; + +static struct db_context *g_dbc; -#define SCHEMA_REVISION "5" + +/*********************************************************************** + * DATABASE SCHEMA AND MIGRATION + ***********************************************************************/ + +#define SCHEMA_REVISION "6" enum { SCHEMA_META, @@ -181,677 +205,638 @@ static const char *create_stmts[] = { ")", }; -static inline int next_row(dbi_result result) -{ - if (!dbi_result_has_next_row(result)) - return 0; - return dbi_result_next_row(result); -} +/*********************************************************************** + * PREPARED STATEMENTS + ***********************************************************************/ + +/* don't change this order as the code assumes this ordering when dereferencing + * database query results! */ +#define SEL_COLUMNS \ + "id," \ + "strftime('%s',created)," \ + "sent," \ + "deliver_attempts," \ + "strftime('%s', valid_until)," \ + "reply_path_req," \ + "status_rep_req," \ + "is_report," \ + "msg_ref," \ + "protocol_id," \ + "data_coding_scheme," \ + "ud_hdr_ind," \ + "src_addr," \ + "src_ton," \ + "src_npi," \ + "dest_addr," \ + "dest_ton," \ + "dest_npi," \ + "user_data," \ + "header," \ + "text" + +enum db_sms_column_idx { + COL_ID, + COL_CREATED, + COL_SENT, + COL_DELIVER_ATTEMPTS, + COL_VALID_UNTIL, + COL_REPLY_PATH_REQ, + COL_STATUS_REP_REQ, + COL_IS_REPORT, + COL_MSG_REF, + COL_PROTOCOL_ID, + COL_DATA_CODING_SCHEME, + COL_UD_HDR_IND, + COL_SRC_ADDR, + COL_SRC_TON, + COL_SRC_NPI, + COL_DEST_ADDR, + COL_DEST_TON, + COL_DEST_NPI, + COL_USER_DATA, + COL_HEADER, + COL_TEXT, +}; -void db_error_func(dbi_conn conn, void *data) +static const char *stmt_sql[] = { + [DB_STMT_SMS_STORE] = + "INSERT INTO SMS " + "(created, valid_until, reply_path_req, status_rep_req, is_report, " + " msg_ref, protocol_id, data_coding_scheme, ud_hdr_ind, user_data, text, " + " dest_addr, dest_ton, dest_npi, src_addr, src_ton, src_npi) " + "VALUES " + "(datetime($created, 'unixepoch'), datetime($valid_until, 'unixepoch'), " + "$reply_path_req, $status_rep_req, $is_report, " + "$msg_ref, $protocol_id, $data_coding_scheme, $ud_hdr_ind, $user_data, $text, " + "$dest_addr, $dest_ton, $dest_npi, $src_addr, $src_ton, $src_npi)", + [DB_STMT_SMS_GET] = "SELECT " SEL_COLUMNS " FROM SMS WHERE SMS.id = $id", + [DB_STMT_SMS_GET_NEXT_UNSENT] = + "SELECT " SEL_COLUMNS " FROM SMS" + " WHERE sent IS NULL" + " AND id >= $id" + " AND deliver_attempts <= $attempts" + " ORDER BY id LIMIT 1", + [DB_STMT_SMS_GET_UNSENT_FOR_SUBSCR] = + "SELECT " SEL_COLUMNS " FROM SMS" + " WHERE sent IS NULL" + " AND dest_addr = $dest_addr" + " AND deliver_attempts <= $attempts" + " ORDER BY id LIMIT 1", + [DB_STMT_SMS_GET_NEXT_UNSENT_RR_MSISDN] = + "SELECT " SEL_COLUMNS " FROM SMS" + " WHERE sent IS NULL" + " AND dest_addr > $dest_addr" + " AND deliver_attempts <= $attempts" + " ORDER BY dest_addr, id LIMIT 1", + [DB_STMT_SMS_MARK_DELIVERED] = + "UPDATE SMS " + " SET sent = datetime('now') " + " WHERE id = $id", + [DB_STMT_SMS_INC_DELIVER_ATTEMPTS] = + "UPDATE SMS " + " SET deliver_attempts = deliver_attempts + 1 " + " WHERE id = $id", + [DB_STMT_SMS_DEL_BY_MSISDN] = + "DELETE FROM SMS WHERE src_addr=$src_addr OR dest_addr=$dest_addr", + [DB_STMT_SMS_DEL_BY_ID] = + "DELETE FROM SMS WHERE id = $id AND sent is NOT NULL", + [DB_STMT_SMS_DEL_EXPIRED] = + "DELETE FROM SMS WHERE id = $id", + [DB_STMT_SMS_GET_VALID_UNTIL_BY_ID] = + "SELECT strftime('%s', valid_until) FROM SMS WHERE id = $id", + [DB_STMT_SMS_GET_OLDEST_EXPIRED] = + "SELECT id, strftime('%s', valid_until) FROM SMS ORDER BY valid_until LIMIT 1", +}; + +/*********************************************************************** + * libsqlite3 helpers + ***********************************************************************/ + +/* libsqlite3 call-back for error logging */ +static void sql3_error_log_cb(void *arg, int err_code, const char *msg) { - const char *msg; - dbi_conn_error(conn, &msg); - LOGP(DDB, LOGL_ERROR, "DBI: %s\n", msg); + LOGP(DDB, LOGL_ERROR, "SQLITE3: (%d) %s\n", err_code, msg); osmo_log_backtrace(DDB, LOGL_ERROR); } -static int update_db_revision_2(void) +/* libsqlite3 call-back for normal logging */ +static void sql3_sql_log_cb(void *arg, sqlite3 *s3, const char *stmt, int type) { - dbi_result result; - - result = dbi_conn_query(conn, - "ALTER TABLE Subscriber " - "ADD COLUMN expire_lu " - "TIMESTAMP DEFAULT NULL"); - if (!result) { - LOGP(DDB, LOGL_ERROR, - "Failed to alter table Subscriber (upgrade from rev 2).\n"); - return -EINVAL; - } - dbi_result_free(result); - - result = dbi_conn_query(conn, - "UPDATE Meta " - "SET value = '3' " - "WHERE key = 'revision'"); - if (!result) { - LOGP(DDB, LOGL_ERROR, - "Failed to update DB schema revision (upgrade from rev 2).\n"); - return -EINVAL; + switch (type) { + case 0: + LOGP(DDB, LOGL_DEBUG, "Opened database\n"); + break; + case 1: + LOGP(DDB, LOGL_DEBUG, "%s\n", stmt); + break; + case 2: + LOGP(DDB, LOGL_DEBUG, "Closed database\n"); + break; + default: + LOGP(DDB, LOGL_DEBUG, "Unknown %d\n", type); + break; } - dbi_result_free(result); - - return 0; } -/** - * Copied from the normal sms_from_result_v3 to avoid having - * to make sure that the real routine will remain backward - * compatible. - */ -static struct gsm_sms *sms_from_result_v3(dbi_result result) +/* remove statement bindings and reset statement to be re-executed */ +static void db_remove_reset(sqlite3_stmt *stmt) { - struct gsm_sms *sms = sms_alloc(); - long long unsigned int sender_id; - const char *text, *daddr; - const unsigned char *user_data; - char buf[32]; - char *quoted; - dbi_result result2; - const char *extension; - - if (!sms) - return NULL; - - sms->id = dbi_result_get_ulonglong(result, "id"); - - /* find extension by id, assuming that the subscriber still exists in - * the db */ - sender_id = dbi_result_get_ulonglong(result, "sender_id"); - snprintf(buf, sizeof(buf), "%llu", sender_id); - - dbi_conn_quote_string_copy(conn, buf, "ed); - result2 = dbi_conn_queryf(conn, - "SELECT extension FROM Subscriber " - "WHERE id = %s ", quoted); - free(quoted); - extension = dbi_result_get_string(result2, "extension"); - if (extension) - OSMO_STRLCPY_ARRAY(sms->src.addr, extension); - dbi_result_free(result2); - /* got the extension */ - - sms->reply_path_req = dbi_result_get_ulonglong(result, "reply_path_req"); - sms->status_rep_req = dbi_result_get_ulonglong(result, "status_rep_req"); - sms->ud_hdr_ind = dbi_result_get_ulonglong(result, "ud_hdr_ind"); - sms->protocol_id = dbi_result_get_ulonglong(result, "protocol_id"); - sms->data_coding_scheme = dbi_result_get_ulonglong(result, - "data_coding_scheme"); - - daddr = dbi_result_get_string(result, "dest_addr"); - if (daddr) - OSMO_STRLCPY_ARRAY(sms->dst.addr, daddr); - - sms->user_data_len = dbi_result_get_field_length(result, "user_data"); - user_data = dbi_result_get_binary(result, "user_data"); - if (sms->user_data_len > sizeof(sms->user_data)) - sms->user_data_len = (uint8_t) sizeof(sms->user_data); - memcpy(sms->user_data, user_data, sms->user_data_len); - - text = dbi_result_get_string(result, "text"); - if (text) - OSMO_STRLCPY_ARRAY(sms->text, text); - return sms; + sqlite3_clear_bindings(stmt); + /* sqlite3_reset() just repeats an error code already evaluated during sqlite3_step(). */ + /* coverity[CHECKED_RETURN] */ + sqlite3_reset(stmt); } -static int update_db_revision_3(void) +/** bind blob arg and do proper cleanup in case of failure. If param_name is + * NULL, bind to the first parameter (useful for SQL statements that have only + * one parameter). */ +static bool db_bind_blob(sqlite3_stmt *stmt, const char *param_name, + const uint8_t *blob, size_t blob_len) { - dbi_result result; - struct gsm_sms *sms; - - LOGP(DDB, LOGL_NOTICE, "Going to migrate from revision 3\n"); - - result = dbi_conn_query(conn, "BEGIN EXCLUSIVE TRANSACTION"); - if (!result) { - LOGP(DDB, LOGL_ERROR, - "Failed to begin transaction (upgrade from rev 3)\n"); - return -EINVAL; + int rc; + int idx = param_name ? sqlite3_bind_parameter_index(stmt, param_name) : 1; + if (idx < 1) { + LOGP(DDB, LOGL_ERROR, "Error composing SQL, cannot bind parameter '%s'\n", + param_name); + return false; } - dbi_result_free(result); - - /* Rename old SMS table to be able create a new one */ - result = dbi_conn_query(conn, "ALTER TABLE SMS RENAME TO SMS_3"); - if (!result) { - LOGP(DDB, LOGL_ERROR, - "Failed to rename the old SMS table (upgrade from rev 3).\n"); - goto rollback; + rc = sqlite3_bind_blob(stmt, idx, blob, blob_len, SQLITE_STATIC); + if (rc != SQLITE_OK) { + LOGP(DDB, LOGL_ERROR, "Error binding blob to SQL parameter %s: %d\n", + param_name ? param_name : "#1", rc); + db_remove_reset(stmt); + return false; } - dbi_result_free(result); - - /* Create new SMS table with all the bells and whistles! */ - result = dbi_conn_query(conn, create_stmts[SCHEMA_SMS]); - if (!result) { - LOGP(DDB, LOGL_ERROR, - "Failed to create a new SMS table (upgrade from rev 3).\n"); - goto rollback; - } - dbi_result_free(result); - - /* Cycle through old messages and convert them to the new format */ - result = dbi_conn_query(conn, "SELECT * FROM SMS_3"); - if (!result) { - LOGP(DDB, LOGL_ERROR, - "Failed fetch messages from the old SMS table (upgrade from rev 3).\n"); - goto rollback; - } - while (next_row(result)) { - sms = sms_from_result_v3(result); - if (db_sms_store(sms) != 0) { - LOGP(DDB, LOGL_ERROR, "Failed to store message to the new SMS table(upgrade from rev 3).\n"); - sms_free(sms); - dbi_result_free(result); - goto rollback; - } - sms_free(sms); - } - dbi_result_free(result); - - /* Remove the temporary table */ - result = dbi_conn_query(conn, "DROP TABLE SMS_3"); - if (!result) { - LOGP(DDB, LOGL_ERROR, - "Failed to drop the old SMS table (upgrade from rev 3).\n"); - goto rollback; - } - dbi_result_free(result); - - /* We're done. Bump DB Meta revision to 4 */ - result = dbi_conn_query(conn, - "UPDATE Meta " - "SET value = '4' " - "WHERE key = 'revision'"); - if (!result) { - LOGP(DDB, LOGL_ERROR, - "Failed to update DB schema revision (upgrade from rev 3).\n"); - goto rollback; - } - dbi_result_free(result); - - result = dbi_conn_query(conn, "COMMIT TRANSACTION"); - if (!result) { - LOGP(DDB, LOGL_ERROR, - "Failed to commit the transaction (upgrade from rev 3)\n"); - return -EINVAL; - } else { - dbi_result_free(result); - } - - /* Shrink DB file size by actually wiping out SMS_3 table data */ - result = dbi_conn_query(conn, "VACUUM"); - if (!result) - LOGP(DDB, LOGL_ERROR, - "VACUUM failed. Ignoring it (upgrade from rev 3).\n"); - else - dbi_result_free(result); - - return 0; - -rollback: - result = dbi_conn_query(conn, "ROLLBACK TRANSACTION"); - if (!result) - LOGP(DDB, LOGL_ERROR, - "Rollback failed (upgrade from rev 3).\n"); - else - dbi_result_free(result); - return -EINVAL; + return true; } -/* Just like v3, but there is a new message reference field for status reports, - * that is set to zero for existing entries since there is no way we can infer - * this. - */ -static struct gsm_sms *sms_from_result_v4(dbi_result result) +/** bind text arg and do proper cleanup in case of failure. If param_name is + * NULL, bind to the first parameter (useful for SQL statements that have only + * one parameter). */ +static bool db_bind_text(sqlite3_stmt *stmt, const char *param_name, const char *text) { - struct gsm_sms *sms = sms_alloc(); - const unsigned char *user_data; - const char *text, *addr; - - if (!sms) - return NULL; - - sms->id = dbi_result_get_ulonglong(result, "id"); - - sms->reply_path_req = dbi_result_get_ulonglong(result, "reply_path_req"); - sms->status_rep_req = dbi_result_get_ulonglong(result, "status_rep_req"); - sms->ud_hdr_ind = dbi_result_get_ulonglong(result, "ud_hdr_ind"); - sms->protocol_id = dbi_result_get_ulonglong(result, "protocol_id"); - sms->data_coding_scheme = dbi_result_get_ulonglong(result, - "data_coding_scheme"); - - addr = dbi_result_get_string(result, "src_addr"); - OSMO_STRLCPY_ARRAY(sms->src.addr, addr); - sms->src.ton = dbi_result_get_ulonglong(result, "src_ton"); - sms->src.npi = dbi_result_get_ulonglong(result, "src_npi"); - - addr = dbi_result_get_string(result, "dest_addr"); - OSMO_STRLCPY_ARRAY(sms->dst.addr, addr); - sms->dst.ton = dbi_result_get_ulonglong(result, "dest_ton"); - sms->dst.npi = dbi_result_get_ulonglong(result, "dest_npi"); - - sms->user_data_len = dbi_result_get_field_length(result, "user_data"); - user_data = dbi_result_get_binary(result, "user_data"); - if (sms->user_data_len > sizeof(sms->user_data)) - sms->user_data_len = (uint8_t) sizeof(sms->user_data); - memcpy(sms->user_data, user_data, sms->user_data_len); - - text = dbi_result_get_string(result, "text"); - if (text) - OSMO_STRLCPY_ARRAY(sms->text, text); - return sms; -} - -static int update_db_revision_4(void) -{ - dbi_result result; - struct gsm_sms *sms; - - LOGP(DDB, LOGL_NOTICE, "Going to migrate from revision 4\n"); - - result = dbi_conn_query(conn, "BEGIN EXCLUSIVE TRANSACTION"); - if (!result) { - LOGP(DDB, LOGL_ERROR, - "Failed to begin transaction (upgrade from rev 4)\n"); - return -EINVAL; + int rc; + int idx = param_name ? sqlite3_bind_parameter_index(stmt, param_name) : 1; + if (idx < 1) { + LOGP(DDB, LOGL_ERROR, "Error composing SQL, cannot bind parameter '%s'\n", + param_name); + return false; } - dbi_result_free(result); - - /* Rename old SMS table to be able create a new one */ - result = dbi_conn_query(conn, "ALTER TABLE SMS RENAME TO SMS_4"); - if (!result) { - LOGP(DDB, LOGL_ERROR, - "Failed to rename the old SMS table (upgrade from rev 4).\n"); - goto rollback; - } - dbi_result_free(result); - - /* Create new SMS table with all the bells and whistles! */ - result = dbi_conn_query(conn, create_stmts[SCHEMA_SMS]); - if (!result) { - LOGP(DDB, LOGL_ERROR, - "Failed to create a new SMS table (upgrade from rev 4).\n"); - goto rollback; + rc = sqlite3_bind_text(stmt, idx, text, -1, SQLITE_STATIC); + if (rc != SQLITE_OK) { + LOGP(DDB, LOGL_ERROR, "Error binding text to SQL parameter %s: %d\n", + param_name ? param_name : "#1", rc); + db_remove_reset(stmt); + return false; } - dbi_result_free(result); + return true; +} - /* Cycle through old messages and convert them to the new format */ - result = dbi_conn_query(conn, "SELECT * FROM SMS_4"); - if (!result) { - LOGP(DDB, LOGL_ERROR, - "Failed fetch messages from the old SMS table (upgrade from rev 4).\n"); - goto rollback; +/** bind int arg and do proper cleanup in case of failure. If param_name is + * NULL, bind to the first parameter (useful for SQL statements that have only + * one parameter). */ +static bool db_bind_int(sqlite3_stmt *stmt, const char *param_name, int nr) +{ + int rc; + int idx = param_name ? sqlite3_bind_parameter_index(stmt, param_name) : 1; + if (idx < 1) { + LOGP(DDB, LOGL_ERROR, "Error composing SQL, cannot bind parameter '%s'\n", + param_name); + return false; } - while (next_row(result)) { - sms = sms_from_result_v4(result); - if (db_sms_store(sms) != 0) { - LOGP(DDB, LOGL_ERROR, "Failed to store message to the new SMS table(upgrade from rev 4).\n"); - sms_free(sms); - dbi_result_free(result); - goto rollback; - } - sms_free(sms); + rc = sqlite3_bind_int(stmt, idx, nr); + if (rc != SQLITE_OK) { + LOGP(DDB, LOGL_ERROR, "Error binding int64 to SQL parameter %s: %d\n", + param_name ? param_name : "#1", rc); + db_remove_reset(stmt); + return false; } - dbi_result_free(result); + return true; +} - /* Remove the temporary table */ - result = dbi_conn_query(conn, "DROP TABLE SMS_4"); - if (!result) { - LOGP(DDB, LOGL_ERROR, - "Failed to drop the old SMS table (upgrade from rev 4).\n"); - goto rollback; - } - dbi_result_free(result); - - /* We're done. Bump DB Meta revision to 4 */ - result = dbi_conn_query(conn, - "UPDATE Meta " - "SET value = '5' " - "WHERE key = 'revision'"); - if (!result) { - LOGP(DDB, LOGL_ERROR, - "Failed to update DB schema revision (upgrade from rev 4).\n"); - goto rollback; +/** bind int64 arg and do proper cleanup in case of failure. If param_name is + * NULL, bind to the first parameter (useful for SQL statements that have only + * one parameter). */ +static bool db_bind_int64(sqlite3_stmt *stmt, const char *param_name, int64_t nr) +{ + int rc; + int idx = param_name ? sqlite3_bind_parameter_index(stmt, param_name) : 1; + if (idx < 1) { + LOGP(DDB, LOGL_ERROR, "Error composing SQL, cannot bind parameter '%s'\n", + param_name); + return false; } - dbi_result_free(result); - - result = dbi_conn_query(conn, "COMMIT TRANSACTION"); - if (!result) { - LOGP(DDB, LOGL_ERROR, - "Failed to commit the transaction (upgrade from rev 4)\n"); - return -EINVAL; - } else { - dbi_result_free(result); + rc = sqlite3_bind_int64(stmt, idx, nr); + if (rc != SQLITE_OK) { + LOGP(DDB, LOGL_ERROR, "Error binding int64 to SQL parameter %s: %d\n", + param_name ? param_name : "#1", rc); + db_remove_reset(stmt); + return false; } + return true; +} - /* Shrink DB file size by actually wiping out SMS_4 table data */ - result = dbi_conn_query(conn, "VACUUM"); - if (!result) - LOGP(DDB, LOGL_ERROR, - "VACUUM failed. Ignoring it (upgrade from rev 4).\n"); - else - dbi_result_free(result); - +/* callback for sqlite3_exec() below */ +static int db_rev_exec_cb(void *priv, int num_cols, char **vals, char **names) +{ + char **rev_s = priv; + OSMO_ASSERT(!strcmp(names[0], "value")); + *rev_s = talloc_strdup(NULL, vals[0]); return 0; - -rollback: - result = dbi_conn_query(conn, "ROLLBACK TRANSACTION"); - if (!result) - LOGP(DDB, LOGL_ERROR, - "Rollback failed (upgrade from rev 4).\n"); - else - dbi_result_free(result); - return -EINVAL; } -static int check_db_revision(void) +static int check_db_revision(struct db_context *dbc) { - dbi_result result; - const char *rev_s; + char *errstr = NULL; + char *rev_s; int db_rev = 0; + int rc; /* Make a query */ - result = dbi_conn_query(conn, - "SELECT value FROM Meta " - "WHERE key = 'revision'"); - - if (!result) - return -EINVAL; - - if (!next_row(result)) { - dbi_result_free(result); - return -EINVAL; - } - - /* Fetch the DB schema revision */ - rev_s = dbi_result_get_string(result, "value"); - if (!rev_s) { - dbi_result_free(result); + rc = sqlite3_exec(dbc->db, "SELECT value FROM Meta WHERE key = 'revision'", + db_rev_exec_cb, &rev_s, &errstr); + if (rc != SQLITE_OK) { + LOGP(DDB, LOGL_ERROR, "Cannot execute SELECT value from META: %s\n", errstr); + sqlite3_free(errstr); return -EINVAL; } if (!strcmp(rev_s, SCHEMA_REVISION)) { /* Everything is fine */ - dbi_result_free(result); + talloc_free(rev_s); return 0; } + LOGP(DDB, LOGL_NOTICE, "Detected DB Revision %s, expected %s\n", rev_s, SCHEMA_REVISION); + db_rev = atoi(rev_s); - dbi_result_free(result); + talloc_free(rev_s); /* Incremental migration waterfall */ switch (db_rev) { case 2: - if (update_db_revision_2()) - goto error; - /* fall through */ case 3: - if (update_db_revision_3()) - goto error; - /* fall through */ case 4: - if (update_db_revision_4()) - goto error; - - /* The end of waterfall */ - break; + LOGP(DDB, LOGL_FATAL, "You must use osmo-msc 1.1.0 to 1.8.0 to upgrade database " + "schema from '%u' to '5', sorry\n", db_rev); + break; + case 5: + LOGP(DDB, LOGL_FATAL, "The storage format of BINARY data in the database " + "has changed. In order to deliver any pending SMS in your database, " + "you must manually convert your database from " + "'%u' to '6'. Alternatively you can use a fresh, blank database " + "with this version of osmo-msc, sorry.\n", db_rev); + return -1; + break; default: - LOGP(DDB, LOGL_FATAL, - "Invalid database schema revision '%d'.\n", db_rev); + LOGP(DDB, LOGL_FATAL, "Invalid database schema revision '%d'.\n", db_rev); return -EINVAL; } return 0; -error: - LOGP(DDB, LOGL_FATAL, "Failed to update database " - "from schema revision '%d'.\n", db_rev); +//error: + LOGP(DDB, LOGL_FATAL, "Failed to update database from schema revision '%d'.\n", db_rev); + talloc_free(rev_s); + return -EINVAL; } -static int db_configure(void) +/*********************************************************************** + * USER API + ***********************************************************************/ + +int db_init(void *ctx, const char *fname, bool enable_sqlite_logging) { - dbi_result result; + unsigned int i; + int rc; + bool has_sqlite_config_sqllog = false; - result = dbi_conn_query(conn, - "PRAGMA synchronous = FULL"); - if (!result) - return -EINVAL; + g_dbc = talloc_zero(ctx, struct db_context); + OSMO_ASSERT(g_dbc); - dbi_result_free(result); - return 0; -} + /* we are a single-threaded program; we want to avoid all the mutex/etc. overhead */ + sqlite3_config(SQLITE_CONFIG_SINGLETHREAD); -int db_init(const char *name) -{ - dbi_initialize_r(NULL, &inst); + LOGP(DDB, LOGL_NOTICE, "Init database connection to '%s' using SQLite3 lib version %s\n", + fname, sqlite3_libversion()); - LOGP(DDB, LOGL_NOTICE, "Init database connection to '%s' using %s\n", - name, dbi_version()); + g_dbc->fname = talloc_strdup(g_dbc, fname); - conn = dbi_conn_new_r("sqlite3", inst); - if (conn == NULL) { - LOGP(DDB, LOGL_FATAL, "Failed to create database connection to sqlite3 db '%s'; " - "Is the sqlite3 database driver for libdbi installed on this system?\n", name); - return 1; + for (i = 0; i < 0xfffff; i++) { + const char *o = sqlite3_compileoption_get(i); + if (!o) + break; + LOGP(DDB, LOGL_DEBUG, "SQLite3 compiled with '%s'\n", o); + if (!strcmp(o, "ENABLE_SQLLOG")) + has_sqlite_config_sqllog = true; } - dbi_conn_error_handler( conn, db_error_func, NULL ); + if (enable_sqlite_logging) { + rc = sqlite3_config(SQLITE_CONFIG_LOG, sql3_error_log_cb, NULL); + if (rc != SQLITE_OK) + LOGP(DDB, LOGL_NOTICE, "Unable to set SQLite3 error log callback\n"); + } - /* MySQL - dbi_conn_set_option(conn, "host", "localhost"); - dbi_conn_set_option(conn, "username", "your_name"); - dbi_conn_set_option(conn, "password", "your_password"); - dbi_conn_set_option(conn, "dbname", "your_dbname"); - dbi_conn_set_option(conn, "encoding", "UTF-8"); - */ + if (has_sqlite_config_sqllog) { + rc = sqlite3_config(SQLITE_CONFIG_SQLLOG, sql3_sql_log_cb, NULL); + if (rc != SQLITE_OK) + LOGP(DDB, LOGL_NOTICE, "Unable to set SQLite3 SQL log callback\n"); + } else { + LOGP(DDB, LOGL_DEBUG, "Not setting SQL log callback:" + " SQLite3 compiled without support for it\n"); + } - /* SqLite 3 */ - db_basename = strdup(name); - db_dirname = strdup(name); - dbi_conn_set_option(conn, "sqlite3_dbdir", dirname(db_dirname)); - dbi_conn_set_option(conn, "dbname", basename(db_basename)); + rc = sqlite3_open(g_dbc->fname, &g_dbc->db); + if (rc != SQLITE_OK) { + LOGP(DDB, LOGL_ERROR, "Unable to open DB; rc =%d\n", rc); + talloc_free(g_dbc); + return -1; + } + + /* enable extended result codes */ + rc = sqlite3_extended_result_codes(g_dbc->db, 1); + if (rc != SQLITE_OK) { + LOGP(DDB, LOGL_ERROR, "Unable to enable SQLite3 extended result codes\n"); + /* non-fatal */ + } - if (dbi_conn_connect(conn) < 0) - goto out_err; + char *err_msg; + rc = sqlite3_exec(g_dbc->db, "PRAGMA journal_mode=WAL; PRAGMA synchronous = NORMAL;", 0, 0, &err_msg); + if (rc != SQLITE_OK) { + LOGP(DDB, LOGL_ERROR, "Unable to set Write-Ahead Logging: %s\n", err_msg); + sqlite3_free(err_msg); + /* non-fatal */ + } + + rc = sqlite3_exec(g_dbc->db, "PRAGMA secure_delete=0;", 0, 0, &err_msg); + if (rc != SQLITE_OK) { + LOGP(DDB, LOGL_ERROR, "Unable to disable SECURE_DELETE: %s\n", err_msg); + sqlite3_free(err_msg); + /* non-fatal */ + } return 0; +} + +int db_fini(void) +{ + unsigned int i; + int rc; + + if (!g_dbc) + return 0; + + for (i = 0; i < ARRAY_SIZE(g_dbc->stmt); i++) { + /* it is ok to call finalize on NULL */ + sqlite3_finalize(g_dbc->stmt[i]); + } -out_err: - free(db_dirname); - free(db_basename); - db_dirname = db_basename = NULL; - return -1; + /* Ask sqlite3 to close DB */ + rc = sqlite3_close(g_dbc->db); + if (rc != SQLITE_OK) { /* Make sure it's actually closed! */ + LOGP(DDB, LOGL_ERROR, "Couldn't close database: (rc=%d) %s\n", + rc, sqlite3_errmsg(g_dbc->db)); + } + + talloc_free(g_dbc); + g_dbc = NULL; + + return 0; } +/* run (execute) a series of SQL statements */ +static int db_run_statements(struct db_context *dbc, const char **statements, size_t statements_count) +{ + int i; + for (i = 0; i < statements_count; i++) { + const char *stmt_str = statements[i]; + char *errmsg = NULL; + int rc; + + rc = sqlite3_exec(dbc->db, stmt_str, NULL, NULL, &errmsg); + if (rc != SQLITE_OK) { + LOGP(DDB, LOGL_ERROR, "SQL error during SQL statement '%s': %s\n", stmt_str, errmsg); + sqlite3_free(errmsg); + return -1; + } + } + return 0; +} int db_prepare(void) { - dbi_result result; - int i; + unsigned int i; + int rc; - for (i = 0; i < ARRAY_SIZE(create_stmts); i++) { - result = dbi_conn_query(conn, create_stmts[i]); - if (!result) { - LOGP(DDB, LOGL_ERROR, - "Failed to create some table.\n"); - return 1; - } - dbi_result_free(result); + OSMO_ASSERT(g_dbc); + rc = db_run_statements(g_dbc, create_stmts, ARRAY_SIZE(create_stmts)); + if (rc < 0) { + LOGP(DDB, LOGL_ERROR, "Failed to create some table.\n"); + return 1; } - if (check_db_revision() < 0) { + if (check_db_revision(g_dbc) < 0) { LOGP(DDB, LOGL_FATAL, "Database schema revision invalid, " "please update your database schema\n"); return -1; } - db_configure(); - - return 0; -} - -int db_fini(void) -{ - dbi_conn_close(conn); - dbi_shutdown_r(inst); + /* prepare all SQL statements */ + for (i = 0; i < ARRAY_SIZE(g_dbc->stmt); i++) { + rc = sqlite3_prepare_v2(g_dbc->db, stmt_sql[i], -1, + &g_dbc->stmt[i], NULL); + if (rc != SQLITE_OK) { + LOGP(DDB, LOGL_ERROR, "Unable to prepare SQL statement '%s'\n", stmt_sql[i]); + return -1; + } + } - free(db_dirname); - free(db_basename); return 0; } /* store an [unsent] SMS to the database */ int db_sms_store(struct gsm_sms *sms) { - dbi_result result; - char *q_text, *q_daddr, *q_saddr; - unsigned char *q_udata; + OSMO_ASSERT(g_dbc); + sqlite3_stmt *stmt = g_dbc->stmt[DB_STMT_SMS_STORE]; time_t now, validity_timestamp; - - dbi_conn_quote_string_copy(conn, (char *)sms->text, &q_text); - dbi_conn_quote_string_copy(conn, (char *)sms->dst.addr, &q_daddr); - dbi_conn_quote_string_copy(conn, (char *)sms->src.addr, &q_saddr); - dbi_conn_quote_binary_copy(conn, sms->user_data, sms->user_data_len, - &q_udata); + int rc; now = time(NULL); validity_timestamp = now + sms->validity_minutes * 60; - result = dbi_conn_queryf(conn, - "INSERT INTO SMS " - "(created, valid_until, " - "reply_path_req, status_rep_req, is_report, " - "msg_ref, protocol_id, data_coding_scheme, " - "ud_hdr_ind, " - "user_data, text, " - "dest_addr, dest_ton, dest_npi, " - "src_addr, src_ton, src_npi) VALUES " - "(datetime('%lld', 'unixepoch'), datetime('%lld', 'unixepoch'), " - "%u, %u, %u, " - "%u, %u, %u, " - "%u, " - "%s, %s, " - "%s, %u, %u, " - "%s, %u, %u)", - (int64_t)now, (int64_t)validity_timestamp, - sms->reply_path_req, sms->status_rep_req, sms->is_report, - sms->msg_ref, sms->protocol_id, sms->data_coding_scheme, - sms->ud_hdr_ind, - q_udata, q_text, - q_daddr, sms->dst.ton, sms->dst.npi, - q_saddr, sms->src.ton, sms->src.npi); - free(q_text); - free(q_udata); - free(q_daddr); - free(q_saddr); - - if (!result) + db_bind_int64(stmt, "$created", (int64_t) now); + db_bind_int64(stmt, "$valid_until", (int64_t) validity_timestamp); + db_bind_int(stmt, "$reply_path_req", sms->reply_path_req); + db_bind_int(stmt, "$status_rep_req", sms->status_rep_req); + db_bind_int(stmt, "$is_report", sms->is_report); + db_bind_int(stmt, "$msg_ref", sms->msg_ref); + db_bind_int(stmt, "$protocol_id", sms->protocol_id); + db_bind_int(stmt, "$data_coding_scheme", sms->data_coding_scheme); + db_bind_int(stmt, "$ud_hdr_ind", sms->ud_hdr_ind); + /* FIXME: do we need to use legacy DBI compatible quoting of sms->user_data? */ + db_bind_blob(stmt, "$user_data", sms->user_data, sms->user_data_len); + db_bind_text(stmt, "$text", (char *)sms->text); + db_bind_text(stmt, "$dest_addr", (char *)sms->dst.addr); + db_bind_int(stmt, "$dest_ton", sms->dst.ton); + db_bind_int(stmt, "$dest_npi", sms->dst.npi); + db_bind_text(stmt, "$src_addr", (char *)sms->src.addr); + db_bind_int(stmt, "$src_ton", sms->src.ton); + db_bind_int(stmt, "$src_npi", sms->src.npi); + + /* execute statement */ + rc = sqlite3_step(stmt); + db_remove_reset(stmt); + if (rc != SQLITE_DONE) { + LOGP(DDB, LOGL_ERROR, "Cannot create SMS: SQL error: (%d) %s\n", rc, sqlite3_errmsg(g_dbc->db)); return -EIO; + } + + sms->id = sqlite3_last_insert_rowid(g_dbc->db); + + LOGP(DLSMS, LOGL_INFO, "Stored SMS id=%llu in DB\n", sms->id); - dbi_result_free(result); return 0; } -static struct gsm_sms *sms_from_result(struct gsm_network *net, dbi_result result) +static void parse_tp_ud_from_result(struct gsm_sms *sms, sqlite3_stmt *stmt) { - struct gsm_sms *sms = sms_alloc(); - const char *text, *daddr, *saddr; const unsigned char *user_data; + unsigned int user_data_len; + unsigned int text_len; + const char *text; + + /* Retrieve TP-UDL (User-Data-Length) in octets (regardless of DCS) */ + user_data_len = sqlite3_column_bytes(stmt, COL_USER_DATA); + if (user_data_len > sizeof(sms->user_data)) { + LOGP(DDB, LOGL_ERROR, + "SMS TP-UD length %u is too big, truncating to %zu\n", + user_data_len, sizeof(sms->user_data)); + user_data_len = (uint8_t) sizeof(sms->user_data); + } + sms->user_data_len = user_data_len; + + /* Retrieve the TP-UD (User-Data) itself */ + if (user_data_len > 0) { + user_data = sqlite3_column_blob(stmt, COL_USER_DATA); + memcpy(sms->user_data, user_data, user_data_len); + } + + /* Retrieve the text length (excluding '\0') */ + text_len = sqlite3_column_bytes(stmt, COL_TEXT); + if (text_len >= sizeof(sms->text)) { + LOGP(DDB, LOGL_ERROR, + "SMS text length %u is too big, truncating to %zu\n", + text_len, sizeof(sms->text) - 1); + /* OSMO_STRLCPY_ARRAY() does truncation for us */ + } + + /* Retrieve the text parsed from TP-UD (User-Data) */ + text = (const char *)sqlite3_column_text(stmt, COL_TEXT); + if (text) + OSMO_STRLCPY_ARRAY(sms->text, text); +} + +static struct gsm_sms *sms_from_result(struct gsm_network *net, sqlite3_stmt *stmt) +{ + struct gsm_sms *sms = sms_alloc(); + const char *daddr, *saddr; time_t validity_timestamp; if (!sms) return NULL; - sms->id = dbi_result_get_ulonglong(result, "id"); + sms->id = sqlite3_column_int64(stmt, COL_ID); + + sms->created = sqlite3_column_int64(stmt, COL_CREATED); + validity_timestamp = sqlite3_column_int64(stmt, COL_VALID_UNTIL); - sms->created = dbi_result_get_datetime(result, "created"); - validity_timestamp = dbi_result_get_datetime(result, "valid_until"); sms->validity_minutes = (validity_timestamp - sms->created) / 60; - /* FIXME: those should all be get_uchar, but sqlite3 is braindead */ - sms->reply_path_req = dbi_result_get_ulonglong(result, "reply_path_req"); - sms->status_rep_req = dbi_result_get_ulonglong(result, "status_rep_req"); - sms->is_report = dbi_result_get_ulonglong(result, "is_report"); - sms->msg_ref = dbi_result_get_ulonglong(result, "msg_ref"); - sms->ud_hdr_ind = dbi_result_get_ulonglong(result, "ud_hdr_ind"); - sms->protocol_id = dbi_result_get_ulonglong(result, "protocol_id"); - sms->data_coding_scheme = dbi_result_get_ulonglong(result, - "data_coding_scheme"); - - sms->dst.npi = dbi_result_get_ulonglong(result, "dest_npi"); - sms->dst.ton = dbi_result_get_ulonglong(result, "dest_ton"); - daddr = dbi_result_get_string(result, "dest_addr"); + sms->reply_path_req = sqlite3_column_int(stmt, COL_REPLY_PATH_REQ); + sms->status_rep_req = sqlite3_column_int(stmt, COL_STATUS_REP_REQ); + sms->is_report = sqlite3_column_int(stmt, COL_IS_REPORT); + sms->msg_ref = sqlite3_column_int(stmt, COL_MSG_REF); + sms->ud_hdr_ind = sqlite3_column_int(stmt, COL_UD_HDR_IND); + sms->protocol_id = sqlite3_column_int(stmt, COL_PROTOCOL_ID); + sms->data_coding_scheme = sqlite3_column_int(stmt, COL_DATA_CODING_SCHEME); + + sms->dst.npi = sqlite3_column_int(stmt, COL_DEST_NPI); + sms->dst.ton = sqlite3_column_int(stmt, COL_DEST_TON); + daddr = (const char *)sqlite3_column_text(stmt, COL_DEST_ADDR); if (daddr) OSMO_STRLCPY_ARRAY(sms->dst.addr, daddr); - sms->receiver = vlr_subscr_find_by_msisdn(net->vlr, sms->dst.addr, VSUB_USE_SMS_RECEIVER); - sms->src.npi = dbi_result_get_ulonglong(result, "src_npi"); - sms->src.ton = dbi_result_get_ulonglong(result, "src_ton"); - saddr = dbi_result_get_string(result, "src_addr"); + if (net != NULL) /* db_sms_test passes NULL, so we need to be tolerant */ + sms->receiver = vlr_subscr_find_by_msisdn(net->vlr, sms->dst.addr, + VSUB_USE_SMS_RECEIVER); + + sms->src.npi = sqlite3_column_int(stmt, COL_SRC_NPI); + sms->src.ton = sqlite3_column_int(stmt, COL_SRC_TON); + saddr = (const char *)sqlite3_column_text(stmt, COL_SRC_ADDR); if (saddr) OSMO_STRLCPY_ARRAY(sms->src.addr, saddr); - sms->user_data_len = dbi_result_get_field_length(result, "user_data"); - user_data = dbi_result_get_binary(result, "user_data"); - if (sms->user_data_len > sizeof(sms->user_data)) - sms->user_data_len = (uint8_t) sizeof(sms->user_data); - memcpy(sms->user_data, user_data, sms->user_data_len); + /* Parse TP-UD, TP-UDL and decoded text */ + parse_tp_ud_from_result(sms, stmt); - text = dbi_result_get_string(result, "text"); - if (text) - OSMO_STRLCPY_ARRAY(sms->text, text); return sms; } struct gsm_sms *db_sms_get(struct gsm_network *net, unsigned long long id) { - dbi_result result; + OSMO_ASSERT(g_dbc); + sqlite3_stmt *stmt = g_dbc->stmt[DB_STMT_SMS_GET]; struct gsm_sms *sms; + int rc; - result = dbi_conn_queryf(conn, - "SELECT * FROM SMS WHERE SMS.id = %llu", id); - if (!result) - return NULL; + db_bind_int64(stmt, "$id", id); - if (!next_row(result)) { - dbi_result_free(result); + rc = sqlite3_step(stmt); + if (rc != SQLITE_ROW) { + db_remove_reset(stmt); return NULL; } - sms = sms_from_result(net, result); - - dbi_result_free(result); + sms = sms_from_result(net, stmt); + db_remove_reset(stmt); return sms; } struct gsm_sms *db_sms_get_next_unsent(struct gsm_network *net, unsigned long long min_sms_id, - unsigned int max_failed) + int max_failed) { - dbi_result result; + OSMO_ASSERT(g_dbc); + sqlite3_stmt *stmt = g_dbc->stmt[DB_STMT_SMS_GET_NEXT_UNSENT]; struct gsm_sms *sms; + int rc; - result = dbi_conn_queryf(conn, - "SELECT * FROM SMS" - " WHERE sent IS NULL" - " AND id >= %llu" - " AND deliver_attempts <= %u" - " ORDER BY id LIMIT 1", - min_sms_id, max_failed); + db_bind_int64(stmt, "$id", min_sms_id); + db_bind_int(stmt, "$attempts", max_failed); - if (!result) - return NULL; - - if (!next_row(result)) { - dbi_result_free(result); + rc = sqlite3_step(stmt); + if (rc != SQLITE_ROW) { + db_remove_reset(stmt); return NULL; } - sms = sms_from_result(net, result); - - dbi_result_free(result); + sms = sms_from_result(net, stmt); + db_remove_reset(stmt); return sms; } /* retrieve the next unsent SMS for a given subscriber */ struct gsm_sms *db_sms_get_unsent_for_subscr(struct vlr_subscr *vsub, - unsigned int max_failed) + int max_failed) { + OSMO_ASSERT(g_dbc); + sqlite3_stmt *stmt = g_dbc->stmt[DB_STMT_SMS_GET_UNSENT_FOR_SUBSCR]; struct gsm_network *net = vsub->vlr->user_ctx; - dbi_result result; struct gsm_sms *sms; - char *q_msisdn; + int rc; if (!vsub->lu_complete) return NULL; @@ -860,60 +845,42 @@ struct gsm_sms *db_sms_get_unsent_for_subscr(struct vlr_subscr *vsub, if (*vsub->msisdn == '\0') return NULL; - dbi_conn_quote_string_copy(conn, vsub->msisdn, &q_msisdn); - result = dbi_conn_queryf(conn, - "SELECT * FROM SMS" - " WHERE sent IS NULL" - " AND dest_addr = %s" - " AND deliver_attempts <= %u" - " ORDER BY id LIMIT 1", - q_msisdn, max_failed); - free(q_msisdn); - - if (!result) - return NULL; + db_bind_text(stmt, "$dest_addr", vsub->msisdn); + db_bind_int(stmt, "$attempts", max_failed); - if (!next_row(result)) { - dbi_result_free(result); + rc = sqlite3_step(stmt); + if (rc != SQLITE_ROW) { + db_remove_reset(stmt); return NULL; } - sms = sms_from_result(net, result); - - dbi_result_free(result); + sms = sms_from_result(net, stmt); + db_remove_reset(stmt); return sms; } struct gsm_sms *db_sms_get_next_unsent_rr_msisdn(struct gsm_network *net, const char *last_msisdn, - unsigned int max_failed) + int max_failed) { - dbi_result result; + OSMO_ASSERT(g_dbc); + sqlite3_stmt *stmt = g_dbc->stmt[DB_STMT_SMS_GET_NEXT_UNSENT_RR_MSISDN]; struct gsm_sms *sms; - char *q_last_msisdn; + int rc; - dbi_conn_quote_string_copy(conn, last_msisdn, &q_last_msisdn); - result = dbi_conn_queryf(conn, - "SELECT * FROM SMS" - " WHERE sent IS NULL" - " AND dest_addr > %s" - " AND deliver_attempts <= %u" - " ORDER BY dest_addr, id LIMIT 1", - q_last_msisdn, max_failed); - free(q_last_msisdn); + db_bind_text(stmt, "$dest_addr", last_msisdn); + db_bind_int(stmt, "$attempts", max_failed); - if (!result) - return NULL; - - if (!next_row(result)) { - dbi_result_free(result); + rc = sqlite3_step(stmt); + if (rc != SQLITE_ROW) { + db_remove_reset(stmt); return NULL; } - sms = sms_from_result(net, result); + sms = sms_from_result(net, stmt); - dbi_result_free(result); + db_remove_reset(stmt); return sms; } @@ -921,142 +888,156 @@ struct gsm_sms *db_sms_get_next_unsent_rr_msisdn(struct gsm_network *net, /* mark a given SMS as delivered */ int db_sms_mark_delivered(struct gsm_sms *sms) { - dbi_result result; + sqlite3_stmt *stmt; + int rc; - result = dbi_conn_queryf(conn, - "UPDATE SMS " - "SET sent = datetime('now') " - "WHERE id = %llu", sms->id); - if (!result) { + /* this only happens in unit tests that don't db_init() */ + if (!g_dbc) + return 0; + + stmt = g_dbc->stmt[DB_STMT_SMS_MARK_DELIVERED]; + db_bind_int64(stmt, "$id", sms->id); + + rc = sqlite3_step(stmt); + if (rc != SQLITE_DONE) { + db_remove_reset(stmt); LOGP(DDB, LOGL_ERROR, "Failed to mark SMS %llu as sent.\n", sms->id); return 1; } - dbi_result_free(result); + db_remove_reset(stmt); return 0; } /* increase the number of attempted deliveries */ int db_sms_inc_deliver_attempts(struct gsm_sms *sms) { - dbi_result result; + sqlite3_stmt *stmt; + int rc; - result = dbi_conn_queryf(conn, - "UPDATE SMS " - "SET deliver_attempts = deliver_attempts + 1 " - "WHERE id = %llu", sms->id); - if (!result) { - LOGP(DDB, LOGL_ERROR, "Failed to inc deliver attempts for " - "SMS %llu.\n", sms->id); + /* this only happens in unit tests that don't db_init() */ + if (!g_dbc) + return 0; + + stmt = g_dbc->stmt[DB_STMT_SMS_INC_DELIVER_ATTEMPTS]; + db_bind_int64(stmt, "$id", sms->id); + + rc = sqlite3_step(stmt); + if (rc != SQLITE_DONE) { + db_remove_reset(stmt); + LOGP(DDB, LOGL_ERROR, "Failed to inc deliver attempts for SMS %llu.\n", sms->id); return 1; } - dbi_result_free(result); + db_remove_reset(stmt); return 0; } /* Drop all pending SMS to or from the given extension */ int db_sms_delete_by_msisdn(const char *msisdn) { - dbi_result result; - char *q_msisdn; + OSMO_ASSERT(g_dbc); + sqlite3_stmt *stmt = g_dbc->stmt[DB_STMT_SMS_DEL_BY_MSISDN]; + int rc; + if (!msisdn || !*msisdn) return 0; - dbi_conn_quote_string_copy(conn, msisdn, &q_msisdn); - result = dbi_conn_queryf(conn, - "DELETE FROM SMS WHERE src_addr=%s OR dest_addr=%s", - q_msisdn, q_msisdn); - free(q_msisdn); + db_bind_text(stmt, "$src_addr", msisdn); + db_bind_text(stmt, "$dest_addr", msisdn); - if (!result) { - LOGP(DDB, LOGL_ERROR, - "Failed to delete SMS for %s\n", msisdn); + rc = sqlite3_step(stmt); + if (rc != SQLITE_DONE) { + db_remove_reset(stmt); + LOGP(DDB, LOGL_ERROR, "Failed to delete SMS for %s\n", msisdn); return -1; } - dbi_result_free(result); + + db_remove_reset(stmt); return 0; } int db_sms_delete_sent_message_by_id(unsigned long long sms_id) { - dbi_result result; + OSMO_ASSERT(g_dbc); + sqlite3_stmt *stmt = g_dbc->stmt[DB_STMT_SMS_DEL_BY_ID]; + int rc; + + db_bind_int64(stmt, "$id", sms_id); - result = dbi_conn_queryf(conn, - "DELETE FROM SMS WHERE id = %llu AND sent is NOT NULL", - sms_id); - if (!result) { + rc = sqlite3_step(stmt); + if (rc != SQLITE_DONE) { + db_remove_reset(stmt); LOGP(DDB, LOGL_ERROR, "Failed to delete SMS %llu.\n", sms_id); return 1; } - dbi_result_free(result); + db_remove_reset(stmt); return 0; } - -static int delete_expired_sms(unsigned long long sms_id, time_t created, time_t validity_timestamp) +static int delete_expired_sms(unsigned long long sms_id, time_t validity_timestamp) { - dbi_result result; - time_t now, min_created; + OSMO_ASSERT(g_dbc); + sqlite3_stmt *stmt = g_dbc->stmt[DB_STMT_SMS_DEL_EXPIRED]; + time_t now; + int rc; now = time(NULL); + + /* Net yet expired */ if (validity_timestamp > now) return -1; - /* Our SMS expiry threshold is hard-coded to roughly 2 weeks at the moment. */ - min_created = now - (time_t)(60 * 60 * 24 * 7 * 2); - if (min_created < 0) /* bogus system clock? */ - return -1; - if (created >= min_created) /* not yet expired */ - return -1; + db_bind_int64(stmt, "$id", sms_id); - result = dbi_conn_queryf(conn, "DELETE FROM SMS WHERE id = %llu", sms_id); - if (!result) { + rc = sqlite3_step(stmt); + if (rc != SQLITE_DONE) { + db_remove_reset(stmt); LOGP(DDB, LOGL_ERROR, "Failed to delete SMS %llu.\n", sms_id); return -1; } - dbi_result_free(result); + + db_remove_reset(stmt); return 0; } int db_sms_delete_expired_message_by_id(unsigned long long sms_id) { - dbi_result result; - time_t created, validity_timestamp; + OSMO_ASSERT(g_dbc); + sqlite3_stmt *stmt = g_dbc->stmt[DB_STMT_SMS_GET_VALID_UNTIL_BY_ID]; + time_t validity_timestamp; + int rc; - result = dbi_conn_queryf(conn, "SELECT created,valid_until FROM SMS WHERE id = %llu", sms_id); - if (!result) - return -1; - if (!next_row(result)) { - dbi_result_free(result); + db_bind_int64(stmt, "$id", sms_id); + + rc = sqlite3_step(stmt); + if (rc != SQLITE_ROW) { + db_remove_reset(stmt); return -1; } - created = dbi_result_get_datetime(result, "created"); - validity_timestamp = dbi_result_get_datetime(result, "valid_until"); + validity_timestamp = sqlite3_column_int64(stmt, 0); - dbi_result_free(result); - return delete_expired_sms(sms_id, created, validity_timestamp); + db_remove_reset(stmt); + return delete_expired_sms(sms_id, validity_timestamp); } void db_sms_delete_oldest_expired_message(void) { - dbi_result result; - - result = dbi_conn_queryf(conn, "SELECT id,created,valid_until FROM SMS ORDER BY created LIMIT 1"); - if (!result) - return; + OSMO_ASSERT(g_dbc); + sqlite3_stmt *stmt = g_dbc->stmt[DB_STMT_SMS_GET_OLDEST_EXPIRED]; + int rc; - if (next_row(result)) { + rc = sqlite3_step(stmt); + if (rc == SQLITE_ROW) { unsigned long long sms_id; - time_t created, validity_timestamp; + time_t validity_timestamp; - sms_id = dbi_result_get_ulonglong(result, "id"); - created = dbi_result_get_datetime(result, "created"); - validity_timestamp = dbi_result_get_datetime(result, "valid_until"); - delete_expired_sms(sms_id, created, validity_timestamp); + sms_id = sqlite3_column_int64(stmt, 0); + validity_timestamp = sqlite3_column_int64(stmt, 1); + delete_expired_sms(sms_id, validity_timestamp); } - dbi_result_free(result); + db_remove_reset(stmt); } diff --git a/src/libmsc/e_link.c b/src/libmsc/e_link.c index 0a2be795c..b26f53bc5 100644 --- a/src/libmsc/e_link.c +++ b/src/libmsc/e_link.c @@ -1,6 +1,6 @@ /* E-interface messaging over a GSUP connection */ /* - * (C) 2019 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de> + * (C) 2019 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de> * All Rights Reserved * * SPDX-License-Identifier: AGPL-3.0+ diff --git a/src/libmsc/gsm_04_08.c b/src/libmsc/gsm_04_08.c index 68b12c03a..17350faad 100644 --- a/src/libmsc/gsm_04_08.c +++ b/src/libmsc/gsm_04_08.c @@ -29,43 +29,34 @@ #include <errno.h> #include <time.h> #include <netinet/in.h> -#include <regex.h> #include <sys/types.h> #include "config.h" -#include <osmocom/msc/db.h> #include <osmocom/msc/debug.h> #include <osmocom/msc/gsm_data.h> -#include <osmocom/msc/gsm_subscriber.h> -#include <osmocom/msc/gsm_04_11.h> #include <osmocom/msc/gsm_04_08.h> -#include <osmocom/msc/gsm_04_80.h> -#include <osmocom/msc/gsm_04_14.h> -#include <osmocom/msc/gsm_09_11.h> +#include <osmocom/msc/msc_vgcs.h> #include <osmocom/msc/signal.h> #include <osmocom/msc/transaction.h> -#include <osmocom/msc/silent_call.h> -#include <osmocom/msc/mncc_int.h> -#include <osmocom/abis/e1_input.h> -#include <osmocom/core/bitvec.h> #include <osmocom/msc/vlr.h> #include <osmocom/msc/msc_a.h> -#include <osmocom/msc/paging.h> #include <osmocom/gsm/gsm48.h> -#include <osmocom/gsm/gsm0480.h> #include <osmocom/gsm/gsm_utils.h> #include <osmocom/gsm/protocol/gsm_04_08.h> #include <osmocom/core/msgb.h> #include <osmocom/core/talloc.h> #include <osmocom/core/utils.h> #include <osmocom/core/byteswap.h> +#include <osmocom/core/fsm.h> #include <osmocom/gsm/tlv.h> #include <osmocom/crypt/auth.h> +#include <osmocom/crypt/utran_cipher.h> #include <osmocom/msc/msub.h> #include <osmocom/msc/msc_roles.h> +#include <osmocom/msc/call_leg.h> #include <assert.h> @@ -129,42 +120,44 @@ static int gsm0408_loc_upd_acc(struct msc_a *msc_a, uint32_t send_tmsi) struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 LOC UPD ACC"); struct gsm48_hdr *gh; struct gsm48_loc_area_id *lai; - uint8_t *mid; - struct gsm_network *net = msc_a_net(msc_a); struct vlr_subscr *vsub = msc_a_vsub(msc_a); - struct osmo_location_area_id laid = { - .plmn = net->plmn, - .lac = vsub->cgi.lai.lac, - }; + uint8_t *l; + int rc; + struct osmo_mobile_identity mi = {}; gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); gh->proto_discr = GSM48_PDISC_MM; gh->msg_type = GSM48_MT_MM_LOC_UPD_ACCEPT; lai = (struct gsm48_loc_area_id *) msgb_put(msg, sizeof(*lai)); - gsm48_generate_lai2(lai, &laid); + gsm48_generate_lai2(lai, &vsub->cgi.lai); if (send_tmsi == GSM_RESERVED_TMSI) { /* we did not allocate a TMSI to the MS, so we need to * include the IMSI in order for the MS to delete any * old TMSI that might still be allocated */ - uint8_t mi[10]; - int len; - len = gsm48_generate_mid_from_imsi(mi, vsub->imsi); - mid = msgb_put(msg, len); - memcpy(mid, mi, len); + mi.type = GSM_MI_TYPE_IMSI; + OSMO_STRLCPY_ARRAY(mi.imsi, vsub->imsi); DEBUGP(DMM, "-> %s LOCATION UPDATE ACCEPT\n", vlr_subscr_name(vsub)); } else { /* Include the TMSI, which means that the MS will send a * TMSI REALLOCATION COMPLETE, and we should wait for * that until T3250 expiration */ - mid = msgb_put(msg, GSM48_MID_TMSI_LEN); - gsm48_generate_mid_from_tmsi(mid, send_tmsi); + mi.type = GSM_MI_TYPE_TMSI; + mi.tmsi = send_tmsi; DEBUGP(DMM, "-> %s LOCATION UPDATE ACCEPT (TMSI = 0x%08x)\n", vlr_subscr_name(vsub), send_tmsi); } + l = msgb_tl_put(msg, GSM48_IE_MOBILE_ID); + rc = osmo_mobile_identity_encode_msgb(msg, &mi, false); + if (rc < 0) { + msgb_free(msg); + return -EINVAL; + } + *l = rc; + /* TODO: Follow-on proceed */ /* TODO: CTS permission */ /* TODO: Equivalent PLMNs */ @@ -193,9 +186,11 @@ static int mm_tx_identity_req(struct msc_a *msc_a, uint8_t id_type) static int mm_rx_id_resp(struct msc_a *msc_a, struct msgb *msg) { struct gsm48_hdr *gh = msgb_l3(msg); - uint8_t *mi = gh->data+1; + uint8_t *mi_data = gh->data+1; uint8_t mi_len = gh->data[0]; struct vlr_subscr *vsub = msc_a_vsub(msc_a); + struct osmo_mobile_identity mi; + int rc; if (!vsub) { LOGP(DMM, LOGL_ERROR, @@ -203,11 +198,33 @@ static int mm_rx_id_resp(struct msc_a *msc_a, struct msgb *msg) return -EINVAL; } - DEBUGP(DMM, "IDENTITY RESPONSE: MI=%s\n", osmo_mi_name(mi, mi_len)); + /* There muct be at least one octet with MI type */ + if (!mi_len) { + LOGP(DMM, LOGL_NOTICE, "MM Identity Response contains " + "malformed Mobile Identity\n"); + return -EINVAL; + } + + rc = osmo_mobile_identity_decode(&mi, mi_data, mi_len, false); + if (rc) { + LOGP(DMM, LOGL_ERROR, "Failure to decode Mobile Identity in MM Identity Response (rc=%d)\n", rc); + return -EINVAL; + } + + /* Make sure we got what we expected */ + if (mi.type != msc_a->mm_id_req_type) { + LOGP(DMM, LOGL_NOTICE, "MM Identity Response contains unexpected " + "Mobile Identity type %s (extected %s)\n", + gsm48_mi_type_name(mi.type), + gsm48_mi_type_name(msc_a->mm_id_req_type)); + return -EINVAL; + } + + DEBUGP(DMM, "IDENTITY RESPONSE: %s\n", osmo_mobile_identity_to_str_c(OTC_SELECT, &mi)); osmo_signal_dispatch(SS_SUBSCR, S_SUBSCR_IDENTITY, gh->data); - return vlr_subscr_rx_id_resp(vsub, mi, mi_len); + return vlr_subscr_rx_id_resp(vsub, &mi); } /* 9.2.5 CM service accept */ @@ -225,7 +242,9 @@ static int msc_gsm48_tx_mm_serv_ack(struct msc_a *msc_a) return msc_a_tx_dtap_to_i(msc_a, msg); } -/* 9.2.6 CM service reject */ +/* 9.2.6 CM service reject. + * For an active and valid CM Service Request, instead use msc_vlr_tx_cm_serv_rej(), which also takes care of + * decrementing the use token for that service type. */ static int msc_gsm48_tx_mm_serv_rej(struct msc_a *msc_a, enum gsm48_reject_value value) { @@ -301,8 +320,6 @@ static int mm_rx_loc_upd_req(struct msc_a *msc_a, struct msgb *msg) { struct gsm48_hdr *gh = msgb_l3(msg); struct gsm48_loc_upd_req *lu; - uint8_t mi_type; - char mi_string[GSM48_MI_SIZE]; enum vlr_lu_type vlr_lu_type = VLR_LU_TYPE_REGULAR; uint32_t tmsi; char *imsi; @@ -311,6 +328,15 @@ static int mm_rx_loc_upd_req(struct msc_a *msc_a, struct msgb *msg) bool is_utran; struct gsm_network *net = msc_a_net(msc_a); struct vlr_subscr *vsub; + struct osmo_mobile_identity mi; + int rc; + + rc = osmo_mobile_identity_decode_from_l3(&mi, msg, false); + if (rc) { + LOG_MSC_A_CAT(msc_a, DMM, LOGL_ERROR, + "Failed to decode Mobile Identity in Location Updating Request\n"); + return -EINVAL; + } lu = (struct gsm48_loc_upd_req *) gh->data; @@ -318,7 +344,7 @@ static int mm_rx_loc_upd_req(struct msc_a *msc_a, struct msgb *msg) LOG_MSC_A_CAT(msc_a, DMM, LOGL_ERROR, "Cannot accept another LU, conn already busy establishing authenticity;" " extraneous LOCATION UPDATING REQUEST: MI=%s LU-type=%s\n", - osmo_mi_name(lu->mi, lu->mi_len), osmo_lu_type_name(lu->type)); + osmo_mobile_identity_to_str_c(OTC_SELECT, &mi), osmo_lu_type_name(lu->type)); return -EINVAL; } @@ -326,47 +352,46 @@ static int mm_rx_loc_upd_req(struct msc_a *msc_a, struct msgb *msg) LOG_MSC_A_CAT(msc_a, DMM, LOGL_ERROR, "Cannot accept another LU, conn already established;" " extraneous LOCATION UPDATING REQUEST: MI=%s LU-type=%s\n", - osmo_mi_name(lu->mi, lu->mi_len), osmo_lu_type_name(lu->type)); + osmo_mobile_identity_to_str_c(OTC_SELECT, &mi), osmo_lu_type_name(lu->type)); return -EINVAL; } msc_a->complete_layer3_type = COMPLETE_LAYER3_LU; - msub_update_id_from_mi(msc_a->c.msub, lu->mi, lu->mi_len); + + msub_update_id_from_mi(msc_a->c.msub, &mi); LOG_MSC_A_CAT(msc_a, DMM, LOGL_DEBUG, "LOCATION UPDATING REQUEST: MI=%s LU-type=%s\n", - osmo_mi_name(lu->mi, lu->mi_len), osmo_lu_type_name(lu->type)); + osmo_mobile_identity_to_str_c(OTC_SELECT, &mi), osmo_lu_type_name(lu->type)); - osmo_signal_dispatch(SS_SUBSCR, S_SUBSCR_IDENTITY, &lu->mi_len); + osmo_signal_dispatch(SS_SUBSCR, S_SUBSCR_IDENTITY, &mi); switch (lu->type) { case GSM48_LUPD_NORMAL: - rate_ctr_inc(&net->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_NORMAL]); + rate_ctr_inc(rate_ctr_group_get_ctr(net->msc_ctrs, MSC_CTR_LOC_UPDATE_TYPE_NORMAL)); vlr_lu_type = VLR_LU_TYPE_REGULAR; break; case GSM48_LUPD_IMSI_ATT: - rate_ctr_inc(&net->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_ATTACH]); + rate_ctr_inc(rate_ctr_group_get_ctr(net->msc_ctrs, MSC_CTR_LOC_UPDATE_TYPE_ATTACH)); vlr_lu_type = VLR_LU_TYPE_IMSI_ATTACH; break; case GSM48_LUPD_PERIODIC: - rate_ctr_inc(&net->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_PERIODIC]); + rate_ctr_inc(rate_ctr_group_get_ctr(net->msc_ctrs, MSC_CTR_LOC_UPDATE_TYPE_PERIODIC)); vlr_lu_type = VLR_LU_TYPE_PERIODIC; break; } /* TODO: 10.5.1.6 MS Classmark for UMTS / Classmark 2 */ - /* TODO: 10.5.3.14 Aditional update parameters (CS fallback calls) */ + /* TODO: 10.5.3.14 Additional update parameters (CS fallback calls) */ /* TODO: 10.5.7.8 Device properties */ /* TODO: 10.5.1.15 MS network feature support */ - mi_type = lu->mi[0] & GSM_MI_TYPE_MASK; - gsm48_mi_to_string(mi_string, sizeof(mi_string), lu->mi, lu->mi_len); - switch (mi_type) { + switch (mi.type) { case GSM_MI_TYPE_IMSI: tmsi = GSM_RESERVED_TMSI; - imsi = mi_string; + imsi = mi.imsi; break; case GSM_MI_TYPE_TMSI: - tmsi = tmsi_from_string(mi_string); + tmsi = mi.tmsi; imsi = NULL; break; default: @@ -388,7 +413,8 @@ static int mm_rx_loc_upd_req(struct msc_a *msc_a, struct msgb *msg) net->vlr, msc_a, vlr_lu_type, tmsi, imsi, &old_lai, &msc_a->via_cell.lai, is_utran || net->authentication_required, - is_utran || net->a5_encryption_mask > 0x01, + msc_a_is_ciphering_to_be_attempted(msc_a), + msc_a_is_ciphering_required(msc_a), lu->key_seq, osmo_gsm48_classmark1_is_r99(&lu->classmark1), is_utran, @@ -402,7 +428,7 @@ static int mm_rx_loc_upd_req(struct msc_a *msc_a, struct msgb *msg) /* From vlr_loc_update() we expect an implicit dispatch of * VLR_ULA_E_UPDATE_LA, and thus we expect msc_vlr_subscr_assoc() to - * already have been called and completed. Has an error occured? */ + * already have been called and completed. Has an error occurred? */ vsub = msc_a_vsub(msc_a); if (!vsub) { @@ -644,44 +670,36 @@ int gsm48_tx_mm_auth_rej(struct msc_a *msc_a) static int msc_vlr_tx_cm_serv_rej(void *msc_conn_ref, enum osmo_cm_service_type cm_service_type, enum gsm48_reject_value cause); -static int cm_serv_reuse_conn(struct msc_a *msc_a, const uint8_t *mi_lv, enum osmo_cm_service_type cm_serv_type) +static int cm_serv_reuse_conn(struct msc_a *msc_a, const struct osmo_mobile_identity *mi, enum osmo_cm_service_type cm_serv_type) { - uint8_t mi_type; - char mi_string[GSM48_MI_SIZE]; - uint32_t tmsi; struct gsm_network *net = msc_a_net(msc_a); struct vlr_subscr *vsub = msc_a_vsub(msc_a); - gsm48_mi_to_string(mi_string, sizeof(mi_string), mi_lv+1, mi_lv[0]); - mi_type = mi_lv[1] & GSM_MI_TYPE_MASK; - - switch (mi_type) { + switch (mi->type) { case GSM_MI_TYPE_IMSI: - if (vlr_subscr_matches_imsi(vsub, mi_string)) + if (vlr_subscr_matches_imsi(vsub, mi->imsi)) goto accept_reuse; break; case GSM_MI_TYPE_TMSI: - tmsi = osmo_load32be(mi_lv+2); - if (vlr_subscr_matches_tmsi(vsub, tmsi)) + if (vlr_subscr_matches_tmsi(vsub, mi->tmsi)) goto accept_reuse; break; case GSM_MI_TYPE_IMEI: - if (vlr_subscr_matches_imei(vsub, mi_string)) + if (vlr_subscr_matches_imei(vsub, mi->imei)) goto accept_reuse; break; default: break; } - LOG_MSC_A_CAT(msc_a, DMM, LOGL_ERROR, "CM Service Request with mismatching mobile identity: %s %s\n", - gsm48_mi_type_name(mi_type), mi_string); + LOG_MSC_A_CAT(msc_a, DMM, LOGL_ERROR, "CM Service Request with mismatching mobile identity: %s\n", + osmo_mobile_identity_to_str_c(OTC_SELECT, mi)); msc_vlr_tx_cm_serv_rej(msc_a, cm_serv_type, GSM48_REJECT_ILLEGAL_MS); return -EINVAL; accept_reuse: LOG_MSC_A_CAT(msc_a, DMM, LOGL_DEBUG, "re-using already accepted connection\n"); - msc_a_get(msc_a, msc_a_cm_service_type_to_use(cm_serv_type)); msub_update_id(msc_a->c.msub); return net->vlr->ops.tx_cm_serv_acc(msc_a, cm_serv_type); } @@ -689,7 +707,7 @@ accept_reuse: /* * Handle CM Service Requests * a) Verify that the packet is long enough to contain the information - * we require otherwsie reject with INCORRECT_MESSAGE + * we require otherwise reject with INCORRECT_MESSAGE * b) Try to parse the TMSI. If we do not have one reject * c) Check that we know the subscriber with the TMSI otherwise reject * with a HLR cause @@ -704,10 +722,18 @@ int gsm48_rx_mm_serv_req(struct msc_a *msc_a, struct msgb *msg) struct gsm48_service_request *req; struct gsm48_classmark2 *cm2; uint8_t *cm2_buf, cm2_len; - uint8_t *mi_buf, mi_len; - uint8_t *mi, mi_type; bool is_utran; struct vlr_subscr *vsub; + struct osmo_mobile_identity mi; + int rc; + + /* There are two ways to respond with a CM Service Reject: + * Directly and only send the CM Service Reject with msc_gsm48_tx_mm_serv_rej(). + * Decrement the CM Service use count token and send the message with msc_vlr_tx_cm_serv_rej(). + * + * Until we accept the CM Service Request message as such, there is no use count placed for the service type. + * So in here use msc_gsm48_tx_mm_serv_rej() to respond. + */ /* Make sure that both header and CM Service Request fit into the buffer */ if (msgb_l3len(msg) < sizeof(*gh) + sizeof(*req)) { @@ -716,6 +742,12 @@ int gsm48_rx_mm_serv_req(struct msc_a *msc_a, struct msgb *msg) return msc_gsm48_tx_mm_serv_rej(msc_a, GSM48_REJECT_INCORRECT_MESSAGE); } + rc = osmo_mobile_identity_decode_from_l3(&mi, msg, false); + if (rc) { + LOG_MSC_A(msc_a, LOGL_ERROR, "Rx CM SERVICE REQUEST: unable to decode Mobile Identity\n"); + return msc_gsm48_tx_mm_serv_rej(msc_a, GSM48_REJECT_INCORRECT_MESSAGE); + } + gh = (struct gsm48_hdr *) msgb_l3(msg); req = (struct gsm48_service_request *) gh->data; @@ -732,18 +764,6 @@ int gsm48_rx_mm_serv_req(struct msc_a *msc_a, struct msgb *msg) return msc_gsm48_tx_mm_serv_rej(msc_a, GSM48_REJECT_INCORRECT_MESSAGE); } - /* MI (Mobile Identity) LV follows the Classmark2 */ - mi_buf = cm2_buf + cm2_len; - mi_len = mi_buf[0]; - mi = mi_buf + 1; - - /* Prevent buffer overrun: check the length of MI */ - if (mi_buf + mi_len > msg->tail) { - LOG_MSC_A(msc_a, LOGL_ERROR, "Rx CM SERVICE REQUEST: Mobile Identity " - "length=%u is too big\n", cm2_len); - return msc_gsm48_tx_mm_serv_rej(msc_a, GSM48_REJECT_INCORRECT_MESSAGE); - } - if (msc_a_is_establishing_auth_ciph(msc_a)) { LOG_MSC_A(msc_a, LOGL_ERROR, "Cannot accept CM Service Request, conn already busy establishing authenticity\n"); @@ -752,12 +772,11 @@ int gsm48_rx_mm_serv_req(struct msc_a *msc_a, struct msgb *msg) } msc_a->complete_layer3_type = COMPLETE_LAYER3_CM_SERVICE_REQ; - msub_update_id_from_mi(msc_a->c.msub, mi, mi_len); + msub_update_id_from_mi(msc_a->c.msub, &mi); LOG_MSC_A_CAT(msc_a, DMM, LOGL_DEBUG, "Rx CM SERVICE REQUEST cm_service_type=%s\n", osmo_cm_service_type_name(req->cm_service_type)); - mi_type = (mi && mi_len) ? (mi[0] & GSM_MI_TYPE_MASK) : GSM_MI_TYPE_NONE; - switch (mi_type) { + switch (mi.type) { case GSM_MI_TYPE_IMSI: case GSM_MI_TYPE_TMSI: /* continue below */ @@ -771,19 +790,22 @@ int gsm48_rx_mm_serv_req(struct msc_a *msc_a, struct msgb *msg) } /* fall-through for non-emergency setup */ default: - LOG_MSC_A(msc_a, LOGL_ERROR, "MI type is not expected: %s\n", gsm48_mi_type_name(mi_type)); + LOG_MSC_A(msc_a, LOGL_ERROR, "MI type is not expected: %s\n", gsm48_mi_type_name(mi.type)); return msc_gsm48_tx_mm_serv_rej(msc_a, GSM48_REJECT_INCORRECT_MESSAGE); } - if (!msc_a_cm_service_type_to_use(req->cm_service_type)) + if (!msc_a_cm_service_type_to_use(msc_a, req->cm_service_type)) return msc_gsm48_tx_mm_serv_rej(msc_a, GSM48_REJECT_SRV_OPT_NOT_SUPPORTED); - if (msc_a_is_accepted(msc_a)) - return cm_serv_reuse_conn(msc_a, mi_buf, req->cm_service_type); + /* At this point, the CM Service Request message is being accepted. + * Increment the matching use token, and from here on use msc_vlr_tx_cm_serv_rej() to respond in case of + * failure. */ + msc_a_get(msc_a, msc_a_cm_service_type_to_use(msc_a, req->cm_service_type)); - osmo_signal_dispatch(SS_SUBSCR, S_SUBSCR_IDENTITY, mi_buf); + if (msc_a_is_accepted(msc_a)) + return cm_serv_reuse_conn(msc_a, &mi, req->cm_service_type); - msc_a_get(msc_a, msc_a_cm_service_type_to_use(req->cm_service_type)); + osmo_signal_dispatch(SS_SUBSCR, S_SUBSCR_IDENTITY, &mi); is_utran = (msc_a->c.ran->type == OSMO_RAT_UTRAN_IU); vlr_proc_acc_req(msc_a->c.fi, @@ -791,15 +813,16 @@ int gsm48_rx_mm_serv_req(struct msc_a *msc_a, struct msgb *msg) net->vlr, msc_a, VLR_PR_ARQ_T_CM_SERV_REQ, req->cm_service_type, - mi-1, &msc_a->via_cell.lai, + &mi, &msc_a->via_cell.lai, is_utran || net->authentication_required, - is_utran || net->a5_encryption_mask > 0x01, + msc_a_is_ciphering_to_be_attempted(msc_a), + msc_a_is_ciphering_required(msc_a), req->cipher_key_seq, osmo_gsm48_classmark2_is_r99(cm2, cm2_len), is_utran); /* From vlr_proc_acc_req() we expect an implicit dispatch of PR_ARQ_E_START we expect - * msc_vlr_subscr_assoc() to already have been called and completed. Has an error occured? */ + * msc_vlr_subscr_assoc() to already have been called and completed. Has an error occurred? */ vsub = msc_a_vsub(msc_a); if (!vsub) { LOG_MSC_A(msc_a, LOGL_ERROR, "subscriber not allowed to do a CM Service Request\n"); @@ -814,21 +837,129 @@ int gsm48_rx_mm_serv_req(struct msc_a *msc_a, struct msgb *msg) /* Receive a CM Re-establish Request */ static int gsm48_rx_cm_reest_req(struct msc_a *msc_a, struct msgb *msg) { - uint8_t mi_type; - char mi_string[GSM48_MI_SIZE]; - struct gsm48_hdr *gh = msgb_l3(msg); + struct gsm_network *net = msc_a_net(msc_a); + struct gsm48_hdr *gh; + struct gsm48_service_request *req; + struct gsm48_classmark2 *cm2; + uint8_t *cm2_buf, cm2_len; + bool is_utran; + struct vlr_subscr *vsub; + struct osmo_mobile_identity mi; + struct msub *prev_msub; + struct msc_a *prev_msc_a; - uint8_t classmark2_len = gh->data[1]; - uint8_t *classmark2 = gh->data+2; - uint8_t mi_len = *(classmark2 + classmark2_len); - uint8_t *mi = (classmark2 + classmark2_len + 1); + int rc = osmo_mobile_identity_decode_from_l3(&mi, msg, false); + if (rc) { + LOGP(DMM, LOGL_ERROR, "CM RE-ESTABLISH REQUEST: cannot decode Mobile Identity\n"); + return -EINVAL; + } + + msc_a->complete_layer3_type = COMPLETE_LAYER3_CM_RE_ESTABLISH_REQ; + msub_update_id_from_mi(msc_a->c.msub, &mi); - gsm48_mi_to_string(mi_string, sizeof(mi_string), mi, mi_len); - mi_type = mi[0] & GSM_MI_TYPE_MASK; - DEBUGP(DMM, "<- CM RE-ESTABLISH REQUEST MI(%s)=%s\n", gsm48_mi_type_name(mi_type), mi_string); + DEBUGP(DMM, "<- CM RE-ESTABLISH REQUEST %s\n", osmo_mobile_identity_to_str_c(OTC_SELECT, &mi)); - /* we don't support CM call re-establishment */ - return msc_gsm48_tx_mm_serv_rej(msc_a, GSM48_REJECT_SRV_OPT_NOT_SUPPORTED); + gh = (struct gsm48_hdr *) msgb_l3(msg); + req = (struct gsm48_service_request *) gh->data; + + /* Unfortunately in Phase1 the Classmark2 length is variable, so we cannot + * just use gsm48_service_request struct, and need to parse it manually. */ + cm2_len = gh->data[1]; + cm2_buf = gh->data + 2; + cm2 = (struct gsm48_classmark2 *) cm2_buf; + + /* Prevent buffer overrun: check the length of Classmark2 */ + if (cm2_buf + cm2_len > msg->tail) { + LOG_MSC_A(msc_a, LOGL_ERROR, "Rx CM SERVICE REQUEST: Classmark2 " + "length=%u is too big\n", cm2_len); + return msc_gsm48_tx_mm_serv_rej(msc_a, GSM48_REJECT_INCORRECT_MESSAGE); + } + + /* Look up the other, previously active connection for this subscriber */ + vsub = vlr_subscr_find_by_mi(net->vlr, &mi, __func__); + prev_msub = msub_for_vsub(vsub); + prev_msc_a = msub_msc_a(prev_msub); + if (!vsub || !prev_msub || !prev_msc_a) { + LOG_MSC_A(msc_a, LOGL_ERROR, "CM Re-Establish Request for unknown subscriber: %s\n", + osmo_mobile_identity_to_str_c(OTC_SELECT, &mi)); + if (vsub) + vlr_subscr_put(vsub, __func__); + return msc_gsm48_tx_mm_serv_rej(msc_a, GSM48_REJECT_CALL_CAN_NOT_BE_IDENTIFIED); + } + + LOG_MSC_A(msc_a, LOGL_NOTICE, "New conn requesting Re-Establishment\n"); + LOG_MSC_A(prev_msc_a, LOGL_NOTICE, "Old conn matching Re-Establishment request (%s)\n", + osmo_use_count_to_str_c(OTC_SELECT, &prev_msc_a->use_count)); + + if (!prev_msc_a->cc.call_leg || !prev_msc_a->cc.active_trans) { + LOG_MSC_A(msc_a, LOGL_ERROR, "CM Re-Establish Request only supported for voice calls\n"); + if (vsub) + vlr_subscr_put(vsub, __func__); + return msc_gsm48_tx_mm_serv_rej(msc_a, GSM48_REJECT_CALL_CAN_NOT_BE_IDENTIFIED); + } + + msc_a_get(prev_msc_a, __func__); + + /* Move the call_leg and active CC trans over to the new msc_a */ + call_leg_reparent(prev_msc_a->cc.call_leg, + msc_a->c.fi, + MSC_EV_CALL_LEG_TERM, + MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE, + MSC_EV_CALL_LEG_RTP_COMPLETE); + msc_a->cc.call_leg = prev_msc_a->cc.call_leg; + prev_msc_a->cc.call_leg = NULL; + + msc_a->cc.active_trans = prev_msc_a->cc.active_trans; + msc_a->cc.active_trans->msc_a = msc_a; + msc_a_get(msc_a, MSC_A_USE_CC); + prev_msc_a->cc.active_trans = NULL; + msc_a_put(prev_msc_a, MSC_A_USE_CC); + + /* Dis-associate the VLR subscriber from the previous msc_a, so that we can start a new Process Access Request + * on the new msc_a. */ + if (vsub->proc_arq_fsm) { + osmo_fsm_inst_term(vsub->proc_arq_fsm, OSMO_FSM_TERM_REGULAR, NULL); + vsub->proc_arq_fsm = NULL; + } + if (prev_msub->vsub) { + vlr_subscr_put(prev_msub->vsub, VSUB_USE_MSUB); + prev_msub->vsub = NULL; + } + + /* Clear the previous conn. + * FIXME: we are clearing the previous conn before having authenticated the new conn. That means anyone can send + * CM Re-Establishing requests with arbitrary mobile identities without having to authenticate, and can freely + * Clear any connections at will. */ + msc_a_release_cn(prev_msc_a); + msc_a_put(prev_msc_a, __func__); + prev_msc_a = NULL; + + /* Kick off Authentication and Ciphering for the new conn. */ + is_utran = (msc_a->c.ran->type == OSMO_RAT_UTRAN_IU); + vlr_proc_acc_req(msc_a->c.fi, + MSC_A_EV_AUTHENTICATED, MSC_A_EV_CN_CLOSE, NULL, + net->vlr, msc_a, + VLR_PR_ARQ_T_CM_RE_ESTABLISH_REQ, 0, + &mi, &msc_a->via_cell.lai, + is_utran || net->authentication_required, + msc_a_is_ciphering_to_be_attempted(msc_a), + msc_a_is_ciphering_required(msc_a), + req->cipher_key_seq, + osmo_gsm48_classmark2_is_r99(cm2, cm2_len), + is_utran); + vlr_subscr_put(vsub, __func__); + + /* From vlr_proc_acc_req() we expect an implicit dispatch of PR_ARQ_E_START, and we expect + * msc_vlr_subscr_assoc() to already have been called and completed. Has an error occurred? */ + vsub = msc_a_vsub(msc_a); + if (!vsub) { + LOG_MSC_A(msc_a, LOGL_ERROR, "subscriber not allowed to do a CM Service Request\n"); + return -EIO; + } + + vsub->classmark.classmark2 = *cm2; + vsub->classmark.classmark2_len = cm2_len; + return 0; } static int gsm48_rx_mm_imsi_detach_ind(struct msc_a *msc_a, struct msgb *msg) @@ -837,39 +968,41 @@ static int gsm48_rx_mm_imsi_detach_ind(struct msc_a *msc_a, struct msgb *msg) struct gsm48_hdr *gh = msgb_l3(msg); struct gsm48_imsi_detach_ind *idi = (struct gsm48_imsi_detach_ind *) gh->data; - uint8_t mi_type = idi->mi[0] & GSM_MI_TYPE_MASK; - char mi_string[GSM48_MI_SIZE]; + struct osmo_mobile_identity mi; struct vlr_subscr *vsub = NULL; - gsm48_mi_to_string(mi_string, sizeof(mi_string), idi->mi, idi->mi_len); - DEBUGP(DMM, "IMSI DETACH INDICATION: MI(%s)=%s\n", - gsm48_mi_type_name(mi_type), mi_string); + int rc = osmo_mobile_identity_decode_from_l3(&mi, msg, false); + if (rc) { + LOGP(DMM, LOGL_ERROR, "IMSI DETACH INDICATION: cannot decode Mobile Identity\n"); + return -EINVAL; + } + + DEBUGP(DMM, "IMSI DETACH INDICATION: %s\n", osmo_mobile_identity_to_str_c(OTC_SELECT, &mi)); - rate_ctr_inc(&net->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_DETACH]); + rate_ctr_inc(rate_ctr_group_get_ctr(net->msc_ctrs, MSC_CTR_LOC_UPDATE_TYPE_DETACH)); - switch (mi_type) { + switch (mi.type) { case GSM_MI_TYPE_TMSI: - vsub = vlr_subscr_find_by_tmsi(net->vlr, - tmsi_from_string(mi_string), __func__); + vsub = vlr_subscr_find_by_tmsi(net->vlr, mi.tmsi, __func__); break; case GSM_MI_TYPE_IMSI: - vsub = vlr_subscr_find_by_imsi(net->vlr, mi_string, __func__); + vsub = vlr_subscr_find_by_imsi(net->vlr, mi.imsi, __func__); break; case GSM_MI_TYPE_IMEI: case GSM_MI_TYPE_IMEISV: /* no sim card... FIXME: what to do ? */ - LOGP(DMM, LOGL_ERROR, "MI(%s)=%s: unimplemented mobile identity type\n", - gsm48_mi_type_name(mi_type), mi_string); + LOGP(DMM, LOGL_ERROR, "%s: unimplemented mobile identity type\n", + osmo_mobile_identity_to_str_c(OTC_SELECT, &mi)); break; default: - LOGP(DMM, LOGL_ERROR, "MI(%s)=%s: unknown mobile identity type\n", - gsm48_mi_type_name(mi_type), mi_string); + LOGP(DMM, LOGL_ERROR, "%s: unknown mobile identity type\n", + osmo_mobile_identity_to_str_c(OTC_SELECT, &mi)); break; } if (!vsub) { - LOGP(DMM, LOGL_ERROR, "IMSI DETACH for unknown subscriber MI(%s)=%s\n", - gsm48_mi_type_name(mi_type), mi_string); + LOGP(DMM, LOGL_ERROR, "IMSI DETACH for unknown subscriber %s\n", + osmo_mobile_identity_to_str_c(OTC_SELECT, &mi)); } else { LOGP(DMM, LOGL_INFO, "IMSI DETACH for %s\n", vlr_subscr_name(vsub)); msub_set_vsub(msc_a->c.msub, vsub); @@ -1138,24 +1271,31 @@ static int gsm48_rx_rr_pag_resp(struct msc_a *msc_a, struct msgb *msg) uint8_t classmark2_len = gh->data[1]; uint8_t *classmark2_buf = gh->data+2; struct gsm48_classmark2 *cm2 = (void*)classmark2_buf; - uint8_t *mi_lv = classmark2_buf + classmark2_len; bool is_utran; struct vlr_subscr *vsub; + struct osmo_mobile_identity mi; + int rc; if (msc_a_is_establishing_auth_ciph(msc_a)) { - LOG_MSC_A_CAT(msc_a, DMM, LOGL_ERROR, + LOG_MSC_A_CAT(msc_a, DRR, LOGL_ERROR, "Ignoring Paging Response, conn already busy establishing authenticity\n"); return 0; } if (msc_a_is_accepted(msc_a)) { - LOG_MSC_A_CAT(msc_a, DMM, LOGL_ERROR, "Ignoring Paging Response, conn already established\n"); + LOG_MSC_A_CAT(msc_a, DRR, LOGL_ERROR, "Ignoring Paging Response, conn already established\n"); return 0; } + rc = osmo_mobile_identity_decode_from_l3(&mi, msg, false); + if (rc) { + LOG_MSC_A_CAT(msc_a, DRR, LOGL_ERROR, "Paging Response: cannot decode Mobile Identity\n"); + return -EINVAL; + } + msc_a->complete_layer3_type = COMPLETE_LAYER3_PAGING_RESP; - msub_update_id_from_mi(msc_a->c.msub, mi_lv + 1, *mi_lv); - LOG_MSC_A_CAT(msc_a, DRR, LOGL_DEBUG, "Rx PAGING RESPONSE\n"); + msub_update_id_from_mi(msc_a->c.msub, &mi); + LOG_MSC_A_CAT(msc_a, DRR, LOGL_DEBUG, "Rx PAGING RESPONSE %s\n", osmo_mobile_identity_to_str_c(OTC_SELECT, &mi)); msc_a_get(msc_a, MSC_A_USE_PAGING_RESPONSE); @@ -1163,19 +1303,25 @@ static int gsm48_rx_rr_pag_resp(struct msc_a *msc_a, struct msgb *msg) vlr_proc_acc_req(msc_a->c.fi, MSC_A_EV_AUTHENTICATED, MSC_A_EV_CN_CLOSE, NULL, net->vlr, msc_a, - VLR_PR_ARQ_T_PAGING_RESP, 0, mi_lv, &msc_a->via_cell.lai, + VLR_PR_ARQ_T_PAGING_RESP, 0, &mi, &msc_a->via_cell.lai, is_utran || net->authentication_required, - is_utran || net->a5_encryption_mask > 0x01, + msc_a_is_ciphering_to_be_attempted(msc_a), + msc_a_is_ciphering_required(msc_a), pr->key_seq, osmo_gsm48_classmark2_is_r99(cm2, classmark2_len), is_utran); /* From vlr_proc_acc_req() we expect an implicit dispatch of PR_ARQ_E_START we expect - * msc_vlr_subscr_assoc() to already have been called and completed. Has an error occured? */ + * msc_vlr_subscr_assoc() to already have been called and completed. Has an error occurred? */ vsub = msc_a_vsub(msc_a); if (!vsub) { - LOG_MSC_A(msc_a, LOGL_ERROR, "subscriber not allowed to do a Paging Response\n"); - msc_a_put(msc_a, MSC_A_USE_PAGING_RESPONSE); + LOG_MSC_A_CAT(msc_a, DRR, LOGL_ERROR, "subscriber not allowed to do a Paging Response\n"); + + /* Above MSC_A_USE_PAGING_RESPONSE may already have been removed by a forced release, put that use only + * if it still exists. (see msc_a_fsm_releasing_onenter()) */ + if (osmo_use_count_by(&msc_a->use_count, MSC_A_USE_PAGING_RESPONSE)) + msc_a_put(msc_a, MSC_A_USE_PAGING_RESPONSE); + return -EIO; } @@ -1190,21 +1336,37 @@ static int gsm48_rx_rr_ciphering_mode_complete(struct msc_a *msc_a, struct msgb struct gsm48_hdr *gh = msgb_l3(msg); unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh); struct tlv_parsed tp; - struct tlv_p_entry *mi; + struct tlv_p_entry *mi_tlv; + struct osmo_mobile_identity mi; tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len, 0, 0); - mi = TLVP_GET(&tp, GSM48_IE_MOBILE_ID); + mi_tlv = TLVP_GET(&tp, GSM48_IE_MOBILE_ID); - if (!mi) + /* IMEI(SV) is optional for this message */ + if (!mi_tlv) return 0; + if (!mi_tlv->len) + return -EINVAL; - LOG_MSC_A(msc_a, LOGL_DEBUG, "Ciphering Mode Complete contains Mobile Identity: %s\n", - osmo_mi_name(mi->val, mi->len)); + if (osmo_mobile_identity_decode(&mi, mi_tlv->val, mi_tlv->len, false)) { + LOGP(DMM, LOGL_ERROR, "RR Ciphering Mode Complete contains invalid Mobile Identity %s\n", + osmo_hexdump(mi_tlv->val, mi_tlv->len)); + return -EINVAL; + } + if (mi.type != GSM_MI_TYPE_IMEISV) { + LOGP(DMM, LOGL_ERROR, "RR Ciphering Mode Complete contains " + "unexpected Mobile Identity type %s\n", + osmo_mobile_identity_to_str_c(OTC_SELECT, &mi)); + return -EINVAL; + } + + LOG_MSC_A(msc_a, LOGL_DEBUG, "RR Ciphering Mode Complete contains Mobile Identity: %s\n", + osmo_mobile_identity_to_str_c(OTC_SELECT, &mi)); if (!vsub) return 0; - return vlr_subscr_rx_id_resp(vsub, mi->val, mi->len); + return vlr_subscr_rx_id_resp(vsub, &mi); } static int gsm48_rx_rr_app_info(struct msc_a *msc_a, struct msgb *msg) @@ -1218,8 +1380,9 @@ static int gsm48_rx_rr_app_info(struct msc_a *msc_a, struct msgb *msg) apdu_len = gh->data[1]; apdu_data = gh->data+2; - DEBUGP(DRR, "RX APPLICATION INFO id/flags=0x%02x apdu_len=%u apdu=%s\n", - apdu_id_flags, apdu_len, osmo_hexdump(apdu_data, apdu_len)); + LOG_MSC_A_CAT(msc_a, DRR, LOGL_DEBUG, "Rx RR APPLICATION INFO " + "(id/flags=0x%02x apdu_len=%u apdu=%s)\n", + apdu_id_flags, apdu_len, osmo_hexdump(apdu_data, apdu_len)); /* we're not using the app info blob anywhere, so ignore. */ #if 0 @@ -1245,6 +1408,9 @@ int gsm0408_rcv_rr(struct msc_a *msc_a, struct msgb *msg) case GSM48_MT_RR_APP_INFO: rc = gsm48_rx_rr_app_info(msc_a, msg); break; + case GSM48_MT_RR_UPLINK_RELEASE: + rc = gsm44068_rcv_rr(msc_a, msg); + break; default: LOG_MSC_A_CAT(msc_a, DRR, LOGL_NOTICE, "MSC: Unimplemented %s GSM 04.08 RR " "message\n", gsm48_rr_msg_name(gh->msg_type)); @@ -1300,6 +1466,10 @@ static int msc_vlr_tx_auth_rej(void *msc_conn_ref) static int msc_vlr_tx_id_req(void *msc_conn_ref, uint8_t mi_type) { struct msc_a *msc_a = msc_conn_ref; + + /* Store requested MI type, so we can check the response */ + msc_a->mm_id_req_type = mi_type; + return mm_tx_identity_req(msc_a, mi_type); } @@ -1327,12 +1497,19 @@ int msc_vlr_tx_cm_serv_acc(void *msc_conn_ref, enum osmo_cm_service_type cm_serv static int msc_vlr_tx_common_id(void *msc_conn_ref) { struct msc_a *msc_a = msc_conn_ref; + struct vlr_subscr *vsub = msc_a_vsub(msc_a); struct ran_msg msg = { .msg_type = RAN_MSG_COMMON_ID, .common_id = { - .imsi = msc_a_vsub(msc_a)->imsi, + .imsi = vsub->imsi, + .last_eutran_plmn_present = vsub->sgs.last_eutran_plmn_present, }, }; + if (vsub->sgs.last_eutran_plmn_present) { + memcpy(&msg.common_id.last_eutran_plmn, &vsub->sgs.last_eutran_plmn, + sizeof(vsub->sgs.last_eutran_plmn)); + } + return msc_a_ran_down(msc_a, MSC_ROLE_I, &msg); } @@ -1346,13 +1523,14 @@ static int msc_vlr_tx_mm_info(void *msc_conn_ref) return gsm48_tx_mm_info(msc_a); } -/* VLR asks us to transmit a CM Service Reject */ +/* VLR asks us to transmit a CM Service Reject. + * Decrement the CM Service type's use token and send the CM Service Reject message. */ static int msc_vlr_tx_cm_serv_rej(void *msc_conn_ref, enum osmo_cm_service_type cm_service_type, enum gsm48_reject_value cause) { struct msc_a *msc_a = msc_conn_ref; msc_gsm48_tx_mm_serv_rej(msc_a, cause); - msc_a_put(msc_a, msc_a_cm_service_type_to_use(cm_service_type)); + msc_a_put(msc_a, msc_a_cm_service_type_to_use(msc_a, cm_service_type)); return 0; } @@ -1365,7 +1543,9 @@ static void msc_vlr_subscr_update(struct vlr_subscr *subscr) msub_update_id(msub); } -/* VLR informs us that the subscriber has been associated with a conn */ +/* VLR informs us that the subscriber has been associated with a conn. + * The subscriber has *not* been authenticated yet, so the vsub should be protected from potentially invalid information + * from the msc_a. */ static int msc_vlr_subscr_assoc(void *msc_conn_ref, struct vlr_subscr *vsub) { @@ -1375,6 +1555,10 @@ static int msc_vlr_subscr_assoc(void *msc_conn_ref, if (msub_set_vsub(msub, vsub)) return -EINVAL; + + /* FIXME: would be better to modify vsub->* only after the subscriber is authenticated, in + * evaluate_acceptance_outcome(conn_accepted == true). */ + vsub->cs.attached_via_ran = msc_a->c.ran->type; /* In case we have already received Classmark Information before the VLR Subscriber was @@ -1388,6 +1572,24 @@ static int msc_vlr_subscr_assoc(void *msc_conn_ref, return 0; } +static void msc_vlr_subscr_inval(void *msc_conn_ref, struct vlr_subscr *vsub) +{ + /* Search vsub backwards to make sure msc_conn_ref is a valid msc_a instance. */ + struct msub *msub; + OSMO_ASSERT(vsub); + llist_for_each_entry(msub, &msub_list, entry) { + struct msc_a *msc_a; + if (msub->vsub != vsub) + continue; + + msc_a = msub_msc_a(msub); + if (msc_a) + msc_a_release_cn(msc_a); + + msub->vsub = NULL; + } +} + /* operations that we need to implement for libvlr */ const struct vlr_ops msc_vlr_ops = { .tx_auth_req = msc_vlr_tx_auth_req, @@ -1402,6 +1604,7 @@ const struct vlr_ops msc_vlr_ops = { .tx_mm_info = msc_vlr_tx_mm_info, .subscr_update = msc_vlr_subscr_update, .subscr_assoc = msc_vlr_subscr_assoc, + .subscr_inval = msc_vlr_subscr_inval, }; struct msgb *gsm48_create_mm_serv_rej(enum gsm48_reject_value value) @@ -1436,27 +1639,3 @@ struct msgb *gsm48_create_loc_upd_rej(uint8_t cause) gh->data[0] = cause; return msg; } - -int gsm48_extract_mi(uint8_t *classmark2_lv, int length, char *mi_string, uint8_t *mi_type) -{ - /* Check the size for the classmark */ - if (length < 1 + *classmark2_lv) - return -1; - - uint8_t *mi_lv = classmark2_lv + *classmark2_lv + 1; - if (length < 2 + *classmark2_lv + mi_lv[0]) - return -2; - - *mi_type = mi_lv[1] & GSM_MI_TYPE_MASK; - return gsm48_mi_to_string(mi_string, GSM48_MI_SIZE, mi_lv+1, *mi_lv); -} - -int gsm48_paging_extract_mi(struct gsm48_pag_resp *resp, int length, - char *mi_string, uint8_t *mi_type) -{ - static const uint32_t classmark_offset = - offsetof(struct gsm48_pag_resp, classmark2); - uint8_t *classmark2_lv = (uint8_t *) &resp->classmark2; - return gsm48_extract_mi(classmark2_lv, length - classmark_offset, - mi_string, mi_type); -} diff --git a/src/libmsc/gsm_04_08_cc.c b/src/libmsc/gsm_04_08_cc.c index 2869bba12..63b1699ab 100644 --- a/src/libmsc/gsm_04_08_cc.c +++ b/src/libmsc/gsm_04_08_cc.c @@ -30,6 +30,8 @@ #include <regex.h> #include <sys/types.h> +#include <osmocom/mgcp_client/mgcp_client_endpoint_fsm.h> + #include <osmocom/msc/db.h> #include <osmocom/msc/debug.h> #include <osmocom/msc/gsm_data.h> @@ -41,6 +43,7 @@ #include <osmocom/msc/gsm_09_11.h> #include <osmocom/msc/signal.h> #include <osmocom/msc/transaction.h> +#include <osmocom/msc/transaction_cc.h> #include <osmocom/msc/silent_call.h> #include <osmocom/msc/mncc_int.h> #include <osmocom/abis/e1_input.h> @@ -53,6 +56,8 @@ #include <osmocom/msc/rtp_stream.h> #include <osmocom/msc/mncc_call.h> #include <osmocom/msc/msc_t.h> +#include <osmocom/msc/sdp_msg.h> +#include <osmocom/msc/codec_mapping.h> #include <osmocom/gsm/gsm48.h> #include <osmocom/gsm/gsm0480.h> @@ -124,7 +129,7 @@ static void gsm48_start_guard_timer(struct gsm_trans *trans) /* Call Control */ -void cc_tx_to_mncc(struct gsm_network *net, struct msgb *msg) +static void cc_tx_to_mncc(struct gsm_network *net, struct msgb *msg) { net->mncc_recv(net, msg); } @@ -161,20 +166,22 @@ static void count_statistics(struct gsm_trans *trans, int new_state) /* state incoming */ switch (new_state) { case GSM_CSTATE_ACTIVE: - osmo_counter_inc(trans->net->active_calls); - rate_ctr_inc(&msc->ctr[MSC_CTR_CALL_ACTIVE]); + osmo_stat_item_inc(osmo_stat_item_group_get_item(trans->net->statg, MSC_STAT_ACTIVE_CALLS), + 1); + rate_ctr_inc(rate_ctr_group_get_ctr(msc, MSC_CTR_CALL_ACTIVE)); break; } /* state outgoing */ switch (old_state) { case GSM_CSTATE_ACTIVE: - osmo_counter_dec(trans->net->active_calls); + osmo_stat_item_dec(osmo_stat_item_group_get_item(trans->net->statg, MSC_STAT_ACTIVE_CALLS), + 1); if (new_state == GSM_CSTATE_DISCONNECT_REQ || new_state == GSM_CSTATE_DISCONNECT_IND) - rate_ctr_inc(&msc->ctr[MSC_CTR_CALL_COMPLETE]); + rate_ctr_inc(rate_ctr_group_get_ctr(msc, MSC_CTR_CALL_COMPLETE)); else - rate_ctr_inc(&msc->ctr[MSC_CTR_CALL_INCOMPLETE]); + rate_ctr_inc(rate_ctr_group_get_ctr(msc, MSC_CTR_CALL_INCOMPLETE)); break; } } @@ -224,15 +231,82 @@ static void gsm48_stop_cc_timer(struct gsm_trans *trans) } } -static int mncc_recvmsg(struct gsm_network *net, struct gsm_trans *trans, - int msg_type, struct gsm_mncc *mncc) +/* Log the MNCC tx and rx events. + * Depending on msg_type, also log whether RTP information is passed on. + * (This is particularly interesting for the doc/sequence_charts/msc_log_to_ladder.py) + */ +#define log_mncc_rx_tx(ARGS...) _log_mncc_rx_tx(__FILE__, __LINE__, ##ARGS) +static void _log_mncc_rx_tx(const char *file, int line, + struct gsm_trans *trans, const char *rx_tx, const union mncc_msg *mncc) +{ + const char *sdp = NULL; + struct sdp_msg sdp_msg = {}; + struct osmo_sockaddr addr = {}; + + if (!log_check_level(DMNCC, LOGL_DEBUG)) + return; + + switch (mncc->msg_type) { + case MNCC_RTP_CREATE: + case MNCC_RTP_CONNECT: + addr = (struct osmo_sockaddr){ .u.sas = mncc->rtp.addr }; + sdp = mncc->rtp.sdp; + break; + + case MNCC_SETUP_IND: + case MNCC_SETUP_REQ: + case MNCC_SETUP_COMPL_IND: + case MNCC_SETUP_COMPL_REQ: + case MNCC_SETUP_RSP: + case MNCC_SETUP_CNF: + case MNCC_CALL_CONF_IND: + case MNCC_CALL_PROC_REQ: + case MNCC_ALERT_IND: + case MNCC_ALERT_REQ: + sdp = mncc->signal.sdp; + break; + + default: + break; + } + + if (sdp && sdp[0]) { + int rc = sdp_msg_from_sdp_str(&sdp_msg, sdp); + if (rc != 0) { + LOG_TRANS_CAT_SRC(trans, DMNCC, LOGL_ERROR, file, line, "%s %s: invalid SDP message (trying anyway)\n", + rx_tx, + get_mncc_name(mncc->msg_type)); + LOG_TRANS_CAT_SRC(trans, DMNCC, LOGL_DEBUG, file, line, "erratic SDP: %s\n", + osmo_quote_cstr_c(OTC_SELECT, sdp, -1)); + return; + } + LOG_TRANS_CAT_SRC(trans, DMNCC, LOGL_DEBUG, file, line, "%s %s (RTP=%s)\n", + rx_tx, + get_mncc_name(mncc->msg_type), + sdp_msg_to_str(&sdp_msg)); + return; + } + + if (osmo_sockaddr_is_any(&addr) == 0) { + LOG_TRANS_CAT_SRC(trans, DMNCC, LOGL_DEBUG, file, line, "%s %s (RTP=%s)\n", + rx_tx, + get_mncc_name(mncc->msg_type), + osmo_sockaddr_to_str_c(OTC_SELECT, &addr)); + return; + } + + LOG_TRANS_CAT_SRC(trans, DMNCC, LOGL_DEBUG, file, line, "%s %s\n", rx_tx, get_mncc_name(mncc->msg_type)); +} + +#define mncc_recvmsg(ARGS...) _mncc_recvmsg(__FILE__, __LINE__, ##ARGS) +static int _mncc_recvmsg(const char *file, int line, + struct gsm_network *net, struct gsm_trans *trans, int msg_type, struct gsm_mncc *mncc) { struct msgb *msg; unsigned char *data; - LOG_TRANS_CAT(trans, DMNCC, LOGL_DEBUG, "tx %s\n", get_mncc_name(msg_type)); - mncc->msg_type = msg_type; + log_mncc_rx_tx(trans, "tx", (union mncc_msg *)mncc); msg = msgb_alloc(sizeof(struct gsm_mncc), "MNCC"); if (!msg) @@ -242,6 +316,9 @@ static int mncc_recvmsg(struct gsm_network *net, struct gsm_trans *trans, memcpy(data, mncc, sizeof(struct gsm_mncc)); cc_tx_to_mncc(net, msg); + /* trans may be NULL when sending an MNCC error reply upon an invalid MNCC request */ + if (trans) + trans->cc.mncc_initiated = true; return 0; } @@ -267,6 +344,15 @@ void _gsm48_cc_trans_free(struct gsm_trans *trans) /* send release to L4, if callref still exists */ if (trans->callref) { + /* Send MNCC REL.ind (cause='Resource unavailable') */ + if (trans->cc.mncc_initiated) { + mncc_release_ind(trans->net, trans, trans->callref, + GSM48_CAUSE_LOC_PRN_S_LU, + (trans->cc.state == GSM_CSTATE_CALL_RECEIVED) ? + GSM48_CC_CAUSE_USER_NOTRESPOND : + GSM48_CC_CAUSE_RESOURCE_UNAVAIL); + } + /* FIXME: currently, a CC trans that would not yet be in state GSM_CSTATE_RELEASE_REQ fails to send a * CC Release to the MS if it gets freed here. Hack it to do so. */ if (trans->cc.state != GSM_CSTATE_RELEASE_REQ) { @@ -275,10 +361,6 @@ void _gsm48_cc_trans_free(struct gsm_trans *trans) mncc_set_cause(&rel, GSM48_CAUSE_LOC_PRN_S_LU, GSM48_CC_CAUSE_RESOURCE_UNAVAIL); gsm48_cc_tx_release(trans, &rel); } - /* Ressource unavailable */ - mncc_release_ind(trans->net, trans, trans->callref, - GSM48_CAUSE_LOC_PRN_S_LU, - GSM48_CC_CAUSE_RESOURCE_UNAVAIL); /* This is a final freeing of the transaction. The MNCC release may have triggered the * T308 release timer, but we don't have the luxury of graceful CC Release here. */ gsm48_stop_cc_timer(trans); @@ -308,6 +390,20 @@ static void cc_paging_cb(struct msc_a *msc_a, struct gsm_trans *trans) msc_a_get(msc_a, MSC_A_USE_CC); trans->msc_a = msc_a; trans->paging_request = NULL; + + /* Get the GCR from the MO call leg (if any). */ + if (!trans->cc.lcls) + trans->cc.lcls = trans_lcls_compose(trans, true); + if (trans->cc.lcls && trans->cc.msg.fields & MNCC_F_GCR) { + int rc = osmo_dec_gcr(&trans->cc.lcls->gcr, + &trans->cc.msg.gcr[0], + sizeof(trans->cc.msg.gcr)); + if (rc < 0) + LOG_TRANS(trans, LOGL_ERROR, "Failed to parse GCR\n"); + else + trans->cc.lcls->gcr_available = true; + } + osmo_fsm_inst_dispatch(msc_a->c.fi, MSC_A_EV_TRANSACTION_ACCEPTED, trans); /* send SETUP request to called party */ gsm48_cc_tx_setup(trans, &trans->cc.msg); @@ -327,8 +423,8 @@ static void cc_paging_cb(struct msc_a *msc_a, struct gsm_trans *trans) /* bridge channels of two transactions */ static int tch_bridge(struct gsm_network *net, const struct gsm_mncc_bridge *bridge) { - struct gsm_trans *trans1 = trans_find_by_callref(net, bridge->callref[0]); - struct gsm_trans *trans2 = trans_find_by_callref(net, bridge->callref[1]); + struct gsm_trans *trans1 = trans_find_by_callref(net, TRANS_CC, bridge->callref[0]); + struct gsm_trans *trans2 = trans_find_by_callref(net, TRANS_CC, bridge->callref[1]); struct call_leg *cl1; struct call_leg *cl2; @@ -353,7 +449,7 @@ static int tch_bridge(struct gsm_network *net, const struct gsm_mncc_bridge *bri cl1 = trans1->msc_a->cc.call_leg; cl2 = trans2->msc_a->cc.call_leg; - return call_leg_local_bridge(cl1, trans1->callref, trans1, cl2, trans2->callref, trans2); + return call_leg_local_bridge(cl1, trans1->call_id, trans1, cl2, trans2->call_id, trans2); } static int gsm48_cc_rx_status_enq(struct gsm_trans *trans, struct msgb *msg) @@ -372,6 +468,8 @@ static void gsm48_cc_timeout(void *arg) int l4_location = GSM48_CAUSE_LOC_PRN_S_LU; struct gsm_mncc mo_rel, l4_rel; + LOG_TRANS(trans, LOGL_INFO, "Timeout of T%x\n", trans->cc.Tcurrent); + memset(&mo_rel, 0, sizeof(struct gsm_mncc)); mo_rel.callref = trans->callref; memset(&l4_rel, 0, sizeof(struct gsm_mncc)); @@ -448,8 +546,8 @@ static void gsm48_cc_timeout(void *arg) static inline void disconnect_bridge(struct gsm_network *net, const struct gsm_mncc_bridge *bridge, int err) { - struct gsm_trans *trans0 = trans_find_by_callref(net, bridge->callref[0]); - struct gsm_trans *trans1 = trans_find_by_callref(net, bridge->callref[1]); + struct gsm_trans *trans0 = trans_find_by_callref(net, TRANS_CC, bridge->callref[0]); + struct gsm_trans *trans1 = trans_find_by_callref(net, TRANS_CC, bridge->callref[1]); struct gsm_mncc mx_rel; if (!trans0 || !trans1) return; @@ -492,6 +590,26 @@ static int gsm48_cc_rx_setup(struct gsm_trans *trans, struct msgb *msg) memset(&setup, 0, sizeof(struct gsm_mncc)); setup.callref = trans->callref; + /* New Global Call Reference */ + if (!trans->cc.lcls) + trans->cc.lcls = trans_lcls_compose(trans, true); + + /* Pass the LCLS GCR on to the MT call leg via MNCC */ + if (trans->cc.lcls) { + struct msgb *gcr_msg = msgb_alloc(sizeof(setup.gcr), "MNCC GCR"); + const struct osmo_gcr_parsed *gcr = &trans->cc.lcls->gcr; + int rc; + + if (gcr_msg != NULL && (rc = osmo_enc_gcr(gcr_msg, gcr)) > 0) { + memcpy(&setup.gcr[0], gcr_msg->data, rc); + setup.fields |= MNCC_F_GCR; + } else + LOG_TRANS(trans, LOGL_ERROR, "Failed to encode GCR\n"); + msgb_free(gcr_msg); + } + + OSMO_ASSERT(trans->msc_a); + tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len, 0, 0); /* emergency setup is identified by msg_type */ if (msg_type == GSM48_MT_CC_EMERG_SETUP) { @@ -536,6 +654,20 @@ static int gsm48_cc_rx_setup(struct gsm_trans *trans, struct msgb *msg) gsm48_decode_called(&setup.called, TLVP_VAL(&tp, GSM48_IE_CALLED_BCD)-1); } + /* low layer compatibility */ + if (TLVP_PRESENT(&tp, GSM48_IE_LOWL_COMPAT) && TLVP_LEN(&tp, GSM48_IE_LOWL_COMPAT) > 0 && + TLVP_LEN(&tp, GSM48_IE_LOWL_COMPAT) <= sizeof(setup.llc.compat)) { + setup.fields |= MNCC_F_LOWL_COMPAT; + setup.llc.len = TLVP_LEN(&tp, GSM48_IE_LOWL_COMPAT); + memcpy(setup.llc.compat, TLVP_VAL(&tp, GSM48_IE_LOWL_COMPAT), setup.llc.len); + } + /* high layer compatibility */ + if (TLVP_PRESENT(&tp, GSM48_IE_HIGHL_COMPAT) && TLVP_LEN(&tp, GSM48_IE_HIGHL_COMPAT) > 0 && + TLVP_LEN(&tp, GSM48_IE_HIGHL_COMPAT) <= sizeof(setup.hlc.compat)) { + setup.fields |= MNCC_F_HIGHL_COMPAT; + setup.hlc.len = TLVP_LEN(&tp, GSM48_IE_HIGHL_COMPAT); + memcpy(setup.hlc.compat, TLVP_VAL(&tp, GSM48_IE_HIGHL_COMPAT), setup.hlc.len); + } /* user-user */ if (TLVP_PRESENT(&tp, GSM48_IE_USER_USER)) { setup.fields |= MNCC_F_USERUSER; @@ -561,28 +693,145 @@ static int gsm48_cc_rx_setup(struct gsm_trans *trans, struct msgb *msg) TLVP_VAL(&tp, GSM48_IE_CC_CAP)-1); } - new_cc_state(trans, GSM_CSTATE_INITIATED); + /* MO call leg starting, gather all codec information so far known: */ + trans_cc_filter_init(trans); + trans_cc_filter_set_ran(trans, trans->msc_a->c.ran->type); + trans_cc_filter_set_bss(trans, trans->msc_a); + if (setup.fields & MNCC_F_BEARER_CAP) + trans_cc_filter_set_ms_from_bc(trans, &trans->bearer_cap); + trans_cc_filter_run(trans); LOG_TRANS(trans, setup.emergency ? LOGL_NOTICE : LOGL_INFO, "%sSETUP to %s\n", setup.emergency ? "EMERGENCY_" : "", setup.called.number); - rate_ctr_inc(&trans->net->msc_ctrs->ctr[MSC_CTR_CALL_MO_SETUP]); + rate_ctr_inc(rate_ctr_group_get_ctr(trans->net->msc_ctrs, MSC_CTR_CALL_MO_SETUP)); + + new_cc_state(trans, GSM_CSTATE_INITIATED); + + /* To complete the MNCC_SETUP_IND, we need to provide an RTP address and port. First instruct the MGW to create + * a CN-side RTP conn, and continue with MNCC_SETUP_IND once that is done. Leave trans.cc in GSM_CSTATE_NULL and + * note down the msg_type to indicate that we indeed composed an MNCC_SETUP_IND for later. */ + setup.msg_type = MNCC_SETUP_IND; + trans->cc.msg = setup; + return msc_a_try_call_assignment(trans); + /* continue in gsm48_cc_rx_setup_cn_local_rtp_port_known() */ +} + +/* Callback for MNCC_SETUP_IND waiting for the core network RTP port to be established by the MGW (via msc_a) */ +void gsm48_cc_rx_setup_cn_local_rtp_port_known(struct gsm_trans *trans) +{ + struct msc_a *msc_a = trans->msc_a; + struct gsm_mncc setup = trans->cc.msg; + struct osmo_sockaddr_str *rtp_cn_local; + struct sdp_msg *sdp; + int rc; + + if (trans->cc.state != GSM_CSTATE_INITIATED + || setup.msg_type != MNCC_SETUP_IND) { + LOG_TRANS(trans, LOGL_ERROR, + "Unexpected CC state. Expected GSM_CSTATE_INITIATED and a buffered MNCC_SETUP_IND message," + " found CC state %d and msg_type %s\n", + trans->cc.state, get_mncc_name(setup.msg_type)); + trans->callref = 0; + trans_free(trans); + return; + } + + if (!msc_a) { + LOG_TRANS(trans, LOGL_ERROR, "No connection for CC trans\n"); + trans->callref = 0; + trans_free(trans); + return; + } + + /* 'setup' above has taken the value of trans->cc.msg, we can now clear that. */ + trans->cc.msg = (struct gsm_mncc){}; + + /* Insert the CN side RTP port now available into SDP and compose SDP string */ + rtp_cn_local = call_leg_local_ip(msc_a->cc.call_leg, RTP_TO_CN); + if (!osmo_sockaddr_str_is_nonzero(rtp_cn_local)) { + LOG_TRANS(trans, LOGL_ERROR, "Cannot compose SDP for MNCC_SETUP_IND: no RTP set up for the CN side\n"); + trans_free(trans); + return; + } + trans->cc.local.rtp = *rtp_cn_local; + + sdp = trans->cc.local.audio_codecs.count ? &trans->cc.local : NULL; + rc = sdp_msg_to_sdp_str_buf(setup.sdp, sizeof(setup.sdp), sdp); + if (rc >= sizeof(setup.sdp)) { + LOG_TRANS(trans, LOGL_ERROR, "MNCC_SETUP_IND: SDP too long (%d > %zu bytes)\n", rc, sizeof(setup.sdp)); + trans_free(trans); + return; + } /* indicate setup to MNCC */ mncc_recvmsg(trans->net, trans, MNCC_SETUP_IND, &setup); +} - /* MNCC code will modify the channel asynchronously, we should - * ipaccess-bind only after the modification has been made to the - * lchan->tch_mode */ - return 0; +static void rx_mncc_sdp(struct gsm_trans *trans, uint32_t mncc_msg_type, const char *sdp, + const struct gsm_mncc_bearer_cap *bcap) +{ + struct codec_filter *codecs = &trans->cc.codecs; + struct call_leg *cl = trans->msc_a ? trans->msc_a->cc.call_leg : NULL; + struct rtp_stream *rtp_cn = cl ? cl->rtp[RTP_TO_CN] : NULL; + + if (sdp[0]) { + int rc = sdp_msg_from_sdp_str(&trans->cc.remote, sdp); + if (rc) + LOG_TRANS_CAT(trans, DMNCC, LOGL_ERROR, "rx %s: Failed to parse SDP: %d. Trying anyway.\n", + get_mncc_name(mncc_msg_type), rc); + } + + /* if there is no SDP information or we failed to parse it, try using the Bearer Cap from MNCC, if any. */ + if (!trans->cc.remote.audio_codecs.count && bcap) { + trans->cc.remote = (struct sdp_msg){}; + trans_cc_set_remote_from_bc(trans, bcap); + LOG_TRANS_CAT(trans, DMNCC, LOGL_DEBUG, "rx %s Bearer Cap: remote=%s\n", + get_mncc_name(mncc_msg_type), sdp_msg_to_str(&trans->cc.remote)); + } + + if (!trans->cc.remote.audio_codecs.count) + LOG_TRANS(trans, LOGL_INFO, + "Got no information of remote audio codecs: neither SDP nor Bearer Capability. Trying anyway.\n"); + + trans_cc_filter_run(trans); + if (rtp_cn) { + rtp_stream_set_remote_addr_and_codecs(rtp_cn, &trans->cc.remote); + rtp_stream_commit(rtp_cn); + } + + /* See if we need to switch codecs to maintain TFO: has the remote side changed the codecs information? If we + * have already assigned a specific codec here, but the remote call leg has now chosen a different codec, we + * need to re-assign this call leg to match the remote leg. */ + if (!sdp_audio_codec_is_set(&codecs->assignment)) { + /* Voice channel assignment has not completed. Do not interfere. */ + return; + } + if (!trans->cc.remote.audio_codecs.count) { + /* Don't know remote codecs, nothing to do. */ + return; + } + if (sdp_audio_codecs_by_descr(&trans->cc.remote.audio_codecs, &codecs->assignment)) { + /* The assigned codec is part of the remote codec set. All is well. */ + /* TODO: maybe this should require exactly the *first* remote codec to match, because we cannot flexibly + * transcode, and assume the actual payload we will receive is listed in the first place? */ + return; + } + + /* We've already completed Assignment of a voice channel (some time ago), and now the remote side has changed + * to a mismatching codec (list). Try to re-assign this side to a matching codec. */ + LOG_TRANS(trans, LOGL_INFO, "Remote call leg mismatches assigned codec: %s\n", + codec_filter_to_str(&trans->cc.codecs, &trans->cc.local, &trans->cc.remote)); + msc_a_tx_assignment_cmd(trans->msc_a); } static int gsm48_cc_tx_setup(struct gsm_trans *trans, void *arg) { - struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 CC STUP"); + struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 CC SETUP"); struct gsm48_hdr *gh; struct gsm_mncc *setup = arg; int rc, trans_id; + struct gsm_mncc_bearer_cap bearer_cap; gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); @@ -596,6 +845,7 @@ static int gsm48_cc_tx_setup(struct gsm_trans *trans, void *arg) GSM48_CC_CAUSE_RESOURCE_UNAVAIL); trans->callref = 0; trans_free(trans); + msgb_free(msg); return rc; } @@ -608,6 +858,7 @@ static int gsm48_cc_tx_setup(struct gsm_trans *trans, void *arg) GSM48_CC_CAUSE_RESOURCE_UNAVAIL); trans->callref = 0; trans_free(trans); + msgb_free(msg); return rc; } trans->transaction_id = trans_id; @@ -616,13 +867,102 @@ static int gsm48_cc_tx_setup(struct gsm_trans *trans, void *arg) gsm48_start_cc_timer(trans, 0x303, GSM48_T303); - /* bearer capability */ - if (setup->fields & MNCC_F_BEARER_CAP) { - /* Create a copy of the bearer capability in the transaction struct, so we - * can use this information later */ - memcpy(&trans->bearer_cap, &setup->bearer_cap, sizeof(trans->bearer_cap)); - gsm48_encode_bearer_cap(msg, 0, &setup->bearer_cap); + /* MT call leg is starting. Gather all codecs information so far known. + * (Usually) paging has succeeded, and now we're processing the MNCC Setup from the remote MO call leg. + * Initialize the codecs filter with this side's BSS' codec list, received at Complete Layer 3. + * We haven't received the MT MS's Bearer Capabilities yet; the Bearer Capabilities handled here are + * actually the remote call leg's Bearer Capabilities. */ + trans_cc_filter_init(trans); + trans_cc_filter_set_ran(trans, trans->msc_a->c.ran->type); + trans_cc_filter_set_bss(trans, trans->msc_a); + if (setup->fields & MNCC_F_BEARER_CAP) + trans->bearer_cap.transfer = setup->bearer_cap.transfer; + + switch (trans->bearer_cap.transfer) { + case GSM48_BCAP_ITCAP_SPEECH: + /* if SDP is included in the MNCC, take that as definitive list of remote audio codecs. */ + rx_mncc_sdp(trans, setup->msg_type, setup->sdp, + (setup->fields & MNCC_F_BEARER_CAP) ? &setup->bearer_cap : NULL); + /* rx_mncc_sdp() has called trans_cc_filter_run(trans); */ + break; + case GSM48_BCAP_ITCAP_3k1_AUDIO: + case GSM48_BCAP_ITCAP_FAX_G3: + case GSM48_BCAP_ITCAP_UNR_DIG_INF: + if (setup->fields & MNCC_F_BEARER_CAP) { + trans->cc.remote = (struct sdp_msg){}; + trans_cc_set_remote_from_bc(trans, &setup->bearer_cap); + LOG_TRANS_CAT(trans, DMNCC, LOGL_DEBUG, "rx %s Bearer Cap: remote=%s\n", + get_mncc_name(setup->msg_type), sdp_msg_to_str(&trans->cc.remote)); + } else { + LOG_TRANS(trans, LOGL_INFO, + "Got no information of remote Bearer Capability. Trying anyway.\n"); + sdp_audio_codecs_set_csd(&trans->cc.codecs.ms); + } + trans_cc_filter_run(trans); + break; + default: + LOG_TRANS(trans, LOGL_ERROR, "Handling of information transfer capability %d not implemented\n", + trans->bearer_cap.transfer); + break; } + + /* Compose Bearer Capability information that reflects only the codecs (Speech Versions) / CSD bearer services + * remaining after intersecting MS, BSS and remote call leg restrictions. To store in trans for later use, and + * to include in the outgoing CC Setup message. */ + switch (trans->bearer_cap.transfer) { + case GSM48_BCAP_ITCAP_SPEECH: + bearer_cap = (struct gsm_mncc_bearer_cap){ + .speech_ver = { -1 }, + }; + sdp_audio_codecs_to_bearer_cap(&bearer_cap, &trans->cc.local.audio_codecs); + rc = bearer_cap_set_radio(&bearer_cap); + if (rc) { + LOG_TRANS(trans, LOGL_ERROR, "Error composing Bearer Capability for CC Setup\n"); + trans_free(trans); + msgb_free(msg); + return rc; + } + /* If no resulting codecs remain, error out. We cannot find a codec that matches both call legs. If the MGW were + * able to transcode, we could use non-identical codecs on each conn of the MGW endpoint, but we are aiming for + * finding a matching codec. */ + if (bearer_cap.speech_ver[0] == -1) { + LOG_TRANS(trans, LOGL_ERROR, "%s: no codec match possible: %s\n", + get_mncc_name(setup->msg_type), + codec_filter_to_str(&trans->cc.codecs, &trans->cc.local, &trans->cc.remote)); + + /* incompatible codecs */ + rc = mncc_release_ind(trans->net, trans, trans->callref, + GSM48_CAUSE_LOC_PRN_S_LU, + GSM48_CC_CAUSE_INCOMPAT_DEST /* TODO: correct cause code? */); + trans->callref = 0; + trans_free(trans); + msgb_free(msg); + return rc; + } + break; + case GSM48_BCAP_ITCAP_3k1_AUDIO: + case GSM48_BCAP_ITCAP_FAX_G3: + case GSM48_BCAP_ITCAP_UNR_DIG_INF: + if (csd_bs_list_to_bearer_cap(&bearer_cap, &trans->cc.local.bearer_services) == 0) { + LOG_TRANS(trans, LOGL_ERROR, "Error composing Bearer Capability for CC Setup\n"); + + /* incompatible codecs */ + rc = mncc_release_ind(trans->net, trans, trans->callref, + GSM48_CAUSE_LOC_PRN_S_LU, + GSM48_CC_CAUSE_INCOMPAT_DEST /* TODO: correct cause code? */); + trans->callref = 0; + trans_free(trans); + msgb_free(msg); + return rc; + } + break; + } + + /* Create a copy of the bearer capability in the transaction struct, so we can use this information later */ + trans->bearer_cap = bearer_cap; + + gsm48_encode_bearer_cap(msg, 0, &bearer_cap); + /* facility */ if (setup->fields & MNCC_F_FACILITY) gsm48_encode_facility(msg, 0, &setup->facility); @@ -635,6 +975,12 @@ static int gsm48_cc_tx_setup(struct gsm_trans *trans, void *arg) /* called party BCD number */ if (setup->fields & MNCC_F_CALLED) gsm48_encode_called(msg, &setup->called); + /* low layer compatibility */ + if (setup->fields & MNCC_F_LOWL_COMPAT && setup->llc.len > 0 && setup->llc.len <= sizeof(setup->llc.compat)) + msgb_tlv_put(msg, GSM48_IE_LOWL_COMPAT, setup->llc.len, setup->llc.compat); + /* high layer compatibility */ + if (setup->fields & MNCC_F_HIGHL_COMPAT && setup->hlc.len > 0 && setup->hlc.len <= sizeof(setup->hlc.compat)) + msgb_tlv_put(msg, GSM48_IE_HIGHL_COMPAT, setup->hlc.len, setup->hlc.compat); /* user-user */ if (setup->fields & MNCC_F_USERUSER) gsm48_encode_useruser(msg, 0, &setup->useruser); @@ -647,7 +993,7 @@ static int gsm48_cc_tx_setup(struct gsm_trans *trans, void *arg) new_cc_state(trans, GSM_CSTATE_CALL_PRESENT); - rate_ctr_inc(&trans->net->msc_ctrs->ctr[MSC_CTR_CALL_MT_SETUP]); + rate_ctr_inc(rate_ctr_group_get_ctr(trans->net->msc_ctrs, MSC_CTR_CALL_MT_SETUP)); return trans_tx_gsm48(trans, msg); } @@ -683,9 +1029,14 @@ static int gsm48_cc_rx_call_conf(struct gsm_trans *trans, struct msgb *msg) /* Create a copy of the bearer capability * in the transaction struct, so we can use * this information later */ - memcpy(&trans->bearer_cap,&call_conf.bearer_cap, + memcpy(&trans->bearer_cap, &call_conf.bearer_cap, sizeof(trans->bearer_cap)); + + /* This is the MT call leg's Call Conf, containing the MS Bearer Capabilities of the MT MS. + * Store in codecs filter. */ + trans_cc_filter_set_ms_from_bc(trans, &call_conf.bearer_cap); } + /* cause */ if (TLVP_PRESENT(&tp, GSM48_IE_CAUSE)) { call_conf.fields |= MNCC_F_CAUSE; @@ -702,8 +1053,6 @@ static int gsm48_cc_rx_call_conf(struct gsm_trans *trans, struct msgb *msg) /* IMSI of called subscriber */ OSMO_STRLCPY_ARRAY(call_conf.imsi, trans->vsub->imsi); - new_cc_state(trans, GSM_CSTATE_MO_TERM_CALL_CONF); - /* Assign call (if not done yet) */ rc = msc_a_try_call_assignment(trans); @@ -712,8 +1061,47 @@ static int gsm48_cc_rx_call_conf(struct gsm_trans *trans, struct msgb *msg) if (rc) return rc; - return mncc_recvmsg(trans->net, trans, MNCC_CALL_CONF_IND, - &call_conf); + /* Directly ack with MNCC_CALL_CONF_IND, not yet containing SDP or RTP IP:port information. */ + new_cc_state(trans, GSM_CSTATE_MO_TERM_CALL_CONF); + return mncc_recvmsg(trans->net, trans, MNCC_CALL_CONF_IND, &call_conf); +} + +static int mncc_recv_rtp(struct gsm_network *net, struct gsm_trans *trans, uint32_t callref, + int cmd, struct osmo_sockaddr_str *rtp_addr, uint32_t payload_type, + uint32_t payload_msg_type, const struct sdp_msg *sdp); + +static int gsm48_cc_mt_rtp_port_and_codec_known(struct gsm_trans *trans) +{ + struct msc_a *msc_a = trans->msc_a; + struct osmo_sockaddr_str *rtp_cn_local; + struct gsm_mncc_rtp; + + if (!msc_a) { + LOG_TRANS(trans, LOGL_ERROR, "No connection for CC trans\n"); + trans->callref = 0; + trans_free(trans); + return -EINVAL; + } + + /* Insert the CN side RTP port now available into SDP */ + rtp_cn_local = call_leg_local_ip(msc_a->cc.call_leg, RTP_TO_CN); + if (!rtp_cn_local) { + LOG_TRANS(trans, LOGL_ERROR, "Cannot compose SDP for MNCC_RTP_CREATE: no RTP set up for the CN side\n"); + trans_free(trans); + return -EINVAL; + } + trans->cc.local.rtp = *rtp_cn_local; + + trans_cc_filter_run(trans); + + /* If we haven't completed Assignment yet, don't sent MNCC_RTP_CREATE */ + if (!sdp_audio_codec_is_set(&trans->cc.codecs.assignment)) { + LOG_TRANS(trans, LOGL_DEBUG, "no codec confirmed by Assignment yet\n"); + return 0; + } + + return mncc_recv_rtp(msc_a_net(msc_a), trans, trans->callref, MNCC_RTP_CREATE, rtp_cn_local, 0, 0, + &trans->cc.local); } static int gsm48_cc_tx_call_proc_and_assign(struct gsm_trans *trans, void *arg) @@ -729,6 +1117,14 @@ static int gsm48_cc_tx_call_proc_and_assign(struct gsm_trans *trans, void *arg) /* bearer capability */ if (proceeding->fields & MNCC_F_BEARER_CAP) { + /* MNCC should not switch from e.g. CSD to speech */ + if (proceeding->bearer_cap.transfer != trans->bearer_cap.transfer) { + LOG_TRANS(trans, LOGL_ERROR, "Unexpected Information Transfer Capability %d from MNCC," + " transaction has %d\n", + proceeding->bearer_cap.transfer, + trans->bearer_cap.transfer); + return -EINVAL; + } gsm48_encode_bearer_cap(msg, 0, &proceeding->bearer_cap); memcpy(&trans->bearer_cap, &proceeding->bearer_cap, sizeof(trans->bearer_cap)); } @@ -753,6 +1149,7 @@ static int gsm48_cc_rx_alerting(struct gsm_trans *trans, struct msgb *msg) unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh); struct tlv_parsed tp; struct gsm_mncc alerting; + int rc; gsm48_stop_cc_timer(trans); gsm48_start_cc_timer(trans, 0x301, GSM48_T301); @@ -782,6 +1179,15 @@ static int gsm48_cc_rx_alerting(struct gsm_trans *trans, struct msgb *msg) new_cc_state(trans, GSM_CSTATE_CALL_RECEIVED); + trans_cc_filter_run(trans); + rc = sdp_msg_to_sdp_str_buf(alerting.sdp, sizeof(alerting.sdp), &trans->cc.local); + if (rc >= sizeof(alerting.sdp)) { + LOG_TRANS(trans, LOGL_ERROR, "MNCC_ALERT_IND: SDP too long (%d > %zu bytes)\n", + rc, sizeof(alerting.sdp)); + trans_free(trans); + return -EINVAL; + } + return mncc_recvmsg(trans->net, trans, MNCC_ALERT_IND, &alerting); } @@ -791,6 +1197,7 @@ static int gsm48_cc_tx_alerting(struct gsm_trans *trans, void *arg) struct gsm_mncc *alerting = arg; struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 CC ALERT"); struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); + int rc; gh->msg_type = GSM48_MT_CC_ALERTING; @@ -806,7 +1213,13 @@ static int gsm48_cc_tx_alerting(struct gsm_trans *trans, void *arg) new_cc_state(trans, GSM_CSTATE_CALL_DELIVERED); - return trans_tx_gsm48(trans, msg); + if (alerting->sdp[0]) + rx_mncc_sdp(trans, alerting->msg_type, alerting->sdp, + (alerting->fields & MNCC_F_BEARER_CAP) ? &alerting->bearer_cap : NULL); + + /* handle the MNCC event */ + rc = trans_tx_gsm48(trans, msg); + return rc; } static int gsm48_cc_tx_progress(struct gsm_trans *trans, void *arg) @@ -852,6 +1265,10 @@ static int gsm48_cc_tx_connect(struct gsm_trans *trans, void *arg) new_cc_state(trans, GSM_CSTATE_CONNECT_IND); + if (connect->sdp[0]) + rx_mncc_sdp(trans, connect->msg_type, connect->sdp, + (connect->fields & MNCC_F_BEARER_CAP) ? &connect->bearer_cap : NULL); + return trans_tx_gsm48(trans, msg); } @@ -892,8 +1309,10 @@ static int gsm48_cc_rx_connect(struct gsm_trans *trans, struct msgb *msg) } new_cc_state(trans, GSM_CSTATE_CONNECT_REQUEST); - rate_ctr_inc(&trans->net->msc_ctrs->ctr[MSC_CTR_CALL_MT_CONNECT]); + rate_ctr_inc(rate_ctr_group_get_ctr(trans->net->msc_ctrs, MSC_CTR_CALL_MT_CONNECT)); + trans_cc_filter_run(trans); + sdp_msg_to_sdp_str_buf(connect.sdp, sizeof(connect.sdp), &trans->cc.local); return mncc_recvmsg(trans->net, trans, MNCC_SETUP_CNF, &connect); } @@ -905,7 +1324,7 @@ static int gsm48_cc_rx_connect_ack(struct gsm_trans *trans, struct msgb *msg) gsm48_stop_cc_timer(trans); new_cc_state(trans, GSM_CSTATE_ACTIVE); - rate_ctr_inc(&trans->net->msc_ctrs->ctr[MSC_CTR_CALL_MO_CONNECT_ACK]); + rate_ctr_inc(rate_ctr_group_get_ctr(trans->net->msc_ctrs, MSC_CTR_CALL_MO_CONNECT_ACK)); memset(&connect_ack, 0, sizeof(struct gsm_mncc)); connect_ack.callref = trans->callref; @@ -1072,8 +1491,16 @@ static int gsm48_cc_rx_release(struct gsm_trans *trans, struct msgb *msg) static int gsm48_cc_tx_release(struct gsm_trans *trans, void *arg) { struct gsm_mncc *rel = arg; - struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 CC REL"); - struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); + struct msgb *msg; + struct gsm48_hdr *gh; + + if (!trans->msc_a) { + LOG_TRANS(trans, LOGL_DEBUG, "Cannot send CC REL, there is no MSC-A connection\n"); + return -EINVAL; + } + + msg = gsm48_msgb_alloc_name("GSM 04.08 CC REL"); + gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); gh->msg_type = GSM48_MT_CC_RELEASE; @@ -1596,7 +2023,7 @@ static int gsm48_cc_rx_userinfo(struct gsm_trans *trans, struct msgb *msg) static int mncc_recv_rtp(struct gsm_network *net, struct gsm_trans *trans, uint32_t callref, int cmd, struct osmo_sockaddr_str *rtp_addr, uint32_t payload_type, - uint32_t payload_msg_type) + uint32_t payload_msg_type, const struct sdp_msg *sdp) { uint8_t data[sizeof(struct gsm_mncc)]; struct gsm_mncc_rtp *rtp; @@ -1607,56 +2034,106 @@ static int mncc_recv_rtp(struct gsm_network *net, struct gsm_trans *trans, uint3 rtp->callref = callref; rtp->msg_type = cmd; if (rtp_addr) { - rtp->ip = osmo_htonl(inet_addr(rtp_addr->ip)); - rtp->port = rtp_addr->port; + if (osmo_sockaddr_str_to_sockaddr(rtp_addr, &rtp->addr) < 0) + return -EINVAL; } rtp->payload_type = payload_type; rtp->payload_msg_type = payload_msg_type; + if (sdp) + sdp_msg_to_sdp_str_buf(rtp->sdp, sizeof(rtp->sdp), sdp); return mncc_recvmsg(net, trans, cmd, (struct gsm_mncc *)data); } static void mncc_recv_rtp_err(struct gsm_network *net, struct gsm_trans *trans, uint32_t callref, int cmd) { - mncc_recv_rtp(net, trans, callref, cmd, NULL, 0, 0); + mncc_recv_rtp(net, trans, callref, cmd, NULL, 0, 0, NULL); } -static int tch_rtp_create(struct gsm_network *net, uint32_t callref) +static int tch_rtp_create(struct gsm_network *net, const struct gsm_mncc_rtp *rtp) { struct gsm_trans *trans; /* Find callref */ - trans = trans_find_by_callref(net, callref); + trans = trans_find_by_callref(net, TRANS_CC, rtp->callref); if (!trans) { LOG_TRANS_CAT(trans, DMNCC, LOGL_ERROR, "RTP create for non-existing trans\n"); - mncc_recv_rtp_err(net, trans, callref, MNCC_RTP_CREATE); + mncc_recv_rtp_err(net, trans, rtp->callref, MNCC_RTP_CREATE); return -EIO; } log_set_context(LOG_CTX_VLR_SUBSCR, trans->vsub); if (!trans->msc_a) { LOG_TRANS_CAT(trans, DMNCC, LOGL_NOTICE, "RTP create for trans without conn\n"); - mncc_recv_rtp_err(net, trans, callref, MNCC_RTP_CREATE); + mncc_recv_rtp_err(net, trans, rtp->callref, MNCC_RTP_CREATE); return 0; } - LOG_TRANS_CAT(trans, DMNCC, LOGL_DEBUG, "rx %s\n", get_mncc_name(MNCC_RTP_CREATE)); - - /* When we call msc_mgcp_call_assignment() we will trigger, depending - * on the RAN type the call assignment on the A or Iu interface. - * msc_mgcp_call_assignment() also takes care about sending the CRCX - * command to the MGCP-GW. The CRCX will return the port number, - * where the PBX (e.g. Asterisk) will send its RTP stream to. We - * have to return this port number back to the MNCC by sending - * it back with the TCH_RTP_CREATE message. To make sure that - * this message is sent AFTER the response to CRCX from the - * MGCP-GW has arrived, we need will instruct msc_mgcp_call_assignment() - * to take care of this by setting trans->tch_rtp_create to true. - * This will make sure that gsm48_tch_rtp_create() (below) is - * called as soon as the local port number has become known. */ - trans->tch_rtp_create = true; + log_mncc_rx_tx(trans, "rx", (const union mncc_msg *)rtp); /* Assign call (if not done yet) */ return msc_a_try_call_assignment(trans); } +int cc_on_cn_local_rtp_port_known(struct gsm_trans *cc_trans) +{ + /* Depending on MO or MT call, dispatch the event differently */ + switch (cc_trans->cc.state) { + case GSM_CSTATE_INITIATED: + if (cc_trans->cc.msg.msg_type != MNCC_SETUP_IND) { + LOG_TRANS(cc_trans, LOGL_ERROR, "Assuming MO call, expected MNCC_SETUP_IND to be prepared\n"); + return -EINVAL; + } + /* This is the MO call leg, waiting for a CN RTP be able to send initial MNCC_SETUP_IND. */ + gsm48_cc_rx_setup_cn_local_rtp_port_known(cc_trans); + return 0; + + case GSM_CSTATE_MO_TERM_CALL_CONF: + /* This is the MT call leg, waiting for a CN RTP to be able to send MNCC_CALL_CONF_IND. */ + return gsm48_cc_mt_rtp_port_and_codec_known(cc_trans); + + default: + LOG_TRANS(cc_trans, LOGL_ERROR, "CN RTP address available, but in unexpected state %d\n", + cc_trans->cc.state); + return -EINVAL; + } +} + +int cc_on_assignment_done(struct gsm_trans *trans) +{ + struct msc_a *msc_a = trans->msc_a; + + switch (trans->cc.state) { + case GSM_CSTATE_INITIATED: + case GSM_CSTATE_MO_CALL_PROC: + /* MO call, send ACK in form of an MNCC_RTP_CREATE (below) */ + break; + + case GSM_CSTATE_CALL_RECEIVED: + case GSM_CSTATE_MO_TERM_CALL_CONF: + /* MT call, send ACK in form of an MNCC_RTP_CREATE (below) */ + break; + + case GSM_CSTATE_ACTIVE: + /* already active. We decided to re-assign later on during the call - at time of writing this never + * happens. */ + case GSM_CSTATE_CALL_DELIVERED: + case GSM_CSTATE_CONNECT_IND: + /* MNCC has progressed past the initial assignment. Usually it means that this happened: after + * MNCC_ALERT_REQ, MO has triggered a re-assignment, to adjust MO's codec to MT's codec. */ + LOG_TRANS(trans, LOGL_DEBUG, "Re-Assignment complete\n"); + return 0; + + default: + LOG_TRANS(trans, LOGL_ERROR, "Assignment done in unexpected CC state: %d\n", trans->cc.state); + return -EINVAL; + } + + if (!call_leg_local_ip(msc_a->cc.call_leg, RTP_TO_CN)) { + LOG_TRANS(trans, LOGL_DEBUG, + "Assignment complete, but still waiting for the CRCX OK on the CN side RTP\n"); + return 0; + } + return gsm48_tch_rtp_create(trans); +} + /* Trigger TCH_RTP_CREATE acknowledgement */ int gsm48_tch_rtp_create(struct gsm_trans *trans) { @@ -1667,26 +2144,38 @@ int gsm48_tch_rtp_create(struct gsm_trans *trans) struct gsm_network *net = msc_a_net(msc_a); struct call_leg *cl = msc_a->cc.call_leg; struct osmo_sockaddr_str *rtp_cn_local; - /* FIXME: This has to be set to some meaningful value, - * before the MSC-Split, this value was pulled from - * lchan->abis_ip.rtp_payload */ - uint32_t payload_type = 0; - int msg_type; - - /* FIXME This has to be set to some meaningful value. - * Possible options are: - * GSM_TCHF_FRAME, GSM_TCHF_FRAME_EFR, - * GSM_TCHH_FRAME, GSM_TCH_FRAME_AMR - * (0 if unknown) */ - msg_type = GSM_TCHF_FRAME; + struct rtp_stream *rtp_cn = cl ? cl->rtp[RTP_TO_CN] : NULL; + int mncc_payload_msg_type; + struct sdp_audio_codec *codec; + const struct codec_mapping *m; + struct sdp_audio_codecs *codecs; + + if (!rtp_cn) { + LOG_TRANS_CAT(trans, DMNCC, LOGL_ERROR, "Cannot RTP CREATE to MNCC, no RTP set up for the CN side\n"); + return -EINVAL; + } + + trans_cc_filter_run(trans); + codecs = &trans->cc.local.audio_codecs; + if (!codecs->count) { + LOG_TRANS_CAT(trans, DMNCC, LOGL_ERROR, + "Cannot RTP CREATE to MNCC, there is no codec available\n"); + return -EINVAL; + } + + /* Populate the legacy MNCC codec elements: payload_type and payload_msg_type */ + codec = &codecs->codec[0]; + m = codec_mapping_by_subtype_name(codec->subtype_name); + mncc_payload_msg_type = m ? m->mncc_payload_msg_type : 0; rtp_cn_local = call_leg_local_ip(cl, RTP_TO_CN); if (!rtp_cn_local) { - LOG_TRANS_CAT(trans, DMNCC, LOGL_ERROR, "Cannot RTP CREATE to MNCC, no local RTP IP:port set up\n"); + LOG_TRANS_CAT(trans, DMNCC, LOGL_ERROR, "Cannot RTP CREATE to MNCC, no local RTP IP:port to CN set up\n"); return -EINVAL; } - return mncc_recv_rtp(net, trans, trans->callref, MNCC_RTP_CREATE, rtp_cn_local, payload_type, msg_type); + return mncc_recv_rtp(net, trans, trans->callref, MNCC_RTP_CREATE, rtp_cn_local, + codec->payload_type, mncc_payload_msg_type, &trans->cc.local); } static int tch_rtp_connect(struct gsm_network *net, const struct gsm_mncc_rtp *rtp) @@ -1694,20 +2183,9 @@ static int tch_rtp_connect(struct gsm_network *net, const struct gsm_mncc_rtp *r struct gsm_trans *trans; struct call_leg *cl; struct rtp_stream *rtps; - struct osmo_sockaddr_str rtp_addr; - - /* FIXME: in *rtp we should get the codec information of the remote - * leg. We will have to populate trans->conn->rtp.codec_cn with a - * meaningful value based on this information but unfortunately we - * can't do that yet because the mncc API can not signal dynamic - * payload types yet. This must be fixed first. Also there may be - * additional members necessary in trans->conn->rtp because we - * somehow need to deal with dynamic payload types that do not - * comply to 3gpp's assumptions of payload type numbers on the A - * interface. See also related tickets: OS#3399 and OS1683 */ /* Find callref */ - trans = trans_find_by_callref(net, rtp->callref); + trans = trans_find_by_callref(net, TRANS_CC, rtp->callref); if (!trans) { LOG_TRANS_CAT(trans, DMNCC, LOGL_ERROR, "RTP connect for non-existing trans\n"); mncc_recv_rtp_err(net, trans, rtp->callref, MNCC_RTP_CONNECT); @@ -1720,22 +2198,23 @@ static int tch_rtp_connect(struct gsm_network *net, const struct gsm_mncc_rtp *r return -EIO; } - LOG_TRANS_CAT(trans, DMNCC, LOGL_DEBUG, "rx %s\n", get_mncc_name(MNCC_RTP_CONNECT)); + log_mncc_rx_tx(trans, "rx", (const union mncc_msg *)rtp); + + rx_mncc_sdp(trans, rtp->msg_type, rtp->sdp, NULL); cl = trans->msc_a->cc.call_leg; rtps = cl ? cl->rtp[RTP_TO_CN] : NULL; - - if (!rtps) { - LOG_TRANS_CAT(trans, DMNCC, LOGL_ERROR, "RTP connect for trans without ongoing call\n"); - mncc_recv_rtp_err(net, trans, rtp->callref, MNCC_RTP_CONNECT); - return -EINVAL; + if (rtps && !osmo_sockaddr_str_is_nonzero(&rtps->remote)) { + /* Didn't get an IP address from SDP. Try legacy MNCC IP address */ + struct osmo_sockaddr_str rtp_addr; + if (osmo_sockaddr_str_from_sockaddr(&rtp_addr, &rtp->addr) < 0) { + LOG_TRANS_CAT(trans, DMNCC, LOGL_ERROR, "RTP connect with invalid IP addr\n"); + mncc_recv_rtp_err(net, trans, rtp->callref, MNCC_RTP_CONNECT); + return -EINVAL; + } + rtp_stream_set_remote_addr(rtps, &rtp_addr); + rtp_stream_commit(rtps); } - - LOG_TRANS_CAT(trans, DMNCC, LOGL_DEBUG, "rx %s\n", get_mncc_name(MNCC_RTP_CONNECT)); - - osmo_sockaddr_str_from_32n(&rtp_addr, rtp->ip, rtp->port); - rtp_stream_set_remote_addr(rtps, &rtp_addr); - rtp_stream_commit(rtps); return 0; } @@ -1798,7 +2277,7 @@ static struct downstate { (sizeof(downstatelist) / sizeof(struct downstate)) -int mncc_tx_to_gsm_cc(struct gsm_network *net, const union mncc_msg *msg) +static int mncc_tx_to_gsm_cc(struct gsm_network *net, const union mncc_msg *msg) { int i, rc = 0; struct msc_a *msc_a = NULL; @@ -1813,7 +2292,7 @@ int mncc_tx_to_gsm_cc(struct gsm_network *net, const union mncc_msg *msg) disconnect_bridge(net, &msg->bridge, -rc); return rc; case MNCC_RTP_CREATE: - return tch_rtp_create(net, msg->rtp.callref); + return tch_rtp_create(net, &msg->rtp); case MNCC_RTP_CONNECT: return tch_rtp_connect(net, &msg->rtp); case MNCC_RTP_FREE: @@ -1834,7 +2313,7 @@ int mncc_tx_to_gsm_cc(struct gsm_network *net, const union mncc_msg *msg) data = &msg->signal; /* Find callref */ - trans = trans_find_by_callref(net, data->callref); + trans = trans_find_by_callref(net, TRANS_CC, data->callref); /* Callref unknown */ if (!trans) { @@ -1870,7 +2349,7 @@ int mncc_tx_to_gsm_cc(struct gsm_network *net, const union mncc_msg *msg) } if (!vsub) return mncc_release_ind(net, NULL, data->callref, GSM48_CAUSE_LOC_PRN_S_LU, - GSM48_CC_CAUSE_UNASSIGNED_NR); + GSM48_CC_CAUSE_USER_NOTRESPOND); /* update the subscriber we deal with */ log_set_context(LOG_CTX_VLR_SUBSCR, vsub); @@ -1884,38 +2363,53 @@ int mncc_tx_to_gsm_cc(struct gsm_network *net, const union mncc_msg *msg) GSM48_CAUSE_LOC_PRN_S_LU, GSM48_CC_CAUSE_DEST_OOO); } + + /* Find valid conn */ + msc_a = msc_a_for_vsub(vsub, true); + + /* If subscriber is BUSY and we do not DO call in call aka "call-waiting" */ + if (!net->call_waiting && msc_a) { + struct gsm_trans *existing_cc_trans = trans_find_by_type(msc_a, TRANS_CC); + if (existing_cc_trans && existing_cc_trans->cc.state != GSM_CSTATE_NULL) { + LOG_TRANS_CAT(existing_cc_trans, DCC, LOGL_NOTICE, + "rx '%s' for subscriber %s with trans state (%s)" + " rejecting with USER_BUSY\n", + get_mncc_name(msg->msg_type), data->called.number, + gsm48_cc_state_name(existing_cc_trans->cc.state)); + return mncc_release_ind(net, NULL, data->callref, + GSM48_CAUSE_LOC_PRN_S_LU, + GSM48_CC_CAUSE_USER_BUSY); + } + } + /* Create transaction */ trans = trans_alloc(net, vsub, TRANS_CC, TRANS_ID_UNASSIGNED, data->callref); if (!trans) { LOG_TRANS(trans, LOGL_ERROR, "No memory for trans.\n"); vlr_subscr_put(vsub, __func__); - /* Ressource unavailable */ + /* Resource unavailable */ mncc_release_ind(net, NULL, data->callref, GSM48_CAUSE_LOC_PRN_S_LU, GSM48_CC_CAUSE_RESOURCE_UNAVAIL); return -ENOMEM; } - /* Find valid conn */ - msc_a = msc_a_for_vsub(vsub, true); + /* Remember remote SDP, if any */ + rx_mncc_sdp(trans, data->msg_type, data->sdp, + (data->fields & MNCC_F_BEARER_CAP) ? &data->bearer_cap : NULL); /* If subscriber has no conn */ if (!msc_a) { - - if (vsub->cs.is_paging) { - LOG_TRANS(trans, LOGL_DEBUG, - "rx %s, subscriber not yet connected, paging already started\n", - get_mncc_name(msg->msg_type)); - vlr_subscr_put(vsub, __func__); - trans_free(trans); - return 0; - } + /* This condition will return before the common logging of the received MNCC message below, so + * log it now. */ + log_mncc_rx_tx(trans, "rx", msg); /* store setup information until paging succeeds */ memcpy(&trans->cc.msg, data, sizeof(struct gsm_mncc)); - /* Request a channel */ + /* Request a channel. If Paging already started, paging_request_start() will append the new + * trans to the already ongoing Paging. */ trans->paging_request = paging_request_start(vsub, PAGING_CAUSE_CALL_CONVERSATIONAL, cc_paging_cb, trans, "MNCC: establish call"); if (!trans->paging_request) { @@ -1936,9 +2430,30 @@ int mncc_tx_to_gsm_cc(struct gsm_network *net, const union mncc_msg *msg) log_set_context(LOG_CTX_VLR_SUBSCR, trans->vsub); } - LOG_TRANS_CAT(trans, DMNCC, LOGL_DEBUG, "rx %s\n", get_mncc_name(msg->msg_type)); + log_mncc_rx_tx(trans, "rx", msg); - gsm48_start_guard_timer(trans); + /* + * The step of gsm48_start_guard_timer() needs to be done for + * major state-impacting MNCC messages, but not for those + * that are a mere pass-through to CC messages to MS. + */ + switch (msg->msg_type) { + case MNCC_PROGRESS_REQ: + case MNCC_NOTIFY_REQ: + case MNCC_FACILITY_REQ: + case MNCC_START_DTMF_RSP: + case MNCC_START_DTMF_REJ: + case MNCC_STOP_DTMF_RSP: + case MNCC_HOLD_CNF: + case MNCC_HOLD_REJ: + case MNCC_RETRIEVE_CNF: + case MNCC_RETRIEVE_REJ: + case MNCC_USERINFO_REQ: + break; + default: + gsm48_start_guard_timer(trans); + } + trans->cc.mncc_initiated = true; if (trans->msc_a) msc_a = trans->msc_a; @@ -1948,7 +2463,7 @@ int mncc_tx_to_gsm_cc(struct gsm_network *net, const union mncc_msg *msg) struct gsm_mncc rel = { .callref = data->callref, }; - LOG_TRANS(trans, LOGL_DEBUG, "rx %s in paging state\n", get_mncc_name(msg->msg_type)); + LOG_TRANS(trans, LOGL_DEBUG, "still paging\n"); mncc_set_cause(&rel, GSM48_CAUSE_LOC_PRN_S_LU, GSM48_CC_CAUSE_NORM_CALL_CLEAR); if (msg->msg_type == MNCC_REL_REQ) @@ -1958,9 +2473,6 @@ int mncc_tx_to_gsm_cc(struct gsm_network *net, const union mncc_msg *msg) trans->callref = 0; trans_free(trans); return rc; - } else { - LOG_TRANS(trans, LOGL_DEBUG, "rx %s in state %s\n", - get_mncc_name(msg->msg_type), gsm48_cc_state_name(trans->cc.state)); } /* Find function for current state and message */ diff --git a/src/libmsc/gsm_04_11.c b/src/libmsc/gsm_04_11.c index a3b383068..aa87a192a 100644 --- a/src/libmsc/gsm_04_11.c +++ b/src/libmsc/gsm_04_11.c @@ -58,7 +58,7 @@ #include <osmocom/msc/paging.h> #ifdef BUILD_SMPP -#include "smpp_smsc.h" +#include <osmocom/smpp/smpp_smsc.h> #endif void *tall_gsms_ctx; @@ -129,6 +129,28 @@ static int gsm411_sendmsg(struct gsm_trans *trans, struct msgb *msg) return msc_a_tx_dtap_to_i(trans->msc_a, msg); } +/* Handle MMTS (More Messages to Send) indication */ +static void gsm411_handle_mmts_ind(const struct gsm_trans *trans) +{ + int32_t use_count; + + OSMO_ASSERT(trans); + OSMO_ASSERT(trans->msc_a); + + use_count = osmo_use_count_by(&trans->msc_a->use_count, MSC_A_USE_SMS_MMTS); + OSMO_ASSERT(use_count >= 0); /* Shall not be negative */ + + if (trans->sms.sm_rp_mmts_ind && use_count == 0) { + LOG_TRANS(trans, LOGL_INFO, "Multi-part SMS delivery is initiated\n"); + msc_a_get(trans->msc_a, MSC_A_USE_SMS_MMTS); + } else if (trans->sms.sm_rp_mmts_ind && use_count > 0) { + LOG_TRANS(trans, LOGL_INFO, "Continuing multi-part SMS delivery\n"); + } else if (!trans->sms.sm_rp_mmts_ind && use_count > 0) { + LOG_TRANS(trans, LOGL_INFO, "Multi-part SMS delivery has been completed\n"); + msc_a_put(trans->msc_a, MSC_A_USE_SMS_MMTS); + } +} + /* Paging callback for MT SMS (Paging is triggered by SMC) */ static void mmsms_paging_cb(struct msc_a *msc_a, struct gsm_trans *trans) { @@ -141,6 +163,10 @@ static void mmsms_paging_cb(struct msc_a *msc_a, struct gsm_trans *trans) /* Associate transaction with established connection */ msc_a_get(msc_a, MSC_A_USE_SMS); trans->msc_a = msc_a; + + /* Multi-part SMS: handle MMTS (More Messages to Send) indication */ + gsm411_handle_mmts_ind(trans); + /* Confirm successful connection establishment */ gsm411_smc_recv(&trans->sms.smc_inst, GSM411_MMSMS_EST_CNF, NULL, 0); } else { @@ -406,7 +432,7 @@ static int sms_route_mt_sms(struct gsm_trans *trans, struct gsm_sms *gsms) LOG_TRANS(trans, LOGL_ERROR, "SMS delivery error: %d\n", rc); rc = GSM411_RP_CAUSE_MO_TEMP_FAIL; /* rc will be logged by gsm411_send_rp_error() */ - rate_ctr_inc(&net->msc_ctrs->ctr[MSC_CTR_SMS_DELIVER_UNKNOWN_ERROR]); + rate_ctr_inc(rate_ctr_group_get_ctr(net->msc_ctrs, MSC_CTR_SMS_DELIVER_UNKNOWN_ERROR)); } return rc; } @@ -416,29 +442,29 @@ try_local: /* determine gsms->receiver based on dialled number */ gsms->receiver = vlr_subscr_find_by_msisdn(net->vlr, gsms->dst.addr, VSUB_USE_SMS_RECEIVER); - if (!gsms->receiver) { + if (gsms->receiver) + return 0; + #ifdef BUILD_SMPP - /* Avoid a second look-up */ - if (smpp_route_smpp_first()) { - rate_ctr_inc(&net->msc_ctrs->ctr[MSC_CTR_SMS_NO_RECEIVER]); - return GSM411_RP_CAUSE_MO_NUM_UNASSIGNED; - } + /* Avoid a second look-up */ + if (smpp_route_smpp_first()) { + rate_ctr_inc(rate_ctr_group_get_ctr(net->msc_ctrs, MSC_CTR_SMS_NO_RECEIVER)); + return GSM411_RP_CAUSE_MO_NUM_UNASSIGNED; + } - rc = smpp_try_deliver(gsms, msc_a); - if (rc == GSM411_RP_CAUSE_MO_NUM_UNASSIGNED) { - rate_ctr_inc(&net->msc_ctrs->ctr[MSC_CTR_SMS_NO_RECEIVER]); - } else if (rc < 0) { - LOG_TRANS(trans, LOGL_ERROR, "SMS delivery error: %d\n", rc); - rc = GSM411_RP_CAUSE_MO_TEMP_FAIL; - /* rc will be logged by gsm411_send_rp_error() */ - rate_ctr_inc(&net->msc_ctrs->ctr[MSC_CTR_SMS_DELIVER_UNKNOWN_ERROR]); - } + rc = smpp_try_deliver(gsms, msc_a); + if (rc == GSM411_RP_CAUSE_MO_NUM_UNASSIGNED) { + rate_ctr_inc(rate_ctr_group_get_ctr(net->msc_ctrs, MSC_CTR_SMS_NO_RECEIVER)); + } else if (rc < 0) { + LOG_TRANS(trans, LOGL_ERROR, "SMS delivery error: %d\n", rc); + rc = GSM411_RP_CAUSE_MO_TEMP_FAIL; + /* rc will be logged by gsm411_send_rp_error() */ + rate_ctr_inc(rate_ctr_group_get_ctr(net->msc_ctrs, MSC_CTR_SMS_DELIVER_UNKNOWN_ERROR)); + } #else - rc = GSM411_RP_CAUSE_MO_NUM_UNASSIGNED; - rate_ctr_inc(&net->msc_ctrs->ctr[MSC_CTR_SMS_NO_RECEIVER]); + rc = GSM411_RP_CAUSE_MO_NUM_UNASSIGNED; + rate_ctr_inc(rate_ctr_group_get_ctr(net->msc_ctrs, MSC_CTR_SMS_NO_RECEIVER)); #endif - } else - rc = 0; return rc; } @@ -475,7 +501,7 @@ static int gsm340_rx_tpdu(struct gsm_trans *trans, struct msgb *msg, } /* FIXME: should we do this on success, after all checks? */ - rate_ctr_inc(&net->msc_ctrs->ctr[MSC_CTR_SMS_SUBMITTED]); + rate_ctr_inc(rate_ctr_group_get_ctr(net->msc_ctrs, MSC_CTR_SMS_SUBMITTED)); gsms = sms_alloc(); if (!gsms) @@ -600,9 +626,30 @@ static int gsm340_rx_tpdu(struct gsm_trans *trans, struct msgb *msg, osmo_hexdump(gsms->user_data, gsms->user_data_len)); gsms->validity_minutes = gsm340_validity_period(sms_vpf, sms_vp); + if (gsms->validity_minutes < net->sms_queue_cfg->minimum_validity_mins) { + LOG_TRANS(trans, LOGL_INFO, "Overriding user-provided validity period (%lu) " + "with minimum SMSC validity period (%u) minutes\n", gsms->validity_minutes, + net->sms_queue_cfg->minimum_validity_mins); + gsms->validity_minutes = net->sms_queue_cfg->minimum_validity_mins; + } rc = sms_route_mt_sms(trans, gsms); + /* This SMS got routed through SMPP and we are waiting on the response. */ + if (gsms->smpp.esme) { + rc = -EINPROGRESS; + goto out; + } + + /* This SMS got routed through SMPP, but the configured ESME was + * unavailable at this time. This is an OOO condition. + * Don't store this SMS in the database as we may never be + * able to deliver it. (we would need to process the stored SMS and + * attempt re-submission to the ESME) + */ + if (rc == GSM411_RP_CAUSE_MO_NET_OUT_OF_ORDER) + goto out; /* free() the message */ + /* * This SMS got routed through SMPP or no receiver exists. * In any case, we store it in the database for further processing. @@ -691,8 +738,10 @@ static int gsm411_rx_rp_ud(struct msgb *msg, struct gsm_trans *trans, return gsm411_send_rp_ack(trans, rph->msg_ref); else if (rc > 0) return gsm411_send_rp_error(trans, rph->msg_ref, rc); - else - return rc; + else if (rc == -EINPROGRESS) + rc = 0; + + return rc; } /* Receive a 04.11 RP-DATA message in accordance with Section 7.3.1.2 */ @@ -861,10 +910,10 @@ static int gsm411_rx_rp_error(struct gsm_trans *trans, * to store this in our database and wait for a SMMA message */ /* FIXME */ send_signal(S_SMS_MEM_EXCEEDED, trans, sms, 0); - rate_ctr_inc(&net->msc_ctrs->ctr[MSC_CTR_SMS_RP_ERR_MEM]); + rate_ctr_inc(rate_ctr_group_get_ctr(net->msc_ctrs, MSC_CTR_SMS_RP_ERR_MEM)); } else { send_signal(S_SMS_UNKNOWN_ERROR, trans, sms, 0); - rate_ctr_inc(&net->msc_ctrs->ctr[MSC_CTR_SMS_RP_ERR_OTHER]); + rate_ctr_inc(rate_ctr_group_get_ctr(net->msc_ctrs, MSC_CTR_SMS_RP_ERR_OTHER)); } sms_free(sms); @@ -1071,13 +1120,13 @@ static struct gsm_trans *gsm411_alloc_mt_trans(struct gsm_network *net, struct vlr_subscr *vsub) { struct msc_a *msc_a; - struct gsm_trans *trans = NULL; + struct gsm_trans *trans; int tid; /* Generate a new transaction ID */ tid = trans_assign_trans_id(net, vsub, TRANS_SMS); if (tid == -1) { - LOG_TRANS(trans, LOGL_ERROR, "No available transaction IDs\n"); + LOGP(DLSMS, LOGL_ERROR, "No available transaction IDs\n"); return NULL; } @@ -1169,7 +1218,7 @@ int gsm411_send_sms(struct gsm_network *net, /* Store a pointer to abstract SMS representation */ trans->sms.sms = sms; - rate_ctr_inc(&net->msc_ctrs->ctr[MSC_CTR_SMS_DELIVERED]); + rate_ctr_inc(rate_ctr_group_get_ctr(net->msc_ctrs, MSC_CTR_SMS_DELIVERED)); db_sms_inc_deliver_attempts(trans->sms.sms); return gsm411_rp_sendmsg(&trans->sms.smr_inst, msg, @@ -1180,7 +1229,9 @@ int gsm411_send_sms(struct gsm_network *net, /* Low-level function to send raw RP-DATA to a given subscriber */ int gsm411_send_rp_data(struct gsm_network *net, struct vlr_subscr *vsub, size_t sm_rp_oa_len, const uint8_t *sm_rp_oa, - size_t sm_rp_ud_len, const uint8_t *sm_rp_ud) + size_t sm_rp_ud_len, const uint8_t *sm_rp_ud, + bool sm_rp_mmts_ind, const uint8_t *gsup_source_name, + size_t gsup_source_name_len) { struct gsm_trans *trans; struct msgb *msg; @@ -1190,6 +1241,22 @@ int gsm411_send_rp_data(struct gsm_network *net, struct vlr_subscr *vsub, if (!trans) return -ENOMEM; + /* Multi-part SMS: handle MMTS (More Messages to Send) indication */ + trans->sms.sm_rp_mmts_ind = sm_rp_mmts_ind; + if (trans->msc_a != NULL) + gsm411_handle_mmts_ind(trans); + + /* Save GSUP source_name for subsequent response messages */ + if (gsup_source_name && gsup_source_name_len) { + trans->sms.gsup_source_name = talloc_memdup(trans, gsup_source_name, + gsup_source_name_len); + if (!trans->sms.gsup_source_name) { + trans_free(trans); + return -ENOMEM; + } + trans->sms.gsup_source_name_len = gsup_source_name_len; + } + /* Allocate a message buffer for to be encoded SMS */ msg = gsm411_msgb_alloc(); if (!msg) { @@ -1206,7 +1273,7 @@ int gsm411_send_rp_data(struct gsm_network *net, struct vlr_subscr *vsub, /* Encode RP-UD itself (SM TPDU) */ msgb_lv_put(msg, sm_rp_ud_len, sm_rp_ud); - rate_ctr_inc(&net->msc_ctrs->ctr[MSC_CTR_SMS_DELIVERED]); + rate_ctr_inc(rate_ctr_group_get_ctr(net->msc_ctrs, MSC_CTR_SMS_DELIVERED)); return gsm411_rp_sendmsg(&trans->sms.smr_inst, msg, GSM411_MT_RP_DATA_MT, trans->sms.sm_rp_mr, @@ -1334,4 +1401,3 @@ void gsm411_sapi_n_reject(struct msc_a *msc_a) trans_free(trans); } } - diff --git a/src/libmsc/gsm_04_11_gsup.c b/src/libmsc/gsm_04_11_gsup.c index 9f5175b3a..1afdfabbc 100644 --- a/src/libmsc/gsm_04_11_gsup.c +++ b/src/libmsc/gsm_04_11_gsup.c @@ -1,5 +1,5 @@ /* - * (C) 2018 by Vadim Yanitskiy <axilirator@gmail.com> + * (C) 2018-2019 by Vadim Yanitskiy <axilirator@gmail.com> * * All Rights Reserved * @@ -33,6 +33,7 @@ #include <osmocom/msc/vlr.h> #include <osmocom/msc/msub.h> #include <osmocom/msc/gsup_client_mux.h> +#include <osmocom/msc/msc_a.h> /* Common helper for preparing to be encoded GSUP message */ static void gsup_sm_msg_init(struct osmo_gsup_message *gsup_msg, @@ -53,7 +54,7 @@ static void gsup_sm_msg_init(struct osmo_gsup_message *gsup_msg, int gsm411_gsup_mo_fwd_sm_req(struct gsm_trans *trans, struct msgb *msg, uint8_t sm_rp_mr, uint8_t *sm_rp_da, uint8_t sm_rp_da_len) { - uint8_t bcd_buf[GSM48_MI_SIZE] = { 0 }; + uint8_t bcd_buf[GSM48_MI_SIZE]; struct osmo_gsup_message gsup_msg; size_t bcd_len; @@ -65,22 +66,28 @@ int gsm411_gsup_mo_fwd_sm_req(struct gsm_trans *trans, struct msgb *msg, /* Assign SM-RP-MR to transaction state */ trans->sms.sm_rp_mr = sm_rp_mr; - /* Encode subscriber's MSISDN */ + /* Encode subscriber's MSISDN as LHV (with room for ToN/NPI header) */ bcd_len = gsm48_encode_bcd_number(bcd_buf, sizeof(bcd_buf), - 0, trans->vsub->msisdn); + 1, trans->vsub->msisdn); if (bcd_len <= 0 || bcd_len > sizeof(bcd_buf)) { LOG_TRANS(trans, LOGL_ERROR, "Failed to encode subscriber's MSISDN\n"); return -EINVAL; } + /* NOTE: assuming default ToN/NPI values as we don't have this info */ + bcd_buf[1] = 0x01 /* NPI: ISDN/Telephony Numbering (ITU-T Rec. E.164 / ITU-T Rec. E.163) */ + | (0x01 << 4) /* ToN: International Number */ + | (0x01 << 7); /* No Extension */ + /* Initialize a new GSUP message */ gsup_sm_msg_init(&gsup_msg, OSMO_GSUP_MSGT_MO_FORWARD_SM_REQUEST, trans->vsub->imsi, &sm_rp_mr); - /* According to 12.2.3, the MSISDN from VLR is inserted here */ + /* According to 12.2.3, the MSISDN from VLR is inserted here. + * NOTE: redundant BCD length octet is not included. */ gsup_msg.sm_rp_oa_type = OSMO_GSUP_SMS_SM_RP_ODA_MSISDN; - gsup_msg.sm_rp_oa_len = bcd_len; - gsup_msg.sm_rp_oa = bcd_buf; + gsup_msg.sm_rp_oa_len = bcd_len - 1; + gsup_msg.sm_rp_oa = bcd_buf + 1; /* SM-RP-DA should (already) contain SMSC address */ gsup_msg.sm_rp_da_type = OSMO_GSUP_SMS_SM_RP_ODA_SMSC_ADDR; @@ -91,6 +98,7 @@ int gsm411_gsup_mo_fwd_sm_req(struct gsm_trans *trans, struct msgb *msg, gsup_msg.sm_rp_ui_len = msgb_l4len(msg); gsup_msg.sm_rp_ui = (uint8_t *) msgb_sms(msg); + gsup_client_mux_tx_set_source(trans->net->gcm, &gsup_msg); return gsup_client_mux_tx(trans->net->gcm, &gsup_msg); } @@ -113,23 +121,18 @@ int gsm411_gsup_mo_ready_for_sm_req(struct gsm_trans *trans, uint8_t sm_rp_mr) /* Indicate SMMA as the Alert Reason */ gsup_msg.sm_alert_rsn = OSMO_GSUP_SMS_SM_ALERT_RSN_MEM_AVAIL; + gsup_client_mux_tx_set_source(trans->net->gcm, &gsup_msg); return gsup_client_mux_tx(trans->net->gcm, &gsup_msg); } /* Triggers either RP-ACK or RP-ERROR on response from SMSC */ -static int gsm411_gsup_mo_handler(struct vlr_subscr *vsub, - const struct osmo_gsup_message *gsup_msg) +static int gsm411_gsup_mo_handler(struct gsm_network *net, struct vlr_subscr *vsub, + const struct osmo_gsup_message *gsup_msg) { - struct vlr_instance *vlr; - struct gsm_network *net; struct gsm_trans *trans; const char *msg_name; bool msg_is_err; - /* Obtain required pointers */ - vlr = vsub->vlr; - net = (struct gsm_network *) vlr->user_ctx; - /* Associate logging messages with this subscriber */ log_set_context(LOG_CTX_VLR_SUBSCR, vsub); @@ -149,14 +152,6 @@ static int gsm411_gsup_mo_handler(struct vlr_subscr *vsub, OSMO_ASSERT(0); } - /* Make sure that 'SMS over GSUP' is expected */ - if (!net->sms_over_gsup) { - /* TODO: notify sender about that? */ - LOGP(DLSMS, LOGL_NOTICE, "Unexpected MO SMS over GSUP, " - "ignoring message...\n"); - return -EIO; - } - /* Verify GSUP message */ if (!gsup_msg->sm_rp_mr) goto msg_error; @@ -169,7 +164,8 @@ static int gsm411_gsup_mo_handler(struct vlr_subscr *vsub, LOGP(DLSMS, LOGL_NOTICE, "No transaction found for %s, " "ignoring %s-%s message...\n", vlr_subscr_name(vsub), msg_name, msg_is_err ? "Err" : "Res"); - return -EIO; /* TODO: notify sender about that? */ + gsup_client_mux_tx_error_reply(net->gcm, gsup_msg, GMM_CAUSE_NO_PDP_ACTIVATED); + return -EIO; } LOG_TRANS(trans, LOGL_DEBUG, "RX %s-%s\n", msg_name, msg_is_err ? "Err" : "Res"); @@ -186,9 +182,8 @@ static int gsm411_gsup_mo_handler(struct vlr_subscr *vsub, return 0; msg_error: - /* TODO: notify sender about that? */ - LOGP(DLSMS, LOGL_NOTICE, "RX malformed %s-%s\n", - msg_name, msg_is_err ? "Err" : "Res"); + LOGP(DLSMS, LOGL_NOTICE, "RX malformed %s-%s\n", msg_name, msg_is_err ? "Err" : "Res"); + gsup_client_mux_tx_error_reply(net->gcm, gsup_msg, GMM_CAUSE_INV_MAND_INFO); return -EINVAL; } @@ -205,6 +200,11 @@ int gsm411_gsup_mt_fwd_sm_res(struct gsm_trans *trans, uint8_t sm_rp_mr) gsup_sm_msg_init(&gsup_msg, OSMO_GSUP_MSGT_MT_FORWARD_SM_RESULT, trans->vsub->imsi, &sm_rp_mr); + /* Ensure routing through OsmoHLR to the MT-sending SMSC */ + gsup_msg.destination_name = trans->sms.gsup_source_name; + gsup_msg.destination_name_len = trans->sms.gsup_source_name_len; + gsup_client_mux_tx_set_source(trans->net->gcm, &gsup_msg); + return gsup_client_mux_tx(trans->net->gcm, &gsup_msg); } @@ -222,6 +222,11 @@ int gsm411_gsup_mt_fwd_sm_err(struct gsm_trans *trans, gsup_sm_msg_init(&gsup_msg, OSMO_GSUP_MSGT_MT_FORWARD_SM_ERROR, trans->vsub->imsi, &sm_rp_mr); + /* Ensure routing through OsmoHLR to the MT-sending SMSC */ + gsup_msg.destination_name = trans->sms.gsup_source_name; + gsup_msg.destination_name_len = trans->sms.gsup_source_name_len; + gsup_client_mux_tx_set_source(trans->net->gcm, &gsup_msg); + /* SM-RP-Cause value */ gsup_msg.sm_rp_cause = &cause; @@ -230,28 +235,17 @@ int gsm411_gsup_mt_fwd_sm_err(struct gsm_trans *trans, } /* Handles MT SMS (and triggers Paging Request if required) */ -static int gsm411_gsup_mt_handler(struct vlr_subscr *vsub, - const struct osmo_gsup_message *gsup_msg) +static int gsm411_gsup_mt_handler(struct gsm_network *net, struct vlr_subscr *vsub, + const struct osmo_gsup_message *gsup_msg) { - struct gsm_network *net; + bool sm_rp_mmts_ind; int rc; - /* Obtain required pointers */ - net = (struct gsm_network *) vsub->vlr->user_ctx; - /* Associate logging messages with this subscriber */ log_set_context(LOG_CTX_VLR_SUBSCR, vsub); LOGP(DLSMS, LOGL_DEBUG, "RX MT-forwardSM-Req\n"); - /* Make sure that 'SMS over GSUP' is expected */ - if (!net->sms_over_gsup) { - LOGP(DLSMS, LOGL_NOTICE, "Unexpected MT SMS over GSUP, " - "ignoring message...\n"); - /* TODO: notify sender about that? */ - return -EIO; - } - /** * Verify GSUP message * @@ -267,31 +261,51 @@ static int gsm411_gsup_mt_handler(struct vlr_subscr *vsub, if (gsup_msg->sm_rp_oa_type != OSMO_GSUP_SMS_SM_RP_ODA_SMSC_ADDR) goto msg_error; + /* MMS (More Messages to Send) IE is optional */ + if (gsup_msg->sm_rp_mms) + sm_rp_mmts_ind = *gsup_msg->sm_rp_mms > 0; + else + sm_rp_mmts_ind = false; + /* Send RP-DATA */ rc = gsm411_send_rp_data(net, vsub, gsup_msg->sm_rp_oa_len, gsup_msg->sm_rp_oa, - gsup_msg->sm_rp_ui_len, gsup_msg->sm_rp_ui); + gsup_msg->sm_rp_ui_len, gsup_msg->sm_rp_ui, + sm_rp_mmts_ind, gsup_msg->source_name, + gsup_msg->source_name_len); if (rc) { LOGP(DLSMS, LOGL_NOTICE, "Failed to send MT SMS, " "ignoring MT-forwardSM-Req message...\n"); - /* TODO: notify sender about that? */ + gsup_client_mux_tx_error_reply(net->gcm, gsup_msg, GMM_CAUSE_NET_FAIL); return rc; } return 0; msg_error: - /* TODO: notify sender about that? */ LOGP(DLSMS, LOGL_NOTICE, "RX malformed MT-forwardSM-Req\n"); + gsup_client_mux_tx_error_reply(net->gcm, gsup_msg, GMM_CAUSE_INV_MAND_INFO); return -EINVAL; } int gsm411_gsup_rx(struct gsup_client_mux *gcm, void *data, const struct osmo_gsup_message *gsup_msg) { - struct vlr_instance *vlr = data; - struct vlr_subscr *vsub = vlr_subscr_find_by_imsi(vlr, gsup_msg->imsi, __func__); + struct gsm_network *net = (struct gsm_network *) data; + struct vlr_subscr *vsub; + int rc; + /* Make sure that 'SMS over GSUP' is expected */ + if (!net->sms_over_gsup) { + LOGP(DLSMS, LOGL_NOTICE, "Unexpected MO/MT SMS over GSUP " + "(sms-over-gsup is not enabled), ignoring message...\n"); + gsup_client_mux_tx_error_reply(gcm, gsup_msg, GMM_CAUSE_GPRS_NOTALLOWED); + return -EIO; + } + + vsub = vlr_subscr_find_by_imsi(net->vlr, gsup_msg->imsi, __func__); if (!vsub) { + LOGP(DLSMS, LOGL_ERROR, "Rx %s for unknown subscriber, rejecting\n", + osmo_gsup_message_type_name(gsup_msg->message_type)); gsup_client_mux_tx_error_reply(gcm, gsup_msg, GMM_CAUSE_IMSI_UNKNOWN); return -GMM_CAUSE_IMSI_UNKNOWN; } @@ -303,16 +317,22 @@ int gsm411_gsup_rx(struct gsup_client_mux *gcm, void *data, const struct osmo_gs case OSMO_GSUP_MSGT_READY_FOR_SM_ERROR: case OSMO_GSUP_MSGT_READY_FOR_SM_RESULT: DEBUGP(DMSC, "Routed to GSM 04.11 MO handler\n"); - return gsm411_gsup_mo_handler(vsub, gsup_msg); + rc = gsm411_gsup_mo_handler(net, vsub, gsup_msg); + break; /* GSM 04.11 code implementing MT SMS */ case OSMO_GSUP_MSGT_MT_FORWARD_SM_REQUEST: DEBUGP(DMSC, "Routed to GSM 04.11 MT handler\n"); - return gsm411_gsup_mt_handler(vsub, gsup_msg); + rc = gsm411_gsup_mt_handler(net, vsub, gsup_msg); + break; default: LOGP(DMM, LOGL_ERROR, "No handler found for %s, dropping message...\n", osmo_gsup_message_type_name(gsup_msg->message_type)); - return -GMM_CAUSE_MSGT_NOTEXIST_NOTIMPL; + gsup_client_mux_tx_error_reply(gcm, gsup_msg, GMM_CAUSE_MSGT_NOTEXIST_NOTIMPL); + rc = -GMM_CAUSE_MSGT_NOTEXIST_NOTIMPL; } + + vlr_subscr_put(vsub, __func__); + return rc; } diff --git a/src/libmsc/gsm_04_14.c b/src/libmsc/gsm_04_14.c index 811655813..03c06fde9 100644 --- a/src/libmsc/gsm_04_14.c +++ b/src/libmsc/gsm_04_14.c @@ -43,7 +43,7 @@ static struct msgb *create_gsm0414_msg(uint8_t msg_type) struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.14"); struct gsm48_hdr *gh; - gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh) + 1); + gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); gh->proto_discr = GSM48_PDISC_TEST; gh->msg_type = msg_type; return msg; diff --git a/src/libmsc/gsm_09_11.c b/src/libmsc/gsm_09_11.c index 6558272a8..e29389015 100644 --- a/src/libmsc/gsm_09_11.c +++ b/src/libmsc/gsm_09_11.c @@ -32,6 +32,7 @@ #include <osmocom/core/linuxlist.h> #include <osmocom/core/rate_ctr.h> +#include <osmocom/core/stat_item.h> #include <osmocom/core/utils.h> #include <osmocom/core/msgb.h> @@ -57,7 +58,7 @@ static uint32_t new_callref = 0x20000001; static void ncss_session_timeout_handler(void *_trans) { struct gsm_trans *trans = (struct gsm_trans *) _trans; - struct osmo_gsup_message gsup_msg = { 0 }; + struct osmo_gsup_message gsup_msg; /* The timeout might be disabled from the VTY */ if (trans->net->ncss_guard_timeout == 0) @@ -124,7 +125,7 @@ int gsm0911_rcv_nc_ss(struct msc_a *msc_a, struct msgb *msg) trans = trans_find_by_id(msc_a, TRANS_USSD, tid); if (!trans) { /* Count MS-initiated attempts to establish a NC SS/USSD session */ - rate_ctr_inc(&net->msc_ctrs->ctr[MSC_CTR_NC_SS_MO_REQUESTS]); + rate_ctr_inc(rate_ctr_group_get_ctr(net->msc_ctrs, MSC_CTR_NC_SS_MO_REQUESTS)); /** * According to GSM TS 04.80, section 2.4.2 "Register @@ -135,8 +136,9 @@ int gsm0911_rcv_nc_ss(struct msc_a *msc_a, struct msgb *msg) * a supplementary service. */ if (msg_type != GSM0480_MTYPE_REGISTER) { - LOG_TRANS(trans, LOGL_ERROR, "Rx wrong SS/USSD message type for new transaction: %s\n", - gsm48_pdisc_msgtype_name(GSM48_PDISC_NC_SS, msg_type)); + LOGP(DSS, LOGL_ERROR, "Rx %s message for non-existing transaction (tid-%u)\n", + gsm48_pdisc_msgtype_name(GSM48_PDISC_NC_SS, msg_type), + gsm48_hdr_trans_id(gh)); gsm48_tx_simple(msc_a, GSM48_PDISC_NC_SS | (tid << 4), GSM0480_MTYPE_RELEASE_COMPLETE); @@ -145,7 +147,7 @@ int gsm0911_rcv_nc_ss(struct msc_a *msc_a, struct msgb *msg) trans = trans_alloc(net, vsub, TRANS_USSD, tid, new_callref++); if (!trans) { - LOG_TRANS(trans, LOGL_ERROR, " -> No memory for trans\n"); + LOGP(DSS, LOGL_ERROR, " -> No memory for trans\n"); gsm48_tx_simple(msc_a, GSM48_PDISC_NC_SS | (tid << 4), GSM0480_MTYPE_RELEASE_COMPLETE); @@ -157,7 +159,7 @@ int gsm0911_rcv_nc_ss(struct msc_a *msc_a, struct msgb *msg) ncss_session_timeout_handler, trans); /* Count active NC SS/USSD sessions */ - osmo_counter_inc(net->active_nc_ss); + osmo_stat_item_inc(osmo_stat_item_group_get_item(net->statg, MSC_STAT_ACTIVE_NC_SS), 1); trans->dlci = OMSC_LINKID_CB(msg); trans->msc_a = msc_a; @@ -239,9 +241,9 @@ int gsm0911_rcv_nc_ss(struct msc_a *msc_a, struct msgb *msg) /* Count established MS-initiated NC SS/USSD sessions */ if (msg_type == GSM0480_MTYPE_REGISTER) - rate_ctr_inc(&net->msc_ctrs->ctr[MSC_CTR_NC_SS_MO_ESTABLISHED]); + rate_ctr_inc(rate_ctr_group_get_ctr(net->msc_ctrs, MSC_CTR_NC_SS_MO_ESTABLISHED)); - return 0; + return rc; error: /* Abort transaction on DTAP-interface */ @@ -263,7 +265,7 @@ static void ss_paging_cb(struct msc_a *msc_a, struct gsm_trans *trans) if (trans->msc_a) { LOG_MSC_A_CAT(msc_a, DPAG, LOGL_ERROR, - "Handle paging error: transaction already associated with subsciber," + "Handle paging error: transaction already associated with subscriber," " apparently it was already handled. Skip.\n"); return; } @@ -295,11 +297,27 @@ static void ss_paging_cb(struct msc_a *msc_a, struct gsm_trans *trans) trans->ss.msg = NULL; /* Count established network-initiated NC SS/USSD sessions */ - rate_ctr_inc(&net->msc_ctrs->ctr[MSC_CTR_NC_SS_MT_ESTABLISHED]); + rate_ctr_inc(rate_ctr_group_get_ctr(net->msc_ctrs, MSC_CTR_NC_SS_MT_ESTABLISHED)); } else { + struct osmo_gsup_message gsup_msg; + LOG_MSC_A_CAT(msc_a, DSS, LOGL_DEBUG, "Paging expired\n"); - /* TODO: inform HLR about this failure */ + gsup_msg = (struct osmo_gsup_message){ + .message_class = OSMO_GSUP_MESSAGE_CLASS_USSD, + .message_type = OSMO_GSUP_MSGT_PROC_SS_ERROR, + + .session_state = OSMO_GSUP_SESSION_STATE_END, + .session_id = trans->callref, + /* FIXME: we need message class specific cause values */ + .cause = GMM_CAUSE_IMPL_DETACHED, + }; + + /* Fill in subscriber's IMSI */ + OSMO_STRLCPY_ARRAY(gsup_msg.imsi, trans->vsub->imsi); + + /* Inform HLR/EUSE about the failure */ + gsup_client_mux_tx(trans->net->gcm, &gsup_msg); msgb_free(trans->ss.msg); trans->ss.msg = NULL; @@ -314,55 +332,38 @@ static struct gsm_trans *establish_nc_ss_trans(struct gsm_network *net, struct vlr_subscr *vsub, const struct osmo_gsup_message *gsup_msg) { struct msc_a *msc_a; - struct gsm_trans *trans, *transt; + struct gsm_trans *trans; int tid; - /* Allocate transaction first, for log context */ - trans = trans_alloc(net, vsub, TRANS_USSD, - TRANS_ID_UNASSIGNED, gsup_msg->session_id); - - if (!trans) { - LOG_TRANS(trans, LOGL_ERROR, " -> No memory for trans\n"); - return NULL; - } - if (gsup_msg->session_state != OSMO_GSUP_SESSION_STATE_BEGIN) { - LOG_TRANS(trans, LOGL_ERROR, "Received non-BEGIN message " - "for non-existing transaction\n"); - trans_free(trans); + LOGP(DSS, LOGL_ERROR, "Received non-BEGIN message for non-existing transaction\n"); return NULL; } + LOGP(DSS, LOGL_DEBUG, "(%s) Establishing a network-originated session (id=0x%x)\n", + vlr_subscr_name(vsub), gsup_msg->session_id); + if (!gsup_msg->ss_info || gsup_msg->ss_info_len < 2) { - LOG_TRANS(trans, LOGL_ERROR, "Missing mandatory Facility IE\n"); - trans_free(trans); + LOGP(DSS, LOGL_ERROR, "Missing mandatory Facility IE\n"); return NULL; } - /* If subscriber is not "attached" */ - if (!vsub->cgi.lai.lac) { - LOG_TRANS(trans, LOGL_ERROR, "Network-originated session " - "rejected - subscriber is not attached\n"); - trans_free(trans); + /* Obtain an unused transaction ID */ + tid = trans_assign_trans_id(net, vsub, TRANS_USSD); + if (tid < 0) { + LOGP(DSS, LOGL_ERROR, "No free transaction ID\n"); return NULL; } - LOG_TRANS(trans, LOGL_DEBUG, "Establishing network-originated session\n"); - - /* Count active NC SS/USSD sessions */ - osmo_counter_inc(net->active_nc_ss); - - /* Assign transaction ID */ - tid = trans_assign_trans_id(trans->net, trans->vsub, TRANS_USSD); - if (tid < 0) { - LOG_TRANS(trans, LOGL_ERROR, "No free transaction ID\n"); - /* TODO: inform HLR about this */ - /* TODO: release connection with subscriber */ - trans->callref = 0; - trans_free(trans); + /* Allocate a new NCSS transaction */ + trans = trans_alloc(net, vsub, TRANS_USSD, tid, gsup_msg->session_id); + if (!trans) { + LOGP(DSS, LOGL_ERROR, " -> No memory for trans\n"); return NULL; } - trans->transaction_id = tid; + + /* Count active NC SS/USSD sessions */ + osmo_stat_item_inc(osmo_stat_item_group_get_item(net->statg, MSC_STAT_ACTIVE_NC_SS), 1); /* Init inactivity timer */ osmo_timer_setup(&trans->ss.timer_guard, @@ -380,20 +381,6 @@ static struct gsm_trans *establish_nc_ss_trans(struct gsm_network *net, LOG_TRANS(trans, LOGL_DEBUG, "Triggering Paging Request\n"); - /* Find transaction with this subscriber already paging */ - llist_for_each_entry(transt, &net->trans_list, entry) { - /* Transaction of our conn? */ - if (transt == trans || transt->vsub != vsub) - continue; - - LOG_TRANS(trans, LOGL_ERROR, "Paging already started, " - "rejecting message...\n"); - trans_free(trans); - /* FIXME: WTF IS THIS!? This is completely insane. Presence of a trans doesn't indicate Paging, and even - * if, why drop the current request??? */ - return NULL; - } - /* Trigger Paging Request */ trans->paging_request = paging_request_start(vsub, PAGING_CAUSE_SIGNALLING_HIGH_PRIO, ss_paging_cb, trans, "GSM 09.11 SS/USSD"); @@ -409,7 +396,7 @@ static struct gsm_trans *establish_nc_ss_trans(struct gsm_network *net, msgb_tlv_put(trans->ss.msg, GSM0480_IE_FACILITY, gsup_msg->ss_info_len, gsup_msg->ss_info); - return NULL; + return trans; } /* NC SS specific transaction release. @@ -428,21 +415,24 @@ void _gsm911_nc_ss_trans_free(struct gsm_trans *trans) osmo_timer_del(&trans->ss.timer_guard); /* One session less */ - osmo_counter_dec(trans->net->active_nc_ss); + osmo_stat_item_dec(osmo_stat_item_group_get_item(trans->net->statg, MSC_STAT_ACTIVE_NC_SS), + 1); } int gsm0911_gsup_rx(struct gsup_client_mux *gcm, void *data, const struct osmo_gsup_message *gsup_msg) { - struct vlr_instance *vlr = data; - struct gsm_network *net; + struct gsm_network *net = (struct gsm_network *) data; struct gsm_trans *trans; struct gsm48_hdr *gh; struct msgb *ss_msg; bool trans_end; struct msc_a *msc_a; - struct vlr_subscr *vsub = vlr_subscr_find_by_imsi(vlr, gsup_msg->imsi, __func__); + struct vlr_subscr *vsub; + vsub = vlr_subscr_find_by_imsi(net->vlr, gsup_msg->imsi, __func__); if (!vsub) { + LOGP(DSS, LOGL_ERROR, "Rx %s for unknown subscriber, rejecting\n", + osmo_gsup_message_type_name(gsup_msg->message_type)); gsup_client_mux_tx_error_reply(gcm, gsup_msg, GMM_CAUSE_IMSI_UNKNOWN); return -GMM_CAUSE_IMSI_UNKNOWN; } @@ -450,38 +440,64 @@ int gsm0911_gsup_rx(struct gsup_client_mux *gcm, void *data, const struct osmo_g /* Associate logging messages with this subscriber */ log_set_context(LOG_CTX_VLR_SUBSCR, vsub); - /* Obtain pointer to vlr_instance */ - vlr = vsub->vlr; - OSMO_ASSERT(vlr); - - /* Obtain pointer to gsm_network */ - net = (struct gsm_network *) vlr->user_ctx; - OSMO_ASSERT(net); + /* Attempt to find DTAP-transaction */ + trans = trans_find_by_callref(net, TRANS_USSD, gsup_msg->session_id); /* Handle errors */ if (OSMO_GSUP_IS_MSGT_ERROR(gsup_msg->message_type)) { - /* FIXME: handle this error somehow! */ + LOGP(DSS, LOGL_NOTICE, "Rx %s from HLR/EUSE (cause=0x%02x, sid=0x%x)\n", + osmo_gsup_message_type_name(gsup_msg->message_type), + gsup_msg->cause, gsup_msg->session_id); + + /* We don't need subscriber info anymore */ + vlr_subscr_put(vsub, __func__); + + if (!trans) { + LOGP(DSS, LOGL_ERROR, "No transaction found for " + "sid=0x%x, nothing to abort\n", gsup_msg->session_id); + return -ENODEV; + } + + LOG_TRANS(trans, LOGL_NOTICE, "Aborting the session: sending RELEASE COMPLETE\n"); + + /* Indicate connection release to subscriber (if active) */ + if (trans->msc_a != NULL) { + /* TODO: implement GSUP - GSM 04.80 cause mapping */ + msc_send_ussd_release_complete_cause(trans->msc_a, trans->transaction_id, + GSM48_CAUSE_LOC_PUN_S_LU, GSM48_CC_CAUSE_TEMP_FAILURE); + } + + /* Terminate transaction */ + trans_free(trans); + return 0; } - /* Attempt to find DTAP-transaction */ - trans = trans_find_by_callref(net, gsup_msg->session_id); if (!trans) { /* Count network-initiated attempts to establish a NC SS/USSD session */ - rate_ctr_inc(&net->msc_ctrs->ctr[MSC_CTR_NC_SS_MT_REQUESTS]); + rate_ctr_inc(rate_ctr_group_get_ctr(net->msc_ctrs, MSC_CTR_NC_SS_MT_REQUESTS)); /* Attempt to establish a new transaction */ trans = establish_nc_ss_trans(net, vsub, gsup_msg); if (!trans) { - /* FIXME: send ERROR back to the HLR */ + LOGP(DSS, LOGL_ERROR, "Failed to establish a network-originated " + "SS/USSD transaction, rejecting %s\n", + osmo_gsup_message_type_name(gsup_msg->message_type)); + gsup_client_mux_tx_error_reply(gcm, gsup_msg, GMM_CAUSE_NET_FAIL); + vlr_subscr_put(vsub, __func__); return -EINVAL; } /* Wait for Paging Response */ - if (trans->paging_request) + if (trans->paging_request) { + vlr_subscr_put(vsub, __func__); return 0; + } } + /* We don't need subscriber info anymore */ + vlr_subscr_put(vsub, __func__); + /* (Re)schedule the inactivity timer */ if (net->ncss_guard_timeout > 0) { osmo_timer_schedule(&trans->ss.timer_guard, @@ -518,7 +534,7 @@ int gsm0911_gsup_rx(struct gsup_client_mux *gcm, void *data, const struct osmo_g default: LOG_TRANS(trans, LOGL_ERROR, "Unexpected session state %d\n", gsup_msg->session_state); - /* FIXME: send ERROR back to the HLR */ + gsup_client_mux_tx_error_reply(gcm, gsup_msg, GMM_CAUSE_MSGT_INCOMP_P_STATE); msgb_free(ss_msg); return -EINVAL; } @@ -528,7 +544,7 @@ int gsm0911_gsup_rx(struct gsup_client_mux *gcm, void *data, const struct osmo_g if (!gsup_msg->ss_info || gsup_msg->ss_info_len < 2) { LOG_TRANS(trans, LOGL_ERROR, "Missing mandatory Facility IE " "for mapped 0x%02x message\n", gh->msg_type); - /* FIXME: send ERROR back to the HLR */ + gsup_client_mux_tx_error_reply(gcm, gsup_msg, GMM_CAUSE_INV_MAND_INFO); msgb_free(ss_msg); return -EINVAL; } @@ -551,6 +567,7 @@ int gsm0911_gsup_rx(struct gsup_client_mux *gcm, void *data, const struct osmo_g msc_a = trans->msc_a; if (!msc_a) { LOG_TRANS(trans, LOGL_ERROR, "Cannot send SS message, no local MSC-A role defined for subscriber\n"); + gsup_client_mux_tx_error_reply(gcm, gsup_msg, GMM_CAUSE_NET_FAIL); msgb_free(ss_msg); return -EINVAL; } @@ -562,7 +579,7 @@ int gsm0911_gsup_rx(struct gsup_client_mux *gcm, void *data, const struct osmo_g /* Count established network-initiated NC SS/USSD sessions */ if (gsup_msg->session_state == OSMO_GSUP_SESSION_STATE_BEGIN) - rate_ctr_inc(&net->msc_ctrs->ctr[MSC_CTR_NC_SS_MT_ESTABLISHED]); + rate_ctr_inc(rate_ctr_group_get_ctr(net->msc_ctrs, MSC_CTR_NC_SS_MT_ESTABLISHED)); return 0; } diff --git a/src/libmsc/gsup_client_mux.c b/src/libmsc/gsup_client_mux.c index 7ec1712e7..e27b6645d 100644 --- a/src/libmsc/gsup_client_mux.c +++ b/src/libmsc/gsup_client_mux.c @@ -1,25 +1,21 @@ /* Directing individual GSUP messages to their respective handlers. */ /* - * (C) 2019 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de> + * (C) 2019 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de> * All Rights Reserved * * Author: Neels Hofmeyr * - * SPDX-License-Identifier: GPL-2.0+ + * SPDX-License-Identifier: AGPL-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 2 of the License, or + * 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 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. + * GNU Affero General Public License for more details. */ #include <errno.h> @@ -140,6 +136,25 @@ int gsup_client_mux_tx(struct gsup_client_mux *gcm, const struct osmo_gsup_messa return osmo_gsup_client_send(gcm->gsup_client, msg); } +/* Set GSUP source_name to our local IPA name */ +void gsup_client_mux_tx_set_source(const struct gsup_client_mux *gcm, + struct osmo_gsup_message *gsup_msg) +{ + const char *local_msc_name; + + if (!gcm) + return; + if (!gcm->gsup_client) + return; + if (!gcm->gsup_client->ipa_dev) + return; + local_msc_name = gcm->gsup_client->ipa_dev->serno; + if (!local_msc_name) + return; + gsup_msg->source_name = (const uint8_t *) local_msc_name; + gsup_msg->source_name_len = strlen(local_msc_name) + 1; +} + /* Transmit GSUP error in response to original message */ void gsup_client_mux_tx_error_reply(struct gsup_client_mux *gcm, const struct osmo_gsup_message *gsup_orig, enum gsm48_gmm_cause cause) @@ -150,13 +165,26 @@ void gsup_client_mux_tx_error_reply(struct gsup_client_mux *gcm, const struct os if (!OSMO_GSUP_IS_MSGT_REQUEST(gsup_orig->message_type)) return; - OSMO_STRLCPY_ARRAY(gsup_reply.imsi, gsup_orig->imsi); - gsup_reply = (struct osmo_gsup_message){ .cause = cause, .message_type = OSMO_GSUP_TO_MSGT_ERROR(gsup_orig->message_type), + .message_class = gsup_orig->message_class, + .destination_name = gsup_orig->source_name, + .destination_name_len = gsup_orig->source_name_len, + + /* RP-Message-Reference is mandatory for SM Service */ + .sm_rp_mr = gsup_orig->sm_rp_mr, }; + OSMO_STRLCPY_ARRAY(gsup_reply.imsi, gsup_orig->imsi); + gsup_client_mux_tx_set_source(gcm, &gsup_reply); + + /* For SS/USSD, it's important to keep both session state and ID IEs */ + if (gsup_orig->session_state != OSMO_GSUP_SESSION_STATE_NONE) { + gsup_reply.session_state = OSMO_GSUP_SESSION_STATE_END; + gsup_reply.session_id = gsup_orig->session_id; + } + if (osmo_gsup_client_enc_send(gcm->gsup_client, &gsup_reply)) LOGP(DLGSUP, LOGL_ERROR, "Failed to send Error reply (imsi=%s)\n", osmo_quote_str(gsup_orig->imsi, -1)); diff --git a/src/libmsc/mncc.c b/src/libmsc/mncc.c index 8c95ecb14..026dae025 100644 --- a/src/libmsc/mncc.c +++ b/src/libmsc/mncc.c @@ -100,6 +100,7 @@ const char *get_mncc_name(int value) void mncc_set_cause(struct gsm_mncc *data, int loc, int val) { data->fields |= MNCC_F_CAUSE; + data->cause.coding = GSM48_CAUSE_CODING_GSM; data->cause.location = loc; data->cause.value = val; } @@ -109,8 +110,6 @@ void mncc_set_cause(struct gsm_mncc *data, int loc, int val) * MNCC validation code. Move to libosmocore once headers are merged ************************************************************************/ -#define MNCC_F_ALL 0x3fff - static int check_string_terminated(const char *str, unsigned int size) { int i; @@ -156,7 +155,7 @@ static int mncc_prim_check_sign(const struct gsm_mncc *mncc_prim) { int rc; - if (mncc_prim->fields & ~ MNCC_F_ALL) { + if (mncc_prim->fields & ~MNCC_F_ALL) { LOGP(DMNCC, LOGL_ERROR, "Unknown MNCC field mask 0x%x\n", mncc_prim->fields); return -EINVAL; } @@ -234,6 +233,34 @@ static int mncc_prim_check_sign(const struct gsm_mncc *mncc_prim) return 0; } +/* Make sure that the SDP section has a terminating \0. The MNCC message may end after that \0, and if SDP is omitted it + * must contain at least one \0 byte. */ +int mncc_check_sdp_termination(const char *label, const struct gsm_mncc *mncc, unsigned int len, const char *sdp) +{ + size_t sdp_offset; + size_t sdp_data_len; + size_t sdp_str_len; + + OSMO_ASSERT(((char*)mncc) < sdp); + + sdp_offset = sdp - (char*)mncc; + if (len < sdp_offset) + goto too_short; + + sdp_data_len = len - sdp_offset; + if (sdp_data_len < 1) + goto too_short; + + sdp_str_len = strnlen(sdp, sdp_data_len); + /* There must be a \0, so sdp_str_len must be at most sdp_data_len - 1 */ + if (sdp_str_len >= sdp_data_len) + goto too_short; + return 0; +too_short: + LOGP(DMNCC, LOGL_ERROR, "Short %s\n", label); + return -EINVAL; +} + int mncc_prim_check(const struct gsm_mncc *mncc_prim, unsigned int len) { if (len < sizeof(mncc_prim->msg_type)) { @@ -261,11 +288,7 @@ int mncc_prim_check(const struct gsm_mncc *mncc_prim, unsigned int len) case MNCC_RTP_FREE: case MNCC_RTP_CONNECT: case MNCC_RTP_CREATE: - if (len < sizeof(struct gsm_mncc_rtp)) { - LOGP(DMNCC, LOGL_ERROR, "Short MNCC RTP\n"); - return -EINVAL; - } - break; + return mncc_check_sdp_termination("MNCC RTP", mncc_prim, len, ((struct gsm_mncc_rtp*)mncc_prim)->sdp); case MNCC_LCHAN_MODIFY: case MNCC_FRAME_DROP: case MNCC_FRAME_RECV: @@ -278,10 +301,8 @@ int mncc_prim_check(const struct gsm_mncc *mncc_prim, unsigned int len) } break; default: - if (len < sizeof(struct gsm_mncc)) { - LOGP(DMNCC, LOGL_ERROR, "Short MNCC Signalling\n"); + if (mncc_check_sdp_termination("MNCC Signalling", mncc_prim, len, mncc_prim->sdp)) return -EINVAL; - } return mncc_prim_check_sign(mncc_prim); } return 0; diff --git a/src/libmsc/mncc_builtin.c b/src/libmsc/mncc_builtin.c index 575497654..647420155 100644 --- a/src/libmsc/mncc_builtin.c +++ b/src/libmsc/mncc_builtin.c @@ -15,10 +15,6 @@ * 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. - * */ @@ -89,10 +85,16 @@ static int mncc_setup_ind(struct gsm_call *call, goto out_reject; } - /* we currently only do speech */ - if (setup->bearer_cap.transfer != GSM_MNCC_BCAP_SPEECH) { + /* we currently only do speech and CSD */ + switch (setup->bearer_cap.transfer) { + case GSM_MNCC_BCAP_SPEECH: + case GSM_MNCC_BCAP_AUDIO: + case GSM_MNCC_BCAP_FAX_G3: + case GSM_MNCC_BCAP_UNR_DIG: + break; + default: LOGP(DMNCC, LOGL_NOTICE, "(call %x) We only support " - "voice calls\n", call->callref); + "voice calls and CSD\n", call->callref); mncc_set_cause(&mncc, GSM48_CAUSE_LOC_PRN_S_LU, GSM48_CC_CAUSE_BEARER_CA_UNAVAIL); goto out_reject; @@ -263,10 +265,6 @@ int int_mncc_recv(struct gsm_network *net, struct msgb *msg) struct gsm_call *call = NULL, *callt; int rc = 0; - /* Special messages */ - switch(msg_type) { - } - /* find callref */ callref = data->callref; llist_for_each_entry(callt, &call_list, entry) { @@ -307,7 +305,7 @@ int int_mncc_recv(struct gsm_network *net, struct msgb *msg) DEBUGP(DMNCC, "(call %x) Received message %s\n", call->callref, get_mncc_name(msg_type)); - switch(msg_type) { + switch (msg_type) { case MNCC_SETUP_IND: rc = mncc_setup_ind(call, arg); break; @@ -374,7 +372,8 @@ int int_mncc_recv(struct gsm_network *net, struct msgb *msg) rc = mncc_tx_to_cc(net, data); break; default: - LOGP(DMNCC, LOGL_NOTICE, "(call %x) Message unhandled\n", callref); + LOGP(DMNCC, LOGL_NOTICE, "(call %x) Message '%s' unhandled\n", + callref, get_mncc_name(msg_type)); break; } diff --git a/src/libmsc/mncc_call.c b/src/libmsc/mncc_call.c index 5ca91d022..557f2d749 100644 --- a/src/libmsc/mncc_call.c +++ b/src/libmsc/mncc_call.c @@ -2,7 +2,7 @@ /* At the time of writing, this is only used for inter-MSC handover: forward a voice stream to a remote MSC. * Maybe it makes sense to also use it for all "normal" external call management at some point. */ /* - * (C) 2019 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de> + * (C) 2019 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de> * All Rights Reserved * * SPDX-License-Identifier: AGPL-3.0+ @@ -35,6 +35,7 @@ #include <osmocom/msc/rtp_stream.h> #include <osmocom/msc/msub.h> #include <osmocom/msc/vlr.h> +#include <osmocom/msc/codec_mapping.h> struct osmo_fsm mncc_call_fsm; static bool mncc_call_tx_rtp_create(struct mncc_call *mncc_call); @@ -60,7 +61,7 @@ struct gsm_network *gsmnet = NULL; void mncc_call_fsm_init(struct gsm_network *net) { - osmo_fsm_register(&mncc_call_fsm); + OSMO_ASSERT(osmo_fsm_register(&mncc_call_fsm) == 0); gsmnet = net; } @@ -192,7 +193,7 @@ int mncc_call_set_rtp_stream(struct mncc_call *mncc_call, struct rtp_stream *rtp /* Disassociate the rtp_stream from this MNCC call instance, and clear the remote RTP IP:port info. * When the MNCC FSM ends for any reason, it will release the RTP stream (which usually triggers complete tear down of - * the call_leg and CC transaction). If the RTP stream should still remain in use, e.g. during Subseqent inter-MSC + * the call_leg and CC transaction). If the RTP stream should still remain in use, e.g. during Subsequent inter-MSC * Handover where this MNCC was a forwarding to a remote MSC that is no longer needed, this function must be called * before the MNCC FSM instance terminates. Call this *before* setting a new remote RTP address on the rtp_stream, since * this clears the rtp_stream->remote ip:port information. */ @@ -208,24 +209,25 @@ void mncc_call_detach_rtp_stream(struct mncc_call *mncc_call) static void mncc_call_tx_setup_ind(struct mncc_call *mncc_call) { - struct gsm_mncc mncc_msg = mncc_call->outgoing_req; - mncc_msg.msg_type = MNCC_SETUP_IND; - mncc_msg.callref = mncc_call->callref; + union mncc_msg mncc_msg; + mncc_msg.signal = mncc_call->outgoing_req; + mncc_msg.signal.msg_type = MNCC_SETUP_IND; + mncc_msg.signal.callref = mncc_call->callref; - OSMO_STRLCPY_ARRAY(mncc_msg.imsi, mncc_call->vsub->imsi); + OSMO_STRLCPY_ARRAY(mncc_msg.signal.imsi, mncc_call->vsub->imsi); if (!(mncc_call->outgoing_req.fields & MNCC_F_CALLING)) { /* No explicit calling number set, use the local subscriber */ - mncc_msg.fields |= MNCC_F_CALLING; - OSMO_STRLCPY_ARRAY(mncc_msg.calling.number, mncc_call->vsub->msisdn); + mncc_msg.signal.fields |= MNCC_F_CALLING; + OSMO_STRLCPY_ARRAY(mncc_msg.signal.calling.number, mncc_call->vsub->msisdn); } mncc_call->local_msisdn_present = true; - mncc_call->local_msisdn = mncc_msg.calling; + mncc_call->local_msisdn = mncc_msg.signal.calling; - rate_ctr_inc(&gsmnet->msc_ctrs->ctr[MSC_CTR_CALL_MO_SETUP]); + rate_ctr_inc(rate_ctr_group_get_ctr(gsmnet->msc_ctrs, MSC_CTR_CALL_MO_SETUP)); - mncc_call_tx(mncc_call, (union mncc_msg*)&mncc_msg); + mncc_call_tx(mncc_call, &mncc_msg); } static void mncc_call_rx_setup_req(struct mncc_call *mncc_call, const struct gsm_mncc *incoming_req) @@ -256,45 +258,26 @@ static bool mncc_call_rx_rtp_create(struct mncc_call *mncc_call) return true; } - if (!osmo_sockaddr_str_is_set(&mncc_call->rtps->local)) { + if (!osmo_sockaddr_str_is_nonzero(&mncc_call->rtps->local)) { LOG_MNCC_CALL(mncc_call, LOGL_DEBUG, "Got RTP_CREATE, but RTP stream has no local address\n"); return true; } - if (!mncc_call->rtps->codec_known) { + if (!mncc_call->rtps->codecs_known) { LOG_MNCC_CALL(mncc_call, LOGL_DEBUG, "Got RTP_CREATE, but RTP stream has no codec set\n"); return true; } LOG_MNCC_CALL(mncc_call, LOGL_DEBUG, "Got RTP_CREATE, responding with " OSMO_SOCKADDR_STR_FMT " %s\n", OSMO_SOCKADDR_STR_FMT_ARGS(&mncc_call->rtps->local), - osmo_mgcpc_codec_name(mncc_call->rtps->codec)); + sdp_audio_codecs_to_str(&mncc_call->rtps->codecs)); /* Already know what RTP IP:port to tell the MNCC. Send it. */ return mncc_call_tx_rtp_create(mncc_call); } -/* Convert enum mgcp_codecs to an gsm_mncc_rtp->payload_msg_type value. */ -uint32_t mgcp_codec_to_mncc_payload_msg_type(enum mgcp_codecs codec) -{ - switch (codec) { - default: - /* disclaimer: i have no idea what i'm doing. */ - case CODEC_GSM_8000_1: - return GSM_TCHF_FRAME; - case CODEC_GSMEFR_8000_1: - return GSM_TCHF_FRAME_EFR; - case CODEC_GSMHR_8000_1: - return GSM_TCHH_FRAME; - case CODEC_AMR_8000_1: - case CODEC_AMRWB_16000_1: - //return GSM_TCHF_FRAME; - return GSM_TCH_FRAME_AMR; - } -} - static bool mncc_call_tx_rtp_create(struct mncc_call *mncc_call) { - if (!mncc_call->rtps || !osmo_sockaddr_str_is_set(&mncc_call->rtps->local)) { + if (!mncc_call->rtps || !osmo_sockaddr_str_is_nonzero(&mncc_call->rtps->local)) { mncc_call_error(mncc_call, "Cannot send RTP_CREATE, no local RTP address set up\n"); return false; } @@ -303,19 +286,26 @@ static bool mncc_call_tx_rtp_create(struct mncc_call *mncc_call) .rtp = { .msg_type = MNCC_RTP_CREATE, .callref = mncc_call->callref, - .port = rtp_local->port, }, }; - if (osmo_sockaddr_str_to_32n(rtp_local, &mncc_msg.rtp.ip)) { + if (osmo_sockaddr_str_to_sockaddr(rtp_local, &mncc_msg.rtp.addr)) { mncc_call_error(mncc_call, "Failed to compose IP address " OSMO_SOCKADDR_STR_FMT "\n", OSMO_SOCKADDR_STR_FMT_ARGS(rtp_local)); return false; } - if (mncc_call->rtps->codec_known) { - mncc_msg.rtp.payload_type = 0; /* ??? */ - mncc_msg.rtp.payload_msg_type = mgcp_codec_to_mncc_payload_msg_type(mncc_call->rtps->codec); + if (mncc_call->rtps->codecs_known) { + struct sdp_audio_codec *codec = &mncc_call->rtps->codecs.codec[0]; + const struct codec_mapping *m = codec_mapping_by_subtype_name(codec->subtype_name); + + if (!m) { + mncc_call_error(mncc_call, "Failed to resolve audio codec '%s'\n", + sdp_audio_codec_to_str(codec)); + return false; + } + mncc_msg.rtp.payload_type = codec->payload_type; + mncc_msg.rtp.payload_msg_type = m->mncc_payload_msg_type; } if (mncc_call_tx(mncc_call, &mncc_msg)) @@ -332,7 +322,7 @@ static bool mncc_call_rx_rtp_connect(struct mncc_call *mncc_call, const struct g return true; } - if (osmo_sockaddr_str_from_32n(&rtp, mncc_msg->ip, mncc_msg->port)) { + if (osmo_sockaddr_str_from_sockaddr(&rtp, &mncc_msg->addr)) { mncc_call_error(mncc_call, "Cannot RTP-CONNECT, invalid RTP IP:port in incoming MNCC message\n"); return false; } diff --git a/src/libmsc/mncc_sock.c b/src/libmsc/mncc_sock.c index 0a4e99b92..410449d6d 100644 --- a/src/libmsc/mncc_sock.c +++ b/src/libmsc/mncc_sock.c @@ -6,18 +6,14 @@ * 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 2 of the License, or + * 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 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. + * GNU Affero General Public License for more details. * */ @@ -65,7 +61,7 @@ int mncc_sock_from_cc(struct gsm_network *net, struct msgb *msg) /* Actually enqueue the message and mark socket write need */ msgb_enqueue(&net->upqueue, msg); - net->mncc_state->conn_bfd.when |= BSC_FD_WRITE; + osmo_fd_write_enable(&net->mncc_state->conn_bfd); return 0; } @@ -75,14 +71,14 @@ static void mncc_sock_close(struct mncc_sock_state *state) LOGP(DMNCC, LOGL_NOTICE, "MNCC Socket has LOST connection\n"); + osmo_fd_unregister(bfd); close(bfd->fd); bfd->fd = -1; - osmo_fd_unregister(bfd); /* re-enable the generation of ACCEPT for new connections */ - state->listen_bfd.when |= BSC_FD_READ; + osmo_fd_read_enable(&state->listen_bfd); - /* release all exisitng calls */ + /* release all existing calls */ gsm0408_clear_all_trans(state->net, TRANS_CC); /* flush the queue */ @@ -146,7 +142,7 @@ static int mncc_sock_write(struct osmo_fd *bfd) msg = llist_entry(net->upqueue.next, struct msgb, list); mncc_prim = (struct gsm_mncc *)msg->data; - bfd->when &= ~BSC_FD_WRITE; + osmo_fd_write_disable(bfd); /* bug hunter 8-): maybe someone forgot msgb_put(...) ? */ if (!msgb_length(msg)) { @@ -161,7 +157,7 @@ static int mncc_sock_write(struct osmo_fd *bfd) goto close; if (rc < 0) { if (errno == EAGAIN) { - bfd->when |= BSC_FD_WRITE; + osmo_fd_write_enable(bfd); break; } goto close; @@ -185,12 +181,12 @@ static int mncc_sock_cb(struct osmo_fd *bfd, unsigned int flags) { int rc = 0; - if (flags & BSC_FD_READ) + if (flags & OSMO_FD_READ) rc = mncc_sock_read(bfd); if (rc < 0) return rc; - if (flags & BSC_FD_WRITE) + if (flags & OSMO_FD_WRITE) rc = mncc_sock_write(bfd); return rc; @@ -222,7 +218,7 @@ static void queue_hello(struct mncc_sock_state *mncc) hello->lchan_type_offset = offsetof(struct gsm_mncc, lchan_type); msgb_enqueue(&mncc->net->upqueue, msg); - mncc->conn_bfd.when |= BSC_FD_WRITE; + osmo_fd_write_enable(&mncc->conn_bfd); } /* accept a new connection */ @@ -245,16 +241,12 @@ static int mncc_sock_accept(struct osmo_fd *bfd, unsigned int flags) LOGP(DMNCC, LOGL_NOTICE, "MNCC app connects but we already have " "another active connection ?!?\n"); /* We already have one MNCC app connected, this is all we support */ - state->listen_bfd.when &= ~BSC_FD_READ; + osmo_fd_read_disable(&state->listen_bfd); close(rc); return 0; } - conn_bfd->fd = rc; - conn_bfd->when = BSC_FD_READ; - conn_bfd->cb = mncc_sock_cb; - conn_bfd->data = state; - + osmo_fd_setup(conn_bfd, rc, OSMO_FD_READ, mncc_sock_cb, state, 0); if (osmo_fd_register(conn_bfd) != 0) { LOGP(DMNCC, LOGL_ERROR, "Failed to register new connection fd\n"); close(conn_bfd->fd); @@ -294,10 +286,7 @@ int mncc_sock_init(struct gsm_network *net, const char *sock_path) return -1; } - bfd->when = BSC_FD_READ; - bfd->cb = mncc_sock_accept; - bfd->data = state; - + osmo_fd_setup(bfd, bfd->fd, OSMO_FD_READ, mncc_sock_accept, state, 0); rc = osmo_fd_register(bfd); if (rc < 0) { LOGP(DMNCC, LOGL_ERROR, "Could not register listen fd: %d\n", rc); diff --git a/src/libmsc/msc_a.c b/src/libmsc/msc_a.c index cfba545be..db1d9983a 100644 --- a/src/libmsc/msc_a.c +++ b/src/libmsc/msc_a.c @@ -1,6 +1,6 @@ /* Code to manage a subscriber's MSC-A role */ /* - * (C) 2019 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de> + * (C) 2019 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de> * All Rights Reserved * * SPDX-License-Identifier: AGPL-3.0+ @@ -36,6 +36,7 @@ #include <osmocom/msc/signal.h> #include <osmocom/msc/vlr.h> #include <osmocom/msc/transaction.h> +#include <osmocom/msc/transaction_cc.h> #include <osmocom/msc/ran_peer.h> #include <osmocom/msc/ran_msg_a.h> #include <osmocom/msc/ran_msg_iu.h> @@ -46,6 +47,8 @@ #include <osmocom/msc/call_leg.h> #include <osmocom/msc/rtp_stream.h> #include <osmocom/msc/msc_ho.h> +#include <osmocom/msc/codec_mapping.h> +#include <osmocom/msc/msc_vgcs.h> #define MSC_A_USE_WAIT_CLEAR_COMPLETE "wait-Clear-Complete" @@ -63,9 +66,15 @@ static const struct osmo_tdef_state_timeout msc_a_fsm_timeouts[32] = { /* Transition to a state, using the T timer defined in msc_a_fsm_timeouts. * The actual timeout value is in turn obtained from network->T_defs. * Assumes local variable fi exists. */ -#define msc_a_state_chg(msc_a, state) \ +#define msc_a_state_chg_always(msc_a, state) \ osmo_tdef_fsm_inst_state_chg((msc_a)->c.fi, state, msc_a_fsm_timeouts, (msc_a)->c.ran->tdefs, 5) +/* Same as msc_a_state_chg_always() but ignore if the msc_a already is in the target state. */ +#define msc_a_state_chg(msc_a, STATE) do { \ + if ((msc_a)->c.fi->state != STATE) \ + msc_a_state_chg_always(msc_a, STATE); \ + } while(0) + struct gsm_network *msc_a_net(const struct msc_a *msc_a) { return msub_net(msc_a->c.msub); @@ -100,25 +109,46 @@ struct msc_a *msc_a_fi_priv(struct osmo_fsm_inst *fi) return fi->priv; } +bool msc_a_is_ciphering_to_be_attempted(const struct msc_a *msc_a) +{ + struct gsm_network *net = msc_a_net(msc_a); + bool is_utran = (msc_a->c.ran->type == OSMO_RAT_UTRAN_IU); + if (is_utran) + return net->uea_encryption_mask > (1 << OSMO_UTRAN_UEA0); + else + return net->a5_encryption_mask > 0x1; +} + +bool msc_a_is_ciphering_required(const struct msc_a *msc_a) +{ + struct gsm_network *net = msc_a_net(msc_a); + bool is_utran = (msc_a->c.ran->type == OSMO_RAT_UTRAN_IU); + if (is_utran) + return net->uea_encryption_mask + && ((net->uea_encryption_mask & (1 << OSMO_UTRAN_UEA0)) == 0); + else + return net->a5_encryption_mask + && ((net->a5_encryption_mask & 0x1) == 0); +} + static void update_counters(struct osmo_fsm_inst *fi, bool conn_accepted) { struct msc_a *msc_a = fi->priv; struct gsm_network *net = msc_a_net(msc_a); switch (msc_a->complete_layer3_type) { case COMPLETE_LAYER3_LU: - rate_ctr_inc(&net->msc_ctrs->ctr[ - conn_accepted ? MSC_CTR_LOC_UPDATE_COMPLETED - : MSC_CTR_LOC_UPDATE_FAILED]); + rate_ctr_inc(rate_ctr_group_get_ctr(net->msc_ctrs, conn_accepted ? MSC_CTR_LOC_UPDATE_COMPLETED : MSC_CTR_LOC_UPDATE_FAILED)); break; case COMPLETE_LAYER3_CM_SERVICE_REQ: - rate_ctr_inc(&net->msc_ctrs->ctr[ - conn_accepted ? MSC_CTR_CM_SERVICE_REQUEST_ACCEPTED - : MSC_CTR_CM_SERVICE_REQUEST_REJECTED]); + rate_ctr_inc(rate_ctr_group_get_ctr(net->msc_ctrs, conn_accepted ? MSC_CTR_CM_SERVICE_REQUEST_ACCEPTED : MSC_CTR_CM_SERVICE_REQUEST_REJECTED)); break; case COMPLETE_LAYER3_PAGING_RESP: - rate_ctr_inc(&net->msc_ctrs->ctr[ - conn_accepted ? MSC_CTR_PAGING_RESP_ACCEPTED - : MSC_CTR_PAGING_RESP_REJECTED]); + rate_ctr_inc(rate_ctr_group_get_ctr(net->msc_ctrs, conn_accepted ? MSC_CTR_PAGING_RESP_ACCEPTED : MSC_CTR_PAGING_RESP_REJECTED)); + break; + case COMPLETE_LAYER3_CM_RE_ESTABLISH_REQ: + rate_ctr_inc(rate_ctr_group_get_ctr(net->msc_ctrs, + conn_accepted ? MSC_CTR_CM_RE_ESTABLISH_REQ_ACCEPTED + : MSC_CTR_CM_RE_ESTABLISH_REQ_REJECTED)); break; default: break; @@ -132,6 +162,12 @@ static void evaluate_acceptance_outcome(struct osmo_fsm_inst *fi, bool conn_acce update_counters(fi, conn_accepted); + if (conn_accepted) { + /* Record the Cell ID seen in Complete Layer 3 Information in the VLR, so that it also shows in vty + * 'show' output. */ + vsub->cgi = msc_a->via_cell; + } + /* Trigger transactions that we paged for */ if (msc_a->complete_layer3_type == COMPLETE_LAYER3_PAGING_RESP) { if (conn_accepted) @@ -145,6 +181,15 @@ static void evaluate_acceptance_outcome(struct osmo_fsm_inst *fi, bool conn_acce if (msc_a->complete_layer3_type == COMPLETE_LAYER3_LU) msc_a_put(msc_a, MSC_A_USE_LOCATION_UPDATING); + + if (conn_accepted && msc_a->complete_layer3_type == COMPLETE_LAYER3_CM_RE_ESTABLISH_REQ) { + /* Trigger new Assignment to recommence the voice call. A little dance here because normally we verify + * that no CC trans is already active. */ + struct gsm_trans *cc_trans = msc_a->cc.active_trans; + msc_a->cc.active_trans = NULL; + osmo_fsm_inst_dispatch(msc_a->c.fi, MSC_A_EV_TRANSACTION_ACCEPTED, cc_trans); + msc_a_try_call_assignment(cc_trans); + } } bool msc_a_is_accepted(const struct msc_a *msc_a) @@ -286,6 +331,14 @@ int msc_a_vlr_set_cipher_mode(void *_msc_a, bool umts_aka, bool retrieve_imeisv) return msc_a_ran_enc_ciphering(msc_a, umts_aka, retrieve_imeisv); } +static uint8_t filter_a5(uint8_t a5_mask, bool umts_aka) +{ + /* With GSM AKA: allow A5/0, 1, 3 = 0b00001011 = 0xb. + * UMTS aka: allow A5/0, 1, 3, 4 = 0b00011011 = 0x1b. + */ + return a5_mask & (umts_aka ? 0x1b : 0x0b); +} + static int msc_a_ran_enc_ciphering(struct msc_a *msc_a, bool umts_aka, bool retrieve_imeisv) { struct gsm_network *net; @@ -315,11 +368,14 @@ static int msc_a_ran_enc_ciphering(struct msc_a *msc_a, bool umts_aka, bool retr .geran = { .umts_aka = umts_aka, .retrieve_imeisv = retrieve_imeisv, - .a5_encryption_mask = net->a5_encryption_mask, + .a5_encryption_mask = filter_a5(net->a5_encryption_mask, umts_aka), /* for ran_a.c to store the GERAN key that is actually used */ .chosen_key = &msc_a->geran_encr, }, + .utran = { + .uea_encryption_mask = net->uea_encryption_mask, + }, }, }; @@ -331,8 +387,12 @@ static int msc_a_ran_enc_ciphering(struct msc_a *msc_a, bool umts_aka, bool retr } if (msc_a->geran_encr.key_len) - LOG_MSC_A(msc_a, LOGL_DEBUG, "RAN encoding chose ciphering key %s\n", - osmo_hexdump_nospc(msc_a->geran_encr.key, msc_a->geran_encr.key_len)); + LOG_MSC_A(msc_a, LOGL_DEBUG, "RAN encoding chose ciphering: A5/%d kc %s kc128 %s\n", + msc_a->geran_encr.alg_id - 1, + osmo_hexdump_nospc_c(OTC_SELECT, msc_a->geran_encr.key, msc_a->geran_encr.key_len), + msc_a->geran_encr.kc128_present ? + osmo_hexdump_nospc_c(OTC_SELECT, msc_a->geran_encr.kc128, sizeof(msc_a->geran_encr.kc128)) + : "-"); return 0; } @@ -429,6 +489,16 @@ static bool msc_a_fsm_has_active_transactions(struct osmo_fsm_inst *fi) __func__); return true; } + if (osmo_use_count_by(&msc_a->use_count, MSC_A_USE_CM_SERVICE_GCC)) { + LOG_MSC_A(msc_a, LOGL_DEBUG, "%s: still awaiting MO GCC request after a CM Service Request\n", + __func__); + return true; + } + if (osmo_use_count_by(&msc_a->use_count, MSC_A_USE_CM_SERVICE_BCC)) { + LOG_MSC_A(msc_a, LOGL_DEBUG, "%s: still awaiting MO BCC request after a CM Service Request\n", + __func__); + return true; + } if (osmo_use_count_by(&msc_a->use_count, MSC_A_USE_CM_SERVICE_SMS)) { LOG_MSC_A(msc_a, LOGL_DEBUG, "%s: still awaiting MO SMS after a CM Service Request\n", __func__); @@ -505,42 +575,141 @@ static void msc_a_fsm_authenticated(struct osmo_fsm_inst *fi, uint32_t event, vo } } +static struct call_leg *msc_a_ensure_call_leg(struct msc_a *msc_a, struct gsm_trans *for_cc_trans) +{ + struct call_leg *cl = msc_a->cc.call_leg; + struct gsm_network *net = msc_a_net(msc_a); + + /* Ensure that events about RTP endpoints coming from the msc_a->cc.call_leg know which gsm_trans to abort on + * error */ + if (!msc_a->cc.active_trans) + msc_a->cc.active_trans = for_cc_trans; + if (msc_a->cc.active_trans != for_cc_trans) { + LOG_TRANS(for_cc_trans, LOGL_ERROR, + "Cannot create call leg, another trans is already active for this conn\n"); + return NULL; + } + + if (!cl) { + cl = msc_a->cc.call_leg = call_leg_alloc(msc_a->c.fi, + MSC_EV_CALL_LEG_TERM, + MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE, + MSC_EV_CALL_LEG_RTP_COMPLETE); + OSMO_ASSERT(cl); + + if (net->use_osmux != OSMUX_USAGE_OFF) { + struct msc_i *msc_i = msc_a_msc_i(msc_a); + if (msc_i->c.remote_to) { + /* TODO: investigate what to do in this case */ + LOG_MSC_A(msc_a, LOGL_ERROR, "Osmux not yet supported for inter-MSC"); + } else { + cl->ran_peer_supports_osmux = msc_i->ran_conn->ran_peer->remote_supports_osmux; + } + } + + } + return cl; +} + +int msc_a_ensure_cn_local_rtp(struct msc_a *msc_a, struct gsm_trans *cc_trans) +{ + struct call_leg *cl; + struct rtp_stream *rtp_to_ran; + + cl = msc_a_ensure_call_leg(msc_a, cc_trans); + if (!cl) + return -EINVAL; + rtp_to_ran = cl->rtp[RTP_TO_RAN]; + + if (call_leg_local_ip(cl, RTP_TO_CN)) { + /* Already has an RTP address and port towards the CN, continue right away. */ + return osmo_fsm_inst_dispatch(msc_a->c.fi, MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE, cl->rtp[RTP_TO_CN]); + } + + /* No CN RTP address available yet, ask the MGW to create one. + * Set a codec to be used: if Assignment on the RAN side is already done, take the same codec as the RTP_TO_RAN. + * If no RAN side RTP is established, try to guess a preliminary codec from SDP -- before Assignment, picking a + * codec from the SDP is more politeness/avoiding confusion than necessity. The actual codec to be used would be + * determined later. If no codec could be determined, pass none for the time being. */ + return call_leg_ensure_ci(cl, RTP_TO_CN, cc_trans->call_id, cc_trans, + rtp_to_ran->codecs_known ? &rtp_to_ran->codecs : NULL, NULL); +} + /* The MGW has given us a local IP address for the RAN side. Ready to start the Assignment of a voice channel. */ -static void msc_a_call_leg_ran_local_addr_available(struct msc_a *msc_a) +void msc_a_tx_assignment_cmd(struct msc_a *msc_a) { struct ran_msg msg; struct gsm_trans *cc_trans = msc_a->cc.active_trans; struct gsm0808_channel_type channel_type; - /* Once a CI is known, we could also CRCX the CN side of the MGW endpoint, but it makes sense to wait for the - * codec to be determined by the Assignment Complete message, first. */ + if (!cc_trans) { + LOG_MSC_A(msc_a, LOGL_ERROR, "No CC transaction active\n"); + call_leg_release(msc_a->cc.call_leg); + return; + } + + trans_cc_filter_run(cc_trans); + LOG_TRANS(cc_trans, LOGL_DEBUG, "Sending Assignment Command\n"); + + switch (cc_trans->bearer_cap.transfer) { + case GSM48_BCAP_ITCAP_SPEECH: + if (!cc_trans->cc.local.audio_codecs.count) { + LOG_TRANS(cc_trans, LOGL_ERROR, "Assignment not possible, no matching codec: %s\n", + codec_filter_to_str(&cc_trans->cc.codecs, &cc_trans->cc.local, &cc_trans->cc.remote)); + call_leg_release(msc_a->cc.call_leg); + return; + } + + /* Compose 48.008 Channel Type from the current set of codecs + * determined from both local and remote codec capabilities. */ + if (sdp_audio_codecs_to_gsm0808_channel_type(&channel_type, &cc_trans->cc.local.audio_codecs)) { + LOG_MSC_A(msc_a, LOGL_ERROR, "Cannot compose Channel Type (Permitted Speech) from codecs: %s\n", + codec_filter_to_str(&cc_trans->cc.codecs, &cc_trans->cc.local, &cc_trans->cc.remote)); + trans_free(cc_trans); + return; + } + break; + case GSM48_BCAP_ITCAP_3k1_AUDIO: + case GSM48_BCAP_ITCAP_FAX_G3: + case GSM48_BCAP_ITCAP_UNR_DIG_INF: + if (!cc_trans->cc.local.bearer_services.count) { + LOG_TRANS(cc_trans, LOGL_ERROR, "Assignment not possible, no matching bearer service: %s\n", + csd_filter_to_str(&cc_trans->cc.csd, &cc_trans->cc.local, &cc_trans->cc.remote)); + call_leg_release(msc_a->cc.call_leg); + return; + } - if (mncc_bearer_cap_to_channel_type(&channel_type, &cc_trans->bearer_cap)) { - LOG_MSC_A(msc_a, LOGL_ERROR, "Cannot compose Channel Type from bearer capabilities\n"); - /* FIXME: ERROR HANDLING */ + /* Compose 48.008 Channel Type from the current set of bearer + * services determined from local and remote capabilities. */ + if (csd_bs_list_to_gsm0808_channel_type(&channel_type, &cc_trans->cc.local.bearer_services)) { + LOG_MSC_A(msc_a, LOGL_ERROR, "Cannot compose channel type from: %s\n", + csd_filter_to_str(&cc_trans->cc.csd, &cc_trans->cc.local, &cc_trans->cc.remote)); + return; + } + break; + default: + LOG_TRANS(cc_trans, LOGL_ERROR, "Assignment not possible for information transfer capability %d\n", + cc_trans->bearer_cap.transfer); + call_leg_release(msc_a->cc.call_leg); return; } - /* The RAN side RTP address is known, so the voice Assignment can commence. */ + /* The RAN side RTP address is known, so the voice/CSD Assignment can commence. */ msg = (struct ran_msg){ .msg_type = RAN_MSG_ASSIGNMENT_COMMAND, .assignment_command = { .cn_rtp = &msc_a->cc.call_leg->rtp[RTP_TO_RAN]->local, .channel_type = &channel_type, + .osmux_present = msc_a->cc.call_leg->rtp[RTP_TO_RAN]->use_osmux, + .osmux_cid = msc_a->cc.call_leg->rtp[RTP_TO_RAN]->local_osmux_cid, + .call_id_present = true, + .call_id = cc_trans->call_id, + .lcls = cc_trans->cc.lcls, }, }; if (msc_a_ran_down(msc_a, MSC_ROLE_I, &msg)) { LOG_MSC_A(msc_a, LOGL_ERROR, "Cannot send Assignment\n"); - /* FIXME: ERROR HANDLING */ - return; - } -} - -static void msc_a_call_leg_cn_local_addr_available(struct msc_a *msc_a, struct gsm_trans *cc_trans) -{ - if (gsm48_tch_rtp_create(cc_trans)) { - LOG_MSC_A(msc_a, LOGL_ERROR, "Cannot inform MNCC of RTP address\n"); - /* FIXME: ERROR HANDLING */ + trans_free(cc_trans); return; } } @@ -619,15 +788,26 @@ static void msc_a_fsm_communicating(struct osmo_fsm_inst *fi, uint32_t event, vo LOG_MSC_A(msc_a, LOGL_ERROR, "Invalid data for %s\n", osmo_fsm_event_name(fi->fsm, event)); return; } + if (!msc_a->cc.call_leg) { + LOG_MSC_A(msc_a, LOGL_ERROR, "No call leg active\n"); + return; + } + if (!osmo_sockaddr_str_is_nonzero(&rtps->local)) { + LOG_MSC_A(msc_a, LOGL_ERROR, "Invalid RTP address received from MGW: " OSMO_SOCKADDR_STR_FMT "\n", + OSMO_SOCKADDR_STR_FMT_ARGS(&rtps->local)); + call_leg_release(msc_a->cc.call_leg); + return; + } LOG_MSC_A(msc_a, LOGL_DEBUG, - "MGW endpoint's RTP address available for the CI %s: " OSMO_SOCKADDR_STR_FMT "\n", - rtp_direction_name(rtps->dir), OSMO_SOCKADDR_STR_FMT_ARGS(&rtps->local)); + "MGW endpoint's RTP address available for the CI %s: " OSMO_SOCKADDR_STR_FMT " (osmux=%s:%d)\n", + rtp_direction_name(rtps->dir), OSMO_SOCKADDR_STR_FMT_ARGS(&rtps->local), + rtps->use_osmux ? "yes" : "no", rtps->local_osmux_cid); switch (rtps->dir) { case RTP_TO_RAN: - msc_a_call_leg_ran_local_addr_available(msc_a); + msc_a_tx_assignment_cmd(msc_a); return; case RTP_TO_CN: - msc_a_call_leg_cn_local_addr_available(msc_a, rtps->for_trans); + cc_on_cn_local_rtp_port_known(rtps->for_trans); return; default: LOG_MSC_A(msc_a, LOGL_ERROR, "Invalid data for %s\n", osmo_fsm_event_name(fi->fsm, event)); @@ -706,6 +886,8 @@ static void msc_a_fsm_releasing_onenter(struct osmo_fsm_inst *fi, uint32_t prev_ MSC_A_USE_CM_SERVICE_CC, MSC_A_USE_CM_SERVICE_SMS, MSC_A_USE_CM_SERVICE_SS, + MSC_A_USE_CM_SERVICE_GCC, + MSC_A_USE_CM_SERVICE_BCC, MSC_A_USE_PAGING_RESPONSE, }; @@ -746,11 +928,19 @@ static void msc_a_fsm_releasing_onenter(struct osmo_fsm_inst *fi, uint32_t prev_ struct ran_msg msg = { .msg_type = RAN_MSG_CLEAR_COMMAND, .clear_command = { + /* "Call Control" is the only cause code listed in 3GPP TS 48.008 3.2.1.21 CLEAR COMMAND + * that qualifies for a normal release situation. (OS#4664) */ + .gsm0808_cause = GSM0808_CAUSE_CALL_CONTROL, .csfb_ind = (vsub && vsub->sgs_fsm->state == SGS_UE_ST_ASSOCIATED), }, }; msc_a_get(msc_a, MSC_A_USE_WAIT_CLEAR_COMPLETE); msc_a_ran_down(msc_a, MSC_ROLE_I, &msg); + + /* The connection is cleared. The MS will now go back to 4G, + Switch the RAN type back to SGS. */ + if (vsub && vsub->sgs_fsm->state == SGS_UE_ST_ASSOCIATED) + vsub->cs.attached_via_ran = OSMO_RAT_EUTRAN_SGS; } if (vsub) @@ -806,19 +996,10 @@ static void msc_a_fsm_released(struct osmo_fsm_inst *fi, uint32_t event, void *d osmo_fsm_inst_term(fi, OSMO_FSM_TERM_REGULAR, fi); } -void msc_a_fsm_allstate_action(struct osmo_fsm_inst *fi, uint32_t event, void *data) -{ - //struct msc_a *a = msc_a_fi_priv(fi); - switch (event) { - - default: - return; - } -} - void msc_a_fsm_cleanup(struct osmo_fsm_inst *fi, enum osmo_fsm_term_cause cause) { struct msc_a *msc_a = msc_a_fi_priv(fi); + struct vlr_subscr *vsub = msc_a_vsub(msc_a); trans_conn_closed(msc_a); @@ -826,6 +1007,10 @@ void msc_a_fsm_cleanup(struct osmo_fsm_inst *fi, enum osmo_fsm_term_cause cause) LOG_MSC_A(msc_a, LOGL_ERROR, "Deallocating active transactions failed\n"); LOG_MSC_A_CAT(msc_a, DREF, LOGL_DEBUG, "max total use count was %d\n", msc_a->max_total_use_count); + + /* Invalidate the active conn in VLR subscriber state, if any. */ + if (vsub && vsub->msc_conn_ref == msc_a) + vsub->msc_conn_ref = NULL; } const struct value_string msc_a_fsm_event_names[] = { @@ -965,6 +1150,7 @@ static const struct osmo_fsm_state msc_a_fsm_states[] = { | S(MSC_EV_CALL_LEG_TERM) | S(MSC_MNCC_EV_CALL_ENDED) | S(MSC_A_EV_HANDOVER_END) + | S(MSC_A_EV_CN_CLOSE) , .out_state_mask = 0 | S(MSC_A_ST_RELEASED) @@ -988,9 +1174,6 @@ static struct osmo_fsm msc_a_fsm = { .num_states = ARRAY_SIZE(msc_a_fsm_states), .log_subsys = DMSC, .event_names = msc_a_fsm_event_names, - .allstate_action = msc_a_fsm_allstate_action, - .allstate_event_mask = 0 - , .timer_cb = msc_a_fsm_timer_cb, .cleanup = msc_a_fsm_cleanup, }; @@ -1041,7 +1224,7 @@ struct msc_a *msc_a_alloc(struct msub *msub, struct ran_infra *ran) }; osmo_use_count_make_static_entries(&msc_a->use_count, msc_a->use_count_buf, ARRAY_SIZE(msc_a->use_count_buf)); /* Start timeout for first state */ - msc_a_state_chg(msc_a, MSC_A_ST_VALIDATE_L3); + msc_a_state_chg_always(msc_a, MSC_A_ST_VALIDATE_L3); return msc_a; } @@ -1057,6 +1240,7 @@ const struct value_string complete_layer3_type_names[] = { { COMPLETE_LAYER3_LU, "LU" }, { COMPLETE_LAYER3_CM_SERVICE_REQ, "CM_SERVICE_REQ" }, { COMPLETE_LAYER3_PAGING_RESP, "PAGING_RESP" }, + { COMPLETE_LAYER3_CM_RE_ESTABLISH_REQ, "CM_RE_ESTABLISH_REQ" }, { 0, NULL } }; @@ -1083,9 +1267,9 @@ const struct value_string complete_layer3_type_names[] = { /* Compose an ID almost like gsm48_mi_to_string(), but print the MI type along, and print a TMSI as hex. */ -void msc_a_update_id_from_mi(struct msc_a *msc_a, const uint8_t mi[], uint8_t mi_len) +void msc_a_update_id_from_mi(struct msc_a *msc_a, const struct osmo_mobile_identity *mi) { - _msc_a_update_id(msc_a, "%s", osmo_mi_name(mi, mi_len)); + _msc_a_update_id(msc_a, "%s", osmo_mobile_identity_to_str_c(OTC_SELECT, mi)); } /* Update msc_a->fi id string from current msc_a->vsub and msc_a->complete_layer3_type. */ @@ -1209,6 +1393,10 @@ int msc_a_up_l3(struct msc_a *msc_a, struct msgb *msg) #endif switch (pdisc) { + case GSM48_PDISC_GROUP_CC: + case GSM48_PDISC_BCAST_CC: + rc = gsm44068_rcv_bcc_gcc(msc_a, NULL, msg); + break; case GSM48_PDISC_CC: rc = gsm0408_rcv_cc(msc_a, msg); break; @@ -1245,32 +1433,109 @@ int msc_a_up_l3(struct msc_a *msc_a, struct msgb *msg) static void msc_a_up_call_assignment_complete(struct msc_a *msc_a, const struct ran_msg *ac) { - struct gsm_trans *cc_trans = msc_a->cc.active_trans; + struct gsm_trans *cc_trans = msc_a->cc.active_trans, *gcc_trans; struct rtp_stream *rtps_to_ran = msc_a->cc.call_leg ? msc_a->cc.call_leg->rtp[RTP_TO_RAN] : NULL; + const struct gsm0808_speech_codec *codec_if_known = ac->assignment_complete.codec_present ? + &ac->assignment_complete.codec : NULL; + + /* For a voice group call, handling is performed by VGCS FSM */ + gcc_trans = trans_find_by_type(msc_a, TRANS_GCC); + if (gcc_trans) { + vgcs_vbs_caller_assign_cpl(gcc_trans); + return; + } + gcc_trans = trans_find_by_type(msc_a, TRANS_BCC); + if (gcc_trans) { + vgcs_vbs_caller_assign_cpl(gcc_trans); + return; + } if (!rtps_to_ran) { LOG_MSC_A(msc_a, LOGL_ERROR, "Rx Assignment Complete, but no RTP stream is set up\n"); return; } if (!cc_trans) { - LOG_MSC_A(msc_a, LOGL_ERROR, "Rx Assignment Complete, but CC transaction is active\n"); + LOG_MSC_A(msc_a, LOGL_ERROR, "Rx Assignment Complete, but no CC transaction is active\n"); return; } - /* Update RAN-side endpoint CI: */ - rtp_stream_set_codec(rtps_to_ran, ac->assignment_complete.codec); + if (rtps_to_ran->use_osmux != ac->assignment_complete.osmux_present) { + LOG_MSC_A_CAT(msc_a, DCC, LOGL_ERROR, "Osmux usage ass request and complete don't match: %d vs %d\n", + rtps_to_ran->use_osmux, ac->assignment_complete.osmux_present); + call_leg_release(msc_a->cc.call_leg); + return; + } + + if (codec_if_known) { + const struct codec_mapping *codec_assigned; + + /* Check for unexpected codec with CSD */ + switch (cc_trans->bearer_cap.transfer) { + case GSM48_BCAP_ITCAP_FAX_G3: + case GSM48_BCAP_ITCAP_3k1_AUDIO: + case GSM48_BCAP_ITCAP_UNR_DIG_INF: + if (codec_if_known->type == GSM0808_SCT_CSD) + break; /* we're good */ + LOG_TRANS(cc_trans, LOGL_ERROR, "Unexpected codec in Assignment Complete for CSD: %s\n", + gsm0808_speech_codec_type_name(codec_if_known->type)); + call_leg_release(msc_a->cc.call_leg); + return; + default: + break; + } + + /* For 2G: + * - The Assignment Complete has returned a specific codec (e.g. FR3 for AMR FR). + * - Set this codec at the MGW endpoint facing the RAN. + * - Also set this codec at the MGW endpoint facing the CN -- we require an exact match on both call + * legs. + * - TODO: be aware of transcoding that the MGW is capable of, e.g. AMR octet-aligned to AMR + * bandwidth-efficient... + * + * For 3G: + * - ran_infra->force_mgw_codecs_to_ran sets VND.3GPP.IUFP as single codec at the MGW towards RAN. + * - ran_msg_iu.c always returns FR3 (AMR FR) for the assigned codec. Set that at the MGW towards CN. + * - So the MGW decapsulates IuUP <-> AMR + */ + codec_assigned = codec_mapping_by_gsm0808_speech_codec_type(codec_if_known->type); + /* TODO: use codec_mapping_by_gsm0808_speech_codec() to also match on codec_if_known->cfg */ + if (!codec_assigned) { + LOG_TRANS(cc_trans, LOGL_ERROR, "Unknown codec in Assignment Complete: %s\n", + gsm0808_speech_codec_type_name(codec_if_known->type)); + call_leg_release(msc_a->cc.call_leg); + return; + } + + /* Update RAN-side endpoint CI from Assignment result -- unless it is forced by the ran_infra, in which + * case it remains unchanged as passed to the earlier call of call_leg_ensure_ci(). */ + if (msc_a->c.ran->force_mgw_codecs_to_ran.count == 0) + rtp_stream_set_one_codec(rtps_to_ran, &codec_assigned->sdp); + + /* Update codec filter with Assignment result, for the CN side */ + cc_trans->cc.codecs.assignment = codec_assigned->sdp; + } else { + /* No codec passed in Assignment Complete, set 'codecs.assignment' to none. */ + cc_trans->cc.codecs.assignment = (struct sdp_audio_codec){}; + LOG_TRANS(cc_trans, LOGL_INFO, "Assignment Complete without voice codec\n"); + } + rtp_stream_set_remote_addr(rtps_to_ran, &ac->assignment_complete.remote_rtp); + if (rtps_to_ran->use_osmux) + rtp_stream_set_remote_osmux_cid(rtps_to_ran, + ac->assignment_complete.osmux_cid); rtp_stream_commit(rtps_to_ran); - /* Setup CN side endpoint CI: - * Now that - * - the first CI has been created and a definitive endpoint name is assigned to the call_leg's MGW - * endpoint, - * - the Assignment has chosen a speech codec - * go on to create the CN side RTP stream's CI. */ - if (call_leg_ensure_ci(msc_a->cc.call_leg, RTP_TO_CN, cc_trans->callref, cc_trans, - &ac->assignment_complete.codec, NULL)) { - LOG_MSC_A_CAT(msc_a, DCC, LOGL_ERROR, "Error creating MGW CI towards CN\n"); + /* Remember the Codec List (BSS Supported) */ + if (ac->assignment_complete.codec_list_bss_supported) + codec_filter_set_bss(&cc_trans->cc.codecs, ac->assignment_complete.codec_list_bss_supported); + + trans_cc_filter_run(cc_trans); + LOG_TRANS(cc_trans, LOGL_INFO, "Assignment Complete: RAN: %s, CN: %s\n", + sdp_audio_codecs_to_str(&rtps_to_ran->codecs), + sdp_audio_codecs_to_str(&cc_trans->cc.local.audio_codecs)); + + if (cc_on_assignment_done(cc_trans)) { + /* If an error occurred, it was logged in cc_assignment_done() */ call_leg_release(msc_a->cc.call_leg); return; } @@ -1287,6 +1552,18 @@ static void msc_a_up_call_assignment_failure(struct msc_a *msc_a, const struct r return; } + /* For a voice group call, release is performed by VGCS FSM */ + trans = trans_find_by_type(msc_a, TRANS_GCC); + if (trans) { + vgcs_vbs_caller_assign_fail(trans); + return; + } + trans = trans_find_by_type(msc_a, TRANS_BCC); + if (trans) { + vgcs_vbs_caller_assign_fail(trans); + return; + } + /* Otherwise, a silent call might be active */ trans = trans_find_by_type(msc_a, TRANS_SILENT_CALL); if (trans) { @@ -1311,7 +1588,7 @@ static void msc_a_up_classmark_update(struct msc_a *msc_a, const struct osmo_gsm dst = &vsub->classmark; } - LOG_MSC_A(msc_a, LOGL_DEBUG, "A5 capabilities recived from Classmark Update: %s\n", + LOG_MSC_A(msc_a, LOGL_DEBUG, "A5 capabilities received from Classmark Update: %s\n", osmo_gsm48_classmark_a5_name(classmark)); osmo_gsm48_classmark_update(dst, classmark); @@ -1339,16 +1616,33 @@ static int msc_a_up_ho(struct msc_a *msc_a, const struct msc_a_ran_dec_data *d, int msc_a_ran_dec_from_msc_i(struct msc_a *msc_a, struct msc_a_ran_dec_data *d) { struct vlr_subscr *vsub = msc_a_vsub(msc_a); + struct gsm_network *net = msc_a_net(msc_a); const struct ran_msg *msg = d->ran_dec; int rc = -99; switch (msg->msg_type) { case RAN_MSG_COMPL_L3: + /* In case the cell_id from Complete Layer 3 Information lacks a PLMN, write the configured PLMN code + * into msc_a->via_cell. Then overwrite with those bits obtained from Complete Layer 3 Information. */ msc_a->via_cell = (struct osmo_cell_global_id){ .lai.plmn = msc_a_net(msc_a)->plmn, }; gsm0808_cell_id_to_cgi(&msc_a->via_cell, msg->compl_l3.cell_id); + + /* If a codec list was sent along in the RAN_MSG_COMPL_L3, remember it for any upcoming codec + * resolution. */ + if (msg->compl_l3.codec_list_bss_supported) { + msc_a->cc.compl_l3_codec_list_bss_supported = *msg->compl_l3.codec_list_bss_supported; + if (log_check_level(msc_a->c.ran->log_subsys, LOGL_DEBUG)) { + struct sdp_audio_codecs ac = {}; + sdp_audio_codecs_from_speech_codec_list(&ac, &msc_a->cc.compl_l3_codec_list_bss_supported); + LOG_MSC_A(msc_a, LOGL_DEBUG, "Complete Layer 3: Codec List (BSS Supported): %s\n", + sdp_audio_codecs_to_str(&ac)); + } + } + + /* Submit the Complete Layer 3 Information DTAP */ rc = msc_a_up_l3(msc_a, msg->compl_l3.msg); if (!rc) { struct ran_conn *conn = msub_ran_conn(msc_a->c.msub); @@ -1392,9 +1686,39 @@ int msc_a_ran_dec_from_msc_i(struct msc_a *msc_a, struct msc_a_ran_dec_data *d) msc_a->geran_encr.alg_id = msg->cipher_mode_complete.alg_id; LOG_MSC_A(msc_a, LOGL_DEBUG, "Cipher Mode Complete: chosen encryption algorithm: A5/%u\n", msc_a->geran_encr.alg_id - 1); - }; + } + + if (msc_a->c.ran->type == OSMO_RAT_UTRAN_IU) { + int16_t utran_encryption; + + /* utran: ensure chosen ciphering mode is allowed + * If the IE is missing (utran_encryption == -1), parse it as no encryption */ + utran_encryption = msg->cipher_mode_complete.utran_encryption; + if (utran_encryption == -1) + utran_encryption = 0; + if ((net->uea_encryption_mask & (1 << utran_encryption)) == 0) { + /* cipher disallowed */ + LOG_MSC_A(msc_a, LOGL_ERROR, "Cipher Mode Complete: RNC chosen forbidden ciphering UEA%d\n", + msg->cipher_mode_complete.utran_encryption); + vlr_subscr_rx_ciph_res(vsub, VLR_CIPH_REJECT); + rc = 0; + break; + } + } vlr_subscr_rx_ciph_res(vsub, VLR_CIPH_COMPL); rc = 0; + + /* Evaluate enclosed L3 message, typically Identity Response (IMEISV) */ + if (msg->cipher_mode_complete.l3_msg) { + unsigned char *data = (unsigned char*)(msg->cipher_mode_complete.l3_msg->val); + uint16_t len = msg->cipher_mode_complete.l3_msg->len; + struct msgb *dtap = msgb_alloc(len, "DTAP from Cipher Mode Complete"); + unsigned char *pos = msgb_put(dtap, len); + memcpy(pos, data, len); + dtap->l3h = pos; + rc = msc_a_up_l3(msc_a, dtap); + msgb_free(dtap); + } break; case RAN_MSG_CIPHER_MODE_REJECT: @@ -1431,6 +1755,13 @@ int msc_a_ran_dec_from_msc_i(struct msc_a *msc_a, struct msc_a_ran_dec_data *d) rc = msc_a_up_ho(msc_a, d, MSC_HO_EV_RX_FAILURE); break; + case RAN_MSG_LCLS_STATUS: + /* The BSS sends us LCLS_STATUS. We do nothing for now, but it is not an error. */ + LOG_MSC_A(msc_a, LOGL_DEBUG, "LCLS_STATUS (%s) received from MSC-I\n", + gsm0808_lcls_status_name(msg->lcls_status.status)); + rc = 0; + break; + default: LOG_MSC_A(msc_a, LOGL_ERROR, "Message from MSC-I not implemented: %s\n", ran_msg_type_name(msg->msg_type)); rc = -ENOTSUP; @@ -1439,6 +1770,136 @@ int msc_a_ran_dec_from_msc_i(struct msc_a *msc_a, struct msc_a_ran_dec_data *d) return rc; } +static int msc_a_rx_vgcs_bss_decoded(struct osmo_fsm_inst *caller_fi, void *caller_data, const struct ran_msg *msg) +{ + struct vgcs_bss *bss = caller_data; + struct msc_a *msc_a = (bss->trans) ? bss->trans->msc_a : NULL; + int rc = 0; + + switch (msg->msg_type) { + case RAN_MSG_VGCS_VBS_SETUP_ACK: + /* The BSS accepts VGCS/VBS and sends us supported features. */ + vgcs_vbs_setup_ack(bss, msg); + break; + case RAN_MSG_VGCS_VBS_SETUP_REFUSE: + /* The BSS refuses VGCS/VBS. */ + vgcs_vbs_setup_refuse(bss, msg); + break; + case RAN_MSG_UPLINK_REQUEST: + /* A mobile station requests the uplink on a VGCS channel. */ + vgcs_uplink_request(bss, msg); + break; + case RAN_MSG_UPLINK_REQUEST_CNF: + /* The uplink on a VGCS channel has been established. */ + vgcs_uplink_request_cnf(bss, msg); + break; + case RAN_MSG_UPLINK_APPLICATION_DATA: + /* Application data received on the uplink of a VGCS channel. */ + vgcs_app_data(bss, msg); + break; + case RAN_MSG_DTAP: + /* BSS confirms the release of the channel. */ + vgcs_bss_dtap(bss, msg); + break; + case RAN_MSG_UPLINK_RELEASE_IND: + /* A mobile station releases the uplink on a VGCS channel. */ + vgcs_uplink_release_ind(bss, msg); + break; + case RAN_MSG_CLEAR_REQUEST: + /* BSS indicated that the channel has been released. */ + vgcs_vbs_clear_req(bss, msg); + break; + case RAN_MSG_CLEAR_COMPLETE: + /* BSS confirms the release of the channel. */ + vgcs_vbs_clear_cpl(bss, msg); + break; + default: + LOG_MSC_A(msc_a, LOGL_ERROR, "VGCS message from BSS not implemented: %s\n", + ran_msg_type_name(msg->msg_type)); + rc = -ENOTSUP; + break; + } + return rc; +} + +int msc_a_rx_vgcs_bss(struct vgcs_bss *bss, struct ran_conn *from_conn, struct msgb *msg) +{ + struct ran_dec ran_dec; + + /* Feed through the decoding mechanism ran_msg. The decoded message arrives in msc_a_rx_vgcs_decoded() */ + ran_dec = (struct ran_dec) { + .caller_data = bss, + .decode_cb = msc_a_rx_vgcs_bss_decoded, + }; + struct ran_peer *ran_peer = from_conn->ran_peer; + struct ran_infra *ran = ran_peer->sri->ran; + if (!ran->ran_dec_l2) { + LOGP(DMSC, LOGL_ERROR, "No ran_dec_l2() defined for RAN type %s\n", + osmo_rat_type_name(ran->type)); + return -ENOTSUP; + } + return ran->ran_dec_l2(&ran_dec, msg); +} + +static int msc_a_rx_vgcs_cell_decoded(struct osmo_fsm_inst *caller_fi, void *caller_data, const struct ran_msg *msg) +{ + struct vgcs_bss_cell *cell = caller_data; + struct msc_a *msc_a = (cell->bss && cell->bss->trans) ? cell->bss->trans->msc_a : NULL; + int rc = 0; + + switch (msg->msg_type) { + case RAN_MSG_VGCS_VBS_ASSIGN_RES: + /* The BSS accepts VGCS/VBS channel assignment. */ + vgcs_vbs_assign_result(cell, msg); + break; + case RAN_MSG_VGCS_VBS_ASSIGN_FAIL: + /* The BSS refuses VGCS/VBS channel assignment. */ + vgcs_vbs_assign_fail(cell, msg); + break; + case RAN_MSG_VGCS_VBS_QUEUING_IND: + /* The BSS needs more time for VGCS/VBS channel assignment. */ + vgcs_vbs_queuing_ind(cell); + break; + case RAN_MSG_VGCS_VBS_ASSIGN_STATUS: + /* The BSS gives cell status about VGCS/VBS channel. */ + vgcs_vbs_assign_status(cell, msg); + break; + case RAN_MSG_CLEAR_REQUEST: + /* BSS indicated that the channel has been released. */ + vgcs_vbs_clear_req_channel(cell, msg); + break; + case RAN_MSG_CLEAR_COMPLETE: + /* BSS confirms the release of the channel. */ + vgcs_vbs_clear_cpl_channel(cell, msg); + break; + default: + LOG_MSC_A(msc_a, LOGL_ERROR, "Message from BSS leg not implemented: %s\n", + ran_msg_type_name(msg->msg_type)); + rc = -ENOTSUP; + break; + } + return rc; +} + +int msc_a_rx_vgcs_cell(struct vgcs_bss_cell *cell, struct ran_conn *from_conn, struct msgb *msg) +{ + struct ran_dec ran_dec; + + /* Feed through the decoding mechanism ran_msg. The decoded message arrives in msc_a_rx_vgcs_decoded() */ + ran_dec = (struct ran_dec) { + .caller_data = cell, + .decode_cb = msc_a_rx_vgcs_cell_decoded, + }; + struct ran_peer *ran_peer = from_conn->ran_peer; + struct ran_infra *ran = ran_peer->sri->ran; + if (!ran->ran_dec_l2) { + LOGP(DMSC, LOGL_ERROR, "No ran_dec_l2() defined for RAN type %s\n", + osmo_rat_type_name(ran->type)); + return -ENOTSUP; + } + return ran->ran_dec_l2(&ran_dec, msg); +} + static int msc_a_ran_dec_from_msc_t(struct msc_a *msc_a, struct msc_a_ran_dec_data *d) { struct msc_t *msc_t = msc_a_msc_t(msc_a); @@ -1544,23 +2005,32 @@ int _msc_a_msg_down(struct msc_a *msc_a, enum msc_role to_role, uint32_t to_role .an_proto = msc_a->c.ran->an_proto, .msg = msc_role_ran_encode(msc_a->c.fi, ran_msg), }; - int rc; if (!an_apdu.msg) return -EIO; - rc = _msub_role_dispatch(msc_a->c.msub, to_role, to_role_event, &an_apdu, file, line); - msgb_free(an_apdu.msg); - return rc; + return _msub_role_dispatch(msc_a->c.msub, to_role, to_role_event, &an_apdu, file, line); } int msc_a_tx_dtap_to_i(struct msc_a *msc_a, struct msgb *dtap) { struct ran_msg ran_msg; + struct gsm48_hdr *gh = msgb_l3(dtap) ? : dtap->data; + uint8_t pdisc = gsm48_hdr_pdisc(gh); + + if (!msc_a) { + LOGP(DMSC, LOGL_ERROR, "Attempt to send DTAP to NULL MSC-A, dropping message: %s %s\n", + gsm48_pdisc_name(pdisc), gsm48_pdisc_msgtype_name(pdisc, gsm48_hdr_msg_type(gh))); + msgb_free(dtap); + return -EIO; + } if (msc_a->c.ran->type == OSMO_RAT_EUTRAN_SGS) { /* The SGs connection to the MME always is at the MSC-A. */ return sgs_iface_tx_dtap_ud(msc_a, dtap); } + LOG_MSC_A(msc_a, LOGL_DEBUG, "Sending DTAP: %s %s\n", + gsm48_pdisc_name(pdisc), gsm48_pdisc_msgtype_name(pdisc, gsm48_hdr_msg_type(gh))); + ran_msg = (struct ran_msg){ .msg_type = RAN_MSG_DTAP, .dtap = dtap, @@ -1579,45 +2049,68 @@ struct msc_a *msc_a_for_vsub(const struct vlr_subscr *vsub, bool valid_conn_only int msc_tx_common_id(struct msc_a *msc_a, enum msc_role to_role) { struct vlr_subscr *vsub = msc_a_vsub(msc_a); + if (vsub == NULL) + return -ENODEV; struct ran_msg msg = { .msg_type = RAN_MSG_COMMON_ID, .common_id = { .imsi = vsub->imsi, + .last_eutran_plmn_present = vsub->sgs.last_eutran_plmn_present, }, }; + if (vsub->sgs.last_eutran_plmn_present) { + memcpy(&msg.common_id.last_eutran_plmn, &vsub->sgs.last_eutran_plmn, + sizeof(vsub->sgs.last_eutran_plmn)); + } return msc_a_ran_down(msc_a, to_role, &msg); } static int msc_a_start_assignment(struct msc_a *msc_a, struct gsm_trans *cc_trans) { - struct call_leg *cl = msc_a->cc.call_leg; + struct call_leg *cl; + bool cn_rtp_available; + bool ran_rtp_available; OSMO_ASSERT(!msc_a->cc.active_trans); msc_a->cc.active_trans = cc_trans; - OSMO_ASSERT(cc_trans && cc_trans->type == TRANS_CC); + cc_trans->cc.codecs.assignment = (struct sdp_audio_codec){}; - if (!cl) { - cl = msc_a->cc.call_leg = call_leg_alloc(msc_a->c.fi, - MSC_EV_CALL_LEG_TERM, - MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE, - MSC_EV_CALL_LEG_RTP_COMPLETE); - OSMO_ASSERT(cl); + OSMO_ASSERT(cc_trans && cc_trans->type == TRANS_CC); + cl = msc_a_ensure_call_leg(msc_a, cc_trans); + if (!cl) + return -EINVAL; - /* HACK: We put the connection in loopback mode at the beginnig to - * trick the hNodeB into doing the IuUP negotiation with itself. - * This is a hack we need because osmo-mgw does not support IuUP yet, see OS#2459. */ - if (msc_a->c.ran->type == OSMO_RAT_UTRAN_IU) - cl->crcx_conn_mode[RTP_TO_RAN] = MGCP_CONN_LOOPBACK; + /* See if we can set a preliminary codec. If not, pass none for the time being. */ + trans_cc_filter_run(cc_trans); + + cn_rtp_available = call_leg_local_ip(cl, RTP_TO_CN); + ran_rtp_available = call_leg_local_ip(cl, RTP_TO_RAN); + + /* Set up RTP ports for both RAN and CN side. Even though we ask for both at the same time, the + * osmo_mgcpc_ep_fsm automagically waits for the first CRCX to complete before firing the second CRCX. The one + * issued first here will also be the first CRCX sent to the MGW. Usually both still need to be set up. */ + if (!cn_rtp_available) + call_leg_ensure_ci(cl, RTP_TO_CN, cc_trans->call_id, cc_trans, + &cc_trans->cc.local.audio_codecs, NULL); + if (!ran_rtp_available) { + struct sdp_audio_codecs *codecs; + if (msc_a->c.ran->force_mgw_codecs_to_ran.count) + codecs = &msc_a->c.ran->force_mgw_codecs_to_ran; + else + codecs = &cc_trans->cc.local.audio_codecs; + return call_leg_ensure_ci(cl, RTP_TO_RAN, cc_trans->call_id, cc_trans, codecs, NULL); } - /* This will lead to either MSC_EV_CALL_LEG_LOCAL_ADDR_AVAILABLE or MSC_EV_CALL_LEG_TERM. - * If the local address is already known, then immediately trigger. */ - if (call_leg_local_ip(cl, RTP_TO_RAN)) + /* Should these already be set up, immediately continue by retriggering the events signalling that the RTP + * ports are available. The ordering is: first CN, then RAN. */ + if (cn_rtp_available && ran_rtp_available) return osmo_fsm_inst_dispatch(msc_a->c.fi, MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE, cl->rtp[RTP_TO_RAN]); - else - return call_leg_ensure_ci(msc_a->cc.call_leg, RTP_TO_RAN, cc_trans->callref, cc_trans, NULL, NULL); + else if (cn_rtp_available) + return osmo_fsm_inst_dispatch(msc_a->c.fi, MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE, cl->rtp[RTP_TO_CN]); + /* Otherwise wait for MGCP response and continue from there. */ + return 0; } int msc_a_try_call_assignment(struct gsm_trans *cc_trans) @@ -1626,7 +2119,7 @@ int msc_a_try_call_assignment(struct gsm_trans *cc_trans) OSMO_ASSERT(cc_trans->type == TRANS_CC); if (msc_a->cc.active_trans == cc_trans) { - /* Assignment for this trans already started earlier. */ + LOG_MSC_A(msc_a, LOGL_DEBUG, "Assignment for this trans already started earlier\n"); return 0; } @@ -1639,8 +2132,14 @@ int msc_a_try_call_assignment(struct gsm_trans *cc_trans) return msc_a_start_assignment(msc_a, cc_trans); } -const char *msc_a_cm_service_type_to_use(enum osmo_cm_service_type cm_service_type) +/* Map CM Service type to use token. + * Given a CM Service type, return a matching token intended for osmo_use_count. + * For unknown service type, return NULL. + */ +const char *msc_a_cm_service_type_to_use(struct msc_a *msc_a, enum osmo_cm_service_type cm_service_type) { + struct gsm_network *net = msc_a_net(msc_a); + switch (cm_service_type) { case GSM48_CMSERV_MO_CALL_PACKET: case GSM48_CMSERV_EMERGENCY: @@ -1652,6 +2151,18 @@ const char *msc_a_cm_service_type_to_use(enum osmo_cm_service_type cm_service_ty case GSM48_CMSERV_SUP_SERV: return MSC_A_USE_CM_SERVICE_SS; + case GSM48_CMSERV_VGCS: + if (net->asci.enable) + return MSC_A_USE_CM_SERVICE_GCC; + else + return NULL; + + case GSM48_CMSERV_VBS: + if (net->asci.enable) + return MSC_A_USE_CM_SERVICE_BCC; + else + return NULL; + default: return NULL; } diff --git a/src/libmsc/msc_a_remote.c b/src/libmsc/msc_a_remote.c index 84eff0730..3b9693e59 100644 --- a/src/libmsc/msc_a_remote.c +++ b/src/libmsc/msc_a_remote.c @@ -1,6 +1,6 @@ /* The MSC-A role implementation variant that forwards requests to/from a remote MSC. */ /* - * (C) 2019 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de> + * (C) 2019 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de> * All Rights Reserved * * SPDX-License-Identifier: AGPL-3.0+ @@ -179,8 +179,6 @@ static void msc_a_remote_send_handover_failure(struct msc_a *msc_a, enum gsm0808 return; msc_a_remote_msg_up_to_remote_msc(msc_a, MSC_ROLE_T, OSMO_GSUP_MSGT_E_PREPARE_HANDOVER_ERROR, &an_apdu); - msgb_free(an_apdu.msg); - return; } /* [MSC-A---------------------] [MSC-B---------------------] diff --git a/src/libmsc/msc_ho.c b/src/libmsc/msc_ho.c index 615b8cd70..54a959d2c 100644 --- a/src/libmsc/msc_ho.c +++ b/src/libmsc/msc_ho.c @@ -1,25 +1,21 @@ /* MSC Handover implementation */ /* - * (C) 2019 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de> + * (C) 2019 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de> * All Rights Reserved * * Author: Neels Hofmeyr * - * SPDX-License-Identifier: GPL-2.0+ + * SPDX-License-Identifier: AGPL-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 2 of the License, or + * 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 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. + * GNU Affero General Public License for more details. */ #include <osmocom/core/fsm.h> @@ -43,6 +39,7 @@ #include <osmocom/msc/call_leg.h> #include <osmocom/msc/rtp_stream.h> #include <osmocom/msc/mncc_call.h> +#include <osmocom/msc/codec_mapping.h> struct osmo_fsm msc_ho_fsm; @@ -62,14 +59,17 @@ static const struct osmo_tdef_state_timeout msc_ho_fsm_timeouts[32] = { static __attribute__((constructor)) void msc_ho_fsm_init() { - osmo_fsm_register(&msc_ho_fsm); + OSMO_ASSERT(osmo_fsm_register(&msc_ho_fsm) == 0); } void msc_ho_down_required_reject(struct msc_a *msc_a, enum gsm0808_cause cause) { - struct msc_i *msc_i = msc_a_msc_i(msc_a); + struct msc_i *msc_i; uint32_t event; + msc_i = msc_a_msc_i(msc_a); + OSMO_ASSERT(msc_i); + struct ran_msg ran_enc_msg = { .msg_type = RAN_MSG_HANDOVER_REQUIRED_REJECT, .handover_required_reject = { @@ -380,6 +380,8 @@ static void msc_ho_send_handover_request(struct msc_a *msc_a) struct vlr_subscr *vsub = msc_a_vsub(msc_a); struct gsm_network *net = msc_a_net(msc_a); struct gsm0808_channel_type channel_type; + struct gsm0808_speech_codec_list scl = {}; + struct gsm_trans *cc_trans = msc_a->cc.active_trans; struct ran_msg ran_enc_msg = { .msg_type = RAN_MSG_HANDOVER_REQUEST, .handover_request = { @@ -402,13 +404,57 @@ static void msc_ho_send_handover_request(struct msc_a *msc_a) }, }; - if (msc_a->cc.active_trans) { - if (mncc_bearer_cap_to_channel_type(&channel_type, &msc_a->cc.active_trans->bearer_cap)) { - msc_ho_failed(msc_a, GSM0808_CAUSE_EQUIPMENT_FAILURE, - "Failed to encode Bearer Cap to Channel Type\n"); + if (msc_a->geran_encr.key_len) + LOG_MSC_A(msc_a, LOGL_DEBUG, "HO Request with ciphering: A5/%d kc %s kc128 %s\n", + msc_a->geran_encr.alg_id - 1, + osmo_hexdump_nospc_c(OTC_SELECT, msc_a->geran_encr.key, msc_a->geran_encr.key_len), + msc_a->geran_encr.kc128_present ? + osmo_hexdump_nospc_c(OTC_SELECT, msc_a->geran_encr.kc128, sizeof(msc_a->geran_encr.kc128)) + : "-"); + + if (cc_trans) { + switch (cc_trans->bearer_cap.transfer) { + case GSM48_BCAP_ITCAP_SPEECH: + if (sdp_audio_codecs_to_gsm0808_channel_type(&channel_type, + &cc_trans->cc.local.audio_codecs)) { + msc_ho_failed(msc_a, GSM0808_CAUSE_EQUIPMENT_FAILURE, + "Failed to determine Channel Type for Handover Request message (speech)\n"); + return; + } + break; + case GSM48_BCAP_ITCAP_3k1_AUDIO: + case GSM48_BCAP_ITCAP_FAX_G3: + case GSM48_BCAP_ITCAP_UNR_DIG_INF: + if (csd_bs_list_to_gsm0808_channel_type(&channel_type, &cc_trans->cc.local.bearer_services)) { + msc_ho_failed(msc_a, GSM0808_CAUSE_EQUIPMENT_FAILURE, + "Failed to determine Channel Type for Handover Request message (CSD)\n"); + return; + } + break; + default: + msc_ho_failed(msc_a, GSM0808_CAUSE_EQUIPMENT_FAILURE, "Failed to create" + " Handover Request message for information transfer capability %d\n", + cc_trans->bearer_cap.transfer); return; } + ran_enc_msg.handover_request.geran.channel_type = &channel_type; + ran_enc_msg.handover_request.call_id_present = true; + ran_enc_msg.handover_request.call_id = cc_trans->call_id; + + /* Call assignment is now capable of re-assigning to overcome a codec mismatch with the remote call leg. + * But for inter-MSC handover, that is not supported yet. So keep here the old limitation of only + * offering the assigned codec. */ + if (sdp_audio_codec_is_set(&cc_trans->cc.codecs.assignment)) + sdp_audio_codec_to_speech_codec_list(&scl, &cc_trans->cc.codecs.assignment); + else + sdp_audio_codecs_to_speech_codec_list(&scl, &cc_trans->cc.local.audio_codecs); + if (!scl.len) { + msc_ho_failed(msc_a, GSM0808_CAUSE_EQUIPMENT_FAILURE, "Failed to compose" + " Codec List (MSC Preferred) for Handover Request message\n"); + return; + } + ran_enc_msg.handover_request.codec_list_msc_preferred = &scl; } gsm0808_cell_id_from_cgi(&ran_enc_msg.handover_request.cell_id_serving, CELL_IDENT_WHOLE_GLOBAL, &vsub->cgi); @@ -560,7 +606,7 @@ static int msc_ho_start_inter_msc_call_forwarding(struct msc_a *msc_a, struct ms /* Backup old cell's RTP IP:port and codec data */ msc_a->ho.old_cell.ran_remote_rtp = rtp_to_ran->remote; - msc_a->ho.old_cell.codec = rtp_to_ran->codec; + msc_a->ho.old_cell.codecs = rtp_to_ran->codecs; /* Blindly taken over from an MNCC trace of existing code: send an all-zero CCCAP: */ outgoing_call_req.fields |= MNCC_F_CCCAP; @@ -661,7 +707,7 @@ static void msc_ho_rx_request_ack(struct msc_a *msc_a, struct msc_a_ran_dec_data } msc_a->ho.new_cell.ran_remote_rtp = hra->ran_dec->handover_request_ack.remote_rtp; - if (osmo_sockaddr_str_is_set(&msc_a->ho.new_cell.ran_remote_rtp)) { + if (osmo_sockaddr_str_is_nonzero(&msc_a->ho.new_cell.ran_remote_rtp)) { LOG_HO(msc_a, LOGL_DEBUG, "Request Ack contains cell's RTP address " OSMO_SOCKADDR_STR_FMT "\n", OSMO_SOCKADDR_STR_FMT_ARGS(&msc_a->ho.new_cell.ran_remote_rtp)); } @@ -670,7 +716,7 @@ static void msc_ho_rx_request_ack(struct msc_a *msc_a, struct msc_a_ran_dec_data msc_a->ho.new_cell.codec = hra->ran_dec->handover_request_ack.codec; if (hra->ran_dec->handover_request_ack.codec_present) { LOG_HO(msc_a, LOGL_DEBUG, "Request Ack contains codec %s\n", - osmo_mgcpc_codec_name(msc_a->ho.new_cell.codec)); + gsm0808_speech_codec_type_name(msc_a->ho.new_cell.codec.type)); } } @@ -684,7 +730,7 @@ static void msc_ho_rtp_switch_to_new_cell(struct msc_a *msc_a) return; } - if (!osmo_sockaddr_str_is_set(&msc_a->ho.new_cell.ran_remote_rtp)) { + if (!osmo_sockaddr_str_is_nonzero(&msc_a->ho.new_cell.ran_remote_rtp)) { LOG_HO(msc_a, LOGL_DEBUG, "New cell's RTP IP:port not yet known, not switching RTP stream\n"); return; } @@ -697,7 +743,7 @@ static void msc_ho_rtp_switch_to_new_cell(struct msc_a *msc_a) /* Backup old cell's RTP IP:port and codec data */ msc_a->ho.old_cell.ran_remote_rtp = rtp_to_ran->remote; - msc_a->ho.old_cell.codec = rtp_to_ran->codec; + msc_a->ho.old_cell.codecs = rtp_to_ran->codecs; LOG_HO(msc_a, LOGL_DEBUG, "Switching RTP stream to new cell: from " OSMO_SOCKADDR_STR_FMT " to " OSMO_SOCKADDR_STR_FMT "\n", OSMO_SOCKADDR_STR_FMT_ARGS(&msc_a->ho.old_cell.ran_remote_rtp), @@ -716,10 +762,18 @@ static void msc_ho_rtp_switch_to_new_cell(struct msc_a *msc_a) /* Switch over to the new peer */ rtp_stream_set_remote_addr(rtp_to_ran, &msc_a->ho.new_cell.ran_remote_rtp); - if (msc_a->ho.new_cell.codec_present) - rtp_stream_set_codec(rtp_to_ran, msc_a->ho.new_cell.codec); - else + if (msc_a->ho.new_cell.codec_present) { + const struct codec_mapping *m; + m = codec_mapping_by_gsm0808_speech_codec_type(msc_a->ho.new_cell.codec.type); + /* TODO: use codec_mapping_by_gsm0808_speech_codec() to also match on codec.cfg */ + if (!m) + LOG_HO(msc_a, LOGL_ERROR, "Cannot resolve codec: %s\n", + gsm0808_speech_codec_type_name(msc_a->ho.new_cell.codec.type)); + else + rtp_stream_set_one_codec(rtp_to_ran, &m->sdp); + } else { LOG_HO(msc_a, LOGL_ERROR, "No codec is set\n"); + } rtp_stream_commit(rtp_to_ran); } @@ -738,7 +792,7 @@ static void msc_ho_rtp_rollback_to_old_cell(struct msc_a *msc_a) return; } - if (!osmo_sockaddr_str_is_set(&msc_a->ho.old_cell.ran_remote_rtp)) { + if (!osmo_sockaddr_str_is_nonzero(&msc_a->ho.old_cell.ran_remote_rtp)) { LOG_HO(msc_a, LOGL_DEBUG, "Have no RTP IP:port for the old cell, not switching back to\n"); return; } @@ -758,7 +812,7 @@ static void msc_ho_rtp_rollback_to_old_cell(struct msc_a *msc_a) /* Switch back to the old cell */ rtp_stream_set_remote_addr(rtp_to_ran, &msc_a->ho.old_cell.ran_remote_rtp); - rtp_stream_set_codec(rtp_to_ran, msc_a->ho.old_cell.codec); + rtp_stream_set_codecs(rtp_to_ran, &msc_a->ho.old_cell.codecs); rtp_stream_commit(rtp_to_ran); } diff --git a/src/libmsc/msc_i.c b/src/libmsc/msc_i.c index f7aab0db1..d3616f3ae 100644 --- a/src/libmsc/msc_i.c +++ b/src/libmsc/msc_i.c @@ -1,6 +1,6 @@ /* Code to manage a subscriber's MSC-I role */ /* - * (C) 2019 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de> + * (C) 2019 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de> * All Rights Reserved * * SPDX-License-Identifier: AGPL-3.0+ diff --git a/src/libmsc/msc_i_remote.c b/src/libmsc/msc_i_remote.c index 7b9598423..c5d22a2e3 100644 --- a/src/libmsc/msc_i_remote.c +++ b/src/libmsc/msc_i_remote.c @@ -1,6 +1,6 @@ /* The MSC-I role implementation variant that forwards requests to/from a remote MSC. */ /* - * (C) 2019 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de> + * (C) 2019 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de> * All Rights Reserved * * SPDX-License-Identifier: AGPL-3.0+ diff --git a/src/libmsc/msc_net_init.c b/src/libmsc/msc_net_init.c index 637ee74ea..1fc712aff 100644 --- a/src/libmsc/msc_net_init.c +++ b/src/libmsc/msc_net_init.c @@ -24,6 +24,7 @@ #include "config.h" #include <osmocom/core/tdef.h> +#include <osmocom/crypt/utran_cipher.h> #include <osmocom/msc/gsm_data.h> #include <osmocom/msc/vlr.h> @@ -31,10 +32,28 @@ #include <osmocom/msc/gsm_04_11_gsup.h> #include <osmocom/msc/gsm_09_11.h> +/* TODO: would be great to have all timer declarations in one place */ +#include <osmocom/msc/ran_infra.h> +#include <osmocom/msc/sccp_ran.h> +#include <osmocom/msc/call_leg.h> + struct osmo_tdef mncc_tdefs[] = { {} }; +struct osmo_tdef_group msc_tdef_group[] = { + { .name = "vlr", .tdefs = msc_tdefs_vlr, .desc = "VLR (Visitors Location Register)" }, + { .name = "mgw", .tdefs = g_mgw_tdefs, .desc = "MGW (Media Gateway) interface" }, + { .name = "mncc", .tdefs = mncc_tdefs, .desc = "MNCC (Mobile Network Call Control) interface" }, + { .name = "sccp", .tdefs = g_sccp_tdefs, .desc = "SCCP (Signalling Connection Control Part)" }, + { .name = "geran", .tdefs = msc_tdefs_geran, .desc = "GERAN (GSM EDGE Radio Access Network)" }, + { .name = "utran", .tdefs = msc_tdefs_utran, .desc = "UTRAN (UMTS Terrestrial Radio Access Network)" }, + { .name = "sgs", .tdefs = msc_tdefs_sgs, .desc = "SGs interface towards MME" }, + { /* terminator */ } +}; + +#include <osmocom/core/stat_item.h> + struct gsm_network *gsm_network_init(void *ctx, mncc_recv_cb_t mncc_recv) { struct gsm_network *net; @@ -47,18 +66,16 @@ struct gsm_network *gsm_network_init(void *ctx, mncc_recv_cb_t mncc_recv) /* Permit a compile-time default of A5/3 and A5/1 */ net->a5_encryption_mask = (1 << 3) | (1 << 1); - - /* Use 30 min periodic update interval as sane default */ - net->t3212 = 5; + /* Permit a compile-time default of UEA2 and UEA1 */ + net->uea_encryption_mask = (1 << OSMO_UTRAN_UEA2) | (1 << OSMO_UTRAN_UEA1); net->mncc_guard_timeout = 180; net->ncss_guard_timeout = 30; - net->paging_response_timer = MSC_PAGING_RESPONSE_TIMER_DEFAULT; - INIT_LLIST_HEAD(&net->trans_list); INIT_LLIST_HEAD(&net->upqueue); INIT_LLIST_HEAD(&net->neighbor_ident_list); + INIT_LLIST_HEAD(&net->asci.gcr_lists); /* init statistics */ net->msc_ctrs = rate_ctr_group_alloc(net, &msc_ctrg_desc, 0); @@ -66,8 +83,13 @@ struct gsm_network *gsm_network_init(void *ctx, mncc_recv_cb_t mncc_recv) talloc_free(net); return NULL; } - net->active_calls = osmo_counter_alloc("msc.active_calls"); - net->active_nc_ss = osmo_counter_alloc("msc.active_nc_ss"); + + net->statg = osmo_stat_item_group_alloc(net, &msc_statg_desc, 0); + if (!net->statg) { + rate_ctr_group_free(net->msc_ctrs); + talloc_free(net); + return NULL; + } net->mncc_tdefs = mncc_tdefs; net->mncc_recv = mncc_recv; @@ -108,17 +130,23 @@ int msc_gsup_client_start(struct gsm_network *net) net->gcm = gsup_client_mux_alloc(net); OSMO_ASSERT(net->gcm); + /* If no IPA name is configured, we need to provide a default + * right here, in order for the defaulted name to get inserted + * as source_name in GSUP response messages. */ + if (!net->msc_ipa_name) + net->msc_ipa_name = "unnamed-MSC"; + ipa_dev = talloc_zero(net->gcm, struct ipaccess_unit); ipa_dev->unit_name = "MSC"; - ipa_dev->serno = net->msc_ipa_name; /* NULL unless configured via VTY */ + ipa_dev->serno = net->msc_ipa_name; ipa_dev->swversion = PACKAGE_NAME "-" PACKAGE_VERSION; *net->gcm = (struct gsup_client_mux){ .rx_cb = { /* vlr.c sets up its own cb and data */ /* MSC-A and MSC-B set up their own cb and data */ - [OSMO_GSUP_MESSAGE_CLASS_SMS] = { .func = gsm411_gsup_rx, .data = net->vlr }, - [OSMO_GSUP_MESSAGE_CLASS_USSD] = { .func = gsm0911_gsup_rx, .data = net->vlr }, + [OSMO_GSUP_MESSAGE_CLASS_SMS] = { .func = gsm411_gsup_rx, .data = net }, + [OSMO_GSUP_MESSAGE_CLASS_USSD] = { .func = gsm0911_gsup_rx, .data = net }, }, }; diff --git a/src/libmsc/msc_t.c b/src/libmsc/msc_t.c index 8eefccc71..eb6c79784 100644 --- a/src/libmsc/msc_t.c +++ b/src/libmsc/msc_t.c @@ -1,6 +1,6 @@ /* The MSC-T role, a transitional RAN connection during Handover. */ /* - * (C) 2019 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de> + * (C) 2019 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de> * All Rights Reserved * * SPDX-License-Identifier: AGPL-3.0+ @@ -38,6 +38,7 @@ #include <osmocom/msc/vlr.h> #include <osmocom/msc/msc_i.h> #include <osmocom/msc/gsm_data.h> +#include <osmocom/msc/codec_mapping.h> static struct osmo_fsm msc_t_fsm; @@ -75,7 +76,7 @@ static int msc_t_assign_handover_number(struct msc_t *msc_t) int rc; uint64_t started_at; uint64_t ho_nr; - char ho_nr_str[VLR_MSISDN_LENGTH+1]; + char ho_nr_str[GSM23003_MSISDN_MAX_DIGITS+1]; struct gsm_network *net = msc_t_net(msc_t); bool usable = false; @@ -145,7 +146,6 @@ static void msc_t_send_handover_failure(struct msc_t *msc_t, enum gsm0808_cause return; msub_role_dispatch(msc_t->c.msub, MSC_ROLE_A, MSC_A_EV_FROM_T_PREPARE_HANDOVER_FAILURE, &an_apdu); - msgb_free(an_apdu.msg); } static int msc_t_ho_request_decode_and_store_cb(struct osmo_fsm_inst *msc_t_fi, void *data, @@ -160,7 +160,7 @@ static int msc_t_ho_request_decode_and_store_cb(struct osmo_fsm_inst *msc_t_fi, } msc_t->inter_msc.cell_id_target = ran_dec->handover_request.cell_id_target; - msc_t->inter_msc.callref = ran_dec->handover_request.call_id; + msc_t->inter_msc.call_id = ran_dec->handover_request.call_id; /* TODO other parameters...? * Global Call Reference @@ -238,7 +238,6 @@ static int msc_t_find_ran_peer_from_ho_request(struct msc_t *msc_t) static int msc_t_send_stored_ho_request__decode_cb(struct osmo_fsm_inst *msc_t_fi, void *data, const struct ran_msg *ran_dec) { - int rc; struct an_apdu an_apdu; struct msc_t *msc_t = msc_t_priv(msc_t_fi); struct osmo_sockaddr_str *rtp_ran_local = data; @@ -263,9 +262,7 @@ static int msc_t_send_stored_ho_request__decode_cb(struct osmo_fsm_inst *msc_t_f }; if (!an_apdu.msg) return -EIO; - rc = msc_t_down_l2_co(msc_t, &an_apdu, true); - msgb_free(an_apdu.msg); - return rc; + return msc_t_down_l2_co(msc_t, &an_apdu, true); } /* The MGW endpoint is created, we know our AoIP Transport Layer Address and can send the Handover Request to the RAN @@ -361,8 +358,8 @@ void msc_t_fsm_wait_local_rtp_onenter(struct osmo_fsm_inst *fi, uint32_t prev_st MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE, MSC_EV_CALL_LEG_RTP_COMPLETE); if (!msc_t->inter_msc.call_leg - || call_leg_ensure_ci(msc_t->inter_msc.call_leg, RTP_TO_RAN, msc_t->inter_msc.callref, NULL, NULL, NULL) - || call_leg_ensure_ci(msc_t->inter_msc.call_leg, RTP_TO_CN, msc_t->inter_msc.callref, NULL, NULL, NULL)) { + || call_leg_ensure_ci(msc_t->inter_msc.call_leg, RTP_TO_RAN, msc_t->inter_msc.call_id, NULL, NULL, NULL) + || call_leg_ensure_ci(msc_t->inter_msc.call_leg, RTP_TO_CN, msc_t->inter_msc.call_id, NULL, NULL, NULL)) { msc_t_error("Failed to set up call leg\n"); return; } @@ -417,7 +414,7 @@ static int msc_t_patch_and_send_ho_request_ack(struct msc_t *msc_t, const struct struct rtp_stream *rtp_cn = msc_t->inter_msc.call_leg? msc_t->inter_msc.call_leg->rtp[RTP_TO_CN] : NULL; /* Since it's BCD, it needs rounded-up half the char* length of an MSISDN plus a type byte. * But no need to introduce obscure math to save a few stack bytes, just have more. */ - uint8_t msisdn_enc_buf[VLR_MSISDN_LENGTH + 1]; + uint8_t msisdn_enc_buf[GSM23003_MSISDN_MAX_DIGITS+1]; /* Copy an_apdu and an_apdu->e_info in "copy-on-write" method, because they are const and we * need to add the Handover Number to e_info. */ const struct ran_handover_request_ack *r = &ran_dec->handover_request_ack; @@ -444,7 +441,7 @@ static int msc_t_patch_and_send_ho_request_ack(struct msc_t *msc_t, const struct /* Also need to fetch the RTP IP:port from AoIP Transport Address IE to tell the MGW about it */ if (rtp_ran) { - if (osmo_sockaddr_str_is_set(&r->remote_rtp)) { + if (osmo_sockaddr_str_is_nonzero(&r->remote_rtp)) { LOG_MSC_T(msc_t, LOGL_DEBUG, "From Handover Request Ack, got " OSMO_SOCKADDR_STR_FMT "\n", OSMO_SOCKADDR_STR_FMT_ARGS(&r->remote_rtp)); rtp_stream_set_remote_addr(rtp_ran, &r->remote_rtp); @@ -452,11 +449,20 @@ static int msc_t_patch_and_send_ho_request_ack(struct msc_t *msc_t, const struct LOG_MSC_T(msc_t, LOGL_DEBUG, "No RTP IP:port in Handover Request Ack\n"); } if (r->codec_present) { - LOG_MSC_T(msc_t, LOGL_DEBUG, "From Handover Request Ack, got %s\n", - osmo_mgcpc_codec_name(r->codec)); - rtp_stream_set_codec(rtp_ran, r->codec); - if (rtp_cn) - rtp_stream_set_codec(rtp_cn, r->codec); + const struct codec_mapping *m = codec_mapping_by_gsm0808_speech_codec_type(r->codec.type); + /* TODO: use codec_mapping_by_gsm0808_speech_codec() to also match on codec.cfg */ + if (!m) { + LOG_MSC_T(msc_t, LOGL_ERROR, "Cannot resolve codec in Handover Request Ack: %s / %s\n", + gsm0808_speech_codec_type_name(r->codec.type), + m ? sdp_audio_codec_to_str(&m->sdp) : "(unknown)"); + } else { + LOG_MSC_T(msc_t, LOGL_DEBUG, "From Handover Request Ack, got codec %s / %s\n", + gsm0808_speech_codec_type_name(r->codec.type), + sdp_audio_codec_to_str(&m->sdp)); + rtp_stream_set_one_codec(rtp_ran, &m->sdp); + if (rtp_cn) + rtp_stream_set_one_codec(rtp_cn, &m->sdp); + } } else { LOG_MSC_T(msc_t, LOGL_DEBUG, "No codec in Handover Request Ack\n"); } @@ -472,9 +478,7 @@ static int msc_t_patch_and_send_ho_request_ack(struct msc_t *msc_t, const struct if (!an_apdu.msg) return -EIO; /* Send to remote MSC via msc_a_remote role */ - rc = msub_role_dispatch(msc_t->c.msub, MSC_ROLE_A, MSC_A_EV_FROM_T_PREPARE_HANDOVER_RESPONSE, &an_apdu); - msgb_free(an_apdu.msg); - return rc; + return msub_role_dispatch(msc_t->c.msub, MSC_ROLE_A, MSC_A_EV_FROM_T_PREPARE_HANDOVER_RESPONSE, &an_apdu); } static int msc_t_wait_ho_request_ack_decode_cb(struct osmo_fsm_inst *msc_t_fi, void *data, diff --git a/src/libmsc/msc_t_remote.c b/src/libmsc/msc_t_remote.c index 22c4e22fd..aea763337 100644 --- a/src/libmsc/msc_t_remote.c +++ b/src/libmsc/msc_t_remote.c @@ -1,6 +1,6 @@ /* The MSC-T role implementation variant that forwards requests to/from a remote MSC. */ /* - * (C) 2019 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de> + * (C) 2019 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de> * All Rights Reserved * * SPDX-License-Identifier: AGPL-3.0+ diff --git a/src/libmsc/msc_vgcs.c b/src/libmsc/msc_vgcs.c new file mode 100644 index 000000000..264fa4953 --- /dev/null +++ b/src/libmsc/msc_vgcs.c @@ -0,0 +1,2765 @@ +/* Handle VGCS/VBCS calls. (Voice Group/Broadcast Call Service). */ +/* + * (C) 2023 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de> + * All Rights Reserved + * + * SPDX-License-Identifier: AGPL-3.0+ + * + * Author: Andreas Eversberg + * + * 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/>. + */ + +/* The process consists of four state machines: + * + * The call control state machine "GCC" handles the voice group/broadcast call. + * There is one instance for every call. It is mainly controlled by the calling + * subscriber. The state machine is described in 3GPP TS 44.068 / 44.069. + * One SCCP connection to the calling subscriber is associated with the state + * machine. Once the calling subscriber leaves or is assigned to the VGCS/VBS + * channel, the association to the MSC-A role is removed and the SCCP connection + * is closed. The state machine with the transaction still exists until the end + * of the call. + * + * The BSS control state machine "vgcs_bss_fsm" handles the call in each BSC. + * There are as many instances as there are BSCs where the call is placed to. + * The instances are linked to the call control in a 1:n relation. + * One SCCP connection for every BSC is associated with the state machine. + * It sets up the call in the BSC and handles the uplink control and signaling + * with the talking phone. + * + * The resource controling state machine "vgcs_cell_fsm" handles the channel for + * each BTS that has a VGCS for the call. The instances are linked to the BSS + * control in a 1:n relation. + * One SCCP connection for every cell is associated with each list entry. + * It assigns the VGCS/VBS channel and the conference bridge in the MGW. + * + * The MGW endpoint state machine "vgcs_mgw_ep_fsm" handles the endpoint + * connection for each call. It controls the clearing of the MGW connections + * in case of endpoint failure. All instances of the resource controlling state + * machine are linked to this state machine in a 1:n relation. + * + * Setup of a call: + * + * When the calling subscriber dials a group/broadcast call, the GCR is checked + * for an existing Group ID. If it exists, the call is setup towards the a given + * list of MSCs for this Group ID. Also the channels are assigned for a given + * list of cells for this Group ID. + * The call can also be initiated via VTY. + * + * Then the calling subscriber is assigned to the VGCS channel of the same cell + * where the call was initialized. Afterwards the call is connected. The calling + * subscriber may then stay on the uplink or release it. + * + * Uplink control: + * + * Any BSC may indicate a talking subscriber. If there is no talking subscriber + * yet, the uplink is granted, otherwise it is rejected. If the uplink is in + * use on one BSC, all other BSCs will be blocked. If the uplink becomes free, + * all other BSCs will be unblocked. + * + * Termination of the call: + * + * The calling subscriber accesses the uplink. The it sends a termination + * request. This request is acknowledged by a termination command towards + * the calling subscriber. The call is cleared. + * The call can also be terminated via VTY and/or a timeout. + * + */ + +#include <osmocom/core/utils.h> +#include <osmocom/core/fsm.h> +#include <osmocom/gsm/protocol/gsm_44_068.h> +#include <osmocom/sigtran/sccp_helpers.h> +#include <osmocom/mgcp_client/mgcp_client_endpoint_fsm.h> + +#include <osmocom/msc/gsm_data.h> +#include <osmocom/msc/sccp_ran.h> +#include <osmocom/msc/ran_infra.h> +#include <osmocom/msc/ran_peer.h> +#include <osmocom/msc/ran_msg_a.h> +#include <osmocom/msc/msub.h> +#include <osmocom/msc/debug.h> +#include <osmocom/msc/msc_a.h> +#include <osmocom/msc/vlr.h> +#include <osmocom/msc/rtp_stream.h> +#include <osmocom/msc/codec_mapping.h> +#include <osmocom/msc/msc_vgcs.h> +#include <osmocom/msc/asci_gcr.h> + +#define S(x) (1 << (x)) + +#define LOG_GCC(trans, level, fmt, args...) \ + LOGP((trans) ? ((trans->type == TRANS_GCC) ? DGCC : DBCC) : DASCI, level, \ + (trans) ? ((trans->type == TRANS_GCC) ? ("GCC callref %s: " fmt) : ("BCC callref %s: " fmt)) : "%s" fmt, \ + (trans) ? gsm44068_group_id_string(trans->callref) : "", ##args) +#define LOG_BSS(bss, level, fmt, args...) \ + LOGP(DASCI, level, \ + (bss->trans_type == TRANS_GCC) ? ("GCC callref %s, BSS #%s: " fmt) : ("BCC callref %s, BSS #%s: " fmt), \ + gsm44068_group_id_string(bss->callref), osmo_ss7_pointcode_print(NULL, bss->pc), ##args) +#define LOG_CELL(cell, level, fmt, args...) \ + LOGP(DASCI, level, \ + (cell->trans_type == TRANS_GCC) ? ("GCC callref %s, BSS #%s, CID %d: " fmt) \ + : ("BCC callref %s, BSS #%s, CID %d: " fmt), \ + gsm44068_group_id_string(cell->callref), osmo_ss7_pointcode_print(NULL, cell->pc), cell->cell_id, ##args) + +static struct osmo_fsm vgcs_bcc_fsm; +static struct osmo_fsm vgcs_gcc_fsm; +static struct osmo_fsm vgcs_bss_fsm; +static struct osmo_fsm vgcs_cell_fsm; +static struct osmo_fsm vgcs_mgw_ep_fsm; + +static __attribute__((constructor)) void vgcs_fsm_init(void) +{ + OSMO_ASSERT(osmo_fsm_register(&vgcs_bcc_fsm) == 0); + OSMO_ASSERT(osmo_fsm_register(&vgcs_gcc_fsm) == 0); + OSMO_ASSERT(osmo_fsm_register(&vgcs_bss_fsm) == 0); + OSMO_ASSERT(osmo_fsm_register(&vgcs_cell_fsm) == 0); + OSMO_ASSERT(osmo_fsm_register(&vgcs_mgw_ep_fsm) == 0); +} + +const char *gsm44068_group_id_string(uint32_t callref) +{ + static char string[9]; + + snprintf(string, sizeof(string), "%08u", callref); + string[sizeof(string) - 1] = '\0'; + + return string; +} + +/* Resolve ran peer from point-code */ +static struct ran_peer *ran_peer_for_pc(struct gsm_network *msc_network, int pc) +{ + struct sccp_ran_inst *sri; + struct osmo_sccp_addr addr = {}; + struct ran_peer *rp; + + sri = msc_network->a.sri; + if (!osmo_sccp_get_ss7(sri->sccp)) { + LOGP(DASCI, LOGL_ERROR, "No SS7???\n"); + return NULL; + } + osmo_sccp_make_addr_pc_ssn(&addr, pc, sri->ran->ssn); + rp = ran_peer_find_by_addr(sri, &addr); + + return rp; +} + +/* Encode message and send towards BSC. */ +int ran_encode_and_send(struct osmo_fsm_inst *fi, struct ran_msg *ran_msg, struct ran_conn *conn, bool initial) +{ + struct msgb *l3_msg; + int rc; + + l3_msg = ran_a_encode(fi, ran_msg); + if (!l3_msg) { + LOGP(DASCI, LOGL_ERROR, "ran_a_encode() failed.\n"); + return -EINVAL; + } + rc = ran_conn_down_l2_co(conn, l3_msg, initial); + msgb_free(l3_msg); + + return rc; +} + +/* Transmit DTAP message to talker + * This is used for sending group/broadcast call control messages. */ +int tx_dtap_to_talker(struct vgcs_bss *bss, struct msgb *l3_msg) +{ + struct ran_msg ran_msg; + struct gsm48_hdr *gh = msgb_l3(l3_msg) ? : l3_msg->data; + uint8_t pdisc = gsm48_hdr_pdisc(gh); + int rc; + + + LOG_BSS(bss, LOGL_DEBUG, "Sending DTAP: %s %s\n", + gsm48_pdisc_name(pdisc), gsm48_pdisc_msgtype_name(pdisc, gsm48_hdr_msg_type(gh))); + + ran_msg = (struct ran_msg){ + .msg_type = RAN_MSG_DTAP, + .dtap = l3_msg, + }; + + rc = ran_encode_and_send(bss->fi, &ran_msg, bss->conn, false); + + return rc; +} + +/* + * GCC/BCC Message transcoding + */ + +static void _add_cause_ie(struct msgb *msg, uint8_t cause, uint8_t *diag, uint8_t diag_len) +{ + uint8_t *ie = msgb_put(msg, 2 + diag_len); + + ie[0] = 1 + diag_len; + ie[1] = cause; + if (diag && diag_len) { + ie[1] |= 0x80; + memcpy(ie + 2, diag, diag_len); + } +} + +static void _add_callref_ie(struct msgb *msg, uint32_t callref, bool with_prio, uint8_t prio) +{ + uint32_t ie; + + ie = callref << 5; + if (with_prio) + ie |= 0x10 | (prio << 1); + msgb_put_u32(msg, ie); +} + +static int _msg_too_short(void) +{ + LOGP(DASCI, LOGL_ERROR, "MSG too short.\n"); + return -EINVAL; +} + +static int _ie_invalid(void) +{ + LOGP(DASCI, LOGL_ERROR, "IE invalid.\n"); + return -EINVAL; +} + +static int _rx_callref(uint8_t *ie, unsigned int remaining_len, uint32_t *callref, bool *with_prio, uint8_t *prio) +{ + uint8_t ie_len; + + ie_len = sizeof(uint32_t); + if (remaining_len < ie_len) + return _msg_too_short(); + *callref = osmo_load32be(ie) >> 5; + if (ie[3] & 0x10) { + *with_prio = true; + *prio = (ie[3] >> 1) & 0x7; + } else + *with_prio = false; + + return ie_len; +} + +/* 3GPP TS 44.068 Clause 8.1 */ +static int gsm44068_tx_connect(struct gsm_trans *trans, uint8_t pdisc, uint32_t callref, bool with_prio, uint8_t prio, + uint8_t oi, uint8_t talker_prio, bool with_sms, uint8_t sms_dc, uint8_t sms_gp) +{ + struct msgb *msg = gsm44068_msgb_alloc_name("GSM 44.068 TX CONNECT"); + struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); + uint8_t ie; + + gh->proto_discr = pdisc; + gh->msg_type = OSMO_GSM44068_MSGT_CONNECT; + _add_callref_ie(msg, callref, with_prio, prio); + ie = (talker_prio << 4) | oi; + msgb_put_u8(msg, ie); + if (with_sms) { + ie = OSMO_GSM44068_IEI_SMS_INDICATIONS | (sms_dc << 1) | sms_gp; + msgb_put_u8(msg, ie); + } + + /* Send to calling subscriber, depending on the link he is. */ + if (trans->msc_a) + return msc_a_tx_dtap_to_i(trans->msc_a, msg); + if (trans->gcc.uplink_bss) + return tx_dtap_to_talker(trans->gcc.uplink_bss, msg); + msgb_free(msg); + return -EIO; +} + +/* The Get Status procedure is not used by the current implementation. + * It is commented out, so it can be used in the future. + * The idea is to have a complete set of GCC/BCC message transcoding. + */ +#if 0 +/* 3GPP TS 44.068 Clause 8.2 */ +static int gsm44068_tx_get_status(struct gsm_trans *trans, uint8_t pdisc, struct osmo_mobile_identity *mi) +{ + struct msgb *msg = gsm44068_msgb_alloc_name("GSM 44.068 TX GET STATUS"); + struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); + + gh->proto_discr = pdisc; + gh->msg_type = OSMO_GSM44068_MSGT_GET_STATUS; + if (mi) { + uint8_t *l; + int rc; + + l = msgb_tl_put(msg, OSMO_GSM44068_IEI_MOBILE_IDENTITY); + rc = osmo_mobile_identity_encode_msgb(msg, mi, false); + if (rc < 0) { + msgb_free(msg); + return -EINVAL; + } + *l = rc; + } + + /* Send to calling subscriber, depending on the link he is. */ + if (trans->msc_a) + return msc_a_tx_dtap_to_i(trans->msc_a, msg); + if (trans->gcc.uplink_bss) + return tx_dtap_to_talker(trans->gcc.uplink_bss, msg); + msgb_free(msg); + return -EIO; +} +#endif + +/* 3GPP TS 44.068 Clause 8.3 and 8.3a */ +static int gsm44068_rx_immediate_setup(struct msgb *msg, uint8_t *talker_prio, uint8_t *key_seq, + struct gsm48_classmark2 *cm2, struct osmo_mobile_identity *mi, + uint32_t *callref, bool *with_prio, uint8_t *prio, char *user_user) +{ + struct gsm48_hdr *gh = msgb_l3(msg); + unsigned int remaining_len = msgb_l3len(msg) - sizeof(*gh); + uint8_t *ie = gh->data; + uint8_t ie_len; + uint64_t otdi; + int i; + int rc; + + /* Talker priority / Cyphering key sequence */ + if (remaining_len < 1) + return _msg_too_short(); + *talker_prio = ie[0] & 0x07; + *key_seq = (ie[0] >> 4) & 0x07; + remaining_len -= 1; + ie += 1; + + /* Mobile station classmark 2 */ + if (remaining_len < 4) + return _msg_too_short(); + ie_len = ie[0]; + if (remaining_len < ie_len + 1) + return _msg_too_short(); + if (ie_len != 3) + return _ie_invalid(); + memcpy(cm2, ie + 1, ie_len); + remaining_len -= ie_len + 1; + ie += ie_len + 1; + + /* Mobile indentity */ + if (gh->msg_type == OSMO_GSM44068_MSGT_IMMEDIATE_SETUP) { + /* IMMEDIATE SETUP uses IMSI/TMSI */ + if (remaining_len < 2) + return _msg_too_short(); + ie_len = ie[0]; + if (remaining_len < ie_len + 1) + return _msg_too_short(); + rc = osmo_mobile_identity_decode(mi, ie + 1, ie_len, false); + if (rc) { + LOGP(DMM, LOGL_ERROR, "Failure to decode Mobile Identity in GCC/BCC IMMEDDIATE SETUP" + " (rc=%d)\n", rc); + return -EINVAL; + } + remaining_len -= ie_len + 1; + ie += ie_len + 1; + } else { + /* IMMEDIATE SETUP 2 uses TMSI only */ + if (remaining_len < 4) + return _msg_too_short(); + mi->type = GSM_MI_TYPE_TMSI; + mi->tmsi = osmo_load32be(ie); + remaining_len -= 4; + ie += 4; + } + + /* Call reference */ + rc = _rx_callref(ie, remaining_len, callref, with_prio, prio); + if (rc < 0) + return rc; + remaining_len -= rc; + ie += rc; + + /* OTID */ + if (gh->msg_type == OSMO_GSM44068_MSGT_IMMEDIATE_SETUP_2 && user_user) { + ie_len = 5; + if (remaining_len < ie_len) + return _msg_too_short(); + otdi = osmo_load32be(ie + 1) | ((uint64_t)ie[0] << 32); + + for (i = 0; i < 12; i++) { + user_user[i] = (otdi % 10) + '0'; + otdi /= 10; + } + user_user[i] = '\0'; + remaining_len -= ie_len; + ie += ie_len; + } else if (user_user) + user_user[0] = '\0'; + + return 0; +} + +/* 3GPP TS 44.068 Clause 8.4 */ +static int gsm44068_tx_set_parameter(struct gsm_trans *trans, uint8_t pdisc, uint8_t da, uint8_t ua, uint8_t comm, + uint8_t oi) +{ + struct msgb *msg = gsm44068_msgb_alloc_name("GSM 44.068 TX SET PARAMETER"); + struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); + uint8_t ie; + + gh->proto_discr = pdisc; + gh->msg_type = OSMO_GSM44068_MSGT_SET_PARAMETER; + ie = (da << 3) | (ua << 2) | (comm << 1) | oi; + msgb_put_u8(msg, ie); + + /* Send to calling subscriber, depending on the link he is. */ + if (trans->msc_a) + return msc_a_tx_dtap_to_i(trans->msc_a, msg); + if (trans->gcc.uplink_bss) + return tx_dtap_to_talker(trans->gcc.uplink_bss, msg); + msgb_free(msg); + return -EIO; +} + +/* 3GPP TS 44.068 Clause 8.5 */ +static int gsm44068_rx_setup(struct msgb *msg, bool *with_talker_prio, uint8_t *talker_prio, + uint32_t *callref, bool *with_prio, uint8_t *prio, char *user_user) +{ + struct gsm48_hdr *gh = msgb_l3(msg); + unsigned int remaining_len = msgb_l3len(msg) - sizeof(*gh); + uint8_t *ie = gh->data; + struct tlv_parsed tp; + struct tlv_p_entry *tlv; + int rc; + + /* Call reference */ + rc = _rx_callref(ie, remaining_len, callref, with_prio, prio); + if (rc < 0) + return rc; + remaining_len -= rc; + ie += rc; + + rc = tlv_parse(&tp, &osmo_gsm44068_att_tlvdef, ie, remaining_len, 0, 0); + if (rc < 0) + return _ie_invalid(); + + /* User-user */ + tlv = TLVP_GET(&tp, OSMO_GSM44068_IEI_USER_USER); + if (tlv && tlv->len && tlv->len <= 1 + 12 && user_user) { + memcpy(user_user, tlv->val, tlv->len - 1); + user_user[tlv->len - 1] = '\0'; + } + + /* Talker priority */ + tlv = TLVP_GET(&tp, OSMO_GSM44068_IEI_TALKER_PRIORITY); + if (tlv && tlv->len) { + *with_talker_prio = true; + *talker_prio = tlv->val[0] & 0x07; + } else + *with_talker_prio = false; + + return 0; +} + +/* 3GPP TS 44.068 Clause 8.6 */ +static int gsm44068_rx_status(struct msgb *msg, uint8_t *cause, uint8_t *diag, uint8_t *diag_len, + bool *with_call_state, enum osmo_gsm44068_call_state *call_state, + bool *with_state_attrs, uint8_t *da, uint8_t *ua, uint8_t *comm, uint8_t *oi) +{ + struct gsm48_hdr *gh = msgb_l3(msg); + unsigned int remaining_len = msgb_l3len(msg) - sizeof(*gh); + uint8_t *ie = gh->data; + uint8_t ie_len; + struct tlv_parsed tp; + struct tlv_p_entry *tlv; + int rc; + + /* Cause */ + if (remaining_len < 2 || ie[0] < remaining_len - 2) + return _msg_too_short(); + ie_len = ie[0]; + if (remaining_len < ie_len + 1) + return _msg_too_short(); + if (ie_len < 1) + return _ie_invalid(); + *cause = ie[1] & 0x7f; + *diag_len = ie_len - 1; + if (*diag_len) + memcpy(diag, ie + 2, ie_len - 1); + remaining_len -= ie_len + 1; + ie += ie_len + 1; + + rc = tlv_parse(&tp, &osmo_gsm44068_att_tlvdef, ie, remaining_len, 0, 0); + if (rc < 0) + return _ie_invalid(); + + /* Call state */ + tlv = TLVP_GET(&tp, OSMO_GSM44068_IEI_CALL_STATE); + if (tlv) { + *with_call_state = true; + *call_state = tlv->val[0] & 0x7; + } else + *with_call_state = false; + + /* State attributes */ + tlv = TLVP_GET(&tp, OSMO_GSM44068_IEI_STATE_ATTRIBUTES); + if (tlv) { + *with_state_attrs = true; + *da = (tlv->val[0] >> 3) & 0x1; + *ua = (tlv->val[0] >> 2) & 0x1; + *comm = (tlv->val[0] >> 1) & 0x1; + *oi = tlv->val[0] & 0x1; + } else + *with_state_attrs = false; + + return 0; +} + +/* 3GPP TS 44.068 Clause 8.7 and 8.8 */ +static int gsm44068_tx_termination(struct msc_a *msc_a, struct vgcs_bss *bss, uint8_t pdisc, uint8_t msg_type, + uint8_t cause, uint8_t *diag, uint8_t diag_len) +{ + struct msgb *msg = gsm44068_msgb_alloc_name("GSM 44.068 TX TERMINATION"); + struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); + + gh->proto_discr = pdisc; + gh->msg_type = msg_type; + _add_cause_ie(msg, cause, diag, diag_len); + + /* Send to calling subscriber, depending on the link he is. */ + if (msc_a) + return msc_a_tx_dtap_to_i(msc_a, msg); + if (bss) + return tx_dtap_to_talker(bss, msg); + msgb_free(msg); + return -EIO; +} + +/* 3GPP TS 44.068 Clause 8.9 */ +static int gsm44068_rx_termination_req(struct msgb *msg, uint32_t *callref, bool *with_prio, uint8_t *prio, + bool *with_talker_prio, uint8_t *talker_prio) +{ + struct gsm48_hdr *gh = msgb_l3(msg); + unsigned int remaining_len = msgb_l3len(msg) - sizeof(*gh); + uint8_t *ie = gh->data; + struct tlv_parsed tp; + struct tlv_p_entry *tlv; + int rc; + + /* Call reference */ + rc = _rx_callref(ie, remaining_len, callref, with_prio, prio); + if (rc < 0) + return rc; + remaining_len -= rc; + ie += rc; + + rc = tlv_parse(&tp, &osmo_gsm44068_att_tlvdef, ie, remaining_len, 0, 0); + if (rc < 0) + return _ie_invalid(); + + /* Talker priority */ + tlv = TLVP_GET(&tp, OSMO_GSM44068_IEI_TALKER_PRIORITY); + if (tlv && tlv->len) { + *with_talker_prio = true; + *talker_prio = tlv->val[0] & 0x07; + } else + *with_talker_prio = false; + + return 0; +} + +/* + * GCC/BCC state machine - handles calling subscriber process + */ + +static const struct value_string vgcs_gcc_fsm_event_names[] = { + OSMO_VALUE_STRING(VGCS_GCC_EV_NET_SETUP), + OSMO_VALUE_STRING(VGCS_GCC_EV_NET_TERM), + OSMO_VALUE_STRING(VGCS_GCC_EV_USER_SETUP), + OSMO_VALUE_STRING(VGCS_GCC_EV_USER_TERM), + OSMO_VALUE_STRING(VGCS_GCC_EV_BSS_ESTABLISHED), + OSMO_VALUE_STRING(VGCS_GCC_EV_BSS_ASSIGN_CPL), + OSMO_VALUE_STRING(VGCS_GCC_EV_BSS_ASSIGN_FAIL), + OSMO_VALUE_STRING(VGCS_GCC_EV_BSS_RELEASED), + OSMO_VALUE_STRING(VGCS_GCC_EV_TIMEOUT), + { } +}; + +static int gcc_establish_bss(struct gsm_trans *trans) +{ + struct gsm_network *net = trans->net; + struct vgcs_mgw_ep *mgw = NULL; + struct mgcp_client *mgcp_client; + struct gcr *gcr; + struct gcr_bss *b; + struct gcr_cell *c; + struct vgcs_bss *bss; + struct vgcs_bss_cell *cell; + struct osmo_fsm_inst *fi; + struct ran_peer *rp; + + /* Failure should not happen, because it has been checked before. */ + gcr = gcr_by_callref(trans->net, trans->type, trans->callref); + if (!gcr) + return -EINVAL; + + /* Allocate MGW endpoint. */ + mgcp_client = mgcp_client_pool_get(trans->net->mgw.mgw_pool); + if (!mgcp_client) { + LOG_GCC(trans, LOGL_ERROR, "No MGW client, please check config.\n"); + goto err_mgw; + } + fi = osmo_fsm_inst_alloc(&vgcs_mgw_ep_fsm, net, NULL, LOGL_DEBUG, NULL); + if (!fi) { + LOG_GCC(trans, LOGL_ERROR, "No memory for VGCS MSG state machine.\n"); + goto err_mgw; + } + osmo_fsm_inst_update_id(fi, "vgcs-mgw-ep"); + osmo_fsm_inst_state_chg(fi, VGCS_MGW_EP_ST_ACTIVE, 0, 0); + mgw = talloc_zero(fi, struct vgcs_mgw_ep); + if (!mgw) { + LOG_GCC(trans, LOGL_ERROR, "No memory for MGW ep structure.\n"); + osmo_fsm_inst_free(fi); + goto err_mgw; + } + mgw->fi = fi; + fi->priv = mgw; + INIT_LLIST_HEAD(&mgw->cell_list); + mgw->mgw_ep = osmo_mgcpc_ep_alloc(mgw->fi, VGCS_MGW_EP_EV_FREE, + mgcp_client, trans->net->mgw.tdefs, mgw->fi->id, + "%s", mgcp_client_rtpbridge_wildcard(mgcp_client)); + if (!mgw->mgw_ep) { + LOG_GCC(trans, LOGL_ERROR, "No memory for MGW endpoint state machine.\n"); + goto err_mgw; + } + + /* Create BSS list structures. */ + LOG_GCC(trans, LOGL_DEBUG, "Creating BSS list structure with cell list structures.\n"); + llist_for_each_entry(b, &gcr->bss_list, list) { + LOG_GCC(trans, LOGL_DEBUG, " -> BSS with PC %s.\n", osmo_ss7_pointcode_print(NULL, b->pc)); + /* Resolve ran_peer. */ + rp = ran_peer_for_pc(trans->net, b->pc); + if (!rp) { + LOG_GCC(trans, LOGL_ERROR, "Failed to resolve point code %s, skipping BSS!\n", + osmo_ss7_pointcode_print(NULL, b->pc)); + continue; + } + /* Create state machine. */ + fi = osmo_fsm_inst_alloc(&vgcs_bss_fsm, net, NULL, LOGL_DEBUG, NULL); + if (!fi) { + LOG_GCC(trans, LOGL_ERROR, "No memory for state machine.\n"); + break; + } + /* Create call structure. */ + bss = talloc_zero(fi, struct vgcs_bss); + if (!bss) { + LOG_GCC(trans, LOGL_ERROR, "No memory for BSS call structure.\n"); + osmo_fsm_inst_free(fi); + break; + } + bss->fi = fi; + fi->priv = bss; + INIT_LLIST_HEAD(&bss->cell_list); + bss->trans = trans; + bss->trans_type = trans->type; + bss->callref = trans->callref; + bss->pc = b->pc; + /* Create ran connection. */ + bss->conn = ran_conn_create_outgoing(rp); + if (!bss->conn) { + LOG_GCC(trans, LOGL_ERROR, "Failed to create RAN connection.\n"); + osmo_fsm_inst_free(bss->fi); + continue; + } + bss->conn->vgcs.bss = bss; + /* Create cell list structures. */ + llist_for_each_entry(c, &b->cell_list, list) { + LOG_GCC(trans, LOGL_DEBUG, " -> Cell ID %d.\n", c->cell_id); + /* Create state machine. */ + fi = osmo_fsm_inst_alloc(&vgcs_cell_fsm, net, NULL, LOGL_DEBUG, NULL); + if (!fi) { + LOG_GCC(trans, LOGL_ERROR, "No memory for state machine.\n"); + break; + } + /* Create cell structure. */ + cell = talloc_zero(fi, struct vgcs_bss_cell); + if (!cell) { + LOG_GCC(trans, LOGL_ERROR, "No memory for BSS cell structure.\n"); + osmo_fsm_inst_free(fi); + break; + } + cell->fi = fi; + fi->priv = cell; + osmo_fsm_inst_update_id_f(cell->fi, "vgcs-cell-%d", c->cell_id); + cell->trans_type = trans->type; + cell->callref = trans->callref; + cell->pc = b->pc; + cell->cell_id = c->cell_id; + cell->call_id = trans->call_id; + /* Create ran connection. */ + cell->conn = ran_conn_create_outgoing(rp); + if (!cell->conn) { + LOG_GCC(trans, LOGL_ERROR, "Failed to create RAN connection.\n"); + osmo_fsm_inst_free(cell->fi); + continue; + } + cell->conn->vgcs.cell = cell; + /* Attach to cell list of BSS and MGW endpoint */ + llist_add_tail(&cell->list_bss, &bss->cell_list); + cell->bss = bss; + llist_add_tail(&cell->list_mgw, &mgw->cell_list); + cell->mgw = mgw; + } + /* No cell? */ + if (llist_empty(&bss->cell_list)) { + LOG_GCC(trans, LOGL_DEBUG, " -> No Cell in this BSS.\n"); + osmo_fsm_inst_free(bss->fi); + break; + } + /* Attach to transaction list */ + llist_add_tail(&bss->list, &trans->gcc.bss_list); + /* Trigger VGCS/VBS SETUP */ + osmo_fsm_inst_dispatch(bss->fi, VGCS_BSS_EV_SETUP, NULL); + } + /* No BSS? */ + if (llist_empty(&trans->gcc.bss_list)) { + /* Also destroy MGW, because this list is empty too! */ + LOG_GCC(trans, LOGL_NOTICE, "No BSS found, please check your VTY configuration and add cells.\n"); + goto err_mgw; + } + return 0; + +err_mgw: + if (mgw) { + if (mgw->mgw_ep) { + /* This will also free FSM instance and vgcs_mgw_ep structure. */ + osmo_fsm_inst_dispatch(mgw->fi, VGCS_MGW_EP_EV_CLEAR, NULL); + return -EINVAL; + } + osmo_fsm_inst_free(mgw->fi); + } + return -EINVAL; +} + +/* Send Assignment Request to the calling subscriber. + * This is used to assign the subscriber from early assigned channel to the VGCS/VBS channel. */ +static int gcc_assign(struct gsm_trans *trans) +{ + struct ran_msg tx_ran_msg; + struct gsm0808_channel_type channel_type; + struct vgcs_bss *bss = NULL, *b; + + /* No assignment, because the calling subscriber is already assigned or there is no calling subscriber. */ + if (!trans->msc_a) + return 0; + + /* Check calling subscriber's MSC */ + struct ran_conn *conn = msub_ran_conn(trans->msc_a->c.msub); + if (!conn) { + LOG_GCC(trans, LOGL_ERROR, "Calling subscriber has no ran_conn????\n"); + return -EINVAL; + } + llist_for_each_entry(b, &trans->gcc.bss_list, list) { + if (osmo_sccp_addr_ri_cmp(&conn->ran_peer->peer_addr, &b->conn->ran_peer->peer_addr)) + continue; + bss = b; + break; + } + if (!bss) { + LOG_GCC(trans, LOGL_ERROR, "Calling subscriber comes from BSC that has no VGCS call.\n"); + return -EINVAL; + } + + /* For now we support GSM/FR V1 only. This shall be supported by all MS. */ + channel_type = (struct gsm0808_channel_type) { + .ch_indctr = GSM0808_CHAN_SPEECH, + .ch_rate_type = GSM0808_SPEECH_FULL_BM, + .perm_spch_len = 1, + .perm_spch[0] = GSM0808_PERM_FR1, + }; + + /* Send assignment to VGCS channel */ + tx_ran_msg = (struct ran_msg) { + .msg_type = RAN_MSG_ASSIGNMENT_COMMAND, + .assignment_command = { + .channel_type = &channel_type, + .callref_present = true, + .callref = { + .sf = (trans->type == TRANS_GCC), + }, + }, + }; + osmo_store32be_ext(trans->callref >> 3, &tx_ran_msg.assignment_command.callref.call_ref_hi, 3); + tx_ran_msg.assignment_command.callref.call_ref_lo = trans->callref & 0x7; + if (msc_a_ran_down(trans->msc_a, MSC_ROLE_I, &tx_ran_msg)) { + LOG_GCC(trans, LOGL_ERROR, "Cannot send Assignment\n"); + return -EIO; + } + + /* Assign Talker to BSS of the calling subscriber. */ + trans->gcc.uplink_bss = bss; + + return 0; +} + +/* Send CONNECT to the calling subscriber. */ +static void gcc_connect(struct gsm_trans *trans) +{ + uint8_t pdisc = (trans->type == TRANS_GCC) ? GSM48_PDISC_GROUP_CC : GSM48_PDISC_BCAST_CC; + int rc; + + /* Send CONNECT towards MS. */ + rc = gsm44068_tx_connect(trans, + pdisc | (trans->transaction_id << 4), + trans->callref, 0, 0, 1, 0, 0, 0, 0); + if (rc < 0) + LOG_GCC(trans, LOGL_ERROR, "Failed to send CONNECT towards MS. Continue anyway.\n"); +} + +/* Release dedicated (SDCCH) channel of calling subscriber after assigning to VGCS */ +static void release_msc_a(struct gsm_trans *trans) +{ + struct msc_a *msc_a = trans->msc_a; + + if (!msc_a) + return; + + trans->msc_a = NULL; + switch (trans->type) { + case TRANS_GCC: + msc_a_put(msc_a, MSC_A_USE_GCC); + break; + case TRANS_BCC: + msc_a_put(msc_a, MSC_A_USE_BCC); + break; + default: + break; + } +} + +/* Send TERMINATE to the calling/talking subscriber, then destroy transaction. */ +static void gcc_terminate_and_destroy(struct gsm_trans *trans, enum osmo_gsm44068_cause cause) +{ + uint8_t pdisc = (trans->type == TRANS_GCC) ? GSM48_PDISC_GROUP_CC : GSM48_PDISC_BCAST_CC; + int rc; + + /* Send TERMINATION towards MS. */ + rc = gsm44068_tx_termination(trans->msc_a, trans->gcc.uplink_bss, + pdisc | (trans->transaction_id << 4), + OSMO_GSM44068_MSGT_TERMINATION, + cause, NULL, 0); + if (rc < 0) + LOG_GCC(trans, LOGL_ERROR, "Failed to send TERMINATION towards MS. Continue anyway.\n"); + + /* Destroy transaction, note that also _gsm44068_gcc_trans_free() will be called by trans_free(). + * There the complete state machine is destroyed. */ + trans->callref = 0; + trans_free(trans); +} + +/* Send TERMINATION REJECT to the calling/talking subscriber. */ +static void gcc_termination_reject(struct gsm_trans *trans, enum osmo_gsm44068_cause cause) +{ + uint8_t pdisc = (trans->type == TRANS_GCC) ? GSM48_PDISC_GROUP_CC : GSM48_PDISC_BCAST_CC; + int rc; + + /* Send TERMINATION towards MS. */ + rc = gsm44068_tx_termination(trans->msc_a, trans->gcc.uplink_bss, + pdisc | (trans->transaction_id << 4), + OSMO_GSM44068_MSGT_TERMINATION_REJECT, + cause, NULL, 0); + if (rc < 0) + LOG_GCC(trans, LOGL_ERROR, "Failed to send TERMINATION REJECT towards MS.\n"); +} + +/* Start inactivity timer. + * This timer is used to terminate the call, if the radio connection to the caller gets lost. */ +static void start_inactivity_timer(struct gsm_trans *trans) +{ + if (trans->gcc.inactivity_to) { + LOG_GCC(trans, LOGL_DEBUG, "Set inactivity timer to %d seconds.\n", trans->gcc.inactivity_to); + osmo_timer_schedule(&trans->gcc.timer_inactivity, trans->gcc.inactivity_to, 0); + } +} + +static void stop_inactivity_timer(struct gsm_trans *trans) +{ + if (osmo_timer_pending(&trans->gcc.timer_inactivity)) { + LOG_GCC(trans, LOGL_DEBUG, "Stop pending inactivity timer.\n"); + osmo_timer_del(&trans->gcc.timer_inactivity); + } +} + +static void inactivity_timer_cb(void *data) +{ + struct gsm_trans *trans = data; + + osmo_fsm_inst_dispatch(trans->gcc.fi, VGCS_GCC_EV_TIMEOUT, NULL); +} + +/* Set the parameters of the talker. (downlink mute/unmute, uplink unmute, COMM=T, originator) */ +static int set_parameter(struct gsm_trans *trans) +{ + uint8_t pdisc = (trans->type == TRANS_GCC) ? GSM48_PDISC_GROUP_CC : GSM48_PDISC_BCAST_CC; + int rc; + + rc = gsm44068_tx_set_parameter(trans, pdisc | (trans->transaction_id << 4), + !trans->gcc.mute_talker, 1, 1, trans->gcc.uplink_originator); + if (rc < 0) + LOG_GCC(trans, LOGL_ERROR, "Failed to send SET PARAMETER towards MS.\n"); + return rc; +} + +/* Check in which cell the uplink is used and set "uplink_cell". */ +static int set_uplink_cell(struct vgcs_bss *bss, struct gsm0808_cell_id *cell_id_ie, uint16_t cell_id) +{ + struct vgcs_bss_cell *cell; + + if (cell_id_ie) { + /* Get cell ID to determine talker channel. */ + switch (cell_id_ie->id_discr) { + case CELL_IDENT_CI: + cell_id = cell_id_ie->id.ci; + break; + case CELL_IDENT_LAC_AND_CI: + cell_id = cell_id_ie->id.lac_and_ci.ci; + break; + default: + LOG_BSS(bss, LOGL_DEBUG, "Cannot idenitfy cell, please fix!\n"); + return -EINVAL; + } + } + + /* Search for cell ID. */ + bss->trans->gcc.uplink_cell = NULL; + llist_for_each_entry(cell, &bss->cell_list, list_bss) { + if (cell->cell_id == cell_id) { + LOG_BSS(bss, LOGL_DEBUG, "Talker is talking on cell %d.\n", cell->cell_id); + bss->trans->gcc.uplink_cell = cell; + return 0; + } + } + + LOG_BSS(bss, LOGL_DEBUG, "Cell ID %d is not in list of current BSS, please fix!\n", cell_id); + return -EINVAL; +} + +/* Set the MGW conference mode. + * All cells are listening to the conference. If there is a talker, this cell is also transmitting to the conference. */ +static int set_mgw_conference(struct gsm_trans *trans) +{ + struct vgcs_bss *bss; + struct vgcs_bss_cell *cell; + struct rtp_stream *rtps; + int rc; + + /* All cells without talker are listening */ + llist_for_each_entry(bss, &trans->gcc.bss_list, list) { + llist_for_each_entry(cell, &bss->cell_list, list_bss) { + if (!(rtps = cell->rtps)) + continue; + if (rtps->crcx_conn_mode != MGCP_CONN_SEND_ONLY) { + LOG_CELL(cell, LOGL_DEBUG, "Setting cell %d into listening mode.\n", cell->cell_id); + rtp_stream_set_mode(rtps, MGCP_CONN_SEND_ONLY); + rc = rtp_stream_commit(rtps); + if (rc < 0) + LOG_CELL(cell, LOGL_ERROR, "Failed to commit parameters to RTP stream " + "for cell %d.\n", cell->cell_id); + } + } + } + + if (trans->gcc.uplink_cell && trans->gcc.uplink_cell->rtps) { + cell = trans->gcc.uplink_cell; + rtps = cell->rtps; + LOG_CELL(cell, LOGL_DEBUG, "Setting cell %d into listening mode.\n", cell->cell_id); + rtp_stream_set_mode(rtps, MGCP_CONN_CONFECHO); + rc = rtp_stream_commit(rtps); + if (rc < 0) + LOG_CELL(cell, LOGL_ERROR, "Failed to commit parameters to RTP stream " + "for cell %d.\n", cell->cell_id); + } + + return 0; +} + +static void _assign_complete(struct gsm_trans *trans, bool send_connect) +{ + uint16_t cell_id; + + OSMO_ASSERT(trans->msc_a); + + /* Change state. */ + osmo_fsm_inst_state_chg(trans->gcc.fi, VGCS_GCC_ST_N2_CALL_ACTIVE, 0, 0); + /* Get cell ID. */ + cell_id = trans->msc_a->via_cell.cell_identity; + /* Releasing dedicated channel. */ + release_msc_a(trans); + /* Send CONNECT to the calling subscriber. */ + if (send_connect) + gcc_connect(trans); + /* Set parameter. */ + set_parameter(trans); + /* Start inactivity timer, if uplink is free. */ + if (!trans->gcc.uplink_busy) + start_inactivity_timer(trans); + /* Set cell of current talker. */ + set_uplink_cell(trans->gcc.uplink_bss, NULL, cell_id); + /* Set MGW conference. */ + set_mgw_conference(trans); +} + +#define CONNECT_OPTION false + +static void vgcs_gcc_fsm_n0_null(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct gsm_trans *trans = fi->priv; + int rc; + + switch (event) { + case VGCS_GCC_EV_NET_SETUP: + /* Establish call towards all BSSs. */ + LOG_GCC(trans, LOGL_DEBUG, "Setup by network, trying to establish cells.\n"); + rc = gcc_establish_bss(trans); + if (rc < 0) { + LOG_GCC(trans, LOGL_NOTICE, "Failed to setup call to any cell.\n"); + gcc_terminate_and_destroy(trans, OSMO_GSM44068_CAUSE_NETWORK_FAILURE); + break; + } + /* Keep state until established or released. */ + break; + case VGCS_GCC_EV_NET_TERM: + LOG_GCC(trans, LOGL_DEBUG, "Termination by network, destroying call.\n"); + /* Destroy group call in all cells. */ + gcc_terminate_and_destroy(trans, OSMO_GSM44068_CAUSE_NORMAL_CALL_CLEARING); + break; + case VGCS_GCC_EV_USER_SETUP: + LOG_GCC(trans, LOGL_DEBUG, "Setup by MS, trying to establish cells.\n"); + /* Change state. */ + osmo_fsm_inst_state_chg(fi, VGCS_GCC_ST_N1_CALL_INITIATED, 0, 0); + /* Establish call towards all BSSs. */ + rc = gcc_establish_bss(trans); + if (rc < 0) { + LOG_GCC(trans, LOGL_NOTICE, "Failed to setup call to any cell.\n"); + gcc_terminate_and_destroy(trans, OSMO_GSM44068_CAUSE_NETWORK_FAILURE); + break; + } + if (CONNECT_OPTION) { + /* Send CONNECT to the calling subscriber. */ + gcc_connect(trans); + /* Change state. */ + osmo_fsm_inst_state_chg(fi, VGCS_GCC_ST_N3_CALL_EST_PROC, 0, 0); + } + break; + case VGCS_GCC_EV_BSS_ESTABLISHED: + LOG_GCC(trans, LOGL_DEBUG, "All cells establised, for a group call, sending CONNECT to caller.\n"); + /* Change state. */ + osmo_fsm_inst_state_chg(fi, VGCS_GCC_ST_N2_CALL_ACTIVE, 0, 0); + /* Start inactivity timer, if uplink is free. */ + if (!trans->gcc.uplink_busy) + start_inactivity_timer(trans); + break; + case VGCS_GCC_EV_BSS_RELEASED: + LOG_GCC(trans, LOGL_DEBUG, "All group call in all cells failed, destroying call.\n"); + /* Send TERMINATE to the calling subscriber. */ + gcc_terminate_and_destroy(trans, OSMO_GSM44068_CAUSE_NETWORK_FAILURE); + break; + default: + OSMO_ASSERT(false); + } +} + +static void vgcs_gcc_fsm_n1_call_initiated(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct gsm_trans *trans = fi->priv; + int rc; + + switch (event) { + case VGCS_GCC_EV_NET_TERM: + LOG_GCC(trans, LOGL_DEBUG, "Termination by network, destroying call.\n"); + /* Destroy group call in all cells. */ + gcc_terminate_and_destroy(trans, OSMO_GSM44068_CAUSE_NORMAL_CALL_CLEARING); + break; + case VGCS_GCC_EV_USER_TERM: + LOG_GCC(trans, LOGL_DEBUG, "Termination by user, destroying call.\n"); + /* Send TERMINATE to the calling subscriber and destroy group call in all cells. */ + gcc_terminate_and_destroy(trans, OSMO_GSM44068_CAUSE_NORMAL_CALL_CLEARING); + break; + case VGCS_GCC_EV_BSS_ESTABLISHED: + LOG_GCC(trans, LOGL_DEBUG, "All cells establised, for a group call, assign caller to VGCS.\n"); + /* Send assignment to the calling subscriber. */ + rc = gcc_assign(trans); + if (rc < 0) { + gcc_terminate_and_destroy(trans, OSMO_GSM44068_CAUSE_NETWORK_FAILURE); + break; + } + break; + case VGCS_GCC_EV_BSS_ASSIGN_CPL: + LOG_GCC(trans, LOGL_DEBUG, "Assignment complete, sending CONNECT to caller, releasing channel.\n"); + /* Handle assignment complete */ + _assign_complete(trans, true); + break; + case VGCS_GCC_EV_BSS_ASSIGN_FAIL: + LOG_GCC(trans, LOGL_DEBUG, "Assignment failed, releasing call.\n"); + /* Send TERMINATE to the calling subscriber. */ + gcc_terminate_and_destroy(trans, OSMO_GSM44068_CAUSE_NETWORK_FAILURE); + break; + case VGCS_GCC_EV_BSS_RELEASED: + LOG_GCC(trans, LOGL_DEBUG, "All group call in all cells failed, destroying call.\n"); + /* Send TERMINATE to the calling subscriber. */ + gcc_terminate_and_destroy(trans, OSMO_GSM44068_CAUSE_NETWORK_FAILURE); + break; + default: + OSMO_ASSERT(false); + } +} + +static void vgcs_gcc_fsm_n2_call_active(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct gsm_trans *trans = fi->priv; + + switch (event) { + case VGCS_GCC_EV_NET_TERM: + LOG_GCC(trans, LOGL_DEBUG, "Termination by network, destroying call.\n"); + /* Destroy group call in all cells. */ + gcc_terminate_and_destroy(trans, OSMO_GSM44068_CAUSE_NORMAL_CALL_CLEARING); + break; + case VGCS_GCC_EV_USER_TERM: + if (!trans->gcc.uplink_originator) { + LOG_GCC(trans, LOGL_ERROR, "Termination by user, but it is not the originator.\n"); + gcc_termination_reject(trans, OSMO_GSM44068_CAUSE_USER_NOT_ORIGINATOR); + break; + } + LOG_GCC(trans, LOGL_DEBUG, "Termination by user, destroying call.\n"); + /* Send TERMINATE to the calling subscriber and destroy group call in all cells. */ + gcc_terminate_and_destroy(trans, OSMO_GSM44068_CAUSE_NORMAL_CALL_CLEARING); + break; + case VGCS_GCC_EV_BSS_RELEASED: + LOG_GCC(trans, LOGL_DEBUG, "All group call in all cells failed, destroying call.\n"); + /* Send TERMINATE to the calling subscriber. */ + gcc_terminate_and_destroy(trans, OSMO_GSM44068_CAUSE_NETWORK_FAILURE); + break; + case VGCS_GCC_EV_TIMEOUT: + LOG_GCC(trans, LOGL_DEBUG, "Termination by inactivity timer, destroying call.\n"); + /* Destroy group call in all cells. */ + gcc_terminate_and_destroy(trans, OSMO_GSM44068_CAUSE_NORMAL_CALL_CLEARING); + break; + default: + OSMO_ASSERT(false); + } +} + +static void vgcs_gcc_fsm_n3_call_est_proc(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct gsm_trans *trans = fi->priv; + int rc; + + switch (event) { + case VGCS_GCC_EV_NET_TERM: + LOG_GCC(trans, LOGL_DEBUG, "Termination by network, destroying call.\n"); + /* Destroy group call in all cells. */ + gcc_terminate_and_destroy(trans, OSMO_GSM44068_CAUSE_NORMAL_CALL_CLEARING); + break; + case VGCS_GCC_EV_USER_TERM: + LOG_GCC(trans, LOGL_DEBUG, "Termination by user, destroying call.\n"); + /* Send TERMINATE to the calling subscriber and destroy group call in all cells. */ + gcc_terminate_and_destroy(trans, OSMO_GSM44068_CAUSE_NORMAL_CALL_CLEARING); + break; + case VGCS_GCC_EV_BSS_ESTABLISHED: + LOG_GCC(trans, LOGL_DEBUG, "All cells establised, for a group call, assign caller to VGCS.\n"); + /* Send assignment to the calling subscriber. */ + rc = gcc_assign(trans); + if (rc < 0) { + gcc_terminate_and_destroy(trans, OSMO_GSM44068_CAUSE_NETWORK_FAILURE); + break; + } + break; + case VGCS_GCC_EV_BSS_ASSIGN_CPL: + LOG_GCC(trans, LOGL_DEBUG, "Assignment complete, sending CONNECT to caller, releasing channel.\n"); + /* Handle assignment complete */ + _assign_complete(trans, false); + break; + case VGCS_GCC_EV_BSS_ASSIGN_FAIL: + LOG_GCC(trans, LOGL_DEBUG, "Assignment failed, releasing call.\n"); + /* Send TERMINATE to the calling subscriber. */ + gcc_terminate_and_destroy(trans, OSMO_GSM44068_CAUSE_NETWORK_FAILURE); + break; + case VGCS_GCC_EV_BSS_RELEASED: + LOG_GCC(trans, LOGL_DEBUG, "All group call in all cells failed, destroying call.\n"); + /* Send TERMINATE to the calling subscriber. */ + gcc_terminate_and_destroy(trans, OSMO_GSM44068_CAUSE_NETWORK_FAILURE); + break; + default: + OSMO_ASSERT(false); + } +} + +static const struct osmo_fsm_state vgcs_gcc_fsm_states[] = { + [VGCS_GCC_ST_N0_NULL] = { + .name = "NULL (N0)", + .in_event_mask = S(VGCS_GCC_EV_NET_SETUP) | + S(VGCS_GCC_EV_NET_TERM) | + S(VGCS_GCC_EV_USER_SETUP) | + S(VGCS_GCC_EV_BSS_ESTABLISHED) | + S(VGCS_GCC_EV_BSS_RELEASED), + .out_state_mask = S(VGCS_GCC_ST_N1_CALL_INITIATED) | + S(VGCS_GCC_ST_N2_CALL_ACTIVE), + .action = vgcs_gcc_fsm_n0_null, + }, + [VGCS_GCC_ST_N1_CALL_INITIATED] = { + .name = "CALL INITATED (N1)", + .in_event_mask = S(VGCS_GCC_EV_NET_TERM) | + S(VGCS_GCC_EV_USER_TERM) | + S(VGCS_GCC_EV_BSS_ESTABLISHED) | + S(VGCS_GCC_EV_BSS_ASSIGN_CPL) | + S(VGCS_GCC_EV_BSS_ASSIGN_FAIL) | + S(VGCS_GCC_EV_BSS_RELEASED), + .out_state_mask = S(VGCS_GCC_ST_N0_NULL) | + S(VGCS_GCC_ST_N2_CALL_ACTIVE) | + S(VGCS_GCC_ST_N3_CALL_EST_PROC), + .action = vgcs_gcc_fsm_n1_call_initiated, + }, + [VGCS_GCC_ST_N2_CALL_ACTIVE] = { + .name = "CALL ACTIVE (N2)", + .in_event_mask = S(VGCS_GCC_EV_NET_TERM) | + S(VGCS_GCC_EV_USER_TERM) | + S(VGCS_GCC_EV_BSS_RELEASED) | + S(VGCS_GCC_EV_TIMEOUT), + .out_state_mask = S(VGCS_GCC_ST_N0_NULL), + .action = vgcs_gcc_fsm_n2_call_active, + }, + [VGCS_GCC_ST_N3_CALL_EST_PROC] = { + .name = "CALL EST PROCEEDING (N3)", + .in_event_mask = S(VGCS_GCC_EV_NET_TERM) | + S(VGCS_GCC_EV_USER_TERM) | + S(VGCS_GCC_EV_BSS_ESTABLISHED) | + S(VGCS_GCC_EV_BSS_ASSIGN_CPL) | + S(VGCS_GCC_EV_BSS_ASSIGN_FAIL) | + S(VGCS_GCC_EV_BSS_RELEASED), + .out_state_mask = S(VGCS_GCC_ST_N2_CALL_ACTIVE) | + S(VGCS_GCC_ST_N0_NULL), + .action = vgcs_gcc_fsm_n3_call_est_proc, + }, + // We don't need a state to wait for the group call to be terminated in all cells +}; + +static struct osmo_fsm vgcs_bcc_fsm = { + .name = "bcc", + .states = vgcs_gcc_fsm_states, + .num_states = ARRAY_SIZE(vgcs_gcc_fsm_states), + .log_subsys = DBCC, + .event_names = vgcs_gcc_fsm_event_names, +}; + +static struct osmo_fsm vgcs_gcc_fsm = { + .name = "gcc", + .states = vgcs_gcc_fsm_states, + .num_states = ARRAY_SIZE(vgcs_gcc_fsm_states), + .log_subsys = DGCC, + .event_names = vgcs_gcc_fsm_event_names, +}; + +const char *vgcs_bcc_gcc_state_name(struct osmo_fsm_inst *fi) +{ + return vgcs_gcc_fsm_states[fi->state].name; +} + +static int update_uplink_state(struct vgcs_bss *bss, bool uplink_busy); + +/* Receive RR messages from calling subscriber, prior assignment to VGCS/VBS. */ +int gsm44068_rcv_rr(struct msc_a *msc_a, struct msgb *msg) +{ + struct gsm_trans *trans = NULL; + struct gsm48_hdr *gh; + uint8_t msg_type; + + gh = msgb_l3(msg); + msg_type = gsm48_hdr_msg_type(gh); + + /* Find transaction. */ + trans = trans_find_by_type(msc_a, TRANS_GCC); + if (!trans) + trans = trans_find_by_type(msc_a, TRANS_BCC); + + if (!trans) { + LOG_GCC(trans, LOGL_ERROR, "No VGCS/VBS transaction.\n"); + return -EINVAL; + } + + /* In case the phone releases uplink prior being assigned to a VGCS */ + if (msg_type == GSM48_MT_RR_UPLINK_RELEASE) { + struct vgcs_bss *bss; + + LOG_GCC(trans, LOGL_INFO, "Received UPLINK RELEASE on initial channel.\n"); + /* Clear the busy flag and unblock all cells. */ + trans->gcc.uplink_bss = NULL; + trans->gcc.uplink_cell = NULL; + trans->gcc.uplink_busy = false; + llist_for_each_entry(bss, &trans->gcc.bss_list, list) { + /* Update uplink state. */ + update_uplink_state(bss, trans->gcc.uplink_busy); + } + /* Start inactivity timer. */ + start_inactivity_timer(bss->trans); + /* Next, the MS will switch to the VGCS as listener. Nothing else to do here. */ + } + + return 0; +} + +/* Allocation of transaction for group call */ +static struct gsm_trans *trans_alloc_vgcs(struct gsm_network *net, + struct vlr_subscr *vsub, + enum trans_type trans_type, uint8_t transaction_id, + uint32_t callref, + struct gcr *gcr, + bool uplink_busy) +{ + struct gsm_trans *trans; + + trans = trans_alloc(net, vsub, trans_type, transaction_id, callref); + if (!trans) { + LOG_GCC(trans, LOGL_ERROR, "No memory for trans.\n"); + return NULL; + } + /* The uplink is busy when the call is started until the calling subscriber releases. */ + trans->gcc.uplink_busy = uplink_busy; + trans->gcc.uplink_originator = true; + INIT_LLIST_HEAD(&trans->gcc.bss_list); + trans->gcc.inactivity_to = gcr->timeout; + trans->gcc.mute_talker = gcr->mute_talker; + trans->gcc.timer_inactivity.data = trans; + trans->gcc.timer_inactivity.cb = inactivity_timer_cb; + trans->gcc.fi = osmo_fsm_inst_alloc((trans_type == TRANS_GCC) ? &vgcs_gcc_fsm : &vgcs_bcc_fsm, + trans, trans, LOGL_DEBUG, NULL); + if (!trans->gcc.fi) { + LOG_GCC(trans, LOGL_ERROR, "No memory for state machine.\n"); + trans_free(trans); + return NULL; + } + + return trans; +} + +/* Create transaction from incoming voice group/broadcast call. */ +static struct gsm_trans *trans_create_bcc_gcc(struct msc_a *msc_a, enum trans_type trans_type, uint8_t transaction_id, + uint8_t pdisc, uint8_t msg_type, uint32_t callref) +{ + struct gsm_network *net; + struct vlr_subscr *vsub; + struct gsm_trans *trans = NULL; + struct gcr *gcr; + int rc; + + if (!msc_a) { + LOG_GCC(trans, LOGL_ERROR, "Invalid conn: no msc_a\n"); + return NULL; + } + net = msc_a_net(msc_a); + vsub = msc_a_vsub(msc_a); + + if (!vsub) { + LOG_GCC(trans, LOGL_ERROR, "Invalid conn: no subscriber\n"); + return NULL; + } + + /* An earlier CM Service Request for this CC message now has concluded */ + if (!osmo_use_count_by(&msc_a->use_count, + (trans_type == TRANS_GCC) ? MSC_A_USE_CM_SERVICE_GCC : MSC_A_USE_CM_SERVICE_BCC)) + LOG_MSC_A(msc_a, LOGL_ERROR, + "Creating new %s transaction without prior CM Service Request.\n", + get_value_string(trans_type_names, trans_type)); + else + msc_a_put(msc_a, + (trans_type == TRANS_GCC) ? MSC_A_USE_CM_SERVICE_GCC : MSC_A_USE_CM_SERVICE_BCC); + + /* A transaction must be created with a SETUP message. */ + if (msg_type != OSMO_GSM44068_MSGT_IMMEDIATE_SETUP + && msg_type != OSMO_GSM44068_MSGT_SETUP + && msg_type != OSMO_GSM44068_MSGT_IMMEDIATE_SETUP_2) { + LOG_GCC(trans, LOGL_ERROR, "No transaction and message is not a SETUP.\n"); + return NULL; + } + + /* Check if callref already exists. */ + trans = trans_find_by_callref(net, trans_type, callref); + if (trans) { + LOG_GCC(trans, LOGL_INFO, "Call to existing %s with callref %s, rejecting!\n", + trans_type_name(trans_type), gsm44068_group_id_string(callref)); + rc = gsm44068_tx_termination(msc_a, NULL, + pdisc | (transaction_id << 4), + OSMO_GSM44068_MSGT_TERMINATION, + OSMO_GSM44068_CAUSE_BUSY, NULL, 0); + if (rc < 0) + LOG_GCC(trans, LOGL_ERROR, "Failed to send TERMINATION towards MS.\n"); + return 0; + } + + /* Check GCR for Group ID. */ + gcr = gcr_by_callref(net, trans_type, callref); + if (!gcr) { + LOG_GCC(trans, LOGL_INFO, "No Group configured for %s callref %s, rejecting!\n", + trans_type_name(trans_type), gsm44068_group_id_string(callref)); + // FIXME: Better cause value for a group that does not exist ? + rc = gsm44068_tx_termination(msc_a, NULL, + pdisc | (transaction_id << 4), + OSMO_GSM44068_MSGT_TERMINATION, + OSMO_GSM44068_CAUSE_REQUESTED_SERVICE_NOT_SUB, NULL, 0); + if (rc < 0) + LOG_GCC(trans, LOGL_ERROR, "Failed to send TERMINATION towards MS.\n"); + return 0; + } + + /* Create transaction, uplink is busy. */ + trans = trans_alloc_vgcs(net, vsub, trans_type, transaction_id, callref, gcr, true); + if (!trans) { + rc = gsm44068_tx_termination(msc_a, NULL, + pdisc | (transaction_id << 4), + OSMO_GSM44068_MSGT_TERMINATION, + OSMO_GSM44068_CAUSE_NETWORK_FAILURE, NULL, 0); + if (rc < 0) + LOG_GCC(trans, LOGL_ERROR, "Failed to send TERMINATION towards MS.\n"); + return NULL; + } + + if (osmo_fsm_inst_dispatch(msc_a->c.fi, MSC_A_EV_TRANSACTION_ACCEPTED, trans)) { + LOG_MSC_A(msc_a, LOGL_ERROR, "Not allowed to accept %s transaction.\n", + get_value_string(trans_type_names, trans_type)); + gcc_terminate_and_destroy(trans, OSMO_GSM44068_CAUSE_NETWORK_FAILURE); + return NULL; + } + + /* Assign transaction */ + msc_a_get(msc_a, (trans_type == TRANS_GCC) ? MSC_A_USE_GCC : MSC_A_USE_BCC); + trans->msc_a = msc_a; + trans->dlci = 0; /* main DCCH */ + + return trans; +} + +/* Receive GCC/BCC messages from calling subscriber, depending on the PDISC used. */ +int gsm44068_rcv_bcc_gcc(struct msc_a *msc_a, struct gsm_trans *trans, struct msgb *msg) +{ + struct gsm48_hdr *gh = msgb_l3(msg); + uint8_t msg_type = gsm48_hdr_msg_type(gh); + uint8_t pdisc = gsm48_hdr_pdisc(gh); + uint8_t transaction_id = gsm48_hdr_trans_id_flip_ti(gh); + enum trans_type trans_type = (pdisc == GSM48_PDISC_GROUP_CC) ? TRANS_GCC : TRANS_BCC; + + uint8_t key_seq; + bool talker_prio_requested; + bool with_talker_prio; + uint8_t talker_prio; + struct gsm48_classmark2 cm2; + struct osmo_mobile_identity mi; + uint32_t callref; + bool with_prio; + uint8_t prio; + char user_user[64] = ""; + uint8_t cause; + uint8_t diag[256]; + uint8_t diag_len; + bool with_call_state; + enum osmo_gsm44068_call_state call_state; + bool with_state_attrs; + uint8_t da, ua, comm, oi; + int rc = 0; + + /* Remove sequence number (bit 7) from message type. */ + msg_type &= 0xbf; + + /* Parse messages. */ + switch (msg_type) { + case OSMO_GSM44068_MSGT_SETUP: + rc = gsm44068_rx_setup(msg, &talker_prio_requested, &talker_prio, &callref, &with_prio, &prio, + user_user); + break; + case OSMO_GSM44068_MSGT_IMMEDIATE_SETUP: + case OSMO_GSM44068_MSGT_IMMEDIATE_SETUP_2: + rc = gsm44068_rx_immediate_setup(msg, &talker_prio, &key_seq, &cm2, &mi, &callref, &with_prio, &prio, + user_user); + break; + case OSMO_GSM44068_MSGT_STATUS: + rc = gsm44068_rx_status(msg, &cause, diag, &diag_len, &with_call_state, &call_state, + &with_state_attrs, &da, &ua, &comm, &oi); + break; + case OSMO_GSM44068_MSGT_TERMINATION_REQUEST: + rc = gsm44068_rx_termination_req(msg, &callref, &with_prio, &prio, &with_talker_prio, &talker_prio); + break; + default: + LOG_GCC(trans, LOGL_ERROR, "Invalid message type: 0x%02x\n", msg_type); + return -EINVAL; + } + if (rc < 0) + return rc; + + /* Find transaction, if called from msc_a. */ + if (!trans) + trans = trans_find_by_id(msc_a, trans_type, transaction_id); + + /* Create transaction for SETUP message. */ + if (!trans) { + trans = trans_create_bcc_gcc(msc_a, trans_type, transaction_id, pdisc, msg_type, callref); + if (!trans) + return -EINVAL; + } else { + /* A phone may not call while a VGCS is already active */ + if (msg_type == OSMO_GSM44068_MSGT_IMMEDIATE_SETUP + || msg_type == OSMO_GSM44068_MSGT_SETUP + || msg_type == OSMO_GSM44068_MSGT_IMMEDIATE_SETUP_2) { + LOG_GCC(trans, LOGL_ERROR, "Received SETUP while call is already set up, rejecting.\n"); + rc = gsm44068_tx_termination(msc_a, NULL, + pdisc | (transaction_id << 4), + OSMO_GSM44068_MSGT_TERMINATION, + OSMO_GSM44068_CAUSE_NETWORK_FAILURE, NULL, 0); + if (rc < 0) + LOG_GCC(trans, LOGL_ERROR, "Failed to send TERMINATION towards MS.\n"); + return -EINVAL; + } + } + + /* Handle received GCC messages (trigger state machine). */ + switch (msg_type) { + case OSMO_GSM44068_MSGT_IMMEDIATE_SETUP: + case OSMO_GSM44068_MSGT_SETUP: + case OSMO_GSM44068_MSGT_IMMEDIATE_SETUP_2: + LOG_GCC(trans, LOGL_INFO, "Received SETUP.\n"); + osmo_fsm_inst_dispatch(trans->gcc.fi, VGCS_GCC_EV_USER_SETUP, NULL); + break; + case OSMO_GSM44068_MSGT_STATUS: + LOG_GCC(trans, LOGL_NOTICE, "Received STATUS with cause %d (%s).\n", cause, + get_value_string(osmo_gsm44068_cause_names, cause)); + if (diag_len) + LOG_GCC(trans, LOGL_NOTICE, " -> diagnostics: %s\n", osmo_hexdump(diag, diag_len)); + if (with_call_state) + LOG_GCC(trans, LOGL_NOTICE, " -> call state %s\n", + get_value_string(osmo_gsm44068_call_state_names, call_state)); + break; + case OSMO_GSM44068_MSGT_TERMINATION_REQUEST: + LOG_GCC(trans, LOGL_INFO, "Received TERMINATRION REQUEST.\n"); + if (callref != trans->callref) { + LOG_GCC(trans, LOGL_NOTICE, "Received callref 0x%x does not match!\n", callref); + break; + } + osmo_fsm_inst_dispatch(trans->gcc.fi, VGCS_GCC_EV_USER_TERM, NULL); + break; + } + + return 0; +} + +static void bss_clear(struct vgcs_bss *bss, uint8_t cause, bool notify_trans); + +/* Call Control Specific transaction release. + * gets called by trans_free, DO NOT CALL YOURSELF! */ +void gsm44068_bcc_gcc_trans_free(struct gsm_trans *trans) +{ + struct vgcs_bss *bss, *bss2; + + /* Free FSM. */ + if (trans->gcc.fi) { + osmo_fsm_inst_state_chg(trans->gcc.fi, VGCS_GCC_ST_N0_NULL, 0, 0); + osmo_fsm_inst_term(trans->gcc.fi, OSMO_FSM_TERM_REGULAR, NULL); + } + + /* Remove relations to cells. + * We must loop safe, because bss_clear() will detach every call control instance from list. */ + llist_for_each_entry_safe(bss, bss2, &trans->gcc.bss_list, list) + osmo_fsm_inst_dispatch(bss->fi, VGCS_BSS_EV_CLEAR, NULL); + + /* Stop inactivity timer. */ + stop_inactivity_timer(trans); +} + +/* Create a new call from VTY command. */ +const char *vgcs_vty_initiate(struct gsm_network *gsmnet, struct gcr *gcr) +{ + enum trans_type trans_type; + uint32_t callref; + struct gsm_trans *trans; + + /* Get callref from stored suffix. Caller cannot choose a prefix. */ + trans_type = gcr->trans_type; + callref = atoi(gcr->group_id); + + /* Check if callref already exists. */ + trans = trans_find_by_callref(gsmnet, trans_type, callref); + if (trans) { + LOG_GCC(trans, LOGL_INFO, "Call to existing %s with callref %s, rejecting!\n", + trans_type_name(trans_type), gsm44068_group_id_string(callref)); + return "Call already exists."; + } + + /* Create transaction, uplink is free. */ + trans = trans_alloc_vgcs(gsmnet, NULL, trans_type, 0, callref, gcr, false); + if (!trans) { + LOG_GCC(trans, LOGL_ERROR, "No memory for trans.\n"); + return "Failed to create call."; + } + + LOG_GCC(trans, LOGL_INFO, "VTY initiates call.\n"); + osmo_fsm_inst_dispatch(trans->gcc.fi, VGCS_GCC_EV_NET_SETUP, NULL); + + return NULL; +} + +/* Destroy a call from VTY command. */ +const char *vgcs_vty_terminate(struct gsm_network *gsmnet, struct gcr *gcr) +{ + enum trans_type trans_type; + uint32_t callref; + struct gsm_trans *trans; + + /* Get callref from stored suffix. Caller cannot choose a prefix. */ + trans_type = gcr->trans_type; + callref = atoi(gcr->group_id); + + /* Check if callref exists. */ + trans = trans_find_by_callref(gsmnet, trans_type, callref); + if (!trans) + return "Call does not exist."; + + LOG_GCC(trans, LOGL_INFO, "VTY terminates call.\n"); + osmo_fsm_inst_dispatch(trans->gcc.fi, VGCS_GCC_EV_NET_TERM, NULL); + + return NULL; +} + +/* + * BSS state machine - handles all BSS "call control" instances + */ + +static const struct value_string vgcs_bss_fsm_event_names[] = { + OSMO_VALUE_STRING(VGCS_BSS_EV_SETUP), + OSMO_VALUE_STRING(VGCS_BSS_EV_SETUP_ACK), + OSMO_VALUE_STRING(VGCS_BSS_EV_SETUP_REFUSE), + OSMO_VALUE_STRING(VGCS_BSS_EV_ACTIVE_OR_FAIL), + OSMO_VALUE_STRING(VGCS_BSS_EV_UL_REQUEST), + OSMO_VALUE_STRING(VGCS_BSS_EV_UL_REQUEST_CNF), + OSMO_VALUE_STRING(VGCS_BSS_EV_UL_APP_DATA), + OSMO_VALUE_STRING(VGCS_BSS_EV_BSS_DTAP), + OSMO_VALUE_STRING(VGCS_BSS_EV_UL_RELEASE), + OSMO_VALUE_STRING(VGCS_BSS_EV_CLEAR), + OSMO_VALUE_STRING(VGCS_BSS_EV_CLOSE), + OSMO_VALUE_STRING(VGCS_BSS_EV_RELEASED), + { } +}; + +/* Blocks or unblocks uplinks of a BSS. */ +static int update_uplink_state(struct vgcs_bss *bss, bool uplink_busy) +{ + struct ran_msg ran_msg; + int rc; + + if (uplink_busy) { + /* Send UPLINK SEIZED COMMAND to BSS. */ + LOG_BSS(bss, LOGL_DEBUG, "Sending (VGCS) UPLINK SEIZED COMMAND towards BSS.\n"); + ran_msg = (struct ran_msg){ + .msg_type = RAN_MSG_UPLINK_SEIZED_CMD, + .uplink_seized_cmd = { + .cause = GSM0808_CAUSE_CALL_CONTROL, + }, + }; + } else { + /* Send UPLINK RELEASE COMMAND to BSS. */ + LOG_BSS(bss, LOGL_DEBUG, "Sending (VGCS) UPLINK RELEASE COMMAND towards BSS.\n"); + ran_msg = (struct ran_msg){ + .msg_type = RAN_MSG_UPLINK_RELEASE_CMD, + .uplink_release_cmd = { + .cause = GSM0808_CAUSE_CALL_CONTROL, + }, + }; + } + + rc = ran_encode_and_send(bss->fi, &ran_msg, bss->conn, false); + + return rc; +} + +/* Clear the connection towards BSS. + * The instance is removed soon, so it is detached from transaction and cells. */ +static void bss_clear(struct vgcs_bss *bss, uint8_t cause, bool notify_trans) +{ + struct ran_msg ran_msg; + struct gsm_trans *trans = bss->trans; + struct vgcs_bss_cell *cell, *cell2; + + /* Must detach us from transaction. */ + if (bss->trans) { + /* Remove pointer to talking BSS and cell. */ + if (bss == bss->trans->gcc.uplink_bss) { + bss->trans->gcc.uplink_bss = NULL; + bss->trans->gcc.uplink_cell = NULL; + } + llist_del(&bss->list); + bss->trans = NULL; + } + + /* Change state. */ + osmo_fsm_inst_state_chg(bss->fi, VGCS_BSS_ST_RELEASE, 0, 0); + + /* Send Clear Command to BSS. */ + ran_msg = (struct ran_msg){ + .msg_type = RAN_MSG_CLEAR_COMMAND, + .clear_command = { + .gsm0808_cause = cause, + }, + }; + if (bss->conn) { + LOG_BSS(bss, LOGL_DEBUG, "Sending CLEAR COMMAND for call controling channel.\n"); + ran_encode_and_send(bss->fi, &ran_msg, bss->conn, false); + } + + /* Trigger clear of all cells. Be safe, because the process will remove cells from list. */ + llist_for_each_entry_safe(cell, cell2, &bss->cell_list, list_bss) + osmo_fsm_inst_dispatch(cell->fi, VGCS_CELL_EV_CLEAR, NULL); + + /* Detach us from all BSS, if still linked */ + llist_for_each_entry_safe(cell, cell2, &bss->cell_list, list_bss) { + llist_del(&cell->list_bss); + cell->bss = NULL; + } + + /* If all BS are gone, notify calling subscriber process. */ + if (notify_trans && trans && llist_empty(&trans->gcc.bss_list)) { + LOG_BSS(bss, LOGL_DEBUG, "Notify calling user process, that all BSSs are cleared.\n"); + osmo_fsm_inst_dispatch(trans->gcc.fi, VGCS_GCC_EV_BSS_RELEASED, NULL); + } +} + +/* When finally the BSS connection is released. (CLEAR COMPLETE response) + * The instance is removed, so it is detached from transaction and cells, if not already. */ +static void bss_destroy(struct vgcs_bss *bss) +{ + struct vgcs_bss_cell *cell, *cell2; + + LOG_BSS(bss, LOGL_DEBUG, "Removing BSS call controling instance.\n"); + + /* Must detach us from transaction, if not already. */ + if (bss->trans) { + /* Remove pointer to talking BSS and cell. */ + if (bss == bss->trans->gcc.uplink_bss) { + bss->trans->gcc.uplink_bss = NULL; + bss->trans->gcc.uplink_cell = NULL; + } + llist_del(&bss->list); + bss->trans = NULL; + } + + /* Detach us from RAN connection. */ + if (bss->conn) { + if (bss->conn->vgcs.bss == bss) + bss->conn->vgcs.bss = NULL; + if (bss->conn->vgcs.cell == bss) + bss->conn->vgcs.cell = NULL; + ran_conn_close(bss->conn); + bss->conn = NULL; + } + + /* Detach us from all BSS, if still linked */ + llist_for_each_entry_safe(cell, cell2, &bss->cell_list, list_bss) { + llist_del(&cell->list_bss); + cell->bss = NULL; + } + + /* Free FSM. (should be allocated) */ + osmo_fsm_inst_state_chg(bss->fi, VGCS_BSS_ST_NULL, 0, 0); + osmo_fsm_inst_term(bss->fi, OSMO_FSM_TERM_REGULAR, NULL); +} + +/* Get identity of talker. + * This is required to detect if the talker is the calling subscriber. */ +static int talker_identity(struct vgcs_bss *bss, uint8_t *l3, int l3_len) +{ + struct osmo_mobile_identity mi; + int rc; + + rc = osmo_mobile_identity_decode_from_l3_buf(&mi, l3, l3_len, false); + if (rc < 0) { + LOG_BSS(bss, LOGL_DEBUG, "Talker's Identity cannot be decoded.\n"); + return rc; + } + + switch (mi.type) { + case GSM_MI_TYPE_IMSI: + if (!bss->trans->vsub) + break; + LOG_BSS(bss, LOGL_DEBUG, "Talker's sends IMSI %s, originator has IMSI %s.\n", + mi.imsi, bss->trans->vsub->imsi); + if (!strcmp(mi.imsi, bss->trans->vsub->imsi)) + return 1; + break; + case GSM_MI_TYPE_TMSI: + if (!bss->trans->vsub) + break; + LOG_BSS(bss, LOGL_DEBUG, "Talker's sends TMSI 0x%08x, originator has TMSI 0x%08x.\n", + mi.tmsi, bss->trans->vsub->tmsi); + if (mi.tmsi == bss->trans->vsub->tmsi) + return 1; + break; + default: + LOG_BSS(bss, LOGL_DEBUG, "Talker's Identity is not IMSI nor TMSI.\n"); + return -EINVAL; + } + + return 0; +} + +static void vgcs_bss_fsm_null(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct vgcs_bss *bss = fi->priv; + struct ran_msg ran_msg; + + switch (event) { + case VGCS_BSS_EV_SETUP: + /* Change state. */ + osmo_fsm_inst_state_chg(fi, VGCS_BSS_ST_SETUP, 0, 0); + /* Send VGCS/VBS SETUP to BSS. */ + LOG_BSS(bss, LOGL_DEBUG, "Sending VGCS/VBS SETUP towards BSS.\n"); + ran_msg = (struct ran_msg){ + .msg_type = RAN_MSG_VGCS_VBS_SETUP, + .vgcs_vbs_setup = { + .callref = { + .sf = (bss->trans->type == TRANS_GCC), + }, + .vgcs_feature_flags_present = true, + }, + }; + osmo_store32be_ext(bss->callref >> 3, &ran_msg.vgcs_vbs_setup.callref.call_ref_hi, 3); + ran_msg.vgcs_vbs_setup.callref.call_ref_lo = bss->callref & 0x7; + /* First message, so we must set "initial" to "true". */ + ran_encode_and_send(fi, &ran_msg, bss->conn, true); + break; + case VGCS_BSS_EV_CLEAR: + /* The calling user process requested clearing of VGCS/VBS call. */ + LOG_BSS(bss, LOGL_DEBUG, "Received clearing from calling user process.\n"); + bss_clear(bss, GSM0808_CAUSE_CALL_CONTROL, false); + break; + default: + OSMO_ASSERT(false); + } +} + +static void vgcs_bss_fsm_setup(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct vgcs_bss *bss = fi->priv; + struct vgcs_bss_cell *cell, *cell2; + + switch (event) { + case VGCS_BSS_EV_SETUP_ACK: + /* Receive VGCS/VBS SETUP ACK from BSS. */ + LOG_BSS(bss, LOGL_DEBUG, "Received VGCS/VBS SETUP ACK from BSS.\n"); + /* Send current uplink state to this BSS. */ + if (bss->trans) + update_uplink_state(bss, bss->trans->gcc.uplink_busy); + /* Change state. */ + osmo_fsm_inst_state_chg(fi, VGCS_BSS_ST_ASSIGNMENT, 0, 0); + /* Trigger VGCS/VBS ASSIGNMENT */ + llist_for_each_entry_safe(cell, cell2, &bss->cell_list, list_bss) + osmo_fsm_inst_dispatch(cell->fi, VGCS_CELL_EV_ASSIGN, NULL); + /* If all failed, clear call. */ + if (llist_empty(&bss->cell_list)) { + LOG_BSS(bss, LOGL_NOTICE, "All VGCS/VBS assignments failed.\n"); + bss_clear(bss, GSM0808_CAUSE_PROTOCOL_ERROR_BETWEEN_BSS_AND_MSC, true); + break; + } + break; + case VGCS_BSS_EV_SETUP_REFUSE: + /* Received VGCS/VBS SETUP REFUSE from BSS. */ + LOG_BSS(bss, LOGL_NOTICE, "Received VGCS/VBS SETUP REFUSE from BSS.\n"); + bss_clear(bss, GSM0808_CAUSE_PROTOCOL_ERROR_BETWEEN_BSS_AND_MSC, true); + break; + case VGCS_BSS_EV_CLEAR: + /* The calling user process requested clearing of VGCS/VBS call. */ + LOG_BSS(bss, LOGL_DEBUG, "Received clearing from calling user process.\n"); + bss_clear(bss, GSM0808_CAUSE_CALL_CONTROL, false); + break; + case VGCS_BSS_EV_CLOSE: + /* The SCCP connection from the MSC has been closed. */ + LOG_BSS(bss, LOGL_NOTICE, "Received SCCP connecting closing from MSC.\n"); + if (bss->conn) { + bss->conn->vgcs.bss = NULL; + bss->conn = NULL; + } + bss_clear(bss, GSM0808_CAUSE_PROTOCOL_ERROR_BETWEEN_BSS_AND_MSC, true); + break; + default: + OSMO_ASSERT(false); + } +} + +static void vgcs_bss_fsm_assignment(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct vgcs_bss *bss = fi->priv; + struct vgcs_bss_cell *c; + bool assigned; + + switch (event) { + case VGCS_BSS_EV_ACTIVE_OR_FAIL: + /* If all gone, clear call. */ + if (llist_empty(&bss->cell_list)) { + LOG_BSS(bss, LOGL_NOTICE, "All VGCS/VBS assignments failed.\n"); + bss_clear(bss, GSM0808_CAUSE_PROTOCOL_ERROR_BETWEEN_BSS_AND_MSC, true); + break; + } + /* Is there a response for all cells? + * This means that all the channels have a positive response + * There is no channel with negative response, because a + * negative response will remove the channel. */ + assigned = true; + llist_for_each_entry(c, &bss->cell_list, list_bss) { + if (!c->assigned) + assigned = false; + } + if (!assigned) + break; + LOG_BSS(bss, LOGL_DEBUG, "All VGCS/VBS assignments have responded.\n"); + /* Change state. */ + osmo_fsm_inst_state_chg(fi, VGCS_BSS_ST_ACTIVE, 0, 0); + /* Notify calling subscriber process. */ + LOG_BSS(bss, LOGL_DEBUG, "Notify calling user process, that all BSSs are connected.\n"); + if (bss->trans) + osmo_fsm_inst_dispatch(bss->trans->gcc.fi, VGCS_GCC_EV_BSS_ESTABLISHED, NULL); + break; + case VGCS_BSS_EV_CLEAR: + /* The calling user process requested clearing of VGCS/VBS call. */ + LOG_BSS(bss, LOGL_DEBUG, "Received clearing from calling user process.\n"); + bss_clear(bss, GSM0808_CAUSE_CALL_CONTROL, false); + break; + case VGCS_BSS_EV_CLOSE: + /* The SCCP connection from the MSC has been closed. */ + LOG_BSS(bss, LOGL_NOTICE, "Received SCCP connecting closing from MSC.\n"); + if (bss->conn) { + bss->conn->vgcs.bss = NULL; + bss->conn = NULL; + } + bss_clear(bss, GSM0808_CAUSE_PROTOCOL_ERROR_BETWEEN_BSS_AND_MSC, true); + break; + default: + OSMO_ASSERT(false); + } +} + +static void vgcs_bss_fsm_active(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct vgcs_bss *bss = fi->priv, *other; + struct ran_msg *rx_ran_msg = data; + struct ran_msg tx_ran_msg; + int rc; + + switch (event) { + case VGCS_BSS_EV_UL_REQUEST: + LOG_BSS(bss, LOGL_DEBUG, "Listener changed to talker.\n"); + if (!bss->trans) + break; + /* Someone is talking. Check if there is no other uplink already busy. + * This should not happen, since all other cells are blocked (SEIZED) as soon as the uplink was + * requested. This may happen due to a race condition, where the uplink was requested before the + * UPLINK SEIZED COMMAND has been received by BSS. */ + if (bss->trans->gcc.uplink_busy) { + /* Send UPLINK REJECT COMMAND to BSS. */ + LOG_BSS(bss, LOGL_DEBUG, "Sending (VGCS) UPLINK REJECT COMMAND towards BSS.\n"); + tx_ran_msg = (struct ran_msg){ + .msg_type = RAN_MSG_UPLINK_REJECT_CMD, + .uplink_reject_cmd = { + .cause = GSM0808_CAUSE_CALL_CONTROL, + }, + }; + ran_encode_and_send(fi, &tx_ran_msg, bss->conn, false); + break; + } + /* Send UPLINK REQUEST ACKNOWLEDGE to BSS. */ + LOG_BSS(bss, LOGL_DEBUG, "Sending (VGCS) UPLINK REQUEST ACKNOWLEDGE towards BSS.\n"); + tx_ran_msg = (struct ran_msg){ + .msg_type = RAN_MSG_UPLINK_REQUEST_ACK, + }; + ran_encode_and_send(fi, &tx_ran_msg, bss->conn, false); + /* Set the busy flag and block all other cells. */ + bss->trans->gcc.uplink_bss = bss; + bss->trans->gcc.uplink_busy = true; + bss->trans->gcc.uplink_originator = false; + llist_for_each_entry(other, &bss->trans->gcc.bss_list, list) { + if (other == bss) + continue; + /* Update uplink state. */ + update_uplink_state(bss, bss->trans->gcc.uplink_busy); + } + /* Stop inactivity timer. */ + stop_inactivity_timer(bss->trans); + break; + case VGCS_BSS_EV_UL_REQUEST_CNF: + LOG_BSS(bss, LOGL_DEBUG, "Talker established uplink.\n"); + if (!bss->trans) + break; + if (!bss->trans->gcc.uplink_busy || bss->trans->gcc.uplink_bss != bss) { + LOG_BSS(bss, LOGL_ERROR, "Got UL REQUEST CNF, but we did not granted uplink.\n"); + break; + } + /* Determine if talker is the originator of the call. */ + rc = talker_identity(bss, rx_ran_msg->uplink_request_cnf.l3.l3, + rx_ran_msg->uplink_request_cnf.l3.l3_len); + if (rc > 0) { + bss->trans->gcc.uplink_originator = true; + LOG_BSS(bss, LOGL_DEBUG, "Talker is the originator of the call.\n"); + } + /* Set parameter. */ + set_parameter(bss->trans); + /* Set cell of current talker. */ + set_uplink_cell(bss, &rx_ran_msg->uplink_request_cnf.cell_identifier, 0); + /* Set MGW conference. */ + set_mgw_conference(bss->trans); + break; + case VGCS_BSS_EV_UL_APP_DATA: + LOG_BSS(bss, LOGL_DEBUG, "Talker sends application data on uplink.\n"); + if (!bss->trans) + break; + if (!bss->trans->gcc.uplink_busy || bss->trans->gcc.uplink_bss != bss) { + LOG_BSS(bss, LOGL_ERROR, "Got UP APP DATA, but we did not granted uplink.\n"); + break; + } + // FIXME: Use L3 info and feed to app. + break; + case VGCS_BSS_EV_BSS_DTAP: + LOG_BSS(bss, LOGL_DEBUG, "Talker sends DTAP message.\n"); + if (!bss->trans) + break; + if (!bss->trans->gcc.uplink_busy || bss->trans->gcc.uplink_bss != bss) { + LOG_BSS(bss, LOGL_ERROR, "Got DTAP from BSS, but we did not granted uplink.\n"); + break; + } + gsm44068_rcv_bcc_gcc(NULL, bss->trans, rx_ran_msg->dtap); + break; + case VGCS_BSS_EV_UL_RELEASE: + LOG_BSS(bss, LOGL_DEBUG, "Talker released uplink.\n"); + if (!bss->trans) + break; + if (bss->trans->type == TRANS_BCC) { + LOG_BSS(bss, LOGL_DEBUG, "This is a broadcast call, terminating call.\n"); + gcc_terminate_and_destroy(bss->trans, OSMO_GSM44068_CAUSE_NORMAL_CALL_CLEARING); + break; + } + if (!bss->trans->gcc.uplink_busy) { + LOG_BSS(bss, LOGL_NOTICE, "Got uplink release, but no uplink busy.\n"); + break; + } + /* Talker release the uplink. Ignore, if not from the current talking cell. */ + if (bss->trans->gcc.uplink_bss != bss) { + LOG_BSS(bss, LOGL_NOTICE, "Got uplink release, but uplink busy in other cell.\n"); + break; + } + /* Clear the busy flag and unblock all other cells. */ + bss->trans->gcc.uplink_bss = NULL; + bss->trans->gcc.uplink_cell = NULL; + bss->trans->gcc.uplink_busy = false; + llist_for_each_entry(other, &bss->trans->gcc.bss_list, list) { + if (other == bss) + continue; + /* Update uplink state. */ + if (bss->trans) + update_uplink_state(bss, bss->trans->gcc.uplink_busy); + } + /* Set MGW conference. */ + set_mgw_conference(bss->trans); + /* Start inactivity timer. */ + start_inactivity_timer(bss->trans); + break; + case VGCS_BSS_EV_CLEAR: + /* The calling user process requested clearing of VGCS/VBS call. */ + LOG_BSS(bss, LOGL_DEBUG, "Received clearing from calling user process.\n"); + bss_clear(bss, GSM0808_CAUSE_CALL_CONTROL, false); + break; + case VGCS_BSS_EV_CLOSE: + /* The SCCP connection from the MSC has been closed. */ + LOG_BSS(bss, LOGL_NOTICE, "Received SCCP connecting closing from MSC.\n"); + if (bss->conn) { + bss->conn->vgcs.bss = NULL; + bss->conn = NULL; + } + bss_clear(bss, GSM0808_CAUSE_PROTOCOL_ERROR_BETWEEN_BSS_AND_MSC, true); + break; + default: + OSMO_ASSERT(false); + } +} + +static void vgcs_bss_fsm_release(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct vgcs_bss *bss = fi->priv; + + switch (event) { + case VGCS_BSS_EV_CLOSE: + /* The SCCP connection from the MSC has been closed while waitring fro CLEAR COMPLETE. */ + LOG_BSS(bss, LOGL_NOTICE, "Received SCCP closing collision.\n"); + bss_destroy(bss); + break; + case VGCS_BSS_EV_RELEASED: + LOG_BSS(bss, LOGL_DEBUG, "Received CLEAR COMPLETE from BSS, we are done!\n"); + bss_destroy(bss); + break; + default: + OSMO_ASSERT(false); + } +} + +static const struct osmo_fsm_state vgcs_bss_fsm_states[] = { + [VGCS_BSS_ST_NULL] = { + .name = "NULL", + .in_event_mask = S(VGCS_BSS_EV_SETUP) | + S(VGCS_BSS_EV_CLEAR), + .out_state_mask = S(VGCS_BSS_ST_SETUP), + .action = vgcs_bss_fsm_null, + }, + [VGCS_BSS_ST_SETUP] = { + .name = "SETUP sent", + .in_event_mask = S(VGCS_BSS_EV_SETUP_ACK) | + S(VGCS_BSS_EV_SETUP_REFUSE) | + S(VGCS_BSS_EV_CLEAR) | + S(VGCS_BSS_EV_CLOSE), + .out_state_mask = S(VGCS_BSS_ST_ASSIGNMENT) | + S(VGCS_BSS_ST_RELEASE), + .action = vgcs_bss_fsm_setup, + }, + [VGCS_BSS_ST_ASSIGNMENT] = { + .name = "ASSIGNMENT Sent", + .in_event_mask = S(VGCS_BSS_EV_ACTIVE_OR_FAIL) | + S(VGCS_BSS_EV_CLEAR) | + S(VGCS_BSS_EV_CLOSE), + .out_state_mask = S(VGCS_BSS_ST_ACTIVE) | + S(VGCS_BSS_ST_RELEASE), + .action = vgcs_bss_fsm_assignment, + }, + [VGCS_BSS_ST_ACTIVE] = { + .name = "VGCS/VBS Active", + .in_event_mask = S(VGCS_BSS_EV_UL_REQUEST) | + S(VGCS_BSS_EV_UL_REQUEST_CNF) | + S(VGCS_BSS_EV_UL_APP_DATA) | + S(VGCS_BSS_EV_BSS_DTAP) | + S(VGCS_BSS_EV_UL_RELEASE) | + S(VGCS_BSS_EV_CLEAR) | + S(VGCS_BSS_EV_CLOSE), + .out_state_mask = S(VGCS_BSS_ST_RELEASE), + .action = vgcs_bss_fsm_active, + }, + [VGCS_BSS_ST_RELEASE] = { + .name = "Releasing VGCS/VBS control", + .in_event_mask = S(VGCS_BSS_EV_CLEAR) | + S(VGCS_BSS_EV_RELEASED), + .out_state_mask = S(VGCS_BSS_ST_NULL), + .action = vgcs_bss_fsm_release, + }, +}; + +static struct osmo_fsm vgcs_bss_fsm = { + .name = "vgcs_bss", + .states = vgcs_bss_fsm_states, + .num_states = ARRAY_SIZE(vgcs_bss_fsm_states), + .log_subsys = DASCI, + .event_names = vgcs_bss_fsm_event_names, +}; + +/* The BSS accepts VGCS/VBS and sends us supported features. */ +void vgcs_vbs_setup_ack(struct vgcs_bss *bss, const struct ran_msg *ran_msg) +{ + if (!bss->trans) + return; + osmo_fsm_inst_dispatch(bss->fi, VGCS_BSS_EV_SETUP_ACK, (void *)ran_msg); +} + +/* The BSS refuses VGCS/VBS. */ +void vgcs_vbs_setup_refuse(struct vgcs_bss *bss, const struct ran_msg *ran_msg) +{ + if (!bss->trans) + return; + osmo_fsm_inst_dispatch(bss->fi, VGCS_BSS_EV_SETUP_REFUSE, (void *)ran_msg); +} + +/* The BSS needs more time for VGCS/VBS channel assignment. */ +void vgcs_vbs_queuing_ind(struct vgcs_bss_cell *cell) +{ + if (!cell->bss) + return; +} + +/* A mobile station requests the uplink on a VGCS channel. */ +void vgcs_uplink_request(struct vgcs_bss *bss, const struct ran_msg *ran_msg) +{ + if (!bss->trans) + return; + osmo_fsm_inst_dispatch(bss->fi, VGCS_BSS_EV_UL_REQUEST, (void *)ran_msg); +} + +/* The uplink on a VGCS channel has been established. */ +void vgcs_uplink_request_cnf(struct vgcs_bss *bss, const struct ran_msg *ran_msg) +{ + if (!bss->trans) + return; + osmo_fsm_inst_dispatch(bss->fi, VGCS_BSS_EV_UL_REQUEST_CNF, (void *)ran_msg); +} + +/* Application data received on the uplink of a VGCS channel. */ +void vgcs_app_data(struct vgcs_bss *bss, const struct ran_msg *ran_msg) +{ + if (!bss->trans) + return; + osmo_fsm_inst_dispatch(bss->fi, VGCS_BSS_EV_UL_APP_DATA, (void *)ran_msg); +} + +/* Application data received on the uplink of a VGCS channel. */ +void vgcs_bss_dtap(struct vgcs_bss *bss, const struct ran_msg *ran_msg) +{ + if (!bss->trans) + return; + osmo_fsm_inst_dispatch(bss->fi, VGCS_BSS_EV_BSS_DTAP, (void *)ran_msg); +} + +/* A mobile station releases the uplink on a VGCS channel. */ +void vgcs_uplink_release_ind(struct vgcs_bss *bss, const struct ran_msg *ran_msg) +{ + if (!bss->trans) + return; + osmo_fsm_inst_dispatch(bss->fi, VGCS_BSS_EV_UL_RELEASE, (void *)ran_msg); +} + +/* The BSS gives cell status about VGCS/VBS channel. */ +void vgcs_vbs_assign_status(struct vgcs_bss_cell *cell, const struct ran_msg *ran_msg) +{ + if (!cell->bss) + return; +} + +void vgcs_vbs_caller_assign_cpl(struct gsm_trans *trans) +{ + osmo_fsm_inst_dispatch(trans->gcc.fi, VGCS_GCC_EV_BSS_ASSIGN_CPL, NULL); +} + +void vgcs_vbs_caller_assign_fail(struct gsm_trans *trans) +{ + osmo_fsm_inst_dispatch(trans->gcc.fi, VGCS_GCC_EV_BSS_ASSIGN_FAIL, NULL); +} + +/* BSS indicated that the channel has been released. */ +void vgcs_vbs_clear_req(struct vgcs_bss *bss, const struct ran_msg *ran_msg) +{ + osmo_fsm_inst_dispatch(bss->fi, VGCS_BSS_EV_CLOSE, (void *)ran_msg); +} + +/* BSS indicated that the channel has been released. */ +void vgcs_vbs_clear_cpl(struct vgcs_bss *bss, const struct ran_msg *ran_msg) +{ + osmo_fsm_inst_dispatch(bss->fi, VGCS_BSS_EV_RELEASED, (void *)ran_msg); +} + +/* + * Cell resource state machine - handles all "resource control" instances + */ + +static const struct value_string vgcs_cell_fsm_event_names[] = { + OSMO_VALUE_STRING(VGCS_CELL_EV_RTP_STREAM_GONE), + OSMO_VALUE_STRING(VGCS_CELL_EV_RTP_STREAM_ADDR_AVAILABLE), + OSMO_VALUE_STRING(VGCS_CELL_EV_RTP_STREAM_ESTABLISHED), + OSMO_VALUE_STRING(VGCS_CELL_EV_ASSIGN), + OSMO_VALUE_STRING(VGCS_CELL_EV_ASSIGN_RES), + OSMO_VALUE_STRING(VGCS_CELL_EV_ASSIGN_FAIL), + OSMO_VALUE_STRING(VGCS_CELL_EV_CLEAR), + OSMO_VALUE_STRING(VGCS_CELL_EV_CLOSE), + OSMO_VALUE_STRING(VGCS_CELL_EV_RELEASED), + { } +}; + +static void cell_destroy(struct vgcs_bss_cell *cell); + +/* Clear the connection towards BSS. + * Relations to the BSS and transaction is removed. */ +static void cell_clear(struct vgcs_bss_cell *cell, uint8_t cause) +{ + struct ran_msg ran_msg; + + /* Must detach us from BSS. */ + if (cell->bss) { + /* Remove pointer to talking channel. */ + if (cell->bss->trans && cell->bss->trans->gcc.uplink_cell == cell) + cell->bss->trans->gcc.uplink_cell = NULL; + llist_del(&cell->list_bss); + cell->bss = NULL; + } + + /* Change state. */ + if (cell->fi->state != VGCS_CELL_ST_RELEASE) + osmo_fsm_inst_state_chg(cell->fi, VGCS_CELL_ST_RELEASE, 0, 0); + + /* If there is no event to wait for, we can just destroy. */ + if (!cell->conn && !cell->rtps) { + cell_destroy(cell); + return; + } + + /* Send Clear Command to BSS. */ + if (cell->conn) { + ran_msg = (struct ran_msg){ + .msg_type = RAN_MSG_CLEAR_COMMAND, + .clear_command = { + .gsm0808_cause = cause, + }, + }; + LOG_CELL(cell, LOGL_DEBUG, "Sending CLEAR COMMAND for call controling channel.\n"); + ran_encode_and_send(cell->fi, &ran_msg, cell->conn, false); + } + + /* Clear RTP stream. This may trigger VGCS_CELL_EV_RTP_STREAM_GONE within this release function. */ + if (cell->rtps) + rtp_stream_release(cell->rtps); +} + +/* When finally the BSS connection is released. (CLEAR COMPLETE response) + * Relations to the BSS and transaction is removed, if not already. */ +static void cell_destroy(struct vgcs_bss_cell *cell) +{ + struct vgcs_mgw_ep *mgw; + + /* close RAN conn */ + if (cell->conn) { + cell->conn->vgcs.cell = NULL; + ran_conn_close(cell->conn); + cell->conn = NULL; + } + + /* Detach from BSS now. Check, to prevent race condition. */ + if (cell->bss) { + /* Remove pointer to talking channel. */ + if (cell->bss->trans && cell->bss->trans->gcc.uplink_cell == cell) + cell->bss->trans->gcc.uplink_cell = NULL; + llist_del(&cell->list_bss); + cell->bss = NULL; + } + + /* Detach from MGW now. Check, to prevent race condition. */ + if (cell->mgw) { + mgw = cell->mgw; + llist_del(&cell->list_mgw); + cell->mgw = NULL; + /* Destroy MGW endpoint, if list is empty. */ + if (llist_empty(&mgw->cell_list)) + osmo_fsm_inst_dispatch(mgw->fi, VGCS_MGW_EP_EV_CLEAR, NULL); + } + + LOG_CELL(cell, LOGL_DEBUG, "Detroy connection to cell.\n"); + + /* Free FSM. (should be allocated) */ + osmo_fsm_inst_state_chg(cell->fi, VGCS_CELL_ST_NULL, 0, 0); + osmo_fsm_inst_term(cell->fi, OSMO_FSM_TERM_REGULAR, NULL); +} + +static void vgcs_cell_fsm_null(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct vgcs_bss_cell *cell = fi->priv; + const struct codec_mapping *cm; + int rc; + + switch (event) { + case VGCS_CELL_EV_ASSIGN: + LOG_CELL(cell, LOGL_DEBUG, "Received assignment from BSS controling process.\n"); + /* Allocate rtps stream. */ + cell->rtps = rtp_stream_alloc(cell->fi, VGCS_CELL_EV_RTP_STREAM_GONE, + VGCS_CELL_EV_RTP_STREAM_ADDR_AVAILABLE, + VGCS_CELL_EV_RTP_STREAM_ESTABLISHED, RTP_TO_RAN, cell->call_id, + NULL); + if (!cell->rtps) { + LOG_CELL(cell, LOGL_DEBUG, "Failed to allocate RTP stream, cannot continue.\n"); + cell_destroy(cell); + break; + } + /* Hard coded codec: GSM V1 */ + cm = codec_mapping_by_gsm0808_speech_codec_type(GSM0808_SCT_FR1); + if (!cm) { + LOG_CELL(cell, LOGL_DEBUG, "Selected codec not supported, cannot continue.\n"); + cell_clear(cell, GSM0808_CAUSE_PROTOCOL_ERROR_BETWEEN_BSS_AND_MSC); + break; + } + rtp_stream_set_one_codec(cell->rtps, &cm->sdp); + /* Set initial mode. */ + rtp_stream_set_mode(cell->rtps, MGCP_CONN_RECV_ONLY); + /* Commit RTP stream. */ + if (!cell->bss || !cell->bss->trans) { + LOG_CELL(cell, LOGL_DEBUG, "No BSS/transaction, cannot continue.\n"); + cell_clear(cell, GSM0808_CAUSE_PROTOCOL_ERROR_BETWEEN_BSS_AND_MSC); + break; + } + if (!cell->mgw || !cell->mgw->mgw_ep) { + LOG_CELL(cell, LOGL_DEBUG, "No MGW endpoint, cannot continue.\n"); + cell_clear(cell, GSM0808_CAUSE_PROTOCOL_ERROR_BETWEEN_BSS_AND_MSC); + break; + } + rc = rtp_stream_ensure_ci(cell->rtps, cell->mgw->mgw_ep); + if (rc < 0) { + LOG_CELL(cell, LOGL_DEBUG, "Failed to trigger RTP stream CI.\n"); + cell_clear(cell, GSM0808_CAUSE_PROTOCOL_ERROR_BETWEEN_BSS_AND_MSC); + break; + } + /* Change state. */ + osmo_fsm_inst_state_chg(fi, VGCS_CELL_ST_ASSIGNMENT, 0, 0); + break; + case VGCS_CELL_EV_CLEAR: + /* The calling user process requested clearing of VGCS/VBS call. */ + LOG_CELL(cell, LOGL_DEBUG, "Received clearing from BSS controling process.\n"); + cell_clear(cell, GSM0808_CAUSE_CALL_CONTROL); + break; + default: + OSMO_ASSERT(false); + } +} + +static void vgcs_cell_fsm_assignment(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct vgcs_bss_cell *cell = fi->priv; + struct ran_msg *rx_ran_msg = data; + struct ran_msg tx_ran_msg; + struct osmo_sockaddr_str ss; + const struct codec_mapping *cm; + struct vgcs_bss *bss; + int rc; + + switch (event) { + case VGCS_CELL_EV_RTP_STREAM_GONE: + /* The RTP stream failed. */ + LOG_CELL(cell, LOGL_ERROR, "RTP stream of MGW failed.\n"); + cell->rtps = NULL; + goto channel_fail; + break; + case VGCS_CELL_EV_RTP_STREAM_ADDR_AVAILABLE: + /* The RTP stream sends its peer. */ + if (!osmo_sockaddr_str_is_nonzero(&cell->rtps->local)) { + LOG_CELL(cell, LOGL_ERROR, "Invalid RTP address received from MGW: " OSMO_SOCKADDR_STR_FMT "\n", + OSMO_SOCKADDR_STR_FMT_ARGS(&cell->rtps->local)); + goto channel_fail; + } + LOG_CELL(cell, LOGL_DEBUG, + "MGW endpoint's RTP address available for the CI %s: " OSMO_SOCKADDR_STR_FMT " (osmux=%s:%d)\n", + rtp_direction_name(cell->rtps->dir), OSMO_SOCKADDR_STR_FMT_ARGS(&cell->rtps->local), + cell->rtps->use_osmux ? "yes" : "no", cell->rtps->local_osmux_cid); + /* Send VGCS/VBS ASSIGNMENT REQUEST to BSS */ + LOG_CELL(cell, LOGL_DEBUG, "Sending VGCS/VBS ASSIGNMENT REQUEST towards BSS.\n"); + tx_ran_msg = (struct ran_msg) { + .msg_type = RAN_MSG_VGCS_VBS_ASSIGN_REQ, + .vgcs_vbs_assign_req = { + /* For now we support GSM/FR V1 only. This shall be supported by all MS. */ + .channel_type = { + .ch_indctr = GSM0808_CHAN_SPEECH, + .ch_rate_type = GSM0808_SPEECH_FULL_BM, + .perm_spch_len = 1, + .perm_spch[0] = GSM0808_PERM_FR1, + }, + /* For now we want a channel without any delay. */ + .ass_req = GSM0808_ASRQ_IMMEDIATE, + .callref = { + .sf = (cell->trans_type == TRANS_GCC), + }, + /* We need to identify the cell only. */ + .cell_identifier = { + .id_discr = CELL_IDENT_CI, + .id.ci = cell->cell_id, + }, + .aoip_transport_layer_present = true, + .call_id_present = true, + .call_id = cell->call_id, + .codec_list_present = true, + .codec_list_msc_preferred = { + .len = 1, + .codec[0] = { + .fi = 1, + .type = GSM0808_SCT_FR1, + .cfg = 0, + }, + }, + }, + }; + osmo_store32be_ext(cell->callref >> 3, &tx_ran_msg.vgcs_vbs_assign_req.callref.call_ref_hi, 3); + tx_ran_msg.vgcs_vbs_assign_req.callref.call_ref_lo = cell->callref & 0x7; + osmo_sockaddr_str_to_sockaddr(&cell->rtps->local, &tx_ran_msg.vgcs_vbs_assign_req.aoip_transport_layer); + /* First message, so we must set "initial" to "true". */ + ran_encode_and_send(fi, &tx_ran_msg, cell->conn, true); + break; + case VGCS_CELL_EV_RTP_STREAM_ESTABLISHED: + /* The RTP stream established. */ + LOG_CELL(cell, LOGL_DEBUG, "RTP stream is established.\n"); + break; + case VGCS_CELL_EV_ASSIGN_RES: + /* Receive VGCS/VBS ASSIGNMENT RESULT from BSS. */ + LOG_CELL(cell, LOGL_DEBUG, "Received VGCS/VBS ASSIGNMENT RESULT from BSS.\n"); + cell->assigned = true; + if (!rx_ran_msg->vgcs_vbs_assign_res.aoip_transport_layer_present + && !rx_ran_msg->vgcs_vbs_assign_res.codec_present + && !rx_ran_msg->vgcs_vbs_assign_res.call_id_present) { + LOG_CELL(cell, LOGL_ERROR, "Mandatory IEs missing.\n"); + goto channel_fail; + } + /* Send remote peer to RTP stream. */ + if (osmo_sockaddr_str_from_sockaddr(&ss, &rx_ran_msg->vgcs_vbs_assign_res.aoip_transport_layer)) { + LOG_CELL(cell, LOGL_ERROR, "Cannot RTP-CONNECT, invalid RTP IP:port in incoming MNCC " + "message\n"); + goto channel_fail; + } + rtp_stream_set_remote_addr(cell->rtps, &ss); + /* Send remote codec to RTP stream. */ + cm = codec_mapping_by_gsm0808_speech_codec_type(rx_ran_msg->vgcs_vbs_assign_res.codec_msc_chosen.type); + if (!cm) { + LOG_CELL(cell, LOGL_ERROR, "Chosen codec by BSC is not supported by MSC.\n"); + goto channel_fail; + } + rtp_stream_set_one_codec(cell->rtps, &cm->sdp); + /* Set listening mode. */ + rtp_stream_set_mode(cell->rtps, MGCP_CONN_SEND_ONLY); + /* Commit RTP stream. */ + rc = rtp_stream_commit(cell->rtps); + if (rc < 0) { + LOG_CELL(cell, LOGL_ERROR, "Failed to commit parameters to RTP stream.\n"); + goto channel_fail; + } + /* Change state. */ + osmo_fsm_inst_state_chg(fi, VGCS_CELL_ST_ACTIVE, 0, 0); + /* Notify BSS FSM about channel activation. */ + if (cell->bss) + osmo_fsm_inst_dispatch(cell->bss->fi, VGCS_BSS_EV_ACTIVE_OR_FAIL, NULL); + break; + case VGCS_CELL_EV_ASSIGN_FAIL: + /* Received VGCS/VBS ASSIGNMENT FAILURE from BSS. */ + LOG_CELL(cell, LOGL_NOTICE, "Received VGCS/VBS ASSIGNMENT FAILURE from BSS.\n"); +channel_fail: + bss = cell->bss; + cell_clear(cell, GSM0808_CAUSE_PROTOCOL_ERROR_BETWEEN_BSS_AND_MSC); + /* Notify BSS FSM about channel failure. */ + if (bss) + osmo_fsm_inst_dispatch(bss->fi, VGCS_BSS_EV_ACTIVE_OR_FAIL, NULL); + break; + case VGCS_CELL_EV_CLEAR: + /* The calling user process requested clearing of VGCS/VBS call. */ + LOG_CELL(cell, LOGL_DEBUG, "Received clearing from BSS controling process.\n"); + cell_clear(cell, GSM0808_CAUSE_CALL_CONTROL); + break; + case VGCS_CELL_EV_CLOSE: + /* The SCCP connection from the MSC has been closed. */ + LOG_CELL(cell, LOGL_NOTICE, "Received SCCP connecting closing from MSC.\n"); + if (cell->conn) { + cell->conn->vgcs.bss = NULL; + cell->conn = NULL; + } + cell_clear(cell, GSM0808_CAUSE_PROTOCOL_ERROR_BETWEEN_BSS_AND_MSC); + break; + default: + OSMO_ASSERT(false); + } +} + +static void vgcs_cell_fsm_active(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct vgcs_bss_cell *cell = fi->priv; + + switch (event) { + case VGCS_CELL_EV_RTP_STREAM_GONE: + /* The RTP stream failed. */ + LOG_CELL(cell, LOGL_ERROR, "RTP stream of MGW failed.\n"); + cell->rtps = NULL; + cell_clear(cell, GSM0808_CAUSE_PROTOCOL_ERROR_BETWEEN_BSS_AND_MSC); + break; + case VGCS_CELL_EV_RTP_STREAM_ESTABLISHED: + /* The RTP stream established. */ + LOG_CELL(cell, LOGL_DEBUG, "RTP stream is established.\n"); + break; + case VGCS_CELL_EV_CLEAR: + /* The calling user process requested clearing of VGCS/VBS call. */ + LOG_CELL(cell, LOGL_DEBUG, "Received clearing from BSS controling process.\n"); + cell_clear(cell, GSM0808_CAUSE_CALL_CONTROL); + break; + case VGCS_CELL_EV_CLOSE: + /* The SCCP connection from the MSC has been closed. */ + LOG_CELL(cell, LOGL_NOTICE, "Received SCCP connecting closing from MSC.\n"); + if (cell->conn) { + cell->conn->vgcs.bss = NULL; + cell->conn = NULL; + } + cell_clear(cell, GSM0808_CAUSE_PROTOCOL_ERROR_BETWEEN_BSS_AND_MSC); + break; + default: + OSMO_ASSERT(false); + } +} + +static void vgcs_cell_fsm_release(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct vgcs_bss_cell *cell = fi->priv; + + switch (event) { + case VGCS_CELL_EV_RTP_STREAM_GONE: + /* The RTP stream gone. */ + LOG_CELL(cell, LOGL_ERROR, "RTP stream gone.\n"); + cell->rtps = NULL; + /* Wait for RAN conn. */ + if (cell->conn) + break; + cell_destroy(cell); + break; + case VGCS_CELL_EV_CLEAR: + case VGCS_CELL_EV_RELEASED: + if (event == VGCS_CELL_EV_CLEAR) { + /* The SCCP connection from the MSC has been closed while waiting for CLEAR COMPLETE. */ + LOG_CELL(cell, LOGL_NOTICE, "Received SCCP closing collision.\n"); + } else + LOG_CELL(cell, LOGL_DEBUG, "Received CLEAR COMPLETE from BSS, we are done!\n"); + /* Wait for RTP stream. */ + if (cell->rtps) { + /* close RAN conn */ + if (cell->conn) { + cell->conn->vgcs.cell = NULL; + ran_conn_close(cell->conn); + cell->conn = NULL; + } + break; + } + cell_destroy(cell); + break; + default: + OSMO_ASSERT(false); + } +} + +static const struct osmo_fsm_state vgcs_cell_fsm_states[] = { + [VGCS_CELL_ST_NULL] = { + .name = "NULL", + .in_event_mask = S(VGCS_CELL_EV_ASSIGN) | + S(VGCS_CELL_EV_CLEAR), + .out_state_mask = S(VGCS_CELL_ST_ASSIGNMENT), + .action = vgcs_cell_fsm_null, + }, + [VGCS_CELL_ST_ASSIGNMENT] = { + .name = "ASSIGNMENT Sent", + .in_event_mask = S(VGCS_CELL_EV_RTP_STREAM_GONE) | + S(VGCS_CELL_EV_RTP_STREAM_ADDR_AVAILABLE) | + S(VGCS_CELL_EV_RTP_STREAM_ESTABLISHED) | + S(VGCS_CELL_EV_ASSIGN_RES) | + S(VGCS_CELL_EV_ASSIGN_FAIL) | + S(VGCS_CELL_EV_CLEAR) | + S(VGCS_CELL_EV_CLOSE), + .out_state_mask = S(VGCS_CELL_ST_ACTIVE) | + S(VGCS_CELL_ST_RELEASE), + .action = vgcs_cell_fsm_assignment, + }, + [VGCS_CELL_ST_ACTIVE] = { + .name = "VGCS/VBS channel active", + .in_event_mask = S(VGCS_CELL_EV_RTP_STREAM_GONE) | + S(VGCS_CELL_EV_RTP_STREAM_ESTABLISHED) | + S(VGCS_CELL_EV_CLEAR) | + S(VGCS_CELL_EV_CLOSE), + .out_state_mask = S(VGCS_CELL_ST_RELEASE), + .action = vgcs_cell_fsm_active, + }, + [VGCS_CELL_ST_RELEASE] = { + .name = "Releasing VGCS/VBS channel", + .in_event_mask = S(VGCS_CELL_EV_RTP_STREAM_GONE) | + S(VGCS_CELL_EV_CLEAR) | + S(VGCS_CELL_EV_RELEASED), + .out_state_mask = S(VGCS_CELL_ST_NULL), + .action = vgcs_cell_fsm_release, + }, +}; + +static struct osmo_fsm vgcs_cell_fsm = { + .name = "vgcs_cell", + .states = vgcs_cell_fsm_states, + .num_states = ARRAY_SIZE(vgcs_cell_fsm_states), + .log_subsys = DASCI, + .event_names = vgcs_cell_fsm_event_names, +}; + +/* The BSS accepts VGCS/VBS channel assignment. */ +void vgcs_vbs_assign_result(struct vgcs_bss_cell *cell, const struct ran_msg *ran_msg) +{ + osmo_fsm_inst_dispatch(cell->fi, VGCS_CELL_EV_ASSIGN_RES, (void *)ran_msg); +} + +/* The BSS refuses VGCS/VBS channel assignment. */ +void vgcs_vbs_assign_fail(struct vgcs_bss_cell *cell, const struct ran_msg *ran_msg) +{ + osmo_fsm_inst_dispatch(cell->fi, VGCS_CELL_EV_ASSIGN_FAIL, (void *)ran_msg); +} + +/* BSS indicated that the channel has been released. */ +void vgcs_vbs_clear_req_channel(struct vgcs_bss_cell *cell, const struct ran_msg *ran_msg) +{ + LOG_CELL(cell, LOGL_DEBUG, "Received CLEAR REQUEST for resource controling channel from BSS.\n"); + osmo_fsm_inst_dispatch(cell->fi, VGCS_CELL_EV_CLOSE, (void *)ran_msg); +} + +/* BSS confirms the release of channel. */ +void vgcs_vbs_clear_cpl_channel(struct vgcs_bss_cell *cell, const struct ran_msg *ran_msg) +{ + LOG_CELL(cell, LOGL_DEBUG, "Received CLEAR COMPLETE for resource controling channel from BSS.\n"); + osmo_fsm_inst_dispatch(cell->fi, VGCS_CELL_EV_RELEASED, (void *)ran_msg); +} + +/* + * MGW endpoint FSM + */ + +static const struct value_string vgcs_mgw_ep_fsm_event_names[] = { + OSMO_VALUE_STRING(VGCS_MGW_EP_EV_FREE), + OSMO_VALUE_STRING(VGCS_MGW_EP_EV_CLEAR), + { } +}; + +static void vgcs_mgw_ep_fsm_active(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct vgcs_mgw_ep *mgw = fi->priv; + struct vgcs_bss_cell *cell, *cell2; + struct mgcp_client *mgcp_client; + + switch (event) { + case VGCS_MGW_EP_EV_FREE: + LOGP(DASCI, LOGL_DEBUG, "MGW connection closed, removing all cell instances.\n"); + llist_for_each_entry_safe(cell, cell2, &mgw->cell_list, list_mgw) { + if (cell->rtps) + cell->rtps->ci = NULL; + llist_del(&cell->list_mgw); + cell->mgw = NULL; + } + /* Put MGCP client back into MGW pool. */ + mgcp_client = osmo_mgcpc_ep_client(mgw->mgw_ep); + mgcp_client_pool_put(mgcp_client); + /* Destroy this instance. */ + osmo_fsm_inst_term_children(fi, OSMO_FSM_TERM_PARENT, NULL); + osmo_fsm_inst_term(fi, OSMO_FSM_TERM_REGULAR, NULL); + break; + case VGCS_MGW_EP_EV_CLEAR: + if (!llist_empty(&mgw->cell_list)) + break; + LOGP(DASCI, LOGL_DEBUG, "Cell list of MGW instance is now empty, dropping.\n"); + /* Destroy this instance. */ + osmo_fsm_inst_term_children(fi, OSMO_FSM_TERM_PARENT, NULL); + osmo_fsm_inst_term(fi, OSMO_FSM_TERM_REGULAR, NULL); + break; + default: + OSMO_ASSERT(false); + } +} + +static const struct osmo_fsm_state vgcs_mgw_ep_fsm_states[] = { + [VGCS_MGW_EP_ST_NULL] = { + .name = "NULL", + .out_state_mask = S(VGCS_MGW_EP_ST_ACTIVE), + }, + [VGCS_MGW_EP_ST_ACTIVE] = { + .name = "MGW endpoint allocated", + .in_event_mask = S(VGCS_MGW_EP_EV_FREE) | + S(VGCS_MGW_EP_EV_CLEAR), + .out_state_mask = S(VGCS_MGW_EP_ST_NULL), + .action = vgcs_mgw_ep_fsm_active, + }, +}; + +static struct osmo_fsm vgcs_mgw_ep_fsm = { + .name = "vgcs_mgw_ep", + .states = vgcs_mgw_ep_fsm_states, + .num_states = ARRAY_SIZE(vgcs_mgw_ep_fsm_states), + .log_subsys = DASCI, + .event_names = vgcs_mgw_ep_fsm_event_names, +}; diff --git a/src/libmsc/msc_vty.c b/src/libmsc/msc_vty.c index 0c07bc217..1f389f455 100644 --- a/src/libmsc/msc_vty.c +++ b/src/libmsc/msc_vty.c @@ -1,5 +1,5 @@ /* MSC interface to quagga VTY */ -/* (C) 2016-2018 by sysmocom s.m.f.c. GmbH <info@sysmocom.de> +/* (C) 2016-2018 by sysmocom s.f.m.c. GmbH <info@sysmocom.de> * Based on OpenBSC interface to quagga VTY (libmsc/vty_interface_layer3.c) * (C) 2009-2017 by Harald Welte <laforge@gnumonks.org> * (C) 2009-2011 by Holger Hans Peter Freyther @@ -33,9 +33,11 @@ #include <osmocom/gsm/protocol/gsm_08_58.h> #include <osmocom/gsm/protocol/gsm_04_14.h> #include <osmocom/gsm/protocol/gsm_08_08.h> +#include <osmocom/gsm/gsm23236.h> #include <osmocom/sigtran/sccp_helpers.h> +#include <osmocom/vty/tdef_vty.h> #include <osmocom/vty/command.h> #include <osmocom/vty/logging.h> #include <osmocom/vty/misc.h> @@ -65,10 +67,12 @@ #include <osmocom/msc/sgs_vty.h> #include <osmocom/msc/sccp_ran.h> #include <osmocom/msc/ran_peer.h> +#include <osmocom/msc/ran_infra.h> +#include <osmocom/msc/asci_vty.h> static struct gsm_network *gsmnet = NULL; -struct cmd_node net_node = { +static struct cmd_node net_node = { GSMNET_NODE, "%s(config-net)# ", 1, @@ -128,27 +132,34 @@ DEFUN(cfg_net_mnc, DEFUN(cfg_net_name_short, cfg_net_name_short_cmd, - "short name NAME", + "short name .NAME", "Set the short GSM network name\n" NAME_CMD_STR NAME_STR) { - osmo_talloc_replace_string(gsmnet, &gsmnet->name_short, argv[0]); + if (gsmnet->name_short != NULL) + talloc_free(gsmnet->name_short); + gsmnet->name_short = argv_concat(argv, argc, 0); return CMD_SUCCESS; } DEFUN(cfg_net_name_long, cfg_net_name_long_cmd, - "long name NAME", + "long name .NAME", "Set the long GSM network name\n" NAME_CMD_STR NAME_STR) { - osmo_talloc_replace_string(gsmnet, &gsmnet->name_long, argv[0]); + if (gsmnet->name_long != NULL) + talloc_free(gsmnet->name_long); + gsmnet->name_long = argv_concat(argv, argc, 0); return CMD_SUCCESS; } +#define ENCRYPTION_STR "Encryption options\n" + DEFUN(cfg_net_encryption, cfg_net_encryption_cmd, - "encryption a5 <0-3> [<0-3>] [<0-3>] [<0-3>]", - "Encryption options\n" - "GSM A5 Air Interface Encryption\n" + "encryption a5 <0-4> [<0-4>] [<0-4>] [<0-4>] [<0-4>]", + ENCRYPTION_STR + "GSM A5 Air Interface Encryption.\n" + "A5/n Algorithm Number\n" "A5/n Algorithm Number\n" "A5/n Algorithm Number\n" "A5/n Algorithm Number\n" @@ -163,6 +174,25 @@ DEFUN(cfg_net_encryption, return CMD_SUCCESS; } +DEFUN(cfg_net_encryption_uea, + cfg_net_encryption_uea_cmd, + "encryption uea <0-2> [<0-2>] [<0-2>]", + ENCRYPTION_STR + "UTRAN (3G) encryption algorithms to allow: 0 = UEA0 (no encryption), 1 = UEA1, 2 = UEA2.\n" + "UEAn Algorithm Number\n" + "UEAn Algorithm Number\n" + "UEAn Algorithm Number\n" + ) +{ + unsigned int i; + + gsmnet->uea_encryption_mask = 0; + for (i = 0; i < argc; i++) + gsmnet->uea_encryption_mask |= (1 << atoi(argv[i])); + + return CMD_SUCCESS; +} + DEFUN(cfg_net_authentication, cfg_net_authentication_cmd, "authentication (optional|required)", @@ -261,30 +291,65 @@ DEFUN(cfg_net_no_timezone, return CMD_SUCCESS; } -DEFUN(cfg_net_per_loc_upd, cfg_net_per_loc_upd_cmd, - "periodic location update <6-1530>", - "Periodic Location Updating Interval\n" - "Periodic Location Updating Interval\n" - "Periodic Location Updating Interval\n" - "Periodic Location Updating Interval in Minutes\n") +/* NOTE: actually this is subscriber expiration timeout */ +#define PER_LOC_UPD_STR "Periodic Location Updating Interval\n" + +DEFUN_DEPRECATED(cfg_net_per_loc_upd, cfg_net_per_loc_upd_cmd, + "periodic location update <6-1530>", + PER_LOC_UPD_STR PER_LOC_UPD_STR PER_LOC_UPD_STR + "Periodic Location Updating Interval in Minutes\n") +{ + int minutes = atoi(argv[0]); + int rc; + + vty_out(vty, "%% 'periodic location update' is now deprecated. " + "Use 'msc' / 'timer vlr T3212' to change subscriber expiration " + "timeout.%s", VTY_NEWLINE); + + /* We used to double this value and add a minute when scheduling the + * expiration timer. Let's emulate the old behaviour here. */ + minutes = minutes * 2 + 1; + vty_out(vty, "%% Setting T3212 to %d minutes " + "(emulating the old behaviour).%s", + minutes, VTY_NEWLINE); + + rc = osmo_tdef_set(msc_tdefs_vlr, 3212, minutes, OSMO_TDEF_M); + return rc ? CMD_WARNING : CMD_SUCCESS; +} + +DEFUN_DEPRECATED(cfg_net_no_per_loc_upd, cfg_net_no_per_loc_upd_cmd, + "no periodic location update", + NO_STR PER_LOC_UPD_STR PER_LOC_UPD_STR PER_LOC_UPD_STR) +{ + int rc; + + vty_out(vty, "%% 'periodic location update' is now deprecated: " + "use 'timer T3212' to change subscriber expiration " + "timeout.%s", VTY_NEWLINE); + + rc = osmo_tdef_set(msc_tdefs_vlr, 3212, 0, OSMO_TDEF_M); + return rc ? CMD_WARNING : CMD_SUCCESS; +} + +DEFUN(cfg_net_call_wait, cfg_net_call_wait_cmd, + "call-waiting", + "Enable Call Waiting on the Network\n") { struct gsm_network *net = vty->index; - net->t3212 = atoi(argv[0]) / 6; + net->call_waiting = true; return CMD_SUCCESS; } -DEFUN(cfg_net_no_per_loc_upd, cfg_net_no_per_loc_upd_cmd, - "no periodic location update", +DEFUN(cfg_net_no_call_wait, cfg_net_no_call_wait_cmd, + "no call-waiting", NO_STR - "Periodic Location Updating Interval\n" - "Periodic Location Updating Interval\n" - "Periodic Location Updating Interval\n") + "Disable Call Waiting on the Network\n") { struct gsm_network *net = vty->index; - net->t3212 = 0; + net->call_waiting = false; return CMD_SUCCESS; } @@ -305,6 +370,13 @@ static int config_write_net(struct vty *vty) vty_out(vty, " %u", i); } vty_out(vty, "%s", VTY_NEWLINE); + + vty_out(vty, " encryption uea"); + for (i = 0; i < 8; i++) { + if (gsmnet->uea_encryption_mask & (1 << i)) + vty_out(vty, " %u", i); + } + vty_out(vty, "%s", VTY_NEWLINE); vty_out(vty, " authentication %s%s", gsmnet->authentication_required ? "required" : "optional", VTY_NEWLINE); vty_out(vty, " rrlp mode %s%s", msc_rrlp_mode_name(gsmnet->rrlp.mode), @@ -319,16 +391,11 @@ static int config_write_net(struct vty *vty) vty_out(vty, " timezone %d %d%s", gsmnet->tz.hr, gsmnet->tz.mn, VTY_NEWLINE); } - if (gsmnet->t3212 == 0) - vty_out(vty, " no periodic location update%s", VTY_NEWLINE); - else - vty_out(vty, " periodic location update %u%s", - gsmnet->t3212 * 6, VTY_NEWLINE); - if (gsmnet->emergency.route_to_msisdn) { - vty_out(vty, " emergency-call route-to-msisdn %s%s", - gsmnet->emergency.route_to_msisdn, VTY_NEWLINE); - } + if (!gsmnet->call_waiting) + vty_out(vty, " no call-waiting%s", VTY_NEWLINE); + + mgcp_client_pool_config_write(vty, " "); return CMD_SUCCESS; } @@ -350,6 +417,15 @@ DEFUN(cfg_msc, cfg_msc_cmd, #define MNCC_GUARD_TIMEOUT_STR "Set global guard timer for mncc interface activity\n" #define MNCC_GUARD_TIMEOUT_VALUE_STR "guard timer value (sec.)\n" +DEFUN_DEPRECATED(cfg_sms_database, cfg_sms_database_cmd, + "sms-database PATH", + "Set the path to the MSC-SMS database file\n" + "Relative or absolute file system path to the database file (default is '" SMS_DEFAULT_DB_FILE_PATH "')\n") +{ + osmo_talloc_replace_string(gsmnet, &gsmnet->sms_queue_cfg->db_file_path, argv[0]); + return CMD_SUCCESS; +} + DEFUN(cfg_msc_mncc_internal, cfg_msc_mncc_internal_cmd, "mncc internal", @@ -412,6 +488,24 @@ DEFUN(cfg_msc_no_assign_tmsi, cfg_msc_no_assign_tmsi_cmd, return CMD_SUCCESS; } +DEFUN_ATTR(cfg_msc_lcls_disable, cfg_msc_lcls_disable_cmd, + "lcls-permitted", + "Globally allow LCLS (Local Call Local Switch) for all calls on this MSC.\n", + CMD_ATTR_IMMEDIATE) +{ + gsmnet->lcls_permitted = true; + return CMD_SUCCESS; +} + +DEFUN_ATTR(cfg_msc_no_lcls_disable, cfg_msc_no_lcls_disable_cmd, + "no lcls-permitted", + NO_STR "Globally disable LCLS (Local Call Local Switch) for all calls on this MSC.\n", + CMD_ATTR_IMMEDIATE) +{ + gsmnet->lcls_permitted = false; + return CMD_SUCCESS; +} + DEFUN(cfg_msc_cs7_instance_a, cfg_msc_cs7_instance_a_cmd, "cs7-instance-a <0-15>", @@ -477,7 +571,7 @@ DEFUN(cfg_msc_check_imei_rqd, cfg_msc_check_imei_rqd_cmd, return CMD_SUCCESS; } -DEFUN(cfg_msc_paging_response_timer, cfg_msc_paging_response_timer_cmd, +DEFUN_DEPRECATED(cfg_msc_paging_response_timer, cfg_msc_paging_response_timer_cmd, "paging response-timer (default|<1-65535>)", "Configure Paging\n" "Set Paging timeout, the minimum time to pass between (unsuccessful) Pagings sent towards" @@ -485,10 +579,22 @@ DEFUN(cfg_msc_paging_response_timer, cfg_msc_paging_response_timer_cmd, "Set to default timeout (" OSMO_STRINGIFY_VAL(MSC_PAGING_RESPONSE_TIMER_DEFAULT) " seconds)\n" "Set paging timeout in seconds\n") { - if (!strcmp(argv[1], "default")) - gsmnet->paging_response_timer = MSC_PAGING_RESPONSE_TIMER_DEFAULT; + int rat; + int paging_response_timer; + if (!strcmp(argv[0], "default")) + paging_response_timer = MSC_PAGING_RESPONSE_TIMER_DEFAULT; else - gsmnet->paging_response_timer = atoi(argv[0]); + paging_response_timer = atoi(argv[0]); + + for (rat = 0; rat < OSMO_RAT_COUNT; rat++) { + osmo_tdef_set(msc_ran_infra[rat].tdefs, -4, paging_response_timer, OSMO_TDEF_S); + } + + vty_out(vty, "%% paging response-timer is deprecated.%s" + "%% All ran timer has been modified.%s" + "%% use 'timer <geran|utran|sgs> X4 %s' instead%s", + VTY_NEWLINE, VTY_NEWLINE, argv[0], VTY_NEWLINE); + return CMD_SUCCESS; } @@ -582,17 +688,91 @@ DEFUN(cfg_msc_osmux, return CMD_SUCCESS; } +#define NRI_STR "Mapping of Network Resource Indicators to this MSC, for MSC pooling\n" +DEFUN(cfg_msc_nri_bitlen, cfg_msc_nri_bitlen_cmd, + "nri bitlen <0-15>", + NRI_STR + "Set number of NRI bits to place in TMSI identities (always starting just after the most significant octet)\n" + "bit count (default: " OSMO_STRINGIFY_VAL(NRI_BITLEN_DEFAULT) ")\n") +{ + gsmnet->vlr->cfg.nri_bitlen = atoi(argv[0]); + return CMD_SUCCESS; +} + +#define NRI_STR "Mapping of Network Resource Indicators to this MSC, for MSC pooling\n" +#define NRI_ARGS_TO_STR_FMT "%s%s%s" +#define NRI_ARGS_TO_STR_ARGS(ARGC, ARGV) ARGV[0], (ARGC>1)? ".." : "", (ARGC>1)? ARGV[1] : "" +#define NRI_FIRST_LAST_STR "First value of the NRI value range, should not surpass the configured 'nri bitlen'.\n" \ + "Last value of the NRI value range, should not surpass the configured 'nri bitlen' and be larger than the" \ + " first value; if omitted, apply only the first value.\n" + +DEFUN(cfg_msc_nri_add, cfg_msc_nri_add_cmd, + "nri add <0-32767> [<0-32767>]", + NRI_STR "Add NRI value or range to the NRI mapping for this MSC\n" + NRI_FIRST_LAST_STR) +{ + const char *message; + int rc = osmo_nri_ranges_vty_add(&message, NULL, gsmnet->vlr->cfg.nri_ranges, argc, argv, gsmnet->vlr->cfg.nri_bitlen); + if (message) { + vty_out(vty, "%% %s: " NRI_ARGS_TO_STR_FMT, message, NRI_ARGS_TO_STR_ARGS(argc, argv)); + } + if (rc < 0) + return CMD_WARNING; + return CMD_SUCCESS; +} + +DEFUN(cfg_msc_nri_del, cfg_msc_nri_del_cmd, + "nri del <0-32767> [<0-32767>]", + NRI_STR "Remove NRI value or range from the NRI mapping for this MSC\n" + NRI_FIRST_LAST_STR) +{ + const char *message; + int rc = osmo_nri_ranges_vty_del(&message, NULL, gsmnet->vlr->cfg.nri_ranges, argc, argv); + if (message) { + vty_out(vty, "%% %s: " NRI_ARGS_TO_STR_FMT, message, NRI_ARGS_TO_STR_ARGS(argc, argv)); + } + if (rc < 0) + return CMD_WARNING; + return CMD_SUCCESS; +} + +static void msc_write_nri(struct vty *vty) +{ + struct osmo_nri_range *r; + + llist_for_each_entry(r, &gsmnet->vlr->cfg.nri_ranges->entries, entry) { + if (osmo_nri_range_validate(r, 255)) + vty_out(vty, " %% INVALID RANGE:"); + vty_out(vty, " nri add %d", r->first); + if (r->first != r->last) + vty_out(vty, " %d", r->last); + vty_out(vty, "%s", VTY_NEWLINE); + } +} + +DEFUN(show_nri, show_nri_cmd, + "show nri", + SHOW_STR NRI_STR) +{ + msc_write_nri(vty); + return CMD_SUCCESS; +} + static int config_write_msc(struct vty *vty) { vty_out(vty, "msc%s", VTY_NEWLINE); if (gsmnet->mncc_sock_path) vty_out(vty, " mncc external %s%s", gsmnet->mncc_sock_path, VTY_NEWLINE); + else + vty_out(vty, " mncc internal%s", VTY_NEWLINE); vty_out(vty, " mncc guard-timeout %i%s", gsmnet->mncc_guard_timeout, VTY_NEWLINE); vty_out(vty, " ncss guard-timeout %i%s", gsmnet->ncss_guard_timeout, VTY_NEWLINE); vty_out(vty, " %sassign-tmsi%s", gsmnet->vlr->cfg.assign_tmsi? "" : "no ", VTY_NEWLINE); + if (gsmnet->lcls_permitted) + vty_out(vty, " lcls-permitted%s", VTY_NEWLINE); vty_out(vty, " cs7-instance-a %u%s", gsmnet->a.cs7_instance, VTY_NEWLINE); @@ -616,9 +796,6 @@ static int config_write_msc(struct vty *vty) vty_out(vty, " check-imei-rqd 1%s", VTY_NEWLINE); } - if (gsmnet->paging_response_timer != MSC_PAGING_RESPONSE_TIMER_DEFAULT) - vty_out(vty, " paging response-timer %u%s", gsmnet->paging_response_timer, VTY_NEWLINE); - if (gsmnet->emergency.route_to_msisdn) { vty_out(vty, " emergency-call route-to-msisdn %s%s", gsmnet->emergency.route_to_msisdn, VTY_NEWLINE); @@ -644,6 +821,11 @@ static int config_write_msc(struct vty *vty) neighbor_ident_vty_write(vty); + /* Timer introspection commands (generic osmo_tdef API) */ + osmo_tdef_vty_groups_write(vty, " "); + + msc_write_nri(vty); + return CMD_SUCCESS; } @@ -661,58 +843,6 @@ DEFUN(show_bsc, show_bsc_cmd, return CMD_SUCCESS; } -/* -_Subscriber_______________________________________ _LAC_ _RAN___________________ _MSC-A_state_________ _MSC-A_use_ -IMSI-123456789012345:MSISDN-12345:TMSI-0x12345678 1 GERAN-A-4294967295:A5-3 WAIT_CLASSMARK_UPDATE 2=cm_service,trans_cc -IMSI-123456789012356:MSISDN-234567:TMSI-0x123ABC78 65535 UTRAN-Iu-4294967295 COMMUNICATING 2=cm_service,trans_sms -IMSI-123456789012367:MSISDN-98712345890:TMSI-0xF.. - EUTRAN-SGs RELEASING 0=none -IMSI-123456789012378:HONR-12345432101 2 MSC-901-700-423:9876 REMOTE_MSC_A 1=inter_msc -*/ -static void vty_dump_one_conn(struct vty *vty, const struct msub *msub, int *idx) -{ - struct msc_a *msc_a = msub_msc_a(msub); - struct vlr_subscr *vsub = msub_vsub(msub); - char buf[128]; - - if (!(*idx)) - vty_out(vty, - "_Subscriber_______________________________________ _LAC_ _RAN___________________" - " _MSC-A_state_________ _MSC-A_use_%s", - VTY_NEWLINE); - (*idx)++; - - vty_out(vty, "%50s %5u %23s %20s %d=%s%s", - vlr_subscr_short_name(msub_vsub(msub), 50), - vsub ? vsub->cgi.lai.lac : 0, - msub_ran_conn_name(msub), - osmo_fsm_inst_state_name(msc_a->c.fi), - osmo_use_count_total(&msc_a->use_count), - osmo_use_count_name_buf(buf, sizeof(buf), &msc_a->use_count), - VTY_NEWLINE); -} - -DEFUN(show_msc_conn, show_msc_conn_cmd, - "show connection", SHOW_STR "Subscriber Connections\n") -{ - struct msub *msub; - int idx = 0; - llist_for_each_entry(msub, &msub_list, entry) { - vty_dump_one_conn(vty, msub, &idx); - } - return CMD_SUCCESS; -} - -static void vty_trans_hdr(struct vty *vty) -{ - if (llist_empty(&gsmnet->trans_list)) - return; - - vty_out(vty, - "_Subscriber_______________________________________ _RAN___________________" - " _P__ TI CallRef_ _state_%s", - VTY_NEWLINE); -} - static const char *get_trans_proto_str(const struct gsm_trans *trans) { static char buf[256]; @@ -725,146 +855,326 @@ static const char *get_trans_proto_str(const struct gsm_trans *trans) trans->cc.T308_second); break; case TRANS_SMS: - snprintf(buf, sizeof(buf), "%s %s", + snprintf(buf, sizeof(buf), "CP:%s RP:%s", gsm411_cp_state_name(trans->sms.smc_inst.cp_state), gsm411_rp_state_name(trans->sms.smr_inst.rp_state)); break; default: - buf[0] = '\0'; - break; + return NULL; } return buf; } -static void vty_dump_one_trans(struct vty *vty, const struct gsm_trans *trans) +/* Prefix a given format string with a given amount of spaces */ +#define MSC_VTY_DUMP(vty, offset, fmt, args...) \ + vty_out(vty, "%*s" fmt, offset, "", ##args) + +/* Print value of a named flag, prefixed with a given amount of spaces */ +#define MSC_VTY_DUMP_FLAG(vty, offset, name, flag) \ + MSC_VTY_DUMP(vty, offset + 2, "%s: %*s%s%s", \ + name, 30 - (int)strlen(name), "", \ + flag ? "true" : "false", \ + VTY_NEWLINE) + +enum msc_vty_dump_flags { + MSC_VTY_DUMP_F_SUBSCR = (1 << 0), + MSC_VTY_DUMP_F_CONNECTION = (1 << 1), + MSC_VTY_DUMP_F_TRANSACTION = (1 << 2), +}; + +static void vty_dump_one_trans(struct vty *vty, const struct gsm_trans *trans, + int offset, uint8_t dump_flags) { - vty_out(vty, "%50s %23s %4s %02u %08x %s%s", - vlr_subscr_short_name(msc_a_vsub(trans->msc_a), 50), - msub_ran_conn_name(trans->msc_a->c.msub), - trans_type_name(trans->type), - trans->transaction_id, - trans->callref, - get_trans_proto_str(trans), - VTY_NEWLINE); + const char *proto_str; + + if (dump_flags & MSC_VTY_DUMP_F_SUBSCR) { + MSC_VTY_DUMP(vty, offset, "Subscriber: %s%s", + vlr_subscr_name(msc_a_vsub(trans->msc_a)), + VTY_NEWLINE); + } + + if (dump_flags & MSC_VTY_DUMP_F_CONNECTION) { + /* (If msc_a exists, there *must* be a non-null msc_a->c.msub) */ + MSC_VTY_DUMP(vty, offset, "RAN connection: %s%s", + trans->msc_a ? msub_ran_conn_name(trans->msc_a->c.msub) + : "(not established)", + VTY_NEWLINE); + } + + MSC_VTY_DUMP(vty, offset, "Unique (global) identifier: 0x%08x%s", + trans->callref, VTY_NEWLINE); + MSC_VTY_DUMP(vty, offset, "GSM 04.07 identifier (%s): %u%s", + (trans->transaction_id & 0x08) ? "MO" : "MT", + trans->transaction_id, + VTY_NEWLINE); + + MSC_VTY_DUMP(vty, offset, "Type: %s%s", + trans_type_name(trans->type), + VTY_NEWLINE); + + if ((proto_str = get_trans_proto_str(trans))) { + MSC_VTY_DUMP(vty, offset, "Protocol specific: %s%s", + proto_str, VTY_NEWLINE); + } } -DEFUN(show_msc_transaction, show_msc_transaction_cmd, - "show transaction", SHOW_STR "Transactions\n") +static void vty_dump_one_conn(struct vty *vty, const struct msub *msub, + int offset, uint8_t dump_flags) { - struct gsm_trans *trans; + struct vlr_subscr *vsub = msub_vsub(msub); + struct msc_a *msc_a = msub_msc_a(msub); + char buf[128]; - vty_trans_hdr(vty); - llist_for_each_entry(trans, &gsmnet->trans_list, entry) - vty_dump_one_trans(vty, trans); + if (dump_flags & MSC_VTY_DUMP_F_SUBSCR) { + dump_flags = dump_flags &~ MSC_VTY_DUMP_F_SUBSCR; + MSC_VTY_DUMP(vty, offset, "Subscriber: %s%s", + vlr_subscr_name(vsub), + VTY_NEWLINE); + } - return CMD_SUCCESS; + MSC_VTY_DUMP(vty, offset, "RAN connection: %s%s", + msub_ran_conn_name(msub), + VTY_NEWLINE); + MSC_VTY_DUMP(vty, offset, "RAN connection state: %s%s", + osmo_fsm_inst_state_name(msc_a->c.fi), + VTY_NEWLINE); + + if (vsub) { + MSC_VTY_DUMP(vty, offset, "LAC / cell ID: %u / %u%s", + msc_a->via_cell.lai.lac, msc_a->via_cell.cell_identity, + VTY_NEWLINE); + } + + MSC_VTY_DUMP(vty, offset, "Use count total: %d%s", + osmo_use_count_total(&msc_a->use_count), + VTY_NEWLINE); + MSC_VTY_DUMP(vty, offset, "Use count: %s%s", + osmo_use_count_name_buf(buf, sizeof(buf), &msc_a->use_count), + VTY_NEWLINE); + + /* Transactions of this connection */ + if (dump_flags & MSC_VTY_DUMP_F_TRANSACTION) { + struct gsm_trans *trans; + unsigned int i = 0; + + /* Both subscriber and connection info is already printed */ + dump_flags = dump_flags &~ MSC_VTY_DUMP_F_CONNECTION; + dump_flags = dump_flags &~ MSC_VTY_DUMP_F_SUBSCR; + + llist_for_each_entry(trans, &gsmnet->trans_list, entry) { + if (trans->msc_a != msc_a) + continue; + MSC_VTY_DUMP(vty, offset, "Transaction #%02u: %s", + i++, VTY_NEWLINE); + vty_dump_one_trans(vty, trans, offset + 2, dump_flags); + } + } } -static void subscr_dump_full_vty(struct vty *vty, struct vlr_subscr *vsub) +static void vty_dump_one_subscr(struct vty *vty, struct vlr_subscr *vsub, + int offset, uint8_t dump_flags) { - struct gsm_trans *trans; + struct timespec now; char buf[128]; - if (strlen(vsub->name)) - vty_out(vty, " Name: '%s'%s", vsub->name, VTY_NEWLINE); - if (strlen(vsub->msisdn)) - vty_out(vty, " Extension: %s%s", vsub->msisdn, - VTY_NEWLINE); - vty_out(vty, " LAC: %d/0x%x%s", - vsub->cgi.lai.lac, vsub->cgi.lai.lac, VTY_NEWLINE); - vty_out(vty, " RAN: %s%s", - osmo_rat_type_name(vsub->cs.attached_via_ran), VTY_NEWLINE); - vty_out(vty, " IMSI: %s%s", vsub->imsi, VTY_NEWLINE); - if (vsub->tmsi != GSM_RESERVED_TMSI) - vty_out(vty, " TMSI: %08X%s", vsub->tmsi, - VTY_NEWLINE); - if (vsub->tmsi_new != GSM_RESERVED_TMSI) - vty_out(vty, " new TMSI: %08X%s", vsub->tmsi_new, - VTY_NEWLINE); - if (vsub->imei[0] != '\0') - vty_out(vty, " IMEI: %s%s", vsub->imei, VTY_NEWLINE); - if (vsub->imeisv[0] != '\0') - vty_out(vty, " IMEISV: %s%s", vsub->imeisv, VTY_NEWLINE); - - vty_out(vty, " Flags: %s", VTY_NEWLINE); - vty_out(vty, " IMSI detached: %s%s", - vsub->imsi_detached_flag ? "true" : "false", VTY_NEWLINE); - vty_out(vty, " Conf. by radio contact: %s%s", - vsub->conf_by_radio_contact_ind ? "true" : "false", - VTY_NEWLINE); - vty_out(vty, " Subscr. data conf. by HLR: %s%s", - vsub->sub_dataconf_by_hlr_ind ? "true" : "false", VTY_NEWLINE); - vty_out(vty, " Location conf. in HLR: %s%s", - vsub->loc_conf_in_hlr_ind ? "true" : "false", VTY_NEWLINE); - vty_out(vty, " Subscriber dormant: %s%s", - vsub->dormant_ind ? "true" : "false", VTY_NEWLINE); - vty_out(vty, " Received cancel locataion: %s%s", - vsub->cancel_loc_rx ? "true" : "false", VTY_NEWLINE); - vty_out(vty, " MS not reachable: %s%s", - vsub->ms_not_reachable_flag ? "true" : "false", VTY_NEWLINE); - vty_out(vty, " LA allowed: %s%s", - vsub->la_allowed ? "true" : "false", VTY_NEWLINE); + if (vsub->name[0] != '\0') { + MSC_VTY_DUMP(vty, offset, "Name: '%s'%s", + vsub->name, VTY_NEWLINE); + } + if (vsub->msisdn[0] != '\0') { + MSC_VTY_DUMP(vty, offset, "MSISDN: %s%s", + vsub->msisdn, VTY_NEWLINE); + } + + MSC_VTY_DUMP(vty, offset, "LAC / cell ID: %u / %u%s", + vsub->cgi.lai.lac, vsub->cgi.cell_identity, + VTY_NEWLINE); + MSC_VTY_DUMP(vty, offset, "RAN type: %s%s", + osmo_rat_type_name(vsub->cs.attached_via_ran), + VTY_NEWLINE); + + MSC_VTY_DUMP(vty, offset, "IMSI: %s%s", + vsub->imsi, VTY_NEWLINE); + if (vsub->tmsi != GSM_RESERVED_TMSI) { + MSC_VTY_DUMP(vty, offset, "TMSI: %08X%s", + vsub->tmsi, VTY_NEWLINE); + } + if (vsub->tmsi_new != GSM_RESERVED_TMSI) { + MSC_VTY_DUMP(vty, offset, "New TMSI: %08X%s", + vsub->tmsi_new, VTY_NEWLINE); + } + if (vsub->imei[0] != '\0') { + MSC_VTY_DUMP(vty, offset, "IMEI: %s%s", + vsub->imei, VTY_NEWLINE); + } + if (vsub->imeisv[0] != '\0') { + MSC_VTY_DUMP(vty, offset, "IMEISV: %s%s", + vsub->imeisv, VTY_NEWLINE); + } + + MSC_VTY_DUMP(vty, offset, "Flags: %s", VTY_NEWLINE); + MSC_VTY_DUMP_FLAG(vty, offset, "IMSI detached", + vsub->imsi_detached_flag); + MSC_VTY_DUMP_FLAG(vty, offset, "Conf. by radio contact", + vsub->conf_by_radio_contact_ind); + MSC_VTY_DUMP_FLAG(vty, offset, "Subscr. data conf. by HLR", + vsub->sub_dataconf_by_hlr_ind); + MSC_VTY_DUMP_FLAG(vty, offset, "Location conf. in HLR", + vsub->loc_conf_in_hlr_ind); + MSC_VTY_DUMP_FLAG(vty, offset, "Subscriber dormant", + vsub->dormant_ind); + MSC_VTY_DUMP_FLAG(vty, offset, "Received cancel location", + vsub->cancel_loc_rx); + MSC_VTY_DUMP_FLAG(vty, offset, "MS not reachable", + vsub->ms_not_reachable_flag); + MSC_VTY_DUMP_FLAG(vty, offset, "LA allowed", + vsub->la_allowed); if (vsub->last_tuple) { struct vlr_auth_tuple *t = vsub->last_tuple; - vty_out(vty, " A3A8 last tuple (used %d times):%s", - t->use_count, VTY_NEWLINE); - vty_out(vty, " seq # : %d%s", - t->key_seq, VTY_NEWLINE); - vty_out(vty, " RAND : %s%s", - osmo_hexdump(t->vec.rand, sizeof(t->vec.rand)), - VTY_NEWLINE); - vty_out(vty, " SRES : %s%s", - osmo_hexdump(t->vec.sres, sizeof(t->vec.sres)), - VTY_NEWLINE); - vty_out(vty, " Kc : %s%s", - osmo_hexdump(t->vec.kc, sizeof(t->vec.kc)), - VTY_NEWLINE); + MSC_VTY_DUMP(vty, offset, "A3A8 last tuple (used %d times): %s", + t->use_count, VTY_NEWLINE); + MSC_VTY_DUMP(vty, offset + 2, "seq # : %d%s", + t->key_seq, VTY_NEWLINE); + MSC_VTY_DUMP(vty, offset + 2, "RAND : %s%s", + osmo_hexdump(t->vec.rand, sizeof(t->vec.rand)), + VTY_NEWLINE); + MSC_VTY_DUMP(vty, offset + 2, "SRES : %s%s", + osmo_hexdump(t->vec.sres, sizeof(t->vec.sres)), + VTY_NEWLINE); + MSC_VTY_DUMP(vty, offset + 2, "Kc : %s%s", + osmo_hexdump(t->vec.kc, sizeof(t->vec.kc)), + VTY_NEWLINE); } - vty_out(vty, " Paging: %s paging for %d requests%s", - vsub->cs.is_paging ? "is" : "not", - llist_count(&vsub->cs.requests), - VTY_NEWLINE); - - /* SGs related */ - vty_out(vty, " SGs-state: %s%s", - osmo_fsm_inst_state_name(vsub->sgs_fsm), VTY_NEWLINE); - if (strlen(vsub->sgs.mme_name)) - vty_out(vty, " SGs-MME: %s%s", vsub->sgs.mme_name, VTY_NEWLINE); - else - vty_out(vty, " SGs-MME: (none)%s", VTY_NEWLINE); + if (!vlr_timer(vsub->vlr, 3212)) { + MSC_VTY_DUMP(vty, offset, "Expires: never (T3212 is disabled)%s", + VTY_NEWLINE); + } else if (vsub->expire_lu == VLR_SUBSCRIBER_NO_EXPIRATION) { + MSC_VTY_DUMP(vty, offset, "Expires: never%s", + VTY_NEWLINE); + } else if (osmo_clock_gettime(CLOCK_MONOTONIC, &now) == 0) { + MSC_VTY_DUMP(vty, offset, "Expires: in %ld min %ld sec%s", + (vsub->expire_lu - now.tv_sec) / 60, + (vsub->expire_lu - now.tv_sec) % 60, + VTY_NEWLINE); + } - vty_out(vty, " Use: %s%s", osmo_use_count_name_buf(buf, sizeof(buf), &vsub->use_count), VTY_NEWLINE); + MSC_VTY_DUMP(vty, offset, "Paging: %s paging for %d requests%s", + vsub->cs.is_paging ? "is" : "not", + llist_count(&vsub->cs.requests), + VTY_NEWLINE); - /* Connection */ - if (vsub->msc_conn_ref) { + /* SGs related */ + MSC_VTY_DUMP(vty, offset, "SGs-state: %s%s", + osmo_fsm_inst_state_name(vsub->sgs_fsm), + VTY_NEWLINE); + MSC_VTY_DUMP(vty, offset, "SGs-MME: %s%s", + vsub->sgs.mme_name[0] != '\0' ? vsub->sgs.mme_name : "(none)", + VTY_NEWLINE); + + MSC_VTY_DUMP(vty, offset, "Use count total: %d%s", + osmo_use_count_total(&vsub->use_count), + VTY_NEWLINE); + MSC_VTY_DUMP(vty, offset, "Use count: %s%s", + osmo_use_count_name_buf(buf, sizeof(buf), &vsub->use_count), + VTY_NEWLINE); + + /* Connection(s) and/or transactions of this subscriber */ + if (dump_flags & MSC_VTY_DUMP_F_CONNECTION) { struct msub *msub = msub_for_vsub(vsub); - int idx = 0; - if (msub) { - vty_dump_one_conn(vty, msub, &idx); + if (!msub) + return; + + /* Subscriber info is already printed */ + dump_flags = dump_flags &~ MSC_VTY_DUMP_F_SUBSCR; + + MSC_VTY_DUMP(vty, offset, "Connection: %s", VTY_NEWLINE); + vty_dump_one_conn(vty, msub, offset + 2, dump_flags); + } else if (dump_flags & MSC_VTY_DUMP_F_TRANSACTION) { + struct gsm_trans *trans; + unsigned int i = 0; + + /* Subscriber info is already printed */ + dump_flags = dump_flags &~ MSC_VTY_DUMP_F_SUBSCR; + /* Do not print connection info, but mention it */ + dump_flags |= MSC_VTY_DUMP_F_CONNECTION; + + llist_for_each_entry(trans, &gsmnet->trans_list, entry) { + if (trans->vsub != vsub) + continue; + MSC_VTY_DUMP(vty, offset, "Transaction #%02u: %s", + i++, VTY_NEWLINE); + vty_dump_one_trans(vty, trans, offset + 2, dump_flags); } } +} + +DEFUN(show_msc_transaction, show_msc_transaction_cmd, + "show transaction", + SHOW_STR "Transactions\n") +{ + struct gsm_trans *trans; + uint8_t flags = 0x00; + unsigned int i = 0; + + flags |= MSC_VTY_DUMP_F_CONNECTION; + flags |= MSC_VTY_DUMP_F_SUBSCR; - /* Transactions */ - vty_trans_hdr(vty); llist_for_each_entry(trans, &gsmnet->trans_list, entry) { - if (trans->vsub != vsub) - continue; - vty_dump_one_trans(vty, trans); + vty_out(vty, " Transaction #%02u: %s", i++, VTY_NEWLINE); + vty_dump_one_trans(vty, trans, 4, flags); + } + + return CMD_SUCCESS; +} + +DEFUN(show_msc_conn, show_msc_conn_cmd, + "show connection [trans]", + SHOW_STR "Subscriber Connections\n" + "Show child transactions of each connection\n") +{ + uint8_t flags = 0x00; + unsigned int i = 0; + struct msub *msub; + + if (argc > 0) + flags |= MSC_VTY_DUMP_F_TRANSACTION; + flags |= MSC_VTY_DUMP_F_SUBSCR; + + llist_for_each_entry(msub, &msub_list, entry) { + vty_out(vty, " Connection #%02u: %s", i++, VTY_NEWLINE); + vty_dump_one_conn(vty, msub, 4, flags); } + + return CMD_SUCCESS; } +#define SUBSCR_FLAGS "[(conn|trans|conn+trans)]" +#define SUBSCR_FLAGS_HELP \ + "Show child connections\n" \ + "Show child transactions\n" \ + "Show child connections and transactions\n" + /* Subscriber */ -DEFUN(show_subscr_cache, - show_subscr_cache_cmd, - "show subscriber cache", +DEFUN(show_subscr_cache, show_subscr_cache_cmd, + "show subscriber cache " SUBSCR_FLAGS, SHOW_STR "Show information about subscribers\n" - "Display contents of subscriber cache\n") + "Display contents of subscriber cache\n" + SUBSCR_FLAGS_HELP) { struct vlr_subscr *vsub; - int count = 0; + unsigned int count = 0; + uint8_t flags = 0x00; + unsigned int i = 0; + + if (argc && strcmp(argv[0], "conn") == 0) + flags |= MSC_VTY_DUMP_F_CONNECTION; + else if (argc && strcmp(argv[0], "trans") == 0) + flags |= MSC_VTY_DUMP_F_TRANSACTION; + else if (argc && strcmp(argv[0], "conn+trans") == 0) + flags |= MSC_VTY_DUMP_F_CONNECTION | MSC_VTY_DUMP_F_TRANSACTION; llist_for_each_entry(vsub, &gsmnet->vlr->subscribers, list) { if (++count > 100) { @@ -872,8 +1182,8 @@ DEFUN(show_subscr_cache, " stopping here.%s", count-1, VTY_NEWLINE); break; } - vty_out(vty, " Subscriber:%s", VTY_NEWLINE); - subscr_dump_full_vty(vty, vsub); + vty_out(vty, " Subscriber #%02u: %s", i++, VTY_NEWLINE); + vty_dump_one_subscr(vty, vsub, 4, flags); } return CMD_SUCCESS; @@ -945,6 +1255,11 @@ static int _send_sms_str(struct vlr_subscr *receiver, struct gsm_sms *sms; sms = sms_from_text(receiver, sender_msisdn, 0, str); + if (!sms) { + LOGP(DLSMS, LOGL_ERROR, "Failed to allocate SMS\n"); + return CMD_WARNING; + } + sms->protocol_id = tp_pid; /* store in database for the queue */ @@ -982,14 +1297,14 @@ static struct vlr_subscr *get_vsub_by_argv(struct gsm_network *gsmnet, "Legacy alias for 'imsi'\n" \ "Identifier for the subscriber\n" -DEFUN(show_subscr, - show_subscr_cmd, - "show subscriber " SUBSCR_TYPES " ID", - SHOW_STR SUBSCR_HELP) +DEFUN(show_subscr, show_subscr_cmd, + "show subscriber " SUBSCR_TYPES " ID " SUBSCR_FLAGS, + SHOW_STR SUBSCR_HELP SUBSCR_FLAGS_HELP) { - struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], - argv[1]); + struct vlr_subscr *vsub; + uint8_t flags = 0x00; + vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]); if (!vsub) { vty_out(vty, "%% No subscriber found for %s %s%s", argv[0], argv[1], VTY_NEWLINE); @@ -1001,18 +1316,25 @@ DEFUN(show_subscr, * this, and since this is not multi-threaded, this vlr_subscr_put() cannot possibly reach a count of 0. */ vlr_subscr_put(vsub, VSUB_USE_VTY); - subscr_dump_full_vty(vty, vsub); + if (argc > 2 && strcmp(argv[2], "conn") == 0) + flags |= MSC_VTY_DUMP_F_CONNECTION; + else if (argc > 2 && strcmp(argv[2], "trans") == 0) + flags |= MSC_VTY_DUMP_F_TRANSACTION; + else if (argc > 2 && strcmp(argv[2], "conn+trans") == 0) + flags |= MSC_VTY_DUMP_F_CONNECTION | MSC_VTY_DUMP_F_TRANSACTION; + + vty_out(vty, " Subscriber: %s", VTY_NEWLINE); + vty_dump_one_subscr(vty, vsub, 4, flags); return CMD_SUCCESS; } -DEFUN(subscriber_create, - subscriber_create_cmd, - "subscriber create imsi ID", - "Operations on a Subscriber\n" \ - "Create new subscriber\n" \ - "Identify the subscriber by his IMSI\n" \ - "Identifier for the subscriber\n") +DEFUN_DEPRECATED(subscriber_create, subscriber_create_cmd, + "subscriber create imsi ID", + "Operations on a Subscriber\n" + "Create new subscriber\n" + "Identify the subscriber by his IMSI\n" + "Identifier for the subscriber\n") { vty_out(vty, "%% 'subscriber create' now needs to be done at osmo-hlr%s", VTY_NEWLINE); @@ -1413,6 +1735,7 @@ DEFUN(subscriber_mstest_close, gsm0414_tx_close_tch_loop_cmd(msc_a, loop_mode); + vlr_subscr_put(vsub, VSUB_USE_VTY); return CMD_SUCCESS; } @@ -1441,6 +1764,7 @@ DEFUN(subscriber_mstest_open, gsm0414_tx_open_loop_cmd(msc_a); + vlr_subscr_put(vsub, VSUB_USE_VTY); return CMD_SUCCESS; } @@ -1500,94 +1824,49 @@ DEFUN(show_stats, SHOW_STR "Display network statistics\n") { vty_out(vty, "Location Update : %" PRIu64 " attach, %" PRIu64 " normal, %" PRIu64 " periodic%s", - gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_ATTACH].current, - gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_NORMAL].current, - gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_PERIODIC].current, + rate_ctr_group_get_ctr(gsmnet->msc_ctrs, MSC_CTR_LOC_UPDATE_TYPE_ATTACH)->current, + rate_ctr_group_get_ctr(gsmnet->msc_ctrs, MSC_CTR_LOC_UPDATE_TYPE_NORMAL)->current, + rate_ctr_group_get_ctr(gsmnet->msc_ctrs, MSC_CTR_LOC_UPDATE_TYPE_PERIODIC)->current, VTY_NEWLINE); vty_out(vty, "IMSI Detach Indications : %" PRIu64 "%s", - gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_DETACH].current, + rate_ctr_group_get_ctr(gsmnet->msc_ctrs, MSC_CTR_LOC_UPDATE_TYPE_DETACH)->current, VTY_NEWLINE); vty_out(vty, "Location Updating Results: %" PRIu64 " completed, %" PRIu64 " failed%s", - gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_COMPLETED].current, - gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_FAILED].current, + rate_ctr_group_get_ctr(gsmnet->msc_ctrs, MSC_CTR_LOC_UPDATE_COMPLETED)->current, + rate_ctr_group_get_ctr(gsmnet->msc_ctrs, MSC_CTR_LOC_UPDATE_FAILED)->current, VTY_NEWLINE); vty_out(vty, "SMS MO : %" PRIu64 " submitted, %" PRIu64 " no receiver%s", - gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_SUBMITTED].current, - gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_NO_RECEIVER].current, + rate_ctr_group_get_ctr(gsmnet->msc_ctrs, MSC_CTR_SMS_SUBMITTED)->current, + rate_ctr_group_get_ctr(gsmnet->msc_ctrs, MSC_CTR_SMS_NO_RECEIVER)->current, VTY_NEWLINE); vty_out(vty, "SMS MT : %" PRIu64 " delivered, %" PRIu64 " no memory, %" PRIu64 " other error%s", - gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_DELIVERED].current, - gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_RP_ERR_MEM].current, - gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_RP_ERR_OTHER].current, + rate_ctr_group_get_ctr(gsmnet->msc_ctrs, MSC_CTR_SMS_DELIVERED)->current, + rate_ctr_group_get_ctr(gsmnet->msc_ctrs, MSC_CTR_SMS_RP_ERR_MEM)->current, + rate_ctr_group_get_ctr(gsmnet->msc_ctrs, MSC_CTR_SMS_RP_ERR_OTHER)->current, VTY_NEWLINE); vty_out(vty, "MO Calls : %" PRIu64 " setup, %" PRIu64 " connect ack%s", - gsmnet->msc_ctrs->ctr[MSC_CTR_CALL_MO_SETUP].current, - gsmnet->msc_ctrs->ctr[MSC_CTR_CALL_MO_CONNECT_ACK].current, + rate_ctr_group_get_ctr(gsmnet->msc_ctrs, MSC_CTR_CALL_MO_SETUP)->current, + rate_ctr_group_get_ctr(gsmnet->msc_ctrs, MSC_CTR_CALL_MO_CONNECT_ACK)->current, VTY_NEWLINE); vty_out(vty, "MT Calls : %" PRIu64 " setup, %" PRIu64 " connect%s", - gsmnet->msc_ctrs->ctr[MSC_CTR_CALL_MT_SETUP].current, - gsmnet->msc_ctrs->ctr[MSC_CTR_CALL_MT_CONNECT].current, + rate_ctr_group_get_ctr(gsmnet->msc_ctrs, MSC_CTR_CALL_MT_SETUP)->current, + rate_ctr_group_get_ctr(gsmnet->msc_ctrs, MSC_CTR_CALL_MT_CONNECT)->current, VTY_NEWLINE); vty_out(vty, "MO NC SS/USSD : %" PRIu64 " requests, %" PRIu64 " established, %" PRIu64 " rejected%s", - gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MO_REQUESTS].current, - gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MO_ESTABLISHED].current, - gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MO_REQUESTS].current - - gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MO_ESTABLISHED].current, + rate_ctr_group_get_ctr(gsmnet->msc_ctrs, MSC_CTR_NC_SS_MO_REQUESTS)->current, + rate_ctr_group_get_ctr(gsmnet->msc_ctrs, MSC_CTR_NC_SS_MO_ESTABLISHED)->current, + rate_ctr_group_get_ctr(gsmnet->msc_ctrs, MSC_CTR_NC_SS_MO_REQUESTS)->current + - rate_ctr_group_get_ctr(gsmnet->msc_ctrs, MSC_CTR_NC_SS_MO_ESTABLISHED)->current, VTY_NEWLINE); vty_out(vty, "MT NC SS/USSD : %" PRIu64 " requests, %" PRIu64 " established, %" PRIu64 " rejected%s", - gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MT_REQUESTS].current, - gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MT_ESTABLISHED].current, - gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MT_REQUESTS].current - - gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MT_ESTABLISHED].current, + rate_ctr_group_get_ctr(gsmnet->msc_ctrs, MSC_CTR_NC_SS_MT_REQUESTS)->current, + rate_ctr_group_get_ctr(gsmnet->msc_ctrs, MSC_CTR_NC_SS_MT_ESTABLISHED)->current, + rate_ctr_group_get_ctr(gsmnet->msc_ctrs, MSC_CTR_NC_SS_MT_REQUESTS)->current + - rate_ctr_group_get_ctr(gsmnet->msc_ctrs, MSC_CTR_NC_SS_MT_ESTABLISHED)->current, VTY_NEWLINE); return CMD_SUCCESS; } -DEFUN(show_smsqueue, - show_smsqueue_cmd, - "show sms-queue", - SHOW_STR "Display SMSqueue statistics\n") -{ - sms_queue_stats(gsmnet->sms_queue, vty); - return CMD_SUCCESS; -} - -DEFUN(smsqueue_trigger, - smsqueue_trigger_cmd, - "sms-queue trigger", - "SMS Queue\n" "Trigger sending messages\n") -{ - sms_queue_trigger(gsmnet->sms_queue); - return CMD_SUCCESS; -} - -DEFUN(smsqueue_max, - smsqueue_max_cmd, - "sms-queue max-pending <1-500>", - "SMS Queue\n" "SMS to deliver in parallel\n" "Amount\n") -{ - sms_queue_set_max_pending(gsmnet->sms_queue, atoi(argv[0])); - return CMD_SUCCESS; -} - -DEFUN(smsqueue_clear, - smsqueue_clear_cmd, - "sms-queue clear", - "SMS Queue\n" "Clear the queue of pending SMS\n") -{ - sms_queue_clear(gsmnet->sms_queue); - return CMD_SUCCESS; -} - -DEFUN(smsqueue_fail, - smsqueue_fail_cmd, - "sms-queue max-failure <1-500>", - "SMS Queue\n" "Maximum amount of delivery failures\n" "Amount\n") -{ - sms_queue_set_max_failure(gsmnet->sms_queue, atoi(argv[0])); - return CMD_SUCCESS; -} - DEFUN(cfg_mncc_int, cfg_mncc_int_cmd, "mncc-int", "Configure internal MNCC handler") @@ -1714,11 +1993,11 @@ DEFUN(cfg_hlr_ipa_name, "Set the IPA name of this MSC\n" "A unique name for this MSC. For example: PLMN + redundancy server number: MSC-901-70-0. " "This name is used for GSUP routing and must be set if more than one MSC is connected to the HLR. " - "The default is 'MSC-00-00-00-00-00-00'.\n") + "The default is 'unnamed-MSC'.\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); + "It can only be set in the configuration file.%s", VTY_NEWLINE); return CMD_WARNING; } @@ -1752,6 +2031,7 @@ void msc_vty_init(struct gsm_network *msc_network) install_element(GSMNET_NODE, &cfg_net_name_short_cmd); install_element(GSMNET_NODE, &cfg_net_name_long_cmd); install_element(GSMNET_NODE, &cfg_net_encryption_cmd); + install_element(GSMNET_NODE, &cfg_net_encryption_uea_cmd); install_element(GSMNET_NODE, &cfg_net_authentication_cmd); install_element(GSMNET_NODE, &cfg_net_rrlp_mode_cmd); install_element(GSMNET_NODE, &cfg_net_mm_info_cmd); @@ -1760,10 +2040,17 @@ void msc_vty_init(struct gsm_network *msc_network) install_element(GSMNET_NODE, &cfg_net_no_timezone_cmd); install_element(GSMNET_NODE, &cfg_net_per_loc_upd_cmd); install_element(GSMNET_NODE, &cfg_net_no_per_loc_upd_cmd); + install_element(GSMNET_NODE, &cfg_net_call_wait_cmd); + install_element(GSMNET_NODE, &cfg_net_no_call_wait_cmd); + mgcp_client_pool_vty_init(GSMNET_NODE, MGW_NODE, NULL, msc_network->mgw.mgw_pool); + install_element(CONFIG_NODE, &cfg_msc_cmd); install_node(&msc_node, config_write_msc); + install_element(MSC_NODE, &cfg_sms_database_cmd); install_element(MSC_NODE, &cfg_msc_assign_tmsi_cmd); + install_element(MSC_NODE, &cfg_msc_lcls_disable_cmd); + install_element(MSC_NODE, &cfg_msc_no_lcls_disable_cmd); install_element(MSC_NODE, &cfg_msc_mncc_internal_cmd); install_element(MSC_NODE, &cfg_msc_mncc_external_cmd); install_element(MSC_NODE, &cfg_msc_mncc_guard_timeout_cmd); @@ -1781,14 +2068,24 @@ void msc_vty_init(struct gsm_network *msc_network) install_element(MSC_NODE, &cfg_msc_no_sms_over_gsup_cmd); install_element(MSC_NODE, &cfg_msc_osmux_cmd); install_element(MSC_NODE, &cfg_msc_handover_number_range_cmd); + install_element(MSC_NODE, &cfg_msc_nri_bitlen_cmd); + install_element(MSC_NODE, &cfg_msc_nri_add_cmd); + install_element(MSC_NODE, &cfg_msc_nri_del_cmd); neighbor_ident_vty_init(msc_network); - mgcp_client_vty_init(msc_network, MSC_NODE, &msc_network->mgw.conf); + /* Timer configuration commands (generic osmo_tdef API) */ + osmo_tdef_vty_groups_init(MSC_NODE, msc_tdef_group); + + /* Deprecated: Old MGCP config without pooling support in MSC node: */ + mgcp_client_vty_init(msc_network, MSC_NODE, msc_network->mgw.conf); + #ifdef BUILD_IU ranap_iu_vty_init(MSC_NODE, (enum ranap_nsap_addr_enc*)&msc_network->iu.rab_assign_addr_enc); #endif sgs_vty_init(); + smsc_vty_init(msc_network); + asci_vty_init(msc_network); osmo_fsm_vty_add_cmds(); @@ -1799,6 +2096,7 @@ void msc_vty_init(struct gsm_network *msc_network) install_element_ve(&show_bsc_cmd); install_element_ve(&show_msc_conn_cmd); install_element_ve(&show_msc_transaction_cmd); + install_element_ve(&show_nri_cmd); install_element_ve(&sms_send_pend_cmd); install_element_ve(&sms_delete_expired_cmd); @@ -1813,14 +2111,9 @@ void msc_vty_init(struct gsm_network *msc_network) install_element_ve(&subscriber_mstest_open_cmd); install_element_ve(&subscriber_paging_cmd); install_element_ve(&show_stats_cmd); - install_element_ve(&show_smsqueue_cmd); install_element_ve(&logging_fltr_imsi_cmd); install_element(ENABLE_NODE, &ena_subscr_expire_cmd); - install_element(ENABLE_NODE, &smsqueue_trigger_cmd); - install_element(ENABLE_NODE, &smsqueue_max_cmd); - install_element(ENABLE_NODE, &smsqueue_clear_cmd); - install_element(ENABLE_NODE, &smsqueue_fail_cmd); install_element(ENABLE_NODE, &subscriber_send_pending_sms_cmd); install_element(ENABLE_NODE, &subscriber_sms_delete_all_cmd); diff --git a/src/libmsc/msub.c b/src/libmsc/msub.c index 2021ed827..ac93665a7 100644 --- a/src/libmsc/msub.c +++ b/src/libmsc/msub.c @@ -1,6 +1,6 @@ /* Manage all MSC roles of a connected subscriber (MSC-A, MSC-I, MSC-T) */ /* - * (C) 2019 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de> + * (C) 2019 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de> * All Rights Reserved * * SPDX-License-Identifier: AGPL-3.0+ @@ -488,9 +488,9 @@ static void _msub_update_id(struct msub *msub, const char *subscr_name) } /* Compose an ID almost like gsm48_mi_to_string(), but print the MI type along, and print a TMSI as hex. */ -void msub_update_id_from_mi(struct msub *msub, const uint8_t mi[], uint8_t mi_len) +void msub_update_id_from_mi(struct msub *msub, const struct osmo_mobile_identity *mi) { - _msub_update_id(msub, osmo_mi_name(mi, mi_len)); + _msub_update_id(msub, osmo_mobile_identity_to_str_c(OTC_SELECT, mi)); } /* Update msub->fi id string from current msub->vsub and msub->complete_layer3_type. */ @@ -544,6 +544,8 @@ void msc_role_forget_conn(struct osmo_fsm_inst *role, struct ran_conn *conn) *conn_p = NULL; } +/* NOTE: the resulting message buffer will be attached to OTC_SELECT, so its lifetime + * is limited by the current select() loop iteration. Use talloc_steal() to avoid this. */ struct msgb *msc_role_ran_encode(struct osmo_fsm_inst *fi, const struct ran_msg *ran_msg) { struct msc_role_common *c = fi->priv; @@ -556,6 +558,8 @@ struct msgb *msc_role_ran_encode(struct osmo_fsm_inst *fi, const struct ran_msg msg = c->ran->ran_encode(fi, ran_msg); if (!msg) LOGPFSML(fi, LOGL_ERROR, "Failed to encode %s\n", ran_msg_type_name(ran_msg->msg_type)); + else + talloc_steal(OTC_SELECT, msg); return msg; } diff --git a/src/libmsc/neighbor_ident.c b/src/libmsc/neighbor_ident.c index 5120e168e..b3cdf17c4 100644 --- a/src/libmsc/neighbor_ident.c +++ b/src/libmsc/neighbor_ident.c @@ -1,6 +1,6 @@ /* Manage identity of neighboring BSS cells for inter-MSC handover. */ /* - * (C) 2018-2019 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de> + * (C) 2018-2019 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de> * All Rights Reserved * * SPDX-License-Identifier: AGPL-3.0+ diff --git a/src/libmsc/paging.c b/src/libmsc/paging.c index 5baa0dca0..9b3dad5d2 100644 --- a/src/libmsc/paging.c +++ b/src/libmsc/paging.c @@ -1,5 +1,5 @@ /* - * (C) 2019 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de> + * (C) 2019 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de> * All Rights Reserved * * SPDX-License-Identifier: AGPL-3.0+ @@ -49,6 +49,10 @@ const struct value_string paging_cause_names[] = { static void paging_response_timer_cb(void *data) { struct vlr_subscr *vsub = data; + + if (vsub->cs.attached_via_ran == OSMO_RAT_EUTRAN_SGS) + sgs_iface_tx_serv_abrt(vsub); + paging_expired(vsub); } @@ -69,11 +73,9 @@ static int msc_paging_request(struct paging_request *pr, struct vlr_subscr *vsub case OSMO_RAT_EUTRAN_SGS: return sgs_iface_tx_paging(vsub, sgs_serv_ind_from_paging_cause(pr->cause)); default: - break; + LOG_PAGING(vsub, pr, LOGL_ERROR, "Cannot page, subscriber not attached\n"); + return -EINVAL; } - - LOG_PAGING(vsub, pr, LOGL_ERROR, " Cannot page, subscriber not attached\n"); - return -EINVAL; } struct paging_request *paging_request_start(struct vlr_subscr *vsub, enum paging_cause cause, @@ -82,9 +84,9 @@ struct paging_request *paging_request_start(struct vlr_subscr *vsub, enum paging { int rc; struct paging_request *pr; - struct gsm_network *net = vsub->vlr->user_ctx; + int paging_response_timer; - pr = talloc_zero(vsub, struct paging_request); + pr = talloc(vsub, struct paging_request); OSMO_ASSERT(pr); *pr = (struct paging_request){ .label = label, @@ -108,8 +110,9 @@ struct paging_request *paging_request_start(struct vlr_subscr *vsub, enum paging /* reduced on the first paging callback */ vlr_subscr_get(vsub, VSUB_USE_PAGING); vsub->cs.is_paging = true; + paging_response_timer = osmo_tdef_get(msc_ran_infra[vsub->cs.attached_via_ran].tdefs, -4, OSMO_TDEF_S, 10); osmo_timer_setup(&vsub->cs.paging_response_timer, paging_response_timer_cb, vsub); - osmo_timer_schedule(&vsub->cs.paging_response_timer, net->paging_response_timer, 0); + osmo_timer_schedule(&vsub->cs.paging_response_timer, paging_response_timer, 0); } llist_add_tail(&pr->entry, &vsub->cs.requests); @@ -117,6 +120,34 @@ struct paging_request *paging_request_start(struct vlr_subscr *vsub, enum paging return pr; } +/* Two subscribers (e.g. an old TMSI and a new TMSI) turn out to have the same identity, so in order to discard one of + * them, transfer any pending Paging requests to the vsub that will survive. */ +void paging_request_join_vsub(struct vlr_subscr *keep_vsub, struct vlr_subscr *discarding_vsub) +{ + struct paging_request *pr; + + if (!discarding_vsub->cs.is_paging) + return; + + /* transfer all Paging Response callbacks */ + while ((pr = llist_first_entry_or_null(&discarding_vsub->cs.requests, struct paging_request, entry))) { + llist_del(&pr->entry); + talloc_steal(keep_vsub, pr); + llist_add_tail(&pr->entry, &keep_vsub->cs.requests); + } + + /* make sure a Paging use count is present on keep_vsub, if needed */ + if (!keep_vsub->cs.is_paging && !llist_empty(&keep_vsub->cs.requests)) { + vlr_subscr_get(keep_vsub, VSUB_USE_PAGING); + keep_vsub->cs.is_paging = true; + } + + /* Already made sure at the top of this function that discarding_vsub->cs.is_paging == true */ + discarding_vsub->cs.is_paging = false; + osmo_timer_del(&discarding_vsub->cs.paging_response_timer); + vlr_subscr_put(discarding_vsub, VSUB_USE_PAGING); +} + void paging_request_remove(struct paging_request *pr) { struct gsm_trans *trans = pr->trans; @@ -135,6 +166,11 @@ static void paging_concludes(struct vlr_subscr *vsub, struct msc_a *msc_a) struct paging_request *pr, *pr_next; struct paging_signal_data sig_data; + if (!vsub) { + /* A Paging Response has no subscriber. (Related: OS#4449) */ + return; + } + osmo_timer_del(&vsub->cs.paging_response_timer); llist_for_each_entry_safe(pr, pr_next, &vsub->cs.requests, entry) { diff --git a/src/libmsc/ran_conn.c b/src/libmsc/ran_conn.c index 8418c9eb5..07638016a 100644 --- a/src/libmsc/ran_conn.c +++ b/src/libmsc/ran_conn.c @@ -1,7 +1,7 @@ /* MSC RAN connection implementation */ /* - * (C) 2016-2018 by sysmocom s.m.f.c. <info@sysmocom.de> + * (C) 2016-2018 by sysmocom s.f.m.c. <info@sysmocom.de> * All Rights Reserved * * Author: Neels Hofmeyr diff --git a/src/libmsc/ran_infra.c b/src/libmsc/ran_infra.c index af4054149..6a178403f 100644 --- a/src/libmsc/ran_infra.c +++ b/src/libmsc/ran_infra.c @@ -1,6 +1,6 @@ /* Lookup table for various RAN implementations */ /* - * (C) 2019 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de> + * (C) 2019 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de> * All Rights Reserved * * SPDX-License-Identifier: AGPL-3.0+ @@ -43,6 +43,7 @@ const struct value_string an_proto_names[] = { { .T = -1, .default_val = 5, .desc = "RAN connection Complete Layer 3, Authentication and Ciphering timeout" }, \ { .T = -2, .default_val = 30, .desc = "RAN connection release sanity timeout" }, \ { .T = -3, .default_val = 10, .desc = "Timeout to find a target BSS after Handover Required" }, \ + { .T = -4, .default_val = 10, .desc = "Paging response timeout" }, \ struct osmo_tdef msc_tdefs_geran[] = { RAN_TDEFS @@ -55,6 +56,7 @@ struct osmo_tdef msc_tdefs_utran[] = { }; struct osmo_tdef msc_tdefs_sgs[] = { + { .T = -4, .default_val = 10, .desc = "Paging response timeout" }, {} }; @@ -106,6 +108,16 @@ struct ran_infra msc_ran_infra[] = { .ran_dec_l2 = ran_iu_decode_l2, .ran_encode = ran_iu_encode, #endif + .force_mgw_codecs_to_ran = { + .count = 1, + .codec = { + { + .payload_type = 96, + .subtype_name = "VND.3GPP.IUFP", + .rate = 16000, + }, + }, + }, }, [OSMO_RAT_EUTRAN_SGS] = { .type = OSMO_RAT_EUTRAN_SGS, diff --git a/src/libmsc/ran_msg.c b/src/libmsc/ran_msg.c index 46816a961..3e4b20c50 100644 --- a/src/libmsc/ran_msg.c +++ b/src/libmsc/ran_msg.c @@ -1,25 +1,21 @@ /* Common bits for RAN message handling */ /* - * (C) 2019 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de> + * (C) 2019 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de> * All Rights Reserved * * Author: Neels Hofmeyr * - * SPDX-License-Identifier: GPL-2.0+ + * SPDX-License-Identifier: AGPL-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 2 of the License, or + * 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 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. + * GNU Affero General Public License for more details. */ #include <osmocom/core/utils.h> @@ -55,6 +51,25 @@ const struct value_string ran_msg_type_names[] = { { RAN_MSG_HANDOVER_DETECT, "HANDOVER_DETECT" }, { RAN_MSG_HANDOVER_COMPLETE, "HANDOVER_COMPLETE" }, { RAN_MSG_HANDOVER_FAILURE, "HANDOVER_FAILURE" }, + { RAN_MSG_VGCS_VBS_SETUP, "VGCS_VBS_SETUP" }, + { RAN_MSG_VGCS_VBS_SETUP_ACK, "VGCS_VBS_SETUP_ACK" }, + { RAN_MSG_VGCS_VBS_SETUP_REFUSE, "VGCS_VBS_SETUP_REFUSE" }, + { RAN_MSG_VGCS_VBS_ASSIGN_REQ, "VGCS_VBS_ASSIGN_REQ" }, + { RAN_MSG_VGCS_VBS_ASSIGN_RES, "VGCS_VBS_ASSIGN_RES" }, + { RAN_MSG_VGCS_VBS_ASSIGN_FAIL, "VGCS_VBS_ASSIGN_FAIL" }, + { RAN_MSG_VGCS_VBS_QUEUING_IND, "VGCS_VBS_QUEUING_IND" }, + { RAN_MSG_UPLINK_REQUEST, "UPLINK_REQUEST" }, + { RAN_MSG_UPLINK_REQUEST_ACK, "UPLINK_REQUEST_ACK" }, + { RAN_MSG_UPLINK_REQUEST_CNF, "UPLINK_REQUEST_CNF" }, + { RAN_MSG_UPLINK_APPLICATION_DATA, "UPLINK_APPLICATION_DATA" }, + { RAN_MSG_UPLINK_RELEASE_IND, "UPLINK_RELEASE_IND" }, + { RAN_MSG_UPLINK_REJECT_CMD, "UPLINK_REJECT_CMD" }, + { RAN_MSG_UPLINK_RELEASE_CMD, "UPLINK_RELEASE_CMD" }, + { RAN_MSG_UPLINK_SEIZED_CMD, "UPLINK_SEIZED_CMD" }, + { RAN_MSG_VGCS_ADDITIONAL_INFO, "VGCS_ADDITIONAL_INFO" }, + { RAN_MSG_VGCS_VBS_AREA_CELL_INFO, "VGCS_VBS_AREA_CELL_INFO" }, + { RAN_MSG_VGCS_VBS_ASSIGN_STATUS, "VGCS_VBS_ASSIGN_STATUS" }, + { RAN_MSG_VGCS_SMS, "VGCS_SMS" }, {} }; diff --git a/src/libmsc/ran_msg_a.c b/src/libmsc/ran_msg_a.c index 64590a1fe..d9041204a 100644 --- a/src/libmsc/ran_msg_a.c +++ b/src/libmsc/ran_msg_a.c @@ -1,30 +1,27 @@ /* BSSAP/BSSMAP encoding and decoding for MSC */ /* - * (C) 2019 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de> + * (C) 2019 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de> * All Rights Reserved * * Author: Neels Hofmeyr * - * SPDX-License-Identifier: GPL-2.0+ + * SPDX-License-Identifier: AGPL-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 2 of the License, or + * 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 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. + * GNU Affero General Public License for more details. */ #include <osmocom/core/byteswap.h> #include <osmocom/crypt/auth.h> +#include <osmocom/crypt/kdf.h> #include <osmocom/gsm/tlv.h> #include <osmocom/gsm/gsm0808.h> @@ -52,9 +49,11 @@ static int ran_a_decode_l3_compl(struct ran_dec *ran_dec, struct msgb *msg, stru struct gsm0808_cell_id cell_id; struct tlv_p_entry *ie_cell_id = TLVP_GET(tp, GSM0808_IE_CELL_IDENTIFIER); struct tlv_p_entry *ie_l3_info = TLVP_GET(tp, GSM0808_IE_LAYER_3_INFORMATION); + struct tlv_p_entry *ie_codec_list_bss_supported = TLVP_GET(tp, GSM0808_IE_SPEECH_CODEC_LIST); + struct gsm0808_speech_codec_list codec_list_bss_supported; struct ran_msg ran_dec_msg = { .msg_type = RAN_MSG_COMPL_L3, - .msg_name = "BSSMAP Complete Layer 3", + .msg_name = "BSSMAP Complete Layer 3 Information", .compl_l3 = { .cell_id = &cell_id, .msg = msg, @@ -105,7 +104,7 @@ static int ran_a_decode_l3_compl(struct ran_dec *ran_dec, struct msgb *msg, stru .id = cil.id_list[0], }; - /* Parse Layer 3 Information element */ + /* Parse Layer 3 Information element; point ran_dec_msg->compl_l3.msg to the L3 Info data */ msg->l3h = (uint8_t*)ie_l3_info->val; msgb_l3trim(msg, ie_l3_info->len); @@ -114,6 +113,19 @@ static int ran_a_decode_l3_compl(struct ran_dec *ran_dec, struct msgb *msg, stru return -ENODATA; } + /* Decode Codec List (BSS Supported) */ + if (ie_codec_list_bss_supported) { + rc = gsm0808_dec_speech_codec_list(&codec_list_bss_supported, + ie_codec_list_bss_supported->val, ie_codec_list_bss_supported->len); + if (rc < 0) { + LOG_RAN_A_DEC_MSG(LOGL_ERROR, + "Complete Layer 3 Information: unable to decode IE Codec List (BSS Supported)" + " (rc=%d), continuing anyway\n", rc); + /* This IE is not critical, do not abort with error. */ + } else + ran_dec_msg.compl_l3.codec_list_bss_supported = &codec_list_bss_supported; + } + return ran_decoded(ran_dec, &ran_dec_msg); } @@ -194,18 +206,10 @@ static int ran_a_decode_cipher_mode_complete(struct ran_dec *ran_dec, struct msg ran_dec_msg.cipher_mode_complete.alg_id = ie_chosen_encr_alg->val[0]; } - rc = ran_decoded(ran_dec, &ran_dec_msg); + if (ie_l3_msg) + ran_dec_msg.cipher_mode_complete.l3_msg = ie_l3_msg; - if (ie_l3_msg) { - msg->l3h = (uint8_t*)ie_l3_msg->val; - msgb_l3trim(msg, ie_l3_msg->len); - ran_dec_msg = (struct ran_msg){ - .msg_type = RAN_MSG_DTAP, - .msg_name = "BSSMAP Ciphering Mode Complete (L3 Message Contents)", - .dtap = msg, - }; - ran_decoded(ran_dec, &ran_dec_msg); - } + rc = ran_decoded(ran_dec, &ran_dec_msg); return rc; } @@ -218,7 +222,7 @@ static int ran_a_decode_cipher_mode_reject(struct ran_dec *ran_dec, struct msgb .msg_name = "BSSMAP Ciphering Mode Reject", }; - rc = gsm0808_get_cipher_reject_cause(tp); + rc = gsm0808_get_cause(tp); if (rc < 0) { LOG_RAN_A_DEC_MSG(LOGL_ERROR, "failed to extract Cause\n"); ran_dec_msg.cipher_mode_reject.bssap_cause = GSM0808_CAUSE_EQUIPMENT_FAILURE; @@ -234,34 +238,26 @@ enum mgcp_codecs ran_a_mgcp_codec_from_sc(const struct gsm0808_speech_codec *sc) switch (sc->type) { case GSM0808_SCT_FR1: return CODEC_GSM_8000_1; - break; case GSM0808_SCT_FR2: return CODEC_GSMEFR_8000_1; - break; case GSM0808_SCT_FR3: return CODEC_AMR_8000_1; - break; case GSM0808_SCT_FR4: return CODEC_AMRWB_16000_1; - break; case GSM0808_SCT_FR5: return CODEC_AMRWB_16000_1; - break; case GSM0808_SCT_HR1: return CODEC_GSMHR_8000_1; - break; case GSM0808_SCT_HR3: return CODEC_AMR_8000_1; - break; case GSM0808_SCT_HR4: return CODEC_AMRWB_16000_1; - break; case GSM0808_SCT_HR6: return CODEC_AMRWB_16000_1; - break; + case GSM0808_SCT_CSD: + return CODEC_CLEARMODE; default: return CODEC_PCMU_8000_1; - break; } } @@ -269,9 +265,10 @@ static int ran_a_decode_assignment_complete(struct ran_dec *ran_dec, struct msgb { struct tlv_p_entry *ie_aoip_transp_addr = TLVP_GET(tp, GSM0808_IE_AOIP_TRASP_ADDR); struct tlv_p_entry *ie_speech_codec = TLVP_GET(tp, GSM0808_IE_SPEECH_CODEC); + struct tlv_p_entry *ie_codec_list_bss_supported = TLVP_GET(tp, GSM0808_IE_SPEECH_CODEC_LIST); + struct tlv_p_entry *ie_osmux_cid = TLVP_GET(tp, GSM0808_IE_OSMO_OSMUX_CID); struct sockaddr_storage rtp_addr; - struct sockaddr_in *rtp_addr_in; - struct gsm0808_speech_codec sc; + struct gsm0808_speech_codec_list codec_list_bss_supported; int rc; struct ran_msg ran_dec_msg = { .msg_type = RAN_MSG_ASSIGNMENT_COMPLETE, @@ -286,30 +283,44 @@ static int ran_a_decode_assignment_complete(struct ran_dec *ran_dec, struct msgb return -EINVAL; } - rtp_addr_in = (struct sockaddr_in*)&rtp_addr; - - if (rtp_addr.ss_family != AF_INET) { - LOG_RAN_A_DEC_MSG(LOGL_ERROR, "Assignment Complete: IE AoIP Transport Address:" - " unsupported addressing scheme (only IPV4 supported)\n"); + if (osmo_sockaddr_str_from_sockaddr(&ran_dec_msg.assignment_complete.remote_rtp, &rtp_addr)) { + LOG_RAN_A_DEC_MSG(LOGL_ERROR, "Assignment Complete: unable to decode remote RTP IP address\n"); return -EINVAL; } + } - if (osmo_sockaddr_str_from_sockaddr_in(&ran_dec_msg.assignment_complete.remote_rtp, rtp_addr_in)) { - LOG_RAN_A_DEC_MSG(LOGL_ERROR, "Assignment Complete: unable to decode remote RTP IP address\n"); + if (ie_osmux_cid) { + rc = gsm0808_dec_osmux_cid(&ran_dec_msg.assignment_complete.osmux_cid, ie_osmux_cid->val, ie_osmux_cid->len); + if (rc < 0) { + LOG_RAN_A_DEC_MSG(LOGL_ERROR, "Unable to decode Osmux CID\n"); return -EINVAL; } + ran_dec_msg.assignment_complete.osmux_present = true; } if (ie_speech_codec) { /* Decode Speech Codec (Chosen) element */ - rc = gsm0808_dec_speech_codec(&sc, ie_speech_codec->val, ie_speech_codec->len); + rc = gsm0808_dec_speech_codec(&ran_dec_msg.assignment_complete.codec, + ie_speech_codec->val, ie_speech_codec->len); if (rc < 0) { LOG_RAN_A_DEC_MSG(LOGL_ERROR, "Assignment Complete: unable to decode IE Speech Codec (Chosen)" " (rc=%d).\n", rc); return -EINVAL; } ran_dec_msg.assignment_complete.codec_present = true; - ran_dec_msg.assignment_complete.codec = ran_a_mgcp_codec_from_sc(&sc); + } + + if (ie_codec_list_bss_supported) { + /* Decode Codec List (BSS Supported) */ + rc = gsm0808_dec_speech_codec_list(&codec_list_bss_supported, + ie_codec_list_bss_supported->val, ie_codec_list_bss_supported->len); + if (rc < 0) { + LOG_RAN_A_DEC_MSG(LOGL_ERROR, + "Assignment Complete: unable to decode IE Codec List (BSS Supported)" + " (rc=%d), continuing anyway\n", rc); + /* This IE is not critical, do not abort with error. */ + } else + ran_dec_msg.assignment_complete.codec_list_bss_supported = &codec_list_bss_supported; } return ran_decoded(ran_dec, &ran_dec_msg); @@ -459,13 +470,13 @@ static int ran_a_decode_handover_request(struct ran_dec *ran_dec, const struct m const struct tlv_p_entry *ie_aoip_transp_addr = TLVP_GET(tp, GSM0808_IE_AOIP_TRASP_ADDR); const struct tlv_p_entry *ie_codec_list_msc_preferred = TLVP_GET(tp, GSM0808_IE_SPEECH_CODEC_LIST); const struct tlv_p_entry *ie_call_id = TLVP_GET(tp, GSM0808_IE_CALL_ID); + const struct tlv_p_entry *ie_kc128 = TLVP_GET(tp, GSM0808_IE_KC_128); const struct tlv_p_entry *ie_global_call_ref = TLVP_GET(tp, GSM0808_IE_GLOBAL_CALL_REF); struct gsm0808_channel_type channel_type; struct gsm0808_encrypt_info encr_info; struct gsm0808_speech_codec_list scl; struct geran_encr geran_encr = {}; - char imsi[OSMO_IMSI_BUF_SIZE]; struct osmo_sockaddr_str rtp_ran_local; if (!ie_channel_type) { @@ -482,7 +493,7 @@ static int ran_a_decode_handover_request(struct ran_dec *ran_dec, const struct m int i; if (gsm0808_dec_encrypt_info(&encr_info, ie_encryption_information->val, ie_encryption_information->len) <= 0) { - LOG_RAN_A_DEC_MSG(LOGL_ERROR, "Failed to decode Encryption Informaiton IE\n"); + LOG_RAN_A_DEC_MSG(LOGL_ERROR, "Failed to decode Encryption Information IE\n"); return -EINVAL; } @@ -492,7 +503,7 @@ static int ran_a_decode_handover_request(struct ran_dec *ran_dec, const struct m } if (encr_info.key_len > sizeof(geran_encr.key)) { - LOG_RAN_A_DEC_MSG(LOGL_ERROR, "Failed to decode Encryption Informaiton IE:" + LOG_RAN_A_DEC_MSG(LOGL_ERROR, "Failed to decode Encryption Information IE:" " encryption key is too long: %u\n", geran_encr.key_len); return -EINVAL; } @@ -502,6 +513,11 @@ static int ran_a_decode_handover_request(struct ran_dec *ran_dec, const struct m geran_encr.key_len = encr_info.key_len; } + if (ie_kc128) { + memcpy(geran_encr.kc128, ie_kc128->val, 16); + geran_encr.kc128_present = true; + } + r->geran.chosen_encryption = &geran_encr; } @@ -576,28 +592,22 @@ static int ran_a_decode_handover_request(struct ran_dec *ran_dec, const struct m } if (ie_imsi) { - gsm48_mi_to_string(imsi, sizeof(imsi), ie_imsi->val, ie_imsi->len); - r->imsi = imsi; + struct osmo_mobile_identity mi; + if (osmo_mobile_identity_decode(&mi, ie_imsi->val, ie_imsi->len, false) + || mi.type != GSM_MI_TYPE_IMSI) + LOG_RAN_A_DEC_MSG(LOGL_ERROR, "IE IMSI: cannot decode IMSI identity\n"); + else + r->imsi = mi.imsi; } if (ie_aoip_transp_addr) { - do { - struct sockaddr_storage rtp_addr; - if (gsm0808_dec_aoip_trasp_addr(&rtp_addr, ie_aoip_transp_addr->val, ie_aoip_transp_addr->len) < 0) { - LOG_RAN_A_DEC_MSG(LOGL_ERROR, "unable to decode AoIP transport address\n"); - break; - } - if (rtp_addr.ss_family != AF_INET) { - LOG_RAN_A_DEC_MSG(LOGL_ERROR, "IE AoIP Transport Address:" - " unsupported addressing scheme (only IPV4 supported)\n"); - break; - } - if (osmo_sockaddr_str_from_sockaddr_in(&rtp_ran_local, (struct sockaddr_in*)&rtp_addr)) { - LOG_RAN_A_DEC_MSG(LOGL_ERROR, "unable to decode remote RTP IP address\n"); - break; - } + struct sockaddr_storage rtp_addr; + if (gsm0808_dec_aoip_trasp_addr(&rtp_addr, ie_aoip_transp_addr->val, ie_aoip_transp_addr->len) < 0) + LOG_RAN_A_DEC_MSG(LOGL_ERROR, "unable to decode AoIP transport address\n"); + else if (osmo_sockaddr_str_from_sockaddr(&rtp_ran_local, &rtp_addr) < 0) + LOG_RAN_A_DEC_MSG(LOGL_ERROR, "unable to decode remote RTP IP address\n"); + else r->rtp_ran_local = &rtp_ran_local; - } while(0); } if (ie_codec_list_msc_preferred @@ -653,45 +663,32 @@ static int ran_a_decode_handover_request_ack(struct ran_dec *ran_dec, const stru } if (ie_chosen_speech_version) { - struct gsm0808_speech_codec sc; ran_dec_msg.handover_request_ack.chosen_speech_version = ie_chosen_speech_version->val[0]; /* the codec may be extrapolated from this Speech Version or below from Speech Codec */ - gsm0808_speech_codec_from_chan_type(&sc, ran_dec_msg.handover_request_ack.chosen_speech_version); - ran_dec_msg.handover_request_ack.codec_present = true; - ran_dec_msg.handover_request_ack.codec = ran_a_mgcp_codec_from_sc(&sc); + if (gsm0808_speech_codec_from_chan_type(&ran_dec_msg.handover_request_ack.codec, + ran_dec_msg.handover_request_ack.chosen_speech_version) == 0) + ran_dec_msg.handover_request_ack.codec_present = true; } if (ie_aoip_transp_addr) { - do { - struct sockaddr_storage rtp_addr; - if (gsm0808_dec_aoip_trasp_addr(&rtp_addr, ie_aoip_transp_addr->val, ie_aoip_transp_addr->len) < 0) { - LOG_RAN_A_DEC_MSG(LOGL_ERROR, "unable to decode AoIP transport address\n"); - break; - } - if (rtp_addr.ss_family != AF_INET) { - LOG_RAN_A_DEC_MSG(LOGL_ERROR, "IE AoIP Transport Address:" - " unsupported addressing scheme (only IPV4 supported)\n"); - break; - } - if (osmo_sockaddr_str_from_sockaddr_in(&ran_dec_msg.handover_request_ack.remote_rtp, - (struct sockaddr_in*)&rtp_addr)) { - LOG_RAN_A_DEC_MSG(LOGL_ERROR, "unable to decode remote RTP IP address\n"); - ran_dec_msg.handover_request_ack.remote_rtp = (struct osmo_sockaddr_str){}; - break; - } - } while(0); + struct sockaddr_storage rtp_addr; + if (gsm0808_dec_aoip_trasp_addr(&rtp_addr, ie_aoip_transp_addr->val, ie_aoip_transp_addr->len) < 0) { + LOG_RAN_A_DEC_MSG(LOGL_ERROR, "unable to decode AoIP transport address\n"); + } else if (osmo_sockaddr_str_from_sockaddr(&ran_dec_msg.handover_request_ack.remote_rtp, + &rtp_addr)) { + LOG_RAN_A_DEC_MSG(LOGL_ERROR, "unable to decode remote RTP IP address\n"); + ran_dec_msg.handover_request_ack.remote_rtp = (struct osmo_sockaddr_str){}; + } } if (ie_speech_codec) { - struct gsm0808_speech_codec sc; - if (gsm0808_dec_speech_codec(&sc, ie_speech_codec->val, ie_speech_codec->len) < 0) + /* the codec may be extrapolated from above Speech Version or from this Speech Codec */ + if (gsm0808_dec_speech_codec(&ran_dec_msg.handover_request_ack.codec, + ie_speech_codec->val, ie_speech_codec->len) < 0) LOG_RAN_A_DEC_MSG(LOGL_ERROR, "unable to decode IE Speech Codec (Chosen)\n"); - else { - /* the codec may be extrapolated from above Speech Version or from this Speech Codec */ + else ran_dec_msg.handover_request_ack.codec_present = true; - ran_dec_msg.handover_request_ack.codec = ran_a_mgcp_codec_from_sc(&sc); - } } return ran_decoded(ran_dec, &ran_dec_msg); @@ -737,6 +734,439 @@ static int ran_a_decode_handover_failure(struct ran_dec *ran_dec, const struct m return ran_decoded(ran_dec, &ran_dec_msg); } +static int ran_a_decode_vgcs_vbs_setup_ack(struct ran_dec *ran_dec, const struct msgb *msg, const struct tlv_parsed *tp) +{ + struct ran_msg ran_dec_msg = { + .msg_type = RAN_MSG_VGCS_VBS_SETUP_ACK, + .msg_name = "BSSMAP VGCS/VBS SETUP ACKNOWLEDGE", + }; + struct gsm0808_vgcs_vbs_setup_ack *r = &ran_dec_msg.vgcs_vbs_setup_ack; + int rc; + + const struct tlv_p_entry *ie_flags = TLVP_GET(tp, GSM0808_IE_VGCS_FEATURE_FLAGS); + + /* VGCS Feature Flags, 3.2.2.88 */ + if (ie_flags) { + rc = gsm0808_dec_vgcs_feature_flags(&r->flags, ie_flags->val, ie_flags->len); + if (rc < 0) { + LOG_RAN_A_DEC_MSG(LOGL_ERROR, "Unable to decode VGCS/VBS Feature Flags\n"); + return -EINVAL; + } + r->vgcs_feature_flags_present = true; + } + + return ran_decoded(ran_dec, &ran_dec_msg); +} + +static int ran_a_decode_vgcs_vbs_setup_refuse(struct ran_dec *ran_dec, const struct msgb *msg, + const struct tlv_parsed *tp) +{ + struct ran_msg ran_dec_msg = { + .msg_type = RAN_MSG_VGCS_VBS_SETUP_REFUSE, + .msg_name = "BSSMAP VGCS/VBS SETUP REFUSE", + }; + + const struct tlv_p_entry *ie_cause = TLVP_GET(tp, GSM0808_IE_CAUSE); + + /* Cause, 3.2.2.5 */ + if (!ie_cause || ie_cause->len < 1) { + LOG_RAN_A_DEC_MSG(LOGL_ERROR, "Mandatory IE missing: Cause\n"); + return -EINVAL; + } + ran_dec_msg.vgcs_vbs_setup_refuse.cause = ie_cause->val[0]; + + return ran_decoded(ran_dec, &ran_dec_msg); +} + +static int ran_a_decode_vgcs_vbs_assign_res(struct ran_dec *ran_dec, const struct msgb *msg, + const struct tlv_parsed *tp) +{ + struct ran_msg ran_dec_msg = { + .msg_type = RAN_MSG_VGCS_VBS_ASSIGN_RES, + .msg_name = "BSSMAP VGCS/VBS ASSIGNMENT RESULT", + }; + struct gsm0808_vgcs_vbs_assign_res *r = &ran_dec_msg.vgcs_vbs_assign_res; + int rc; + + const struct tlv_p_entry *ie_channel_type = TLVP_GET(tp, GSM0808_IE_CHANNEL_TYPE); + const struct tlv_p_entry *ie_cell_id = TLVP_GET(tp, GSM0808_IE_CELL_IDENTIFIER); + const struct tlv_p_entry *ie_chosen_channel = TLVP_GET(tp, GSM0808_IE_CHOSEN_CHANNEL); + const struct tlv_p_entry *ie_cic = TLVP_GET(tp, GSM0808_IE_CIRCUIT_IDENTITY_CODE); + const struct tlv_p_entry *ie_circuit_pool = TLVP_GET(tp, GSM0808_IE_CIRCUIT_POOL); + const struct tlv_p_entry *ie_aoip = TLVP_GET(tp, GSM0808_IE_AOIP_TRASP_ADDR); + const struct tlv_p_entry *ie_call_id = TLVP_GET(tp, GSM0808_IE_CALL_ID); + + /* Channel Type, 3.2.2.11 */ + if (!ie_channel_type) { + LOG_RAN_A_DEC_MSG(LOGL_ERROR, "Mandatory IE missing: Channel Type\n"); + return -EINVAL; + } + if (gsm0808_dec_channel_type(&r->channel_type, ie_channel_type->val, ie_channel_type->len) <= 0) { + LOG_RAN_A_DEC_MSG(LOGL_ERROR, "Failed to decode Channel Type IE\n"); + return -EINVAL; + } + + /* Cell Identifier, 3.2.2.17 */ + if (!ie_cell_id) { + LOG_RAN_A_DEC_MSG(LOGL_ERROR, "Mandatory IE missing: Cell Identifier\n"); + return -EINVAL; + } + rc = gsm0808_dec_cell_id(&r->cell_identifier, ie_cell_id->val, ie_cell_id->len); + if (rc < 0) { + LOG_RAN_A_DEC_MSG(LOGL_ERROR, "Decoding Cell Identifier gave rc=%d\n", rc); + return -EINVAL; + } + + /* Chosen Channel, 3.2.2.33 */ + if (ie_chosen_channel) { + r->chosen_channel = ie_chosen_channel->val[0]; + r->chosen_channel_present = true; + } + + /* Circuit Identity Code, 3.2.2.2 */ + if (ie_cic) { + if (ie_cic->len != 2) { + LOG_RAN_A_DEC_MSG(LOGL_ERROR, "Circuit Identity Code has invalid length.\n"); + return -EINVAL; + } + r->cic = *(uint16_t *)ie_cic->val; + r->cic_present = true; + } + + /* Circuit Pool, 3.2.2.45 */ + if (ie_circuit_pool) { + r->circuit_pool = ie_circuit_pool->val[0]; + r->circuit_pool_present = true; + } + + /* AoIP Transport Layer Address (BSS), 3.2.2.102 */ + if (ie_aoip) { + if (gsm0808_dec_aoip_trasp_addr(&r->aoip_transport_layer, ie_aoip->val, ie_aoip->len) < 0) { + LOG_RAN_A_DEC_MSG(LOGL_ERROR, "unable to decode AoIP transport address\n"); + return -EINVAL; + } + r->aoip_transport_layer_present = true; + } + + if (ie_call_id) { + if (ie_call_id->len != 4) { + LOG_RAN_A_DEC_MSG(LOGL_ERROR, "Call Identifier has invalid length.\n"); + return -EINVAL; + } + r->call_id = osmo_load32le(ie_call_id->val); + r->call_id_present = true; + } + + return ran_decoded(ran_dec, &ran_dec_msg); +} + +static int ran_a_decode_vgcs_vbs_assign_fail(struct ran_dec *ran_dec, const struct msgb *msg, + const struct tlv_parsed *tp) +{ + struct ran_msg ran_dec_msg = { + .msg_type = RAN_MSG_VGCS_VBS_ASSIGN_FAIL, + .msg_name = "BSSMAP VGCS/VBS ASSIGNMENT FAILURE", + }; + struct gsm0808_vgcs_vbs_assign_fail *r = &ran_dec_msg.vgcs_vbs_assign_fail; + int rc; + + const struct tlv_p_entry *ie_cause = TLVP_GET(tp, GSM0808_IE_CAUSE); + const struct tlv_p_entry *ie_circuit_pool = TLVP_GET(tp, GSM0808_IE_CIRCUIT_POOL); + const struct tlv_p_entry *ie_circuit_pool_list = TLVP_GET(tp, GSM0808_IE_CIRCUIT_POOL_LIST); + const struct tlv_p_entry *ie_codec_list_bss_supported = TLVP_GET(tp, GSM0808_IE_SPEECH_CODEC_LIST); + + /* Cause, 3.2.2.5 */ + if (!ie_cause || ie_cause->len < 1) { + LOG_RAN_A_DEC_MSG(LOGL_ERROR, "Mandatory IE missing: Cause\n"); + return -EINVAL; + } + r->cause = ie_cause->val[0]; + + /* Circuit Pool, 3.2.2.45 */ + if (ie_circuit_pool) { + r->circuit_pool = ie_circuit_pool->val[0]; + r->circuit_pool_present = true; + } + + /* Circuit Pool List, 3.2.2.46 */ + if (ie_circuit_pool_list && ie_circuit_pool_list->len) { + if (ie_circuit_pool_list->len > CIRCUIT_POOL_LIST_MAXLEN) { + LOG_RAN_A_DEC_MSG(LOGL_ERROR, "Circuit Pool List has invalid length.\n"); + return -EINVAL; + } + memcpy(r->cpl.pool, ie_circuit_pool_list->val, ie_circuit_pool_list->len); + r->cpl.list_len = ie_circuit_pool_list->len; + r->cpl_present = true; + } + + /* Codec List (BSS Supported) 3.2.2.103 */ + if (ie_codec_list_bss_supported) { + rc = gsm0808_dec_speech_codec_list(&r->codec_list_bss_supported, + ie_codec_list_bss_supported->val, ie_codec_list_bss_supported->len); + if (rc < 0) { + LOG_RAN_A_DEC_MSG(LOGL_ERROR, + "Complete Layer 3 Information: unable to decode IE Codec List (BSS Supported)" + " (rc=%d), continuing anyway\n", rc); + /* This IE is not critical, do not abort with error. */ + } else + r->codec_list_present = true; + } + + return ran_decoded(ran_dec, &ran_dec_msg); +} + +static int ran_a_decode_vgcs_vbs_queuing_ind(struct ran_dec *ran_dec, const struct msgb *msg, + const struct tlv_parsed *tp) +{ + struct ran_msg ran_dec_msg = { + .msg_type = RAN_MSG_VGCS_VBS_QUEUING_IND, + .msg_name = "BSSMAP VGCS/VBS QUEUING INDICATION", + }; + + return ran_decoded(ran_dec, &ran_dec_msg); +} + +static int ran_a_decode_uplink_request(struct ran_dec *ran_dec, const struct msgb *msg, const struct tlv_parsed *tp) +{ + struct ran_msg ran_dec_msg = { + .msg_type = RAN_MSG_UPLINK_REQUEST, + .msg_name = "BSSMAP UPLINK REQUEST", + }; + struct gsm0808_uplink_request *r = &ran_dec_msg.uplink_request; + int rc; + + const struct tlv_p_entry *ie_talker_priority = TLVP_GET(tp, GSM0808_IE_TALKER_PRIORITY); + const struct tlv_p_entry *ie_cell_id = TLVP_GET(tp, GSM0808_IE_CELL_IDENTIFIER); + const struct tlv_p_entry *ie_l3_info = TLVP_GET(tp, GSM0808_IE_LAYER_3_INFORMATION); + const struct tlv_p_entry *ie_mi = TLVP_GET(tp, GSM0808_IE_MOBILE_IDENTITY); + + /* Talker Priority, 3.2.2.89 */ + if (ie_talker_priority) { + r->talker_priority = ie_talker_priority->val[0] & 0x03; + r->talker_priority_present = true; + } + + /* Cell Identifier, 3.2.2.17 */ + if (ie_cell_id) { + rc = gsm0808_dec_cell_id(&r->cell_identifier, ie_cell_id->val, ie_cell_id->len); + if (rc < 0) { + LOG_RAN_A_DEC_MSG(LOGL_ERROR, "Decoding Cell Identifier gave rc=%d\n", rc); + return -EINVAL; + } + } + + /* Layer 3 Information, 3.2.2.24 */ + if (ie_l3_info && ie_l3_info->len) { + if (ie_l3_info->len > LAYER_3_INFORMATION_MAXLEN) { + LOG_RAN_A_DEC_MSG(LOGL_ERROR, "Call Identifier has invalid length.\n"); + return -EINVAL; + } + memcpy(r->l3.l3, ie_l3_info->val, ie_l3_info->len); + r->l3.l3_len = ie_l3_info->len; + r->l3_present = true; + } + + /* Mobile Identity, 3.2.2.41 */ + if (ie_mi) { + rc = osmo_mobile_identity_decode(&r->mi, ie_mi->val, ie_mi->len, false); + if (rc < 0) { + LOG_RAN_A_DEC_MSG(LOGL_ERROR, "Decoding Mobile Identity gave rc=%d\n", rc); + return -EINVAL; + } + r->mi_present = true; + } + + return ran_decoded(ran_dec, &ran_dec_msg); +} + +static int ran_a_decode_uplink_request_cnf(struct ran_dec *ran_dec, const struct msgb *msg, const struct tlv_parsed *tp) +{ + struct ran_msg ran_dec_msg = { + .msg_type = RAN_MSG_UPLINK_REQUEST_CNF, + .msg_name = "BSSMAP UPLINK REQUEST CONFIRM", + }; + struct gsm0808_uplink_request_cnf *r = &ran_dec_msg.uplink_request_cnf; + int rc; + + const struct tlv_p_entry *ie_cell_id = TLVP_GET(tp, GSM0808_IE_CELL_IDENTIFIER); + const struct tlv_p_entry *ie_talker_identity = TLVP_GET(tp, GSM0808_IE_TALKER_IDENTITY); + const struct tlv_p_entry *ie_l3_info = TLVP_GET(tp, GSM0808_IE_LAYER_3_INFORMATION); + + /* Cell Identifier, 3.2.2.17 */ + if (!ie_cell_id) { + LOG_RAN_A_DEC_MSG(LOGL_ERROR, "Mandatory IE missing: Cell Identifier\n"); + return -EINVAL; + } + rc = gsm0808_dec_cell_id(&r->cell_identifier, ie_cell_id->val, ie_cell_id->len); + if (rc < 0) { + LOG_RAN_A_DEC_MSG(LOGL_ERROR, "Decoding Cell Identifier gave rc=%d\n", rc); + return -EINVAL; + } + + /* Talker Identity, 3.2.2.91 */ + if (ie_talker_identity) { + rc = gsm0808_dec_talker_identity(&r->talker_identity, ie_talker_identity->val, ie_talker_identity->len); + if (rc < 0) { + LOG_RAN_A_DEC_MSG(LOGL_ERROR, "Decoding Talker Identity gave rc=%d\n", rc); + return -EINVAL; + } + r->talker_identity_present = true; + } + + /* Layer 3 Information, 3.2.2.24 */ + if (!ie_l3_info) { + LOG_RAN_A_DEC_MSG(LOGL_ERROR, "Mandatory IE missing: Layer 3 Information\n"); + return -EINVAL; + } + if (ie_l3_info->len > LAYER_3_INFORMATION_MAXLEN) { + LOG_RAN_A_DEC_MSG(LOGL_ERROR, "Call Identifier has invalid length.\n"); + return -EINVAL; + } + memcpy(r->l3.l3, ie_l3_info->val, ie_l3_info->len); + r->l3.l3_len = ie_l3_info->len; + + return ran_decoded(ran_dec, &ran_dec_msg); +} + +static int ran_a_decode_uplink_application_data(struct ran_dec *ran_dec, const struct msgb *msg, + const struct tlv_parsed *tp) +{ + struct ran_msg ran_dec_msg = { + .msg_type = RAN_MSG_UPLINK_APPLICATION_DATA, + .msg_name = "BSSMAP UPLINK APPLICATION DATA", + }; + struct gsm0808_uplink_app_data *r = &ran_dec_msg.uplink_app_data; + int rc; + + const struct tlv_p_entry *ie_cell_id = TLVP_GET(tp, GSM0808_IE_CELL_IDENTIFIER); + const struct tlv_p_entry *ie_l3_info = TLVP_GET(tp, GSM0808_IE_LAYER_3_INFORMATION); + const struct tlv_p_entry *ie_app_data = TLVP_GET(tp, GSM0808_IE_APP_DATA); + + /* Cell Identifier, 3.2.2.17 */ + if (!ie_cell_id) { + LOG_RAN_A_DEC_MSG(LOGL_ERROR, "Mandatory IE missing: Cell Identifier\n"); + return -EINVAL; + } + rc = gsm0808_dec_cell_id(&r->cell_identifier, ie_cell_id->val, ie_cell_id->len); + if (rc < 0) { + LOG_RAN_A_DEC_MSG(LOGL_ERROR, "Decoding Cell Identifier gave rc=%d\n", rc); + return -EINVAL; + } + + /* Layer 3 Information, 3.2.2.24 */ + if (!ie_l3_info) { + LOG_RAN_A_DEC_MSG(LOGL_ERROR, "Mandatory IE missing: Layer 3 Information\n"); + return -EINVAL; + } + if (ie_l3_info->len > LAYER_3_INFORMATION_MAXLEN) { + LOG_RAN_A_DEC_MSG(LOGL_ERROR, "Call Identifier has invalid length.\n"); + return -EINVAL; + } + memcpy(r->l3.l3, ie_l3_info->val, ie_l3_info->len); + r->l3.l3_len = ie_l3_info->len; + + /* Application Data Information, 3.2.2.100 */ + if (!ie_app_data || ie_app_data->len < 1) { + LOG_RAN_A_DEC_MSG(LOGL_ERROR, "Mandatory IE missing: Application Data Information\n"); + return -EINVAL; + } + r->bt_ind = ie_app_data->val[0] & 0x01; + + return ran_decoded(ran_dec, &ran_dec_msg); +} + +static int ran_a_decode_uplink_release_ind(struct ran_dec *ran_dec, const struct msgb *msg, const struct tlv_parsed *tp) +{ + struct ran_msg ran_dec_msg = { + .msg_type = RAN_MSG_UPLINK_RELEASE_IND, + .msg_name = "BSSMAP UPLINK RELEASE INDICATION", + }; + struct gsm0808_uplink_release_ind *r = &ran_dec_msg.uplink_release_ind; + + const struct tlv_p_entry *ie_cause = TLVP_GET(tp, GSM0808_IE_CAUSE); + const struct tlv_p_entry *ie_talker_priority = TLVP_GET(tp, GSM0808_IE_TALKER_PRIORITY); + + /* Cause, 3.2.2.5 */ + if (!ie_cause || ie_cause->len < 1) { + LOG_RAN_A_DEC_MSG(LOGL_ERROR, "Mandatory IE missing: Cause\n"); + return -EINVAL; + } + r->cause = ie_cause->val[0]; + + /* Talker Priority, 3.2.2.89 */ + if (ie_talker_priority) { + r->talker_priority = ie_talker_priority->val[0] & 0x03; + r->talker_priority_present = true; + } + + return ran_decoded(ran_dec, &ran_dec_msg); +} + +static int ran_a_decode_vgcs_vbs_assign_status(struct ran_dec *ran_dec, const struct msgb *msg, + const struct tlv_parsed *tp) +{ + struct ran_msg ran_dec_msg = { + .msg_type = RAN_MSG_VGCS_VBS_ASSIGN_STATUS, + .msg_name = "BSSMAP VGCS/VBS ASSIGNMENT STATUS", + }; + struct gsm0808_vgcs_vbs_assign_stat *r = &ran_dec_msg.vgcs_vbs_assign_stat; + int rc; + + const struct tlv_p_entry *ie_cils_est = TLVP_GET(tp, GSM0808_IE_CELL_ID_LIST_SEG_EST_CELLS); + const struct tlv_p_entry *ie_cils_tbe = TLVP_GET(tp, GSM0808_IE_CELL_ID_LIST_SEG_CELLS_TBE); + const struct tlv_p_entry *ie_cils_rel = TLVP_GET(tp, GSM0808_IE_CELL_ID_LIST_SEG_REL_CELLS); + const struct tlv_p_entry *ie_cils_ne = TLVP_GET(tp, GSM0808_IE_CELL_ID_LIST_SEG_NE_CELLS); + const struct tlv_p_entry *ie_cell_status = TLVP_GET(tp, GSM0808_IE_VGCS_VBS_CELL_STATUS); + + /* Cell Identifier List Segment, 3.2.2.27b */ + if (ie_cils_est) { + rc = gsm0808_dec_cell_id_list_segment(&r->cils_est, ie_cils_est->val, ie_cils_est->len); + if (rc < 0) { + LOG_RAN_A_DEC_MSG(LOGL_ERROR, "Decoding Cell Identifier gave rc=%d\n", rc); + return -EINVAL; + } + r->cils_est_present = true; + } + + /* Cell Identifier List Segment, 3.2.2.27c */ + if (ie_cils_tbe) { + rc = gsm0808_dec_cell_id_list_segment(&r->cils_tbe, ie_cils_tbe->val, ie_cils_tbe->len); + if (rc < 0) { + LOG_RAN_A_DEC_MSG(LOGL_ERROR, "Decoding Cell Identifier gave rc=%d\n", rc); + return -EINVAL; + } + r->cils_tbe_present = true; + } + + /* Cell Identifier List Segment, 3.2.2.27e */ + if (ie_cils_rel) { + rc = gsm0808_dec_cell_id_list_segment(&r->cils_rel, ie_cils_rel->val, ie_cils_rel->len); + if (rc < 0) { + LOG_RAN_A_DEC_MSG(LOGL_ERROR, "Decoding Cell Identifier gave rc=%d\n", rc); + return -EINVAL; + } + r->cils_rel_present = true; + } + + /* Cell Identifier List Segment, 3.2.2.27f */ + if (ie_cils_ne) { + rc = gsm0808_dec_cell_id_list_segment(&r->cils_ne, ie_cils_ne->val, ie_cils_ne->len); + if (rc < 0) { + LOG_RAN_A_DEC_MSG(LOGL_ERROR, "Decoding Cell Identifier gave rc=%d\n", rc); + return -EINVAL; + } + r->cils_ne_present = true; + } + + /* VGCS/VBS Cell Status, 3.2.2.94 */ + if (ie_cell_status && ie_cell_status->len) { + r->cell_status = ie_cell_status->val[0] & 0x73; + r->cell_status_present = true; + } + + return ran_decoded(ran_dec, &ran_dec_msg); +} + static int ran_a_decode_bssmap(struct ran_dec *ran_dec, struct msgb *bssmap) { struct tlv_parsed tp[2]; @@ -751,13 +1181,17 @@ static int ran_a_decode_bssmap(struct ran_dec *ran_dec, struct msgb *bssmap) } if (msgb_l3len(bssmap) < h->length) { - LOG_RAN_A_DEC(ran_dec, LOGL_ERROR, "BSSMAP data truncated, discarding message\n"); + LOG_RAN_A_DEC(ran_dec, LOGL_ERROR, "BSSMAP data truncated, discarding message:" + " msgb_l3len(bssmap) == %u < bssmap_header->length == %u\n", + msgb_l3len(bssmap), h->length); return -1; } if (msgb_l3len(bssmap) > h->length) { - LOG_RAN_A_DEC(ran_dec, LOGL_NOTICE, "There are %u extra bytes after the BSSMAP data, truncating\n", - msgb_l3len(bssmap) - h->length); + LOG_RAN_A_DEC(ran_dec, LOGL_NOTICE, "There are %u extra bytes after the BSSMAP data, truncating:" + " msgb_l3len(bssmap) == %u > bssmap_header->length == %u\n", + msgb_l3len(bssmap) - h->length, + msgb_l3len(bssmap), h->length); msgb_l3trim(bssmap, h->length); } @@ -770,7 +1204,7 @@ static int ran_a_decode_bssmap(struct ran_dec *ran_dec, struct msgb *bssmap) return -EINVAL; } - LOG_RAN_A_DEC(ran_dec, LOGL_DEBUG, "Rx BSSMAP DT1 %s\n", gsm0808_bssmap_name(msg_type)); + LOG_RAN_A_DEC(ran_dec, LOGL_DEBUG, "%s\n", gsm0808_bssmap_name(msg_type)); switch (msg_type) { case BSS_MAP_MSG_COMPLETE_LAYER_3: @@ -804,6 +1238,26 @@ static int ran_a_decode_bssmap(struct ran_dec *ran_dec, struct msgb *bssmap) return ran_a_decode_sapi_n_reject(ran_dec, bssmap, tp); case BSS_MAP_MSG_LCLS_NOTIFICATION: return ran_a_decode_lcls_notification(ran_dec, bssmap, tp); + case BSS_MAP_MSG_VGCS_VBS_SETUP_ACK: + return ran_a_decode_vgcs_vbs_setup_ack(ran_dec, bssmap, tp); + case BSS_MAP_MSG_VGCS_VBS_SETUP_REFUSE: + return ran_a_decode_vgcs_vbs_setup_refuse(ran_dec, bssmap, tp); + case BSS_MAP_MSG_VGCS_VBS_ASSIGNMENT_RESULT: + return ran_a_decode_vgcs_vbs_assign_res(ran_dec, bssmap, tp); + case BSS_MAP_MSG_VGCS_VBS_ASSIGNMENT_FAILURE: + return ran_a_decode_vgcs_vbs_assign_fail(ran_dec, bssmap, tp); + case BSS_MAP_MSG_VGCS_VBS_QUEUING_INDICATION: + return ran_a_decode_vgcs_vbs_queuing_ind(ran_dec, bssmap, tp); + case BSS_MAP_MSG_UPLINK_RQST: + return ran_a_decode_uplink_request(ran_dec, bssmap, tp); + case BSS_MAP_MSG_UPLINK_RQST_CONFIRMATION: + return ran_a_decode_uplink_request_cnf(ran_dec, bssmap, tp); + case BSS_MAP_MSG_UPLINK_APP_DATA: + return ran_a_decode_uplink_application_data(ran_dec, bssmap, tp); + case BSS_MAP_MSG_UPLINK_RELEASE_INDICATION: + return ran_a_decode_uplink_release_ind(ran_dec, bssmap, tp); + case BSS_MAP_MSG_VGCS_VBS_ASSIGNMENT_STATUS: + return ran_a_decode_vgcs_vbs_assign_status(ran_dec, bssmap, tp); /* From current RAN peer, the Handover origin: */ case BSS_MAP_MSG_HANDOVER_REQUIRED: @@ -892,12 +1346,29 @@ static int ran_a_channel_type_to_speech_codec_list(struct gsm0808_speech_codec_l int rc; memset(scl, 0, sizeof(*scl)); - for (i = 0; i < ct->perm_spch_len; i++) { - rc = gsm0808_speech_codec_from_chan_type(&scl->codec[i], ct->perm_spch[i]); - if (rc != 0) - return -EINVAL; + + switch (ct->ch_indctr) { + case GSM0808_CHAN_DATA: + scl->codec[0] = (struct gsm0808_speech_codec) { + .pi = true, /* PI indicates CSDoIP is supported */ + .pt = false, /* PT indicates CSDoTDM is not supported */ + .type = GSM0808_SCT_CSD, + .cfg = 0, /* R2/R3 not set (redundancy not supported) */ + }; + scl->len = 1; + break; + case GSM0808_CHAN_SPEECH: + for (i = 0; i < ct->perm_spch_len; i++) { + rc = gsm0808_speech_codec_from_chan_type(&scl->codec[i], ct->perm_spch[i]); + if (rc != 0) + return -EINVAL; + } + scl->len = i; + break; + default: + OSMO_ASSERT(0); + break; } - scl->len = i; return 0; } @@ -912,6 +1383,8 @@ static struct msgb *ran_a_make_assignment_command(struct osmo_fsm_inst *log_fi, struct gsm0808_speech_codec_list *use_scl = NULL; struct sockaddr_storage rtp_addr; struct sockaddr_storage *use_rtp_addr = NULL; + struct msgb *msg; + const uint32_t *call_id = NULL; int rc; if (!ac->channel_type) { @@ -919,7 +1392,7 @@ static struct msgb *ran_a_make_assignment_command(struct osmo_fsm_inst *log_fi, return NULL; } - if (ac->channel_type->ch_indctr == GSM0808_CHAN_SPEECH) { + if (ac->channel_type->ch_indctr == GSM0808_CHAN_SPEECH || ac->channel_type->ch_indctr == GSM0808_CHAN_DATA) { rc = ran_a_channel_type_to_speech_codec_list(&scl, ac->channel_type); if (rc < 0) { LOG_RAN_A_ENC(log_fi, LOGL_ERROR, "Assignment Command: Cannot translate Channel Type to Speech Codec List\n"); @@ -928,31 +1401,72 @@ static struct msgb *ran_a_make_assignment_command(struct osmo_fsm_inst *log_fi, use_scl = &scl; /* Package RTP-Address data */ - if (osmo_sockaddr_str_is_set(ac->cn_rtp)) { - struct sockaddr_in rtp_addr_in; - - memset(&rtp_addr_in, 0, sizeof(rtp_addr_in)); - rtp_addr_in.sin_family = AF_INET; - rtp_addr_in.sin_port = osmo_htons(ac->cn_rtp->port), - rtp_addr_in.sin_addr.s_addr = inet_addr(ac->cn_rtp->ip); - - if (rtp_addr_in.sin_addr.s_addr == INADDR_NONE) { - LOG_RAN_A_ENC(log_fi, LOGL_ERROR, "Assignment Command: Invalid RTP-Address\n"); - return NULL; - } - if (rtp_addr_in.sin_port == 0) { - LOG_RAN_A_ENC(log_fi, LOGL_ERROR, "Assignment Command: Invalid RTP-Port\n"); + if (osmo_sockaddr_str_is_nonzero(ac->cn_rtp)) { + struct sockaddr_in *sin; + struct sockaddr_in6 *sin6; + int family = osmo_ip_str_type(ac->cn_rtp->ip); + switch (family) { + case AF_INET: + sin = (struct sockaddr_in *)&rtp_addr; + sin->sin_family = AF_INET; + sin->sin_port = osmo_htons(ac->cn_rtp->port); + if (inet_pton(AF_INET, ac->cn_rtp->ip, &sin->sin_addr) != 1) { + LOG_RAN_A_ENC(log_fi, LOGL_ERROR, + "Assignment Command: Invalid RTP-Address %s\n", + ac->cn_rtp->ip); + return NULL; + } + if (sin->sin_port == 0) { + LOG_RAN_A_ENC(log_fi, LOGL_ERROR, + "Assignment Command: Invalid RTP-Port\n"); + return NULL; + } + break; + case AF_INET6: + sin6 = (struct sockaddr_in6 *)&rtp_addr; + sin6->sin6_family = AF_INET6; + sin6->sin6_port = osmo_htons(ac->cn_rtp->port); + if (inet_pton(AF_INET6, ac->cn_rtp->ip, &sin6->sin6_addr) != 1) { + LOG_RAN_A_ENC(log_fi, LOGL_ERROR, + "Assignment Command: Invalid RTP-Address %s\n", + ac->cn_rtp->ip); + return NULL; + } + if (sin6->sin6_port == 0) { + LOG_RAN_A_ENC(log_fi, LOGL_ERROR, + "Assignment Command: Invalid RTP-Port\n"); + return NULL; + } + break; + default: + LOG_RAN_A_ENC(log_fi, LOGL_ERROR, + "Assignment Command: Invalid RTP-Address type for %s\n", + ac->cn_rtp->ip); return NULL; } - - memset(&rtp_addr, 0, sizeof(rtp_addr)); - memcpy(&rtp_addr, &rtp_addr_in, sizeof(rtp_addr_in)); - use_rtp_addr = &rtp_addr; } } - return gsm0808_create_ass(ac->channel_type, NULL, use_rtp_addr, use_scl, NULL); + if(ac->call_id_present == true) + call_id = &ac->call_id; + + msg = gsm0808_create_ass2(ac->channel_type, NULL, use_rtp_addr, use_scl, call_id, + NULL, ac->lcls); + if (msg == NULL) { + LOG_RAN_A_ENC(log_fi, LOGL_ERROR, + "Failed to encode BSSMAP Assignment Request message\n"); + return NULL; + } + + /* Append optional IEs: Group Call Reference and Osmux CID */ + OSMO_ASSERT(msg->l3h[1] == msgb_l3len(msg) - 2); /* TL not in len */ + if (ac->callref_present) + gsm0808_enc_group_callref(msg, &ac->callref); + if (ac->osmux_present) + msgb_tv_put(msg, GSM0808_IE_OSMO_OSMUX_CID, ac->osmux_cid); + msg->l3h[1] = msgb_l3len(msg) - 2; + return msg; } /* For an A5/N number a5_n set dst to the matching GSM0808_ALG_ID_A5_<n>. */ @@ -971,6 +1485,9 @@ static int a5_n_to_gsm0808_chosen_enc_alg(uint8_t *dst, int a5_n) case 3: *dst = GSM0808_ALG_ID_A5_3; return 0; + case 4: + *dst = GSM0808_ALG_ID_A5_4; + return 0; default: return -ENOTSUP; } @@ -1010,14 +1527,17 @@ osmo_static_assert(sizeof(((struct gsm0808_encrypt_info*)0)->key) >= sizeof(((st gsm0808_encrypt_info_key_fits_osmo_auth_vec_kc); static struct msgb *ran_a_make_cipher_mode_command(struct osmo_fsm_inst *fi, const struct ran_cipher_mode_command *cm) { - struct gsm0808_encrypt_info ei = {}; + struct gsm0808_cipher_mode_command cmc = { + .cipher_response_mode_present = true, + .cipher_response_mode = 1, /* 1: include IMEISV (3GPP TS 48.008 3.2.2.34) */ + }; + struct gsm0808_encrypt_info *ei = &cmc.ei; char buf[16 * 2 + 1]; - const uint8_t cipher_response_mode = 1; - if (make_encrypt_info_perm_algo(fi, &ei, cm->geran.a5_encryption_mask, cm->classmark)) + if (make_encrypt_info_perm_algo(fi, ei, cm->geran.a5_encryption_mask, cm->classmark)) return NULL; - if (ei.perm_algo_len == 0) { + if (ei->perm_algo_len == 0) { LOG_RAN_A_ENC(fi, LOGL_ERROR, "cannot start ciphering, no intersection between MSC-configured" " and MS-supported A5 algorithms. MSC: 0x%02x MS: %s\n", cm->geran.a5_encryption_mask, osmo_gsm48_classmark_a5_name(cm->classmark)); @@ -1027,27 +1547,45 @@ static struct msgb *ran_a_make_cipher_mode_command(struct osmo_fsm_inst *fi, con /* In case of UMTS AKA, the Kc for ciphering must be derived from the 3G auth * tokens. vec->kc was calculated from the GSM algorithm and is not * necessarily a match for the UMTS AKA tokens. */ - if (cm->geran.umts_aka) - osmo_auth_c3(ei.key, cm->vec->ck, cm->vec->ik); - else - memcpy(ei.key, cm->vec->kc, sizeof(cm->vec->kc)); - ei.key_len = sizeof(cm->vec->kc); + if (cm->geran.umts_aka) { + int i; + osmo_auth_c3(ei->key, cm->vec->ck, cm->vec->ik); + + for (i = 0; i < ei->perm_algo_len; i++) { + if (ei->perm_algo[i] != GSM0808_ALG_ID_A5_4) + continue; + /* A5/4 is included, so need to generate Kc128 */ + osmo_kdf_kc128(cm->vec->ck, cm->vec->ik, cmc.kc128); + cmc.kc128_present = true; + break; + } + } else { + memcpy(ei->key, cm->vec->kc, sizeof(cm->vec->kc)); + } + ei->key_len = sizeof(cm->vec->kc); /* Store chosen GERAN key where the caller asked it to be stored. * alg_id remains unknown until we receive a Cipher Mode Complete from the BSC */ if (cm->geran.chosen_key) { - if (ei.key_len > sizeof(cm->geran.chosen_key->key)) { + *cm->geran.chosen_key = (struct geran_encr){0}; + + if (ei->key_len > sizeof(cm->geran.chosen_key->key)) { LOG_RAN_A_ENC(fi, LOGL_ERROR, "Chosen key is larger than I can store\n"); return NULL; } - memcpy(cm->geran.chosen_key->key, ei.key, ei.key_len); - cm->geran.chosen_key->key_len = ei.key_len; + memcpy(cm->geran.chosen_key->key, ei->key, ei->key_len); + cm->geran.chosen_key->key_len = ei->key_len; + + if (cmc.kc128_present) { + memcpy(cm->geran.chosen_key->kc128, cmc.kc128, 16); + cm->geran.chosen_key->kc128_present = true; + } } LOG_RAN_A_ENC(fi, LOGL_DEBUG, "Tx BSSMAP CIPHER MODE COMMAND to BSC, %u ciphers (%s) key %s\n", - ei.perm_algo_len, osmo_hexdump_nospc(ei.perm_algo, ei.perm_algo_len), - osmo_hexdump_buf(buf, sizeof(buf), ei.key, ei.key_len, NULL, false)); - return gsm0808_create_cipher(&ei, cm->geran.retrieve_imeisv ? &cipher_response_mode : NULL); + ei->perm_algo_len, osmo_hexdump_nospc(ei->perm_algo, ei->perm_algo_len), + osmo_hexdump_buf(buf, sizeof(buf), ei->key, ei->key_len, NULL, false)); + return gsm0808_create_cipher2(&cmc); } struct msgb *ran_a_make_handover_request(struct osmo_fsm_inst *log_fi, const struct ran_handover_request *n) @@ -1067,6 +1605,7 @@ struct msgb *ran_a_make_handover_request(struct osmo_fsm_inst *log_fi, const str .imsi = n->imsi, .codec_list_msc_preferred = n->codec_list_msc_preferred, + .call_id_present = n->call_id_present, .call_id = n->call_id, .global_call_reference = n->global_call_reference, .global_call_reference_len = n->global_call_reference_len, @@ -1092,12 +1631,18 @@ struct msgb *ran_a_make_handover_request(struct osmo_fsm_inst *log_fi, const str n->geran.chosen_encryption->key, n->geran.chosen_encryption->key_len); r.encryption_information.key_len = n->geran.chosen_encryption->key_len; r.chosen_encryption_algorithm_serving = n->geran.chosen_encryption->alg_id; + + if (n->geran.chosen_encryption->kc128_present) { + r.more_items = true; + memcpy(r.kc128, n->geran.chosen_encryption->kc128, sizeof(r.kc128)); + r.kc128_present = true; + } } if (n->classmark) r.classmark_information = *n->classmark; - if (osmo_sockaddr_str_is_set(n->rtp_ran_local)) { + if (osmo_sockaddr_str_is_nonzero(n->rtp_ran_local)) { if (osmo_sockaddr_str_to_sockaddr(n->rtp_ran_local, &ss)) { LOG_RAN_A_ENC(log_fi, LOGL_ERROR, "Handover Request: invalid AoIP Transport Layer address/port: " @@ -1122,7 +1667,7 @@ static struct msgb *ran_a_make_handover_request_ack(struct osmo_fsm_inst *caller .chosen_speech_version = r->chosen_speech_version, }; - if (osmo_sockaddr_str_is_set(&r->remote_rtp)) { + if (osmo_sockaddr_str_is_nonzero(&r->remote_rtp)) { osmo_sockaddr_str_to_sockaddr(&r->remote_rtp, &ss); params.aoip_transport_layer = &ss; } @@ -1168,6 +1713,13 @@ static struct msgb *_ran_a_encode(struct osmo_fsm_inst *caller_fi, const struct case RAN_MSG_ASSIGNMENT_COMMAND: return ran_a_make_assignment_command(caller_fi, &ran_enc_msg->assignment_command); + case RAN_MSG_COMMON_ID: + return gsm0808_create_common_id(ran_enc_msg->common_id.imsi, NULL, + ran_enc_msg->common_id.last_eutran_plmn_present ? + &ran_enc_msg->common_id.last_eutran_plmn : + NULL + ); + case RAN_MSG_CIPHER_MODE_COMMAND: return ran_a_make_cipher_mode_command(caller_fi, &ran_enc_msg->cipher_mode_command); @@ -1189,6 +1741,36 @@ static struct msgb *_ran_a_encode(struct osmo_fsm_inst *caller_fi, const struct case RAN_MSG_HANDOVER_FAILURE: return ran_a_make_handover_failure(caller_fi, ran_enc_msg); + case RAN_MSG_VGCS_VBS_SETUP: + return gsm0808_create_vgcs_vbs_setup(&ran_enc_msg->vgcs_vbs_setup); + + case RAN_MSG_VGCS_VBS_ASSIGN_REQ: + return gsm0808_create_vgcs_vbs_assign_req(&ran_enc_msg->vgcs_vbs_assign_req); + + case RAN_MSG_UPLINK_REQUEST_ACK: + return gsm0808_create_uplink_request_ack(&ran_enc_msg->uplink_request_ack); + + case RAN_MSG_UPLINK_REJECT_CMD: + return gsm0808_create_uplink_reject_cmd(&ran_enc_msg->uplink_reject_cmd); + + case RAN_MSG_UPLINK_RELEASE_CMD: + return gsm0808_create_uplink_release_cmd(ran_enc_msg->uplink_release_cmd.cause); + + case RAN_MSG_UPLINK_SEIZED_CMD: + return gsm0808_create_uplink_seized_cmd(&ran_enc_msg->uplink_seized_cmd); + + case RAN_MSG_VGCS_ADDITIONAL_INFO: + return gsm0808_create_vgcs_additional_info(&ran_enc_msg->vgcs_additional_info.talker_identity); + + case RAN_MSG_VGCS_VBS_AREA_CELL_INFO: + return gsm0808_create_vgcs_vbs_area_cell_info(&ran_enc_msg->vgcs_vbs_area_cell_info); + + case RAN_MSG_VGCS_SMS: + return gsm0808_create_vgcs_sms(&ran_enc_msg->vgcs_sms.sms_to_vgcs); + + case RAN_MSG_NOTIFICATION_DATA: + return gsm0808_create_notification_data(&ran_enc_msg->notification_data); + default: LOG_RAN_A_ENC(caller_fi, LOGL_ERROR, "Unimplemented RAN-encode message type: %s\n", ran_msg_type_name(ran_enc_msg->msg_type)); @@ -1220,20 +1802,50 @@ struct msgb *ran_a_encode(struct osmo_fsm_inst *caller_fi, const struct ran_msg return msg; } -/* Return 1 for a RESET, 2 for a RESET ACK message, 0 otherwise */ -enum reset_msg_type bssmap_is_reset_msg(const struct sccp_ran_inst *sri, const struct msgb *l2) +static void cl_parse_osmux(struct osmo_fsm_inst *log_fi, struct msgb *msg, int *supports_osmux) +{ + struct tlv_parsed tp; + int rc; + + if (supports_osmux == NULL) + return; + + rc = tlv_parse(&tp, gsm0808_att_tlvdef(), msgb_l3(msg) + 1, msgb_l3len(msg) - 1, 0, 0); + if (rc < 0) { + LOGPFSMSL(log_fi, DBSSAP, LOGL_ERROR, "BSSMAP: Failed parsing TLV looking for Osmux support\n"); + return; + } + + if (TLVP_PRESENT(&tp, GSM0808_IE_OSMO_OSMUX_SUPPORT)) { + *supports_osmux = true; + } else { + *supports_osmux = false; + } +} + +/* Return 1 for a RESET, 2 for a RESET ACK message, 0 otherwise. + * In supports_osmux, return 0 for no information, 1 for support detected, -1 for non-support detected. */ +enum reset_msg_type bssmap_is_reset_msg(const struct sccp_ran_inst *sri, struct osmo_fsm_inst *log_fi, + struct msgb *l2, int *supports_osmux) { struct bssmap_header *bs = (struct bssmap_header *)msgb_l2(l2); + if (supports_osmux != NULL) + *supports_osmux = 0; + if (!bs || msgb_l2len(l2) < (sizeof(*bs) + 1) || bs->type != BSSAP_MSG_BSS_MANAGEMENT) return SCCP_RAN_MSG_NON_RESET; - switch (l2->l2h[sizeof(*bs)]) { + l2->l3h = l2->l2h + sizeof(struct bssmap_header); + + switch (l2->l3h[0]) { case BSS_MAP_MSG_RESET: + cl_parse_osmux(log_fi, l2, supports_osmux); return SCCP_RAN_MSG_RESET; case BSS_MAP_MSG_RESET_ACKNOWLEDGE: + cl_parse_osmux(log_fi, l2, supports_osmux); return SCCP_RAN_MSG_RESET_ACK; default: return SCCP_RAN_MSG_NON_RESET; diff --git a/src/libmsc/ran_msg_iu.c b/src/libmsc/ran_msg_iu.c index f4439449d..37cdf1065 100644 --- a/src/libmsc/ran_msg_iu.c +++ b/src/libmsc/ran_msg_iu.c @@ -1,25 +1,21 @@ /* RANAP encoding and decoding for MSC */ /* - * (C) 2019 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de> + * (C) 2019 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de> * All Rights Reserved * * Author: Neels Hofmeyr * - * SPDX-License-Identifier: GPL-2.0+ + * SPDX-License-Identifier: AGPL-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 2 of the License, or + * 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 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. + * GNU Affero General Public License for more details. */ #include <asn1c/asn1helpers.h> @@ -27,6 +23,7 @@ #include <osmocom/core/prim.h> #include <osmocom/core/byteswap.h> #include <osmocom/crypt/auth.h> +#include <osmocom/crypt/utran_cipher.h> #include <osmocom/gsm/gsm48.h> #include <osmocom/ranap/ranap_common_cn.h> @@ -37,16 +34,7 @@ #include <osmocom/msc/msc_common.h> #include <osmocom/msc/sccp_ran.h> #include <osmocom/msc/ran_msg_iu.h> - -/* Implement the extern talloc_asn1_ctx from libasn1c as talloc ctx for ASN.1 message composition */ -void *talloc_asn1_ctx = NULL; - -/* Implement the extern asn_debug from libasn1c to indicate whether to print asn.1 debug messages. */ -int asn_debug = 0; - -/* Implement the extern asn1_xer_print to indicate whether the ASN.1 binary code decoded and encoded during Iu - * communication should be logged to stderr (see asn.1 generated code in osmo-iuh). */ -int asn1_xer_print = 0; +#include <osmocom/msc/gsm_04_11.h> #define LOG_RAN_IU_DEC(RAN_DEC, level, fmt, args...) \ LOG_RAN_DEC(RAN_DEC, DIUCS, level, "RANAP: " fmt, ## args) @@ -92,8 +80,11 @@ static void ran_iu_decode_l3_initial(struct ran_dec *ran_iu_decode, const RANAP_ msgb_free(ran); } -static void ran_iu_decode_l3(struct ran_dec *ran_iu_decode, const RANAP_NAS_PDU_t *nas_pdu, const char *msg_name) +static void ran_iu_decode_l3(struct ran_dec *ran_iu_decode, + const RANAP_DirectTransferIEs_t *ies, + const char *msg_name) { + const RANAP_NAS_PDU_t *nas_pdu = &ies->nas_pdu; struct msgb *ran = msgb_alloc(256, msg_name); struct ran_msg ran_dec_msg; @@ -101,6 +92,12 @@ static void ran_iu_decode_l3(struct ran_dec *ran_iu_decode, const RANAP_NAS_PDU_ ran->l3h = msgb_put(ran, nas_pdu->size); memcpy(ran->l3h, nas_pdu->buf, nas_pdu->size); + /* Handle optional SAPI IE */ + if (ies->presenceMask & DIRECTTRANSFERIES_RANAP_SAPI_PRESENT) { + if (ies->sapi == RANAP_SAPI_sapi_3) + OMSC_LINKID_CB(ran) = UM_SAPI_SMS; + } + ran_dec_msg = (struct ran_msg){ .msg_type = RAN_MSG_DTAP, .msg_name = msg_name, @@ -156,7 +153,16 @@ static int ran_iu_decode_rab_assignment_response_decode_setup_ies(struct ran_dec .msg_type = RAN_MSG_ASSIGNMENT_COMPLETE, .msg_name = "RANAP RAB Assignment Response", .assignment_complete = { - .codec = CODEC_AMR_8000_1, + /* For codec compatibility resolution, indicate AMR-FR */ + .codec_present = true, + .codec = { + .fi = true, + .type = GSM0808_SCT_FR3, + .cfg = GSM0808_SC_CFG_DEFAULT_FR_AMR, + }, + /* Indicate that (at least) the first MGW endpoint towards RAN needs to expect VND.3GPP.IUFP + * that encapsulates the AMR-FR RTP payload. */ + .codec_with_iuup = true, }, }; if (osmo_sockaddr_str_from_str(&ran_dec_msg->assignment_complete.remote_rtp, addr, port)) { @@ -211,12 +217,20 @@ success: ranap_free_rab_setupormodifieditemies(&setup_ies); } -static void ran_iu_decode_security_mode_complete(struct ran_dec *ran_iu_decode) +static void ran_iu_decode_security_mode_complete(struct ran_dec *ran_iu_decode, const RANAP_SecurityModeCompleteIEs_t *ies) { struct ran_msg ran_dec_msg = { .msg_type = RAN_MSG_CIPHER_MODE_COMPLETE, .msg_name = "RANAP SecurityModeControl successfulOutcome", + .cipher_mode_complete = { + .utran_integrity = ies->chosenIntegrityProtectionAlgorithm, + .utran_encryption = -1, + }, }; + + if (ies->presenceMask & SECURITYMODECOMPLETEIES_RANAP_CHOSENENCRYPTIONALGORITHM_PRESENT) + ran_dec_msg.cipher_mode_complete.utran_encryption = ies->chosenEncryptionAlgorithm; + ran_decoded(ran_iu_decode, &ran_dec_msg); } @@ -266,13 +280,13 @@ static void ran_iu_decode_ranap_msg(void *_ran_dec, ranap_message *message) return; case RANAP_ProcedureCode_id_DirectTransfer: - ran_iu_decode_l3(ran_iu_decode, &message->msg.directTransferIEs.nas_pdu, "RANAP DirectTransfer RAN PDU"); + ran_iu_decode_l3(ran_iu_decode, &message->msg.directTransferIEs, "RANAP DirectTransfer RAN PDU"); return; case RANAP_ProcedureCode_id_SecurityModeControl: switch (message->direction) { case RANAP_RANAP_PDU_PR_successfulOutcome: - ran_iu_decode_security_mode_complete(ran_iu_decode); + ran_iu_decode_security_mode_complete(ran_iu_decode, &message->msg.securityModeCompleteIEs); return; case RANAP_RANAP_PDU_PR_unsuccessfulOutcome: ran_iu_decode_security_mode_reject(ran_iu_decode); @@ -366,10 +380,21 @@ static struct msgb *ran_iu_make_rab_assignment(struct osmo_fsm_inst *caller_fi, static struct msgb *ran_iu_make_security_mode_command(struct osmo_fsm_inst *caller_fi, const struct ran_cipher_mode_command *cm) { - - LOG_RAN_IU_ENC(caller_fi, LOGL_DEBUG, "Tx RANAP SECURITY MODE COMMAND to RNC, ik %s\n", - osmo_hexdump_nospc(cm->vec->ik, 16)); - return ranap_new_msg_sec_mod_cmd(cm->vec->ik, NULL, RANAP_KeyStatus_new); + /* TODO: make the choice of available UIA algorithms configurable */ + const uint8_t uia_mask = (1 << OSMO_UTRAN_UIA1) | (1 << OSMO_UTRAN_UIA2); + const uint8_t uea_mask = cm->utran.uea_encryption_mask & ~(1 << OSMO_UTRAN_UEA0); + bool use_encryption = uea_mask != 0x00; + + LOG_RAN_IU_ENC(caller_fi, LOGL_DEBUG, "Tx RANAP SECURITY MODE COMMAND to RNC, IK=%s, CK=%s\n", + osmo_hexdump_nospc(cm->vec->ik, 16), + use_encryption ? osmo_hexdump_nospc(cm->vec->ck, 16) : "NONE"); + /* TODO: Do we need to check if the UE supports all of the algorithms and build an intersection like + * in the case of A5? */ + return ranap_new_msg_sec_mod_cmd2(cm->vec->ik, + use_encryption ? cm->vec->ck : NULL, + RANAP_KeyStatus_new, + (uia_mask << 1), /* API treats LSB as UIA0 */ + uea_mask); } @@ -386,25 +411,28 @@ static struct msgb *ran_iu_make_release_command(struct osmo_fsm_inst *caller_fi, struct msgb *ran_iu_encode(struct osmo_fsm_inst *caller_fi, const struct ran_msg *ran_enc_msg) { - LOG_RAN_IU_ENC(caller_fi, LOGL_DEBUG, "%s\n", ran_msg_type_name(ran_enc_msg->msg_type)); - switch (ran_enc_msg->msg_type) { case RAN_MSG_DTAP: + LOG_RAN_IU_ENC(caller_fi, LOGL_DEBUG, "DirectTransfer\n"); return ran_iu_wrap_dtap(ran_enc_msg->dtap); // TODO: RAN_MSG_CLASSMARK_REQUEST ?? case RAN_MSG_CIPHER_MODE_COMMAND: + LOG_RAN_IU_ENC(caller_fi, LOGL_DEBUG, "SecurityModeCommand\n"); return ran_iu_make_security_mode_command(caller_fi, &ran_enc_msg->cipher_mode_command); case RAN_MSG_ASSIGNMENT_COMMAND: + LOG_RAN_IU_ENC(caller_fi, LOGL_DEBUG, "RAB AssignmentRequest\n"); return ran_iu_make_rab_assignment(caller_fi, &ran_enc_msg->assignment_command); case RAN_MSG_COMMON_ID: + LOG_RAN_IU_ENC(caller_fi, LOGL_DEBUG, "CommonId\n"); return ranap_new_msg_common_id(ran_enc_msg->common_id.imsi); case RAN_MSG_CLEAR_COMMAND: + LOG_RAN_IU_ENC(caller_fi, LOGL_DEBUG, "Iu Release\n"); return ran_iu_make_release_command(caller_fi, &ran_enc_msg->clear_command); default: @@ -435,11 +463,15 @@ static void ranap_handle_cl(void *ctx, ranap_message *message) } } -enum reset_msg_type ranap_is_reset_msg(const struct sccp_ran_inst *sri, const struct msgb *l2) +enum reset_msg_type ranap_is_reset_msg(const struct sccp_ran_inst *sri, struct osmo_fsm_inst *log_fi, + struct msgb *l2, int *supports_osmux) { int ret = SCCP_RAN_MSG_NON_RESET; int rc; + if (supports_osmux != NULL) + *supports_osmux = -1; + rc = ranap_cn_rx_cl(ranap_handle_cl, &ret, msgb_l2(l2), msgb_l2len(l2)); if (rc) return 0; diff --git a/src/libmsc/ran_peer.c b/src/libmsc/ran_peer.c index ce26794cd..860444334 100644 --- a/src/libmsc/ran_peer.c +++ b/src/libmsc/ran_peer.c @@ -1,5 +1,5 @@ /* - * (C) 2019 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de> + * (C) 2019 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de> * All Rights Reserved * * SPDX-License-Identifier: AGPL-3.0+ @@ -33,6 +33,7 @@ #include <osmocom/msc/vlr.h> #include <osmocom/msc/ran_conn.h> #include <osmocom/msc/cell_id_list.h> +#include <osmocom/msc/msc_vgcs.h> static struct osmo_fsm ran_peer_fsm; @@ -80,13 +81,13 @@ static struct ran_peer *ran_peer_alloc(struct sccp_ran_inst *sri, const struct o struct ran_peer *ran_peer_find_or_create(struct sccp_ran_inst *sri, const struct osmo_sccp_addr *peer_addr) { - struct ran_peer *rp = ran_peer_find(sri, peer_addr); + struct ran_peer *rp = ran_peer_find_by_addr(sri, peer_addr); if (rp) return rp; return ran_peer_alloc(sri, peer_addr); } -struct ran_peer *ran_peer_find(struct sccp_ran_inst *sri, const struct osmo_sccp_addr *peer_addr) +struct ran_peer *ran_peer_find_by_addr(struct sccp_ran_inst *sri, const struct osmo_sccp_addr *peer_addr) { struct ran_peer *rp; llist_for_each_entry(rp, &sri->ran_peers, entry) { @@ -118,29 +119,28 @@ void ran_peer_discard_all_conns(struct ran_peer *rp) struct ran_conn *conn, *next; ran_peer_for_each_ran_conn_safe(conn, next, rp) { - ran_conn_discard(conn); + /* Tell VGCS FSM that the connections have been cleared. */ + if (conn->vgcs.bss) + vgcs_vbs_clear_cpl(conn->vgcs.bss, NULL); + else if (conn->vgcs.cell) + vgcs_vbs_clear_cpl_channel(conn->vgcs.cell, NULL); + else ran_conn_discard(conn); } } -/* TODO: create an sccp_ran_ops.rx_reset(_ack) to handle this differently on 2g and 3G */ -/* We expect RAN peer to provide use with an Osmocom extension TLV in BSSMAP_RESET to - * announce Osmux support */ -static void ran_peer_update_osmux_support(struct ran_peer *rp, struct msgb *msg) +static void ran_peer_update_osmux_support(struct ran_peer *rp, int supports_osmux) { - struct tlv_parsed tp; - int rc; bool old_value = rp->remote_supports_osmux; - OSMO_ASSERT(msg); - msg->l3h = msg->l2h + sizeof(struct bssmap_header); - rc = tlv_parse(&tp, gsm0808_att_tlvdef(), msg->l3h + 1, msgb_l3len(msg) - 1, 0, 0); - if (rc < 0) - LOG_RAN_PEER(rp, LOGL_NOTICE, "Failed parsing TLV looking for Osmux support\n"); - - if (TLVP_PRESENT(&tp, GSM0808_IE_OSMO_OSMUX_SUPPORT)) { + switch (supports_osmux) { + case 1: rp->remote_supports_osmux = true; - } else { + break; + case -1: rp->remote_supports_osmux = false; + break; + default: + return; } if (old_value != rp->remote_supports_osmux) @@ -155,8 +155,6 @@ static void ran_peer_rx_reset(struct ran_peer *rp, struct msgb* msg) ran_peer_discard_all_conns(rp); - ran_peer_update_osmux_support(rp, msg); - reset_ack = rp->sri->ran->sccp_ran_ops.make_reset_msg(rp->sri, SCCP_RAN_MSG_RESET_ACK); if (!reset_ack) { @@ -183,7 +181,6 @@ static void ran_peer_rx_reset(struct ran_peer *rp, struct msgb* msg) static void ran_peer_rx_reset_ack(struct ran_peer *rp, struct msgb* msg) { ran_peer_state_chg(rp, RAN_PEER_ST_READY); - ran_peer_update_osmux_support(rp, msg); } void ran_peer_reset(struct ran_peer *rp) @@ -213,14 +210,18 @@ void ran_peer_allstate_action(struct osmo_fsm_inst *fi, uint32_t event, void *da struct ran_peer *rp = fi->priv; struct ran_peer_ev_ctx *ctx = data; struct msgb *msg = ctx->msg; + enum reset_msg_type is_reset; + int supports_osmux; switch (event) { case RAN_PEER_EV_MSG_UP_CL: - switch (rp->sri->ran->sccp_ran_ops.is_reset_msg(rp->sri, msg)) { - case 1: + is_reset = rp->sri->ran->sccp_ran_ops.is_reset_msg(rp->sri, fi, msg, &supports_osmux); + ran_peer_update_osmux_support(rp, supports_osmux); + switch (is_reset) { + case SCCP_RAN_MSG_RESET: osmo_fsm_inst_dispatch(fi, RAN_PEER_EV_RX_RESET, msg); return; - case 2: + case SCCP_RAN_MSG_RESET_ACK: osmo_fsm_inst_dispatch(fi, RAN_PEER_EV_RX_RESET_ACK, msg); return; default: @@ -370,7 +371,7 @@ void ran_peer_st_ready(struct osmo_fsm_inst *fi, uint32_t event, void *data) case RAN_PEER_EV_MSG_UP_CO_INITIAL: ctx = data; - OSMO_ASSERT(ctx) + OSMO_ASSERT(ctx); OSMO_ASSERT(!ctx->conn); OSMO_ASSERT(ctx->msg); @@ -398,18 +399,22 @@ void ran_peer_st_ready(struct osmo_fsm_inst *fi, uint32_t event, void *data) OSMO_ASSERT(ctx->conn); OSMO_ASSERT(ctx->msg); - if (!ctx->conn->msc_role) { + if (ctx->conn->msc_role) { + /* "normal" A connection, dispatch to MSC-I or MSC-T */ + an_apdu = (struct an_apdu){ + .an_proto = rp->sri->ran->an_proto, + .msg = ctx->msg, + }; + osmo_fsm_inst_dispatch(ctx->conn->msc_role, MSC_EV_FROM_RAN_UP_L2, &an_apdu); + } else if (ctx->conn->vgcs.bss) { + /* VGCS call related */ + msc_a_rx_vgcs_bss(ctx->conn->vgcs.bss, ctx->conn, ctx->msg); + } else if (ctx->conn->vgcs.cell) { + /* VGCS channel related */ + msc_a_rx_vgcs_cell(ctx->conn->vgcs.cell, ctx->conn, ctx->msg); + } else LOG_RAN_PEER(rp, LOGL_ERROR, "Rx CO message on conn that is not associated with any MSC role\n"); - return; - } - - an_apdu = (struct an_apdu){ - .an_proto = rp->sri->ran->an_proto, - .msg = ctx->msg, - }; - - osmo_fsm_inst_dispatch(ctx->conn->msc_role, MSC_EV_FROM_RAN_UP_L2, &an_apdu); return; case RAN_PEER_EV_MSG_DOWN_CO_INITIAL: @@ -629,17 +634,6 @@ struct ran_peer *ran_peer_find_by_cell_id(struct sccp_ran_inst *sri, const struc return found; } -struct ran_peer *ran_peer_find_by_addr(struct sccp_ran_inst *sri, const struct osmo_sccp_addr *addr) -{ - struct ran_peer *rp; - - llist_for_each_entry(rp, &sri->ran_peers, entry) { - if (!osmo_sccp_addr_ri_cmp(addr, &rp->peer_addr)) - return rp; - } - return NULL; -} - int ran_peers_down_paging(struct sccp_ran_inst *sri, enum CELL_IDENT page_where, struct vlr_subscr *vsub, enum paging_cause cause) { @@ -650,7 +644,7 @@ int ran_peers_down_paging(struct sccp_ran_inst *sri, enum CELL_IDENT page_where, switch (page_where) { case CELL_IDENT_NO_CELL: - LOG_SCCP_RAN_CAT(sri, DPAG, LOGL_ERROR, "Asked to page on NO_CELL, wich doesn't make sense.\n"); + LOG_SCCP_RAN_CAT(sri, DPAG, LOGL_ERROR, "Asked to page on NO_CELL, which doesn't make sense.\n"); return 0; case CELL_IDENT_UTRAN_PLMN_LAC_RNC: diff --git a/src/libmsc/rtp_stream.c b/src/libmsc/rtp_stream.c index afe24ad51..eb9ba7e52 100644 --- a/src/libmsc/rtp_stream.c +++ b/src/libmsc/rtp_stream.c @@ -1,5 +1,5 @@ /* - * (C) 2019 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de> + * (C) 2019 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de> * All Rights Reserved * * SPDX-License-Identifier: AGPL-3.0+ @@ -28,6 +28,7 @@ #include <osmocom/msc/transaction.h> #include <osmocom/msc/call_leg.h> #include <osmocom/msc/rtp_stream.h> +#include <osmocom/msc/codec_mapping.h> #define LOG_RTPS(rtps, level, fmt, args...) \ LOGPFSML(rtps->fi, level, fmt, ##args) @@ -74,19 +75,29 @@ void rtp_stream_update_id(struct rtp_stream *rtps) OSMO_STRBUF_PRINTF(sb, ":no-CI"); } else { OSMO_STRBUF_PRINTF(sb, ":CI-%s", osmo_mgcpc_ep_ci_id(rtps->ci)); - if (!osmo_sockaddr_str_is_set(&rtps->remote)) + if (!osmo_sockaddr_str_is_nonzero(&rtps->remote)) OSMO_STRBUF_PRINTF(sb, ":no-remote-port"); else if (!rtps->remote_sent_to_mgw) OSMO_STRBUF_PRINTF(sb, ":remote-port-not-sent"); - if (!rtps->codec_known) - OSMO_STRBUF_PRINTF(sb, ":no-codec"); - else if (!rtps->codec_sent_to_mgw) - OSMO_STRBUF_PRINTF(sb, ":codec-not-sent"); + if (!rtps->codecs_known) + OSMO_STRBUF_PRINTF(sb, ":no-codecs"); + else if (!rtps->codecs_sent_to_mgw) + OSMO_STRBUF_PRINTF(sb, ":codecs-not-sent"); + if (!rtps->codecs_sent_to_mgw) + OSMO_STRBUF_PRINTF(sb, ":mode-not-sent"); + if (rtps->use_osmux) { + if (rtps->remote_osmux_cid < 0) + OSMO_STRBUF_PRINTF(sb, ":no-remote-osmux-cid"); + else if (!rtps->remote_osmux_cid_sent_to_mgw) + OSMO_STRBUF_PRINTF(sb, ":remote-osmux-cid-not-sent"); + } } - if (osmo_sockaddr_str_is_set(&rtps->local)) + if (osmo_sockaddr_str_is_nonzero(&rtps->local)) OSMO_STRBUF_PRINTF(sb, ":local-%s-%u", rtps->local.ip, rtps->local.port); - if (osmo_sockaddr_str_is_set(&rtps->remote)) + if (osmo_sockaddr_str_is_nonzero(&rtps->remote)) OSMO_STRBUF_PRINTF(sb, ":remote-%s-%u", rtps->remote.ip, rtps->remote.port); + if (rtps->use_osmux) + OSMO_STRBUF_PRINTF(sb, ":osmux-%d-%d", rtps->local_osmux_cid, rtps->remote_osmux_cid); /* Replace any dots in the IP address, dots not allowed as FSM instance name */ for (p = buf; *p; p++) @@ -99,13 +110,14 @@ void rtp_stream_update_id(struct rtp_stream *rtps) /* Allocate RTP stream under a call leg. This is one RTP connection from some remote entity with address and port to a * local RTP address and port. call_id is stored for sending in MGCP transactions and as logging context. for_trans is * optional, merely stored for reference by callers, and appears as log context if not NULL. */ -struct rtp_stream *rtp_stream_alloc(struct call_leg *parent_call_leg, enum rtp_direction dir, - uint32_t call_id, struct gsm_trans *for_trans) +struct rtp_stream *rtp_stream_alloc(struct osmo_fsm_inst *parent_fi, uint32_t event_gone, uint32_t event_avail, + uint32_t event_estab, enum rtp_direction dir, uint32_t call_id, + struct gsm_trans *for_trans) { struct osmo_fsm_inst *fi; struct rtp_stream *rtps; - fi = osmo_fsm_inst_alloc_child(&rtp_stream_fsm, parent_call_leg->fi, CALL_LEG_EV_RTP_STREAM_GONE); + fi = osmo_fsm_inst_alloc_child(&rtp_stream_fsm, parent_fi, event_gone); OSMO_ASSERT(fi); rtps = talloc(fi, struct rtp_stream); @@ -113,10 +125,14 @@ struct rtp_stream *rtp_stream_alloc(struct call_leg *parent_call_leg, enum rtp_d fi->priv = rtps; *rtps = (struct rtp_stream){ .fi = fi, - .parent_call_leg = parent_call_leg, + .event_avail = event_avail, + .event_estab = event_estab, .call_id = call_id, .for_trans = for_trans, .dir = dir, + .local_osmux_cid = -2, + .remote_osmux_cid = -2, + .crcx_conn_mode = MGCP_CONN_NONE, /* Use connection's default mode. */ }; rtp_stream_update_id(rtps); @@ -127,10 +143,11 @@ struct rtp_stream *rtp_stream_alloc(struct call_leg *parent_call_leg, enum rtp_d static void check_established(struct rtp_stream *rtps) { if (rtps->fi->state != RTP_STREAM_ST_ESTABLISHED - && osmo_sockaddr_str_is_set(&rtps->local) - && osmo_sockaddr_str_is_set(&rtps->remote) + && osmo_sockaddr_str_is_nonzero(&rtps->local) + && osmo_sockaddr_str_is_nonzero(&rtps->remote) && rtps->remote_sent_to_mgw - && rtps->codec_known) + && (!rtps->use_osmux || rtps->remote_osmux_cid_sent_to_mgw) + && rtps->codecs_known) rtp_stream_state_chg(rtps, RTP_STREAM_ST_ESTABLISHED); } @@ -148,17 +165,28 @@ static void rtp_stream_fsm_establishing_established(struct osmo_fsm_inst *fi, ui } osmo_sockaddr_str_from_str(&rtps->local, crcx_info->addr, crcx_info->port); + if (rtps->use_osmux != crcx_info->x_osmo_osmux_use) { + LOG_RTPS(rtps, LOGL_ERROR, "Osmux usage request and response don't match: %d vs %d", + rtps->use_osmux, crcx_info->x_osmo_osmux_use); + /* TODO: proper failure path */ + OSMO_ASSERT(rtps->use_osmux != crcx_info->x_osmo_osmux_use); + } + if (crcx_info->x_osmo_osmux_use) + rtps->local_osmux_cid = crcx_info->x_osmo_osmux_cid; rtp_stream_update_id(rtps); - osmo_fsm_inst_dispatch(fi->proc.parent, CALL_LEG_EV_RTP_STREAM_ADDR_AVAILABLE, rtps); + osmo_fsm_inst_dispatch(fi->proc.parent, rtps->event_avail, rtps); check_established(rtps); - if ((!rtps->remote_sent_to_mgw || !rtps->codec_sent_to_mgw) - && osmo_sockaddr_str_is_set(&rtps->remote) - && rtps->codec_known) { + if ((!rtps->remote_sent_to_mgw || !rtps->codecs_sent_to_mgw || !rtps->mode_sent_to_mgw) + && osmo_sockaddr_str_is_nonzero(&rtps->remote) + && (!rtps->use_osmux || rtps->remote_osmux_cid_sent_to_mgw) + && rtps->codecs_known) { LOG_RTPS(rtps, LOGL_DEBUG, - "local ip:port set;%s%s triggering MDCX to send the new settings\n", - (!rtps->remote_sent_to_mgw)? " remote ip:port not yet sent," : "", - (!rtps->codec_sent_to_mgw)? " codec not yet sent," : ""); + "local ip:port set;%s%s%s%s triggering MDCX to send the new settings\n", + (!rtps->remote_sent_to_mgw) ? " remote ip:port not yet sent," : "", + (!rtps->codecs_sent_to_mgw) ? " codecs not yet sent," : "", + (!rtps->mode_sent_to_mgw) ? " mode not yet sent," : "", + (rtps->use_osmux && !rtps->remote_osmux_cid_sent_to_mgw) ? "Osmux CID not yet sent,": ""); rtp_stream_do_mdcx(rtps); } return; @@ -171,7 +199,9 @@ static void rtp_stream_fsm_establishing_established(struct osmo_fsm_inst *fi, ui case RTP_STREAM_EV_CRCX_FAIL: case RTP_STREAM_EV_MDCX_FAIL: rtps->remote_sent_to_mgw = false; - rtps->codec_sent_to_mgw = false; + rtps->codecs_sent_to_mgw = false; + rtps->mode_sent_to_mgw = false; + rtps->remote_osmux_cid_sent_to_mgw = false; rtp_stream_update_id(rtps); rtp_stream_state_chg(rtps, RTP_STREAM_ST_DISCARDING); return; @@ -184,7 +214,7 @@ static void rtp_stream_fsm_establishing_established(struct osmo_fsm_inst *fi, ui void rtp_stream_fsm_established_onenter(struct osmo_fsm_inst *fi, uint32_t prev_state) { struct rtp_stream *rtps = fi->priv; - osmo_fsm_inst_dispatch(fi->proc.parent, CALL_LEG_EV_RTP_STREAM_ESTABLISHED, rtps); + osmo_fsm_inst_dispatch(fi->proc.parent, rtps->event_estab, rtps); } static int rtp_stream_fsm_timer_cb(struct osmo_fsm_inst *fi) @@ -198,6 +228,7 @@ static void rtp_stream_fsm_cleanup(struct osmo_fsm_inst *fi, enum osmo_fsm_term_ { struct rtp_stream *rtps = fi->priv; if (rtps->ci) { + osmo_mgcpc_ep_cancel_notify(osmo_mgcpc_ep_ci_ep(rtps->ci), fi); osmo_mgcpc_ep_ci_dlcx(rtps->ci); rtps->ci = NULL; } @@ -280,17 +311,36 @@ static int rtp_stream_do_mgcp_verb(struct rtp_stream *rtps, enum mgcp_verb verb, verb_info = (struct mgcp_conn_peer){ .call_id = rtps->call_id, .ptime = 20, + .x_osmo_osmux_use = rtps->use_osmux, + .x_osmo_osmux_cid = rtps->remote_osmux_cid, }; - if (verb == MGCP_VERB_CRCX) - verb_info.conn_mode = rtps->crcx_conn_mode; - - if (rtps->codec_known) { - verb_info.codecs[0] = rtps->codec; - verb_info.codecs_len = 1; - rtps->codec_sent_to_mgw = true; + verb_info.conn_mode = rtps->crcx_conn_mode; + + if (rtps->codecs_known) { + /* Send the list of codecs to the MGW. Ideally we would just feed the SDP directly, but for legacy + * reasons we still need to translate to a struct mgcp_conn_peer representation to send it. */ + struct sdp_audio_codec *codec; + int i = 0; + sdp_audio_codecs_foreach(codec, &rtps->codecs) { + const struct codec_mapping *m = codec_mapping_by_subtype_name(codec->subtype_name); + if (!m) { + LOG_RTPS(rtps, LOGL_ERROR, "Cannot map codec '%s' to MGCP: codec is unknown\n", + codec->subtype_name); + continue; + } + verb_info.codecs[i] = m->mgcp; + verb_info.ptmap[i] = (struct ptmap){ + .codec = m->mgcp, + .pt = codec->payload_type, + }; + i++; + verb_info.codecs_len = i; + verb_info.ptmap_len = i; + } + rtps->codecs_sent_to_mgw = true; } - if (osmo_sockaddr_str_is_set(&rtps->remote)) { + if (osmo_sockaddr_str_is_nonzero(&rtps->remote)) { int rc = osmo_strlcpy(verb_info.addr, rtps->remote.ip, sizeof(verb_info.addr)); if (rc <= 0 || rc >= sizeof(verb_info.addr)) { LOG_RTPS(rtps, LOGL_ERROR, "Failure to write IP address to MGCP message (rc=%d)\n", rc); @@ -299,6 +349,10 @@ static int rtp_stream_do_mgcp_verb(struct rtp_stream *rtps, enum mgcp_verb verb, verb_info.port = rtps->remote.port; rtps->remote_sent_to_mgw = true; } + rtps->mode_sent_to_mgw = true; + if (rtps->use_osmux && rtps->remote_osmux_cid >= 0) + rtps->remote_osmux_cid_sent_to_mgw = true; + rtp_stream_update_id(rtps); osmo_mgcpc_ep_ci_request(rtps->ci, verb, &verb_info, rtps->fi, ok_event, fail_event, NULL); return 0; @@ -332,46 +386,91 @@ void rtp_stream_release(struct rtp_stream *rtps) } /* After setting up a remote RTP address or a new codec, call this to trigger an MDCX. - * The MDCX will only trigger if all data needed by an endpoint is available (both RTP address and codec) and if at + * The MDCX will only trigger if all data needed by an endpoint is available (RTP address, codecs and mode) and if at * least one of them has not yet been sent to the MGW in a previous CRCX or MDCX. */ int rtp_stream_commit(struct rtp_stream *rtps) { - if (!rtps->ci) { - LOG_RTPS(rtps, LOGL_DEBUG, "Not committing: no MGW endpoint CI set up\n"); - return -1; - } - if (!osmo_sockaddr_str_is_set(&rtps->remote)) { + if (!osmo_sockaddr_str_is_nonzero(&rtps->remote)) { LOG_RTPS(rtps, LOGL_DEBUG, "Not committing: no remote RTP address known\n"); return -1; } - if (!rtps->codec_known) { - LOG_RTPS(rtps, LOGL_DEBUG, "Not committing: no codec known\n"); + if (!rtps->codecs_known) { + LOG_RTPS(rtps, LOGL_DEBUG, "Not committing: no codecs known\n"); return -1; } - if (rtps->remote_sent_to_mgw && rtps->codec_sent_to_mgw) { - LOG_RTPS(rtps, LOGL_DEBUG, "Not committing: both remote RTP address and codec already set up at MGW\n"); + if (rtps->remote_sent_to_mgw && rtps->codecs_sent_to_mgw && rtps->mode_sent_to_mgw) { + LOG_RTPS(rtps, LOGL_DEBUG, + "Not committing: remote RTP address, codecs and mode are already set up at MGW\n"); return 0; } + if (!rtps->ci) { + LOG_RTPS(rtps, LOGL_DEBUG, "Not committing: no MGW endpoint CI set up\n"); + return -1; + } - LOG_RTPS(rtps, LOGL_DEBUG, "Committing: Tx MDCX to update the MGW: updating%s%s\n", + LOG_RTPS(rtps, LOGL_DEBUG, "Committing: Tx MDCX to update the MGW: updating%s%s%s%s\n", rtps->remote_sent_to_mgw ? "" : " remote-RTP-IP-port", - rtps->codec_sent_to_mgw ? "" : " codec"); + rtps->codecs_sent_to_mgw ? "" : " codecs", + rtps->mode_sent_to_mgw ? "" : " mode", + (!rtps->use_osmux || rtps->remote_osmux_cid_sent_to_mgw) ? "" : " remote-Osmux-CID"); return rtp_stream_do_mdcx(rtps); } -void rtp_stream_set_codec(struct rtp_stream *rtps, enum mgcp_codecs codec) +void rtp_stream_set_codecs(struct rtp_stream *rtps, const struct sdp_audio_codecs *codecs) +{ + if (!codecs || !codecs->count) + return; + if (sdp_audio_codecs_cmp(&rtps->codecs, codecs, false, true) == 0) { + LOG_RTPS(rtps, LOGL_DEBUG, "no change: codecs already set to %s\n", + sdp_audio_codecs_to_str(&rtps->codecs)); + return; + } + if (rtps->fi->state == RTP_STREAM_ST_ESTABLISHED) + rtp_stream_state_chg(rtps, RTP_STREAM_ST_ESTABLISHING); + LOG_RTPS(rtps, LOGL_DEBUG, "setting codecs to %s\n", sdp_audio_codecs_to_str(codecs)); + rtps->codecs = *codecs; + rtps->codecs_known = true; + rtps->codecs_sent_to_mgw = false; + rtp_stream_update_id(rtps); +} + +void rtp_stream_set_mode(struct rtp_stream *rtps, enum mgcp_connection_mode mode) { + if (rtps->crcx_conn_mode == mode) + return; if (rtps->fi->state == RTP_STREAM_ST_ESTABLISHED) rtp_stream_state_chg(rtps, RTP_STREAM_ST_ESTABLISHING); - LOG_RTPS(rtps, LOGL_DEBUG, "setting codec to %s\n", osmo_mgcpc_codec_name(codec)); - rtps->codec = codec; - rtps->codec_known = true; - rtps->codec_sent_to_mgw = false; + LOG_RTPS(rtps, LOGL_DEBUG, "setting mode to %s\n", mgcp_client_cmode_name(mode)); + rtps->mode_sent_to_mgw = false; + rtps->crcx_conn_mode = mode; rtp_stream_update_id(rtps); } +/* Convenience shortcut to call rtp_stream_set_codecs() with a list of only one sdp_audio_codec record. */ +void rtp_stream_set_one_codec(struct rtp_stream *rtps, const struct sdp_audio_codec *codec) +{ + struct sdp_audio_codecs codecs = {}; + sdp_audio_codecs_add_copy(&codecs, codec); + rtp_stream_set_codecs(rtps, &codecs); +} + +/* For legacy, rather use rtp_stream_set_codecs() with a full codecs list. */ +bool rtp_stream_set_codecs_from_mgcp_codec(struct rtp_stream *rtps, enum mgcp_codecs codec) +{ + struct sdp_audio_codecs codecs = {}; + if (!sdp_audio_codecs_add_mgcp_codec(&codecs, codec)) + return false; + rtp_stream_set_codecs(rtps, &codecs); + return true; +} + void rtp_stream_set_remote_addr(struct rtp_stream *rtps, const struct osmo_sockaddr_str *r) { + if (osmo_sockaddr_str_cmp(&rtps->remote, r) == 0) { + LOG_RTPS(rtps, LOGL_DEBUG, "remote addr already " OSMO_SOCKADDR_STR_FMT ", no change\n", + OSMO_SOCKADDR_STR_FMT_ARGS(r)); + return; + } if (rtps->fi->state == RTP_STREAM_ST_ESTABLISHED) rtp_stream_state_chg(rtps, RTP_STREAM_ST_ESTABLISHING); LOG_RTPS(rtps, LOGL_DEBUG, "setting remote addr to " OSMO_SOCKADDR_STR_FMT "\n", OSMO_SOCKADDR_STR_FMT_ARGS(r)); @@ -380,6 +479,23 @@ void rtp_stream_set_remote_addr(struct rtp_stream *rtps, const struct osmo_socka rtp_stream_update_id(rtps); } +void rtp_stream_set_remote_addr_and_codecs(struct rtp_stream *rtps, const struct sdp_msg *sdp) +{ + rtp_stream_set_codecs(rtps, &sdp->audio_codecs); + if (osmo_sockaddr_str_is_nonzero(&sdp->rtp)) + rtp_stream_set_remote_addr(rtps, &sdp->rtp); +} + +void rtp_stream_set_remote_osmux_cid(struct rtp_stream *rtps, uint8_t osmux_cid) +{ + if (rtps->fi->state == RTP_STREAM_ST_ESTABLISHED) + rtp_stream_state_chg(rtps, RTP_STREAM_ST_ESTABLISHING); + LOG_RTPS(rtps, LOGL_DEBUG, "setting remote Osmux CID to %u\n", osmux_cid); + rtps->remote_osmux_cid = osmux_cid; + rtps->remote_osmux_cid_sent_to_mgw = false; + rtp_stream_update_id(rtps); +} + bool rtp_stream_is_established(struct rtp_stream *rtps) { if (!rtps) @@ -389,7 +505,9 @@ bool rtp_stream_is_established(struct rtp_stream *rtps) if (rtps->fi->state != RTP_STREAM_ST_ESTABLISHED) return false; if (!rtps->remote_sent_to_mgw - || !rtps->codec_sent_to_mgw) + || !rtps->codecs_sent_to_mgw + || !rtps->mode_sent_to_mgw + || (rtps->use_osmux && !rtps->remote_osmux_cid_sent_to_mgw)) return false; return true; } diff --git a/src/libmsc/sccp_ran.c b/src/libmsc/sccp_ran.c index 99317b500..9907f200d 100644 --- a/src/libmsc/sccp_ran.c +++ b/src/libmsc/sccp_ran.c @@ -1,5 +1,5 @@ /* - * (C) 2019 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de> + * (C) 2019 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de> * All Rights Reserved * * SPDX-License-Identifier: AGPL-3.0+ diff --git a/src/libmsc/sdp_msg.c b/src/libmsc/sdp_msg.c new file mode 100644 index 000000000..9b4cd988c --- /dev/null +++ b/src/libmsc/sdp_msg.c @@ -0,0 +1,686 @@ +/* Minimalistic SDP parse/compose implementation, focused on GSM audio codecs */ +/* + * (C) 2019 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de> + * All Rights Reserved + * + * SPDX-License-Identifier: AGPL-3.0+ + * + * 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/core/logging.h> + +#include <osmocom/msc/debug.h> +#include <osmocom/msc/sdp_msg.h> + +bool sdp_audio_codec_is_set(const struct sdp_audio_codec *a) +{ + return a && a->subtype_name[0]; +} + +/* Compare name, rate and fmtp, returning typical cmp result: 0 on match, and -1 / 1 on mismatch. + * If cmp_fmtp is false, do *not* compare the fmtp string; if true, compare fmtp 1:1 as strings. + * If cmp_payload_type is false, do *not* compare the payload_type number. + * The fmtp is only string-compared -- e.g. if AMR parameters appear in a different order, it amounts to a mismatch even + * though all parameters are the same. */ +int sdp_audio_codec_cmp(const struct sdp_audio_codec *a, const struct sdp_audio_codec *b, + bool cmp_fmtp, bool cmp_payload_type) +{ + int cmp; + if (a == b) + return 0; + if (!a) + return -1; + if (!b) + return 1; + cmp = strncmp(a->subtype_name, b->subtype_name, sizeof(a->subtype_name)); + if (cmp) + return cmp; + cmp = OSMO_CMP(a->rate, b->rate); + if (cmp) + return cmp; + if (cmp_fmtp) { + cmp = strncmp(a->fmtp, b->fmtp, sizeof(a->fmtp)); + if (cmp) + return cmp; + } + if (cmp_payload_type) { + cmp = OSMO_CMP(a->payload_type, b->payload_type); + if (cmp) + return cmp; + } + return 0; +} + +/* Compare two lists of audio codecs, returning typical cmp result: 0 on match, and -1 / 1 on mismatch. + * The ordering in the two lists may differ, except that the first codec in 'a' must also be the first codec in 'b'. + * This is because the first codec typically expresses the preferred codec to use. + * If cmp_fmtp is false, do *not* compare the fmtp strings; if true, compare fmtp 1:1 as strings. + * If cmp_payload_type is false, do *not* compare the payload_type numbers. + * The fmtp is only string-compared -- e.g. if AMR parameters appear in a different order, it amounts to a mismatch even + * though all parameters are the same. */ +int sdp_audio_codecs_cmp(const struct sdp_audio_codecs *a, const struct sdp_audio_codecs *b, + bool cmp_fmtp, bool cmp_payload_type) +{ + const struct sdp_audio_codec *codec_a; + const struct sdp_audio_codec *codec_b; + int cmp; + if (a == b) + return 0; + if (!a) + return -1; + if (!b) + return 1; + + cmp = OSMO_CMP(a->count, b->count); + if (cmp) + return cmp; + + if (!a->count) + return 0; + + /* The first codec is the "chosen" codec and should match. The others may appear in different order. */ + cmp = sdp_audio_codec_cmp(&a->codec[0], &b->codec[0], cmp_fmtp, cmp_payload_type); + if (cmp) + return cmp; + + /* See if each codec in a is also present in b */ + sdp_audio_codecs_foreach(codec_a, a) { + bool match_found = false; + sdp_audio_codecs_foreach(codec_b, b) { + if (!sdp_audio_codec_cmp(codec_a, codec_b, cmp_fmtp, cmp_payload_type)) { + match_found = true; + break; + } + } + if (!match_found) + return -1; + } + + return 0; +} + +/* Given a predefined fixed payload_type number, add an SDP audio codec entry, if not present yet. + * The payload_type must exist in sdp_msg_payload_type_names. + * Return the audio codec created or already existing for this payload type number. + */ +struct sdp_audio_codec *sdp_audio_codecs_add(struct sdp_audio_codecs *ac, unsigned int payload_type, + const char *subtype_name, unsigned int rate, const char *fmtp) +{ + struct sdp_audio_codec *codec; + + /* Does an entry already exist? */ + codec = sdp_audio_codecs_by_payload_type(ac, payload_type, false); + if (codec) { + /* Already exists, sanity check */ + if (!codec->subtype_name[0]) + OSMO_STRLCPY_ARRAY(codec->subtype_name, subtype_name); + else if (strcmp(codec->subtype_name, subtype_name)) { + /* There already is an entry with this payload_type number but a mismatching subtype_name. That is + * weird, rather abort. */ + return NULL; + } + if (codec->rate != rate + || (fmtp && strcmp(fmtp, codec->fmtp))) { + /* Mismatching details. Rather abort */ + return NULL; + } + return codec; + } + + /* None exists, create codec entry for this payload type number */ + codec = sdp_audio_codecs_by_payload_type(ac, payload_type, true); + /* NULL means unable to add an entry */ + if (!codec) + return NULL; + + OSMO_STRLCPY_ARRAY(codec->subtype_name, subtype_name); + if (fmtp) + OSMO_STRLCPY_ARRAY(codec->fmtp, fmtp); + codec->rate = rate; + return codec; +} + +struct sdp_audio_codec *sdp_audio_codecs_add_copy(struct sdp_audio_codecs *ac, const struct sdp_audio_codec *codec) +{ + return sdp_audio_codecs_add(ac, codec->payload_type, codec->subtype_name, codec->rate, + codec->fmtp[0] ? codec->fmtp : NULL); +} + +/* Find or create an entry for the given payload_type number in the given list of codecs. + * If the given payload_type number is already present in ac, return the first matching entry. + * If no such payload_type number is present: a) return NULL if create == false; + * b) If create == true, add a mostly empty codec entry to the end of ac with the given payload_type number, and return + * the created entry. + * If create == true, a NULL return value means that there was no unused entry left in ac to add this payload_type. + */ +struct sdp_audio_codec *sdp_audio_codecs_by_payload_type(struct sdp_audio_codecs *ac, unsigned int payload_type, + bool create) +{ + struct sdp_audio_codec *codec; + sdp_audio_codecs_foreach(codec, ac) { + if (codec->payload_type == payload_type) + return codec; + } + if (!create) + return NULL; + + if (ac->count >= ARRAY_SIZE(ac->codec)) + return NULL; + + codec = &ac->codec[ac->count]; + *codec = (struct sdp_audio_codec){ + .payload_type = payload_type, + .rate = 8000, + }; + ac->count++; + return codec; +} + +/* Return a given sdp_msg's codec entry that matches the subtype_name and rate of the given codec, or NULL if no + * match is found. Comparison is made by sdp_audio_codec_cmp(cmp_payload_type=false). */ +struct sdp_audio_codec *sdp_audio_codecs_by_descr(struct sdp_audio_codecs *ac, const struct sdp_audio_codec *codec) +{ + struct sdp_audio_codec *i; + sdp_audio_codecs_foreach(i, ac) { + if (!sdp_audio_codec_cmp(i, codec, false, false)) + return i; + } + return NULL; +} + +/* Remove the codec entry pointed at by 'codec'. 'codec' must point at an entry of 'ac'. + * To use any external codec instance, use sdp_audio_codecs_remove(ac, sdp_audio_codecs_by_descr(ac, codec)). + * Return 0 on success, -ENOENT if codec does not point at the sdp->codec array. */ +int sdp_audio_codecs_remove(struct sdp_audio_codecs *ac, const struct sdp_audio_codec *codec) +{ + struct sdp_audio_codec *i; + if ((codec < ac->codec) + || ((codec - ac->codec) >= OSMO_MIN(ac->count, ARRAY_SIZE(ac->codec)))) + return -ENOENT; + + /* Move all following entries one up */ + ac->count--; + sdp_audio_codecs_foreach(i, ac) { + if (i < codec) + continue; + *i = *(i+1); + } + return 0; +} + +static const char * const sdp_mode_str[] = { + [SDP_MODE_UNSET] = "-", + [SDP_MODE_SENDONLY] = "sendonly", + [SDP_MODE_RECVONLY] = "recvonly", + [SDP_MODE_SENDRECV] = "sendrecv", + [SDP_MODE_INACTIVE] = "inactive", +}; + +/* Convert struct sdp_msg to the actual SDP protocol representation */ +int sdp_msg_to_sdp_str_buf(char *dst, size_t dst_size, const struct sdp_msg *sdp) +{ + const struct sdp_audio_codec *codec; + struct osmo_strbuf sb = { .buf = dst, .len = dst_size }; + const char *ip; + char ipv; + + if (!sdp) { + OSMO_STRBUF_PRINTF(sb, "%s", ""); + return sb.chars_needed; + } + + ip = sdp->rtp.ip[0] ? sdp->rtp.ip : "0.0.0.0"; + ipv = (osmo_ip_str_type(ip) == AF_INET6) ? '6' : '4'; + + OSMO_STRBUF_PRINTF(sb, + "v=0\r\n" + "o=OsmoMSC 0 0 IN IP%c %s\r\n" + "s=GSM Call\r\n" + "c=IN IP%c %s\r\n" + "t=0 0\r\n" + "m=audio %d RTP/AVP", + ipv, ip, ipv, ip, + sdp->rtp.port); + + /* Append all payload type numbers to 'm=audio <port> RTP/AVP 3 4 112' line */ + sdp_audio_codecs_foreach(codec, &sdp->audio_codecs) + OSMO_STRBUF_PRINTF(sb, " %d", codec->payload_type); + OSMO_STRBUF_PRINTF(sb, "\r\n"); + + /* Add details for all codecs */ + sdp_audio_codecs_foreach(codec, &sdp->audio_codecs) { + if (!sdp_audio_codec_is_set(codec)) + continue; + OSMO_STRBUF_PRINTF(sb, "a=rtpmap:%d %s/%d\r\n", codec->payload_type, codec->subtype_name, + codec->rate > 0 ? codec->rate : 8000); + if (codec->fmtp[0]) + OSMO_STRBUF_PRINTF(sb, "a=fmtp:%d %s\r\n", codec->payload_type, codec->fmtp); + } + + OSMO_STRBUF_PRINTF(sb, "a=ptime:%d\r\n", sdp->ptime > 0? sdp->ptime : 20); + + if (sdp->mode != SDP_MODE_UNSET && sdp->mode < ARRAY_SIZE(sdp_mode_str)) + OSMO_STRBUF_PRINTF(sb, "a=%s\r\n", sdp_mode_str[sdp->mode]); + + return sb.chars_needed; +} + +/* Return the first line ending (or the end of the string) at or after the given string position. */ +const char *sdp_msg_line_end(const char *src) +{ + const char *line_end = strchr(src, '\r'); + if (!line_end) + line_end = strchr(src, '\n'); + if (!line_end) + line_end = src + strlen(src); + return line_end; +} + +/* parse a line like 'a=rtpmap:0 PCMU/8000', 'a=fmtp:112 octet-align=1; mode-set=4', 'a=ptime:20'. + * The src should point at the character after 'a=', e.g. at the start of 'rtpmap', 'fmtp', 'ptime' + */ +int sdp_parse_attrib(struct sdp_msg *sdp, const char *src) +{ + unsigned int payload_type; + struct sdp_audio_codec *codec; +#define A_RTPMAP "rtpmap:" +#define A_FMTP "fmtp:" +#define A_PTIME "ptime:" +#define A_RTCP "rtcp:" + + if (osmo_str_startswith(src, A_RTPMAP)) { + /* "a=rtpmap:3 GSM/8000" */ + char *audio_name; + unsigned int channels = 1; + if (sscanf(src, A_RTPMAP "%u", &payload_type) != 1) + return -EINVAL; + + audio_name = strchr(src, ' '); + if (!audio_name || audio_name >= sdp_msg_line_end(src)) + return -EINVAL; + + codec = sdp_audio_codecs_by_payload_type(&sdp->audio_codecs, payload_type, true); + if (!codec) + return -ENOSPC; + + if (sscanf(audio_name, " %31[^/]/%u/%u", codec->subtype_name, &codec->rate, &channels) < 1) + return -EINVAL; + + if (channels != 1) + return -ENOTSUP; + } + + else if (osmo_str_startswith(src, A_FMTP)) { + /* "a=fmtp:112 octet-align=1;mode-set=0,1,2,3" */ + char *fmtp_str; + const char *line_end = sdp_msg_line_end(src); + if (sscanf(src, A_FMTP "%u", &payload_type) != 1) + return -EINVAL; + + fmtp_str = strchr(src, ' '); + if (!fmtp_str) + return -EINVAL; + fmtp_str++; + if (fmtp_str >= line_end) + return -EINVAL; + + codec = sdp_audio_codecs_by_payload_type(&sdp->audio_codecs, payload_type, true); + if (!codec) + return -ENOSPC; + + /* (+1 because osmo_strlcpy() interprets it as size including the '\0') */ + osmo_strlcpy(codec->fmtp, fmtp_str, line_end - fmtp_str + 1); + } + + else if (osmo_str_startswith(src, A_PTIME)) { + /* "a=ptime:20" */ + if (sscanf(src, A_PTIME "%u", &sdp->ptime) != 1) + return -EINVAL; + + } + + else if (osmo_str_startswith(src, A_RTCP)) { + /* TODO? */ + } + + else if (osmo_str_startswith(src, sdp_mode_str[SDP_MODE_SENDRECV])) { + /* "a=sendrecv" */ + sdp->mode = SDP_MODE_SENDRECV; + } + + else if (osmo_str_startswith(src, sdp_mode_str[SDP_MODE_SENDONLY])) { + /* "a=sendonly" */ + sdp->mode = SDP_MODE_SENDONLY; + } + + else if (osmo_str_startswith(src, sdp_mode_str[SDP_MODE_RECVONLY])) { + /* "a=recvonly" */ + sdp->mode = SDP_MODE_RECVONLY; + } + + else if (osmo_str_startswith(src, sdp_mode_str[SDP_MODE_INACTIVE])) { + /* "a=inactive" */ + sdp->mode = SDP_MODE_INACTIVE; + } + + return 0; +} + +const struct value_string sdp_msg_payload_type_names[] = { + { 0, "PCMU" }, + { 3, "GSM" }, + { 8, "PCMA" }, + { 18, "G729" }, + { 110, "GSM-EFR" }, + { 111, "GSM-HR-08" }, + { 112, "AMR" }, + { 113, "AMR-WB" }, + {} +}; + +/* Return payload type number matching given string ("AMR", "GSM", ...) or negative if not found. */ +int sdp_subtype_name_to_payload_type(const char *subtype_name) +{ + return get_string_value(sdp_msg_payload_type_names, subtype_name); +} + +/* Parse a line like 'm=audio 16398 RTP/AVP 0 3 8 96 112', starting after the '=' */ +static int sdp_parse_media_description(struct sdp_msg *sdp, const char *src) +{ + unsigned int port; + int i; + const char *payload_type_str; + const char *line_end = sdp_msg_line_end(src); + if (sscanf(src, "audio %u RTP/AVP", &port) < 1) + return -ENOTSUP; + + if (port > 0xffff) + return -EINVAL; + + sdp->rtp.port = port; + + /* skip "audio 12345 RTP/AVP ", i.e. 3 spaces on */ + payload_type_str = src; + for (i = 0; i < 3; i++) { + payload_type_str = strchr(payload_type_str, ' '); + if (!payload_type_str) + return -EINVAL; + while (*payload_type_str == ' ') + payload_type_str++; + if (payload_type_str >= line_end) + return -EINVAL; + } + + /* Parse listing of payload type numbers after "RTP/AVP" */ + while (payload_type_str < line_end) { + unsigned int payload_type; + struct sdp_audio_codec *codec; + const char *subtype_name; + if (sscanf(payload_type_str, "%u", &payload_type) < 1) + return -EINVAL; + + codec = sdp_audio_codecs_by_payload_type(&sdp->audio_codecs, payload_type, true); + if (!codec) + return -ENOSPC; + + /* Fill in subtype name for fixed payload types */ + subtype_name = get_value_string_or_null(sdp_msg_payload_type_names, codec->payload_type); + if (subtype_name) + OSMO_STRLCPY_ARRAY(codec->subtype_name, subtype_name); + + payload_type_str = strchr(payload_type_str, ' '); + if (!payload_type_str) + payload_type_str = line_end; + while (*payload_type_str == ' ') + payload_type_str++; + } + + return 0; +} + +/* parse a line like 'c=IN IP4 192.168.11.151' starting after the '=' */ +static int sdp_parse_connection_info(struct sdp_msg *sdp, const char *src) +{ + char ipv[10]; + char addr_str[INET6_ADDRSTRLEN]; + if (sscanf(src, "IN %s %s", ipv, addr_str) < 2) + return -EINVAL; + + /* supporting only IPv4 */ + if (strcmp(ipv, "IP4")) + return -ENOTSUP; + + osmo_sockaddr_str_from_str(&sdp->rtp, addr_str, sdp->rtp.port); + return 0; +} + +/* Parse SDP string into struct sdp_msg. Return 0 on success, negative on error. */ +int sdp_msg_from_sdp_str(struct sdp_msg *sdp, const char *src) +{ + const char *pos; + *sdp = (struct sdp_msg){}; + + for (pos = src; pos && *pos; pos++) { + char attrib; + int rc = 0; + + if (*pos == '\r' || *pos == '\n') + continue; + + /* Expecting only lines starting with 'X='. Not being too strict about it is probably alright. */ + if (pos[1] != '=') + goto next_line; + + attrib = *pos; + pos += 2; + switch (attrib) { + /* a=... */ + case 'a': + rc = sdp_parse_attrib(sdp, pos); + break; + case 'm': + rc = sdp_parse_media_description(sdp, pos); + break; + case 'c': + rc = sdp_parse_connection_info(sdp, pos); + break; + default: + /* ignore any other parameters */ + break; + } + + if (rc) { + size_t line_len; + const char *line_end = sdp_msg_line_end(pos); + pos -= 2; + line_len = line_end - pos; + switch (rc) { + case -EINVAL: + LOGP(DMNCC, LOGL_ERROR, + "Failed to parse SDP: invalid line: %s\n", osmo_quote_str(pos, line_len)); + break; + case -ENOSPC: + LOGP(DMNCC, LOGL_ERROR, + "Failed to parse SDP: no more space for: %s\n", osmo_quote_str(pos, line_len)); + break; + case -ENOTSUP: + LOGP(DMNCC, LOGL_ERROR, + "Failed to parse SDP: not supported: %s\n", osmo_quote_str(pos, line_len)); + break; + default: + LOGP(DMNCC, LOGL_ERROR, + "Failed to parse SDP: %s\n", osmo_quote_str(pos, line_len)); + break; + } + return rc; + } +next_line: + pos = strstr(pos, "\r\n"); + if (!pos) + break; + } + + return 0; +} + +/* Leave only those codecs in 'ac_dest' that are also present in 'ac_other'. + * The matching is made by sdp_audio_codec_cmp(cmp_payload_type=false), i.e. payload_type numbers are not compared and + * fmtp parameters are compared 1:1 as plain strings. + * If translate_payload_type_numbers has an effect if ac_dest and ac_other have mismatching payload_type numbers for the + * same SDP codec descriptions. If translate_payload_type_numbers is true, take the payload_type numbers from ac_other. + * If false, keep payload_type numbers in ac_dest unchanged. */ +void sdp_audio_codecs_intersection(struct sdp_audio_codecs *ac_dest, const struct sdp_audio_codecs *ac_other, + bool translate_payload_type_numbers) +{ + int i; + for (i = 0; i < ac_dest->count; i++) { + struct sdp_audio_codec *codec = &ac_dest->codec[i]; + struct sdp_audio_codec *other; + OSMO_ASSERT(i < ARRAY_SIZE(ac_dest->codec)); + + other = sdp_audio_codecs_by_descr((struct sdp_audio_codecs *)ac_other, codec); + + if (!other) { + OSMO_ASSERT(sdp_audio_codecs_remove(ac_dest, codec) == 0); + i--; + continue; + } + + /* Doing payload_type number translation of part of the intersection because it makes the algorithm + * simpler: we already know ac_dest is a subset of ac_other, and there is no need to resolve payload + * type number conflicts. */ + if (translate_payload_type_numbers) + codec->payload_type = other->payload_type; + } +} + +/* Make sure the given codec is listed as the first codec. 'codec' must be an actual codec entry of the given audio + * codecs list. */ +void sdp_audio_codecs_select(struct sdp_audio_codecs *ac, struct sdp_audio_codec *codec) +{ + struct sdp_audio_codec tmp; + struct sdp_audio_codec *pos; + OSMO_ASSERT((codec >= ac->codec) + && ((codec - ac->codec) < OSMO_MIN(ac->count, ARRAY_SIZE(ac->codec)))); + + /* Already the first? */ + if (codec == ac->codec) + return; + + tmp = *codec; + for (pos = codec - 1; pos >= ac->codec; pos--) + pos[1] = pos[0]; + + ac->codec[0] = tmp; + return; +} + +/* Short single-line representation of an SDP audio codec, convenient for logging. + * Like "AMR/8000:octet-align=1#122" */ +int sdp_audio_codec_to_str_buf(char *buf, size_t buflen, const struct sdp_audio_codec *codec) +{ + struct osmo_strbuf sb = { .buf = buf, .len = buflen }; + OSMO_STRBUF_PRINTF(sb, "%s", codec->subtype_name); + if (codec->rate != 8000) + OSMO_STRBUF_PRINTF(sb, "/%u", codec->rate); + if (codec->fmtp[0]) + OSMO_STRBUF_PRINTF(sb, ":%s", codec->fmtp); + OSMO_STRBUF_PRINTF(sb, "#%d", codec->payload_type); + return sb.chars_needed; +} + +char *sdp_audio_codec_to_str_c(void *ctx, const struct sdp_audio_codec *codec) +{ + OSMO_NAME_C_IMPL(ctx, 32, "sdp_audio_codec_to_str_c-ERROR", sdp_audio_codec_to_str_buf, codec) +} + +const char *sdp_audio_codec_to_str(const struct sdp_audio_codec *codec) +{ + return sdp_audio_codec_to_str_c(OTC_SELECT, codec); +} + +/* Short single-line representation of a list of SDP audio codecs, convenient for logging */ +int sdp_audio_codecs_to_str_buf(char *buf, size_t buflen, const struct sdp_audio_codecs *ac) +{ + struct osmo_strbuf sb = { .buf = buf, .len = buflen }; + const struct sdp_audio_codec *codec; + if (!ac->count) + OSMO_STRBUF_PRINTF(sb, "(no-codecs)"); + sdp_audio_codecs_foreach(codec, ac) { + bool first = (codec == ac->codec); + if (!first) + OSMO_STRBUF_PRINTF(sb, ","); + OSMO_STRBUF_APPEND(sb, sdp_audio_codec_to_str_buf, codec); + } + return sb.chars_needed; +} + +char *sdp_audio_codecs_to_str_c(void *ctx, const struct sdp_audio_codecs *ac) +{ + OSMO_NAME_C_IMPL(ctx, 128, "sdp_audio_codecs_to_str_c-ERROR", sdp_audio_codecs_to_str_buf, ac) +} + +const char *sdp_audio_codecs_to_str(const struct sdp_audio_codecs *ac) +{ + return sdp_audio_codecs_to_str_c(OTC_SELECT, ac); +} + +/* Short single-line representation of an SDP message, convenient for logging */ +int sdp_msg_to_str_buf(char *buf, size_t buflen, const struct sdp_msg *sdp) +{ + struct osmo_strbuf sb = { .buf = buf, .len = buflen }; + if (!sdp) { + OSMO_STRBUF_PRINTF(sb, "NULL"); + return sb.chars_needed; + } + + OSMO_STRBUF_PRINTF(sb, OSMO_SOCKADDR_STR_FMT, OSMO_SOCKADDR_STR_FMT_ARGS(&sdp->rtp)); + OSMO_STRBUF_PRINTF(sb, "{"); + OSMO_STRBUF_APPEND(sb, sdp_audio_codecs_to_str_buf, &sdp->audio_codecs); + if (sdp->bearer_services.count) { + OSMO_STRBUF_PRINTF(sb, ","); + OSMO_STRBUF_APPEND(sb, csd_bs_list_to_str_buf, &sdp->bearer_services); + } + OSMO_STRBUF_PRINTF(sb, "}"); + return sb.chars_needed; +} + +char *sdp_msg_to_str_c(void *ctx, const struct sdp_msg *sdp) +{ + OSMO_NAME_C_IMPL(ctx, 128, "sdp_msg_to_str_c-ERROR", sdp_msg_to_str_buf, sdp) +} + +const char *sdp_msg_to_str(const struct sdp_msg *sdp) +{ + return sdp_msg_to_str_c(OTC_SELECT, sdp); +} + +void sdp_audio_codecs_set_csd(struct sdp_audio_codecs *ac) +{ + *ac = (struct sdp_audio_codecs){ + .count = 1, + .codec = {{ + .payload_type = 120, + .subtype_name = "CLEARMODE", + .rate = 8000, + }}, + }; +} diff --git a/src/libmsc/sgs_iface.c b/src/libmsc/sgs_iface.c index d83a730ef..a845ab84b 100644 --- a/src/libmsc/sgs_iface.c +++ b/src/libmsc/sgs_iface.c @@ -124,7 +124,7 @@ static void subscr_conn_toss(struct vlr_subscr *vsub) LOG_MSUB(msub, LOGL_ERROR, "Force releasing previous subscriber connection: an SGs connection for this" " subscriber is being initiated\n"); - msc_a_release_mo(msub_msc_a(msub), GSM48_REJECT_CONGESTION); + msc_a_release_mo(msub_msc_a(msub), GSM_CAUSE_AUTH_FAILED); /* TODO: is this strong enough? After this, it should be completely disassociated with this subscriber. */ } @@ -336,7 +336,7 @@ const char *subscr_info(const char *imsi) } /* Comfortable status message generator that also generates some basic - * context-dependent dependand log output */ + * context-dependent log output */ static int sgs_tx_status(struct sgs_connection *sgc, const char *imsi, enum sgsap_sgs_cause cause, struct msgb *msg, int sgsap_iei) { @@ -352,7 +352,7 @@ static int sgs_tx_status(struct sgs_connection *sgc, const char *imsi, enum sgsa LOGSGC_VSUB(sgc, subscr_info(imsi), LOGL_ERROR, "Rx %s with invalid mandatory %s IEI!\n", sgsap_msg_type_name(msg->data[0]), sgsap_iei_name(sgsap_iei)); } else if (cause == SGSAP_SGS_CAUSE_COND_IE_ERROR) { - LOGSGC_VSUB(sgc, subscr_info(imsi), LOGL_ERROR, "Rx %s with errornous conditional %s IEI!\n", + LOGSGC_VSUB(sgc, subscr_info(imsi), LOGL_ERROR, "Rx %s with erroneous conditional %s IEI!\n", sgsap_msg_type_name(msg->data[0]), sgsap_iei_name(sgsap_iei)); } else { LOGSGC_VSUB(sgc, subscr_info(imsi), LOGL_ERROR, "Rx %s failed with cause %s at %s IEI!\n", @@ -364,7 +364,7 @@ static int sgs_tx_status(struct sgs_connection *sgc, const char *imsi, enum sgsa return 0; } -/* Called by VLR via callback, transmits the the location update response or +/* Called by VLR via callback, transmits the location update response or * reject, depending on the outcome of the location update. */ static void sgs_tx_loc_upd_resp_cb(struct sgs_lu_response *response) { @@ -372,24 +372,45 @@ static void sgs_tx_loc_upd_resp_cb(struct sgs_lu_response *response) struct vlr_subscr *vsub = response->vsub; struct sgs_mme_ctx *mme; uint8_t new_id[2 + GSM48_TMSI_LEN]; - uint8_t *new_id_ptr = new_id; - unsigned int new_id_len = 0; + uint8_t *new_id_ptr = NULL; + int new_id_len = 0; uint8_t resp_msg_type; + /* Determine message type that is sent next (needed for logging) */ if (response->accepted) resp_msg_type = SGSAP_MSGT_LOC_UPD_ACK; + else if (response->error) + resp_msg_type = SGSAP_MSGT_RESET_IND; else resp_msg_type = SGSAP_MSGT_LOC_UPD_REJ; + /* Determine MME */ mme = sgs_mme_ctx_by_vsub(vsub, resp_msg_type); if (!mme) return; + /* Handle error (HLR failure) */ + if (response->error) { + osmo_fsm_inst_dispatch(mme->fi, SGS_VLRR_E_START_RESET, NULL); + return; + } + + /* Handle LU accept/reject */ if (response->accepted) { if (vsub->tmsi_new != GSM_RESERVED_TMSI) { - new_id_len = gsm48_generate_mid_from_tmsi(new_id, vsub->tmsi_new); - new_id_ptr = new_id + 2; - new_id_len -= 2; + struct osmo_mobile_identity tmsi_mi = { + .type = GSM_MI_TYPE_TMSI, + .tmsi = vsub->tmsi_new, + }; + new_id_len = osmo_mobile_identity_encode_buf(new_id, sizeof(new_id), &tmsi_mi, false); + if (new_id_len > 0) { + new_id_ptr = new_id; + } else { + /* Failure to encode the TMSI is not actually possible here, this is just for paranoia + * and coverity scan. */ + new_id_len = 0; + LOGPFSMSL(vsub->sgs_fsm, DMM, LOGL_ERROR, "Cannot encode TMSI Mobile Identity\n"); + } } resp = gsm29118_create_lu_ack(vsub->imsi, &vsub->sgs.lai, new_id_ptr, new_id_len); sgs_tx(mme->conn, resp); @@ -455,9 +476,6 @@ int sgs_iface_tx_paging(struct vlr_subscr *vsub, enum sgsap_service_ind serv_ind struct gsm29118_paging_req paging_params; struct sgs_mme_ctx *mme; - LOGP(DMSC, LOGL_NOTICE, "XXXXXXXXXX state == %d conf_by_radio_contact_ind == %d\n", - vsub->sgs_fsm->state, vsub->conf_by_radio_contact_ind); - /* See also: 3GPP TS 29.118, chapter 5.1.2.2 Paging Initiation */ if (vsub->sgs_fsm->state == SGS_UE_ST_NULL && vsub->conf_by_radio_contact_ind == true) { LOGPFSMSL(vsub->sgs_fsm, DPAG, LOGL_ERROR, "Will not Page (conf_by_radio_contact_ind == true)\n"); @@ -475,6 +493,9 @@ int sgs_iface_tx_paging(struct vlr_subscr *vsub, enum sgsap_service_ind serv_ind if (vlr_sgs_pag_pend(vsub)) return 0; + LOGMME(mme, LOGL_INFO, "Paging on SGs: %s for %s (conf_by_radio_contact_ind=%d)\n", + vlr_subscr_name(vsub), sgsap_service_ind_name(serv_ind), vsub->conf_by_radio_contact_ind); + memset(&paging_params, 0, sizeof(paging_params)); osmo_strlcpy(paging_params.imsi, vsub->imsi, sizeof(paging_params.imsi)); osmo_strlcpy(paging_params.vlr_name, mme->sgs->cfg.vlr_name, sizeof(paging_params.vlr_name)); @@ -587,12 +608,14 @@ static int sgs_rx_loc_upd_req(struct sgs_connection *sgc, struct msgb *msg, cons char *mme_name; struct vlr_sgs_cfg vlr_sgs_cfg; struct vlr_subscr *vsub; + struct osmo_plmn_id last_eutran_plmn_buf, *last_eutran_plmn = NULL; /* Check for lingering connections */ vsub = vlr_subscr_find_by_imsi(gsm_network->vlr, imsi, __func__); if (vsub) { subscr_conn_toss(vsub); vlr_subscr_put(vsub, __func__); + vsub = NULL; } /* Determine MME-Name */ @@ -618,11 +641,29 @@ static int sgs_rx_loc_upd_req(struct sgs_connection *sgc, struct msgb *msg, cons return sgs_tx_status(sgc, imsi, SGSAP_SGS_CAUSE_MISSING_MAND_IE, msg, SGSAP_IE_LAI); gsm48_decode_lai2(gsm48_lai, &new_lai); + /* 3GPP TS 23.272 sec 4.3.3 (CSFB): + * "During the SGs location update procedure, obtaining the last used LTE PLMN ID via TAI" + */ + if (TLVP_PRES_LEN(tp, SGSAP_IE_TAI, 3)) { + last_eutran_plmn = &last_eutran_plmn_buf; + osmo_plmn_from_bcd(TLVP_VAL(tp, SGSAP_IE_TAI), last_eutran_plmn); + /* TODO: we could also gather the TAC from here, but we don't need it yet */ + } else if (TLVP_PRES_LEN(tp, SGSAP_IE_EUTRAN_CGI, 3)) { + /* Since TAI is optional, let's try harder getting Last Used + * E-UTRAN PLMN ID by fetching it from E-UTRAN CGI */ + last_eutran_plmn = &last_eutran_plmn_buf; + osmo_plmn_from_bcd(TLVP_VAL(tp, SGSAP_IE_EUTRAN_CGI), last_eutran_plmn); + /* TODO: we could also gather the ECI from here, but we don't need it yet */ + } else { + LOGSGC(sgc, LOGL_INFO, "Receiving SGsAP-LOCATION-UPDATE-REQUEST without TAI nor " + "E-CGI IEs, fast fallback GERAN->EUTRAN won't be possible!\n"); + } + /* Perform actual location update */ memcpy(vlr_sgs_cfg.timer, sgc->sgs->cfg.timer, sizeof(vlr_sgs_cfg.timer)); memcpy(vlr_sgs_cfg.counter, sgc->sgs->cfg.counter, sizeof(vlr_sgs_cfg.counter)); rc = vlr_sgs_loc_update(gsm_network->vlr, &vlr_sgs_cfg, sgs_tx_loc_upd_resp_cb, sgs_iface_tx_paging, - sgs_tx_mm_info_cb, mme_name, type, imsi, &new_lai); + sgs_tx_mm_info_cb, mme_name, type, imsi, &new_lai, last_eutran_plmn); if (rc != 0) { resp = gsm29118_create_lu_rej(imsi, SGSAP_SGS_CAUSE_IMSI_UNKNOWN, NULL); sgs_tx(sgc, resp); @@ -849,7 +890,7 @@ static int sgs_rx_ul_ud(struct sgs_connection *sgc, struct msgb *msg, const stru vlr_subscr_put(vsub, __func__); /* If we do not find an existing connection and allocating a new one - * faild, give up and return status. */ + * failed, give up and return status. */ if (!msc_a) return sgs_tx_status(sgc, imsi, SGSAP_SGS_CAUSE_MSG_INCOMP_STATE, msg, 0); @@ -874,19 +915,41 @@ static int sgs_rx_ul_ud(struct sgs_connection *sgc, struct msgb *msg, const stru static int sgs_rx_csfb_ind(struct sgs_connection *sgc, struct msgb *msg, const struct tlv_parsed *tp, char *imsi) { struct vlr_subscr *vsub; + struct osmo_plmn_id last_eutran_plmn_buf; + const struct osmo_plmn_id *last_eutran_plmn = &last_eutran_plmn_buf; - /* The MME informs us with this message that the UE has returned back - * to the 4G network, so we use the SGs interface again for further - * communication with the UE. */ + /* The MME informs us with this message that the UE has initiated a + * service request for MO CS fallback. There is not much we can do with + * this information, however, we can check if the subscriber actually + * exists in the VLR and if there are any lingering connections open.*/ vsub = vlr_subscr_find_by_imsi(gsm_network->vlr, imsi, __func__); if (!vsub) return sgs_tx_status(sgc, imsi, SGSAP_SGS_CAUSE_IMSI_UNKNOWN, msg, SGSAP_IE_IMSI); + /* 3GPP TS 23.272 sec 4.3.3 (CSFB): + * "During the SGs location update procedure, obtaining the last used LTE PLMN ID via TAI" + */ + if (TLVP_PRES_LEN(tp, SGSAP_IE_TAI, 3)) { + osmo_plmn_from_bcd(TLVP_VAL(tp, SGSAP_IE_TAI), &last_eutran_plmn_buf); + /* TODO: we could also gather the TAC from here, but we don't need it yet */ + } else if (TLVP_PRES_LEN(tp, SGSAP_IE_EUTRAN_CGI, 3)) { + /* Since TAI is optional, let's try harder getting Last Used + * E-UTRAN PLMN ID by fetching it from E-UTRAN CGI */ + osmo_plmn_from_bcd(TLVP_VAL(tp, SGSAP_IE_EUTRAN_CGI), &last_eutran_plmn_buf); + /* TODO: we could also gather the ECI from here, but we don't need it yet */ + } else { + LOGSGC(sgc, LOGL_INFO, "Receiving SGsAP-MO-CSFB-INDICATION without TAI nor " + "E-CGI IEs, and they are not known from previous SGsAP-LOCATION-UPDATE-REQUEST. " + "Fast fallback GERAN->EUTRAN won't be possible!\n"); + last_eutran_plmn = NULL; + } + + vlr_subscr_set_last_used_eutran_plmn_id(vsub, last_eutran_plmn); + /* Check for lingering connections */ subscr_conn_toss(vsub); - vsub->cs.attached_via_ran = OSMO_RAT_EUTRAN_SGS; vlr_subscr_put(vsub, __func__); return 0; } @@ -934,10 +997,8 @@ int sgs_iface_rx(struct sgs_connection *sgc, struct msgb *msg) /* Parse TLV elements */ rc = tlv_parse(&tp, &sgsap_ie_tlvdef, msgb_l2(msg) + 1, msgb_l2len(msg) - 1, 0, 0); - if (rc < 0) { - TX_STATUS_AND_LOG(sgc, msg_type, SGSAP_SGS_CAUSE_SEMANT_INCORR_MSG, "SGsAP Message %s parsing error\n"); - goto error; - } + if (rc < 0) + LOGSGC(sgc, LOGL_NOTICE, "SGsAP Message %s contains unknown TLV IEs\n", sgsap_msg_type_name(msg_type)); /* Most of the messages contain an IMSI as mandatory IE, parse it right here */ if (!TLVP_PRESENT(&tp, SGSAP_IE_IMSI) && @@ -949,16 +1010,20 @@ int sgs_iface_rx(struct sgs_connection *sgc, struct msgb *msg) } if (TLVP_PRESENT(&tp, SGSAP_IE_IMSI)) { - gsm48_mi_to_string(imsi, sizeof(imsi), TLVP_VAL(&tp, SGSAP_IE_IMSI), TLVP_LEN(&tp, SGSAP_IE_IMSI)); - if (strlen(imsi) < GSM23003_IMSI_MIN_DIGITS) { + struct osmo_mobile_identity mi; + if (osmo_mobile_identity_decode(&mi, + TLVP_VAL(&tp, SGSAP_IE_IMSI), + TLVP_LEN(&tp, SGSAP_IE_IMSI), false) + || mi.type != GSM_MI_TYPE_IMSI) { TX_STATUS_AND_LOG(sgc, msg_type, SGSAP_SGS_CAUSE_INVALID_MAND_IE, - "SGsAP Message %s with short IMSI, dropping\n"); + "SGsAP Message %s with invalid IMSI, dropping\n"); goto error; } + OSMO_STRLCPY_ARRAY(imsi, mi.imsi); } - /* Some messages contain an MME-NAME as mandatore IE, parse it right here. The - * MME-NAME is als immediately registered with the sgc, so it will be implicitly + /* Some messages contain an MME-NAME as mandatory IE, parse it right here. The + * MME-NAME is also immediately registered with the sgc, so it will be implicitly * known to all functions that have access to the sgc context. */ if (!TLVP_PRESENT(&tp, SGSAP_IE_MME_NAME) && (msg_type == SGSAP_MSGT_RESET_IND || msg_type == SGSAP_MSGT_RESET_ACK @@ -1120,6 +1185,10 @@ static void sgs_vlr_reset_fsm_allstate(struct osmo_fsm_inst *fi, uint32_t event, reset_params.vlr_name_present = true; reset_ind = gsm29118_create_reset_ind(&reset_params); sgs_tx(sgc, reset_ind); + + /* Perform a reset of the SGS FSM of all subscribers that are present in the VLR */ + vlr_sgs_reset(gsm_network->vlr); + osmo_fsm_inst_state_chg(fi, SGS_VLRR_ST_WAIT_ACK, sgs->cfg.timer[SGS_STATE_TS11], 11); break; default: @@ -1187,6 +1256,7 @@ static const struct osmo_fsm_state sgs_vlr_reset_fsm_states[] = { static struct osmo_fsm sgs_vlr_reset_fsm = { .name = "SGs-VLR-RESET", .states = sgs_vlr_reset_fsm_states, + .num_states = ARRAY_SIZE(sgs_vlr_reset_fsm_states), .allstate_event_mask = S(SGS_VLRR_E_START_RESET), .allstate_action = sgs_vlr_reset_fsm_allstate, .timer_cb = sgs_vlr_reset_fsm_timer_cb, @@ -1242,7 +1312,29 @@ void sgs_iface_tx_release(struct vlr_subscr *vsub) sgs_tx(mme->conn, msg_sgs); } -/*! initalize SGs new interface +/*! Send SGsAP-SERVICE-ABORT-REQUEST message to MME + * \param[in] vsub subscriber context */ +void sgs_iface_tx_serv_abrt(struct vlr_subscr *vsub) +{ + struct msgb *msg_sgs; + struct sgs_mme_ctx *mme; + + OSMO_ASSERT(vsub); + + /* The service abort procedure is only defined for MT calls, + * see also 3GPP TS 29.118, chapter 5.13.2 */ + if (vsub->sgs.paging_serv_ind != SGSAP_SERV_IND_CS_CALL) + return; + + mme = sgs_mme_ctx_by_vsub(vsub, SGSAP_MSGT_DL_UD); + if (!mme) + return; + + msg_sgs = gsm29118_create_service_abort_req(vsub->imsi); + sgs_tx(mme->conn, msg_sgs); +} + +/*! initialize SGs new interface * \param[in] ctx talloc context * \param[in] network associated gsm network * \returns returns allocated sgs_stae, NULL in case of error. */ diff --git a/src/libmsc/silent_call.c b/src/libmsc/silent_call.c index 3b95a901f..4de12b9e2 100644 --- a/src/libmsc/silent_call.c +++ b/src/libmsc/silent_call.c @@ -140,7 +140,11 @@ int gsm_silent_call_start(struct vlr_subscr *vsub, struct vty *vty) { struct gsm_network *net = vsub->vlr->user_ctx; - struct gsm_trans *trans = trans_alloc(net, vsub, TRANS_SILENT_CALL, 0, 0); + struct gsm_trans *trans; + + trans = trans_alloc(net, vsub, TRANS_SILENT_CALL, 0, 0); + if (trans == NULL) + return -ENODEV; trans->silent_call.ct = *ct; if (traffic_dst_ip) { diff --git a/src/libmsc/smpp_utils.c b/src/libmsc/smpp_utils.c deleted file mode 100644 index 7fffdd27a..000000000 --- a/src/libmsc/smpp_utils.c +++ /dev/null @@ -1,61 +0,0 @@ - -/* (C) 2012-2013 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 "smpp_smsc.h" -#include <osmocom/core/logging.h> - -int smpp_determine_scheme(uint8_t dcs, uint8_t *data_coding, int *mode) -{ - if ((dcs & 0xF0) == 0xF0) { - if (dcs & 0x04) { - /* bit 2 == 1: 8bit data */ - *data_coding = 0x02; - *mode = MODE_8BIT; - } else { - /* bit 2 == 0: default alphabet */ - *data_coding = 0x01; - *mode = MODE_7BIT; - } - } else if ((dcs & 0xE0) == 0) { - switch (dcs & 0xC) { - case 0: - *data_coding = 0x01; - *mode = MODE_7BIT; - break; - case 4: - *data_coding = 0x02; - *mode = MODE_8BIT; - break; - case 8: - *data_coding = 0x08; /* UCS-2 */ - *mode = MODE_8BIT; - break; - default: - goto unknown_mo; - } - } else { -unknown_mo: - LOGP(DLSMS, LOGL_ERROR, "SMPP MO Unknown Data Coding 0x%02x\n", dcs); - return -1; - } - - return 0; - -} diff --git a/src/libmsc/sms_queue.c b/src/libmsc/sms_queue.c index 2c380b294..9f18f4feb 100644 --- a/src/libmsc/sms_queue.c +++ b/src/libmsc/sms_queue.c @@ -1,4 +1,4 @@ -/* SMS queue to continously attempt to deliver SMS */ +/* SMS queue to continuously attempt to deliver SMS */ /* * (C) 2010 by Holger Hans Peter Freyther <zecke@selfish.org> * All Rights Reserved @@ -40,38 +40,113 @@ #include <osmocom/msc/vlr.h> #include <osmocom/core/talloc.h> +#include <osmocom/core/utils.h> +#include <osmocom/core/rate_ctr.h> +#include <osmocom/core/stat_item.h> #include <osmocom/vty/vty.h> -/* - * One pending SMS that we wait for. - */ +enum smsq_stat_item_idx { + SMSQ_STAT_SMS_RAM_PENDING, +}; + +static const struct osmo_stat_item_desc smsq_stat_item_desc[] = { + [SMSQ_STAT_SMS_RAM_PENDING] = { "ram:pending", + "Number of SMSs in the in-RAM pending delivery queue" }, +}; + +static const struct osmo_stat_item_group_desc smsq_statg_desc = { + "sms_queue", + "SMS queue", + OSMO_STATS_CLASS_GLOBAL, + ARRAY_SIZE(smsq_stat_item_desc), + smsq_stat_item_desc, +}; + +enum smsq_rate_ctr_idx { + SMSQ_CTR_SMS_DELIVERY_ATTEMPTS, + SMSQ_CTR_SMS_DELIVERY_ACK, + SMSQ_CTR_SMS_DELIVERY_ERR, + SMSQ_CTR_SMS_DELIVERY_NOMEM, + SMSQ_CTR_SMS_DELIVERY_TIMEOUT, +}; + +static const struct rate_ctr_desc smsq_ctr_desc[] = { + [SMSQ_CTR_SMS_DELIVERY_ATTEMPTS] = { "delivery:attempts", + "Attempted MT SMS deliveries to subscriber" }, + [SMSQ_CTR_SMS_DELIVERY_ACK] = { "deliver:ack", + "Successful MT SMS delivery to subscriber" }, + [SMSQ_CTR_SMS_DELIVERY_ERR] = { "deliver:error", + "Erroneous MT SMS delivery" }, + [SMSQ_CTR_SMS_DELIVERY_NOMEM] = { "deliver:no_memory", + "Failed MT SMS delivery due to no memory on MS" }, + [SMSQ_CTR_SMS_DELIVERY_TIMEOUT] = { "deliver:paging_timeout", + "Failed MT SMS delivery due to paging timeout (MS gone?)" }, +}; + +static const struct rate_ctr_group_desc smsq_ctrg_desc = { + "sms_queue", + "SMS queue", + OSMO_STATS_CLASS_GLOBAL, + ARRAY_SIZE(smsq_ctr_desc), + smsq_ctr_desc, +}; + +#define smsq_rate_ctr_inc(smsq, idx) \ + rate_ctr_inc(rate_ctr_group_get_ctr((smsq)->ctrg, idx)) +#define smsq_rate_ctr_add(smsq, idx, val) \ + rate_ctr_add(rate_ctr_group_get_ctr((smsq)->ctrg, idx), val) + +#define smsq_stat_item_inc(smsq, idx) \ + osmo_stat_item_inc(osmo_stat_item_group_get_item((smsq)->statg, idx), 1) +#define smsq_stat_item_dec(smsq, idx) \ + osmo_stat_item_dec(osmo_stat_item_group_get_item((smsq)->statg, idx), 1) +#define smsq_stat_item_set(smsq, idx, val) \ + osmo_stat_item_set(osmo_stat_item_group_get_item((smsq)->statg, idx), val) + + +/* One in-RAM record of a "pending SMS". This is not the SMS itself, but merely + * a pointer to the database record. It holds a reference on the vlr_subscriber + * and some counters. While this object exists in RAM, we are regularly attempting + * to deliver the related SMS. */ struct gsm_sms_pending { - struct llist_head entry; + struct llist_head entry; /* gsm_sms_queue.pending_sms */ - struct vlr_subscr *vsub; - struct msc_a *msc_a; - unsigned long long sms_id; - int failed_attempts; - int resend; + struct vlr_subscr *vsub; /* destination subscriber for this SMS */ + struct msc_a *msc_a; /* MSC_A associated with this SMS */ + unsigned long long sms_id; /* unique ID (in SQL database) of this SMS */ + int failed_attempts; /* count of failed deliver attempts so far */ + int resend; /* should we try re-sending it (now) ? */ }; +/* (global) state of the SMS queue. */ struct gsm_sms_queue { - struct osmo_timer_list resend_pending; - struct osmo_timer_list push_queue; + struct osmo_timer_list resend_pending; /* timer triggering sms_resend_pending() */ + struct osmo_timer_list push_queue; /* timer triggering sms_submit_pending() */ struct gsm_network *network; - int max_fail; - int max_pending; - int pending; + struct llist_head pending_sms; /* list of gsm_sms_pending */ + struct sms_queue_config *cfg; + int pending; /* current number of gsm_sms_pending in RAM */ - struct llist_head pending_sms; + /* last MSISDN for which we read SMS from the database and created gsm_sms_pending records */ + char last_msisdn[GSM23003_MSISDN_MAX_DIGITS+1]; - char last_msisdn[VLR_MSISDN_LENGTH+1]; + /* statistics / counters */ + struct osmo_stat_item_group *statg; + struct rate_ctr_group *ctrg; }; +/* private wrapper function to make sure we count all SMS delivery attempts */ +static void _gsm411_send_sms(struct gsm_network *net, struct vlr_subscr *vsub, struct gsm_sms *sms) +{ + smsq_rate_ctr_inc(net->sms_queue, SMSQ_CTR_SMS_DELIVERY_ATTEMPTS); + gsm411_send_sms(net, vsub, sms); +} + static int sms_subscr_cb(unsigned int, unsigned int, void *, void *); static int sms_sms_cb(unsigned int, unsigned int, void *, void *); +/* look-up a 'gsm_sms_pending' for the given sms_id; return NULL if none */ static struct gsm_sms_pending *sms_find_pending(struct gsm_sms_queue *smsq, unsigned long long sms_id) { @@ -85,11 +160,13 @@ static struct gsm_sms_pending *sms_find_pending(struct gsm_sms_queue *smsq, return NULL; } +/* do we currently have a gsm_sms_pending object for the given SMS id? */ int sms_queue_sms_is_pending(struct gsm_sms_queue *smsq, unsigned long long sms_id) { return sms_find_pending(smsq, sms_id) != NULL; } +/* find the first pending SMS (in RAM) for the given subscriber */ static struct gsm_sms_pending *sms_subscriber_find_pending( struct gsm_sms_queue *smsq, struct vlr_subscr *vsub) @@ -104,12 +181,14 @@ static struct gsm_sms_pending *sms_subscriber_find_pending( return NULL; } +/* do we have any pending SMS (in RAM) for the given subscriber? */ static int sms_subscriber_is_pending(struct gsm_sms_queue *smsq, struct vlr_subscr *vsub) { return sms_subscriber_find_pending(smsq, vsub) != NULL; } +/* allocate a new gsm_sms_pending record and fill it with information from 'sms' */ static struct gsm_sms_pending *sms_pending_from(struct gsm_sms_queue *smsq, struct gsm_sms *sms) { @@ -122,16 +201,26 @@ static struct gsm_sms_pending *sms_pending_from(struct gsm_sms_queue *smsq, vlr_subscr_get(sms->receiver, VSUB_USE_SMS_PENDING); pending->vsub = sms->receiver; pending->sms_id = sms->id; + llist_add_tail(&pending->entry, &smsq->pending_sms); + + smsq->pending += 1; + smsq_stat_item_inc(smsq, SMSQ_STAT_SMS_RAM_PENDING); + return pending; } -static void sms_pending_free(struct gsm_sms_pending *pending) +/* release a gsm_sms_pending object */ +static void sms_pending_free(struct gsm_sms_queue *smsq, struct gsm_sms_pending *pending) { + smsq->pending -= 1; + smsq_stat_item_dec(smsq, SMSQ_STAT_SMS_RAM_PENDING); vlr_subscr_put(pending->vsub, VSUB_USE_SMS_PENDING); llist_del(&pending->entry); talloc_free(pending); } +/* this sets the 'resend' flag of the gsm_sms_pending and schedules + * the timer for re-sending */ static void sms_pending_resend(struct gsm_sms_pending *pending) { struct gsm_network *net = pending->vsub->vlr->user_ctx; @@ -148,6 +237,8 @@ static void sms_pending_resend(struct gsm_sms_pending *pending) osmo_timer_schedule(&smsq->resend_pending, 1, 0); } +/* call-back when a pending SMS has failed; try another re-send if number of + * attempts is < smsq->max_fail */ static void sms_pending_failed(struct gsm_sms_pending *pending, int paging_error) { struct gsm_network *net = pending->vsub->vlr->user_ctx; @@ -158,17 +249,16 @@ static void sms_pending_failed(struct gsm_sms_pending *pending, int paging_error pending->sms_id, pending->failed_attempts); smsq = net->sms_queue; - if (pending->failed_attempts < smsq->max_fail) + if (pending->failed_attempts < smsq->cfg->max_fail) return sms_pending_resend(pending); - sms_pending_free(pending); - smsq->pending -= 1; + sms_pending_free(smsq, pending); } -/* - * Resend all SMS that are scheduled for a resend. This is done to - * avoid an immediate failure. - */ +/* Resend all SMS that are scheduled for a resend. This is done to + * avoid an immediate failure. This iterates over all the (in RAM) + * pending_sms records, checks for resend == true, reads them from the + * DB and attempts to send them via _gsm411_send_sms() */ static void sms_resend_pending(void *_data) { struct gsm_sms_pending *pending, *tmp; @@ -183,12 +273,11 @@ static void sms_resend_pending(void *_data) /* the sms is gone? Move to the next */ if (!sms) { - sms_pending_free(pending); - smsq->pending -= 1; + sms_pending_free(smsq, pending); sms_queue_trigger(smsq); } else { pending->resend = 0; - gsm411_send_sms(smsq->network, sms->receiver, sms); + _gsm411_send_sms(smsq->network, sms->receiver, sms); } } } @@ -244,19 +333,19 @@ struct gsm_sms *smsq_take_next_sms(struct gsm_network *net, return NULL; } -/** - * I will submit up to max_pending - pending SMS to the - * subsystem. - */ +/* read up to 'max_pending' pending SMS from the database and add them to the in-memory + * sms_queue; trigger the first delivery attempt. 'submit' in this context means + * "read from the database and add to the in-memory gsm_sms_queue" and is not to be + * confused with the SMS SUBMIT operation a MS performs when sending a MO-SMS. */ static void sms_submit_pending(void *_data) { struct gsm_sms_queue *smsq = _data; - int attempts = smsq->max_pending - smsq->pending; + int attempts = smsq->cfg->max_pending - smsq->pending; int initialized = 0; unsigned long long first_sub = 0; int attempted = 0, rounds = 0; - LOGP(DLSMS, LOGL_DEBUG, "Attempting to send %d SMS\n", attempts); + LOGP(DLSMS, LOGL_DEBUG, "Attempting to send up to %d SMS\n", attempts); do { struct gsm_sms_pending *pending; @@ -272,7 +361,7 @@ static void sms_submit_pending(void *_data) } rounds += 1; - LOGP(DLSMS, LOGL_DEBUG, "Sending SMS round %d\n", rounds); + LOGP(DLSMS, LOGL_DEBUG, "Checking whether to send SMS %llu\n", sms->id); /* * This code needs to detect a loop. It assumes that no SMS @@ -309,6 +398,7 @@ static void sms_submit_pending(void *_data) continue; } + /* allocate a new gsm_sms_pending object in RAM */ pending = sms_pending_from(smsq, sms); if (!pending) { LOGP(DLSMS, LOGL_ERROR, @@ -318,17 +408,16 @@ static void sms_submit_pending(void *_data) } attempted += 1; - smsq->pending += 1; - llist_add_tail(&pending->entry, &smsq->pending_sms); - gsm411_send_sms(smsq->network, sms->receiver, sms); + _gsm411_send_sms(smsq->network, sms->receiver, sms); } while (attempted < attempts && rounds < 1000); LOGP(DLSMS, LOGL_DEBUG, "SMSqueue added %d messages in %d rounds\n", attempted, rounds); } -/** - * Send the next SMS or trigger the queue - */ +/* obtain the next pending SMS for given subscriber from database, + * create gsm_sms_pending object and attempt first delivery. If there + * are no SMS pending for the given subscriber, call sms_submit_pending() + * to read more SMS (for any subscriber) into the in-RAM pending queue */ static void sms_send_next(struct vlr_subscr *vsub) { struct gsm_network *net = vsub->vlr->user_ctx; @@ -340,7 +429,7 @@ static void sms_send_next(struct vlr_subscr *vsub) OSMO_ASSERT(!sms_subscriber_is_pending(smsq, vsub)); /* check for more messages for this subscriber */ - sms = db_sms_get_unsent_for_subscr(vsub, UINT_MAX); + sms = db_sms_get_unsent_for_subscr(vsub, INT_MAX); if (!sms) goto no_pending_sms; @@ -356,9 +445,7 @@ static void sms_send_next(struct vlr_subscr *vsub) goto no_pending_sms; } - smsq->pending += 1; - llist_add_tail(&pending->entry, &smsq->pending_sms); - gsm411_send_sms(smsq->network, sms->receiver, sms); + _gsm411_send_sms(smsq->network, sms->receiver, sms); return; no_pending_sms: @@ -366,9 +453,7 @@ no_pending_sms: sms_submit_pending(net->sms_queue); } -/* - * Kick off the queue again. - */ +/* Trigger a call to sms_submit_pending() in one second */ int sms_queue_trigger(struct gsm_sms_queue *smsq) { LOGP(DLSMS, LOGL_DEBUG, "Triggering SMS queue\n"); @@ -379,7 +464,26 @@ int sms_queue_trigger(struct gsm_sms_queue *smsq) return 0; } -int sms_queue_start(struct gsm_network *network, int max_pending) +/* allocate + initialize SMS queue configuration with some default values */ +struct sms_queue_config *sms_queue_cfg_alloc(void *ctx) +{ + struct sms_queue_config *sqcfg = talloc_zero(ctx, struct sms_queue_config); + OSMO_ASSERT(sqcfg); + + sqcfg->max_pending = 20; + sqcfg->max_fail = 1; + sqcfg->delete_delivered = true; + sqcfg->delete_expired = true; + sqcfg->default_validity_mins = 7 * 24 * 60; /* 7 days */ + sqcfg->minimum_validity_mins = 1; + sqcfg->db_file_path = talloc_strdup(ctx, SMS_DEFAULT_DB_FILE_PATH); + + return sqcfg; +} + +/* initialize the sms_queue subsystem and read the first batch of SMS from + * the database for delivery */ +int sms_queue_start(struct gsm_network *network) { struct gsm_sms_queue *sms = talloc_zero(network, struct gsm_sms_queue); if (!sms) { @@ -387,22 +491,48 @@ int sms_queue_start(struct gsm_network *network, int max_pending) return -1; } - osmo_signal_register_handler(SS_SUBSCR, sms_subscr_cb, network); - osmo_signal_register_handler(SS_SMS, sms_sms_cb, network); + sms->cfg = network->sms_queue_cfg; + sms->statg = osmo_stat_item_group_alloc(sms, &smsq_statg_desc, 0); + if (!sms->statg) + goto err_free; + + sms->ctrg = rate_ctr_group_alloc(sms, &smsq_ctrg_desc, 0); + if (!sms->ctrg) + goto err_statg; network->sms_queue = sms; INIT_LLIST_HEAD(&sms->pending_sms); - sms->max_fail = 1; sms->network = network; - sms->max_pending = max_pending; osmo_timer_setup(&sms->push_queue, sms_submit_pending, sms); osmo_timer_setup(&sms->resend_pending, sms_resend_pending, sms); + osmo_signal_register_handler(SS_SUBSCR, sms_subscr_cb, network); + osmo_signal_register_handler(SS_SMS, sms_sms_cb, network); + + if (db_init(sms, sms->cfg->db_file_path, true)) { + LOGP(DMSC, LOGL_FATAL, "DB: Failed to init database: %s\n", + osmo_quote_str(sms->cfg->db_file_path, -1)); + return -1; + } + + if (db_prepare()) { + LOGP(DMSC, LOGL_FATAL, "DB: Failed to prepare database.\n"); + return -1; + } + sms_submit_pending(sms); return 0; + +err_statg: + osmo_stat_item_group_free(sms->statg); +err_free: + talloc_free(sms); + + return -ENOMEM; } +/* call-back: Given subscriber is now ready for short messages. */ static int sub_ready_for_sm(struct gsm_network *net, struct vlr_subscr *vsub) { struct gsm_sms *sms; @@ -432,14 +562,15 @@ static int sub_ready_for_sm(struct gsm_network *net, struct vlr_subscr *vsub) } /* Now try to deliver any pending SMS to this sub */ - sms = db_sms_get_unsent_for_subscr(vsub, UINT_MAX); + sms = db_sms_get_unsent_for_subscr(vsub, INT_MAX); if (!sms) return -1; - gsm411_send_sms(net, vsub, sms); + _gsm411_send_sms(net, vsub, sms); return 0; } +/* call-back for SS_SUBSCR signals */ static int sms_subscr_cb(unsigned int subsys, unsigned int signal, void *handler_data, void *signal_data) { @@ -452,10 +583,12 @@ static int sms_subscr_cb(unsigned int subsys, unsigned int signal, return sub_ready_for_sm(handler_data, vsub); } +/* call-back for SS_SMS signals */ static int sms_sms_cb(unsigned int subsys, unsigned int signal, void *handler_data, void *signal_data) { struct gsm_network *network = handler_data; + struct gsm_sms_queue *smq = network->sms_queue; struct sms_signal_data *sig_sms = signal_data; struct gsm_sms_pending *pending; struct vlr_subscr *vsub; @@ -463,7 +596,7 @@ static int sms_sms_cb(unsigned int subsys, unsigned int signal, /* We got a new SMS and maybe should launch the queue again. */ if (signal == S_SMS_SUBMITTED || signal == S_SMS_SMMA) { /* TODO: For SMMA we might want to re-use the radio connection. */ - sms_queue_trigger(network->sms_queue); + sms_queue_trigger(smq); return 0; } @@ -476,26 +609,27 @@ static int sms_sms_cb(unsigned int subsys, unsigned int signal, * sms that are not in our control as we just have a channel * open anyway. */ - pending = sms_find_pending(network->sms_queue, sig_sms->sms->id); + pending = sms_find_pending(smq, sig_sms->sms->id); if (!pending) return 0; switch (signal) { case S_SMS_DELIVERED: + smsq_rate_ctr_inc(smq, SMSQ_CTR_SMS_DELIVERY_ACK); /* Remember the subscriber and clear the pending entry */ - network->sms_queue->pending -= 1; vsub = pending->vsub; vlr_subscr_get(vsub, __func__); - db_sms_delete_sent_message_by_id(pending->sms_id); - sms_pending_free(pending); + if (smq->cfg->delete_delivered) + db_sms_delete_sent_message_by_id(pending->sms_id); + sms_pending_free(smq, pending); /* Attempt to send another SMS to this subscriber */ sms_send_next(vsub); vlr_subscr_put(vsub, __func__); break; case S_SMS_MEM_EXCEEDED: - network->sms_queue->pending -= 1; - sms_pending_free(pending); - sms_queue_trigger(network->sms_queue); + smsq_rate_ctr_inc(smq, SMSQ_CTR_SMS_DELIVERY_NOMEM); + sms_pending_free(smq, pending); + sms_queue_trigger(smq); break; case S_SMS_UNKNOWN_ERROR: /* @@ -509,10 +643,12 @@ static int sms_sms_cb(unsigned int subsys, unsigned int signal, * should flag the SMS as bad. */ if (sig_sms->paging_result) { + smsq_rate_ctr_inc(smq, SMSQ_CTR_SMS_DELIVERY_ERR); /* BAD SMS? */ db_sms_inc_deliver_attempts(sig_sms->sms); sms_pending_failed(pending, 0); } else { + smsq_rate_ctr_inc(smq, SMSQ_CTR_SMS_DELIVERY_TIMEOUT); sms_pending_failed(pending, 1); } break; @@ -522,7 +658,8 @@ static int sms_sms_cb(unsigned int subsys, unsigned int signal, } /* While here, attempt to remove an expired SMS from the DB. */ - db_sms_delete_oldest_expired_message(); + if (smq->cfg->delete_expired) + db_sms_delete_oldest_expired_message(); return 0; } @@ -533,7 +670,7 @@ int sms_queue_stats(struct gsm_sms_queue *smsq, struct vty *vty) struct gsm_sms_pending *pending; vty_out(vty, "SMSqueue with max_pending: %d pending: %d%s", - smsq->max_pending, smsq->pending, VTY_NEWLINE); + smsq->cfg->max_pending, smsq->pending, VTY_NEWLINE); llist_for_each_entry(pending, &smsq->pending_sms, entry) vty_out(vty, " SMS Pending for Subscriber: %llu SMS: %llu Failed: %d.%s", @@ -542,22 +679,6 @@ int sms_queue_stats(struct gsm_sms_queue *smsq, struct vty *vty) return 0; } -int sms_queue_set_max_pending(struct gsm_sms_queue *smsq, int max_pending) -{ - LOGP(DLSMS, LOGL_NOTICE, "SMSqueue old max: %d new: %d\n", - smsq->max_pending, max_pending); - smsq->max_pending = max_pending; - return 0; -} - -int sms_queue_set_max_failure(struct gsm_sms_queue *smsq, int max_fail) -{ - LOGP(DLSMS, LOGL_NOTICE, "SMSqueue max failure old: %d new: %d\n", - smsq->max_fail, max_fail); - smsq->max_fail = max_fail; - return 0; -} - int sms_queue_clear(struct gsm_sms_queue *smsq) { struct gsm_sms_pending *pending, *tmp; @@ -565,9 +686,8 @@ int sms_queue_clear(struct gsm_sms_queue *smsq) llist_for_each_entry_safe(pending, tmp, &smsq->pending_sms, entry) { LOGP(DLSMS, LOGL_NOTICE, "SMSqueue clearing for sub %llu\n", pending->vsub->id); - sms_pending_free(pending); + sms_pending_free(smsq, pending); } - smsq->pending = 0; return 0; } diff --git a/src/libmsc/smsc_vty.c b/src/libmsc/smsc_vty.c new file mode 100644 index 000000000..f30907f4b --- /dev/null +++ b/src/libmsc/smsc_vty.c @@ -0,0 +1,214 @@ +/* SMSC interface to VTY */ +/* (C) 2016-2018 by sysmocom s.f.m.c. GmbH <info@sysmocom.de> + * Based on OpenBSC interface to quagga VTY (libmsc/vty_interface_layer3.c) + * (C) 2009-2022 by Harald Welte <laforge@gnumonks.org> + * (C) 2009-2011 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 "config.h" + +#include <osmocom/vty/command.h> +#include <osmocom/vty/logging.h> +#include <osmocom/vty/misc.h> + +#include <osmocom/msc/vty.h> +#include <osmocom/msc/gsm_data.h> +#include <osmocom/msc/sms_queue.h> + + +static struct gsm_network *gsmnet; +static struct sms_queue_config *smqcfg; + +/*********************************************************************** + * SMSC Config Node + ***********************************************************************/ + +static struct cmd_node smsc_node = { + SMSC_NODE, + "%s(config-smsc)# ", + 1, +}; + +DEFUN(cfg_smsc, cfg_smsc_cmd, + "smsc", "Configure SMSC options") +{ + vty->node = SMSC_NODE; + return CMD_SUCCESS; +} + +DEFUN(cfg_sms_database, cfg_sms_database_cmd, + "database PATH", + "Set the path to the MSC-SMS database file\n" + "Relative or absolute file system path to the database file (default is '" SMS_DEFAULT_DB_FILE_PATH "')\n") +{ + osmo_talloc_replace_string(smqcfg, &smqcfg->db_file_path, argv[0]); + return CMD_SUCCESS; +} + +DEFUN(cfg_sms_queue_max, cfg_sms_queue_max_cmd, + "queue max-pending <1-500>", + "SMS Queue\n" "SMS to deliver in parallel\n" "Amount\n") +{ + smqcfg->max_pending = atoi(argv[0]); + return CMD_SUCCESS; +} + +DEFUN(cfg_sms_queue_fail, cfg_sms_queue_fail_cmd, + "queue max-failure <1-500>", + "SMS Queue\n" "Maximum number of delivery failures before giving up\n" "Amount\n") +{ + smqcfg->max_fail = atoi(argv[0]); + return CMD_SUCCESS; +} + +#define DB_STR "SMS Database Configuration\n" + +DEFUN(cfg_sms_db_del_delivered, cfg_sms_db_del_delivered_cmd, + "database delete-delivered (0|1)", + DB_STR "Configure if delivered SMS are deleted from DB\n" + "Do not delete SMS after delivery\n" + "Delete SMS after delivery\n") +{ + smqcfg->delete_delivered = atoi(argv[0]); + return CMD_SUCCESS; +} + +DEFUN(cfg_sms_db_del_expired, cfg_sms_db_del_expired_cmd, + "database delete-expired (0|1)", + DB_STR "Configure if expired SMS are deleted from DB\n" + "Do not delete SMS after expiration of validity period\n" + "Delete SMS after expiration of validity period\n") +{ + smqcfg->delete_expired = atoi(argv[0]); + return CMD_SUCCESS; +} + +DEFUN(cfg_sms_def_val_per, cfg_sms_def_val_per_cmd, + "validity-period (minimum|default) <1-5256000>", + "Configure validity period for SMS\n" + "Minimum SMS validity period in minutes\n" + "Default SMS validity period in minutes\n" + "Validity period in minutes\n") +{ + if (!strcmp(argv[0], "minimum")) + smqcfg->minimum_validity_mins = atoi(argv[1]); + else + smqcfg->default_validity_mins = atoi(argv[1]); + return CMD_SUCCESS; +} + + +/*********************************************************************** + * View / Enable Node + ***********************************************************************/ + +DEFUN(show_smsqueue, + show_smsqueue_cmd, + "show sms-queue", + SHOW_STR "Display SMSqueue statistics\n") +{ + sms_queue_stats(gsmnet->sms_queue, vty); + return CMD_SUCCESS; +} + +DEFUN(smsqueue_trigger, + smsqueue_trigger_cmd, + "sms-queue trigger", + "SMS Queue\n" "Trigger sending messages\n") +{ + sms_queue_trigger(gsmnet->sms_queue); + return CMD_SUCCESS; +} + +DEFUN(smsqueue_max, + smsqueue_max_cmd, + "sms-queue max-pending <1-500>", + "SMS Queue\n" "SMS to deliver in parallel\n" "Amount\n") +{ + int max_pending = atoi(argv[0]); + vty_out(vty, "%% SMSqueue old max: %d new: %d%s", + smqcfg->max_pending, max_pending, VTY_NEWLINE); + smqcfg->max_pending = max_pending; + return CMD_SUCCESS; +} + +DEFUN(smsqueue_clear, + smsqueue_clear_cmd, + "sms-queue clear", + "SMS Queue\n" "Clear the queue of pending SMS\n") +{ + sms_queue_clear(gsmnet->sms_queue); + return CMD_SUCCESS; +} + +DEFUN(smsqueue_fail, + smsqueue_fail_cmd, + "sms-queue max-failure <1-500>", + "SMS Queue\n" "Maximum amount of delivery failures\n" "Amount\n") +{ + int max_fail = atoi(argv[0]); + vty_out(vty, "%% SMSqueue max failure old: %d new: %d%s", + smqcfg->max_fail, max_fail, VTY_NEWLINE); + smqcfg->max_fail = max_fail; + return CMD_SUCCESS; +} + +static int config_write_smsc(struct vty *vty) +{ + vty_out(vty, "smsc%s", VTY_NEWLINE); + + if (smqcfg->db_file_path && strcmp(smqcfg->db_file_path, SMS_DEFAULT_DB_FILE_PATH)) + vty_out(vty, " database %s%s", smqcfg->db_file_path, VTY_NEWLINE); + + vty_out(vty, " queue max-pending %u%s", smqcfg->max_pending, VTY_NEWLINE); + vty_out(vty, " queue max-failure %u%s", smqcfg->max_fail, VTY_NEWLINE); + + vty_out(vty, " database delete-delivered %u%s", smqcfg->delete_delivered, VTY_NEWLINE); + vty_out(vty, " database delete-expired %u%s", smqcfg->delete_expired, VTY_NEWLINE); + + vty_out(vty, " validity-period minimum %u%s", smqcfg->minimum_validity_mins, VTY_NEWLINE); + vty_out(vty, " validity-period default %u%s", smqcfg->default_validity_mins, VTY_NEWLINE); + + return 0; +} + +void smsc_vty_init(struct gsm_network *msc_network) +{ + OSMO_ASSERT(gsmnet == NULL); + gsmnet = msc_network; + smqcfg = msc_network->sms_queue_cfg; + + /* config node */ + install_element(CONFIG_NODE, &cfg_smsc_cmd); + install_node(&smsc_node, config_write_smsc); + install_element(SMSC_NODE, &cfg_sms_database_cmd); + install_element(SMSC_NODE, &cfg_sms_queue_max_cmd); + install_element(SMSC_NODE, &cfg_sms_queue_fail_cmd); + install_element(SMSC_NODE, &cfg_sms_db_del_delivered_cmd); + install_element(SMSC_NODE, &cfg_sms_db_del_expired_cmd); + install_element(SMSC_NODE, &cfg_sms_def_val_per_cmd); + + /* enable node */ + install_element(ENABLE_NODE, &smsqueue_trigger_cmd); + install_element(ENABLE_NODE, &smsqueue_max_cmd); + install_element(ENABLE_NODE, &smsqueue_clear_cmd); + install_element(ENABLE_NODE, &smsqueue_fail_cmd); + + /* view / enable node */ + install_element_ve(&show_smsqueue_cmd); +} diff --git a/src/libmsc/transaction.c b/src/libmsc/transaction.c index d6f8c3b17..7ae4c7d92 100644 --- a/src/libmsc/transaction.c +++ b/src/libmsc/transaction.c @@ -29,6 +29,7 @@ #include <osmocom/msc/msub.h> #include <osmocom/msc/paging.h> #include <osmocom/msc/silent_call.h> +#include <osmocom/msc/msc_vgcs.h> void *tall_trans_ctx; @@ -73,16 +74,17 @@ struct gsm_trans *trans_find_by_id(const struct msc_a *msc_a, /*! Find a transaction by call reference * \param[in] net Network in which we should search + * \param[in] type Transaction type (e.g. TRANS_CC) * \param[in] callref Call Reference of transaction * \returns Matching transaction, if any */ -struct gsm_trans *trans_find_by_callref(const struct gsm_network *net, +struct gsm_trans *trans_find_by_callref(const struct gsm_network *net, enum trans_type type, uint32_t callref) { struct gsm_trans *trans; llist_for_each_entry(trans, &net->trans_list, entry) { - if (trans->callref == callref) + if (trans->callref == callref && trans->type == type) return trans; } return NULL; @@ -110,13 +112,81 @@ struct gsm_trans *trans_find_by_sm_rp_mr(const struct gsm_network *net, return NULL; } +struct osmo_lcls *trans_lcls_compose(const struct gsm_trans *trans, bool use_lac) +{ + if (!trans) { + LOGP(DCC, LOGL_ERROR, "LCLS: unable to fill parameters for unallocated transaction\n"); + return NULL; + } + + if (!trans->net->a.sri->sccp) + return NULL; + + struct osmo_ss7_instance *ss7 = osmo_sccp_get_ss7(trans->net->a.sri->sccp); + struct osmo_lcls *lcls; + uint8_t w = osmo_ss7_pc_width(&ss7->cfg.pc_fmt); + + if (!trans->net->lcls_permitted) { + LOGP(DCC, LOGL_NOTICE, "LCLS disabled globally\n"); + return NULL; + } + + if (!trans->msc_a) { + LOGP(DCC, LOGL_ERROR, "LCLS: unable to fill parameters for transaction without connection\n"); + return NULL; + } + + if (trans->msc_a->c.ran->type != OSMO_RAT_GERAN_A) { + LOGP(DCC, LOGL_ERROR, "LCLS: only A interface is supported at the moment\n"); + return NULL; + } + + lcls = talloc_zero(trans, struct osmo_lcls); + if (!lcls) { + LOGP(DCC, LOGL_ERROR, "LCLS: failed to allocate osmo_lcls\n"); + return NULL; + } + + LOGP(DCC, LOGL_INFO, "LCLS: using %u bits (%u bytes) for node ID\n", w, w / 8); + + lcls->gcr.net_len = 3; + lcls->gcr.node = ss7->cfg.primary_pc; + + /* net id from Q.1902.3 3-5 bytes, this function gives 3 bytes exactly */ + osmo_plmn_to_bcd(lcls->gcr.net, &trans->msc_a->via_cell.lai.plmn); + + + /* TS 29.205 Table B.2.1.9.2 Call Reference ID + * 3 octets Call ID + 2 octets BSS ID + */ + lcls->gcr.cr[2] = (trans->callref >> 0) & 0xff; + lcls->gcr.cr[1] = (trans->callref >> 8) & 0xff; + lcls->gcr.cr[0] = (trans->callref >> 16) & 0xff; + osmo_store16be(use_lac ? trans->msc_a->via_cell.lai.lac : trans->msc_a->via_cell.cell_identity, &lcls->gcr.cr[3]); + + LOGP(DCC, LOGL_INFO, "LCLS: allocated %s-based CR-ID %sfor callref 0x%04x\n", use_lac ? "LAC" : "CI", + osmo_hexdump(lcls->gcr.cr, 5), trans->callref); + + lcls->config = GSM0808_LCLS_CFG_BOTH_WAY; + lcls->control = GSM0808_LCLS_CSC_CONNECT; + lcls->corr_needed = true; + lcls->gcr_available = true; + + LOGP(DCC, LOGL_DEBUG, "Filled %s\n", osmo_lcls_dump(lcls)); + LOGP(DCC, LOGL_DEBUG, "Filled %s\n", osmo_gcr_dump(lcls)); + + return lcls; +} + static const char *trans_vsub_use(enum trans_type type) { return get_value_string_or_null(trans_type_names, type) ? : "trans-type-unknown"; } +static uint32_t new_call_id = 1; + /*! Allocate a new transaction and add it to network list - * \param[in] net Netwokr in which we allocate transaction + * \param[in] net Network in which we allocate transaction * \param[in] subscr Subscriber for which we allocate transaction * \param[in] protocol Protocol (CC/SMS/...) * \param[in] callref Call Reference @@ -127,11 +197,12 @@ struct gsm_trans *trans_alloc(struct gsm_network *net, enum trans_type type, uint8_t trans_id, uint32_t callref) { - struct gsm_trans *trans = NULL; /* (NULL for LOG_TRANS() before allocation) */ + int subsys = trans_log_subsys(type); + struct gsm_trans *trans; - /* a valid subscriber is indispensable */ - if (vsub == NULL) { - LOG_TRANS(trans, LOGL_ERROR, "unable to alloc transaction, invalid subscriber (NULL)\n"); + /* A valid subscriber is indispensable, except for voice group/broadcast calls. */ + if (vsub == NULL && type != TRANS_GCC && type != TRANS_BCC) { + LOGP(subsys, LOGL_ERROR, "unable to alloc transaction, invalid subscriber (NULL)\n"); return NULL; } @@ -142,12 +213,18 @@ struct gsm_trans *trans_alloc(struct gsm_network *net, *trans = (struct gsm_trans){ .vsub = vsub, .type = type, + .log_subsys = subsys, .transaction_id = trans_id, .callref = callref, + .call_id = new_call_id++, .net = net, + /* empty bearer_cap: make sure the speech_ver array is empty */ + .bearer_cap = { + .speech_ver = { -1 }, + }, }; - trans->log_subsys = trans_log_subsys(trans); - vlr_subscr_get(vsub, trans_vsub_use(type)); + if (vsub) + vlr_subscr_get(vsub, trans_vsub_use(type)); llist_add_tail(&trans->entry, &net->trans_list); LOG_TRANS(trans, LOGL_DEBUG, "New transaction\n"); @@ -165,6 +242,14 @@ void trans_free(struct gsm_trans *trans) LOG_TRANS(trans, LOGL_DEBUG, "Freeing transaction\n"); switch (trans->type) { + case TRANS_GCC: + gsm44068_bcc_gcc_trans_free(trans); + usage_token = MSC_A_USE_GCC; + break; + case TRANS_BCC: + gsm44068_bcc_gcc_trans_free(trans); + usage_token = MSC_A_USE_BCC; + break; case TRANS_CC: _gsm48_cc_trans_free(trans); usage_token = MSC_A_USE_CC; @@ -276,6 +361,8 @@ void trans_conn_closed(const struct msc_a *msc_a) } const struct value_string trans_type_names[] = { + { TRANS_GCC, "GCC" }, + { TRANS_BCC, "BCC" }, { TRANS_CC, "CC" }, { TRANS_SMS, "SMS" }, { TRANS_USSD, "NCSS" }, @@ -286,6 +373,10 @@ const struct value_string trans_type_names[] = { uint8_t trans_type_to_gsm48_proto(enum trans_type type) { switch (type) { + case TRANS_GCC: + return GSM48_PDISC_GROUP_CC; + case TRANS_BCC: + return GSM48_PDISC_BCAST_CC; case TRANS_CC: case TRANS_SILENT_CALL: return GSM48_PDISC_CC; @@ -298,3 +389,25 @@ uint8_t trans_type_to_gsm48_proto(enum trans_type type) } } + +const char *trans_name(const struct gsm_trans *trans) +{ + static char namebuf[32]; + if (!trans) + return "NULL"; + switch (trans->type) { + case TRANS_CC: + snprintf(namebuf, sizeof(namebuf), "%s:%s", + trans_type_name(trans->type), gsm48_cc_state_name(trans->cc.state)); + return namebuf; + + case TRANS_GCC: + case TRANS_BCC: + snprintf(namebuf, sizeof(namebuf), "%s:%s", + trans_type_name(trans->type), gsm44068_group_id_string(trans->callref)); + return namebuf; + + default: + return trans_type_name(trans->type); + } +} diff --git a/src/libmsc/transaction_cc.c b/src/libmsc/transaction_cc.c new file mode 100644 index 000000000..2a540bfa5 --- /dev/null +++ b/src/libmsc/transaction_cc.c @@ -0,0 +1,120 @@ +/* Filter/overlay codec and CSD bearer service selections for voice calls/CSD, + * across MS, RAN and CN limitations + * + * (C) 2023 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de> + * All Rights Reserved + * + * Author: Oliver Smith + * + * SPDX-License-Identifier: AGPL-3.0+ + * + * 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/msc/transaction_cc.h> +#include <osmocom/msc/codec_filter.h> +#include <osmocom/msc/csd_filter.h> + +void trans_cc_filter_init(struct gsm_trans *trans) +{ + trans->cc.codecs = (struct codec_filter){}; + trans->cc.csd = (struct csd_filter){}; +} + +void trans_cc_filter_set_ran(struct gsm_trans *trans, enum osmo_rat_type ran_type) +{ + codec_filter_set_ran(&trans->cc.codecs, ran_type); + csd_filter_set_ran(&trans->cc.csd, ran_type); +} + +void trans_cc_filter_set_bss(struct gsm_trans *trans, struct msc_a *msc_a) +{ + codec_filter_set_bss(&trans->cc.codecs, &msc_a->cc.compl_l3_codec_list_bss_supported); + + /* For CSD, there is no list of supported bearer services passed in + * Complete Layer 3. TODO: make it configurable? */ +} + +void _trans_cc_filter_run(const char *file, int line, struct gsm_trans *trans) +{ + switch (trans->bearer_cap.transfer) { + case GSM48_BCAP_ITCAP_SPEECH: + codec_filter_run(&trans->cc.codecs, &trans->cc.local, &trans->cc.remote); + LOG_TRANS_CAT_SRC(trans, DCC, LOGL_DEBUG, file, line, "codecs: %s\n", + codec_filter_to_str(&trans->cc.codecs, &trans->cc.local, &trans->cc.remote)); + break; + case GSM48_BCAP_ITCAP_3k1_AUDIO: + case GSM48_BCAP_ITCAP_FAX_G3: + case GSM48_BCAP_ITCAP_UNR_DIG_INF: + csd_filter_run(&trans->cc.csd, &trans->cc.local, &trans->cc.remote); + LOG_TRANS_CAT_SRC(trans, DCC, LOGL_DEBUG, file, line, "codec/BS: %s\n", + csd_filter_to_str(&trans->cc.csd, &trans->cc.local, &trans->cc.remote)); + break; + default: + LOG_TRANS_CAT_SRC(trans, DCC, LOGL_ERROR, file, line, + "Handling of information transfer capability %d not implemented\n", + trans->bearer_cap.transfer); + break; + } +} + +void trans_cc_filter_set_ms_from_bc(struct gsm_trans *trans, const struct gsm_mncc_bearer_cap *bcap) +{ + trans->cc.codecs.ms = (struct sdp_audio_codecs){0}; + trans->cc.csd.ms = (struct csd_bs_list){0}; + + if (!bcap) + return; + + switch (bcap->transfer) { + case GSM48_BCAP_ITCAP_SPEECH: + sdp_audio_codecs_from_bearer_cap(&trans->cc.codecs.ms, bcap); + break; + case GSM48_BCAP_ITCAP_3k1_AUDIO: + case GSM48_BCAP_ITCAP_FAX_G3: + case GSM48_BCAP_ITCAP_UNR_DIG_INF: + sdp_audio_codecs_set_csd(&trans->cc.codecs.ms); + csd_bs_list_from_bearer_cap(&trans->cc.csd.ms, bcap); + break; + default: + LOG_TRANS(trans, LOGL_ERROR, "Handling of information transfer capability %d not implemented\n", + bcap->transfer); + break; + } +} + +void trans_cc_set_remote_from_bc(struct gsm_trans *trans, const struct gsm_mncc_bearer_cap *bcap) +{ + trans->cc.remote.audio_codecs = (struct sdp_audio_codecs){0}; + trans->cc.remote.bearer_services = (struct csd_bs_list){0}; + + if (!bcap) + return; + + switch (bcap->transfer) { + case GSM48_BCAP_ITCAP_SPEECH: + sdp_audio_codecs_from_bearer_cap(&trans->cc.remote.audio_codecs, bcap); + break; + case GSM48_BCAP_ITCAP_3k1_AUDIO: + case GSM48_BCAP_ITCAP_FAX_G3: + case GSM48_BCAP_ITCAP_UNR_DIG_INF: + sdp_audio_codecs_set_csd(&trans->cc.remote.audio_codecs); + csd_bs_list_from_bearer_cap(&trans->cc.remote.bearer_services, bcap); + break; + default: + LOG_TRANS(trans, LOGL_ERROR, "Handling of information transfer capability %d not implemented\n", + bcap->transfer); + break; + } +} diff --git a/src/libsmpputil/Makefile.am b/src/libsmpputil/Makefile.am new file mode 100644 index 000000000..b180ddf6f --- /dev/null +++ b/src/libsmpputil/Makefile.am @@ -0,0 +1,25 @@ +AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir) +AM_CFLAGS= \ + -Wall \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOVTY_CFLAGS) \ + $(LIBOSMOSCCP_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMONETIF_CFLAGS) \ + $(LIBOSMOMGCPCLIENT_CFLAGS) \ + $(LIBOSMOGSUPCLIENT_CFLAGS) \ + $(LIBSMPP34_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(NULL) + +noinst_HEADERS = \ + $(NULL) + +noinst_LIBRARIES = libsmpputil.a + +libsmpputil_a_SOURCES = \ + smpp_utils.c \ + smpp_vty.c \ + smpp_msc.c \ + smpp_smsc.c \ + $(NULL) diff --git a/src/libmsc/smpp_openbsc.c b/src/libsmpputil/smpp_msc.c index bbfc5008f..0c2a9282f 100644 --- a/src/libmsc/smpp_openbsc.c +++ b/src/libsmpputil/smpp_msc.c @@ -1,6 +1,6 @@ /* OpenBSC SMPP 3.4 interface, SMSC-side implementation */ -/* (C) 2012-2013 by Harald Welte <laforge@gnumonks.org> +/* (C) 2012-2022 by Harald Welte <laforge@gnumonks.org> * * All Rights Reserved * @@ -24,6 +24,7 @@ #include <string.h> #include <stdint.h> #include <errno.h> +#include <time.h> #include <smpp34.h> #include <smpp34_structs.h> @@ -47,8 +48,7 @@ #include <osmocom/msc/gsm_subscriber.h> #include <osmocom/msc/vlr.h> #include <osmocom/msc/msc_a.h> - -#include "smpp_smsc.h" +#include <osmocom/smpp/smpp_smsc.h> #define VSUB_USE_SMPP "SMPP" #define VSUB_USE_SMPP_CMD "SMPP-cmd" @@ -122,6 +122,8 @@ static int smpp34_submit_tlv_msg_payload(const struct tlv_t *t, static int submit_to_sms(struct gsm_sms **psms, struct gsm_network *net, const struct submit_sm_t *submit) { + time_t t_now = time(NULL); + time_t t_validity_absolute; const uint8_t *sms_msg = NULL; unsigned int sms_msg_len = 0; struct vlr_subscr *dest; @@ -239,10 +241,16 @@ static int submit_to_sms(struct gsm_sms **psms, struct gsm_network *net, } if (mode == MODE_7BIT) { - uint8_t ud_len = 0, padbits = 0; + unsigned int ud_len = 0, padbits = 0; sms->data_coding_scheme = GSM338_DCS_1111_7BIT; if (sms->ud_hdr_ind) { ud_len = *sms_msg + 1; + if (ud_len > sms_msg_len) { + sms_free(sms); + LOGP(DLSMS, LOGL_ERROR, "invalid ud_len=%u > sms_msg_len=%u\n", ud_len, + sms_msg_len); + return ESME_RINVPARLEN; + } printf("copying %u bytes user data...\n", ud_len); memcpy(sms->user_data, sms_msg, OSMO_MIN(ud_len, sizeof(sms->user_data))); @@ -250,8 +258,7 @@ static int submit_to_sms(struct gsm_sms **psms, struct gsm_network *net, sms_msg_len -= ud_len; padbits = 7 - (ud_len % 7); } - gsm_septets2octets(sms->user_data+ud_len, sms_msg, - sms_msg_len, padbits); + gsm_septet_pack(sms->user_data+ud_len, sms_msg, sms_msg_len, padbits); sms->user_data_len = (ud_len*8 + padbits)/7 + sms_msg_len;/* SEPTETS */ /* FIXME: sms->text */ } else { @@ -259,12 +266,25 @@ static int submit_to_sms(struct gsm_sms **psms, struct gsm_network *net, sms->user_data_len = sms_msg_len; } + t_validity_absolute = smpp_parse_time_format((const char *) submit->validity_period, &t_now); + if (!t_validity_absolute) + sms->validity_minutes = net->sms_queue_cfg->default_validity_mins; + else + sms->validity_minutes = (t_validity_absolute - t_now) / 60; + + if (sms->validity_minutes < net->sms_queue_cfg->minimum_validity_mins) { + LOGP(DLSMS, LOGL_INFO, "SMS to %s: Overriding ESME-provided validity period (%lu) " + "with minimum SMSC validity period (%u) minutes\n", submit->destination_addr, + sms->validity_minutes, net->sms_queue_cfg->minimum_validity_mins); + sms->validity_minutes = net->sms_queue_cfg->minimum_validity_mins; + } + *psms = sms; return ESME_ROK; } /*! \brief handle incoming libsmpp34 ssubmit_sm_t from remote ESME */ -int handle_smpp_submit(struct osmo_esme *esme, struct submit_sm_t *submit, +int handle_smpp_submit(struct smpp_esme *esme, struct submit_sm_t *submit, struct submit_sm_resp_t *submit_r) { struct gsm_sms *sms; @@ -315,21 +335,19 @@ int handle_smpp_submit(struct osmo_esme *esme, struct submit_sm_t *submit, static void alert_all_esme(struct smsc *smsc, struct vlr_subscr *vsub, uint8_t smpp_avail_status) { - struct osmo_esme *esme; + struct smpp_esme *esme; llist_for_each_entry(esme, &smsc->esme_list, list) { /* we currently send an alert notification to each ESME that is - * connected, and do not require a (non-existant) delivery + * connected, and do not require a (non-existent) delivery * pending flag to be set before. */ if (!esme->bind_flags) { LOGP(DSMPP, LOGL_DEBUG, "ESME is not (yet) bound, skipping alert\n"); continue; } - if (!esme->acl->alert_notifications) { - LOGP(DSMPP, LOGL_DEBUG, - "[%s] is not set to receive Alert Notifications\n", - esme->system_id); + if (esme->acl && !esme->acl->alert_notifications) { + LOGPESME(esme->esme, LOGL_DEBUG, "is not set to receive Alert Notifications\n"); continue; } if (esme->acl && esme->acl->deliver_src_imsi) { @@ -367,7 +385,7 @@ static int smpp_sms_cb(unsigned int subsys, unsigned int signal, * to the ESME */ case S_SMS_UNKNOWN_ERROR: if (sms->smpp.transaction_mode) { - /* Send back the SUBMIT-SM response with apropriate error */ + /* Send back the SUBMIT-SM response with appropriate error */ LOGP(DLSMS, LOGL_INFO, "SMPP SUBMIT-SM: Error\n"); rc = smpp_tx_submit_r(sms->smpp.esme, sms->smpp.sequence_nr, @@ -573,7 +591,7 @@ static void smpp_cmd_free(struct osmo_smpp_cmd *cmd) talloc_free(cmd); } -void smpp_cmd_flush_pending(struct osmo_esme *esme) +void smpp_cmd_flush_pending(struct smpp_esme *esme) { struct osmo_smpp_cmd *cmd, *next; @@ -641,7 +659,7 @@ static void smpp_deliver_sm_cb(void *data) smpp_cmd_err(data, ESME_RSYSERR); } -static int smpp_cmd_enqueue(struct osmo_esme *esme, +static int smpp_cmd_enqueue(struct smpp_esme *esme, struct vlr_subscr *vsub, struct gsm_sms *sms, uint32_t sequence_number) { @@ -670,7 +688,7 @@ static int smpp_cmd_enqueue(struct osmo_esme *esme, return 0; } -struct osmo_smpp_cmd *smpp_cmd_find_by_seqnum(struct osmo_esme *esme, +struct osmo_smpp_cmd *smpp_cmd_find_by_seqnum(struct smpp_esme *esme, uint32_t sequence_nr) { struct osmo_smpp_cmd *cmd; @@ -682,7 +700,7 @@ struct osmo_smpp_cmd *smpp_cmd_find_by_seqnum(struct osmo_esme *esme, return NULL; } -static int deliver_to_esme(struct osmo_esme *esme, struct gsm_sms *sms, +static int deliver_to_esme(struct smpp_esme *esme, struct gsm_sms *sms, struct msc_a *msc_a) { struct deliver_sm_t deliver; @@ -770,15 +788,18 @@ static int deliver_to_esme(struct osmo_esme *esme, struct gsm_sms *sms, sms->msg_ref); ret = smpp_tx_deliver(esme, &deliver); + destroy_tlv(deliver.tlv); if (ret < 0) return ret; + OSMO_ASSERT(!sms->smpp.esme); + smpp_esme_get(esme); + sms->smpp.esme = esme; + return smpp_cmd_enqueue(esme, vsub, sms, deliver.sequence_number); } -static struct smsc *g_smsc; - bool smpp_route_smpp_first() { return (bool)(g_smsc->smpp_first); @@ -786,7 +807,7 @@ bool smpp_route_smpp_first() int smpp_try_deliver(struct gsm_sms *sms, struct msc_a *msc_a) { - struct osmo_esme *esme; + struct smpp_esme *esme; struct osmo_smpp_addr dst; int rc; @@ -808,8 +829,8 @@ struct smsc *smsc_from_vty(struct vty *v) return g_smsc; } -/*! \brief Allocate the OpenBSC SMPP interface struct and init VTY. */ -int smpp_openbsc_alloc_init(void *ctx) +/*! \brief Allocate the OsmoMSC SMPP interface struct and init VTY. */ +int smpp_msc_alloc_init(void *ctx) { g_smsc = smpp_smsc_alloc_init(ctx); if (!g_smsc) { @@ -820,9 +841,9 @@ int smpp_openbsc_alloc_init(void *ctx) return smpp_vty_init(); } -/*! \brief Launch the OpenBSC SMPP interface with the parameters set from VTY. +/*! \brief Launch the OsmoMSC SMPP interface with the parameters set from VTY. */ -int smpp_openbsc_start(struct gsm_network *net) +int smpp_msc_start(struct gsm_network *net) { int rc; g_smsc->priv = net; @@ -843,4 +864,3 @@ int smpp_openbsc_start(struct gsm_network *net) return 0; } - diff --git a/src/libmsc/smpp_smsc.c b/src/libsmpputil/smpp_smsc.c index 3bfb81a3d..34e24c513 100644 --- a/src/libmsc/smpp_smsc.c +++ b/src/libsmpputil/smpp_smsc.c @@ -38,16 +38,11 @@ #include <osmocom/core/logging.h> #include <osmocom/core/write_queue.h> #include <osmocom/core/talloc.h> - -#include "smpp_smsc.h" +#include <osmocom/gsm/protocol/gsm_04_11.h> #include <osmocom/msc/debug.h> #include <osmocom/msc/gsm_data.h> - -/*! \brief Ugly wrapper. libsmpp34 should do this itself! */ -#define SMPP34_UNPACK(rc, type, str, data, len) \ - memset(str, 0, sizeof(*str)); \ - rc = smpp34_unpack(type, str, data, len) +#include <osmocom/smpp/smpp_smsc.h> enum emse_bind { ESME_BIND_RX = 0x01, @@ -164,12 +159,12 @@ void smpp_acl_delete(struct osmo_smpp_acl *acl) /* kill any active ESMEs */ if (acl->esme) { - struct osmo_esme *esme = acl->esme; + struct esme *esme = acl->esme->esme; osmo_fd_unregister(&esme->wqueue.bfd); close(esme->wqueue.bfd.fd); esme->wqueue.bfd.fd = -1; - esme->acl = NULL; - smpp_esme_put(esme); + smpp_esme_put(acl->esme); + acl->esme = NULL; } /* delete all routes for this ACL */ @@ -236,17 +231,17 @@ int smpp_route_pfx_del(struct osmo_smpp_acl *acl, /*! \brief increaes the use/reference count */ -void smpp_esme_get(struct osmo_esme *esme) +void smpp_esme_get(struct smpp_esme *esme) { esme->use++; } -static void esme_destroy(struct osmo_esme *esme) +static void esme_destroy(struct smpp_esme *esme) { - osmo_wqueue_clear(&esme->wqueue); - if (esme->wqueue.bfd.fd >= 0) { - osmo_fd_unregister(&esme->wqueue.bfd); - close(esme->wqueue.bfd.fd); + osmo_wqueue_clear(&esme->esme->wqueue); + if (esme->esme->wqueue.bfd.fd >= 0) { + osmo_fd_unregister(&esme->esme->wqueue.bfd); + close(esme->esme->wqueue.bfd.fd); } smpp_cmd_flush_pending(esme); llist_del(&esme->list); @@ -255,7 +250,7 @@ static void esme_destroy(struct osmo_esme *esme) talloc_free(esme); } -static uint32_t esme_inc_seq_nr(struct osmo_esme *esme) +uint32_t esme_inc_seq_nr(struct esme *esme) { esme->own_seq_nr++; if (esme->own_seq_nr > 0x7fffffff) @@ -265,7 +260,7 @@ static uint32_t esme_inc_seq_nr(struct osmo_esme *esme) } /*! \brief decrease the use/reference count, free if it is 0 */ -void smpp_esme_put(struct osmo_esme *esme) +void smpp_esme_put(struct smpp_esme *esme) { esme->use--; if (esme->use <= 0) @@ -273,7 +268,7 @@ void smpp_esme_put(struct osmo_esme *esme) } /*! \brief try to find a SMPP route (ESME) for given destination */ -int smpp_route(const struct smsc *smsc, const struct osmo_smpp_addr *dest, struct osmo_esme **pesme) +int smpp_route(const struct smsc *smsc, const struct osmo_smpp_addr *dest, struct smpp_esme **pesme) { struct osmo_smpp_route *r; struct osmo_smpp_acl *acl = NULL; @@ -313,56 +308,48 @@ int smpp_route(const struct smsc *smsc, const struct osmo_smpp_addr *dest, struc } if (acl && acl->esme) { - struct osmo_esme *esme; + struct smpp_esme *esme; DEBUGP(DSMPP, "ACL even has ESME, we can route to it!\n"); esme = acl->esme; if (esme->bind_flags & ESME_BIND_RX) { *pesme = esme; return 0; } else - LOGP(DSMPP, LOGL_NOTICE, "[%s] is matching route, " - "but not bound for Rx, discarding MO SMS\n", - esme->system_id); + LOGPESME(esme->esme, LOGL_NOTICE, "is matching route, but not bound for Rx, discarding MO SMS\n"); } *pesme = NULL; if (acl) - return GSM48_CC_CAUSE_NETWORK_OOO; + return GSM411_RP_CAUSE_MO_NET_OUT_OF_ORDER; else - return GSM48_CC_CAUSE_UNASSIGNED_NR; -} - - -/*! \brief initialize the libsmpp34 data structure for a response */ -#define INIT_RESP(type, resp, req) { \ - memset((resp), 0, sizeof(*(resp))); \ - (resp)->command_length = 0; \ - (resp)->command_id = type; \ - (resp)->command_status = ESME_ROK; \ - (resp)->sequence_number = (req)->sequence_number; \ + return GSM411_RP_CAUSE_MO_NUM_UNASSIGNED; } /*! \brief pack a libsmpp34 data strcutrure and send it to the ESME */ -#define PACK_AND_SEND(esme, ptr) pack_and_send(esme, (ptr)->command_id, ptr) -static int pack_and_send(struct osmo_esme *esme, uint32_t type, void *ptr) +int pack_and_send(struct esme *esme, uint32_t type, void *ptr) { - struct msgb *msg = msgb_alloc(4096, "SMPP_Tx"); + struct msgb *msg; int rc, rlen; + + /* the socket was closed. Avoid allocating + enqueueing msgb, see + * https://osmocom.org/issues/3278 */ + if (esme->wqueue.bfd.fd == -1) + return -EIO; + + msg = msgb_alloc(4096, "SMPP_Tx"); if (!msg) return -ENOMEM; rc = smpp34_pack(type, msg->tail, msgb_tailroom(msg), &rlen, ptr); if (rc != 0) { - LOGP(DSMPP, LOGL_ERROR, "[%s] Error during smpp34_pack(): %s\n", - esme->system_id, smpp34_strerror); + LOGPESMERR(esme, "during smpp34_pack()\n"); msgb_free(msg); return -EINVAL; } msgb_put(msg, rlen); if (osmo_wqueue_enqueue(&esme->wqueue, msg) != 0) { - LOGP(DSMPP, LOGL_ERROR, "[%s] Write queue full. Dropping message\n", - esme->system_id); + LOGPESME(esme, LOGL_ERROR, "Write queue full. Dropping message\n"); msgb_free(msg); return -EAGAIN; } @@ -370,7 +357,7 @@ static int pack_and_send(struct osmo_esme *esme, uint32_t type, void *ptr) } /*! \brief transmit a generic NACK to a remote ESME */ -static int smpp_tx_gen_nack(struct osmo_esme *esme, uint32_t seq, uint32_t status) +static int smpp_tx_gen_nack(struct esme *esme, uint32_t seq, uint32_t status) { struct generic_nack_t nack; char buf[SMALL_BUFF]; @@ -380,19 +367,11 @@ static int smpp_tx_gen_nack(struct osmo_esme *esme, uint32_t seq, uint32_t statu nack.sequence_number = seq; nack.command_status = status; - LOGP(DSMPP, LOGL_ERROR, "[%s] Tx GENERIC NACK: %s\n", - esme->system_id, str_command_status(status, buf)); + LOGPESME(esme, LOGL_ERROR, "Tx GENERIC NACK: %s\n", str_command_status(status, buf)); return PACK_AND_SEND(esme, &nack); } -/*! \brief retrieve SMPP command ID from a msgb */ -static inline uint32_t smpp_msgb_cmdid(struct msgb *msg) -{ - uint8_t *tmp = msgb_data(msg) + 4; - return ntohl(*(uint32_t *)tmp); -} - /*! \brief retrieve SMPP sequence number from a msgb */ static inline uint32_t smpp_msgb_seq(struct msgb *msg) { @@ -401,7 +380,7 @@ static inline uint32_t smpp_msgb_seq(struct msgb *msg) } /*! \brief handle an incoming SMPP generic NACK */ -static int smpp_handle_gen_nack(struct osmo_esme *esme, struct msgb *msg) +static int smpp_handle_gen_nack(struct esme *esme, struct msgb *msg) { struct generic_nack_t nack; char buf[SMALL_BUFF]; @@ -410,18 +389,16 @@ static int smpp_handle_gen_nack(struct osmo_esme *esme, struct msgb *msg) SMPP34_UNPACK(rc, GENERIC_NACK, &nack, msgb_data(msg), msgb_length(msg)); if (rc < 0) { - LOGP(DSMPP, LOGL_ERROR, "[%s] Error in smpp34_unpack():%s\n", - esme->system_id, smpp34_strerror); + LOGPESMERR(esme, "in smpp34_unpack()\n"); return rc; } - LOGP(DSMPP, LOGL_ERROR, "[%s] Rx GENERIC NACK: %s\n", - esme->system_id, str_command_status(nack.command_status, buf)); + LOGPESME(esme, LOGL_ERROR, "Rx GENERIC NACK: %s\n", str_command_status(nack.command_status, buf)); return 0; } -static int _process_bind(struct osmo_esme *esme, uint8_t if_version, +static int _process_bind(struct smpp_esme *esme, uint8_t if_version, uint32_t bind_flags, const char *sys_id, const char *passwd) { @@ -434,9 +411,9 @@ static int _process_bind(struct osmo_esme *esme, uint8_t if_version, return ESME_RALYBND; esme->smpp_version = if_version; - snprintf(esme->system_id, sizeof(esme->system_id), "%s", sys_id); + snprintf(esme->esme->system_id, sizeof(esme->esme->system_id), "%s", sys_id); - acl = smpp_acl_by_system_id(esme->smsc, esme->system_id); + acl = smpp_acl_by_system_id(esme->smsc, esme->esme->system_id); if (!esme->smsc->accept_all) { if (!acl) { /* This system is unknown */ @@ -460,7 +437,7 @@ static int _process_bind(struct osmo_esme *esme, uint8_t if_version, /*! \brief handle an incoming SMPP BIND RECEIVER */ -static int smpp_handle_bind_rx(struct osmo_esme *esme, struct msgb *msg) +static int smpp_handle_bind_rx(struct smpp_esme *esme, struct msgb *msg) { struct bind_receiver_t bind; struct bind_receiver_resp_t bind_r; @@ -469,8 +446,7 @@ static int smpp_handle_bind_rx(struct osmo_esme *esme, struct msgb *msg) SMPP34_UNPACK(rc, BIND_RECEIVER, &bind, msgb_data(msg), msgb_length(msg)); if (rc < 0) { - LOGP(DSMPP, LOGL_ERROR, "[%s] Error in smpp34_unpack():%s\n", - esme->system_id, smpp34_strerror); + LOGPESMERR(esme->esme, "in smpp34_unpack()\n"); return rc; } @@ -483,22 +459,21 @@ static int smpp_handle_bind_rx(struct osmo_esme *esme, struct msgb *msg) (const char *)bind.system_id, (const char *)bind.password); bind_r.command_status = rc; - return PACK_AND_SEND(esme, &bind_r); + return PACK_AND_SEND(esme->esme, &bind_r); } /*! \brief handle an incoming SMPP BIND TRANSMITTER */ -static int smpp_handle_bind_tx(struct osmo_esme *esme, struct msgb *msg) +static int smpp_handle_bind_tx(struct smpp_esme *esme, struct msgb *msg) { struct bind_transmitter_t bind; struct bind_transmitter_resp_t bind_r; - struct tlv_t tlv; + struct tlv_t tlv = {}; int rc; SMPP34_UNPACK(rc, BIND_TRANSMITTER, &bind, msgb_data(msg), msgb_length(msg)); if (rc < 0) { - LOGP(DSMPP, LOGL_ERROR, "[%s] Error in smpp34_unpack():%s\n", - esme->system_id, smpp34_strerror); + LOGPESMERR(esme->esme, "in smpp34_unpack()\n"); return rc; } @@ -520,13 +495,13 @@ static int smpp_handle_bind_tx(struct osmo_esme *esme, struct msgb *msg) tlv.value.val16 = esme->smpp_version; build_tlv(&bind_r.tlv, &tlv); - rc = PACK_AND_SEND(esme, &bind_r); + rc = PACK_AND_SEND(esme->esme, &bind_r); destroy_tlv(bind_r.tlv); return rc; } /*! \brief handle an incoming SMPP BIND TRANSCEIVER */ -static int smpp_handle_bind_trx(struct osmo_esme *esme, struct msgb *msg) +static int smpp_handle_bind_trx(struct smpp_esme *esme, struct msgb *msg) { struct bind_transceiver_t bind; struct bind_transceiver_resp_t bind_r; @@ -535,8 +510,7 @@ static int smpp_handle_bind_trx(struct osmo_esme *esme, struct msgb *msg) SMPP34_UNPACK(rc, BIND_TRANSCEIVER, &bind, msgb_data(msg), msgb_length(msg)); if (rc < 0) { - LOGP(DSMPP, LOGL_ERROR, "[%s] Error in smpp34_unpack():%s\n", - esme->system_id, smpp34_strerror); + LOGPESMERR(esme->esme, "in smpp34_unpack()\n"); return rc; } @@ -549,11 +523,11 @@ static int smpp_handle_bind_trx(struct osmo_esme *esme, struct msgb *msg) (const char *)bind.system_id, (const char *)bind.password); bind_r.command_status = rc; - return PACK_AND_SEND(esme, &bind_r); + return PACK_AND_SEND(esme->esme, &bind_r); } /*! \brief handle an incoming SMPP UNBIND */ -static int smpp_handle_unbind(struct osmo_esme *esme, struct msgb *msg) +static int smpp_handle_unbind(struct smpp_esme *esme, struct msgb *msg) { struct unbind_t unbind; struct unbind_resp_t unbind_r; @@ -562,14 +536,13 @@ static int smpp_handle_unbind(struct osmo_esme *esme, struct msgb *msg) SMPP34_UNPACK(rc, UNBIND, &unbind, msgb_data(msg), msgb_length(msg)); if (rc < 0) { - LOGP(DSMPP, LOGL_ERROR, "[%s] Error in smpp34_unpack():%s\n", - esme->system_id, smpp34_strerror); + LOGPESMERR(esme->esme, "in smpp34_unpack()\n"); return rc; } INIT_RESP(UNBIND_RESP, &unbind_r, &unbind); - LOGP(DSMPP, LOGL_INFO, "[%s] Rx UNBIND\n", esme->system_id); + LOGPESME(esme->esme, LOGL_INFO, "Rx UNBIND\n"); if (esme->bind_flags == 0) { unbind_r.command_status = ESME_RINVBNDSTS; @@ -578,11 +551,11 @@ static int smpp_handle_unbind(struct osmo_esme *esme, struct msgb *msg) esme->bind_flags = 0; err: - return PACK_AND_SEND(esme, &unbind_r); + return PACK_AND_SEND(esme->esme, &unbind_r); } /*! \brief handle an incoming SMPP ENQUIRE LINK */ -static int smpp_handle_enq_link(struct osmo_esme *esme, struct msgb *msg) +static int smpp_handle_enq_link(struct smpp_esme *esme, struct msgb *msg) { struct enquire_link_t enq; struct enquire_link_resp_t enq_r; @@ -591,22 +564,21 @@ static int smpp_handle_enq_link(struct osmo_esme *esme, struct msgb *msg) SMPP34_UNPACK(rc, ENQUIRE_LINK, &enq, msgb_data(msg), msgb_length(msg)); if (rc < 0) { - LOGP(DSMPP, LOGL_ERROR, "[%s] Error in smpp34_unpack():%s\n", - esme->system_id, smpp34_strerror); + LOGPESMERR(esme->esme, "in smpp34_unpack()\n"); return rc; } - LOGP(DSMPP, LOGL_DEBUG, "[%s] Rx Enquire Link\n", esme->system_id); + LOGPESME(esme->esme, LOGL_DEBUG, "Rx Enquire Link\n"); INIT_RESP(ENQUIRE_LINK_RESP, &enq_r, &enq); - LOGP(DSMPP, LOGL_DEBUG, "[%s] Tx Enquire Link Response\n", esme->system_id); + LOGPESME(esme->esme, LOGL_DEBUG, "Tx Enquire Link Response\n"); - return PACK_AND_SEND(esme, &enq_r); + return PACK_AND_SEND(esme->esme, &enq_r); } /*! \brief send a SUBMIT-SM RESPONSE to a remote ESME */ -int smpp_tx_submit_r(struct osmo_esme *esme, uint32_t sequence_nr, +int smpp_tx_submit_r(struct smpp_esme *esme, uint32_t sequence_nr, uint32_t command_status, char *msg_id) { struct submit_sm_resp_t submit_r; @@ -618,7 +590,7 @@ int smpp_tx_submit_r(struct osmo_esme *esme, uint32_t sequence_nr, submit_r.sequence_number= sequence_nr; snprintf((char *) submit_r.message_id, sizeof(submit_r.message_id), "%s", msg_id); - return PACK_AND_SEND(esme, &submit_r); + return PACK_AND_SEND(esme->esme, &submit_r); } static const struct value_string smpp_avail_strs[] = { @@ -629,7 +601,7 @@ static const struct value_string smpp_avail_strs[] = { }; /*! \brief send an ALERT_NOTIFICATION to a remote ESME */ -int smpp_tx_alert(struct osmo_esme *esme, uint8_t ton, uint8_t npi, +int smpp_tx_alert(struct smpp_esme *esme, uint8_t ton, uint8_t npi, const char *addr, uint8_t avail_status) { struct alert_notification_t alert; @@ -640,7 +612,7 @@ int smpp_tx_alert(struct osmo_esme *esme, uint8_t ton, uint8_t npi, alert.command_length = 0; alert.command_id = ALERT_NOTIFICATION; alert.command_status = ESME_ROK; - alert.sequence_number = esme_inc_seq_nr(esme); + alert.sequence_number = esme_inc_seq_nr(esme->esme); alert.source_addr_ton = ton; alert.source_addr_npi = npi; snprintf((char *)alert.source_addr, sizeof(alert.source_addr), "%s", addr); @@ -650,29 +622,28 @@ int smpp_tx_alert(struct osmo_esme *esme, uint8_t ton, uint8_t npi, tlv.value.val08 = avail_status; build_tlv(&alert.tlv, &tlv); - LOGP(DSMPP, LOGL_DEBUG, "[%s] Tx ALERT_NOTIFICATION (%s/%u/%u): %s\n", - esme->system_id, alert.source_addr, alert.source_addr_ton, - alert.source_addr_npi, - get_value_string(smpp_avail_strs, avail_status)); + LOGPESME(esme->esme, LOGL_DEBUG, "Tx ALERT_NOTIFICATION (%s/%u/%u): %s\n", + alert.source_addr, alert.source_addr_ton, + alert.source_addr_npi, + get_value_string(smpp_avail_strs, avail_status)); - rc = PACK_AND_SEND(esme, &alert); + rc = PACK_AND_SEND(esme->esme, &alert); destroy_tlv(alert.tlv); return rc; } /* \brief send a DELIVER-SM message to given ESME */ -int smpp_tx_deliver(struct osmo_esme *esme, struct deliver_sm_t *deliver) +int smpp_tx_deliver(struct smpp_esme *esme, struct deliver_sm_t *deliver) { - deliver->sequence_number = esme_inc_seq_nr(esme); + deliver->sequence_number = esme_inc_seq_nr(esme->esme); - LOGP(DSMPP, LOGL_DEBUG, "[%s] Tx DELIVER-SM (from %s)\n", - esme->system_id, deliver->source_addr); + LOGPESME(esme->esme, LOGL_DEBUG, "Tx DELIVER-SM (from %s)\n", deliver->source_addr); - return PACK_AND_SEND(esme, deliver); + return PACK_AND_SEND(esme->esme, deliver); } /*! \brief handle an incoming SMPP DELIVER-SM RESPONSE */ -static int smpp_handle_deliver_resp(struct osmo_esme *esme, struct msgb *msg) +static int smpp_handle_deliver_resp(struct smpp_esme *esme, struct msgb *msg) { struct deliver_sm_resp_t deliver_r; struct osmo_smpp_cmd *cmd; @@ -682,16 +653,14 @@ static int smpp_handle_deliver_resp(struct osmo_esme *esme, struct msgb *msg) SMPP34_UNPACK(rc, DELIVER_SM_RESP, &deliver_r, msgb_data(msg), msgb_length(msg)); if (rc < 0) { - LOGP(DSMPP, LOGL_ERROR, "[%s] Error in smpp34_unpack():%s\n", - esme->system_id, smpp34_strerror); + LOGPESMERR(esme->esme, "in smpp34_unpack()\n"); return rc; } cmd = smpp_cmd_find_by_seqnum(esme, deliver_r.sequence_number); if (!cmd) { - LOGP(DSMPP, LOGL_ERROR, "[%s] Rx DELIVER-SM RESP !? (%s)\n", - esme->system_id, get_value_string(smpp_status_strs, - deliver_r.command_status)); + LOGPESME(esme->esme, LOGL_ERROR, "Rx DELIVER-SM RESP !? (%s)\n", + get_value_string(smpp_status_strs, deliver_r.command_status)); return -1; } @@ -700,15 +669,14 @@ static int smpp_handle_deliver_resp(struct osmo_esme *esme, struct msgb *msg) else smpp_cmd_err(cmd, deliver_r.command_status); - LOGP(DSMPP, LOGL_INFO, "[%s] Rx DELIVER-SM RESP (%s)\n", - esme->system_id, get_value_string(smpp_status_strs, - deliver_r.command_status)); + LOGPESME(esme->esme, LOGL_INFO, "Rx DELIVER-SM RESP (%s)\n", + get_value_string(smpp_status_strs, deliver_r.command_status)); return 0; } /*! \brief handle an incoming SMPP SUBMIT-SM */ -static int smpp_handle_submit(struct osmo_esme *esme, struct msgb *msg) +static int smpp_handle_submit(struct smpp_esme *esme, struct msgb *msg) { struct submit_sm_t submit; struct submit_sm_resp_t submit_r; @@ -718,8 +686,7 @@ static int smpp_handle_submit(struct osmo_esme *esme, struct msgb *msg) SMPP34_UNPACK(rc, SUBMIT_SM, &submit, msgb_data(msg), msgb_length(msg)); if (rc < 0) { - LOGP(DSMPP, LOGL_ERROR, "[%s] Error in smpp34_unpack():%s\n", - esme->system_id, smpp34_strerror); + LOGPESMERR(esme->esme, "in smpp34_unpack()\n"); return rc; } @@ -727,34 +694,34 @@ static int smpp_handle_submit(struct osmo_esme *esme, struct msgb *msg) if (!(esme->bind_flags & ESME_BIND_TX)) { submit_r.command_status = ESME_RINVBNDSTS; - return PACK_AND_SEND(esme, &submit_r); + destroy_tlv(submit.tlv); + return PACK_AND_SEND(esme->esme, &submit_r); } - LOGP(DSMPP, LOGL_INFO, "[%s] Rx SUBMIT-SM (%s/%u/%u)\n", - esme->system_id, submit.destination_addr, - submit.dest_addr_ton, submit.dest_addr_npi); + LOGPESME(esme->esme, LOGL_INFO, "Rx SUBMIT-SM (%s/%u/%u)\n", + submit.destination_addr, submit.dest_addr_ton, submit.dest_addr_npi); INIT_RESP(SUBMIT_SM_RESP, &submit_r, &submit); rc = handle_smpp_submit(esme, &submit, &submit_r); + destroy_tlv(submit.tlv); if (rc == 0) - return PACK_AND_SEND(esme, &submit_r); + return PACK_AND_SEND(esme->esme, &submit_r); return rc; } /*! \brief one complete SMPP PDU from the ESME has been received */ -static int smpp_pdu_rx(struct osmo_esme *esme, struct msgb *msg __uses) +static int smpp_pdu_rx(struct smpp_esme *esme, struct msgb *msg __uses) { uint32_t cmd_id = smpp_msgb_cmdid(msg); int rc = 0; - LOGP(DSMPP, LOGL_DEBUG, "[%s] smpp_pdu_rx(%s)\n", esme->system_id, - msgb_hexdump(msg)); + LOGPESME(esme->esme, LOGL_DEBUG, "smpp_pdu_rx(%s)\n", msgb_hexdump(msg)); switch (cmd_id) { case GENERIC_NACK: - rc = smpp_handle_gen_nack(esme, msg); + rc = smpp_handle_gen_nack(esme->esme, msg); break; case BIND_RECEIVER: rc = smpp_handle_bind_rx(esme, msg); @@ -785,13 +752,11 @@ static int smpp_pdu_rx(struct osmo_esme *esme, struct msgb *msg __uses) case QUERY_SM: case REPLACE_SM: case SUBMIT_MULTI: - LOGP(DSMPP, LOGL_NOTICE, "[%s] Unimplemented PDU Command " - "0x%08x\n", esme->system_id, cmd_id); + LOGPESME(esme->esme, LOGL_NOTICE, "Unimplemented PDU Command 0x%08x\n", cmd_id); break; default: - LOGP(DSMPP, LOGL_ERROR, "[%s] Unknown PDU Command 0x%08x\n", - esme->system_id, cmd_id); - rc = smpp_tx_gen_nack(esme, smpp_msgb_seq(msg), ESME_RINVCMDID); + LOGPESME(esme->esme, LOGL_ERROR, "Unknown PDU Command 0x%08x\n", cmd_id); + rc = smpp_tx_gen_nack(esme->esme, smpp_msgb_seq(msg), ESME_RINVCMDID); break; } @@ -818,7 +783,8 @@ static int smpp_pdu_rx(struct osmo_esme *esme, struct msgb *msg __uses) /* !\brief call-back when per-ESME TCP socket has some data to be read */ static int esme_link_read_cb(struct osmo_fd *ofd) { - struct osmo_esme *esme = ofd->data; + struct smpp_esme *e = ofd->data; + struct esme *esme = e->esme; uint32_t len; uint8_t *lenptr = (uint8_t *) &len; uint8_t *cur; @@ -830,8 +796,7 @@ static int esme_link_read_cb(struct osmo_fd *ofd) rdlen = sizeof(uint32_t) - esme->read_idx; rc = read(ofd->fd, lenptr + esme->read_idx, rdlen); if (rc < 0) - LOGP(DSMPP, LOGL_ERROR, "[%s] read returned %zd (%s)\n", - esme->system_id, rc, strerror(errno)); + LOGPESME(esme, LOGL_ERROR, "read returned %zd (%s)\n", rc, strerror(errno)); OSMO_FD_CHECK_READ(rc, dead_socket); esme->read_idx += rc; @@ -839,8 +804,7 @@ static int esme_link_read_cb(struct osmo_fd *ofd) if (esme->read_idx >= sizeof(uint32_t)) { esme->read_len = ntohl(len); if (esme->read_len < 8 || esme->read_len > UINT16_MAX) { - LOGP(DSMPP, LOGL_ERROR, "[%s] length invalid %u\n", - esme->system_id, esme->read_len); + LOGPESME(esme, LOGL_ERROR, "length invalid %u\n", esme->read_len); goto dead_socket; } @@ -859,15 +823,15 @@ static int esme_link_read_cb(struct osmo_fd *ofd) rdlen = esme->read_len - esme->read_idx; rc = read(ofd->fd, msg->tail, OSMO_MIN(rdlen, msgb_tailroom(msg))); if (rc < 0) - LOGP(DSMPP, LOGL_ERROR, "[%s] read returned %zd (%s)\n", - esme->system_id, rc, strerror(errno)); + LOGPESME(esme, LOGL_ERROR, "read returned %zd (%s)\n", + rc, strerror(errno)); OSMO_FD_CHECK_READ(rc, dead_socket); esme->read_idx += rc; msgb_put(msg, rc); if (esme->read_idx >= esme->read_len) { - rc = smpp_pdu_rx(esme, esme->read_msg); + rc = smpp_pdu_rx(e, esme->read_msg); msgb_free(esme->read_msg); esme->read_msg = NULL; esme->read_idx = 0; @@ -883,66 +847,77 @@ dead_socket: osmo_fd_unregister(&esme->wqueue.bfd); close(esme->wqueue.bfd.fd); esme->wqueue.bfd.fd = -1; - if (esme->acl) - esme->acl->esme = NULL; - smpp_esme_put(esme); + if (e->acl) + e->acl->esme = NULL; + smpp_esme_put(e); - return 0; + return -EBADF; } /* call-back of write queue once it wishes to write a message to the socket */ static int esme_link_write_cb(struct osmo_fd *ofd, struct msgb *msg) { - struct osmo_esme *esme = ofd->data; + struct smpp_esme *esme = ofd->data; int rc; rc = write(ofd->fd, msgb_data(msg), msgb_length(msg)); if (rc == 0) { - osmo_fd_unregister(&esme->wqueue.bfd); - close(esme->wqueue.bfd.fd); - esme->wqueue.bfd.fd = -1; + osmo_fd_unregister(&esme->esme->wqueue.bfd); + close(esme->esme->wqueue.bfd.fd); + esme->esme->wqueue.bfd.fd = -1; if (esme->acl) esme->acl->esme = NULL; smpp_esme_put(esme); } else if (rc < msgb_length(msg)) { - LOGP(DSMPP, LOGL_ERROR, "[%s] Short write\n", esme->system_id); + LOGPESME(esme->esme, LOGL_ERROR, "Short write\n"); return -1; } return 0; } +struct esme *esme_alloc(void *ctx) +{ + struct esme *e = talloc_zero(ctx, struct esme); + if (!e) + return NULL; + + e->own_seq_nr = rand(); + esme_inc_seq_nr(e); + osmo_wqueue_init(&e->wqueue, 10); + + return e; +} + /* callback for already-accepted new TCP socket */ static int link_accept_cb(struct smsc *smsc, int fd, struct sockaddr_storage *s, socklen_t s_len) { - struct osmo_esme *esme = talloc_zero(smsc, struct osmo_esme); + struct smpp_esme *esme = talloc_zero(smsc, struct smpp_esme); if (!esme) { close(fd); return -ENOMEM; } + esme->esme = esme_alloc(esme); + if (!esme->esme) { + close(fd); + return -ENOMEM; + } + INIT_LLIST_HEAD(&esme->smpp_cmd_list); smpp_esme_get(esme); - esme->own_seq_nr = rand(); - esme_inc_seq_nr(esme); esme->smsc = smsc; - osmo_wqueue_init(&esme->wqueue, 10); - esme->wqueue.bfd.fd = fd; - esme->wqueue.bfd.data = esme; - esme->wqueue.bfd.when = BSC_FD_READ; + osmo_fd_setup(&esme->esme->wqueue.bfd, fd, OSMO_FD_READ, osmo_wqueue_bfd_cb, esme, 0); - if (osmo_fd_register(&esme->wqueue.bfd) != 0) { + if (osmo_fd_register(&esme->esme->wqueue.bfd) != 0) { close(fd); talloc_free(esme); return -EIO; } - esme->wqueue.read_cb = esme_link_read_cb; - esme->wqueue.write_cb = esme_link_write_cb; - - esme->sa_len = OSMO_MIN(sizeof(esme->sa), s_len); - memcpy(&esme->sa, s, esme->sa_len); + esme->esme->wqueue.read_cb = esme_link_read_cb; + esme->esme->wqueue.write_cb = esme_link_write_cb; llist_add_tail(&esme->list, &smsc->esme_list); @@ -988,17 +963,21 @@ int smpp_smsc_conf(struct smsc *smsc, const char *bind_addr, uint16_t port) /* Avoid use-after-free if bind_addr == smsc->bind_addr */ if (smsc->bind_addr == bind_addr) return 0; + osmo_talloc_replace_string(smsc, &smsc->bind_addr, bind_addr); - talloc_free((void*)smsc->bind_addr); - smsc->bind_addr = NULL; - if (bind_addr) { - smsc->bind_addr = bind_addr ? talloc_strdup(smsc, bind_addr) : NULL; - if (!smsc->bind_addr) - return -ENOMEM; - } return 0; } +/*! /brief Close SMPP connection. */ +static void smpp_smsc_stop(struct smsc *smsc) +{ + if (smsc->listen_ofd.fd > 0) { + close(smsc->listen_ofd.fd); + smsc->listen_ofd.fd = 0; + osmo_fd_unregister(&smsc->listen_ofd); + } +} + /*! \brief Bind to given address and port and accept connections. * \param[in] bind_addr Local IP address, may be NULL for any. * \param[in] port TCP port number, may be 0 for default SMPP (2775). @@ -1007,23 +986,17 @@ int smpp_smsc_start(struct smsc *smsc, const char *bind_addr, uint16_t port) { int rc; - /* default port for SMPP */ - if (!port) - port = 2775; - - smpp_smsc_stop(smsc); - LOGP(DSMPP, LOGL_NOTICE, "SMPP at %s %d\n", - bind_addr? bind_addr : "0.0.0.0", port); + bind_addr ? bind_addr : "0.0.0.0", port ? port : SMPP_PORT); rc = osmo_sock_init_ofd(&smsc->listen_ofd, AF_UNSPEC, SOCK_STREAM, - IPPROTO_TCP, bind_addr, port, + IPPROTO_TCP, bind_addr, port ? port : SMPP_PORT, OSMO_SOCK_F_BIND); if (rc < 0) return rc; /* store new address and port */ - rc = smpp_smsc_conf(smsc, bind_addr, port); + rc = smpp_smsc_conf(smsc, bind_addr, port ? port : SMPP_PORT); if (rc) smpp_smsc_stop(smsc); return rc; @@ -1035,19 +1008,11 @@ int smpp_smsc_restart(struct smsc *smsc, const char *bind_addr, uint16_t port) { int rc; + smpp_smsc_stop(smsc); + rc = smpp_smsc_start(smsc, bind_addr, port); if (rc) /* if there is an error, try to re-bind to the old port */ return smpp_smsc_start(smsc, smsc->bind_addr, smsc->listen_port); return 0; } - -/*! /brief Close SMPP connection. */ -void smpp_smsc_stop(struct smsc *smsc) -{ - if (smsc->listen_ofd.fd > 0) { - close(smsc->listen_ofd.fd); - smsc->listen_ofd.fd = 0; - osmo_fd_unregister(&smsc->listen_ofd); - } -} diff --git a/src/libsmpputil/smpp_utils.c b/src/libsmpputil/smpp_utils.c new file mode 100644 index 000000000..bada97217 --- /dev/null +++ b/src/libsmpputil/smpp_utils.c @@ -0,0 +1,174 @@ + +/* (C) 2012-2022 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 "config.h" + +#include <time.h> + +#include <osmocom/core/logging.h> +#include <osmocom/netif/stream.h> +#include <osmocom/smpp/smpp_smsc.h> + +/*! \brief retrieve SMPP command ID from a msgb */ +uint32_t smpp_msgb_cmdid(struct msgb *msg) +{ + uint8_t *tmp = msgb_data(msg) + 4; + return ntohl(*(uint32_t *)tmp); +} + +int smpp_determine_scheme(uint8_t dcs, uint8_t *data_coding, int *mode) +{ + if ((dcs & 0xF0) == 0xF0) { + if (dcs & 0x04) { + /* bit 2 == 1: 8bit data */ + *data_coding = 0x02; + *mode = MODE_8BIT; + } else { + /* bit 2 == 0: default alphabet */ + *data_coding = 0x01; + *mode = MODE_7BIT; + } + } else if ((dcs & 0xE0) == 0) { + switch (dcs & 0xC) { + case 0: + *data_coding = 0x01; + *mode = MODE_7BIT; + break; + case 4: + *data_coding = 0x02; + *mode = MODE_8BIT; + break; + case 8: + *data_coding = 0x08; /* UCS-2 */ + *mode = MODE_8BIT; + break; + default: + goto unknown_mo; + } + } else { +unknown_mo: + LOGP(DLSMS, LOGL_ERROR, "SMPP MO Unknown Data Coding 0x%02x\n", dcs); + return -1; + } + + return 0; + +} + +/* convert a 'struct tm' holding relative time to an absolute one by adding it to t_now */ +static void relative2absolute(struct tm *tm, time_t t_now) +{ + struct tm tm_now; + + localtime_r(&t_now, &tm_now); + + tm->tm_year += tm_now.tm_year; + tm->tm_mon += tm_now.tm_mon; + tm->tm_mday += tm_now.tm_mday; + tm->tm_hour += tm_now.tm_hour; + tm->tm_min += tm_now.tm_min; + tm->tm_sec += tm_now.tm_sec; +} + +#ifndef HAVE_TIMEGM +/* for systems without a timegm() function, provide a reimplementation */ +static time_t timegm(struct tm *tm) +{ + const char *orig_tz = getenv("TZ"); + time_t ret; + + setenv("TZ", "UTC", 1); + + ret = mktime(tm); + + if (orig_tz) + setenv("TZ", orig_tz, 1); + else + unsetenv("TZ"); + + return ret; +} +#endif + + +/*! Parse a SMPP time format as defined in SMPP v3.4 7.1.1. + * \param[in] vp string containing the time as encoded in SMPP v3.4 + * \param[in] t_now pointer to a time value for 'now'. Can be NULL, then we call time() ourselves. + * \returns time_t value in seconds since the epoch of the absolute decoded time */ +time_t smpp_parse_time_format(const char *vp, time_t *t_now) +{ + unsigned int year, month, day, hour, minute, second, tenth, gmt_off_quarter; + char plus_minus_relative; + int gmt_off_minutes; + struct tm tm; + time_t ret; + int rc; + + memset(&tm, 0, sizeof(tm)); + + if (vp[0] == '\0') + return 0; + + /* YYMMDDhhmmsstnnp (where p can be -, + or R) */ + rc = sscanf(vp, "%2u%2u%2u%2u%2u%2u%1u%2u%c", &year, &month, &day, &hour, &minute, + &second, &tenth, &gmt_off_quarter, &plus_minus_relative); + if (rc != 9) + return (time_t) -1; + + tm.tm_year = year; + /* month handling differs between absolute/relative below... */ + tm.tm_mday = day; + tm.tm_hour = hour; + tm.tm_min = minute; + tm.tm_sec = second; + tm.tm_isdst = 0; + + switch (plus_minus_relative) { + case '+': /* time is in quarter hours advanced compared to UTC */ + if (year < 70) + tm.tm_year += 100; + tm.tm_mon = month - 1; + gmt_off_minutes = 15 * gmt_off_quarter; + tm.tm_min -= gmt_off_minutes; + ret = timegm(&tm); + break; + case '-': /* time is in quarter hours retared compared to UTC */ + if (year < 70) + tm.tm_year += 100; + tm.tm_mon = month - 1; + gmt_off_minutes = 15 * gmt_off_quarter; + tm.tm_min += gmt_off_minutes; + ret = timegm(&tm); + break; + case 'R': + /* relative time */ + tm.tm_mon = month; + if (t_now) + relative2absolute(&tm, *t_now); + else + relative2absolute(&tm, time(NULL)); + /* here we do want local time, as we're passing local time in above! */ + ret = mktime(&tm); + break; + default: + return (time_t) -1; + } + + return ret; +} diff --git a/src/libmsc/smpp_vty.c b/src/libsmpputil/smpp_vty.c index 9026f6cf5..c6e642161 100644 --- a/src/libmsc/smpp_vty.c +++ b/src/libsmpputil/smpp_vty.c @@ -30,11 +30,11 @@ #include <osmocom/core/linuxlist.h> #include <osmocom/core/utils.h> +#include <osmocom/core/socket.h> #include <osmocom/core/talloc.h> #include <osmocom/msc/vty.h> - -#include "smpp_smsc.h" +#include <osmocom/smpp/smpp_smsc.h> struct smsc *smsc_from_vty(struct vty *v); @@ -80,8 +80,8 @@ static int smpp_local_tcp(struct vty *vty, const char *bind_addr, uint16_t port) { struct smsc *smsc = smsc_from_vty(vty); - int is_running = smsc->listen_ofd.fd > 0; - int same_bind_addr; + bool is_running = smsc->listen_ofd.fd > 0; + bool same_bind_addr; int rc; /* If it is not up yet, don't rebind, just set values. */ @@ -501,7 +501,7 @@ DEFUN(cfg_esme_no_dcs_transp, cfg_esme_no_dcs_transp_cmd, DEFUN(cfg_esme_alert_notif, cfg_esme_alert_notif_cmd, "alert-notifications", - "Disable sending of SMPP Alert Notifications for this ESME") + "Enable sending of SMPP Alert Notifications for this ESME") { struct osmo_smpp_acl *acl = vty->index; @@ -522,19 +522,12 @@ DEFUN(cfg_esme_no_alert_notif, cfg_esme_no_alert_notif_cmd, } -static void dump_one_esme(struct vty *vty, struct osmo_esme *esme) +static void dump_one_esme(struct vty *vty, struct smpp_esme *esme) { - char host[128], serv[128]; - - host[0] = 0; - serv[0] = 0; - getnameinfo((const struct sockaddr *) &esme->sa, esme->sa_len, - host, sizeof(host), serv, sizeof(serv), NI_NUMERICSERV); - vty_out(vty, "ESME System ID: %s, Password: %s, SMPP Version %02x%s", - esme->system_id, esme->acl ? esme->acl->passwd : "", + esme->esme->system_id, esme->acl ? esme->acl->passwd : "", esme->smpp_version, VTY_NEWLINE); - vty_out(vty, " Connected from: %s:%s%s", host, serv, VTY_NEWLINE); + vty_out(vty, " Connection %s%s", osmo_sock_get_name(tall_vty_ctx, esme->esme->wqueue.bfd.fd), VTY_NEWLINE); if (esme->smsc->def_route == esme->acl) vty_out(vty, " Is current default route%s", VTY_NEWLINE); } @@ -544,7 +537,7 @@ DEFUN(show_esme, show_esme_cmd, SHOW_STR "SMPP Interface\n" "SMPP External SMS Entity\n") { struct smsc *smsc = smsc_from_vty(vty); - struct osmo_esme *esme; + struct smpp_esme *esme; llist_for_each_entry(esme, &smsc->esme_list, list) dump_one_esme(vty, esme); diff --git a/src/libvlr/vlr.c b/src/libvlr/vlr.c index b156b430b..cb5794f30 100644 --- a/src/libvlr/vlr.c +++ b/src/libvlr/vlr.c @@ -23,7 +23,9 @@ #include <osmocom/core/fsm.h> #include <osmocom/core/utils.h> #include <osmocom/core/timer.h> +#include <osmocom/core/tdef.h> #include <osmocom/gsm/protocol/gsm_04_08_gprs.h> +#include <osmocom/gsm/gsm23236.h> #include <osmocom/gsm/gsup.h> #include <osmocom/gsm/apn.h> #include <osmocom/gsm/gsm48.h> @@ -34,6 +36,7 @@ #include <osmocom/msc/vlr.h> #include <osmocom/msc/debug.h> #include <osmocom/msc/gsup_client_mux.h> +#include <osmocom/msc/paging.h> #include <netinet/in.h> #include <arpa/inet.h> @@ -49,10 +52,139 @@ #define SGSN_SUBSCR_MAX_RETRIES 3 #define SGSN_SUBSCR_RETRY_INTERVAL 10 +enum vlr_stat_item_idx { + VLR_STAT_SUBSCRIBER_COUNT, + VLR_STAT_PDP_COUNT, +}; + +static const struct osmo_stat_item_desc vlr_stat_item_desc[] = { + [VLR_STAT_SUBSCRIBER_COUNT] = { "subscribers", + "Number of subscribers present in VLR" }, + [VLR_STAT_PDP_COUNT] = { "pdp", + "Number of PDP records present in VLR" }, +}; + +static const struct osmo_stat_item_group_desc vlr_statg_desc = { + "vlr", + "visitor location register", + OSMO_STATS_CLASS_GLOBAL, + ARRAY_SIZE(vlr_stat_item_desc), + vlr_stat_item_desc, +}; + +enum vlr_rate_ctr_idx { + VLR_CTR_GSUP_RX_UNKNOWN_IMSI, + VLR_CTR_GSUP_RX_PURGE_NO_SUBSCR, + VLR_CTR_GSUP_RX_TUPLES, + VLR_CTR_GSUP_RX_UL_RES, + VLR_CTR_GSUP_RX_UL_ERR, + VLR_CTR_GSUP_RX_SAI_RES, + VLR_CTR_GSUP_RX_SAI_ERR, + VLR_CTR_GSUP_RX_ISD_REQ, + VLR_CTR_GSUP_RX_CANCEL_REQ, + VLR_CTR_GSUP_RX_CHECK_IMEI_RES, + VLR_CTR_GSUP_RX_CHECK_IMEI_ERR, + VLR_CTR_GSUP_RX_PURGE_MS_RES, + VLR_CTR_GSUP_RX_PURGE_MS_ERR, + VLR_CTR_GSUP_RX_DELETE_DATA_REQ, + VLR_CTR_GSUP_RX_UNKNOWN, + + VLR_CTR_GSUP_TX_UL_REQ, + VLR_CTR_GSUP_TX_ISD_RES, + VLR_CTR_GSUP_TX_SAI_REQ, + VLR_CTR_GSUP_TX_PURGE_MS_REQ, + VLR_CTR_GSUP_TX_CHECK_IMEI_REQ, + VLR_CTR_GSUP_TX_AUTH_FAIL_REP, + VLR_CTR_GSUP_TX_CANCEL_RES, + + VLR_CTR_DETACH_BY_REQ, + VLR_CTR_DETACH_BY_CANCEL, + VLR_CTR_DETACH_BY_T3212, +}; + +static const struct rate_ctr_desc vlr_ctr_desc[] = { + [VLR_CTR_GSUP_RX_UNKNOWN_IMSI] = { "gsup:rx:unknown_imsi", + "Received GSUP messages for unknown IMSI" }, + [VLR_CTR_GSUP_RX_PURGE_NO_SUBSCR] = { "gsup:rx:purge_no_subscr", + "Received GSUP purge for unknown subscriber" }, + [VLR_CTR_GSUP_RX_TUPLES] = { "gsup:rx:auth_tuples", + "Received GSUP authentication tuples" }, + [VLR_CTR_GSUP_RX_UL_RES] = { "gsup:rx:upd_loc:res", + "Received GSUP Update Location Result messages" }, + [VLR_CTR_GSUP_RX_UL_ERR] = { "gsup:rx:upd_loc:err", + "Received GSUP Update Location Error messages" }, + [VLR_CTR_GSUP_RX_SAI_RES] = { "gsup:rx:send_auth_info:res", + "Received GSUP Send Auth Info Result messages" }, + [VLR_CTR_GSUP_RX_SAI_ERR] = { "gsup:rx:send_auth_info:err", + "Received GSUP Send Auth Info Error messages" }, + [VLR_CTR_GSUP_RX_ISD_REQ] = { "gsup:rx:ins_sub_data:req", + "Received GSUP Insert Subscriber Data Request messages" }, + [VLR_CTR_GSUP_RX_CANCEL_REQ] = { "gsup:rx:cancel:req", + "Received GSUP Cancel Subscriber messages" }, + [VLR_CTR_GSUP_RX_CHECK_IMEI_RES] = { "gsup:rx:check_imei:res", + "Received GSUP Check IMEI Result messages" }, + [VLR_CTR_GSUP_RX_CHECK_IMEI_ERR] = { "gsup:rx:check_imei:err", + "Received GSUP Check IMEI Error messages" }, + [VLR_CTR_GSUP_RX_PURGE_MS_RES] = { "gsup:rx:purge_ms:res", + "Received GSUP Purge MS Result messages" }, + [VLR_CTR_GSUP_RX_PURGE_MS_ERR] = { "gsup:rx:purge_ms:err", + "Received GSUP Purge MS Error messages" }, + [VLR_CTR_GSUP_RX_DELETE_DATA_REQ] = { "gsup:rx:del_sub_data:req", + "Received GSUP Delete Subscriber Data Request messages" }, + [VLR_CTR_GSUP_RX_UNKNOWN] = { "gsup:rx:unknown_msgtype", + "Received GSUP message of unknown type" }, + + [VLR_CTR_GSUP_TX_UL_REQ] = { "gsup:tx:upd_loc:req", + "Transmitted GSUP Update Location Request messages" }, + [VLR_CTR_GSUP_TX_ISD_RES] = { "gsup:tx:ins_sub_data:res", + "Transmitted GSUP Insert Subscriber Data Result messages" }, + [VLR_CTR_GSUP_TX_SAI_REQ] = { "gsup:tx:send_auth_info:res", + "Transmitted GSUP Send Auth Info Request messages" }, + [VLR_CTR_GSUP_TX_PURGE_MS_REQ] = { "gsup:tx:purge_ms:req", + "Transmitted GSUP Purge MS Request messages" }, + [VLR_CTR_GSUP_TX_CHECK_IMEI_REQ] = { "gsup:tx:check_imei:req", + "Transmitted GSUP Check IMEI Request messages" }, + [VLR_CTR_GSUP_TX_AUTH_FAIL_REP] = { "gsup:tx:auth_fail:rep", + "Transmitted GSUP Auth Fail Report messages" }, + [VLR_CTR_GSUP_TX_CANCEL_RES] = { "gsup:tx:cancel:res", + "Transmitted GSUP Cancel Result messages" }, + + [VLR_CTR_DETACH_BY_REQ] = { "detach:imsi_det_req", + "VLR Subscriber Detach by IMSI DETACH REQ" }, + [VLR_CTR_DETACH_BY_CANCEL] = { "detach:gsup_cancel_req", + "VLR Subscriber Detach by GSUP CANCEL REQ" }, + [VLR_CTR_DETACH_BY_T3212] = { "detach:t3212_timeout", + "VLR Subscriber Detach by T3212 timeout" }, +}; + +static const struct rate_ctr_group_desc vlr_ctrg_desc = { + "vlr", + "visitor location register", + OSMO_STATS_CLASS_GLOBAL, + ARRAY_SIZE(vlr_ctr_desc), + vlr_ctr_desc, +}; + + +#define vlr_rate_ctr_inc(vlr, idx) \ + rate_ctr_inc(rate_ctr_group_get_ctr((vlr)->ctrg, idx)) +#define vlr_rate_ctr_add(vlr, idx, val) \ + rate_ctr_add(rate_ctr_group_get_ctr((vlr)->ctrg, idx), val) + +#define vlr_stat_item_inc(vlr, idx) \ + osmo_stat_item_inc(osmo_stat_item_group_get_item((vlr)->statg, idx), 1) +#define vlr_stat_item_dec(vlr, idx) \ + osmo_stat_item_dec(osmo_stat_item_group_get_item((vlr)->statg, idx), 1) +#define vlr_stat_item_set(vlr, idx, val) \ + osmo_stat_item_set(osmo_stat_item_group_get_item((vlr)->statg, idx), val) + + /*********************************************************************** * Convenience functions ***********************************************************************/ +static int vlr_subscr_detach(struct vlr_subscr *vsub); + const struct value_string vlr_ciph_names[] = { OSMO_VALUE_STRING(VLR_CIPH_NONE), OSMO_VALUE_STRING(VLR_CIPH_A5_1), @@ -61,24 +193,23 @@ const struct value_string vlr_ciph_names[] = { { 0, NULL } }; +/* 3GPP TS 24.008, table 11.2 Mobility management timers (network-side) */ +struct osmo_tdef msc_tdefs_vlr[] = { + { .T = 3212, .default_val = 60, .unit = OSMO_TDEF_M, .desc = "Subscriber expiration timeout" }, + { .T = 3250, .default_val = 12, .desc = "TMSI Reallocation procedure" }, + { .T = 3260, .default_val = 12, .desc = "Authentication procedure" }, + { .T = 3270, .default_val = 12, .desc = "Identification procedure" }, + { /* terminator */ } +}; + +/* This is just a wrapper around the osmo_tdef API. + * TODO: we should start using osmo_tdef_fsm_inst_state_chg() */ uint32_t vlr_timer(struct vlr_instance *vlr, uint32_t timer) { - uint32_t tidx = 0xffffffff; - - switch (timer) { - case 3270: - tidx = VLR_T_3270; - break; - case 3260: - tidx = VLR_T_3260; - break; - case 3250: - tidx = VLR_T_3250; - break; - } - - OSMO_ASSERT(tidx < sizeof(vlr->cfg.timer)); - return vlr->cfg.timer[tidx]; + /* NOTE: since we usually do not need more than one instance of the VLR, + * and since libosmocore's osmo_tdef API does not (yet) support dynamic + * configuration, we always use the global instance of msc_tdefs_vlr. */ + return osmo_tdef_get(msc_tdefs_vlr, timer, OSMO_TDEF_S, 0); } /* return static buffer with printable name of VLR subscriber */ @@ -142,7 +273,8 @@ struct vlr_subscr *_vlr_subscr_find_by_imsi(struct vlr_instance *vlr, llist_for_each_entry(vsub, &vlr->subscribers, list) { if (vlr_subscr_matches_imsi(vsub, imsi)) { - vlr_subscr_get_src(vsub, use, file, line); + if (use) + vlr_subscr_get_src(vsub, use, file, line); return vsub; } } @@ -187,6 +319,21 @@ struct vlr_subscr *_vlr_subscr_find_by_msisdn(struct vlr_instance *vlr, return NULL; } +struct vlr_subscr *_vlr_subscr_find_by_mi(struct vlr_instance *vlr, + const struct osmo_mobile_identity *mi, + const char *use, + const char *file, int line) +{ + switch (mi->type) { + case GSM_MI_TYPE_IMSI: + return _vlr_subscr_find_by_imsi(vlr, mi->imsi, use, file, line); + case GSM_MI_TYPE_TMSI: + return _vlr_subscr_find_by_tmsi(vlr, mi->tmsi, use, file, line); + default: + return NULL; + } +} + /* Transmit GSUP message for subscriber to HLR, using IMSI from subscriber */ static int vlr_subscr_tx_gsup_message(const struct vlr_subscr *vsub, struct osmo_gsup_message *gsup_msg) @@ -264,6 +411,7 @@ static struct vlr_subscr *_vlr_subscr_alloc(struct vlr_instance *vlr) vlr_sgs_fsm_create(vsub); llist_add_tail(&vsub->list, &vlr->subscribers); + vlr_stat_item_inc(vlr, VLR_STAT_SUBSCRIBER_COUNT); return vsub; } @@ -274,6 +422,8 @@ int vlr_subscr_purge(struct vlr_subscr *vsub) { struct osmo_gsup_message gsup_msg = {0}; + vlr_rate_ctr_inc(vsub->vlr, VLR_CTR_GSUP_TX_PURGE_MS_REQ); + gsup_msg.message_type = OSMO_GSUP_MSGT_PURGE_MS_REQUEST; /* provide HLR number in case we know it */ @@ -302,6 +452,7 @@ void vlr_subscr_cancel_attach_fsm(struct vlr_subscr *vsub, void vlr_subscr_free(struct vlr_subscr *vsub) { llist_del(&vsub->list); + vlr_stat_item_dec(vsub->vlr, VLR_STAT_SUBSCRIBER_COUNT); DEBUGP(DVLR, "freeing VLR subscr %s (max total use count was %d)\n", vlr_subscr_name(vsub), vsub->max_total_use_count); @@ -329,6 +480,15 @@ int vlr_subscr_alloc_tmsi(struct vlr_subscr *vsub) LOGP(DDB, LOGL_ERROR, "osmo_get_rand_id() failed: %s\n", strerror(-rc)); return rc; } + + if (!llist_empty(&vlr->cfg.nri_ranges->entries)) { + int16_t nri_v; + osmo_tmsi_nri_v_limit_by_ranges(&tmsi, vlr->cfg.nri_ranges, vlr->cfg.nri_bitlen); + osmo_tmsi_nri_v_get(&nri_v, tmsi, vlr->cfg.nri_bitlen); + LOGP(DVLR, LOGL_DEBUG, "New NRI from range [%s] = 0x%x --> TMSI 0x%08x\n", + osmo_nri_ranges_to_str_c(OTC_SELECT, vlr->cfg.nri_ranges), nri_v, tmsi); + } + /* throw the dice again, if the TSMI doesn't fit */ if (tmsi == GSM_RESERVED_TMSI) continue; @@ -336,11 +496,11 @@ int vlr_subscr_alloc_tmsi(struct vlr_subscr *vsub) /* Section 2.4 of 23.003: MSC has two MSB 00/01/10, SGSN 11 */ if (vlr->cfg.is_ps) { /* SGSN */ - tmsi |= 0xC000000; + tmsi |= GSM23003_TMSI_SGSN_MASK; } else { /* MSC */ - if ((tmsi & 0xC0000000) == 0xC0000000) - tmsi &= ~0xC0000000; + if ((tmsi & GSM23003_TMSI_SGSN_MASK) == GSM23003_TMSI_SGSN_MASK) + tmsi &= ~GSM23003_TMSI_SGSN_MASK; } /* If this TMSI is already in use, try another one. */ @@ -360,7 +520,7 @@ int vlr_subscr_alloc_tmsi(struct vlr_subscr *vsub) } /* Find subscriber by IMSI, or create new subscriber if not found. - * \param[in] vlr VLR instace. + * \param[in] vlr VLR instance. * \param[in] imsi IMSI string. * \param[out] created if non-NULL, returns whether a new entry was created. */ struct vlr_subscr *_vlr_subscr_find_or_create_by_imsi(struct vlr_instance *vlr, @@ -390,7 +550,7 @@ struct vlr_subscr *_vlr_subscr_find_or_create_by_imsi(struct vlr_instance *vlr, } /* Find subscriber by TMSI, or create new subscriber if not found. - * \param[in] vlr VLR instace. + * \param[in] vlr VLR instance. * \param[in] tmsi TMSI. * \param[out] created if non-NULL, returns whether a new entry was created. */ struct vlr_subscr *_vlr_subscr_find_or_create_by_tmsi(struct vlr_instance *vlr, @@ -419,11 +579,63 @@ struct vlr_subscr *_vlr_subscr_find_or_create_by_tmsi(struct vlr_instance *vlr, return vsub; } +static void dedup_vsub(struct vlr_subscr *exists, struct vlr_subscr *vsub) +{ + struct vlr_instance *vlr = exists->vlr; + int i; + int j; + LOGP(DVLR, LOGL_NOTICE, + "There is an existing subscriber for IMSI %s used by %s, replacing with new VLR subscr: %s used by %s\n", + exists->imsi, osmo_use_count_to_str_c(OTC_SELECT, &exists->use_count), + vlr_subscr_name(vsub), + osmo_use_count_to_str_c(OTC_SELECT, &vsub->use_count)); + + /* Take over some state from the previous vsub */ + paging_request_join_vsub(vsub, exists); + if (!vsub->msisdn[0]) + OSMO_STRLCPY_ARRAY(vsub->msisdn, exists->msisdn); + if (!vsub->name[0]) + OSMO_STRLCPY_ARRAY(vsub->name, exists->name); + /* Copy valid auth tuples we may already have, to reduce the need to ask for new ones from the HLR */ + for (i = 0; i < ARRAY_SIZE(exists->auth_tuples); i++) { + if (exists->auth_tuples[i].key_seq == VLR_KEY_SEQ_INVAL) + continue; + for (j = 0; j < ARRAY_SIZE(vsub->auth_tuples); j++) { + if (vsub->auth_tuples[j].key_seq != VLR_KEY_SEQ_INVAL) + continue; + vsub->auth_tuples[j] = exists->auth_tuples[i]; + } + } + + if (exists->msc_conn_ref) + LOGVSUBP(LOGL_ERROR, vsub, + "There is an existing VLR entry for this same subscriber with an active connection." + " That should not be possible. Discarding old subscriber entry %s.\n", + exists->imsi); + + if (vlr->ops.subscr_inval) + vlr->ops.subscr_inval(exists->msc_conn_ref, exists); + vlr_subscr_free(exists); +} + void vlr_subscr_set_imsi(struct vlr_subscr *vsub, const char *imsi) { + struct vlr_subscr *exists; if (!vsub) return; + /* If the same IMSI is already set, nothing changes. */ + if (!strcmp(vsub->imsi, imsi)) + return; + + /* We've just learned about this new IMSI, our primary key in the VLR. make sure to invalidate any prior VLR + * entries for this IMSI. */ + exists = vlr_subscr_find_by_imsi(vsub->vlr, imsi, NULL); + + if (exists) + dedup_vsub(exists, vsub); + + /* Set the IMSI on the new subscriber, here. */ if (OSMO_STRLCPY_ARRAY(vsub->imsi, imsi) >= sizeof(vsub->imsi)) { LOGP(DVLR, LOGL_NOTICE, "IMSI was truncated: full IMSI=%s, truncated IMSI=%s\n", imsi, vsub->imsi); @@ -466,6 +678,23 @@ void vlr_subscr_set_msisdn(struct vlr_subscr *vsub, const char *msisdn) vsub->imsi, vsub->msisdn); } +void vlr_subscr_set_last_used_eutran_plmn_id(struct vlr_subscr *vsub, + const struct osmo_plmn_id *last_eutran_plmn) +{ + if (!vsub) + return; + if (last_eutran_plmn) { + vsub->sgs.last_eutran_plmn_present = true; + memcpy(&vsub->sgs.last_eutran_plmn, last_eutran_plmn, sizeof(*last_eutran_plmn)); + } else { + vsub->sgs.last_eutran_plmn_present = false; + } + DEBUGP(DVLR, "set Last E-UTRAN PLMN ID on subscriber: %s\n", + vsub->sgs.last_eutran_plmn_present ? + osmo_plmn_name(&vsub->sgs.last_eutran_plmn) : + "(none)"); +} + bool vlr_subscr_matches_imsi(struct vlr_subscr *vsub, const char *imsi) { return vsub && imsi && vsub->imsi[0] && !strcmp(vsub->imsi, imsi); @@ -499,14 +728,11 @@ int vlr_subscr_changed(struct vlr_subscr *vsub) void vlr_subscr_enable_expire_lu(struct vlr_subscr *vsub) { - struct gsm_network *net = vsub->vlr->user_ctx; /* XXX move t3212 into struct vlr_instance? */ struct timespec now; - /* The T3212 timeout value field is coded as the binary representation of the timeout - * value for periodic updating in decihours. Mark the subscriber as inactive if it missed - * two consecutive location updates. Timeout is twice the t3212 value plus one minute. */ + /* Mark the subscriber as inactive if it stopped to do periodical location updates. */ if (osmo_clock_gettime(CLOCK_MONOTONIC, &now) == 0) { - vsub->expire_lu = now.tv_sec + (net->t3212 * 60 * 6 * 2) + 60; + vsub->expire_lu = now.tv_sec + vlr_timer(vsub->vlr, 3212); } else { LOGP(DVLR, LOGL_ERROR, "%s: Could not enable Location Update expiry: unable to read current time\n", vlr_subscr_name(vsub)); @@ -521,6 +747,11 @@ void vlr_subscr_expire_lu(void *data) struct vlr_subscr *vsub, *vsub_tmp; struct timespec now; + /* Periodic location update might be disabled from the VTY, + * so we shall not expire subscribers until explicit IMSI Detach. */ + if (!vlr_timer(vlr, 3212)) + goto done; + if (llist_empty(&vlr->subscribers)) goto done; @@ -534,7 +765,8 @@ void vlr_subscr_expire_lu(void *data) continue; LOGP(DVLR, LOGL_DEBUG, "%s: Location Update expired\n", vlr_subscr_name(vsub)); - vlr_subscr_rx_imsi_detach(vsub); + vlr_rate_ctr_inc(vlr, VLR_CTR_DETACH_BY_T3212); + vlr_subscr_detach(vsub); } done: @@ -550,13 +782,15 @@ done: /* see GSM 09.02, 17.7.1, PDP-Context and GPRSSubscriptionData */ /* see GSM 09.02, B.1, gprsSubscriptionData */ struct sgsn_subscriber_pdp_data { - struct llist_head list; - - unsigned int context_id; - uint16_t pdp_type; - char apn_str[GSM_APN_LENGTH]; - uint8_t qos_subscribed[20]; - size_t qos_subscribed_len; + struct llist_head list; + + unsigned int context_id; + enum gsm48_pdp_type_org pdp_type_org; + enum gsm48_pdp_type_nr pdp_type_nr; + struct osmo_sockaddr pdp_address[2]; + char apn_str[GSM_APN_LENGTH]; + uint8_t qos_subscribed[20]; + size_t qos_subscribed_len; }; struct sgsn_subscriber_pdp_data * @@ -567,6 +801,7 @@ vlr_subscr_pdp_data_alloc(struct vlr_subscr *vsub) pdata = talloc_zero(vsub, struct sgsn_subscriber_pdp_data); llist_add_tail(&pdata->list, &vsub->ps.pdp_list); + vlr_stat_item_inc(vsub->vlr, VLR_STAT_PDP_COUNT); return pdata; } @@ -578,6 +813,7 @@ static int vlr_subscr_pdp_data_clear(struct vlr_subscr *vsub) llist_for_each_entry_safe(pdp, pdp2, &vsub->ps.pdp_list, list) { llist_del(&pdp->list); + vlr_stat_item_dec(vsub->vlr, VLR_STAT_PDP_COUNT); talloc_free(pdp); count += 1; } @@ -648,6 +884,8 @@ int vlr_subscr_req_lu(struct vlr_subscr *vsub) struct osmo_gsup_message gsup_msg = {0}; int rc; + vlr_rate_ctr_inc(vsub->vlr, VLR_CTR_GSUP_TX_UL_REQ); + gsup_msg.message_type = OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST; gsup_msg.cn_domain = vsub->vlr->cfg.is_ps ? OSMO_GSUP_CN_DOMAIN_PS : OSMO_GSUP_CN_DOMAIN_CS; rc = vlr_subscr_tx_gsup_message(vsub, &gsup_msg); @@ -661,9 +899,12 @@ int vlr_subscr_req_sai(struct vlr_subscr *vsub, { struct osmo_gsup_message gsup_msg = {0}; + vlr_rate_ctr_inc(vsub->vlr, VLR_CTR_GSUP_TX_SAI_REQ); + gsup_msg.message_type = OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST; gsup_msg.auts = auts; gsup_msg.rand = auts_rand; + gsup_msg.cn_domain = OSMO_GSUP_CN_DOMAIN_CS; return vlr_subscr_tx_gsup_message(vsub, &gsup_msg); } @@ -673,6 +914,7 @@ int vlr_subscr_tx_req_check_imei(const struct vlr_subscr *vsub) { struct osmo_gsup_message gsup_msg = { .message_class = OSMO_GSUP_MESSAGE_CLASS_SUBSCRIBER_MANAGEMENT, + .message_type = OSMO_GSUP_MSGT_CHECK_IMEI_REQUEST, }; uint8_t imei_enc[GSM23003_IMEI_NUM_DIGITS+2]; /* +2: IE header */ int len; @@ -686,8 +928,9 @@ int vlr_subscr_tx_req_check_imei(const struct vlr_subscr *vsub) gsup_msg.imei_enc = imei_enc; gsup_msg.imei_enc_len = len; + vlr_rate_ctr_inc(vsub->vlr, VLR_CTR_GSUP_TX_CHECK_IMEI_REQ); + /* Send CHECK_IMEI_REQUEST */ - gsup_msg.message_type = OSMO_GSUP_MSGT_CHECK_IMEI_REQUEST; OSMO_STRLCPY_ARRAY(gsup_msg.imsi, vsub->imsi); return gsup_client_mux_tx(vsub->vlr->gcm, &gsup_msg); } @@ -697,9 +940,11 @@ int vlr_subscr_tx_auth_fail_rep(const struct vlr_subscr *vsub) { struct osmo_gsup_message gsup_msg = { .message_class = OSMO_GSUP_MESSAGE_CLASS_SUBSCRIBER_MANAGEMENT, + .message_type = OSMO_GSUP_MSGT_AUTH_FAIL_REPORT, }; - gsup_msg.message_type = OSMO_GSUP_MSGT_AUTH_FAIL_REPORT; + vlr_rate_ctr_inc(vsub->vlr, VLR_CTR_GSUP_TX_AUTH_FAIL_REP); + OSMO_STRLCPY_ARRAY(gsup_msg.imsi, vsub->imsi); return gsup_client_mux_tx(vsub->vlr->gcm, &gsup_msg); } @@ -723,7 +968,7 @@ void vlr_subscr_update_tuples(struct vlr_subscr *vsub, if (key_seq >= ARRAY_SIZE(vsub->auth_tuples)) { LOGVSUBP(LOGL_NOTICE, vsub, - "Skipping auth tuple wih invalid cksn %zu\n", + "Skipping auth tuple with invalid cksn %zu\n", key_seq); continue; } @@ -733,6 +978,7 @@ void vlr_subscr_update_tuples(struct vlr_subscr *vsub, } LOGVSUBP(LOGL_DEBUG, vsub, "Received %u auth tuples\n", got_tuples); + vlr_rate_ctr_add(vsub->vlr, VLR_CTR_GSUP_RX_TUPLES, got_tuples); if (!got_tuples) { /* FIXME what now? */ @@ -750,6 +996,12 @@ static int vlr_subscr_handle_sai_res(struct vlr_subscr *vsub, struct osmo_fsm_inst *auth_fi = vsub->auth_fsm; void *data = (void *) gsup; + if (!auth_fi) { + LOGVSUBP(LOGL_ERROR, vsub, "Received GSUP %s, but there is no auth_fsm\n", + osmo_gsup_message_type_name(gsup->message_type)); + return -1; + } + switch (gsup->message_type) { case OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT: osmo_fsm_inst_dispatch(auth_fi, VLR_AUTH_E_HLR_SAI_ACK, data); @@ -770,7 +1022,7 @@ static void vlr_subscr_gsup_insert_data(struct vlr_subscr *vsub, unsigned idx; int rc; - if (gsup_msg->msisdn_enc) {//FIXME: vlr_subscr_set_msisdn()? + if (gsup_msg->msisdn_enc_len) {//FIXME: vlr_subscr_set_msisdn()? gsm48_decode_bcd_number2(vsub->msisdn, sizeof(vsub->msisdn), gsup_msg->msisdn_enc, gsup_msg->msisdn_enc_len, 0); @@ -828,7 +1080,10 @@ static void vlr_subscr_gsup_insert_data(struct vlr_subscr *vsub, } OSMO_ASSERT(pdp_data != NULL); - pdp_data->pdp_type = pdp_info->pdp_type; + pdp_data->pdp_type_org = pdp_info->pdp_type_org; + pdp_data->pdp_type_nr = pdp_info->pdp_type_nr; + memcpy(&pdp_data->pdp_address[0], &pdp_info->pdp_address[0], sizeof(pdp_data->pdp_address[0])); + memcpy(&pdp_data->pdp_address[1], &pdp_info->pdp_address[1], sizeof(pdp_data->pdp_address[1])); 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); @@ -843,6 +1098,8 @@ static int vlr_subscr_handle_isd_req(struct vlr_subscr *vsub, { struct osmo_gsup_message gsup_reply = {0}; + vlr_rate_ctr_inc(vsub->vlr, VLR_CTR_GSUP_TX_ISD_RES); + vlr_subscr_gsup_insert_data(vsub, gsup); vsub->vlr->ops.subscr_update(vsub); @@ -854,7 +1111,7 @@ static int vlr_subscr_handle_isd_req(struct vlr_subscr *vsub, static int vlr_subscr_handle_lu_res(struct vlr_subscr *vsub, const struct osmo_gsup_message *gsup) { - struct sgs_lu_response sgs_lu_response; + struct sgs_lu_response sgs_lu_response = {0}; bool sgs_lu_in_progress = false; if (vsub->sgs_fsm->state == SGS_UE_ST_LA_UPD_PRES) @@ -885,7 +1142,7 @@ static int vlr_subscr_handle_lu_res(struct vlr_subscr *vsub, static int vlr_subscr_handle_lu_err(struct vlr_subscr *vsub, const struct osmo_gsup_message *gsup) { - struct sgs_lu_response sgs_lu_response; + struct sgs_lu_response sgs_lu_response = {0}; bool sgs_lu_in_progress = false; if (vsub->sgs_fsm->state == SGS_UE_ST_LA_UPD_PRES) @@ -910,11 +1167,9 @@ static int vlr_subscr_handle_lu_err(struct vlr_subscr *vsub, return 0; } -static void gmm_cause_to_fsm_and_mm_cause(enum gsm48_gmm_cause gmm_cause, - enum osmo_fsm_term_cause *fsm_cause_p, - enum gsm48_reject_value *gsm48_rej_p) +void vlr_gmm_cause_to_mm_cause(enum gsm48_gmm_cause gmm_cause, + enum gsm48_reject_value *gsm48_rej_p) { - enum osmo_fsm_term_cause fsm_cause = OSMO_FSM_TERM_ERROR; enum gsm48_reject_value gsm48_rej = GSM48_REJECT_NETWORK_FAILURE; switch (gmm_cause) { case GMM_CAUSE_IMSI_UNKNOWN: @@ -997,16 +1252,8 @@ static void gmm_cause_to_fsm_and_mm_cause(enum gsm48_gmm_cause gmm_cause, gsm48_rej = GSM48_REJECT_NETWORK_FAILURE; break; } - switch (gmm_cause) { - /* refine any error causes here? */ - default: - fsm_cause = OSMO_FSM_TERM_ERROR; - break; - } - if (fsm_cause_p) - *fsm_cause_p = fsm_cause; - if (gsm48_rej_p) - *gsm48_rej_p = gsm48_rej; + + *gsm48_rej_p = gsm48_rej; } /* Handle LOCATION CANCEL request from HLR */ @@ -1014,11 +1261,13 @@ static int vlr_subscr_handle_cancel_req(struct vlr_subscr *vsub, const struct osmo_gsup_message *gsup_msg) { enum gsm48_reject_value gsm48_rej; - enum osmo_fsm_term_cause fsm_cause; + enum osmo_fsm_term_cause fsm_cause = OSMO_FSM_TERM_ERROR; struct osmo_gsup_message gsup_reply = {0}; int rc, is_update_procedure = !gsup_msg->cancel_type || gsup_msg->cancel_type == OSMO_GSUP_CANCEL_TYPE_UPDATE; + vlr_rate_ctr_inc(vsub->vlr, VLR_CTR_GSUP_TX_CANCEL_RES); + LOGVSUBP(LOGL_INFO, vsub, "Cancelling MS subscriber (%s)\n", is_update_procedure ? "update procedure" : "subscription withdraw"); @@ -1026,10 +1275,11 @@ static int vlr_subscr_handle_cancel_req(struct vlr_subscr *vsub, gsup_reply.message_type = OSMO_GSUP_MSGT_LOCATION_CANCEL_RESULT; rc = vlr_subscr_tx_gsup_message(vsub, &gsup_reply); - gmm_cause_to_fsm_and_mm_cause(gsup_msg->cause, &fsm_cause, &gsm48_rej); + vlr_gmm_cause_to_mm_cause(gsup_msg->cause, &gsm48_rej); vlr_subscr_cancel_attach_fsm(vsub, fsm_cause, gsm48_rej); - vlr_subscr_rx_imsi_detach(vsub); + vlr_rate_ctr_inc(vsub->vlr, VLR_CTR_DETACH_BY_CANCEL); + vlr_subscr_detach(vsub); return rc; } @@ -1065,49 +1315,65 @@ int vlr_gsup_rx(struct gsup_client_mux *gcm, void *data, const struct osmo_gsup_ { struct vlr_instance *vlr = data; struct vlr_subscr *vsub; - int rc; + int rc = 0; vsub = vlr_subscr_find_by_imsi(vlr, gsup->imsi, __func__); if (!vsub) { switch (gsup->message_type) { case OSMO_GSUP_MSGT_PURGE_MS_RESULT: case OSMO_GSUP_MSGT_PURGE_MS_ERROR: + vlr_rate_ctr_inc(vlr, VLR_CTR_GSUP_RX_PURGE_NO_SUBSCR); return vlr_rx_gsup_purge_no_subscr(vlr, gsup); default: + vlr_rate_ctr_inc(vlr, VLR_CTR_GSUP_RX_UNKNOWN_IMSI); return vlr_rx_gsup_unknown_imsi(vlr, gsup); } } switch (gsup->message_type) { case OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT: + vlr_rate_ctr_inc(vlr, VLR_CTR_GSUP_RX_SAI_RES); + rc = vlr_subscr_handle_sai_res(vsub, gsup); + break; case OSMO_GSUP_MSGT_SEND_AUTH_INFO_ERROR: + vlr_rate_ctr_inc(vlr, VLR_CTR_GSUP_RX_SAI_ERR); rc = vlr_subscr_handle_sai_res(vsub, gsup); break; case OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: + vlr_rate_ctr_inc(vlr, VLR_CTR_GSUP_RX_ISD_REQ); rc = vlr_subscr_handle_isd_req(vsub, gsup); break; case OSMO_GSUP_MSGT_LOCATION_CANCEL_REQUEST: + vlr_rate_ctr_inc(vlr, VLR_CTR_GSUP_RX_CANCEL_REQ); rc = vlr_subscr_handle_cancel_req(vsub, gsup); break; case OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: + vlr_rate_ctr_inc(vlr, VLR_CTR_GSUP_RX_UL_RES); rc = vlr_subscr_handle_lu_res(vsub, gsup); break; case OSMO_GSUP_MSGT_UPDATE_LOCATION_ERROR: + vlr_rate_ctr_inc(vlr, VLR_CTR_GSUP_RX_UL_ERR); rc = vlr_subscr_handle_lu_err(vsub, gsup); break; case OSMO_GSUP_MSGT_PURGE_MS_ERROR: + vlr_rate_ctr_inc(vlr, VLR_CTR_GSUP_RX_PURGE_MS_ERR); + goto out_unimpl; case OSMO_GSUP_MSGT_PURGE_MS_RESULT: + vlr_rate_ctr_inc(vlr, VLR_CTR_GSUP_RX_PURGE_MS_RES); + goto out_unimpl; case OSMO_GSUP_MSGT_DELETE_DATA_REQUEST: - LOGVSUBP(LOGL_ERROR, vsub, - "Rx GSUP msg_type=%d not yet implemented\n", - gsup->message_type); - rc = -GMM_CAUSE_MSGT_NOTEXIST_NOTIMPL; - break; + vlr_rate_ctr_inc(vlr, VLR_CTR_GSUP_RX_DELETE_DATA_REQ); + goto out_unimpl; case OSMO_GSUP_MSGT_CHECK_IMEI_ERROR: + vlr_rate_ctr_inc(vlr, VLR_CTR_GSUP_RX_CHECK_IMEI_ERR); + rc = vlr_subscr_handle_check_imei(vsub, gsup); + break; case OSMO_GSUP_MSGT_CHECK_IMEI_RESULT: + vlr_rate_ctr_inc(vlr, VLR_CTR_GSUP_RX_CHECK_IMEI_RES); rc = vlr_subscr_handle_check_imei(vsub, gsup); break; default: + vlr_rate_ctr_inc(vlr, VLR_CTR_GSUP_RX_UNKNOWN); LOGP(DLGSUP, LOGL_ERROR, "GSUP Message type not handled by VLR: %d\n", gsup->message_type); rc = -EINVAL; break; @@ -1115,68 +1381,57 @@ int vlr_gsup_rx(struct gsup_client_mux *gcm, void *data, const struct osmo_gsup_ vlr_subscr_put(vsub, __func__); return rc; + +out_unimpl: + LOGVSUBP(LOGL_ERROR, vsub, "Rx GSUP msg_type=%d not yet implemented\n", gsup->message_type); + vlr_subscr_put(vsub, __func__); + return -GMM_CAUSE_MSGT_NOTEXIST_NOTIMPL; } /* MSC->VLR: Subscriber has provided IDENTITY RESPONSE */ -int vlr_subscr_rx_id_resp(struct vlr_subscr *vsub, - const uint8_t *mi, size_t mi_len) +int vlr_subscr_rx_id_resp(struct vlr_subscr *vsub, const struct osmo_mobile_identity *mi) { - char mi_string[GSM48_MI_SIZE]; - uint8_t mi_type = mi[0] & GSM_MI_TYPE_MASK; - - gsm48_mi_to_string(mi_string, sizeof(mi_string), mi, mi_len); - /* update the vlr_subscr with the given identity */ - switch (mi_type) { + switch (mi->type) { case GSM_MI_TYPE_IMSI: - if (strlen(mi_string) >= sizeof(vsub->imsi)) { - LOGVSUBP(LOGL_ERROR, vsub, "IMSI in ID RESP too long (>%zu bytes): %s\n", - sizeof(vsub->imsi) - 1, mi_string); - return -ENOSPC; /* ignore message; do not avance LU FSM */ - } else if (vsub->imsi[0] - && !vlr_subscr_matches_imsi(vsub, mi_string)) { + if (vsub->imsi[0] + && !vlr_subscr_matches_imsi(vsub, mi->imsi)) { LOGVSUBP(LOGL_ERROR, vsub, "IMSI in ID RESP differs:" - " %s\n", mi_string); + " %s\n", mi->imsi); /* XXX Should we return an error, e.g. -EINVAL ? */ } else - vlr_subscr_set_imsi(vsub, mi_string); + vlr_subscr_set_imsi(vsub, mi->imsi); break; case GSM_MI_TYPE_IMEI: - vlr_subscr_set_imei(vsub, mi_string); + vlr_subscr_set_imei(vsub, mi->imei); break; case GSM_MI_TYPE_IMEISV: - vlr_subscr_set_imeisv(vsub, mi_string); + vlr_subscr_set_imeisv(vsub, mi->imeisv); break; + default: + return -EINVAL; } if (vsub->auth_fsm) { - switch (mi_type) { + switch (mi->type) { case GSM_MI_TYPE_IMSI: - osmo_fsm_inst_dispatch(vsub->auth_fsm, - VLR_AUTH_E_MS_ID_IMSI, mi_string); + return osmo_fsm_inst_dispatch(vsub->auth_fsm, + VLR_AUTH_E_MS_ID_IMSI, (void*)mi->imsi); break; } } if (vsub->lu_fsm) { - uint32_t event = 0; - switch (mi_type) { + switch (mi->type) { case GSM_MI_TYPE_IMSI: - event = VLR_ULA_E_ID_IMSI; - break; + return osmo_fsm_inst_dispatch(vsub->lu_fsm, VLR_ULA_E_ID_IMSI, (void*)mi->imsi); case GSM_MI_TYPE_IMEI: - event = VLR_ULA_E_ID_IMEI; - break; + return osmo_fsm_inst_dispatch(vsub->lu_fsm, VLR_ULA_E_ID_IMEI, (void*)mi->imei); case GSM_MI_TYPE_IMEISV: - event = VLR_ULA_E_ID_IMEISV; - break; + return osmo_fsm_inst_dispatch(vsub->lu_fsm, VLR_ULA_E_ID_IMEISV, (void*)mi->imeisv); default: - OSMO_ASSERT(0); - break; + return -EINVAL; } - osmo_fsm_inst_dispatch(vsub->lu_fsm, event, mi_string); - } else { - LOGVSUBP(LOGL_NOTICE, vsub, "gratuitous ID RESPONSE?!?\n"); } return 0; @@ -1211,8 +1466,7 @@ bool vlr_subscr_expire(struct vlr_subscr *vsub) return false; } -/* See TS 23.012 version 9.10.0 4.3.2.1 "Process Detach_IMSI_VLR" */ -int vlr_subscr_rx_imsi_detach(struct vlr_subscr *vsub) +static int vlr_subscr_detach(struct vlr_subscr *vsub) { /* paranoia: should any LU or PARQ FSMs still be running, stop them. */ vlr_subscr_cancel_attach_fsm(vsub, OSMO_FSM_TERM_ERROR, GSM48_REJECT_CONGESTION); @@ -1228,6 +1482,13 @@ int vlr_subscr_rx_imsi_detach(struct vlr_subscr *vsub) return 0; } +/* See TS 23.012 version 9.10.0 4.3.2.1 "Process Detach_IMSI_VLR" */ +int vlr_subscr_rx_imsi_detach(struct vlr_subscr *vsub) +{ + vlr_rate_ctr_inc(vsub->vlr, VLR_CTR_DETACH_BY_REQ); + return vlr_subscr_detach(vsub); +} + /* Tear down any running FSMs due to MSC connection timeout. * Visit all vsub->*_fsm pointers and give them a queue to send a final reject * message before the entire connection is torn down. @@ -1263,6 +1524,19 @@ struct vlr_instance *vlr_alloc(void *ctx, const struct vlr_ops *ops) /* defaults */ vlr->cfg.assign_tmsi = true; + vlr->cfg.nri_bitlen = OSMO_NRI_BITLEN_DEFAULT; + vlr->cfg.nri_ranges = osmo_nri_ranges_alloc(vlr); + + vlr->statg = osmo_stat_item_group_alloc(vlr, &vlr_statg_desc, 0); + if (!vlr->statg) + goto err_free; + + vlr->ctrg = rate_ctr_group_alloc(vlr, &vlr_ctrg_desc, 0); + if (!vlr->ctrg) + goto err_statg; + + /* reset shared timer definitions */ + osmo_tdefs_reset(msc_tdefs_vlr); /* osmo_auth_fsm.c */ OSMO_ASSERT(osmo_fsm_register(&vlr_auth_fsm) == 0); @@ -1274,6 +1548,12 @@ struct vlr_instance *vlr_alloc(void *ctx, const struct vlr_ops *ops) vlr_sgs_fsm_init(); return vlr; + +err_statg: + osmo_stat_item_group_free(vlr->statg); +err_free: + talloc_free(vlr); + return NULL; } int vlr_start(struct vlr_instance *vlr, struct gsup_client_mux *gcm) @@ -1352,13 +1632,9 @@ void vlr_subscr_rx_ciph_res(struct vlr_subscr *vsub, enum vlr_ciph_result_cause int vlr_set_ciph_mode(struct vlr_instance *vlr, struct osmo_fsm_inst *fi, void *msc_conn_ref, - bool ciph_required, bool umts_aka, bool retrieve_imeisv) { - if (!ciph_required) - return 0; - LOGPFSML(fi, LOGL_DEBUG, "Set Ciphering Mode\n"); return vlr->ops.set_ciph_mode(msc_conn_ref, umts_aka, retrieve_imeisv); } diff --git a/src/libvlr/vlr_access_req_fsm.c b/src/libvlr/vlr_access_req_fsm.c index 7684d02f0..629625ea4 100644 --- a/src/libvlr/vlr_access_req_fsm.c +++ b/src/libvlr/vlr_access_req_fsm.c @@ -40,6 +40,8 @@ static const struct value_string proc_arq_vlr_event_names[] = { OSMO_VALUE_STRING(PR_ARQ_E_START), OSMO_VALUE_STRING(PR_ARQ_E_ID_IMSI), OSMO_VALUE_STRING(PR_ARQ_E_AUTH_RES), + OSMO_VALUE_STRING(PR_ARQ_E_AUTH_NO_INFO), + OSMO_VALUE_STRING(PR_ARQ_E_AUTH_FAILURE), OSMO_VALUE_STRING(PR_ARQ_E_CIPH_RES), OSMO_VALUE_STRING(PR_ARQ_E_UPD_LOC_RES), OSMO_VALUE_STRING(PR_ARQ_E_TRACE_RES), @@ -67,7 +69,12 @@ struct proc_arq_priv { uint32_t tmsi; struct osmo_location_area_id lai; bool authentication_required; - bool ciphering_required; + /* is_ciphering_to_be_attempted: true when any A5/n > 0 are enabled. Ciphering is allowed, always attempt to get Auth Info from + * the HLR. */ + bool is_ciphering_to_be_attempted; + /* is_ciphering_required: true when A5/0 is disabled. If we cannot get Auth Info from the HLR, reject the + * subscriber. */ + bool is_ciphering_required; uint8_t key_seq; bool is_r99; bool is_utran; @@ -246,16 +253,13 @@ static void _proc_arq_vlr_node2_post_ciph(struct osmo_fsm_inst *fi) { struct proc_arq_priv *par = fi->priv; struct vlr_subscr *vsub = par->vsub; + int rc; LOGPFSM(fi, "%s()\n", __func__); - if (par->is_utran) { - int rc; - rc = par->vlr->ops.tx_common_id(par->msc_conn_ref); - if (rc) - LOGPFSML(fi, LOGL_ERROR, - "Error while sending Common ID (%d)\n", rc); - } + rc = par->vlr->ops.tx_common_id(par->msc_conn_ref); + if (rc) + LOGPFSML(fi, LOGL_ERROR, "Error while sending Common ID (%d)\n", rc); vsub->conf_by_radio_contact_ind = true; if (vsub->loc_conf_in_hlr_ind == false) { @@ -270,9 +274,12 @@ static void _proc_arq_vlr_node2_post_ciph(struct osmo_fsm_inst *fi) _proc_arq_vlr_node2_post_vlr(fi); } -static bool is_ciph_required(struct proc_arq_priv *par) +/* Return true when CipherModeCmd / SecurityModeCmd should be attempted. */ +static bool is_cmc_smc_to_be_attempted(struct proc_arq_priv *par) { - return par->ciphering_required; + /* UTRAN: always send SecModeCmd, even if ciphering is not required. + * GERAN: avoid sending CiphModeCmd if ciphering is not required. */ + return par->is_utran || par->is_ciphering_to_be_attempted; } static void _proc_arq_vlr_node2(struct osmo_fsm_inst *fi) @@ -283,7 +290,10 @@ static void _proc_arq_vlr_node2(struct osmo_fsm_inst *fi) LOGPFSM(fi, "%s()\n", __func__); - if (!is_ciph_required(par)) { + /* Continue with ciphering, if enabled. + * If auth/ciph is optional and the HLR returned no auth info, continue without ciphering. */ + if (!is_cmc_smc_to_be_attempted(par) + || (vsub->sec_ctx == VLR_SEC_CTX_NONE && !par->is_ciphering_required)) { _proc_arq_vlr_node2_post_ciph(fi); return; } @@ -302,7 +312,6 @@ static void _proc_arq_vlr_node2(struct osmo_fsm_inst *fi) } if (vlr_set_ciph_mode(vsub->vlr, fi, par->msc_conn_ref, - par->ciphering_required, umts_aka, vsub->vlr->cfg.retrieve_imeisv_ciphered)) { LOGPFSML(fi, LOGL_ERROR, @@ -315,13 +324,13 @@ static void _proc_arq_vlr_node2(struct osmo_fsm_inst *fi) osmo_fsm_inst_state_chg(fi, PR_ARQ_S_WAIT_CIPH, 0, 0); } -static bool is_auth_required(struct proc_arq_priv *par) +static bool is_auth_to_be_attempted(struct proc_arq_priv *par) { /* The cases where the authentication procedure should be used * are defined in 3GPP TS 33.102 */ /* For now we use a default value passed in to vlr_lu_fsm(). */ return par->authentication_required || - (par->ciphering_required && !auth_try_reuse_tuple(par->vsub, par->key_seq)); + (par->is_ciphering_to_be_attempted && !auth_try_reuse_tuple(par->vsub, par->key_seq)); } /* after the IMSI is known */ @@ -335,11 +344,13 @@ static void proc_arq_vlr_fn_post_imsi(struct osmo_fsm_inst *fi) OSMO_ASSERT(vsub); /* TODO: Identity IMEI -> System Failure */ - if (is_auth_required(par)) { + if (is_auth_to_be_attempted(par)) { osmo_fsm_inst_state_chg(fi, PR_ARQ_S_WAIT_AUTH, 0, 0); - vsub->auth_fsm = auth_fsm_start(vsub, fi->log_level, fi, + vsub->auth_fsm = auth_fsm_start(vsub, fi, PR_ARQ_E_AUTH_RES, + PR_ARQ_E_AUTH_NO_INFO, + PR_ARQ_E_AUTH_FAILURE, par->is_r99, par->is_utran); } else { @@ -432,17 +443,34 @@ static void proc_arq_vlr_fn_w_obt_imsi(struct osmo_fsm_inst *fi, static void proc_arq_vlr_fn_w_auth(struct osmo_fsm_inst *fi, uint32_t event, void *data) { + struct proc_arq_priv *par = fi->priv; enum gsm48_reject_value *cause = data; - OSMO_ASSERT(event == PR_ARQ_E_AUTH_RES); + switch (event) { + case PR_ARQ_E_AUTH_RES: + /* Node 2 */ + _proc_arq_vlr_node2(fi); + return; - if (!cause || *cause) { - proc_arq_fsm_done(fi, cause? *cause : GSM48_REJECT_NETWORK_FAILURE); + case PR_ARQ_E_AUTH_FAILURE: + proc_arq_fsm_done(fi, cause ? *cause : GSM48_REJECT_NETWORK_FAILURE); return; - } - /* Node 2 */ - _proc_arq_vlr_node2(fi); + case PR_ARQ_E_AUTH_NO_INFO: + /* HLR returned no auth info for the subscriber. Continue only if authentication is optional. */ + if (par->authentication_required) { + proc_arq_fsm_done(fi, cause ? *cause : GSM48_REJECT_NETWORK_FAILURE); + return; + } + LOGPFSML(fi, LOGL_INFO, + "Attaching subscriber without auth (auth is optional, and no auth info received from HLR)\n"); + /* Node 2 */ + _proc_arq_vlr_node2(fi); + return; + + default: + OSMO_ASSERT(false); + } } static void proc_arq_vlr_fn_w_ciph(struct osmo_fsm_inst *fi, @@ -547,7 +575,9 @@ static const struct osmo_fsm_state proc_arq_vlr_states[] = { }, [PR_ARQ_S_WAIT_AUTH] = { .name = OSMO_STRINGIFY(PR_ARQ_S_WAIT_AUTH), - .in_event_mask = S(PR_ARQ_E_AUTH_RES), + .in_event_mask = S(PR_ARQ_E_AUTH_RES) | + S(PR_ARQ_E_AUTH_NO_INFO) | + S(PR_ARQ_E_AUTH_FAILURE), .out_state_mask = S(PR_ARQ_S_DONE) | S(PR_ARQ_S_WAIT_CIPH) | S(PR_ARQ_S_WAIT_UPD_LOC_CHILD) | @@ -632,17 +662,19 @@ vlr_proc_acc_req(struct osmo_fsm_inst *parent, void *parent_event_data, struct vlr_instance *vlr, void *msc_conn_ref, enum vlr_parq_type type, enum osmo_cm_service_type cm_service_type, - const uint8_t *mi_lv, + const struct osmo_mobile_identity *mi, const struct osmo_location_area_id *lai, bool authentication_required, - bool ciphering_required, + bool is_ciphering_to_be_attempted, + bool is_ciphering_required, uint8_t key_seq, bool is_r99, bool is_utran) { struct osmo_fsm_inst *fi; struct proc_arq_priv *par; - char mi_string[GSM48_MI_SIZE]; - uint8_t mi_type; + + if (is_ciphering_required) + OSMO_ASSERT(is_ciphering_to_be_attempted); fi = osmo_fsm_inst_alloc_child(&proc_arq_vlr_fsm, parent, parent_event_failure); @@ -660,7 +692,8 @@ vlr_proc_acc_req(struct osmo_fsm_inst *parent, par->parent_event_failure = parent_event_failure; par->parent_event_data = parent_event_data; par->authentication_required = authentication_required; - par->ciphering_required = ciphering_required; + par->is_ciphering_to_be_attempted = is_ciphering_to_be_attempted; + par->is_ciphering_required = is_ciphering_required; par->key_seq = key_seq; par->is_r99 = is_r99; par->is_utran = is_utran; @@ -668,26 +701,24 @@ vlr_proc_acc_req(struct osmo_fsm_inst *parent, LOGPFSM(fi, "rev=%s net=%s%s%s\n", is_r99 ? "R99" : "GSM", is_utran ? "UTRAN" : "GERAN", - (authentication_required || ciphering_required)? + (authentication_required || is_ciphering_to_be_attempted) ? " Auth" : " (no Auth)", - (authentication_required || ciphering_required)? - (ciphering_required? "+Ciph" : " (no Ciph)") + (authentication_required || is_ciphering_to_be_attempted) ? + (is_ciphering_to_be_attempted ? "+Ciph" : " (no Ciph)") : ""); if (is_utran && !authentication_required) LOGPFSML(fi, LOGL_ERROR, "Authentication off on UTRAN network. Good luck.\n"); - gsm48_mi_to_string(mi_string, sizeof(mi_string), mi_lv+1, mi_lv[0]); - mi_type = mi_lv[1] & GSM_MI_TYPE_MASK; - switch (mi_type) { + switch (mi->type) { case GSM_MI_TYPE_IMSI: - osmo_strlcpy(par->imsi, mi_string, sizeof(par->imsi)); + OSMO_STRLCPY_ARRAY(par->imsi, mi->imsi); par->by_tmsi = false; break; case GSM_MI_TYPE_TMSI: par->by_tmsi = true; - par->tmsi = osmo_load32be(mi_lv+2); + par->tmsi = mi->tmsi; break; case GSM_MI_TYPE_IMEI: /* TODO: IMEI (emergency call) */ diff --git a/src/libvlr/vlr_auth_fsm.c b/src/libvlr/vlr_auth_fsm.c index 60265104d..b5052b072 100644 --- a/src/libvlr/vlr_auth_fsm.c +++ b/src/libvlr/vlr_auth_fsm.c @@ -1,4 +1,4 @@ -/* Osmocom Visitor Location Register (VLR) Autentication FSM */ +/* Osmocom Visitor Location Register (VLR) Authentication FSM */ /* (C) 2016 by Harald Welte <laforge@gnumonks.org> * @@ -51,6 +51,10 @@ struct auth_fsm_priv { bool auth_requested; int auth_tuple_max_reuse_count; /* see vlr->cfg instead */ + + uint32_t parent_event_success; + uint32_t parent_event_no_auth_info; + uint32_t parent_event_failure; }; /*********************************************************************** @@ -230,27 +234,50 @@ static void auth_fsm_onenter_failed(struct osmo_fsm_inst *fi, uint32_t prev_stat } } -static const char *vlr_auth_fsm_result_name(enum gsm48_reject_value result) -{ - if (!result) - return "PASSED"; - return get_value_string(gsm48_gmm_cause_names, result); -} +enum auth_fsm_result { + /* Authentication verified the subscriber. */ + AUTH_FSM_PASSED = 0, + /* HLR does not have authentication info for this subscriber. */ + AUTH_FSM_NO_AUTH_INFO, + /* Authentication was attempted but failed. */ + AUTH_FSM_FAILURE, +}; + +const char *auth_fsm_result_str[] = { + [AUTH_FSM_PASSED] = "PASSED", + [AUTH_FSM_NO_AUTH_INFO] = "NO_AUTH_INFO", + [AUTH_FSM_FAILURE] = "FAILURE", +}; /* Terminate the Auth FSM Instance and notify parent */ -static void auth_fsm_term(struct osmo_fsm_inst *fi, enum gsm48_reject_value result) +static void auth_fsm_term(struct osmo_fsm_inst *fi, enum auth_fsm_result result, enum gsm48_reject_value cause) { - LOGPFSM(fi, "Authentication terminating with result %s\n", - vlr_auth_fsm_result_name(result)); + struct auth_fsm_priv *afp = fi->priv; + + LOGPFSM(fi, "Authentication terminating with result %s%s%s\n", + auth_fsm_result_str[result], + cause ? ", cause " : "", + cause ? gsm48_reject_value_name(cause) : ""); - /* Do one final state transition (mostly for logging purpose) */ - if (!result) + /* Do one final state transition (mostly for logging purpose) + * and set the parent_term_event according to result */ + switch (result) { + case AUTH_FSM_PASSED: osmo_fsm_inst_state_chg(fi, VLR_SUB_AS_AUTHENTICATED, 0, 0); - else + fi->proc.parent_term_event = afp->parent_event_success; + break; + case AUTH_FSM_NO_AUTH_INFO: + osmo_fsm_inst_state_chg(fi, VLR_SUB_AS_AUTH_FAILED, 0, 0); + fi->proc.parent_term_event = afp->parent_event_no_auth_info; + break; + case AUTH_FSM_FAILURE: osmo_fsm_inst_state_chg(fi, VLR_SUB_AS_AUTH_FAILED, 0, 0); + fi->proc.parent_term_event = afp->parent_event_failure; + break; + } /* return the result to the parent FSM */ - osmo_fsm_inst_term(fi, OSMO_FSM_TERM_REGULAR, &result); + osmo_fsm_inst_term(fi, OSMO_FSM_TERM_REGULAR, &cause); } static void auth_fsm_cleanup(struct osmo_fsm_inst *fi, enum osmo_fsm_term_cause cause) @@ -275,7 +302,7 @@ static int _vlr_subscr_authenticate(struct osmo_fsm_inst *fi) LOGPFSML(fi, LOGL_ERROR, "A previous check ensured that an" " auth tuple was available, but now there is in fact" " none.\n"); - auth_fsm_term(fi, GSM48_REJECT_NETWORK_FAILURE); + auth_fsm_term(fi, AUTH_FSM_FAILURE, GSM48_REJECT_NETWORK_FAILURE); return -1; } @@ -331,6 +358,7 @@ static void auth_fsm_wait_ai(struct osmo_fsm_inst *fi, uint32_t event, struct auth_fsm_priv *afp = fi->priv; struct vlr_subscr *vsub = afp->vsub; struct osmo_gsup_message *gsup = data; + enum gsm48_reject_value gsm48_rej; if (event == VLR_AUTH_E_HLR_SAI_NACK) LOGPFSM(fi, "GSUP: rx Auth Info Error cause: %d: %s\n", @@ -350,21 +378,25 @@ static void auth_fsm_wait_ai(struct osmo_fsm_inst *fi, uint32_t event, afp->auth_tuple_max_reuse_count = -1; goto pass; } - /* result = procedure error */ - auth_fsm_term(fi, GSM48_REJECT_NETWORK_FAILURE); - return; } switch (event) { case VLR_AUTH_E_HLR_SAI_ACK: + if (!gsup->num_auth_vectors) { + auth_fsm_term(fi, AUTH_FSM_FAILURE, GSM48_REJECT_NETWORK_FAILURE); + return; + } vlr_subscr_update_tuples(vsub, gsup); goto pass; - break; case VLR_AUTH_E_HLR_SAI_NACK: - auth_fsm_term(fi, - gsup->cause == GMM_CAUSE_IMSI_UNKNOWN? - GSM48_REJECT_IMSI_UNKNOWN_IN_HLR - : GSM48_REJECT_NETWORK_FAILURE); + /* HLR did not return Auth Info, hence cannot authenticate. (The caller may still decide to permit + * attaching without authentication) */ + vlr_gmm_cause_to_mm_cause(gsup->cause, &gsm48_rej); + auth_fsm_term(fi, AUTH_FSM_NO_AUTH_INFO, gsm48_rej); + break; + case VLR_AUTH_E_HLR_SAI_ABORT: + vlr_gmm_cause_to_mm_cause(gsup->cause, &gsm48_rej); + auth_fsm_term(fi, AUTH_FSM_FAILURE, gsm48_rej); break; } @@ -397,10 +429,10 @@ static void auth_fsm_wait_auth_resp(struct osmo_fsm_inst *fi, uint32_t event, VLR_SUB_AS_WAIT_ID_IMSI, vlr_timer(vlr, 3270), 3270); } else { - auth_fsm_term(fi, GSM48_REJECT_ILLEGAL_MS); + auth_fsm_term(fi, AUTH_FSM_FAILURE, GSM48_REJECT_ILLEGAL_MS); } } else { - auth_fsm_term(fi, 0); + auth_fsm_term(fi, AUTH_FSM_PASSED, 0); } break; case VLR_AUTH_E_MS_AUTH_FAIL: @@ -412,7 +444,7 @@ static void auth_fsm_wait_auth_resp(struct osmo_fsm_inst *fi, uint32_t event, VLR_SUB_AS_NEEDS_AUTH_WAIT_SAI_RESYNC, GSM_29002_TIMER_M, 0); } else - auth_fsm_term(fi, GSM48_REJECT_ILLEGAL_MS); + auth_fsm_term(fi, AUTH_FSM_FAILURE, GSM48_REJECT_ILLEGAL_MS); break; } } @@ -432,26 +464,23 @@ static void auth_fsm_wait_ai_resync(struct osmo_fsm_inst *fi, gsup->cause != GMM_CAUSE_IMSI_UNKNOWN) || (event == VLR_AUTH_E_HLR_SAI_ABORT)) { /* result = procedure error */ - auth_fsm_term(fi, GSM48_REJECT_NETWORK_FAILURE); + auth_fsm_term(fi, AUTH_FSM_FAILURE, GSM48_REJECT_NETWORK_FAILURE); } switch (event) { case VLR_AUTH_E_HLR_SAI_ACK: vlr_subscr_update_tuples(vsub, gsup); - goto pass; + osmo_fsm_inst_state_chg(fi, VLR_SUB_AS_WAIT_RESP_RESYNC, + vlr_timer(vsub->vlr, 3260), 3260); + _vlr_subscr_authenticate(fi); break; case VLR_AUTH_E_HLR_SAI_NACK: auth_fsm_term(fi, + AUTH_FSM_FAILURE, gsup->cause == GMM_CAUSE_IMSI_UNKNOWN? GSM48_REJECT_IMSI_UNKNOWN_IN_HLR : GSM48_REJECT_NETWORK_FAILURE); break; } - - return; -pass: - osmo_fsm_inst_state_chg(fi, VLR_SUB_AS_WAIT_RESP_RESYNC, - vlr_timer(vsub->vlr, 3260), 3260); - _vlr_subscr_authenticate(fi); } /* Waiting for AUTH RESP from MS (re-sync case) */ @@ -477,16 +506,16 @@ static void auth_fsm_wait_auth_resp_resync(struct osmo_fsm_inst *fi, vlr_timer(vlr, 3270), 3270); } else { /* Result = Aborted */ - auth_fsm_term(fi, GSM48_REJECT_SYNCH_FAILURE); + auth_fsm_term(fi, AUTH_FSM_FAILURE, GSM48_REJECT_SYNCH_FAILURE); } } else { /* Result = Pass */ - auth_fsm_term(fi, 0); + auth_fsm_term(fi, AUTH_FSM_PASSED, 0); } break; case VLR_AUTH_E_MS_AUTH_FAIL: /* Second failure: Result = Fail */ - auth_fsm_term(fi, GSM48_REJECT_SYNCH_FAILURE); + auth_fsm_term(fi, AUTH_FSM_FAILURE, GSM48_REJECT_SYNCH_FAILURE); break; } } @@ -595,25 +624,25 @@ struct osmo_fsm vlr_auth_fsm = { /* MSC->VLR: Start Procedure Authenticate_VLR (TS 23.012 Ch. 4.1.2.2) */ struct osmo_fsm_inst *auth_fsm_start(struct vlr_subscr *vsub, - uint32_t log_level, struct osmo_fsm_inst *parent, - uint32_t parent_term_event, + uint32_t parent_event_success, + uint32_t parent_event_no_auth_info, + uint32_t parent_event_failure, bool is_r99, bool is_utran) { struct osmo_fsm_inst *fi; struct auth_fsm_priv *afp; - fi = osmo_fsm_inst_alloc_child(&vlr_auth_fsm, parent, - parent_term_event); + fi = osmo_fsm_inst_alloc_child(&vlr_auth_fsm, parent, parent_event_failure); if (!fi) { - osmo_fsm_inst_dispatch(parent, parent_term_event, 0); + osmo_fsm_inst_dispatch(parent, parent_event_failure, 0); return NULL; } afp = talloc_zero(fi, struct auth_fsm_priv); if (!afp) { - osmo_fsm_inst_dispatch(parent, parent_term_event, 0); + osmo_fsm_inst_dispatch(parent, parent_event_failure, 0); return NULL; } @@ -622,6 +651,9 @@ struct osmo_fsm_inst *auth_fsm_start(struct vlr_subscr *vsub, afp->by_imsi = true; afp->is_r99 = is_r99; afp->is_utran = is_utran; + afp->parent_event_success = parent_event_success; + afp->parent_event_no_auth_info = parent_event_no_auth_info; + afp->parent_event_failure = parent_event_failure; fi->priv = afp; vsub->auth_fsm = fi; diff --git a/src/libvlr/vlr_auth_fsm.h b/src/libvlr/vlr_auth_fsm.h index 1f2cb4969..828384206 100644 --- a/src/libvlr/vlr_auth_fsm.h +++ b/src/libvlr/vlr_auth_fsm.h @@ -27,12 +27,13 @@ enum vlr_fsm_auth_event { VLR_AUTH_E_MS_ID_IMSI, }; -struct osmo_fsm vlr_auth_fsm; +extern struct osmo_fsm vlr_auth_fsm; struct osmo_fsm_inst *auth_fsm_start(struct vlr_subscr *vsub, - uint32_t log_level, struct osmo_fsm_inst *parent, - uint32_t parent_term_event, + uint32_t parent_event_success, + uint32_t parent_event_no_auth_info, + uint32_t parent_event_failure, bool is_r99, bool is_utran); diff --git a/src/libvlr/vlr_lu_fsm.c b/src/libvlr/vlr_lu_fsm.c index 9dff4aa2d..5d8f78bc2 100644 --- a/src/libvlr/vlr_lu_fsm.c +++ b/src/libvlr/vlr_lu_fsm.c @@ -366,13 +366,6 @@ static void vlr_lu_compl_fsm_success(struct osmo_fsm_inst *fi) vlr_sgs_fsm_update_id(vsub); } -static void vlr_lu_compl_fsm_failure(struct osmo_fsm_inst *fi, uint8_t cause) -{ - struct lu_compl_vlr_priv *lcvp = lu_compl_vlr_fi_priv(fi); - lcvp->vsub->vlr->ops.tx_lu_rej(lcvp->msc_conn_ref, cause); - _vlr_lu_compl_fsm_done(fi, VLR_FSM_RESULT_FAILURE, cause); -} - static void vlr_lu_compl_fsm_dispatch_result(struct osmo_fsm_inst *fi, uint32_t prev_state) { @@ -434,8 +427,7 @@ static void lu_compl_vlr_new_tmsi(struct osmo_fsm_inst *fi) LOGPFSM(fi, "%s()\n", __func__); if (vlr_subscr_alloc_tmsi(vsub)) { - vlr_lu_compl_fsm_failure(fi, - GSM48_REJECT_SRV_OPT_TMP_OUT_OF_ORDER); + _vlr_lu_compl_fsm_done(fi, VLR_FSM_RESULT_FAILURE, GSM48_REJECT_SRV_OPT_TMP_OUT_OF_ORDER); return; } @@ -477,6 +469,8 @@ static void lu_compl_vlr_wait_subscr_pres(struct osmo_fsm_inst *fi, lu_compl_vlr_new_tmsi(fi); return; } + /* else, any previously used TMSI is now invalid. */ + vsub->tmsi = GSM_RESERVED_TMSI; /* Location Updating Accept */ vlr->ops.tx_lu_acc(lcvp->msc_conn_ref, GSM_RESERVED_TMSI); @@ -495,15 +489,14 @@ static void lu_compl_vlr_wait_imei(struct osmo_fsm_inst *fi, uint32_t event, case LU_COMPL_VLR_E_IMEI_CHECK_ACK: if (!vsub->imei[0]) { /* Abort: Do nothing */ - vlr_lu_compl_fsm_failure(fi, - GSM48_REJECT_PROTOCOL_ERROR); + _vlr_lu_compl_fsm_done(fi, VLR_FSM_RESULT_FAILURE, GSM48_REJECT_PROTOCOL_ERROR); return; } /* Pass */ break; case LU_COMPL_VLR_E_IMEI_CHECK_NACK: - vlr_lu_compl_fsm_failure(fi, GSM48_REJECT_ILLEGAL_ME); + _vlr_lu_compl_fsm_done(fi, VLR_FSM_RESULT_FAILURE, GSM48_REJECT_ILLEGAL_ME); /* FIXME: IMEI Check Fail to VLR Application (Detach IMSI VLR) */ return; } @@ -523,6 +516,8 @@ static void lu_compl_vlr_wait_imei(struct osmo_fsm_inst *fi, uint32_t event, /* Wait for TMSI ack */ return; } + /* else, any previously used TMSI is now invalid. */ + vsub->tmsi = GSM_RESERVED_TMSI; /* No TMSI needed, accept now. */ vlr->ops.tx_lu_acc(lcvp->msc_conn_ref, GSM_RESERVED_TMSI); @@ -544,7 +539,7 @@ static void lu_compl_vlr_wait_tmsi(struct osmo_fsm_inst *fi, uint32_t event, LOGPFSML(fi, LOGL_ERROR, "TMSI Realloc Compl implies that" " the subscriber has a new TMSI allocated, but" " the new TMSI is unset.\n"); - vlr_lu_compl_fsm_failure(fi, GSM48_REJECT_NETWORK_FAILURE); + _vlr_lu_compl_fsm_done(fi, VLR_FSM_RESULT_FAILURE, GSM48_REJECT_NETWORK_FAILURE); return; } @@ -651,7 +646,9 @@ static const struct value_string fsm_lu_event_names[] = { OSMO_VALUE_STRING(VLR_ULA_E_UPDATE_LA), OSMO_VALUE_STRING(VLR_ULA_E_SEND_ID_ACK), OSMO_VALUE_STRING(VLR_ULA_E_SEND_ID_NACK), - OSMO_VALUE_STRING(VLR_ULA_E_AUTH_RES), + OSMO_VALUE_STRING(VLR_ULA_E_AUTH_SUCCESS), + OSMO_VALUE_STRING(VLR_ULA_E_AUTH_NO_INFO), + OSMO_VALUE_STRING(VLR_ULA_E_AUTH_FAILURE), OSMO_VALUE_STRING(VLR_ULA_E_CIPH_RES), OSMO_VALUE_STRING(VLR_ULA_E_ID_IMSI), OSMO_VALUE_STRING(VLR_ULA_E_ID_IMEI), @@ -685,7 +682,12 @@ struct lu_fsm_priv { struct osmo_location_area_id old_lai; struct osmo_location_area_id new_lai; bool authentication_required; - bool ciphering_required; + /* is_ciphering_to_be_attempted: true when any A5/n > 0 are enabled. Ciphering is allowed, always attempt to get Auth Info from + * the HLR. */ + bool is_ciphering_to_be_attempted; + /* is_ciphering_required: true when A5/0 is disabled. If we cannot get Auth Info from the HLR, reject the + * subscriber. */ + bool is_ciphering_required; uint8_t key_seq; bool is_r99; bool is_utran; @@ -697,24 +699,26 @@ struct lu_fsm_priv { static bool lai_in_this_vlr(struct vlr_instance *vlr, const struct osmo_location_area_id *lai) { - /* TODO: VLR needs to keep a locally configued list of LAIs */ + /* TODO: VLR needs to keep a locally configured list of LAIs */ return true; } -/* Determine if authentication is required */ -static bool is_auth_required(struct lu_fsm_priv *lfp) +/* Return true when authentication should be attempted. */ +static bool try_auth(struct lu_fsm_priv *lfp) { /* The cases where the authentication procedure should be used * are defined in 3GPP TS 33.102 */ /* For now we use a default value passed in to vlr_lu_fsm(). */ return lfp->authentication_required || - (lfp->ciphering_required && !auth_try_reuse_tuple(lfp->vsub, lfp->key_seq)); + (lfp->is_ciphering_to_be_attempted && !auth_try_reuse_tuple(lfp->vsub, lfp->key_seq)); } -/* Determine if ciphering is required */ -static bool is_ciph_required(struct lu_fsm_priv *lfp) +/* Return true when CipherModeCmd / SecurityModeCmd should be attempted. */ +static bool is_cmc_smc_to_be_attempted(struct lu_fsm_priv *lfp) { - return lfp->ciphering_required; + /* UTRAN: always send SecModeCmd, even if ciphering is not required. + * GERAN: avoid sending CiphModeCmd if ciphering is not required. */ + return lfp->is_utran || lfp->is_ciphering_to_be_attempted; } /* Determine if a HLR Update is required */ @@ -827,18 +831,15 @@ static void vlr_loc_upd_post_ciph(struct osmo_fsm_inst *fi) { struct lu_fsm_priv *lfp = lu_fsm_fi_priv(fi); struct vlr_subscr *vsub = lfp->vsub; + int rc; LOGPFSM(fi, "%s()\n", __func__); OSMO_ASSERT(vsub); - if (lfp->is_utran) { - int rc; - rc = lfp->vlr->ops.tx_common_id(lfp->msc_conn_ref); - if (rc) - LOGPFSML(fi, LOGL_ERROR, - "Error while sending Common ID (%d)\n", rc); - } + rc = lfp->vlr->ops.tx_common_id(lfp->msc_conn_ref); + if (rc) + LOGPFSML(fi, LOGL_ERROR, "Error while sending Common ID (%d)\n", rc); vsub->conf_by_radio_contact_ind = true; /* Update LAI */ @@ -865,7 +866,10 @@ static void vlr_loc_upd_post_auth(struct osmo_fsm_inst *fi) OSMO_ASSERT(vsub); - if (!is_ciph_required(lfp)) { + /* Continue with ciphering, if enabled. + * If auth/ciph is optional and the HLR returned no auth info, continue without ciphering. */ + if (!is_cmc_smc_to_be_attempted(lfp) + || (vsub->sec_ctx == VLR_SEC_CTX_NONE && !lfp->is_ciphering_required)) { vlr_loc_upd_post_ciph(fi); return; } @@ -890,7 +894,6 @@ static void vlr_loc_upd_post_auth(struct osmo_fsm_inst *fi) } if (vlr_set_ciph_mode(vsub->vlr, fi, lfp->msc_conn_ref, - lfp->ciphering_required, umts_aka, vsub->vlr->cfg.retrieve_imeisv_ciphered)) { LOGPFSML(fi, LOGL_ERROR, @@ -911,12 +914,15 @@ static void vlr_loc_upd_node1(struct osmo_fsm_inst *fi) OSMO_ASSERT(vsub); - if (is_auth_required(lfp)) { + if (try_auth(lfp)) { /* Authenticate_VLR */ osmo_fsm_inst_state_chg(fi, VLR_ULA_S_WAIT_AUTH, LU_TIMEOUT_LONG, 0); - vsub->auth_fsm = auth_fsm_start(lfp->vsub, fi->log_level, - fi, VLR_ULA_E_AUTH_RES, + vsub->auth_fsm = auth_fsm_start(lfp->vsub, + fi, + VLR_ULA_E_AUTH_SUCCESS, + VLR_ULA_E_AUTH_NO_INFO, + VLR_ULA_E_AUTH_FAILURE, lfp->is_r99, lfp->is_utran); } else { @@ -1149,17 +1155,32 @@ static void lu_fsm_wait_auth(struct osmo_fsm_inst *fi, uint32_t event, struct lu_fsm_priv *lfp = lu_fsm_fi_priv(fi); enum gsm48_reject_value *res = data; - OSMO_ASSERT(event == VLR_ULA_E_AUTH_RES); - lfp->upd_hlr_vlr_fsm = NULL; - if (!res || *res) { - lu_fsm_failure(fi, res? *res : GSM48_REJECT_NETWORK_FAILURE); + switch (event) { + case VLR_ULA_E_AUTH_SUCCESS: + /* Result == Pass */ + vlr_loc_upd_post_auth(fi); + return; + + case VLR_ULA_E_AUTH_FAILURE: + lu_fsm_failure(fi, res ? *res : GSM48_REJECT_NETWORK_FAILURE); return; - } - /* Result == Pass */ - vlr_loc_upd_post_auth(fi); + case VLR_ULA_E_AUTH_NO_INFO: + /* HLR returned no auth info for the subscriber. Continue only if authentication is optional. */ + if (lfp->authentication_required || lfp->is_ciphering_required) { + lu_fsm_failure(fi, res ? *res : GSM48_REJECT_NETWORK_FAILURE); + return; + } + LOGPFSML(fi, LOGL_INFO, + "Attaching subscriber without auth (auth is optional, and no auth info received from HLR)\n"); + vlr_loc_upd_post_auth(fi); + return; + + default: + OSMO_ASSERT(false); + } } static void lu_fsm_wait_ciph(struct osmo_fsm_inst *fi, uint32_t event, @@ -1243,6 +1264,10 @@ static void lu_fsm_wait_hlr_ul_res(struct osmo_fsm_inst *fi, uint32_t event, } } break; + case VLR_ULA_E_ID_IMEI: + case VLR_ULA_E_ID_IMEISV: + /* Got the IMEI from ME, nothing to do right now though. */ + break; default: OSMO_ASSERT(0); break; @@ -1262,6 +1287,7 @@ static void lu_fsm_wait_lu_compl(struct osmo_fsm_inst *fi, uint32_t event, LU_COMPL_VLR_E_NEW_TMSI_ACK, NULL); break; case VLR_ULA_E_ID_IMEI: + case VLR_ULA_E_ID_IMEISV: /* Got the IMEI from ME, now send it to HLR */ vlr_subscr_tx_req_check_imei(lfp->vsub); break; @@ -1369,7 +1395,9 @@ static const struct osmo_fsm_state vlr_lu_fsm_states[] = { .action = lu_fsm_wait_pvlr, }, [VLR_ULA_S_WAIT_AUTH] = { - .in_event_mask = S(VLR_ULA_E_AUTH_RES), + .in_event_mask = S(VLR_ULA_E_AUTH_SUCCESS) | + S(VLR_ULA_E_AUTH_NO_INFO) | + S(VLR_ULA_E_AUTH_FAILURE), .out_state_mask = S(VLR_ULA_S_WAIT_CIPH) | S(VLR_ULA_S_WAIT_LU_COMPL) | S(VLR_ULA_S_WAIT_HLR_UPD) | @@ -1408,7 +1436,9 @@ static const struct osmo_fsm_state vlr_lu_fsm_states[] = { }, [VLR_ULA_S_WAIT_HLR_UPD] = { .in_event_mask = S(VLR_ULA_E_HLR_LU_RES) | - S(VLR_ULA_E_UPD_HLR_COMPL), + S(VLR_ULA_E_UPD_HLR_COMPL) | + S(VLR_ULA_E_ID_IMEI) | + S(VLR_ULA_E_ID_IMEISV), .out_state_mask = S(VLR_ULA_S_WAIT_LU_COMPL) | S(VLR_ULA_S_WAIT_LU_COMPL_STANDALONE) | S(VLR_ULA_S_DONE), @@ -1479,7 +1509,8 @@ vlr_loc_update(struct osmo_fsm_inst *parent, const struct osmo_location_area_id *old_lai, const struct osmo_location_area_id *new_lai, bool authentication_required, - bool ciphering_required, + bool is_ciphering_to_be_attempted, + bool is_ciphering_required, uint8_t key_seq, bool is_r99, bool is_utran, bool assign_tmsi) @@ -1487,6 +1518,9 @@ vlr_loc_update(struct osmo_fsm_inst *parent, struct osmo_fsm_inst *fi; struct lu_fsm_priv *lfp; + if (is_ciphering_required) + OSMO_ASSERT(is_ciphering_to_be_attempted); + fi = osmo_fsm_inst_alloc_child(&vlr_lu_fsm, parent, parent_event_failure); if (!fi) return NULL; @@ -1503,7 +1537,8 @@ vlr_loc_update(struct osmo_fsm_inst *parent, lfp->parent_event_failure = parent_event_failure; lfp->parent_event_data = parent_event_data; lfp->authentication_required = authentication_required; - lfp->ciphering_required = ciphering_required; + lfp->is_ciphering_to_be_attempted = is_ciphering_to_be_attempted; + lfp->is_ciphering_required = is_ciphering_required; lfp->key_seq = key_seq; lfp->is_r99 = is_r99; lfp->is_utran = is_utran; @@ -1518,10 +1553,10 @@ vlr_loc_update(struct osmo_fsm_inst *parent, LOGPFSM(fi, "rev=%s net=%s%s%s\n", is_r99 ? "R99" : "GSM", is_utran ? "UTRAN" : "GERAN", - (authentication_required || ciphering_required)? + (authentication_required || is_ciphering_to_be_attempted) ? " Auth" : " (no Auth)", - (authentication_required || ciphering_required)? - (ciphering_required? "+Ciph" : " (no Ciph)") + (authentication_required || is_ciphering_to_be_attempted) ? + (is_ciphering_to_be_attempted ? "+Ciph" : " (no Ciph)") : ""); if (is_utran && !authentication_required) diff --git a/src/libvlr/vlr_sgs.c b/src/libvlr/vlr_sgs.c index 452de2cca..61db585b6 100644 --- a/src/libvlr/vlr_sgs.c +++ b/src/libvlr/vlr_sgs.c @@ -44,7 +44,7 @@ const struct value_string sgs_state_counter_names[] = { }; /* Reset all SGs-Associations back to zero. - * \param[in] vlr VLR instace. */ + * \param[in] vlr VLR instance. */ void vlr_sgs_reset(struct vlr_instance *vlr) { struct vlr_subscr *vsub; @@ -59,20 +59,21 @@ void vlr_sgs_reset(struct vlr_instance *vlr) } /*! Perform an SGs location update. - * \param[in] vlr VLR instace. + * \param[in] vlr VLR instance. * \param[in] cfg SGs interface configuration parameters. - * \param[in] response_cb calback function that is called when LU is done. - * \param[in] paging_cb calback function that is called when LU needs to page. - * \param[in] mminfo_cb calback function that is called to provide MM info to the UE. + * \param[in] response_cb callback function that is called when LU is done. + * \param[in] paging_cb callback function that is called when LU needs to page. + * \param[in] mminfo_cb callback function that is called to provide MM info to the UE. * \param[in] mme_name fqdn of the requesting MME (mme-name). * \param[in] type location update type (normal or IMSI attach). * \param[in] imsi mobile identity (IMSI). * \param[in] new_lai identifier of the new location area. + * \param[in] last_eutran_plnm_id Last E-UTRAN PLMN ID (can be NULL). * \returns 0 in case of success, -EINVAL in case of error. */ int vlr_sgs_loc_update(struct vlr_instance *vlr, struct vlr_sgs_cfg *cfg, vlr_sgs_lu_response_cb_t response_cb, vlr_sgs_lu_paging_cb_t paging_cb, vlr_sgs_lu_mminfo_cb_t mminfo_cb, char *mme_name, enum vlr_lu_type type, const char *imsi, - struct osmo_location_area_id *new_lai) + struct osmo_location_area_id *new_lai, struct osmo_plmn_id *last_eutran_plmn) { struct vlr_subscr *vsub = NULL; @@ -82,7 +83,7 @@ int vlr_sgs_loc_update(struct vlr_instance *vlr, struct vlr_sgs_cfg *cfg, OSMO_ASSERT(cfg); OSMO_ASSERT(imsi); - vsub = vlr_subscr_find_or_create_by_imsi(vlr, imsi, VSUB_USE_SGS, NULL); + vsub = vlr_subscr_find_or_create_by_imsi(vlr, imsi, VSUB_USE_SGS_LU, NULL); if (!vsub) { LOGP(DSGS, LOGL_ERROR, "VLR subscriber allocation failed\n"); return -EINVAL; @@ -93,6 +94,7 @@ int vlr_sgs_loc_update(struct vlr_instance *vlr, struct vlr_sgs_cfg *cfg, vsub->sgs.paging_cb = paging_cb; vsub->sgs.mminfo_cb = mminfo_cb; vlr_subscr_set_imsi(vsub, imsi); + vlr_subscr_set_last_used_eutran_plmn_id(vsub, last_eutran_plmn); osmo_strlcpy(vsub->sgs.mme_name, mme_name, sizeof(vsub->sgs.mme_name)); osmo_fsm_inst_dispatch(vsub->sgs_fsm, SGS_UE_E_RX_LU_FROM_MME, NULL); @@ -117,6 +119,9 @@ void vlr_sgs_loc_update_acc_sent(struct vlr_subscr *vsub) { osmo_fsm_inst_dispatch(vsub->sgs_fsm, SGS_UE_E_TX_LU_ACCEPT, NULL); + /* Balance vlr_subscr_find_or_create_by_imsi() in vlr_sgs_loc_update() */ + vlr_subscr_put(vsub, VSUB_USE_SGS_LU); + /* FIXME: At this point we need to check the status of Ts5 and if * it is still running this means the LU has interrupted the paging, * and we need to start paging again. 3GPP TS 29.118, @@ -128,6 +133,8 @@ void vlr_sgs_loc_update_acc_sent(struct vlr_subscr *vsub) void vlr_sgs_loc_update_rej_sent(struct vlr_subscr *vsub) { osmo_fsm_inst_dispatch(vsub->sgs_fsm, SGS_UE_E_TX_LU_REJECT, NULL); + /* Balance vlr_subscr_find_or_create_by_imsi() in vlr_sgs_loc_update() */ + vlr_subscr_put(vsub, VSUB_USE_SGS_LU); } /*! Perform an SGs IMSI detach. @@ -146,8 +153,10 @@ void vlr_sgs_imsi_detach(struct vlr_instance *vlr, const char *imsi, enum sgsap_ /* See also: 3GPP TS 29.118, 5.6.3 Procedures in the VLR: In case of * an implicit detach, we are supposed to check if the state of the * SGs-association, and only when it is not SGs-NULL, we may proceed. */ - if (vsub->sgs_fsm->state == SGS_UE_ST_NULL && type == SGSAP_ID_NONEPS_T_IMPLICIT_UE_EPS_NONEPS) + if (vsub->sgs_fsm->state == SGS_UE_ST_NULL && type == SGSAP_ID_NONEPS_T_IMPLICIT_UE_EPS_NONEPS) { + vlr_subscr_put(vsub, __func__); return; + } switch (type) { case SGSAP_ID_NONEPS_T_EXPLICIT_UE_NONEPS: @@ -299,7 +308,7 @@ static void Ts5_timeout_cb(void *arg) { struct vlr_subscr *vsub = arg; - /* 3GPP TS 29.118 does not specify a specif action that has to happen + /* 3GPP TS 29.118 does not specify a specific action that has to happen * in case Ts5 times out. The timeout just indicates that the paging * failed. Other actions may check the status of Ts5 to see if a paging * is still ongoing or not. */ @@ -327,7 +336,7 @@ void vlr_sgs_pag(struct vlr_subscr *vsub, enum sgsap_service_ind serv_ind) /* Note: 3GPP TS 29.118, chapter 4.2.2 mentions paging in the FSM * diagram, but paging never causes a state transition except when * an explicit failure is indicated (MME actively rejects paging). - * Apparantly it is also possible that an LU happens while the paging + * Apparently it is also possible that an LU happens while the paging * is still ongoing and Ts5 is running. (chapter 5.1.2.3). This means * that the paging procedure is intended to run in parallel to the * SGs FSM and given that the benaviour around Ts5 must be implemented diff --git a/src/libvlr/vlr_sgs_fsm.c b/src/libvlr/vlr_sgs_fsm.c index 13639ca3c..2771cf5ce 100644 --- a/src/libvlr/vlr_sgs_fsm.c +++ b/src/libvlr/vlr_sgs_fsm.c @@ -48,35 +48,21 @@ static const struct value_string sgs_ue_fsm_event_names[] = { {0, NULL} }; -/* Initiate location update and change to SGS_UE_ST_LA_UPD_PRES state */ -static void perform_lu(struct osmo_fsm_inst *fi) -{ - struct vlr_subscr *vsub = fi->priv; - int rc; - osmo_fsm_inst_state_chg(fi, SGS_UE_ST_LA_UPD_PRES, 0, 0); - vsub->ms_not_reachable_flag = false; - - /* Note: At the moment we allocate a new TMSI on each LU. */ - rc = vlr_subscr_alloc_tmsi(vsub); - if (rc != 0) - LOGPFSML(fi, LOGL_ERROR, "(sub %s) VLR LU tmsi allocation failed\n", vlr_subscr_name(vsub)); - - rc = vlr_subscr_req_lu(vsub); - if (rc != 0) - LOGPFSML(fi, LOGL_ERROR, "(sub %s) HLR LU request failed\n", vlr_subscr_name(vsub)); -} - /* Send the SGs Association to NULL state immediately */ static void to_null(struct osmo_fsm_inst *fi) { struct vlr_subscr *vsub = fi->priv; osmo_fsm_inst_state_chg(fi, SGS_UE_ST_NULL, 0, 0); - /* Note: This is only relevent for cases where we are in the middle + /* Note: This is only relevant for cases where we are in the middle * of an TMSI reallocation procedure. Should a failure of some sort * put us to NULL state, we have to free the pending TMSI */ vsub->tmsi_new = GSM_RESERVED_TMSI; + /* Make sure we remove recorded Last EUTRAN PLMN Id when UE ceases to be + * available over SGs */ + vlr_subscr_set_last_used_eutran_plmn_id(vsub, NULL); + /* Make sure any ongoing paging is aborted. */ if (vsub->cs.is_paging) paging_expired(vsub); @@ -86,6 +72,37 @@ static void to_null(struct osmo_fsm_inst *fi) osmo_timer_del(&vsub->sgs.Ts5); } +/* Initiate location update and change to SGS_UE_ST_LA_UPD_PRES state */ +static void perform_lu(struct osmo_fsm_inst *fi) +{ + struct vlr_subscr *vsub = fi->priv; + struct sgs_lu_response sgs_lu_response = {0}; + int rc; + + /* Note: At the moment we allocate a new TMSI on each LU. */ + rc = vlr_subscr_alloc_tmsi(vsub); + if (rc != 0) { + LOGPFSML(fi, LOGL_ERROR, "(sub %s) VLR LU tmsi allocation failed\n", vlr_subscr_name(vsub)); + goto error; + } + + rc = vlr_subscr_req_lu(vsub); + if (rc != 0) { + LOGPFSML(fi, LOGL_ERROR, "(sub %s) HLR LU request failed\n", vlr_subscr_name(vsub)); + goto error; + } + + osmo_fsm_inst_state_chg(fi, SGS_UE_ST_LA_UPD_PRES, 0, 0); + vsub->ms_not_reachable_flag = false; + return; + +error: + to_null(fi); + sgs_lu_response.error = true; + sgs_lu_response.vsub = vsub; + vsub->sgs.response_cb(&sgs_lu_response); +} + /* Respawn a pending paging (Timer is reset and a new paging request is sent) */ static void respawn_paging(struct vlr_subscr *vsub) { @@ -143,7 +160,7 @@ static void sgs_ue_fsm_lau_present(struct osmo_fsm_inst *fi, uint32_t event, voi /* Check if we expect a TMSI REALLOCATION COMPLETE message from the MME * by checking the tmsi_new flag. If this flag is not GSM_RESERVED_TMSI * we know that we have a TMSI pending and need to wait for the MME - * to acknowlege first */ + * to acknowledge first */ if (vsub->tmsi_new != GSM_RESERVED_TMSI) { osmo_fsm_inst_state_chg(fi, SGS_UE_ST_ASSOCIATED, vsub->sgs.cfg.timer[SGS_STATE_TS6_2], SGS_STATE_TS6_2); @@ -209,7 +226,7 @@ static void sgs_ue_fsm_associated(struct osmo_fsm_inst *fi, uint32_t event, void /* Note: We are already in SGS_UE_ST_ASSOCIATED but the * transition that lead us here had is guarded with Ts6-1, - * wo we change the state now once more without timeout + * so we change the state now once more without timeout * to ensure the timer is stopped */ osmo_fsm_inst_state_chg(fi, SGS_UE_ST_ASSOCIATED, 0, 0); break; @@ -221,6 +238,7 @@ static void sgs_ue_fsm_associated(struct osmo_fsm_inst *fi, uint32_t event, void if (*cause == SGSAP_SGS_CAUSE_MT_CSFB_REJ_USER) break; to_null(fi); + break; case SGS_UE_E_RX_ALERT_FAILURE: to_null(fi); break; @@ -342,7 +360,7 @@ static struct osmo_fsm sgs_ue_fsm = { .event_names = sgs_ue_fsm_event_names, }; -/*! Initalize/Register SGs FSM in osmo-fsm subsystem */ +/*! Initialize/Register SGs FSM in osmo-fsm subsystem */ void vlr_sgs_fsm_init(void) { if (osmo_fsm_find_by_name(sgs_ue_fsm.name) != &sgs_ue_fsm) diff --git a/src/osmo-msc/Makefile.am b/src/osmo-msc/Makefile.am index 7b56c7458..0380d5d1f 100644 --- a/src/osmo-msc/Makefile.am +++ b/src/osmo-msc/Makefile.am @@ -19,6 +19,7 @@ AM_CFLAGS = \ $(LIBOSMOSIGTRAN_CFLAGS) \ $(LIBOSMOMGCPCLIENT_CFLAGS) \ $(LIBOSMOGSUPCLIENT_CFLAGS) \ + $(LIBSQLITE3_CFLAGS) \ $(NULL) AM_LDFLAGS = \ @@ -42,12 +43,20 @@ osmo_msc_LDADD = \ $(LIBOSMOCTRL_LIBS) \ $(LIBOSMOABIS_LIBS) \ $(LIBOSMONETIF_LIBS) \ - $(LIBSMPP34_LIBS) \ $(LIBOSMORANAP_LIBS) \ $(LIBASN1C_LIBS) \ $(LIBOSMOSIGTRAN_LIBS) \ $(LIBOSMOMGCPCLIENT_LIBS) \ $(LIBOSMOGSUPCLIENT_LIBS) \ - -ldbi \ + $(LIBSQLITE3_LIBS) \ -lsctp \ $(NULL) + +if BUILD_SMPP + +osmo_msc_LDADD += \ + $(top_builddir)/src/libsmpputil/libsmpputil.a \ + $(LIBSMPP34_LIBS) \ + $(NULL) + +endif diff --git a/src/osmo-msc/msc_main.c b/src/osmo-msc/msc_main.c index 9da26fba0..913bd212f 100644 --- a/src/osmo-msc/msc_main.c +++ b/src/osmo-msc/msc_main.c @@ -1,4 +1,4 @@ -/* OsmoMSC - Circuit-Switched Core Network (MSC+VLR+HLR+SMSC) implementation +/* OsmoMSC - Circuit-Switched Core Network (MSC+VLR+SMSC) implementation */ /* (C) 2016-2019 by sysmocom s.f.m.c. GmbH <info@sysmocom.de> @@ -26,6 +26,7 @@ #include <stdbool.h> #include <unistd.h> +#include <stdio.h> #include <time.h> #include <errno.h> #include <signal.h> @@ -52,13 +53,14 @@ #include <osmocom/vty/ports.h> #include <osmocom/vty/logging.h> #include <osmocom/vty/misc.h> +#include <osmocom/vty/cpu_sched_vty.h> #include <osmocom/msc/vty.h> #include <osmocom/msc/mncc.h> #include <osmocom/msc/rrlp.h> #include <osmocom/ctrl/control_if.h> #include <osmocom/ctrl/control_vty.h> #include <osmocom/ctrl/ports.h> -#include <osmocom/msc/smpp.h> +#include <osmocom/smpp/smpp.h> #include <osmocom/sigtran/osmo_ss7.h> #include <osmocom/mgcp_client/mgcp_client.h> #include <osmocom/msc/sgs_iface.h> @@ -98,12 +100,10 @@ void *tall_map_ctx = NULL; /* end deps from libbsc legacy. */ static struct { - const char *database_name; const char *config_file; int daemonize; const char *mncc_sock_path; } msc_cmdline_config = { - .database_name = "sms.db", .config_file = "osmo-msc.cfg", }; @@ -119,35 +119,65 @@ static void print_usage() static void print_help() { - printf(" Some useful help...\n"); + printf("Some useful options:\n"); printf(" -h --help This text.\n"); printf(" -d option --debug=DCC:DMM:DRR: 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(" -s --disable-color\n"); - printf(" -l --database db-name The database to use.\n"); printf(" -T --timestamp Prefix every log line with a timestamp.\n"); printf(" -V --version Print the version of OsmoMSC.\n"); printf(" -e --log-level number Set a global loglevel.\n"); - printf(" -M --mncc-sock-path PATH Disable built-in MNCC handler and offer socket.\n"); + + printf("\nVTY reference generation:\n"); + printf(" --vty-ref-mode MODE VTY reference generation mode (e.g. 'expert').\n"); + printf(" --vty-ref-xml Generate the VTY reference XML output and exit.\n"); +} + +static void handle_long_options(const char *prog_name, const int long_option) +{ + static int vty_ref_mode = VTY_REF_GEN_MODE_DEFAULT; + + switch (long_option) { + case 1: + vty_ref_mode = get_string_value(vty_ref_gen_mode_names, optarg); + if (vty_ref_mode < 0) { + fprintf(stderr, "%s: Unknown VTY reference generation " + "mode '%s'\n", prog_name, optarg); + exit(2); + } + break; + case 2: + fprintf(stderr, "Generating the VTY reference in mode '%s' (%s)\n", + get_value_string(vty_ref_gen_mode_names, vty_ref_mode), + get_value_string(vty_ref_gen_mode_desc, vty_ref_mode)); + vty_dump_xml_ref_mode(stdout, (enum vty_ref_gen_mode) vty_ref_mode); + exit(0); + default: + fprintf(stderr, "%s: error parsing cmdline options\n", prog_name); + exit(2); + } } static void handle_options(int argc, char **argv) { while (1) { int option_index = 0, c; + static int long_option = 0; static struct option long_options[] = { {"help", 0, 0, 'h'}, {"debug", 1, 0, 'd'}, {"daemonize", 0, 0, 'D'}, {"config-file", 1, 0, 'c'}, {"disable-color", 0, 0, 's'}, - {"database", 1, 0, 'l'}, + {"database", 1, 0, 'l'}, /* deprecated */ {"timestamp", 0, 0, 'T'}, {"version", 0, 0, 'V' }, {"log-level", 1, 0, 'e'}, - {"mncc-sock-path", 1, 0, 'M'}, + {"mncc-sock-path", 1, 0, 'M'}, /* deprecated */ {"no-dbcounter", 0, 0, 'C'}, /* deprecated */ + {"vty-ref-mode", 1, &long_option, 1}, + {"vty-ref-xml", 0, &long_option, 2}, {0, 0, 0, 0} }; @@ -161,6 +191,9 @@ static void handle_options(int argc, char **argv) print_usage(); print_help(); exit(0); + case 0: + handle_long_options(argv[0], long_option); + break; case 's': log_set_use_color(osmo_stderr_target, 0); break; @@ -171,7 +204,9 @@ static void handle_options(int argc, char **argv) msc_cmdline_config.daemonize = 1; break; case 'l': - msc_cmdline_config.database_name = optarg; + fprintf(stderr, "Command line argument '-%c' is deprecated, use VTY " + "parameter 'smsc' / 'database %s' instead.\n", c, optarg); + exit(2); break; case 'c': msc_cmdline_config.config_file = optarg; @@ -184,6 +219,8 @@ static void handle_options(int argc, char **argv) break; case 'M': msc_cmdline_config.mncc_sock_path = optarg; + fprintf(stderr, "Command line argument '-%c' is deprecated, use VTY " + "parameter 'msc' / 'mncc external %s' instead.\n", c, optarg); break; case 'C': fprintf(stderr, "-C is deprecated and does nothing."); @@ -198,10 +235,15 @@ static void handle_options(int argc, char **argv) exit(-1); } } + + if (argc > optind) { + fprintf(stderr, "Unsupported positional arguments on command line\n"); + exit(2); + } } -struct gsm_network *msc_network_alloc(void *ctx, - mncc_recv_cb_t mncc_recv) +static struct gsm_network *msc_network_alloc(void *ctx, + mncc_recv_cb_t mncc_recv) { struct gsm_network *net = gsm_network_init(ctx, mncc_recv); if (!net) @@ -214,8 +256,14 @@ struct gsm_network *msc_network_alloc(void *ctx, MSC_HLR_REMOTE_IP_DEFAULT); net->gsup_server_port = MSC_HLR_REMOTE_PORT_DEFAULT; - mgcp_client_conf_init(&net->mgw.conf); + net->mgw.mgw_pool = mgcp_client_pool_alloc(net); + net->mgw.conf = mgcp_client_conf_alloc(net); + net->call_waiting = true; + net->lcls_permitted = false; + net->mgw.tdefs = g_mgw_tdefs; + osmo_tdefs_reset(net->mgw.tdefs); + net->sms_queue_cfg = sms_queue_cfg_alloc(ctx); return net; } @@ -228,20 +276,29 @@ void msc_network_shutdown(struct gsm_network *net) static struct gsm_network *msc_network = NULL; extern void *tall_vty_ctx; -static void signal_handler(int signal) +static void signal_handler(int signum) { - fprintf(stdout, "signal %u received\n", signal); + fprintf(stdout, "signal %u received\n", signum); - switch (signal) { + switch (signum) { case SIGINT: case SIGTERM: - LOGP(DMSC, LOGL_NOTICE, "Terminating due to signal %d\n", signal); + LOGP(DMSC, LOGL_NOTICE, "Terminating due to signal %d\n", signum); quit++; break; case SIGABRT: osmo_generate_backtrace(); - /* in case of abort, we want to obtain a talloc report - * and then return to the caller, who will abort the process */ + /* in case of abort, we want to obtain a talloc report and + * then run default SIGABRT handler, who will generate coredump + * and abort the process. abort() should do this for us after we + * return, but program wouldn't exit if an external SIGABRT is + * received. + */ + talloc_report(tall_vty_ctx, stderr); + talloc_report_full(tall_msc_ctx, stderr); + signal(SIGABRT, SIG_DFL); + raise(SIGABRT); + break; case SIGUSR1: talloc_report(tall_vty_ctx, stderr); talloc_report_full(tall_msc_ctx, stderr); @@ -261,6 +318,11 @@ static int msc_vty_go_parent(struct vty *vty) vty->node = CONFIG_NODE; vty->index = NULL; break; + case MGW_NODE: + OSMO_ASSERT(msc_network != NULL); + vty->node = GSMNET_NODE; + vty->index = msc_network; + break; case SMPP_ESME_NODE: vty->node = SMPP_NODE; vty->index = NULL; @@ -268,9 +330,19 @@ static int msc_vty_go_parent(struct vty *vty) case SMPP_NODE: case MSC_NODE: case MNCC_INT_NODE: + case ASCI_NODE: vty->node = CONFIG_NODE; vty->index = NULL; break; + case GCR_NODE: + vty->node = ASCI_NODE; + vty->index = NULL; + break; + case VGC_NODE: + case VBC_NODE: + vty->node = GCR_NODE; + vty->index = NULL; + break; case SUBSCR_NODE: vty->node = ENABLE_NODE; vty->index = NULL; @@ -307,7 +379,8 @@ static struct vty_app_info msc_vty_info = { .is_config_node = msc_vty_is_config_node, }; -#define DEFAULT_M3UA_REMOTE_IP "127.0.0.1" +#define DEFAULT_M3UA_LOCAL_IP "localhost" +#define DEFAULT_M3UA_REMOTE_IP "localhost" #define DEFAULT_PC "0.23.1" static struct osmo_sccp_instance *sccp_setup(void *ctx, uint32_t cs7_instance, @@ -319,7 +392,7 @@ static struct osmo_sccp_instance *sccp_setup(void *ctx, uint32_t cs7_instance, return osmo_sccp_simple_client_on_ss7_id(ctx, cs7_instance, label, default_pc, OSMO_SS7_ASP_PROT_M3UA, - 0, NULL, /* local: use arbitrary port and 0.0.0.0. */ + 0, DEFAULT_M3UA_LOCAL_IP, /* local: use arbitrary port and 0.0.0.0. */ 0, /* remote: use protocol default port */ DEFAULT_M3UA_REMOTE_IP); /* Note: If a differing remote IP is to be used, it was already entered in the vty config at @@ -376,6 +449,18 @@ static const struct log_info_cat msc_default_categories[] = { .color = "\033[1;32m", .enabled = 1, .loglevel = LOGL_NOTICE, }, + [DBCC] = { + .name = "DBCC", + .description = "Layer3 Broadcast Call Control (BCC)", + .color = "\033[1;32m", + .enabled = 1, .loglevel = LOGL_NOTICE, + }, + [DGCC] = { + .name = "DGCC", + .description = "Layer3 Group Call Control (GCC)", + .color = "\033[1;32m", + .enabled = 1, .loglevel = LOGL_NOTICE, + }, [DMM] = { .name = "DMM", .description = "Layer3 Mobility Management (MM)", @@ -466,6 +551,11 @@ static const struct log_info_cat msc_default_categories[] = { .description = "Supplementary Services", .enabled = 1, .loglevel = LOGL_NOTICE, }, + [DASCI] = { + .name = "DASCI", + .description = "Advanced Speech Call Items", + .enabled = 1, .loglevel = LOGL_NOTICE, + }, }; static int filter_fn(const struct log_context *ctx, struct log_target *tar) @@ -489,9 +579,49 @@ extern void *tall_gsms_ctx; extern void *tall_call_ctx; extern void *tall_trans_ctx; +static int msc_mgw_setup(void) +{ + struct mgcp_client *mgcp_client_single; + unsigned int pool_members_initalized; + + /* Initialize MGW pool. This initalizes and connects all MGCP clients that are currently configured in + * the pool. Adding additional MGCP clients to the pool is possible but the user has to configure and + * (re)connect them manually from the VTY. */ + if (!mgcp_client_pool_empty(msc_network->mgw.mgw_pool)) { + pool_members_initalized = mgcp_client_pool_connect(msc_network->mgw.mgw_pool); + if (!pool_members_initalized) { + LOGP(DMSC, LOGL_ERROR, "MGW pool failed to initialize any pool members\n"); + return -EINVAL; + } + LOGP(DMSC, LOGL_NOTICE, + "MGW pool with %u pool members configured, (ignoring MGW configuration in VTY node 'msc').\n", + pool_members_initalized); + return 0; + } + + /* Initialize and connect a single MGCP client. This MGCP client will appear as the one and only pool + * member if there is no MGW pool configured. */ + LOGP(DMSC, LOGL_NOTICE, "No MGW pool configured, using MGW configuration in VTY node 'msc'\n"); + mgcp_client_single = mgcp_client_init(msc_network, msc_network->mgw.conf); + if (!mgcp_client_single) { + LOGP(DMSC, LOGL_ERROR, "MGW (single) client initalization failed\n"); + return -EINVAL; + } + if (mgcp_client_connect(mgcp_client_single)) { + LOGP(DMSC, LOGL_ERROR, "MGW (single) connect failed at (%s:%u)\n", + msc_network->mgw.conf->remote_addr, + msc_network->mgw.conf->remote_port); + return -EINVAL; + } + mgcp_client_pool_register_single(msc_network->mgw.mgw_pool, mgcp_client_single); + + return 0; +} + int main(int argc, char **argv) { int rc; + int ret = 0; struct osmo_sccp_instance *sccp_a; struct osmo_sccp_instance *sccp_iu; @@ -499,7 +629,7 @@ int main(int argc, char **argv) /* Track the use of talloc NULL memory contexts */ talloc_enable_null_tracking(); - osmo_fsm_term_safely(true); + osmo_fsm_set_dealloc_ctx(OTC_SELECT); msc_vty_info.copyright = osmomsc_copyright; @@ -518,16 +648,18 @@ int main(int argc, char **argv) osmo_fsm_log_addr(true); osmo_stats_init(tall_msc_ctx); + rate_ctr_init(tall_msc_ctx); /* For --version, vty_init() must be called before handling options */ vty_init(&msc_vty_info); - osmo_ss7_init(); + OSMO_ASSERT(osmo_ss7_init() == 0); osmo_ss7_vty_init_asp(tall_msc_ctx); osmo_sccp_vty_init(); - - /* Parse options */ - handle_options(argc, argv); + ctrl_vty_init(tall_msc_ctx); + logging_vty_add_cmds(); + osmo_talloc_vty_add_cmds(); + osmo_cpu_sched_vty_init(tall_msc_ctx); /* Allocate global gsm_network struct. * At first set the internal MNCC as default, may be changed below according to cfg or cmdline option. */ @@ -535,6 +667,11 @@ int main(int argc, char **argv) if (!msc_network) return -ENOMEM; + msc_vty_init(msc_network); + + /* Parse options */ + handle_options(argc, argv); + call_leg_init(msc_network); mncc_call_fsm_init(msc_network); @@ -543,13 +680,8 @@ int main(int argc, char **argv) exit(1); } - ctrl_vty_init(tall_msc_ctx); - logging_vty_add_cmds(&log_info); - osmo_talloc_vty_add_cmds(); - msc_vty_init(msc_network); - #ifdef BUILD_SMPP - if (smpp_openbsc_alloc_init(tall_msc_ctx) < 0) + if (smpp_msc_alloc_init(tall_msc_ctx) < 0) return -1; #endif sgs_iface_init(tall_msc_ctx, msc_network); @@ -583,8 +715,7 @@ int main(int argc, char **argv) DEBUGP(DMNCC, "Using internal MNCC handler.\n"); /* start telnet after reading config for vty_get_bind_addr() */ - rc = telnet_init_dynif(tall_msc_ctx, &msc_network, - vty_get_bind_addr(), OSMO_VTY_PORT_MSC); + rc = telnet_init_default(tall_msc_ctx, &msc_network, OSMO_VTY_PORT_MSC); if (rc < 0) return 2; @@ -593,28 +724,27 @@ int main(int argc, char **argv) * following code until iu_init() is legacy. */ #ifdef BUILD_SMPP - smpp_openbsc_start(msc_network); + smpp_msc_start(msc_network); #endif /* start control interface after reading config for * ctrl_vty_get_bind_addr() */ - msc_network->ctrl = ctrl_interface_setup_dynip(msc_network, ctrl_vty_get_bind_addr(), - OSMO_CTRL_PORT_MSC, NULL); + msc_network->ctrl = ctrl_interface_setup(msc_network, OSMO_CTRL_PORT_MSC, NULL); if (!msc_network->ctrl) { - printf("Failed to initialize control interface. Exiting.\n"); + fprintf(stderr, "Failed to initialize control interface. Exiting.\n"); return -1; } #if 0 TODO: we probably want some of the _net_ ctrl commands from bsc_base_ctrl_cmds_install(). if (bsc_base_ctrl_cmds_install() != 0) { - printf("Failed to initialize the BSC control commands.\n"); + fprintf(stderr, "Failed to initialize the BSC control commands.\n"); return -1; } #endif if (msc_ctrl_cmds_install(msc_network) != 0) { - printf("Failed to initialize the MSC control commands.\n"); + fprintf(stderr, "Failed to initialize the MSC control commands.\n"); return -1; } @@ -623,12 +753,6 @@ TODO: we probably want some of the _net_ ctrl commands from bsc_base_ctrl_cmds_i /* TODO: is this used for crypto?? Improve randomness, at least we * should try to use the nanoseconds part of the current time. */ - if (db_init(msc_cmdline_config.database_name)) { - printf("DB: Failed to init database: %s\n", - msc_cmdline_config.database_name); - return 4; - } - if (msc_gsup_client_start(msc_network)) { fprintf(stderr, "Failed to start GSUP client\n"); exit(1); @@ -641,11 +765,6 @@ TODO: we probably want some of the _net_ ctrl commands from bsc_base_ctrl_cmds_i exit(1); } - if (db_prepare()) { - printf("DB: Failed to prepare database.\n"); - return 5; - } - signal(SIGINT, &signal_handler); signal(SIGTERM, &signal_handler); signal(SIGABRT, &signal_handler); @@ -654,33 +773,35 @@ TODO: we probably want some of the _net_ ctrl commands from bsc_base_ctrl_cmds_i osmo_init_ignore_signals(); /* start the SMS queue */ - if (sms_queue_start(msc_network, 20) != 0) - return -1; - - msc_network->mgw.client = mgcp_client_init( - msc_network, &msc_network->mgw.conf); + if (sms_queue_start(msc_network) != 0) { + ret = -1; + goto error; + } - if (mgcp_client_connect(msc_network->mgw.client)) { - printf("MGCPGW connect failed\n"); - return 7; + if (msc_mgw_setup() != 0) { + ret = 7; + goto error; } if (ss7_setup(tall_msc_ctx, &sccp_a, &sccp_iu)) { - printf("Setting up SCCP client failed.\n"); - return 8; + fprintf(stderr, "Setting up SCCP client failed.\n"); + ret = 8; + goto error; } if (sgs_server_open(g_sgs)) { - printf("Starting SGs server failed\n"); - return 9; + fprintf(stderr, "Starting SGs server failed\n"); + ret = 9; + goto error; } msc_network->a.sri = sccp_ran_init(msc_network, sccp_a, OSMO_SCCP_SSN_BSSAP, "OsmoMSC-A", &msc_ran_infra[OSMO_RAT_GERAN_A], msc_network); if (!msc_network->a.sri) { - printf("Setting up A receiver failed\n"); - return 10; + fprintf(stderr, "Setting up A receiver failed\n"); + ret = 10; + goto error; } LOGP(DMSC, LOGL_NOTICE, "A-interface: SCCP user %s, cs7-instance %u (%s)\n", osmo_sccp_user_name(msc_network->a.sri->scu), @@ -694,8 +815,9 @@ TODO: we probably want some of the _net_ ctrl commands from bsc_base_ctrl_cmds_i "OsmoMSC-IuCS", &msc_ran_infra[OSMO_RAT_UTRAN_IU], msc_network); if (!msc_network->iu.sri) { - printf("Setting up IuCS receiver failed\n"); - return 11; + fprintf(stderr, "Setting up IuCS receiver failed\n"); + ret = 11; + goto error; } /* Compatibility with legacy osmo-hnbgw that was unable to properly handle RESET messages. */ @@ -714,19 +836,32 @@ TODO: we probably want some of the _net_ ctrl commands from bsc_base_ctrl_cmds_i rc = osmo_daemonize(); if (rc < 0) { perror("Error during daemonize"); - return 6; + ret = 6; + goto error; } } - while (!quit) { + do { log_reset_context(); - osmo_select_main(0); - } + osmo_select_main_ctx(0); + + /* If the user hits Ctrl-C the third time, just terminate immediately. */ + if (quit >= 3) + break; + + /* Has SIGTERM been received (and not yet been handled)? */ + if (quit && !osmo_select_shutdown_requested()) { + msc_network_shutdown(msc_network); + osmo_signal_dispatch(SS_L_GLOBAL, S_L_GLOBAL_SHUTDOWN, NULL); - msc_network_shutdown(msc_network); - osmo_signal_dispatch(SS_L_GLOBAL, S_L_GLOBAL_SHUTDOWN, NULL); - sleep(3); + /* Request write-only mode in osmo_select_main_ctx() */ + osmo_select_shutdown_request(); + /* continue the main select loop until all write queues are serviced. */ + } + } while (!osmo_select_shutdown_done()); +error: + db_fini(); log_fini(); /** @@ -745,5 +880,5 @@ TODO: we probably want some of the _net_ ctrl commands from bsc_base_ctrl_cmds_i */ talloc_report_full(NULL, stderr); talloc_disable_null_tracking(); - return 0; + return ret; } diff --git a/src/utils/Makefile.am b/src/utils/Makefile.am index cb0faf69f..606967245 100644 --- a/src/utils/Makefile.am +++ b/src/utils/Makefile.am @@ -34,12 +34,26 @@ smpp_mirror_SOURCES = \ smpp_mirror_CFLAGS = \ $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOSCCP_CFLAGS) \ + $(LIBOSMOMGCPCLIENT_CFLAGS) \ $(LIBSMPP34_CFLAGS) \ $(NULL) smpp_mirror_LDADD = \ + $(top_builddir)/src/libsmpputil/libsmpputil.a \ + $(top_builddir)/src/libmsc/libmsc.a \ + $(top_builddir)/src/libvlr/libvlr.a \ $(LIBOSMOCORE_LIBS) \ $(LIBOSMOGSM_LIBS) \ + $(LIBOSMOVTY_LIBS) \ + $(LIBOSMONETIF_LIBS) \ $(LIBSMPP34_LIBS) \ + $(LIBOSMORANAP_LIBS) \ + $(LIBASN1C_LIBS) \ + $(LIBOSMOSIGTRAN_LIBS) \ + $(LIBOSMOMGCPCLIENT_LIBS) \ + $(LIBOSMOGSUPCLIENT_LIBS) \ + $(LIBSQLITE3_LIBS) \ + -lsctp \ $(NULL) endif diff --git a/src/utils/smpp_mirror.c b/src/utils/smpp_mirror.c index 30535535b..3356468ae 100644 --- a/src/utils/smpp_mirror.c +++ b/src/utils/smpp_mirror.c @@ -19,80 +19,9 @@ #include <osmocom/core/write_queue.h> #include <osmocom/msc/debug.h> +#include <osmocom/smpp/smpp.h> -/* FIXME: merge with smpp_smsc.c */ -#define SMPP_SYS_ID_LEN 16 -enum esme_read_state { - READ_ST_IN_LEN = 0, - READ_ST_IN_MSG = 1, -}; -/* FIXME: merge with smpp_smsc.c */ - -struct esme { - struct osmo_fd ofd; - - uint32_t own_seq_nr; - - struct osmo_wqueue wqueue; - enum esme_read_state read_state; - uint32_t read_len; - uint32_t read_idx; - struct msgb *read_msg; - - uint8_t smpp_version; - char system_id[SMPP_SYS_ID_LEN+1]; - char password[SMPP_SYS_ID_LEN+1]; -}; - -/* FIXME: merge with smpp_smsc.c */ -#define SMPP34_UNPACK(rc, type, str, data, len) \ - memset(str, 0, sizeof(*str)); \ - rc = smpp34_unpack(type, str, data, len) -#define INIT_RESP(type, resp, req) { \ - memset((resp), 0, sizeof(*(resp))); \ - (resp)->command_length = 0; \ - (resp)->command_id = type; \ - (resp)->command_status = ESME_ROK; \ - (resp)->sequence_number = (req)->sequence_number; \ -} -#define PACK_AND_SEND(esme, ptr) pack_and_send(esme, (ptr)->command_id, ptr) -static inline uint32_t smpp_msgb_cmdid(struct msgb *msg) -{ - uint8_t *tmp = msgb_data(msg) + 4; - return ntohl(*(uint32_t *)tmp); -} -static uint32_t esme_inc_seq_nr(struct esme *esme) -{ - esme->own_seq_nr++; - if (esme->own_seq_nr > 0x7fffffff) - esme->own_seq_nr = 1; - return esme->own_seq_nr; -} -static int pack_and_send(struct esme *esme, uint32_t type, void *ptr) -{ - struct msgb *msg = msgb_alloc(4096, "SMPP_Tx"); - int rc, rlen; - if (!msg) - return -ENOMEM; - - rc = smpp34_pack(type, msg->tail, msgb_tailroom(msg), &rlen, ptr); - if (rc != 0) { - LOGP(DSMPP, LOGL_ERROR, "[%s] Error during smpp34_pack(): %s\n", - esme->system_id, smpp34_strerror); - msgb_free(msg); - return -EINVAL; - } - msgb_put(msg, rlen); - - if (osmo_wqueue_enqueue(&esme->wqueue, msg) != 0) { - LOGP(DSMPP, LOGL_ERROR, "[%s] Write queue full. Dropping message\n", - esme->system_id); - msgb_free(msg); - return -EAGAIN; - } - return 0; -} /* FIXME: merge with smpp_smsc.c */ static struct tlv_t *find_tlv(struct tlv_t *head, uint16_t tag) @@ -188,8 +117,8 @@ static int bind_transceiver(struct esme *esme) memset(&bind, 0, sizeof(bind)); bind.command_id = BIND_TRANSCEIVER; bind.sequence_number = esme_inc_seq_nr(esme); - snprintf((char *)bind.system_id, sizeof(bind.system_id), "%s", esme->system_id); - snprintf((char *)bind.password, sizeof(bind.password), "%s", esme->password); + snprintf((char *)bind.system_id, SMPP_SYS_ID_LEN + 1, "%s", esme->system_id); + snprintf((char *)bind.password, SMPP_SYS_ID_LEN + 1, "%s", esme->password); snprintf((char *)bind.system_type, sizeof(bind.system_type), "mirror"); bind.interface_version = esme->smpp_version; @@ -214,6 +143,14 @@ static int smpp_pdu_rx(struct esme *esme, struct msgb *msg) return rc; } +static void esme_read_state_reset(struct esme *esme) +{ + esme->read_msg = NULL; + esme->read_idx = 0; + esme->read_len = 0; + esme->read_state = READ_ST_IN_LEN; +} + /* FIXME: merge with smpp_smsc.c */ static int esme_read_cb(struct osmo_fd *ofd) { @@ -230,14 +167,17 @@ static int esme_read_cb(struct osmo_fd *ofd) rdlen = sizeof(uint32_t) - esme->read_idx; rc = read(ofd->fd, lenptr + esme->read_idx, rdlen); if (rc < 0) { - LOGP(DSMPP, LOGL_ERROR, "[%s] read returned %d\n", - esme->system_id, rc); + LOGPESME(esme, LOGL_ERROR, "read returned %d\n", rc); } else if (rc == 0) { goto dead_socket; } else esme->read_idx += rc; if (esme->read_idx >= sizeof(uint32_t)) { esme->read_len = ntohl(len); + if (esme->read_len > 65535) { + /* unrealistic */ + goto dead_socket; + } msg = msgb_alloc(esme->read_len, "SMPP Rx"); if (!msg) return -ENOMEM; @@ -253,8 +193,7 @@ static int esme_read_cb(struct osmo_fd *ofd) rdlen = esme->read_len - esme->read_idx; rc = read(ofd->fd, msg->tail, OSMO_MIN(rdlen, msgb_tailroom(msg))); if (rc < 0) { - LOGP(DSMPP, LOGL_ERROR, "[%s] read returned %d\n", - esme->system_id, rc); + LOGPESME(esme, LOGL_ERROR, "read returned %d\n", rc); } else if (rc == 0) { goto dead_socket; } else { @@ -264,10 +203,7 @@ static int esme_read_cb(struct osmo_fd *ofd) if (esme->read_idx >= esme->read_len) { rc = smpp_pdu_rx(esme, esme->read_msg); - esme->read_msg = NULL; - esme->read_idx = 0; - esme->read_len = 0; - esme->read_state = READ_ST_IN_LEN; + esme_read_state_reset(esme); } break; } @@ -278,6 +214,7 @@ dead_socket: osmo_fd_unregister(&esme->wqueue.bfd); close(esme->wqueue.bfd.fd); esme->wqueue.bfd.fd = -1; + esme_read_state_reset(esme); exit(2342); return 0; @@ -295,7 +232,7 @@ static int esme_write_cb(struct osmo_fd *ofd, struct msgb *msg) esme->wqueue.bfd.fd = -1; exit(99); } else if (rc < msgb_length(msg)) { - LOGP(DSMPP, LOGL_ERROR, "[%s] Short write\n", esme->system_id); + LOGPESME(esme, LOGL_ERROR, "Short write\n"); return 0; } @@ -307,11 +244,8 @@ static int smpp_esme_init(struct esme *esme, const char *host, uint16_t port) int rc; if (port == 0) - port = 2775; + port = SMPP_PORT; - esme->own_seq_nr = rand(); - esme_inc_seq_nr(esme); - osmo_wqueue_init(&esme->wqueue, 10); esme->wqueue.bfd.data = esme; esme->wqueue.read_cb = esme_read_cb; esme->wqueue.write_cb = esme_write_cb; @@ -339,7 +273,7 @@ const struct log_info log_info = { int main(int argc, char **argv) { - struct esme esme; + struct esme *esme; char *host = "localhost"; int port = 0; int rc; @@ -347,20 +281,22 @@ int main(int argc, char **argv) msgb_talloc_ctx_init(ctx, 0); - memset(&esme, 0, sizeof(esme)); - osmo_init_logging2(ctx, &log_info); - snprintf((char *) esme.system_id, sizeof(esme.system_id), "mirror"); - snprintf((char *) esme.password, sizeof(esme.password), "mirror"); - esme.smpp_version = 0x34; + esme = esme_alloc(ctx); + if (!esme) + exit(2); + + snprintf((char *) esme->system_id, sizeof(esme->system_id), "mirror"); + snprintf((char *) esme->password, sizeof(esme->password), "mirror"); + esme->smpp_version = 0x34; if (argc >= 2) host = argv[1]; if (argc >= 3) port = atoi(argv[2]); - rc = smpp_esme_init(&esme, host, port); + rc = smpp_esme_init(esme, host, port); if (rc < 0) exit(1); diff --git a/tests/Makefile.am b/tests/Makefile.am index ee4f47a0c..7ab3c377f 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -1,6 +1,10 @@ SUBDIRS = \ sms_queue \ msc_vlr \ + db_sms \ + sdp_msg \ + mncc \ + csd \ $(NULL) if BUILD_SMPP @@ -34,7 +38,7 @@ EXTRA_DIST = \ vty_test_runner.py \ ctrl_test_runner.py \ smpp_test_runner.py \ - test_nodes.vty \ + $(srcdir)/*.vty \ $(NULL) TESTSUITE = $(srcdir)/testsuite @@ -45,7 +49,7 @@ DISTCLEANFILES = \ if ENABLE_EXT_TESTS # don't run multiple tests concurrently so that the ports don't conflict -python-tests: $(BUILT_SOURCES) +python-tests: $(MAKE) vty-test $(MAKE) ctrl-test if BUILD_SMPP @@ -53,34 +57,42 @@ if BUILD_SMPP endif else -python-tests: $(BUILT_SOURCES) +python-tests: 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 +vty-python-test: $(top_builddir)/src/osmo-msc/osmo-msc +if BUILD_IU + IU=1 osmotestvty.py -p $(abs_top_srcdir) -w $(abs_top_builddir) -v + IU=1 osmotestconfig.py -p $(abs_top_srcdir) -w $(abs_top_builddir) -v +else + IU=0 osmotestvty.py -p $(abs_top_srcdir) -w $(abs_top_builddir) -v + IU=0 osmotestconfig.py -p $(abs_top_srcdir) -w $(abs_top_builddir) -v +endif $(srcdir)/vty_test_runner.py -w $(abs_top_builddir) -v - rm -f $(top_builddir)/sms.db + rm -f $(top_builddir)/sms.db* + +# Run a specific transcript test with: 'make vty-transcript-test VTY_TEST=osmo-msc.vty' +VTY_TEST ?= *.vty # 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: +vty-transcript-test: $(top_builddir)/src/osmo-msc/osmo-msc osmo_verify_transcript_vty.py -v \ -n OsmoMSC -p 4254 \ -r "$(top_builddir)/src/osmo-msc/osmo-msc -c $(top_srcdir)/doc/examples/osmo-msc/osmo-msc.cfg" \ - $(U) $${T:-$(srcdir)/*.vty} - rm -f $(builddir)/sms.db + $(U) $(srcdir)/$(VTY_TEST) + rm -f $(builddir)/sms.db* # 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) +ctrl-python-test: $(top_builddir)/src/osmo-msc/osmo-msc $(srcdir)/ctrl_test_runner.py -w $(abs_top_builddir) -v - rm -f $(top_builddir)/sms.db + rm -f $(top_builddir)/sms.db* # To update the CTRL script from current application behavior, # pass -u to ctrl_script_runner.py by doing: @@ -93,9 +105,9 @@ ctrl-test: $(MAKE) ctrl-python-test $(MAKE) ctrl-transcript-test -smpp-test: +smpp-test:$(top_builddir)/src/osmo-msc/osmo-msc $(srcdir)/smpp_test_runner.py -w $(abs_top_builddir) -v - rm -f $(top_builddir)/sms.db + rm -f $(top_builddir)/sms.db* check-local: atconfig $(TESTSUITE) $(SHELL) '$(TESTSUITE)' $(TESTSUITEFLAGS) diff --git a/tests/csd/Makefile.am b/tests/csd/Makefile.am new file mode 100644 index 000000000..581f7d402 --- /dev/null +++ b/tests/csd/Makefile.am @@ -0,0 +1,37 @@ +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + $(NULL) + +AM_CFLAGS = \ + -Wall \ + -ggdb3 \ + $(LIBOSMOCORE_CFLAGS) \ + $(NULL) + +AM_LDFLAGS = \ + $(COVERAGE_LDFLAGS) \ + -no-install \ + $(NULL) + +LDADD = \ + $(top_builddir)/src/libmsc/libmsc.a \ + $(LIBOSMOCORE_LIBS) \ + $(NULL) + +EXTRA_DIST = \ + csd_test.ok \ + csd_test.err \ + $(NULL) + +check_PROGRAMS = \ + csd_test \ + $(NULL) + +csd_test_SOURCES = \ + csd_test.c \ + $(NULL) + +.PHONY: update_exp +update_exp: + $(builddir)/csd_test >$(srcdir)/csd_test.ok 2>$(srcdir)/csd_test.err diff --git a/tests/csd/csd_test.c b/tests/csd/csd_test.c new file mode 100644 index 000000000..ad3b0daf4 --- /dev/null +++ b/tests/csd/csd_test.c @@ -0,0 +1,44 @@ +#include <stdio.h> +#include <string.h> +#include <errno.h> +#include <osmocom/core/application.h> +#include <osmocom/msc/csd_bs.h> +#include <osmocom/msc/debug.h> + +void test_csd_bs_list_remove(void) +{ + struct csd_bs_list list = { + .count = 3, + .bs = { + CSD_BS_21_T_V110_0k3, + CSD_BS_22_T_V110_1k2, + CSD_BS_24_T_V110_2k4, + }, + }; + + printf("=== %s ===\n", __func__); + printf("initial:\n"); + printf(" %s\n", csd_bs_list_to_str(&list)); + + printf("removing BS25T (not in the list):\n"); + csd_bs_list_remove(&list, CSD_BS_25_T_V110_4k8); + printf(" %s\n", csd_bs_list_to_str(&list)); + + printf("removing BS22T:\n"); + csd_bs_list_remove(&list, CSD_BS_22_T_V110_1k2); + printf(" %s\n", csd_bs_list_to_str(&list)); + + printf("removing BS24T:\n"); + csd_bs_list_remove(&list, CSD_BS_24_T_V110_2k4); + printf(" %s\n", csd_bs_list_to_str(&list)); + + printf("removing BS21T:\n"); + csd_bs_list_remove(&list, CSD_BS_21_T_V110_0k3); + printf(" %s\n", csd_bs_list_to_str(&list)); +} + +int main(void) +{ + test_csd_bs_list_remove(); + return 0; +} diff --git a/src/libmsc/ran_up_l2.c b/tests/csd/csd_test.err index e69de29bb..e69de29bb 100644 --- a/src/libmsc/ran_up_l2.c +++ b/tests/csd/csd_test.err diff --git a/tests/csd/csd_test.ok b/tests/csd/csd_test.ok new file mode 100644 index 000000000..0beac462a --- /dev/null +++ b/tests/csd/csd_test.ok @@ -0,0 +1,11 @@ +=== test_csd_bs_list_remove === +initial: + BS21T,BS22T,BS24T +removing BS25T (not in the list): + BS21T,BS22T,BS24T +removing BS22T: + BS21T,BS24T +removing BS24T: + BS21T +removing BS21T: + (no-bearer-services) diff --git a/tests/ctrl_test_runner.py b/tests/ctrl_test_runner.py index f652a6729..16d1e7cca 100755 --- a/tests/ctrl_test_runner.py +++ b/tests/ctrl_test_runner.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python3 # (C) 2013 by Jacob Erlbeck <jerlbeck@sysmocom.de> # (C) 2014 by Holger Hans Peter Freyther @@ -53,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] @@ -64,7 +64,9 @@ class TestCtrlBase(unittest.TestCase): def tearDown(self): self.disconnect() - osmoutil.end_proc(self.proc) + rc = osmoutil.end_proc(self.proc) + if rc is not None and rc != 0: + raise Exception("Process returned %d" % rc) def disconnect(self): if not (self.sock is None): @@ -72,7 +74,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: @@ -92,7 +94,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) @@ -123,7 +125,7 @@ class TestCtrlBase(unittest.TestCase): (head, data) = IPA().split_combined(data) answer = Ctrl().rem_header(head) 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} @@ -139,7 +141,7 @@ class TestCtrlBase(unittest.TestCase): responses[id] = rsp if verbose: - print "Decoded replies: ", responses + print("Decoded replies: ", responses) return responses @@ -183,9 +185,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 control commands" + print("Running tests for specific control commands") suite = unittest.TestSuite() suite.addTest(unittest.TestLoader().loadTestsFromTestCase(TestCtrlMSC)) res = unittest.TextTestRunner(verbosity=verbose_level).run(suite) diff --git a/tests/db_sms/Makefile.am b/tests/db_sms/Makefile.am new file mode 100644 index 000000000..9dabfe719 --- /dev/null +++ b/tests/db_sms/Makefile.am @@ -0,0 +1,55 @@ +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + $(NULL) + +AM_CFLAGS = \ + -Wall \ + -ggdb3 \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBASN1C_CFLAGS) \ + $(LIBOSMOVTY_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(LIBOSMOSIGTRAN_CFLAGS) \ + $(LIBOSMORANAP_CFLAGS) \ + $(LIBOSMONETIF_CFLAGS) \ + $(LIBOSMOMGCPCLIENT_CFLAGS) \ + $(LIBOSMOGSUPCLIENT_CFLAGS) \ + $(LIBSQLITE3_CFLAGS) \ + $(NULL) + +AM_LDFLAGS = \ + $(COVERAGE_LDFLAGS) \ + -no-install \ + $(NULL) + +EXTRA_DIST = \ + db_sms_test.ok \ + db_sms_test.err \ + $(NULL) + +check_PROGRAMS = \ + db_sms_test \ + $(NULL) + +db_sms_test_SOURCES = \ + db_sms_test.c \ + $(srcdir)/../stubs.c \ + $(NULL) + +db_sms_test_LDADD = \ + $(top_builddir)/src/libmsc/libmsc.a \ + $(top_builddir)/src/libvlr/libvlr.a \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBOSMOVTY_LIBS) \ + $(LIBOSMOABIS_LIBS) \ + $(LIBOSMOSIGTRAN_LIBS) \ + $(LIBOSMORANAP_LIBS) \ + $(LIBASN1C_LIBS) \ + $(LIBOSMOMGCPCLIENT_LIBS) \ + $(LIBOSMOGSUPCLIENT_LIBS) \ + $(LIBSQLITE3_LIBS) \ + $(LIBRARY_GSM) \ + $(NULL) diff --git a/tests/db_sms/db_sms_test.c b/tests/db_sms/db_sms_test.c new file mode 100644 index 000000000..7c015d318 --- /dev/null +++ b/tests/db_sms/db_sms_test.c @@ -0,0 +1,576 @@ +/* + * Test the storage API of the internal SMS Centre. + * + * (C) 2019 by Vadim Yanitskiy <axilirator@gmail.com> + * + * 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 <inttypes.h> +#include <stdbool.h> +#include <string.h> +#include <stdio.h> + +#include <osmocom/core/application.h> +#include <osmocom/core/utils.h> + +#include <osmocom/gsm/protocol/gsm_03_40.h> + +#include <osmocom/msc/gsm_data.h> +#include <osmocom/msc/debug.h> +#include <osmocom/msc/vlr.h> +#include <osmocom/msc/db.h> + +/* Talloc context of this unit test */ +static void *talloc_ctx = NULL; + +static const struct sms_tp_ud { + /* Data Coding Scheme */ + uint8_t dcs; + /* TP User-Data-Length (depends on DCS) */ + uint8_t length; + /* Static TP User-Data filler (0 means disabled) */ + uint8_t filler_byte; + /* TP User-Data */ + uint8_t data[GSM340_UDL_OCT_MAX]; + /* Decoded text (for 7-bit default alphabet only) */ + char dec_text[GSM340_UDL_SPT_MAX + 1]; +} sms_tp_ud_set[] = { + { + .dcs = 0x00, /* Default GSM 7-bit alphabet */ + .length = 9, /* in septets */ + .dec_text = "Mahlzeit!", + .data = { + 0xcd, 0x30, 0x9a, 0xad, 0x2f, 0xa7, 0xe9, 0x21, + }, + }, + { + .dcs = 0x08, /* UCS-2 (16-bit) / UTF-16 */ + .length = 120, /* in octets */ + .data = { + 0x04, 0x23, 0x04, 0x32, 0x04, 0x30, 0x04, 0x36, + 0x04, 0x30, 0x04, 0x35, 0x04, 0x3c, 0x04, 0x4b, + 0x04, 0x39, 0x00, 0x20, 0x04, 0x3a, 0x04, 0x3b, + 0x04, 0x38, 0x04, 0x35, 0x04, 0x3d, 0x04, 0x42, + 0x00, 0x21, 0x00, 0x20, 0x04, 0x1d, 0x04, 0x30, + 0x04, 0x41, 0x04, 0x42, 0x04, 0x40, 0x04, 0x3e, + 0x04, 0x39, 0x04, 0x3a, 0x04, 0x38, 0x00, 0x20, + 0x00, 0x49, 0x00, 0x6e, 0x00, 0x74, 0x00, 0x65, + 0x00, 0x72, 0x00, 0x6e, 0x00, 0x65, 0x00, 0x74, + 0x00, 0x20, 0x04, 0x38, 0x00, 0x20, 0x00, 0x4d, + 0x00, 0x4d, 0x00, 0x53, 0x00, 0x20, 0x04, 0x31, + 0x04, 0x43, 0x04, 0x34, 0x04, 0x43, 0x04, 0x42, + 0x00, 0x20, 0x04, 0x34, 0x04, 0x3e, 0x04, 0x41, + 0x04, 0x42, 0x04, 0x30, 0x04, 0x32, 0x04, 0x3b, + 0x04, 0x35, 0x04, 0x3d, 0x04, 0x4b, 0x00, 0x2e, + }, + }, + { + .dcs = 0x04, /* 8-bit data */ + .length = 12, /* in octets */ + .data = { + /* User-Data-Header */ + 0x1e, /* Buffer-overflow! (should be 0x05) */ + /* Concatenated SM, 8-bit reference number */ + 0x00, 0x03, 0x5a, 0x05, 0x01, + + /* Dummy payload... */ + 0x05, 0x04, 0x0b, 0x84, 0x0b, 0x84, + }, + }, + { + .dcs = 0x00, /* Default GSM 7-bit alphabet */ + .length = 160, /* maximum, in septets */ + .filler_byte = 0x41, + }, + { + .dcs = 0x04, /* 8-bit data */ + .length = 140, /* maximum, in octets */ + .filler_byte = 0x42, + }, + { + .dcs = 0x00, /* Default GSM 7-bit alphabet */ + .length = 200, /* invalid, buffer overflow */ + .filler_byte = 0x41, + }, + { + .dcs = 0x04, /* 8-bit data */ + .length = 0xff, /* invalid, buffer overflow */ + .filler_byte = 0x42, + }, +}; + +#define SMS_ADDR(addr) \ + { 0x00, 0x00, addr } + +static struct sms_test { + /* Human-readable name of particular test message */ + const char *name; + /* Whether we expect db_sms_store() to fail */ + bool exp_db_sms_store_fail; + /* Whether we expect db_sms_get() to fail */ + bool exp_db_sms_get_fail; + /* SM TP-User-Data from sms_tp_ud_set[] */ + const struct sms_tp_ud *ud; + /* The message itself */ + struct gsm_sms sms; +} sms_test_set[] = { + { + .name = "Regular MO SMS", + .sms = { + .msg_ref = 0xde, + .src = SMS_ADDR("123456"), + .dst = SMS_ADDR("654321"), + .validity_minutes = 10, + .protocol_id = 0x00, + /* SM TP-User-Data is taken from sms_tp_ud_set[] */ + }, + .ud = &sms_tp_ud_set[0], + }, + { + .name = "Regular MT SMS", + .sms = { + .msg_ref = 0xbe, + .src = SMS_ADDR("654321"), + .dst = SMS_ADDR("123456"), + .validity_minutes = 180, + .protocol_id = 0x00, + /* SM TP-User-Data is taken from sms_tp_ud_set[] */ + }, + .ud = &sms_tp_ud_set[1], + }, + { + .name = "Complete TP-UD (160 septets, 7-bit encoding)", + .sms = { + .msg_ref = 0xee, + .src = SMS_ADDR("266753837248772"), + .dst = SMS_ADDR("266753837248378"), + .validity_minutes = 360, + .protocol_id = 0x00, + /* SM TP-User-Data is taken from sms_tp_ud_set[] */ + }, + .ud = &sms_tp_ud_set[3], + }, + { + .name = "Complete TP-UD (140 octets, 8-bit encoding)", + .sms = { + .msg_ref = 0xee, + .src = SMS_ADDR("266753838248772"), + .dst = SMS_ADDR("266753838248378"), + .validity_minutes = 360, + .protocol_id = 0xaa, + /* SM TP-User-Data is taken from sms_tp_ud_set[] */ + }, + .ud = &sms_tp_ud_set[4], + }, + { + .name = "TP-UD buffer overflow (UDH-Length > UD-Length)", + .sms = { + .msg_ref = 0x88, + .src = SMS_ADDR("834568373569772"), + .dst = SMS_ADDR("834568373569378"), + .validity_minutes = 200, + .protocol_id = 0xbb, + .ud_hdr_ind = 0x01, + /* SM TP-User-Data is taken from sms_tp_ud_set[] */ + }, + .ud = &sms_tp_ud_set[2], + }, + { + .name = "Truncated TP-UD (200 septets, 7-bit encoding)", + .sms = { + .msg_ref = 0xee, + .src = { 0x01, 0x00, "8786228337248772" }, + .dst = { 0x00, 0x01, "8786228337248378" }, + .validity_minutes = 360, + .protocol_id = 0xcc, + /* SM TP-User-Data is taken from sms_tp_ud_set[] */ + }, + .ud = &sms_tp_ud_set[5], + }, + { + .name = "Truncated TP-UD (255 octets, 8-bit encoding)", + .sms = { + .msg_ref = 0xee, + .src = { 0x01, 0x01, "8786228338248772" }, + .dst = { 0xaa, 0xff, "8786228338248378" }, + .validity_minutes = 360, + .protocol_id = 0xbb, + /* SM TP-User-Data is taken from sms_tp_ud_set[] */ + }, + .ud = &sms_tp_ud_set[6], + }, + { + .name = "Same MSISDN #1", + .sms = { + .msg_ref = 0x11, + .src = SMS_ADDR("72631"), + .dst = SMS_ADDR("72632"), + .validity_minutes = 10, + /* SM TP-User-Data is taken from sms_tp_ud_set[] */ + }, + .ud = &sms_tp_ud_set[0], + }, + { + .name = "Same MSISDN #2", + .sms = { + .msg_ref = 0x12, + .src = SMS_ADDR("72632"), + .dst = SMS_ADDR("72631"), + .validity_minutes = 10, + /* SM TP-User-Data is taken from sms_tp_ud_set[] */ + }, + .ud = &sms_tp_ud_set[0], + }, + { + .name = "Expired SMS", + .sms = { + .msg_ref = 0xde, + .src = SMS_ADDR("3974733772"), + .dst = SMS_ADDR("3974733378"), + .validity_minutes = 0, + /* SM TP-User-Data is taken from sms_tp_ud_set[] */ + }, + .ud = &sms_tp_ud_set[0], + }, + { + .name = "Empty TP-UD", + .sms = { + .msg_ref = 0x38, + .src = SMS_ADDR("3678983772"), + .dst = SMS_ADDR("3678983378"), + .validity_minutes = 450, + .is_report = true, + .reply_path_req = 0x01, + .status_rep_req = 0x01, + .protocol_id = 0x55, + .data_coding_scheme = 0x08, + .ud_hdr_ind = 0x00, + .user_data_len = 0x00, + /* No TP-User-Data */ + }, + .ud = NULL, + }, +}; + +static void prepare_sms_test_set(void) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(sms_test_set); i++) { + struct sms_test *test = &sms_test_set[i]; + const struct sms_tp_ud *ud = test->ud; + + /* ID auto-increment */ + test->sms.id = i + 1; + + if (ud == NULL) + continue; + + test->sms.data_coding_scheme = ud->dcs; + test->sms.user_data_len = ud->length; + + if (ud->filler_byte) { + memset(test->sms.user_data, ud->filler_byte, + sizeof(test->sms.user_data)); + } else { + memcpy(test->sms.user_data, ud->data, sizeof(ud->data)); + if (ud->dec_text[0] != '\0') + strcpy(test->sms.text, ud->dec_text); + } + } +} + +static void test_db_sms_store(void) +{ + int rc, i; + + LOGP(DDB, LOGL_INFO, "Testing db_sms_store()...\n"); + + /* Store test SMS messages */ + for (i = 0; i < ARRAY_SIZE(sms_test_set); i++) { + struct sms_test *test = &sms_test_set[i]; + + LOGP(DDB, LOGL_NOTICE, "%s('%s'): ", __func__, test->name); + + rc = db_sms_store(&test->sms); + if (!test->exp_db_sms_store_fail && rc == 0) + LOGPC(DDB, LOGL_INFO, "success, as expected\n"); + else if (test->exp_db_sms_store_fail && rc != 0) + LOGPC(DDB, LOGL_INFO, "failure, as expected\n"); + else + LOGPC(DDB, LOGL_ERROR, "unexpected rc=%d\n", rc); + } +} + +static int verify_sms(const struct sms_test *test, const struct gsm_sms *sms) +{ + int rc; + + LOGP(DDB, LOGL_NOTICE, "%s('%s'): ", __func__, test->name); + +#define MATCH_SMS_ADDR(ADDR) \ + if (strcmp(sms->ADDR.addr, test->sms.ADDR.addr) \ + || sms->ADDR.npi != test->sms.ADDR.npi \ + || sms->ADDR.ton != test->sms.ADDR.ton) { \ + LOGPC(DDB, LOGL_ERROR, #ADDR " address mismatch\n"); \ + return -EINVAL; \ + } + + MATCH_SMS_ADDR(src); + MATCH_SMS_ADDR(dst); + +#define MATCH_SMS_PARAM(PARAM, FMT) \ + if (sms->PARAM != test->sms.PARAM) { \ + LOGPC(DDB, LOGL_ERROR, \ + #PARAM " mismatch: E%" FMT " vs A%" FMT "\n", \ + test->sms.PARAM, sms->PARAM); \ + return -EINVAL; \ + } + + MATCH_SMS_PARAM(id, "llu"); + MATCH_SMS_PARAM(validity_minutes, "lu"); + MATCH_SMS_PARAM(is_report, "i"); + MATCH_SMS_PARAM(reply_path_req, PRIu8); + MATCH_SMS_PARAM(status_rep_req, PRIu8); + MATCH_SMS_PARAM(ud_hdr_ind, PRIu8); + MATCH_SMS_PARAM(protocol_id, PRIu8); + MATCH_SMS_PARAM(data_coding_scheme, PRIu8); + MATCH_SMS_PARAM(msg_ref, PRIu8); + MATCH_SMS_PARAM(user_data_len, PRIu8); + + /* Compare TP-User-Data */ + rc = memcmp(sms->user_data, test->sms.user_data, + sizeof(sms->user_data)); + if (rc) { + LOGPC(DDB, LOGL_ERROR, "TP-User-Data mismatch\n"); + return -EINVAL; + } + + /* Compare decoded text */ + rc = strncmp(sms->text, test->sms.text, sizeof(sms->text)); + if (rc) { + LOGPC(DDB, LOGL_ERROR, "TP-User-Data (text) mismatch\n"); + return -EINVAL; + } + + LOGPC(DDB, LOGL_NOTICE, "match\n"); + return 0; +} + +static void test_db_sms_get(void) +{ + struct gsm_sms *sms; + int i; + + LOGP(DDB, LOGL_INFO, "Testing db_sms_get()...\n"); + + /* Retrieve stored SMS messages */ + for (i = 0; i < ARRAY_SIZE(sms_test_set); i++) { + const struct sms_test *test = &sms_test_set[i]; + + LOGP(DDB, LOGL_NOTICE, "%s('%s'): ", __func__, test->name); + + sms = db_sms_get(NULL, test->sms.id); + if (!test->exp_db_sms_get_fail && sms != NULL) + LOGPC(DDB, LOGL_INFO, "success, as expected\n"); + else if (test->exp_db_sms_get_fail && sms == NULL) + LOGPC(DDB, LOGL_INFO, "failure, as expected\n"); + else + LOGPC(DDB, LOGL_ERROR, "unexpected result\n"); + + if (sms) { + verify_sms(test, sms); + talloc_free(sms); + } + } +} + +static void test_db_sms_delivery(void) +{ + struct gsm_sms *sms1, *sms2; + struct gsm_sms *sms; + int rc; + + LOGP(DDB, LOGL_INFO, "Testing db_sms_get_next_unsent() " + "and db_sms_mark_delivered()...\n"); + + /* Retrieve both #1 and #2 */ + sms1 = db_sms_get_next_unsent(NULL, 1, 0); + LOGP(DDB, LOGL_NOTICE, "db_sms_get_next_unsent(#1): %s\n", + sms1 ? "found" : "not found"); + if (sms1 != NULL) + verify_sms(&sms_test_set[0], sms1); + + sms2 = db_sms_get_next_unsent(NULL, 2, 0); + LOGP(DDB, LOGL_NOTICE, "db_sms_get_next_unsent(#2): %s\n", + sms2 ? "found" : "not found"); + if (sms2 != NULL) + verify_sms(&sms_test_set[1], sms2); + + /* Mark both #1 and #2 and delivered, release memory */ + if (sms1) { + LOGP(DDB, LOGL_DEBUG, "Marking #%llu as delivered: ", sms1->id); + rc = db_sms_mark_delivered(sms1); + LOGPC(DDB, LOGL_DEBUG, "rc=%d\n", rc); + talloc_free(sms1); + } + + if (sms2) { + LOGP(DDB, LOGL_DEBUG, "Marking #%llu as delivered: ", sms2->id); + rc = db_sms_mark_delivered(sms2); + LOGPC(DDB, LOGL_DEBUG, "rc=%d\n", rc); + talloc_free(sms2); + } + + /* Expect #3 as the next undelivered */ + sms = db_sms_get_next_unsent(NULL, 1, 0); + LOGP(DDB, LOGL_NOTICE, "db_sms_get_next_unsent(starting from #1): %s\n", + sms ? "found" : "not found"); + if (sms) { + verify_sms(&sms_test_set[2], sms); + talloc_free(sms); + } +} + +static void test_db_sms_delete(void) +{ + int rc; + + LOGP(DDB, LOGL_INFO, "Testing db_sms_delete_sent_message_by_id()...\n"); + + /* Delete #1, which is marked as sent */ + LOGP(DDB, LOGL_NOTICE, "db_sms_delete_sent_message_by_id(#1, sent): "); + rc = db_sms_delete_sent_message_by_id(1); + LOGPC(DDB, LOGL_NOTICE, "rc=%d\n", rc); + /* Don't expect to retrieve this message anymore */ + sms_test_set[0].exp_db_sms_get_fail = true; + + /* Try to delete #3, which is not marked as sent */ + LOGP(DDB, LOGL_NOTICE, "db_sms_delete_sent_message_by_id(#3, not sent): "); + rc = db_sms_delete_sent_message_by_id(3); + LOGPC(DDB, LOGL_NOTICE, "rc=%d\n", rc); + /* Do expect to retrieve this message anyway */ + sms_test_set[2].exp_db_sms_get_fail = false; + + LOGP(DDB, LOGL_INFO, "Testing db_sms_delete_by_msisdn()...\n"); + + LOGP(DDB, LOGL_NOTICE, "db_sms_delete_by_msisdn('72631'): "); + rc = db_sms_delete_by_msisdn("72631"); + LOGPC(DDB, LOGL_NOTICE, "rc=%d\n", rc); + + /* Don't expect both #8 and #9 anymore */ + sms_test_set[7].exp_db_sms_get_fail = true; + sms_test_set[8].exp_db_sms_get_fail = true; + + LOGP(DDB, LOGL_INFO, "Testing db_sms_delete_oldest_expired_message()...\n"); + + LOGP(DDB, LOGL_NOTICE, "db_sms_delete_oldest_expired_message()\n"); + db_sms_delete_oldest_expired_message(); + + /* Don't expect #10 anymore */ + sms_test_set[9].exp_db_sms_get_fail = true; + + /* We need to make sure that we removed exactly what we expected to remove */ + LOGP(DDB, LOGL_INFO, "Expectations updated, retrieving all messages again\n"); + test_db_sms_get(); +} + +static struct log_info_cat db_sms_test_categories[] = { + [DDB] = { + .name = "DDB", + .description = "Database Layer", + .enabled = 1, .loglevel = LOGL_DEBUG, + }, +}; + +static struct log_info info = { + .cat = db_sms_test_categories, + .num_cat = ARRAY_SIZE(db_sms_test_categories), +}; + +int main(int argc, char **argv) +{ + void *logging_ctx; + int rc; + + /* Track the use of talloc NULL memory contexts */ + talloc_enable_null_tracking(); + + talloc_ctx = talloc_named_const(NULL, 0, "db_sms_test"); + logging_ctx = talloc_named_const(talloc_ctx, 0, "logging"); + osmo_init_logging2(logging_ctx, &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_filename2(osmo_stderr_target, LOG_FILENAME_NONE); + log_set_print_category_hex(osmo_stderr_target, 0); + log_set_print_category(osmo_stderr_target, 1); + log_set_print_level(osmo_stderr_target, 1); + +#if 0 + /* Having the database stored in a regular file may be useful + * for debugging, but this comes at the price of performance. */ + FILE *dbf = fopen("db_sms_test.db", "wb"); + OSMO_ASSERT(dbf != NULL); + fclose(dbf); +#endif + + /* Init a volatile database in RAM */ + LOGP(DDB, LOGL_DEBUG, "Init a new database\n"); + + /* HACK: db_init() prints libdbi version using LOGL_NOTICE, so + * the test output is not deterministic. Let's suppress this + * message by increasing the log level to LOGL_ERROR. */ + log_parse_category_mask(osmo_stderr_target, "DDB,7"); + rc = db_init(talloc_ctx, ":memory:", true); + OSMO_ASSERT(rc == 0); + + /* HACK: relax log level back to LOGL_DEBUG (see note above) */ + log_parse_category_mask(osmo_stderr_target, "DDB,1"); + + /* Prepare some tables */ + rc = db_prepare(); + OSMO_ASSERT(rc == 0); + LOGP(DDB, LOGL_DEBUG, "Init complete\n"); + + /* Prepare the test set */ + prepare_sms_test_set(); + + test_db_sms_store(); + test_db_sms_get(); + + test_db_sms_delivery(); + test_db_sms_delete(); + + /* Close the database */ + db_fini(); + + /* Deinit logging */ + log_fini(); + + /* Check for memory leaks */ + rc = talloc_total_blocks(talloc_ctx); + OSMO_ASSERT(rc == 2); /* db_sms_test + logging */ + talloc_free(talloc_ctx); + + talloc_report_full(NULL, stderr); + talloc_disable_null_tracking(); + + return 0; +} diff --git a/tests/db_sms/db_sms_test.err b/tests/db_sms/db_sms_test.err new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/tests/db_sms/db_sms_test.err diff --git a/tests/db_sms/db_sms_test.ok b/tests/db_sms/db_sms_test.ok new file mode 100644 index 000000000..486dcc356 --- /dev/null +++ b/tests/db_sms/db_sms_test.ok @@ -0,0 +1,74 @@ +DDB DEBUG Init a new database +DDB DEBUG Init complete +DDB INFO Testing db_sms_store()... +DDB NOTICE test_db_sms_store('Regular MO SMS'): success, as expected +DDB NOTICE test_db_sms_store('Regular MT SMS'): success, as expected +DDB NOTICE test_db_sms_store('Complete TP-UD (160 septets, 7-bit encoding)'): success, as expected +DDB NOTICE test_db_sms_store('Complete TP-UD (140 octets, 8-bit encoding)'): success, as expected +DDB NOTICE test_db_sms_store('TP-UD buffer overflow (UDH-Length > UD-Length)'): success, as expected +DDB NOTICE test_db_sms_store('Truncated TP-UD (200 septets, 7-bit encoding)'): success, as expected +DDB NOTICE test_db_sms_store('Truncated TP-UD (255 octets, 8-bit encoding)'): success, as expected +DDB NOTICE test_db_sms_store('Same MSISDN #1'): success, as expected +DDB NOTICE test_db_sms_store('Same MSISDN #2'): success, as expected +DDB NOTICE test_db_sms_store('Expired SMS'): success, as expected +DDB NOTICE test_db_sms_store('Empty TP-UD'): success, as expected +DDB INFO Testing db_sms_get()... +DDB NOTICE test_db_sms_get('Regular MO SMS'): success, as expected +DDB NOTICE verify_sms('Regular MO SMS'): match +DDB NOTICE test_db_sms_get('Regular MT SMS'): success, as expected +DDB NOTICE verify_sms('Regular MT SMS'): match +DDB NOTICE test_db_sms_get('Complete TP-UD (160 septets, 7-bit encoding)'): success, as expected +DDB NOTICE verify_sms('Complete TP-UD (160 septets, 7-bit encoding)'): TP-User-Data mismatch +DDB NOTICE test_db_sms_get('Complete TP-UD (140 octets, 8-bit encoding)'): success, as expected +DDB NOTICE verify_sms('Complete TP-UD (140 octets, 8-bit encoding)'): TP-User-Data mismatch +DDB NOTICE test_db_sms_get('TP-UD buffer overflow (UDH-Length > UD-Length)'): success, as expected +DDB NOTICE verify_sms('TP-UD buffer overflow (UDH-Length > UD-Length)'): match +DDB NOTICE test_db_sms_get('Truncated TP-UD (200 septets, 7-bit encoding)'): success, as expected +DDB NOTICE verify_sms('Truncated TP-UD (200 septets, 7-bit encoding)'): TP-User-Data mismatch +DDB NOTICE test_db_sms_get('Truncated TP-UD (255 octets, 8-bit encoding)'): success, as expected +DDB NOTICE verify_sms('Truncated TP-UD (255 octets, 8-bit encoding)'): TP-User-Data mismatch +DDB NOTICE test_db_sms_get('Same MSISDN #1'): success, as expected +DDB NOTICE verify_sms('Same MSISDN #1'): match +DDB NOTICE test_db_sms_get('Same MSISDN #2'): success, as expected +DDB NOTICE verify_sms('Same MSISDN #2'): match +DDB NOTICE test_db_sms_get('Expired SMS'): success, as expected +DDB NOTICE verify_sms('Expired SMS'): match +DDB NOTICE test_db_sms_get('Empty TP-UD'): success, as expected +DDB NOTICE verify_sms('Empty TP-UD'): match +DDB INFO Testing db_sms_get_next_unsent() and db_sms_mark_delivered()... +DDB NOTICE db_sms_get_next_unsent(#1): found +DDB NOTICE verify_sms('Regular MO SMS'): match +DDB NOTICE db_sms_get_next_unsent(#2): found +DDB NOTICE verify_sms('Regular MT SMS'): match +DDB DEBUG Marking #1 as delivered: rc=0 +DDB DEBUG Marking #2 as delivered: rc=0 +DDB NOTICE db_sms_get_next_unsent(starting from #1): found +DDB NOTICE verify_sms('Complete TP-UD (160 septets, 7-bit encoding)'): TP-User-Data mismatch +DDB INFO Testing db_sms_delete_sent_message_by_id()... +DDB NOTICE db_sms_delete_sent_message_by_id(#1, sent): rc=0 +DDB NOTICE db_sms_delete_sent_message_by_id(#3, not sent): rc=0 +DDB INFO Testing db_sms_delete_by_msisdn()... +DDB NOTICE db_sms_delete_by_msisdn('72631'): rc=0 +DDB INFO Testing db_sms_delete_oldest_expired_message()... +DDB NOTICE db_sms_delete_oldest_expired_message() +DDB INFO Expectations updated, retrieving all messages again +DDB INFO Testing db_sms_get()... +DDB NOTICE test_db_sms_get('Regular MO SMS'): failure, as expected +DDB NOTICE test_db_sms_get('Regular MT SMS'): success, as expected +DDB NOTICE verify_sms('Regular MT SMS'): match +DDB NOTICE test_db_sms_get('Complete TP-UD (160 septets, 7-bit encoding)'): success, as expected +DDB NOTICE verify_sms('Complete TP-UD (160 septets, 7-bit encoding)'): TP-User-Data mismatch +DDB NOTICE test_db_sms_get('Complete TP-UD (140 octets, 8-bit encoding)'): success, as expected +DDB NOTICE verify_sms('Complete TP-UD (140 octets, 8-bit encoding)'): TP-User-Data mismatch +DDB NOTICE test_db_sms_get('TP-UD buffer overflow (UDH-Length > UD-Length)'): success, as expected +DDB NOTICE verify_sms('TP-UD buffer overflow (UDH-Length > UD-Length)'): match +DDB NOTICE test_db_sms_get('Truncated TP-UD (200 septets, 7-bit encoding)'): success, as expected +DDB NOTICE verify_sms('Truncated TP-UD (200 septets, 7-bit encoding)'): TP-User-Data mismatch +DDB NOTICE test_db_sms_get('Truncated TP-UD (255 octets, 8-bit encoding)'): success, as expected +DDB NOTICE verify_sms('Truncated TP-UD (255 octets, 8-bit encoding)'): TP-User-Data mismatch +DDB NOTICE test_db_sms_get('Same MSISDN #1'): failure, as expected +DDB NOTICE test_db_sms_get('Same MSISDN #2'): failure, as expected +DDB NOTICE test_db_sms_get('Expired SMS'): failure, as expected +DDB NOTICE test_db_sms_get('Empty TP-UD'): success, as expected +DDB NOTICE verify_sms('Empty TP-UD'): match +full talloc report on 'null_context' (total 0 bytes in 1 blocks) diff --git a/tests/mncc/Makefile.am b/tests/mncc/Makefile.am new file mode 100644 index 000000000..a4c296008 --- /dev/null +++ b/tests/mncc/Makefile.am @@ -0,0 +1,37 @@ +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + $(NULL) + +AM_CFLAGS = \ + -Wall \ + -ggdb3 \ + $(LIBOSMOCORE_CFLAGS) \ + $(NULL) + +AM_LDFLAGS = \ + $(COVERAGE_LDFLAGS) \ + -no-install \ + $(NULL) + +LDADD = \ + $(top_builddir)/src/libmsc/libmsc.a \ + $(LIBOSMOCORE_LIBS) \ + $(NULL) + +EXTRA_DIST = \ + mncc_test.ok \ + mncc_test.err \ + $(NULL) + +check_PROGRAMS = \ + mncc_test \ + $(NULL) + +mncc_test_SOURCES = \ + mncc_test.c \ + $(NULL) + +.PHONY: update_exp +update_exp: + $(builddir)/mncc_test >$(srcdir)/mncc_test.ok 2>$(srcdir)/mncc_test.err diff --git a/tests/mncc/mncc_test.c b/tests/mncc/mncc_test.c new file mode 100644 index 000000000..9532846f4 --- /dev/null +++ b/tests/mncc/mncc_test.c @@ -0,0 +1,79 @@ +#include <stdio.h> +#include <string.h> +#include <errno.h> +#include <osmocom/core/application.h> +#include <osmocom/core/logging.h> +#include <osmocom/msc/debug.h> +#include <osmocom/msc/mncc.h> + +#define _test_sdp_termination(LABEL, MNCC, MNCC_MSG_LEN, RC) do { \ + int sdp_len = ((int)(MNCC_MSG_LEN)) - ((MNCC)->sdp - (char*)MNCC); \ + size_t sdp_strlen = strnlen(MNCC->sdp, sizeof(MNCC->sdp)); \ + int rc = mncc_check_sdp_termination("<" LABEL ">", (struct gsm_mncc*)MNCC, MNCC_MSG_LEN, MNCC->sdp); \ + printf("%s: len=%d sdplen=%d sdp=%s rc=%d\n", \ + LABEL, (int)(MNCC_MSG_LEN), sdp_len, \ + sdp_len > 0? osmo_quote_str((MNCC)->sdp, OSMO_MIN(sdp_len, sdp_strlen+1)) : "-", rc); \ + if (RC != rc) \ + printf("ERROR!\n"); \ + } while (0) + +#define test_sdp_termination_cases(MNCC) \ + _test_sdp_termination("empty SDP", MNCC, sizeof(*MNCC), 0); \ + _test_sdp_termination("empty SDP, shortest possible", MNCC, MNCC->sdp - ((char*)MNCC) + 1, 0); \ + _test_sdp_termination("empty SDP, zero len", MNCC, MNCC->sdp - ((char*)MNCC), -EINVAL); \ + OSMO_STRLCPY_ARRAY(MNCC->sdp, "Privacy is a desirable marketing option"); \ + _test_sdp_termination("terminated SDP str", MNCC, sizeof(*MNCC), 0); \ + _test_sdp_termination("terminated SDP str, shortest possible", MNCC, \ + MNCC->sdp - ((char*)MNCC) + strlen(MNCC->sdp) + 1, 0); \ + _test_sdp_termination("terminated SDP str, but len excludes nul", MNCC, \ + MNCC->sdp - ((char*)MNCC) + strlen(MNCC->sdp), -EINVAL); \ + _test_sdp_termination("terminated SDP str, but len too short", MNCC, \ + MNCC->sdp - ((char*)MNCC) + 23, -EINVAL); \ + _test_sdp_termination("len way too short", MNCC, 10, -EINVAL); \ + _test_sdp_termination("len zero", MNCC, 0, -EINVAL); + + +void test_sdp_termination(void) +{ + struct gsm_mncc _mncc = {}; + struct gsm_mncc_rtp _mncc_rtp = {}; + + struct gsm_mncc *mncc = &_mncc; + struct gsm_mncc_rtp *mncc_rtp = &_mncc_rtp; + + printf("%s()\n", __func__); + printf("\nstruct gsm_mncc:\n"); + test_sdp_termination_cases(mncc); + + _mncc = (struct gsm_mncc){}; + _mncc_rtp = (struct gsm_mncc_rtp){}; + printf("\nstruct gsm_mncc_rtp:\n"); + test_sdp_termination_cases(mncc_rtp); +} + +static const struct log_info_cat default_categories[] = { + [DMNCC] = { + .name = "DMNCC", + .description = "MNCC API for Call Control application", + .color = "\033[1;39m", + .enabled = 1, .loglevel = LOGL_NOTICE, + }, +}; + +const struct log_info log_info = { + .cat = default_categories, + .num_cat = ARRAY_SIZE(default_categories), +}; + +int main(void) +{ + void *ctx = talloc_named_const(NULL, 0, "mncc_test"); + osmo_init_logging2(ctx, &log_info); + log_set_use_color(osmo_stderr_target, 0); + log_set_print_filename2(osmo_stderr_target, LOG_FILENAME_NONE); + log_set_print_category(osmo_stderr_target, 1); + log_set_print_category_hex(osmo_stderr_target, 0); + + test_sdp_termination(); + return 0; +} diff --git a/tests/mncc/mncc_test.err b/tests/mncc/mncc_test.err new file mode 100644 index 000000000..5ee7e2cc3 --- /dev/null +++ b/tests/mncc/mncc_test.err @@ -0,0 +1,10 @@ +DMNCC Short <empty SDP, zero len> +DMNCC Short <terminated SDP str, but len excludes nul> +DMNCC Short <terminated SDP str, but len too short> +DMNCC Short <len way too short> +DMNCC Short <len zero> +DMNCC Short <empty SDP, zero len> +DMNCC Short <terminated SDP str, but len excludes nul> +DMNCC Short <terminated SDP str, but len too short> +DMNCC Short <len way too short> +DMNCC Short <len zero> diff --git a/tests/mncc/mncc_test.ok b/tests/mncc/mncc_test.ok new file mode 100644 index 000000000..ca3ac6484 --- /dev/null +++ b/tests/mncc/mncc_test.ok @@ -0,0 +1,23 @@ +test_sdp_termination() + +struct gsm_mncc: +empty SDP: len=1896 sdplen=1046 sdp="\0" rc=0 +empty SDP, shortest possible: len=851 sdplen=1 sdp="\0" rc=0 +empty SDP, zero len: len=850 sdplen=0 sdp=- rc=-22 +terminated SDP str: len=1896 sdplen=1046 sdp="Privacy is a desirable marketing option\0" rc=0 +terminated SDP str, shortest possible: len=890 sdplen=40 sdp="Privacy is a desirable marketing option\0" rc=0 +terminated SDP str, but len excludes nul: len=889 sdplen=39 sdp="Privacy is a desirable marketing option" rc=-22 +terminated SDP str, but len too short: len=873 sdplen=23 sdp="Privacy is a desirable " rc=-22 +len way too short: len=10 sdplen=-840 sdp=- rc=-22 +len zero: len=0 sdplen=-850 sdp=- rc=-22 + +struct gsm_mncc_rtp: +empty SDP: len=1168 sdplen=1024 sdp="\0" rc=0 +empty SDP, shortest possible: len=145 sdplen=1 sdp="\0" rc=0 +empty SDP, zero len: len=144 sdplen=0 sdp=- rc=-22 +terminated SDP str: len=1168 sdplen=1024 sdp="Privacy is a desirable marketing option\0" rc=0 +terminated SDP str, shortest possible: len=184 sdplen=40 sdp="Privacy is a desirable marketing option\0" rc=0 +terminated SDP str, but len excludes nul: len=183 sdplen=39 sdp="Privacy is a desirable marketing option" rc=-22 +terminated SDP str, but len too short: len=167 sdplen=23 sdp="Privacy is a desirable " rc=-22 +len way too short: len=10 sdplen=-134 sdp=- rc=-22 +len zero: len=0 sdplen=-144 sdp=- rc=-22 diff --git a/tests/msc_vlr/Makefile.am b/tests/msc_vlr/Makefile.am index f9a922465..cbdd6a409 100644 --- a/tests/msc_vlr/Makefile.am +++ b/tests/msc_vlr/Makefile.am @@ -8,14 +8,15 @@ AM_CFLAGS = \ -ggdb3 \ $(LIBOSMOCORE_CFLAGS) \ $(LIBOSMOGSM_CFLAGS) \ - $(LIBSMPP34_CFLAGS) \ $(LIBOSMOVTY_CFLAGS) \ $(LIBOSMOABIS_CFLAGS) \ $(LIBOSMOSIGTRAN_CFLAGS) \ $(LIBOSMORANAP_CFLAGS) \ + $(LIBOSMONETIF_CFLAGS) \ $(LIBASN1C_CFLAGS) \ $(LIBOSMOMGCPCLIENT_CFLAGS) \ $(LIBOSMOGSUPCLIENT_CFLAGS) \ + $(LIBSQLITE3_CFLAGS) \ $(NULL) AM_LDFLAGS = \ @@ -25,12 +26,13 @@ AM_LDFLAGS = \ -Wl,--wrap=osmo_get_rand_id \ -Wl,--wrap=ran_peers_down_paging \ -Wl,--wrap=call_leg_ensure_ci \ + $(COVERAGE_LDFLAGS) \ + -no-install \ $(NULL) LDADD = \ $(top_builddir)/src/libmsc/libmsc.a \ $(top_builddir)/src/libvlr/libvlr.a \ - $(LIBSMPP34_LIBS) \ $(LIBOSMOCORE_LIBS) \ $(LIBOSMOGSM_LIBS) \ $(LIBOSMOVTY_LIBS) \ @@ -40,13 +42,12 @@ LDADD = \ $(LIBASN1C_LIBS) \ $(LIBOSMOMGCPCLIENT_LIBS) \ $(LIBOSMOGSUPCLIENT_LIBS) \ + $(LIBSQLITE3_LIBS) \ $(LIBRARY_GSM) \ - -ldbi \ $(NULL) noinst_HEADERS = \ msc_vlr_tests.h \ - stubs.h \ $(NULL) EXTRA_DIST = \ @@ -76,7 +77,7 @@ EXTRA_DIST = \ msc_vlr_test_ss.err \ $(NULL) -noinst_PROGRAMS = \ +check_PROGRAMS = \ msc_vlr_test_no_authen \ msc_vlr_test_gsm_authen \ msc_vlr_test_gsm_ciph \ @@ -94,61 +95,73 @@ noinst_PROGRAMS = \ msc_vlr_test_no_authen_SOURCES = \ msc_vlr_test_no_authen.c \ msc_vlr_tests.c \ + $(srcdir)/../stubs.c \ $(NULL) msc_vlr_test_gsm_authen_SOURCES = \ msc_vlr_test_gsm_authen.c \ msc_vlr_tests.c \ + $(srcdir)/../stubs.c \ $(NULL) msc_vlr_test_gsm_ciph_SOURCES = \ msc_vlr_test_gsm_ciph.c \ msc_vlr_tests.c \ + $(srcdir)/../stubs.c \ $(NULL) msc_vlr_test_umts_authen_SOURCES = \ msc_vlr_test_umts_authen.c \ msc_vlr_tests.c \ + $(srcdir)/../stubs.c \ $(NULL) msc_vlr_test_authen_reuse_SOURCES = \ msc_vlr_test_authen_reuse.c \ msc_vlr_tests.c \ + $(srcdir)/../stubs.c \ $(NULL) msc_vlr_test_hlr_reject_SOURCES = \ msc_vlr_test_hlr_reject.c \ msc_vlr_tests.c \ + $(srcdir)/../stubs.c \ $(NULL) msc_vlr_test_hlr_timeout_SOURCES = \ msc_vlr_test_hlr_timeout.c \ msc_vlr_tests.c \ + $(srcdir)/../stubs.c \ $(NULL) msc_vlr_test_ms_timeout_SOURCES = \ msc_vlr_test_ms_timeout.c \ msc_vlr_tests.c \ + $(srcdir)/../stubs.c \ $(NULL) msc_vlr_test_reject_concurrency_SOURCES = \ msc_vlr_test_reject_concurrency.c \ msc_vlr_tests.c \ + $(srcdir)/../stubs.c \ $(NULL) msc_vlr_test_call_SOURCES = \ msc_vlr_test_call.c \ msc_vlr_tests.c \ + $(srcdir)/../stubs.c \ $(NULL) msc_vlr_test_rest_SOURCES = \ msc_vlr_test_rest.c \ msc_vlr_tests.c \ + $(srcdir)/../stubs.c \ $(NULL) msc_vlr_test_ss_SOURCES = \ msc_vlr_test_ss.c \ msc_vlr_tests.c \ + $(srcdir)/../stubs.c \ $(NULL) .PHONY: update_exp diff --git a/tests/msc_vlr/msc_vlr_test_authen_reuse.c b/tests/msc_vlr/msc_vlr_test_authen_reuse.c index 9eadec7f9..870f99369 100644 --- a/tests/msc_vlr/msc_vlr_test_authen_reuse.c +++ b/tests/msc_vlr/msc_vlr_test_authen_reuse.c @@ -24,7 +24,6 @@ /* NOTE that further auth re-use tests exist in msc_vlr_test_hlr_reject.c */ #include "msc_vlr_tests.h" -#include "stubs.h" static void _test_auth_reuse(enum osmo_rat_type via_ran, int set_max_reuse_count, @@ -44,7 +43,7 @@ static void _test_auth_reuse(enum osmo_rat_type via_ran, btw("Location Update request causes a GSUP Send Auth Info request to HLR"); lu_result_sent = RES_NONE; - gsup_expect_tx("080108" "09710000000156f0" VLR_TO_HLR); + gsup_expect_tx("080108" "09710000000156f0" CN_DOMAIN VLR_TO_HLR); ms_sends_msg("0508" /* MM LU */ "7" /* ciph key seq: no key available */ "0" /* LU type: normal */ @@ -86,7 +85,7 @@ static void _test_auth_reuse(enum osmo_rat_type via_ran, if (via_ran == OSMO_RAT_GERAN_A) { btw("MS sends Authen Response, VLR accepts and sends GSUP LU Req to HLR"); - gsup_expect_tx("04010809710000000156f0280102" VLR_TO_HLR); + gsup_expect_tx("04010809710000000156f0" CN_DOMAIN VLR_TO_HLR); ms_sends_msg("0554" "e229c19e" "2104" "791f2e41"); VERBOSE_ASSERT(gsup_tx_confirmed, == true, "%d"); VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); @@ -99,8 +98,8 @@ static void _test_auth_reuse(enum osmo_rat_type via_ran, VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); btw("MS sends SecurityModeControl acceptance, VLR accepts and sends GSUP LU Req to HLR"); - gsup_expect_tx("04010809710000000156f0280102" VLR_TO_HLR); - ms_sends_security_mode_complete(); + gsup_expect_tx("04010809710000000156f0" CN_DOMAIN VLR_TO_HLR); + ms_sends_security_mode_complete(1); VERBOSE_ASSERT(gsup_tx_confirmed, == true, "%d"); VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); } @@ -171,7 +170,7 @@ static void _test_auth_reuse(enum osmo_rat_type via_ran, VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d"); btw("MS sends SecurityModeControl acceptance, VLR accepts; above Ciphering is an implicit CM Service Accept"); - ms_sends_security_mode_complete(); + ms_sends_security_mode_complete(1); VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d"); } @@ -196,7 +195,7 @@ static void _test_auth_reuse(enum osmo_rat_type via_ran, " and needs to request a second auth vector from HLR"); auth_request_sent = false; cm_service_result_sent = RES_NONE; - gsup_expect_tx("080108" "09710000000156f0" VLR_TO_HLR); + gsup_expect_tx("080108" "09710000000156f0" CN_DOMAIN VLR_TO_HLR); ms_sends_msg("052474" "03575886" /* classmark 2 */ "089910070000106005" /* IMSI */); @@ -240,7 +239,7 @@ static void _test_auth_reuse(enum osmo_rat_type via_ran, VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d"); btw("MS sends SecurityModeControl acceptance, VLR accepts; above Ciphering is an implicit CM Service Accept"); - ms_sends_security_mode_complete(); + ms_sends_security_mode_complete(1); VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d"); } diff --git a/tests/msc_vlr/msc_vlr_test_authen_reuse.err b/tests/msc_vlr/msc_vlr_test_authen_reuse.err index ea156de99..1f8afb07f 100644 --- a/tests/msc_vlr/msc_vlr_test_authen_reuse.err +++ b/tests/msc_vlr/msc_vlr_test_authen_reuse.err @@ -1,7 +1,3 @@ -DLMGCP MGCP client: using endpoint domain '@mgw' -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 17 - ===== test_auth_use_twice_geran - Location Update request causes a GSUP Send Auth Info request to HLR MSC <--GERAN-A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST @@ -30,13 +26,14 @@ DREF VLR subscr IMSI-901700000010650 + active-conn: now used by 2 (_lu_fsm_assoc DMSC msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK DMSC msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH DREF VLR subscr IMSI-901700000010650 - _lu_fsm_associate_vsub: now used by 1 (active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre() DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Allocated DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU) DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START -GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f00a0101 +GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f02801020a0101 DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI DREF msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - mm_rx_loc_upd_req: now used by 2 (rx_from_ms,lu) DREF msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu) @@ -69,9 +66,11 @@ DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: Au DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU) -DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES +DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_SUCCESS DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth() DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_ciph() +DMSC msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(IMSI-901700000010650:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_node_4() DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD DVLR upd_hlr_vlr_fsm(IMSI-901700000010650:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated @@ -261,6 +260,8 @@ DVLR VLR_Authenticate(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A: DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: Received Event PR_ARQ_E_AUTH_RES DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2() DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2_post_ciph() +DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2_post_vlr() DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_pres() DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_trace() @@ -268,6 +269,7 @@ DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x0302010 DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: proc_arq_fsm_done(PASSED) DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: state_chg to PR_ARQ_S_DONE DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_DONE}: Process Access Request result: PASSED +DBSSAP msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: Sending DTAP: MM GSM48_MT_MM_CM_SERV_ACC DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN encode: DTAP on GERAN-A - DTAP --GERAN-A--> MS: GSM48_MT_MM_CM_SERV_ACC: 0521 DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST @@ -350,7 +352,7 @@ DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x0302010 DVLR VLR_Authenticate(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){VLR_SUB_AS_NEEDS_AUTH}: Allocated DVLR VLR_Authenticate(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){VLR_SUB_AS_NEEDS_AUTH}: is child of Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ) DVLR VLR_Authenticate(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START -GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f00a0101 +GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f02801020a0101 DVLR VLR_Authenticate(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - proc_arq_vlr_fn_init: now used by 2 (attached,active-conn) DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (cm_service_sms) @@ -388,6 +390,8 @@ DVLR VLR_Authenticate(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A: DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: Received Event PR_ARQ_E_AUTH_RES DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2() DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2_post_ciph() +DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2_post_vlr() DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_pres() DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_trace() @@ -395,6 +399,7 @@ DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x0302010 DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: proc_arq_fsm_done(PASSED) DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: state_chg to PR_ARQ_S_DONE DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_DONE}: Process Access Request result: PASSED +DBSSAP msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: Sending DTAP: MM GSM48_MT_MM_CM_SERV_ACC DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN encode: DTAP on GERAN-A - DTAP --GERAN-A--> MS: GSM48_MT_MM_CM_SERV_ACC: 0521 DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST @@ -456,12 +461,13 @@ DMSC dummy_msc_i{0}: is child of msub_fsm DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms) DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3 DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: MM GSM48_MT_MM_IMSI_DETACH_IND -DMM IMSI DETACH INDICATION: MI(IMSI)=901700000010650 +DMM IMSI DETACH INDICATION: IMSI-901700000010650 DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + gsm48_rx_mm_imsi_detach_ind: now used by 2 (attached,gsm48_rx_mm_imsi_detach_ind) DMM IMSI DETACH for IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + active-conn: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn) DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn,vlr_subscr_cancel_attach_fsm) DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - attached: now used by 2 (gsm48_rx_mm_imsi_detach_ind,active-conn) DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - gsm48_rx_mm_imsi_detach_ind: now used by 1 (active-conn) DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_CN_CLOSE @@ -501,9 +507,6 @@ DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:NONE){MSC_A llist_count(&msub_list) == 0 ===== test_auth_use_twice_geran: SUCCESS -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 17 - ===== test_auth_use_twice_utran - Location Update request causes a GSUP Send Auth Info request to HLR MSC <--UTRAN-Iu-- MS: GSM48_MT_MM_LOC_UPD_REQUEST @@ -532,13 +535,14 @@ DREF VLR subscr IMSI-901700000010650 + active-conn: now used by 2 (_lu_fsm_assoc DMSC msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK DMSC msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH DREF VLR subscr IMSI-901700000010650 - _lu_fsm_associate_vsub: now used by 1 (active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre() DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: Allocated DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU) DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START -GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f00a0101 +GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f02801020a0101 DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI DREF msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: - mm_rx_loc_upd_req: now used by 2 (rx_from_ms,lu) DREF msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu) @@ -571,7 +575,7 @@ DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_WAIT_RESP}: A DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU) -DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES +DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_SUCCESS DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth() DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: Set Ciphering Mode DMSC msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: CIPHER_MODE_COMMAND on UTRAN-Iu @@ -873,7 +877,7 @@ DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x0302010 DVLR VLR_Authenticate(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){VLR_SUB_AS_NEEDS_AUTH}: Allocated DVLR VLR_Authenticate(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){VLR_SUB_AS_NEEDS_AUTH}: is child of Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ) DVLR VLR_Authenticate(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START -GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f00a0101 +GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f02801020a0101 DVLR VLR_Authenticate(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - proc_arq_vlr_fn_init: now used by 2 (attached,active-conn) DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (cm_service_sms) @@ -988,12 +992,13 @@ DMSC dummy_msc_i{0}: is child of msub_fsm DREF msc_a(unknown:UTRAN-Iu:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms) DIUCS msc_a(unknown:UTRAN-Iu:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3 DRLL msc_a(unknown:UTRAN-Iu:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: MM GSM48_MT_MM_IMSI_DETACH_IND -DMM IMSI DETACH INDICATION: MI(IMSI)=901700000010650 +DMM IMSI DETACH INDICATION: IMSI-901700000010650 DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + gsm48_rx_mm_imsi_detach_ind: now used by 2 (attached,gsm48_rx_mm_imsi_detach_ind) DMM IMSI DETACH for IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + active-conn: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn) DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn,vlr_subscr_cancel_attach_fsm) DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - attached: now used by 2 (gsm48_rx_mm_imsi_detach_ind,active-conn) DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - gsm48_rx_mm_imsi_detach_ind: now used by 1 (active-conn) DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:NONE){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_CN_CLOSE @@ -1033,9 +1038,6 @@ DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:NONE){MSC_ llist_count(&msub_list) == 0 ===== test_auth_use_twice_utran: SUCCESS -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 17 - ===== test_auth_use_infinitely_geran - Location Update request causes a GSUP Send Auth Info request to HLR MSC <--GERAN-A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST @@ -1064,13 +1066,14 @@ DREF VLR subscr IMSI-901700000010650 + active-conn: now used by 2 (_lu_fsm_assoc DMSC msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK DMSC msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH DREF VLR subscr IMSI-901700000010650 - _lu_fsm_associate_vsub: now used by 1 (active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre() DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Allocated DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU) DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START -GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f00a0101 +GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f02801020a0101 DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI DREF msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - mm_rx_loc_upd_req: now used by 2 (rx_from_ms,lu) DREF msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu) @@ -1103,9 +1106,11 @@ DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: Au DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU) -DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES +DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_SUCCESS DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth() DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_ciph() +DMSC msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(IMSI-901700000010650:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_node_4() DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD DVLR upd_hlr_vlr_fsm(IMSI-901700000010650:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated @@ -1295,6 +1300,8 @@ DVLR VLR_Authenticate(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A: DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: Received Event PR_ARQ_E_AUTH_RES DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2() DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2_post_ciph() +DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2_post_vlr() DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_pres() DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_trace() @@ -1302,6 +1309,7 @@ DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x0302010 DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: proc_arq_fsm_done(PASSED) DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: state_chg to PR_ARQ_S_DONE DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_DONE}: Process Access Request result: PASSED +DBSSAP msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: Sending DTAP: MM GSM48_MT_MM_CM_SERV_ACC DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN encode: DTAP on GERAN-A - DTAP --GERAN-A--> MS: GSM48_MT_MM_CM_SERV_ACC: 0521 DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST @@ -1410,6 +1418,8 @@ DVLR VLR_Authenticate(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A: DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: Received Event PR_ARQ_E_AUTH_RES DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2() DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2_post_ciph() +DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2_post_vlr() DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_pres() DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_trace() @@ -1417,6 +1427,7 @@ DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x0302010 DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: proc_arq_fsm_done(PASSED) DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: state_chg to PR_ARQ_S_DONE DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_DONE}: Process Access Request result: PASSED +DBSSAP msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: Sending DTAP: MM GSM48_MT_MM_CM_SERV_ACC DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN encode: DTAP on GERAN-A - DTAP --GERAN-A--> MS: GSM48_MT_MM_CM_SERV_ACC: 0521 DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST @@ -1525,6 +1536,8 @@ DVLR VLR_Authenticate(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A: DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: Received Event PR_ARQ_E_AUTH_RES DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2() DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2_post_ciph() +DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2_post_vlr() DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_pres() DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_trace() @@ -1532,6 +1545,7 @@ DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x0302010 DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: proc_arq_fsm_done(PASSED) DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: state_chg to PR_ARQ_S_DONE DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_DONE}: Process Access Request result: PASSED +DBSSAP msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: Sending DTAP: MM GSM48_MT_MM_CM_SERV_ACC DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN encode: DTAP on GERAN-A - DTAP --GERAN-A--> MS: GSM48_MT_MM_CM_SERV_ACC: 0521 DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST @@ -1593,12 +1607,13 @@ DMSC dummy_msc_i{0}: is child of msub_fsm DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms) DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3 DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: MM GSM48_MT_MM_IMSI_DETACH_IND -DMM IMSI DETACH INDICATION: MI(IMSI)=901700000010650 +DMM IMSI DETACH INDICATION: IMSI-901700000010650 DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + gsm48_rx_mm_imsi_detach_ind: now used by 2 (attached,gsm48_rx_mm_imsi_detach_ind) DMM IMSI DETACH for IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + active-conn: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn) DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn,vlr_subscr_cancel_attach_fsm) DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - attached: now used by 2 (gsm48_rx_mm_imsi_detach_ind,active-conn) DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - gsm48_rx_mm_imsi_detach_ind: now used by 1 (active-conn) DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_CN_CLOSE @@ -1638,9 +1653,6 @@ DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:NONE){MSC_A llist_count(&msub_list) == 0 ===== test_auth_use_infinitely_geran: SUCCESS -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 17 - ===== test_auth_use_infinitely_utran - Location Update request causes a GSUP Send Auth Info request to HLR MSC <--UTRAN-Iu-- MS: GSM48_MT_MM_LOC_UPD_REQUEST @@ -1669,13 +1681,14 @@ DREF VLR subscr IMSI-901700000010650 + active-conn: now used by 2 (_lu_fsm_assoc DMSC msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK DMSC msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH DREF VLR subscr IMSI-901700000010650 - _lu_fsm_associate_vsub: now used by 1 (active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre() DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: Allocated DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU) DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START -GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f00a0101 +GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f02801020a0101 DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI DREF msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: - mm_rx_loc_upd_req: now used by 2 (rx_from_ms,lu) DREF msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu) @@ -1708,7 +1721,7 @@ DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_WAIT_RESP}: A DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU) -DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES +DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_SUCCESS DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth() DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: Set Ciphering Mode DMSC msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: CIPHER_MODE_COMMAND on UTRAN-Iu @@ -2237,12 +2250,13 @@ DMSC dummy_msc_i{0}: is child of msub_fsm DREF msc_a(unknown:UTRAN-Iu:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms) DIUCS msc_a(unknown:UTRAN-Iu:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3 DRLL msc_a(unknown:UTRAN-Iu:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: MM GSM48_MT_MM_IMSI_DETACH_IND -DMM IMSI DETACH INDICATION: MI(IMSI)=901700000010650 +DMM IMSI DETACH INDICATION: IMSI-901700000010650 DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + gsm48_rx_mm_imsi_detach_ind: now used by 2 (attached,gsm48_rx_mm_imsi_detach_ind) DMM IMSI DETACH for IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + active-conn: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn) DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn,vlr_subscr_cancel_attach_fsm) DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - attached: now used by 2 (gsm48_rx_mm_imsi_detach_ind,active-conn) DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - gsm48_rx_mm_imsi_detach_ind: now used by 1 (active-conn) DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:NONE){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_CN_CLOSE @@ -2282,9 +2296,6 @@ DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:NONE){MSC_ llist_count(&msub_list) == 0 ===== test_auth_use_infinitely_utran: SUCCESS -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 17 - ===== test_no_auth_reuse_geran - Location Update request causes a GSUP Send Auth Info request to HLR MSC <--GERAN-A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST @@ -2313,13 +2324,14 @@ DREF VLR subscr IMSI-901700000010650 + active-conn: now used by 2 (_lu_fsm_assoc DMSC msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK DMSC msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH DREF VLR subscr IMSI-901700000010650 - _lu_fsm_associate_vsub: now used by 1 (active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre() DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Allocated DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU) DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START -GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f00a0101 +GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f02801020a0101 DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI DREF msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - mm_rx_loc_upd_req: now used by 2 (rx_from_ms,lu) DREF msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu) @@ -2352,9 +2364,11 @@ DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: Au DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU) -DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES +DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_SUCCESS DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth() DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_ciph() +DMSC msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(IMSI-901700000010650:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_node_4() DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD DVLR upd_hlr_vlr_fsm(IMSI-901700000010650:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated @@ -2518,7 +2532,7 @@ DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x0302010 DVLR VLR_Authenticate(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){VLR_SUB_AS_NEEDS_AUTH}: Allocated DVLR VLR_Authenticate(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){VLR_SUB_AS_NEEDS_AUTH}: is child of Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ) DVLR VLR_Authenticate(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START -GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f00a0101 +GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f02801020a0101 DVLR VLR_Authenticate(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - proc_arq_vlr_fn_init: now used by 2 (attached,active-conn) DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (cm_service_sms) @@ -2556,6 +2570,8 @@ DVLR VLR_Authenticate(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A: DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: Received Event PR_ARQ_E_AUTH_RES DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2() DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2_post_ciph() +DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2_post_vlr() DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_pres() DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_trace() @@ -2563,6 +2579,7 @@ DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x0302010 DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: proc_arq_fsm_done(PASSED) DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: state_chg to PR_ARQ_S_DONE DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_DONE}: Process Access Request result: PASSED +DBSSAP msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: Sending DTAP: MM GSM48_MT_MM_CM_SERV_ACC DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN encode: DTAP on GERAN-A - DTAP --GERAN-A--> MS: GSM48_MT_MM_CM_SERV_ACC: 0521 DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST @@ -2624,12 +2641,13 @@ DMSC dummy_msc_i{0}: is child of msub_fsm DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms) DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3 DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: MM GSM48_MT_MM_IMSI_DETACH_IND -DMM IMSI DETACH INDICATION: MI(IMSI)=901700000010650 +DMM IMSI DETACH INDICATION: IMSI-901700000010650 DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + gsm48_rx_mm_imsi_detach_ind: now used by 2 (attached,gsm48_rx_mm_imsi_detach_ind) DMM IMSI DETACH for IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + active-conn: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn) DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn,vlr_subscr_cancel_attach_fsm) DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - attached: now used by 2 (gsm48_rx_mm_imsi_detach_ind,active-conn) DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - gsm48_rx_mm_imsi_detach_ind: now used by 1 (active-conn) DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_CN_CLOSE @@ -2669,9 +2687,6 @@ DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:NONE){MSC_A llist_count(&msub_list) == 0 ===== test_no_auth_reuse_geran: SUCCESS -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 17 - ===== test_no_auth_reuse_utran - Location Update request causes a GSUP Send Auth Info request to HLR MSC <--UTRAN-Iu-- MS: GSM48_MT_MM_LOC_UPD_REQUEST @@ -2700,13 +2715,14 @@ DREF VLR subscr IMSI-901700000010650 + active-conn: now used by 2 (_lu_fsm_assoc DMSC msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK DMSC msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH DREF VLR subscr IMSI-901700000010650 - _lu_fsm_associate_vsub: now used by 1 (active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre() DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: Allocated DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU) DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START -GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f00a0101 +GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f02801020a0101 DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI DREF msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: - mm_rx_loc_upd_req: now used by 2 (rx_from_ms,lu) DREF msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu) @@ -2739,7 +2755,7 @@ DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_WAIT_RESP}: A DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU) -DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES +DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_SUCCESS DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth() DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: Set Ciphering Mode DMSC msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: CIPHER_MODE_COMMAND on UTRAN-Iu @@ -2917,7 +2933,7 @@ DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x0302010 DVLR VLR_Authenticate(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){VLR_SUB_AS_NEEDS_AUTH}: Allocated DVLR VLR_Authenticate(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){VLR_SUB_AS_NEEDS_AUTH}: is child of Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ) DVLR VLR_Authenticate(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START -GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f00a0101 +GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f02801020a0101 DVLR VLR_Authenticate(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - proc_arq_vlr_fn_init: now used by 2 (attached,active-conn) DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (cm_service_sms) @@ -3032,12 +3048,13 @@ DMSC dummy_msc_i{0}: is child of msub_fsm DREF msc_a(unknown:UTRAN-Iu:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms) DIUCS msc_a(unknown:UTRAN-Iu:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3 DRLL msc_a(unknown:UTRAN-Iu:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: MM GSM48_MT_MM_IMSI_DETACH_IND -DMM IMSI DETACH INDICATION: MI(IMSI)=901700000010650 +DMM IMSI DETACH INDICATION: IMSI-901700000010650 DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + gsm48_rx_mm_imsi_detach_ind: now used by 2 (attached,gsm48_rx_mm_imsi_detach_ind) DMM IMSI DETACH for IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + active-conn: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn) DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn,vlr_subscr_cancel_attach_fsm) DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - attached: now used by 2 (gsm48_rx_mm_imsi_detach_ind,active-conn) DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - gsm48_rx_mm_imsi_detach_ind: now used by 1 (active-conn) DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:NONE){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_CN_CLOSE @@ -3077,9 +3094,3 @@ DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:NONE){MSC_ llist_count(&msub_list) == 0 ===== test_no_auth_reuse_utran: SUCCESS -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 17 - -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 17 - diff --git a/tests/msc_vlr/msc_vlr_test_call.c b/tests/msc_vlr/msc_vlr_test_call.c index b31239e48..14c8ea304 100644 --- a/tests/msc_vlr/msc_vlr_test_call.c +++ b/tests/msc_vlr/msc_vlr_test_call.c @@ -22,15 +22,17 @@ */ #include "msc_vlr_tests.h" -#include "stubs.h" #include <osmocom/msc/gsm_04_08.h> +#include <osmocom/msc/codec_mapping.h> -static void mncc_sends_to_cc(uint32_t msg_type, struct gsm_mncc *mncc) -{ - mncc->msg_type = msg_type; - mncc_tx_to_cc(net, mncc); -} +#define mncc_sends_to_cc(MSG_TYPE, MNCC) do { \ + (MNCC)->msg_type = MSG_TYPE; \ + log("MSC <-- MNCC: callref 0x%x: %s\n%s", (MNCC)->callref, \ + get_mncc_name((MNCC)->msg_type), \ + (MNCC)->sdp); \ + mncc_tx_to_cc(net, MNCC); \ + } while(0) /* static void on_call_release_mncc_sends_to_cc(uint32_t msg_type, struct gsm_mncc *mncc) @@ -42,7 +44,7 @@ static void on_call_release_mncc_sends_to_cc(uint32_t msg_type, struct gsm_mncc #define IMSI "901700000010650" -static void standard_lu() +static void lu_utran_tmsi() { struct vlr_subscr *vsub; @@ -52,7 +54,7 @@ static void standard_lu() btw("Location Update request causes a GSUP Send Auth Info request to HLR"); lu_result_sent = RES_NONE; - gsup_expect_tx("080108" "09710000000156f0" VLR_TO_HLR); + gsup_expect_tx("080108" "09710000000156f0" CN_DOMAIN VLR_TO_HLR); ms_sends_msg("0508" /* MM LU */ "7" /* ciph key seq: no key available */ "0" /* LU type: normal */ @@ -126,8 +128,8 @@ static void standard_lu() VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); btw("MS sends SecurityModeControl acceptance, VLR accepts and sends GSUP LU Req to HLR"); - gsup_expect_tx("04010809710000000156f0280102" VLR_TO_HLR); - ms_sends_security_mode_complete(); + gsup_expect_tx("04010809710000000156f0" CN_DOMAIN VLR_TO_HLR); + ms_sends_security_mode_complete(1); VERBOSE_ASSERT(gsup_tx_confirmed, == true, "%d"); VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); @@ -162,17 +164,56 @@ static void standard_lu() vlr_subscr_put(vsub, __func__); } +static void lu_geran_noauth(void) +{ + rx_from_ran = OSMO_RAT_GERAN_A; + net->authentication_required = false; + net->vlr->cfg.assign_tmsi = false; + + btw("Location Update request causes a GSUP LU request to HLR"); + lu_result_sent = RES_NONE; + gsup_expect_tx("04010809710000000156f0280102" VLR_TO_HLR); + ms_sends_msg("0508" /* MM LU */ + "7" /* ciph key seq: no key available */ + "0" /* LU type: normal */ + "09f107" "0017" /* LAI, LAC */ + "57" /* classmark 1: R99, early classmark, no power lvl */ + "089910070000106005" /* IMSI */ + "3303575886" /* classmark 2 */ + ); + OSMO_ASSERT(gsup_tx_confirmed); + VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); + + btw("HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT"); + gsup_rx("10010809710000000156f00804036470f1" HLR_TO_VLR, + "12010809710000000156f0" VLR_TO_HLR); + VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); + + btw("HLR also sends GSUP _UPDATE_LOCATION_RESULT"); + expect_bssap_clear(); + gsup_rx("06010809710000000156f0" HLR_TO_VLR, NULL); + + btw("LU was successful, and the conn has already been closed"); + VERBOSE_ASSERT(lu_result_sent, == RES_ACCEPT, "%d"); + VERBOSE_ASSERT(bssap_clear_sent, == true, "%d"); + + ran_sends_clear_complete(); + EXPECT_CONN_COUNT(0); +} + + static void test_call_mo() { struct gsm_mncc mncc = { .imsi = IMSI, }; + struct gsm_mncc_rtp mncc_rtp = {}; comment_start(); fake_time_start(); - standard_lu(); + lu_utran_tmsi(); BTW("after a while, a new conn sends a CM Service Request. VLR responds with Auth Req, 2nd auth vector"); auth_request_sent = false; @@ -196,13 +237,14 @@ static void test_call_mo() VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d"); btw("MS sends SecurityModeControl acceptance, VLR accepts; above Ciphering is an implicit CM Service Accept"); - ms_sends_security_mode_complete(); + ms_sends_security_mode_complete(1); VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d"); BTW("a call is initiated"); - btw("SETUP gets forwarded to MNCC"); - cc_to_mncc_expect_tx(IMSI, MNCC_SETUP_IND); + btw("CC SETUP causes CRCX towards CN and RAN"); + expect_crcx(RTP_TO_CN); + expect_crcx(RTP_TO_RAN); ms_sends_msg("0385" /* CC, seq = 2 -> 0x80 | CC Setup = 0x5 */ "0406600402000581" /* Bearer Capability */ "5e038121f3" /* Called Number BCD */ @@ -211,8 +253,27 @@ static void test_call_mo() "04026000" /* UMTS: AMR 2 | AMR */ "00021f00" /* GSM: HR AMR | FR AMR | GSM EFR | GSM HR | GSM FR */ ); + OSMO_ASSERT(crcx_scheduled(RTP_TO_CN)); + OSMO_ASSERT(crcx_scheduled(RTP_TO_RAN)); + + btw("As soon as the MGW port towards CN is created, MNCC_SETUP_IND is triggered"); + cc_to_mncc_expect_tx(IMSI, MNCC_SETUP_IND); + crcx_ok(RTP_TO_CN); + OSMO_ASSERT(cc_to_mncc_tx_confirmed); + mncc.callref = mncc_rtp.callref = cc_to_mncc_tx_got_callref; + + btw("MNCC replies with MNCC_RTP_CREATE"); + mncc_sends_to_cc(MNCC_RTP_CREATE, &mncc_rtp); + + btw("MGW acknowledges the CRCX, triggering Assignment"); + expect_iu_rab_assignment(); + crcx_ok(RTP_TO_RAN); + OSMO_ASSERT(iu_rab_assignment_sent); + + btw("Assignment succeeds, triggering MNCC_RTP_CREATE ack to MNCC"); + cc_to_mncc_expect_tx("", MNCC_RTP_CREATE); + ms_sends_assignment_complete("AMR"); OSMO_ASSERT(cc_to_mncc_tx_confirmed); - mncc.callref = cc_to_mncc_tx_got_callref; btw("MNCC says that's fine"); dtap_expect_tx("8302" /* CC: Call Proceeding */); @@ -265,19 +326,48 @@ static void test_call_mt() struct gsm_mncc mncc = { .imsi = IMSI, .callref = 0x423, + .fields = MNCC_F_BEARER_CAP, + .bearer_cap = { + .speech_ver = { + GSM48_BCAP_SV_AMR_F, + GSM48_BCAP_SV_EFR, + GSM48_BCAP_SV_FR, + GSM48_BCAP_SV_AMR_H, + GSM48_BCAP_SV_HR, + -1 }, + }, + /* NOTE: below SDP includes only AMR, above bearer_cap includes more codecs. Ideally, these would match, + * but in reality the bearer cap in MNCC was never implemented properly. This test shows that above + * bearer_cap is ignored when SDP is present: In the CC Setup below, the Bearer Capability is only + * "04 04 60 04 05 8b" with speech versions '04' == GSM48_BCAP_SV_AMR_F and '05' == GSM48_BCAP_SV_AMR_H. + */ + .sdp = "v=0\r\n" + "o=OsmoMSC 0 0 IN IP4 10.23.23.1\r\n" + "s=GSM Call\r\n" + "c=IN IP4 10.23.23.1\r\n" + "t=0 0\r\n" + "m=audio 23 RTP/AVP 112\r\n" + "a=rtpmap:112 AMR/8000\r\n" + "a=fmtp:112 octet-align=1\r\n" + "a=ptime:20\r\n", + }; + + struct gsm_mncc_rtp mncc_rtp = { + .callref = 0x423, }; comment_start(); fake_time_start(); - standard_lu(); + lu_utran_tmsi(); BTW("after a while, MNCC asks us to setup a call, causing Paging"); paging_expect_imsi(IMSI); paging_sent = false; mncc_sends_to_cc(MNCC_SETUP_REQ, &mncc); + mncc.sdp[0] = '\0'; VERBOSE_ASSERT(paging_sent, == true, "%d"); @@ -296,24 +386,49 @@ static void test_call_mt() VERBOSE_ASSERT(security_mode_ctrl_sent, == true, "%d"); btw("MS sends SecurityModeControl acceptance, VLR accepts, sends CC Setup"); - dtap_expect_tx("0305" /* CC: Setup */); - ms_sends_security_mode_complete(); + dtap_expect_tx("0305" /* CC: Setup */ "04 04 60 04 05 8b" /* Bearer Cap, speech ver of AMR-FR and AMR-HR */); + ms_sends_security_mode_complete(1); + btw("MS confirms call, we create a RAN-side RTP and forward MNCC_CALL_CONF_IND"); + expect_crcx(RTP_TO_CN); + expect_crcx(RTP_TO_RAN); cc_to_mncc_expect_tx(IMSI, MNCC_CALL_CONF_IND); ms_sends_msg("8348" /* CC: Call Confirmed */ "0406600402000581" /* Bearer Capability */ "15020100" /* Call Control Capabilities */ "40080402600400021f00" /* Supported Codec List */); + OSMO_ASSERT(crcx_scheduled(RTP_TO_CN)); + OSMO_ASSERT(crcx_scheduled(RTP_TO_RAN)); + OSMO_ASSERT(cc_to_mncc_tx_confirmed); + + btw("MGW acknowledges the CRCX to RAN, triggering Assignment"); + expect_iu_rab_assignment(); + crcx_ok(RTP_TO_RAN); + OSMO_ASSERT(iu_rab_assignment_sent); + + btw("Assignment completes, triggering CRCX to CN"); + expect_crcx(RTP_TO_CN); + ms_sends_assignment_complete("AMR"); + + btw("MNCC sends MNCC_RTP_CREATE, which first waits for the CN side RTP"); + mncc_sends_to_cc(MNCC_RTP_CREATE, &mncc_rtp); + + btw("When the CN side RTP address is known, ack MNCC_RTP_CREATE with full SDP"); + cc_to_mncc_expect_tx("", MNCC_RTP_CREATE); + crcx_ok(RTP_TO_CN); + OSMO_ASSERT(cc_to_mncc_tx_confirmed); fake_time_passes(1, 23); cc_to_mncc_expect_tx("", MNCC_ALERT_IND); ms_sends_msg("8381" /* CC: Alerting */); + OSMO_ASSERT(cc_to_mncc_tx_confirmed); fake_time_passes(1, 23); cc_to_mncc_expect_tx(IMSI, MNCC_SETUP_CNF); ms_sends_msg("83c7" /* CC: Connect */); + OSMO_ASSERT(cc_to_mncc_tx_confirmed); dtap_expect_tx("030f" /* CC: Connect Acknowledge */); mncc_sends_to_cc(MNCC_SETUP_COMPL_REQ, &mncc); @@ -347,13 +462,44 @@ static void test_call_mt2() struct gsm_mncc mncc = { .imsi = IMSI, .callref = 0x423, + .fields = MNCC_F_BEARER_CAP, + .bearer_cap = { + .speech_ver = { GSM48_BCAP_SV_FR, -1, }, + }, + /* NOTE: below SDP includes only AMR, above bearer_cap includes only GSM-FR. Ideally, these would match, + * but in reality the bearer cap in MNCC was never implemented properly. This test shows that above + * bearer_cap is ignored when SDP is present: In the CC Setup below, the Bearer Capability is only + * "04 04 60 04 05 8b" with speech versions '04' == GSM48_BCAP_SV_AMR_F and '05' == GSM48_BCAP_SV_AMR_H. + */ + .sdp = "v=0\r\n" + "o=OsmoMSC 0 0 IN IP4 10.23.23.1\r\n" + "s=GSM Call\r\n" + "c=IN IP4 10.23.23.1\r\n" + "t=0 0\r\n" + "m=audio 23 RTP/AVP 112\r\n" + "a=rtpmap:112 AMR/8000\r\n" + "a=fmtp:112 octet-align=1\r\n" + "a=ptime:20\r\n", + }; + + struct gsm_mncc_rtp mncc_rtp = { + .callref = 0x423, + .sdp = "v=0\r\n" + "o=OsmoMSC 0 0 IN IP4 10.23.23.1\r\n" + "s=GSM Call\r\n" + "c=IN IP4 10.23.23.1\r\n" + "t=0 0\r\n" + "m=audio 23 RTP/AVP 112\r\n" + "a=rtpmap:112 AMR/8000\r\n" + "a=fmtp:112 octet-align=1\r\n" + "a=ptime:20\r\n", }; comment_start(); fake_time_start(); - standard_lu(); + lu_utran_tmsi(); BTW("after a while, MNCC asks us to setup a call, causing Paging"); @@ -378,14 +524,35 @@ static void test_call_mt2() VERBOSE_ASSERT(security_mode_ctrl_sent, == true, "%d"); btw("MS sends SecurityModeControl acceptance, VLR accepts, sends CC Setup"); - dtap_expect_tx("0305" /* CC: Setup */); - ms_sends_security_mode_complete(); + dtap_expect_tx("0305" /* CC: Setup */ "04 04 60 04 05 8b" /* Bearer Cap, speech ver of AMR-FR and AMR-HR */); + ms_sends_security_mode_complete(1); + btw("MS confirms call, we create a RAN-side RTP and forward MNCC_CALL_CONF_IND"); + expect_crcx(RTP_TO_CN); + expect_crcx(RTP_TO_RAN); cc_to_mncc_expect_tx(IMSI, MNCC_CALL_CONF_IND); ms_sends_msg("8348" /* CC: Call Confirmed */ "0406600402000581" /* Bearer Capability */ "15020100" /* Call Control Capabilities */ "40080402600400021f00" /* Supported Codec List */); + OSMO_ASSERT(crcx_scheduled(RTP_TO_CN)); + OSMO_ASSERT(crcx_scheduled(RTP_TO_RAN)); + OSMO_ASSERT(cc_to_mncc_tx_confirmed); + + btw("MNCC sends MNCC_RTP_CREATE, which first waits for the CN side RTP"); + mncc_sends_to_cc(MNCC_RTP_CREATE, &mncc_rtp); + + btw("MGW acknowledges the CRCX to RAN, triggering Assignment"); + expect_iu_rab_assignment(); + crcx_ok(RTP_TO_RAN); + OSMO_ASSERT(iu_rab_assignment_sent); + + btw("Assignment completes, triggering CRCX to CN"); + ms_sends_assignment_complete("AMR"); + + btw("When the CN side RTP address is known, ack MNCC_RTP_CREATE with full SDP"); + cc_to_mncc_expect_tx("", MNCC_RTP_CREATE); + crcx_ok(RTP_TO_CN); OSMO_ASSERT(cc_to_mncc_tx_confirmed); fake_time_passes(1, 23); @@ -397,12 +564,8 @@ static void test_call_mt2() fake_time_passes(15, 23); btw("The call failed, the BSC sends a BSSMAP Clear Request"); - /* FIXME: in this scenario, we send an MNCC_REL_CNF even though MNCC never asked us to MNCC_REL_REQ. Legacy - * behavior did get to both MNCC_REL_IND, then an MNCC_REL_REQ from MNCC as well as a final MNCC_REL_CNF, but - * this only worked synchronously, i.e. only with internal MNCC. Instead of mimicking that, we need a proper - * async solution that also works with a PBX. */ - cc_to_mncc_expect_tx("", MNCC_REL_CNF); - dtap_expect_tx("032d080281af"); /* CC: Release */ + cc_to_mncc_expect_tx("", MNCC_REL_IND); + dtap_expect_tx("032d0802e1af"); /* CC: Release */ expect_iu_release(); msc_a_release_cn(msub_msc_a(g_msub)); OSMO_ASSERT(dtap_tx_confirmed); @@ -425,11 +588,13 @@ static void test_call_mo_to_unknown() .imsi = IMSI, }; + struct gsm_mncc_rtp mncc_rtp = {}; + comment_start(); fake_time_start(); - standard_lu(); + lu_utran_tmsi(); BTW("after a while, a new conn sends a CM Service Request. VLR responds with Auth Req, 2nd auth vector"); auth_request_sent = false; @@ -453,13 +618,14 @@ static void test_call_mo_to_unknown() VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d"); btw("MS sends SecurityModeControl acceptance, VLR accepts; above Ciphering is an implicit CM Service Accept"); - ms_sends_security_mode_complete(); + ms_sends_security_mode_complete(1); VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d"); BTW("a call is initiated"); - btw("SETUP gets forwarded to MNCC"); - cc_to_mncc_expect_tx(IMSI, MNCC_SETUP_IND); + btw("CC SETUP causes CRCX towards CN and RAN"); + expect_crcx(RTP_TO_CN); + expect_crcx(RTP_TO_RAN); ms_sends_msg("0385" /* CC, seq = 2 -> 0x80 | CC Setup = 0x5 */ "0406600402000581" /* Bearer Capability */ "5e038121f3" /* Called Number BCD */ @@ -468,8 +634,27 @@ static void test_call_mo_to_unknown() "04026000" /* UMTS: AMR 2 | AMR */ "00021f00" /* GSM: HR AMR | FR AMR | GSM EFR | GSM HR | GSM FR */ ); + OSMO_ASSERT(crcx_scheduled(RTP_TO_CN)); + OSMO_ASSERT(crcx_scheduled(RTP_TO_RAN)); + + btw("As soon as the MGW port towards CN is created, MNCC_SETUP_IND is triggered"); + cc_to_mncc_expect_tx(IMSI, MNCC_SETUP_IND); + crcx_ok(RTP_TO_CN); + OSMO_ASSERT(cc_to_mncc_tx_confirmed); + mncc.callref = mncc_rtp.callref = cc_to_mncc_tx_got_callref; + + btw("MNCC replies with MNCC_RTP_CREATE"); + mncc_sends_to_cc(MNCC_RTP_CREATE, &mncc_rtp); + + btw("MGW acknowledges the CRCX, triggering Assignment"); + expect_iu_rab_assignment(); + crcx_ok(RTP_TO_RAN); + OSMO_ASSERT(iu_rab_assignment_sent); + + btw("Assignment succeeds, triggering MNCC_RTP_CREATE ack to MNCC"); + cc_to_mncc_expect_tx("", MNCC_RTP_CREATE); + ms_sends_assignment_complete("AMR"); OSMO_ASSERT(cc_to_mncc_tx_confirmed); - mncc.callref = cc_to_mncc_tx_got_callref; btw("MNCC says that's fine"); dtap_expect_tx("8302" /* CC: Call Proceeding */); @@ -486,7 +671,6 @@ static void test_call_mo_to_unknown() expect_iu_release(); cc_to_mncc_expect_tx("", MNCC_REL_CNF); ms_sends_msg("036a" /* CC: Release Complete */); - OSMO_ASSERT(cc_to_mncc_tx_confirmed); OSMO_ASSERT(iu_release_sent); OSMO_ASSERT(cc_to_mncc_tx_confirmed); @@ -501,12 +685,13 @@ static void test_call_mo_to_unknown_timeout() struct gsm_mncc mncc = { .imsi = IMSI, }; + struct gsm_mncc_rtp mncc_rtp = {}; comment_start(); fake_time_start(); - standard_lu(); + lu_utran_tmsi(); BTW("after a while, a new conn sends a CM Service Request. VLR responds with Auth Req, 2nd auth vector"); auth_request_sent = false; @@ -530,13 +715,14 @@ static void test_call_mo_to_unknown_timeout() VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d"); btw("MS sends SecurityModeControl acceptance, VLR accepts; above Ciphering is an implicit CM Service Accept"); - ms_sends_security_mode_complete(); + ms_sends_security_mode_complete(1); VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d"); BTW("a call is initiated"); - btw("SETUP gets forwarded to MNCC"); - cc_to_mncc_expect_tx(IMSI, MNCC_SETUP_IND); + btw("CC SETUP causes CRCX towards CN and RAN"); + expect_crcx(RTP_TO_CN); + expect_crcx(RTP_TO_RAN); ms_sends_msg("0385" /* CC, seq = 2 -> 0x80 | CC Setup = 0x5 */ "0406600402000581" /* Bearer Capability */ "5e038121f3" /* Called Number BCD */ @@ -545,8 +731,27 @@ static void test_call_mo_to_unknown_timeout() "04026000" /* UMTS: AMR 2 | AMR */ "00021f00" /* GSM: HR AMR | FR AMR | GSM EFR | GSM HR | GSM FR */ ); + OSMO_ASSERT(crcx_scheduled(RTP_TO_CN)); + OSMO_ASSERT(crcx_scheduled(RTP_TO_RAN)); + + btw("As soon as the MGW port towards CN is created, MNCC_SETUP_IND is triggered"); + cc_to_mncc_expect_tx(IMSI, MNCC_SETUP_IND); + crcx_ok(RTP_TO_CN); + OSMO_ASSERT(cc_to_mncc_tx_confirmed); + mncc.callref = mncc_rtp.callref = cc_to_mncc_tx_got_callref; + + btw("MNCC replies with MNCC_RTP_CREATE"); + mncc_sends_to_cc(MNCC_RTP_CREATE, &mncc_rtp); + + btw("MGW acknowledges the CRCX, triggering Assignment"); + expect_iu_rab_assignment(); + crcx_ok(RTP_TO_RAN); + OSMO_ASSERT(iu_rab_assignment_sent); + + btw("Assignment succeeds, triggering MNCC_RTP_CREATE ack to MNCC"); + cc_to_mncc_expect_tx("", MNCC_RTP_CREATE); + ms_sends_assignment_complete("AMR"); OSMO_ASSERT(cc_to_mncc_tx_confirmed); - mncc.callref = cc_to_mncc_tx_got_callref; btw("MNCC says that's fine"); dtap_expect_tx("8302" /* CC: Call Proceeding */); @@ -574,6 +779,862 @@ static void test_call_mo_to_unknown_timeout() comment_end(); } +#define LIST_END 0xffff + +struct codec_test { + const char *desc; + + /* What to send during Complete Layer 3 as Codec List (BSS Supported). List ends with a LIST_END entry */ + enum gsm0808_speech_codec_type mo_rx_compl_l3_codec_list_bss_supported[8]; + + /* What to send during CC Setup as MS Bearer Capability. List ends with a LIST_END entry */ + enum gsm48_bcap_speech_ver mo_rx_ms_bcap[8]; + + /* What codecs should osmo-msc send in the MNCC_SETUP_IND message. + * Just the SDP subtype names like "GSM", "GSM-EFR", "AMR", ..., list ends with NULL entry */ + const char *mo_tx_sdp_mncc_setup_ind[8]; + + /* What codecs the remote call leg should send as SDP via MNCC during MNCC_RTP_CREATE (if any). */ + const char *mo_rx_sdp_mncc_rtp_create[8]; + + /* What the MSC should send as Channel Type IE in the Assignment Command to the BSS. List ends with a + * LIST_END entry */ + enum gsm0808_permitted_speech mo_tx_assignment_perm_speech[8]; + + /* What codec to assign in the Assignment Complete's Codec (Chosen) IE. Just a subtype name. */ + const char *mo_rx_assigned_codec; + + /* MO acks the MNCC_RTP_CREATE with these codecs (if any). */ + const char *mo_tx_sdp_mncc_rtp_create[8]; + + /* mt_rx_sdp_mncc_setup_req == mo_tx_sdp_mncc_rtp_create */ +#define mt_rx_sdp_mncc_setup_req mo_tx_sdp_mncc_rtp_create + + enum gsm0808_speech_codec_type mt_rx_compl_l3_codec_list_bss_supported[8]; + bool expect_codec_mismatch_on_paging_response; + enum gsm48_bcap_speech_ver mt_tx_cc_setup_bcap[8]; + enum gsm48_bcap_speech_ver mt_rx_ms_bcap[8]; + bool expect_codec_mismatch_on_cc_call_conf; + const char *mt_tx_sdp_mncc_call_conf_ind[8]; + + enum gsm0808_permitted_speech mt_tx_assignment_perm_speech[8]; + const char *mt_rx_assigned_codec; + + const char *mt_rx_sdp_mncc_rtp_create[8]; + const char *mt_tx_sdp_mncc_rtp_create[8]; + + const char *mt_tx_sdp_mncc_alert_ind[8]; + + bool mo_expect_reassignment; + enum gsm0808_permitted_speech mo_tx_reassignment_perm_speech[8]; + const char *mo_rx_reassigned_codec; + + const char *mt_tx_sdp_mncc_setup_cnf[8]; + const char *mt_rx_sdp_mncc_setup_compl_req[8]; + + /* mo_rx_sdp_mncc_alert_req == mt_tx_sdp_mncc_alert_ind */ +#define mo_rx_sdp_mncc_alert_req mt_tx_sdp_mncc_alert_ind +#define mo_rx_sdp_mncc_setup_rsp mt_tx_sdp_mncc_alert_ind + + const char *mo_tx_sdp_mncc_setup_compl_ind[8]; +}; + +#define CODEC_LIST_ALL_GSM { \ + GSM0808_SCT_FR1, \ + GSM0808_SCT_FR2, \ + GSM0808_SCT_FR3, \ + GSM0808_SCT_HR1, \ + GSM0808_SCT_HR3, \ + LIST_END \ + } + +#define BCAP_ALL_GSM { \ + GSM48_BCAP_SV_AMR_F, \ + GSM48_BCAP_SV_AMR_H, \ + GSM48_BCAP_SV_AMR_OH, \ + GSM48_BCAP_SV_EFR, \ + GSM48_BCAP_SV_FR, \ + GSM48_BCAP_SV_HR, \ + LIST_END \ + } + +#define PERM_SPEECH_ALL_GSM { \ + GSM0808_PERM_FR3, \ + GSM0808_PERM_HR3, \ + GSM0808_PERM_FR2, \ + GSM0808_PERM_FR1, \ + GSM0808_PERM_HR1, \ + LIST_END \ + } + +#define SDP_CODECS_ALL_GSM { \ + "AMR", \ + "GSM-EFR", \ + "GSM", \ + "GSM-HR-08", \ + } + +static const struct codec_test codec_tests[] = { + { + .desc = "AMR picked by both MO and MT", + .mo_rx_compl_l3_codec_list_bss_supported = CODEC_LIST_ALL_GSM, + .mo_rx_ms_bcap = BCAP_ALL_GSM, + .mo_tx_sdp_mncc_setup_ind = SDP_CODECS_ALL_GSM, + .mo_rx_sdp_mncc_rtp_create = {}, + .mo_tx_assignment_perm_speech = PERM_SPEECH_ALL_GSM, + .mo_rx_assigned_codec = "AMR", + .mo_tx_sdp_mncc_rtp_create = { "AMR", "GSM-EFR", "GSM", "GSM-HR-08" }, + /* mt_rx_sdp_mncc_setup_req == mo_tx_sdp_mncc_rtp_create */ + .mt_rx_compl_l3_codec_list_bss_supported = CODEC_LIST_ALL_GSM, + .mt_tx_cc_setup_bcap = { + GSM48_BCAP_SV_AMR_F, + GSM48_BCAP_SV_AMR_H, + GSM48_BCAP_SV_AMR_OH, + GSM48_BCAP_SV_EFR, + GSM48_BCAP_SV_FR, + GSM48_BCAP_SV_HR, + LIST_END + }, + .mt_rx_ms_bcap = BCAP_ALL_GSM, + .mt_tx_sdp_mncc_call_conf_ind = {}, + .mt_rx_sdp_mncc_rtp_create = {}, + .mt_tx_assignment_perm_speech = { + GSM0808_PERM_FR3, + GSM0808_PERM_HR3, + GSM0808_PERM_FR2, + GSM0808_PERM_FR1, + GSM0808_PERM_HR1, + LIST_END + }, + .mt_rx_assigned_codec = "AMR", + .mt_tx_sdp_mncc_rtp_create = { "AMR", "GSM-EFR", "GSM", "GSM-HR-08" }, + .mt_tx_sdp_mncc_alert_ind = { "AMR", "GSM-EFR", "GSM", "GSM-HR-08" }, + .mt_tx_sdp_mncc_setup_cnf = { "AMR", "GSM-EFR", "GSM", "GSM-HR-08" }, + .mo_tx_sdp_mncc_setup_compl_ind = {}, + }, + + { + .desc = "FR1 picked by MO from Codec List (BSS Supported), MT hence also picks FR1", + .mo_rx_compl_l3_codec_list_bss_supported = { GSM0808_SCT_FR1, LIST_END }, + .mo_rx_ms_bcap = BCAP_ALL_GSM, + .mo_tx_sdp_mncc_setup_ind = { "GSM" }, + .mo_rx_sdp_mncc_rtp_create = {}, + .mo_tx_assignment_perm_speech = { GSM0808_PERM_FR1, LIST_END }, + .mo_rx_assigned_codec = "GSM", + .mo_tx_sdp_mncc_rtp_create = { "GSM" }, + /* mt_rx_sdp_mncc_setup_req == mo_tx_sdp_mncc_rtp_create */ + .mt_rx_compl_l3_codec_list_bss_supported = CODEC_LIST_ALL_GSM, + .mt_tx_cc_setup_bcap = { GSM48_BCAP_SV_FR, LIST_END }, + .mt_rx_ms_bcap = BCAP_ALL_GSM, + .mt_tx_sdp_mncc_call_conf_ind = {}, + .mt_rx_sdp_mncc_rtp_create = {}, + .mt_tx_assignment_perm_speech = { GSM0808_PERM_FR1, LIST_END }, + .mt_rx_assigned_codec = "GSM", + .mt_tx_sdp_mncc_rtp_create = { "GSM" }, + .mt_tx_sdp_mncc_alert_ind = { "GSM" }, + .mt_tx_sdp_mncc_setup_cnf = { "GSM" }, + .mo_tx_sdp_mncc_setup_compl_ind = {}, + }, + + { + .desc = "FR1 picked by MO from Bearer Cap, MT hence also picks FR1", + .mo_rx_compl_l3_codec_list_bss_supported = CODEC_LIST_ALL_GSM, + .mo_rx_ms_bcap = { GSM48_BCAP_SV_FR, LIST_END }, + .mo_tx_sdp_mncc_setup_ind = { "GSM" }, + .mo_rx_sdp_mncc_rtp_create = {}, + .mo_tx_assignment_perm_speech = { GSM0808_PERM_FR1, LIST_END }, + .mo_rx_assigned_codec = "GSM", + .mo_tx_sdp_mncc_rtp_create = { "GSM" }, + /* mt_rx_sdp_mncc_setup_req == mo_tx_sdp_mncc_rtp_create */ + .mt_rx_compl_l3_codec_list_bss_supported = CODEC_LIST_ALL_GSM, + .mt_tx_cc_setup_bcap = { GSM48_BCAP_SV_FR, LIST_END }, + .mt_rx_ms_bcap = BCAP_ALL_GSM, + .mt_tx_sdp_mncc_call_conf_ind = {}, + .mt_rx_sdp_mncc_rtp_create = {}, + .mt_tx_assignment_perm_speech = { GSM0808_PERM_FR1, LIST_END }, + .mt_rx_assigned_codec = "GSM", + .mt_tx_sdp_mncc_rtp_create = { "GSM" }, + .mt_tx_sdp_mncc_alert_ind = { "GSM" }, + .mt_tx_sdp_mncc_setup_cnf = { "GSM" }, + .mo_tx_sdp_mncc_setup_compl_ind = {}, + }, + + { + .desc = "FR1 picked by MT's Codec List (BSS Supported), hence MO re-assigns to FR1", + .mo_rx_compl_l3_codec_list_bss_supported = CODEC_LIST_ALL_GSM, + .mo_rx_ms_bcap = BCAP_ALL_GSM, + .mo_tx_sdp_mncc_setup_ind = SDP_CODECS_ALL_GSM, + .mo_rx_sdp_mncc_rtp_create = {}, + .mo_tx_assignment_perm_speech = PERM_SPEECH_ALL_GSM, + .mo_rx_assigned_codec = "AMR", /* <- Early Assignment first picks a mismatching codec */ + .mo_tx_sdp_mncc_rtp_create = { "AMR", "GSM-EFR", "GSM", "GSM-HR-08" }, + + /* This is the codec limitation this test verifies, Codec List (BSS Supported): */ + .mt_rx_compl_l3_codec_list_bss_supported = { GSM0808_SCT_FR1, LIST_END }, + + /* from above codec list, MSC derives the limited bcap sent in CC Setup to MS */ + .mt_tx_cc_setup_bcap = { + GSM48_BCAP_SV_FR, + LIST_END + }, + /* MS could do more, but it doesn't affect the choice of FR1 */ + .mt_rx_ms_bcap = BCAP_ALL_GSM, + .mt_tx_sdp_mncc_call_conf_ind = {}, + .mt_rx_sdp_mncc_rtp_create = {}, + .mt_tx_assignment_perm_speech = { + GSM0808_PERM_FR1, + LIST_END + }, + .mt_rx_assigned_codec = "GSM", + .mt_tx_sdp_mncc_rtp_create = { "GSM" }, + .mt_tx_sdp_mncc_alert_ind = { "GSM" }, + + .mo_expect_reassignment = true, + .mo_tx_reassignment_perm_speech = { + GSM0808_PERM_FR1, + LIST_END + }, + .mo_rx_reassigned_codec = "GSM", + + .mt_tx_sdp_mncc_setup_cnf = { "GSM" }, + .mo_tx_sdp_mncc_setup_compl_ind = {}, + }, + + { + .desc = "FR1 picked by MT's MS Bearer Capability, hence MO re-assigns to FR1", + .mo_rx_compl_l3_codec_list_bss_supported = CODEC_LIST_ALL_GSM, + .mo_rx_ms_bcap = BCAP_ALL_GSM, + .mo_tx_sdp_mncc_setup_ind = SDP_CODECS_ALL_GSM, + .mo_rx_sdp_mncc_rtp_create = {}, + .mo_tx_assignment_perm_speech = PERM_SPEECH_ALL_GSM, + .mo_rx_assigned_codec = "AMR", /* <- Early Assignment first picks a mismatching codec */ + .mo_tx_sdp_mncc_rtp_create = { "AMR", "GSM-EFR", "GSM", "GSM-HR-08" }, + + .mt_rx_compl_l3_codec_list_bss_supported = CODEC_LIST_ALL_GSM, + .mt_tx_cc_setup_bcap = BCAP_ALL_GSM, + + /* This is the codec limitation this test verifies: */ + .mt_rx_ms_bcap = { + GSM48_BCAP_SV_FR, + LIST_END + }, + .mt_tx_sdp_mncc_call_conf_ind = {}, + .mt_rx_sdp_mncc_rtp_create = {}, + .mt_tx_assignment_perm_speech = { + GSM0808_PERM_FR1, + LIST_END + }, + .mt_rx_assigned_codec = "GSM", + .mt_tx_sdp_mncc_rtp_create = { "GSM" }, + .mt_tx_sdp_mncc_alert_ind = { "GSM" }, + + .mo_expect_reassignment = true, + .mo_tx_reassignment_perm_speech = { + GSM0808_PERM_FR1, + LIST_END + }, + .mo_rx_reassigned_codec = "GSM", + + .mt_tx_sdp_mncc_setup_cnf = { "GSM" }, + .mo_tx_sdp_mncc_setup_compl_ind = {}, + }, + + { + .desc = "AMR picked by both MO and MT, but MT assigns a different payload type number", + .mo_rx_compl_l3_codec_list_bss_supported = CODEC_LIST_ALL_GSM, + .mo_rx_ms_bcap = BCAP_ALL_GSM, + .mo_tx_sdp_mncc_setup_ind = SDP_CODECS_ALL_GSM, + .mo_rx_sdp_mncc_rtp_create = {}, + .mo_tx_assignment_perm_speech = PERM_SPEECH_ALL_GSM, + .mo_rx_assigned_codec = "AMR", + .mo_tx_sdp_mncc_rtp_create = { "AMR", "GSM-EFR", "GSM", "GSM-HR-08" }, + /* mt_rx_sdp_mncc_setup_req == mo_tx_sdp_mncc_rtp_create */ + .mt_rx_compl_l3_codec_list_bss_supported = CODEC_LIST_ALL_GSM, + .mt_tx_cc_setup_bcap = { + GSM48_BCAP_SV_AMR_F, + GSM48_BCAP_SV_AMR_H, + GSM48_BCAP_SV_AMR_OH, + GSM48_BCAP_SV_EFR, + GSM48_BCAP_SV_FR, + GSM48_BCAP_SV_HR, + LIST_END + }, + .mt_rx_ms_bcap = BCAP_ALL_GSM, + .mt_tx_sdp_mncc_call_conf_ind = {}, + .mt_rx_sdp_mncc_rtp_create = {}, + .mt_tx_assignment_perm_speech = { + GSM0808_PERM_FR3, + GSM0808_PERM_HR3, + GSM0808_PERM_FR2, + GSM0808_PERM_FR1, + GSM0808_PERM_HR1, + LIST_END + }, + .mt_rx_assigned_codec = "AMR", + .mt_tx_sdp_mncc_rtp_create = { "AMR#96", "GSM-EFR", "GSM", "GSM-HR-08" }, + .mt_tx_sdp_mncc_alert_ind = { "AMR#96", "GSM-EFR", "GSM", "GSM-HR-08" }, + .mt_tx_sdp_mncc_setup_cnf = { "AMR#96", "GSM-EFR", "GSM", "GSM-HR-08" }, + .mo_tx_sdp_mncc_setup_compl_ind = {}, + }, + + { + .desc = "AMR picked by both MO and MT, but MO assigns a different payload type number", + .mo_rx_compl_l3_codec_list_bss_supported = CODEC_LIST_ALL_GSM, + .mo_rx_ms_bcap = BCAP_ALL_GSM, + .mo_tx_sdp_mncc_setup_ind = SDP_CODECS_ALL_GSM, + .mo_rx_sdp_mncc_rtp_create = {}, + .mo_tx_assignment_perm_speech = PERM_SPEECH_ALL_GSM, + .mo_rx_assigned_codec = "AMR", + .mo_tx_sdp_mncc_rtp_create = { "AMR#98", "GSM-EFR", "GSM", "GSM-HR-08" }, + /* mt_rx_sdp_mncc_setup_req == mo_tx_sdp_mncc_rtp_create */ + .mt_rx_compl_l3_codec_list_bss_supported = CODEC_LIST_ALL_GSM, + .mt_tx_cc_setup_bcap = { + GSM48_BCAP_SV_AMR_F, + GSM48_BCAP_SV_AMR_H, + GSM48_BCAP_SV_AMR_OH, + GSM48_BCAP_SV_EFR, + GSM48_BCAP_SV_FR, + GSM48_BCAP_SV_HR, + LIST_END + }, + .mt_rx_ms_bcap = BCAP_ALL_GSM, + .mt_tx_sdp_mncc_call_conf_ind = {}, + .mt_rx_sdp_mncc_rtp_create = {}, + .mt_tx_assignment_perm_speech = { + GSM0808_PERM_FR3, + GSM0808_PERM_HR3, + GSM0808_PERM_FR2, + GSM0808_PERM_FR1, + GSM0808_PERM_HR1, + LIST_END + }, + .mt_rx_assigned_codec = "AMR", + .mt_tx_sdp_mncc_rtp_create = { "AMR#98", "GSM-EFR", "GSM", "GSM-HR-08" }, + .mt_tx_sdp_mncc_alert_ind = { "AMR#98", "GSM-EFR", "GSM", "GSM-HR-08" }, + .mt_tx_sdp_mncc_setup_cnf = { "AMR#98", "GSM-EFR", "GSM", "GSM-HR-08" }, + .mo_tx_sdp_mncc_setup_compl_ind = {}, + }, +}; + +static char namebuf[4][1024]; +static int use_namebuf = 0; + +static const char *codec_list_name(const enum gsm0808_speech_codec_type compl_l3_codec_list_bss_supported[]) +{ + struct osmo_strbuf sb = { .buf = namebuf[use_namebuf], .len = sizeof(namebuf[0]) }; + use_namebuf = (use_namebuf + 1) % ARRAY_SIZE(namebuf); + + const enum gsm0808_speech_codec_type *pos; + sb.buf[0] = '\0'; + for (pos = compl_l3_codec_list_bss_supported; *pos != LIST_END; pos++) + OSMO_STRBUF_PRINTF(sb, " %s", gsm0808_speech_codec_type_name(*pos)); + return sb.buf; +} + +static const struct gsm0808_speech_codec_list *codec_list(const enum gsm0808_speech_codec_type compl_l3_codec_list_bss_supported[]) +{ + static struct gsm0808_speech_codec_list scl; + scl = (struct gsm0808_speech_codec_list){}; + const enum gsm0808_speech_codec_type *pos; + for (pos = compl_l3_codec_list_bss_supported; *pos != LIST_END; pos++) { + scl.codec[scl.len] = (struct gsm0808_speech_codec){ + .fi = true, + .type = *pos, + }; + scl.len++; + } + return &scl; +} + +static const char *bcap_name(const enum gsm48_bcap_speech_ver ms_bcap[]) +{ + struct osmo_strbuf sb = { .buf = namebuf[use_namebuf], .len = sizeof(namebuf[0]) }; + use_namebuf = (use_namebuf + 1) % ARRAY_SIZE(namebuf); + + const enum gsm48_bcap_speech_ver *pos; + sb.buf[0] = '\0'; + for (pos = ms_bcap; *pos != LIST_END; pos++) { + const struct codec_mapping *m = codec_mapping_by_speech_ver(*pos); + OSMO_STRBUF_PRINTF(sb, " %s", m ? m->sdp.subtype_name : "NULL"); + } + return sb.buf; +} + +static const char *perm_speech_name(const enum gsm0808_permitted_speech perm_speech[]) +{ + struct osmo_strbuf sb = { .buf = namebuf[use_namebuf], .len = sizeof(namebuf[0]) }; + use_namebuf = (use_namebuf + 1) % ARRAY_SIZE(namebuf); + + const enum gsm0808_permitted_speech *pos; + sb.buf[0] = '\0'; + for (pos = perm_speech; *pos != LIST_END; pos++) + OSMO_STRBUF_PRINTF(sb, " %s", gsm0808_permitted_speech_name(*pos)); + return sb.buf; +} + +static const char *strlist_name(const char *const*strs) +{ + struct osmo_strbuf sb = { .buf = namebuf[use_namebuf], .len = sizeof(namebuf[0]) }; + use_namebuf = (use_namebuf + 1) % ARRAY_SIZE(namebuf); + + const char * const *pos; + sb.buf[0] = '\0'; + for (pos = strs; *pos != NULL; pos++) + OSMO_STRBUF_PRINTF(sb, " %s", *pos); + return sb.buf; +} + +/* Split an input string of "AMR#96" into "AMR" and 96: copy the subtype name without the "#96" part to + * split_subtype_name_and_pt_nr which must be a char[16]. If pt_nr is non-NULL, write the 96 to *pt_nr. + */ +static void split_subtype_name_and_pt_nr(char subtype_name_wo_pt[], int *pt_nr, const char *input) +{ + char *hash; + osmo_strlcpy(subtype_name_wo_pt, input, 16); + hash = strchr(subtype_name_wo_pt, '#'); + if (hash) { + *hash = '\0'; + if (pt_nr) + *pt_nr = atoi(hash + 1); + } +} + +/* Validate that the codecs in sdp_str appear in the order as expected by the list of subtype names in expected_codecs. + * Ignore any payload type numbers ("#96") in expected_codecs. + */ +static bool validate_sdp(const char *func, const char *desc, + const char *sdp_str, const char * const expected_codecs[]) +{ + const char * const *expect_pos; + struct sdp_audio_codec *codec; + struct sdp_msg sdp; + if (sdp_msg_from_sdp_str(&sdp, sdp_str)) { + BTW("%s: %s: ERROR: failed to parse SDP\n%s", func, desc, sdp_str); + return false; + } + + expect_pos = expected_codecs; + sdp_audio_codecs_foreach(codec, &sdp.audio_codecs) { + char subtype_name_wo_pt[16]; + if (!*expect_pos) { + BTW("%s: %s: ERROR: did not expect %s", func, desc, codec->subtype_name); + return false; + } + split_subtype_name_and_pt_nr(subtype_name_wo_pt, NULL, *expect_pos); + if (strcmp(subtype_name_wo_pt, codec->subtype_name)) { + BTW("%s: %s: ERROR: mismatch: in idx %d, expect %s, got %s", func, desc, + (int)(expect_pos - expected_codecs), *expect_pos, codec->subtype_name); + return false; + } + expect_pos++; + + /* only match first codec */ + return true; + } + if (*expect_pos) { + BTW("%s: %s: ERROR: mismatch: expected %s to be listed, but not found", func, desc, *expect_pos); + return false; + } + return true; +} + +#define VALIDATE_SDP(GOT_SDP_STR, EXPECT_SDP_STR) do { \ + if (validate_sdp(__func__, t->desc, GOT_SDP_STR, EXPECT_SDP_STR)) { \ + btw("VALIDATE_SDP OK: " #GOT_SDP_STR " == " #EXPECT_SDP_STR " ==%s", strlist_name(EXPECT_SDP_STR)); \ + } else { \ + btw("Failed to validate SDP:\nexpected%s\ngot\n%s", \ + strlist_name(EXPECT_SDP_STR), GOT_SDP_STR); \ + OSMO_ASSERT(false); \ + } \ + } while (0) + +static bool validate_perm_speech(const char *func, const char *desc, + const struct gsm0808_channel_type *ct, + const enum gsm0808_permitted_speech perm_speech[]) +{ + const enum gsm0808_permitted_speech *pos; + const uint8_t *pos2 = ct->perm_spch; + for (pos = perm_speech; *pos != LIST_END; pos++, pos2++) { + if (pos2 - ct->perm_spch >= ct->perm_spch_len) { + BTW("%s: %s: ERROR: mismatch: expected %s to be listed, but not found", func, desc, + gsm0808_permitted_speech_name(*pos)); + return false; + } + if (*pos2 != *pos) { + BTW("%s: %s: ERROR: mismatch: in idx %d, expect %s", func, desc, + (int)(pos - perm_speech), gsm0808_permitted_speech_name(*pos)); + btw("in idx %d, got %s", (int)(pos - perm_speech), gsm0808_permitted_speech_name(*pos2)); + return false; + } + } + if (pos2 - ct->perm_spch < ct->perm_spch_len) { + BTW("%s: %s: ERROR: did not expect %s", func, desc, gsm0808_permitted_speech_name(*pos2)); + return false; + } + return true; +} + +#define VALIDATE_PERM_SPEECH(GOT_PERM_SPEECH, EXPECT_PERM_SPEECH) do { \ + if (validate_perm_speech(__func__, t->desc, GOT_PERM_SPEECH, EXPECT_PERM_SPEECH)) { \ + btw("VALIDATE_PERM_SPEECH OK: " #GOT_PERM_SPEECH " == " #EXPECT_PERM_SPEECH " ==%s", \ + perm_speech_name(EXPECT_PERM_SPEECH)); \ + } else { \ + btw("Failed to validate Permitted Speech:\nexpected%s", \ + perm_speech_name(EXPECT_PERM_SPEECH)); \ + btw("got:"); \ + int i; \ + for (i = 0; i < (GOT_PERM_SPEECH)->perm_spch_len; i++) { \ + btw("%s", gsm0808_permitted_speech_name((GOT_PERM_SPEECH)->perm_spch[i])); \ + } \ + OSMO_ASSERT(false); \ + } \ + } while (0) + +/* Compose a valid SDP string from the list of codec subtype names given. If a subtype name includes a payload type + * number ("AMR#96") then use that PT number in the SDP instead of the default from codec_mapping.c. */ +static struct sdp_msg *sdp_from_subtype_names(const char *const *subtype_names) +{ + static struct sdp_msg sdp; + sdp = (struct sdp_msg){}; + const char *const *subtype_name; + osmo_sockaddr_str_from_str(&sdp.rtp, "1.2.3.4", 56); + for (subtype_name = subtype_names; *subtype_name; subtype_name++) { + char subtype_name_wo_pt[16]; + const struct codec_mapping *m; + struct sdp_audio_codec *ac; + int set_pt = -1; + split_subtype_name_and_pt_nr(subtype_name_wo_pt, &set_pt, *subtype_name); + m = codec_mapping_by_subtype_name(subtype_name_wo_pt); + if (!m) { + BTW("ERROR: unknown subtype_name: %s", *subtype_name); + abort(); + } + ac = sdp_audio_codecs_add_copy(&sdp.audio_codecs, &m->sdp); + if (set_pt >= 0) + ac->payload_type = set_pt; + } + return &sdp; +} + +static int sdp_str_from_subtype_names(char *buf, size_t buflen, const char *const *subtype_names) +{ + if (!subtype_names[0]) { + buf[0] = '\0'; + return 0; + } + return sdp_msg_to_sdp_str_buf(buf, buflen, sdp_from_subtype_names(subtype_names)); +} + +static const char *bcap_hexstr(const enum gsm48_bcap_speech_ver ms_bcap[]) +{ + struct gsm_mncc_bearer_cap bcap = { + .transfer = GSM_MNCC_BCAP_SPEECH, + .speech_ver = { -1 }, + }; + const enum gsm48_bcap_speech_ver *pos; + for (pos = ms_bcap; *pos != LIST_END; pos++) + bearer_cap_add_speech_ver(&bcap, *pos); + bearer_cap_set_radio(&bcap); + struct msgb *msg = msgb_alloc(128, "bcap"); + gsm48_encode_bearer_cap(msg, 0, &bcap); + char *ret = osmo_hexdump_nospc(msg->data, msg->len); + msgb_free(msg); + return ret; +} + +static void test_codecs_mo(const struct codec_test *t) +{ + struct gsm_mncc mncc = { + .imsi = IMSI, + }; + + struct gsm_mncc_rtp mncc_rtp = {}; + + BTW("======================== MO call: %s", t->desc); + btw("CM Service Request with Codec List (BSS Supported) =%s", + codec_list_name(t->mo_rx_compl_l3_codec_list_bss_supported)); + + cm_service_result_sent = RES_NONE; + ms_sends_compl_l3("052471" + "03575886" /* classmark 2 */ + "089910070000106005" /* IMSI */, + codec_list(t->mo_rx_compl_l3_codec_list_bss_supported)); + VERBOSE_ASSERT(cm_service_result_sent, == RES_ACCEPT, "%d"); + EXPECT_ACCEPTED(true); + + btw("MS sends CC SETUP with Bearer Capability = %s", + bcap_name(t->mo_rx_ms_bcap)); + expect_crcx(RTP_TO_CN); + expect_crcx(RTP_TO_RAN); + ms_sends_msgf("0385" /* CC, seq = 2 -> 0x80 | CC Setup = 0x5 */ + "%s" /* Bearer Capability */ + "5e038121f3" /* Called Number BCD */ + "15020100" /* CC Capabilities */ + "4008" /* Supported Codec List */ + "04026000" /* UMTS: AMR 2 | AMR */ + "00021f00" /* GSM: HR AMR | FR AMR | GSM EFR | GSM HR | GSM FR */, + bcap_hexstr(t->mo_rx_ms_bcap) + ); + OSMO_ASSERT(crcx_scheduled(RTP_TO_CN)); + OSMO_ASSERT(crcx_scheduled(RTP_TO_RAN)); + + btw("As soon as the MGW port towards CN is created, MNCC_SETUP_IND is triggered"); + cc_to_mncc_expect_tx(IMSI, MNCC_SETUP_IND); + crcx_ok(RTP_TO_CN); + OSMO_ASSERT(cc_to_mncc_tx_confirmed); + mncc.callref = mncc_rtp.callref = cc_to_mncc_tx_got_callref; + VALIDATE_SDP(cc_to_mncc_tx_last_sdp, t->mo_tx_sdp_mncc_setup_ind); + + btw("MNCC replies with MNCC_RTP_CREATE"); + sdp_str_from_subtype_names(mncc_rtp.sdp, sizeof(mncc_rtp.sdp), t->mo_rx_sdp_mncc_rtp_create); + mncc_sends_to_cc(MNCC_RTP_CREATE, &mncc_rtp); + + btw("MGW acknowledges the CRCX, triggering Assignment with%s", perm_speech_name(t->mo_tx_assignment_perm_speech)); + expect_bssap_assignment(); + crcx_ok(RTP_TO_RAN); + OSMO_ASSERT(bssap_assignment_sent); + VALIDATE_PERM_SPEECH(&bssap_assignment_command_last_channel_type, t->mo_tx_assignment_perm_speech); + + btw("Assignment succeeds, triggering MNCC_RTP_CREATE ack to MNCC"); + cc_to_mncc_expect_tx("", MNCC_RTP_CREATE); + ms_sends_assignment_complete(t->mo_rx_assigned_codec); + OSMO_ASSERT(cc_to_mncc_tx_confirmed); + VALIDATE_SDP(cc_to_mncc_tx_last_sdp, t->mo_tx_sdp_mncc_rtp_create); + + btw("MNCC says that's fine"); + dtap_expect_tx("8302" /* CC: Call Proceeding */); + mncc_sends_to_cc(MNCC_CALL_PROC_REQ, &mncc); + OSMO_ASSERT(dtap_tx_confirmed); + + fake_time_passes(1, 23); + + btw("The other call leg got established (not shown here), MNCC tells us so, with codecs {%s }", + strlist_name(t->mo_rx_sdp_mncc_alert_req)); + dtap_expect_tx("8301" /* CC: Call Alerting */); + + if (t->mo_expect_reassignment) { + btw("Expecting re-assignment"); + expect_bssap_assignment(); + } + + sdp_str_from_subtype_names(mncc.sdp, sizeof(mncc.sdp), t->mo_rx_sdp_mncc_alert_req); + mncc_sends_to_cc(MNCC_ALERT_REQ, &mncc); + OSMO_ASSERT(dtap_tx_confirmed); + + if (t->mo_expect_reassignment) { + btw("Validating re-assignment"); + OSMO_ASSERT(bssap_assignment_sent); + VALIDATE_PERM_SPEECH(&bssap_assignment_command_last_channel_type, t->mo_tx_reassignment_perm_speech); + ms_sends_assignment_complete(t->mo_rx_reassigned_codec); + } + + dtap_expect_tx("8307" /* CC: Connect */); + sdp_str_from_subtype_names(mncc.sdp, sizeof(mncc.sdp), t->mo_rx_sdp_mncc_setup_rsp); + mncc_sends_to_cc(MNCC_SETUP_RSP, &mncc); + OSMO_ASSERT(dtap_tx_confirmed); + + fake_time_passes(1, 23); + + cc_to_mncc_expect_tx("", MNCC_SETUP_COMPL_IND); + ms_sends_msg("03cf" /* CC: Connect Acknowledge */); + OSMO_ASSERT(cc_to_mncc_tx_confirmed); + VALIDATE_SDP(cc_to_mncc_tx_last_sdp, t->mo_tx_sdp_mncc_setup_compl_ind); + + BTW("RTP stream goes ahead, not shown here."); + fake_time_passes(123, 45); + + BTW("Call ends"); + cc_to_mncc_expect_tx("", MNCC_DISC_IND); + ms_sends_msg("032502e090" /* CC: Disconnect, cause: Normal Call Clearing */); + OSMO_ASSERT(cc_to_mncc_tx_confirmed); + + dtap_expect_tx("832d" /* CC: Release */); + mncc_sends_to_cc(MNCC_REL_REQ, &mncc); + OSMO_ASSERT(dtap_tx_confirmed); + + cc_to_mncc_expect_tx("", MNCC_REL_CNF); + expect_bssap_clear(); + ms_sends_msg("036a" /* CC: Release Complete */); + OSMO_ASSERT(cc_to_mncc_tx_confirmed); + OSMO_ASSERT(bssap_clear_sent); + + ran_sends_clear_complete(); + EXPECT_CONN_COUNT(0); + BTW("======================== SUCCESS: MO call: %s", t->desc); +} + +static void test_codecs_mt(const struct codec_test *t) +{ + struct gsm_mncc mncc = { + .imsi = IMSI, + .callref = 0x423, + .fields = MNCC_F_BEARER_CAP, + .bearer_cap = { + .speech_ver = { GSM48_BCAP_SV_FR, -1, }, + }, + }; + struct gsm_mncc_rtp mncc_rtp = { + .callref = 0x423, + }; + + BTW("======================== MT call: %s", t->desc); + + BTW("MNCC asks us to setup a call, causing Paging"); + + paging_expect_imsi(IMSI); + paging_sent = false; + sdp_str_from_subtype_names(mncc.sdp, sizeof(mncc.sdp), t->mt_rx_sdp_mncc_setup_req); + mncc_sends_to_cc(MNCC_SETUP_REQ, &mncc); + mncc.sdp[0] = '\0'; + + VERBOSE_ASSERT(paging_sent, == true, "%d"); + + btw("MS replies with Paging Response, with Codec List (BSS Supported) =%s", + codec_list_name(t->mt_rx_compl_l3_codec_list_bss_supported)); + + if (t->expect_codec_mismatch_on_paging_response) { + btw("VLR accepts, but MSC notices a codec mismatch and aborts"); + cc_to_mncc_expect_tx("", MNCC_REL_IND); + expect_bssap_clear(); + ms_sends_compl_l3("062707" + "03575886" /* classmark 2 */ + "089910070000106005" /* IMSI */, + codec_list(t->mt_rx_compl_l3_codec_list_bss_supported)); + OSMO_ASSERT(cc_to_mncc_tx_confirmed); + OSMO_ASSERT(bssap_clear_sent); + + ran_sends_clear_complete(); + EXPECT_CONN_COUNT(0); + + BTW("======================== SUCCESS: MT call: %s", t->desc); + return; + } + + btw("VLR accepts, MSC sends CC Setup with Bearer Capability = %s", + bcap_name(t->mt_tx_cc_setup_bcap)); + char *cc_setup_bcap = talloc_asprintf(msc_vlr_tests_ctx, "0305%s", + bcap_hexstr(t->mt_tx_cc_setup_bcap)); + dtap_expect_tx(cc_setup_bcap); + ms_sends_compl_l3("062707" + "03575886" /* classmark 2 */ + "089910070000106005" /* IMSI */, + codec_list(t->mt_rx_compl_l3_codec_list_bss_supported)); + OSMO_ASSERT(dtap_tx_confirmed); + talloc_free(cc_setup_bcap); + + btw("MS confirms call, we create a RAN-side RTP and forward MNCC_CALL_CONF_IND"); + expect_crcx(RTP_TO_CN); + expect_crcx(RTP_TO_RAN); + cc_to_mncc_expect_tx(IMSI, MNCC_CALL_CONF_IND); + ms_sends_msgf("8348" /* CC: Call Confirmed */ + "%s" /* Bearer Capability */ + "15020100" /* Call Control Capabilities */ + "40080402600400021f00" /* Supported Codec List */, + bcap_hexstr(t->mt_rx_ms_bcap) + ); + OSMO_ASSERT(crcx_scheduled(RTP_TO_CN)); + OSMO_ASSERT(crcx_scheduled(RTP_TO_RAN)); + OSMO_ASSERT(cc_to_mncc_tx_confirmed); + VALIDATE_SDP(cc_to_mncc_tx_last_sdp, t->mt_tx_sdp_mncc_call_conf_ind); + + btw("MGW acknowledges the CRCX to RAN, triggering Assignment with%s", perm_speech_name(t->mt_tx_assignment_perm_speech)); + + if (t->expect_codec_mismatch_on_cc_call_conf) { + btw("MS Bearer Capability leads to a codec mismatch, Assignment aborts"); + + dtap_expect_tx("032d0802e1af" /* CC Release */); + cc_to_mncc_expect_tx("", MNCC_REL_IND); + expect_bssap_clear(); + crcx_ok(RTP_TO_RAN); + + OSMO_ASSERT(cc_to_mncc_tx_confirmed); + OSMO_ASSERT(bssap_clear_sent); + + ran_sends_clear_complete(); + EXPECT_CONN_COUNT(0); + BTW("======================== SUCCESS: MT call: %s", t->desc); + return; + } + + expect_bssap_assignment(); + crcx_ok(RTP_TO_RAN); + OSMO_ASSERT(bssap_assignment_sent); + VALIDATE_PERM_SPEECH(&bssap_assignment_command_last_channel_type, t->mt_tx_assignment_perm_speech); + + btw("Assignment completes, triggering CRCX to CN"); + ms_sends_assignment_complete(t->mt_rx_assigned_codec); + + btw("MNCC sends MNCC_RTP_CREATE, which first waits for the CN side RTP"); + sdp_str_from_subtype_names(mncc_rtp.sdp, sizeof(mncc_rtp.sdp), t->mt_rx_sdp_mncc_rtp_create); + mncc_sends_to_cc(MNCC_RTP_CREATE, &mncc_rtp); + + btw("When the CN side RTP address is known, ack MNCC_RTP_CREATE"); + cc_to_mncc_expect_tx("", MNCC_RTP_CREATE); + crcx_ok(RTP_TO_CN); + OSMO_ASSERT(cc_to_mncc_tx_confirmed); + VALIDATE_SDP(cc_to_mncc_tx_last_sdp, t->mt_tx_sdp_mncc_rtp_create); + + fake_time_passes(1, 23); + + cc_to_mncc_expect_tx("", MNCC_ALERT_IND); + ms_sends_msg("8381" /* CC: Alerting */); + OSMO_ASSERT(cc_to_mncc_tx_confirmed); + VALIDATE_SDP(cc_to_mncc_tx_last_sdp, t->mt_tx_sdp_mncc_alert_ind); + + fake_time_passes(1, 23); + + cc_to_mncc_expect_tx(IMSI, MNCC_SETUP_CNF); + ms_sends_msg("83c7" /* CC: Connect */); + OSMO_ASSERT(cc_to_mncc_tx_confirmed); + VALIDATE_SDP(cc_to_mncc_tx_last_sdp, t->mt_tx_sdp_mncc_setup_cnf); + + dtap_expect_tx("030f" /* CC: Connect Acknowledge */); + sdp_str_from_subtype_names(mncc.sdp, sizeof(mncc.sdp), t->mt_rx_sdp_mncc_setup_compl_req); + mncc_sends_to_cc(MNCC_SETUP_COMPL_REQ, &mncc); + + BTW("RTP stream goes ahead, not shown here."); + fake_time_passes(123, 45); + + BTW("Call ends"); + cc_to_mncc_expect_tx("", MNCC_DISC_IND); + ms_sends_msg("832502e090" /* CC: Disconnect, cause: Normal Call Clearing */); + OSMO_ASSERT(cc_to_mncc_tx_confirmed); + + dtap_expect_tx("032d" /* CC: Release */); + mncc_sends_to_cc(MNCC_REL_REQ, &mncc); + OSMO_ASSERT(dtap_tx_confirmed); + + cc_to_mncc_expect_tx("", MNCC_REL_CNF); + expect_bssap_clear(); + ms_sends_msg("836a" /* CC: Release Complete */); + OSMO_ASSERT(cc_to_mncc_tx_confirmed); + OSMO_ASSERT(bssap_clear_sent); + + ran_sends_clear_complete(); + EXPECT_CONN_COUNT(0); + BTW("======================== SUCCESS: MT call: %s", t->desc); +} + +static void test_codecs(void) +{ + const struct codec_test *t; + clear_vlr(); + + comment_start(); + + fake_time_start(); + + lu_geran_noauth(); + + for (t = codec_tests; t - codec_tests < ARRAY_SIZE(codec_tests); t++) { + test_codecs_mo(t); + test_codecs_mt(t); + } + + EXPECT_CONN_COUNT(0); + clear_vlr(); + comment_end(); +} msc_vlr_test_func_t msc_vlr_tests[] = { test_call_mo, @@ -581,5 +1642,6 @@ msc_vlr_test_func_t msc_vlr_tests[] = { test_call_mt2, test_call_mo_to_unknown, test_call_mo_to_unknown_timeout, + test_codecs, NULL }; diff --git a/tests/msc_vlr/msc_vlr_test_call.err b/tests/msc_vlr/msc_vlr_test_call.err index 0eaa2f304..6fae30e73 100644 --- a/tests/msc_vlr/msc_vlr_test_call.err +++ b/tests/msc_vlr/msc_vlr_test_call.err @@ -1,7 +1,3 @@ -DLMGCP MGCP client: using endpoint domain '@mgw' -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 17 - ===== test_call_mo - Total time passed: 0.000000 s - Location Update request causes a GSUP Send Auth Info request to HLR @@ -31,13 +27,14 @@ DREF VLR subscr IMSI-901700000010650 + active-conn: now used by 2 (_lu_fsm_assoc DMSC msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK DMSC msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH DREF VLR subscr IMSI-901700000010650 - _lu_fsm_associate_vsub: now used by 1 (active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre() DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: Allocated DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU) DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START -GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f00a0101 +GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f02801020a0101 DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI DREF msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: - mm_rx_loc_upd_req: now used by 2 (rx_from_ms,lu) DREF msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu) @@ -70,7 +67,7 @@ DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_WAIT_RESP}: A DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU) -DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES +DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_SUCCESS DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth() DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: Set Ciphering Mode DMSC msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: CIPHER_MODE_COMMAND on UTRAN-Iu @@ -189,11 +186,11 @@ DMSC msub_fsm{terminating}: Deferring: will deallocate with msc_a(IMSI-901700000 DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){MSC_A_ST_RELEASED}: Deallocated, including all deferred deallocations - msub gone llist_count(&msub_list) == 0 -DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + standard_lu: now used by 2 (attached,standard_lu) +DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + lu_utran_tmsi: now used by 2 (attached,lu_utran_tmsi) vsub != NULL == 1 strcmp(vsub->imsi, IMSI) == 0 LAC == 23 -DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - standard_lu: now used by 1 (attached) +DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - lu_utran_tmsi: now used by 1 (attached) - after a while, a new conn sends a CM Service Request. VLR responds with Auth Req, 2nd auth vector @@ -278,55 +275,119 @@ DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE - a call is initiated -- SETUP gets forwarded to MNCC +- CC SETUP causes CRCX towards CN and RAN MSC <--UTRAN-Iu-- MS: GSM48_MT_CC_SETUP DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: + rx_from_ms: now used by 2 (cm_service_cc,rx_from_ms) DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: RAN decode: DTAP DRLL msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: Dispatching 04.08 message: CC GSM48_MT_CC_SETUP DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + CC: now used by 3 (attached,active-conn,CC) -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 callref-0x80000001 tid-8) New transaction +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 callref-0x80000001 tid-8) New transaction DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: Received Event MSC_A_EV_TRANSACTION_ACCEPTED DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: state_chg to MSC_A_ST_COMMUNICATING DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: + cc: now used by 3 (cm_service_cc,rx_from_ms,cc) DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - cm_service_cc: now used by 2 (rx_from_ms,cc) -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) rx SETUP in state NULL -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) starting guard timer with 180 seconds -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) new state NULL -> INITIATED -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) SETUP to 123 -DMNCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) tx MNCC_SETUP_IND - MSC --> MNCC: callref 0x80000001: MNCC_SETUP_IND +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) rx SETUP in state NULL +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) starting guard timer with 180 seconds +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) codecs: :0{AMR:octet-align=1#112} (from: MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} RAN={AMR:octet-align=1#112,AMR-WB/16000:octet-align=1#113}) +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) SETUP to 123 +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) new state NULL -> INITIATED +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Starting call assignment +DCC call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){ESTABLISHING}: Allocated +DCC call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){ESTABLISHING}: is child of msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ) +DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) codecs: :0{AMR:octet-align=1#112} (from: MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} RAN={AMR:octet-align=1#112,AMR-WB/16000:octet-align=1#113}) + MGW <--CRCX to RTP_TO_CN-- MSC: call_id=0x1 codecs=AMR:octet-align=1#112 +DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){UNINITIALIZED}: Allocated +DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){UNINITIALIZED}: is child of call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ) +DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ:trans-8:call-1:RTP_TO_CN:no-CI){UNINITIALIZED}: setting codecs to AMR:octet-align=1#112 + MGW <--CRCX to RTP_TO_RAN-- MSC: call_id=0x1 codecs=VND.3GPP.IUFP/16000#96 +DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){UNINITIALIZED}: Allocated +DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){UNINITIALIZED}: is child of call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ) +DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ:trans-8:call-1:RTP_TO_RAN:no-CI){UNINITIALIZED}: setting codecs to VND.3GPP.IUFP/16000#96 DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc) +- As soon as the MGW port towards CN is created, MNCC_SETUP_IND is triggered + MGW --CRCX OK to RTP_TO_CN--> MSC +DCC call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){ESTABLISHING}: Received Event CALL_LEG_EV_RTP_STREAM_ADDR_AVAILABLE +DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Received Event MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: MGW endpoint's RTP address available for the CI RTP_TO_CN: 10.23.23.1:23 (osmux=no:-2) +DMNCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) tx MNCC_SETUP_IND (RTP=10.23.23.1:23{AMR:octet-align=1#112}) + MSC --> MNCC: callref 0x80000001: MNCC_SETUP_IND +v=0
+o=OsmoMSC 0 0 IN IP4 10.23.23.1
+s=GSM Call
+c=IN IP4 10.23.23.1
+t=0 0
+m=audio 23 RTP/AVP 112
+a=rtpmap:112 AMR/8000
+a=fmtp:112 octet-align=1
+a=ptime:20
+ +- MNCC replies with MNCC_RTP_CREATE + MSC <-- MNCC: callref 0x80000001: MNCC_RTP_CREATE + +DMNCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) rx MNCC_RTP_CREATE +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Assignment for this trans already started earlier +- MGW acknowledges the CRCX, triggering Assignment + MGW --CRCX OK to RTP_TO_RAN--> MSC +DCC call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){ESTABLISHING}: Received Event CALL_LEG_EV_RTP_STREAM_ADDR_AVAILABLE +DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Received Event MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: MGW endpoint's RTP address available for the CI RTP_TO_RAN: 10.23.23.1:23 (osmux=no:-2) +DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) codecs: 10.23.23.1:23{AMR:octet-align=1#112} (from: MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} RAN={AMR:octet-align=1#112,AMR-WB/16000:octet-align=1#113}) +DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) Sending Assignment Command +DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN encode: ASSIGNMENT_COMMAND on UTRAN-Iu +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST +- Assignment succeeds, triggering MNCC_RTP_CREATE ack to MNCC +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN decode: ASSIGNMENT_COMPLETE +DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ:trans-8:call-1:RTP_TO_RAN:no-CI){UNINITIALIZED}: setting remote addr to 1.2.3.4:1234 +DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ:trans-8:call-1:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Not committing: no MGW endpoint CI set up +DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) codecs: 10.23.23.1:23{AMR:octet-align=1#112} (from: assigned=AMR:octet-align=1#112 MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} RAN={AMR:octet-align=1#112,AMR-WB/16000:octet-align=1#113}) +DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) Assignment Complete: RAN: VND.3GPP.IUFP/16000#96, CN: AMR:octet-align=1#112 +DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) codecs: 10.23.23.1:23{AMR:octet-align=1#112} (from: assigned=AMR:octet-align=1#112 MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} RAN={AMR:octet-align=1#112,AMR-WB/16000:octet-align=1#113}) +DMNCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) tx MNCC_RTP_CREATE (RTP=10.23.23.1:23{AMR:octet-align=1#112}) + MSC --> MNCC: callref 0x80000001: MNCC_RTP_CREATE +v=0
+o=OsmoMSC 0 0 IN IP4 10.23.23.1
+s=GSM Call
+c=IN IP4 10.23.23.1
+t=0 0
+m=audio 23 RTP/AVP 112
+a=rtpmap:112 AMR/8000
+a=fmtp:112 octet-align=1
+a=ptime:20
+ - MNCC says that's fine -DMNCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) rx MNCC_CALL_PROC_REQ -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) stopping pending guard timer -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) starting guard timer with 180 seconds -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) rx MNCC_CALL_PROC_REQ in state INITIATED -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) new state INITIATED -> MO_CALL_PROC + MSC <-- MNCC: callref 0x80000001: MNCC_CALL_PROC_REQ + +DMNCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) rx MNCC_CALL_PROC_REQ +DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) stopping pending guard timer +DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) starting guard timer with 180 seconds +DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) new state INITIATED -> MO_CALL_PROC +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_CALL_PROC DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on UTRAN-Iu - DTAP --UTRAN-Iu--> MS: GSM48_MT_CC_CALL_PROC: 8302 - DTAP matches expected message DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST -DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Starting call assignment -DCC call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){ESTABLISHING}: Allocated -DCC call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){ESTABLISHING}: is child of msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ) - MS <--Call Assignment-- MSC: callref=0x80000001 +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Assignment for this trans already started earlier - Total time passed: 1.000023 s - The other call leg got established (not shown here), MNCC tells us so -DMNCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) rx MNCC_ALERT_REQ -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) stopping pending guard timer -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) starting guard timer with 180 seconds -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) rx MNCC_ALERT_REQ in state MO_CALL_PROC -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) new state MO_CALL_PROC -> CALL_DELIVERED + MSC <-- MNCC: callref 0x80000001: MNCC_ALERT_REQ + +DMNCC trans(CC:MO_CALL_PROC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) rx MNCC_ALERT_REQ +DCC trans(CC:MO_CALL_PROC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) stopping pending guard timer +DCC trans(CC:MO_CALL_PROC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) starting guard timer with 180 seconds +DCC trans(CC:MO_CALL_PROC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) new state MO_CALL_PROC -> CALL_DELIVERED +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_ALERTING DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on UTRAN-Iu - DTAP --UTRAN-Iu--> MS: GSM48_MT_CC_ALERTING: 8301 - DTAP matches expected message DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST -DMNCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) rx MNCC_SETUP_RSP -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) stopping pending guard timer -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) starting guard timer with 180 seconds -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) rx MNCC_SETUP_RSP in state CALL_DELIVERED -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) starting timer T313 with 30 seconds -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) new state CALL_DELIVERED -> CONNECT_IND + MSC <-- MNCC: callref 0x80000001: MNCC_SETUP_RSP + +DMNCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) rx MNCC_SETUP_RSP +DCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) stopping pending guard timer +DCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) starting guard timer with 180 seconds +DCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) starting timer T313 with 30 seconds +DCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) new state CALL_DELIVERED -> CONNECT_IND +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_CONNECT DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on UTRAN-Iu - DTAP --UTRAN-Iu--> MS: GSM48_MT_CC_CONNECT: 8307 - DTAP matches expected message @@ -336,12 +397,13 @@ DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_S DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms) DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP DRLL msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_CONNECT_ACK -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) rx CONNECT_ACK in state CONNECT_IND -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) stopping pending timer T313 -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) new state CONNECT_IND -> ACTIVE -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) stopping pending guard timer -DMNCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) tx MNCC_SETUP_COMPL_IND +DCC trans(CC:CONNECT_IND IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) rx CONNECT_ACK in state CONNECT_IND +DCC trans(CC:CONNECT_IND IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) stopping pending timer T313 +DCC trans(CC:CONNECT_IND IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) new state CONNECT_IND -> ACTIVE +DCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) stopping pending guard timer +DMNCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) tx MNCC_SETUP_COMPL_IND MSC --> MNCC: callref 0x80000001: MNCC_SETUP_COMPL_IND + DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc) @@ -354,16 +416,19 @@ DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms) DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP DRLL msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_DISCONNECT -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) rx DISCONNECT in state ACTIVE -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) new state ACTIVE -> DISCONNECT_IND -DMNCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) tx MNCC_DISC_IND +DCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) rx DISCONNECT in state ACTIVE +DCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) new state ACTIVE -> DISCONNECT_IND +DMNCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) tx MNCC_DISC_IND MSC --> MNCC: callref 0x80000001: MNCC_DISC_IND + DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc) -DMNCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) rx MNCC_REL_REQ -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) starting guard timer with 180 seconds -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) rx MNCC_REL_REQ in state DISCONNECT_IND -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) starting timer T308 with 10 seconds -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) new state DISCONNECT_IND -> RELEASE_REQ + MSC <-- MNCC: callref 0x80000001: MNCC_REL_REQ + +DMNCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) rx MNCC_REL_REQ +DCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) starting guard timer with 180 seconds +DCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) starting timer T308 with 10 seconds +DCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) new state DISCONNECT_IND -> RELEASE_REQ +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_RELEASE DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on UTRAN-Iu - DTAP --UTRAN-Iu--> MS: GSM48_MT_CC_RELEASE: 832d - DTAP matches expected message @@ -372,13 +437,14 @@ DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_S DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms) DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP DRLL msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_RELEASE_COMPL -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) rx RELEASE_COMPL in state RELEASE_REQ -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) stopping pending timer T308 -DMNCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) tx MNCC_REL_CNF +DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) rx RELEASE_COMPL in state RELEASE_REQ +DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) stopping pending timer T308 +DMNCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) tx MNCC_REL_CNF MSC --> MNCC: callref 0x80000001: MNCC_REL_CNF -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x0 tid-8) Freeing transaction -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x0 tid-8) new state RELEASE_REQ -> NULL -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x0 tid-8) stopping pending guard timer + +DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x0 tid-8) Freeing transaction +DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x0 tid-8) new state RELEASE_REQ -> NULL +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x0 tid-8) stopping pending guard timer DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - CC: now used by 2 (attached,active-conn) DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - cc: now used by 1 (rx_from_ms) DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 0 (-) @@ -389,6 +455,12 @@ DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + msc_a_fsm_re DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,active-conn,msc_a_fsm_releasing_onenter,vlr_subscr_cancel_attach_fsm) DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,active-conn,msc_a_fsm_releasing_onenter) DCC call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){ESTABLISHING}: state_chg to RELEASING +DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ:trans-8:call-1:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Terminating (cause = OSMO_FSM_TERM_PARENT) +DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ:trans-8:call-1:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Removing from parent call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ) +DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ:trans-8:call-1:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Deallocated +DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ:trans-8:call-1:RTP_TO_CN:no-CI){UNINITIALIZED}: Terminating (cause = OSMO_FSM_TERM_PARENT) +DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ:trans-8:call-1:RTP_TO_CN:no-CI){UNINITIALIZED}: Removing from parent call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ) +DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ:trans-8:call-1:RTP_TO_CN:no-CI){UNINITIALIZED}: Deallocated DCC call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){RELEASING}: Terminating (cause = OSMO_FSM_TERM_REGULAR) DCC call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){RELEASING}: Removing from parent msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ) DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: Received Event MSC_EV_CALL_LEG_TERM @@ -425,9 +497,6 @@ DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE DVLR freeing VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 (max total use count was 4) ===== test_call_mo: SUCCESS -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 17 - ===== test_call_mt - Total time passed: 0.000000 s - Location Update request causes a GSUP Send Auth Info request to HLR @@ -457,13 +526,14 @@ DREF VLR subscr IMSI-901700000010650 + active-conn: now used by 2 (_lu_fsm_assoc DMSC msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK DMSC msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH DREF VLR subscr IMSI-901700000010650 - _lu_fsm_associate_vsub: now used by 1 (active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre() DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: Allocated DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU) DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START -GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f00a0101 +GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f02801020a0101 DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI DREF msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: - mm_rx_loc_upd_req: now used by 2 (rx_from_ms,lu) DREF msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu) @@ -496,7 +566,7 @@ DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_WAIT_RESP}: A DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU) -DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES +DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_SUCCESS DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth() DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: Set Ciphering Mode DMSC msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: CIPHER_MODE_COMMAND on UTRAN-Iu @@ -615,17 +685,30 @@ DMSC msub_fsm{terminating}: Deferring: will deallocate with msc_a(IMSI-901700000 DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){MSC_A_ST_RELEASED}: Deallocated, including all deferred deallocations - msub gone llist_count(&msub_list) == 0 -DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + standard_lu: now used by 2 (attached,standard_lu) +DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + lu_utran_tmsi: now used by 2 (attached,lu_utran_tmsi) vsub != NULL == 1 strcmp(vsub->imsi, IMSI) == 0 LAC == 23 -DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - standard_lu: now used by 1 (attached) +DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - lu_utran_tmsi: now used by 1 (attached) - after a while, MNCC asks us to setup a call, causing Paging + MSC <-- MNCC: callref 0x423: MNCC_SETUP_REQ +v=0
+o=OsmoMSC 0 0 IN IP4 10.23.23.1
+s=GSM Call
+c=IN IP4 10.23.23.1
+t=0 0
+m=audio 23 RTP/AVP 112
+a=rtpmap:112 AMR/8000
+a=fmtp:112 octet-align=1
+a=ptime:20
+ DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + mncc_tx_to_gsm_cc: now used by 2 (attached,mncc_tx_to_gsm_cc) DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + CC: now used by 3 (attached,mncc_tx_to_gsm_cc,CC) -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 callref-0x423 tid-255) New transaction +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 callref-0x423 tid-255) New transaction +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 callref-0x423 tid-255) codecs: :0{(no-codecs)} (from: remote=10.23.23.1:23{AMR:octet-align=1#112} RAN={(no-codecs)}) +DMNCC trans(CC:NULL IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 callref-0x423 tid-255) rx MNCC_SETUP_REQ (RTP=10.23.23.1:23{AMR:octet-align=1#112}) DPAG Paging: IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 for MNCC: establish call: Starting paging paging request (CALL_CONVERSATIONAL) to IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 on UTRAN-Iu strcmp(paging_expecting_imsi, vsub->imsi) == 0 @@ -644,7 +727,7 @@ DMSC dummy_msc_i{0}: is child of msub_fsm DREF msc_a(unknown:UTRAN-Iu:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms) DIUCS msc_a(unknown:UTRAN-Iu:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3 DRLL msc_a(unknown:UTRAN-Iu:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: RR GSM48_MT_RR_PAG_RESP -DRR msc_a(IMSI-901700000010650:UTRAN-Iu:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: Rx PAGING RESPONSE +DRR msc_a(IMSI-901700000010650:UTRAN-Iu:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: Rx PAGING RESPONSE IMSI-901700000010650 DREF msc_a(IMSI-901700000010650:UTRAN-Iu:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: + paging-response: now used by 2 (rx_from_ms,paging-response) DVLR Process_Access_Request_VLR(IMSI-901700000010650:UTRAN-Iu:PAGING_RESP){PR_ARQ_S_INIT}: Allocated DVLR Process_Access_Request_VLR(IMSI-901700000010650:UTRAN-Iu:PAGING_RESP){PR_ARQ_S_INIT}: is child of msc_a(IMSI-901700000010650:UTRAN-Iu:PAGING_RESP) @@ -708,61 +791,136 @@ DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RES DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: state_chg to MSC_A_ST_AUTHENTICATED DPAG Paging: IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 for MNCC: establish call: Paging Response action (success) DPAG Paging: IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 for MNCC: establish call: Removing Paging Request -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 callref-0x423 tid-255) Paging succeeded +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 callref-0x423 tid-255) Paging succeeded DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: + cc: now used by 2 (paging-response,cc) DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: Received Event MSC_A_EV_TRANSACTION_ACCEPTED DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: state_chg to MSC_A_ST_COMMUNICATING -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) starting timer T303 with 30 seconds -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) new state NULL -> CALL_PRESENT +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) starting timer T303 with 30 seconds +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) codecs: :0{AMR:octet-align=1#112} (from: remote=10.23.23.1:23{AMR:octet-align=1#112} RAN={AMR:octet-align=1#112,AMR-WB/16000:octet-align=1#113}) +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) new state NULL -> CALL_PRESENT +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_SETUP DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on UTRAN-Iu -- DTAP --UTRAN-Iu--> MS: GSM48_MT_CC_SETUP: 0305 +- DTAP --UTRAN-Iu--> MS: GSM48_MT_CC_SETUP: 030504046004058b - DTAP matches expected message DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - Paging: now used by 3 (attached,CC,active-conn) DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - paging-response: now used by 1 (cc) +- MS confirms call, we create a RAN-side RTP and forward MNCC_CALL_CONF_IND MSC <--UTRAN-Iu-- MS: GSM48_MT_CC_CALL_CONF DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms) DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP DRLL msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_CALL_CONF -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) rx CALL_CONF in state CALL_PRESENT -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) stopping pending timer T303 -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) starting timer T310 with 30 seconds -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) new state CALL_PRESENT -> MO_TERM_CALL_CONF +DCC trans(CC:CALL_PRESENT IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) rx CALL_CONF in state CALL_PRESENT +DCC trans(CC:CALL_PRESENT IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) stopping pending timer T303 +DCC trans(CC:CALL_PRESENT IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) starting timer T310 with 30 seconds DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Starting call assignment DCC call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){ESTABLISHING}: Allocated DCC call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){ESTABLISHING}: is child of msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP) - MS <--Call Assignment-- MSC: callref=0x423 -DMNCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) tx MNCC_CALL_CONF_IND +DCC trans(CC:CALL_PRESENT IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) codecs: :0{AMR:octet-align=1#112} (from: remote=10.23.23.1:23{AMR:octet-align=1#112} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} RAN={AMR:octet-align=1#112,AMR-WB/16000:octet-align=1#113}) + MGW <--CRCX to RTP_TO_CN-- MSC: call_id=0x2 codecs=AMR:octet-align=1#112 +DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){UNINITIALIZED}: Allocated +DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){UNINITIALIZED}: is child of call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP) +DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP:trans-0:call-2:RTP_TO_CN:no-CI){UNINITIALIZED}: setting codecs to AMR:octet-align=1#112 + MGW <--CRCX to RTP_TO_RAN-- MSC: call_id=0x2 codecs=VND.3GPP.IUFP/16000#96 +DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){UNINITIALIZED}: Allocated +DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){UNINITIALIZED}: is child of call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP) +DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP:trans-0:call-2:RTP_TO_RAN:no-CI){UNINITIALIZED}: setting codecs to VND.3GPP.IUFP/16000#96 +DCC trans(CC:CALL_PRESENT IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) new state CALL_PRESENT -> MO_TERM_CALL_CONF +DMNCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) tx MNCC_CALL_CONF_IND MSC --> MNCC: callref 0x423: MNCC_CALL_CONF_IND + DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc) +- MGW acknowledges the CRCX to RAN, triggering Assignment + MGW --CRCX OK to RTP_TO_RAN--> MSC +DCC call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){ESTABLISHING}: Received Event CALL_LEG_EV_RTP_STREAM_ADDR_AVAILABLE +DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Received Event MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: MGW endpoint's RTP address available for the CI RTP_TO_RAN: 10.23.23.1:23 (osmux=no:-2) +DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) codecs: :0{AMR:octet-align=1#112} (from: remote=10.23.23.1:23{AMR:octet-align=1#112} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} RAN={AMR:octet-align=1#112,AMR-WB/16000:octet-align=1#113}) +DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) Sending Assignment Command +DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN encode: ASSIGNMENT_COMMAND on UTRAN-Iu +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST +- Assignment completes, triggering CRCX to CN +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN decode: ASSIGNMENT_COMPLETE +DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP:trans-0:call-2:RTP_TO_RAN:no-CI){UNINITIALIZED}: setting remote addr to 1.2.3.4:1234 +DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP:trans-0:call-2:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Not committing: no MGW endpoint CI set up +DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) codecs: :0{AMR:octet-align=1#112} (from: assigned=AMR:octet-align=1#112 remote=10.23.23.1:23{AMR:octet-align=1#112} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} RAN={AMR:octet-align=1#112,AMR-WB/16000:octet-align=1#113}) +DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) Assignment Complete: RAN: VND.3GPP.IUFP/16000#96, CN: AMR:octet-align=1#112 +DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) Assignment complete, but still waiting for the CRCX OK on the CN side RTP +- MNCC sends MNCC_RTP_CREATE, which first waits for the CN side RTP + MSC <-- MNCC: callref 0x423: MNCC_RTP_CREATE + +DMNCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) rx MNCC_RTP_CREATE +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Assignment for this trans already started earlier +- When the CN side RTP address is known, ack MNCC_RTP_CREATE with full SDP + MGW --CRCX OK to RTP_TO_CN--> MSC +DCC call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){ESTABLISHING}: Received Event CALL_LEG_EV_RTP_STREAM_ADDR_AVAILABLE +DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Received Event MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: MGW endpoint's RTP address available for the CI RTP_TO_CN: 10.23.23.1:23 (osmux=no:-2) +DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) codecs: 10.23.23.1:23{AMR:octet-align=1#112} (from: assigned=AMR:octet-align=1#112 remote=10.23.23.1:23{AMR:octet-align=1#112} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} RAN={AMR:octet-align=1#112,AMR-WB/16000:octet-align=1#113}) +DMNCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) tx MNCC_RTP_CREATE (RTP=10.23.23.1:23{AMR:octet-align=1#112}) + MSC --> MNCC: callref 0x423: MNCC_RTP_CREATE +v=0
+o=OsmoMSC 0 0 IN IP4 10.23.23.1
+s=GSM Call
+c=IN IP4 10.23.23.1
+t=0 0
+m=audio 23 RTP/AVP 112
+a=rtpmap:112 AMR/8000
+a=fmtp:112 octet-align=1
+a=ptime:20
+ - Total time passed: 1.000023 s MSC <--UTRAN-Iu-- MS: GSM48_MT_CC_ALERTING DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms) DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP DRLL msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_ALERTING -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) rx ALERTING in state MO_TERM_CALL_CONF -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) stopping pending timer T310 -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) starting timer T301 with 180 seconds -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) new state MO_TERM_CALL_CONF -> CALL_RECEIVED -DMNCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) tx MNCC_ALERT_IND +DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) rx ALERTING in state MO_TERM_CALL_CONF +DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) stopping pending timer T310 +DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) starting timer T301 with 180 seconds +DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) new state MO_TERM_CALL_CONF -> CALL_RECEIVED +DCC trans(CC:CALL_RECEIVED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) codecs: 10.23.23.1:23{AMR:octet-align=1#112} (from: assigned=AMR:octet-align=1#112 remote=10.23.23.1:23{AMR:octet-align=1#112} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} RAN={AMR:octet-align=1#112,AMR-WB/16000:octet-align=1#113}) +DMNCC trans(CC:CALL_RECEIVED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) tx MNCC_ALERT_IND (RTP=10.23.23.1:23{AMR:octet-align=1#112}) MSC --> MNCC: callref 0x423: MNCC_ALERT_IND +v=0
+o=OsmoMSC 0 0 IN IP4 10.23.23.1
+s=GSM Call
+c=IN IP4 10.23.23.1
+t=0 0
+m=audio 23 RTP/AVP 112
+a=rtpmap:112 AMR/8000
+a=fmtp:112 octet-align=1
+a=ptime:20
+ DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc) - Total time passed: 2.000046 s MSC <--UTRAN-Iu-- MS: GSM48_MT_CC_CONNECT DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms) DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP DRLL msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_CONNECT -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) rx CONNECT in state CALL_RECEIVED -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) stopping pending timer T301 -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) new state CALL_RECEIVED -> CONNECT_REQUEST -DMNCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) tx MNCC_SETUP_CNF +DCC trans(CC:CALL_RECEIVED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) rx CONNECT in state CALL_RECEIVED +DCC trans(CC:CALL_RECEIVED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) stopping pending timer T301 +DCC trans(CC:CALL_RECEIVED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) new state CALL_RECEIVED -> CONNECT_REQUEST +DCC trans(CC:CONNECT_REQUEST IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) codecs: 10.23.23.1:23{AMR:octet-align=1#112} (from: assigned=AMR:octet-align=1#112 remote=10.23.23.1:23{AMR:octet-align=1#112} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} RAN={AMR:octet-align=1#112,AMR-WB/16000:octet-align=1#113}) +DMNCC trans(CC:CONNECT_REQUEST IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) tx MNCC_SETUP_CNF (RTP=10.23.23.1:23{AMR:octet-align=1#112}) MSC --> MNCC: callref 0x423: MNCC_SETUP_CNF +v=0
+o=OsmoMSC 0 0 IN IP4 10.23.23.1
+s=GSM Call
+c=IN IP4 10.23.23.1
+t=0 0
+m=audio 23 RTP/AVP 112
+a=rtpmap:112 AMR/8000
+a=fmtp:112 octet-align=1
+a=ptime:20
+ DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc) -DMNCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) rx MNCC_SETUP_COMPL_REQ -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) starting guard timer with 180 seconds -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) rx MNCC_SETUP_COMPL_REQ in state CONNECT_REQUEST -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) new state CONNECT_REQUEST -> ACTIVE -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) stopping pending guard timer + MSC <-- MNCC: callref 0x423: MNCC_SETUP_COMPL_REQ + +DMNCC trans(CC:CONNECT_REQUEST IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) rx MNCC_SETUP_COMPL_REQ +DCC trans(CC:CONNECT_REQUEST IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) starting guard timer with 180 seconds +DCC trans(CC:CONNECT_REQUEST IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) new state CONNECT_REQUEST -> ACTIVE +DCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) stopping pending guard timer +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_CONNECT_ACK DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on UTRAN-Iu - DTAP --UTRAN-Iu--> MS: GSM48_MT_CC_CONNECT_ACK: 030f - DTAP matches expected message @@ -778,16 +936,19 @@ DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGI DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms) DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP DRLL msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_DISCONNECT -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) rx DISCONNECT in state ACTIVE -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) new state ACTIVE -> DISCONNECT_IND -DMNCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) tx MNCC_DISC_IND +DCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) rx DISCONNECT in state ACTIVE +DCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) new state ACTIVE -> DISCONNECT_IND +DMNCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) tx MNCC_DISC_IND MSC --> MNCC: callref 0x423: MNCC_DISC_IND + DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc) -DMNCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) rx MNCC_REL_REQ -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) starting guard timer with 180 seconds -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) rx MNCC_REL_REQ in state DISCONNECT_IND -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) starting timer T308 with 10 seconds -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) new state DISCONNECT_IND -> RELEASE_REQ + MSC <-- MNCC: callref 0x423: MNCC_REL_REQ + +DMNCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) rx MNCC_REL_REQ +DCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) starting guard timer with 180 seconds +DCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) starting timer T308 with 10 seconds +DCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) new state DISCONNECT_IND -> RELEASE_REQ +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_RELEASE DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on UTRAN-Iu - DTAP --UTRAN-Iu--> MS: GSM48_MT_CC_RELEASE: 032d - DTAP matches expected message @@ -796,13 +957,14 @@ DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGI DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms) DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP DRLL msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_RELEASE_COMPL -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) rx RELEASE_COMPL in state RELEASE_REQ -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) stopping pending timer T308 -DMNCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) tx MNCC_REL_CNF +DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) rx RELEASE_COMPL in state RELEASE_REQ +DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) stopping pending timer T308 +DMNCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) tx MNCC_REL_CNF MSC --> MNCC: callref 0x423: MNCC_REL_CNF -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x0 tid-0) Freeing transaction -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x0 tid-0) new state RELEASE_REQ -> NULL -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x0 tid-0) stopping pending guard timer + +DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x0 tid-0) Freeing transaction +DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x0 tid-0) new state RELEASE_REQ -> NULL +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x0 tid-0) stopping pending guard timer DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - CC: now used by 2 (attached,active-conn) DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - cc: now used by 1 (rx_from_ms) DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 0 (-) @@ -813,6 +975,12 @@ DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + msc_a_fsm_re DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,active-conn,msc_a_fsm_releasing_onenter,vlr_subscr_cancel_attach_fsm) DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,active-conn,msc_a_fsm_releasing_onenter) DCC call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){ESTABLISHING}: state_chg to RELEASING +DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP:trans-0:call-2:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Terminating (cause = OSMO_FSM_TERM_PARENT) +DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP:trans-0:call-2:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Removing from parent call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP) +DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP:trans-0:call-2:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Deallocated +DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP:trans-0:call-2:RTP_TO_CN:no-CI){UNINITIALIZED}: Terminating (cause = OSMO_FSM_TERM_PARENT) +DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP:trans-0:call-2:RTP_TO_CN:no-CI){UNINITIALIZED}: Removing from parent call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP) +DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP:trans-0:call-2:RTP_TO_CN:no-CI){UNINITIALIZED}: Deallocated DCC call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){RELEASING}: Terminating (cause = OSMO_FSM_TERM_REGULAR) DCC call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){RELEASING}: Removing from parent msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP) DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_RELEASING}: Received Event MSC_EV_CALL_LEG_TERM @@ -849,9 +1017,6 @@ DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RES DVLR freeing VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 (max total use count was 5) ===== test_call_mt: SUCCESS -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 17 - ===== test_call_mt2 - Total time passed: 0.000000 s - Location Update request causes a GSUP Send Auth Info request to HLR @@ -881,13 +1046,14 @@ DREF VLR subscr IMSI-901700000010650 + active-conn: now used by 2 (_lu_fsm_assoc DMSC msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK DMSC msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH DREF VLR subscr IMSI-901700000010650 - _lu_fsm_associate_vsub: now used by 1 (active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre() DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: Allocated DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU) DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START -GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f00a0101 +GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f02801020a0101 DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI DREF msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: - mm_rx_loc_upd_req: now used by 2 (rx_from_ms,lu) DREF msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu) @@ -920,7 +1086,7 @@ DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_WAIT_RESP}: A DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU) -DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES +DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_SUCCESS DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth() DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: Set Ciphering Mode DMSC msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: CIPHER_MODE_COMMAND on UTRAN-Iu @@ -1039,17 +1205,30 @@ DMSC msub_fsm{terminating}: Deferring: will deallocate with msc_a(IMSI-901700000 DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){MSC_A_ST_RELEASED}: Deallocated, including all deferred deallocations - msub gone llist_count(&msub_list) == 0 -DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + standard_lu: now used by 2 (attached,standard_lu) +DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + lu_utran_tmsi: now used by 2 (attached,lu_utran_tmsi) vsub != NULL == 1 strcmp(vsub->imsi, IMSI) == 0 LAC == 23 -DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - standard_lu: now used by 1 (attached) +DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - lu_utran_tmsi: now used by 1 (attached) - after a while, MNCC asks us to setup a call, causing Paging + MSC <-- MNCC: callref 0x423: MNCC_SETUP_REQ +v=0
+o=OsmoMSC 0 0 IN IP4 10.23.23.1
+s=GSM Call
+c=IN IP4 10.23.23.1
+t=0 0
+m=audio 23 RTP/AVP 112
+a=rtpmap:112 AMR/8000
+a=fmtp:112 octet-align=1
+a=ptime:20
+ DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + mncc_tx_to_gsm_cc: now used by 2 (attached,mncc_tx_to_gsm_cc) DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + CC: now used by 3 (attached,mncc_tx_to_gsm_cc,CC) -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 callref-0x423 tid-255) New transaction +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 callref-0x423 tid-255) New transaction +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 callref-0x423 tid-255) codecs: :0{(no-codecs)} (from: remote=10.23.23.1:23{AMR:octet-align=1#112} RAN={(no-codecs)}) +DMNCC trans(CC:NULL IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 callref-0x423 tid-255) rx MNCC_SETUP_REQ (RTP=10.23.23.1:23{AMR:octet-align=1#112}) DPAG Paging: IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 for MNCC: establish call: Starting paging paging request (CALL_CONVERSATIONAL) to IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 on UTRAN-Iu strcmp(paging_expecting_imsi, vsub->imsi) == 0 @@ -1068,7 +1247,7 @@ DMSC dummy_msc_i{0}: is child of msub_fsm DREF msc_a(unknown:UTRAN-Iu:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms) DIUCS msc_a(unknown:UTRAN-Iu:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3 DRLL msc_a(unknown:UTRAN-Iu:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: RR GSM48_MT_RR_PAG_RESP -DRR msc_a(IMSI-901700000010650:UTRAN-Iu:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: Rx PAGING RESPONSE +DRR msc_a(IMSI-901700000010650:UTRAN-Iu:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: Rx PAGING RESPONSE IMSI-901700000010650 DREF msc_a(IMSI-901700000010650:UTRAN-Iu:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: + paging-response: now used by 2 (rx_from_ms,paging-response) DVLR Process_Access_Request_VLR(IMSI-901700000010650:UTRAN-Iu:PAGING_RESP){PR_ARQ_S_INIT}: Allocated DVLR Process_Access_Request_VLR(IMSI-901700000010650:UTRAN-Iu:PAGING_RESP){PR_ARQ_S_INIT}: is child of msc_a(IMSI-901700000010650:UTRAN-Iu:PAGING_RESP) @@ -1132,44 +1311,115 @@ DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RES DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: state_chg to MSC_A_ST_AUTHENTICATED DPAG Paging: IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 for MNCC: establish call: Paging Response action (success) DPAG Paging: IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 for MNCC: establish call: Removing Paging Request -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 callref-0x423 tid-255) Paging succeeded +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 callref-0x423 tid-255) Paging succeeded DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: + cc: now used by 2 (paging-response,cc) DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: Received Event MSC_A_EV_TRANSACTION_ACCEPTED DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: state_chg to MSC_A_ST_COMMUNICATING -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) starting timer T303 with 30 seconds -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) new state NULL -> CALL_PRESENT +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) starting timer T303 with 30 seconds +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) codecs: :0{AMR:octet-align=1#112} (from: remote=10.23.23.1:23{AMR:octet-align=1#112} RAN={AMR:octet-align=1#112,AMR-WB/16000:octet-align=1#113}) +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) new state NULL -> CALL_PRESENT +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_SETUP DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on UTRAN-Iu -- DTAP --UTRAN-Iu--> MS: GSM48_MT_CC_SETUP: 0305 +- DTAP --UTRAN-Iu--> MS: GSM48_MT_CC_SETUP: 030504046004058b - DTAP matches expected message DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - Paging: now used by 3 (attached,CC,active-conn) DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - paging-response: now used by 1 (cc) +- MS confirms call, we create a RAN-side RTP and forward MNCC_CALL_CONF_IND MSC <--UTRAN-Iu-- MS: GSM48_MT_CC_CALL_CONF DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms) DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP DRLL msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_CALL_CONF -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) rx CALL_CONF in state CALL_PRESENT -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) stopping pending timer T303 -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) starting timer T310 with 30 seconds -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) new state CALL_PRESENT -> MO_TERM_CALL_CONF +DCC trans(CC:CALL_PRESENT IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) rx CALL_CONF in state CALL_PRESENT +DCC trans(CC:CALL_PRESENT IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) stopping pending timer T303 +DCC trans(CC:CALL_PRESENT IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) starting timer T310 with 30 seconds DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Starting call assignment DCC call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){ESTABLISHING}: Allocated DCC call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){ESTABLISHING}: is child of msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP) - MS <--Call Assignment-- MSC: callref=0x423 -DMNCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) tx MNCC_CALL_CONF_IND +DCC trans(CC:CALL_PRESENT IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) codecs: :0{AMR:octet-align=1#112} (from: remote=10.23.23.1:23{AMR:octet-align=1#112} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} RAN={AMR:octet-align=1#112,AMR-WB/16000:octet-align=1#113}) + MGW <--CRCX to RTP_TO_CN-- MSC: call_id=0x3 codecs=AMR:octet-align=1#112 +DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){UNINITIALIZED}: Allocated +DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){UNINITIALIZED}: is child of call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP) +DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP:trans-0:call-3:RTP_TO_CN:no-CI){UNINITIALIZED}: setting codecs to AMR:octet-align=1#112 + MGW <--CRCX to RTP_TO_RAN-- MSC: call_id=0x3 codecs=VND.3GPP.IUFP/16000#96 +DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){UNINITIALIZED}: Allocated +DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){UNINITIALIZED}: is child of call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP) +DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP:trans-0:call-3:RTP_TO_RAN:no-CI){UNINITIALIZED}: setting codecs to VND.3GPP.IUFP/16000#96 +DCC trans(CC:CALL_PRESENT IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) new state CALL_PRESENT -> MO_TERM_CALL_CONF +DMNCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) tx MNCC_CALL_CONF_IND MSC --> MNCC: callref 0x423: MNCC_CALL_CONF_IND + DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc) +- MNCC sends MNCC_RTP_CREATE, which first waits for the CN side RTP + MSC <-- MNCC: callref 0x423: MNCC_RTP_CREATE +v=0
+o=OsmoMSC 0 0 IN IP4 10.23.23.1
+s=GSM Call
+c=IN IP4 10.23.23.1
+t=0 0
+m=audio 23 RTP/AVP 112
+a=rtpmap:112 AMR/8000
+a=fmtp:112 octet-align=1
+a=ptime:20
+ +DMNCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) rx MNCC_RTP_CREATE (RTP=10.23.23.1:23{AMR:octet-align=1#112}) +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Assignment for this trans already started earlier +- MGW acknowledges the CRCX to RAN, triggering Assignment + MGW --CRCX OK to RTP_TO_RAN--> MSC +DCC call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){ESTABLISHING}: Received Event CALL_LEG_EV_RTP_STREAM_ADDR_AVAILABLE +DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Received Event MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: MGW endpoint's RTP address available for the CI RTP_TO_RAN: 10.23.23.1:23 (osmux=no:-2) +DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) codecs: :0{AMR:octet-align=1#112} (from: remote=10.23.23.1:23{AMR:octet-align=1#112} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} RAN={AMR:octet-align=1#112,AMR-WB/16000:octet-align=1#113}) +DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) Sending Assignment Command +DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN encode: ASSIGNMENT_COMMAND on UTRAN-Iu +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST +- Assignment completes, triggering CRCX to CN +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN decode: ASSIGNMENT_COMPLETE +DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP:trans-0:call-3:RTP_TO_RAN:no-CI){UNINITIALIZED}: setting remote addr to 1.2.3.4:1234 +DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP:trans-0:call-3:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Not committing: no MGW endpoint CI set up +DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) codecs: :0{AMR:octet-align=1#112} (from: assigned=AMR:octet-align=1#112 remote=10.23.23.1:23{AMR:octet-align=1#112} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} RAN={AMR:octet-align=1#112,AMR-WB/16000:octet-align=1#113}) +DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) Assignment Complete: RAN: VND.3GPP.IUFP/16000#96, CN: AMR:octet-align=1#112 +DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) Assignment complete, but still waiting for the CRCX OK on the CN side RTP +- When the CN side RTP address is known, ack MNCC_RTP_CREATE with full SDP + MGW --CRCX OK to RTP_TO_CN--> MSC +DCC call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){ESTABLISHING}: Received Event CALL_LEG_EV_RTP_STREAM_ADDR_AVAILABLE +DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Received Event MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: MGW endpoint's RTP address available for the CI RTP_TO_CN: 10.23.23.1:23 (osmux=no:-2) +DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) codecs: 10.23.23.1:23{AMR:octet-align=1#112} (from: assigned=AMR:octet-align=1#112 remote=10.23.23.1:23{AMR:octet-align=1#112} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} RAN={AMR:octet-align=1#112,AMR-WB/16000:octet-align=1#113}) +DMNCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) tx MNCC_RTP_CREATE (RTP=10.23.23.1:23{AMR:octet-align=1#112}) + MSC --> MNCC: callref 0x423: MNCC_RTP_CREATE +v=0
+o=OsmoMSC 0 0 IN IP4 10.23.23.1
+s=GSM Call
+c=IN IP4 10.23.23.1
+t=0 0
+m=audio 23 RTP/AVP 112
+a=rtpmap:112 AMR/8000
+a=fmtp:112 octet-align=1
+a=ptime:20
+ - Total time passed: 1.000023 s MSC <--UTRAN-Iu-- MS: GSM48_MT_CC_ALERTING DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms) DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP DRLL msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_ALERTING -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) rx ALERTING in state MO_TERM_CALL_CONF -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) stopping pending timer T310 -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) starting timer T301 with 180 seconds -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) new state MO_TERM_CALL_CONF -> CALL_RECEIVED -DMNCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) tx MNCC_ALERT_IND +DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) rx ALERTING in state MO_TERM_CALL_CONF +DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) stopping pending timer T310 +DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) starting timer T301 with 180 seconds +DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) new state MO_TERM_CALL_CONF -> CALL_RECEIVED +DCC trans(CC:CALL_RECEIVED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) codecs: 10.23.23.1:23{AMR:octet-align=1#112} (from: assigned=AMR:octet-align=1#112 remote=10.23.23.1:23{AMR:octet-align=1#112} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} RAN={AMR:octet-align=1#112,AMR-WB/16000:octet-align=1#113}) +DMNCC trans(CC:CALL_RECEIVED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) tx MNCC_ALERT_IND (RTP=10.23.23.1:23{AMR:octet-align=1#112}) MSC --> MNCC: callref 0x423: MNCC_ALERT_IND +v=0
+o=OsmoMSC 0 0 IN IP4 10.23.23.1
+s=GSM Call
+c=IN IP4 10.23.23.1
+t=0 0
+m=audio 23 RTP/AVP 112
+a=rtpmap:112 AMR/8000
+a=fmtp:112 octet-align=1
+a=ptime:20
+ DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc) - Total time passed: 16.000046 s - The call failed, the BSC sends a BSSMAP Clear Request @@ -1179,22 +1429,30 @@ DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RE DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + msc_a_fsm_releasing_onenter: now used by 4 (attached,CC,active-conn,msc_a_fsm_releasing_onenter) DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + vlr_subscr_cancel_attach_fsm: now used by 5 (attached,CC,active-conn,msc_a_fsm_releasing_onenter,vlr_subscr_cancel_attach_fsm) DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - vlr_subscr_cancel_attach_fsm: now used by 4 (attached,CC,active-conn,msc_a_fsm_releasing_onenter) -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) Freeing transaction -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) stopping pending timer T301 -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) starting timer T308 with 10 seconds -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) new state CALL_RECEIVED -> RELEASE_REQ +DCC trans(CC:CALL_RECEIVED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) Freeing transaction +DCC trans(CC:CALL_RECEIVED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) stopping pending timer T301 +DMNCC trans(CC:CALL_RECEIVED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) tx MNCC_REL_IND + MSC --> MNCC: callref 0x423: MNCC_REL_IND + +DCC trans(CC:CALL_RECEIVED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) starting timer T308 with 10 seconds +DCC trans(CC:CALL_RECEIVED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) new state CALL_RECEIVED -> RELEASE_REQ +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_RELEASING}: Sending DTAP: CC GSM48_MT_CC_RELEASE DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_RELEASING}: RAN encode: DTAP on UTRAN-Iu -- DTAP --UTRAN-Iu--> MS: GSM48_MT_CC_RELEASE: 032d080281af +- DTAP --UTRAN-Iu--> MS: GSM48_MT_CC_RELEASE: 032d0802e1af - DTAP matches expected message DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST -DMNCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) tx MNCC_REL_CNF - MSC --> MNCC: callref 0x423: MNCC_REL_CNF -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) stopping pending timer T308 -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) new state RELEASE_REQ -> NULL +DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) stopping pending timer T308 +DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) new state RELEASE_REQ -> NULL DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - CC: now used by 3 (attached,active-conn,msc_a_fsm_releasing_onenter) DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_RELEASING}: - cc: now used by 0 (-) DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_RELEASING}: Received Event MSC_A_EV_UNUSED DCC call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){ESTABLISHING}: state_chg to RELEASING +DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP:trans-0:call-3:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Terminating (cause = OSMO_FSM_TERM_PARENT) +DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP:trans-0:call-3:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Removing from parent call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP) +DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP:trans-0:call-3:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Deallocated +DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP:trans-0:call-3:RTP_TO_CN:no-CI){UNINITIALIZED}: Terminating (cause = OSMO_FSM_TERM_PARENT) +DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP:trans-0:call-3:RTP_TO_CN:no-CI){UNINITIALIZED}: Removing from parent call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP) +DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP:trans-0:call-3:RTP_TO_CN:no-CI){UNINITIALIZED}: Deallocated DCC call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){RELEASING}: Terminating (cause = OSMO_FSM_TERM_REGULAR) DCC call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){RELEASING}: Removing from parent msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP) DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_RELEASING}: Received Event MSC_EV_CALL_LEG_TERM @@ -1232,9 +1490,6 @@ DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RES DVLR freeing VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 (max total use count was 5) ===== test_call_mt2: SUCCESS -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 17 - ===== test_call_mo_to_unknown - Total time passed: 0.000000 s - Location Update request causes a GSUP Send Auth Info request to HLR @@ -1264,13 +1519,14 @@ DREF VLR subscr IMSI-901700000010650 + active-conn: now used by 2 (_lu_fsm_assoc DMSC msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK DMSC msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH DREF VLR subscr IMSI-901700000010650 - _lu_fsm_associate_vsub: now used by 1 (active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre() DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: Allocated DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU) DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START -GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f00a0101 +GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f02801020a0101 DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI DREF msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: - mm_rx_loc_upd_req: now used by 2 (rx_from_ms,lu) DREF msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu) @@ -1303,7 +1559,7 @@ DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_WAIT_RESP}: A DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU) -DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES +DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_SUCCESS DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth() DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: Set Ciphering Mode DMSC msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: CIPHER_MODE_COMMAND on UTRAN-Iu @@ -1422,11 +1678,11 @@ DMSC msub_fsm{terminating}: Deferring: will deallocate with msc_a(IMSI-901700000 DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){MSC_A_ST_RELEASED}: Deallocated, including all deferred deallocations - msub gone llist_count(&msub_list) == 0 -DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + standard_lu: now used by 2 (attached,standard_lu) +DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + lu_utran_tmsi: now used by 2 (attached,lu_utran_tmsi) vsub != NULL == 1 strcmp(vsub->imsi, IMSI) == 0 LAC == 23 -DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - standard_lu: now used by 1 (attached) +DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - lu_utran_tmsi: now used by 1 (attached) - after a while, a new conn sends a CM Service Request. VLR responds with Auth Req, 2nd auth vector @@ -1511,51 +1767,115 @@ DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE - a call is initiated -- SETUP gets forwarded to MNCC +- CC SETUP causes CRCX towards CN and RAN MSC <--UTRAN-Iu-- MS: GSM48_MT_CC_SETUP DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: + rx_from_ms: now used by 2 (cm_service_cc,rx_from_ms) DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: RAN decode: DTAP DRLL msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: Dispatching 04.08 message: CC GSM48_MT_CC_SETUP DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + CC: now used by 3 (attached,active-conn,CC) -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 callref-0x80000002 tid-8) New transaction +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 callref-0x80000002 tid-8) New transaction DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: Received Event MSC_A_EV_TRANSACTION_ACCEPTED DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: state_chg to MSC_A_ST_COMMUNICATING DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: + cc: now used by 3 (cm_service_cc,rx_from_ms,cc) DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - cm_service_cc: now used by 2 (rx_from_ms,cc) -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000002 tid-8) rx SETUP in state NULL -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000002 tid-8) starting guard timer with 180 seconds -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000002 tid-8) new state NULL -> INITIATED -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000002 tid-8) SETUP to 123 -DMNCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000002 tid-8) tx MNCC_SETUP_IND - MSC --> MNCC: callref 0x80000002: MNCC_SETUP_IND +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000002 tid-8) rx SETUP in state NULL +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000002 tid-8) starting guard timer with 180 seconds +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000002 tid-8) codecs: :0{AMR:octet-align=1#112} (from: MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} RAN={AMR:octet-align=1#112,AMR-WB/16000:octet-align=1#113}) +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000002 tid-8) SETUP to 123 +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000002 tid-8) new state NULL -> INITIATED +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Starting call assignment +DCC call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){ESTABLISHING}: Allocated +DCC call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){ESTABLISHING}: is child of msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ) +DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000002 tid-8) codecs: :0{AMR:octet-align=1#112} (from: MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} RAN={AMR:octet-align=1#112,AMR-WB/16000:octet-align=1#113}) + MGW <--CRCX to RTP_TO_CN-- MSC: call_id=0x4 codecs=AMR:octet-align=1#112 +DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){UNINITIALIZED}: Allocated +DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){UNINITIALIZED}: is child of call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ) +DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ:trans-8:call-4:RTP_TO_CN:no-CI){UNINITIALIZED}: setting codecs to AMR:octet-align=1#112 + MGW <--CRCX to RTP_TO_RAN-- MSC: call_id=0x4 codecs=VND.3GPP.IUFP/16000#96 +DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){UNINITIALIZED}: Allocated +DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){UNINITIALIZED}: is child of call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ) +DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ:trans-8:call-4:RTP_TO_RAN:no-CI){UNINITIALIZED}: setting codecs to VND.3GPP.IUFP/16000#96 DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc) +- As soon as the MGW port towards CN is created, MNCC_SETUP_IND is triggered + MGW --CRCX OK to RTP_TO_CN--> MSC +DCC call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){ESTABLISHING}: Received Event CALL_LEG_EV_RTP_STREAM_ADDR_AVAILABLE +DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Received Event MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: MGW endpoint's RTP address available for the CI RTP_TO_CN: 10.23.23.1:23 (osmux=no:-2) +DMNCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000002 tid-8) tx MNCC_SETUP_IND (RTP=10.23.23.1:23{AMR:octet-align=1#112}) + MSC --> MNCC: callref 0x80000002: MNCC_SETUP_IND +v=0
+o=OsmoMSC 0 0 IN IP4 10.23.23.1
+s=GSM Call
+c=IN IP4 10.23.23.1
+t=0 0
+m=audio 23 RTP/AVP 112
+a=rtpmap:112 AMR/8000
+a=fmtp:112 octet-align=1
+a=ptime:20
+ +- MNCC replies with MNCC_RTP_CREATE + MSC <-- MNCC: callref 0x80000002: MNCC_RTP_CREATE + +DMNCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000002 tid-8) rx MNCC_RTP_CREATE +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Assignment for this trans already started earlier +- MGW acknowledges the CRCX, triggering Assignment + MGW --CRCX OK to RTP_TO_RAN--> MSC +DCC call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){ESTABLISHING}: Received Event CALL_LEG_EV_RTP_STREAM_ADDR_AVAILABLE +DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Received Event MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: MGW endpoint's RTP address available for the CI RTP_TO_RAN: 10.23.23.1:23 (osmux=no:-2) +DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000002 tid-8) codecs: 10.23.23.1:23{AMR:octet-align=1#112} (from: MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} RAN={AMR:octet-align=1#112,AMR-WB/16000:octet-align=1#113}) +DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000002 tid-8) Sending Assignment Command +DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN encode: ASSIGNMENT_COMMAND on UTRAN-Iu +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST +- Assignment succeeds, triggering MNCC_RTP_CREATE ack to MNCC +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN decode: ASSIGNMENT_COMPLETE +DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ:trans-8:call-4:RTP_TO_RAN:no-CI){UNINITIALIZED}: setting remote addr to 1.2.3.4:1234 +DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ:trans-8:call-4:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Not committing: no MGW endpoint CI set up +DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000002 tid-8) codecs: 10.23.23.1:23{AMR:octet-align=1#112} (from: assigned=AMR:octet-align=1#112 MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} RAN={AMR:octet-align=1#112,AMR-WB/16000:octet-align=1#113}) +DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000002 tid-8) Assignment Complete: RAN: VND.3GPP.IUFP/16000#96, CN: AMR:octet-align=1#112 +DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000002 tid-8) codecs: 10.23.23.1:23{AMR:octet-align=1#112} (from: assigned=AMR:octet-align=1#112 MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} RAN={AMR:octet-align=1#112,AMR-WB/16000:octet-align=1#113}) +DMNCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000002 tid-8) tx MNCC_RTP_CREATE (RTP=10.23.23.1:23{AMR:octet-align=1#112}) + MSC --> MNCC: callref 0x80000002: MNCC_RTP_CREATE +v=0
+o=OsmoMSC 0 0 IN IP4 10.23.23.1
+s=GSM Call
+c=IN IP4 10.23.23.1
+t=0 0
+m=audio 23 RTP/AVP 112
+a=rtpmap:112 AMR/8000
+a=fmtp:112 octet-align=1
+a=ptime:20
+ - MNCC says that's fine -DMNCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000002 tid-8) rx MNCC_CALL_PROC_REQ -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000002 tid-8) stopping pending guard timer -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000002 tid-8) starting guard timer with 180 seconds -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000002 tid-8) rx MNCC_CALL_PROC_REQ in state INITIATED -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000002 tid-8) new state INITIATED -> MO_CALL_PROC + MSC <-- MNCC: callref 0x80000002: MNCC_CALL_PROC_REQ + +DMNCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000002 tid-8) rx MNCC_CALL_PROC_REQ +DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000002 tid-8) stopping pending guard timer +DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000002 tid-8) starting guard timer with 180 seconds +DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000002 tid-8) new state INITIATED -> MO_CALL_PROC +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_CALL_PROC DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on UTRAN-Iu - DTAP --UTRAN-Iu--> MS: GSM48_MT_CC_CALL_PROC: 8302 - DTAP matches expected message DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST -DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Starting call assignment -DCC call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){ESTABLISHING}: Allocated -DCC call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){ESTABLISHING}: is child of msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ) - MS <--Call Assignment-- MSC: callref=0x80000002 +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Assignment for this trans already started earlier - But the other side's MSISDN could not be resolved, MNCC tells us to cancel -DMNCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000002 tid-8) rx MNCC_REL_REQ -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000002 tid-8) stopping pending guard timer -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000002 tid-8) starting guard timer with 180 seconds -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000002 tid-8) rx MNCC_REL_REQ in state MO_CALL_PROC -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000002 tid-8) starting timer T308 with 10 seconds -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000002 tid-8) new state MO_CALL_PROC -> RELEASE_REQ + MSC <-- MNCC: callref 0x80000002: MNCC_REL_REQ + +DMNCC trans(CC:MO_CALL_PROC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000002 tid-8) rx MNCC_REL_REQ +DCC trans(CC:MO_CALL_PROC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000002 tid-8) stopping pending guard timer +DCC trans(CC:MO_CALL_PROC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000002 tid-8) starting guard timer with 180 seconds +DCC trans(CC:MO_CALL_PROC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000002 tid-8) starting timer T308 with 10 seconds +DCC trans(CC:MO_CALL_PROC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000002 tid-8) new state MO_CALL_PROC -> RELEASE_REQ +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_RELEASE DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on UTRAN-Iu - DTAP --UTRAN-Iu--> MS: GSM48_MT_CC_RELEASE: 832d - DTAP matches expected message DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST - Total time passed: 10.000023 s -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000002 tid-8) starting timer T308 with 10 seconds +DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000002 tid-8) Timeout of T308 +DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000002 tid-8) starting timer T308 with 10 seconds +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_RELEASE DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on UTRAN-Iu - DTAP --UTRAN-Iu--> MS: GSM48_MT_CC_RELEASE: 832d - DTAP matches expected message @@ -1564,13 +1884,14 @@ DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_S DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms) DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP DRLL msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_RELEASE_COMPL -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000002 tid-8) rx RELEASE_COMPL in state RELEASE_REQ -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000002 tid-8) stopping pending timer T308 -DMNCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000002 tid-8) tx MNCC_REL_CNF +DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000002 tid-8) rx RELEASE_COMPL in state RELEASE_REQ +DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000002 tid-8) stopping pending timer T308 +DMNCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000002 tid-8) tx MNCC_REL_CNF MSC --> MNCC: callref 0x80000002: MNCC_REL_CNF -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x0 tid-8) Freeing transaction -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x0 tid-8) new state RELEASE_REQ -> NULL -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x0 tid-8) stopping pending guard timer + +DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x0 tid-8) Freeing transaction +DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x0 tid-8) new state RELEASE_REQ -> NULL +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x0 tid-8) stopping pending guard timer DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - CC: now used by 2 (attached,active-conn) DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - cc: now used by 1 (rx_from_ms) DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 0 (-) @@ -1581,6 +1902,12 @@ DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + msc_a_fsm_re DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,active-conn,msc_a_fsm_releasing_onenter,vlr_subscr_cancel_attach_fsm) DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,active-conn,msc_a_fsm_releasing_onenter) DCC call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){ESTABLISHING}: state_chg to RELEASING +DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ:trans-8:call-4:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Terminating (cause = OSMO_FSM_TERM_PARENT) +DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ:trans-8:call-4:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Removing from parent call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ) +DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ:trans-8:call-4:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Deallocated +DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ:trans-8:call-4:RTP_TO_CN:no-CI){UNINITIALIZED}: Terminating (cause = OSMO_FSM_TERM_PARENT) +DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ:trans-8:call-4:RTP_TO_CN:no-CI){UNINITIALIZED}: Removing from parent call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ) +DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ:trans-8:call-4:RTP_TO_CN:no-CI){UNINITIALIZED}: Deallocated DCC call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){RELEASING}: Terminating (cause = OSMO_FSM_TERM_REGULAR) DCC call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){RELEASING}: Removing from parent msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ) DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: Received Event MSC_EV_CALL_LEG_TERM @@ -1617,9 +1944,6 @@ DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE DVLR freeing VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 (max total use count was 4) ===== test_call_mo_to_unknown: SUCCESS -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 17 - ===== test_call_mo_to_unknown_timeout - Total time passed: 0.000000 s - Location Update request causes a GSUP Send Auth Info request to HLR @@ -1649,13 +1973,14 @@ DREF VLR subscr IMSI-901700000010650 + active-conn: now used by 2 (_lu_fsm_assoc DMSC msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK DMSC msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH DREF VLR subscr IMSI-901700000010650 - _lu_fsm_associate_vsub: now used by 1 (active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre() DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: Allocated DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU) DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START -GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f00a0101 +GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f02801020a0101 DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI DREF msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: - mm_rx_loc_upd_req: now used by 2 (rx_from_ms,lu) DREF msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu) @@ -1688,7 +2013,7 @@ DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_WAIT_RESP}: A DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU) -DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES +DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_SUCCESS DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth() DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: Set Ciphering Mode DMSC msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: CIPHER_MODE_COMMAND on UTRAN-Iu @@ -1807,11 +2132,11 @@ DMSC msub_fsm{terminating}: Deferring: will deallocate with msc_a(IMSI-901700000 DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){MSC_A_ST_RELEASED}: Deallocated, including all deferred deallocations - msub gone llist_count(&msub_list) == 0 -DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + standard_lu: now used by 2 (attached,standard_lu) +DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + lu_utran_tmsi: now used by 2 (attached,lu_utran_tmsi) vsub != NULL == 1 strcmp(vsub->imsi, IMSI) == 0 LAC == 23 -DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - standard_lu: now used by 1 (attached) +DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - lu_utran_tmsi: now used by 1 (attached) - after a while, a new conn sends a CM Service Request. VLR responds with Auth Req, 2nd auth vector @@ -1896,63 +2221,129 @@ DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE - a call is initiated -- SETUP gets forwarded to MNCC +- CC SETUP causes CRCX towards CN and RAN MSC <--UTRAN-Iu-- MS: GSM48_MT_CC_SETUP DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: + rx_from_ms: now used by 2 (cm_service_cc,rx_from_ms) DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: RAN decode: DTAP DRLL msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: Dispatching 04.08 message: CC GSM48_MT_CC_SETUP DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + CC: now used by 3 (attached,active-conn,CC) -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 callref-0x80000003 tid-8) New transaction +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 callref-0x80000003 tid-8) New transaction DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: Received Event MSC_A_EV_TRANSACTION_ACCEPTED DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: state_chg to MSC_A_ST_COMMUNICATING DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: + cc: now used by 3 (cm_service_cc,rx_from_ms,cc) DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - cm_service_cc: now used by 2 (rx_from_ms,cc) -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000003 tid-8) rx SETUP in state NULL -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000003 tid-8) starting guard timer with 180 seconds -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000003 tid-8) new state NULL -> INITIATED -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000003 tid-8) SETUP to 123 -DMNCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000003 tid-8) tx MNCC_SETUP_IND - MSC --> MNCC: callref 0x80000003: MNCC_SETUP_IND +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000003 tid-8) rx SETUP in state NULL +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000003 tid-8) starting guard timer with 180 seconds +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000003 tid-8) codecs: :0{AMR:octet-align=1#112} (from: MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} RAN={AMR:octet-align=1#112,AMR-WB/16000:octet-align=1#113}) +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000003 tid-8) SETUP to 123 +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000003 tid-8) new state NULL -> INITIATED +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Starting call assignment +DCC call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){ESTABLISHING}: Allocated +DCC call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){ESTABLISHING}: is child of msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ) +DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000003 tid-8) codecs: :0{AMR:octet-align=1#112} (from: MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} RAN={AMR:octet-align=1#112,AMR-WB/16000:octet-align=1#113}) + MGW <--CRCX to RTP_TO_CN-- MSC: call_id=0x5 codecs=AMR:octet-align=1#112 +DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){UNINITIALIZED}: Allocated +DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){UNINITIALIZED}: is child of call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ) +DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ:trans-8:call-5:RTP_TO_CN:no-CI){UNINITIALIZED}: setting codecs to AMR:octet-align=1#112 + MGW <--CRCX to RTP_TO_RAN-- MSC: call_id=0x5 codecs=VND.3GPP.IUFP/16000#96 +DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){UNINITIALIZED}: Allocated +DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){UNINITIALIZED}: is child of call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ) +DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ:trans-8:call-5:RTP_TO_RAN:no-CI){UNINITIALIZED}: setting codecs to VND.3GPP.IUFP/16000#96 DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc) +- As soon as the MGW port towards CN is created, MNCC_SETUP_IND is triggered + MGW --CRCX OK to RTP_TO_CN--> MSC +DCC call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){ESTABLISHING}: Received Event CALL_LEG_EV_RTP_STREAM_ADDR_AVAILABLE +DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Received Event MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: MGW endpoint's RTP address available for the CI RTP_TO_CN: 10.23.23.1:23 (osmux=no:-2) +DMNCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000003 tid-8) tx MNCC_SETUP_IND (RTP=10.23.23.1:23{AMR:octet-align=1#112}) + MSC --> MNCC: callref 0x80000003: MNCC_SETUP_IND +v=0
+o=OsmoMSC 0 0 IN IP4 10.23.23.1
+s=GSM Call
+c=IN IP4 10.23.23.1
+t=0 0
+m=audio 23 RTP/AVP 112
+a=rtpmap:112 AMR/8000
+a=fmtp:112 octet-align=1
+a=ptime:20
+ +- MNCC replies with MNCC_RTP_CREATE + MSC <-- MNCC: callref 0x80000003: MNCC_RTP_CREATE + +DMNCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000003 tid-8) rx MNCC_RTP_CREATE +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Assignment for this trans already started earlier +- MGW acknowledges the CRCX, triggering Assignment + MGW --CRCX OK to RTP_TO_RAN--> MSC +DCC call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){ESTABLISHING}: Received Event CALL_LEG_EV_RTP_STREAM_ADDR_AVAILABLE +DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Received Event MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: MGW endpoint's RTP address available for the CI RTP_TO_RAN: 10.23.23.1:23 (osmux=no:-2) +DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000003 tid-8) codecs: 10.23.23.1:23{AMR:octet-align=1#112} (from: MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} RAN={AMR:octet-align=1#112,AMR-WB/16000:octet-align=1#113}) +DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000003 tid-8) Sending Assignment Command +DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN encode: ASSIGNMENT_COMMAND on UTRAN-Iu +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST +- Assignment succeeds, triggering MNCC_RTP_CREATE ack to MNCC +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN decode: ASSIGNMENT_COMPLETE +DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ:trans-8:call-5:RTP_TO_RAN:no-CI){UNINITIALIZED}: setting remote addr to 1.2.3.4:1234 +DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ:trans-8:call-5:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Not committing: no MGW endpoint CI set up +DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000003 tid-8) codecs: 10.23.23.1:23{AMR:octet-align=1#112} (from: assigned=AMR:octet-align=1#112 MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} RAN={AMR:octet-align=1#112,AMR-WB/16000:octet-align=1#113}) +DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000003 tid-8) Assignment Complete: RAN: VND.3GPP.IUFP/16000#96, CN: AMR:octet-align=1#112 +DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000003 tid-8) codecs: 10.23.23.1:23{AMR:octet-align=1#112} (from: assigned=AMR:octet-align=1#112 MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} RAN={AMR:octet-align=1#112,AMR-WB/16000:octet-align=1#113}) +DMNCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000003 tid-8) tx MNCC_RTP_CREATE (RTP=10.23.23.1:23{AMR:octet-align=1#112}) + MSC --> MNCC: callref 0x80000003: MNCC_RTP_CREATE +v=0
+o=OsmoMSC 0 0 IN IP4 10.23.23.1
+s=GSM Call
+c=IN IP4 10.23.23.1
+t=0 0
+m=audio 23 RTP/AVP 112
+a=rtpmap:112 AMR/8000
+a=fmtp:112 octet-align=1
+a=ptime:20
+ - MNCC says that's fine -DMNCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000003 tid-8) rx MNCC_CALL_PROC_REQ -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000003 tid-8) stopping pending guard timer -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000003 tid-8) starting guard timer with 180 seconds -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000003 tid-8) rx MNCC_CALL_PROC_REQ in state INITIATED -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000003 tid-8) new state INITIATED -> MO_CALL_PROC + MSC <-- MNCC: callref 0x80000003: MNCC_CALL_PROC_REQ + +DMNCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000003 tid-8) rx MNCC_CALL_PROC_REQ +DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000003 tid-8) stopping pending guard timer +DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000003 tid-8) starting guard timer with 180 seconds +DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000003 tid-8) new state INITIATED -> MO_CALL_PROC +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_CALL_PROC DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on UTRAN-Iu - DTAP --UTRAN-Iu--> MS: GSM48_MT_CC_CALL_PROC: 8302 - DTAP matches expected message DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST -DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Starting call assignment -DCC call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){ESTABLISHING}: Allocated -DCC call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){ESTABLISHING}: is child of msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ) - MS <--Call Assignment-- MSC: callref=0x80000003 +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Assignment for this trans already started earlier - But the other side's MSISDN could not be resolved, MNCC tells us to cancel -DMNCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000003 tid-8) rx MNCC_REL_REQ -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000003 tid-8) stopping pending guard timer -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000003 tid-8) starting guard timer with 180 seconds -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000003 tid-8) rx MNCC_REL_REQ in state MO_CALL_PROC -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000003 tid-8) starting timer T308 with 10 seconds -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000003 tid-8) new state MO_CALL_PROC -> RELEASE_REQ + MSC <-- MNCC: callref 0x80000003: MNCC_REL_REQ + +DMNCC trans(CC:MO_CALL_PROC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000003 tid-8) rx MNCC_REL_REQ +DCC trans(CC:MO_CALL_PROC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000003 tid-8) stopping pending guard timer +DCC trans(CC:MO_CALL_PROC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000003 tid-8) starting guard timer with 180 seconds +DCC trans(CC:MO_CALL_PROC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000003 tid-8) starting timer T308 with 10 seconds +DCC trans(CC:MO_CALL_PROC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000003 tid-8) new state MO_CALL_PROC -> RELEASE_REQ +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_RELEASE DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on UTRAN-Iu - DTAP --UTRAN-Iu--> MS: GSM48_MT_CC_RELEASE: 832d - DTAP matches expected message DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST - Despite our repeated CC Release Requests, the MS does not respond anymore - Total time passed: 10.000023 s -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000003 tid-8) starting timer T308 with 10 seconds +DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000003 tid-8) Timeout of T308 +DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000003 tid-8) starting timer T308 with 10 seconds +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_RELEASE DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on UTRAN-Iu - DTAP --UTRAN-Iu--> MS: GSM48_MT_CC_RELEASE: 832d - DTAP matches expected message DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST - The CC Release times out and we still properly clear the conn - Total time passed: 20.000046 s -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000003 tid-8) Freeing transaction -DMNCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000003 tid-8) tx MNCC_REL_CNF +DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000003 tid-8) Timeout of T308 +DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000003 tid-8) Freeing transaction +DMNCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000003 tid-8) tx MNCC_REL_CNF MSC --> MNCC: callref 0x80000003: MNCC_REL_CNF -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000003 tid-8) new state RELEASE_REQ -> NULL -DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000003 tid-8) stopping pending guard timer + +DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000003 tid-8) new state RELEASE_REQ -> NULL +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000003 tid-8) stopping pending guard timer DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - CC: now used by 2 (attached,active-conn) DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - cc: now used by 0 (-) DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Received Event MSC_A_EV_UNUSED @@ -1962,6 +2353,12 @@ DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + msc_a_fsm_re DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,active-conn,msc_a_fsm_releasing_onenter,vlr_subscr_cancel_attach_fsm) DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,active-conn,msc_a_fsm_releasing_onenter) DCC call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){ESTABLISHING}: state_chg to RELEASING +DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ:trans-8:call-5:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Terminating (cause = OSMO_FSM_TERM_PARENT) +DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ:trans-8:call-5:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Removing from parent call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ) +DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ:trans-8:call-5:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Deallocated +DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ:trans-8:call-5:RTP_TO_CN:no-CI){UNINITIALIZED}: Terminating (cause = OSMO_FSM_TERM_PARENT) +DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ:trans-8:call-5:RTP_TO_CN:no-CI){UNINITIALIZED}: Removing from parent call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ) +DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ:trans-8:call-5:RTP_TO_CN:no-CI){UNINITIALIZED}: Deallocated DCC call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){RELEASING}: Terminating (cause = OSMO_FSM_TERM_REGULAR) DCC call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){RELEASING}: Removing from parent msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ) DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: Received Event MSC_EV_CALL_LEG_TERM @@ -1998,9 +2395,4513 @@ DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE DVLR freeing VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 (max total use count was 4) ===== test_call_mo_to_unknown_timeout: SUCCESS -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 17 +===== test_codecs +- Total time passed: 0.000000 s +- Location Update request causes a GSUP LU request to HLR + MSC <--GERAN-A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST + new conn +DMSC msub_fsm{active}: Allocated +DMSC msc_a{MSC_A_ST_VALIDATE_L3}: Allocated +DMSC msc_a{MSC_A_ST_VALIDATE_L3}: is child of msub_fsm +DMSC msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_VALIDATE_L3 +DMSC dummy_msc_i{0}: Allocated +DMSC dummy_msc_i{0}: is child of msub_fsm +DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms) +DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3 +DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: MM GSM48_MT_MM_LOC_UPD_REQUEST +DMM msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: LOCATION UPDATING REQUEST: MI=IMSI-901700000010650 LU-type=NORMAL +DMM msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: USIM: old LAI: 901-70-23 +DREF msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: + mm_rx_loc_upd_req: now used by 2 (rx_from_ms,mm_rx_loc_upd_req) +DREF msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: + lu: now used by 3 (rx_from_ms,mm_rx_loc_upd_req,lu) +DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_IDLE}: Allocated +DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_IDLE}: is child of msc_a(IMSI-901700000010650:GERAN-A:LU) +DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_IDLE}: rev=R99 net=GERAN (no Auth) +DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA +DREF VLR subscr unknown + _lu_fsm_associate_vsub: now used by 1 (_lu_fsm_associate_vsub) +DVLR set IMSI on subscriber; IMSI=901700000010650 id=901700000010650 +DVLR New subscr, IMSI: 901700000010650 +DREF VLR subscr IMSI-901700000010650 + active-conn: now used by 2 (_lu_fsm_associate_vsub,active-conn) +DMSC msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK +DMSC msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH +DREF VLR subscr IMSI-901700000010650 - _lu_fsm_associate_vsub: now used by 1 (active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) +DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre() +DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() +DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_post_auth() +DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_post_ciph() +DMSC msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(IMSI-901700000010650:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST +DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node_4() +DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_HLR_UPD +DVLR upd_hlr_vlr_fsm(IMSI-901700000010650:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated +DVLR upd_hlr_vlr_fsm(IMSI-901700000010650:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU) +DVLR upd_hlr_vlr_fsm(IMSI-901700000010650:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START +GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000000156f02801020a0101 +DVLR upd_hlr_vlr_fsm(IMSI-901700000010650:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA +DREF msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - mm_rx_loc_upd_req: now used by 2 (rx_from_ms,lu) +DREF msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu) + lu_result_sent == 0 +- HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT +<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: 10010809710000000156f00804036470f10a0101 +DREF VLR subscr IMSI-901700000010650 + vlr_gsup_rx: now used by 2 (active-conn,vlr_gsup_rx) +DVLR IMSI:901700000010650 has MSISDN:46071 +DVLR SUBSCR(IMSI-901700000010650:MSISDN-46071) VLR: update for IMSI=901700000010650 (MSISDN=46071) +GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000000156f00a0101 +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - vlr_gsup_rx: now used by 1 (active-conn) +<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: vlr_gsupc_read_cb() returns 0 + lu_result_sent == 0 +- HLR also sends GSUP _UPDATE_LOCATION_RESULT +<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: 06010809710000000156f00a0101 +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + vlr_gsup_rx: now used by 2 (active-conn,vlr_gsup_rx) +DVLR vlr_lu_fsm(IMSI-901700000010650:MSISDN-46071:GERAN-A:LU){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES +DVLR upd_hlr_vlr_fsm(IMSI-901700000010650:GERAN-A:LU){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK +DVLR upd_hlr_vlr_fsm(IMSI-901700000010650:GERAN-A:LU){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE +DVLR upd_hlr_vlr_fsm(IMSI-901700000010650:GERAN-A:LU){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR) +DVLR upd_hlr_vlr_fsm(IMSI-901700000010650:GERAN-A:LU){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(IMSI-901700000010650:MSISDN-46071:GERAN-A:LU) +DVLR vlr_lu_fsm(IMSI-901700000010650:MSISDN-46071:GERAN-A:LU){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL +DVLR vlr_lu_fsm(IMSI-901700000010650:MSISDN-46071:GERAN-A:LU){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL +DVLR lu_compl_vlr_fsm(IMSI-901700000010650:MSISDN-46071:GERAN-A:LU){LU_COMPL_VLR_S_INIT}: Allocated +DVLR lu_compl_vlr_fsm(IMSI-901700000010650:MSISDN-46071:GERAN-A:LU){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(IMSI-901700000010650:MSISDN-46071:GERAN-A:LU) +DVLR lu_compl_vlr_fsm(IMSI-901700000010650:MSISDN-46071:GERAN-A:LU){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START +DVLR lu_compl_vlr_fsm(IMSI-901700000010650:MSISDN-46071:GERAN-A:LU){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES +DVLR lu_compl_vlr_fsm(IMSI-901700000010650:MSISDN-46071:GERAN-A:LU){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL +- sending LU Accept for IMSI-901700000010650:MSISDN-46071:GERAN-A:LU +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + attached: now used by 3 (active-conn,vlr_gsup_rx,attached) +DVLR lu_compl_vlr_fsm(IMSI-901700000010650:MSISDN-46071:GERAN-A:LU){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_DONE +DVLR vlr_lu_fsm(IMSI-901700000010650:MSISDN-46071:GERAN-A:LU){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS +DVLR lu_compl_vlr_fsm(IMSI-901700000010650:MSISDN-46071:GERAN-A:LU){LU_COMPL_VLR_S_DONE}: Terminating in cascade, depth 2 (cause = OSMO_FSM_TERM_PARENT, caused by: upd_hlr_vlr_fsm(IMSI-901700000010650:GERAN-A:LU)) +DVLR lu_compl_vlr_fsm(IMSI-901700000010650:MSISDN-46071:GERAN-A:LU){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(IMSI-901700000010650:MSISDN-46071:GERAN-A:LU) +DVLR lu_compl_vlr_fsm(IMSI-901700000010650:MSISDN-46071:GERAN-A:LU){LU_COMPL_VLR_S_DONE}: Deferring: will deallocate with upd_hlr_vlr_fsm(IMSI-901700000010650:GERAN-A:LU) +DVLR vlr_lu_fsm(IMSI-901700000010650:MSISDN-46071:GERAN-A:LU){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: Received Event MSC_A_EV_AUTHENTICATED +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: state_chg to MSC_A_ST_AUTHENTICATED +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTHENTICATED}: - lu: now used by 0 (-) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTHENTICATED}: Received Event MSC_A_EV_UNUSED +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTHENTICATED}: state_chg to MSC_A_ST_RELEASING +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:LU){MSC_A_ST_RELEASING}: Releasing: msc_a use is 0 (-) +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + msc_a_fsm_releasing_onenter: now used by 4 (active-conn,vlr_gsup_rx,attached,msc_a_fsm_releasing_onenter) +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + vlr_subscr_cancel_attach_fsm: now used by 5 (active-conn,vlr_gsup_rx,attached,msc_a_fsm_releasing_onenter,vlr_subscr_cancel_attach_fsm) +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - vlr_subscr_cancel_attach_fsm: now used by 4 (active-conn,vlr_gsup_rx,attached,msc_a_fsm_releasing_onenter) +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:LU){MSC_A_ST_RELEASING}: + wait-Clear-Complete: now used by 1 (wait-Clear-Complete) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:LU){MSC_A_ST_RELEASING}: RAN encode: CLEAR_COMMAND on GERAN-A +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - msc_a_fsm_releasing_onenter: now used by 3 (active-conn,vlr_gsup_rx,attached) +DVLR upd_hlr_vlr_fsm(IMSI-901700000010650:GERAN-A:LU){UPD_HLR_VLR_S_DONE}: Deallocated, including all deferred deallocations +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - vlr_gsup_rx: now used by 2 (active-conn,attached) +<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: vlr_gsupc_read_cb() returns 0 +- LU was successful, and the conn has already been closed + lu_result_sent == 1 + bssap_clear_sent == 1 +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:LU){MSC_A_ST_RELEASING}: RAN decode: CLEAR_COMPLETE +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:LU){MSC_A_ST_RELEASING}: - wait-Clear-Complete: now used by 0 (-) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:LU){MSC_A_ST_RELEASING}: Received Event MSC_A_EV_UNUSED +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:LU){MSC_A_ST_RELEASING}: state_chg to MSC_A_ST_RELEASED +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:LU){MSC_A_ST_RELEASED}: Released: msc_a use is 0 (-) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:LU){MSC_A_ST_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) +DVLR vlr_lu_fsm(IMSI-901700000010650:MSISDN-46071:GERAN-A:LU){VLR_ULA_S_DONE}: Terminating in cascade, depth 2 (cause = OSMO_FSM_TERM_PARENT, caused by: msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:LU)) +DVLR vlr_lu_fsm(IMSI-901700000010650:MSISDN-46071:GERAN-A:LU){VLR_ULA_S_DONE}: Removing from parent msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:LU) +DVLR vlr_lu_fsm(IMSI-901700000010650:MSISDN-46071:GERAN-A:LU){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT +DVLR vlr_lu_fsm(IMSI-901700000010650:MSISDN-46071:GERAN-A:LU){VLR_ULA_S_DONE}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:LU) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:LU){MSC_A_ST_RELEASED}: Removing from parent msub_fsm +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:LU){MSC_A_ST_RELEASED}: max total use count was 3 +DMSC msub_fsm{active}: Received Event MSUB_EV_ROLE_TERMINATED +DMSC msub(IMSI-901700000010650:MSISDN-46071) MSC-A terminated +DMSC msub(IMSI-901700000010650:MSISDN-46071) 1 MSC-I still active +DMSC msub_fsm{active}: state_chg to terminating +DMSC msub_fsm{terminating}: Terminating in cascade, depth 2 (cause = OSMO_FSM_TERM_REGULAR, caused by: msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:LU)) +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:LU){0}: Terminating in cascade, depth 3 (cause = OSMO_FSM_TERM_PARENT, caused by: msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:LU)) +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:LU){0}: Removing from parent msub_fsm +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:LU){0}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:LU) +DMSC msub(IMSI-901700000010650:MSISDN-46071) Free +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - active-conn: now used by 1 (attached) +DMSC msub_fsm{terminating}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:LU) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:LU){MSC_A_ST_RELEASED}: Deallocated, including all deferred deallocations +- msub gone + llist_count(&msub_list) == 0 + + +- ======================== MO call: AMR picked by both MO and MT +- CM Service Request with Codec List (BSS Supported) = FR1 FR2 FR3 HR1 HR3 + MSC <--GERAN-A-- MS: GSM48_MT_MM_CM_SERV_REQ + new conn +DMSC msub_fsm{active}: Allocated +DMSC msc_a{MSC_A_ST_VALIDATE_L3}: Allocated +DMSC msc_a{MSC_A_ST_VALIDATE_L3}: is child of msub_fsm +DMSC msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_VALIDATE_L3 +DMSC dummy_msc_i{0}: Allocated +DMSC dummy_msc_i{0}: is child of msub_fsm +DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms) +DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3 +DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Complete Layer 3: Codec List (BSS Supported): GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111 +DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: MM GSM48_MT_MM_CM_SERV_REQ +DMM msc_a(IMSI-901700000010650:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_VALIDATE_L3}: Rx CM SERVICE REQUEST cm_service_type=MO-Call +DREF msc_a(IMSI-901700000010650:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_VALIDATE_L3}: + cm_service_cc: now used by 2 (rx_from_ms,cm_service_cc) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: Allocated +DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: is child of msc_a(IMSI-901700000010650:GERAN-A:CM_SERVICE_REQ) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: rev=R99 net=GERAN (no Auth) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + proc_arq_vlr_fn_init: now used by 2 (attached,proc_arq_vlr_fn_init) +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + active-conn: now used by 3 (attached,proc_arq_vlr_fn_init,active-conn) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi() +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_node2() +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_ciph() +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_vlr() +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_post_pres() +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_post_trace() +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_post_imei() +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: proc_arq_fsm_done(PASSED) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_DONE +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_DONE}: Process Access Request result: PASSED +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: Sending DTAP: MM GSM48_MT_MM_CM_SERV_ACC +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN encode: DTAP on GERAN-A +- DTAP --GERAN-A--> MS: GSM48_MT_MM_CM_SERV_ACC: 0521 +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: Received Event MSC_A_EV_AUTHENTICATED +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: state_chg to MSC_A_ST_AUTHENTICATED +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - proc_arq_vlr_fn_init: now used by 2 (attached,active-conn) +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: - rx_from_ms: now used by 1 (cm_service_cc) + cm_service_result_sent == 1 +msc_a_is_accepted() == true +- MS sends CC SETUP with Bearer Capability = AMR AMR AMR GSM-EFR GSM GSM-HR-08 + MSC <--GERAN-A-- MS: GSM48_MT_CC_SETUP +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: + rx_from_ms: now used by 2 (cm_service_cc,rx_from_ms) +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: RAN decode: DTAP +DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: Dispatching 04.08 message: CC GSM48_MT_CC_SETUP +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + CC: now used by 3 (attached,active-conn,CC) +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071 callref-0x80000004 tid-8) New transaction +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: Received Event MSC_A_EV_TRANSACTION_ACCEPTED +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: state_chg to MSC_A_ST_COMMUNICATING +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: + cc: now used by 3 (cm_service_cc,rx_from_ms,cc) +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - cm_service_cc: now used by 2 (rx_from_ms,cc) +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000004 tid-8) rx SETUP in state NULL +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000004 tid-8) starting guard timer with 180 seconds +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000004 tid-8) codecs: :0{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} (from: MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000004 tid-8) SETUP to 123 +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000004 tid-8) new state NULL -> INITIATED +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Starting call assignment +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){ESTABLISHING}: Allocated +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){ESTABLISHING}: is child of msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ) +DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000004 tid-8) codecs: :0{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} (from: MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) + MGW <--CRCX to RTP_TO_CN-- MSC: call_id=0x6 codecs=AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111 +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){UNINITIALIZED}: Allocated +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){UNINITIALIZED}: is child of call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ) +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-6:RTP_TO_CN:no-CI){UNINITIALIZED}: setting codecs to AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111 + MGW <--CRCX to RTP_TO_RAN-- MSC: call_id=0x6 codecs=AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111 +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){UNINITIALIZED}: Allocated +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){UNINITIALIZED}: is child of call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ) +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-6:RTP_TO_RAN:no-CI){UNINITIALIZED}: setting codecs to AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111 +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc) +- As soon as the MGW port towards CN is created, MNCC_SETUP_IND is triggered + MGW --CRCX OK to RTP_TO_CN--> MSC +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){ESTABLISHING}: Received Event CALL_LEG_EV_RTP_STREAM_ADDR_AVAILABLE +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Received Event MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: MGW endpoint's RTP address available for the CI RTP_TO_CN: 10.23.23.1:23 (osmux=no:-2) +DMNCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000004 tid-8) tx MNCC_SETUP_IND (RTP=10.23.23.1:23{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) + MSC --> MNCC: callref 0x80000004: MNCC_SETUP_IND +v=0
+o=OsmoMSC 0 0 IN IP4 10.23.23.1
+s=GSM Call
+c=IN IP4 10.23.23.1
+t=0 0
+m=audio 23 RTP/AVP 112 110 3 111
+a=rtpmap:112 AMR/8000
+a=fmtp:112 octet-align=1
+a=rtpmap:110 GSM-EFR/8000
+a=rtpmap:3 GSM/8000
+a=rtpmap:111 GSM-HR-08/8000
+a=ptime:20
+ +- VALIDATE_SDP OK: cc_to_mncc_tx_last_sdp == t->mo_tx_sdp_mncc_setup_ind == AMR GSM-EFR GSM GSM-HR-08 +- MNCC replies with MNCC_RTP_CREATE + MSC <-- MNCC: callref 0x80000004: MNCC_RTP_CREATE + +DMNCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000004 tid-8) rx MNCC_RTP_CREATE +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Assignment for this trans already started earlier +- MGW acknowledges the CRCX, triggering Assignment with FR3 HR3 FR2 FR1 HR1 + MGW --CRCX OK to RTP_TO_RAN--> MSC +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){ESTABLISHING}: Received Event CALL_LEG_EV_RTP_STREAM_ADDR_AVAILABLE +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Received Event MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: MGW endpoint's RTP address available for the CI RTP_TO_RAN: 10.23.23.1:23 (osmux=no:-2) +DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000004 tid-8) codecs: 10.23.23.1:23{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} (from: MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) +DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000004 tid-8) Sending Assignment Command +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN encode: ASSIGNMENT_COMMAND on GERAN-A +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST +- VALIDATE_PERM_SPEECH OK: &bssap_assignment_command_last_channel_type == t->mo_tx_assignment_perm_speech == FR3 HR3 FR2 FR1 HR1 +- Assignment succeeds, triggering MNCC_RTP_CREATE ack to MNCC +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN decode: ASSIGNMENT_COMPLETE +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-6:RTP_TO_RAN:no-CI){UNINITIALIZED}: setting codecs to AMR:octet-align=1#112 +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-6:RTP_TO_RAN:no-CI:local-10-23-23-1-23){UNINITIALIZED}: setting remote addr to 1.2.3.4:1234 +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-6:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Not committing: no MGW endpoint CI set up +DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000004 tid-8) codecs: 10.23.23.1:23{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} (from: assigned=AMR:octet-align=1#112 MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) +DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000004 tid-8) Assignment Complete: RAN: AMR:octet-align=1#112, CN: AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111 +DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000004 tid-8) codecs: 10.23.23.1:23{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} (from: assigned=AMR:octet-align=1#112 MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) +DMNCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000004 tid-8) tx MNCC_RTP_CREATE (RTP=10.23.23.1:23{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) + MSC --> MNCC: callref 0x80000004: MNCC_RTP_CREATE +v=0
+o=OsmoMSC 0 0 IN IP4 10.23.23.1
+s=GSM Call
+c=IN IP4 10.23.23.1
+t=0 0
+m=audio 23 RTP/AVP 112 110 3 111
+a=rtpmap:112 AMR/8000
+a=fmtp:112 octet-align=1
+a=rtpmap:110 GSM-EFR/8000
+a=rtpmap:3 GSM/8000
+a=rtpmap:111 GSM-HR-08/8000
+a=ptime:20
+ +- VALIDATE_SDP OK: cc_to_mncc_tx_last_sdp == t->mo_tx_sdp_mncc_rtp_create == AMR GSM-EFR GSM GSM-HR-08 +- MNCC says that's fine + MSC <-- MNCC: callref 0x80000004: MNCC_CALL_PROC_REQ + +DMNCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000004 tid-8) rx MNCC_CALL_PROC_REQ +DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000004 tid-8) stopping pending guard timer +DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000004 tid-8) starting guard timer with 180 seconds +DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000004 tid-8) new state INITIATED -> MO_CALL_PROC +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_CALL_PROC +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on GERAN-A +- DTAP --GERAN-A--> MS: GSM48_MT_CC_CALL_PROC: 8302 +- DTAP matches expected message +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Assignment for this trans already started earlier +- Total time passed: 1.000023 s +- The other call leg got established (not shown here), MNCC tells us so, with codecs { AMR GSM-EFR GSM GSM-HR-08 } + MSC <-- MNCC: callref 0x80000004: MNCC_ALERT_REQ +v=0
+o=OsmoMSC 0 0 IN IP4 1.2.3.4
+s=GSM Call
+c=IN IP4 1.2.3.4
+t=0 0
+m=audio 56 RTP/AVP 112 110 3 111
+a=rtpmap:112 AMR/8000
+a=fmtp:112 octet-align=1
+a=rtpmap:110 GSM-EFR/8000
+a=rtpmap:3 GSM/8000
+a=rtpmap:111 GSM-HR-08/8000
+a=ptime:20
+ +DMNCC trans(CC:MO_CALL_PROC IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000004 tid-8) rx MNCC_ALERT_REQ (RTP=1.2.3.4:56{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) +DCC trans(CC:MO_CALL_PROC IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000004 tid-8) stopping pending guard timer +DCC trans(CC:MO_CALL_PROC IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000004 tid-8) starting guard timer with 180 seconds +DCC trans(CC:MO_CALL_PROC IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000004 tid-8) new state MO_CALL_PROC -> CALL_DELIVERED +DCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000004 tid-8) codecs: 10.23.23.1:23{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} (from: assigned=AMR:octet-align=1#112 remote=1.2.3.4:56{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-6:RTP_TO_CN:no-CI){UNINITIALIZED}: no change: codecs already set to AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111 +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-6:RTP_TO_CN:no-CI){UNINITIALIZED}: setting remote addr to 1.2.3.4:56 +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-6:RTP_TO_CN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-56){UNINITIALIZED}: Not committing: no MGW endpoint CI set up +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_ALERTING +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on GERAN-A +- DTAP --GERAN-A--> MS: GSM48_MT_CC_ALERTING: 8301 +- DTAP matches expected message +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST + MSC <-- MNCC: callref 0x80000004: MNCC_SETUP_RSP +v=0
+o=OsmoMSC 0 0 IN IP4 1.2.3.4
+s=GSM Call
+c=IN IP4 1.2.3.4
+t=0 0
+m=audio 56 RTP/AVP 112 110 3 111
+a=rtpmap:112 AMR/8000
+a=fmtp:112 octet-align=1
+a=rtpmap:110 GSM-EFR/8000
+a=rtpmap:3 GSM/8000
+a=rtpmap:111 GSM-HR-08/8000
+a=ptime:20
+ +DMNCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000004 tid-8) rx MNCC_SETUP_RSP (RTP=1.2.3.4:56{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) +DCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000004 tid-8) stopping pending guard timer +DCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000004 tid-8) starting guard timer with 180 seconds +DCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000004 tid-8) starting timer T313 with 30 seconds +DCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000004 tid-8) new state CALL_DELIVERED -> CONNECT_IND +DCC trans(CC:CONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000004 tid-8) codecs: 10.23.23.1:23{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} (from: assigned=AMR:octet-align=1#112 remote=1.2.3.4:56{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-6:RTP_TO_CN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-56){UNINITIALIZED}: no change: codecs already set to AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111 +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-6:RTP_TO_CN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-56){UNINITIALIZED}: remote addr already 1.2.3.4:56, no change +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-6:RTP_TO_CN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-56){UNINITIALIZED}: Not committing: no MGW endpoint CI set up +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_CONNECT +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on GERAN-A +- DTAP --GERAN-A--> MS: GSM48_MT_CC_CONNECT: 8307 +- DTAP matches expected message +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST +- Total time passed: 2.000046 s + MSC <--GERAN-A-- MS: GSM48_MT_CC_CONNECT_ACK +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms) +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP +DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_CONNECT_ACK +DCC trans(CC:CONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000004 tid-8) rx CONNECT_ACK in state CONNECT_IND +DCC trans(CC:CONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000004 tid-8) stopping pending timer T313 +DCC trans(CC:CONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000004 tid-8) new state CONNECT_IND -> ACTIVE +DCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000004 tid-8) stopping pending guard timer +DMNCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000004 tid-8) tx MNCC_SETUP_COMPL_IND + MSC --> MNCC: callref 0x80000004: MNCC_SETUP_COMPL_IND + +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc) +- VALIDATE_SDP OK: cc_to_mncc_tx_last_sdp == t->mo_tx_sdp_mncc_setup_compl_ind == + + +- RTP stream goes ahead, not shown here. +- Total time passed: 125.000091 s + + +- Call ends + MSC <--GERAN-A-- MS: GSM48_MT_CC_DISCONNECT +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms) +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP +DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_DISCONNECT +DCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000004 tid-8) rx DISCONNECT in state ACTIVE +DCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000004 tid-8) new state ACTIVE -> DISCONNECT_IND +DMNCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000004 tid-8) tx MNCC_DISC_IND + MSC --> MNCC: callref 0x80000004: MNCC_DISC_IND + +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc) + MSC <-- MNCC: callref 0x80000004: MNCC_REL_REQ +v=0
+o=OsmoMSC 0 0 IN IP4 1.2.3.4
+s=GSM Call
+c=IN IP4 1.2.3.4
+t=0 0
+m=audio 56 RTP/AVP 112 110 3 111
+a=rtpmap:112 AMR/8000
+a=fmtp:112 octet-align=1
+a=rtpmap:110 GSM-EFR/8000
+a=rtpmap:3 GSM/8000
+a=rtpmap:111 GSM-HR-08/8000
+a=ptime:20
+ +DMNCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000004 tid-8) rx MNCC_REL_REQ +DCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000004 tid-8) starting guard timer with 180 seconds +DCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000004 tid-8) starting timer T308 with 10 seconds +DCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000004 tid-8) new state DISCONNECT_IND -> RELEASE_REQ +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_RELEASE +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on GERAN-A +- DTAP --GERAN-A--> MS: GSM48_MT_CC_RELEASE: 832d +- DTAP matches expected message +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST + MSC <--GERAN-A-- MS: GSM48_MT_CC_RELEASE_COMPL +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms) +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP +DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_RELEASE_COMPL +DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000004 tid-8) rx RELEASE_COMPL in state RELEASE_REQ +DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000004 tid-8) stopping pending timer T308 +DMNCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000004 tid-8) tx MNCC_REL_CNF + MSC --> MNCC: callref 0x80000004: MNCC_REL_CNF + +DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x0 tid-8) Freeing transaction +DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x0 tid-8) new state RELEASE_REQ -> NULL +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x0 tid-8) stopping pending guard timer +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - CC: now used by 2 (attached,active-conn) +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - cc: now used by 1 (rx_from_ms) +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 0 (-) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Received Event MSC_A_EV_UNUSED +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: state_chg to MSC_A_ST_RELEASING +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: Releasing: msc_a use is 0 (-) +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + msc_a_fsm_releasing_onenter: now used by 3 (attached,active-conn,msc_a_fsm_releasing_onenter) +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,active-conn,msc_a_fsm_releasing_onenter,vlr_subscr_cancel_attach_fsm) +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,active-conn,msc_a_fsm_releasing_onenter) +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){ESTABLISHING}: state_chg to RELEASING +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-6:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Terminating (cause = OSMO_FSM_TERM_PARENT) +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-6:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Removing from parent call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ) +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-6:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Deallocated +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-6:RTP_TO_CN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-56){UNINITIALIZED}: Terminating (cause = OSMO_FSM_TERM_PARENT) +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-6:RTP_TO_CN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-56){UNINITIALIZED}: Removing from parent call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ) +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-6:RTP_TO_CN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-56){UNINITIALIZED}: Deallocated +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){RELEASING}: Terminating (cause = OSMO_FSM_TERM_REGULAR) +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){RELEASING}: Removing from parent msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: Received Event MSC_EV_CALL_LEG_TERM +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){RELEASING}: Deallocated +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: + wait-Clear-Complete: now used by 1 (wait-Clear-Complete) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: RAN encode: CLEAR_COMMAND on GERAN-A +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - msc_a_fsm_releasing_onenter: now used by 2 (attached,active-conn) +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: RAN decode: CLEAR_COMPLETE +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: - wait-Clear-Complete: now used by 0 (-) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: Received Event MSC_A_EV_UNUSED +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: state_chg to MSC_A_ST_RELEASED +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASED}: Released: msc_a use is 0 (-) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_DONE}: Terminating in cascade, depth 2 (cause = OSMO_FSM_TERM_PARENT, caused by: msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ)) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_DONE}: Removing from parent msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_DONE}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASED}: Removing from parent msub_fsm +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASED}: max total use count was 3 +DMSC msub_fsm{active}: Received Event MSUB_EV_ROLE_TERMINATED +DMSC msub(IMSI-901700000010650:MSISDN-46071) MSC-A terminated +DMSC msub(IMSI-901700000010650:MSISDN-46071) 1 MSC-I still active +DMSC msub_fsm{active}: state_chg to terminating +DMSC msub_fsm{terminating}: Terminating in cascade, depth 2 (cause = OSMO_FSM_TERM_REGULAR, caused by: msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ)) +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Terminating in cascade, depth 3 (cause = OSMO_FSM_TERM_PARENT, caused by: msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ)) +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Removing from parent msub_fsm +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ) +DMSC msub(IMSI-901700000010650:MSISDN-46071) Free +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - active-conn: now used by 1 (attached) +DMSC msub_fsm{terminating}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASED}: Deallocated, including all deferred deallocations +- msub gone + llist_count(&msub_list) == 0 + + +- ======================== SUCCESS: MO call: AMR picked by both MO and MT + + +- ======================== MT call: AMR picked by both MO and MT + + +- MNCC asks us to setup a call, causing Paging + MSC <-- MNCC: callref 0x423: MNCC_SETUP_REQ +v=0
+o=OsmoMSC 0 0 IN IP4 1.2.3.4
+s=GSM Call
+c=IN IP4 1.2.3.4
+t=0 0
+m=audio 56 RTP/AVP 112 110 3 111
+a=rtpmap:112 AMR/8000
+a=fmtp:112 octet-align=1
+a=rtpmap:110 GSM-EFR/8000
+a=rtpmap:3 GSM/8000
+a=rtpmap:111 GSM-HR-08/8000
+a=ptime:20
+ +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + mncc_tx_to_gsm_cc: now used by 2 (attached,mncc_tx_to_gsm_cc) +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + CC: now used by 3 (attached,mncc_tx_to_gsm_cc,CC) +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071 callref-0x423 tid-255) New transaction +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071 callref-0x423 tid-255) codecs: :0{(no-codecs)} (from: remote=1.2.3.4:56{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} RAN={(no-codecs)}) +DMNCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071 callref-0x423 tid-255) rx MNCC_SETUP_REQ (RTP=1.2.3.4:56{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) +DPAG Paging: IMSI-901700000010650:MSISDN-46071 for MNCC: establish call: Starting paging + paging request (CALL_CONVERSATIONAL) to IMSI-901700000010650:MSISDN-46071 on GERAN-A + strcmp(paging_expecting_imsi, vsub->imsi) == 0 +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + Paging: now used by 4 (attached,mncc_tx_to_gsm_cc,CC,Paging) +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - mncc_tx_to_gsm_cc: now used by 3 (attached,CC,Paging) + paging_sent == 1 +- MS replies with Paging Response, with Codec List (BSS Supported) = FR1 FR2 FR3 HR1 HR3 +- VLR accepts, MSC sends CC Setup with Bearer Capability = AMR AMR AMR GSM-EFR GSM GSM-HR-08 + MSC <--GERAN-A-- MS: GSM48_MT_RR_PAG_RESP + new conn +DMSC msub_fsm{active}: Allocated +DMSC msc_a{MSC_A_ST_VALIDATE_L3}: Allocated +DMSC msc_a{MSC_A_ST_VALIDATE_L3}: is child of msub_fsm +DMSC msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_VALIDATE_L3 +DMSC dummy_msc_i{0}: Allocated +DMSC dummy_msc_i{0}: is child of msub_fsm +DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms) +DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3 +DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Complete Layer 3: Codec List (BSS Supported): GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111 +DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: RR GSM48_MT_RR_PAG_RESP +DRR msc_a(IMSI-901700000010650:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: Rx PAGING RESPONSE IMSI-901700000010650 +DREF msc_a(IMSI-901700000010650:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: + paging-response: now used by 2 (rx_from_ms,paging-response) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: Allocated +DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: is child of msc_a(IMSI-901700000010650:GERAN-A:PAGING_RESP) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: rev=R99 net=GERAN (no Auth) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + proc_arq_vlr_fn_init: now used by 4 (attached,CC,Paging,proc_arq_vlr_fn_init) +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + active-conn: now used by 5 (attached,CC,Paging,proc_arq_vlr_fn_init,active-conn) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi() +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_node2() +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_ciph() +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_vlr() +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_post_pres() +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_post_trace() +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_post_imei() +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: proc_arq_fsm_done(PASSED) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_DONE +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_DONE}: Process Access Request result: PASSED +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: Received Event MSC_A_EV_AUTHENTICATED +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: state_chg to MSC_A_ST_AUTHENTICATED +DPAG Paging: IMSI-901700000010650:MSISDN-46071 for MNCC: establish call: Paging Response action (success) +DPAG Paging: IMSI-901700000010650:MSISDN-46071 for MNCC: establish call: Removing Paging Request +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071 callref-0x423 tid-255) Paging succeeded +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: + cc: now used by 3 (rx_from_ms,paging-response,cc) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: Received Event MSC_A_EV_TRANSACTION_ACCEPTED +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: state_chg to MSC_A_ST_COMMUNICATING +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) starting timer T303 with 30 seconds +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) codecs: :0{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} (from: remote=1.2.3.4:56{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) new state NULL -> CALL_PRESENT +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_SETUP +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on GERAN-A +- DTAP --GERAN-A--> MS: GSM48_MT_CC_SETUP: 030504076004050b020081 +- DTAP matches expected message +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - Paging: now used by 4 (attached,CC,proc_arq_vlr_fn_init,active-conn) +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - paging-response: now used by 2 (rx_from_ms,cc) +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - proc_arq_vlr_fn_init: now used by 3 (attached,CC,active-conn) +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc) +- MS confirms call, we create a RAN-side RTP and forward MNCC_CALL_CONF_IND + MSC <--GERAN-A-- MS: GSM48_MT_CC_CALL_CONF +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms) +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP +DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_CALL_CONF +DCC trans(CC:CALL_PRESENT IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx CALL_CONF in state CALL_PRESENT +DCC trans(CC:CALL_PRESENT IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) stopping pending timer T303 +DCC trans(CC:CALL_PRESENT IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) starting timer T310 with 30 seconds +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Starting call assignment +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){ESTABLISHING}: Allocated +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){ESTABLISHING}: is child of msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP) +DCC trans(CC:CALL_PRESENT IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) codecs: :0{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} (from: remote=1.2.3.4:56{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) + MGW <--CRCX to RTP_TO_CN-- MSC: call_id=0x7 codecs=AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111 +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){UNINITIALIZED}: Allocated +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){UNINITIALIZED}: is child of call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP) +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-7:RTP_TO_CN:no-CI){UNINITIALIZED}: setting codecs to AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111 + MGW <--CRCX to RTP_TO_RAN-- MSC: call_id=0x7 codecs=AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111 +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){UNINITIALIZED}: Allocated +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){UNINITIALIZED}: is child of call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP) +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-7:RTP_TO_RAN:no-CI){UNINITIALIZED}: setting codecs to AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111 +DCC trans(CC:CALL_PRESENT IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) new state CALL_PRESENT -> MO_TERM_CALL_CONF +DMNCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) tx MNCC_CALL_CONF_IND + MSC --> MNCC: callref 0x423: MNCC_CALL_CONF_IND + +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc) +- VALIDATE_SDP OK: cc_to_mncc_tx_last_sdp == t->mt_tx_sdp_mncc_call_conf_ind == +- MGW acknowledges the CRCX to RAN, triggering Assignment with FR3 HR3 FR2 FR1 HR1 + MGW --CRCX OK to RTP_TO_RAN--> MSC +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){ESTABLISHING}: Received Event CALL_LEG_EV_RTP_STREAM_ADDR_AVAILABLE +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Received Event MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: MGW endpoint's RTP address available for the CI RTP_TO_RAN: 10.23.23.1:23 (osmux=no:-2) +DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) codecs: :0{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} (from: remote=1.2.3.4:56{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) +DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) Sending Assignment Command +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN encode: ASSIGNMENT_COMMAND on GERAN-A +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST +- VALIDATE_PERM_SPEECH OK: &bssap_assignment_command_last_channel_type == t->mt_tx_assignment_perm_speech == FR3 HR3 FR2 FR1 HR1 +- Assignment completes, triggering CRCX to CN +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN decode: ASSIGNMENT_COMPLETE +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-7:RTP_TO_RAN:no-CI){UNINITIALIZED}: setting codecs to AMR:octet-align=1#112 +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-7:RTP_TO_RAN:no-CI:local-10-23-23-1-23){UNINITIALIZED}: setting remote addr to 1.2.3.4:1234 +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-7:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Not committing: no MGW endpoint CI set up +DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) codecs: :0{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} (from: assigned=AMR:octet-align=1#112 remote=1.2.3.4:56{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) +DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) Assignment Complete: RAN: AMR:octet-align=1#112, CN: AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111 +DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) Assignment complete, but still waiting for the CRCX OK on the CN side RTP +- MNCC sends MNCC_RTP_CREATE, which first waits for the CN side RTP + MSC <-- MNCC: callref 0x423: MNCC_RTP_CREATE + +DMNCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx MNCC_RTP_CREATE +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Assignment for this trans already started earlier +- When the CN side RTP address is known, ack MNCC_RTP_CREATE + MGW --CRCX OK to RTP_TO_CN--> MSC +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){ESTABLISHING}: Received Event CALL_LEG_EV_RTP_STREAM_ADDR_AVAILABLE +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Received Event MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: MGW endpoint's RTP address available for the CI RTP_TO_CN: 10.23.23.1:23 (osmux=no:-2) +DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) codecs: 10.23.23.1:23{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} (from: assigned=AMR:octet-align=1#112 remote=1.2.3.4:56{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) +DMNCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) tx MNCC_RTP_CREATE (RTP=10.23.23.1:23{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) + MSC --> MNCC: callref 0x423: MNCC_RTP_CREATE +v=0
+o=OsmoMSC 0 0 IN IP4 10.23.23.1
+s=GSM Call
+c=IN IP4 10.23.23.1
+t=0 0
+m=audio 23 RTP/AVP 112 110 3 111
+a=rtpmap:112 AMR/8000
+a=fmtp:112 octet-align=1
+a=rtpmap:110 GSM-EFR/8000
+a=rtpmap:3 GSM/8000
+a=rtpmap:111 GSM-HR-08/8000
+a=ptime:20
+ +- VALIDATE_SDP OK: cc_to_mncc_tx_last_sdp == t->mt_tx_sdp_mncc_rtp_create == AMR GSM-EFR GSM GSM-HR-08 +- Total time passed: 126.000114 s + MSC <--GERAN-A-- MS: GSM48_MT_CC_ALERTING +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms) +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP +DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_ALERTING +DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx ALERTING in state MO_TERM_CALL_CONF +DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) stopping pending timer T310 +DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) starting timer T301 with 180 seconds +DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) new state MO_TERM_CALL_CONF -> CALL_RECEIVED +DCC trans(CC:CALL_RECEIVED IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) codecs: 10.23.23.1:23{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} (from: assigned=AMR:octet-align=1#112 remote=1.2.3.4:56{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) +DMNCC trans(CC:CALL_RECEIVED IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) tx MNCC_ALERT_IND (RTP=10.23.23.1:23{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) + MSC --> MNCC: callref 0x423: MNCC_ALERT_IND +v=0
+o=OsmoMSC 0 0 IN IP4 10.23.23.1
+s=GSM Call
+c=IN IP4 10.23.23.1
+t=0 0
+m=audio 23 RTP/AVP 112 110 3 111
+a=rtpmap:112 AMR/8000
+a=fmtp:112 octet-align=1
+a=rtpmap:110 GSM-EFR/8000
+a=rtpmap:3 GSM/8000
+a=rtpmap:111 GSM-HR-08/8000
+a=ptime:20
+ +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc) +- VALIDATE_SDP OK: cc_to_mncc_tx_last_sdp == t->mt_tx_sdp_mncc_alert_ind == AMR GSM-EFR GSM GSM-HR-08 +- Total time passed: 127.000137 s + MSC <--GERAN-A-- MS: GSM48_MT_CC_CONNECT +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms) +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP +DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_CONNECT +DCC trans(CC:CALL_RECEIVED IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx CONNECT in state CALL_RECEIVED +DCC trans(CC:CALL_RECEIVED IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) stopping pending timer T301 +DCC trans(CC:CALL_RECEIVED IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) new state CALL_RECEIVED -> CONNECT_REQUEST +DCC trans(CC:CONNECT_REQUEST IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) codecs: 10.23.23.1:23{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} (from: assigned=AMR:octet-align=1#112 remote=1.2.3.4:56{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) +DMNCC trans(CC:CONNECT_REQUEST IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) tx MNCC_SETUP_CNF (RTP=10.23.23.1:23{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) + MSC --> MNCC: callref 0x423: MNCC_SETUP_CNF +v=0
+o=OsmoMSC 0 0 IN IP4 10.23.23.1
+s=GSM Call
+c=IN IP4 10.23.23.1
+t=0 0
+m=audio 23 RTP/AVP 112 110 3 111
+a=rtpmap:112 AMR/8000
+a=fmtp:112 octet-align=1
+a=rtpmap:110 GSM-EFR/8000
+a=rtpmap:3 GSM/8000
+a=rtpmap:111 GSM-HR-08/8000
+a=ptime:20
+ +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc) +- VALIDATE_SDP OK: cc_to_mncc_tx_last_sdp == t->mt_tx_sdp_mncc_setup_cnf == AMR GSM-EFR GSM GSM-HR-08 + MSC <-- MNCC: callref 0x423: MNCC_SETUP_COMPL_REQ -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 17 +DMNCC trans(CC:CONNECT_REQUEST IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx MNCC_SETUP_COMPL_REQ +DCC trans(CC:CONNECT_REQUEST IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) starting guard timer with 180 seconds +DCC trans(CC:CONNECT_REQUEST IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) new state CONNECT_REQUEST -> ACTIVE +DCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) stopping pending guard timer +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_CONNECT_ACK +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on GERAN-A +- DTAP --GERAN-A--> MS: GSM48_MT_CC_CONNECT_ACK: 030f +- DTAP matches expected message +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST + + +- RTP stream goes ahead, not shown here. +- Total time passed: 250.000182 s + + +- Call ends + MSC <--GERAN-A-- MS: GSM48_MT_CC_DISCONNECT +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms) +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP +DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_DISCONNECT +DCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx DISCONNECT in state ACTIVE +DCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) new state ACTIVE -> DISCONNECT_IND +DMNCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) tx MNCC_DISC_IND + MSC --> MNCC: callref 0x423: MNCC_DISC_IND + +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc) + MSC <-- MNCC: callref 0x423: MNCC_REL_REQ + +DMNCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx MNCC_REL_REQ +DCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) starting guard timer with 180 seconds +DCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) starting timer T308 with 10 seconds +DCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) new state DISCONNECT_IND -> RELEASE_REQ +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_RELEASE +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on GERAN-A +- DTAP --GERAN-A--> MS: GSM48_MT_CC_RELEASE: 032d +- DTAP matches expected message +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST + MSC <--GERAN-A-- MS: GSM48_MT_CC_RELEASE_COMPL +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms) +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP +DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_RELEASE_COMPL +DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx RELEASE_COMPL in state RELEASE_REQ +DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) stopping pending timer T308 +DMNCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) tx MNCC_REL_CNF + MSC --> MNCC: callref 0x423: MNCC_REL_CNF + +DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x0 tid-0) Freeing transaction +DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x0 tid-0) new state RELEASE_REQ -> NULL +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x0 tid-0) stopping pending guard timer +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - CC: now used by 2 (attached,active-conn) +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - cc: now used by 1 (rx_from_ms) +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 0 (-) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Received Event MSC_A_EV_UNUSED +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: state_chg to MSC_A_ST_RELEASING +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: Releasing: msc_a use is 0 (-) +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + msc_a_fsm_releasing_onenter: now used by 3 (attached,active-conn,msc_a_fsm_releasing_onenter) +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,active-conn,msc_a_fsm_releasing_onenter,vlr_subscr_cancel_attach_fsm) +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,active-conn,msc_a_fsm_releasing_onenter) +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){ESTABLISHING}: state_chg to RELEASING +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-7:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Terminating (cause = OSMO_FSM_TERM_PARENT) +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-7:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Removing from parent call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP) +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-7:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Deallocated +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-7:RTP_TO_CN:no-CI){UNINITIALIZED}: Terminating (cause = OSMO_FSM_TERM_PARENT) +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-7:RTP_TO_CN:no-CI){UNINITIALIZED}: Removing from parent call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP) +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-7:RTP_TO_CN:no-CI){UNINITIALIZED}: Deallocated +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){RELEASING}: Terminating (cause = OSMO_FSM_TERM_REGULAR) +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){RELEASING}: Removing from parent msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: Received Event MSC_EV_CALL_LEG_TERM +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){RELEASING}: Deallocated +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: + wait-Clear-Complete: now used by 1 (wait-Clear-Complete) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: RAN encode: CLEAR_COMMAND on GERAN-A +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - msc_a_fsm_releasing_onenter: now used by 2 (attached,active-conn) +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: RAN decode: CLEAR_COMPLETE +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: - wait-Clear-Complete: now used by 0 (-) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: Received Event MSC_A_EV_UNUSED +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: state_chg to MSC_A_ST_RELEASED +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASED}: Released: msc_a use is 0 (-) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_DONE}: Terminating in cascade, depth 2 (cause = OSMO_FSM_TERM_PARENT, caused by: msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP)) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_DONE}: Removing from parent msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_DONE}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASED}: Removing from parent msub_fsm +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASED}: max total use count was 3 +DMSC msub_fsm{active}: Received Event MSUB_EV_ROLE_TERMINATED +DMSC msub(IMSI-901700000010650:MSISDN-46071) MSC-A terminated +DMSC msub(IMSI-901700000010650:MSISDN-46071) 1 MSC-I still active +DMSC msub_fsm{active}: state_chg to terminating +DMSC msub_fsm{terminating}: Terminating in cascade, depth 2 (cause = OSMO_FSM_TERM_REGULAR, caused by: msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP)) +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Terminating in cascade, depth 3 (cause = OSMO_FSM_TERM_PARENT, caused by: msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP)) +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Removing from parent msub_fsm +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP) +DMSC msub(IMSI-901700000010650:MSISDN-46071) Free +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - active-conn: now used by 1 (attached) +DMSC msub_fsm{terminating}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASED}: Deallocated, including all deferred deallocations +- msub gone + llist_count(&msub_list) == 0 + + +- ======================== SUCCESS: MT call: AMR picked by both MO and MT + + +- ======================== MO call: FR1 picked by MO from Codec List (BSS Supported), MT hence also picks FR1 +- CM Service Request with Codec List (BSS Supported) = FR1 + MSC <--GERAN-A-- MS: GSM48_MT_MM_CM_SERV_REQ + new conn +DMSC msub_fsm{active}: Allocated +DMSC msc_a{MSC_A_ST_VALIDATE_L3}: Allocated +DMSC msc_a{MSC_A_ST_VALIDATE_L3}: is child of msub_fsm +DMSC msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_VALIDATE_L3 +DMSC dummy_msc_i{0}: Allocated +DMSC dummy_msc_i{0}: is child of msub_fsm +DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms) +DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3 +DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Complete Layer 3: Codec List (BSS Supported): GSM#3 +DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: MM GSM48_MT_MM_CM_SERV_REQ +DMM msc_a(IMSI-901700000010650:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_VALIDATE_L3}: Rx CM SERVICE REQUEST cm_service_type=MO-Call +DREF msc_a(IMSI-901700000010650:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_VALIDATE_L3}: + cm_service_cc: now used by 2 (rx_from_ms,cm_service_cc) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: Allocated +DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: is child of msc_a(IMSI-901700000010650:GERAN-A:CM_SERVICE_REQ) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: rev=R99 net=GERAN (no Auth) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + proc_arq_vlr_fn_init: now used by 2 (attached,proc_arq_vlr_fn_init) +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + active-conn: now used by 3 (attached,proc_arq_vlr_fn_init,active-conn) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi() +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_node2() +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_ciph() +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_vlr() +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_post_pres() +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_post_trace() +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_post_imei() +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: proc_arq_fsm_done(PASSED) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_DONE +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_DONE}: Process Access Request result: PASSED +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: Sending DTAP: MM GSM48_MT_MM_CM_SERV_ACC +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN encode: DTAP on GERAN-A +- DTAP --GERAN-A--> MS: GSM48_MT_MM_CM_SERV_ACC: 0521 +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: Received Event MSC_A_EV_AUTHENTICATED +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: state_chg to MSC_A_ST_AUTHENTICATED +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - proc_arq_vlr_fn_init: now used by 2 (attached,active-conn) +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: - rx_from_ms: now used by 1 (cm_service_cc) + cm_service_result_sent == 1 +msc_a_is_accepted() == true +- MS sends CC SETUP with Bearer Capability = AMR AMR AMR GSM-EFR GSM GSM-HR-08 + MSC <--GERAN-A-- MS: GSM48_MT_CC_SETUP +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: + rx_from_ms: now used by 2 (cm_service_cc,rx_from_ms) +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: RAN decode: DTAP +DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: Dispatching 04.08 message: CC GSM48_MT_CC_SETUP +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + CC: now used by 3 (attached,active-conn,CC) +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071 callref-0x80000005 tid-8) New transaction +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: Received Event MSC_A_EV_TRANSACTION_ACCEPTED +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: state_chg to MSC_A_ST_COMMUNICATING +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: + cc: now used by 3 (cm_service_cc,rx_from_ms,cc) +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - cm_service_cc: now used by 2 (rx_from_ms,cc) +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000005 tid-8) rx SETUP in state NULL +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000005 tid-8) starting guard timer with 180 seconds +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000005 tid-8) codecs: :0{GSM#3} (from: MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000005 tid-8) SETUP to 123 +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000005 tid-8) new state NULL -> INITIATED +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Starting call assignment +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){ESTABLISHING}: Allocated +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){ESTABLISHING}: is child of msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ) +DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000005 tid-8) codecs: :0{GSM#3} (from: MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) + MGW <--CRCX to RTP_TO_CN-- MSC: call_id=0x8 codecs=GSM#3 +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){UNINITIALIZED}: Allocated +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){UNINITIALIZED}: is child of call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ) +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-8:RTP_TO_CN:no-CI){UNINITIALIZED}: setting codecs to GSM#3 + MGW <--CRCX to RTP_TO_RAN-- MSC: call_id=0x8 codecs=GSM#3 +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){UNINITIALIZED}: Allocated +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){UNINITIALIZED}: is child of call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ) +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-8:RTP_TO_RAN:no-CI){UNINITIALIZED}: setting codecs to GSM#3 +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc) +- As soon as the MGW port towards CN is created, MNCC_SETUP_IND is triggered + MGW --CRCX OK to RTP_TO_CN--> MSC +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){ESTABLISHING}: Received Event CALL_LEG_EV_RTP_STREAM_ADDR_AVAILABLE +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Received Event MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: MGW endpoint's RTP address available for the CI RTP_TO_CN: 10.23.23.1:23 (osmux=no:-2) +DMNCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000005 tid-8) tx MNCC_SETUP_IND (RTP=10.23.23.1:23{GSM#3}) + MSC --> MNCC: callref 0x80000005: MNCC_SETUP_IND +v=0
+o=OsmoMSC 0 0 IN IP4 10.23.23.1
+s=GSM Call
+c=IN IP4 10.23.23.1
+t=0 0
+m=audio 23 RTP/AVP 3
+a=rtpmap:3 GSM/8000
+a=ptime:20
+ +- VALIDATE_SDP OK: cc_to_mncc_tx_last_sdp == t->mo_tx_sdp_mncc_setup_ind == GSM +- MNCC replies with MNCC_RTP_CREATE + MSC <-- MNCC: callref 0x80000005: MNCC_RTP_CREATE + +DMNCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000005 tid-8) rx MNCC_RTP_CREATE +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Assignment for this trans already started earlier +- MGW acknowledges the CRCX, triggering Assignment with FR1 + MGW --CRCX OK to RTP_TO_RAN--> MSC +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){ESTABLISHING}: Received Event CALL_LEG_EV_RTP_STREAM_ADDR_AVAILABLE +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Received Event MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: MGW endpoint's RTP address available for the CI RTP_TO_RAN: 10.23.23.1:23 (osmux=no:-2) +DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000005 tid-8) codecs: 10.23.23.1:23{GSM#3} (from: MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) +DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000005 tid-8) Sending Assignment Command +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN encode: ASSIGNMENT_COMMAND on GERAN-A +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST +- VALIDATE_PERM_SPEECH OK: &bssap_assignment_command_last_channel_type == t->mo_tx_assignment_perm_speech == FR1 +- Assignment succeeds, triggering MNCC_RTP_CREATE ack to MNCC +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN decode: ASSIGNMENT_COMPLETE +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-8:RTP_TO_RAN:no-CI){UNINITIALIZED}: no change: codecs already set to GSM#3 +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-8:RTP_TO_RAN:no-CI){UNINITIALIZED}: setting remote addr to 1.2.3.4:1234 +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-8:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Not committing: no MGW endpoint CI set up +DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000005 tid-8) codecs: 10.23.23.1:23{GSM#3} (from: assigned=GSM#3 MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) +DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000005 tid-8) Assignment Complete: RAN: GSM#3, CN: GSM#3 +DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000005 tid-8) codecs: 10.23.23.1:23{GSM#3} (from: assigned=GSM#3 MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) +DMNCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000005 tid-8) tx MNCC_RTP_CREATE (RTP=10.23.23.1:23{GSM#3}) + MSC --> MNCC: callref 0x80000005: MNCC_RTP_CREATE +v=0
+o=OsmoMSC 0 0 IN IP4 10.23.23.1
+s=GSM Call
+c=IN IP4 10.23.23.1
+t=0 0
+m=audio 23 RTP/AVP 3
+a=rtpmap:3 GSM/8000
+a=ptime:20
+ +- VALIDATE_SDP OK: cc_to_mncc_tx_last_sdp == t->mo_tx_sdp_mncc_rtp_create == GSM +- MNCC says that's fine + MSC <-- MNCC: callref 0x80000005: MNCC_CALL_PROC_REQ + +DMNCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000005 tid-8) rx MNCC_CALL_PROC_REQ +DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000005 tid-8) stopping pending guard timer +DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000005 tid-8) starting guard timer with 180 seconds +DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000005 tid-8) new state INITIATED -> MO_CALL_PROC +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_CALL_PROC +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on GERAN-A +- DTAP --GERAN-A--> MS: GSM48_MT_CC_CALL_PROC: 8302 +- DTAP matches expected message +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Assignment for this trans already started earlier +- Total time passed: 251.000205 s +- The other call leg got established (not shown here), MNCC tells us so, with codecs { GSM } + MSC <-- MNCC: callref 0x80000005: MNCC_ALERT_REQ +v=0
+o=OsmoMSC 0 0 IN IP4 1.2.3.4
+s=GSM Call
+c=IN IP4 1.2.3.4
+t=0 0
+m=audio 56 RTP/AVP 3
+a=rtpmap:3 GSM/8000
+a=ptime:20
+ +DMNCC trans(CC:MO_CALL_PROC IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000005 tid-8) rx MNCC_ALERT_REQ (RTP=1.2.3.4:56{GSM#3}) +DCC trans(CC:MO_CALL_PROC IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000005 tid-8) stopping pending guard timer +DCC trans(CC:MO_CALL_PROC IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000005 tid-8) starting guard timer with 180 seconds +DCC trans(CC:MO_CALL_PROC IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000005 tid-8) new state MO_CALL_PROC -> CALL_DELIVERED +DCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000005 tid-8) codecs: 10.23.23.1:23{GSM#3} (from: assigned=GSM#3 remote=1.2.3.4:56{GSM#3} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-8:RTP_TO_CN:no-CI){UNINITIALIZED}: no change: codecs already set to GSM#3 +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-8:RTP_TO_CN:no-CI){UNINITIALIZED}: setting remote addr to 1.2.3.4:56 +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-8:RTP_TO_CN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-56){UNINITIALIZED}: Not committing: no MGW endpoint CI set up +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_ALERTING +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on GERAN-A +- DTAP --GERAN-A--> MS: GSM48_MT_CC_ALERTING: 8301 +- DTAP matches expected message +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST + MSC <-- MNCC: callref 0x80000005: MNCC_SETUP_RSP +v=0
+o=OsmoMSC 0 0 IN IP4 1.2.3.4
+s=GSM Call
+c=IN IP4 1.2.3.4
+t=0 0
+m=audio 56 RTP/AVP 3
+a=rtpmap:3 GSM/8000
+a=ptime:20
+ +DMNCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000005 tid-8) rx MNCC_SETUP_RSP (RTP=1.2.3.4:56{GSM#3}) +DCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000005 tid-8) stopping pending guard timer +DCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000005 tid-8) starting guard timer with 180 seconds +DCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000005 tid-8) starting timer T313 with 30 seconds +DCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000005 tid-8) new state CALL_DELIVERED -> CONNECT_IND +DCC trans(CC:CONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000005 tid-8) codecs: 10.23.23.1:23{GSM#3} (from: assigned=GSM#3 remote=1.2.3.4:56{GSM#3} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-8:RTP_TO_CN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-56){UNINITIALIZED}: no change: codecs already set to GSM#3 +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-8:RTP_TO_CN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-56){UNINITIALIZED}: remote addr already 1.2.3.4:56, no change +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-8:RTP_TO_CN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-56){UNINITIALIZED}: Not committing: no MGW endpoint CI set up +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_CONNECT +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on GERAN-A +- DTAP --GERAN-A--> MS: GSM48_MT_CC_CONNECT: 8307 +- DTAP matches expected message +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST +- Total time passed: 252.000228 s + MSC <--GERAN-A-- MS: GSM48_MT_CC_CONNECT_ACK +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms) +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP +DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_CONNECT_ACK +DCC trans(CC:CONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000005 tid-8) rx CONNECT_ACK in state CONNECT_IND +DCC trans(CC:CONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000005 tid-8) stopping pending timer T313 +DCC trans(CC:CONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000005 tid-8) new state CONNECT_IND -> ACTIVE +DCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000005 tid-8) stopping pending guard timer +DMNCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000005 tid-8) tx MNCC_SETUP_COMPL_IND + MSC --> MNCC: callref 0x80000005: MNCC_SETUP_COMPL_IND + +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc) +- VALIDATE_SDP OK: cc_to_mncc_tx_last_sdp == t->mo_tx_sdp_mncc_setup_compl_ind == + + +- RTP stream goes ahead, not shown here. +- Total time passed: 375.000273 s + + +- Call ends + MSC <--GERAN-A-- MS: GSM48_MT_CC_DISCONNECT +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms) +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP +DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_DISCONNECT +DCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000005 tid-8) rx DISCONNECT in state ACTIVE +DCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000005 tid-8) new state ACTIVE -> DISCONNECT_IND +DMNCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000005 tid-8) tx MNCC_DISC_IND + MSC --> MNCC: callref 0x80000005: MNCC_DISC_IND + +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc) + MSC <-- MNCC: callref 0x80000005: MNCC_REL_REQ +v=0
+o=OsmoMSC 0 0 IN IP4 1.2.3.4
+s=GSM Call
+c=IN IP4 1.2.3.4
+t=0 0
+m=audio 56 RTP/AVP 3
+a=rtpmap:3 GSM/8000
+a=ptime:20
+ +DMNCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000005 tid-8) rx MNCC_REL_REQ +DCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000005 tid-8) starting guard timer with 180 seconds +DCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000005 tid-8) starting timer T308 with 10 seconds +DCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000005 tid-8) new state DISCONNECT_IND -> RELEASE_REQ +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_RELEASE +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on GERAN-A +- DTAP --GERAN-A--> MS: GSM48_MT_CC_RELEASE: 832d +- DTAP matches expected message +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST + MSC <--GERAN-A-- MS: GSM48_MT_CC_RELEASE_COMPL +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms) +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP +DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_RELEASE_COMPL +DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000005 tid-8) rx RELEASE_COMPL in state RELEASE_REQ +DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000005 tid-8) stopping pending timer T308 +DMNCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000005 tid-8) tx MNCC_REL_CNF + MSC --> MNCC: callref 0x80000005: MNCC_REL_CNF + +DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x0 tid-8) Freeing transaction +DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x0 tid-8) new state RELEASE_REQ -> NULL +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x0 tid-8) stopping pending guard timer +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - CC: now used by 2 (attached,active-conn) +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - cc: now used by 1 (rx_from_ms) +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 0 (-) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Received Event MSC_A_EV_UNUSED +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: state_chg to MSC_A_ST_RELEASING +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: Releasing: msc_a use is 0 (-) +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + msc_a_fsm_releasing_onenter: now used by 3 (attached,active-conn,msc_a_fsm_releasing_onenter) +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,active-conn,msc_a_fsm_releasing_onenter,vlr_subscr_cancel_attach_fsm) +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,active-conn,msc_a_fsm_releasing_onenter) +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){ESTABLISHING}: state_chg to RELEASING +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-8:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Terminating (cause = OSMO_FSM_TERM_PARENT) +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-8:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Removing from parent call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ) +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-8:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Deallocated +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-8:RTP_TO_CN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-56){UNINITIALIZED}: Terminating (cause = OSMO_FSM_TERM_PARENT) +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-8:RTP_TO_CN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-56){UNINITIALIZED}: Removing from parent call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ) +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-8:RTP_TO_CN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-56){UNINITIALIZED}: Deallocated +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){RELEASING}: Terminating (cause = OSMO_FSM_TERM_REGULAR) +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){RELEASING}: Removing from parent msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: Received Event MSC_EV_CALL_LEG_TERM +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){RELEASING}: Deallocated +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: + wait-Clear-Complete: now used by 1 (wait-Clear-Complete) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: RAN encode: CLEAR_COMMAND on GERAN-A +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - msc_a_fsm_releasing_onenter: now used by 2 (attached,active-conn) +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: RAN decode: CLEAR_COMPLETE +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: - wait-Clear-Complete: now used by 0 (-) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: Received Event MSC_A_EV_UNUSED +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: state_chg to MSC_A_ST_RELEASED +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASED}: Released: msc_a use is 0 (-) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_DONE}: Terminating in cascade, depth 2 (cause = OSMO_FSM_TERM_PARENT, caused by: msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ)) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_DONE}: Removing from parent msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_DONE}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASED}: Removing from parent msub_fsm +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASED}: max total use count was 3 +DMSC msub_fsm{active}: Received Event MSUB_EV_ROLE_TERMINATED +DMSC msub(IMSI-901700000010650:MSISDN-46071) MSC-A terminated +DMSC msub(IMSI-901700000010650:MSISDN-46071) 1 MSC-I still active +DMSC msub_fsm{active}: state_chg to terminating +DMSC msub_fsm{terminating}: Terminating in cascade, depth 2 (cause = OSMO_FSM_TERM_REGULAR, caused by: msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ)) +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Terminating in cascade, depth 3 (cause = OSMO_FSM_TERM_PARENT, caused by: msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ)) +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Removing from parent msub_fsm +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ) +DMSC msub(IMSI-901700000010650:MSISDN-46071) Free +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - active-conn: now used by 1 (attached) +DMSC msub_fsm{terminating}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASED}: Deallocated, including all deferred deallocations +- msub gone + llist_count(&msub_list) == 0 + + +- ======================== SUCCESS: MO call: FR1 picked by MO from Codec List (BSS Supported), MT hence also picks FR1 + + +- ======================== MT call: FR1 picked by MO from Codec List (BSS Supported), MT hence also picks FR1 + + +- MNCC asks us to setup a call, causing Paging + MSC <-- MNCC: callref 0x423: MNCC_SETUP_REQ +v=0
+o=OsmoMSC 0 0 IN IP4 1.2.3.4
+s=GSM Call
+c=IN IP4 1.2.3.4
+t=0 0
+m=audio 56 RTP/AVP 3
+a=rtpmap:3 GSM/8000
+a=ptime:20
+ +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + mncc_tx_to_gsm_cc: now used by 2 (attached,mncc_tx_to_gsm_cc) +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + CC: now used by 3 (attached,mncc_tx_to_gsm_cc,CC) +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071 callref-0x423 tid-255) New transaction +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071 callref-0x423 tid-255) codecs: :0{(no-codecs)} (from: remote=1.2.3.4:56{GSM#3} RAN={(no-codecs)}) +DMNCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071 callref-0x423 tid-255) rx MNCC_SETUP_REQ (RTP=1.2.3.4:56{GSM#3}) +DPAG Paging: IMSI-901700000010650:MSISDN-46071 for MNCC: establish call: Starting paging + paging request (CALL_CONVERSATIONAL) to IMSI-901700000010650:MSISDN-46071 on GERAN-A + strcmp(paging_expecting_imsi, vsub->imsi) == 0 +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + Paging: now used by 4 (attached,mncc_tx_to_gsm_cc,CC,Paging) +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - mncc_tx_to_gsm_cc: now used by 3 (attached,CC,Paging) + paging_sent == 1 +- MS replies with Paging Response, with Codec List (BSS Supported) = FR1 FR2 FR3 HR1 HR3 +- VLR accepts, MSC sends CC Setup with Bearer Capability = GSM + MSC <--GERAN-A-- MS: GSM48_MT_RR_PAG_RESP + new conn +DMSC msub_fsm{active}: Allocated +DMSC msc_a{MSC_A_ST_VALIDATE_L3}: Allocated +DMSC msc_a{MSC_A_ST_VALIDATE_L3}: is child of msub_fsm +DMSC msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_VALIDATE_L3 +DMSC dummy_msc_i{0}: Allocated +DMSC dummy_msc_i{0}: is child of msub_fsm +DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms) +DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3 +DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Complete Layer 3: Codec List (BSS Supported): GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111 +DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: RR GSM48_MT_RR_PAG_RESP +DRR msc_a(IMSI-901700000010650:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: Rx PAGING RESPONSE IMSI-901700000010650 +DREF msc_a(IMSI-901700000010650:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: + paging-response: now used by 2 (rx_from_ms,paging-response) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: Allocated +DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: is child of msc_a(IMSI-901700000010650:GERAN-A:PAGING_RESP) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: rev=R99 net=GERAN (no Auth) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + proc_arq_vlr_fn_init: now used by 4 (attached,CC,Paging,proc_arq_vlr_fn_init) +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + active-conn: now used by 5 (attached,CC,Paging,proc_arq_vlr_fn_init,active-conn) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi() +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_node2() +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_ciph() +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_vlr() +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_post_pres() +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_post_trace() +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_post_imei() +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: proc_arq_fsm_done(PASSED) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_DONE +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_DONE}: Process Access Request result: PASSED +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: Received Event MSC_A_EV_AUTHENTICATED +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: state_chg to MSC_A_ST_AUTHENTICATED +DPAG Paging: IMSI-901700000010650:MSISDN-46071 for MNCC: establish call: Paging Response action (success) +DPAG Paging: IMSI-901700000010650:MSISDN-46071 for MNCC: establish call: Removing Paging Request +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071 callref-0x423 tid-255) Paging succeeded +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: + cc: now used by 3 (rx_from_ms,paging-response,cc) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: Received Event MSC_A_EV_TRANSACTION_ACCEPTED +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: state_chg to MSC_A_ST_COMMUNICATING +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) starting timer T303 with 30 seconds +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) codecs: :0{GSM#3} (from: remote=1.2.3.4:56{GSM#3} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) new state NULL -> CALL_PRESENT +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_SETUP +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on GERAN-A +- DTAP --GERAN-A--> MS: GSM48_MT_CC_SETUP: 030504022080 +- DTAP matches expected message +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - Paging: now used by 4 (attached,CC,proc_arq_vlr_fn_init,active-conn) +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - paging-response: now used by 2 (rx_from_ms,cc) +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - proc_arq_vlr_fn_init: now used by 3 (attached,CC,active-conn) +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc) +- MS confirms call, we create a RAN-side RTP and forward MNCC_CALL_CONF_IND + MSC <--GERAN-A-- MS: GSM48_MT_CC_CALL_CONF +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms) +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP +DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_CALL_CONF +DCC trans(CC:CALL_PRESENT IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx CALL_CONF in state CALL_PRESENT +DCC trans(CC:CALL_PRESENT IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) stopping pending timer T303 +DCC trans(CC:CALL_PRESENT IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) starting timer T310 with 30 seconds +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Starting call assignment +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){ESTABLISHING}: Allocated +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){ESTABLISHING}: is child of msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP) +DCC trans(CC:CALL_PRESENT IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) codecs: :0{GSM#3} (from: remote=1.2.3.4:56{GSM#3} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) + MGW <--CRCX to RTP_TO_CN-- MSC: call_id=0x9 codecs=GSM#3 +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){UNINITIALIZED}: Allocated +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){UNINITIALIZED}: is child of call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP) +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-9:RTP_TO_CN:no-CI){UNINITIALIZED}: setting codecs to GSM#3 + MGW <--CRCX to RTP_TO_RAN-- MSC: call_id=0x9 codecs=GSM#3 +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){UNINITIALIZED}: Allocated +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){UNINITIALIZED}: is child of call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP) +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-9:RTP_TO_RAN:no-CI){UNINITIALIZED}: setting codecs to GSM#3 +DCC trans(CC:CALL_PRESENT IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) new state CALL_PRESENT -> MO_TERM_CALL_CONF +DMNCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) tx MNCC_CALL_CONF_IND + MSC --> MNCC: callref 0x423: MNCC_CALL_CONF_IND + +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc) +- VALIDATE_SDP OK: cc_to_mncc_tx_last_sdp == t->mt_tx_sdp_mncc_call_conf_ind == +- MGW acknowledges the CRCX to RAN, triggering Assignment with FR1 + MGW --CRCX OK to RTP_TO_RAN--> MSC +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){ESTABLISHING}: Received Event CALL_LEG_EV_RTP_STREAM_ADDR_AVAILABLE +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Received Event MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: MGW endpoint's RTP address available for the CI RTP_TO_RAN: 10.23.23.1:23 (osmux=no:-2) +DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) codecs: :0{GSM#3} (from: remote=1.2.3.4:56{GSM#3} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) +DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) Sending Assignment Command +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN encode: ASSIGNMENT_COMMAND on GERAN-A +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST +- VALIDATE_PERM_SPEECH OK: &bssap_assignment_command_last_channel_type == t->mt_tx_assignment_perm_speech == FR1 +- Assignment completes, triggering CRCX to CN +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN decode: ASSIGNMENT_COMPLETE +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-9:RTP_TO_RAN:no-CI){UNINITIALIZED}: no change: codecs already set to GSM#3 +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-9:RTP_TO_RAN:no-CI){UNINITIALIZED}: setting remote addr to 1.2.3.4:1234 +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-9:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Not committing: no MGW endpoint CI set up +DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) codecs: :0{GSM#3} (from: assigned=GSM#3 remote=1.2.3.4:56{GSM#3} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) +DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) Assignment Complete: RAN: GSM#3, CN: GSM#3 +DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) Assignment complete, but still waiting for the CRCX OK on the CN side RTP +- MNCC sends MNCC_RTP_CREATE, which first waits for the CN side RTP + MSC <-- MNCC: callref 0x423: MNCC_RTP_CREATE + +DMNCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx MNCC_RTP_CREATE +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Assignment for this trans already started earlier +- When the CN side RTP address is known, ack MNCC_RTP_CREATE + MGW --CRCX OK to RTP_TO_CN--> MSC +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){ESTABLISHING}: Received Event CALL_LEG_EV_RTP_STREAM_ADDR_AVAILABLE +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Received Event MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: MGW endpoint's RTP address available for the CI RTP_TO_CN: 10.23.23.1:23 (osmux=no:-2) +DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) codecs: 10.23.23.1:23{GSM#3} (from: assigned=GSM#3 remote=1.2.3.4:56{GSM#3} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) +DMNCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) tx MNCC_RTP_CREATE (RTP=10.23.23.1:23{GSM#3}) + MSC --> MNCC: callref 0x423: MNCC_RTP_CREATE +v=0
+o=OsmoMSC 0 0 IN IP4 10.23.23.1
+s=GSM Call
+c=IN IP4 10.23.23.1
+t=0 0
+m=audio 23 RTP/AVP 3
+a=rtpmap:3 GSM/8000
+a=ptime:20
+ +- VALIDATE_SDP OK: cc_to_mncc_tx_last_sdp == t->mt_tx_sdp_mncc_rtp_create == GSM +- Total time passed: 376.000296 s + MSC <--GERAN-A-- MS: GSM48_MT_CC_ALERTING +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms) +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP +DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_ALERTING +DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx ALERTING in state MO_TERM_CALL_CONF +DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) stopping pending timer T310 +DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) starting timer T301 with 180 seconds +DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) new state MO_TERM_CALL_CONF -> CALL_RECEIVED +DCC trans(CC:CALL_RECEIVED IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) codecs: 10.23.23.1:23{GSM#3} (from: assigned=GSM#3 remote=1.2.3.4:56{GSM#3} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) +DMNCC trans(CC:CALL_RECEIVED IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) tx MNCC_ALERT_IND (RTP=10.23.23.1:23{GSM#3}) + MSC --> MNCC: callref 0x423: MNCC_ALERT_IND +v=0
+o=OsmoMSC 0 0 IN IP4 10.23.23.1
+s=GSM Call
+c=IN IP4 10.23.23.1
+t=0 0
+m=audio 23 RTP/AVP 3
+a=rtpmap:3 GSM/8000
+a=ptime:20
+ +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc) +- VALIDATE_SDP OK: cc_to_mncc_tx_last_sdp == t->mt_tx_sdp_mncc_alert_ind == GSM +- Total time passed: 377.000319 s + MSC <--GERAN-A-- MS: GSM48_MT_CC_CONNECT +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms) +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP +DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_CONNECT +DCC trans(CC:CALL_RECEIVED IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx CONNECT in state CALL_RECEIVED +DCC trans(CC:CALL_RECEIVED IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) stopping pending timer T301 +DCC trans(CC:CALL_RECEIVED IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) new state CALL_RECEIVED -> CONNECT_REQUEST +DCC trans(CC:CONNECT_REQUEST IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) codecs: 10.23.23.1:23{GSM#3} (from: assigned=GSM#3 remote=1.2.3.4:56{GSM#3} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) +DMNCC trans(CC:CONNECT_REQUEST IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) tx MNCC_SETUP_CNF (RTP=10.23.23.1:23{GSM#3}) + MSC --> MNCC: callref 0x423: MNCC_SETUP_CNF +v=0
+o=OsmoMSC 0 0 IN IP4 10.23.23.1
+s=GSM Call
+c=IN IP4 10.23.23.1
+t=0 0
+m=audio 23 RTP/AVP 3
+a=rtpmap:3 GSM/8000
+a=ptime:20
+ +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc) +- VALIDATE_SDP OK: cc_to_mncc_tx_last_sdp == t->mt_tx_sdp_mncc_setup_cnf == GSM + MSC <-- MNCC: callref 0x423: MNCC_SETUP_COMPL_REQ + +DMNCC trans(CC:CONNECT_REQUEST IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx MNCC_SETUP_COMPL_REQ +DCC trans(CC:CONNECT_REQUEST IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) starting guard timer with 180 seconds +DCC trans(CC:CONNECT_REQUEST IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) new state CONNECT_REQUEST -> ACTIVE +DCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) stopping pending guard timer +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_CONNECT_ACK +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on GERAN-A +- DTAP --GERAN-A--> MS: GSM48_MT_CC_CONNECT_ACK: 030f +- DTAP matches expected message +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST + + +- RTP stream goes ahead, not shown here. +- Total time passed: 500.000364 s + + +- Call ends + MSC <--GERAN-A-- MS: GSM48_MT_CC_DISCONNECT +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms) +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP +DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_DISCONNECT +DCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx DISCONNECT in state ACTIVE +DCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) new state ACTIVE -> DISCONNECT_IND +DMNCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) tx MNCC_DISC_IND + MSC --> MNCC: callref 0x423: MNCC_DISC_IND + +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc) + MSC <-- MNCC: callref 0x423: MNCC_REL_REQ + +DMNCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx MNCC_REL_REQ +DCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) starting guard timer with 180 seconds +DCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) starting timer T308 with 10 seconds +DCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) new state DISCONNECT_IND -> RELEASE_REQ +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_RELEASE +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on GERAN-A +- DTAP --GERAN-A--> MS: GSM48_MT_CC_RELEASE: 032d +- DTAP matches expected message +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST + MSC <--GERAN-A-- MS: GSM48_MT_CC_RELEASE_COMPL +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms) +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP +DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_RELEASE_COMPL +DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx RELEASE_COMPL in state RELEASE_REQ +DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) stopping pending timer T308 +DMNCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) tx MNCC_REL_CNF + MSC --> MNCC: callref 0x423: MNCC_REL_CNF + +DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x0 tid-0) Freeing transaction +DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x0 tid-0) new state RELEASE_REQ -> NULL +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x0 tid-0) stopping pending guard timer +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - CC: now used by 2 (attached,active-conn) +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - cc: now used by 1 (rx_from_ms) +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 0 (-) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Received Event MSC_A_EV_UNUSED +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: state_chg to MSC_A_ST_RELEASING +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: Releasing: msc_a use is 0 (-) +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + msc_a_fsm_releasing_onenter: now used by 3 (attached,active-conn,msc_a_fsm_releasing_onenter) +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,active-conn,msc_a_fsm_releasing_onenter,vlr_subscr_cancel_attach_fsm) +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,active-conn,msc_a_fsm_releasing_onenter) +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){ESTABLISHING}: state_chg to RELEASING +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-9:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Terminating (cause = OSMO_FSM_TERM_PARENT) +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-9:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Removing from parent call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP) +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-9:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Deallocated +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-9:RTP_TO_CN:no-CI){UNINITIALIZED}: Terminating (cause = OSMO_FSM_TERM_PARENT) +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-9:RTP_TO_CN:no-CI){UNINITIALIZED}: Removing from parent call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP) +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-9:RTP_TO_CN:no-CI){UNINITIALIZED}: Deallocated +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){RELEASING}: Terminating (cause = OSMO_FSM_TERM_REGULAR) +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){RELEASING}: Removing from parent msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: Received Event MSC_EV_CALL_LEG_TERM +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){RELEASING}: Deallocated +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: + wait-Clear-Complete: now used by 1 (wait-Clear-Complete) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: RAN encode: CLEAR_COMMAND on GERAN-A +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - msc_a_fsm_releasing_onenter: now used by 2 (attached,active-conn) +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: RAN decode: CLEAR_COMPLETE +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: - wait-Clear-Complete: now used by 0 (-) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: Received Event MSC_A_EV_UNUSED +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: state_chg to MSC_A_ST_RELEASED +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASED}: Released: msc_a use is 0 (-) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_DONE}: Terminating in cascade, depth 2 (cause = OSMO_FSM_TERM_PARENT, caused by: msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP)) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_DONE}: Removing from parent msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_DONE}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASED}: Removing from parent msub_fsm +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASED}: max total use count was 3 +DMSC msub_fsm{active}: Received Event MSUB_EV_ROLE_TERMINATED +DMSC msub(IMSI-901700000010650:MSISDN-46071) MSC-A terminated +DMSC msub(IMSI-901700000010650:MSISDN-46071) 1 MSC-I still active +DMSC msub_fsm{active}: state_chg to terminating +DMSC msub_fsm{terminating}: Terminating in cascade, depth 2 (cause = OSMO_FSM_TERM_REGULAR, caused by: msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP)) +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Terminating in cascade, depth 3 (cause = OSMO_FSM_TERM_PARENT, caused by: msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP)) +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Removing from parent msub_fsm +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP) +DMSC msub(IMSI-901700000010650:MSISDN-46071) Free +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - active-conn: now used by 1 (attached) +DMSC msub_fsm{terminating}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASED}: Deallocated, including all deferred deallocations +- msub gone + llist_count(&msub_list) == 0 + + +- ======================== SUCCESS: MT call: FR1 picked by MO from Codec List (BSS Supported), MT hence also picks FR1 + + +- ======================== MO call: FR1 picked by MO from Bearer Cap, MT hence also picks FR1 +- CM Service Request with Codec List (BSS Supported) = FR1 FR2 FR3 HR1 HR3 + MSC <--GERAN-A-- MS: GSM48_MT_MM_CM_SERV_REQ + new conn +DMSC msub_fsm{active}: Allocated +DMSC msc_a{MSC_A_ST_VALIDATE_L3}: Allocated +DMSC msc_a{MSC_A_ST_VALIDATE_L3}: is child of msub_fsm +DMSC msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_VALIDATE_L3 +DMSC dummy_msc_i{0}: Allocated +DMSC dummy_msc_i{0}: is child of msub_fsm +DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms) +DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3 +DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Complete Layer 3: Codec List (BSS Supported): GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111 +DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: MM GSM48_MT_MM_CM_SERV_REQ +DMM msc_a(IMSI-901700000010650:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_VALIDATE_L3}: Rx CM SERVICE REQUEST cm_service_type=MO-Call +DREF msc_a(IMSI-901700000010650:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_VALIDATE_L3}: + cm_service_cc: now used by 2 (rx_from_ms,cm_service_cc) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: Allocated +DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: is child of msc_a(IMSI-901700000010650:GERAN-A:CM_SERVICE_REQ) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: rev=R99 net=GERAN (no Auth) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + proc_arq_vlr_fn_init: now used by 2 (attached,proc_arq_vlr_fn_init) +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + active-conn: now used by 3 (attached,proc_arq_vlr_fn_init,active-conn) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi() +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_node2() +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_ciph() +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_vlr() +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_post_pres() +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_post_trace() +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_post_imei() +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: proc_arq_fsm_done(PASSED) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_DONE +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_DONE}: Process Access Request result: PASSED +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: Sending DTAP: MM GSM48_MT_MM_CM_SERV_ACC +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN encode: DTAP on GERAN-A +- DTAP --GERAN-A--> MS: GSM48_MT_MM_CM_SERV_ACC: 0521 +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: Received Event MSC_A_EV_AUTHENTICATED +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: state_chg to MSC_A_ST_AUTHENTICATED +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - proc_arq_vlr_fn_init: now used by 2 (attached,active-conn) +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: - rx_from_ms: now used by 1 (cm_service_cc) + cm_service_result_sent == 1 +msc_a_is_accepted() == true +- MS sends CC SETUP with Bearer Capability = GSM + MSC <--GERAN-A-- MS: GSM48_MT_CC_SETUP +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: + rx_from_ms: now used by 2 (cm_service_cc,rx_from_ms) +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: RAN decode: DTAP +DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: Dispatching 04.08 message: CC GSM48_MT_CC_SETUP +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + CC: now used by 3 (attached,active-conn,CC) +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071 callref-0x80000006 tid-8) New transaction +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: Received Event MSC_A_EV_TRANSACTION_ACCEPTED +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: state_chg to MSC_A_ST_COMMUNICATING +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: + cc: now used by 3 (cm_service_cc,rx_from_ms,cc) +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - cm_service_cc: now used by 2 (rx_from_ms,cc) +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000006 tid-8) rx SETUP in state NULL +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000006 tid-8) starting guard timer with 180 seconds +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000006 tid-8) codecs: :0{GSM#3} (from: MS={GSM#3} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000006 tid-8) SETUP to 123 +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000006 tid-8) new state NULL -> INITIATED +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Starting call assignment +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){ESTABLISHING}: Allocated +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){ESTABLISHING}: is child of msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ) +DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000006 tid-8) codecs: :0{GSM#3} (from: MS={GSM#3} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) + MGW <--CRCX to RTP_TO_CN-- MSC: call_id=0xa codecs=GSM#3 +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){UNINITIALIZED}: Allocated +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){UNINITIALIZED}: is child of call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ) +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-10:RTP_TO_CN:no-CI){UNINITIALIZED}: setting codecs to GSM#3 + MGW <--CRCX to RTP_TO_RAN-- MSC: call_id=0xa codecs=GSM#3 +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){UNINITIALIZED}: Allocated +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){UNINITIALIZED}: is child of call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ) +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-10:RTP_TO_RAN:no-CI){UNINITIALIZED}: setting codecs to GSM#3 +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc) +- As soon as the MGW port towards CN is created, MNCC_SETUP_IND is triggered + MGW --CRCX OK to RTP_TO_CN--> MSC +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){ESTABLISHING}: Received Event CALL_LEG_EV_RTP_STREAM_ADDR_AVAILABLE +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Received Event MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: MGW endpoint's RTP address available for the CI RTP_TO_CN: 10.23.23.1:23 (osmux=no:-2) +DMNCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000006 tid-8) tx MNCC_SETUP_IND (RTP=10.23.23.1:23{GSM#3}) + MSC --> MNCC: callref 0x80000006: MNCC_SETUP_IND +v=0
+o=OsmoMSC 0 0 IN IP4 10.23.23.1
+s=GSM Call
+c=IN IP4 10.23.23.1
+t=0 0
+m=audio 23 RTP/AVP 3
+a=rtpmap:3 GSM/8000
+a=ptime:20
+ +- VALIDATE_SDP OK: cc_to_mncc_tx_last_sdp == t->mo_tx_sdp_mncc_setup_ind == GSM +- MNCC replies with MNCC_RTP_CREATE + MSC <-- MNCC: callref 0x80000006: MNCC_RTP_CREATE + +DMNCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000006 tid-8) rx MNCC_RTP_CREATE +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Assignment for this trans already started earlier +- MGW acknowledges the CRCX, triggering Assignment with FR1 + MGW --CRCX OK to RTP_TO_RAN--> MSC +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){ESTABLISHING}: Received Event CALL_LEG_EV_RTP_STREAM_ADDR_AVAILABLE +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Received Event MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: MGW endpoint's RTP address available for the CI RTP_TO_RAN: 10.23.23.1:23 (osmux=no:-2) +DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000006 tid-8) codecs: 10.23.23.1:23{GSM#3} (from: MS={GSM#3} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) +DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000006 tid-8) Sending Assignment Command +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN encode: ASSIGNMENT_COMMAND on GERAN-A +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST +- VALIDATE_PERM_SPEECH OK: &bssap_assignment_command_last_channel_type == t->mo_tx_assignment_perm_speech == FR1 +- Assignment succeeds, triggering MNCC_RTP_CREATE ack to MNCC +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN decode: ASSIGNMENT_COMPLETE +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-10:RTP_TO_RAN:no-CI){UNINITIALIZED}: no change: codecs already set to GSM#3 +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-10:RTP_TO_RAN:no-CI){UNINITIALIZED}: setting remote addr to 1.2.3.4:1234 +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-10:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Not committing: no MGW endpoint CI set up +DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000006 tid-8) codecs: 10.23.23.1:23{GSM#3} (from: assigned=GSM#3 MS={GSM#3} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) +DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000006 tid-8) Assignment Complete: RAN: GSM#3, CN: GSM#3 +DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000006 tid-8) codecs: 10.23.23.1:23{GSM#3} (from: assigned=GSM#3 MS={GSM#3} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) +DMNCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000006 tid-8) tx MNCC_RTP_CREATE (RTP=10.23.23.1:23{GSM#3}) + MSC --> MNCC: callref 0x80000006: MNCC_RTP_CREATE +v=0
+o=OsmoMSC 0 0 IN IP4 10.23.23.1
+s=GSM Call
+c=IN IP4 10.23.23.1
+t=0 0
+m=audio 23 RTP/AVP 3
+a=rtpmap:3 GSM/8000
+a=ptime:20
+ +- VALIDATE_SDP OK: cc_to_mncc_tx_last_sdp == t->mo_tx_sdp_mncc_rtp_create == GSM +- MNCC says that's fine + MSC <-- MNCC: callref 0x80000006: MNCC_CALL_PROC_REQ + +DMNCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000006 tid-8) rx MNCC_CALL_PROC_REQ +DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000006 tid-8) stopping pending guard timer +DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000006 tid-8) starting guard timer with 180 seconds +DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000006 tid-8) new state INITIATED -> MO_CALL_PROC +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_CALL_PROC +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on GERAN-A +- DTAP --GERAN-A--> MS: GSM48_MT_CC_CALL_PROC: 8302 +- DTAP matches expected message +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Assignment for this trans already started earlier +- Total time passed: 501.000387 s +- The other call leg got established (not shown here), MNCC tells us so, with codecs { GSM } + MSC <-- MNCC: callref 0x80000006: MNCC_ALERT_REQ +v=0
+o=OsmoMSC 0 0 IN IP4 1.2.3.4
+s=GSM Call
+c=IN IP4 1.2.3.4
+t=0 0
+m=audio 56 RTP/AVP 3
+a=rtpmap:3 GSM/8000
+a=ptime:20
+ +DMNCC trans(CC:MO_CALL_PROC IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000006 tid-8) rx MNCC_ALERT_REQ (RTP=1.2.3.4:56{GSM#3}) +DCC trans(CC:MO_CALL_PROC IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000006 tid-8) stopping pending guard timer +DCC trans(CC:MO_CALL_PROC IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000006 tid-8) starting guard timer with 180 seconds +DCC trans(CC:MO_CALL_PROC IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000006 tid-8) new state MO_CALL_PROC -> CALL_DELIVERED +DCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000006 tid-8) codecs: 10.23.23.1:23{GSM#3} (from: assigned=GSM#3 remote=1.2.3.4:56{GSM#3} MS={GSM#3} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-10:RTP_TO_CN:no-CI){UNINITIALIZED}: no change: codecs already set to GSM#3 +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-10:RTP_TO_CN:no-CI){UNINITIALIZED}: setting remote addr to 1.2.3.4:56 +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-10:RTP_TO_CN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-56){UNINITIALIZED}: Not committing: no MGW endpoint CI set up +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_ALERTING +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on GERAN-A +- DTAP --GERAN-A--> MS: GSM48_MT_CC_ALERTING: 8301 +- DTAP matches expected message +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST + MSC <-- MNCC: callref 0x80000006: MNCC_SETUP_RSP +v=0
+o=OsmoMSC 0 0 IN IP4 1.2.3.4
+s=GSM Call
+c=IN IP4 1.2.3.4
+t=0 0
+m=audio 56 RTP/AVP 3
+a=rtpmap:3 GSM/8000
+a=ptime:20
+ +DMNCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000006 tid-8) rx MNCC_SETUP_RSP (RTP=1.2.3.4:56{GSM#3}) +DCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000006 tid-8) stopping pending guard timer +DCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000006 tid-8) starting guard timer with 180 seconds +DCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000006 tid-8) starting timer T313 with 30 seconds +DCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000006 tid-8) new state CALL_DELIVERED -> CONNECT_IND +DCC trans(CC:CONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000006 tid-8) codecs: 10.23.23.1:23{GSM#3} (from: assigned=GSM#3 remote=1.2.3.4:56{GSM#3} MS={GSM#3} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-10:RTP_TO_CN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-56){UNINITIALIZED}: no change: codecs already set to GSM#3 +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-10:RTP_TO_CN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-56){UNINITIALIZED}: remote addr already 1.2.3.4:56, no change +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-10:RTP_TO_CN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-56){UNINITIALIZED}: Not committing: no MGW endpoint CI set up +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_CONNECT +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on GERAN-A +- DTAP --GERAN-A--> MS: GSM48_MT_CC_CONNECT: 8307 +- DTAP matches expected message +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST +- Total time passed: 502.000410 s + MSC <--GERAN-A-- MS: GSM48_MT_CC_CONNECT_ACK +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms) +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP +DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_CONNECT_ACK +DCC trans(CC:CONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000006 tid-8) rx CONNECT_ACK in state CONNECT_IND +DCC trans(CC:CONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000006 tid-8) stopping pending timer T313 +DCC trans(CC:CONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000006 tid-8) new state CONNECT_IND -> ACTIVE +DCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000006 tid-8) stopping pending guard timer +DMNCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000006 tid-8) tx MNCC_SETUP_COMPL_IND + MSC --> MNCC: callref 0x80000006: MNCC_SETUP_COMPL_IND + +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc) +- VALIDATE_SDP OK: cc_to_mncc_tx_last_sdp == t->mo_tx_sdp_mncc_setup_compl_ind == + + +- RTP stream goes ahead, not shown here. +- Total time passed: 625.000455 s + + +- Call ends + MSC <--GERAN-A-- MS: GSM48_MT_CC_DISCONNECT +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms) +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP +DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_DISCONNECT +DCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000006 tid-8) rx DISCONNECT in state ACTIVE +DCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000006 tid-8) new state ACTIVE -> DISCONNECT_IND +DMNCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000006 tid-8) tx MNCC_DISC_IND + MSC --> MNCC: callref 0x80000006: MNCC_DISC_IND + +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc) + MSC <-- MNCC: callref 0x80000006: MNCC_REL_REQ +v=0
+o=OsmoMSC 0 0 IN IP4 1.2.3.4
+s=GSM Call
+c=IN IP4 1.2.3.4
+t=0 0
+m=audio 56 RTP/AVP 3
+a=rtpmap:3 GSM/8000
+a=ptime:20
+ +DMNCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000006 tid-8) rx MNCC_REL_REQ +DCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000006 tid-8) starting guard timer with 180 seconds +DCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000006 tid-8) starting timer T308 with 10 seconds +DCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000006 tid-8) new state DISCONNECT_IND -> RELEASE_REQ +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_RELEASE +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on GERAN-A +- DTAP --GERAN-A--> MS: GSM48_MT_CC_RELEASE: 832d +- DTAP matches expected message +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST + MSC <--GERAN-A-- MS: GSM48_MT_CC_RELEASE_COMPL +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms) +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP +DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_RELEASE_COMPL +DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000006 tid-8) rx RELEASE_COMPL in state RELEASE_REQ +DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000006 tid-8) stopping pending timer T308 +DMNCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000006 tid-8) tx MNCC_REL_CNF + MSC --> MNCC: callref 0x80000006: MNCC_REL_CNF + +DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x0 tid-8) Freeing transaction +DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x0 tid-8) new state RELEASE_REQ -> NULL +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x0 tid-8) stopping pending guard timer +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - CC: now used by 2 (attached,active-conn) +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - cc: now used by 1 (rx_from_ms) +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 0 (-) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Received Event MSC_A_EV_UNUSED +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: state_chg to MSC_A_ST_RELEASING +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: Releasing: msc_a use is 0 (-) +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + msc_a_fsm_releasing_onenter: now used by 3 (attached,active-conn,msc_a_fsm_releasing_onenter) +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,active-conn,msc_a_fsm_releasing_onenter,vlr_subscr_cancel_attach_fsm) +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,active-conn,msc_a_fsm_releasing_onenter) +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){ESTABLISHING}: state_chg to RELEASING +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-10:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Terminating (cause = OSMO_FSM_TERM_PARENT) +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-10:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Removing from parent call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ) +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-10:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Deallocated +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-10:RTP_TO_CN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-56){UNINITIALIZED}: Terminating (cause = OSMO_FSM_TERM_PARENT) +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-10:RTP_TO_CN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-56){UNINITIALIZED}: Removing from parent call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ) +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-10:RTP_TO_CN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-56){UNINITIALIZED}: Deallocated +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){RELEASING}: Terminating (cause = OSMO_FSM_TERM_REGULAR) +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){RELEASING}: Removing from parent msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: Received Event MSC_EV_CALL_LEG_TERM +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){RELEASING}: Deallocated +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: + wait-Clear-Complete: now used by 1 (wait-Clear-Complete) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: RAN encode: CLEAR_COMMAND on GERAN-A +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - msc_a_fsm_releasing_onenter: now used by 2 (attached,active-conn) +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: RAN decode: CLEAR_COMPLETE +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: - wait-Clear-Complete: now used by 0 (-) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: Received Event MSC_A_EV_UNUSED +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: state_chg to MSC_A_ST_RELEASED +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASED}: Released: msc_a use is 0 (-) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_DONE}: Terminating in cascade, depth 2 (cause = OSMO_FSM_TERM_PARENT, caused by: msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ)) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_DONE}: Removing from parent msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_DONE}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASED}: Removing from parent msub_fsm +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASED}: max total use count was 3 +DMSC msub_fsm{active}: Received Event MSUB_EV_ROLE_TERMINATED +DMSC msub(IMSI-901700000010650:MSISDN-46071) MSC-A terminated +DMSC msub(IMSI-901700000010650:MSISDN-46071) 1 MSC-I still active +DMSC msub_fsm{active}: state_chg to terminating +DMSC msub_fsm{terminating}: Terminating in cascade, depth 2 (cause = OSMO_FSM_TERM_REGULAR, caused by: msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ)) +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Terminating in cascade, depth 3 (cause = OSMO_FSM_TERM_PARENT, caused by: msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ)) +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Removing from parent msub_fsm +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ) +DMSC msub(IMSI-901700000010650:MSISDN-46071) Free +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - active-conn: now used by 1 (attached) +DMSC msub_fsm{terminating}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASED}: Deallocated, including all deferred deallocations +- msub gone + llist_count(&msub_list) == 0 + + +- ======================== SUCCESS: MO call: FR1 picked by MO from Bearer Cap, MT hence also picks FR1 + + +- ======================== MT call: FR1 picked by MO from Bearer Cap, MT hence also picks FR1 + + +- MNCC asks us to setup a call, causing Paging + MSC <-- MNCC: callref 0x423: MNCC_SETUP_REQ +v=0
+o=OsmoMSC 0 0 IN IP4 1.2.3.4
+s=GSM Call
+c=IN IP4 1.2.3.4
+t=0 0
+m=audio 56 RTP/AVP 3
+a=rtpmap:3 GSM/8000
+a=ptime:20
+ +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + mncc_tx_to_gsm_cc: now used by 2 (attached,mncc_tx_to_gsm_cc) +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + CC: now used by 3 (attached,mncc_tx_to_gsm_cc,CC) +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071 callref-0x423 tid-255) New transaction +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071 callref-0x423 tid-255) codecs: :0{(no-codecs)} (from: remote=1.2.3.4:56{GSM#3} RAN={(no-codecs)}) +DMNCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071 callref-0x423 tid-255) rx MNCC_SETUP_REQ (RTP=1.2.3.4:56{GSM#3}) +DPAG Paging: IMSI-901700000010650:MSISDN-46071 for MNCC: establish call: Starting paging + paging request (CALL_CONVERSATIONAL) to IMSI-901700000010650:MSISDN-46071 on GERAN-A + strcmp(paging_expecting_imsi, vsub->imsi) == 0 +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + Paging: now used by 4 (attached,mncc_tx_to_gsm_cc,CC,Paging) +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - mncc_tx_to_gsm_cc: now used by 3 (attached,CC,Paging) + paging_sent == 1 +- MS replies with Paging Response, with Codec List (BSS Supported) = FR1 FR2 FR3 HR1 HR3 +- VLR accepts, MSC sends CC Setup with Bearer Capability = GSM + MSC <--GERAN-A-- MS: GSM48_MT_RR_PAG_RESP + new conn +DMSC msub_fsm{active}: Allocated +DMSC msc_a{MSC_A_ST_VALIDATE_L3}: Allocated +DMSC msc_a{MSC_A_ST_VALIDATE_L3}: is child of msub_fsm +DMSC msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_VALIDATE_L3 +DMSC dummy_msc_i{0}: Allocated +DMSC dummy_msc_i{0}: is child of msub_fsm +DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms) +DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3 +DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Complete Layer 3: Codec List (BSS Supported): GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111 +DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: RR GSM48_MT_RR_PAG_RESP +DRR msc_a(IMSI-901700000010650:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: Rx PAGING RESPONSE IMSI-901700000010650 +DREF msc_a(IMSI-901700000010650:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: + paging-response: now used by 2 (rx_from_ms,paging-response) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: Allocated +DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: is child of msc_a(IMSI-901700000010650:GERAN-A:PAGING_RESP) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: rev=R99 net=GERAN (no Auth) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + proc_arq_vlr_fn_init: now used by 4 (attached,CC,Paging,proc_arq_vlr_fn_init) +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + active-conn: now used by 5 (attached,CC,Paging,proc_arq_vlr_fn_init,active-conn) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi() +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_node2() +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_ciph() +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_vlr() +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_post_pres() +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_post_trace() +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_post_imei() +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: proc_arq_fsm_done(PASSED) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_DONE +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_DONE}: Process Access Request result: PASSED +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: Received Event MSC_A_EV_AUTHENTICATED +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: state_chg to MSC_A_ST_AUTHENTICATED +DPAG Paging: IMSI-901700000010650:MSISDN-46071 for MNCC: establish call: Paging Response action (success) +DPAG Paging: IMSI-901700000010650:MSISDN-46071 for MNCC: establish call: Removing Paging Request +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071 callref-0x423 tid-255) Paging succeeded +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: + cc: now used by 3 (rx_from_ms,paging-response,cc) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: Received Event MSC_A_EV_TRANSACTION_ACCEPTED +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: state_chg to MSC_A_ST_COMMUNICATING +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) starting timer T303 with 30 seconds +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) codecs: :0{GSM#3} (from: remote=1.2.3.4:56{GSM#3} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) new state NULL -> CALL_PRESENT +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_SETUP +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on GERAN-A +- DTAP --GERAN-A--> MS: GSM48_MT_CC_SETUP: 030504022080 +- DTAP matches expected message +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - Paging: now used by 4 (attached,CC,proc_arq_vlr_fn_init,active-conn) +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - paging-response: now used by 2 (rx_from_ms,cc) +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - proc_arq_vlr_fn_init: now used by 3 (attached,CC,active-conn) +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc) +- MS confirms call, we create a RAN-side RTP and forward MNCC_CALL_CONF_IND + MSC <--GERAN-A-- MS: GSM48_MT_CC_CALL_CONF +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms) +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP +DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_CALL_CONF +DCC trans(CC:CALL_PRESENT IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx CALL_CONF in state CALL_PRESENT +DCC trans(CC:CALL_PRESENT IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) stopping pending timer T303 +DCC trans(CC:CALL_PRESENT IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) starting timer T310 with 30 seconds +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Starting call assignment +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){ESTABLISHING}: Allocated +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){ESTABLISHING}: is child of msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP) +DCC trans(CC:CALL_PRESENT IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) codecs: :0{GSM#3} (from: remote=1.2.3.4:56{GSM#3} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) + MGW <--CRCX to RTP_TO_CN-- MSC: call_id=0xb codecs=GSM#3 +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){UNINITIALIZED}: Allocated +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){UNINITIALIZED}: is child of call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP) +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-11:RTP_TO_CN:no-CI){UNINITIALIZED}: setting codecs to GSM#3 + MGW <--CRCX to RTP_TO_RAN-- MSC: call_id=0xb codecs=GSM#3 +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){UNINITIALIZED}: Allocated +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){UNINITIALIZED}: is child of call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP) +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-11:RTP_TO_RAN:no-CI){UNINITIALIZED}: setting codecs to GSM#3 +DCC trans(CC:CALL_PRESENT IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) new state CALL_PRESENT -> MO_TERM_CALL_CONF +DMNCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) tx MNCC_CALL_CONF_IND + MSC --> MNCC: callref 0x423: MNCC_CALL_CONF_IND + +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc) +- VALIDATE_SDP OK: cc_to_mncc_tx_last_sdp == t->mt_tx_sdp_mncc_call_conf_ind == +- MGW acknowledges the CRCX to RAN, triggering Assignment with FR1 + MGW --CRCX OK to RTP_TO_RAN--> MSC +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){ESTABLISHING}: Received Event CALL_LEG_EV_RTP_STREAM_ADDR_AVAILABLE +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Received Event MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: MGW endpoint's RTP address available for the CI RTP_TO_RAN: 10.23.23.1:23 (osmux=no:-2) +DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) codecs: :0{GSM#3} (from: remote=1.2.3.4:56{GSM#3} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) +DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) Sending Assignment Command +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN encode: ASSIGNMENT_COMMAND on GERAN-A +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST +- VALIDATE_PERM_SPEECH OK: &bssap_assignment_command_last_channel_type == t->mt_tx_assignment_perm_speech == FR1 +- Assignment completes, triggering CRCX to CN +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN decode: ASSIGNMENT_COMPLETE +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-11:RTP_TO_RAN:no-CI){UNINITIALIZED}: no change: codecs already set to GSM#3 +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-11:RTP_TO_RAN:no-CI){UNINITIALIZED}: setting remote addr to 1.2.3.4:1234 +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-11:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Not committing: no MGW endpoint CI set up +DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) codecs: :0{GSM#3} (from: assigned=GSM#3 remote=1.2.3.4:56{GSM#3} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) +DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) Assignment Complete: RAN: GSM#3, CN: GSM#3 +DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) Assignment complete, but still waiting for the CRCX OK on the CN side RTP +- MNCC sends MNCC_RTP_CREATE, which first waits for the CN side RTP + MSC <-- MNCC: callref 0x423: MNCC_RTP_CREATE + +DMNCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx MNCC_RTP_CREATE +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Assignment for this trans already started earlier +- When the CN side RTP address is known, ack MNCC_RTP_CREATE + MGW --CRCX OK to RTP_TO_CN--> MSC +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){ESTABLISHING}: Received Event CALL_LEG_EV_RTP_STREAM_ADDR_AVAILABLE +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Received Event MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: MGW endpoint's RTP address available for the CI RTP_TO_CN: 10.23.23.1:23 (osmux=no:-2) +DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) codecs: 10.23.23.1:23{GSM#3} (from: assigned=GSM#3 remote=1.2.3.4:56{GSM#3} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) +DMNCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) tx MNCC_RTP_CREATE (RTP=10.23.23.1:23{GSM#3}) + MSC --> MNCC: callref 0x423: MNCC_RTP_CREATE +v=0
+o=OsmoMSC 0 0 IN IP4 10.23.23.1
+s=GSM Call
+c=IN IP4 10.23.23.1
+t=0 0
+m=audio 23 RTP/AVP 3
+a=rtpmap:3 GSM/8000
+a=ptime:20
+ +- VALIDATE_SDP OK: cc_to_mncc_tx_last_sdp == t->mt_tx_sdp_mncc_rtp_create == GSM +- Total time passed: 626.000478 s + MSC <--GERAN-A-- MS: GSM48_MT_CC_ALERTING +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms) +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP +DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_ALERTING +DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx ALERTING in state MO_TERM_CALL_CONF +DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) stopping pending timer T310 +DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) starting timer T301 with 180 seconds +DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) new state MO_TERM_CALL_CONF -> CALL_RECEIVED +DCC trans(CC:CALL_RECEIVED IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) codecs: 10.23.23.1:23{GSM#3} (from: assigned=GSM#3 remote=1.2.3.4:56{GSM#3} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) +DMNCC trans(CC:CALL_RECEIVED IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) tx MNCC_ALERT_IND (RTP=10.23.23.1:23{GSM#3}) + MSC --> MNCC: callref 0x423: MNCC_ALERT_IND +v=0
+o=OsmoMSC 0 0 IN IP4 10.23.23.1
+s=GSM Call
+c=IN IP4 10.23.23.1
+t=0 0
+m=audio 23 RTP/AVP 3
+a=rtpmap:3 GSM/8000
+a=ptime:20
+ +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc) +- VALIDATE_SDP OK: cc_to_mncc_tx_last_sdp == t->mt_tx_sdp_mncc_alert_ind == GSM +- Total time passed: 627.000501 s + MSC <--GERAN-A-- MS: GSM48_MT_CC_CONNECT +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms) +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP +DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_CONNECT +DCC trans(CC:CALL_RECEIVED IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx CONNECT in state CALL_RECEIVED +DCC trans(CC:CALL_RECEIVED IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) stopping pending timer T301 +DCC trans(CC:CALL_RECEIVED IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) new state CALL_RECEIVED -> CONNECT_REQUEST +DCC trans(CC:CONNECT_REQUEST IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) codecs: 10.23.23.1:23{GSM#3} (from: assigned=GSM#3 remote=1.2.3.4:56{GSM#3} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) +DMNCC trans(CC:CONNECT_REQUEST IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) tx MNCC_SETUP_CNF (RTP=10.23.23.1:23{GSM#3}) + MSC --> MNCC: callref 0x423: MNCC_SETUP_CNF +v=0
+o=OsmoMSC 0 0 IN IP4 10.23.23.1
+s=GSM Call
+c=IN IP4 10.23.23.1
+t=0 0
+m=audio 23 RTP/AVP 3
+a=rtpmap:3 GSM/8000
+a=ptime:20
+ +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc) +- VALIDATE_SDP OK: cc_to_mncc_tx_last_sdp == t->mt_tx_sdp_mncc_setup_cnf == GSM + MSC <-- MNCC: callref 0x423: MNCC_SETUP_COMPL_REQ + +DMNCC trans(CC:CONNECT_REQUEST IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx MNCC_SETUP_COMPL_REQ +DCC trans(CC:CONNECT_REQUEST IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) starting guard timer with 180 seconds +DCC trans(CC:CONNECT_REQUEST IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) new state CONNECT_REQUEST -> ACTIVE +DCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) stopping pending guard timer +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_CONNECT_ACK +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on GERAN-A +- DTAP --GERAN-A--> MS: GSM48_MT_CC_CONNECT_ACK: 030f +- DTAP matches expected message +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST + + +- RTP stream goes ahead, not shown here. +- Total time passed: 750.000546 s + + +- Call ends + MSC <--GERAN-A-- MS: GSM48_MT_CC_DISCONNECT +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms) +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP +DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_DISCONNECT +DCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx DISCONNECT in state ACTIVE +DCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) new state ACTIVE -> DISCONNECT_IND +DMNCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) tx MNCC_DISC_IND + MSC --> MNCC: callref 0x423: MNCC_DISC_IND + +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc) + MSC <-- MNCC: callref 0x423: MNCC_REL_REQ + +DMNCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx MNCC_REL_REQ +DCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) starting guard timer with 180 seconds +DCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) starting timer T308 with 10 seconds +DCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) new state DISCONNECT_IND -> RELEASE_REQ +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_RELEASE +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on GERAN-A +- DTAP --GERAN-A--> MS: GSM48_MT_CC_RELEASE: 032d +- DTAP matches expected message +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST + MSC <--GERAN-A-- MS: GSM48_MT_CC_RELEASE_COMPL +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms) +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP +DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_RELEASE_COMPL +DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx RELEASE_COMPL in state RELEASE_REQ +DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) stopping pending timer T308 +DMNCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) tx MNCC_REL_CNF + MSC --> MNCC: callref 0x423: MNCC_REL_CNF + +DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x0 tid-0) Freeing transaction +DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x0 tid-0) new state RELEASE_REQ -> NULL +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x0 tid-0) stopping pending guard timer +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - CC: now used by 2 (attached,active-conn) +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - cc: now used by 1 (rx_from_ms) +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 0 (-) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Received Event MSC_A_EV_UNUSED +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: state_chg to MSC_A_ST_RELEASING +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: Releasing: msc_a use is 0 (-) +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + msc_a_fsm_releasing_onenter: now used by 3 (attached,active-conn,msc_a_fsm_releasing_onenter) +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,active-conn,msc_a_fsm_releasing_onenter,vlr_subscr_cancel_attach_fsm) +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,active-conn,msc_a_fsm_releasing_onenter) +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){ESTABLISHING}: state_chg to RELEASING +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-11:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Terminating (cause = OSMO_FSM_TERM_PARENT) +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-11:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Removing from parent call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP) +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-11:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Deallocated +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-11:RTP_TO_CN:no-CI){UNINITIALIZED}: Terminating (cause = OSMO_FSM_TERM_PARENT) +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-11:RTP_TO_CN:no-CI){UNINITIALIZED}: Removing from parent call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP) +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-11:RTP_TO_CN:no-CI){UNINITIALIZED}: Deallocated +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){RELEASING}: Terminating (cause = OSMO_FSM_TERM_REGULAR) +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){RELEASING}: Removing from parent msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: Received Event MSC_EV_CALL_LEG_TERM +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){RELEASING}: Deallocated +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: + wait-Clear-Complete: now used by 1 (wait-Clear-Complete) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: RAN encode: CLEAR_COMMAND on GERAN-A +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - msc_a_fsm_releasing_onenter: now used by 2 (attached,active-conn) +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: RAN decode: CLEAR_COMPLETE +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: - wait-Clear-Complete: now used by 0 (-) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: Received Event MSC_A_EV_UNUSED +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: state_chg to MSC_A_ST_RELEASED +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASED}: Released: msc_a use is 0 (-) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_DONE}: Terminating in cascade, depth 2 (cause = OSMO_FSM_TERM_PARENT, caused by: msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP)) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_DONE}: Removing from parent msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_DONE}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASED}: Removing from parent msub_fsm +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASED}: max total use count was 3 +DMSC msub_fsm{active}: Received Event MSUB_EV_ROLE_TERMINATED +DMSC msub(IMSI-901700000010650:MSISDN-46071) MSC-A terminated +DMSC msub(IMSI-901700000010650:MSISDN-46071) 1 MSC-I still active +DMSC msub_fsm{active}: state_chg to terminating +DMSC msub_fsm{terminating}: Terminating in cascade, depth 2 (cause = OSMO_FSM_TERM_REGULAR, caused by: msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP)) +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Terminating in cascade, depth 3 (cause = OSMO_FSM_TERM_PARENT, caused by: msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP)) +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Removing from parent msub_fsm +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP) +DMSC msub(IMSI-901700000010650:MSISDN-46071) Free +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - active-conn: now used by 1 (attached) +DMSC msub_fsm{terminating}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASED}: Deallocated, including all deferred deallocations +- msub gone + llist_count(&msub_list) == 0 + + +- ======================== SUCCESS: MT call: FR1 picked by MO from Bearer Cap, MT hence also picks FR1 + + +- ======================== MO call: FR1 picked by MT's Codec List (BSS Supported), hence MO re-assigns to FR1 +- CM Service Request with Codec List (BSS Supported) = FR1 FR2 FR3 HR1 HR3 + MSC <--GERAN-A-- MS: GSM48_MT_MM_CM_SERV_REQ + new conn +DMSC msub_fsm{active}: Allocated +DMSC msc_a{MSC_A_ST_VALIDATE_L3}: Allocated +DMSC msc_a{MSC_A_ST_VALIDATE_L3}: is child of msub_fsm +DMSC msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_VALIDATE_L3 +DMSC dummy_msc_i{0}: Allocated +DMSC dummy_msc_i{0}: is child of msub_fsm +DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms) +DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3 +DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Complete Layer 3: Codec List (BSS Supported): GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111 +DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: MM GSM48_MT_MM_CM_SERV_REQ +DMM msc_a(IMSI-901700000010650:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_VALIDATE_L3}: Rx CM SERVICE REQUEST cm_service_type=MO-Call +DREF msc_a(IMSI-901700000010650:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_VALIDATE_L3}: + cm_service_cc: now used by 2 (rx_from_ms,cm_service_cc) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: Allocated +DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: is child of msc_a(IMSI-901700000010650:GERAN-A:CM_SERVICE_REQ) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: rev=R99 net=GERAN (no Auth) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + proc_arq_vlr_fn_init: now used by 2 (attached,proc_arq_vlr_fn_init) +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + active-conn: now used by 3 (attached,proc_arq_vlr_fn_init,active-conn) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi() +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_node2() +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_ciph() +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_vlr() +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_post_pres() +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_post_trace() +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_post_imei() +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: proc_arq_fsm_done(PASSED) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_DONE +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_DONE}: Process Access Request result: PASSED +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: Sending DTAP: MM GSM48_MT_MM_CM_SERV_ACC +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN encode: DTAP on GERAN-A +- DTAP --GERAN-A--> MS: GSM48_MT_MM_CM_SERV_ACC: 0521 +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: Received Event MSC_A_EV_AUTHENTICATED +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: state_chg to MSC_A_ST_AUTHENTICATED +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - proc_arq_vlr_fn_init: now used by 2 (attached,active-conn) +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: - rx_from_ms: now used by 1 (cm_service_cc) + cm_service_result_sent == 1 +msc_a_is_accepted() == true +- MS sends CC SETUP with Bearer Capability = AMR AMR AMR GSM-EFR GSM GSM-HR-08 + MSC <--GERAN-A-- MS: GSM48_MT_CC_SETUP +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: + rx_from_ms: now used by 2 (cm_service_cc,rx_from_ms) +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: RAN decode: DTAP +DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: Dispatching 04.08 message: CC GSM48_MT_CC_SETUP +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + CC: now used by 3 (attached,active-conn,CC) +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071 callref-0x80000007 tid-8) New transaction +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: Received Event MSC_A_EV_TRANSACTION_ACCEPTED +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: state_chg to MSC_A_ST_COMMUNICATING +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: + cc: now used by 3 (cm_service_cc,rx_from_ms,cc) +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - cm_service_cc: now used by 2 (rx_from_ms,cc) +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000007 tid-8) rx SETUP in state NULL +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000007 tid-8) starting guard timer with 180 seconds +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000007 tid-8) codecs: :0{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} (from: MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000007 tid-8) SETUP to 123 +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000007 tid-8) new state NULL -> INITIATED +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Starting call assignment +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){ESTABLISHING}: Allocated +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){ESTABLISHING}: is child of msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ) +DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000007 tid-8) codecs: :0{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} (from: MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) + MGW <--CRCX to RTP_TO_CN-- MSC: call_id=0xc codecs=AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111 +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){UNINITIALIZED}: Allocated +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){UNINITIALIZED}: is child of call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ) +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-12:RTP_TO_CN:no-CI){UNINITIALIZED}: setting codecs to AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111 + MGW <--CRCX to RTP_TO_RAN-- MSC: call_id=0xc codecs=AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111 +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){UNINITIALIZED}: Allocated +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){UNINITIALIZED}: is child of call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ) +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-12:RTP_TO_RAN:no-CI){UNINITIALIZED}: setting codecs to AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111 +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc) +- As soon as the MGW port towards CN is created, MNCC_SETUP_IND is triggered + MGW --CRCX OK to RTP_TO_CN--> MSC +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){ESTABLISHING}: Received Event CALL_LEG_EV_RTP_STREAM_ADDR_AVAILABLE +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Received Event MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: MGW endpoint's RTP address available for the CI RTP_TO_CN: 10.23.23.1:23 (osmux=no:-2) +DMNCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000007 tid-8) tx MNCC_SETUP_IND (RTP=10.23.23.1:23{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) + MSC --> MNCC: callref 0x80000007: MNCC_SETUP_IND +v=0
+o=OsmoMSC 0 0 IN IP4 10.23.23.1
+s=GSM Call
+c=IN IP4 10.23.23.1
+t=0 0
+m=audio 23 RTP/AVP 112 110 3 111
+a=rtpmap:112 AMR/8000
+a=fmtp:112 octet-align=1
+a=rtpmap:110 GSM-EFR/8000
+a=rtpmap:3 GSM/8000
+a=rtpmap:111 GSM-HR-08/8000
+a=ptime:20
+ +- VALIDATE_SDP OK: cc_to_mncc_tx_last_sdp == t->mo_tx_sdp_mncc_setup_ind == AMR GSM-EFR GSM GSM-HR-08 +- MNCC replies with MNCC_RTP_CREATE + MSC <-- MNCC: callref 0x80000007: MNCC_RTP_CREATE + +DMNCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000007 tid-8) rx MNCC_RTP_CREATE +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Assignment for this trans already started earlier +- MGW acknowledges the CRCX, triggering Assignment with FR3 HR3 FR2 FR1 HR1 + MGW --CRCX OK to RTP_TO_RAN--> MSC +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){ESTABLISHING}: Received Event CALL_LEG_EV_RTP_STREAM_ADDR_AVAILABLE +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Received Event MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: MGW endpoint's RTP address available for the CI RTP_TO_RAN: 10.23.23.1:23 (osmux=no:-2) +DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000007 tid-8) codecs: 10.23.23.1:23{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} (from: MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) +DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000007 tid-8) Sending Assignment Command +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN encode: ASSIGNMENT_COMMAND on GERAN-A +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST +- VALIDATE_PERM_SPEECH OK: &bssap_assignment_command_last_channel_type == t->mo_tx_assignment_perm_speech == FR3 HR3 FR2 FR1 HR1 +- Assignment succeeds, triggering MNCC_RTP_CREATE ack to MNCC +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN decode: ASSIGNMENT_COMPLETE +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-12:RTP_TO_RAN:no-CI){UNINITIALIZED}: setting codecs to AMR:octet-align=1#112 +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-12:RTP_TO_RAN:no-CI:local-10-23-23-1-23){UNINITIALIZED}: setting remote addr to 1.2.3.4:1234 +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-12:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Not committing: no MGW endpoint CI set up +DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000007 tid-8) codecs: 10.23.23.1:23{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} (from: assigned=AMR:octet-align=1#112 MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) +DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000007 tid-8) Assignment Complete: RAN: AMR:octet-align=1#112, CN: AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111 +DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000007 tid-8) codecs: 10.23.23.1:23{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} (from: assigned=AMR:octet-align=1#112 MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) +DMNCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000007 tid-8) tx MNCC_RTP_CREATE (RTP=10.23.23.1:23{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) + MSC --> MNCC: callref 0x80000007: MNCC_RTP_CREATE +v=0
+o=OsmoMSC 0 0 IN IP4 10.23.23.1
+s=GSM Call
+c=IN IP4 10.23.23.1
+t=0 0
+m=audio 23 RTP/AVP 112 110 3 111
+a=rtpmap:112 AMR/8000
+a=fmtp:112 octet-align=1
+a=rtpmap:110 GSM-EFR/8000
+a=rtpmap:3 GSM/8000
+a=rtpmap:111 GSM-HR-08/8000
+a=ptime:20
+ +- VALIDATE_SDP OK: cc_to_mncc_tx_last_sdp == t->mo_tx_sdp_mncc_rtp_create == AMR GSM-EFR GSM GSM-HR-08 +- MNCC says that's fine + MSC <-- MNCC: callref 0x80000007: MNCC_CALL_PROC_REQ + +DMNCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000007 tid-8) rx MNCC_CALL_PROC_REQ +DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000007 tid-8) stopping pending guard timer +DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000007 tid-8) starting guard timer with 180 seconds +DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000007 tid-8) new state INITIATED -> MO_CALL_PROC +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_CALL_PROC +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on GERAN-A +- DTAP --GERAN-A--> MS: GSM48_MT_CC_CALL_PROC: 8302 +- DTAP matches expected message +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Assignment for this trans already started earlier +- Total time passed: 751.000569 s +- The other call leg got established (not shown here), MNCC tells us so, with codecs { GSM } +- Expecting re-assignment + MSC <-- MNCC: callref 0x80000007: MNCC_ALERT_REQ +v=0
+o=OsmoMSC 0 0 IN IP4 1.2.3.4
+s=GSM Call
+c=IN IP4 1.2.3.4
+t=0 0
+m=audio 56 RTP/AVP 3
+a=rtpmap:3 GSM/8000
+a=ptime:20
+ +DMNCC trans(CC:MO_CALL_PROC IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000007 tid-8) rx MNCC_ALERT_REQ (RTP=1.2.3.4:56{GSM#3}) +DCC trans(CC:MO_CALL_PROC IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000007 tid-8) stopping pending guard timer +DCC trans(CC:MO_CALL_PROC IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000007 tid-8) starting guard timer with 180 seconds +DCC trans(CC:MO_CALL_PROC IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000007 tid-8) new state MO_CALL_PROC -> CALL_DELIVERED +DCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000007 tid-8) codecs: 10.23.23.1:23{GSM#3} (from: assigned=AMR:octet-align=1#112 remote=1.2.3.4:56{GSM#3} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-12:RTP_TO_CN:no-CI){UNINITIALIZED}: setting codecs to GSM#3 +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-12:RTP_TO_CN:no-CI:local-10-23-23-1-23){UNINITIALIZED}: setting remote addr to 1.2.3.4:56 +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-12:RTP_TO_CN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-56){UNINITIALIZED}: Not committing: no MGW endpoint CI set up +DCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000007 tid-8) Remote call leg mismatches assigned codec: 10.23.23.1:23{GSM#3} (from: assigned=AMR:octet-align=1#112 remote=1.2.3.4:56{GSM#3} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) +DCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000007 tid-8) codecs: 10.23.23.1:23{GSM#3} (from: assigned=AMR:octet-align=1#112 remote=1.2.3.4:56{GSM#3} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) +DCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000007 tid-8) Sending Assignment Command +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN encode: ASSIGNMENT_COMMAND on GERAN-A +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_ALERTING +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on GERAN-A +- DTAP --GERAN-A--> MS: GSM48_MT_CC_ALERTING: 8301 +- DTAP matches expected message +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST +- Validating re-assignment +- VALIDATE_PERM_SPEECH OK: &bssap_assignment_command_last_channel_type == t->mo_tx_reassignment_perm_speech == FR1 +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN decode: ASSIGNMENT_COMPLETE +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-12:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: setting codecs to GSM#3 +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-12:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: remote addr already 1.2.3.4:1234, no change +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-12:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Not committing: no MGW endpoint CI set up +DCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000007 tid-8) codecs: 10.23.23.1:23{GSM#3} (from: assigned=GSM#3 remote=1.2.3.4:56{GSM#3} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) +DCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000007 tid-8) Assignment Complete: RAN: GSM#3, CN: GSM#3 +DCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000007 tid-8) Re-Assignment complete + MSC <-- MNCC: callref 0x80000007: MNCC_SETUP_RSP +v=0
+o=OsmoMSC 0 0 IN IP4 1.2.3.4
+s=GSM Call
+c=IN IP4 1.2.3.4
+t=0 0
+m=audio 56 RTP/AVP 3
+a=rtpmap:3 GSM/8000
+a=ptime:20
+ +DMNCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000007 tid-8) rx MNCC_SETUP_RSP (RTP=1.2.3.4:56{GSM#3}) +DCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000007 tid-8) stopping pending guard timer +DCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000007 tid-8) starting guard timer with 180 seconds +DCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000007 tid-8) starting timer T313 with 30 seconds +DCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000007 tid-8) new state CALL_DELIVERED -> CONNECT_IND +DCC trans(CC:CONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000007 tid-8) codecs: 10.23.23.1:23{GSM#3} (from: assigned=GSM#3 remote=1.2.3.4:56{GSM#3} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-12:RTP_TO_CN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-56){UNINITIALIZED}: no change: codecs already set to GSM#3 +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-12:RTP_TO_CN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-56){UNINITIALIZED}: remote addr already 1.2.3.4:56, no change +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-12:RTP_TO_CN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-56){UNINITIALIZED}: Not committing: no MGW endpoint CI set up +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_CONNECT +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on GERAN-A +- DTAP --GERAN-A--> MS: GSM48_MT_CC_CONNECT: 8307 +- DTAP matches expected message +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST +- Total time passed: 752.000592 s + MSC <--GERAN-A-- MS: GSM48_MT_CC_CONNECT_ACK +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms) +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP +DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_CONNECT_ACK +DCC trans(CC:CONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000007 tid-8) rx CONNECT_ACK in state CONNECT_IND +DCC trans(CC:CONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000007 tid-8) stopping pending timer T313 +DCC trans(CC:CONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000007 tid-8) new state CONNECT_IND -> ACTIVE +DCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000007 tid-8) stopping pending guard timer +DMNCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000007 tid-8) tx MNCC_SETUP_COMPL_IND + MSC --> MNCC: callref 0x80000007: MNCC_SETUP_COMPL_IND + +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc) +- VALIDATE_SDP OK: cc_to_mncc_tx_last_sdp == t->mo_tx_sdp_mncc_setup_compl_ind == + + +- RTP stream goes ahead, not shown here. +- Total time passed: 875.000637 s + + +- Call ends + MSC <--GERAN-A-- MS: GSM48_MT_CC_DISCONNECT +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms) +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP +DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_DISCONNECT +DCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000007 tid-8) rx DISCONNECT in state ACTIVE +DCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000007 tid-8) new state ACTIVE -> DISCONNECT_IND +DMNCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000007 tid-8) tx MNCC_DISC_IND + MSC --> MNCC: callref 0x80000007: MNCC_DISC_IND + +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc) + MSC <-- MNCC: callref 0x80000007: MNCC_REL_REQ +v=0
+o=OsmoMSC 0 0 IN IP4 1.2.3.4
+s=GSM Call
+c=IN IP4 1.2.3.4
+t=0 0
+m=audio 56 RTP/AVP 3
+a=rtpmap:3 GSM/8000
+a=ptime:20
+ +DMNCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000007 tid-8) rx MNCC_REL_REQ +DCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000007 tid-8) starting guard timer with 180 seconds +DCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000007 tid-8) starting timer T308 with 10 seconds +DCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000007 tid-8) new state DISCONNECT_IND -> RELEASE_REQ +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_RELEASE +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on GERAN-A +- DTAP --GERAN-A--> MS: GSM48_MT_CC_RELEASE: 832d +- DTAP matches expected message +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST + MSC <--GERAN-A-- MS: GSM48_MT_CC_RELEASE_COMPL +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms) +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP +DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_RELEASE_COMPL +DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000007 tid-8) rx RELEASE_COMPL in state RELEASE_REQ +DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000007 tid-8) stopping pending timer T308 +DMNCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000007 tid-8) tx MNCC_REL_CNF + MSC --> MNCC: callref 0x80000007: MNCC_REL_CNF + +DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x0 tid-8) Freeing transaction +DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x0 tid-8) new state RELEASE_REQ -> NULL +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x0 tid-8) stopping pending guard timer +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - CC: now used by 2 (attached,active-conn) +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - cc: now used by 1 (rx_from_ms) +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 0 (-) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Received Event MSC_A_EV_UNUSED +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: state_chg to MSC_A_ST_RELEASING +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: Releasing: msc_a use is 0 (-) +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + msc_a_fsm_releasing_onenter: now used by 3 (attached,active-conn,msc_a_fsm_releasing_onenter) +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,active-conn,msc_a_fsm_releasing_onenter,vlr_subscr_cancel_attach_fsm) +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,active-conn,msc_a_fsm_releasing_onenter) +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){ESTABLISHING}: state_chg to RELEASING +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-12:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Terminating (cause = OSMO_FSM_TERM_PARENT) +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-12:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Removing from parent call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ) +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-12:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Deallocated +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-12:RTP_TO_CN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-56){UNINITIALIZED}: Terminating (cause = OSMO_FSM_TERM_PARENT) +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-12:RTP_TO_CN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-56){UNINITIALIZED}: Removing from parent call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ) +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-12:RTP_TO_CN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-56){UNINITIALIZED}: Deallocated +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){RELEASING}: Terminating (cause = OSMO_FSM_TERM_REGULAR) +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){RELEASING}: Removing from parent msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: Received Event MSC_EV_CALL_LEG_TERM +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){RELEASING}: Deallocated +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: + wait-Clear-Complete: now used by 1 (wait-Clear-Complete) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: RAN encode: CLEAR_COMMAND on GERAN-A +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - msc_a_fsm_releasing_onenter: now used by 2 (attached,active-conn) +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: RAN decode: CLEAR_COMPLETE +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: - wait-Clear-Complete: now used by 0 (-) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: Received Event MSC_A_EV_UNUSED +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: state_chg to MSC_A_ST_RELEASED +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASED}: Released: msc_a use is 0 (-) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_DONE}: Terminating in cascade, depth 2 (cause = OSMO_FSM_TERM_PARENT, caused by: msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ)) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_DONE}: Removing from parent msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_DONE}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASED}: Removing from parent msub_fsm +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASED}: max total use count was 3 +DMSC msub_fsm{active}: Received Event MSUB_EV_ROLE_TERMINATED +DMSC msub(IMSI-901700000010650:MSISDN-46071) MSC-A terminated +DMSC msub(IMSI-901700000010650:MSISDN-46071) 1 MSC-I still active +DMSC msub_fsm{active}: state_chg to terminating +DMSC msub_fsm{terminating}: Terminating in cascade, depth 2 (cause = OSMO_FSM_TERM_REGULAR, caused by: msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ)) +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Terminating in cascade, depth 3 (cause = OSMO_FSM_TERM_PARENT, caused by: msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ)) +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Removing from parent msub_fsm +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ) +DMSC msub(IMSI-901700000010650:MSISDN-46071) Free +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - active-conn: now used by 1 (attached) +DMSC msub_fsm{terminating}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASED}: Deallocated, including all deferred deallocations +- msub gone + llist_count(&msub_list) == 0 + + +- ======================== SUCCESS: MO call: FR1 picked by MT's Codec List (BSS Supported), hence MO re-assigns to FR1 + + +- ======================== MT call: FR1 picked by MT's Codec List (BSS Supported), hence MO re-assigns to FR1 + + +- MNCC asks us to setup a call, causing Paging + MSC <-- MNCC: callref 0x423: MNCC_SETUP_REQ +v=0
+o=OsmoMSC 0 0 IN IP4 1.2.3.4
+s=GSM Call
+c=IN IP4 1.2.3.4
+t=0 0
+m=audio 56 RTP/AVP 112 110 3 111
+a=rtpmap:112 AMR/8000
+a=fmtp:112 octet-align=1
+a=rtpmap:110 GSM-EFR/8000
+a=rtpmap:3 GSM/8000
+a=rtpmap:111 GSM-HR-08/8000
+a=ptime:20
+ +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + mncc_tx_to_gsm_cc: now used by 2 (attached,mncc_tx_to_gsm_cc) +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + CC: now used by 3 (attached,mncc_tx_to_gsm_cc,CC) +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071 callref-0x423 tid-255) New transaction +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071 callref-0x423 tid-255) codecs: :0{(no-codecs)} (from: remote=1.2.3.4:56{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} RAN={(no-codecs)}) +DMNCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071 callref-0x423 tid-255) rx MNCC_SETUP_REQ (RTP=1.2.3.4:56{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) +DPAG Paging: IMSI-901700000010650:MSISDN-46071 for MNCC: establish call: Starting paging + paging request (CALL_CONVERSATIONAL) to IMSI-901700000010650:MSISDN-46071 on GERAN-A + strcmp(paging_expecting_imsi, vsub->imsi) == 0 +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + Paging: now used by 4 (attached,mncc_tx_to_gsm_cc,CC,Paging) +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - mncc_tx_to_gsm_cc: now used by 3 (attached,CC,Paging) + paging_sent == 1 +- MS replies with Paging Response, with Codec List (BSS Supported) = FR1 +- VLR accepts, MSC sends CC Setup with Bearer Capability = GSM + MSC <--GERAN-A-- MS: GSM48_MT_RR_PAG_RESP + new conn +DMSC msub_fsm{active}: Allocated +DMSC msc_a{MSC_A_ST_VALIDATE_L3}: Allocated +DMSC msc_a{MSC_A_ST_VALIDATE_L3}: is child of msub_fsm +DMSC msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_VALIDATE_L3 +DMSC dummy_msc_i{0}: Allocated +DMSC dummy_msc_i{0}: is child of msub_fsm +DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms) +DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3 +DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Complete Layer 3: Codec List (BSS Supported): GSM#3 +DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: RR GSM48_MT_RR_PAG_RESP +DRR msc_a(IMSI-901700000010650:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: Rx PAGING RESPONSE IMSI-901700000010650 +DREF msc_a(IMSI-901700000010650:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: + paging-response: now used by 2 (rx_from_ms,paging-response) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: Allocated +DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: is child of msc_a(IMSI-901700000010650:GERAN-A:PAGING_RESP) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: rev=R99 net=GERAN (no Auth) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + proc_arq_vlr_fn_init: now used by 4 (attached,CC,Paging,proc_arq_vlr_fn_init) +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + active-conn: now used by 5 (attached,CC,Paging,proc_arq_vlr_fn_init,active-conn) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi() +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_node2() +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_ciph() +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_vlr() +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_post_pres() +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_post_trace() +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_post_imei() +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: proc_arq_fsm_done(PASSED) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_DONE +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_DONE}: Process Access Request result: PASSED +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: Received Event MSC_A_EV_AUTHENTICATED +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: state_chg to MSC_A_ST_AUTHENTICATED +DPAG Paging: IMSI-901700000010650:MSISDN-46071 for MNCC: establish call: Paging Response action (success) +DPAG Paging: IMSI-901700000010650:MSISDN-46071 for MNCC: establish call: Removing Paging Request +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071 callref-0x423 tid-255) Paging succeeded +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: + cc: now used by 3 (rx_from_ms,paging-response,cc) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: Received Event MSC_A_EV_TRANSACTION_ACCEPTED +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: state_chg to MSC_A_ST_COMMUNICATING +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) starting timer T303 with 30 seconds +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) codecs: :0{GSM#3} (from: remote=1.2.3.4:56{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) new state NULL -> CALL_PRESENT +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_SETUP +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on GERAN-A +- DTAP --GERAN-A--> MS: GSM48_MT_CC_SETUP: 030504022080 +- DTAP matches expected message +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - Paging: now used by 4 (attached,CC,proc_arq_vlr_fn_init,active-conn) +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - paging-response: now used by 2 (rx_from_ms,cc) +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - proc_arq_vlr_fn_init: now used by 3 (attached,CC,active-conn) +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc) +- MS confirms call, we create a RAN-side RTP and forward MNCC_CALL_CONF_IND + MSC <--GERAN-A-- MS: GSM48_MT_CC_CALL_CONF +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms) +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP +DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_CALL_CONF +DCC trans(CC:CALL_PRESENT IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx CALL_CONF in state CALL_PRESENT +DCC trans(CC:CALL_PRESENT IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) stopping pending timer T303 +DCC trans(CC:CALL_PRESENT IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) starting timer T310 with 30 seconds +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Starting call assignment +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){ESTABLISHING}: Allocated +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){ESTABLISHING}: is child of msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP) +DCC trans(CC:CALL_PRESENT IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) codecs: :0{GSM#3} (from: remote=1.2.3.4:56{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) + MGW <--CRCX to RTP_TO_CN-- MSC: call_id=0xd codecs=GSM#3 +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){UNINITIALIZED}: Allocated +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){UNINITIALIZED}: is child of call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP) +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-13:RTP_TO_CN:no-CI){UNINITIALIZED}: setting codecs to GSM#3 + MGW <--CRCX to RTP_TO_RAN-- MSC: call_id=0xd codecs=GSM#3 +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){UNINITIALIZED}: Allocated +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){UNINITIALIZED}: is child of call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP) +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-13:RTP_TO_RAN:no-CI){UNINITIALIZED}: setting codecs to GSM#3 +DCC trans(CC:CALL_PRESENT IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) new state CALL_PRESENT -> MO_TERM_CALL_CONF +DMNCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) tx MNCC_CALL_CONF_IND + MSC --> MNCC: callref 0x423: MNCC_CALL_CONF_IND + +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc) +- VALIDATE_SDP OK: cc_to_mncc_tx_last_sdp == t->mt_tx_sdp_mncc_call_conf_ind == +- MGW acknowledges the CRCX to RAN, triggering Assignment with FR1 + MGW --CRCX OK to RTP_TO_RAN--> MSC +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){ESTABLISHING}: Received Event CALL_LEG_EV_RTP_STREAM_ADDR_AVAILABLE +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Received Event MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: MGW endpoint's RTP address available for the CI RTP_TO_RAN: 10.23.23.1:23 (osmux=no:-2) +DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) codecs: :0{GSM#3} (from: remote=1.2.3.4:56{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) +DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) Sending Assignment Command +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN encode: ASSIGNMENT_COMMAND on GERAN-A +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST +- VALIDATE_PERM_SPEECH OK: &bssap_assignment_command_last_channel_type == t->mt_tx_assignment_perm_speech == FR1 +- Assignment completes, triggering CRCX to CN +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN decode: ASSIGNMENT_COMPLETE +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-13:RTP_TO_RAN:no-CI){UNINITIALIZED}: no change: codecs already set to GSM#3 +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-13:RTP_TO_RAN:no-CI){UNINITIALIZED}: setting remote addr to 1.2.3.4:1234 +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-13:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Not committing: no MGW endpoint CI set up +DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) codecs: :0{GSM#3} (from: assigned=GSM#3 remote=1.2.3.4:56{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) +DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) Assignment Complete: RAN: GSM#3, CN: GSM#3 +DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) Assignment complete, but still waiting for the CRCX OK on the CN side RTP +- MNCC sends MNCC_RTP_CREATE, which first waits for the CN side RTP + MSC <-- MNCC: callref 0x423: MNCC_RTP_CREATE + +DMNCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx MNCC_RTP_CREATE +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Assignment for this trans already started earlier +- When the CN side RTP address is known, ack MNCC_RTP_CREATE + MGW --CRCX OK to RTP_TO_CN--> MSC +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){ESTABLISHING}: Received Event CALL_LEG_EV_RTP_STREAM_ADDR_AVAILABLE +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Received Event MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: MGW endpoint's RTP address available for the CI RTP_TO_CN: 10.23.23.1:23 (osmux=no:-2) +DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) codecs: 10.23.23.1:23{GSM#3} (from: assigned=GSM#3 remote=1.2.3.4:56{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) +DMNCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) tx MNCC_RTP_CREATE (RTP=10.23.23.1:23{GSM#3}) + MSC --> MNCC: callref 0x423: MNCC_RTP_CREATE +v=0
+o=OsmoMSC 0 0 IN IP4 10.23.23.1
+s=GSM Call
+c=IN IP4 10.23.23.1
+t=0 0
+m=audio 23 RTP/AVP 3
+a=rtpmap:3 GSM/8000
+a=ptime:20
+ +- VALIDATE_SDP OK: cc_to_mncc_tx_last_sdp == t->mt_tx_sdp_mncc_rtp_create == GSM +- Total time passed: 876.000660 s + MSC <--GERAN-A-- MS: GSM48_MT_CC_ALERTING +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms) +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP +DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_ALERTING +DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx ALERTING in state MO_TERM_CALL_CONF +DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) stopping pending timer T310 +DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) starting timer T301 with 180 seconds +DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) new state MO_TERM_CALL_CONF -> CALL_RECEIVED +DCC trans(CC:CALL_RECEIVED IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) codecs: 10.23.23.1:23{GSM#3} (from: assigned=GSM#3 remote=1.2.3.4:56{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) +DMNCC trans(CC:CALL_RECEIVED IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) tx MNCC_ALERT_IND (RTP=10.23.23.1:23{GSM#3}) + MSC --> MNCC: callref 0x423: MNCC_ALERT_IND +v=0
+o=OsmoMSC 0 0 IN IP4 10.23.23.1
+s=GSM Call
+c=IN IP4 10.23.23.1
+t=0 0
+m=audio 23 RTP/AVP 3
+a=rtpmap:3 GSM/8000
+a=ptime:20
+ +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc) +- VALIDATE_SDP OK: cc_to_mncc_tx_last_sdp == t->mt_tx_sdp_mncc_alert_ind == GSM +- Total time passed: 877.000683 s + MSC <--GERAN-A-- MS: GSM48_MT_CC_CONNECT +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms) +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP +DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_CONNECT +DCC trans(CC:CALL_RECEIVED IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx CONNECT in state CALL_RECEIVED +DCC trans(CC:CALL_RECEIVED IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) stopping pending timer T301 +DCC trans(CC:CALL_RECEIVED IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) new state CALL_RECEIVED -> CONNECT_REQUEST +DCC trans(CC:CONNECT_REQUEST IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) codecs: 10.23.23.1:23{GSM#3} (from: assigned=GSM#3 remote=1.2.3.4:56{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) +DMNCC trans(CC:CONNECT_REQUEST IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) tx MNCC_SETUP_CNF (RTP=10.23.23.1:23{GSM#3}) + MSC --> MNCC: callref 0x423: MNCC_SETUP_CNF +v=0
+o=OsmoMSC 0 0 IN IP4 10.23.23.1
+s=GSM Call
+c=IN IP4 10.23.23.1
+t=0 0
+m=audio 23 RTP/AVP 3
+a=rtpmap:3 GSM/8000
+a=ptime:20
+ +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc) +- VALIDATE_SDP OK: cc_to_mncc_tx_last_sdp == t->mt_tx_sdp_mncc_setup_cnf == GSM + MSC <-- MNCC: callref 0x423: MNCC_SETUP_COMPL_REQ + +DMNCC trans(CC:CONNECT_REQUEST IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx MNCC_SETUP_COMPL_REQ +DCC trans(CC:CONNECT_REQUEST IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) starting guard timer with 180 seconds +DCC trans(CC:CONNECT_REQUEST IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) new state CONNECT_REQUEST -> ACTIVE +DCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) stopping pending guard timer +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_CONNECT_ACK +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on GERAN-A +- DTAP --GERAN-A--> MS: GSM48_MT_CC_CONNECT_ACK: 030f +- DTAP matches expected message +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST + + +- RTP stream goes ahead, not shown here. +- Total time passed: 1000.000728 s + + +- Call ends + MSC <--GERAN-A-- MS: GSM48_MT_CC_DISCONNECT +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms) +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP +DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_DISCONNECT +DCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx DISCONNECT in state ACTIVE +DCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) new state ACTIVE -> DISCONNECT_IND +DMNCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) tx MNCC_DISC_IND + MSC --> MNCC: callref 0x423: MNCC_DISC_IND + +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc) + MSC <-- MNCC: callref 0x423: MNCC_REL_REQ + +DMNCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx MNCC_REL_REQ +DCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) starting guard timer with 180 seconds +DCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) starting timer T308 with 10 seconds +DCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) new state DISCONNECT_IND -> RELEASE_REQ +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_RELEASE +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on GERAN-A +- DTAP --GERAN-A--> MS: GSM48_MT_CC_RELEASE: 032d +- DTAP matches expected message +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST + MSC <--GERAN-A-- MS: GSM48_MT_CC_RELEASE_COMPL +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms) +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP +DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_RELEASE_COMPL +DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx RELEASE_COMPL in state RELEASE_REQ +DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) stopping pending timer T308 +DMNCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) tx MNCC_REL_CNF + MSC --> MNCC: callref 0x423: MNCC_REL_CNF + +DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x0 tid-0) Freeing transaction +DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x0 tid-0) new state RELEASE_REQ -> NULL +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x0 tid-0) stopping pending guard timer +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - CC: now used by 2 (attached,active-conn) +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - cc: now used by 1 (rx_from_ms) +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 0 (-) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Received Event MSC_A_EV_UNUSED +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: state_chg to MSC_A_ST_RELEASING +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: Releasing: msc_a use is 0 (-) +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + msc_a_fsm_releasing_onenter: now used by 3 (attached,active-conn,msc_a_fsm_releasing_onenter) +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,active-conn,msc_a_fsm_releasing_onenter,vlr_subscr_cancel_attach_fsm) +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,active-conn,msc_a_fsm_releasing_onenter) +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){ESTABLISHING}: state_chg to RELEASING +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-13:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Terminating (cause = OSMO_FSM_TERM_PARENT) +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-13:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Removing from parent call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP) +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-13:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Deallocated +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-13:RTP_TO_CN:no-CI){UNINITIALIZED}: Terminating (cause = OSMO_FSM_TERM_PARENT) +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-13:RTP_TO_CN:no-CI){UNINITIALIZED}: Removing from parent call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP) +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-13:RTP_TO_CN:no-CI){UNINITIALIZED}: Deallocated +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){RELEASING}: Terminating (cause = OSMO_FSM_TERM_REGULAR) +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){RELEASING}: Removing from parent msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: Received Event MSC_EV_CALL_LEG_TERM +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){RELEASING}: Deallocated +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: + wait-Clear-Complete: now used by 1 (wait-Clear-Complete) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: RAN encode: CLEAR_COMMAND on GERAN-A +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - msc_a_fsm_releasing_onenter: now used by 2 (attached,active-conn) +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: RAN decode: CLEAR_COMPLETE +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: - wait-Clear-Complete: now used by 0 (-) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: Received Event MSC_A_EV_UNUSED +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: state_chg to MSC_A_ST_RELEASED +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASED}: Released: msc_a use is 0 (-) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_DONE}: Terminating in cascade, depth 2 (cause = OSMO_FSM_TERM_PARENT, caused by: msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP)) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_DONE}: Removing from parent msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_DONE}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASED}: Removing from parent msub_fsm +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASED}: max total use count was 3 +DMSC msub_fsm{active}: Received Event MSUB_EV_ROLE_TERMINATED +DMSC msub(IMSI-901700000010650:MSISDN-46071) MSC-A terminated +DMSC msub(IMSI-901700000010650:MSISDN-46071) 1 MSC-I still active +DMSC msub_fsm{active}: state_chg to terminating +DMSC msub_fsm{terminating}: Terminating in cascade, depth 2 (cause = OSMO_FSM_TERM_REGULAR, caused by: msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP)) +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Terminating in cascade, depth 3 (cause = OSMO_FSM_TERM_PARENT, caused by: msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP)) +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Removing from parent msub_fsm +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP) +DMSC msub(IMSI-901700000010650:MSISDN-46071) Free +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - active-conn: now used by 1 (attached) +DMSC msub_fsm{terminating}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASED}: Deallocated, including all deferred deallocations +- msub gone + llist_count(&msub_list) == 0 + + +- ======================== SUCCESS: MT call: FR1 picked by MT's Codec List (BSS Supported), hence MO re-assigns to FR1 + + +- ======================== MO call: FR1 picked by MT's MS Bearer Capability, hence MO re-assigns to FR1 +- CM Service Request with Codec List (BSS Supported) = FR1 FR2 FR3 HR1 HR3 + MSC <--GERAN-A-- MS: GSM48_MT_MM_CM_SERV_REQ + new conn +DMSC msub_fsm{active}: Allocated +DMSC msc_a{MSC_A_ST_VALIDATE_L3}: Allocated +DMSC msc_a{MSC_A_ST_VALIDATE_L3}: is child of msub_fsm +DMSC msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_VALIDATE_L3 +DMSC dummy_msc_i{0}: Allocated +DMSC dummy_msc_i{0}: is child of msub_fsm +DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms) +DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3 +DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Complete Layer 3: Codec List (BSS Supported): GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111 +DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: MM GSM48_MT_MM_CM_SERV_REQ +DMM msc_a(IMSI-901700000010650:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_VALIDATE_L3}: Rx CM SERVICE REQUEST cm_service_type=MO-Call +DREF msc_a(IMSI-901700000010650:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_VALIDATE_L3}: + cm_service_cc: now used by 2 (rx_from_ms,cm_service_cc) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: Allocated +DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: is child of msc_a(IMSI-901700000010650:GERAN-A:CM_SERVICE_REQ) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: rev=R99 net=GERAN (no Auth) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + proc_arq_vlr_fn_init: now used by 2 (attached,proc_arq_vlr_fn_init) +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + active-conn: now used by 3 (attached,proc_arq_vlr_fn_init,active-conn) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi() +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_node2() +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_ciph() +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_vlr() +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_post_pres() +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_post_trace() +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_post_imei() +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: proc_arq_fsm_done(PASSED) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_DONE +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_DONE}: Process Access Request result: PASSED +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: Sending DTAP: MM GSM48_MT_MM_CM_SERV_ACC +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN encode: DTAP on GERAN-A +- DTAP --GERAN-A--> MS: GSM48_MT_MM_CM_SERV_ACC: 0521 +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: Received Event MSC_A_EV_AUTHENTICATED +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: state_chg to MSC_A_ST_AUTHENTICATED +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - proc_arq_vlr_fn_init: now used by 2 (attached,active-conn) +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: - rx_from_ms: now used by 1 (cm_service_cc) + cm_service_result_sent == 1 +msc_a_is_accepted() == true +- MS sends CC SETUP with Bearer Capability = AMR AMR AMR GSM-EFR GSM GSM-HR-08 + MSC <--GERAN-A-- MS: GSM48_MT_CC_SETUP +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: + rx_from_ms: now used by 2 (cm_service_cc,rx_from_ms) +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: RAN decode: DTAP +DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: Dispatching 04.08 message: CC GSM48_MT_CC_SETUP +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + CC: now used by 3 (attached,active-conn,CC) +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071 callref-0x80000008 tid-8) New transaction +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: Received Event MSC_A_EV_TRANSACTION_ACCEPTED +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: state_chg to MSC_A_ST_COMMUNICATING +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: + cc: now used by 3 (cm_service_cc,rx_from_ms,cc) +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - cm_service_cc: now used by 2 (rx_from_ms,cc) +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000008 tid-8) rx SETUP in state NULL +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000008 tid-8) starting guard timer with 180 seconds +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000008 tid-8) codecs: :0{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} (from: MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000008 tid-8) SETUP to 123 +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000008 tid-8) new state NULL -> INITIATED +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Starting call assignment +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){ESTABLISHING}: Allocated +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){ESTABLISHING}: is child of msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ) +DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000008 tid-8) codecs: :0{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} (from: MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) + MGW <--CRCX to RTP_TO_CN-- MSC: call_id=0xe codecs=AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111 +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){UNINITIALIZED}: Allocated +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){UNINITIALIZED}: is child of call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ) +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-14:RTP_TO_CN:no-CI){UNINITIALIZED}: setting codecs to AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111 + MGW <--CRCX to RTP_TO_RAN-- MSC: call_id=0xe codecs=AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111 +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){UNINITIALIZED}: Allocated +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){UNINITIALIZED}: is child of call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ) +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-14:RTP_TO_RAN:no-CI){UNINITIALIZED}: setting codecs to AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111 +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc) +- As soon as the MGW port towards CN is created, MNCC_SETUP_IND is triggered + MGW --CRCX OK to RTP_TO_CN--> MSC +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){ESTABLISHING}: Received Event CALL_LEG_EV_RTP_STREAM_ADDR_AVAILABLE +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Received Event MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: MGW endpoint's RTP address available for the CI RTP_TO_CN: 10.23.23.1:23 (osmux=no:-2) +DMNCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000008 tid-8) tx MNCC_SETUP_IND (RTP=10.23.23.1:23{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) + MSC --> MNCC: callref 0x80000008: MNCC_SETUP_IND +v=0
+o=OsmoMSC 0 0 IN IP4 10.23.23.1
+s=GSM Call
+c=IN IP4 10.23.23.1
+t=0 0
+m=audio 23 RTP/AVP 112 110 3 111
+a=rtpmap:112 AMR/8000
+a=fmtp:112 octet-align=1
+a=rtpmap:110 GSM-EFR/8000
+a=rtpmap:3 GSM/8000
+a=rtpmap:111 GSM-HR-08/8000
+a=ptime:20
+ +- VALIDATE_SDP OK: cc_to_mncc_tx_last_sdp == t->mo_tx_sdp_mncc_setup_ind == AMR GSM-EFR GSM GSM-HR-08 +- MNCC replies with MNCC_RTP_CREATE + MSC <-- MNCC: callref 0x80000008: MNCC_RTP_CREATE + +DMNCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000008 tid-8) rx MNCC_RTP_CREATE +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Assignment for this trans already started earlier +- MGW acknowledges the CRCX, triggering Assignment with FR3 HR3 FR2 FR1 HR1 + MGW --CRCX OK to RTP_TO_RAN--> MSC +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){ESTABLISHING}: Received Event CALL_LEG_EV_RTP_STREAM_ADDR_AVAILABLE +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Received Event MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: MGW endpoint's RTP address available for the CI RTP_TO_RAN: 10.23.23.1:23 (osmux=no:-2) +DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000008 tid-8) codecs: 10.23.23.1:23{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} (from: MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) +DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000008 tid-8) Sending Assignment Command +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN encode: ASSIGNMENT_COMMAND on GERAN-A +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST +- VALIDATE_PERM_SPEECH OK: &bssap_assignment_command_last_channel_type == t->mo_tx_assignment_perm_speech == FR3 HR3 FR2 FR1 HR1 +- Assignment succeeds, triggering MNCC_RTP_CREATE ack to MNCC +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN decode: ASSIGNMENT_COMPLETE +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-14:RTP_TO_RAN:no-CI){UNINITIALIZED}: setting codecs to AMR:octet-align=1#112 +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-14:RTP_TO_RAN:no-CI:local-10-23-23-1-23){UNINITIALIZED}: setting remote addr to 1.2.3.4:1234 +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-14:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Not committing: no MGW endpoint CI set up +DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000008 tid-8) codecs: 10.23.23.1:23{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} (from: assigned=AMR:octet-align=1#112 MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) +DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000008 tid-8) Assignment Complete: RAN: AMR:octet-align=1#112, CN: AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111 +DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000008 tid-8) codecs: 10.23.23.1:23{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} (from: assigned=AMR:octet-align=1#112 MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) +DMNCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000008 tid-8) tx MNCC_RTP_CREATE (RTP=10.23.23.1:23{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) + MSC --> MNCC: callref 0x80000008: MNCC_RTP_CREATE +v=0
+o=OsmoMSC 0 0 IN IP4 10.23.23.1
+s=GSM Call
+c=IN IP4 10.23.23.1
+t=0 0
+m=audio 23 RTP/AVP 112 110 3 111
+a=rtpmap:112 AMR/8000
+a=fmtp:112 octet-align=1
+a=rtpmap:110 GSM-EFR/8000
+a=rtpmap:3 GSM/8000
+a=rtpmap:111 GSM-HR-08/8000
+a=ptime:20
+ +- VALIDATE_SDP OK: cc_to_mncc_tx_last_sdp == t->mo_tx_sdp_mncc_rtp_create == AMR GSM-EFR GSM GSM-HR-08 +- MNCC says that's fine + MSC <-- MNCC: callref 0x80000008: MNCC_CALL_PROC_REQ + +DMNCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000008 tid-8) rx MNCC_CALL_PROC_REQ +DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000008 tid-8) stopping pending guard timer +DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000008 tid-8) starting guard timer with 180 seconds +DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000008 tid-8) new state INITIATED -> MO_CALL_PROC +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_CALL_PROC +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on GERAN-A +- DTAP --GERAN-A--> MS: GSM48_MT_CC_CALL_PROC: 8302 +- DTAP matches expected message +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Assignment for this trans already started earlier +- Total time passed: 1001.000751 s +- The other call leg got established (not shown here), MNCC tells us so, with codecs { GSM } +- Expecting re-assignment + MSC <-- MNCC: callref 0x80000008: MNCC_ALERT_REQ +v=0
+o=OsmoMSC 0 0 IN IP4 1.2.3.4
+s=GSM Call
+c=IN IP4 1.2.3.4
+t=0 0
+m=audio 56 RTP/AVP 3
+a=rtpmap:3 GSM/8000
+a=ptime:20
+ +DMNCC trans(CC:MO_CALL_PROC IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000008 tid-8) rx MNCC_ALERT_REQ (RTP=1.2.3.4:56{GSM#3}) +DCC trans(CC:MO_CALL_PROC IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000008 tid-8) stopping pending guard timer +DCC trans(CC:MO_CALL_PROC IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000008 tid-8) starting guard timer with 180 seconds +DCC trans(CC:MO_CALL_PROC IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000008 tid-8) new state MO_CALL_PROC -> CALL_DELIVERED +DCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000008 tid-8) codecs: 10.23.23.1:23{GSM#3} (from: assigned=AMR:octet-align=1#112 remote=1.2.3.4:56{GSM#3} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-14:RTP_TO_CN:no-CI){UNINITIALIZED}: setting codecs to GSM#3 +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-14:RTP_TO_CN:no-CI:local-10-23-23-1-23){UNINITIALIZED}: setting remote addr to 1.2.3.4:56 +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-14:RTP_TO_CN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-56){UNINITIALIZED}: Not committing: no MGW endpoint CI set up +DCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000008 tid-8) Remote call leg mismatches assigned codec: 10.23.23.1:23{GSM#3} (from: assigned=AMR:octet-align=1#112 remote=1.2.3.4:56{GSM#3} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) +DCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000008 tid-8) codecs: 10.23.23.1:23{GSM#3} (from: assigned=AMR:octet-align=1#112 remote=1.2.3.4:56{GSM#3} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) +DCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000008 tid-8) Sending Assignment Command +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN encode: ASSIGNMENT_COMMAND on GERAN-A +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_ALERTING +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on GERAN-A +- DTAP --GERAN-A--> MS: GSM48_MT_CC_ALERTING: 8301 +- DTAP matches expected message +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST +- Validating re-assignment +- VALIDATE_PERM_SPEECH OK: &bssap_assignment_command_last_channel_type == t->mo_tx_reassignment_perm_speech == FR1 +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN decode: ASSIGNMENT_COMPLETE +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-14:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: setting codecs to GSM#3 +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-14:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: remote addr already 1.2.3.4:1234, no change +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-14:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Not committing: no MGW endpoint CI set up +DCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000008 tid-8) codecs: 10.23.23.1:23{GSM#3} (from: assigned=GSM#3 remote=1.2.3.4:56{GSM#3} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) +DCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000008 tid-8) Assignment Complete: RAN: GSM#3, CN: GSM#3 +DCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000008 tid-8) Re-Assignment complete + MSC <-- MNCC: callref 0x80000008: MNCC_SETUP_RSP +v=0
+o=OsmoMSC 0 0 IN IP4 1.2.3.4
+s=GSM Call
+c=IN IP4 1.2.3.4
+t=0 0
+m=audio 56 RTP/AVP 3
+a=rtpmap:3 GSM/8000
+a=ptime:20
+ +DMNCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000008 tid-8) rx MNCC_SETUP_RSP (RTP=1.2.3.4:56{GSM#3}) +DCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000008 tid-8) stopping pending guard timer +DCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000008 tid-8) starting guard timer with 180 seconds +DCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000008 tid-8) starting timer T313 with 30 seconds +DCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000008 tid-8) new state CALL_DELIVERED -> CONNECT_IND +DCC trans(CC:CONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000008 tid-8) codecs: 10.23.23.1:23{GSM#3} (from: assigned=GSM#3 remote=1.2.3.4:56{GSM#3} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-14:RTP_TO_CN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-56){UNINITIALIZED}: no change: codecs already set to GSM#3 +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-14:RTP_TO_CN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-56){UNINITIALIZED}: remote addr already 1.2.3.4:56, no change +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-14:RTP_TO_CN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-56){UNINITIALIZED}: Not committing: no MGW endpoint CI set up +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_CONNECT +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on GERAN-A +- DTAP --GERAN-A--> MS: GSM48_MT_CC_CONNECT: 8307 +- DTAP matches expected message +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST +- Total time passed: 1002.000774 s + MSC <--GERAN-A-- MS: GSM48_MT_CC_CONNECT_ACK +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms) +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP +DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_CONNECT_ACK +DCC trans(CC:CONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000008 tid-8) rx CONNECT_ACK in state CONNECT_IND +DCC trans(CC:CONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000008 tid-8) stopping pending timer T313 +DCC trans(CC:CONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000008 tid-8) new state CONNECT_IND -> ACTIVE +DCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000008 tid-8) stopping pending guard timer +DMNCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000008 tid-8) tx MNCC_SETUP_COMPL_IND + MSC --> MNCC: callref 0x80000008: MNCC_SETUP_COMPL_IND + +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc) +- VALIDATE_SDP OK: cc_to_mncc_tx_last_sdp == t->mo_tx_sdp_mncc_setup_compl_ind == + + +- RTP stream goes ahead, not shown here. +- Total time passed: 1125.000819 s + + +- Call ends + MSC <--GERAN-A-- MS: GSM48_MT_CC_DISCONNECT +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms) +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP +DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_DISCONNECT +DCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000008 tid-8) rx DISCONNECT in state ACTIVE +DCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000008 tid-8) new state ACTIVE -> DISCONNECT_IND +DMNCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000008 tid-8) tx MNCC_DISC_IND + MSC --> MNCC: callref 0x80000008: MNCC_DISC_IND + +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc) + MSC <-- MNCC: callref 0x80000008: MNCC_REL_REQ +v=0
+o=OsmoMSC 0 0 IN IP4 1.2.3.4
+s=GSM Call
+c=IN IP4 1.2.3.4
+t=0 0
+m=audio 56 RTP/AVP 3
+a=rtpmap:3 GSM/8000
+a=ptime:20
+ +DMNCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000008 tid-8) rx MNCC_REL_REQ +DCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000008 tid-8) starting guard timer with 180 seconds +DCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000008 tid-8) starting timer T308 with 10 seconds +DCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000008 tid-8) new state DISCONNECT_IND -> RELEASE_REQ +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_RELEASE +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on GERAN-A +- DTAP --GERAN-A--> MS: GSM48_MT_CC_RELEASE: 832d +- DTAP matches expected message +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST + MSC <--GERAN-A-- MS: GSM48_MT_CC_RELEASE_COMPL +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms) +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP +DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_RELEASE_COMPL +DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000008 tid-8) rx RELEASE_COMPL in state RELEASE_REQ +DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000008 tid-8) stopping pending timer T308 +DMNCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000008 tid-8) tx MNCC_REL_CNF + MSC --> MNCC: callref 0x80000008: MNCC_REL_CNF + +DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x0 tid-8) Freeing transaction +DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x0 tid-8) new state RELEASE_REQ -> NULL +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x0 tid-8) stopping pending guard timer +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - CC: now used by 2 (attached,active-conn) +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - cc: now used by 1 (rx_from_ms) +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 0 (-) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Received Event MSC_A_EV_UNUSED +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: state_chg to MSC_A_ST_RELEASING +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: Releasing: msc_a use is 0 (-) +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + msc_a_fsm_releasing_onenter: now used by 3 (attached,active-conn,msc_a_fsm_releasing_onenter) +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,active-conn,msc_a_fsm_releasing_onenter,vlr_subscr_cancel_attach_fsm) +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,active-conn,msc_a_fsm_releasing_onenter) +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){ESTABLISHING}: state_chg to RELEASING +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-14:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Terminating (cause = OSMO_FSM_TERM_PARENT) +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-14:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Removing from parent call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ) +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-14:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Deallocated +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-14:RTP_TO_CN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-56){UNINITIALIZED}: Terminating (cause = OSMO_FSM_TERM_PARENT) +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-14:RTP_TO_CN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-56){UNINITIALIZED}: Removing from parent call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ) +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-14:RTP_TO_CN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-56){UNINITIALIZED}: Deallocated +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){RELEASING}: Terminating (cause = OSMO_FSM_TERM_REGULAR) +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){RELEASING}: Removing from parent msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: Received Event MSC_EV_CALL_LEG_TERM +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){RELEASING}: Deallocated +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: + wait-Clear-Complete: now used by 1 (wait-Clear-Complete) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: RAN encode: CLEAR_COMMAND on GERAN-A +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - msc_a_fsm_releasing_onenter: now used by 2 (attached,active-conn) +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: RAN decode: CLEAR_COMPLETE +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: - wait-Clear-Complete: now used by 0 (-) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: Received Event MSC_A_EV_UNUSED +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: state_chg to MSC_A_ST_RELEASED +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASED}: Released: msc_a use is 0 (-) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_DONE}: Terminating in cascade, depth 2 (cause = OSMO_FSM_TERM_PARENT, caused by: msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ)) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_DONE}: Removing from parent msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_DONE}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASED}: Removing from parent msub_fsm +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASED}: max total use count was 3 +DMSC msub_fsm{active}: Received Event MSUB_EV_ROLE_TERMINATED +DMSC msub(IMSI-901700000010650:MSISDN-46071) MSC-A terminated +DMSC msub(IMSI-901700000010650:MSISDN-46071) 1 MSC-I still active +DMSC msub_fsm{active}: state_chg to terminating +DMSC msub_fsm{terminating}: Terminating in cascade, depth 2 (cause = OSMO_FSM_TERM_REGULAR, caused by: msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ)) +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Terminating in cascade, depth 3 (cause = OSMO_FSM_TERM_PARENT, caused by: msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ)) +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Removing from parent msub_fsm +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ) +DMSC msub(IMSI-901700000010650:MSISDN-46071) Free +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - active-conn: now used by 1 (attached) +DMSC msub_fsm{terminating}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASED}: Deallocated, including all deferred deallocations +- msub gone + llist_count(&msub_list) == 0 + + +- ======================== SUCCESS: MO call: FR1 picked by MT's MS Bearer Capability, hence MO re-assigns to FR1 + + +- ======================== MT call: FR1 picked by MT's MS Bearer Capability, hence MO re-assigns to FR1 + + +- MNCC asks us to setup a call, causing Paging + MSC <-- MNCC: callref 0x423: MNCC_SETUP_REQ +v=0
+o=OsmoMSC 0 0 IN IP4 1.2.3.4
+s=GSM Call
+c=IN IP4 1.2.3.4
+t=0 0
+m=audio 56 RTP/AVP 112 110 3 111
+a=rtpmap:112 AMR/8000
+a=fmtp:112 octet-align=1
+a=rtpmap:110 GSM-EFR/8000
+a=rtpmap:3 GSM/8000
+a=rtpmap:111 GSM-HR-08/8000
+a=ptime:20
+ +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + mncc_tx_to_gsm_cc: now used by 2 (attached,mncc_tx_to_gsm_cc) +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + CC: now used by 3 (attached,mncc_tx_to_gsm_cc,CC) +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071 callref-0x423 tid-255) New transaction +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071 callref-0x423 tid-255) codecs: :0{(no-codecs)} (from: remote=1.2.3.4:56{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} RAN={(no-codecs)}) +DMNCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071 callref-0x423 tid-255) rx MNCC_SETUP_REQ (RTP=1.2.3.4:56{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) +DPAG Paging: IMSI-901700000010650:MSISDN-46071 for MNCC: establish call: Starting paging + paging request (CALL_CONVERSATIONAL) to IMSI-901700000010650:MSISDN-46071 on GERAN-A + strcmp(paging_expecting_imsi, vsub->imsi) == 0 +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + Paging: now used by 4 (attached,mncc_tx_to_gsm_cc,CC,Paging) +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - mncc_tx_to_gsm_cc: now used by 3 (attached,CC,Paging) + paging_sent == 1 +- MS replies with Paging Response, with Codec List (BSS Supported) = FR1 FR2 FR3 HR1 HR3 +- VLR accepts, MSC sends CC Setup with Bearer Capability = AMR AMR AMR GSM-EFR GSM GSM-HR-08 + MSC <--GERAN-A-- MS: GSM48_MT_RR_PAG_RESP + new conn +DMSC msub_fsm{active}: Allocated +DMSC msc_a{MSC_A_ST_VALIDATE_L3}: Allocated +DMSC msc_a{MSC_A_ST_VALIDATE_L3}: is child of msub_fsm +DMSC msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_VALIDATE_L3 +DMSC dummy_msc_i{0}: Allocated +DMSC dummy_msc_i{0}: is child of msub_fsm +DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms) +DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3 +DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Complete Layer 3: Codec List (BSS Supported): GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111 +DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: RR GSM48_MT_RR_PAG_RESP +DRR msc_a(IMSI-901700000010650:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: Rx PAGING RESPONSE IMSI-901700000010650 +DREF msc_a(IMSI-901700000010650:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: + paging-response: now used by 2 (rx_from_ms,paging-response) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: Allocated +DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: is child of msc_a(IMSI-901700000010650:GERAN-A:PAGING_RESP) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: rev=R99 net=GERAN (no Auth) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + proc_arq_vlr_fn_init: now used by 4 (attached,CC,Paging,proc_arq_vlr_fn_init) +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + active-conn: now used by 5 (attached,CC,Paging,proc_arq_vlr_fn_init,active-conn) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi() +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_node2() +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_ciph() +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_vlr() +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_post_pres() +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_post_trace() +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_post_imei() +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: proc_arq_fsm_done(PASSED) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_DONE +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_DONE}: Process Access Request result: PASSED +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: Received Event MSC_A_EV_AUTHENTICATED +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: state_chg to MSC_A_ST_AUTHENTICATED +DPAG Paging: IMSI-901700000010650:MSISDN-46071 for MNCC: establish call: Paging Response action (success) +DPAG Paging: IMSI-901700000010650:MSISDN-46071 for MNCC: establish call: Removing Paging Request +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071 callref-0x423 tid-255) Paging succeeded +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: + cc: now used by 3 (rx_from_ms,paging-response,cc) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: Received Event MSC_A_EV_TRANSACTION_ACCEPTED +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: state_chg to MSC_A_ST_COMMUNICATING +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) starting timer T303 with 30 seconds +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) codecs: :0{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} (from: remote=1.2.3.4:56{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) new state NULL -> CALL_PRESENT +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_SETUP +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on GERAN-A +- DTAP --GERAN-A--> MS: GSM48_MT_CC_SETUP: 030504076004050b020081 +- DTAP matches expected message +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - Paging: now used by 4 (attached,CC,proc_arq_vlr_fn_init,active-conn) +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - paging-response: now used by 2 (rx_from_ms,cc) +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - proc_arq_vlr_fn_init: now used by 3 (attached,CC,active-conn) +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc) +- MS confirms call, we create a RAN-side RTP and forward MNCC_CALL_CONF_IND + MSC <--GERAN-A-- MS: GSM48_MT_CC_CALL_CONF +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms) +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP +DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_CALL_CONF +DCC trans(CC:CALL_PRESENT IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx CALL_CONF in state CALL_PRESENT +DCC trans(CC:CALL_PRESENT IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) stopping pending timer T303 +DCC trans(CC:CALL_PRESENT IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) starting timer T310 with 30 seconds +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Starting call assignment +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){ESTABLISHING}: Allocated +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){ESTABLISHING}: is child of msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP) +DCC trans(CC:CALL_PRESENT IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) codecs: :0{GSM#3} (from: remote=1.2.3.4:56{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} MS={GSM#3} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) + MGW <--CRCX to RTP_TO_CN-- MSC: call_id=0xf codecs=GSM#3 +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){UNINITIALIZED}: Allocated +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){UNINITIALIZED}: is child of call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP) +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-15:RTP_TO_CN:no-CI){UNINITIALIZED}: setting codecs to GSM#3 + MGW <--CRCX to RTP_TO_RAN-- MSC: call_id=0xf codecs=GSM#3 +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){UNINITIALIZED}: Allocated +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){UNINITIALIZED}: is child of call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP) +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-15:RTP_TO_RAN:no-CI){UNINITIALIZED}: setting codecs to GSM#3 +DCC trans(CC:CALL_PRESENT IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) new state CALL_PRESENT -> MO_TERM_CALL_CONF +DMNCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) tx MNCC_CALL_CONF_IND + MSC --> MNCC: callref 0x423: MNCC_CALL_CONF_IND + +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc) +- VALIDATE_SDP OK: cc_to_mncc_tx_last_sdp == t->mt_tx_sdp_mncc_call_conf_ind == +- MGW acknowledges the CRCX to RAN, triggering Assignment with FR1 + MGW --CRCX OK to RTP_TO_RAN--> MSC +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){ESTABLISHING}: Received Event CALL_LEG_EV_RTP_STREAM_ADDR_AVAILABLE +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Received Event MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: MGW endpoint's RTP address available for the CI RTP_TO_RAN: 10.23.23.1:23 (osmux=no:-2) +DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) codecs: :0{GSM#3} (from: remote=1.2.3.4:56{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} MS={GSM#3} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) +DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) Sending Assignment Command +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN encode: ASSIGNMENT_COMMAND on GERAN-A +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST +- VALIDATE_PERM_SPEECH OK: &bssap_assignment_command_last_channel_type == t->mt_tx_assignment_perm_speech == FR1 +- Assignment completes, triggering CRCX to CN +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN decode: ASSIGNMENT_COMPLETE +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-15:RTP_TO_RAN:no-CI){UNINITIALIZED}: no change: codecs already set to GSM#3 +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-15:RTP_TO_RAN:no-CI){UNINITIALIZED}: setting remote addr to 1.2.3.4:1234 +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-15:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Not committing: no MGW endpoint CI set up +DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) codecs: :0{GSM#3} (from: assigned=GSM#3 remote=1.2.3.4:56{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} MS={GSM#3} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) +DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) Assignment Complete: RAN: GSM#3, CN: GSM#3 +DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) Assignment complete, but still waiting for the CRCX OK on the CN side RTP +- MNCC sends MNCC_RTP_CREATE, which first waits for the CN side RTP + MSC <-- MNCC: callref 0x423: MNCC_RTP_CREATE + +DMNCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx MNCC_RTP_CREATE +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Assignment for this trans already started earlier +- When the CN side RTP address is known, ack MNCC_RTP_CREATE + MGW --CRCX OK to RTP_TO_CN--> MSC +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){ESTABLISHING}: Received Event CALL_LEG_EV_RTP_STREAM_ADDR_AVAILABLE +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Received Event MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: MGW endpoint's RTP address available for the CI RTP_TO_CN: 10.23.23.1:23 (osmux=no:-2) +DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) codecs: 10.23.23.1:23{GSM#3} (from: assigned=GSM#3 remote=1.2.3.4:56{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} MS={GSM#3} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) +DMNCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) tx MNCC_RTP_CREATE (RTP=10.23.23.1:23{GSM#3}) + MSC --> MNCC: callref 0x423: MNCC_RTP_CREATE +v=0
+o=OsmoMSC 0 0 IN IP4 10.23.23.1
+s=GSM Call
+c=IN IP4 10.23.23.1
+t=0 0
+m=audio 23 RTP/AVP 3
+a=rtpmap:3 GSM/8000
+a=ptime:20
+ +- VALIDATE_SDP OK: cc_to_mncc_tx_last_sdp == t->mt_tx_sdp_mncc_rtp_create == GSM +- Total time passed: 1126.000842 s + MSC <--GERAN-A-- MS: GSM48_MT_CC_ALERTING +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms) +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP +DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_ALERTING +DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx ALERTING in state MO_TERM_CALL_CONF +DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) stopping pending timer T310 +DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) starting timer T301 with 180 seconds +DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) new state MO_TERM_CALL_CONF -> CALL_RECEIVED +DCC trans(CC:CALL_RECEIVED IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) codecs: 10.23.23.1:23{GSM#3} (from: assigned=GSM#3 remote=1.2.3.4:56{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} MS={GSM#3} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) +DMNCC trans(CC:CALL_RECEIVED IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) tx MNCC_ALERT_IND (RTP=10.23.23.1:23{GSM#3}) + MSC --> MNCC: callref 0x423: MNCC_ALERT_IND +v=0
+o=OsmoMSC 0 0 IN IP4 10.23.23.1
+s=GSM Call
+c=IN IP4 10.23.23.1
+t=0 0
+m=audio 23 RTP/AVP 3
+a=rtpmap:3 GSM/8000
+a=ptime:20
+ +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc) +- VALIDATE_SDP OK: cc_to_mncc_tx_last_sdp == t->mt_tx_sdp_mncc_alert_ind == GSM +- Total time passed: 1127.000865 s + MSC <--GERAN-A-- MS: GSM48_MT_CC_CONNECT +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms) +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP +DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_CONNECT +DCC trans(CC:CALL_RECEIVED IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx CONNECT in state CALL_RECEIVED +DCC trans(CC:CALL_RECEIVED IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) stopping pending timer T301 +DCC trans(CC:CALL_RECEIVED IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) new state CALL_RECEIVED -> CONNECT_REQUEST +DCC trans(CC:CONNECT_REQUEST IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) codecs: 10.23.23.1:23{GSM#3} (from: assigned=GSM#3 remote=1.2.3.4:56{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} MS={GSM#3} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) +DMNCC trans(CC:CONNECT_REQUEST IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) tx MNCC_SETUP_CNF (RTP=10.23.23.1:23{GSM#3}) + MSC --> MNCC: callref 0x423: MNCC_SETUP_CNF +v=0
+o=OsmoMSC 0 0 IN IP4 10.23.23.1
+s=GSM Call
+c=IN IP4 10.23.23.1
+t=0 0
+m=audio 23 RTP/AVP 3
+a=rtpmap:3 GSM/8000
+a=ptime:20
+ +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc) +- VALIDATE_SDP OK: cc_to_mncc_tx_last_sdp == t->mt_tx_sdp_mncc_setup_cnf == GSM + MSC <-- MNCC: callref 0x423: MNCC_SETUP_COMPL_REQ + +DMNCC trans(CC:CONNECT_REQUEST IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx MNCC_SETUP_COMPL_REQ +DCC trans(CC:CONNECT_REQUEST IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) starting guard timer with 180 seconds +DCC trans(CC:CONNECT_REQUEST IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) new state CONNECT_REQUEST -> ACTIVE +DCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) stopping pending guard timer +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_CONNECT_ACK +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on GERAN-A +- DTAP --GERAN-A--> MS: GSM48_MT_CC_CONNECT_ACK: 030f +- DTAP matches expected message +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST + + +- RTP stream goes ahead, not shown here. +- Total time passed: 1250.000910 s + + +- Call ends + MSC <--GERAN-A-- MS: GSM48_MT_CC_DISCONNECT +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms) +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP +DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_DISCONNECT +DCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx DISCONNECT in state ACTIVE +DCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) new state ACTIVE -> DISCONNECT_IND +DMNCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) tx MNCC_DISC_IND + MSC --> MNCC: callref 0x423: MNCC_DISC_IND + +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc) + MSC <-- MNCC: callref 0x423: MNCC_REL_REQ + +DMNCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx MNCC_REL_REQ +DCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) starting guard timer with 180 seconds +DCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) starting timer T308 with 10 seconds +DCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) new state DISCONNECT_IND -> RELEASE_REQ +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_RELEASE +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on GERAN-A +- DTAP --GERAN-A--> MS: GSM48_MT_CC_RELEASE: 032d +- DTAP matches expected message +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST + MSC <--GERAN-A-- MS: GSM48_MT_CC_RELEASE_COMPL +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms) +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP +DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_RELEASE_COMPL +DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx RELEASE_COMPL in state RELEASE_REQ +DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) stopping pending timer T308 +DMNCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) tx MNCC_REL_CNF + MSC --> MNCC: callref 0x423: MNCC_REL_CNF + +DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x0 tid-0) Freeing transaction +DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x0 tid-0) new state RELEASE_REQ -> NULL +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x0 tid-0) stopping pending guard timer +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - CC: now used by 2 (attached,active-conn) +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - cc: now used by 1 (rx_from_ms) +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 0 (-) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Received Event MSC_A_EV_UNUSED +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: state_chg to MSC_A_ST_RELEASING +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: Releasing: msc_a use is 0 (-) +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + msc_a_fsm_releasing_onenter: now used by 3 (attached,active-conn,msc_a_fsm_releasing_onenter) +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,active-conn,msc_a_fsm_releasing_onenter,vlr_subscr_cancel_attach_fsm) +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,active-conn,msc_a_fsm_releasing_onenter) +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){ESTABLISHING}: state_chg to RELEASING +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-15:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Terminating (cause = OSMO_FSM_TERM_PARENT) +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-15:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Removing from parent call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP) +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-15:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Deallocated +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-15:RTP_TO_CN:no-CI){UNINITIALIZED}: Terminating (cause = OSMO_FSM_TERM_PARENT) +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-15:RTP_TO_CN:no-CI){UNINITIALIZED}: Removing from parent call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP) +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-15:RTP_TO_CN:no-CI){UNINITIALIZED}: Deallocated +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){RELEASING}: Terminating (cause = OSMO_FSM_TERM_REGULAR) +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){RELEASING}: Removing from parent msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: Received Event MSC_EV_CALL_LEG_TERM +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){RELEASING}: Deallocated +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: + wait-Clear-Complete: now used by 1 (wait-Clear-Complete) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: RAN encode: CLEAR_COMMAND on GERAN-A +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - msc_a_fsm_releasing_onenter: now used by 2 (attached,active-conn) +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: RAN decode: CLEAR_COMPLETE +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: - wait-Clear-Complete: now used by 0 (-) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: Received Event MSC_A_EV_UNUSED +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: state_chg to MSC_A_ST_RELEASED +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASED}: Released: msc_a use is 0 (-) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_DONE}: Terminating in cascade, depth 2 (cause = OSMO_FSM_TERM_PARENT, caused by: msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP)) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_DONE}: Removing from parent msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_DONE}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASED}: Removing from parent msub_fsm +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASED}: max total use count was 3 +DMSC msub_fsm{active}: Received Event MSUB_EV_ROLE_TERMINATED +DMSC msub(IMSI-901700000010650:MSISDN-46071) MSC-A terminated +DMSC msub(IMSI-901700000010650:MSISDN-46071) 1 MSC-I still active +DMSC msub_fsm{active}: state_chg to terminating +DMSC msub_fsm{terminating}: Terminating in cascade, depth 2 (cause = OSMO_FSM_TERM_REGULAR, caused by: msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP)) +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Terminating in cascade, depth 3 (cause = OSMO_FSM_TERM_PARENT, caused by: msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP)) +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Removing from parent msub_fsm +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP) +DMSC msub(IMSI-901700000010650:MSISDN-46071) Free +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - active-conn: now used by 1 (attached) +DMSC msub_fsm{terminating}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASED}: Deallocated, including all deferred deallocations +- msub gone + llist_count(&msub_list) == 0 + + +- ======================== SUCCESS: MT call: FR1 picked by MT's MS Bearer Capability, hence MO re-assigns to FR1 + + +- ======================== MO call: AMR picked by both MO and MT, but MT assigns a different payload type number +- CM Service Request with Codec List (BSS Supported) = FR1 FR2 FR3 HR1 HR3 + MSC <--GERAN-A-- MS: GSM48_MT_MM_CM_SERV_REQ + new conn +DMSC msub_fsm{active}: Allocated +DMSC msc_a{MSC_A_ST_VALIDATE_L3}: Allocated +DMSC msc_a{MSC_A_ST_VALIDATE_L3}: is child of msub_fsm +DMSC msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_VALIDATE_L3 +DMSC dummy_msc_i{0}: Allocated +DMSC dummy_msc_i{0}: is child of msub_fsm +DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms) +DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3 +DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Complete Layer 3: Codec List (BSS Supported): GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111 +DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: MM GSM48_MT_MM_CM_SERV_REQ +DMM msc_a(IMSI-901700000010650:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_VALIDATE_L3}: Rx CM SERVICE REQUEST cm_service_type=MO-Call +DREF msc_a(IMSI-901700000010650:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_VALIDATE_L3}: + cm_service_cc: now used by 2 (rx_from_ms,cm_service_cc) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: Allocated +DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: is child of msc_a(IMSI-901700000010650:GERAN-A:CM_SERVICE_REQ) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: rev=R99 net=GERAN (no Auth) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + proc_arq_vlr_fn_init: now used by 2 (attached,proc_arq_vlr_fn_init) +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + active-conn: now used by 3 (attached,proc_arq_vlr_fn_init,active-conn) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi() +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_node2() +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_ciph() +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_vlr() +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_post_pres() +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_post_trace() +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_post_imei() +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: proc_arq_fsm_done(PASSED) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_DONE +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_DONE}: Process Access Request result: PASSED +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: Sending DTAP: MM GSM48_MT_MM_CM_SERV_ACC +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN encode: DTAP on GERAN-A +- DTAP --GERAN-A--> MS: GSM48_MT_MM_CM_SERV_ACC: 0521 +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: Received Event MSC_A_EV_AUTHENTICATED +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: state_chg to MSC_A_ST_AUTHENTICATED +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - proc_arq_vlr_fn_init: now used by 2 (attached,active-conn) +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: - rx_from_ms: now used by 1 (cm_service_cc) + cm_service_result_sent == 1 +msc_a_is_accepted() == true +- MS sends CC SETUP with Bearer Capability = AMR AMR AMR GSM-EFR GSM GSM-HR-08 + MSC <--GERAN-A-- MS: GSM48_MT_CC_SETUP +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: + rx_from_ms: now used by 2 (cm_service_cc,rx_from_ms) +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: RAN decode: DTAP +DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: Dispatching 04.08 message: CC GSM48_MT_CC_SETUP +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + CC: now used by 3 (attached,active-conn,CC) +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071 callref-0x80000009 tid-8) New transaction +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: Received Event MSC_A_EV_TRANSACTION_ACCEPTED +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: state_chg to MSC_A_ST_COMMUNICATING +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: + cc: now used by 3 (cm_service_cc,rx_from_ms,cc) +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - cm_service_cc: now used by 2 (rx_from_ms,cc) +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000009 tid-8) rx SETUP in state NULL +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000009 tid-8) starting guard timer with 180 seconds +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000009 tid-8) codecs: :0{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} (from: MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000009 tid-8) SETUP to 123 +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000009 tid-8) new state NULL -> INITIATED +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Starting call assignment +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){ESTABLISHING}: Allocated +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){ESTABLISHING}: is child of msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ) +DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000009 tid-8) codecs: :0{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} (from: MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) + MGW <--CRCX to RTP_TO_CN-- MSC: call_id=0x10 codecs=AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111 +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){UNINITIALIZED}: Allocated +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){UNINITIALIZED}: is child of call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ) +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-16:RTP_TO_CN:no-CI){UNINITIALIZED}: setting codecs to AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111 + MGW <--CRCX to RTP_TO_RAN-- MSC: call_id=0x10 codecs=AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111 +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){UNINITIALIZED}: Allocated +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){UNINITIALIZED}: is child of call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ) +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-16:RTP_TO_RAN:no-CI){UNINITIALIZED}: setting codecs to AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111 +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc) +- As soon as the MGW port towards CN is created, MNCC_SETUP_IND is triggered + MGW --CRCX OK to RTP_TO_CN--> MSC +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){ESTABLISHING}: Received Event CALL_LEG_EV_RTP_STREAM_ADDR_AVAILABLE +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Received Event MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: MGW endpoint's RTP address available for the CI RTP_TO_CN: 10.23.23.1:23 (osmux=no:-2) +DMNCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000009 tid-8) tx MNCC_SETUP_IND (RTP=10.23.23.1:23{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) + MSC --> MNCC: callref 0x80000009: MNCC_SETUP_IND +v=0
+o=OsmoMSC 0 0 IN IP4 10.23.23.1
+s=GSM Call
+c=IN IP4 10.23.23.1
+t=0 0
+m=audio 23 RTP/AVP 112 110 3 111
+a=rtpmap:112 AMR/8000
+a=fmtp:112 octet-align=1
+a=rtpmap:110 GSM-EFR/8000
+a=rtpmap:3 GSM/8000
+a=rtpmap:111 GSM-HR-08/8000
+a=ptime:20
+ +- VALIDATE_SDP OK: cc_to_mncc_tx_last_sdp == t->mo_tx_sdp_mncc_setup_ind == AMR GSM-EFR GSM GSM-HR-08 +- MNCC replies with MNCC_RTP_CREATE + MSC <-- MNCC: callref 0x80000009: MNCC_RTP_CREATE + +DMNCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000009 tid-8) rx MNCC_RTP_CREATE +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Assignment for this trans already started earlier +- MGW acknowledges the CRCX, triggering Assignment with FR3 HR3 FR2 FR1 HR1 + MGW --CRCX OK to RTP_TO_RAN--> MSC +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){ESTABLISHING}: Received Event CALL_LEG_EV_RTP_STREAM_ADDR_AVAILABLE +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Received Event MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: MGW endpoint's RTP address available for the CI RTP_TO_RAN: 10.23.23.1:23 (osmux=no:-2) +DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000009 tid-8) codecs: 10.23.23.1:23{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} (from: MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) +DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000009 tid-8) Sending Assignment Command +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN encode: ASSIGNMENT_COMMAND on GERAN-A +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST +- VALIDATE_PERM_SPEECH OK: &bssap_assignment_command_last_channel_type == t->mo_tx_assignment_perm_speech == FR3 HR3 FR2 FR1 HR1 +- Assignment succeeds, triggering MNCC_RTP_CREATE ack to MNCC +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN decode: ASSIGNMENT_COMPLETE +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-16:RTP_TO_RAN:no-CI){UNINITIALIZED}: setting codecs to AMR:octet-align=1#112 +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-16:RTP_TO_RAN:no-CI:local-10-23-23-1-23){UNINITIALIZED}: setting remote addr to 1.2.3.4:1234 +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-16:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Not committing: no MGW endpoint CI set up +DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000009 tid-8) codecs: 10.23.23.1:23{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} (from: assigned=AMR:octet-align=1#112 MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) +DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000009 tid-8) Assignment Complete: RAN: AMR:octet-align=1#112, CN: AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111 +DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000009 tid-8) codecs: 10.23.23.1:23{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} (from: assigned=AMR:octet-align=1#112 MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) +DMNCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000009 tid-8) tx MNCC_RTP_CREATE (RTP=10.23.23.1:23{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) + MSC --> MNCC: callref 0x80000009: MNCC_RTP_CREATE +v=0
+o=OsmoMSC 0 0 IN IP4 10.23.23.1
+s=GSM Call
+c=IN IP4 10.23.23.1
+t=0 0
+m=audio 23 RTP/AVP 112 110 3 111
+a=rtpmap:112 AMR/8000
+a=fmtp:112 octet-align=1
+a=rtpmap:110 GSM-EFR/8000
+a=rtpmap:3 GSM/8000
+a=rtpmap:111 GSM-HR-08/8000
+a=ptime:20
+ +- VALIDATE_SDP OK: cc_to_mncc_tx_last_sdp == t->mo_tx_sdp_mncc_rtp_create == AMR GSM-EFR GSM GSM-HR-08 +- MNCC says that's fine + MSC <-- MNCC: callref 0x80000009: MNCC_CALL_PROC_REQ + +DMNCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000009 tid-8) rx MNCC_CALL_PROC_REQ +DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000009 tid-8) stopping pending guard timer +DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000009 tid-8) starting guard timer with 180 seconds +DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000009 tid-8) new state INITIATED -> MO_CALL_PROC +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_CALL_PROC +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on GERAN-A +- DTAP --GERAN-A--> MS: GSM48_MT_CC_CALL_PROC: 8302 +- DTAP matches expected message +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Assignment for this trans already started earlier +- Total time passed: 1251.000933 s +- The other call leg got established (not shown here), MNCC tells us so, with codecs { AMR#96 GSM-EFR GSM GSM-HR-08 } + MSC <-- MNCC: callref 0x80000009: MNCC_ALERT_REQ +v=0
+o=OsmoMSC 0 0 IN IP4 1.2.3.4
+s=GSM Call
+c=IN IP4 1.2.3.4
+t=0 0
+m=audio 56 RTP/AVP 96 110 3 111
+a=rtpmap:96 AMR/8000
+a=fmtp:96 octet-align=1
+a=rtpmap:110 GSM-EFR/8000
+a=rtpmap:3 GSM/8000
+a=rtpmap:111 GSM-HR-08/8000
+a=ptime:20
+ +DMNCC trans(CC:MO_CALL_PROC IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000009 tid-8) rx MNCC_ALERT_REQ (RTP=1.2.3.4:56{AMR:octet-align=1#96,GSM-EFR#110,GSM#3,GSM-HR-08#111}) +DCC trans(CC:MO_CALL_PROC IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000009 tid-8) stopping pending guard timer +DCC trans(CC:MO_CALL_PROC IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000009 tid-8) starting guard timer with 180 seconds +DCC trans(CC:MO_CALL_PROC IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000009 tid-8) new state MO_CALL_PROC -> CALL_DELIVERED +DCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000009 tid-8) codecs: 10.23.23.1:23{AMR:octet-align=1#96,GSM-EFR#110,GSM#3,GSM-HR-08#111} (from: assigned=AMR:octet-align=1#112 remote=1.2.3.4:56{AMR:octet-align=1#96,GSM-EFR#110,GSM#3,GSM-HR-08#111} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-16:RTP_TO_CN:no-CI){UNINITIALIZED}: setting codecs to AMR:octet-align=1#96,GSM-EFR#110,GSM#3,GSM-HR-08#111 +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-16:RTP_TO_CN:no-CI:local-10-23-23-1-23){UNINITIALIZED}: setting remote addr to 1.2.3.4:56 +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-16:RTP_TO_CN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-56){UNINITIALIZED}: Not committing: no MGW endpoint CI set up +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_ALERTING +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on GERAN-A +- DTAP --GERAN-A--> MS: GSM48_MT_CC_ALERTING: 8301 +- DTAP matches expected message +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST + MSC <-- MNCC: callref 0x80000009: MNCC_SETUP_RSP +v=0
+o=OsmoMSC 0 0 IN IP4 1.2.3.4
+s=GSM Call
+c=IN IP4 1.2.3.4
+t=0 0
+m=audio 56 RTP/AVP 96 110 3 111
+a=rtpmap:96 AMR/8000
+a=fmtp:96 octet-align=1
+a=rtpmap:110 GSM-EFR/8000
+a=rtpmap:3 GSM/8000
+a=rtpmap:111 GSM-HR-08/8000
+a=ptime:20
+ +DMNCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000009 tid-8) rx MNCC_SETUP_RSP (RTP=1.2.3.4:56{AMR:octet-align=1#96,GSM-EFR#110,GSM#3,GSM-HR-08#111}) +DCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000009 tid-8) stopping pending guard timer +DCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000009 tid-8) starting guard timer with 180 seconds +DCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000009 tid-8) starting timer T313 with 30 seconds +DCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000009 tid-8) new state CALL_DELIVERED -> CONNECT_IND +DCC trans(CC:CONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000009 tid-8) codecs: 10.23.23.1:23{AMR:octet-align=1#96,GSM-EFR#110,GSM#3,GSM-HR-08#111} (from: assigned=AMR:octet-align=1#112 remote=1.2.3.4:56{AMR:octet-align=1#96,GSM-EFR#110,GSM#3,GSM-HR-08#111} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-16:RTP_TO_CN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-56){UNINITIALIZED}: no change: codecs already set to AMR:octet-align=1#96,GSM-EFR#110,GSM#3,GSM-HR-08#111 +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-16:RTP_TO_CN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-56){UNINITIALIZED}: remote addr already 1.2.3.4:56, no change +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-16:RTP_TO_CN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-56){UNINITIALIZED}: Not committing: no MGW endpoint CI set up +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_CONNECT +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on GERAN-A +- DTAP --GERAN-A--> MS: GSM48_MT_CC_CONNECT: 8307 +- DTAP matches expected message +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST +- Total time passed: 1252.000956 s + MSC <--GERAN-A-- MS: GSM48_MT_CC_CONNECT_ACK +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms) +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP +DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_CONNECT_ACK +DCC trans(CC:CONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000009 tid-8) rx CONNECT_ACK in state CONNECT_IND +DCC trans(CC:CONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000009 tid-8) stopping pending timer T313 +DCC trans(CC:CONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000009 tid-8) new state CONNECT_IND -> ACTIVE +DCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000009 tid-8) stopping pending guard timer +DMNCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000009 tid-8) tx MNCC_SETUP_COMPL_IND + MSC --> MNCC: callref 0x80000009: MNCC_SETUP_COMPL_IND + +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc) +- VALIDATE_SDP OK: cc_to_mncc_tx_last_sdp == t->mo_tx_sdp_mncc_setup_compl_ind == + + +- RTP stream goes ahead, not shown here. +- Total time passed: 1375.001001 s + + +- Call ends + MSC <--GERAN-A-- MS: GSM48_MT_CC_DISCONNECT +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms) +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP +DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_DISCONNECT +DCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000009 tid-8) rx DISCONNECT in state ACTIVE +DCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000009 tid-8) new state ACTIVE -> DISCONNECT_IND +DMNCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000009 tid-8) tx MNCC_DISC_IND + MSC --> MNCC: callref 0x80000009: MNCC_DISC_IND + +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc) + MSC <-- MNCC: callref 0x80000009: MNCC_REL_REQ +v=0
+o=OsmoMSC 0 0 IN IP4 1.2.3.4
+s=GSM Call
+c=IN IP4 1.2.3.4
+t=0 0
+m=audio 56 RTP/AVP 96 110 3 111
+a=rtpmap:96 AMR/8000
+a=fmtp:96 octet-align=1
+a=rtpmap:110 GSM-EFR/8000
+a=rtpmap:3 GSM/8000
+a=rtpmap:111 GSM-HR-08/8000
+a=ptime:20
+ +DMNCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000009 tid-8) rx MNCC_REL_REQ +DCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000009 tid-8) starting guard timer with 180 seconds +DCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000009 tid-8) starting timer T308 with 10 seconds +DCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000009 tid-8) new state DISCONNECT_IND -> RELEASE_REQ +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_RELEASE +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on GERAN-A +- DTAP --GERAN-A--> MS: GSM48_MT_CC_RELEASE: 832d +- DTAP matches expected message +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST + MSC <--GERAN-A-- MS: GSM48_MT_CC_RELEASE_COMPL +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms) +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP +DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_RELEASE_COMPL +DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000009 tid-8) rx RELEASE_COMPL in state RELEASE_REQ +DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000009 tid-8) stopping pending timer T308 +DMNCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000009 tid-8) tx MNCC_REL_CNF + MSC --> MNCC: callref 0x80000009: MNCC_REL_CNF + +DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x0 tid-8) Freeing transaction +DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x0 tid-8) new state RELEASE_REQ -> NULL +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x0 tid-8) stopping pending guard timer +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - CC: now used by 2 (attached,active-conn) +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - cc: now used by 1 (rx_from_ms) +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 0 (-) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Received Event MSC_A_EV_UNUSED +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: state_chg to MSC_A_ST_RELEASING +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: Releasing: msc_a use is 0 (-) +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + msc_a_fsm_releasing_onenter: now used by 3 (attached,active-conn,msc_a_fsm_releasing_onenter) +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,active-conn,msc_a_fsm_releasing_onenter,vlr_subscr_cancel_attach_fsm) +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,active-conn,msc_a_fsm_releasing_onenter) +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){ESTABLISHING}: state_chg to RELEASING +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-16:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Terminating (cause = OSMO_FSM_TERM_PARENT) +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-16:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Removing from parent call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ) +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-16:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Deallocated +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-16:RTP_TO_CN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-56){UNINITIALIZED}: Terminating (cause = OSMO_FSM_TERM_PARENT) +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-16:RTP_TO_CN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-56){UNINITIALIZED}: Removing from parent call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ) +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-16:RTP_TO_CN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-56){UNINITIALIZED}: Deallocated +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){RELEASING}: Terminating (cause = OSMO_FSM_TERM_REGULAR) +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){RELEASING}: Removing from parent msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: Received Event MSC_EV_CALL_LEG_TERM +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){RELEASING}: Deallocated +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: + wait-Clear-Complete: now used by 1 (wait-Clear-Complete) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: RAN encode: CLEAR_COMMAND on GERAN-A +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - msc_a_fsm_releasing_onenter: now used by 2 (attached,active-conn) +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: RAN decode: CLEAR_COMPLETE +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: - wait-Clear-Complete: now used by 0 (-) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: Received Event MSC_A_EV_UNUSED +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: state_chg to MSC_A_ST_RELEASED +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASED}: Released: msc_a use is 0 (-) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_DONE}: Terminating in cascade, depth 2 (cause = OSMO_FSM_TERM_PARENT, caused by: msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ)) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_DONE}: Removing from parent msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_DONE}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASED}: Removing from parent msub_fsm +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASED}: max total use count was 3 +DMSC msub_fsm{active}: Received Event MSUB_EV_ROLE_TERMINATED +DMSC msub(IMSI-901700000010650:MSISDN-46071) MSC-A terminated +DMSC msub(IMSI-901700000010650:MSISDN-46071) 1 MSC-I still active +DMSC msub_fsm{active}: state_chg to terminating +DMSC msub_fsm{terminating}: Terminating in cascade, depth 2 (cause = OSMO_FSM_TERM_REGULAR, caused by: msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ)) +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Terminating in cascade, depth 3 (cause = OSMO_FSM_TERM_PARENT, caused by: msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ)) +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Removing from parent msub_fsm +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ) +DMSC msub(IMSI-901700000010650:MSISDN-46071) Free +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - active-conn: now used by 1 (attached) +DMSC msub_fsm{terminating}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASED}: Deallocated, including all deferred deallocations +- msub gone + llist_count(&msub_list) == 0 + + +- ======================== SUCCESS: MO call: AMR picked by both MO and MT, but MT assigns a different payload type number + + +- ======================== MT call: AMR picked by both MO and MT, but MT assigns a different payload type number + + +- MNCC asks us to setup a call, causing Paging + MSC <-- MNCC: callref 0x423: MNCC_SETUP_REQ +v=0
+o=OsmoMSC 0 0 IN IP4 1.2.3.4
+s=GSM Call
+c=IN IP4 1.2.3.4
+t=0 0
+m=audio 56 RTP/AVP 112 110 3 111
+a=rtpmap:112 AMR/8000
+a=fmtp:112 octet-align=1
+a=rtpmap:110 GSM-EFR/8000
+a=rtpmap:3 GSM/8000
+a=rtpmap:111 GSM-HR-08/8000
+a=ptime:20
+ +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + mncc_tx_to_gsm_cc: now used by 2 (attached,mncc_tx_to_gsm_cc) +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + CC: now used by 3 (attached,mncc_tx_to_gsm_cc,CC) +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071 callref-0x423 tid-255) New transaction +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071 callref-0x423 tid-255) codecs: :0{(no-codecs)} (from: remote=1.2.3.4:56{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} RAN={(no-codecs)}) +DMNCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071 callref-0x423 tid-255) rx MNCC_SETUP_REQ (RTP=1.2.3.4:56{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) +DPAG Paging: IMSI-901700000010650:MSISDN-46071 for MNCC: establish call: Starting paging + paging request (CALL_CONVERSATIONAL) to IMSI-901700000010650:MSISDN-46071 on GERAN-A + strcmp(paging_expecting_imsi, vsub->imsi) == 0 +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + Paging: now used by 4 (attached,mncc_tx_to_gsm_cc,CC,Paging) +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - mncc_tx_to_gsm_cc: now used by 3 (attached,CC,Paging) + paging_sent == 1 +- MS replies with Paging Response, with Codec List (BSS Supported) = FR1 FR2 FR3 HR1 HR3 +- VLR accepts, MSC sends CC Setup with Bearer Capability = AMR AMR AMR GSM-EFR GSM GSM-HR-08 + MSC <--GERAN-A-- MS: GSM48_MT_RR_PAG_RESP + new conn +DMSC msub_fsm{active}: Allocated +DMSC msc_a{MSC_A_ST_VALIDATE_L3}: Allocated +DMSC msc_a{MSC_A_ST_VALIDATE_L3}: is child of msub_fsm +DMSC msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_VALIDATE_L3 +DMSC dummy_msc_i{0}: Allocated +DMSC dummy_msc_i{0}: is child of msub_fsm +DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms) +DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3 +DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Complete Layer 3: Codec List (BSS Supported): GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111 +DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: RR GSM48_MT_RR_PAG_RESP +DRR msc_a(IMSI-901700000010650:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: Rx PAGING RESPONSE IMSI-901700000010650 +DREF msc_a(IMSI-901700000010650:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: + paging-response: now used by 2 (rx_from_ms,paging-response) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: Allocated +DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: is child of msc_a(IMSI-901700000010650:GERAN-A:PAGING_RESP) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: rev=R99 net=GERAN (no Auth) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + proc_arq_vlr_fn_init: now used by 4 (attached,CC,Paging,proc_arq_vlr_fn_init) +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + active-conn: now used by 5 (attached,CC,Paging,proc_arq_vlr_fn_init,active-conn) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi() +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_node2() +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_ciph() +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_vlr() +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_post_pres() +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_post_trace() +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_post_imei() +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: proc_arq_fsm_done(PASSED) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_DONE +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_DONE}: Process Access Request result: PASSED +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: Received Event MSC_A_EV_AUTHENTICATED +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: state_chg to MSC_A_ST_AUTHENTICATED +DPAG Paging: IMSI-901700000010650:MSISDN-46071 for MNCC: establish call: Paging Response action (success) +DPAG Paging: IMSI-901700000010650:MSISDN-46071 for MNCC: establish call: Removing Paging Request +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071 callref-0x423 tid-255) Paging succeeded +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: + cc: now used by 3 (rx_from_ms,paging-response,cc) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: Received Event MSC_A_EV_TRANSACTION_ACCEPTED +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: state_chg to MSC_A_ST_COMMUNICATING +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) starting timer T303 with 30 seconds +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) codecs: :0{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} (from: remote=1.2.3.4:56{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) new state NULL -> CALL_PRESENT +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_SETUP +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on GERAN-A +- DTAP --GERAN-A--> MS: GSM48_MT_CC_SETUP: 030504076004050b020081 +- DTAP matches expected message +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - Paging: now used by 4 (attached,CC,proc_arq_vlr_fn_init,active-conn) +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - paging-response: now used by 2 (rx_from_ms,cc) +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - proc_arq_vlr_fn_init: now used by 3 (attached,CC,active-conn) +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc) +- MS confirms call, we create a RAN-side RTP and forward MNCC_CALL_CONF_IND + MSC <--GERAN-A-- MS: GSM48_MT_CC_CALL_CONF +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms) +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP +DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_CALL_CONF +DCC trans(CC:CALL_PRESENT IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx CALL_CONF in state CALL_PRESENT +DCC trans(CC:CALL_PRESENT IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) stopping pending timer T303 +DCC trans(CC:CALL_PRESENT IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) starting timer T310 with 30 seconds +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Starting call assignment +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){ESTABLISHING}: Allocated +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){ESTABLISHING}: is child of msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP) +DCC trans(CC:CALL_PRESENT IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) codecs: :0{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} (from: remote=1.2.3.4:56{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) + MGW <--CRCX to RTP_TO_CN-- MSC: call_id=0x11 codecs=AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111 +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){UNINITIALIZED}: Allocated +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){UNINITIALIZED}: is child of call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP) +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-17:RTP_TO_CN:no-CI){UNINITIALIZED}: setting codecs to AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111 + MGW <--CRCX to RTP_TO_RAN-- MSC: call_id=0x11 codecs=AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111 +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){UNINITIALIZED}: Allocated +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){UNINITIALIZED}: is child of call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP) +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-17:RTP_TO_RAN:no-CI){UNINITIALIZED}: setting codecs to AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111 +DCC trans(CC:CALL_PRESENT IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) new state CALL_PRESENT -> MO_TERM_CALL_CONF +DMNCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) tx MNCC_CALL_CONF_IND + MSC --> MNCC: callref 0x423: MNCC_CALL_CONF_IND + +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc) +- VALIDATE_SDP OK: cc_to_mncc_tx_last_sdp == t->mt_tx_sdp_mncc_call_conf_ind == +- MGW acknowledges the CRCX to RAN, triggering Assignment with FR3 HR3 FR2 FR1 HR1 + MGW --CRCX OK to RTP_TO_RAN--> MSC +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){ESTABLISHING}: Received Event CALL_LEG_EV_RTP_STREAM_ADDR_AVAILABLE +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Received Event MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: MGW endpoint's RTP address available for the CI RTP_TO_RAN: 10.23.23.1:23 (osmux=no:-2) +DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) codecs: :0{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} (from: remote=1.2.3.4:56{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) +DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) Sending Assignment Command +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN encode: ASSIGNMENT_COMMAND on GERAN-A +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST +- VALIDATE_PERM_SPEECH OK: &bssap_assignment_command_last_channel_type == t->mt_tx_assignment_perm_speech == FR3 HR3 FR2 FR1 HR1 +- Assignment completes, triggering CRCX to CN +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN decode: ASSIGNMENT_COMPLETE +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-17:RTP_TO_RAN:no-CI){UNINITIALIZED}: setting codecs to AMR:octet-align=1#112 +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-17:RTP_TO_RAN:no-CI:local-10-23-23-1-23){UNINITIALIZED}: setting remote addr to 1.2.3.4:1234 +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-17:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Not committing: no MGW endpoint CI set up +DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) codecs: :0{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} (from: assigned=AMR:octet-align=1#112 remote=1.2.3.4:56{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) +DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) Assignment Complete: RAN: AMR:octet-align=1#112, CN: AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111 +DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) Assignment complete, but still waiting for the CRCX OK on the CN side RTP +- MNCC sends MNCC_RTP_CREATE, which first waits for the CN side RTP + MSC <-- MNCC: callref 0x423: MNCC_RTP_CREATE + +DMNCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx MNCC_RTP_CREATE +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Assignment for this trans already started earlier +- When the CN side RTP address is known, ack MNCC_RTP_CREATE + MGW --CRCX OK to RTP_TO_CN--> MSC +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){ESTABLISHING}: Received Event CALL_LEG_EV_RTP_STREAM_ADDR_AVAILABLE +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Received Event MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: MGW endpoint's RTP address available for the CI RTP_TO_CN: 10.23.23.1:23 (osmux=no:-2) +DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) codecs: 10.23.23.1:23{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} (from: assigned=AMR:octet-align=1#112 remote=1.2.3.4:56{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) +DMNCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) tx MNCC_RTP_CREATE (RTP=10.23.23.1:23{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) + MSC --> MNCC: callref 0x423: MNCC_RTP_CREATE +v=0
+o=OsmoMSC 0 0 IN IP4 10.23.23.1
+s=GSM Call
+c=IN IP4 10.23.23.1
+t=0 0
+m=audio 23 RTP/AVP 112 110 3 111
+a=rtpmap:112 AMR/8000
+a=fmtp:112 octet-align=1
+a=rtpmap:110 GSM-EFR/8000
+a=rtpmap:3 GSM/8000
+a=rtpmap:111 GSM-HR-08/8000
+a=ptime:20
+ +- VALIDATE_SDP OK: cc_to_mncc_tx_last_sdp == t->mt_tx_sdp_mncc_rtp_create == AMR#96 GSM-EFR GSM GSM-HR-08 +- Total time passed: 1376.001024 s + MSC <--GERAN-A-- MS: GSM48_MT_CC_ALERTING +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms) +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP +DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_ALERTING +DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx ALERTING in state MO_TERM_CALL_CONF +DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) stopping pending timer T310 +DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) starting timer T301 with 180 seconds +DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) new state MO_TERM_CALL_CONF -> CALL_RECEIVED +DCC trans(CC:CALL_RECEIVED IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) codecs: 10.23.23.1:23{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} (from: assigned=AMR:octet-align=1#112 remote=1.2.3.4:56{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) +DMNCC trans(CC:CALL_RECEIVED IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) tx MNCC_ALERT_IND (RTP=10.23.23.1:23{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) + MSC --> MNCC: callref 0x423: MNCC_ALERT_IND +v=0
+o=OsmoMSC 0 0 IN IP4 10.23.23.1
+s=GSM Call
+c=IN IP4 10.23.23.1
+t=0 0
+m=audio 23 RTP/AVP 112 110 3 111
+a=rtpmap:112 AMR/8000
+a=fmtp:112 octet-align=1
+a=rtpmap:110 GSM-EFR/8000
+a=rtpmap:3 GSM/8000
+a=rtpmap:111 GSM-HR-08/8000
+a=ptime:20
+ +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc) +- VALIDATE_SDP OK: cc_to_mncc_tx_last_sdp == t->mt_tx_sdp_mncc_alert_ind == AMR#96 GSM-EFR GSM GSM-HR-08 +- Total time passed: 1377.001047 s + MSC <--GERAN-A-- MS: GSM48_MT_CC_CONNECT +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms) +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP +DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_CONNECT +DCC trans(CC:CALL_RECEIVED IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx CONNECT in state CALL_RECEIVED +DCC trans(CC:CALL_RECEIVED IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) stopping pending timer T301 +DCC trans(CC:CALL_RECEIVED IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) new state CALL_RECEIVED -> CONNECT_REQUEST +DCC trans(CC:CONNECT_REQUEST IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) codecs: 10.23.23.1:23{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} (from: assigned=AMR:octet-align=1#112 remote=1.2.3.4:56{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) +DMNCC trans(CC:CONNECT_REQUEST IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) tx MNCC_SETUP_CNF (RTP=10.23.23.1:23{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) + MSC --> MNCC: callref 0x423: MNCC_SETUP_CNF +v=0
+o=OsmoMSC 0 0 IN IP4 10.23.23.1
+s=GSM Call
+c=IN IP4 10.23.23.1
+t=0 0
+m=audio 23 RTP/AVP 112 110 3 111
+a=rtpmap:112 AMR/8000
+a=fmtp:112 octet-align=1
+a=rtpmap:110 GSM-EFR/8000
+a=rtpmap:3 GSM/8000
+a=rtpmap:111 GSM-HR-08/8000
+a=ptime:20
+ +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc) +- VALIDATE_SDP OK: cc_to_mncc_tx_last_sdp == t->mt_tx_sdp_mncc_setup_cnf == AMR#96 GSM-EFR GSM GSM-HR-08 + MSC <-- MNCC: callref 0x423: MNCC_SETUP_COMPL_REQ + +DMNCC trans(CC:CONNECT_REQUEST IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx MNCC_SETUP_COMPL_REQ +DCC trans(CC:CONNECT_REQUEST IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) starting guard timer with 180 seconds +DCC trans(CC:CONNECT_REQUEST IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) new state CONNECT_REQUEST -> ACTIVE +DCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) stopping pending guard timer +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_CONNECT_ACK +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on GERAN-A +- DTAP --GERAN-A--> MS: GSM48_MT_CC_CONNECT_ACK: 030f +- DTAP matches expected message +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST + + +- RTP stream goes ahead, not shown here. +- Total time passed: 1500.001092 s + + +- Call ends + MSC <--GERAN-A-- MS: GSM48_MT_CC_DISCONNECT +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms) +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP +DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_DISCONNECT +DCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx DISCONNECT in state ACTIVE +DCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) new state ACTIVE -> DISCONNECT_IND +DMNCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) tx MNCC_DISC_IND + MSC --> MNCC: callref 0x423: MNCC_DISC_IND + +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc) + MSC <-- MNCC: callref 0x423: MNCC_REL_REQ + +DMNCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx MNCC_REL_REQ +DCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) starting guard timer with 180 seconds +DCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) starting timer T308 with 10 seconds +DCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) new state DISCONNECT_IND -> RELEASE_REQ +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_RELEASE +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on GERAN-A +- DTAP --GERAN-A--> MS: GSM48_MT_CC_RELEASE: 032d +- DTAP matches expected message +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST + MSC <--GERAN-A-- MS: GSM48_MT_CC_RELEASE_COMPL +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms) +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP +DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_RELEASE_COMPL +DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx RELEASE_COMPL in state RELEASE_REQ +DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) stopping pending timer T308 +DMNCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) tx MNCC_REL_CNF + MSC --> MNCC: callref 0x423: MNCC_REL_CNF + +DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x0 tid-0) Freeing transaction +DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x0 tid-0) new state RELEASE_REQ -> NULL +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x0 tid-0) stopping pending guard timer +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - CC: now used by 2 (attached,active-conn) +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - cc: now used by 1 (rx_from_ms) +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 0 (-) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Received Event MSC_A_EV_UNUSED +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: state_chg to MSC_A_ST_RELEASING +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: Releasing: msc_a use is 0 (-) +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + msc_a_fsm_releasing_onenter: now used by 3 (attached,active-conn,msc_a_fsm_releasing_onenter) +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,active-conn,msc_a_fsm_releasing_onenter,vlr_subscr_cancel_attach_fsm) +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,active-conn,msc_a_fsm_releasing_onenter) +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){ESTABLISHING}: state_chg to RELEASING +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-17:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Terminating (cause = OSMO_FSM_TERM_PARENT) +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-17:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Removing from parent call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP) +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-17:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Deallocated +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-17:RTP_TO_CN:no-CI){UNINITIALIZED}: Terminating (cause = OSMO_FSM_TERM_PARENT) +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-17:RTP_TO_CN:no-CI){UNINITIALIZED}: Removing from parent call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP) +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-17:RTP_TO_CN:no-CI){UNINITIALIZED}: Deallocated +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){RELEASING}: Terminating (cause = OSMO_FSM_TERM_REGULAR) +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){RELEASING}: Removing from parent msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: Received Event MSC_EV_CALL_LEG_TERM +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){RELEASING}: Deallocated +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: + wait-Clear-Complete: now used by 1 (wait-Clear-Complete) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: RAN encode: CLEAR_COMMAND on GERAN-A +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - msc_a_fsm_releasing_onenter: now used by 2 (attached,active-conn) +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: RAN decode: CLEAR_COMPLETE +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: - wait-Clear-Complete: now used by 0 (-) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: Received Event MSC_A_EV_UNUSED +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: state_chg to MSC_A_ST_RELEASED +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASED}: Released: msc_a use is 0 (-) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_DONE}: Terminating in cascade, depth 2 (cause = OSMO_FSM_TERM_PARENT, caused by: msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP)) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_DONE}: Removing from parent msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_DONE}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASED}: Removing from parent msub_fsm +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASED}: max total use count was 3 +DMSC msub_fsm{active}: Received Event MSUB_EV_ROLE_TERMINATED +DMSC msub(IMSI-901700000010650:MSISDN-46071) MSC-A terminated +DMSC msub(IMSI-901700000010650:MSISDN-46071) 1 MSC-I still active +DMSC msub_fsm{active}: state_chg to terminating +DMSC msub_fsm{terminating}: Terminating in cascade, depth 2 (cause = OSMO_FSM_TERM_REGULAR, caused by: msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP)) +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Terminating in cascade, depth 3 (cause = OSMO_FSM_TERM_PARENT, caused by: msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP)) +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Removing from parent msub_fsm +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP) +DMSC msub(IMSI-901700000010650:MSISDN-46071) Free +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - active-conn: now used by 1 (attached) +DMSC msub_fsm{terminating}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASED}: Deallocated, including all deferred deallocations +- msub gone + llist_count(&msub_list) == 0 + + +- ======================== SUCCESS: MT call: AMR picked by both MO and MT, but MT assigns a different payload type number + + +- ======================== MO call: AMR picked by both MO and MT, but MO assigns a different payload type number +- CM Service Request with Codec List (BSS Supported) = FR1 FR2 FR3 HR1 HR3 + MSC <--GERAN-A-- MS: GSM48_MT_MM_CM_SERV_REQ + new conn +DMSC msub_fsm{active}: Allocated +DMSC msc_a{MSC_A_ST_VALIDATE_L3}: Allocated +DMSC msc_a{MSC_A_ST_VALIDATE_L3}: is child of msub_fsm +DMSC msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_VALIDATE_L3 +DMSC dummy_msc_i{0}: Allocated +DMSC dummy_msc_i{0}: is child of msub_fsm +DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms) +DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3 +DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Complete Layer 3: Codec List (BSS Supported): GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111 +DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: MM GSM48_MT_MM_CM_SERV_REQ +DMM msc_a(IMSI-901700000010650:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_VALIDATE_L3}: Rx CM SERVICE REQUEST cm_service_type=MO-Call +DREF msc_a(IMSI-901700000010650:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_VALIDATE_L3}: + cm_service_cc: now used by 2 (rx_from_ms,cm_service_cc) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: Allocated +DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: is child of msc_a(IMSI-901700000010650:GERAN-A:CM_SERVICE_REQ) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: rev=R99 net=GERAN (no Auth) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + proc_arq_vlr_fn_init: now used by 2 (attached,proc_arq_vlr_fn_init) +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + active-conn: now used by 3 (attached,proc_arq_vlr_fn_init,active-conn) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi() +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_node2() +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_ciph() +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_vlr() +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_post_pres() +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_post_trace() +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_post_imei() +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: proc_arq_fsm_done(PASSED) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_DONE +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_DONE}: Process Access Request result: PASSED +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: Sending DTAP: MM GSM48_MT_MM_CM_SERV_ACC +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN encode: DTAP on GERAN-A +- DTAP --GERAN-A--> MS: GSM48_MT_MM_CM_SERV_ACC: 0521 +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: Received Event MSC_A_EV_AUTHENTICATED +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: state_chg to MSC_A_ST_AUTHENTICATED +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - proc_arq_vlr_fn_init: now used by 2 (attached,active-conn) +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: - rx_from_ms: now used by 1 (cm_service_cc) + cm_service_result_sent == 1 +msc_a_is_accepted() == true +- MS sends CC SETUP with Bearer Capability = AMR AMR AMR GSM-EFR GSM GSM-HR-08 + MSC <--GERAN-A-- MS: GSM48_MT_CC_SETUP +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: + rx_from_ms: now used by 2 (cm_service_cc,rx_from_ms) +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: RAN decode: DTAP +DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: Dispatching 04.08 message: CC GSM48_MT_CC_SETUP +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + CC: now used by 3 (attached,active-conn,CC) +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071 callref-0x8000000a tid-8) New transaction +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: Received Event MSC_A_EV_TRANSACTION_ACCEPTED +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: state_chg to MSC_A_ST_COMMUNICATING +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: + cc: now used by 3 (cm_service_cc,rx_from_ms,cc) +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - cm_service_cc: now used by 2 (rx_from_ms,cc) +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x8000000a tid-8) rx SETUP in state NULL +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x8000000a tid-8) starting guard timer with 180 seconds +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x8000000a tid-8) codecs: :0{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} (from: MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x8000000a tid-8) SETUP to 123 +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x8000000a tid-8) new state NULL -> INITIATED +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Starting call assignment +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){ESTABLISHING}: Allocated +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){ESTABLISHING}: is child of msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ) +DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x8000000a tid-8) codecs: :0{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} (from: MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) + MGW <--CRCX to RTP_TO_CN-- MSC: call_id=0x12 codecs=AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111 +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){UNINITIALIZED}: Allocated +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){UNINITIALIZED}: is child of call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ) +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-18:RTP_TO_CN:no-CI){UNINITIALIZED}: setting codecs to AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111 + MGW <--CRCX to RTP_TO_RAN-- MSC: call_id=0x12 codecs=AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111 +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){UNINITIALIZED}: Allocated +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){UNINITIALIZED}: is child of call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ) +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-18:RTP_TO_RAN:no-CI){UNINITIALIZED}: setting codecs to AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111 +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc) +- As soon as the MGW port towards CN is created, MNCC_SETUP_IND is triggered + MGW --CRCX OK to RTP_TO_CN--> MSC +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){ESTABLISHING}: Received Event CALL_LEG_EV_RTP_STREAM_ADDR_AVAILABLE +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Received Event MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: MGW endpoint's RTP address available for the CI RTP_TO_CN: 10.23.23.1:23 (osmux=no:-2) +DMNCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x8000000a tid-8) tx MNCC_SETUP_IND (RTP=10.23.23.1:23{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) + MSC --> MNCC: callref 0x8000000a: MNCC_SETUP_IND +v=0
+o=OsmoMSC 0 0 IN IP4 10.23.23.1
+s=GSM Call
+c=IN IP4 10.23.23.1
+t=0 0
+m=audio 23 RTP/AVP 112 110 3 111
+a=rtpmap:112 AMR/8000
+a=fmtp:112 octet-align=1
+a=rtpmap:110 GSM-EFR/8000
+a=rtpmap:3 GSM/8000
+a=rtpmap:111 GSM-HR-08/8000
+a=ptime:20
+ +- VALIDATE_SDP OK: cc_to_mncc_tx_last_sdp == t->mo_tx_sdp_mncc_setup_ind == AMR GSM-EFR GSM GSM-HR-08 +- MNCC replies with MNCC_RTP_CREATE + MSC <-- MNCC: callref 0x8000000a: MNCC_RTP_CREATE + +DMNCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x8000000a tid-8) rx MNCC_RTP_CREATE +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Assignment for this trans already started earlier +- MGW acknowledges the CRCX, triggering Assignment with FR3 HR3 FR2 FR1 HR1 + MGW --CRCX OK to RTP_TO_RAN--> MSC +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){ESTABLISHING}: Received Event CALL_LEG_EV_RTP_STREAM_ADDR_AVAILABLE +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Received Event MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: MGW endpoint's RTP address available for the CI RTP_TO_RAN: 10.23.23.1:23 (osmux=no:-2) +DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x8000000a tid-8) codecs: 10.23.23.1:23{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} (from: MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) +DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x8000000a tid-8) Sending Assignment Command +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN encode: ASSIGNMENT_COMMAND on GERAN-A +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST +- VALIDATE_PERM_SPEECH OK: &bssap_assignment_command_last_channel_type == t->mo_tx_assignment_perm_speech == FR3 HR3 FR2 FR1 HR1 +- Assignment succeeds, triggering MNCC_RTP_CREATE ack to MNCC +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN decode: ASSIGNMENT_COMPLETE +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-18:RTP_TO_RAN:no-CI){UNINITIALIZED}: setting codecs to AMR:octet-align=1#112 +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-18:RTP_TO_RAN:no-CI:local-10-23-23-1-23){UNINITIALIZED}: setting remote addr to 1.2.3.4:1234 +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-18:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Not committing: no MGW endpoint CI set up +DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x8000000a tid-8) codecs: 10.23.23.1:23{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} (from: assigned=AMR:octet-align=1#112 MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) +DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x8000000a tid-8) Assignment Complete: RAN: AMR:octet-align=1#112, CN: AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111 +DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x8000000a tid-8) codecs: 10.23.23.1:23{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} (from: assigned=AMR:octet-align=1#112 MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) +DMNCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x8000000a tid-8) tx MNCC_RTP_CREATE (RTP=10.23.23.1:23{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) + MSC --> MNCC: callref 0x8000000a: MNCC_RTP_CREATE +v=0
+o=OsmoMSC 0 0 IN IP4 10.23.23.1
+s=GSM Call
+c=IN IP4 10.23.23.1
+t=0 0
+m=audio 23 RTP/AVP 112 110 3 111
+a=rtpmap:112 AMR/8000
+a=fmtp:112 octet-align=1
+a=rtpmap:110 GSM-EFR/8000
+a=rtpmap:3 GSM/8000
+a=rtpmap:111 GSM-HR-08/8000
+a=ptime:20
+ +- VALIDATE_SDP OK: cc_to_mncc_tx_last_sdp == t->mo_tx_sdp_mncc_rtp_create == AMR#98 GSM-EFR GSM GSM-HR-08 +- MNCC says that's fine + MSC <-- MNCC: callref 0x8000000a: MNCC_CALL_PROC_REQ + +DMNCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x8000000a tid-8) rx MNCC_CALL_PROC_REQ +DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x8000000a tid-8) stopping pending guard timer +DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x8000000a tid-8) starting guard timer with 180 seconds +DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x8000000a tid-8) new state INITIATED -> MO_CALL_PROC +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_CALL_PROC +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on GERAN-A +- DTAP --GERAN-A--> MS: GSM48_MT_CC_CALL_PROC: 8302 +- DTAP matches expected message +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Assignment for this trans already started earlier +- Total time passed: 1501.001115 s +- The other call leg got established (not shown here), MNCC tells us so, with codecs { AMR#98 GSM-EFR GSM GSM-HR-08 } + MSC <-- MNCC: callref 0x8000000a: MNCC_ALERT_REQ +v=0
+o=OsmoMSC 0 0 IN IP4 1.2.3.4
+s=GSM Call
+c=IN IP4 1.2.3.4
+t=0 0
+m=audio 56 RTP/AVP 98 110 3 111
+a=rtpmap:98 AMR/8000
+a=fmtp:98 octet-align=1
+a=rtpmap:110 GSM-EFR/8000
+a=rtpmap:3 GSM/8000
+a=rtpmap:111 GSM-HR-08/8000
+a=ptime:20
+ +DMNCC trans(CC:MO_CALL_PROC IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x8000000a tid-8) rx MNCC_ALERT_REQ (RTP=1.2.3.4:56{AMR:octet-align=1#98,GSM-EFR#110,GSM#3,GSM-HR-08#111}) +DCC trans(CC:MO_CALL_PROC IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x8000000a tid-8) stopping pending guard timer +DCC trans(CC:MO_CALL_PROC IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x8000000a tid-8) starting guard timer with 180 seconds +DCC trans(CC:MO_CALL_PROC IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x8000000a tid-8) new state MO_CALL_PROC -> CALL_DELIVERED +DCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x8000000a tid-8) codecs: 10.23.23.1:23{AMR:octet-align=1#98,GSM-EFR#110,GSM#3,GSM-HR-08#111} (from: assigned=AMR:octet-align=1#112 remote=1.2.3.4:56{AMR:octet-align=1#98,GSM-EFR#110,GSM#3,GSM-HR-08#111} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-18:RTP_TO_CN:no-CI){UNINITIALIZED}: setting codecs to AMR:octet-align=1#98,GSM-EFR#110,GSM#3,GSM-HR-08#111 +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-18:RTP_TO_CN:no-CI:local-10-23-23-1-23){UNINITIALIZED}: setting remote addr to 1.2.3.4:56 +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-18:RTP_TO_CN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-56){UNINITIALIZED}: Not committing: no MGW endpoint CI set up +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_ALERTING +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on GERAN-A +- DTAP --GERAN-A--> MS: GSM48_MT_CC_ALERTING: 8301 +- DTAP matches expected message +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST + MSC <-- MNCC: callref 0x8000000a: MNCC_SETUP_RSP +v=0
+o=OsmoMSC 0 0 IN IP4 1.2.3.4
+s=GSM Call
+c=IN IP4 1.2.3.4
+t=0 0
+m=audio 56 RTP/AVP 98 110 3 111
+a=rtpmap:98 AMR/8000
+a=fmtp:98 octet-align=1
+a=rtpmap:110 GSM-EFR/8000
+a=rtpmap:3 GSM/8000
+a=rtpmap:111 GSM-HR-08/8000
+a=ptime:20
+ +DMNCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x8000000a tid-8) rx MNCC_SETUP_RSP (RTP=1.2.3.4:56{AMR:octet-align=1#98,GSM-EFR#110,GSM#3,GSM-HR-08#111}) +DCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x8000000a tid-8) stopping pending guard timer +DCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x8000000a tid-8) starting guard timer with 180 seconds +DCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x8000000a tid-8) starting timer T313 with 30 seconds +DCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x8000000a tid-8) new state CALL_DELIVERED -> CONNECT_IND +DCC trans(CC:CONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x8000000a tid-8) codecs: 10.23.23.1:23{AMR:octet-align=1#98,GSM-EFR#110,GSM#3,GSM-HR-08#111} (from: assigned=AMR:octet-align=1#112 remote=1.2.3.4:56{AMR:octet-align=1#98,GSM-EFR#110,GSM#3,GSM-HR-08#111} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-18:RTP_TO_CN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-56){UNINITIALIZED}: no change: codecs already set to AMR:octet-align=1#98,GSM-EFR#110,GSM#3,GSM-HR-08#111 +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-18:RTP_TO_CN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-56){UNINITIALIZED}: remote addr already 1.2.3.4:56, no change +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-18:RTP_TO_CN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-56){UNINITIALIZED}: Not committing: no MGW endpoint CI set up +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_CONNECT +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on GERAN-A +- DTAP --GERAN-A--> MS: GSM48_MT_CC_CONNECT: 8307 +- DTAP matches expected message +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST +- Total time passed: 1502.001138 s + MSC <--GERAN-A-- MS: GSM48_MT_CC_CONNECT_ACK +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms) +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP +DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_CONNECT_ACK +DCC trans(CC:CONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x8000000a tid-8) rx CONNECT_ACK in state CONNECT_IND +DCC trans(CC:CONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x8000000a tid-8) stopping pending timer T313 +DCC trans(CC:CONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x8000000a tid-8) new state CONNECT_IND -> ACTIVE +DCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x8000000a tid-8) stopping pending guard timer +DMNCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x8000000a tid-8) tx MNCC_SETUP_COMPL_IND + MSC --> MNCC: callref 0x8000000a: MNCC_SETUP_COMPL_IND + +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc) +- VALIDATE_SDP OK: cc_to_mncc_tx_last_sdp == t->mo_tx_sdp_mncc_setup_compl_ind == + + +- RTP stream goes ahead, not shown here. +- Total time passed: 1625.001183 s + + +- Call ends + MSC <--GERAN-A-- MS: GSM48_MT_CC_DISCONNECT +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms) +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP +DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_DISCONNECT +DCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x8000000a tid-8) rx DISCONNECT in state ACTIVE +DCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x8000000a tid-8) new state ACTIVE -> DISCONNECT_IND +DMNCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x8000000a tid-8) tx MNCC_DISC_IND + MSC --> MNCC: callref 0x8000000a: MNCC_DISC_IND + +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc) + MSC <-- MNCC: callref 0x8000000a: MNCC_REL_REQ +v=0
+o=OsmoMSC 0 0 IN IP4 1.2.3.4
+s=GSM Call
+c=IN IP4 1.2.3.4
+t=0 0
+m=audio 56 RTP/AVP 98 110 3 111
+a=rtpmap:98 AMR/8000
+a=fmtp:98 octet-align=1
+a=rtpmap:110 GSM-EFR/8000
+a=rtpmap:3 GSM/8000
+a=rtpmap:111 GSM-HR-08/8000
+a=ptime:20
+ +DMNCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x8000000a tid-8) rx MNCC_REL_REQ +DCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x8000000a tid-8) starting guard timer with 180 seconds +DCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x8000000a tid-8) starting timer T308 with 10 seconds +DCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x8000000a tid-8) new state DISCONNECT_IND -> RELEASE_REQ +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_RELEASE +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on GERAN-A +- DTAP --GERAN-A--> MS: GSM48_MT_CC_RELEASE: 832d +- DTAP matches expected message +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST + MSC <--GERAN-A-- MS: GSM48_MT_CC_RELEASE_COMPL +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms) +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP +DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_RELEASE_COMPL +DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x8000000a tid-8) rx RELEASE_COMPL in state RELEASE_REQ +DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x8000000a tid-8) stopping pending timer T308 +DMNCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x8000000a tid-8) tx MNCC_REL_CNF + MSC --> MNCC: callref 0x8000000a: MNCC_REL_CNF + +DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x0 tid-8) Freeing transaction +DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x0 tid-8) new state RELEASE_REQ -> NULL +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x0 tid-8) stopping pending guard timer +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - CC: now used by 2 (attached,active-conn) +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - cc: now used by 1 (rx_from_ms) +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 0 (-) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Received Event MSC_A_EV_UNUSED +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: state_chg to MSC_A_ST_RELEASING +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: Releasing: msc_a use is 0 (-) +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + msc_a_fsm_releasing_onenter: now used by 3 (attached,active-conn,msc_a_fsm_releasing_onenter) +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,active-conn,msc_a_fsm_releasing_onenter,vlr_subscr_cancel_attach_fsm) +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,active-conn,msc_a_fsm_releasing_onenter) +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){ESTABLISHING}: state_chg to RELEASING +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-18:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Terminating (cause = OSMO_FSM_TERM_PARENT) +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-18:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Removing from parent call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ) +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-18:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Deallocated +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-18:RTP_TO_CN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-56){UNINITIALIZED}: Terminating (cause = OSMO_FSM_TERM_PARENT) +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-18:RTP_TO_CN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-56){UNINITIALIZED}: Removing from parent call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ) +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-18:RTP_TO_CN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-56){UNINITIALIZED}: Deallocated +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){RELEASING}: Terminating (cause = OSMO_FSM_TERM_REGULAR) +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){RELEASING}: Removing from parent msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: Received Event MSC_EV_CALL_LEG_TERM +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){RELEASING}: Deallocated +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: + wait-Clear-Complete: now used by 1 (wait-Clear-Complete) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: RAN encode: CLEAR_COMMAND on GERAN-A +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - msc_a_fsm_releasing_onenter: now used by 2 (attached,active-conn) +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: RAN decode: CLEAR_COMPLETE +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: - wait-Clear-Complete: now used by 0 (-) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: Received Event MSC_A_EV_UNUSED +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: state_chg to MSC_A_ST_RELEASED +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASED}: Released: msc_a use is 0 (-) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_DONE}: Terminating in cascade, depth 2 (cause = OSMO_FSM_TERM_PARENT, caused by: msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ)) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_DONE}: Removing from parent msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_DONE}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASED}: Removing from parent msub_fsm +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASED}: max total use count was 3 +DMSC msub_fsm{active}: Received Event MSUB_EV_ROLE_TERMINATED +DMSC msub(IMSI-901700000010650:MSISDN-46071) MSC-A terminated +DMSC msub(IMSI-901700000010650:MSISDN-46071) 1 MSC-I still active +DMSC msub_fsm{active}: state_chg to terminating +DMSC msub_fsm{terminating}: Terminating in cascade, depth 2 (cause = OSMO_FSM_TERM_REGULAR, caused by: msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ)) +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Terminating in cascade, depth 3 (cause = OSMO_FSM_TERM_PARENT, caused by: msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ)) +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Removing from parent msub_fsm +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ) +DMSC msub(IMSI-901700000010650:MSISDN-46071) Free +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - active-conn: now used by 1 (attached) +DMSC msub_fsm{terminating}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASED}: Deallocated, including all deferred deallocations +- msub gone + llist_count(&msub_list) == 0 + + +- ======================== SUCCESS: MO call: AMR picked by both MO and MT, but MO assigns a different payload type number + + +- ======================== MT call: AMR picked by both MO and MT, but MO assigns a different payload type number + + +- MNCC asks us to setup a call, causing Paging + MSC <-- MNCC: callref 0x423: MNCC_SETUP_REQ +v=0
+o=OsmoMSC 0 0 IN IP4 1.2.3.4
+s=GSM Call
+c=IN IP4 1.2.3.4
+t=0 0
+m=audio 56 RTP/AVP 98 110 3 111
+a=rtpmap:98 AMR/8000
+a=fmtp:98 octet-align=1
+a=rtpmap:110 GSM-EFR/8000
+a=rtpmap:3 GSM/8000
+a=rtpmap:111 GSM-HR-08/8000
+a=ptime:20
+ +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + mncc_tx_to_gsm_cc: now used by 2 (attached,mncc_tx_to_gsm_cc) +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + CC: now used by 3 (attached,mncc_tx_to_gsm_cc,CC) +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071 callref-0x423 tid-255) New transaction +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071 callref-0x423 tid-255) codecs: :0{(no-codecs)} (from: remote=1.2.3.4:56{AMR:octet-align=1#98,GSM-EFR#110,GSM#3,GSM-HR-08#111} RAN={(no-codecs)}) +DMNCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071 callref-0x423 tid-255) rx MNCC_SETUP_REQ (RTP=1.2.3.4:56{AMR:octet-align=1#98,GSM-EFR#110,GSM#3,GSM-HR-08#111}) +DPAG Paging: IMSI-901700000010650:MSISDN-46071 for MNCC: establish call: Starting paging + paging request (CALL_CONVERSATIONAL) to IMSI-901700000010650:MSISDN-46071 on GERAN-A + strcmp(paging_expecting_imsi, vsub->imsi) == 0 +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + Paging: now used by 4 (attached,mncc_tx_to_gsm_cc,CC,Paging) +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - mncc_tx_to_gsm_cc: now used by 3 (attached,CC,Paging) + paging_sent == 1 +- MS replies with Paging Response, with Codec List (BSS Supported) = FR1 FR2 FR3 HR1 HR3 +- VLR accepts, MSC sends CC Setup with Bearer Capability = AMR AMR AMR GSM-EFR GSM GSM-HR-08 + MSC <--GERAN-A-- MS: GSM48_MT_RR_PAG_RESP + new conn +DMSC msub_fsm{active}: Allocated +DMSC msc_a{MSC_A_ST_VALIDATE_L3}: Allocated +DMSC msc_a{MSC_A_ST_VALIDATE_L3}: is child of msub_fsm +DMSC msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_VALIDATE_L3 +DMSC dummy_msc_i{0}: Allocated +DMSC dummy_msc_i{0}: is child of msub_fsm +DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms) +DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3 +DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Complete Layer 3: Codec List (BSS Supported): GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111 +DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: RR GSM48_MT_RR_PAG_RESP +DRR msc_a(IMSI-901700000010650:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: Rx PAGING RESPONSE IMSI-901700000010650 +DREF msc_a(IMSI-901700000010650:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: + paging-response: now used by 2 (rx_from_ms,paging-response) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: Allocated +DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: is child of msc_a(IMSI-901700000010650:GERAN-A:PAGING_RESP) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: rev=R99 net=GERAN (no Auth) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + proc_arq_vlr_fn_init: now used by 4 (attached,CC,Paging,proc_arq_vlr_fn_init) +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + active-conn: now used by 5 (attached,CC,Paging,proc_arq_vlr_fn_init,active-conn) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi() +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_node2() +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_ciph() +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_vlr() +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_post_pres() +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_post_trace() +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_post_imei() +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: proc_arq_fsm_done(PASSED) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_DONE +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_DONE}: Process Access Request result: PASSED +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: Received Event MSC_A_EV_AUTHENTICATED +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: state_chg to MSC_A_ST_AUTHENTICATED +DPAG Paging: IMSI-901700000010650:MSISDN-46071 for MNCC: establish call: Paging Response action (success) +DPAG Paging: IMSI-901700000010650:MSISDN-46071 for MNCC: establish call: Removing Paging Request +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071 callref-0x423 tid-255) Paging succeeded +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: + cc: now used by 3 (rx_from_ms,paging-response,cc) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: Received Event MSC_A_EV_TRANSACTION_ACCEPTED +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: state_chg to MSC_A_ST_COMMUNICATING +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) starting timer T303 with 30 seconds +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) codecs: :0{AMR:octet-align=1#98,GSM-EFR#110,GSM#3,GSM-HR-08#111} (from: remote=1.2.3.4:56{AMR:octet-align=1#98,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) new state NULL -> CALL_PRESENT +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_SETUP +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on GERAN-A +- DTAP --GERAN-A--> MS: GSM48_MT_CC_SETUP: 030504076004050b020081 +- DTAP matches expected message +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - Paging: now used by 4 (attached,CC,proc_arq_vlr_fn_init,active-conn) +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - paging-response: now used by 2 (rx_from_ms,cc) +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - proc_arq_vlr_fn_init: now used by 3 (attached,CC,active-conn) +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc) +- MS confirms call, we create a RAN-side RTP and forward MNCC_CALL_CONF_IND + MSC <--GERAN-A-- MS: GSM48_MT_CC_CALL_CONF +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms) +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP +DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_CALL_CONF +DCC trans(CC:CALL_PRESENT IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx CALL_CONF in state CALL_PRESENT +DCC trans(CC:CALL_PRESENT IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) stopping pending timer T303 +DCC trans(CC:CALL_PRESENT IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) starting timer T310 with 30 seconds +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Starting call assignment +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){ESTABLISHING}: Allocated +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){ESTABLISHING}: is child of msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP) +DCC trans(CC:CALL_PRESENT IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) codecs: :0{AMR:octet-align=1#98,GSM-EFR#110,GSM#3,GSM-HR-08#111} (from: remote=1.2.3.4:56{AMR:octet-align=1#98,GSM-EFR#110,GSM#3,GSM-HR-08#111} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) + MGW <--CRCX to RTP_TO_CN-- MSC: call_id=0x13 codecs=AMR:octet-align=1#98,GSM-EFR#110,GSM#3,GSM-HR-08#111 +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){UNINITIALIZED}: Allocated +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){UNINITIALIZED}: is child of call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP) +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-19:RTP_TO_CN:no-CI){UNINITIALIZED}: setting codecs to AMR:octet-align=1#98,GSM-EFR#110,GSM#3,GSM-HR-08#111 + MGW <--CRCX to RTP_TO_RAN-- MSC: call_id=0x13 codecs=AMR:octet-align=1#98,GSM-EFR#110,GSM#3,GSM-HR-08#111 +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){UNINITIALIZED}: Allocated +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){UNINITIALIZED}: is child of call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP) +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-19:RTP_TO_RAN:no-CI){UNINITIALIZED}: setting codecs to AMR:octet-align=1#98,GSM-EFR#110,GSM#3,GSM-HR-08#111 +DCC trans(CC:CALL_PRESENT IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) new state CALL_PRESENT -> MO_TERM_CALL_CONF +DMNCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) tx MNCC_CALL_CONF_IND + MSC --> MNCC: callref 0x423: MNCC_CALL_CONF_IND + +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc) +- VALIDATE_SDP OK: cc_to_mncc_tx_last_sdp == t->mt_tx_sdp_mncc_call_conf_ind == +- MGW acknowledges the CRCX to RAN, triggering Assignment with FR3 HR3 FR2 FR1 HR1 + MGW --CRCX OK to RTP_TO_RAN--> MSC +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){ESTABLISHING}: Received Event CALL_LEG_EV_RTP_STREAM_ADDR_AVAILABLE +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Received Event MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: MGW endpoint's RTP address available for the CI RTP_TO_RAN: 10.23.23.1:23 (osmux=no:-2) +DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) codecs: :0{AMR:octet-align=1#98,GSM-EFR#110,GSM#3,GSM-HR-08#111} (from: remote=1.2.3.4:56{AMR:octet-align=1#98,GSM-EFR#110,GSM#3,GSM-HR-08#111} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) +DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) Sending Assignment Command +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN encode: ASSIGNMENT_COMMAND on GERAN-A +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST +- VALIDATE_PERM_SPEECH OK: &bssap_assignment_command_last_channel_type == t->mt_tx_assignment_perm_speech == FR3 HR3 FR2 FR1 HR1 +- Assignment completes, triggering CRCX to CN +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN decode: ASSIGNMENT_COMPLETE +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-19:RTP_TO_RAN:no-CI){UNINITIALIZED}: setting codecs to AMR:octet-align=1#112 +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-19:RTP_TO_RAN:no-CI:local-10-23-23-1-23){UNINITIALIZED}: setting remote addr to 1.2.3.4:1234 +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-19:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Not committing: no MGW endpoint CI set up +DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) codecs: :0{AMR:octet-align=1#98,GSM-EFR#110,GSM#3,GSM-HR-08#111} (from: assigned=AMR:octet-align=1#112 remote=1.2.3.4:56{AMR:octet-align=1#98,GSM-EFR#110,GSM#3,GSM-HR-08#111} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) +DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) Assignment Complete: RAN: AMR:octet-align=1#112, CN: AMR:octet-align=1#98,GSM-EFR#110,GSM#3,GSM-HR-08#111 +DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) Assignment complete, but still waiting for the CRCX OK on the CN side RTP +- MNCC sends MNCC_RTP_CREATE, which first waits for the CN side RTP + MSC <-- MNCC: callref 0x423: MNCC_RTP_CREATE + +DMNCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx MNCC_RTP_CREATE +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Assignment for this trans already started earlier +- When the CN side RTP address is known, ack MNCC_RTP_CREATE + MGW --CRCX OK to RTP_TO_CN--> MSC +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){ESTABLISHING}: Received Event CALL_LEG_EV_RTP_STREAM_ADDR_AVAILABLE +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Received Event MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: MGW endpoint's RTP address available for the CI RTP_TO_CN: 10.23.23.1:23 (osmux=no:-2) +DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) codecs: 10.23.23.1:23{AMR:octet-align=1#98,GSM-EFR#110,GSM#3,GSM-HR-08#111} (from: assigned=AMR:octet-align=1#112 remote=1.2.3.4:56{AMR:octet-align=1#98,GSM-EFR#110,GSM#3,GSM-HR-08#111} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) +DMNCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) tx MNCC_RTP_CREATE (RTP=10.23.23.1:23{AMR:octet-align=1#98,GSM-EFR#110,GSM#3,GSM-HR-08#111}) + MSC --> MNCC: callref 0x423: MNCC_RTP_CREATE +v=0
+o=OsmoMSC 0 0 IN IP4 10.23.23.1
+s=GSM Call
+c=IN IP4 10.23.23.1
+t=0 0
+m=audio 23 RTP/AVP 98 110 3 111
+a=rtpmap:98 AMR/8000
+a=fmtp:98 octet-align=1
+a=rtpmap:110 GSM-EFR/8000
+a=rtpmap:3 GSM/8000
+a=rtpmap:111 GSM-HR-08/8000
+a=ptime:20
+ +- VALIDATE_SDP OK: cc_to_mncc_tx_last_sdp == t->mt_tx_sdp_mncc_rtp_create == AMR#98 GSM-EFR GSM GSM-HR-08 +- Total time passed: 1626.001206 s + MSC <--GERAN-A-- MS: GSM48_MT_CC_ALERTING +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms) +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP +DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_ALERTING +DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx ALERTING in state MO_TERM_CALL_CONF +DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) stopping pending timer T310 +DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) starting timer T301 with 180 seconds +DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) new state MO_TERM_CALL_CONF -> CALL_RECEIVED +DCC trans(CC:CALL_RECEIVED IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) codecs: 10.23.23.1:23{AMR:octet-align=1#98,GSM-EFR#110,GSM#3,GSM-HR-08#111} (from: assigned=AMR:octet-align=1#112 remote=1.2.3.4:56{AMR:octet-align=1#98,GSM-EFR#110,GSM#3,GSM-HR-08#111} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) +DMNCC trans(CC:CALL_RECEIVED IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) tx MNCC_ALERT_IND (RTP=10.23.23.1:23{AMR:octet-align=1#98,GSM-EFR#110,GSM#3,GSM-HR-08#111}) + MSC --> MNCC: callref 0x423: MNCC_ALERT_IND +v=0
+o=OsmoMSC 0 0 IN IP4 10.23.23.1
+s=GSM Call
+c=IN IP4 10.23.23.1
+t=0 0
+m=audio 23 RTP/AVP 98 110 3 111
+a=rtpmap:98 AMR/8000
+a=fmtp:98 octet-align=1
+a=rtpmap:110 GSM-EFR/8000
+a=rtpmap:3 GSM/8000
+a=rtpmap:111 GSM-HR-08/8000
+a=ptime:20
+ +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc) +- VALIDATE_SDP OK: cc_to_mncc_tx_last_sdp == t->mt_tx_sdp_mncc_alert_ind == AMR#98 GSM-EFR GSM GSM-HR-08 +- Total time passed: 1627.001229 s + MSC <--GERAN-A-- MS: GSM48_MT_CC_CONNECT +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms) +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP +DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_CONNECT +DCC trans(CC:CALL_RECEIVED IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx CONNECT in state CALL_RECEIVED +DCC trans(CC:CALL_RECEIVED IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) stopping pending timer T301 +DCC trans(CC:CALL_RECEIVED IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) new state CALL_RECEIVED -> CONNECT_REQUEST +DCC trans(CC:CONNECT_REQUEST IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) codecs: 10.23.23.1:23{AMR:octet-align=1#98,GSM-EFR#110,GSM#3,GSM-HR-08#111} (from: assigned=AMR:octet-align=1#112 remote=1.2.3.4:56{AMR:octet-align=1#98,GSM-EFR#110,GSM#3,GSM-HR-08#111} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111}) +DMNCC trans(CC:CONNECT_REQUEST IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) tx MNCC_SETUP_CNF (RTP=10.23.23.1:23{AMR:octet-align=1#98,GSM-EFR#110,GSM#3,GSM-HR-08#111}) + MSC --> MNCC: callref 0x423: MNCC_SETUP_CNF +v=0
+o=OsmoMSC 0 0 IN IP4 10.23.23.1
+s=GSM Call
+c=IN IP4 10.23.23.1
+t=0 0
+m=audio 23 RTP/AVP 98 110 3 111
+a=rtpmap:98 AMR/8000
+a=fmtp:98 octet-align=1
+a=rtpmap:110 GSM-EFR/8000
+a=rtpmap:3 GSM/8000
+a=rtpmap:111 GSM-HR-08/8000
+a=ptime:20
+ +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc) +- VALIDATE_SDP OK: cc_to_mncc_tx_last_sdp == t->mt_tx_sdp_mncc_setup_cnf == AMR#98 GSM-EFR GSM GSM-HR-08 + MSC <-- MNCC: callref 0x423: MNCC_SETUP_COMPL_REQ + +DMNCC trans(CC:CONNECT_REQUEST IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx MNCC_SETUP_COMPL_REQ +DCC trans(CC:CONNECT_REQUEST IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) starting guard timer with 180 seconds +DCC trans(CC:CONNECT_REQUEST IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) new state CONNECT_REQUEST -> ACTIVE +DCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) stopping pending guard timer +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_CONNECT_ACK +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on GERAN-A +- DTAP --GERAN-A--> MS: GSM48_MT_CC_CONNECT_ACK: 030f +- DTAP matches expected message +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST + + +- RTP stream goes ahead, not shown here. +- Total time passed: 1750.001274 s + + +- Call ends + MSC <--GERAN-A-- MS: GSM48_MT_CC_DISCONNECT +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms) +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP +DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_DISCONNECT +DCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx DISCONNECT in state ACTIVE +DCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) new state ACTIVE -> DISCONNECT_IND +DMNCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) tx MNCC_DISC_IND + MSC --> MNCC: callref 0x423: MNCC_DISC_IND + +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc) + MSC <-- MNCC: callref 0x423: MNCC_REL_REQ + +DMNCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx MNCC_REL_REQ +DCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) starting guard timer with 180 seconds +DCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) starting timer T308 with 10 seconds +DCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) new state DISCONNECT_IND -> RELEASE_REQ +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_RELEASE +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on GERAN-A +- DTAP --GERAN-A--> MS: GSM48_MT_CC_RELEASE: 032d +- DTAP matches expected message +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST + MSC <--GERAN-A-- MS: GSM48_MT_CC_RELEASE_COMPL +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms) +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP +DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_RELEASE_COMPL +DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx RELEASE_COMPL in state RELEASE_REQ +DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) stopping pending timer T308 +DMNCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) tx MNCC_REL_CNF + MSC --> MNCC: callref 0x423: MNCC_REL_CNF + +DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x0 tid-0) Freeing transaction +DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x0 tid-0) new state RELEASE_REQ -> NULL +DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x0 tid-0) stopping pending guard timer +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - CC: now used by 2 (attached,active-conn) +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - cc: now used by 1 (rx_from_ms) +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 0 (-) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Received Event MSC_A_EV_UNUSED +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: state_chg to MSC_A_ST_RELEASING +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: Releasing: msc_a use is 0 (-) +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + msc_a_fsm_releasing_onenter: now used by 3 (attached,active-conn,msc_a_fsm_releasing_onenter) +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,active-conn,msc_a_fsm_releasing_onenter,vlr_subscr_cancel_attach_fsm) +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,active-conn,msc_a_fsm_releasing_onenter) +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){ESTABLISHING}: state_chg to RELEASING +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-19:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Terminating (cause = OSMO_FSM_TERM_PARENT) +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-19:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Removing from parent call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP) +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-19:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Deallocated +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-19:RTP_TO_CN:no-CI){UNINITIALIZED}: Terminating (cause = OSMO_FSM_TERM_PARENT) +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-19:RTP_TO_CN:no-CI){UNINITIALIZED}: Removing from parent call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP) +DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-19:RTP_TO_CN:no-CI){UNINITIALIZED}: Deallocated +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){RELEASING}: Terminating (cause = OSMO_FSM_TERM_REGULAR) +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){RELEASING}: Removing from parent msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: Received Event MSC_EV_CALL_LEG_TERM +DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){RELEASING}: Deallocated +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: + wait-Clear-Complete: now used by 1 (wait-Clear-Complete) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: RAN encode: CLEAR_COMMAND on GERAN-A +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - msc_a_fsm_releasing_onenter: now used by 2 (attached,active-conn) +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: RAN decode: CLEAR_COMPLETE +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: - wait-Clear-Complete: now used by 0 (-) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: Received Event MSC_A_EV_UNUSED +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: state_chg to MSC_A_ST_RELEASED +DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASED}: Released: msc_a use is 0 (-) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_DONE}: Terminating in cascade, depth 2 (cause = OSMO_FSM_TERM_PARENT, caused by: msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP)) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_DONE}: Removing from parent msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_DONE}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASED}: Removing from parent msub_fsm +DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASED}: max total use count was 3 +DMSC msub_fsm{active}: Received Event MSUB_EV_ROLE_TERMINATED +DMSC msub(IMSI-901700000010650:MSISDN-46071) MSC-A terminated +DMSC msub(IMSI-901700000010650:MSISDN-46071) 1 MSC-I still active +DMSC msub_fsm{active}: state_chg to terminating +DMSC msub_fsm{terminating}: Terminating in cascade, depth 2 (cause = OSMO_FSM_TERM_REGULAR, caused by: msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP)) +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Terminating in cascade, depth 3 (cause = OSMO_FSM_TERM_PARENT, caused by: msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP)) +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Removing from parent msub_fsm +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP) +DMSC msub(IMSI-901700000010650:MSISDN-46071) Free +DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - active-conn: now used by 1 (attached) +DMSC msub_fsm{terminating}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP) +DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASED}: Deallocated, including all deferred deallocations +- msub gone + llist_count(&msub_list) == 0 + + +- ======================== SUCCESS: MT call: AMR picked by both MO and MT, but MO assigns a different payload type number + llist_count(&msub_list) == 0 +DVLR freeing VLR subscr IMSI-901700000010650:MSISDN-46071 (max total use count was 5) +===== test_codecs: SUCCESS diff --git a/tests/msc_vlr/msc_vlr_test_gsm_authen.c b/tests/msc_vlr/msc_vlr_test_gsm_authen.c index 805ae6425..6d7e88a0d 100644 --- a/tests/msc_vlr/msc_vlr_test_gsm_authen.c +++ b/tests/msc_vlr/msc_vlr_test_gsm_authen.c @@ -22,7 +22,6 @@ */ #include "msc_vlr_tests.h" -#include "stubs.h" static void test_gsm_authen() { @@ -35,7 +34,7 @@ static void test_gsm_authen() btw("Location Update request causes a GSUP Send Auth Info request to HLR"); lu_result_sent = RES_NONE; - gsup_expect_tx("08010809710000004026f0" VLR_TO_HLR); + gsup_expect_tx("08010809710000004026f0" CN_DOMAIN VLR_TO_HLR); ms_sends_msg("0508020081680001" "30" /* <-- Revision Level == 1, i.e. is_r99 == false */ "089910070000006402"); @@ -77,7 +76,7 @@ static void test_gsm_authen() VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); btw("MS sends Authen Response, VLR accepts and sends GSUP LU Req to HLR"); - gsup_expect_tx("04010809710000004026f0280102" VLR_TO_HLR); + gsup_expect_tx("04010809710000004026f0" CN_DOMAIN VLR_TO_HLR); ms_sends_msg("05542d8b2c3e"); VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); @@ -114,7 +113,7 @@ static void test_gsm_authen() VERBOSE_ASSERT(cm_service_result_sent, == RES_ACCEPT, "%d"); /* Release connection */ - expect_bssap_clear(OSMO_RAT_GERAN_A); + expect_bssap_clear(); conn_conclude_cm_service_req(g_msub, MSC_A_USE_CM_SERVICE_SMS); btw("all requests serviced, conn has been released"); @@ -225,7 +224,7 @@ static void test_gsm_authen_tmsi() btw("Location Update request causes a GSUP Send Auth Info request to HLR"); lu_result_sent = RES_NONE; - gsup_expect_tx("08010809710000004026f0" VLR_TO_HLR); + gsup_expect_tx("08010809710000004026f0" CN_DOMAIN VLR_TO_HLR); ms_sends_msg("0508020081680001" "30" /* <-- Revision Level == 1, i.e. is_r99 == false */ "089910070000006402"); @@ -267,7 +266,7 @@ static void test_gsm_authen_tmsi() VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); btw("MS sends Authen Response, VLR accepts and sends GSUP LU Req to HLR"); - gsup_expect_tx("04010809710000004026f0280102" VLR_TO_HLR); + gsup_expect_tx("04010809710000004026f0" CN_DOMAIN VLR_TO_HLR); ms_sends_msg("05542d8b2c3e"); VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); @@ -328,7 +327,7 @@ static void test_gsm_authen_tmsi() VERBOSE_ASSERT(cm_service_result_sent, == RES_ACCEPT, "%d"); /* Release connection */ - expect_bssap_clear(OSMO_RAT_GERAN_A); + expect_bssap_clear(); conn_conclude_cm_service_req(g_msub, MSC_A_USE_CM_SERVICE_SMS); btw("all requests serviced, conn has been released"); @@ -439,7 +438,7 @@ static void test_gsm_authen_tmsi() VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); btw("MS sends Authen Response, VLR accepts and sends GSUP LU Req to HLR"); - gsup_expect_tx("04010809710000004026f0280102" VLR_TO_HLR); + gsup_expect_tx("04010809710000004026f0" CN_DOMAIN VLR_TO_HLR); ms_sends_msg("05545afc8d72"); VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); @@ -505,7 +504,7 @@ static void test_gsm_authen_imei() btw("Location Update request causes a GSUP Send Auth Info request to HLR"); lu_result_sent = RES_NONE; - gsup_expect_tx("08010809710000004026f0" VLR_TO_HLR); + gsup_expect_tx("08010809710000004026f0" CN_DOMAIN VLR_TO_HLR); ms_sends_msg("0508020081680001" "30" /* <-- Revision Level == 1, i.e. is_r99 == false */ "089910070000006402"); @@ -545,7 +544,7 @@ static void test_gsm_authen_imei() VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); btw("MS sends Authen Response, VLR accepts and sends GSUP LU Req to HLR"); - gsup_expect_tx("04010809710000004026f0280102" VLR_TO_HLR); + gsup_expect_tx("04010809710000004026f0" CN_DOMAIN VLR_TO_HLR); ms_sends_msg("05542d8b2c3e"); VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); @@ -612,7 +611,7 @@ static void test_gsm_authen_imei_nack() btw("Location Update request causes a GSUP Send Auth Info request to HLR"); lu_result_sent = RES_NONE; - gsup_expect_tx("08010809710000004026f0" VLR_TO_HLR); + gsup_expect_tx("08010809710000004026f0" CN_DOMAIN VLR_TO_HLR); ms_sends_msg("0508020081680001" "30" /* <-- Revision Level == 1, i.e. is_r99 == false */ "089910070000006402"); @@ -654,7 +653,7 @@ static void test_gsm_authen_imei_nack() VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); btw("MS sends Authen Response, VLR accepts and sends GSUP LU Req to HLR"); - gsup_expect_tx("04010809710000004026f0280102" VLR_TO_HLR); + gsup_expect_tx("04010809710000004026f0" CN_DOMAIN VLR_TO_HLR); ms_sends_msg("05542d8b2c3e"); VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); @@ -706,7 +705,7 @@ static void test_gsm_authen_imei_err() btw("Location Update request causes a GSUP Send Auth Info request to HLR"); lu_result_sent = RES_NONE; - gsup_expect_tx("08010809710000004026f0" VLR_TO_HLR); + gsup_expect_tx("08010809710000004026f0" CN_DOMAIN VLR_TO_HLR); ms_sends_msg("0508020081680001" "30" /* <-- Revision Level == 1, i.e. is_r99 == false */ "089910070000006402"); @@ -747,7 +746,7 @@ static void test_gsm_authen_imei_err() VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); btw("MS sends Authen Response, VLR accepts and sends GSUP LU Req to HLR"); - gsup_expect_tx("04010809710000004026f0280102" VLR_TO_HLR); + gsup_expect_tx("04010809710000004026f0" CN_DOMAIN VLR_TO_HLR); ms_sends_msg("05542d8b2c3e"); VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); @@ -800,7 +799,7 @@ static void test_gsm_authen_tmsi_imei() btw("Location Update request causes a GSUP Send Auth Info request to HLR"); lu_result_sent = RES_NONE; - gsup_expect_tx("08010809710000004026f0" VLR_TO_HLR); + gsup_expect_tx("08010809710000004026f0" CN_DOMAIN VLR_TO_HLR); ms_sends_msg("0508020081680001" "30" /* <-- Revision Level == 1, i.e. is_r99 == false */ "089910070000006402"); @@ -841,7 +840,7 @@ static void test_gsm_authen_tmsi_imei() VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); btw("MS sends Authen Response, VLR accepts and sends GSUP LU Req to HLR"); - gsup_expect_tx("04010809710000004026f0280102" VLR_TO_HLR); + gsup_expect_tx("04010809710000004026f0" CN_DOMAIN VLR_TO_HLR); ms_sends_msg("05542d8b2c3e"); VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); @@ -925,7 +924,7 @@ static void test_gsm_milenage_authen() btw("Location Update request causes a GSUP Send Auth Info request to HLR"); lu_result_sent = RES_NONE; - gsup_expect_tx("080108" "09710000000156f0" VLR_TO_HLR); + gsup_expect_tx("080108" "09710000000156f0" CN_DOMAIN VLR_TO_HLR); ms_sends_msg("0508" /* MM LU */ "7" /* ciph key seq: no key available */ "0" /* LU type: normal */ @@ -978,7 +977,7 @@ static void test_gsm_milenage_authen() VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); btw("MS sends Authen Response, VLR accepts and sends GSUP LU Req to HLR"); - gsup_expect_tx("04010809710000000156f0280102" VLR_TO_HLR); + gsup_expect_tx("04010809710000000156f0" CN_DOMAIN VLR_TO_HLR); ms_sends_msg("0554" "9b36efdf"); VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); @@ -1018,7 +1017,7 @@ static void test_gsm_milenage_authen() VERBOSE_ASSERT(cm_service_result_sent, == RES_ACCEPT, "%d"); /* Release connection */ - expect_bssap_clear(OSMO_RAT_GERAN_A); + expect_bssap_clear(); conn_conclude_cm_service_req(g_msub, MSC_A_USE_CM_SERVICE_SMS); btw("all requests serviced, conn has been released"); @@ -1130,7 +1129,7 @@ static void test_wrong_sres_length() btw("Location Update request causes a GSUP Send Auth Info request to HLR"); lu_result_sent = RES_NONE; - gsup_expect_tx("08010809710000004026f0" VLR_TO_HLR); + gsup_expect_tx("08010809710000004026f0" CN_DOMAIN VLR_TO_HLR); ms_sends_msg("0508020081680001" "30" /* <-- Revision Level == 1, i.e. is_r99 == false */ "089910070000006402"); diff --git a/tests/msc_vlr/msc_vlr_test_gsm_authen.err b/tests/msc_vlr/msc_vlr_test_gsm_authen.err index 45b047d86..94c169488 100644 --- a/tests/msc_vlr/msc_vlr_test_gsm_authen.err +++ b/tests/msc_vlr/msc_vlr_test_gsm_authen.err @@ -1,7 +1,3 @@ -DLMGCP MGCP client: using endpoint domain '@mgw' -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 17 - ===== test_gsm_authen - Location Update request causes a GSUP Send Auth Info request to HLR MSC <--GERAN-A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST @@ -30,13 +26,14 @@ DREF VLR subscr IMSI-901700000004620 + active-conn: now used by 2 (_lu_fsm_assoc DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH DREF VLR subscr IMSI-901700000004620 - _lu_fsm_associate_vsub: now used by 1 (active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Allocated DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU) DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START -GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f00a0101 +GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f02801020a0101 DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - mm_rx_loc_upd_req: now used by 2 (rx_from_ms,lu) DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu) @@ -94,9 +91,11 @@ DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: Au DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU) -DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES +DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_SUCCESS DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_ciph() +DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(IMSI-901700000004620:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_node_4() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD DVLR upd_hlr_vlr_fsm(IMSI-901700000004620:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated @@ -257,6 +256,8 @@ DVLR VLR_Authenticate(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){ DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: Received Event PR_ARQ_E_AUTH_RES DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2() DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2_post_ciph() +DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2_post_vlr() DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_pres() DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_trace() @@ -264,6 +265,7 @@ DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SER DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: proc_arq_fsm_done(PASSED) DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: state_chg to PR_ARQ_S_DONE DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_DONE}: Process Access Request result: PASSED +DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: Sending DTAP: MM GSM48_MT_MM_CM_SERV_ACC DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN encode: DTAP on GERAN-A - DTAP --GERAN-A--> MS: GSM48_MT_MM_CM_SERV_ACC: 0521 DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST @@ -351,7 +353,7 @@ DMSC dummy_msc_i{0}: is child of msub_fsm DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms) DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3 DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: RR GSM48_MT_RR_PAG_RESP -DRR msc_a(IMSI-901700000004620:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: Rx PAGING RESPONSE +DRR msc_a(IMSI-901700000004620:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: Rx PAGING RESPONSE IMSI-901700000004620 DREF msc_a(IMSI-901700000004620:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: + paging-response: now used by 2 (rx_from_ms,paging-response) DVLR Process_Access_Request_VLR(IMSI-901700000004620:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: Allocated DVLR Process_Access_Request_VLR(IMSI-901700000004620:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: is child of msc_a(IMSI-901700000004620:GERAN-A:PAGING_RESP) @@ -409,6 +411,8 @@ DVLR VLR_Authenticate(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){VLR DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_WAIT_AUTH}: Received Event PR_ARQ_E_AUTH_RES DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2() DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2_post_ciph() +DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2_post_vlr() DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_pres() DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_trace() @@ -427,6 +431,7 @@ DLSMS SMC(0) send CP data DLSMS SMC(0) new CP state MM_CONN_PENDING -> WAIT_CP_ACK DLSMS trans(SMS IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x40000001 tid-0) sending CP message (trans=0) DLSMS trans(SMS IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x40000001 tid-0) GSM4.11 TX 09 01 58 01 00 07 91 44 77 58 10 06 50 00 4c 00 05 80 64 70 f1 00 00 07 10 10 00 00 00 00 44 50 79 da 1e 1e e7 41 69 37 48 5e 9e a7 c9 65 37 3d 1d 66 83 c2 70 38 3b 3d 0e d3 d3 6f f7 1c 94 9e 83 c2 20 72 79 9e 96 87 c5 ec 32 a8 1d 96 af cb f4 b4 fb 0c 7a c3 e9 e9 b7 db 05 +DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: Sending DTAP: SMS SMS:0x01 DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: RAN encode: DTAP on GERAN-A - DTAP --GERAN-A--> MS: SMS:0x01: 09015801000791447758100650004c0005806470f1000007101000000000445079da1e1ee7416937485e9ea7c965373d1d6683c270383b3d0ed3d36ff71c949e83c22072799e9687c5ec32a81d96afcbf4b4fb0c7ac3e9e9b7db05 - DTAP matches expected message @@ -463,6 +468,7 @@ DLSMS SMC(0) message MMSMS-DATA-IND (CP DATA) received in state MM_ESTABLISHED DLSMS SMC(0) received CP-DATA DLSMS trans(SMS IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x40000001 tid-0) sending CP message (trans=0) DLSMS trans(SMS IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x40000001 tid-0) GSM4.11 TX 09 04 +DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: Sending DTAP: SMS SMS:0x04 DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: RAN encode: DTAP on GERAN-A - DTAP --GERAN-A--> MS: SMS:0x04: 0904 - DTAP matches expected message @@ -535,12 +541,13 @@ DMSC dummy_msc_i{0}: is child of msub_fsm DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms) DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3 DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: MM GSM48_MT_MM_IMSI_DETACH_IND -DMM IMSI DETACH INDICATION: MI(IMSI)=901700000004620 +DMM IMSI DETACH INDICATION: IMSI-901700000004620 DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + gsm48_rx_mm_imsi_detach_ind: now used by 2 (attached,gsm48_rx_mm_imsi_detach_ind) DMM IMSI DETACH for IMSI-901700000004620:MSISDN-46071 DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + active-conn: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn) DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn,vlr_subscr_cancel_attach_fsm) DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - attached: now used by 2 (gsm48_rx_mm_imsi_detach_ind,active-conn) DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - gsm48_rx_mm_imsi_detach_ind: now used by 1 (active-conn) DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_CN_CLOSE @@ -580,9 +587,6 @@ DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:NONE){MSC_A_ST_RELEASED}: D llist_count(&msub_list) == 0 ===== test_gsm_authen: SUCCESS -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 17 - ===== test_gsm_authen_tmsi - Location Update request causes a GSUP Send Auth Info request to HLR MSC <--GERAN-A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST @@ -611,13 +615,14 @@ DREF VLR subscr IMSI-901700000004620 + active-conn: now used by 2 (_lu_fsm_assoc DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH DREF VLR subscr IMSI-901700000004620 - _lu_fsm_associate_vsub: now used by 1 (active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Allocated DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU) DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START -GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f00a0101 +GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f02801020a0101 DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - mm_rx_loc_upd_req: now used by 2 (rx_from_ms,lu) DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu) @@ -675,9 +680,11 @@ DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: Au DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU) -DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES +DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_SUCCESS DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_ciph() +DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(IMSI-901700000004620:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_node_4() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD DVLR upd_hlr_vlr_fsm(IMSI-901700000004620:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated @@ -885,6 +892,8 @@ DVLR VLR_Authenticate(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A: DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: Received Event PR_ARQ_E_AUTH_RES DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2() DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2_post_ciph() +DMSC msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2_post_vlr() DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_pres() DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_trace() @@ -892,6 +901,7 @@ DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:TMSI-0x0302010 DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: proc_arq_fsm_done(PASSED) DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: state_chg to PR_ARQ_S_DONE DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_DONE}: Process Access Request result: PASSED +DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: Sending DTAP: MM GSM48_MT_MM_CM_SERV_ACC DMSC msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN encode: DTAP on GERAN-A - DTAP --GERAN-A--> MS: GSM48_MT_MM_CM_SERV_ACC: 0521 DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST @@ -979,7 +989,7 @@ DMSC dummy_msc_i{0}: is child of msub_fsm DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms) DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3 DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: RR GSM48_MT_RR_PAG_RESP -DRR msc_a(TMSI-0x03020100:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: Rx PAGING RESPONSE +DRR msc_a(TMSI-0x03020100:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: Rx PAGING RESPONSE TMSI-0x03020100 DREF msc_a(TMSI-0x03020100:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: + paging-response: now used by 2 (rx_from_ms,paging-response) DVLR Process_Access_Request_VLR(TMSI-0x03020100:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: Allocated DVLR Process_Access_Request_VLR(TMSI-0x03020100:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: is child of msc_a(TMSI-0x03020100:GERAN-A:PAGING_RESP) @@ -1037,6 +1047,8 @@ DVLR VLR_Authenticate(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A: DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:PAGING_RESP){PR_ARQ_S_WAIT_AUTH}: Received Event PR_ARQ_E_AUTH_RES DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:PAGING_RESP){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2() DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:PAGING_RESP){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2_post_ciph() +DMSC msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:PAGING_RESP){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2_post_vlr() DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:PAGING_RESP){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_pres() DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:PAGING_RESP){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_trace() @@ -1055,6 +1067,7 @@ DLSMS SMC(0) send CP data DLSMS SMC(0) new CP state MM_CONN_PENDING -> WAIT_CP_ACK DLSMS trans(SMS IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:PAGING_RESP callref-0x40000002 tid-0) sending CP message (trans=0) DLSMS trans(SMS IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:PAGING_RESP callref-0x40000002 tid-0) GSM4.11 TX 09 01 58 01 00 07 91 44 77 58 10 06 50 00 4c 00 05 80 64 70 f1 00 00 07 10 10 00 00 00 00 44 50 79 da 1e 1e e7 41 69 37 48 5e 9e a7 c9 65 37 3d 1d 66 83 c2 70 38 3b 3d 0e d3 d3 6f f7 1c 94 9e 83 c2 20 72 79 9e 96 87 c5 ec 32 a8 1d 96 af cb f4 b4 fb 0c 7a c3 e9 e9 b7 db 05 +DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: Sending DTAP: SMS SMS:0x01 DMSC msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: RAN encode: DTAP on GERAN-A - DTAP --GERAN-A--> MS: SMS:0x01: 09015801000791447758100650004c0005806470f1000007101000000000445079da1e1ee7416937485e9ea7c965373d1d6683c270383b3d0ed3d36ff71c949e83c22072799e9687c5ec32a81d96afcbf4b4fb0c7ac3e9e9b7db05 - DTAP matches expected message @@ -1091,6 +1104,7 @@ DLSMS SMC(0) message MMSMS-DATA-IND (CP DATA) received in state MM_ESTABLISHED DLSMS SMC(0) received CP-DATA DLSMS trans(SMS IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:PAGING_RESP callref-0x40000002 tid-0) sending CP message (trans=0) DLSMS trans(SMS IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:PAGING_RESP callref-0x40000002 tid-0) GSM4.11 TX 09 04 +DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: Sending DTAP: SMS SMS:0x04 DMSC msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: RAN encode: DTAP on GERAN-A - DTAP --GERAN-A--> MS: SMS:0x04: 0904 - DTAP matches expected message @@ -1177,6 +1191,7 @@ DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100 + active-conn: DMSC msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK DMSC msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100 - _lu_fsm_associate_vsub: now used by 2 (attached,active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre() DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH @@ -1205,9 +1220,11 @@ DVLR VLR_Authenticate(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A: DVLR VLR_Authenticate(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED DVLR VLR_Authenticate(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) DVLR VLR_Authenticate(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:LU) -DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES +DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_SUCCESS DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth() DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_ciph() +DMSC msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_node_4() DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD DVLR upd_hlr_vlr_fsm(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated @@ -1355,12 +1372,13 @@ DMSC dummy_msc_i{0}: is child of msub_fsm DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms) DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3 DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: MM GSM48_MT_MM_IMSI_DETACH_IND -DMM IMSI DETACH INDICATION: MI(TMSI)=117835012 +DMM IMSI DETACH INDICATION: TMSI-0x07060504 DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x07060504 + gsm48_rx_mm_imsi_detach_ind: now used by 2 (attached,gsm48_rx_mm_imsi_detach_ind) DMM IMSI DETACH for IMSI-901700000004620:MSISDN-46071:TMSI-0x07060504 DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x07060504 + active-conn: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn) DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x07060504 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn,vlr_subscr_cancel_attach_fsm) DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x07060504 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x07060504 - attached: now used by 2 (gsm48_rx_mm_imsi_detach_ind,active-conn) DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x07060504 - gsm48_rx_mm_imsi_detach_ind: now used by 1 (active-conn) DMSC msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x07060504:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_CN_CLOSE @@ -1400,9 +1418,6 @@ DMSC msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x07060504:GERAN-A:NONE){MSC_A llist_count(&msub_list) == 0 ===== test_gsm_authen_tmsi: SUCCESS -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 17 - ===== test_gsm_authen_imei - Location Update request causes a GSUP Send Auth Info request to HLR MSC <--GERAN-A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST @@ -1431,13 +1446,14 @@ DREF VLR subscr IMSI-901700000004620 + active-conn: now used by 2 (_lu_fsm_assoc DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH DREF VLR subscr IMSI-901700000004620 - _lu_fsm_associate_vsub: now used by 1 (active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Allocated DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU) DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START -GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f00a0101 +GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f02801020a0101 DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - mm_rx_loc_upd_req: now used by 2 (rx_from_ms,lu) DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu) @@ -1495,9 +1511,11 @@ DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: Au DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU) -DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES +DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_SUCCESS DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_ciph() +DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(IMSI-901700000004620:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_node_4() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD DVLR upd_hlr_vlr_fsm(IMSI-901700000004620:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated @@ -1533,6 +1551,7 @@ DVLR lu_compl_vlr_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){LU_COMPL_VLR DVLR lu_compl_vlr_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES DVLR lu_compl_vlr_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL DVLR lu_compl_vlr_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_WAIT_IMEI +DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: Sending DTAP: MM GSM48_MT_MM_ID_REQ DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: DTAP on GERAN-A - DTAP --GERAN-A--> MS: GSM48_MT_MM_ID_REQ: 051802 - DTAP matches expected message @@ -1568,7 +1587,7 @@ DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: DREF msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: + rx_from_ms: now used by 2 (lu,rx_from_ms) DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN decode: DTAP DRLL msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: Dispatching 04.08 message: MM GSM48_MT_MM_ID_RESP -DMM IDENTITY RESPONSE: MI=IMEI-423423423423420 +DMM IDENTITY RESPONSE: IMEI-423423423423420 DVLR set IMEI on subscriber; IMSI=901700000004620 IMEI=42342342342342 DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_ID_IMEI GSUP --> HLR: OSMO_GSUP_MSGT_CHECK_IMEI_REQUEST: 30010809710000004026f0500807244332244332240a0101 @@ -1666,12 +1685,13 @@ DMSC dummy_msc_i{0}: is child of msub_fsm DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms) DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3 DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: MM GSM48_MT_MM_IMSI_DETACH_IND -DMM IMSI DETACH INDICATION: MI(IMSI)=901700000004620 +DMM IMSI DETACH INDICATION: IMSI-901700000004620 DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + gsm48_rx_mm_imsi_detach_ind: now used by 2 (attached,gsm48_rx_mm_imsi_detach_ind) DMM IMSI DETACH for IMSI-901700000004620:MSISDN-46071 DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + active-conn: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn) DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn,vlr_subscr_cancel_attach_fsm) DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - attached: now used by 2 (gsm48_rx_mm_imsi_detach_ind,active-conn) DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - gsm48_rx_mm_imsi_detach_ind: now used by 1 (active-conn) DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_CN_CLOSE @@ -1711,9 +1731,6 @@ DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:NONE){MSC_A_ST_RELEASED}: D llist_count(&msub_list) == 0 ===== test_gsm_authen_imei: SUCCESS -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 17 - ===== test_gsm_authen_imei_nack - Location Update request causes a GSUP Send Auth Info request to HLR MSC <--GERAN-A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST @@ -1742,13 +1759,14 @@ DREF VLR subscr IMSI-901700000004620 + active-conn: now used by 2 (_lu_fsm_assoc DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH DREF VLR subscr IMSI-901700000004620 - _lu_fsm_associate_vsub: now used by 1 (active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Allocated DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU) DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START -GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f00a0101 +GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f02801020a0101 DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - mm_rx_loc_upd_req: now used by 2 (rx_from_ms,lu) DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu) @@ -1806,9 +1824,11 @@ DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: Au DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU) -DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES +DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_SUCCESS DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_ciph() +DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(IMSI-901700000004620:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_node_4() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD DVLR upd_hlr_vlr_fsm(IMSI-901700000004620:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated @@ -1844,6 +1864,7 @@ DVLR lu_compl_vlr_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){LU_COMPL_VLR DVLR lu_compl_vlr_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES DVLR lu_compl_vlr_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL DVLR lu_compl_vlr_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_WAIT_IMEI +DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: Sending DTAP: MM GSM48_MT_MM_ID_REQ DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: DTAP on GERAN-A - DTAP --GERAN-A--> MS: GSM48_MT_MM_ID_REQ: 051802 - DTAP matches expected message @@ -1879,7 +1900,7 @@ DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: DREF msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: + rx_from_ms: now used by 2 (lu,rx_from_ms) DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN decode: DTAP DRLL msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: Dispatching 04.08 message: MM GSM48_MT_MM_ID_RESP -DMM IDENTITY RESPONSE: MI=IMEI-423423423423420 +DMM IDENTITY RESPONSE: IMEI-423423423423420 DVLR set IMEI on subscriber; IMSI=901700000004620 IMEI=42342342342342 DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_ID_IMEI GSUP --> HLR: OSMO_GSUP_MSGT_CHECK_IMEI_REQUEST: 30010809710000004026f0500807244332244332240a0101 @@ -1907,7 +1928,6 @@ DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + vlr_gsup_rx: now used by 2 (active-conn,vlr_gsup_rx) DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_HLR_IMEI_NACK DVLR lu_compl_vlr_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){LU_COMPL_VLR_S_WAIT_IMEI}: Received Event LU_COMPL_VLR_E_IMEI_CHECK_NACK -- sending LU Reject for IMSI-901700000004620:MSISDN-46071:GERAN-A:LU, cause 6 DVLR lu_compl_vlr_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){LU_COMPL_VLR_S_WAIT_IMEI}: state_chg to LU_COMPL_VLR_S_DONE DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_FAILURE DVLR lu_compl_vlr_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) @@ -1927,7 +1947,6 @@ DREF msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_RELEASING}: + DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_RELEASING}: RAN encode: CLEAR_COMMAND on GERAN-A DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - msc_a_fsm_releasing_onenter: now used by 2 (active-conn,vlr_gsup_rx) -DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_RELEASING}: transition to state MSC_A_ST_RELEASING not permitted! DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - vlr_gsup_rx: now used by 1 (active-conn) <-- GSUP rx OSMO_GSUP_MSGT_CHECK_IMEI_RESULT: vlr_gsupc_read_cb() returns 0 msc_a_is_accepted() == false @@ -1977,9 +1996,6 @@ DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_RELEASED}: Dea llist_count(&msub_list) == 0 ===== test_gsm_authen_imei_nack: SUCCESS -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 17 - ===== test_gsm_authen_imei_err - Location Update request causes a GSUP Send Auth Info request to HLR MSC <--GERAN-A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST @@ -2008,13 +2024,14 @@ DREF VLR subscr IMSI-901700000004620 + active-conn: now used by 2 (_lu_fsm_assoc DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH DREF VLR subscr IMSI-901700000004620 - _lu_fsm_associate_vsub: now used by 1 (active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Allocated DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU) DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START -GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f00a0101 +GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f02801020a0101 DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - mm_rx_loc_upd_req: now used by 2 (rx_from_ms,lu) DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu) @@ -2072,9 +2089,11 @@ DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: Au DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU) -DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES +DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_SUCCESS DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_ciph() +DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(IMSI-901700000004620:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_node_4() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD DVLR upd_hlr_vlr_fsm(IMSI-901700000004620:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated @@ -2110,6 +2129,7 @@ DVLR lu_compl_vlr_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){LU_COMPL_VLR DVLR lu_compl_vlr_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES DVLR lu_compl_vlr_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL DVLR lu_compl_vlr_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_WAIT_IMEI +DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: Sending DTAP: MM GSM48_MT_MM_ID_REQ DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: DTAP on GERAN-A - DTAP --GERAN-A--> MS: GSM48_MT_MM_ID_REQ: 051802 - DTAP matches expected message @@ -2145,7 +2165,7 @@ DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: DREF msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: + rx_from_ms: now used by 2 (lu,rx_from_ms) DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN decode: DTAP DRLL msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: Dispatching 04.08 message: MM GSM48_MT_MM_ID_RESP -DMM IDENTITY RESPONSE: MI=IMEI-423423423423420 +DMM IDENTITY RESPONSE: IMEI-423423423423420 DVLR set IMEI on subscriber; IMSI=901700000004620 IMEI=42342342342342 DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_ID_IMEI GSUP --> HLR: OSMO_GSUP_MSGT_CHECK_IMEI_REQUEST: 30010809710000004026f0500807244332244332240a0101 @@ -2174,7 +2194,6 @@ DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + vlr_gsup_rx: now used by 2 ( DVLR SUBSCR(IMSI-901700000004620:MSISDN-46071) Check_IMEI_VLR failed; gmm_cause: Invalid mandatory information DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_HLR_IMEI_NACK DVLR lu_compl_vlr_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){LU_COMPL_VLR_S_WAIT_IMEI}: Received Event LU_COMPL_VLR_E_IMEI_CHECK_NACK -- sending LU Reject for IMSI-901700000004620:MSISDN-46071:GERAN-A:LU, cause 6 DVLR lu_compl_vlr_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){LU_COMPL_VLR_S_WAIT_IMEI}: state_chg to LU_COMPL_VLR_S_DONE DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_FAILURE DVLR lu_compl_vlr_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) @@ -2194,7 +2213,6 @@ DREF msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_RELEASING}: + DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_RELEASING}: RAN encode: CLEAR_COMMAND on GERAN-A DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - msc_a_fsm_releasing_onenter: now used by 2 (active-conn,vlr_gsup_rx) -DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_RELEASING}: transition to state MSC_A_ST_RELEASING not permitted! DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - vlr_gsup_rx: now used by 1 (active-conn) <-- GSUP rx OSMO_GSUP_MSGT_CHECK_IMEI_ERROR: vlr_gsupc_read_cb() returns 0 msc_a_is_accepted() == false @@ -2244,9 +2262,6 @@ DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_RELEASED}: Dea llist_count(&msub_list) == 0 ===== test_gsm_authen_imei_err: SUCCESS -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 17 - ===== test_gsm_authen_tmsi_imei - Location Update request causes a GSUP Send Auth Info request to HLR MSC <--GERAN-A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST @@ -2275,13 +2290,14 @@ DREF VLR subscr IMSI-901700000004620 + active-conn: now used by 2 (_lu_fsm_assoc DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH DREF VLR subscr IMSI-901700000004620 - _lu_fsm_associate_vsub: now used by 1 (active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Allocated DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU) DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START -GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f00a0101 +GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f02801020a0101 DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - mm_rx_loc_upd_req: now used by 2 (rx_from_ms,lu) DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu) @@ -2339,9 +2355,11 @@ DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: Au DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU) -DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES +DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_SUCCESS DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_ciph() +DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(IMSI-901700000004620:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_node_4() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD DVLR upd_hlr_vlr_fsm(IMSI-901700000004620:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated @@ -2377,6 +2395,7 @@ DVLR lu_compl_vlr_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){LU_COMPL_VLR DVLR lu_compl_vlr_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES DVLR lu_compl_vlr_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL DVLR lu_compl_vlr_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_WAIT_IMEI_TMSI +DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: Sending DTAP: MM GSM48_MT_MM_ID_REQ DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: DTAP on GERAN-A - DTAP --GERAN-A--> MS: GSM48_MT_MM_ID_REQ: 051802 - DTAP matches expected message @@ -2412,7 +2431,7 @@ DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: DREF msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: + rx_from_ms: now used by 2 (lu,rx_from_ms) DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN decode: DTAP DRLL msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: Dispatching 04.08 message: MM GSM48_MT_MM_ID_RESP -DMM IDENTITY RESPONSE: MI=IMEI-423423423423420 +DMM IDENTITY RESPONSE: IMEI-423423423423420 DVLR set IMEI on subscriber; IMSI=901700000004620 IMEI=42342342342342 DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_ID_IMEI GSUP --> HLR: OSMO_GSUP_MSGT_CHECK_IMEI_REQUEST: 30010809710000004026f0500807244332244332240a0101 @@ -2551,12 +2570,13 @@ DMSC dummy_msc_i{0}: is child of msub_fsm DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms) DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3 DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: MM GSM48_MT_MM_IMSI_DETACH_IND -DMM IMSI DETACH INDICATION: MI(TMSI)=50462976 +DMM IMSI DETACH INDICATION: TMSI-0x03020100 DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100 + gsm48_rx_mm_imsi_detach_ind: now used by 2 (attached,gsm48_rx_mm_imsi_detach_ind) DMM IMSI DETACH for IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100 DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100 + active-conn: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn) DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn,vlr_subscr_cancel_attach_fsm) DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100 - attached: now used by 2 (gsm48_rx_mm_imsi_detach_ind,active-conn) DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100 - gsm48_rx_mm_imsi_detach_ind: now used by 1 (active-conn) DMSC msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_CN_CLOSE @@ -2596,9 +2616,6 @@ DMSC msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:NONE){MSC_A llist_count(&msub_list) == 0 ===== test_gsm_authen_tmsi_imei: SUCCESS -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 17 - ===== test_gsm_milenage_authen - Location Update request causes a GSUP Send Auth Info request to HLR MSC <--GERAN-A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST @@ -2627,13 +2644,14 @@ DREF VLR subscr IMSI-901700000010650 + active-conn: now used by 2 (_lu_fsm_assoc DMSC msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK DMSC msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH DREF VLR subscr IMSI-901700000010650 - _lu_fsm_associate_vsub: now used by 1 (active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre() DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Allocated DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU) DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START -GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f00a0101 +GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f02801020a0101 DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI DREF msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - mm_rx_loc_upd_req: now used by 2 (rx_from_ms,lu) DREF msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu) @@ -2665,9 +2683,11 @@ DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: Au DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU) -DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES +DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_SUCCESS DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth() DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_ciph() +DMSC msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(IMSI-901700000010650:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_node_4() DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD DVLR upd_hlr_vlr_fsm(IMSI-901700000010650:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated @@ -2828,6 +2848,8 @@ DVLR VLR_Authenticate(IMSI-901700000010650:MSISDN-42342:GERAN-A:CM_SERVICE_REQ){ DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: Received Event PR_ARQ_E_AUTH_RES DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2() DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2_post_ciph() +DMSC msc_a(IMSI-901700000010650:MSISDN-42342:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2_post_vlr() DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_pres() DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_trace() @@ -2835,6 +2857,7 @@ DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:GERAN-A:CM_SER DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: proc_arq_fsm_done(PASSED) DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: state_chg to PR_ARQ_S_DONE DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_DONE}: Process Access Request result: PASSED +DBSSAP msc_a(IMSI-901700000010650:MSISDN-42342:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: Sending DTAP: MM GSM48_MT_MM_CM_SERV_ACC DMSC msc_a(IMSI-901700000010650:MSISDN-42342:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN encode: DTAP on GERAN-A - DTAP --GERAN-A--> MS: GSM48_MT_MM_CM_SERV_ACC: 0521 DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST @@ -2922,7 +2945,7 @@ DMSC dummy_msc_i{0}: is child of msub_fsm DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms) DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3 DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: RR GSM48_MT_RR_PAG_RESP -DRR msc_a(IMSI-901700000010650:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: Rx PAGING RESPONSE +DRR msc_a(IMSI-901700000010650:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: Rx PAGING RESPONSE IMSI-901700000010650 DREF msc_a(IMSI-901700000010650:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: + paging-response: now used by 2 (rx_from_ms,paging-response) DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: Allocated DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: is child of msc_a(IMSI-901700000010650:GERAN-A:PAGING_RESP) @@ -2980,6 +3003,8 @@ DVLR VLR_Authenticate(IMSI-901700000010650:MSISDN-42342:GERAN-A:PAGING_RESP){VLR DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:GERAN-A:PAGING_RESP){PR_ARQ_S_WAIT_AUTH}: Received Event PR_ARQ_E_AUTH_RES DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:GERAN-A:PAGING_RESP){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2() DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:GERAN-A:PAGING_RESP){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2_post_ciph() +DMSC msc_a(IMSI-901700000010650:MSISDN-42342:GERAN-A:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:GERAN-A:PAGING_RESP){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2_post_vlr() DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:GERAN-A:PAGING_RESP){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_pres() DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:GERAN-A:PAGING_RESP){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_trace() @@ -2998,6 +3023,7 @@ DLSMS SMC(0) send CP data DLSMS SMC(0) new CP state MM_CONN_PENDING -> WAIT_CP_ACK DLSMS trans(SMS IMSI-901700000010650:MSISDN-42342:GERAN-A:PAGING_RESP callref-0x40000003 tid-0) sending CP message (trans=0) DLSMS trans(SMS IMSI-901700000010650:MSISDN-42342:GERAN-A:PAGING_RESP callref-0x40000003 tid-0) GSM4.11 TX 09 01 58 01 00 07 91 44 77 58 10 06 50 00 4c 00 05 80 24 43 f2 00 00 07 10 10 00 00 00 00 44 50 79 da 1e 1e e7 41 69 37 48 5e 9e a7 c9 65 37 3d 1d 66 83 c2 70 38 3b 3d 0e d3 d3 6f f7 1c 94 9e 83 c2 20 72 79 9e 96 87 c5 ec 32 a8 1d 96 af cb f4 b4 fb 0c 7a c3 e9 e9 b7 db 05 +DBSSAP msc_a(IMSI-901700000010650:MSISDN-42342:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: Sending DTAP: SMS SMS:0x01 DMSC msc_a(IMSI-901700000010650:MSISDN-42342:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: RAN encode: DTAP on GERAN-A - DTAP --GERAN-A--> MS: SMS:0x01: 09015801000791447758100650004c0005802443f2000007101000000000445079da1e1ee7416937485e9ea7c965373d1d6683c270383b3d0ed3d36ff71c949e83c22072799e9687c5ec32a81d96afcbf4b4fb0c7ac3e9e9b7db05 - DTAP matches expected message @@ -3034,6 +3060,7 @@ DLSMS SMC(0) message MMSMS-DATA-IND (CP DATA) received in state MM_ESTABLISHED DLSMS SMC(0) received CP-DATA DLSMS trans(SMS IMSI-901700000010650:MSISDN-42342:GERAN-A:PAGING_RESP callref-0x40000003 tid-0) sending CP message (trans=0) DLSMS trans(SMS IMSI-901700000010650:MSISDN-42342:GERAN-A:PAGING_RESP callref-0x40000003 tid-0) GSM4.11 TX 09 04 +DBSSAP msc_a(IMSI-901700000010650:MSISDN-42342:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: Sending DTAP: SMS SMS:0x04 DMSC msc_a(IMSI-901700000010650:MSISDN-42342:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: RAN encode: DTAP on GERAN-A - DTAP --GERAN-A--> MS: SMS:0x04: 0904 - DTAP matches expected message @@ -3106,12 +3133,13 @@ DMSC dummy_msc_i{0}: is child of msub_fsm DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms) DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3 DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: MM GSM48_MT_MM_IMSI_DETACH_IND -DMM IMSI DETACH INDICATION: MI(IMSI)=901700000010650 +DMM IMSI DETACH INDICATION: IMSI-901700000010650 DREF VLR subscr IMSI-901700000010650:MSISDN-42342 + gsm48_rx_mm_imsi_detach_ind: now used by 2 (attached,gsm48_rx_mm_imsi_detach_ind) DMM IMSI DETACH for IMSI-901700000010650:MSISDN-42342 DREF VLR subscr IMSI-901700000010650:MSISDN-42342 + active-conn: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn) DREF VLR subscr IMSI-901700000010650:MSISDN-42342 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn,vlr_subscr_cancel_attach_fsm) DREF VLR subscr IMSI-901700000010650:MSISDN-42342 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DREF VLR subscr IMSI-901700000010650:MSISDN-42342 - attached: now used by 2 (gsm48_rx_mm_imsi_detach_ind,active-conn) DREF VLR subscr IMSI-901700000010650:MSISDN-42342 - gsm48_rx_mm_imsi_detach_ind: now used by 1 (active-conn) DMSC msc_a(IMSI-901700000010650:MSISDN-42342:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_CN_CLOSE @@ -3151,9 +3179,6 @@ DMSC msc_a(IMSI-901700000010650:MSISDN-42342:GERAN-A:NONE){MSC_A_ST_RELEASED}: D llist_count(&msub_list) == 0 ===== test_gsm_milenage_authen: SUCCESS -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 17 - ===== test_wrong_sres_length - Total time passed: 0.000000 s - Location Update request causes a GSUP Send Auth Info request to HLR @@ -3183,13 +3208,14 @@ DREF VLR subscr IMSI-901700000004620 + active-conn: now used by 2 (_lu_fsm_assoc DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH DREF VLR subscr IMSI-901700000004620 - _lu_fsm_associate_vsub: now used by 1 (active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Allocated DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU) DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START -GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f00a0101 +GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f02801020a0101 DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - mm_rx_loc_upd_req: now used by 2 (rx_from_ms,lu) DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu) @@ -3245,12 +3271,12 @@ DMM msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: MM GSM AUTHENTIC DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP DVLR SUBSCR(IMSI-901700000004620) AUTH on GERAN received SRES/RES: (0 bytes) DVLR SUBSCR(IMSI-901700000004620) AUTH SRES/RES missing -DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result Illegal MS +DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result FAILURE, cause ILLEGAL_MS DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTH_FAILED GSUP --> HLR: OSMO_GSUP_MSGT_AUTH_FAIL_REPORT: 0b010809710000004026f00a0101 DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_AUTH_FAILED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_AUTH_FAILED}: Removing from parent vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU) -DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES +DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_FAILURE - sending LU Reject for IMSI-901700000004620:GERAN-A:LU, cause 3 DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_DONE DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: Received Event MSC_A_EV_CN_CLOSE @@ -3296,9 +3322,3 @@ DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_RELEASED}: Deallocated, inc llist_count(&msub_list) == 0 ===== test_wrong_sres_length: SUCCESS -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 17 - -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 17 - diff --git a/tests/msc_vlr/msc_vlr_test_gsm_ciph.c b/tests/msc_vlr/msc_vlr_test_gsm_ciph.c index ceb17a5fe..38a5caff0 100644 --- a/tests/msc_vlr/msc_vlr_test_gsm_ciph.c +++ b/tests/msc_vlr/msc_vlr_test_gsm_ciph.c @@ -22,7 +22,6 @@ */ #include "msc_vlr_tests.h" -#include "stubs.h" static const struct osmo_gsm48_classmark classmark = { // TODO @@ -41,7 +40,7 @@ static void test_ciph() btw("Location Update request causes a GSUP Send Auth Info request to HLR"); lu_result_sent = RES_NONE; - gsup_expect_tx("08010809710000004026f0" VLR_TO_HLR); + gsup_expect_tx("08010809710000004026f0" CN_DOMAIN VLR_TO_HLR); ms_sends_msg("050802008168000130089910070000006402"); OSMO_ASSERT(gsup_tx_confirmed); VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); @@ -83,7 +82,7 @@ static void test_ciph() VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); btw("MS sends Ciphering Mode Complete, VLR accepts and sends GSUP LU Req to HLR"); - gsup_expect_tx("04010809710000004026f0280102" VLR_TO_HLR); + gsup_expect_tx("04010809710000004026f0" CN_DOMAIN VLR_TO_HLR); ms_sends_ciphering_mode_complete(NULL); VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); @@ -129,7 +128,7 @@ static void test_ciph() VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d"); /* Release connection */ - expect_bssap_clear(OSMO_RAT_GERAN_A); + expect_bssap_clear(); conn_conclude_cm_service_req(g_msub, MSC_A_USE_CM_SERVICE_SMS); btw("all requests serviced, conn has been released"); @@ -250,7 +249,7 @@ static void test_ciph_tmsi() btw("Location Update request causes a GSUP Send Auth Info request to HLR"); lu_result_sent = RES_NONE; - gsup_expect_tx("08010809710000004026f0" VLR_TO_HLR); + gsup_expect_tx("08010809710000004026f0" CN_DOMAIN VLR_TO_HLR); ms_sends_msg("050802008168000130089910070000006402"); OSMO_ASSERT(gsup_tx_confirmed); VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); @@ -293,7 +292,7 @@ static void test_ciph_tmsi() VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); btw("MS sends Ciphering Mode Complete, VLR accepts and sends GSUP LU Req to HLR"); - gsup_expect_tx("04010809710000004026f0280102" VLR_TO_HLR); + gsup_expect_tx("04010809710000004026f0" CN_DOMAIN VLR_TO_HLR); ms_sends_ciphering_mode_complete(NULL); VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); @@ -364,7 +363,7 @@ static void test_ciph_tmsi() VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d"); /* Release connection */ - expect_bssap_clear(OSMO_RAT_GERAN_A); + expect_bssap_clear(); conn_conclude_cm_service_req(g_msub, MSC_A_USE_CM_SERVICE_SMS); btw("all requests serviced, conn has been released"); @@ -485,7 +484,7 @@ static void test_ciph_imei() btw("Location Update request causes a GSUP Send Auth Info request to HLR"); lu_result_sent = RES_NONE; - gsup_expect_tx("08010809710000004026f0" VLR_TO_HLR); + gsup_expect_tx("08010809710000004026f0" CN_DOMAIN VLR_TO_HLR); ms_sends_msg("050802008168000130089910070000006402"); OSMO_ASSERT(gsup_tx_confirmed); VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); @@ -527,7 +526,7 @@ static void test_ciph_imei() VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); btw("MS sends Ciphering Mode Complete, VLR accepts and sends GSUP LU Req to HLR"); - gsup_expect_tx("04010809710000004026f0280102" VLR_TO_HLR); + gsup_expect_tx("04010809710000004026f0" CN_DOMAIN VLR_TO_HLR); ms_sends_ciphering_mode_complete(NULL); VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); @@ -595,7 +594,7 @@ static void test_ciph_imeisv() btw("Location Update request causes a GSUP Send Auth Info request to HLR"); lu_result_sent = RES_NONE; - gsup_expect_tx("08010809710000004026f0" VLR_TO_HLR); + gsup_expect_tx("08010809710000004026f0" CN_DOMAIN VLR_TO_HLR); ms_sends_msg("050802008168000130089910070000006402"); OSMO_ASSERT(gsup_tx_confirmed); VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); @@ -643,8 +642,8 @@ static void test_ciph_imeisv() vlr_subscr_put(vsub, __func__); btw("MS sends Ciphering Mode Complete with IMEISV, VLR accepts and sends GSUP LU Req to HLR"); - gsup_expect_tx("04010809710000004026f0280102" VLR_TO_HLR); - ms_sends_ciphering_mode_complete("063217094b32244332244372f5"); + gsup_expect_tx("04010809710000004026f0" CN_DOMAIN VLR_TO_HLR); + ms_sends_ciphering_mode_complete("063217094332244332244372f5"); VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); btw("Subscriber has the IMEISV"); @@ -696,7 +695,7 @@ static void test_ciph_tmsi_imei() btw("Location Update request causes a GSUP Send Auth Info request to HLR"); lu_result_sent = RES_NONE; - gsup_expect_tx("08010809710000004026f0" VLR_TO_HLR); + gsup_expect_tx("08010809710000004026f0" CN_DOMAIN VLR_TO_HLR); ms_sends_msg("050802008168000130089910070000006402"); OSMO_ASSERT(gsup_tx_confirmed); VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); @@ -738,7 +737,7 @@ static void test_ciph_tmsi_imei() VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); btw("MS sends Ciphering Mode Complete, VLR accepts and sends GSUP LU Req to HLR"); - gsup_expect_tx("04010809710000004026f0280102" VLR_TO_HLR); + gsup_expect_tx("04010809710000004026f0" CN_DOMAIN VLR_TO_HLR); ms_sends_ciphering_mode_complete(NULL); VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); @@ -845,7 +844,7 @@ static void test_gsm_ciph_in_umts_env() btw("Location Update request causes a GSUP Send Auth Info request to HLR"); lu_result_sent = RES_NONE; - gsup_expect_tx("080108" "09710000000156f0" VLR_TO_HLR); + gsup_expect_tx("080108" "09710000000156f0" CN_DOMAIN VLR_TO_HLR); ms_sends_msg("0508" /* MM LU */ "7" /* ciph key seq: no key available */ "0" /* LU type: normal */ @@ -923,7 +922,7 @@ static void test_gsm_ciph_in_umts_env() VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); btw("MS sends Ciphering Mode Complete, VLR accepts and sends GSUP LU Req to HLR"); - gsup_expect_tx("04010809710000000156f0280102" VLR_TO_HLR); + gsup_expect_tx("04010809710000000156f0" CN_DOMAIN VLR_TO_HLR); ms_sends_ciphering_mode_complete(NULL); VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); @@ -968,7 +967,7 @@ static void test_gsm_ciph_in_umts_env() VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d"); /* Release connection */ - expect_bssap_clear(OSMO_RAT_GERAN_A); + expect_bssap_clear(); conn_conclude_cm_service_req(g_msub, MSC_A_USE_CM_SERVICE_SMS); btw("all requests serviced, conn has been released"); @@ -1068,7 +1067,7 @@ static void test_a5_3_supported() btw("Location Update request causes a GSUP Send Auth Info request to HLR"); lu_result_sent = RES_NONE; - gsup_expect_tx("08010809710000004026f0" VLR_TO_HLR); + gsup_expect_tx("08010809710000004026f0" CN_DOMAIN VLR_TO_HLR); ms_sends_msg("050802008168000130089910070000006402"); OSMO_ASSERT(gsup_tx_confirmed); VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); @@ -1112,7 +1111,7 @@ static void test_a5_3_supported() VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); btw("MS sends Ciphering Mode Complete, VLR accepts and sends GSUP LU Req to HLR"); - gsup_expect_tx("04010809710000004026f0280102" VLR_TO_HLR); + gsup_expect_tx("04010809710000004026f0" CN_DOMAIN VLR_TO_HLR); ms_sends_ciphering_mode_complete(NULL); VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); @@ -1159,7 +1158,7 @@ static void test_a5_3_supported() VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d"); /* Release connection */ - expect_bssap_clear(OSMO_RAT_GERAN_A); + expect_bssap_clear(); conn_conclude_cm_service_req(g_msub, MSC_A_USE_CM_SERVICE_SMS); btw("all requests serviced, conn has been released"); @@ -1268,7 +1267,7 @@ static void test_a5_3_supported() } /* During CM Service Request or Paging Response we already have Classmark 2 that indicates A5/3 - * availablity. Here, in a hacky way remove the knowledge of Classmark 2 to tickle a code path where + * availability. Here, in a hacky way remove the knowledge of Classmark 2 to tickle a code path where * proc_arq_fsm needs a Classmark Update during Ciphering. Shouldn't happen in reality though. */ static void test_cm_service_needs_classmark_update() { @@ -1284,7 +1283,7 @@ static void test_cm_service_needs_classmark_update() btw("Location Update request causes a GSUP Send Auth Info request to HLR"); lu_result_sent = RES_NONE; - gsup_expect_tx("08010809710000004026f0" VLR_TO_HLR); + gsup_expect_tx("08010809710000004026f0" CN_DOMAIN VLR_TO_HLR); ms_sends_msg("050802008168000130089910070000006402"); OSMO_ASSERT(gsup_tx_confirmed); VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); @@ -1328,7 +1327,7 @@ static void test_cm_service_needs_classmark_update() VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); btw("MS sends Ciphering Mode Complete, VLR accepts and sends GSUP LU Req to HLR"); - gsup_expect_tx("04010809710000004026f0280102" VLR_TO_HLR); + gsup_expect_tx("04010809710000004026f0" CN_DOMAIN VLR_TO_HLR); ms_sends_ciphering_mode_complete(NULL); VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); @@ -1376,7 +1375,7 @@ static void test_cm_service_needs_classmark_update() VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d"); /* Release connection */ - expect_bssap_clear(OSMO_RAT_GERAN_A); + expect_bssap_clear(); conn_conclude_cm_service_req(g_msub, MSC_A_USE_CM_SERVICE_SMS); btw("all requests serviced, conn has been released"); diff --git a/tests/msc_vlr/msc_vlr_test_gsm_ciph.err b/tests/msc_vlr/msc_vlr_test_gsm_ciph.err index b527f05af..afea400c8 100644 --- a/tests/msc_vlr/msc_vlr_test_gsm_ciph.err +++ b/tests/msc_vlr/msc_vlr_test_gsm_ciph.err @@ -1,7 +1,3 @@ -DLMGCP MGCP client: using endpoint domain '@mgw' -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 17 - ===== test_ciph - Location Update request causes a GSUP Send Auth Info request to HLR MSC <--GERAN-A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST @@ -30,13 +26,14 @@ DREF VLR subscr IMSI-901700000004620 + active-conn: now used by 2 (_lu_fsm_assoc DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH DREF VLR subscr IMSI-901700000004620 - _lu_fsm_associate_vsub: now used by 1 (active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Allocated DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU) DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START -GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f00a0101 +GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f02801020a0101 DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - mm_rx_loc_upd_req: now used by 2 (rx_from_ms,lu) DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu) @@ -68,7 +65,7 @@ DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: Au DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU) -DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES +DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_SUCCESS DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Set Ciphering Mode DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: CIPHER_MODE_COMMAND on GERAN-A @@ -105,6 +102,8 @@ DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: + ms_sends_ciph DBSSAP msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN decode: CIPHER_MODE_COMPLETE DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_CIPH}: Received Event VLR_ULA_E_CIPH_RES DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_CIPH}: vlr_loc_upd_post_ciph() +DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(IMSI-901700000004620:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_CIPH}: vlr_loc_upd_node_4() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_CIPH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD DVLR upd_hlr_vlr_fsm(IMSI-901700000004620:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated @@ -298,6 +297,8 @@ DREF msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AU DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN decode: CIPHER_MODE_COMPLETE DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_CIPH}: Received Event PR_ARQ_E_CIPH_RES DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_node2_post_ciph() +DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_node2_post_vlr() DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_pres() DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_trace() @@ -388,7 +389,7 @@ DMSC dummy_msc_i{0}: is child of msub_fsm DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms) DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3 DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: RR GSM48_MT_RR_PAG_RESP -DRR msc_a(IMSI-901700000004620:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: Rx PAGING RESPONSE +DRR msc_a(IMSI-901700000004620:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: Rx PAGING RESPONSE IMSI-901700000004620 DREF msc_a(IMSI-901700000004620:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: + paging-response: now used by 2 (rx_from_ms,paging-response) DVLR Process_Access_Request_VLR(IMSI-901700000004620:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: Allocated DVLR Process_Access_Request_VLR(IMSI-901700000004620:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: is child of msc_a(IMSI-901700000004620:GERAN-A:PAGING_RESP) @@ -479,6 +480,8 @@ DREF msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTH_ DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: RAN decode: CIPHER_MODE_COMPLETE DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_WAIT_CIPH}: Received Event PR_ARQ_E_CIPH_RES DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_node2_post_ciph() +DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_node2_post_vlr() DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_pres() DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_trace() @@ -497,6 +500,7 @@ DLSMS SMC(0) send CP data DLSMS SMC(0) new CP state MM_CONN_PENDING -> WAIT_CP_ACK DLSMS trans(SMS IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x40000001 tid-0) sending CP message (trans=0) DLSMS trans(SMS IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x40000001 tid-0) GSM4.11 TX 09 01 58 01 00 07 91 44 77 58 10 06 50 00 4c 00 05 80 64 70 f1 00 00 07 10 10 00 00 00 00 44 50 79 da 1e 1e e7 41 69 37 48 5e 9e a7 c9 65 37 3d 1d 66 83 c2 70 38 3b 3d 0e d3 d3 6f f7 1c 94 9e 83 c2 20 72 79 9e 96 87 c5 ec 32 a8 1d 96 af cb f4 b4 fb 0c 7a c3 e9 e9 b7 db 05 +DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: Sending DTAP: SMS SMS:0x01 DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: RAN encode: DTAP on GERAN-A - DTAP --GERAN-A--> MS: SMS:0x01: 09015801000791447758100650004c0005806470f1000007101000000000445079da1e1ee7416937485e9ea7c965373d1d6683c270383b3d0ed3d36ff71c949e83c22072799e9687c5ec32a81d96afcbf4b4fb0c7ac3e9e9b7db05 - DTAP matches expected message @@ -532,6 +536,7 @@ DLSMS SMC(0) message MMSMS-DATA-IND (CP DATA) received in state MM_ESTABLISHED DLSMS SMC(0) received CP-DATA DLSMS trans(SMS IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x40000001 tid-0) sending CP message (trans=0) DLSMS trans(SMS IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x40000001 tid-0) GSM4.11 TX 09 04 +DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: Sending DTAP: SMS SMS:0x04 DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: RAN encode: DTAP on GERAN-A - DTAP --GERAN-A--> MS: SMS:0x04: 0904 - DTAP matches expected message @@ -604,12 +609,13 @@ DMSC dummy_msc_i{0}: is child of msub_fsm DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms) DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3 DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: MM GSM48_MT_MM_IMSI_DETACH_IND -DMM IMSI DETACH INDICATION: MI(IMSI)=901700000004620 +DMM IMSI DETACH INDICATION: IMSI-901700000004620 DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + gsm48_rx_mm_imsi_detach_ind: now used by 2 (attached,gsm48_rx_mm_imsi_detach_ind) DMM IMSI DETACH for IMSI-901700000004620:MSISDN-46071 DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + active-conn: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn) DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn,vlr_subscr_cancel_attach_fsm) DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - attached: now used by 2 (gsm48_rx_mm_imsi_detach_ind,active-conn) DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - gsm48_rx_mm_imsi_detach_ind: now used by 1 (active-conn) DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_CN_CLOSE @@ -649,9 +655,6 @@ DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:NONE){MSC_A_ST_RELEASED}: D llist_count(&msub_list) == 0 ===== test_ciph: SUCCESS -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 17 - ===== test_ciph_tmsi - Location Update request causes a GSUP Send Auth Info request to HLR MSC <--GERAN-A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST @@ -680,13 +683,14 @@ DREF VLR subscr IMSI-901700000004620 + active-conn: now used by 2 (_lu_fsm_assoc DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH DREF VLR subscr IMSI-901700000004620 - _lu_fsm_associate_vsub: now used by 1 (active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Allocated DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU) DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START -GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f00a0101 +GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f02801020a0101 DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - mm_rx_loc_upd_req: now used by 2 (rx_from_ms,lu) DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu) @@ -718,7 +722,7 @@ DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: Au DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU) -DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES +DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_SUCCESS DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Set Ciphering Mode DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: CIPHER_MODE_COMMAND on GERAN-A @@ -756,6 +760,8 @@ DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: + ms_sends_ciph DBSSAP msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN decode: CIPHER_MODE_COMPLETE DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_CIPH}: Received Event VLR_ULA_E_CIPH_RES DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_CIPH}: vlr_loc_upd_post_ciph() +DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(IMSI-901700000004620:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_CIPH}: vlr_loc_upd_node_4() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_CIPH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD DVLR upd_hlr_vlr_fsm(IMSI-901700000004620:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated @@ -996,6 +1002,8 @@ DREF msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:CM_SERVICE_ DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN decode: CIPHER_MODE_COMPLETE DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_CIPH}: Received Event PR_ARQ_E_CIPH_RES DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_node2_post_ciph() +DMSC msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_node2_post_vlr() DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_pres() DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_trace() @@ -1086,7 +1094,7 @@ DMSC dummy_msc_i{0}: is child of msub_fsm DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms) DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3 DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: RR GSM48_MT_RR_PAG_RESP -DRR msc_a(TMSI-0x03020100:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: Rx PAGING RESPONSE +DRR msc_a(TMSI-0x03020100:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: Rx PAGING RESPONSE TMSI-0x03020100 DREF msc_a(TMSI-0x03020100:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: + paging-response: now used by 2 (rx_from_ms,paging-response) DVLR Process_Access_Request_VLR(TMSI-0x03020100:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: Allocated DVLR Process_Access_Request_VLR(TMSI-0x03020100:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: is child of msc_a(TMSI-0x03020100:GERAN-A:PAGING_RESP) @@ -1177,6 +1185,8 @@ DREF msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:PAGING_RESP DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: RAN decode: CIPHER_MODE_COMPLETE DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:PAGING_RESP){PR_ARQ_S_WAIT_CIPH}: Received Event PR_ARQ_E_CIPH_RES DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:PAGING_RESP){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_node2_post_ciph() +DMSC msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:PAGING_RESP){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_node2_post_vlr() DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:PAGING_RESP){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_pres() DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:PAGING_RESP){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_trace() @@ -1195,6 +1205,7 @@ DLSMS SMC(0) send CP data DLSMS SMC(0) new CP state MM_CONN_PENDING -> WAIT_CP_ACK DLSMS trans(SMS IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:PAGING_RESP callref-0x40000002 tid-0) sending CP message (trans=0) DLSMS trans(SMS IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:PAGING_RESP callref-0x40000002 tid-0) GSM4.11 TX 09 01 58 01 00 07 91 44 77 58 10 06 50 00 4c 00 05 80 64 70 f1 00 00 07 10 10 00 00 00 00 44 50 79 da 1e 1e e7 41 69 37 48 5e 9e a7 c9 65 37 3d 1d 66 83 c2 70 38 3b 3d 0e d3 d3 6f f7 1c 94 9e 83 c2 20 72 79 9e 96 87 c5 ec 32 a8 1d 96 af cb f4 b4 fb 0c 7a c3 e9 e9 b7 db 05 +DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: Sending DTAP: SMS SMS:0x01 DMSC msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: RAN encode: DTAP on GERAN-A - DTAP --GERAN-A--> MS: SMS:0x01: 09015801000791447758100650004c0005806470f1000007101000000000445079da1e1ee7416937485e9ea7c965373d1d6683c270383b3d0ed3d36ff71c949e83c22072799e9687c5ec32a81d96afcbf4b4fb0c7ac3e9e9b7db05 - DTAP matches expected message @@ -1230,6 +1241,7 @@ DLSMS SMC(0) message MMSMS-DATA-IND (CP DATA) received in state MM_ESTABLISHED DLSMS SMC(0) received CP-DATA DLSMS trans(SMS IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:PAGING_RESP callref-0x40000002 tid-0) sending CP message (trans=0) DLSMS trans(SMS IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:PAGING_RESP callref-0x40000002 tid-0) GSM4.11 TX 09 04 +DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: Sending DTAP: SMS SMS:0x04 DMSC msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: RAN encode: DTAP on GERAN-A - DTAP --GERAN-A--> MS: SMS:0x04: 0904 - DTAP matches expected message @@ -1302,12 +1314,13 @@ DMSC dummy_msc_i{0}: is child of msub_fsm DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms) DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3 DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: MM GSM48_MT_MM_IMSI_DETACH_IND -DMM IMSI DETACH INDICATION: MI(TMSI)=50462976 +DMM IMSI DETACH INDICATION: TMSI-0x03020100 DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100 + gsm48_rx_mm_imsi_detach_ind: now used by 2 (attached,gsm48_rx_mm_imsi_detach_ind) DMM IMSI DETACH for IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100 DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100 + active-conn: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn) DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn,vlr_subscr_cancel_attach_fsm) DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100 - attached: now used by 2 (gsm48_rx_mm_imsi_detach_ind,active-conn) DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100 - gsm48_rx_mm_imsi_detach_ind: now used by 1 (active-conn) DMSC msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_CN_CLOSE @@ -1347,9 +1360,6 @@ DMSC msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:NONE){MSC_A llist_count(&msub_list) == 0 ===== test_ciph_tmsi: SUCCESS -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 17 - ===== test_ciph_imei - Location Update request causes a GSUP Send Auth Info request to HLR MSC <--GERAN-A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST @@ -1378,13 +1388,14 @@ DREF VLR subscr IMSI-901700000004620 + active-conn: now used by 2 (_lu_fsm_assoc DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH DREF VLR subscr IMSI-901700000004620 - _lu_fsm_associate_vsub: now used by 1 (active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Allocated DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU) DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START -GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f00a0101 +GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f02801020a0101 DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - mm_rx_loc_upd_req: now used by 2 (rx_from_ms,lu) DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu) @@ -1416,7 +1427,7 @@ DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: Au DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU) -DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES +DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_SUCCESS DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Set Ciphering Mode DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: CIPHER_MODE_COMMAND on GERAN-A @@ -1453,6 +1464,8 @@ DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: + ms_sends_ciph DBSSAP msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN decode: CIPHER_MODE_COMPLETE DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_CIPH}: Received Event VLR_ULA_E_CIPH_RES DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_CIPH}: vlr_loc_upd_post_ciph() +DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(IMSI-901700000004620:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_CIPH}: vlr_loc_upd_node_4() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_CIPH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD DVLR upd_hlr_vlr_fsm(IMSI-901700000004620:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated @@ -1487,6 +1500,7 @@ DVLR lu_compl_vlr_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){LU_COMPL_VLR DVLR lu_compl_vlr_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES DVLR lu_compl_vlr_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL DVLR lu_compl_vlr_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_WAIT_IMEI +DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: Sending DTAP: MM GSM48_MT_MM_ID_REQ DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: DTAP on GERAN-A - DTAP --GERAN-A--> MS: GSM48_MT_MM_ID_REQ: 051802 - DTAP matches expected message @@ -1522,7 +1536,7 @@ DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: DREF msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: + rx_from_ms: now used by 2 (lu,rx_from_ms) DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN decode: DTAP DRLL msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: Dispatching 04.08 message: MM GSM48_MT_MM_ID_RESP -DMM IDENTITY RESPONSE: MI=IMEI-423423423423420 +DMM IDENTITY RESPONSE: IMEI-423423423423420 DVLR set IMEI on subscriber; IMSI=901700000004620 IMEI=42342342342342 DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_ID_IMEI GSUP --> HLR: OSMO_GSUP_MSGT_CHECK_IMEI_REQUEST: 30010809710000004026f0500807244332244332240a0101 @@ -1620,12 +1634,13 @@ DMSC dummy_msc_i{0}: is child of msub_fsm DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms) DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3 DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: MM GSM48_MT_MM_IMSI_DETACH_IND -DMM IMSI DETACH INDICATION: MI(IMSI)=901700000004620 +DMM IMSI DETACH INDICATION: IMSI-901700000004620 DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + gsm48_rx_mm_imsi_detach_ind: now used by 2 (attached,gsm48_rx_mm_imsi_detach_ind) DMM IMSI DETACH for IMSI-901700000004620:MSISDN-46071 DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + active-conn: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn) DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn,vlr_subscr_cancel_attach_fsm) DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - attached: now used by 2 (gsm48_rx_mm_imsi_detach_ind,active-conn) DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - gsm48_rx_mm_imsi_detach_ind: now used by 1 (active-conn) DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_CN_CLOSE @@ -1665,9 +1680,6 @@ DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:NONE){MSC_A_ST_RELEASED}: D llist_count(&msub_list) == 0 ===== test_ciph_imei: SUCCESS -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 17 - ===== test_ciph_imeisv - Location Update request causes a GSUP Send Auth Info request to HLR MSC <--GERAN-A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST @@ -1696,13 +1708,14 @@ DREF VLR subscr IMSI-901700000004620 + active-conn: now used by 2 (_lu_fsm_assoc DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH DREF VLR subscr IMSI-901700000004620 - _lu_fsm_associate_vsub: now used by 1 (active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Allocated DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU) DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START -GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f00a0101 +GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f02801020a0101 DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - mm_rx_loc_upd_req: now used by 2 (rx_from_ms,lu) DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu) @@ -1734,7 +1747,7 @@ DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: Au DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU) -DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES +DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_SUCCESS DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Set Ciphering Mode DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: CIPHER_MODE_COMMAND on GERAN-A @@ -1776,6 +1789,8 @@ DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: + ms_sends_ciph DBSSAP msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN decode: CIPHER_MODE_COMPLETE DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_CIPH}: Received Event VLR_ULA_E_CIPH_RES DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_CIPH}: vlr_loc_upd_post_ciph() +DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(IMSI-901700000004620:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_CIPH}: vlr_loc_upd_node_4() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_CIPH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD DVLR upd_hlr_vlr_fsm(IMSI-901700000004620:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated @@ -1785,11 +1800,10 @@ GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000004026f02801 DVLR upd_hlr_vlr_fsm(IMSI-901700000004620:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA DBSSAP msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN decode: DTAP DRLL msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: Dispatching 04.08 message: RR GSM48_MT_RR_CIPH_M_COMPL -DBSSAP msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: Ciphering Mode Complete contains Mobile Identity: IMEI-SV-4234234234234275F +DBSSAP msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RR Ciphering Mode Complete contains Mobile Identity: IMEI-SV-4234234234234275 DVLR set IMEISV on subscriber; IMSI=901700000004620 IMEISV=4234234234234275 DVLR set IMEI on subscriber; IMSI=901700000004620 IMEI=42342342342342 DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_ID_IMEISV -DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_HLR_UPD}: Event VLR_ULA_E_ID_IMEISV not permitted DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - ms_sends_ciphering_mode_complete: now used by 1 (lu) lu_result_sent == 0 - Subscriber has the IMEISV @@ -1905,12 +1919,13 @@ DMSC dummy_msc_i{0}: is child of msub_fsm DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms) DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3 DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: MM GSM48_MT_MM_IMSI_DETACH_IND -DMM IMSI DETACH INDICATION: MI(IMSI)=901700000004620 +DMM IMSI DETACH INDICATION: IMSI-901700000004620 DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + gsm48_rx_mm_imsi_detach_ind: now used by 2 (attached,gsm48_rx_mm_imsi_detach_ind) DMM IMSI DETACH for IMSI-901700000004620:MSISDN-46071 DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + active-conn: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn) DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn,vlr_subscr_cancel_attach_fsm) DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - attached: now used by 2 (gsm48_rx_mm_imsi_detach_ind,active-conn) DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - gsm48_rx_mm_imsi_detach_ind: now used by 1 (active-conn) DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_CN_CLOSE @@ -1950,9 +1965,6 @@ DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:NONE){MSC_A_ST_RELEASED}: D llist_count(&msub_list) == 0 ===== test_ciph_imeisv: SUCCESS -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 17 - ===== test_ciph_tmsi_imei - Location Update request causes a GSUP Send Auth Info request to HLR MSC <--GERAN-A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST @@ -1981,13 +1993,14 @@ DREF VLR subscr IMSI-901700000004620 + active-conn: now used by 2 (_lu_fsm_assoc DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH DREF VLR subscr IMSI-901700000004620 - _lu_fsm_associate_vsub: now used by 1 (active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Allocated DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU) DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START -GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f00a0101 +GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f02801020a0101 DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - mm_rx_loc_upd_req: now used by 2 (rx_from_ms,lu) DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu) @@ -2019,7 +2032,7 @@ DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: Au DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU) -DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES +DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_SUCCESS DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Set Ciphering Mode DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: CIPHER_MODE_COMMAND on GERAN-A @@ -2056,6 +2069,8 @@ DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: + ms_sends_ciph DBSSAP msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN decode: CIPHER_MODE_COMPLETE DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_CIPH}: Received Event VLR_ULA_E_CIPH_RES DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_CIPH}: vlr_loc_upd_post_ciph() +DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(IMSI-901700000004620:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_CIPH}: vlr_loc_upd_node_4() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_CIPH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD DVLR upd_hlr_vlr_fsm(IMSI-901700000004620:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated @@ -2090,6 +2105,7 @@ DVLR lu_compl_vlr_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){LU_COMPL_VLR DVLR lu_compl_vlr_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES DVLR lu_compl_vlr_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL DVLR lu_compl_vlr_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_WAIT_IMEI_TMSI +DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: Sending DTAP: MM GSM48_MT_MM_ID_REQ DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: DTAP on GERAN-A - DTAP --GERAN-A--> MS: GSM48_MT_MM_ID_REQ: 051802 - DTAP matches expected message @@ -2125,7 +2141,7 @@ DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: DREF msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: + rx_from_ms: now used by 2 (lu,rx_from_ms) DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN decode: DTAP DRLL msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: Dispatching 04.08 message: MM GSM48_MT_MM_ID_RESP -DMM IDENTITY RESPONSE: MI=IMEI-423423423423420 +DMM IDENTITY RESPONSE: IMEI-423423423423420 DVLR set IMEI on subscriber; IMSI=901700000004620 IMEI=42342342342342 DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_ID_IMEI GSUP --> HLR: OSMO_GSUP_MSGT_CHECK_IMEI_REQUEST: 30010809710000004026f0500807244332244332240a0101 @@ -2264,12 +2280,13 @@ DMSC dummy_msc_i{0}: is child of msub_fsm DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms) DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3 DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: MM GSM48_MT_MM_IMSI_DETACH_IND -DMM IMSI DETACH INDICATION: MI(TMSI)=50462976 +DMM IMSI DETACH INDICATION: TMSI-0x03020100 DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100 + gsm48_rx_mm_imsi_detach_ind: now used by 2 (attached,gsm48_rx_mm_imsi_detach_ind) DMM IMSI DETACH for IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100 DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100 + active-conn: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn) DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn,vlr_subscr_cancel_attach_fsm) DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100 - attached: now used by 2 (gsm48_rx_mm_imsi_detach_ind,active-conn) DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100 - gsm48_rx_mm_imsi_detach_ind: now used by 1 (active-conn) DMSC msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_CN_CLOSE @@ -2309,9 +2326,6 @@ DMSC msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:NONE){MSC_A llist_count(&msub_list) == 0 ===== test_ciph_tmsi_imei: SUCCESS -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 17 - ===== test_gsm_ciph_in_umts_env - Location Update request causes a GSUP Send Auth Info request to HLR MSC <--GERAN-A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST @@ -2340,13 +2354,14 @@ DREF VLR subscr IMSI-901700000010650 + active-conn: now used by 2 (_lu_fsm_assoc DMSC msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK DMSC msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH DREF VLR subscr IMSI-901700000010650 - _lu_fsm_associate_vsub: now used by 1 (active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre() DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Allocated DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU) DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START -GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f00a0101 +GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f02801020a0101 DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI DREF msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - mm_rx_loc_upd_req: now used by 2 (rx_from_ms,lu) DREF msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu) @@ -2379,7 +2394,7 @@ DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: Au DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU) -DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES +DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_SUCCESS DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth() DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Set Ciphering Mode DMSC msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: CIPHER_MODE_COMMAND on GERAN-A @@ -2396,6 +2411,8 @@ DREF msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: + ms_sends_ciph DBSSAP msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN decode: CIPHER_MODE_COMPLETE DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_WAIT_CIPH}: Received Event VLR_ULA_E_CIPH_RES DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_WAIT_CIPH}: vlr_loc_upd_post_ciph() +DMSC msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(IMSI-901700000010650:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_WAIT_CIPH}: vlr_loc_upd_node_4() DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_WAIT_CIPH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD DVLR upd_hlr_vlr_fsm(IMSI-901700000010650:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated @@ -2571,6 +2588,8 @@ DREF msc_a(IMSI-901700000010650:MSISDN-42342:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AU DBSSAP msc_a(IMSI-901700000010650:MSISDN-42342:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN decode: CIPHER_MODE_COMPLETE DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_CIPH}: Received Event PR_ARQ_E_CIPH_RES DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_node2_post_ciph() +DMSC msc_a(IMSI-901700000010650:MSISDN-42342:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_node2_post_vlr() DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_pres() DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_trace() @@ -2661,7 +2680,7 @@ DMSC dummy_msc_i{0}: is child of msub_fsm DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms) DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3 DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: RR GSM48_MT_RR_PAG_RESP -DRR msc_a(IMSI-901700000010650:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: Rx PAGING RESPONSE +DRR msc_a(IMSI-901700000010650:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: Rx PAGING RESPONSE IMSI-901700000010650 DREF msc_a(IMSI-901700000010650:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: + paging-response: now used by 2 (rx_from_ms,paging-response) DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: Allocated DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: is child of msc_a(IMSI-901700000010650:GERAN-A:PAGING_RESP) @@ -2734,6 +2753,8 @@ DREF msc_a(IMSI-901700000010650:MSISDN-42342:GERAN-A:PAGING_RESP){MSC_A_ST_AUTH_ DBSSAP msc_a(IMSI-901700000010650:MSISDN-42342:GERAN-A:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: RAN decode: CIPHER_MODE_COMPLETE DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:GERAN-A:PAGING_RESP){PR_ARQ_S_WAIT_CIPH}: Received Event PR_ARQ_E_CIPH_RES DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:GERAN-A:PAGING_RESP){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_node2_post_ciph() +DMSC msc_a(IMSI-901700000010650:MSISDN-42342:GERAN-A:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:GERAN-A:PAGING_RESP){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_node2_post_vlr() DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:GERAN-A:PAGING_RESP){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_pres() DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:GERAN-A:PAGING_RESP){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_trace() @@ -2752,6 +2773,7 @@ DLSMS SMC(0) send CP data DLSMS SMC(0) new CP state MM_CONN_PENDING -> WAIT_CP_ACK DLSMS trans(SMS IMSI-901700000010650:MSISDN-42342:GERAN-A:PAGING_RESP callref-0x40000003 tid-0) sending CP message (trans=0) DLSMS trans(SMS IMSI-901700000010650:MSISDN-42342:GERAN-A:PAGING_RESP callref-0x40000003 tid-0) GSM4.11 TX 09 01 58 01 00 07 91 44 77 58 10 06 50 00 4c 00 05 80 24 43 f2 00 00 07 10 10 00 00 00 00 44 50 79 da 1e 1e e7 41 69 37 48 5e 9e a7 c9 65 37 3d 1d 66 83 c2 70 38 3b 3d 0e d3 d3 6f f7 1c 94 9e 83 c2 20 72 79 9e 96 87 c5 ec 32 a8 1d 96 af cb f4 b4 fb 0c 7a c3 e9 e9 b7 db 05 +DBSSAP msc_a(IMSI-901700000010650:MSISDN-42342:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: Sending DTAP: SMS SMS:0x01 DMSC msc_a(IMSI-901700000010650:MSISDN-42342:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: RAN encode: DTAP on GERAN-A - DTAP --GERAN-A--> MS: SMS:0x01: 09015801000791447758100650004c0005802443f2000007101000000000445079da1e1ee7416937485e9ea7c965373d1d6683c270383b3d0ed3d36ff71c949e83c22072799e9687c5ec32a81d96afcbf4b4fb0c7ac3e9e9b7db05 - DTAP matches expected message @@ -2787,6 +2809,7 @@ DLSMS SMC(0) message MMSMS-DATA-IND (CP DATA) received in state MM_ESTABLISHED DLSMS SMC(0) received CP-DATA DLSMS trans(SMS IMSI-901700000010650:MSISDN-42342:GERAN-A:PAGING_RESP callref-0x40000003 tid-0) sending CP message (trans=0) DLSMS trans(SMS IMSI-901700000010650:MSISDN-42342:GERAN-A:PAGING_RESP callref-0x40000003 tid-0) GSM4.11 TX 09 04 +DBSSAP msc_a(IMSI-901700000010650:MSISDN-42342:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: Sending DTAP: SMS SMS:0x04 DMSC msc_a(IMSI-901700000010650:MSISDN-42342:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: RAN encode: DTAP on GERAN-A - DTAP --GERAN-A--> MS: SMS:0x04: 0904 - DTAP matches expected message @@ -2859,12 +2882,13 @@ DMSC dummy_msc_i{0}: is child of msub_fsm DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms) DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3 DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: MM GSM48_MT_MM_IMSI_DETACH_IND -DMM IMSI DETACH INDICATION: MI(IMSI)=901700000010650 +DMM IMSI DETACH INDICATION: IMSI-901700000010650 DREF VLR subscr IMSI-901700000010650:MSISDN-42342 + gsm48_rx_mm_imsi_detach_ind: now used by 2 (attached,gsm48_rx_mm_imsi_detach_ind) DMM IMSI DETACH for IMSI-901700000010650:MSISDN-42342 DREF VLR subscr IMSI-901700000010650:MSISDN-42342 + active-conn: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn) DREF VLR subscr IMSI-901700000010650:MSISDN-42342 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn,vlr_subscr_cancel_attach_fsm) DREF VLR subscr IMSI-901700000010650:MSISDN-42342 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DREF VLR subscr IMSI-901700000010650:MSISDN-42342 - attached: now used by 2 (gsm48_rx_mm_imsi_detach_ind,active-conn) DREF VLR subscr IMSI-901700000010650:MSISDN-42342 - gsm48_rx_mm_imsi_detach_ind: now used by 1 (active-conn) DMSC msc_a(IMSI-901700000010650:MSISDN-42342:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_CN_CLOSE @@ -2904,9 +2928,6 @@ DMSC msc_a(IMSI-901700000010650:MSISDN-42342:GERAN-A:NONE){MSC_A_ST_RELEASED}: D llist_count(&msub_list) == 0 ===== test_gsm_ciph_in_umts_env: SUCCESS -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 17 - ===== test_a5_3_supported - Location Update request causes a GSUP Send Auth Info request to HLR MSC <--GERAN-A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST @@ -2935,13 +2956,14 @@ DREF VLR subscr IMSI-901700000004620 + active-conn: now used by 2 (_lu_fsm_assoc DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH DREF VLR subscr IMSI-901700000004620 - _lu_fsm_associate_vsub: now used by 1 (active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Allocated DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU) DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START -GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f00a0101 +GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f02801020a0101 DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - mm_rx_loc_upd_req: now used by 2 (rx_from_ms,lu) DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu) @@ -2975,7 +2997,7 @@ DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: Au DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU) -DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES +DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_SUCCESS DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Set Ciphering Mode DBSSAP msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: For A5/3, we still need Classmark 2 @@ -2988,7 +3010,7 @@ DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_WAIT_CLASSMARK_UPDATE}: - r lu_result_sent == 0 - BSC sends back a BSSMAP Classmark Update, that triggers the Ciphering Mode Command in A5/3 DBSSAP msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_WAIT_CLASSMARK_UPDATE}: RAN decode: CLASSMARK_UPDATE -DBSSAP msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_WAIT_CLASSMARK_UPDATE}: A5 capabilities recived from Classmark Update: no-cm1 no-cm2 no-cm3 +DBSSAP msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_WAIT_CLASSMARK_UPDATE}: A5 capabilities received from Classmark Update: no-cm1 no-cm2 no-cm3 DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_WAIT_CLASSMARK_UPDATE}: Received Event MSC_A_EV_CLASSMARK_UPDATE DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_WAIT_CLASSMARK_UPDATE}: state_chg to MSC_A_ST_AUTH_CIPH DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: CIPHER_MODE_COMMAND on GERAN-A @@ -3002,6 +3024,8 @@ DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: + ms_sends_ciph DBSSAP msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN decode: CIPHER_MODE_COMPLETE DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_CIPH}: Received Event VLR_ULA_E_CIPH_RES DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_CIPH}: vlr_loc_upd_post_ciph() +DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(IMSI-901700000004620:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_CIPH}: vlr_loc_upd_node_4() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_CIPH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD DVLR upd_hlr_vlr_fsm(IMSI-901700000004620:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated @@ -3195,6 +3219,8 @@ DREF msc_a(IMSI-901700000004620:MSISDN-42342:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AU DBSSAP msc_a(IMSI-901700000004620:MSISDN-42342:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN decode: CIPHER_MODE_COMPLETE DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-42342:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_CIPH}: Received Event PR_ARQ_E_CIPH_RES DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-42342:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_node2_post_ciph() +DMSC msc_a(IMSI-901700000004620:MSISDN-42342:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-42342:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-42342:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_node2_post_vlr() DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-42342:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_pres() DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-42342:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_trace() @@ -3285,7 +3311,7 @@ DMSC dummy_msc_i{0}: is child of msub_fsm DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms) DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3 DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: RR GSM48_MT_RR_PAG_RESP -DRR msc_a(IMSI-901700000004620:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: Rx PAGING RESPONSE +DRR msc_a(IMSI-901700000004620:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: Rx PAGING RESPONSE IMSI-901700000004620 DREF msc_a(IMSI-901700000004620:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: + paging-response: now used by 2 (rx_from_ms,paging-response) DVLR Process_Access_Request_VLR(IMSI-901700000004620:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: Allocated DVLR Process_Access_Request_VLR(IMSI-901700000004620:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: is child of msc_a(IMSI-901700000004620:GERAN-A:PAGING_RESP) @@ -3376,6 +3402,8 @@ DREF msc_a(IMSI-901700000004620:MSISDN-42342:GERAN-A:PAGING_RESP){MSC_A_ST_AUTH_ DBSSAP msc_a(IMSI-901700000004620:MSISDN-42342:GERAN-A:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: RAN decode: CIPHER_MODE_COMPLETE DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-42342:GERAN-A:PAGING_RESP){PR_ARQ_S_WAIT_CIPH}: Received Event PR_ARQ_E_CIPH_RES DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-42342:GERAN-A:PAGING_RESP){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_node2_post_ciph() +DMSC msc_a(IMSI-901700000004620:MSISDN-42342:GERAN-A:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-42342:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-42342:GERAN-A:PAGING_RESP){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_node2_post_vlr() DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-42342:GERAN-A:PAGING_RESP){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_pres() DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-42342:GERAN-A:PAGING_RESP){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_trace() @@ -3394,6 +3422,7 @@ DLSMS SMC(0) send CP data DLSMS SMC(0) new CP state MM_CONN_PENDING -> WAIT_CP_ACK DLSMS trans(SMS IMSI-901700000004620:MSISDN-42342:GERAN-A:PAGING_RESP callref-0x40000004 tid-0) sending CP message (trans=0) DLSMS trans(SMS IMSI-901700000004620:MSISDN-42342:GERAN-A:PAGING_RESP callref-0x40000004 tid-0) GSM4.11 TX 09 01 58 01 00 07 91 44 77 58 10 06 50 00 4c 00 05 80 24 43 f2 00 00 07 10 10 00 00 00 00 44 50 79 da 1e 1e e7 41 69 37 48 5e 9e a7 c9 65 37 3d 1d 66 83 c2 70 38 3b 3d 0e d3 d3 6f f7 1c 94 9e 83 c2 20 72 79 9e 96 87 c5 ec 32 a8 1d 96 af cb f4 b4 fb 0c 7a c3 e9 e9 b7 db 05 +DBSSAP msc_a(IMSI-901700000004620:MSISDN-42342:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: Sending DTAP: SMS SMS:0x01 DMSC msc_a(IMSI-901700000004620:MSISDN-42342:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: RAN encode: DTAP on GERAN-A - DTAP --GERAN-A--> MS: SMS:0x01: 09015801000791447758100650004c0005802443f2000007101000000000445079da1e1ee7416937485e9ea7c965373d1d6683c270383b3d0ed3d36ff71c949e83c22072799e9687c5ec32a81d96afcbf4b4fb0c7ac3e9e9b7db05 - DTAP matches expected message @@ -3429,6 +3458,7 @@ DLSMS SMC(0) message MMSMS-DATA-IND (CP DATA) received in state MM_ESTABLISHED DLSMS SMC(0) received CP-DATA DLSMS trans(SMS IMSI-901700000004620:MSISDN-42342:GERAN-A:PAGING_RESP callref-0x40000004 tid-0) sending CP message (trans=0) DLSMS trans(SMS IMSI-901700000004620:MSISDN-42342:GERAN-A:PAGING_RESP callref-0x40000004 tid-0) GSM4.11 TX 09 04 +DBSSAP msc_a(IMSI-901700000004620:MSISDN-42342:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: Sending DTAP: SMS SMS:0x04 DMSC msc_a(IMSI-901700000004620:MSISDN-42342:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: RAN encode: DTAP on GERAN-A - DTAP --GERAN-A--> MS: SMS:0x04: 0904 - DTAP matches expected message @@ -3501,12 +3531,13 @@ DMSC dummy_msc_i{0}: is child of msub_fsm DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms) DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3 DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: MM GSM48_MT_MM_IMSI_DETACH_IND -DMM IMSI DETACH INDICATION: MI(IMSI)=901700000004620 +DMM IMSI DETACH INDICATION: IMSI-901700000004620 DREF VLR subscr IMSI-901700000004620:MSISDN-42342 + gsm48_rx_mm_imsi_detach_ind: now used by 2 (attached,gsm48_rx_mm_imsi_detach_ind) DMM IMSI DETACH for IMSI-901700000004620:MSISDN-42342 DREF VLR subscr IMSI-901700000004620:MSISDN-42342 + active-conn: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn) DREF VLR subscr IMSI-901700000004620:MSISDN-42342 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn,vlr_subscr_cancel_attach_fsm) DREF VLR subscr IMSI-901700000004620:MSISDN-42342 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DREF VLR subscr IMSI-901700000004620:MSISDN-42342 - attached: now used by 2 (gsm48_rx_mm_imsi_detach_ind,active-conn) DREF VLR subscr IMSI-901700000004620:MSISDN-42342 - gsm48_rx_mm_imsi_detach_ind: now used by 1 (active-conn) DMSC msc_a(IMSI-901700000004620:MSISDN-42342:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_CN_CLOSE @@ -3546,9 +3577,6 @@ DMSC msc_a(IMSI-901700000004620:MSISDN-42342:GERAN-A:NONE){MSC_A_ST_RELEASED}: D llist_count(&msub_list) == 0 ===== test_a5_3_supported: SUCCESS -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 17 - ===== test_cm_service_needs_classmark_update - Location Update request causes a GSUP Send Auth Info request to HLR MSC <--GERAN-A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST @@ -3577,13 +3605,14 @@ DREF VLR subscr IMSI-901700000004620 + active-conn: now used by 2 (_lu_fsm_assoc DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH DREF VLR subscr IMSI-901700000004620 - _lu_fsm_associate_vsub: now used by 1 (active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Allocated DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU) DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START -GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f00a0101 +GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f02801020a0101 DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - mm_rx_loc_upd_req: now used by 2 (rx_from_ms,lu) DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu) @@ -3617,7 +3646,7 @@ DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: Au DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU) -DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES +DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_SUCCESS DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Set Ciphering Mode DBSSAP msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: For A5/3, we still need Classmark 2 @@ -3630,7 +3659,7 @@ DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_WAIT_CLASSMARK_UPDATE}: - r lu_result_sent == 0 - BSC sends back a BSSMAP Classmark Update, that triggers the Ciphering Mode Command in A5/3 DBSSAP msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_WAIT_CLASSMARK_UPDATE}: RAN decode: CLASSMARK_UPDATE -DBSSAP msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_WAIT_CLASSMARK_UPDATE}: A5 capabilities recived from Classmark Update: no-cm1 no-cm2 no-cm3 +DBSSAP msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_WAIT_CLASSMARK_UPDATE}: A5 capabilities received from Classmark Update: no-cm1 no-cm2 no-cm3 DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_WAIT_CLASSMARK_UPDATE}: Received Event MSC_A_EV_CLASSMARK_UPDATE DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_WAIT_CLASSMARK_UPDATE}: state_chg to MSC_A_ST_AUTH_CIPH DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: CIPHER_MODE_COMMAND on GERAN-A @@ -3644,6 +3673,8 @@ DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: + ms_sends_ciph DBSSAP msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN decode: CIPHER_MODE_COMPLETE DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_CIPH}: Received Event VLR_ULA_E_CIPH_RES DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_CIPH}: vlr_loc_upd_post_ciph() +DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(IMSI-901700000004620:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_CIPH}: vlr_loc_upd_node_4() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_CIPH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD DVLR upd_hlr_vlr_fsm(IMSI-901700000004620:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated @@ -3837,6 +3868,8 @@ DREF msc_a(IMSI-901700000004620:MSISDN-42342:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AU DBSSAP msc_a(IMSI-901700000004620:MSISDN-42342:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN decode: CIPHER_MODE_COMPLETE DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-42342:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_CIPH}: Received Event PR_ARQ_E_CIPH_RES DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-42342:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_node2_post_ciph() +DMSC msc_a(IMSI-901700000004620:MSISDN-42342:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-42342:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-42342:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_node2_post_vlr() DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-42342:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_pres() DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-42342:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_trace() @@ -3927,7 +3960,7 @@ DMSC dummy_msc_i{0}: is child of msub_fsm DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms) DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3 DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: RR GSM48_MT_RR_PAG_RESP -DRR msc_a(IMSI-901700000004620:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: Rx PAGING RESPONSE +DRR msc_a(IMSI-901700000004620:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: Rx PAGING RESPONSE IMSI-901700000004620 DREF msc_a(IMSI-901700000004620:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: + paging-response: now used by 2 (rx_from_ms,paging-response) DVLR Process_Access_Request_VLR(IMSI-901700000004620:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: Allocated DVLR Process_Access_Request_VLR(IMSI-901700000004620:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: is child of msc_a(IMSI-901700000004620:GERAN-A:PAGING_RESP) @@ -3981,7 +4014,7 @@ DVLR VLR_Authenticate(IMSI-901700000004620:MSISDN-42342:GERAN-A:PAGING_RESP){VLR DREF msc_a(IMSI-901700000004620:MSISDN-42342:GERAN-A:PAGING_RESP){MSC_A_ST_WAIT_CLASSMARK_UPDATE}: - rx_from_ms: now used by 1 (paging-response) - BSC sends back a BSSMAP Classmark Update, that triggers the Ciphering Mode Command in A5/3 DBSSAP msc_a(IMSI-901700000004620:MSISDN-42342:GERAN-A:PAGING_RESP){MSC_A_ST_WAIT_CLASSMARK_UPDATE}: RAN decode: CLASSMARK_UPDATE -DBSSAP msc_a(IMSI-901700000004620:MSISDN-42342:GERAN-A:PAGING_RESP){MSC_A_ST_WAIT_CLASSMARK_UPDATE}: A5 capabilities recived from Classmark Update: no-cm1 no-cm2 no-cm3 +DBSSAP msc_a(IMSI-901700000004620:MSISDN-42342:GERAN-A:PAGING_RESP){MSC_A_ST_WAIT_CLASSMARK_UPDATE}: A5 capabilities received from Classmark Update: no-cm1 no-cm2 no-cm3 DMSC msc_a(IMSI-901700000004620:MSISDN-42342:GERAN-A:PAGING_RESP){MSC_A_ST_WAIT_CLASSMARK_UPDATE}: Received Event MSC_A_EV_CLASSMARK_UPDATE DMSC msc_a(IMSI-901700000004620:MSISDN-42342:GERAN-A:PAGING_RESP){MSC_A_ST_WAIT_CLASSMARK_UPDATE}: state_chg to MSC_A_ST_AUTH_CIPH DMSC msc_a(IMSI-901700000004620:MSISDN-42342:GERAN-A:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: RAN encode: CIPHER_MODE_COMMAND on GERAN-A @@ -3996,6 +4029,8 @@ DREF msc_a(IMSI-901700000004620:MSISDN-42342:GERAN-A:PAGING_RESP){MSC_A_ST_AUTH_ DBSSAP msc_a(IMSI-901700000004620:MSISDN-42342:GERAN-A:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: RAN decode: CIPHER_MODE_COMPLETE DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-42342:GERAN-A:PAGING_RESP){PR_ARQ_S_WAIT_CIPH}: Received Event PR_ARQ_E_CIPH_RES DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-42342:GERAN-A:PAGING_RESP){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_node2_post_ciph() +DMSC msc_a(IMSI-901700000004620:MSISDN-42342:GERAN-A:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-42342:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-42342:GERAN-A:PAGING_RESP){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_node2_post_vlr() DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-42342:GERAN-A:PAGING_RESP){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_pres() DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-42342:GERAN-A:PAGING_RESP){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_trace() @@ -4014,6 +4049,7 @@ DLSMS SMC(0) send CP data DLSMS SMC(0) new CP state MM_CONN_PENDING -> WAIT_CP_ACK DLSMS trans(SMS IMSI-901700000004620:MSISDN-42342:GERAN-A:PAGING_RESP callref-0x40000005 tid-0) sending CP message (trans=0) DLSMS trans(SMS IMSI-901700000004620:MSISDN-42342:GERAN-A:PAGING_RESP callref-0x40000005 tid-0) GSM4.11 TX 09 01 58 01 00 07 91 44 77 58 10 06 50 00 4c 00 05 80 24 43 f2 00 00 07 10 10 00 00 00 00 44 50 79 da 1e 1e e7 41 69 37 48 5e 9e a7 c9 65 37 3d 1d 66 83 c2 70 38 3b 3d 0e d3 d3 6f f7 1c 94 9e 83 c2 20 72 79 9e 96 87 c5 ec 32 a8 1d 96 af cb f4 b4 fb 0c 7a c3 e9 e9 b7 db 05 +DBSSAP msc_a(IMSI-901700000004620:MSISDN-42342:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: Sending DTAP: SMS SMS:0x01 DMSC msc_a(IMSI-901700000004620:MSISDN-42342:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: RAN encode: DTAP on GERAN-A - DTAP --GERAN-A--> MS: SMS:0x01: 09015801000791447758100650004c0005802443f2000007101000000000445079da1e1ee7416937485e9ea7c965373d1d6683c270383b3d0ed3d36ff71c949e83c22072799e9687c5ec32a81d96afcbf4b4fb0c7ac3e9e9b7db05 - DTAP matches expected message @@ -4049,6 +4085,7 @@ DLSMS SMC(0) message MMSMS-DATA-IND (CP DATA) received in state MM_ESTABLISHED DLSMS SMC(0) received CP-DATA DLSMS trans(SMS IMSI-901700000004620:MSISDN-42342:GERAN-A:PAGING_RESP callref-0x40000005 tid-0) sending CP message (trans=0) DLSMS trans(SMS IMSI-901700000004620:MSISDN-42342:GERAN-A:PAGING_RESP callref-0x40000005 tid-0) GSM4.11 TX 09 04 +DBSSAP msc_a(IMSI-901700000004620:MSISDN-42342:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: Sending DTAP: SMS SMS:0x04 DMSC msc_a(IMSI-901700000004620:MSISDN-42342:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: RAN encode: DTAP on GERAN-A - DTAP --GERAN-A--> MS: SMS:0x04: 0904 - DTAP matches expected message @@ -4121,12 +4158,13 @@ DMSC dummy_msc_i{0}: is child of msub_fsm DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms) DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3 DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: MM GSM48_MT_MM_IMSI_DETACH_IND -DMM IMSI DETACH INDICATION: MI(IMSI)=901700000004620 +DMM IMSI DETACH INDICATION: IMSI-901700000004620 DREF VLR subscr IMSI-901700000004620:MSISDN-42342 + gsm48_rx_mm_imsi_detach_ind: now used by 2 (attached,gsm48_rx_mm_imsi_detach_ind) DMM IMSI DETACH for IMSI-901700000004620:MSISDN-42342 DREF VLR subscr IMSI-901700000004620:MSISDN-42342 + active-conn: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn) DREF VLR subscr IMSI-901700000004620:MSISDN-42342 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn,vlr_subscr_cancel_attach_fsm) DREF VLR subscr IMSI-901700000004620:MSISDN-42342 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DREF VLR subscr IMSI-901700000004620:MSISDN-42342 - attached: now used by 2 (gsm48_rx_mm_imsi_detach_ind,active-conn) DREF VLR subscr IMSI-901700000004620:MSISDN-42342 - gsm48_rx_mm_imsi_detach_ind: now used by 1 (active-conn) DMSC msc_a(IMSI-901700000004620:MSISDN-42342:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_CN_CLOSE @@ -4166,9 +4204,3 @@ DMSC msc_a(IMSI-901700000004620:MSISDN-42342:GERAN-A:NONE){MSC_A_ST_RELEASED}: D llist_count(&msub_list) == 0 ===== test_cm_service_needs_classmark_update: SUCCESS -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 17 - -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 17 - diff --git a/tests/msc_vlr/msc_vlr_test_hlr_reject.c b/tests/msc_vlr/msc_vlr_test_hlr_reject.c index 1134d8971..6cdadcb8f 100644 --- a/tests/msc_vlr/msc_vlr_test_hlr_reject.c +++ b/tests/msc_vlr/msc_vlr_test_hlr_reject.c @@ -22,7 +22,6 @@ */ #include "msc_vlr_tests.h" -#include "stubs.h" static void test_hlr_rej_auth_info_unknown_imsi() { @@ -32,7 +31,7 @@ static void test_hlr_rej_auth_info_unknown_imsi() btw("Location Update request causes a GSUP Send Auth Info request to HLR"); lu_result_sent = RES_NONE; - gsup_expect_tx("08010809710000004026f0" VLR_TO_HLR); + gsup_expect_tx("08010809710000004026f0" CN_DOMAIN VLR_TO_HLR); ms_sends_msg("050802008168000130089910070000006402"); OSMO_ASSERT(gsup_tx_confirmed); VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); @@ -59,7 +58,7 @@ static void test_hlr_rej_auth_info_net_fail() btw("Location Update request causes a GSUP Send Auth Info request to HLR"); lu_result_sent = RES_NONE; - gsup_expect_tx("08010809710000004026f0" VLR_TO_HLR); + gsup_expect_tx("08010809710000004026f0" CN_DOMAIN VLR_TO_HLR); ms_sends_msg("050802008168000130089910070000006402"); OSMO_ASSERT(gsup_tx_confirmed); VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); @@ -92,7 +91,7 @@ static void test_hlr_rej_auth_info_net_fail_no_reuse_tuples() BTW("Submit a used auth tuple in the VLR"); btw("Location Update request causes a GSUP Send Auth Info request to HLR"); lu_result_sent = RES_NONE; - gsup_expect_tx("08010809710000004026f0" VLR_TO_HLR); + gsup_expect_tx("08010809710000004026f0" CN_DOMAIN VLR_TO_HLR); ms_sends_msg("050802008168000130089910070000006402"); OSMO_ASSERT(gsup_tx_confirmed); VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); @@ -115,7 +114,7 @@ static void test_hlr_rej_auth_info_net_fail_no_reuse_tuples() VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); btw("MS sends Authen Response, VLR accepts and sends GSUP LU Req to HLR"); - gsup_expect_tx("04010809710000004026f0280102" VLR_TO_HLR); + gsup_expect_tx("04010809710000004026f0" CN_DOMAIN VLR_TO_HLR); ms_sends_msg("05542d8b2c3e"); VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); @@ -148,7 +147,7 @@ static void test_hlr_rej_auth_info_net_fail_no_reuse_tuples() btw("Location Update request causes a GSUP Send Auth Info request to HLR"); lu_result_sent = RES_NONE; - gsup_expect_tx("08010809710000004026f0" VLR_TO_HLR); + gsup_expect_tx("08010809710000004026f0" CN_DOMAIN VLR_TO_HLR); ms_sends_msg("050802008168000130089910070000006402"); OSMO_ASSERT(gsup_tx_confirmed); VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); @@ -181,7 +180,7 @@ static void test_hlr_rej_auth_info_unkown_imsi_no_reuse_tuples() BTW("Submit a used auth tuple in the VLR"); btw("Location Update request causes a GSUP Send Auth Info request to HLR"); lu_result_sent = RES_NONE; - gsup_expect_tx("08010809710000004026f0" VLR_TO_HLR); + gsup_expect_tx("08010809710000004026f0" CN_DOMAIN VLR_TO_HLR); ms_sends_msg("050802008168000130089910070000006402"); OSMO_ASSERT(gsup_tx_confirmed); VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); @@ -204,7 +203,7 @@ static void test_hlr_rej_auth_info_unkown_imsi_no_reuse_tuples() VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); btw("MS sends Authen Response, VLR accepts and sends GSUP LU Req to HLR"); - gsup_expect_tx("04010809710000004026f0280102" VLR_TO_HLR); + gsup_expect_tx("04010809710000004026f0" CN_DOMAIN VLR_TO_HLR); ms_sends_msg("05542d8b2c3e"); VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); @@ -238,7 +237,7 @@ static void test_hlr_rej_auth_info_unkown_imsi_no_reuse_tuples() btw("Location Update request causes a GSUP Send Auth Info request to HLR"); lu_result_sent = RES_NONE; - gsup_expect_tx("08010809710000004026f0" VLR_TO_HLR); + gsup_expect_tx("08010809710000004026f0" CN_DOMAIN VLR_TO_HLR); ms_sends_msg("050802008168000130089910070000006402"); OSMO_ASSERT(gsup_tx_confirmed); VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); @@ -267,7 +266,7 @@ static void test_hlr_acc_but_no_auth_tuples() btw("Location Update request causes a GSUP Send Auth Info request to HLR"); lu_result_sent = RES_NONE; - gsup_expect_tx("08010809710000004026f0" VLR_TO_HLR); + gsup_expect_tx("08010809710000004026f0" CN_DOMAIN VLR_TO_HLR); ms_sends_msg("050802008168000130089910070000006402"); OSMO_ASSERT(gsup_tx_confirmed); VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); @@ -305,7 +304,7 @@ static void test_hlr_rej_auth_info_net_fail_reuse_tuples() BTW("Submit a used auth tuple in the VLR"); btw("Location Update request causes a GSUP Send Auth Info request to HLR"); lu_result_sent = RES_NONE; - gsup_expect_tx("08010809710000004026f0" VLR_TO_HLR); + gsup_expect_tx("08010809710000004026f0" CN_DOMAIN VLR_TO_HLR); ms_sends_msg("050802008168000130089910070000006402"); OSMO_ASSERT(gsup_tx_confirmed); VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); @@ -329,7 +328,7 @@ static void test_hlr_rej_auth_info_net_fail_reuse_tuples() VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); btw("MS sends Authen Response, VLR accepts and sends GSUP LU Req to HLR"); - gsup_expect_tx("04010809710000004026f0280102" VLR_TO_HLR); + gsup_expect_tx("04010809710000004026f0" CN_DOMAIN VLR_TO_HLR); ms_sends_msg("05542d8b2c3e"); VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); @@ -362,7 +361,7 @@ static void test_hlr_rej_auth_info_net_fail_reuse_tuples() btw("Location Update request causes a GSUP Send Auth Info request to HLR"); lu_result_sent = RES_NONE; - gsup_expect_tx("08010809710000004026f0" VLR_TO_HLR); + gsup_expect_tx("08010809710000004026f0" CN_DOMAIN VLR_TO_HLR); ms_sends_msg("050802008168000130089910070000006402"); OSMO_ASSERT(gsup_tx_confirmed); VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); @@ -374,7 +373,7 @@ static void test_hlr_rej_auth_info_net_fail_reuse_tuples() VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); btw("MS sends Authen Response, VLR accepts and sends GSUP LU Req to HLR"); - gsup_expect_tx("04010809710000004026f0280102" VLR_TO_HLR); + gsup_expect_tx("04010809710000004026f0" CN_DOMAIN VLR_TO_HLR); ms_sends_msg("05542d8b2c3e"); VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); @@ -403,7 +402,7 @@ static void test_hlr_rej_lu() btw("Location Update request causes a GSUP LU request to HLR"); lu_result_sent = RES_NONE; - gsup_expect_tx("04010809710000004026f0280102" VLR_TO_HLR); + gsup_expect_tx("04010809710000004026f0" CN_DOMAIN VLR_TO_HLR); ms_sends_msg("050802008168000130089910070000006402"); OSMO_ASSERT(gsup_tx_confirmed); VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); @@ -427,7 +426,7 @@ static void test_hlr_no_insert_data() btw("Location Update request causes a GSUP LU request to HLR"); lu_result_sent = RES_NONE; - gsup_expect_tx("04010809710000004026f0280102" VLR_TO_HLR); + gsup_expect_tx("04010809710000004026f0" CN_DOMAIN VLR_TO_HLR); ms_sends_msg("050802008168000130089910070000006402"); OSMO_ASSERT(gsup_tx_confirmed); VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); diff --git a/tests/msc_vlr/msc_vlr_test_hlr_reject.err b/tests/msc_vlr/msc_vlr_test_hlr_reject.err index 2dd6a52e6..305e1b814 100644 --- a/tests/msc_vlr/msc_vlr_test_hlr_reject.err +++ b/tests/msc_vlr/msc_vlr_test_hlr_reject.err @@ -1,7 +1,3 @@ -DLMGCP MGCP client: using endpoint domain '@mgw' -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 17 - ===== test_hlr_rej_auth_info_unknown_imsi - Location Update request causes a GSUP Send Auth Info request to HLR MSC <--GERAN-A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST @@ -30,13 +26,14 @@ DREF VLR subscr IMSI-901700000004620 + active-conn: now used by 2 (_lu_fsm_assoc DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH DREF VLR subscr IMSI-901700000004620 - _lu_fsm_associate_vsub: now used by 1 (active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Allocated DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU) DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START -GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f00a0101 +GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f02801020a0101 DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - mm_rx_loc_upd_req: now used by 2 (rx_from_ms,lu) DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu) @@ -46,11 +43,11 @@ DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: n DREF VLR subscr IMSI-901700000004620 + vlr_gsup_rx: now used by 2 (active-conn,vlr_gsup_rx) DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: Received Event VLR_AUTH_E_HLR_SAI_NACK DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: GSUP: rx Auth Info Error cause: 2: IMSI unknown in HLR -DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: Authentication terminating with result IMSI unknown in HLR +DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: Authentication terminating with result NO_AUTH_INFO, cause IMSI_UNKNOWN_IN_HLR DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: state_chg to VLR_SUB_AS_AUTH_FAILED DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_AUTH_FAILED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_AUTH_FAILED}: Removing from parent vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU) -DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES +DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_NO_INFO - sending LU Reject for IMSI-901700000004620:GERAN-A:LU, cause 2 DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_DONE DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: Received Event MSC_A_EV_CN_CLOSE @@ -65,7 +62,6 @@ DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_RELEASING}: + wait-Clear-Co DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_RELEASING}: RAN encode: CLEAR_COMMAND on GERAN-A DMSC dummy_msc_i(IMSI-901700000004620:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DREF VLR subscr IMSI-901700000004620 - msc_a_fsm_releasing_onenter: now used by 2 (active-conn,vlr_gsup_rx) -DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_RELEASING}: transition to state MSC_A_ST_RELEASING not permitted! DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_AUTH_FAILED}: Deallocated DREF VLR subscr IMSI-901700000004620 - vlr_gsup_rx: now used by 1 (active-conn) <-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_ERROR: vlr_gsupc_read_cb() returns 0 @@ -101,9 +97,6 @@ DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_RELEASED}: Deallocated, inc llist_count(&msub_list) == 0 ===== test_hlr_rej_auth_info_unknown_imsi: SUCCESS -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 17 - ===== test_hlr_rej_auth_info_net_fail - Location Update request causes a GSUP Send Auth Info request to HLR MSC <--GERAN-A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST @@ -132,13 +125,14 @@ DREF VLR subscr IMSI-901700000004620 + active-conn: now used by 2 (_lu_fsm_assoc DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH DREF VLR subscr IMSI-901700000004620 - _lu_fsm_associate_vsub: now used by 1 (active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Allocated DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU) DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START -GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f00a0101 +GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f02801020a0101 DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - mm_rx_loc_upd_req: now used by 2 (rx_from_ms,lu) DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu) @@ -148,11 +142,11 @@ DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: n DREF VLR subscr IMSI-901700000004620 + vlr_gsup_rx: now used by 2 (active-conn,vlr_gsup_rx) DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: Received Event VLR_AUTH_E_HLR_SAI_NACK DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: GSUP: rx Auth Info Error cause: 17: Network failure -DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: Authentication terminating with result Network failure +DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: Authentication terminating with result NO_AUTH_INFO, cause NETWORK_FAILURE DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: state_chg to VLR_SUB_AS_AUTH_FAILED DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_AUTH_FAILED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_AUTH_FAILED}: Removing from parent vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU) -DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES +DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_NO_INFO - sending LU Reject for IMSI-901700000004620:GERAN-A:LU, cause 17 DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_DONE DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: Received Event MSC_A_EV_CN_CLOSE @@ -167,7 +161,6 @@ DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_RELEASING}: + wait-Clear-Co DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_RELEASING}: RAN encode: CLEAR_COMMAND on GERAN-A DMSC dummy_msc_i(IMSI-901700000004620:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DREF VLR subscr IMSI-901700000004620 - msc_a_fsm_releasing_onenter: now used by 2 (active-conn,vlr_gsup_rx) -DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_RELEASING}: transition to state MSC_A_ST_RELEASING not permitted! DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_AUTH_FAILED}: Deallocated DREF VLR subscr IMSI-901700000004620 - vlr_gsup_rx: now used by 1 (active-conn) <-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_ERROR: vlr_gsupc_read_cb() returns 0 @@ -203,9 +196,6 @@ DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_RELEASED}: Deallocated, inc llist_count(&msub_list) == 0 ===== test_hlr_rej_auth_info_net_fail: SUCCESS -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 17 - ===== test_hlr_rej_auth_info_net_fail_reuse_tuples @@ -237,13 +227,14 @@ DREF VLR subscr IMSI-901700000004620 + active-conn: now used by 2 (_lu_fsm_assoc DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH DREF VLR subscr IMSI-901700000004620 - _lu_fsm_associate_vsub: now used by 1 (active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Allocated DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU) DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START -GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f00a0101 +GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f02801020a0101 DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - mm_rx_loc_upd_req: now used by 2 (rx_from_ms,lu) DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu) @@ -275,9 +266,11 @@ DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: Au DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU) -DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES +DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_SUCCESS DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_ciph() +DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(IMSI-901700000004620:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_node_4() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD DVLR upd_hlr_vlr_fsm(IMSI-901700000004620:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated @@ -399,13 +392,14 @@ DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + active-conn: now used by 3 ( DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - _lu_fsm_associate_vsub: now used by 2 (attached,active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre() DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH DVLR VLR_Authenticate(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Allocated DVLR VLR_Authenticate(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU) DVLR VLR_Authenticate(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START -GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f00a0101 +GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f02801020a0101 DVLR VLR_Authenticate(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI DREF msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - mm_rx_loc_upd_req: now used by 2 (rx_from_ms,lu) DREF msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu) @@ -437,9 +431,11 @@ DVLR VLR_Authenticate(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_SUB_AS_W DVLR VLR_Authenticate(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED DVLR VLR_Authenticate(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) DVLR VLR_Authenticate(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU) -DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES +DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_SUCCESS DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth() DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_ciph() +DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_node_4() DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD DVLR upd_hlr_vlr_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated @@ -529,9 +525,6 @@ DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_RELEASED}: Dea DVLR freeing VLR subscr IMSI-901700000004620:MSISDN-46071 (max total use count was 5) ===== test_hlr_rej_auth_info_net_fail_reuse_tuples: SUCCESS -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 17 - ===== test_hlr_rej_auth_info_net_fail_no_reuse_tuples @@ -563,13 +556,14 @@ DREF VLR subscr IMSI-901700000004620 + active-conn: now used by 2 (_lu_fsm_assoc DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH DREF VLR subscr IMSI-901700000004620 - _lu_fsm_associate_vsub: now used by 1 (active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Allocated DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU) DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START -GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f00a0101 +GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f02801020a0101 DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - mm_rx_loc_upd_req: now used by 2 (rx_from_ms,lu) DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu) @@ -601,9 +595,11 @@ DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: Au DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU) -DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES +DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_SUCCESS DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_ciph() +DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(IMSI-901700000004620:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_node_4() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD DVLR upd_hlr_vlr_fsm(IMSI-901700000004620:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated @@ -725,13 +721,14 @@ DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + active-conn: now used by 3 ( DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - _lu_fsm_associate_vsub: now used by 2 (attached,active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre() DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH DVLR VLR_Authenticate(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Allocated DVLR VLR_Authenticate(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU) DVLR VLR_Authenticate(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START -GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f00a0101 +GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f02801020a0101 DVLR VLR_Authenticate(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI DREF msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - mm_rx_loc_upd_req: now used by 2 (rx_from_ms,lu) DREF msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu) @@ -741,11 +738,11 @@ DREF msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + vlr_gsup_rx: now used by 3 (attached,active-conn,vlr_gsup_rx) DVLR VLR_Authenticate(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: Received Event VLR_AUTH_E_HLR_SAI_NACK DVLR VLR_Authenticate(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: GSUP: rx Auth Info Error cause: 17: Network failure -DVLR VLR_Authenticate(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: Authentication terminating with result Network failure +DVLR VLR_Authenticate(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: Authentication terminating with result NO_AUTH_INFO, cause NETWORK_FAILURE DVLR VLR_Authenticate(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: state_chg to VLR_SUB_AS_AUTH_FAILED DVLR VLR_Authenticate(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_SUB_AS_AUTH_FAILED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) DVLR VLR_Authenticate(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_SUB_AS_AUTH_FAILED}: Removing from parent vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU) -DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES +DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_NO_INFO - sending LU Reject for IMSI-901700000004620:MSISDN-46071:GERAN-A:LU, cause 17 DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_DONE DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: Received Event MSC_A_EV_CN_CLOSE @@ -760,7 +757,6 @@ DREF msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_RELEASING}: + DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_RELEASING}: RAN encode: CLEAR_COMMAND on GERAN-A DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - msc_a_fsm_releasing_onenter: now used by 3 (attached,active-conn,vlr_gsup_rx) -DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_RELEASING}: transition to state MSC_A_ST_RELEASING not permitted! DVLR VLR_Authenticate(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_SUB_AS_AUTH_FAILED}: Deallocated DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - vlr_gsup_rx: now used by 2 (attached,active-conn) <-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_ERROR: vlr_gsupc_read_cb() returns 0 @@ -796,9 +792,6 @@ DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_RELEASED}: Dea DVLR freeing VLR subscr IMSI-901700000004620:MSISDN-46071 (max total use count was 5) ===== test_hlr_rej_auth_info_net_fail_no_reuse_tuples: SUCCESS -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 17 - ===== test_hlr_rej_auth_info_unkown_imsi_no_reuse_tuples @@ -830,13 +823,14 @@ DREF VLR subscr IMSI-901700000004620 + active-conn: now used by 2 (_lu_fsm_assoc DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH DREF VLR subscr IMSI-901700000004620 - _lu_fsm_associate_vsub: now used by 1 (active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Allocated DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU) DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START -GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f00a0101 +GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f02801020a0101 DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - mm_rx_loc_upd_req: now used by 2 (rx_from_ms,lu) DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu) @@ -868,9 +862,11 @@ DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: Au DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU) -DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES +DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_SUCCESS DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_ciph() +DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(IMSI-901700000004620:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_node_4() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD DVLR upd_hlr_vlr_fsm(IMSI-901700000004620:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated @@ -993,13 +989,14 @@ DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + active-conn: now used by 3 ( DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - _lu_fsm_associate_vsub: now used by 2 (attached,active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre() DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH DVLR VLR_Authenticate(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Allocated DVLR VLR_Authenticate(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU) DVLR VLR_Authenticate(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START -GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f00a0101 +GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f02801020a0101 DVLR VLR_Authenticate(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI DREF msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - mm_rx_loc_upd_req: now used by 2 (rx_from_ms,lu) DREF msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu) @@ -1009,11 +1006,11 @@ DREF msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + vlr_gsup_rx: now used by 3 (attached,active-conn,vlr_gsup_rx) DVLR VLR_Authenticate(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: Received Event VLR_AUTH_E_HLR_SAI_NACK DVLR VLR_Authenticate(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: GSUP: rx Auth Info Error cause: 2: IMSI unknown in HLR -DVLR VLR_Authenticate(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: Authentication terminating with result IMSI unknown in HLR +DVLR VLR_Authenticate(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: Authentication terminating with result NO_AUTH_INFO, cause IMSI_UNKNOWN_IN_HLR DVLR VLR_Authenticate(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: state_chg to VLR_SUB_AS_AUTH_FAILED DVLR VLR_Authenticate(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_SUB_AS_AUTH_FAILED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) DVLR VLR_Authenticate(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_SUB_AS_AUTH_FAILED}: Removing from parent vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU) -DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES +DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_NO_INFO - sending LU Reject for IMSI-901700000004620:MSISDN-46071:GERAN-A:LU, cause 2 DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_DONE DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: Received Event MSC_A_EV_CN_CLOSE @@ -1028,7 +1025,6 @@ DREF msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_RELEASING}: + DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_RELEASING}: RAN encode: CLEAR_COMMAND on GERAN-A DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - msc_a_fsm_releasing_onenter: now used by 3 (attached,active-conn,vlr_gsup_rx) -DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_RELEASING}: transition to state MSC_A_ST_RELEASING not permitted! DVLR VLR_Authenticate(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_SUB_AS_AUTH_FAILED}: Deallocated DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - vlr_gsup_rx: now used by 2 (attached,active-conn) <-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_ERROR: vlr_gsupc_read_cb() returns 0 @@ -1064,9 +1060,6 @@ DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_RELEASED}: Dea DVLR freeing VLR subscr IMSI-901700000004620:MSISDN-46071 (max total use count was 5) ===== test_hlr_rej_auth_info_unkown_imsi_no_reuse_tuples: SUCCESS -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 17 - ===== test_hlr_acc_but_no_auth_tuples - Location Update request causes a GSUP Send Auth Info request to HLR MSC <--GERAN-A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST @@ -1095,13 +1088,14 @@ DREF VLR subscr IMSI-901700000004620 + active-conn: now used by 2 (_lu_fsm_assoc DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH DREF VLR subscr IMSI-901700000004620 - _lu_fsm_associate_vsub: now used by 1 (active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Allocated DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU) DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START -GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f00a0101 +GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f02801020a0101 DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - mm_rx_loc_upd_req: now used by 2 (rx_from_ms,lu) DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu) @@ -1110,11 +1104,11 @@ DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: n <-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT: 0a010809710000004026f00a0101 DREF VLR subscr IMSI-901700000004620 + vlr_gsup_rx: now used by 2 (active-conn,vlr_gsup_rx) DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: Received Event VLR_AUTH_E_HLR_SAI_ACK -DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: Authentication terminating with result Network failure +DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: Authentication terminating with result FAILURE, cause NETWORK_FAILURE DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: state_chg to VLR_SUB_AS_AUTH_FAILED DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_AUTH_FAILED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_AUTH_FAILED}: Removing from parent vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU) -DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES +DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_FAILURE - sending LU Reject for IMSI-901700000004620:GERAN-A:LU, cause 17 DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_DONE DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: Received Event MSC_A_EV_CN_CLOSE @@ -1129,7 +1123,6 @@ DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_RELEASING}: + wait-Clear-Co DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_RELEASING}: RAN encode: CLEAR_COMMAND on GERAN-A DMSC dummy_msc_i(IMSI-901700000004620:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DREF VLR subscr IMSI-901700000004620 - msc_a_fsm_releasing_onenter: now used by 2 (active-conn,vlr_gsup_rx) -DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_RELEASING}: transition to state MSC_A_ST_RELEASING not permitted! DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_AUTH_FAILED}: Deallocated DREF VLR subscr IMSI-901700000004620 - vlr_gsup_rx: now used by 1 (active-conn) <-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT: vlr_gsupc_read_cb() returns 0 @@ -1165,9 +1158,6 @@ DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_RELEASED}: Deallocated, inc llist_count(&msub_list) == 0 ===== test_hlr_acc_but_no_auth_tuples: SUCCESS -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 17 - ===== test_hlr_rej_lu - Location Update request causes a GSUP LU request to HLR MSC <--GERAN-A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST @@ -1196,10 +1186,13 @@ DREF VLR subscr IMSI-901700000004620 + active-conn: now used by 2 (_lu_fsm_assoc DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH DREF VLR subscr IMSI-901700000004620 - _lu_fsm_associate_vsub: now used by 1 (active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_post_auth() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_post_ciph() +DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(IMSI-901700000004620:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node_4() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_HLR_UPD DVLR upd_hlr_vlr_fsm(IMSI-901700000004620:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated @@ -1234,7 +1227,6 @@ DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_RELEASING}: + wait-Clear-Co DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_RELEASING}: RAN encode: CLEAR_COMMAND on GERAN-A DMSC dummy_msc_i(IMSI-901700000004620:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DREF VLR subscr IMSI-901700000004620 - msc_a_fsm_releasing_onenter: now used by 2 (active-conn,vlr_gsup_rx) -DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_RELEASING}: transition to state MSC_A_ST_RELEASING not permitted! DVLR upd_hlr_vlr_fsm(IMSI-901700000004620:GERAN-A:LU){UPD_HLR_VLR_S_DONE}: Deallocated DREF VLR subscr IMSI-901700000004620 - vlr_gsup_rx: now used by 1 (active-conn) <-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_ERROR: vlr_gsupc_read_cb() returns 0 @@ -1269,9 +1261,6 @@ DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_RELEASED}: Deallocated, inc llist_count(&msub_list) == 0 ===== test_hlr_rej_lu: SUCCESS -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 17 - ===== test_hlr_no_insert_data - Location Update request causes a GSUP LU request to HLR MSC <--GERAN-A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST @@ -1300,10 +1289,13 @@ DREF VLR subscr IMSI-901700000004620 + active-conn: now used by 2 (_lu_fsm_assoc DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH DREF VLR subscr IMSI-901700000004620 - _lu_fsm_associate_vsub: now used by 1 (active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_post_auth() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_post_ciph() +DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(IMSI-901700000004620:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node_4() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_HLR_UPD DVLR upd_hlr_vlr_fsm(IMSI-901700000004620:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated @@ -1385,9 +1377,3 @@ DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_RELEASED}: Deallocated, inc DVLR freeing VLR subscr IMSI-901700000004620 (max total use count was 5) ===== test_hlr_no_insert_data: SUCCESS -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 17 - -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 17 - diff --git a/tests/msc_vlr/msc_vlr_test_hlr_timeout.c b/tests/msc_vlr/msc_vlr_test_hlr_timeout.c index af5441b7c..4523a7c7b 100644 --- a/tests/msc_vlr/msc_vlr_test_hlr_timeout.c +++ b/tests/msc_vlr/msc_vlr_test_hlr_timeout.c @@ -22,7 +22,6 @@ */ #include "msc_vlr_tests.h" -#include "stubs.h" #include <osmocom/core/logging.h> @@ -36,7 +35,7 @@ static void test_hlr_timeout_lu_auth_info() btw("Location Update request causes a GSUP Send Auth Info request to HLR"); lu_result_sent = RES_NONE; - gsup_expect_tx("08010809710000004026f0" VLR_TO_HLR); + gsup_expect_tx("08010809710000004026f0" CN_DOMAIN VLR_TO_HLR); ms_sends_msg("050802008168000130089910070000006402"); OSMO_ASSERT(gsup_tx_confirmed); VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); @@ -74,7 +73,7 @@ static void test_hlr_timeout_lu_upd_loc_result() btw("Location Update request causes a GSUP LU request to HLR"); lu_result_sent = RES_NONE; - gsup_expect_tx("04010809710000004026f0280102" VLR_TO_HLR); + gsup_expect_tx("04010809710000004026f0" CN_DOMAIN VLR_TO_HLR); ms_sends_msg("050802008168000130089910070000006402"); OSMO_ASSERT(gsup_tx_confirmed); VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); diff --git a/tests/msc_vlr/msc_vlr_test_hlr_timeout.err b/tests/msc_vlr/msc_vlr_test_hlr_timeout.err index 60b240da6..6a4daa5bd 100644 --- a/tests/msc_vlr/msc_vlr_test_hlr_timeout.err +++ b/tests/msc_vlr/msc_vlr_test_hlr_timeout.err @@ -1,7 +1,3 @@ -DLMGCP MGCP client: using endpoint domain '@mgw' -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 17 - ===== test_hlr_timeout_lu_auth_info - Total time passed: 0.000000 s - Location Update request causes a GSUP Send Auth Info request to HLR @@ -31,13 +27,14 @@ DREF VLR subscr IMSI-901700000004620 + active-conn: now used by 2 (_lu_fsm_assoc DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH DREF VLR subscr IMSI-901700000004620 - _lu_fsm_associate_vsub: now used by 1 (active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Allocated DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU) DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START -GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f00a0101 +GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f02801020a0101 DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - mm_rx_loc_upd_req: now used by 2 (rx_from_ms,lu) DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu) @@ -68,13 +65,11 @@ DREF VLR subscr IMSI-901700000004620 + vlr_subscr_cancel_attach_fsm: now used by - sending LU Reject for IMSI-901700000004620:GERAN-A:LU, cause 22 DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_DONE DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_RELEASING}: Received Event MSC_A_EV_CN_CLOSE -DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_RELEASING}: Event MSC_A_EV_CN_CLOSE not permitted DREF VLR subscr IMSI-901700000004620 - vlr_subscr_cancel_attach_fsm: now used by 2 (active-conn,msc_a_fsm_releasing_onenter) DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_RELEASING}: + wait-Clear-Complete: now used by 1 (wait-Clear-Complete) DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_RELEASING}: RAN encode: CLEAR_COMMAND on GERAN-A DMSC dummy_msc_i(IMSI-901700000004620:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DREF VLR subscr IMSI-901700000004620 - msc_a_fsm_releasing_onenter: now used by 1 (active-conn) -DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_RELEASING}: transition to state MSC_A_ST_RELEASING not permitted! - RAN_CONN_TIMEOUT has passed, conn is gone. bssap_clear_sent == 1 DBSSAP msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_RELEASING}: RAN decode: CLEAR_COMPLETE @@ -110,9 +105,6 @@ DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_RELEASED}: Deallocated, inc lu_result_sent == 2 ===== test_hlr_timeout_lu_auth_info: SUCCESS -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 17 - ===== test_hlr_timeout_lu_upd_loc_result - Total time passed: 0.000000 s - Location Update request causes a GSUP LU request to HLR @@ -142,10 +134,13 @@ DREF VLR subscr IMSI-901700000004620 + active-conn: now used by 2 (_lu_fsm_assoc DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH DREF VLR subscr IMSI-901700000004620 - _lu_fsm_associate_vsub: now used by 1 (active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_post_auth() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_post_ciph() +DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(IMSI-901700000004620:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node_4() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_HLR_UPD DVLR upd_hlr_vlr_fsm(IMSI-901700000004620:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated @@ -196,13 +191,11 @@ DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + vlr_subscr_cancel_attach_fsm - sending LU Reject for IMSI-901700000004620:MSISDN-46071:GERAN-A:LU, cause 22 DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_DONE DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_RELEASING}: Received Event MSC_A_EV_CN_CLOSE -DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_RELEASING}: Event MSC_A_EV_CN_CLOSE not permitted DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - vlr_subscr_cancel_attach_fsm: now used by 2 (active-conn,msc_a_fsm_releasing_onenter) DREF msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_RELEASING}: + wait-Clear-Complete: now used by 1 (wait-Clear-Complete) DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_RELEASING}: RAN encode: CLEAR_COMMAND on GERAN-A DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - msc_a_fsm_releasing_onenter: now used by 1 (active-conn) -DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_RELEASING}: transition to state MSC_A_ST_RELEASING not permitted! - RAN_CONN_TIMEOUT has passed, conn is gone. bssap_clear_sent == 1 DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_RELEASING}: RAN decode: CLEAR_COMPLETE @@ -238,9 +231,3 @@ DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_RELEASED}: Dea lu_result_sent == 2 ===== test_hlr_timeout_lu_upd_loc_result: SUCCESS -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 17 - -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 17 - diff --git a/tests/msc_vlr/msc_vlr_test_ms_timeout.c b/tests/msc_vlr/msc_vlr_test_ms_timeout.c index 450909fe9..11afc5196 100644 --- a/tests/msc_vlr/msc_vlr_test_ms_timeout.c +++ b/tests/msc_vlr/msc_vlr_test_ms_timeout.c @@ -22,7 +22,6 @@ */ #include "msc_vlr_tests.h" -#include "stubs.h" static void test_ms_timeout_lu_auth_resp() { @@ -34,7 +33,7 @@ static void test_ms_timeout_lu_auth_resp() btw("Location Update request causes a GSUP Send Auth Info request to HLR"); lu_result_sent = RES_NONE; - gsup_expect_tx("08010809710000004026f0" VLR_TO_HLR); + gsup_expect_tx("08010809710000004026f0" CN_DOMAIN VLR_TO_HLR); ms_sends_msg("050802008168000130089910070000006402"); OSMO_ASSERT(gsup_tx_confirmed); VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); @@ -95,7 +94,7 @@ static void test_ms_timeout_cm_auth_resp() btw("Location Update request causes a GSUP Send Auth Info request to HLR"); lu_result_sent = RES_NONE; - gsup_expect_tx("08010809710000004026f0" VLR_TO_HLR); + gsup_expect_tx("08010809710000004026f0" CN_DOMAIN VLR_TO_HLR); ms_sends_msg("050802008168000130089910070000006402"); OSMO_ASSERT(gsup_tx_confirmed); VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); @@ -126,7 +125,7 @@ static void test_ms_timeout_cm_auth_resp() VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); btw("MS sends Authen Response, VLR accepts and sends GSUP LU Req to HLR"); - gsup_expect_tx("04010809710000004026f0280102" VLR_TO_HLR); + gsup_expect_tx("04010809710000004026f0" CN_DOMAIN VLR_TO_HLR); ms_sends_msg("05542d8b2c3e"); VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); @@ -196,7 +195,7 @@ static void test_ms_timeout_paging() btw("Location Update request causes a GSUP LU request to HLR"); lu_result_sent = RES_NONE; - gsup_expect_tx("04010809710000004026f0280102" VLR_TO_HLR); + gsup_expect_tx("04010809710000004026f0" CN_DOMAIN VLR_TO_HLR); ms_sends_msg("050802008168000130089910070000006402"); OSMO_ASSERT(gsup_tx_confirmed); VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); @@ -297,7 +296,7 @@ static void test_classmark_update_timeout() btw("Location Update request causes a GSUP Send Auth Info request to HLR"); lu_result_sent = RES_NONE; - gsup_expect_tx("08010809710000004026f0" VLR_TO_HLR); + gsup_expect_tx("08010809710000004026f0" CN_DOMAIN VLR_TO_HLR); ms_sends_msg("050802008168000130089910070000006402"); OSMO_ASSERT(gsup_tx_confirmed); VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); diff --git a/tests/msc_vlr/msc_vlr_test_ms_timeout.err b/tests/msc_vlr/msc_vlr_test_ms_timeout.err index 07f2b5b40..c4a73e35b 100644 --- a/tests/msc_vlr/msc_vlr_test_ms_timeout.err +++ b/tests/msc_vlr/msc_vlr_test_ms_timeout.err @@ -1,7 +1,3 @@ -DLMGCP MGCP client: using endpoint domain '@mgw' -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 17 - ===== test_ms_timeout_lu_auth_resp - Total time passed: 0.000000 s - Location Update request causes a GSUP Send Auth Info request to HLR @@ -31,13 +27,14 @@ DREF VLR subscr IMSI-901700000004620 + active-conn: now used by 2 (_lu_fsm_assoc DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH DREF VLR subscr IMSI-901700000004620 - _lu_fsm_associate_vsub: now used by 1 (active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Allocated DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU) DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START -GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f00a0101 +GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f02801020a0101 DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - mm_rx_loc_upd_req: now used by 2 (rx_from_ms,lu) DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu) @@ -87,13 +84,11 @@ DREF VLR subscr IMSI-901700000004620 + vlr_subscr_cancel_attach_fsm: now used by - sending LU Reject for IMSI-901700000004620:GERAN-A:LU, cause 22 DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_DONE DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_RELEASING}: Received Event MSC_A_EV_CN_CLOSE -DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_RELEASING}: Event MSC_A_EV_CN_CLOSE not permitted DREF VLR subscr IMSI-901700000004620 - vlr_subscr_cancel_attach_fsm: now used by 2 (active-conn,msc_a_fsm_releasing_onenter) DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_RELEASING}: + wait-Clear-Complete: now used by 1 (wait-Clear-Complete) DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_RELEASING}: RAN encode: CLEAR_COMMAND on GERAN-A DMSC dummy_msc_i(IMSI-901700000004620:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DREF VLR subscr IMSI-901700000004620 - msc_a_fsm_releasing_onenter: now used by 1 (active-conn) -DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_RELEASING}: transition to state MSC_A_ST_RELEASING not permitted! - RAN_CONN_TIMEOUT has passed, conn is gone. bssap_clear_sent == 1 DBSSAP msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_RELEASING}: RAN decode: CLEAR_COMPLETE @@ -129,9 +124,6 @@ DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_RELEASED}: Deallocated, inc lu_result_sent == 2 ===== test_ms_timeout_lu_auth_resp: SUCCESS -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 17 - ===== test_ms_timeout_cm_auth_resp - Total time passed: 0.000000 s - Location Update request causes a GSUP Send Auth Info request to HLR @@ -161,13 +153,14 @@ DREF VLR subscr IMSI-901700000004620 + active-conn: now used by 2 (_lu_fsm_assoc DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH DREF VLR subscr IMSI-901700000004620 - _lu_fsm_associate_vsub: now used by 1 (active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Allocated DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU) DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START -GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f00a0101 +GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f02801020a0101 DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - mm_rx_loc_upd_req: now used by 2 (rx_from_ms,lu) DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu) @@ -199,9 +192,11 @@ DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: Au DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU) -DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES +DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_SUCCESS DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_ciph() +DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(IMSI-901700000004620:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_node_4() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD DVLR upd_hlr_vlr_fsm(IMSI-901700000004620:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated @@ -359,7 +354,6 @@ DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SER DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_DONE}: Process Access Request result: CONGESTION - sending CM Service Reject (Short-Messaging-Service) for IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ, cause: CONGESTION DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: Received Event MSC_A_EV_CN_CLOSE -DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: Event MSC_A_EV_CN_CLOSE not permitted DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,active-conn,msc_a_fsm_releasing_onenter) DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: Releasing: canceling still pending use: cm_service_sms (1) DREF msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: - cm_service_sms: now used by 0 (-) @@ -402,9 +396,6 @@ DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RE DVLR freeing VLR subscr IMSI-901700000004620:MSISDN-46071 (max total use count was 5) ===== test_ms_timeout_cm_auth_resp: SUCCESS -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 17 - ===== test_ms_timeout_paging - Total time passed: 0.000000 s - Location Update request causes a GSUP LU request to HLR @@ -434,10 +425,13 @@ DREF VLR subscr IMSI-901700000004620 + active-conn: now used by 2 (_lu_fsm_assoc DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH DREF VLR subscr IMSI-901700000004620 - _lu_fsm_associate_vsub: now used by 1 (active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_post_auth() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_post_ciph() +DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(IMSI-901700000004620:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node_4() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_HLR_UPD DVLR upd_hlr_vlr_fsm(IMSI-901700000004620:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated @@ -647,7 +641,7 @@ DMSC dummy_msc_i{0}: is child of msub_fsm DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms) DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3 DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: MM GSM48_MT_MM_IMSI_DETACH_IND -DMM IMSI DETACH INDICATION: MI(IMSI)=901700000004620 +DMM IMSI DETACH INDICATION: IMSI-901700000004620 DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + gsm48_rx_mm_imsi_detach_ind: now used by 5 (attached,SMS-receiver,SMS,Paging,gsm48_rx_mm_imsi_detach_ind) DMM IMSI DETACH for IMSI-901700000004620:MSISDN-46071 DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + active-conn: now used by 6 (attached,SMS-receiver,SMS,Paging,gsm48_rx_mm_imsi_detach_ind,active-conn) @@ -671,6 +665,7 @@ DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - SMS: now used by 4 (attached DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - Paging: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn) DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn,vlr_subscr_cancel_attach_fsm) DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - attached: now used by 2 (gsm48_rx_mm_imsi_detach_ind,active-conn) DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - gsm48_rx_mm_imsi_detach_ind: now used by 1 (active-conn) DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_CN_CLOSE @@ -710,9 +705,6 @@ DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:NONE){MSC_A_ST_RELEASED}: D llist_count(&msub_list) == 0 ===== test_ms_timeout_paging: SUCCESS -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 17 - ===== test_classmark_update_timeout - Total time passed: 0.000000 s - Location Update request causes a GSUP Send Auth Info request to HLR @@ -742,13 +734,14 @@ DREF VLR subscr IMSI-901700000004620 + active-conn: now used by 2 (_lu_fsm_assoc DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH DREF VLR subscr IMSI-901700000004620 - _lu_fsm_associate_vsub: now used by 1 (active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Allocated DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU) DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START -GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f00a0101 +GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f02801020a0101 DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - mm_rx_loc_upd_req: now used by 2 (rx_from_ms,lu) DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu) @@ -782,7 +775,7 @@ DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: Au DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU) -DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES +DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_SUCCESS DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Set Ciphering Mode DBSSAP msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: For A5/3, we still need Classmark 2 @@ -825,7 +818,6 @@ DREF VLR subscr IMSI-901700000004620 + vlr_subscr_cancel_attach_fsm: now used by - sending LU Reject for IMSI-901700000004620:GERAN-A:LU, cause 22 DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_CIPH}: state_chg to VLR_ULA_S_DONE DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_RELEASING}: Received Event MSC_A_EV_CN_CLOSE -DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_RELEASING}: Event MSC_A_EV_CN_CLOSE not permitted DREF VLR subscr IMSI-901700000004620 - vlr_subscr_cancel_attach_fsm: now used by 2 (active-conn,msc_a_fsm_releasing_onenter) DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_RELEASING}: + wait-Clear-Complete: now used by 1 (wait-Clear-Complete) DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_RELEASING}: RAN encode: CLEAR_COMMAND on GERAN-A @@ -863,9 +855,3 @@ DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_RELEASED}: Deallocated, inc lu_result_sent == 2 ===== test_classmark_update_timeout: SUCCESS -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 17 - -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 17 - diff --git a/tests/msc_vlr/msc_vlr_test_no_authen.c b/tests/msc_vlr/msc_vlr_test_no_authen.c index b3289f3eb..5d3db69ae 100644 --- a/tests/msc_vlr/msc_vlr_test_no_authen.c +++ b/tests/msc_vlr/msc_vlr_test_no_authen.c @@ -22,7 +22,6 @@ */ #include "msc_vlr_tests.h" -#include "stubs.h" static void test_no_authen() { @@ -35,7 +34,7 @@ static void test_no_authen() btw("Location Update request causes a GSUP LU request to HLR"); lu_result_sent = RES_NONE; - gsup_expect_tx("04010809710000004026f0280102" VLR_TO_HLR); + gsup_expect_tx("04010809710000004026f0" CN_DOMAIN VLR_TO_HLR); ms_sends_msg("050802008168000130089910070000006402"); OSMO_ASSERT(gsup_tx_confirmed); VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); @@ -70,7 +69,7 @@ static void test_no_authen() EXPECT_ACCEPTED(true); /* Release connection */ - expect_bssap_clear(OSMO_RAT_GERAN_A); + expect_bssap_clear(); conn_conclude_cm_service_req(g_msub, MSC_A_USE_CM_SERVICE_SMS); btw("all requests serviced, conn has been released"); @@ -172,7 +171,7 @@ static void test_no_authen_tmsi() btw("Location Update request causes a GSUP LU request to HLR"); lu_result_sent = RES_NONE; - gsup_expect_tx("04010809710000004026f0280102" VLR_TO_HLR); + gsup_expect_tx("04010809710000004026f0" CN_DOMAIN VLR_TO_HLR); ms_sends_msg("050802008168000130089910070000006402"); OSMO_ASSERT(gsup_tx_confirmed); VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); @@ -228,7 +227,7 @@ static void test_no_authen_tmsi() EXPECT_ACCEPTED(true); /* Release connection */ - expect_bssap_clear(OSMO_RAT_GERAN_A); + expect_bssap_clear(); conn_conclude_cm_service_req(g_msub, MSC_A_USE_CM_SERVICE_SMS); btw("all requests serviced, conn has been released"); @@ -317,7 +316,7 @@ static void test_no_authen_tmsi() BTW("subscriber sends LU Request, this time with the TMSI"); btw("Location Update request causes a GSUP LU request to HLR"); lu_result_sent = RES_NONE; - gsup_expect_tx("04010809710000004026f0280102" VLR_TO_HLR); + gsup_expect_tx("04010809710000004026f0" CN_DOMAIN VLR_TO_HLR); ms_sends_msg("050802008168000130" "05f4" "03020100"); OSMO_ASSERT(gsup_tx_confirmed); VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); @@ -390,7 +389,7 @@ static void test_no_authen_imei() btw("Location Update request causes a GSUP LU request to HLR"); lu_result_sent = RES_NONE; - gsup_expect_tx("04010809710000004026f0280102" VLR_TO_HLR); + gsup_expect_tx("04010809710000004026f0" CN_DOMAIN VLR_TO_HLR); ms_sends_msg("050802008168000130089910070000006402"); OSMO_ASSERT(gsup_tx_confirmed); VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); @@ -465,7 +464,7 @@ static void test_no_authen_tmsi_imei() btw("Location Update request causes a GSUP LU request to HLR"); lu_result_sent = RES_NONE; - gsup_expect_tx("04010809710000004026f0280102" VLR_TO_HLR); + gsup_expect_tx("04010809710000004026f0" CN_DOMAIN VLR_TO_HLR); ms_sends_msg("050802008168000130089910070000006402"); OSMO_ASSERT(gsup_tx_confirmed); VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); @@ -553,7 +552,7 @@ static void test_no_authen_imeisv() OSMO_ASSERT(dtap_tx_confirmed); btw("MS replies with an Identity Response, causes LU to commence with a GSUP LU request to HLR"); - gsup_expect_tx("04010809710000004026f0280102" VLR_TO_HLR); + gsup_expect_tx("04010809710000004026f0" CN_DOMAIN VLR_TO_HLR); ms_sends_msg("0559094332244332244372f5"); OSMO_ASSERT(gsup_tx_confirmed); VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); @@ -629,7 +628,7 @@ static void test_no_authen_imeisv_imei() btw("HLR accepts the IMEI, VLR responds with LU Request"); expect_bssap_clear(); gsup_rx("32010809710000004026f0510100" HLR_TO_VLR, - "04010809710000004026f0280102" VLR_TO_HLR); + "04010809710000004026f0" CN_DOMAIN VLR_TO_HLR); OSMO_ASSERT(gsup_tx_confirmed); VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); @@ -687,7 +686,7 @@ static void test_no_authen_imeisv_tmsi() OSMO_ASSERT(dtap_tx_confirmed); btw("MS replies with an Identity Response, causes LU to commence with a GSUP LU request to HLR"); - gsup_expect_tx("04010809710000004026f0280102" VLR_TO_HLR); + gsup_expect_tx("04010809710000004026f0" CN_DOMAIN VLR_TO_HLR); ms_sends_msg("0559094332244332244372f5"); OSMO_ASSERT(gsup_tx_confirmed); VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); @@ -743,7 +742,7 @@ static void test_no_authen_imeisv_tmsi() OSMO_ASSERT(dtap_tx_confirmed); btw("MS replies with an Identity Response, causes LU to commence with a GSUP LU request to HLR"); - gsup_expect_tx("04010809710000004026f0280102" VLR_TO_HLR); + gsup_expect_tx("04010809710000004026f0" CN_DOMAIN VLR_TO_HLR); ms_sends_msg("0559095332244332244372f6"); OSMO_ASSERT(gsup_tx_confirmed); VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); @@ -842,7 +841,7 @@ static void test_no_authen_imeisv_tmsi_imei() btw("HLR accepts the IMEI, VLR responds with LU Request"); expect_bssap_clear(); gsup_rx("32010809710000004026f0510100" HLR_TO_VLR, - "04010809710000004026f0280102" VLR_TO_HLR); + "04010809710000004026f0" CN_DOMAIN VLR_TO_HLR); OSMO_ASSERT(gsup_tx_confirmed); VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); @@ -916,7 +915,7 @@ static void test_no_authen_subscr_expire() btw("Location Update request causes a GSUP LU request to HLR"); lu_result_sent = RES_NONE; - gsup_expect_tx("04010809710000004026f0280102" VLR_TO_HLR); + gsup_expect_tx("04010809710000004026f0" CN_DOMAIN VLR_TO_HLR); ms_sends_msg("050802008168000130089910070000006402"); OSMO_ASSERT(gsup_tx_confirmed); VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); @@ -942,7 +941,7 @@ static void test_no_authen_subscr_expire() vlr_subscr_put(vsub, __func__); /* Let T3212 (periodic Location update timer) expire */ - fake_time_passes((net->t3212 * 60 * 6 * 2) + 60*4, 0); + fake_time_passes(vlr_timer(net->vlr, 3212) + 60 * 4, 0); /* The subscriber should now be gone. */ vsub = vlr_subscr_find_by_imsi(net->vlr, imsi, __func__); diff --git a/tests/msc_vlr/msc_vlr_test_no_authen.err b/tests/msc_vlr/msc_vlr_test_no_authen.err index b6c069854..1cc55de80 100644 --- a/tests/msc_vlr/msc_vlr_test_no_authen.err +++ b/tests/msc_vlr/msc_vlr_test_no_authen.err @@ -1,7 +1,3 @@ -DLMGCP MGCP client: using endpoint domain '@mgw' -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 17 - ===== test_no_authen - Location Update request causes a GSUP LU request to HLR MSC <--GERAN-A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST @@ -30,10 +26,13 @@ DREF VLR subscr IMSI-901700000004620 + active-conn: now used by 2 (_lu_fsm_assoc DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH DREF VLR subscr IMSI-901700000004620 - _lu_fsm_associate_vsub: now used by 1 (active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_post_auth() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_post_ciph() +DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(IMSI-901700000004620:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node_4() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_HLR_UPD DVLR upd_hlr_vlr_fsm(IMSI-901700000004620:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated @@ -168,6 +167,8 @@ DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_VA DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi() DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_node2() DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_ciph() +DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_vlr() DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_post_pres() DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_post_trace() @@ -175,6 +176,7 @@ DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SER DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: proc_arq_fsm_done(PASSED) DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_DONE DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_DONE}: Process Access Request result: PASSED +DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: Sending DTAP: MM GSM48_MT_MM_CM_SERV_ACC DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN encode: DTAP on GERAN-A - DTAP --GERAN-A--> MS: GSM48_MT_MM_CM_SERV_ACC: 0521 DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST @@ -263,7 +265,7 @@ DMSC dummy_msc_i{0}: is child of msub_fsm DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms) DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3 DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: RR GSM48_MT_RR_PAG_RESP -DRR msc_a(IMSI-901700000004620:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: Rx PAGING RESPONSE +DRR msc_a(IMSI-901700000004620:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: Rx PAGING RESPONSE IMSI-901700000004620 DREF msc_a(IMSI-901700000004620:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: + paging-response: now used by 2 (rx_from_ms,paging-response) DVLR Process_Access_Request_VLR(IMSI-901700000004620:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: Allocated DVLR Process_Access_Request_VLR(IMSI-901700000004620:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: is child of msc_a(IMSI-901700000004620:GERAN-A:PAGING_RESP) @@ -276,6 +278,8 @@ DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_VALID DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi() DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_node2() DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_ciph() +DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_vlr() DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_post_pres() DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_post_trace() @@ -294,6 +298,7 @@ DLSMS SMC(0) send CP data DLSMS SMC(0) new CP state MM_CONN_PENDING -> WAIT_CP_ACK DLSMS trans(SMS IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x40000001 tid-0) sending CP message (trans=0) DLSMS trans(SMS IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x40000001 tid-0) GSM4.11 TX 09 01 58 01 00 07 91 44 77 58 10 06 50 00 4c 00 05 80 64 70 f1 00 00 07 10 10 00 00 00 00 44 50 79 da 1e 1e e7 41 69 37 48 5e 9e a7 c9 65 37 3d 1d 66 83 c2 70 38 3b 3d 0e d3 d3 6f f7 1c 94 9e 83 c2 20 72 79 9e 96 87 c5 ec 32 a8 1d 96 af cb f4 b4 fb 0c 7a c3 e9 e9 b7 db 05 +DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: Sending DTAP: SMS SMS:0x01 DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: RAN encode: DTAP on GERAN-A - DTAP --GERAN-A--> MS: SMS:0x01: 09015801000791447758100650004c0005806470f1000007101000000000445079da1e1ee7416937485e9ea7c965373d1d6683c270383b3d0ed3d36ff71c949e83c22072799e9687c5ec32a81d96afcbf4b4fb0c7ac3e9e9b7db05 - DTAP matches expected message @@ -330,6 +335,7 @@ DLSMS SMC(0) message MMSMS-DATA-IND (CP DATA) received in state MM_ESTABLISHED DLSMS SMC(0) received CP-DATA DLSMS trans(SMS IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x40000001 tid-0) sending CP message (trans=0) DLSMS trans(SMS IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x40000001 tid-0) GSM4.11 TX 09 04 +DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: Sending DTAP: SMS SMS:0x04 DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: RAN encode: DTAP on GERAN-A - DTAP --GERAN-A--> MS: SMS:0x04: 0904 - DTAP matches expected message @@ -402,12 +408,13 @@ DMSC dummy_msc_i{0}: is child of msub_fsm DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms) DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3 DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: MM GSM48_MT_MM_IMSI_DETACH_IND -DMM IMSI DETACH INDICATION: MI(IMSI)=901700000004620 +DMM IMSI DETACH INDICATION: IMSI-901700000004620 DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + gsm48_rx_mm_imsi_detach_ind: now used by 2 (attached,gsm48_rx_mm_imsi_detach_ind) DMM IMSI DETACH for IMSI-901700000004620:MSISDN-46071 DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + active-conn: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn) DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn,vlr_subscr_cancel_attach_fsm) DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - attached: now used by 2 (gsm48_rx_mm_imsi_detach_ind,active-conn) DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - gsm48_rx_mm_imsi_detach_ind: now used by 1 (active-conn) DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_CN_CLOSE @@ -447,9 +454,6 @@ DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:NONE){MSC_A_ST_RELEASED}: D llist_count(&msub_list) == 0 ===== test_no_authen: SUCCESS -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 17 - ===== test_no_authen_tmsi - Location Update request causes a GSUP LU request to HLR MSC <--GERAN-A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST @@ -478,10 +482,13 @@ DREF VLR subscr IMSI-901700000004620 + active-conn: now used by 2 (_lu_fsm_assoc DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH DREF VLR subscr IMSI-901700000004620 - _lu_fsm_associate_vsub: now used by 1 (active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_post_auth() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_post_ciph() +DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(IMSI-901700000004620:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node_4() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_HLR_UPD DVLR upd_hlr_vlr_fsm(IMSI-901700000004620:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated @@ -663,6 +670,8 @@ DMSC msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:CM_SERVICE_ DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi() DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_node2() DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_ciph() +DMSC msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_vlr() DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_post_pres() DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_post_trace() @@ -670,6 +679,7 @@ DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:TMSI-0x0302010 DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: proc_arq_fsm_done(PASSED) DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_DONE DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_DONE}: Process Access Request result: PASSED +DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: Sending DTAP: MM GSM48_MT_MM_CM_SERV_ACC DMSC msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN encode: DTAP on GERAN-A - DTAP --GERAN-A--> MS: GSM48_MT_MM_CM_SERV_ACC: 0521 DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST @@ -758,7 +768,7 @@ DMSC dummy_msc_i{0}: is child of msub_fsm DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms) DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3 DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: RR GSM48_MT_RR_PAG_RESP -DRR msc_a(TMSI-0x03020100:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: Rx PAGING RESPONSE +DRR msc_a(TMSI-0x03020100:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: Rx PAGING RESPONSE TMSI-0x03020100 DREF msc_a(TMSI-0x03020100:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: + paging-response: now used by 2 (rx_from_ms,paging-response) DVLR Process_Access_Request_VLR(TMSI-0x03020100:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: Allocated DVLR Process_Access_Request_VLR(TMSI-0x03020100:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: is child of msc_a(TMSI-0x03020100:GERAN-A:PAGING_RESP) @@ -771,6 +781,8 @@ DMSC msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:PAGING_RESP DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi() DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_node2() DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_ciph() +DMSC msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_vlr() DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_post_pres() DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_post_trace() @@ -789,6 +801,7 @@ DLSMS SMC(0) send CP data DLSMS SMC(0) new CP state MM_CONN_PENDING -> WAIT_CP_ACK DLSMS trans(SMS IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:PAGING_RESP callref-0x40000002 tid-0) sending CP message (trans=0) DLSMS trans(SMS IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:PAGING_RESP callref-0x40000002 tid-0) GSM4.11 TX 09 01 58 01 00 07 91 44 77 58 10 06 50 00 4c 00 05 80 64 70 f1 00 00 07 10 10 00 00 00 00 44 50 79 da 1e 1e e7 41 69 37 48 5e 9e a7 c9 65 37 3d 1d 66 83 c2 70 38 3b 3d 0e d3 d3 6f f7 1c 94 9e 83 c2 20 72 79 9e 96 87 c5 ec 32 a8 1d 96 af cb f4 b4 fb 0c 7a c3 e9 e9 b7 db 05 +DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: Sending DTAP: SMS SMS:0x01 DMSC msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: RAN encode: DTAP on GERAN-A - DTAP --GERAN-A--> MS: SMS:0x01: 09015801000791447758100650004c0005806470f1000007101000000000445079da1e1ee7416937485e9ea7c965373d1d6683c270383b3d0ed3d36ff71c949e83c22072799e9687c5ec32a81d96afcbf4b4fb0c7ac3e9e9b7db05 - DTAP matches expected message @@ -825,6 +838,7 @@ DLSMS SMC(0) message MMSMS-DATA-IND (CP DATA) received in state MM_ESTABLISHED DLSMS SMC(0) received CP-DATA DLSMS trans(SMS IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:PAGING_RESP callref-0x40000002 tid-0) sending CP message (trans=0) DLSMS trans(SMS IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:PAGING_RESP callref-0x40000002 tid-0) GSM4.11 TX 09 04 +DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: Sending DTAP: SMS SMS:0x04 DMSC msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: RAN encode: DTAP on GERAN-A - DTAP --GERAN-A--> MS: SMS:0x04: 0904 - DTAP matches expected message @@ -911,10 +925,13 @@ DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100 + active-conn: DMSC msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK DMSC msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100 - _lu_fsm_associate_vsub: now used by 2 (attached,active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre() DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_post_auth() DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_post_ciph() +DMSC msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node_4() DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_HLR_UPD DVLR upd_hlr_vlr_fsm(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated @@ -1082,12 +1099,13 @@ DMSC dummy_msc_i{0}: is child of msub_fsm DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms) DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3 DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: MM GSM48_MT_MM_IMSI_DETACH_IND -DMM IMSI DETACH INDICATION: MI(TMSI)=117835012 +DMM IMSI DETACH INDICATION: TMSI-0x07060504 DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x07060504 + gsm48_rx_mm_imsi_detach_ind: now used by 2 (attached,gsm48_rx_mm_imsi_detach_ind) DMM IMSI DETACH for IMSI-901700000004620:MSISDN-46071:TMSI-0x07060504 DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x07060504 + active-conn: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn) DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x07060504 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn,vlr_subscr_cancel_attach_fsm) DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x07060504 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x07060504 - attached: now used by 2 (gsm48_rx_mm_imsi_detach_ind,active-conn) DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x07060504 - gsm48_rx_mm_imsi_detach_ind: now used by 1 (active-conn) DMSC msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x07060504:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_CN_CLOSE @@ -1127,9 +1145,6 @@ DMSC msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x07060504:GERAN-A:NONE){MSC_A llist_count(&msub_list) == 0 ===== test_no_authen_tmsi: SUCCESS -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 17 - ===== test_no_authen_imei - Location Update request causes a GSUP LU request to HLR MSC <--GERAN-A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST @@ -1158,10 +1173,13 @@ DREF VLR subscr IMSI-901700000004620 + active-conn: now used by 2 (_lu_fsm_assoc DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH DREF VLR subscr IMSI-901700000004620 - _lu_fsm_associate_vsub: now used by 1 (active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_post_auth() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_post_ciph() +DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(IMSI-901700000004620:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node_4() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_HLR_UPD DVLR upd_hlr_vlr_fsm(IMSI-901700000004620:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated @@ -1217,6 +1235,7 @@ DVLR lu_compl_vlr_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){LU_COMPL_VLR DVLR lu_compl_vlr_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES DVLR lu_compl_vlr_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL DVLR lu_compl_vlr_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_WAIT_IMEI +DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: Sending DTAP: MM GSM48_MT_MM_ID_REQ DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: DTAP on GERAN-A - DTAP --GERAN-A--> MS: GSM48_MT_MM_ID_REQ: 051802 - DTAP matches expected message @@ -1252,7 +1271,7 @@ DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: DREF msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: + rx_from_ms: now used by 2 (lu,rx_from_ms) DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN decode: DTAP DRLL msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: Dispatching 04.08 message: MM GSM48_MT_MM_ID_RESP -DMM IDENTITY RESPONSE: MI=IMEI-423423423423420 +DMM IDENTITY RESPONSE: IMEI-423423423423420 DVLR set IMEI on subscriber; IMSI=901700000004620 IMEI=42342342342342 DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_ID_IMEI GSUP --> HLR: OSMO_GSUP_MSGT_CHECK_IMEI_REQUEST: 30010809710000004026f0500807244332244332240a0101 @@ -1332,12 +1351,13 @@ DMSC dummy_msc_i{0}: is child of msub_fsm DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms) DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3 DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: MM GSM48_MT_MM_IMSI_DETACH_IND -DMM IMSI DETACH INDICATION: MI(IMSI)=901700000004620 +DMM IMSI DETACH INDICATION: IMSI-901700000004620 DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + gsm48_rx_mm_imsi_detach_ind: now used by 2 (attached,gsm48_rx_mm_imsi_detach_ind) DMM IMSI DETACH for IMSI-901700000004620:MSISDN-46071 DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + active-conn: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn) DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn,vlr_subscr_cancel_attach_fsm) DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - attached: now used by 2 (gsm48_rx_mm_imsi_detach_ind,active-conn) DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - gsm48_rx_mm_imsi_detach_ind: now used by 1 (active-conn) DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_CN_CLOSE @@ -1377,9 +1397,6 @@ DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:NONE){MSC_A_ST_RELEASED}: D llist_count(&msub_list) == 0 ===== test_no_authen_imei: SUCCESS -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 17 - ===== test_no_authen_tmsi_imei - Location Update request causes a GSUP LU request to HLR MSC <--GERAN-A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST @@ -1408,10 +1425,13 @@ DREF VLR subscr IMSI-901700000004620 + active-conn: now used by 2 (_lu_fsm_assoc DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH DREF VLR subscr IMSI-901700000004620 - _lu_fsm_associate_vsub: now used by 1 (active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_post_auth() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_post_ciph() +DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(IMSI-901700000004620:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node_4() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_HLR_UPD DVLR upd_hlr_vlr_fsm(IMSI-901700000004620:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated @@ -1467,6 +1487,7 @@ DVLR lu_compl_vlr_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){LU_COMPL_VLR DVLR lu_compl_vlr_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES DVLR lu_compl_vlr_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL DVLR lu_compl_vlr_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_WAIT_IMEI_TMSI +DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: Sending DTAP: MM GSM48_MT_MM_ID_REQ DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: DTAP on GERAN-A - DTAP --GERAN-A--> MS: GSM48_MT_MM_ID_REQ: 051802 - DTAP matches expected message @@ -1502,7 +1523,7 @@ DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: DREF msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: + rx_from_ms: now used by 2 (lu,rx_from_ms) DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN decode: DTAP DRLL msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: Dispatching 04.08 message: MM GSM48_MT_MM_ID_RESP -DMM IDENTITY RESPONSE: MI=IMEI-423423423423420 +DMM IDENTITY RESPONSE: IMEI-423423423423420 DVLR set IMEI on subscriber; IMSI=901700000004620 IMEI=42342342342342 DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_ID_IMEI GSUP --> HLR: OSMO_GSUP_MSGT_CHECK_IMEI_REQUEST: 30010809710000004026f0500807244332244332240a0101 @@ -1617,12 +1638,13 @@ DMSC dummy_msc_i{0}: is child of msub_fsm DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms) DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3 DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: MM GSM48_MT_MM_IMSI_DETACH_IND -DMM IMSI DETACH INDICATION: MI(IMSI)=901700000004620 +DMM IMSI DETACH INDICATION: IMSI-901700000004620 DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100 + gsm48_rx_mm_imsi_detach_ind: now used by 2 (attached,gsm48_rx_mm_imsi_detach_ind) DMM IMSI DETACH for IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100 DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100 + active-conn: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn) DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn,vlr_subscr_cancel_attach_fsm) DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100 - attached: now used by 2 (gsm48_rx_mm_imsi_detach_ind,active-conn) DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100 - gsm48_rx_mm_imsi_detach_ind: now used by 1 (active-conn) DMSC msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_CN_CLOSE @@ -1662,9 +1684,6 @@ DMSC msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:NONE){MSC_A llist_count(&msub_list) == 0 ===== test_no_authen_tmsi_imei: SUCCESS -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 17 - ===== test_no_authen_imeisv - Location Update request causes an IMEISV ID request back to the MS MSC <--GERAN-A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST @@ -1693,6 +1712,8 @@ DREF VLR subscr IMSI-901700000004620 + active-conn: now used by 2 (_lu_fsm_assoc DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH DREF VLR subscr IMSI-901700000004620 - _lu_fsm_associate_vsub: now used by 1 (active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) +DBSSAP msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: Sending DTAP: MM GSM48_MT_MM_ID_REQ DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: DTAP on GERAN-A - DTAP --GERAN-A--> MS: GSM48_MT_MM_ID_REQ: 051803 - DTAP matches expected message @@ -1705,7 +1726,7 @@ DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: n DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: + rx_from_ms: now used by 2 (lu,rx_from_ms) DBSSAP msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN decode: DTAP DRLL msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: Dispatching 04.08 message: MM GSM48_MT_MM_ID_RESP -DMM IDENTITY RESPONSE: MI=IMEI-SV-4234234234234275 +DMM IDENTITY RESPONSE: IMEI-SV-4234234234234275 DVLR set IMEISV on subscriber; IMSI=901700000004620 IMEISV=4234234234234275 DVLR set IMEI on subscriber; IMSI=901700000004620 IMEI=42342342342342 DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_IMEISV}: Received Event VLR_ULA_E_ID_IMEISV @@ -1713,6 +1734,8 @@ DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_IMEISV}: vlr_loc DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_IMEISV}: vlr_loc_upd_node1() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_IMEISV}: vlr_loc_upd_post_auth() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_IMEISV}: vlr_loc_upd_post_ciph() +DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(IMSI-901700000004620:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_IMEISV}: vlr_loc_upd_node_4() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_IMEISV}: state_chg to VLR_ULA_S_WAIT_HLR_UPD DVLR upd_hlr_vlr_fsm(IMSI-901700000004620:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated @@ -1837,12 +1860,13 @@ DMSC dummy_msc_i{0}: is child of msub_fsm DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms) DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3 DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: MM GSM48_MT_MM_IMSI_DETACH_IND -DMM IMSI DETACH INDICATION: MI(IMSI)=901700000004620 +DMM IMSI DETACH INDICATION: IMSI-901700000004620 DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + gsm48_rx_mm_imsi_detach_ind: now used by 2 (attached,gsm48_rx_mm_imsi_detach_ind) DMM IMSI DETACH for IMSI-901700000004620:MSISDN-46071 DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + active-conn: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn) DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn,vlr_subscr_cancel_attach_fsm) DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - attached: now used by 2 (gsm48_rx_mm_imsi_detach_ind,active-conn) DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - gsm48_rx_mm_imsi_detach_ind: now used by 1 (active-conn) DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_CN_CLOSE @@ -1882,9 +1906,6 @@ DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:NONE){MSC_A_ST_RELEASED}: D llist_count(&msub_list) == 0 ===== test_no_authen_imeisv: SUCCESS -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 17 - ===== test_no_authen_imeisv_imei - Location Update request causes an IMEISV ID request back to the MS MSC <--GERAN-A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST @@ -1913,6 +1934,8 @@ DREF VLR subscr IMSI-901700000004620 + active-conn: now used by 2 (_lu_fsm_assoc DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH DREF VLR subscr IMSI-901700000004620 - _lu_fsm_associate_vsub: now used by 1 (active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) +DBSSAP msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: Sending DTAP: MM GSM48_MT_MM_ID_REQ DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: DTAP on GERAN-A - DTAP --GERAN-A--> MS: GSM48_MT_MM_ID_REQ: 051803 - DTAP matches expected message @@ -1925,7 +1948,7 @@ DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: n DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: + rx_from_ms: now used by 2 (lu,rx_from_ms) DBSSAP msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN decode: DTAP DRLL msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: Dispatching 04.08 message: MM GSM48_MT_MM_ID_RESP -DMM IDENTITY RESPONSE: MI=IMEI-SV-4234234234234275 +DMM IDENTITY RESPONSE: IMEI-SV-4234234234234275 DVLR set IMEISV on subscriber; IMSI=901700000004620 IMEISV=4234234234234275 DVLR set IMEI on subscriber; IMSI=901700000004620 IMEI=42342342342342 DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_IMEISV}: Received Event VLR_ULA_E_ID_IMEISV @@ -1944,6 +1967,8 @@ DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_HLR_CHECK_IMEI_E DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_HLR_CHECK_IMEI_EARLY}: vlr_loc_upd_node1() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_HLR_CHECK_IMEI_EARLY}: vlr_loc_upd_post_auth() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_HLR_CHECK_IMEI_EARLY}: vlr_loc_upd_post_ciph() +DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(IMSI-901700000004620:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_HLR_CHECK_IMEI_EARLY}: vlr_loc_upd_node_4() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_HLR_CHECK_IMEI_EARLY}: state_chg to VLR_ULA_S_WAIT_HLR_UPD DVLR upd_hlr_vlr_fsm(IMSI-901700000004620:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated @@ -2068,12 +2093,13 @@ DMSC dummy_msc_i{0}: is child of msub_fsm DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms) DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3 DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: MM GSM48_MT_MM_IMSI_DETACH_IND -DMM IMSI DETACH INDICATION: MI(IMSI)=901700000004620 +DMM IMSI DETACH INDICATION: IMSI-901700000004620 DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + gsm48_rx_mm_imsi_detach_ind: now used by 2 (attached,gsm48_rx_mm_imsi_detach_ind) DMM IMSI DETACH for IMSI-901700000004620:MSISDN-46071 DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + active-conn: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn) DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn,vlr_subscr_cancel_attach_fsm) DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - attached: now used by 2 (gsm48_rx_mm_imsi_detach_ind,active-conn) DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - gsm48_rx_mm_imsi_detach_ind: now used by 1 (active-conn) DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_CN_CLOSE @@ -2113,9 +2139,6 @@ DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:NONE){MSC_A_ST_RELEASED}: D llist_count(&msub_list) == 0 ===== test_no_authen_imeisv_imei: SUCCESS -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 17 - ===== test_no_authen_imeisv_tmsi - Location Update request causes an IMEISV ID request back to the MS MSC <--GERAN-A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST @@ -2144,6 +2167,8 @@ DREF VLR subscr IMSI-901700000004620 + active-conn: now used by 2 (_lu_fsm_assoc DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH DREF VLR subscr IMSI-901700000004620 - _lu_fsm_associate_vsub: now used by 1 (active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) +DBSSAP msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: Sending DTAP: MM GSM48_MT_MM_ID_REQ DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: DTAP on GERAN-A - DTAP --GERAN-A--> MS: GSM48_MT_MM_ID_REQ: 051803 - DTAP matches expected message @@ -2156,7 +2181,7 @@ DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: n DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: + rx_from_ms: now used by 2 (lu,rx_from_ms) DBSSAP msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN decode: DTAP DRLL msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: Dispatching 04.08 message: MM GSM48_MT_MM_ID_RESP -DMM IDENTITY RESPONSE: MI=IMEI-SV-4234234234234275 +DMM IDENTITY RESPONSE: IMEI-SV-4234234234234275 DVLR set IMEISV on subscriber; IMSI=901700000004620 IMEISV=4234234234234275 DVLR set IMEI on subscriber; IMSI=901700000004620 IMEI=42342342342342 DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_IMEISV}: Received Event VLR_ULA_E_ID_IMEISV @@ -2164,6 +2189,8 @@ DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_IMEISV}: vlr_loc DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_IMEISV}: vlr_loc_upd_node1() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_IMEISV}: vlr_loc_upd_post_auth() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_IMEISV}: vlr_loc_upd_post_ciph() +DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(IMSI-901700000004620:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_IMEISV}: vlr_loc_upd_node_4() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_IMEISV}: state_chg to VLR_ULA_S_WAIT_HLR_UPD DVLR upd_hlr_vlr_fsm(IMSI-901700000004620:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated @@ -2342,6 +2369,8 @@ DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100 + active-conn: DMSC msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK DMSC msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100 - _lu_fsm_associate_vsub: now used by 2 (attached,active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) +DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: Sending DTAP: MM GSM48_MT_MM_ID_REQ DMSC msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: DTAP on GERAN-A - DTAP --GERAN-A--> MS: GSM48_MT_MM_ID_REQ: 051803 - DTAP matches expected message @@ -2354,7 +2383,7 @@ DREF msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:LU){MSC_A_S DREF msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: + rx_from_ms: now used by 2 (lu,rx_from_ms) DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN decode: DTAP DRLL msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: Dispatching 04.08 message: MM GSM48_MT_MM_ID_RESP -DMM IDENTITY RESPONSE: MI=IMEI-SV-5234234234234276 +DMM IDENTITY RESPONSE: IMEI-SV-5234234234234276 DVLR set IMEISV on subscriber; IMSI=901700000004620 IMEISV=5234234234234276 DVLR set IMEI on subscriber; IMSI=901700000004620 IMEI=52342342342342 DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:LU){VLR_ULA_S_WAIT_IMEISV}: Received Event VLR_ULA_E_ID_IMEISV @@ -2362,6 +2391,8 @@ DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:LU){VL DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:LU){VLR_ULA_S_WAIT_IMEISV}: vlr_loc_upd_node1() DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:LU){VLR_ULA_S_WAIT_IMEISV}: vlr_loc_upd_post_auth() DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:LU){VLR_ULA_S_WAIT_IMEISV}: vlr_loc_upd_post_ciph() +DMSC msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:LU){VLR_ULA_S_WAIT_IMEISV}: vlr_loc_upd_node_4() DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:LU){VLR_ULA_S_WAIT_IMEISV}: state_chg to VLR_ULA_S_WAIT_HLR_UPD DVLR upd_hlr_vlr_fsm(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated @@ -2532,12 +2563,13 @@ DMSC dummy_msc_i{0}: is child of msub_fsm DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms) DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3 DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: MM GSM48_MT_MM_IMSI_DETACH_IND -DMM IMSI DETACH INDICATION: MI(TMSI)=117835012 +DMM IMSI DETACH INDICATION: TMSI-0x07060504 DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x07060504 + gsm48_rx_mm_imsi_detach_ind: now used by 2 (attached,gsm48_rx_mm_imsi_detach_ind) DMM IMSI DETACH for IMSI-901700000004620:MSISDN-46071:TMSI-0x07060504 DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x07060504 + active-conn: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn) DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x07060504 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn,vlr_subscr_cancel_attach_fsm) DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x07060504 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x07060504 - attached: now used by 2 (gsm48_rx_mm_imsi_detach_ind,active-conn) DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x07060504 - gsm48_rx_mm_imsi_detach_ind: now used by 1 (active-conn) DMSC msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x07060504:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_CN_CLOSE @@ -2577,9 +2609,6 @@ DMSC msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x07060504:GERAN-A:NONE){MSC_A llist_count(&msub_list) == 0 ===== test_no_authen_imeisv_tmsi: SUCCESS -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 17 - ===== test_no_authen_imeisv_tmsi_imei - Location Update request causes an IMEISV ID request back to the MS MSC <--GERAN-A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST @@ -2608,6 +2637,8 @@ DREF VLR subscr IMSI-901700000004620 + active-conn: now used by 2 (_lu_fsm_assoc DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH DREF VLR subscr IMSI-901700000004620 - _lu_fsm_associate_vsub: now used by 1 (active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) +DBSSAP msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: Sending DTAP: MM GSM48_MT_MM_ID_REQ DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: DTAP on GERAN-A - DTAP --GERAN-A--> MS: GSM48_MT_MM_ID_REQ: 051803 - DTAP matches expected message @@ -2620,7 +2651,7 @@ DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: n DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: + rx_from_ms: now used by 2 (lu,rx_from_ms) DBSSAP msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN decode: DTAP DRLL msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: Dispatching 04.08 message: MM GSM48_MT_MM_ID_RESP -DMM IDENTITY RESPONSE: MI=IMEI-SV-4234234234234275 +DMM IDENTITY RESPONSE: IMEI-SV-4234234234234275 DVLR set IMEISV on subscriber; IMSI=901700000004620 IMEISV=4234234234234275 DVLR set IMEI on subscriber; IMSI=901700000004620 IMEI=42342342342342 DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_IMEISV}: Received Event VLR_ULA_E_ID_IMEISV @@ -2639,6 +2670,8 @@ DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_HLR_CHECK_IMEI_E DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_HLR_CHECK_IMEI_EARLY}: vlr_loc_upd_node1() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_HLR_CHECK_IMEI_EARLY}: vlr_loc_upd_post_auth() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_HLR_CHECK_IMEI_EARLY}: vlr_loc_upd_post_ciph() +DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(IMSI-901700000004620:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_HLR_CHECK_IMEI_EARLY}: vlr_loc_upd_node_4() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_HLR_CHECK_IMEI_EARLY}: state_chg to VLR_ULA_S_WAIT_HLR_UPD DVLR upd_hlr_vlr_fsm(IMSI-901700000004620:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated @@ -2800,12 +2833,13 @@ DMSC dummy_msc_i{0}: is child of msub_fsm DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms) DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3 DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: MM GSM48_MT_MM_IMSI_DETACH_IND -DMM IMSI DETACH INDICATION: MI(IMSI)=901700000004620 +DMM IMSI DETACH INDICATION: IMSI-901700000004620 DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100 + gsm48_rx_mm_imsi_detach_ind: now used by 2 (attached,gsm48_rx_mm_imsi_detach_ind) DMM IMSI DETACH for IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100 DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100 + active-conn: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn) DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn,vlr_subscr_cancel_attach_fsm) DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100 - attached: now used by 2 (gsm48_rx_mm_imsi_detach_ind,active-conn) DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100 - gsm48_rx_mm_imsi_detach_ind: now used by 1 (active-conn) DMSC msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_CN_CLOSE @@ -2845,9 +2879,6 @@ DMSC msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:NONE){MSC_A llist_count(&msub_list) == 0 ===== test_no_authen_imeisv_tmsi_imei: SUCCESS -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 17 - ===== test_no_authen_subscr_expire - Total time passed: 0.000000 s - Total time passed: 61.000000 s @@ -2878,10 +2909,13 @@ DREF VLR subscr IMSI-901700000004620 + active-conn: now used by 2 (_lu_fsm_assoc DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH DREF VLR subscr IMSI-901700000004620 - _lu_fsm_associate_vsub: now used by 1 (active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_post_auth() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_post_ciph() +DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(IMSI-901700000004620:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node_4() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_HLR_UPD DVLR upd_hlr_vlr_fsm(IMSI-901700000004620:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated @@ -2975,14 +3009,9 @@ DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - test_no_authen_subscr_expire DVLR IMSI-901700000004620:MSISDN-46071: Location Update expired DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + vlr_subscr_cancel_attach_fsm: now used by 2 (attached,vlr_subscr_cancel_attach_fsm) DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - vlr_subscr_cancel_attach_fsm: now used by 1 (attached) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - attached: now used by 0 (-) DVLR freeing VLR subscr IMSI-901700000004620:MSISDN-46071 (max total use count was 5) llist_count(&msub_list) == 0 ===== test_no_authen_subscr_expire: SUCCESS -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 17 - -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 17 - diff --git a/tests/msc_vlr/msc_vlr_test_reject_concurrency.c b/tests/msc_vlr/msc_vlr_test_reject_concurrency.c index 7eaedb27c..dea0c291b 100644 --- a/tests/msc_vlr/msc_vlr_test_reject_concurrency.c +++ b/tests/msc_vlr/msc_vlr_test_reject_concurrency.c @@ -22,7 +22,6 @@ */ #include "msc_vlr_tests.h" -#include "stubs.h" static void test_reject_2nd_conn() { @@ -31,7 +30,7 @@ static void test_reject_2nd_conn() btw("Location Update Request on one connection"); lu_result_sent = RES_NONE; - gsup_expect_tx("04010809710000004026f0280102" VLR_TO_HLR); + gsup_expect_tx("04010809710000004026f0" CN_DOMAIN VLR_TO_HLR); ms_sends_msg("050802008168000130089910070000006402"); OSMO_ASSERT(gsup_tx_confirmed); VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); @@ -74,7 +73,7 @@ static void _normal_lu_part1() { btw("Location Update Request"); lu_result_sent = RES_NONE; - gsup_expect_tx("04010809710000004026f0280102" VLR_TO_HLR); + gsup_expect_tx("04010809710000004026f0" CN_DOMAIN VLR_TO_HLR); ms_sends_msg("050802008168000130089910070000006402"); OSMO_ASSERT(gsup_tx_confirmed); VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); @@ -309,7 +308,7 @@ static void test_reject_paging_resp_during_cm() BTW("The original CM Service Request can conclude"); /* Release connection */ - expect_bssap_clear(OSMO_RAT_GERAN_A); + expect_bssap_clear(); conn_conclude_cm_service_req(g_msub, MSC_A_USE_CM_SERVICE_SMS); btw("all requests serviced, conn has been released"); diff --git a/tests/msc_vlr/msc_vlr_test_reject_concurrency.err b/tests/msc_vlr/msc_vlr_test_reject_concurrency.err index e1df2db14..25ccdfb64 100644 --- a/tests/msc_vlr/msc_vlr_test_reject_concurrency.err +++ b/tests/msc_vlr/msc_vlr_test_reject_concurrency.err @@ -1,7 +1,3 @@ -DLMGCP MGCP client: using endpoint domain '@mgw' -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 17 - ===== test_reject_2nd_conn - Location Update Request on one connection MSC <--GERAN-A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST @@ -30,10 +26,13 @@ DREF VLR subscr IMSI-901700000004620 + active-conn: now used by 2 (_lu_fsm_assoc DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH DREF VLR subscr IMSI-901700000004620 - _lu_fsm_associate_vsub: now used by 1 (active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_post_auth() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_post_ciph() +DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(IMSI-901700000004620:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node_4() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_HLR_UPD DVLR upd_hlr_vlr_fsm(IMSI-901700000004620:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated @@ -189,9 +188,6 @@ DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_RELEASED}: Dea DVLR freeing VLR subscr IMSI-901700000004620:MSISDN-46071 (max total use count was 5) ===== test_reject_2nd_conn: SUCCESS -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 17 - ===== test_reject_lu_during_lu - Location Update Request MSC <--GERAN-A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST @@ -220,10 +216,13 @@ DREF VLR subscr IMSI-901700000004620 + active-conn: now used by 2 (_lu_fsm_assoc DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH DREF VLR subscr IMSI-901700000004620 - _lu_fsm_associate_vsub: now used by 1 (active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_post_auth() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_post_ciph() +DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(IMSI-901700000004620:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node_4() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_HLR_UPD DVLR upd_hlr_vlr_fsm(IMSI-901700000004620:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated @@ -330,9 +329,6 @@ DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_RELEASED}: Dea DVLR freeing VLR subscr IMSI-901700000004620:MSISDN-46071 (max total use count was 5) ===== test_reject_lu_during_lu: SUCCESS -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 17 - ===== test_reject_cm_during_lu - Location Update Request MSC <--GERAN-A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST @@ -361,10 +357,13 @@ DREF VLR subscr IMSI-901700000004620 + active-conn: now used by 2 (_lu_fsm_assoc DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH DREF VLR subscr IMSI-901700000004620 - _lu_fsm_associate_vsub: now used by 1 (active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_post_auth() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_post_ciph() +DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(IMSI-901700000004620:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node_4() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_HLR_UPD DVLR upd_hlr_vlr_fsm(IMSI-901700000004620:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated @@ -385,6 +384,7 @@ DBSSAP msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN decode: D DRLL msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: Dispatching 04.08 message: MM GSM48_MT_MM_CM_SERV_REQ DBSSAP msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: Cannot accept CM Service Request, conn already busy establishing authenticity DMM msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: -> CM SERVICE Reject cause: 22 +DBSSAP msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: Sending DTAP: MM GSM48_MT_MM_CM_SERV_REJ DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: DTAP on GERAN-A - DTAP --GERAN-A--> MS: GSM48_MT_MM_CM_SERV_REJ: 052216 DMSC dummy_msc_i(IMSI-901700000004620:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST @@ -475,9 +475,6 @@ DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_RELEASED}: Dea DVLR freeing VLR subscr IMSI-901700000004620:MSISDN-46071 (max total use count was 5) ===== test_reject_cm_during_lu: SUCCESS -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 17 - ===== test_reject_paging_resp_during_lu - Location Update Request MSC <--GERAN-A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST @@ -506,10 +503,13 @@ DREF VLR subscr IMSI-901700000004620 + active-conn: now used by 2 (_lu_fsm_assoc DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH DREF VLR subscr IMSI-901700000004620 - _lu_fsm_associate_vsub: now used by 1 (active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_post_auth() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_post_ciph() +DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(IMSI-901700000004620:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node_4() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_HLR_UPD DVLR upd_hlr_vlr_fsm(IMSI-901700000004620:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated @@ -528,7 +528,7 @@ DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: n DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: + rx_from_ms: now used by 2 (lu,rx_from_ms) DBSSAP msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN decode: DTAP DRLL msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: Dispatching 04.08 message: RR GSM48_MT_RR_PAG_RESP -DMM msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: Ignoring Paging Response, conn already busy establishing authenticity +DRR msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: Ignoring Paging Response, conn already busy establishing authenticity DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu) lu_result_sent == 0 llist_count(&msub_list) == 1 @@ -615,9 +615,6 @@ DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_RELEASED}: Dea DVLR freeing VLR subscr IMSI-901700000004620:MSISDN-46071 (max total use count was 5) ===== test_reject_paging_resp_during_lu: SUCCESS -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 17 - ===== test_reject_lu_during_cm @@ -649,10 +646,13 @@ DREF VLR subscr IMSI-901700000004620 + active-conn: now used by 2 (_lu_fsm_assoc DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH DREF VLR subscr IMSI-901700000004620 - _lu_fsm_associate_vsub: now used by 1 (active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_post_auth() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_post_ciph() +DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(IMSI-901700000004620:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node_4() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_HLR_UPD DVLR upd_hlr_vlr_fsm(IMSI-901700000004620:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated @@ -768,6 +768,8 @@ DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_VA DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi() DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_node2() DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_ciph() +DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_vlr() DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_post_pres() DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_post_trace() @@ -775,6 +777,7 @@ DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SER DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: proc_arq_fsm_done(PASSED) DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_DONE DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_DONE}: Process Access Request result: PASSED +DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: Sending DTAP: MM GSM48_MT_MM_CM_SERV_ACC DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN encode: DTAP on GERAN-A - DTAP --GERAN-A--> MS: GSM48_MT_MM_CM_SERV_ACC: 0521 DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST @@ -801,11 +804,12 @@ DREF msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AU DREF msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: + rx_from_ms: now used by 2 (cm_service_sms,rx_from_ms) DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: RAN decode: DTAP DRLL msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: Dispatching 04.08 message: MM GSM48_MT_MM_IMSI_DETACH_IND -DMM IMSI DETACH INDICATION: MI(IMSI)=901700000004620 +DMM IMSI DETACH INDICATION: IMSI-901700000004620 DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + gsm48_rx_mm_imsi_detach_ind: now used by 3 (attached,active-conn,gsm48_rx_mm_imsi_detach_ind) DMM IMSI DETACH for IMSI-901700000004620:MSISDN-46071 DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,active-conn,gsm48_rx_mm_imsi_detach_ind,vlr_subscr_cancel_attach_fsm) DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,active-conn,gsm48_rx_mm_imsi_detach_ind) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - attached: now used by 2 (active-conn,gsm48_rx_mm_imsi_detach_ind) DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - gsm48_rx_mm_imsi_detach_ind: now used by 1 (active-conn) DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: Received Event MSC_A_EV_CN_CLOSE @@ -850,9 +854,6 @@ DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RE llist_count(&msub_list) == 0 ===== test_reject_lu_during_cm: SUCCESS -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 17 - ===== test_reject_cm_during_cm @@ -884,10 +885,13 @@ DREF VLR subscr IMSI-901700000004620 + active-conn: now used by 2 (_lu_fsm_assoc DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH DREF VLR subscr IMSI-901700000004620 - _lu_fsm_associate_vsub: now used by 1 (active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_post_auth() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_post_ciph() +DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(IMSI-901700000004620:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node_4() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_HLR_UPD DVLR upd_hlr_vlr_fsm(IMSI-901700000004620:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated @@ -1003,6 +1007,8 @@ DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_VA DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi() DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_node2() DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_ciph() +DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_vlr() DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_post_pres() DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_post_trace() @@ -1010,6 +1016,7 @@ DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SER DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: proc_arq_fsm_done(PASSED) DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_DONE DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_DONE}: Process Access Request result: PASSED +DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: Sending DTAP: MM GSM48_MT_MM_CM_SERV_ACC DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN encode: DTAP on GERAN-A - DTAP --GERAN-A--> MS: GSM48_MT_MM_CM_SERV_ACC: 0521 DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST @@ -1025,8 +1032,9 @@ DREF msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AU DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: RAN decode: DTAP DRLL msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: Dispatching 04.08 message: MM GSM48_MT_MM_CM_SERV_REQ DMM msc_a(IMSI-901700000004620:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: Rx CM SERVICE REQUEST cm_service_type=Short-Messaging-Service -DMM msc_a(IMSI-901700000004620:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: re-using already accepted connection DREF msc_a(IMSI-901700000004620:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: + cm_service_sms: now used by 3 (2*cm_service_sms,rx_from_ms) +DMM msc_a(IMSI-901700000004620:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: re-using already accepted connection +DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: Sending DTAP: MM GSM48_MT_MM_CM_SERV_ACC DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: RAN encode: DTAP on GERAN-A - DTAP --GERAN-A--> MS: GSM48_MT_MM_CM_SERV_ACC: 0521 DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST @@ -1040,11 +1048,12 @@ DREF msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AU DREF msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: + rx_from_ms: now used by 3 (2*cm_service_sms,rx_from_ms) DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: RAN decode: DTAP DRLL msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: Dispatching 04.08 message: MM GSM48_MT_MM_IMSI_DETACH_IND -DMM IMSI DETACH INDICATION: MI(IMSI)=901700000004620 +DMM IMSI DETACH INDICATION: IMSI-901700000004620 DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + gsm48_rx_mm_imsi_detach_ind: now used by 3 (attached,active-conn,gsm48_rx_mm_imsi_detach_ind) DMM IMSI DETACH for IMSI-901700000004620:MSISDN-46071 DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,active-conn,gsm48_rx_mm_imsi_detach_ind,vlr_subscr_cancel_attach_fsm) DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,active-conn,gsm48_rx_mm_imsi_detach_ind) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - attached: now used by 2 (active-conn,gsm48_rx_mm_imsi_detach_ind) DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - gsm48_rx_mm_imsi_detach_ind: now used by 1 (active-conn) DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: Received Event MSC_A_EV_CN_CLOSE @@ -1089,9 +1098,6 @@ DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RE llist_count(&msub_list) == 0 ===== test_reject_cm_during_cm: SUCCESS -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 17 - ===== test_reject_paging_resp_during_cm @@ -1123,10 +1129,13 @@ DREF VLR subscr IMSI-901700000004620 + active-conn: now used by 2 (_lu_fsm_assoc DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH DREF VLR subscr IMSI-901700000004620 - _lu_fsm_associate_vsub: now used by 1 (active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_post_auth() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_post_ciph() +DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(IMSI-901700000004620:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node_4() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_HLR_UPD DVLR upd_hlr_vlr_fsm(IMSI-901700000004620:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated @@ -1242,6 +1251,8 @@ DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_VA DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi() DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_node2() DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_ciph() +DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_vlr() DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_post_pres() DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_post_trace() @@ -1249,6 +1260,7 @@ DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SER DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: proc_arq_fsm_done(PASSED) DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_DONE DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_DONE}: Process Access Request result: PASSED +DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: Sending DTAP: MM GSM48_MT_MM_CM_SERV_ACC DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN encode: DTAP on GERAN-A - DTAP --GERAN-A--> MS: GSM48_MT_MM_CM_SERV_ACC: 0521 DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST @@ -1265,7 +1277,7 @@ msc_a_is_accepted() == true DREF msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: + rx_from_ms: now used by 2 (cm_service_sms,rx_from_ms) DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: RAN decode: DTAP DRLL msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: Dispatching 04.08 message: RR GSM48_MT_RR_PAG_RESP -DMM msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: Ignoring Paging Response, conn already established +DRR msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: Ignoring Paging Response, conn already established DREF msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: - rx_from_ms: now used by 1 (cm_service_sms) llist_count(&msub_list) == 1 @@ -1313,9 +1325,6 @@ DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RE DVLR freeing VLR subscr IMSI-901700000004620:MSISDN-46071 (max total use count was 5) ===== test_reject_paging_resp_during_cm: SUCCESS -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 17 - ===== test_reject_lu_during_paging_resp @@ -1347,10 +1356,13 @@ DREF VLR subscr IMSI-901700000004620 + active-conn: now used by 2 (_lu_fsm_assoc DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH DREF VLR subscr IMSI-901700000004620 - _lu_fsm_associate_vsub: now used by 1 (active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_post_auth() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_post_ciph() +DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(IMSI-901700000004620:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node_4() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_HLR_UPD DVLR upd_hlr_vlr_fsm(IMSI-901700000004620:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated @@ -1475,7 +1487,7 @@ DMSC dummy_msc_i{0}: is child of msub_fsm DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms) DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3 DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: RR GSM48_MT_RR_PAG_RESP -DRR msc_a(IMSI-901700000004620:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: Rx PAGING RESPONSE +DRR msc_a(IMSI-901700000004620:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: Rx PAGING RESPONSE IMSI-901700000004620 DREF msc_a(IMSI-901700000004620:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: + paging-response: now used by 2 (rx_from_ms,paging-response) DVLR Process_Access_Request_VLR(IMSI-901700000004620:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: Allocated DVLR Process_Access_Request_VLR(IMSI-901700000004620:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: is child of msc_a(IMSI-901700000004620:GERAN-A:PAGING_RESP) @@ -1488,6 +1500,8 @@ DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_VALID DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi() DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_node2() DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_ciph() +DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_vlr() DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_post_pres() DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_post_trace() @@ -1506,6 +1520,7 @@ DLSMS SMC(0) send CP data DLSMS SMC(0) new CP state MM_CONN_PENDING -> WAIT_CP_ACK DLSMS trans(SMS IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x40000001 tid-0) sending CP message (trans=0) DLSMS trans(SMS IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x40000001 tid-0) GSM4.11 TX 09 01 58 01 00 07 91 44 77 58 10 06 50 00 4c 00 05 80 64 70 f1 00 00 07 10 10 00 00 00 00 44 50 79 da 1e 1e e7 41 69 37 48 5e 9e a7 c9 65 37 3d 1d 66 83 c2 70 38 3b 3d 0e d3 d3 6f f7 1c 94 9e 83 c2 20 72 79 9e 96 87 c5 ec 32 a8 1d 96 af cb f4 b4 fb 0c 7a c3 e9 e9 b7 db 05 +DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: Sending DTAP: SMS SMS:0x01 DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: RAN encode: DTAP on GERAN-A - DTAP --GERAN-A--> MS: SMS:0x01: 09015801000791447758100650004c0005806470f1000007101000000000445079da1e1ee7416937485e9ea7c965373d1d6683c270383b3d0ed3d36ff71c949e83c22072799e9687c5ec32a81d96afcbf4b4fb0c7ac3e9e9b7db05 - DTAP matches expected message @@ -1550,6 +1565,7 @@ DLSMS SMC(0) message MMSMS-DATA-IND (CP DATA) received in state MM_ESTABLISHED DLSMS SMC(0) received CP-DATA DLSMS trans(SMS IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x40000001 tid-0) sending CP message (trans=0) DLSMS trans(SMS IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x40000001 tid-0) GSM4.11 TX 09 04 +DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: Sending DTAP: SMS SMS:0x04 DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: RAN encode: DTAP on GERAN-A - DTAP --GERAN-A--> MS: SMS:0x04: 0904 - DTAP matches expected message @@ -1611,9 +1627,6 @@ DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEA DVLR freeing VLR subscr IMSI-901700000004620:MSISDN-46071 (max total use count was 6) ===== test_reject_lu_during_paging_resp: SUCCESS -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 17 - ===== test_accept_cm_during_paging_resp @@ -1645,10 +1658,13 @@ DREF VLR subscr IMSI-901700000004620 + active-conn: now used by 2 (_lu_fsm_assoc DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH DREF VLR subscr IMSI-901700000004620 - _lu_fsm_associate_vsub: now used by 1 (active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_post_auth() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_post_ciph() +DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(IMSI-901700000004620:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node_4() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_HLR_UPD DVLR upd_hlr_vlr_fsm(IMSI-901700000004620:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated @@ -1773,7 +1789,7 @@ DMSC dummy_msc_i{0}: is child of msub_fsm DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms) DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3 DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: RR GSM48_MT_RR_PAG_RESP -DRR msc_a(IMSI-901700000004620:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: Rx PAGING RESPONSE +DRR msc_a(IMSI-901700000004620:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: Rx PAGING RESPONSE IMSI-901700000004620 DREF msc_a(IMSI-901700000004620:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: + paging-response: now used by 2 (rx_from_ms,paging-response) DVLR Process_Access_Request_VLR(IMSI-901700000004620:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: Allocated DVLR Process_Access_Request_VLR(IMSI-901700000004620:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: is child of msc_a(IMSI-901700000004620:GERAN-A:PAGING_RESP) @@ -1786,6 +1802,8 @@ DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_VALID DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi() DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_node2() DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_ciph() +DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_vlr() DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_post_pres() DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_post_trace() @@ -1804,6 +1822,7 @@ DLSMS SMC(0) send CP data DLSMS SMC(0) new CP state MM_CONN_PENDING -> WAIT_CP_ACK DLSMS trans(SMS IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x40000002 tid-0) sending CP message (trans=0) DLSMS trans(SMS IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x40000002 tid-0) GSM4.11 TX 09 01 58 01 00 07 91 44 77 58 10 06 50 00 4c 00 05 80 64 70 f1 00 00 07 10 10 00 00 00 00 44 50 79 da 1e 1e e7 41 69 37 48 5e 9e a7 c9 65 37 3d 1d 66 83 c2 70 38 3b 3d 0e d3 d3 6f f7 1c 94 9e 83 c2 20 72 79 9e 96 87 c5 ec 32 a8 1d 96 af cb f4 b4 fb 0c 7a c3 e9 e9 b7 db 05 +DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: Sending DTAP: SMS SMS:0x01 DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: RAN encode: DTAP on GERAN-A - DTAP --GERAN-A--> MS: SMS:0x01: 09015801000791447758100650004c0005806470f1000007101000000000445079da1e1ee7416937485e9ea7c965373d1d6683c270383b3d0ed3d36ff71c949e83c22072799e9687c5ec32a81d96afcbf4b4fb0c7ac3e9e9b7db05 - DTAP matches expected message @@ -1823,8 +1842,9 @@ DREF msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHE DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: RAN decode: DTAP DRLL msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: Dispatching 04.08 message: MM GSM48_MT_MM_CM_SERV_REQ DMM msc_a(IMSI-901700000004620:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: Rx CM SERVICE REQUEST cm_service_type=Short-Messaging-Service -DMM msc_a(IMSI-901700000004620:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: re-using already accepted connection DREF msc_a(IMSI-901700000004620:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: + cm_service_sms: now used by 3 (sms,rx_from_ms,cm_service_sms) +DMM msc_a(IMSI-901700000004620:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: re-using already accepted connection +DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: Sending DTAP: MM GSM48_MT_MM_CM_SERV_ACC DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: RAN encode: DTAP on GERAN-A - DTAP --GERAN-A--> MS: GSM48_MT_MM_CM_SERV_ACC: 0521 DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST @@ -1853,6 +1873,7 @@ DLSMS SMC(0) message MMSMS-DATA-IND (CP DATA) received in state MM_ESTABLISHED DLSMS SMC(0) received CP-DATA DLSMS trans(SMS IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x40000002 tid-0) sending CP message (trans=0) DLSMS trans(SMS IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x40000002 tid-0) GSM4.11 TX 09 04 +DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: Sending DTAP: SMS SMS:0x04 DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: RAN encode: DTAP on GERAN-A - DTAP --GERAN-A--> MS: SMS:0x04: 0904 - DTAP matches expected message @@ -1883,11 +1904,12 @@ DREF msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AU DREF msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: + rx_from_ms: now used by 2 (cm_service_sms,rx_from_ms) DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: RAN decode: DTAP DRLL msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: Dispatching 04.08 message: MM GSM48_MT_MM_IMSI_DETACH_IND -DMM IMSI DETACH INDICATION: MI(IMSI)=901700000004620 +DMM IMSI DETACH INDICATION: IMSI-901700000004620 DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + gsm48_rx_mm_imsi_detach_ind: now used by 3 (attached,active-conn,gsm48_rx_mm_imsi_detach_ind) DMM IMSI DETACH for IMSI-901700000004620:MSISDN-46071 DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,active-conn,gsm48_rx_mm_imsi_detach_ind,vlr_subscr_cancel_attach_fsm) DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,active-conn,gsm48_rx_mm_imsi_detach_ind) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - attached: now used by 2 (active-conn,gsm48_rx_mm_imsi_detach_ind) DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - gsm48_rx_mm_imsi_detach_ind: now used by 1 (active-conn) DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: Received Event MSC_A_EV_CN_CLOSE @@ -1932,9 +1954,6 @@ DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RE llist_count(&msub_list) == 0 ===== test_accept_cm_during_paging_resp: SUCCESS -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 17 - ===== test_reject_paging_resp_during_paging_resp @@ -1966,10 +1985,13 @@ DREF VLR subscr IMSI-901700000004620 + active-conn: now used by 2 (_lu_fsm_assoc DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH DREF VLR subscr IMSI-901700000004620 - _lu_fsm_associate_vsub: now used by 1 (active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_post_auth() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_post_ciph() +DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(IMSI-901700000004620:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node_4() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_HLR_UPD DVLR upd_hlr_vlr_fsm(IMSI-901700000004620:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated @@ -2094,7 +2116,7 @@ DMSC dummy_msc_i{0}: is child of msub_fsm DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms) DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3 DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: RR GSM48_MT_RR_PAG_RESP -DRR msc_a(IMSI-901700000004620:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: Rx PAGING RESPONSE +DRR msc_a(IMSI-901700000004620:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: Rx PAGING RESPONSE IMSI-901700000004620 DREF msc_a(IMSI-901700000004620:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: + paging-response: now used by 2 (rx_from_ms,paging-response) DVLR Process_Access_Request_VLR(IMSI-901700000004620:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: Allocated DVLR Process_Access_Request_VLR(IMSI-901700000004620:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: is child of msc_a(IMSI-901700000004620:GERAN-A:PAGING_RESP) @@ -2107,6 +2129,8 @@ DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_VALID DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi() DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_node2() DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_ciph() +DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_vlr() DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_post_pres() DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_post_trace() @@ -2125,6 +2149,7 @@ DLSMS SMC(0) send CP data DLSMS SMC(0) new CP state MM_CONN_PENDING -> WAIT_CP_ACK DLSMS trans(SMS IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x40000003 tid-0) sending CP message (trans=0) DLSMS trans(SMS IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x40000003 tid-0) GSM4.11 TX 09 01 58 01 00 07 91 44 77 58 10 06 50 00 4c 00 05 80 64 70 f1 00 00 07 10 10 00 00 00 00 44 50 79 da 1e 1e e7 41 69 37 48 5e 9e a7 c9 65 37 3d 1d 66 83 c2 70 38 3b 3d 0e d3 d3 6f f7 1c 94 9e 83 c2 20 72 79 9e 96 87 c5 ec 32 a8 1d 96 af cb f4 b4 fb 0c 7a c3 e9 e9 b7 db 05 +DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: Sending DTAP: SMS SMS:0x01 DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: RAN encode: DTAP on GERAN-A - DTAP --GERAN-A--> MS: SMS:0x01: 09015801000791447758100650004c0005806470f1000007101000000000445079da1e1ee7416937485e9ea7c965373d1d6683c270383b3d0ed3d36ff71c949e83c22072799e9687c5ec32a81d96afcbf4b4fb0c7ac3e9e9b7db05 - DTAP matches expected message @@ -2143,7 +2168,7 @@ DREF msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHE DREF msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: + rx_from_ms: now used by 2 (sms,rx_from_ms) DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: RAN decode: DTAP DRLL msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: Dispatching 04.08 message: RR GSM48_MT_RR_PAG_RESP -DMM msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: Ignoring Paging Response, conn already established +DRR msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: Ignoring Paging Response, conn already established DREF msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: - rx_from_ms: now used by 1 (sms) - MS replies with CP-ACK for received SMS MSC <--GERAN-A-- MS: SMS:0x04 @@ -2166,6 +2191,7 @@ DLSMS SMC(0) message MMSMS-DATA-IND (CP DATA) received in state MM_ESTABLISHED DLSMS SMC(0) received CP-DATA DLSMS trans(SMS IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x40000003 tid-0) sending CP message (trans=0) DLSMS trans(SMS IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x40000003 tid-0) GSM4.11 TX 09 04 +DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: Sending DTAP: SMS SMS:0x04 DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: RAN encode: DTAP on GERAN-A - DTAP --GERAN-A--> MS: SMS:0x04: 0904 - DTAP matches expected message @@ -2227,9 +2253,3 @@ DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEA DVLR freeing VLR subscr IMSI-901700000004620:MSISDN-46071 (max total use count was 6) ===== test_reject_paging_resp_during_paging_resp: SUCCESS -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 17 - -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 17 - diff --git a/tests/msc_vlr/msc_vlr_test_rest.c b/tests/msc_vlr/msc_vlr_test_rest.c index 620652c95..029e8b5b7 100644 --- a/tests/msc_vlr/msc_vlr_test_rest.c +++ b/tests/msc_vlr/msc_vlr_test_rest.c @@ -22,7 +22,7 @@ */ #include "msc_vlr_tests.h" -#include "stubs.h" + #include <osmocom/msc/vlr.h> #if 0 @@ -89,7 +89,7 @@ static void test_two_lu() btw("Location Update request causes a GSUP LU request to HLR"); lu_result_sent = RES_NONE; - gsup_expect_tx("04010809710000004026f0280102" VLR_TO_HLR); + gsup_expect_tx("04010809710000004026f0" CN_DOMAIN VLR_TO_HLR); ms_sends_msg("050802008168000130089910070000006402"); OSMO_ASSERT(gsup_tx_confirmed); VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); @@ -120,7 +120,7 @@ static void test_two_lu() BTW("verify that the MS can send another LU request"); btw("Location Update request causes a GSUP LU request to HLR"); lu_result_sent = RES_NONE; - gsup_expect_tx("04010809710000004026f0280102" VLR_TO_HLR); + gsup_expect_tx("04010809710000004026f0" CN_DOMAIN VLR_TO_HLR); ms_sends_msg("050802008168000130089910070000006402"); OSMO_ASSERT(gsup_tx_confirmed); VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); @@ -172,7 +172,7 @@ static void test_lu_unknown_tmsi() thwart_rx_non_initial_requests(); btw("MS tells us the IMSI, causes a GSUP LU request to HLR"); - gsup_expect_tx("04010809710000004026f0280102" VLR_TO_HLR); + gsup_expect_tx("04010809710000004026f0" CN_DOMAIN VLR_TO_HLR); ms_sends_msg("0559089910070000006402"); OSMO_ASSERT(gsup_tx_confirmed); VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); diff --git a/tests/msc_vlr/msc_vlr_test_rest.err b/tests/msc_vlr/msc_vlr_test_rest.err index 3990d109a..3a6442e21 100644 --- a/tests/msc_vlr/msc_vlr_test_rest.err +++ b/tests/msc_vlr/msc_vlr_test_rest.err @@ -1,7 +1,3 @@ -DLMGCP MGCP client: using endpoint domain '@mgw' -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 17 - ===== test_cm_service_without_lu - CM Service Request without a prior Location Updating MSC <--GERAN-A-- MS: GSM48_MT_MM_CM_SERV_REQ @@ -64,9 +60,6 @@ DMSC msc_a(IMSI-901700000004620:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASED}: Deal llist_count(&msub_list) == 0 ===== test_cm_service_without_lu: SUCCESS -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 17 - ===== test_two_lu - Location Update request causes a GSUP LU request to HLR MSC <--GERAN-A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST @@ -95,10 +88,13 @@ DREF VLR subscr IMSI-901700000004620 + active-conn: now used by 2 (_lu_fsm_assoc DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH DREF VLR subscr IMSI-901700000004620 - _lu_fsm_associate_vsub: now used by 1 (active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_post_auth() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_post_ciph() +DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(IMSI-901700000004620:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node_4() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_HLR_UPD DVLR upd_hlr_vlr_fsm(IMSI-901700000004620:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated @@ -234,10 +230,13 @@ DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + active-conn: now used by 3 ( DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - _lu_fsm_associate_vsub: now used by 2 (attached,active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre() DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_post_auth() DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_post_ciph() +DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node_4() DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_HLR_UPD DVLR upd_hlr_vlr_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated @@ -358,12 +357,13 @@ DMSC dummy_msc_i{0}: is child of msub_fsm DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms) DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3 DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: MM GSM48_MT_MM_IMSI_DETACH_IND -DMM IMSI DETACH INDICATION: MI(IMSI)=901700000004620 +DMM IMSI DETACH INDICATION: IMSI-901700000004620 DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + gsm48_rx_mm_imsi_detach_ind: now used by 2 (attached,gsm48_rx_mm_imsi_detach_ind) DMM IMSI DETACH for IMSI-901700000004620:MSISDN-46071 DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + active-conn: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn) DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn,vlr_subscr_cancel_attach_fsm) DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - attached: now used by 2 (gsm48_rx_mm_imsi_detach_ind,active-conn) DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - gsm48_rx_mm_imsi_detach_ind: now used by 1 (active-conn) DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_CN_CLOSE @@ -403,9 +403,6 @@ DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:NONE){MSC_A_ST_RELEASED}: D llist_count(&msub_list) == 0 ===== test_two_lu: SUCCESS -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 17 - ===== test_lu_unknown_tmsi - Location Update request with unknown TMSI sends ID Request for IMSI MSC <--GERAN-A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST @@ -433,8 +430,10 @@ DREF VLR subscr TMSI-0x23422342 + active-conn: now used by 2 (_lu_fsm_associate_ DMSC msc_a(TMSI-0x23422342:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK DMSC msc_a(TMSI-0x23422342:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH DREF VLR subscr TMSI-0x23422342 - _lu_fsm_associate_vsub: now used by 1 (active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DVLR vlr_lu_fsm(TMSI-0x23422342:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_want_imsi() DVLR vlr_lu_fsm(TMSI-0x23422342:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_IMSI +DBSSAP msc_a(TMSI-0x23422342:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: Sending DTAP: MM GSM48_MT_MM_ID_REQ DMSC msc_a(TMSI-0x23422342:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: DTAP on GERAN-A - DTAP --GERAN-A--> MS: GSM48_MT_MM_ID_REQ: 051801 - DTAP matches expected message @@ -465,14 +464,15 @@ DBSSAP msc_a(TMSI-0x23422342:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN decode error ( DREF msc_a(TMSI-0x23422342:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: + rx_from_ms: now used by 2 (lu,rx_from_ms) DBSSAP msc_a(TMSI-0x23422342:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN decode: DTAP DRLL msc_a(TMSI-0x23422342:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: Dispatching 04.08 message: MM GSM48_MT_MM_ID_RESP -DMM IDENTITY RESPONSE: MI=IMSI-901700000004620 +DMM IDENTITY RESPONSE: IMSI-901700000004620 DVLR set IMSI on subscriber; IMSI=901700000004620 id=901700000004620 DVLR vlr_lu_fsm(TMSI-0x23422342:GERAN-A:LU){VLR_ULA_S_WAIT_IMSI}: Received Event VLR_ULA_E_ID_IMSI -DVLR set IMSI on subscriber; IMSI=901700000004620 id=901700000004620 DVLR vlr_lu_fsm(TMSI-0x23422342:GERAN-A:LU){VLR_ULA_S_WAIT_IMSI}: vlr_loc_upd_node1_pre() DVLR vlr_lu_fsm(TMSI-0x23422342:GERAN-A:LU){VLR_ULA_S_WAIT_IMSI}: vlr_loc_upd_node1() DVLR vlr_lu_fsm(TMSI-0x23422342:GERAN-A:LU){VLR_ULA_S_WAIT_IMSI}: vlr_loc_upd_post_auth() DVLR vlr_lu_fsm(TMSI-0x23422342:GERAN-A:LU){VLR_ULA_S_WAIT_IMSI}: vlr_loc_upd_post_ciph() +DMSC msc_a(TMSI-0x23422342:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(TMSI-0x23422342:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DVLR vlr_lu_fsm(TMSI-0x23422342:GERAN-A:LU){VLR_ULA_S_WAIT_IMSI}: vlr_loc_upd_node_4() DVLR vlr_lu_fsm(TMSI-0x23422342:GERAN-A:LU){VLR_ULA_S_WAIT_IMSI}: state_chg to VLR_ULA_S_WAIT_HLR_UPD DVLR upd_hlr_vlr_fsm(TMSI-0x23422342:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated @@ -527,7 +527,7 @@ DVLR lu_compl_vlr_fsm(IMSI-901700000004620:MSISDN-46071:TMSI-0x23422342:GERAN-A: DVLR lu_compl_vlr_fsm(IMSI-901700000004620:MSISDN-46071:TMSI-0x23422342:GERAN-A:LU){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES DVLR lu_compl_vlr_fsm(IMSI-901700000004620:MSISDN-46071:TMSI-0x23422342:GERAN-A:LU){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL - sending LU Accept for IMSI-901700000004620:MSISDN-46071:TMSI-0x23422342:GERAN-A:LU -DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x23422342 + attached: now used by 3 (active-conn,vlr_gsup_rx,attached) +DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + attached: now used by 3 (active-conn,vlr_gsup_rx,attached) DVLR lu_compl_vlr_fsm(IMSI-901700000004620:MSISDN-46071:TMSI-0x23422342:GERAN-A:LU){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_DONE DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:TMSI-0x23422342:GERAN-A:LU){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS DVLR lu_compl_vlr_fsm(IMSI-901700000004620:MSISDN-46071:TMSI-0x23422342:GERAN-A:LU){LU_COMPL_VLR_S_DONE}: Terminating in cascade, depth 2 (cause = OSMO_FSM_TERM_PARENT, caused by: upd_hlr_vlr_fsm(TMSI-0x23422342:GERAN-A:LU)) @@ -540,15 +540,15 @@ DREF msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x23422342:GERAN-A:LU){MSC_A_S DMSC msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x23422342:GERAN-A:LU){MSC_A_ST_AUTHENTICATED}: Received Event MSC_A_EV_UNUSED DMSC msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x23422342:GERAN-A:LU){MSC_A_ST_AUTHENTICATED}: state_chg to MSC_A_ST_RELEASING DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x23422342:GERAN-A:LU){MSC_A_ST_RELEASING}: Releasing: msc_a use is 0 (-) -DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x23422342 + msc_a_fsm_releasing_onenter: now used by 4 (active-conn,vlr_gsup_rx,attached,msc_a_fsm_releasing_onenter) -DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x23422342 + vlr_subscr_cancel_attach_fsm: now used by 5 (active-conn,vlr_gsup_rx,attached,msc_a_fsm_releasing_onenter,vlr_subscr_cancel_attach_fsm) -DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x23422342 - vlr_subscr_cancel_attach_fsm: now used by 4 (active-conn,vlr_gsup_rx,attached,msc_a_fsm_releasing_onenter) +DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + msc_a_fsm_releasing_onenter: now used by 4 (active-conn,vlr_gsup_rx,attached,msc_a_fsm_releasing_onenter) +DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + vlr_subscr_cancel_attach_fsm: now used by 5 (active-conn,vlr_gsup_rx,attached,msc_a_fsm_releasing_onenter,vlr_subscr_cancel_attach_fsm) +DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - vlr_subscr_cancel_attach_fsm: now used by 4 (active-conn,vlr_gsup_rx,attached,msc_a_fsm_releasing_onenter) DREF msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x23422342:GERAN-A:LU){MSC_A_ST_RELEASING}: + wait-Clear-Complete: now used by 1 (wait-Clear-Complete) DMSC msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x23422342:GERAN-A:LU){MSC_A_ST_RELEASING}: RAN encode: CLEAR_COMMAND on GERAN-A DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:TMSI-0x23422342:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST -DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x23422342 - msc_a_fsm_releasing_onenter: now used by 3 (active-conn,vlr_gsup_rx,attached) +DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - msc_a_fsm_releasing_onenter: now used by 3 (active-conn,vlr_gsup_rx,attached) DVLR upd_hlr_vlr_fsm(TMSI-0x23422342:GERAN-A:LU){UPD_HLR_VLR_S_DONE}: Deallocated, including all deferred deallocations -DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x23422342 - vlr_gsup_rx: now used by 2 (active-conn,attached) +DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - vlr_gsup_rx: now used by 2 (active-conn,attached) <-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: vlr_gsupc_read_cb() returns 0 bssap_clear_sent == 1 - LU was successful, and the conn has already been closed @@ -566,25 +566,19 @@ DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:TMSI-0x23422342:GERAN-A:LU){VL DMSC msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x23422342:GERAN-A:LU){MSC_A_ST_RELEASED}: Removing from parent msub_fsm DREF msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x23422342:GERAN-A:LU){MSC_A_ST_RELEASED}: max total use count was 3 DMSC msub_fsm{active}: Received Event MSUB_EV_ROLE_TERMINATED -DMSC msub(IMSI-901700000004620:MSISDN-46071:TMSI-0x23422342) MSC-A terminated -DMSC msub(IMSI-901700000004620:MSISDN-46071:TMSI-0x23422342) 1 MSC-I still active +DMSC msub(IMSI-901700000004620:MSISDN-46071) MSC-A terminated +DMSC msub(IMSI-901700000004620:MSISDN-46071) 1 MSC-I still active DMSC msub_fsm{active}: state_chg to terminating DMSC msub_fsm{terminating}: Terminating in cascade, depth 2 (cause = OSMO_FSM_TERM_REGULAR, caused by: msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x23422342:GERAN-A:LU)) DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:TMSI-0x23422342:GERAN-A:LU){0}: Terminating in cascade, depth 3 (cause = OSMO_FSM_TERM_PARENT, caused by: msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x23422342:GERAN-A:LU)) DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:TMSI-0x23422342:GERAN-A:LU){0}: Removing from parent msub_fsm DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:TMSI-0x23422342:GERAN-A:LU){0}: Deferring: will deallocate with msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x23422342:GERAN-A:LU) -DMSC msub(IMSI-901700000004620:MSISDN-46071:TMSI-0x23422342) Free -DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x23422342 - active-conn: now used by 1 (attached) +DMSC msub(IMSI-901700000004620:MSISDN-46071) Free +DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - active-conn: now used by 1 (attached) DMSC msub_fsm{terminating}: Deferring: will deallocate with msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x23422342:GERAN-A:LU) DMSC msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x23422342:GERAN-A:LU){MSC_A_ST_RELEASED}: Deallocated, including all deferred deallocations - msub gone llist_count(&msub_list) == 0 -DVLR freeing VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x23422342 (max total use count was 5) +DVLR freeing VLR subscr IMSI-901700000004620:MSISDN-46071 (max total use count was 5) ===== test_lu_unknown_tmsi: SUCCESS -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 17 - -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 17 - diff --git a/tests/msc_vlr/msc_vlr_test_ss.c b/tests/msc_vlr/msc_vlr_test_ss.c index e4b3a4e4d..772429e72 100644 --- a/tests/msc_vlr/msc_vlr_test_ss.c +++ b/tests/msc_vlr/msc_vlr_test_ss.c @@ -21,7 +21,6 @@ */ #include "msc_vlr_tests.h" -#include "stubs.h" #define IMSI "901700000004620" @@ -48,7 +47,7 @@ static void perform_lu(void) btw("Location Update request causes a GSUP LU request to HLR"); lu_result_sent = RES_NONE; - gsup_expect_tx("04010809710000004026f0280102" VLR_TO_HLR); + gsup_expect_tx("04010809710000004026f0" CN_DOMAIN VLR_TO_HLR); ms_sends_msg("050802008168000130089910070000006402"); OSMO_ASSERT(gsup_tx_confirmed); VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); diff --git a/tests/msc_vlr/msc_vlr_test_ss.err b/tests/msc_vlr/msc_vlr_test_ss.err index 976b26395..8a1bd8272 100644 --- a/tests/msc_vlr/msc_vlr_test_ss.err +++ b/tests/msc_vlr/msc_vlr_test_ss.err @@ -1,7 +1,3 @@ -DLMGCP MGCP client: using endpoint domain '@mgw' -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 17 - ===== test_ss_ussd_mo_geran - Location Update request causes a GSUP LU request to HLR MSC <--GERAN-A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST @@ -30,10 +26,13 @@ DREF VLR subscr IMSI-901700000004620 + active-conn: now used by 2 (_lu_fsm_assoc DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH DREF VLR subscr IMSI-901700000004620 - _lu_fsm_associate_vsub: now used by 1 (active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_post_auth() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_post_ciph() +DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(IMSI-901700000004620:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node_4() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_HLR_UPD DVLR upd_hlr_vlr_fsm(IMSI-901700000004620:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated @@ -153,6 +152,8 @@ DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_VA DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi() DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_node2() DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_ciph() +DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_vlr() DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_post_pres() DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_post_trace() @@ -160,6 +161,7 @@ DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SER DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: proc_arq_fsm_done(PASSED) DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_DONE DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_DONE}: Process Access Request result: PASSED +DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: Sending DTAP: MM GSM48_MT_MM_CM_SERV_ACC DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN encode: DTAP on GERAN-A - DTAP --GERAN-A--> MS: GSM48_MT_MM_CM_SERV_ACC: 0521 DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST @@ -184,23 +186,25 @@ GSUP --> HLR: OSMO_GSUP_MSGT_PROC_SS_REQUEST: 20010809710000004026f0300420000001 DREF msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (nc_ss) <-- GSUP rx OSMO_GSUP_MSGT_PROC_SS_REQUEST: 20010809710000004026f03004200000013101033527a225020101302002013b301b04010f0416d9775d0e2ae3e965f73cfd7683d27310cd06bbc51a0d0a0103 DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + gsm0911_gsup_rx: now used by 4 (attached,active-conn,NCSS,gsm0911_gsup_rx) +DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - gsm0911_gsup_rx: now used by 3 (attached,active-conn,NCSS) +DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Sending DTAP: NCSS GSM0480_MTYPE_RELEASE_COMPLETE DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on GERAN-A - DTAP --GERAN-A--> MS: GSM0480_MTYPE_RELEASE_COMPLETE: 8b2a1c27a225020101302002013b301b04010f0416d9775d0e2ae3e965f73cfd7683d27310cd06bbc51a0d - DTAP matches expected message DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DSS trans(NCSS IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x20000001 tid-8) Freeing transaction -DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - NCSS: now used by 3 (attached,active-conn,gsm0911_gsup_rx) +DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - NCSS: now used by 2 (attached,active-conn) DREF msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - nc_ss: now used by 0 (-) DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Received Event MSC_A_EV_UNUSED DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: state_chg to MSC_A_ST_RELEASING DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: Releasing: msc_a use is 0 (-) -DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + msc_a_fsm_releasing_onenter: now used by 4 (attached,active-conn,gsm0911_gsup_rx,msc_a_fsm_releasing_onenter) -DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + vlr_subscr_cancel_attach_fsm: now used by 5 (attached,active-conn,gsm0911_gsup_rx,msc_a_fsm_releasing_onenter,vlr_subscr_cancel_attach_fsm) -DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - vlr_subscr_cancel_attach_fsm: now used by 4 (attached,active-conn,gsm0911_gsup_rx,msc_a_fsm_releasing_onenter) +DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + msc_a_fsm_releasing_onenter: now used by 3 (attached,active-conn,msc_a_fsm_releasing_onenter) +DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,active-conn,msc_a_fsm_releasing_onenter,vlr_subscr_cancel_attach_fsm) +DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,active-conn,msc_a_fsm_releasing_onenter) DREF msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: + wait-Clear-Complete: now used by 1 (wait-Clear-Complete) DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: RAN encode: CLEAR_COMMAND on GERAN-A DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST -DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - msc_a_fsm_releasing_onenter: now used by 3 (attached,active-conn,gsm0911_gsup_rx) +DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - msc_a_fsm_releasing_onenter: now used by 2 (attached,active-conn) <-- GSUP rx OSMO_GSUP_MSGT_PROC_SS_REQUEST: vlr_gsupc_read_cb() returns 0 dtap_tx_confirmed == 1 bssap_clear_sent == 1 @@ -225,7 +229,7 @@ DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: T DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Removing from parent msub_fsm DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Deferring: will deallocate with msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ) DMSC msub(IMSI-901700000004620:MSISDN-46071) Free -DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - active-conn: now used by 2 (attached,gsm0911_gsup_rx) +DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - active-conn: now used by 1 (attached) DMSC msub_fsm{terminating}: Deferring: will deallocate with msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ) DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASED}: Deallocated, including all deferred deallocations - msub gone @@ -233,9 +237,6 @@ DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RE DVLR freeing VLR subscr IMSI-901700000004620:MSISDN-46071 (max total use count was 5) ===== test_ss_ussd_mo_geran: SUCCESS -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 17 - ===== test_ss_ussd_no_geran - Location Update request causes a GSUP LU request to HLR MSC <--GERAN-A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST @@ -264,10 +265,13 @@ DREF VLR subscr IMSI-901700000004620 + active-conn: now used by 2 (_lu_fsm_assoc DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH DREF VLR subscr IMSI-901700000004620 - _lu_fsm_associate_vsub: now used by 1 (active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_post_auth() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_post_ciph() +DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(IMSI-901700000004620:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node_4() DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_HLR_UPD DVLR upd_hlr_vlr_fsm(IMSI-901700000004620:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated @@ -367,22 +371,23 @@ DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + _test_ss_ussd_no: now used b llist_count(&vsub->cs.requests) == 0 <-- GSUP rx OSMO_GSUP_MSGT_PROC_SS_REQUEST: 20010809710000004026f03004200001013101013515a11302010102013b300b04010f0406aa510c061b010a0103 DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + gsm0911_gsup_rx: now used by 3 (attached,_test_ss_ussd_no,gsm0911_gsup_rx) +DSS (IMSI-901700000004620:MSISDN-46071) Establishing a network-originated session (id=0x20000101) DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + NCSS: now used by 4 (attached,_test_ss_ussd_no,gsm0911_gsup_rx,NCSS) -DSS trans(NCSS IMSI-901700000004620:MSISDN-46071 callref-0x20000101 tid-255) New transaction -DSS trans(NCSS IMSI-901700000004620:MSISDN-46071 callref-0x20000101 tid-255) Establishing network-originated session +DSS trans(NCSS IMSI-901700000004620:MSISDN-46071 callref-0x20000101 tid-0) New transaction DSS trans(NCSS IMSI-901700000004620:MSISDN-46071 callref-0x20000101 tid-0) Triggering Paging Request DPAG Paging: IMSI-901700000004620:MSISDN-46071 for GSM 09.11 SS/USSD: Starting paging paging request (SIGNALLING_HIGH_PRIO) to IMSI-901700000004620:MSISDN-46071 on GERAN-A strcmp(paging_expecting_imsi, vsub->imsi) == 0 DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + Paging: now used by 5 (attached,_test_ss_ussd_no,gsm0911_gsup_rx,NCSS,Paging) -<-- GSUP rx OSMO_GSUP_MSGT_PROC_SS_REQUEST: vlr_gsupc_read_cb() returns -22 +DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - gsm0911_gsup_rx: now used by 4 (attached,_test_ss_ussd_no,NCSS,Paging) +<-- GSUP rx OSMO_GSUP_MSGT_PROC_SS_REQUEST: vlr_gsupc_read_cb() returns 0 llist_count(&vsub->cs.requests) == 1 -DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - _test_ss_ussd_no: now used by 4 (attached,gsm0911_gsup_rx,NCSS,Paging) +DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - _test_ss_ussd_no: now used by 3 (attached,NCSS,Paging) paging_sent == 1 - the subscriber and its pending request should remain -DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + _test_ss_ussd_no: now used by 5 (attached,gsm0911_gsup_rx,NCSS,Paging,_test_ss_ussd_no) +DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + _test_ss_ussd_no: now used by 4 (attached,NCSS,Paging,_test_ss_ussd_no) llist_count(&vsub->cs.requests) == 1 -DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - _test_ss_ussd_no: now used by 4 (attached,gsm0911_gsup_rx,NCSS,Paging) +DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - _test_ss_ussd_no: now used by 3 (attached,NCSS,Paging) - MS replies with Paging Response, we deliver the NC/USSD MSC <--GERAN-A-- MS: GSM48_MT_RR_PAG_RESP new conn @@ -395,19 +400,21 @@ DMSC dummy_msc_i{0}: is child of msub_fsm DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms) DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3 DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: RR GSM48_MT_RR_PAG_RESP -DRR msc_a(IMSI-901700000004620:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: Rx PAGING RESPONSE +DRR msc_a(IMSI-901700000004620:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: Rx PAGING RESPONSE IMSI-901700000004620 DREF msc_a(IMSI-901700000004620:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: + paging-response: now used by 2 (rx_from_ms,paging-response) DVLR Process_Access_Request_VLR(IMSI-901700000004620:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: Allocated DVLR Process_Access_Request_VLR(IMSI-901700000004620:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: is child of msc_a(IMSI-901700000004620:GERAN-A:PAGING_RESP) DVLR Process_Access_Request_VLR(IMSI-901700000004620:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: rev=GSM net=GERAN (no Auth) DVLR Process_Access_Request_VLR(IMSI-901700000004620:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START -DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + proc_arq_vlr_fn_init: now used by 5 (attached,gsm0911_gsup_rx,NCSS,Paging,proc_arq_vlr_fn_init) -DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + active-conn: now used by 6 (attached,gsm0911_gsup_rx,NCSS,Paging,proc_arq_vlr_fn_init,active-conn) +DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + proc_arq_vlr_fn_init: now used by 4 (attached,NCSS,Paging,proc_arq_vlr_fn_init) +DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + active-conn: now used by 5 (attached,NCSS,Paging,proc_arq_vlr_fn_init,active-conn) DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi() DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_node2() DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_ciph() +DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_vlr() DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_post_pres() DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_post_trace() @@ -421,13 +428,14 @@ DPAG Paging: IMSI-901700000004620:MSISDN-46071 for GSM 09.11 SS/USSD: Paging Res DPAG Paging: IMSI-901700000004620:MSISDN-46071 for GSM 09.11 SS/USSD: Removing Paging Request DSS msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: Paging succeeded DREF msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: + nc_ss: now used by 3 (rx_from_ms,paging-response,nc_ss) +DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: Sending DTAP: NCSS GSM0480_MTYPE_REGISTER DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: RAN encode: DTAP on GERAN-A - DTAP --GERAN-A--> MS: GSM0480_MTYPE_REGISTER: 0b3b1c15a11302010102013b300b04010f0406aa510c061b01 - DTAP matches expected message DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST -DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - Paging: now used by 5 (attached,gsm0911_gsup_rx,NCSS,proc_arq_vlr_fn_init,active-conn) +DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - Paging: now used by 4 (attached,NCSS,proc_arq_vlr_fn_init,active-conn) DREF msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: - paging-response: now used by 2 (rx_from_ms,nc_ss) -DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - proc_arq_vlr_fn_init: now used by 4 (attached,gsm0911_gsup_rx,NCSS,active-conn) +DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - proc_arq_vlr_fn_init: now used by 3 (attached,NCSS,active-conn) DREF msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: - rx_from_ms: now used by 1 (nc_ss) dtap_tx_confirmed == 1 - MS responds to SS/USSD request @@ -441,24 +449,26 @@ DREF msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHE dtap_tx_confirmed == 1 - HLR terminates the session <-- GSUP rx OSMO_GSUP_MSGT_PROC_SS_REQUEST: 20010809710000004026f03004200001013101030a0103 -DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + gsm0911_gsup_rx: now used by 5 (attached,2*gsm0911_gsup_rx,NCSS,active-conn) +DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + gsm0911_gsup_rx: now used by 4 (attached,NCSS,active-conn,gsm0911_gsup_rx) +DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - gsm0911_gsup_rx: now used by 3 (attached,NCSS,active-conn) +DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: Sending DTAP: NCSS GSM0480_MTYPE_RELEASE_COMPLETE DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: RAN encode: DTAP on GERAN-A - DTAP --GERAN-A--> MS: GSM0480_MTYPE_RELEASE_COMPLETE: 0b2a - DTAP matches expected message DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DSS trans(NCSS IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x20000101 tid-0) Freeing transaction -DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - NCSS: now used by 4 (attached,2*gsm0911_gsup_rx,active-conn) +DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - NCSS: now used by 2 (attached,active-conn) DREF msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: - nc_ss: now used by 0 (-) DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: Received Event MSC_A_EV_UNUSED DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: state_chg to MSC_A_ST_RELEASING DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: Releasing: msc_a use is 0 (-) -DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + msc_a_fsm_releasing_onenter: now used by 5 (attached,2*gsm0911_gsup_rx,active-conn,msc_a_fsm_releasing_onenter) -DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + vlr_subscr_cancel_attach_fsm: now used by 6 (attached,2*gsm0911_gsup_rx,active-conn,msc_a_fsm_releasing_onenter,vlr_subscr_cancel_attach_fsm) -DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - vlr_subscr_cancel_attach_fsm: now used by 5 (attached,2*gsm0911_gsup_rx,active-conn,msc_a_fsm_releasing_onenter) +DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + msc_a_fsm_releasing_onenter: now used by 3 (attached,active-conn,msc_a_fsm_releasing_onenter) +DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,active-conn,msc_a_fsm_releasing_onenter,vlr_subscr_cancel_attach_fsm) +DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,active-conn,msc_a_fsm_releasing_onenter) DREF msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: + wait-Clear-Complete: now used by 1 (wait-Clear-Complete) DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: RAN encode: CLEAR_COMMAND on GERAN-A DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST -DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - msc_a_fsm_releasing_onenter: now used by 4 (attached,2*gsm0911_gsup_rx,active-conn) +DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - msc_a_fsm_releasing_onenter: now used by 2 (attached,active-conn) <-- GSUP rx OSMO_GSUP_MSGT_PROC_SS_REQUEST: vlr_gsupc_read_cb() returns 0 dtap_tx_confirmed == 1 bssap_clear_sent == 1 @@ -483,17 +493,11 @@ DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Term DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Removing from parent msub_fsm DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Deferring: will deallocate with msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP) DMSC msub(IMSI-901700000004620:MSISDN-46071) Free -DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - active-conn: now used by 3 (attached,2*gsm0911_gsup_rx) +DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - active-conn: now used by 1 (attached) DMSC msub_fsm{terminating}: Deferring: will deallocate with msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP) DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASED}: Deallocated, including all deferred deallocations - msub gone llist_count(&msub_list) == 0 -DVLR freeing VLR subscr IMSI-901700000004620:MSISDN-46071 (max total use count was 6) +DVLR freeing VLR subscr IMSI-901700000004620:MSISDN-46071 (max total use count was 5) ===== test_ss_ussd_no_geran: SUCCESS -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 17 - -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 17 - diff --git a/tests/msc_vlr/msc_vlr_test_umts_authen.c b/tests/msc_vlr/msc_vlr_test_umts_authen.c index cb8a03291..0a2a4464b 100644 --- a/tests/msc_vlr/msc_vlr_test_umts_authen.c +++ b/tests/msc_vlr/msc_vlr_test_umts_authen.c @@ -22,7 +22,6 @@ */ #include "msc_vlr_tests.h" -#include "stubs.h" static void _test_umts_authen(enum osmo_rat_type via_ran) { @@ -50,6 +49,8 @@ static void _test_umts_authen(enum osmo_rat_type via_ran) "5079da1e1ee7416937485e9ea7c965373d1d6683c270383b3d0e" "d3d36ff71c949e83c22072799e9687c5ec32a81d96afcbf4b4fb" "0c7ac3e9e9b7db05"; + bool encryption = (via_ran == OSMO_RAT_GERAN_A && net->a5_encryption_mask > 0x1) + || (via_ran == OSMO_RAT_UTRAN_IU && net->uea_encryption_mask > (1 << OSMO_UTRAN_UEA0)); net->authentication_required = true; net->vlr->cfg.assign_tmsi = true; @@ -57,7 +58,7 @@ static void _test_umts_authen(enum osmo_rat_type via_ran) btw("Location Update request causes a GSUP Send Auth Info request to HLR"); lu_result_sent = RES_NONE; - gsup_expect_tx("080108" "09710000000156f0" VLR_TO_HLR); + gsup_expect_tx("080108" "09710000000156f0" CN_DOMAIN VLR_TO_HLR); ms_sends_msg("0508" /* MM LU */ "7" /* ciph key seq: no key available */ "0" /* LU type: normal */ @@ -123,25 +124,38 @@ static void _test_umts_authen(enum osmo_rat_type via_ran) VERBOSE_ASSERT(auth_request_sent, == true, "%d"); VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - if (via_ran == OSMO_RAT_GERAN_A) { - btw("MS sends Authen Response, VLR accepts and sends GSUP LU Req to HLR"); - gsup_expect_tx("04010809710000000156f0280102" VLR_TO_HLR); + switch (via_ran) { + case OSMO_RAT_GERAN_A: + if (encryption) { + btw("Test code not implemented"); + OSMO_ASSERT(false); + } + + btw("Encryption disabled. MS sends Authen Response, VLR accepts and sends GSUP LU Req to HLR"); + gsup_expect_tx("04010809710000000156f0" CN_DOMAIN VLR_TO_HLR); ms_sends_msg("0554" "e229c19e" "2104" "791f2e41"); VERBOSE_ASSERT(gsup_tx_confirmed, == true, "%d"); VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - } else { - /* On UTRAN */ - btw("MS sends Authen Response, VLR accepts and sends SecurityModeControl"); + break; + case OSMO_RAT_UTRAN_IU: + /* Even if encryption is disabled (UEA0), we still expect a SecurityModeControl + * message indicating UIA, because integrity protection is mandatory in UTRAN. */ + btw("Encryption %sabled. MS sends Authen Response, VLR accepts and sends SecurityModeControl", + encryption ? "en" : "dis"); expect_security_mode_ctrl(NULL, "27497388b6cb044648f396aa155b95ef"); ms_sends_msg("0554" "e229c19e" "2104" "791f2e41"); VERBOSE_ASSERT(security_mode_ctrl_sent, == true, "%d"); VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); btw("MS sends SecurityModeControl acceptance, VLR accepts and sends GSUP LU Req to HLR"); - gsup_expect_tx("04010809710000000156f0280102" VLR_TO_HLR); - ms_sends_security_mode_complete(); + gsup_expect_tx("04010809710000000156f0" CN_DOMAIN VLR_TO_HLR); + ms_sends_security_mode_complete(encryption ? 0x01 : 0x00); VERBOSE_ASSERT(gsup_tx_confirmed, == true, "%d"); VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); + break; + default: + btw("Unhandled RAT %s", osmo_rat_type_name(via_ran)); + OSMO_ASSERT(false); } btw("HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT"); @@ -191,22 +205,35 @@ static void _test_umts_authen(enum osmo_rat_type via_ran) EXPECT_ACCEPTED(false); thwart_rx_non_initial_requests(); - if (via_ran == OSMO_RAT_GERAN_A) { - btw("MS sends Authen Response, VLR accepts with a CM Service Accept"); + switch (via_ran) { + case OSMO_RAT_GERAN_A: + if (encryption) { + btw("Test code not implemented"); + OSMO_ASSERT(false); + } + + btw("Encryption disabled. MS sends Authen Response, VLR accepts with a CM Service Accept"); gsup_expect_tx(NULL); ms_sends_msg("0554" "7db47cf7" "2104" "f81e4dc7"); /* 2nd vector's res, s.a. */ VERBOSE_ASSERT(cm_service_result_sent, == RES_ACCEPT, "%d"); - } else { - /* On UTRAN */ - btw("MS sends Authen Response, VLR accepts and sends SecurityModeControl"); + break; + case OSMO_RAT_UTRAN_IU: + /* Even if encryption is disabled (UEA0), we still expect a SecurityModeControl + * message indicating UIA, because integrity protection is mandatory in UTRAN. */ + btw("Encryption %sabled. MS sends Authen Response, VLR accepts and sends SecurityModeControl", + encryption ? "en" : "dis"); expect_security_mode_ctrl(NULL, "1159ec926a50e98c034a6b7d7c9f418d"); ms_sends_msg("0554" "7db47cf7" "2104" "f81e4dc7"); /* 2nd vector's res, s.a. */ VERBOSE_ASSERT(security_mode_ctrl_sent, == true, "%d"); VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d"); btw("MS sends SecurityModeControl acceptance, VLR accepts; above Ciphering is an implicit CM Service Accept"); - ms_sends_security_mode_complete(); + ms_sends_security_mode_complete(encryption ? 0x01 : 0x00); VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d"); + break; + default: + btw("Unhandled RAT %s", osmo_rat_type_name(via_ran)); + OSMO_ASSERT(false); } /* Release connection */ @@ -252,21 +279,34 @@ static void _test_umts_authen(enum osmo_rat_type via_ran) EXPECT_ACCEPTED(false); thwart_rx_non_initial_requests(); - if (via_ran == OSMO_RAT_GERAN_A) { - btw("MS sends Authen Response, VLR accepts and sends pending SMS"); + switch (via_ran) { + case OSMO_RAT_GERAN_A: + if (encryption) { + btw("Test code not implemented"); + OSMO_ASSERT(false); + } + + btw("Encryption disabled. MS sends Authen Response, VLR accepts and sends pending SMS"); dtap_expect_tx(sms); ms_sends_msg("0554" "706f9967" "2104" "19ba609c"); /* 3nd vector's res, s.a. */ VERBOSE_ASSERT(dtap_tx_confirmed, == true, "%d"); - } else { - /* On UTRAN */ - btw("MS sends Authen Response, VLR accepts and sends SecurityModeControl"); + break; + case OSMO_RAT_UTRAN_IU: + /* Even if encryption is disabled (UEA0), we still expect a SecurityModeControl + * message indicating UIA, because integrity protection is mandatory in UTRAN. */ + btw("Encryption %sabled. MS sends Authen Response, VLR accepts and sends SecurityModeControl", + encryption ? "en" : "dis"); expect_security_mode_ctrl(NULL, "eb50e770ddcc3060101d2f43b6c2b884"); ms_sends_msg("0554" "706f9967" "2104" "19ba609c"); /* 3nd vector's res, s.a. */ VERBOSE_ASSERT(security_mode_ctrl_sent, == true, "%d"); btw("MS sends SecurityModeControl acceptance, VLR accepts and sends SMS"); dtap_expect_tx(sms); - ms_sends_security_mode_complete(); + ms_sends_security_mode_complete(encryption ? 0x01 : 0x00); + break; + default: + btw("Unhandled RAT %s", osmo_rat_type_name(via_ran)); + OSMO_ASSERT(false); } btw("SMS was delivered, no requests pending for subscr"); @@ -314,6 +354,15 @@ static void test_umts_authen_geran() static void test_umts_authen_utran() { comment_start(); + net->uea_encryption_mask = (1 << OSMO_UTRAN_UEA0); + _test_umts_authen(OSMO_RAT_UTRAN_IU); + comment_end(); +} + +static void test_umts_auth_ciph_utran() +{ + comment_start(); + net->uea_encryption_mask = (1 << OSMO_UTRAN_UEA1) | (1 << OSMO_UTRAN_UEA2); _test_umts_authen(OSMO_RAT_UTRAN_IU); comment_end(); } @@ -332,6 +381,8 @@ static void _test_umts_authen_resync(enum osmo_rat_type via_ran) { struct vlr_subscr *vsub; const char *imsi = "901700000010650"; + bool encryption = (via_ran == OSMO_RAT_GERAN_A && net->a5_encryption_mask > 0x1) + || (via_ran == OSMO_RAT_UTRAN_IU && net->uea_encryption_mask > (1 << OSMO_UTRAN_UEA0)); net->authentication_required = true; net->vlr->cfg.assign_tmsi = true; @@ -339,7 +390,7 @@ static void _test_umts_authen_resync(enum osmo_rat_type via_ran) btw("Location Update request causes a GSUP Send Auth Info request to HLR"); lu_result_sent = RES_NONE; - gsup_expect_tx("080108" "09710000000156f0" VLR_TO_HLR); + gsup_expect_tx("080108" "09710000000156f0" CN_DOMAIN VLR_TO_HLR); ms_sends_msg("0508" /* MM LU */ "7" /* ciph key seq: no key available */ "0" /* LU type: normal */ @@ -441,7 +492,7 @@ static void _test_umts_authen_resync(enum osmo_rat_type via_ran) "0108" "09710000000156f0" /* IMSI */ "260e" "979498b1f72d3e28c59fa2e72f9c" /* AUTS */ "2010" "39fa2f4e3d523d8619a73b4f65c3e14d" /* RAND */ - VLR_TO_HLR); + CN_DOMAIN VLR_TO_HLR); ms_sends_msg("051c" /* 05 = MM; 1c = Auth Failure */ "15" /* cause = Synch Failure */ "220e" "979498b1f72d3e28c59fa2e72f9c" /* AUTS */); @@ -486,25 +537,38 @@ static void _test_umts_authen_resync(enum osmo_rat_type via_ran) VERBOSE_ASSERT(auth_request_sent, == true, "%d"); VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - if (via_ran == OSMO_RAT_GERAN_A) { - btw("MS sends Authen Response, VLR accepts and sends GSUP LU Req to HLR"); - gsup_expect_tx("04010809710000000156f0280102" VLR_TO_HLR); + switch (via_ran) { + case OSMO_RAT_GERAN_A: + if (encryption) { + btw("Test code not implemented"); + OSMO_ASSERT(false); + } + + btw("Encryption disabled. MS sends Authen Response, VLR accepts and sends GSUP LU Req to HLR"); + gsup_expect_tx("04010809710000000156f0" CN_DOMAIN VLR_TO_HLR); ms_sends_msg("0554" "1df5f0b4" "2104" "f22b696e"); VERBOSE_ASSERT(gsup_tx_confirmed, == true, "%d"); VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); - } else { - /* On UTRAN */ - btw("MS sends Authen Response, VLR accepts and sends SecurityModeControl"); + break; + case OSMO_RAT_UTRAN_IU: + /* Even if encryption is disabled (UEA0), we still expect a SecurityModeControl + * message indicating UIA, because integrity protection is mandatory in UTRAN. */ + btw("Encryption %sabled. MS sends Authen Response, VLR accepts and sends SecurityModeControl", + encryption ? "en" : "dis"); expect_security_mode_ctrl(NULL, "8a90c769b7272f3bb7a1c1fbb1ea9349"); ms_sends_msg("0554" "1df5f0b4" "2104" "f22b696e"); VERBOSE_ASSERT(security_mode_ctrl_sent, == true, "%d"); VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); btw("MS sends SecurityModeControl acceptance, VLR accepts and sends GSUP LU Req to HLR"); - gsup_expect_tx("04010809710000000156f0280102" VLR_TO_HLR); - ms_sends_security_mode_complete(); + gsup_expect_tx("04010809710000000156f0" CN_DOMAIN VLR_TO_HLR); + ms_sends_security_mode_complete(encryption ? 0x01 : 0x00); VERBOSE_ASSERT(gsup_tx_confirmed, == true, "%d"); VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d"); + break; + default: + btw("Unhandled RAT %s", osmo_rat_type_name(via_ran)); + OSMO_ASSERT(false); } btw("HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT"); @@ -552,6 +616,15 @@ static void test_umts_authen_resync_geran() static void test_umts_authen_resync_utran() { comment_start(); + net->uea_encryption_mask = (1 << OSMO_UTRAN_UEA0); + _test_umts_authen_resync(OSMO_RAT_UTRAN_IU); + comment_end(); +} + +static void test_umts_auth_ciph_resync_utran() +{ + comment_start(); + net->uea_encryption_mask = (1 << OSMO_UTRAN_UEA1) | (1 << OSMO_UTRAN_UEA2); _test_umts_authen_resync(OSMO_RAT_UTRAN_IU); comment_end(); } @@ -564,7 +637,7 @@ static void _test_umts_authen_too_short_res(enum osmo_rat_type via_ran) btw("Location Update request causes a GSUP Send Auth Info request to HLR"); lu_result_sent = RES_NONE; - gsup_expect_tx("080108" "09710000000156f0" VLR_TO_HLR); + gsup_expect_tx("080108" "09710000000156f0" CN_DOMAIN VLR_TO_HLR); ms_sends_msg("0508" /* MM LU */ "7" /* ciph key seq: no key available */ "0" /* LU type: normal */ @@ -664,7 +737,7 @@ static void _test_umts_authen_too_long_res(enum osmo_rat_type via_ran) btw("Location Update request causes a GSUP Send Auth Info request to HLR"); lu_result_sent = RES_NONE; - gsup_expect_tx("080108" "09710000000156f0" VLR_TO_HLR); + gsup_expect_tx("080108" "09710000000156f0" CN_DOMAIN VLR_TO_HLR); ms_sends_msg("0508" /* MM LU */ "7" /* ciph key seq: no key available */ "0" /* LU type: normal */ @@ -764,7 +837,7 @@ static void _test_umts_authen_only_sres(enum osmo_rat_type via_ran) btw("Location Update request causes a GSUP Send Auth Info request to HLR"); lu_result_sent = RES_NONE; - gsup_expect_tx("080108" "09710000000156f0" VLR_TO_HLR); + gsup_expect_tx("080108" "09710000000156f0" CN_DOMAIN VLR_TO_HLR); ms_sends_msg("0508" /* MM LU */ "7" /* ciph key seq: no key available */ "0" /* LU type: normal */ @@ -865,8 +938,10 @@ static void test_umts_authen_only_sres_utran() msc_vlr_test_func_t msc_vlr_tests[] = { test_umts_authen_geran, test_umts_authen_utran, + test_umts_auth_ciph_utran, test_umts_authen_resync_geran, test_umts_authen_resync_utran, + test_umts_auth_ciph_resync_utran, test_umts_authen_too_short_res_geran, test_umts_authen_too_short_res_utran, test_umts_authen_too_long_res_geran, diff --git a/tests/msc_vlr/msc_vlr_test_umts_authen.err b/tests/msc_vlr/msc_vlr_test_umts_authen.err index b11f077d4..aacff394d 100644 --- a/tests/msc_vlr/msc_vlr_test_umts_authen.err +++ b/tests/msc_vlr/msc_vlr_test_umts_authen.err @@ -1,7 +1,3 @@ -DLMGCP MGCP client: using endpoint domain '@mgw' -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 17 - ===== test_umts_authen_geran - Location Update request causes a GSUP Send Auth Info request to HLR MSC <--GERAN-A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST @@ -30,13 +26,14 @@ DREF VLR subscr IMSI-901700000010650 + active-conn: now used by 2 (_lu_fsm_assoc DMSC msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK DMSC msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH DREF VLR subscr IMSI-901700000010650 - _lu_fsm_associate_vsub: now used by 1 (active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre() DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Allocated DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU) DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START -GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f00a0101 +GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f02801020a0101 DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI DREF msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - mm_rx_loc_upd_req: now used by 2 (rx_from_ms,lu) DREF msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu) @@ -56,7 +53,7 @@ DREF VLR subscr IMSI-901700000010650 - vlr_gsup_rx: now used by 1 (active-conn) <-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT: vlr_gsupc_read_cb() returns 0 auth_request_sent == 1 lu_result_sent == 0 -- MS sends Authen Response, VLR accepts and sends GSUP LU Req to HLR +- Encryption disabled. MS sends Authen Response, VLR accepts and sends GSUP LU Req to HLR MSC <--GERAN-A-- MS: GSM48_MT_MM_AUTH_RESP DREF msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: + rx_from_ms: now used by 2 (lu,rx_from_ms) DBSSAP msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN decode: DTAP @@ -69,9 +66,11 @@ DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: Au DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU) -DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES +DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_SUCCESS DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth() DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_ciph() +DMSC msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(IMSI-901700000010650:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_node_4() DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD DVLR upd_hlr_vlr_fsm(IMSI-901700000010650:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated @@ -258,7 +257,7 @@ DBSSAP msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVIC DRLL msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: Dispatching 04.08 message: SMS SMS:0x01 DBSSAP msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: Message not permitted for initial conn: SMS:0x01 DBSSAP msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN decode error (rc=-13) for DTAP from MSC-I -- MS sends Authen Response, VLR accepts with a CM Service Accept +- Encryption disabled. MS sends Authen Response, VLR accepts with a CM Service Accept MSC <--GERAN-A-- MS: GSM48_MT_MM_AUTH_RESP DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: + rx_from_ms: now used by 2 (cm_service_sms,rx_from_ms) DBSSAP msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN decode: DTAP @@ -274,6 +273,8 @@ DVLR VLR_Authenticate(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A: DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: Received Event PR_ARQ_E_AUTH_RES DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2() DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2_post_ciph() +DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2_post_vlr() DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_pres() DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_trace() @@ -281,6 +282,7 @@ DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x0302010 DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: proc_arq_fsm_done(PASSED) DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: state_chg to PR_ARQ_S_DONE DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_DONE}: Process Access Request result: PASSED +DBSSAP msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: Sending DTAP: MM GSM48_MT_MM_CM_SERV_ACC DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN encode: DTAP on GERAN-A - DTAP --GERAN-A--> MS: GSM48_MT_MM_CM_SERV_ACC: 0521 DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST @@ -368,7 +370,7 @@ DMSC dummy_msc_i{0}: is child of msub_fsm DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms) DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3 DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: RR GSM48_MT_RR_PAG_RESP -DRR msc_a(IMSI-901700000010650:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: Rx PAGING RESPONSE +DRR msc_a(IMSI-901700000010650:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: Rx PAGING RESPONSE IMSI-901700000010650 DREF msc_a(IMSI-901700000010650:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: + paging-response: now used by 2 (rx_from_ms,paging-response) DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: Allocated DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: is child of msc_a(IMSI-901700000010650:GERAN-A:PAGING_RESP) @@ -411,7 +413,7 @@ DBSSAP msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:PAGING_RE DRLL msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: Dispatching 04.08 message: SMS SMS:0x01 DBSSAP msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: Message not permitted for initial conn: SMS:0x01 DBSSAP msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: RAN decode error (rc=-13) for DTAP from MSC-I -- MS sends Authen Response, VLR accepts and sends pending SMS +- Encryption disabled. MS sends Authen Response, VLR accepts and sends pending SMS MSC <--GERAN-A-- MS: GSM48_MT_MM_AUTH_RESP DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: + rx_from_ms: now used by 2 (paging-response,rx_from_ms) DBSSAP msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: RAN decode: DTAP @@ -427,6 +429,8 @@ DVLR VLR_Authenticate(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A: DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:PAGING_RESP){PR_ARQ_S_WAIT_AUTH}: Received Event PR_ARQ_E_AUTH_RES DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:PAGING_RESP){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2() DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:PAGING_RESP){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2_post_ciph() +DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:PAGING_RESP){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2_post_vlr() DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:PAGING_RESP){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_pres() DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:PAGING_RESP){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_trace() @@ -445,6 +449,7 @@ DLSMS SMC(0) send CP data DLSMS SMC(0) new CP state MM_CONN_PENDING -> WAIT_CP_ACK DLSMS trans(SMS IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:PAGING_RESP callref-0x40000001 tid-0) sending CP message (trans=0) DLSMS trans(SMS IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:PAGING_RESP callref-0x40000001 tid-0) GSM4.11 TX 09 01 58 01 00 07 91 44 77 58 10 06 50 00 4c 00 05 80 24 43 f2 00 00 07 10 10 00 00 00 00 44 50 79 da 1e 1e e7 41 69 37 48 5e 9e a7 c9 65 37 3d 1d 66 83 c2 70 38 3b 3d 0e d3 d3 6f f7 1c 94 9e 83 c2 20 72 79 9e 96 87 c5 ec 32 a8 1d 96 af cb f4 b4 fb 0c 7a c3 e9 e9 b7 db 05 +DBSSAP msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: Sending DTAP: SMS SMS:0x01 DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: RAN encode: DTAP on GERAN-A - DTAP --GERAN-A--> MS: SMS:0x01: 09015801000791447758100650004c0005802443f2000007101000000000445079da1e1ee7416937485e9ea7c965373d1d6683c270383b3d0ed3d36ff71c949e83c22072799e9687c5ec32a81d96afcbf4b4fb0c7ac3e9e9b7db05 - DTAP matches expected message @@ -481,6 +486,7 @@ DLSMS SMC(0) message MMSMS-DATA-IND (CP DATA) received in state MM_ESTABLISHED DLSMS SMC(0) received CP-DATA DLSMS trans(SMS IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:PAGING_RESP callref-0x40000001 tid-0) sending CP message (trans=0) DLSMS trans(SMS IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:PAGING_RESP callref-0x40000001 tid-0) GSM4.11 TX 09 04 +DBSSAP msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: Sending DTAP: SMS SMS:0x04 DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: RAN encode: DTAP on GERAN-A - DTAP --GERAN-A--> MS: SMS:0x04: 0904 - DTAP matches expected message @@ -553,12 +559,13 @@ DMSC dummy_msc_i{0}: is child of msub_fsm DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms) DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3 DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: MM GSM48_MT_MM_IMSI_DETACH_IND -DMM IMSI DETACH INDICATION: MI(IMSI)=901700000010650 +DMM IMSI DETACH INDICATION: IMSI-901700000010650 DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + gsm48_rx_mm_imsi_detach_ind: now used by 2 (attached,gsm48_rx_mm_imsi_detach_ind) DMM IMSI DETACH for IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + active-conn: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn) DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn,vlr_subscr_cancel_attach_fsm) DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - attached: now used by 2 (gsm48_rx_mm_imsi_detach_ind,active-conn) DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - gsm48_rx_mm_imsi_detach_ind: now used by 1 (active-conn) DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_CN_CLOSE @@ -598,9 +605,6 @@ DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:NONE){MSC_A llist_count(&msub_list) == 0 ===== test_umts_authen_geran: SUCCESS -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 17 - ===== test_umts_authen_utran - Location Update request causes a GSUP Send Auth Info request to HLR MSC <--UTRAN-Iu-- MS: GSM48_MT_MM_LOC_UPD_REQUEST @@ -620,7 +624,7 @@ DREF msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_VALIDATE_L3}: + mm_rx_loc_ DREF msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_VALIDATE_L3}: + lu: now used by 3 (rx_from_ms,mm_rx_loc_upd_req,lu) DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: Allocated DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: is child of msc_a(IMSI-901700000010650:UTRAN-Iu:LU) -DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: rev=R99 net=UTRAN Auth+Ciph +DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: rev=R99 net=UTRAN Auth (no Ciph) DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA DREF VLR subscr unknown + _lu_fsm_associate_vsub: now used by 1 (_lu_fsm_associate_vsub) DVLR set IMSI on subscriber; IMSI=901700000010650 id=901700000010650 @@ -629,13 +633,14 @@ DREF VLR subscr IMSI-901700000010650 + active-conn: now used by 2 (_lu_fsm_assoc DMSC msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK DMSC msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH DREF VLR subscr IMSI-901700000010650 - _lu_fsm_associate_vsub: now used by 1 (active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre() DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: Allocated DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU) DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START -GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f00a0101 +GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f02801020a0101 DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI DREF msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: - mm_rx_loc_upd_req: now used by 2 (rx_from_ms,lu) DREF msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu) @@ -655,7 +660,7 @@ DREF VLR subscr IMSI-901700000010650 - vlr_gsup_rx: now used by 1 (active-conn) <-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT: vlr_gsupc_read_cb() returns 0 auth_request_sent == 1 lu_result_sent == 0 -- MS sends Authen Response, VLR accepts and sends SecurityModeControl +- Encryption disabled. MS sends Authen Response, VLR accepts and sends SecurityModeControl MSC <--UTRAN-Iu-- MS: GSM48_MT_MM_AUTH_RESP DREF msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: + rx_from_ms: now used by 2 (lu,rx_from_ms) DIUCS msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: RAN decode: DTAP @@ -668,7 +673,7 @@ DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_WAIT_RESP}: A DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU) -DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES +DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_SUCCESS DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth() DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: Set Ciphering Mode DMSC msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: CIPHER_MODE_COMMAND on UTRAN-Iu @@ -829,7 +834,7 @@ DMM msc_a(IMSI-901700000010650:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_VALIDATE_L3}: R DREF msc_a(IMSI-901700000010650:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_VALIDATE_L3}: + cm_service_sms: now used by 2 (rx_from_ms,cm_service_sms) DVLR Process_Access_Request_VLR(IMSI-901700000010650:UTRAN-Iu:CM_SERVICE_REQ){PR_ARQ_S_INIT}: Allocated DVLR Process_Access_Request_VLR(IMSI-901700000010650:UTRAN-Iu:CM_SERVICE_REQ){PR_ARQ_S_INIT}: is child of msc_a(IMSI-901700000010650:UTRAN-Iu:CM_SERVICE_REQ) -DVLR Process_Access_Request_VLR(IMSI-901700000010650:UTRAN-Iu:CM_SERVICE_REQ){PR_ARQ_S_INIT}: rev=R99 net=UTRAN Auth+Ciph +DVLR Process_Access_Request_VLR(IMSI-901700000010650:UTRAN-Iu:CM_SERVICE_REQ){PR_ARQ_S_INIT}: rev=R99 net=UTRAN Auth (no Ciph) DVLR Process_Access_Request_VLR(IMSI-901700000010650:UTRAN-Iu:CM_SERVICE_REQ){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + proc_arq_vlr_fn_init: now used by 2 (attached,proc_arq_vlr_fn_init) DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + active-conn: now used by 3 (attached,proc_arq_vlr_fn_init,active-conn) @@ -869,7 +874,7 @@ DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVIC DRLL msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: Dispatching 04.08 message: SMS SMS:0x01 DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: Message not permitted for initial conn: SMS:0x01 DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN decode error (rc=-13) for DTAP from MSC-I -- MS sends Authen Response, VLR accepts and sends SecurityModeControl +- Encryption disabled. MS sends Authen Response, VLR accepts and sends SecurityModeControl MSC <--UTRAN-Iu-- MS: GSM48_MT_MM_AUTH_RESP DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: + rx_from_ms: now used by 2 (cm_service_sms,rx_from_ms) DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN decode: DTAP @@ -988,11 +993,11 @@ DMSC dummy_msc_i{0}: is child of msub_fsm DREF msc_a(unknown:UTRAN-Iu:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms) DIUCS msc_a(unknown:UTRAN-Iu:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3 DRLL msc_a(unknown:UTRAN-Iu:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: RR GSM48_MT_RR_PAG_RESP -DRR msc_a(IMSI-901700000010650:UTRAN-Iu:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: Rx PAGING RESPONSE +DRR msc_a(IMSI-901700000010650:UTRAN-Iu:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: Rx PAGING RESPONSE IMSI-901700000010650 DREF msc_a(IMSI-901700000010650:UTRAN-Iu:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: + paging-response: now used by 2 (rx_from_ms,paging-response) DVLR Process_Access_Request_VLR(IMSI-901700000010650:UTRAN-Iu:PAGING_RESP){PR_ARQ_S_INIT}: Allocated DVLR Process_Access_Request_VLR(IMSI-901700000010650:UTRAN-Iu:PAGING_RESP){PR_ARQ_S_INIT}: is child of msc_a(IMSI-901700000010650:UTRAN-Iu:PAGING_RESP) -DVLR Process_Access_Request_VLR(IMSI-901700000010650:UTRAN-Iu:PAGING_RESP){PR_ARQ_S_INIT}: rev=R99 net=UTRAN Auth+Ciph +DVLR Process_Access_Request_VLR(IMSI-901700000010650:UTRAN-Iu:PAGING_RESP){PR_ARQ_S_INIT}: rev=R99 net=UTRAN Auth (no Ciph) DVLR Process_Access_Request_VLR(IMSI-901700000010650:UTRAN-Iu:PAGING_RESP){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + proc_arq_vlr_fn_init: now used by 5 (attached,SMS-receiver,SMS,Paging,proc_arq_vlr_fn_init) DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + active-conn: now used by 6 (attached,SMS-receiver,SMS,Paging,proc_arq_vlr_fn_init,active-conn) @@ -1031,7 +1036,7 @@ DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RE DRLL msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: Dispatching 04.08 message: SMS SMS:0x01 DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: Message not permitted for initial conn: SMS:0x01 DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: RAN decode error (rc=-13) for DTAP from MSC-I -- MS sends Authen Response, VLR accepts and sends SecurityModeControl +- Encryption disabled. MS sends Authen Response, VLR accepts and sends SecurityModeControl MSC <--UTRAN-Iu-- MS: GSM48_MT_MM_AUTH_RESP DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: + rx_from_ms: now used by 2 (paging-response,rx_from_ms) DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: RAN decode: DTAP @@ -1078,6 +1083,7 @@ DLSMS SMC(0) send CP data DLSMS SMC(0) new CP state MM_CONN_PENDING -> WAIT_CP_ACK DLSMS trans(SMS IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x40000002 tid-0) sending CP message (trans=0) DLSMS trans(SMS IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x40000002 tid-0) GSM4.11 TX 09 01 58 01 00 07 91 44 77 58 10 06 50 00 4c 00 05 80 24 43 f2 00 00 07 10 10 00 00 00 00 44 50 79 da 1e 1e e7 41 69 37 48 5e 9e a7 c9 65 37 3d 1d 66 83 c2 70 38 3b 3d 0e d3 d3 6f f7 1c 94 9e 83 c2 20 72 79 9e 96 87 c5 ec 32 a8 1d 96 af cb f4 b4 fb 0c 7a c3 e9 e9 b7 db 05 +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: Sending DTAP: SMS SMS:0x01 DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: RAN encode: DTAP on UTRAN-Iu - DTAP --UTRAN-Iu--> MS: SMS:0x01: 09015801000791447758100650004c0005802443f2000007101000000000445079da1e1ee7416937485e9ea7c965373d1d6683c270383b3d0ed3d36ff71c949e83c22072799e9687c5ec32a81d96afcbf4b4fb0c7ac3e9e9b7db05 - DTAP matches expected message @@ -1111,6 +1117,7 @@ DLSMS SMC(0) message MMSMS-DATA-IND (CP DATA) received in state MM_ESTABLISHED DLSMS SMC(0) received CP-DATA DLSMS trans(SMS IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x40000002 tid-0) sending CP message (trans=0) DLSMS trans(SMS IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x40000002 tid-0) GSM4.11 TX 09 04 +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: Sending DTAP: SMS SMS:0x04 DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: RAN encode: DTAP on UTRAN-Iu - DTAP --UTRAN-Iu--> MS: SMS:0x04: 0904 - DTAP matches expected message @@ -1183,12 +1190,13 @@ DMSC dummy_msc_i{0}: is child of msub_fsm DREF msc_a(unknown:UTRAN-Iu:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms) DIUCS msc_a(unknown:UTRAN-Iu:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3 DRLL msc_a(unknown:UTRAN-Iu:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: MM GSM48_MT_MM_IMSI_DETACH_IND -DMM IMSI DETACH INDICATION: MI(IMSI)=901700000010650 +DMM IMSI DETACH INDICATION: IMSI-901700000010650 DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + gsm48_rx_mm_imsi_detach_ind: now used by 2 (attached,gsm48_rx_mm_imsi_detach_ind) DMM IMSI DETACH for IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + active-conn: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn) DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn,vlr_subscr_cancel_attach_fsm) DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - attached: now used by 2 (gsm48_rx_mm_imsi_detach_ind,active-conn) DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - gsm48_rx_mm_imsi_detach_ind: now used by 1 (active-conn) DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:NONE){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_CN_CLOSE @@ -1228,8 +1236,636 @@ DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:NONE){MSC_ llist_count(&msub_list) == 0 ===== test_umts_authen_utran: SUCCESS -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 17 +===== test_umts_auth_ciph_utran +- Location Update request causes a GSUP Send Auth Info request to HLR + MSC <--UTRAN-Iu-- MS: GSM48_MT_MM_LOC_UPD_REQUEST + new conn +DMSC msub_fsm{active}: Allocated +DMSC msc_a{MSC_A_ST_VALIDATE_L3}: Allocated +DMSC msc_a{MSC_A_ST_VALIDATE_L3}: is child of msub_fsm +DMSC msc_a(unknown:UTRAN-Iu:NONE){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_VALIDATE_L3 +DMSC dummy_msc_i{0}: Allocated +DMSC dummy_msc_i{0}: is child of msub_fsm +DREF msc_a(unknown:UTRAN-Iu:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms) +DIUCS msc_a(unknown:UTRAN-Iu:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3 +DRLL msc_a(unknown:UTRAN-Iu:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: MM GSM48_MT_MM_LOC_UPD_REQUEST +DMM msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_VALIDATE_L3}: LOCATION UPDATING REQUEST: MI=IMSI-901700000010650 LU-type=NORMAL +DMM msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_VALIDATE_L3}: USIM: old LAI: 1665-165-0 +DREF msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_VALIDATE_L3}: + mm_rx_loc_upd_req: now used by 2 (rx_from_ms,mm_rx_loc_upd_req) +DREF msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_VALIDATE_L3}: + lu: now used by 3 (rx_from_ms,mm_rx_loc_upd_req,lu) +DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: Allocated +DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: is child of msc_a(IMSI-901700000010650:UTRAN-Iu:LU) +DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: rev=R99 net=UTRAN Auth+Ciph +DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA +DREF VLR subscr unknown + _lu_fsm_associate_vsub: now used by 1 (_lu_fsm_associate_vsub) +DVLR set IMSI on subscriber; IMSI=901700000010650 id=901700000010650 +DVLR New subscr, IMSI: 901700000010650 +DREF VLR subscr IMSI-901700000010650 + active-conn: now used by 2 (_lu_fsm_associate_vsub,active-conn) +DMSC msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK +DMSC msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH +DREF VLR subscr IMSI-901700000010650 - _lu_fsm_associate_vsub: now used by 1 (active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) +DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre() +DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() +DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH +DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: Allocated +DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU) +DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START +GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f02801020a0101 +DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI +DREF msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: - mm_rx_loc_upd_req: now used by 2 (rx_from_ms,lu) +DREF msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu) + lu_result_sent == 0 +- from HLR, rx _SEND_AUTH_INFO_RESULT; VLR sends Auth Req to MS +<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT: 0a010809710000000156f00362201039fa2f4e3d523d8619a73b4f65c3e14d21049b36efdf2208059a4f668f6fbe39231027497388b6cb044648f396aa155b95ef2410f64735036e5871319c679f4742a75ea125108704f5ba55f30000d2ee44b22c8ea9192708e229c19e791f2e4103622010c187a53a5e6b9d573cac7c74451fd46d210485aa31302208d3d50a000bf04f6e23101159ec926a50e98c034a6b7d7c9f418d2410df3a03d9ca5335641efc8e36d76cd20b25101843a645b98d00005b2d666af46c45d927087db47cf7f81e4dc703622010efa9c29a9742148d5c9070348716e1bb210469d5f9fb22083df176f0c29f1a3d2310eb50e770ddcc3060101d2f43b6c2b884241076542abce5ff9345b0e8947f4c6e019c2510f9375e6d41e1000096e7fe4ff1c27e392708706f996719ba609c03622010f023d5a3b24726e0631b64b3840f82532104d570c03f2208ec011be8919883d62310c4e58af4ba43f3bcd904e16984f086d724100593f65e752e5cb7f473862bda05aa0a2510541ff1f077270000c5ea00d658bc7e9a27083fd26072eaa2a04d036220102f8f90c780d6a9c0c53da7ac57b6707e2104b072446f220823f39f9f425ad6e6231065af0527fda95b0dc5ae4aa515cdf32f2410537c3b35a3b13b08d08eeb28098f45cc25104bf4e564f75300009bc796706bc6574427080edb0eadbea94ac20a0101 +DREF VLR subscr IMSI-901700000010650 + vlr_gsup_rx: now used by 2 (active-conn,vlr_gsup_rx) +DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: Received Event VLR_AUTH_E_HLR_SAI_ACK +DVLR SUBSCR(IMSI-901700000010650) Received 5 auth tuples +DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: state_chg to VLR_SUB_AS_WAIT_RESP +DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_WAIT_RESP}: got auth tuple: use_count=1 key_seq=0 -- will use UMTS AKA (is_r99=yes, at->vec.auth_types=0x3) +- sending UMTS Auth Request for IMSI-901700000010650:UTRAN-Iu:LU: tuple use_count=1 key_seq=0 auth_types=0x3 and... +- ...rand=39fa2f4e3d523d8619a73b4f65c3e14d +- ...autn=8704f5ba55f30000d2ee44b22c8ea919 +- ...expecting res=e229c19e791f2e41 +DREF VLR subscr IMSI-901700000010650 - vlr_gsup_rx: now used by 1 (active-conn) +<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT: vlr_gsupc_read_cb() returns 0 + auth_request_sent == 1 + lu_result_sent == 0 +- Encryption enabled. MS sends Authen Response, VLR accepts and sends SecurityModeControl + MSC <--UTRAN-Iu-- MS: GSM48_MT_MM_AUTH_RESP +DREF msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: + rx_from_ms: now used by 2 (lu,rx_from_ms) +DIUCS msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: RAN decode: DTAP +DRLL msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: Dispatching 04.08 message: MM GSM48_MT_MM_AUTH_RESP +DMM msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: MM UMTS AUTHENTICATION RESPONSE (res = e229c19e791f2e41) +DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP +DVLR SUBSCR(IMSI-901700000010650) AUTH on UTRAN received RES: e229c19e791f2e41 (8 bytes) +DVLR SUBSCR(IMSI-901700000010650) AUTH established UMTS security context +DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result PASSED +DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED +DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) +DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU) +DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_SUCCESS +DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth() +DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: Set Ciphering Mode +DMSC msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: CIPHER_MODE_COMMAND on UTRAN-Iu +- sending SecurityModeControl: ik=27497388b6cb044648f396aa155b95ef +DMSC dummy_msc_i(IMSI-901700000010650:UTRAN-Iu:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST +DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_WAIT_CIPH +DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_AUTHENTICATED}: Deallocated +DREF msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu) + security_mode_ctrl_sent == 1 + lu_result_sent == 0 +- MS sends SecurityModeControl acceptance, VLR accepts and sends GSUP LU Req to HLR +DIUCS msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: RAN decode: CIPHER_MODE_COMPLETE +DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_CIPH}: Received Event VLR_ULA_E_CIPH_RES +DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_CIPH}: vlr_loc_upd_post_ciph() +DMSC msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on UTRAN-Iu +DMSC dummy_msc_i(IMSI-901700000010650:UTRAN-Iu:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST +DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_CIPH}: vlr_loc_upd_node_4() +DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_CIPH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD +DVLR upd_hlr_vlr_fsm(IMSI-901700000010650:UTRAN-Iu:LU){UPD_HLR_VLR_S_INIT}: Allocated +DVLR upd_hlr_vlr_fsm(IMSI-901700000010650:UTRAN-Iu:LU){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU) +DVLR upd_hlr_vlr_fsm(IMSI-901700000010650:UTRAN-Iu:LU){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START +GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000000156f02801020a0101 +DVLR upd_hlr_vlr_fsm(IMSI-901700000010650:UTRAN-Iu:LU){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA + gsup_tx_confirmed == 1 + lu_result_sent == 0 +- HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT +<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: 10010809710000000156f00804032443f20a0101 +DREF VLR subscr IMSI-901700000010650 + vlr_gsup_rx: now used by 2 (active-conn,vlr_gsup_rx) +DVLR IMSI:901700000010650 has MSISDN:42342 +DVLR SUBSCR(IMSI-901700000010650:MSISDN-42342) VLR: update for IMSI=901700000010650 (MSISDN=42342) +GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000000156f00a0101 +DREF VLR subscr IMSI-901700000010650:MSISDN-42342 - vlr_gsup_rx: now used by 1 (active-conn) +<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: vlr_gsupc_read_cb() returns 0 + lu_result_sent == 0 +- HLR also sends GSUP _UPDATE_LOCATION_RESULT +<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: 06010809710000000156f00a0101 +DREF VLR subscr IMSI-901700000010650:MSISDN-42342 + vlr_gsup_rx: now used by 2 (active-conn,vlr_gsup_rx) +DVLR vlr_lu_fsm(IMSI-901700000010650:MSISDN-42342:UTRAN-Iu:LU){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES +DVLR upd_hlr_vlr_fsm(IMSI-901700000010650:UTRAN-Iu:LU){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK +DVLR upd_hlr_vlr_fsm(IMSI-901700000010650:UTRAN-Iu:LU){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE +DVLR upd_hlr_vlr_fsm(IMSI-901700000010650:UTRAN-Iu:LU){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR) +DVLR upd_hlr_vlr_fsm(IMSI-901700000010650:UTRAN-Iu:LU){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(IMSI-901700000010650:MSISDN-42342:UTRAN-Iu:LU) +DVLR vlr_lu_fsm(IMSI-901700000010650:MSISDN-42342:UTRAN-Iu:LU){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL +DVLR vlr_lu_fsm(IMSI-901700000010650:MSISDN-42342:UTRAN-Iu:LU){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL +DVLR lu_compl_vlr_fsm(IMSI-901700000010650:MSISDN-42342:UTRAN-Iu:LU){LU_COMPL_VLR_S_INIT}: Allocated +DVLR lu_compl_vlr_fsm(IMSI-901700000010650:MSISDN-42342:UTRAN-Iu:LU){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(IMSI-901700000010650:MSISDN-42342:UTRAN-Iu:LU) +DVLR lu_compl_vlr_fsm(IMSI-901700000010650:MSISDN-42342:UTRAN-Iu:LU){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START +DVLR lu_compl_vlr_fsm(IMSI-901700000010650:MSISDN-42342:UTRAN-Iu:LU){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES +DVLR lu_compl_vlr_fsm(IMSI-901700000010650:MSISDN-42342:UTRAN-Iu:LU){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL +DVLR lu_compl_vlr_fsm(IMSI-901700000010650:MSISDN-42342:UTRAN-Iu:LU){LU_COMPL_VLR_S_WAIT_SUB_PRES}: lu_compl_vlr_new_tmsi() +DVLR SUBSCR(IMSI-901700000010650:MSISDN-42342:TMSInew-0x03020100) VLR: update for IMSI=901700000010650 (MSISDN=42342) +DVLR lu_compl_vlr_fsm(IMSI-901700000010650:MSISDN-42342:UTRAN-Iu:LU){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_WAIT_TMSI_CNF +- sending LU Accept for IMSI-901700000010650:MSISDN-42342:TMSInew-0x03020100:UTRAN-Iu:LU, with TMSI 0x03020100 +DVLR upd_hlr_vlr_fsm(IMSI-901700000010650:UTRAN-Iu:LU){UPD_HLR_VLR_S_DONE}: Deallocated +DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSInew-0x03020100 - vlr_gsup_rx: now used by 1 (active-conn) +<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: vlr_gsupc_read_cb() returns 0 + lu_result_sent == 1 +- a LU Accept with a new TMSI was sent, waiting for TMSI Realloc Compl + llist_count(&msub_list) == 1 +msc_a_is_accepted() == false + requests shall be thwarted +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSInew-0x03020100:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: RAN decode: DTAP +DRLL msc_a(IMSI-901700000010650:MSISDN-42342:TMSInew-0x03020100:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: Dispatching 04.08 message: CC GSM48_MT_CC_SETUP +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSInew-0x03020100:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: Message not permitted for initial conn: GSM48_MT_CC_SETUP +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSInew-0x03020100:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: RAN decode error (rc=-13) for DTAP from MSC-I +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSInew-0x03020100:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: RAN decode: DTAP +DRLL msc_a(IMSI-901700000010650:MSISDN-42342:TMSInew-0x03020100:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: Dispatching 04.08 message: MM unknown 0x33 +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSInew-0x03020100:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: Message not permitted for initial conn: unknown 0x33 +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSInew-0x03020100:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: RAN decode error (rc=-13) for DTAP from MSC-I +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSInew-0x03020100:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: RAN decode: DTAP +DRLL msc_a(IMSI-901700000010650:MSISDN-42342:TMSInew-0x03020100:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: Dispatching 04.08 message: RR GSM48_MT_RR_SYSINFO_1 +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSInew-0x03020100:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1 +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSInew-0x03020100:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: RAN decode error (rc=-13) for DTAP from MSC-I +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSInew-0x03020100:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: RAN decode: DTAP +DRLL msc_a(IMSI-901700000010650:MSISDN-42342:TMSInew-0x03020100:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: Dispatching 04.08 message: SMS SMS:0x01 +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSInew-0x03020100:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: Message not permitted for initial conn: SMS:0x01 +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSInew-0x03020100:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: RAN decode error (rc=-13) for DTAP from MSC-I +- even though the TMSI is not acked, we can already find the subscr with it +DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSInew-0x03020100 + _test_umts_authen: now used by 2 (active-conn,_test_umts_authen) + vsub != NULL == 1 + strcmp(vsub->imsi, imsi) == 0 + vsub->tmsi_new == 0x03020100 + vsub->tmsi == 0xffffffff +DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSInew-0x03020100 - _test_umts_authen: now used by 1 (active-conn) +- MS sends TMSI Realloc Complete + MSC <--UTRAN-Iu-- MS: GSM48_MT_MM_TMSI_REALL_COMPL +DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSInew-0x03020100:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: + rx_from_ms: now used by 2 (lu,rx_from_ms) +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSInew-0x03020100:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: RAN decode: DTAP +DRLL msc_a(IMSI-901700000010650:MSISDN-42342:TMSInew-0x03020100:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: Dispatching 04.08 message: MM GSM48_MT_MM_TMSI_REALL_COMPL +DMM msc_a(IMSI-901700000010650:MSISDN-42342:TMSInew-0x03020100:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: TMSI Reallocation Completed +DVLR vlr_lu_fsm(IMSI-901700000010650:MSISDN-42342:TMSInew-0x03020100:UTRAN-Iu:LU){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_NEW_TMSI_ACK +DVLR lu_compl_vlr_fsm(IMSI-901700000010650:MSISDN-42342:UTRAN-Iu:LU){LU_COMPL_VLR_S_WAIT_TMSI_CNF}: Received Event LU_COMPL_VLR_E_NEW_TMSI_ACK +DVLR SUBSCR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100) VLR: update for IMSI=901700000010650 (MSISDN=42342) +DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + attached: now used by 2 (active-conn,attached) +DVLR lu_compl_vlr_fsm(IMSI-901700000010650:MSISDN-42342:UTRAN-Iu:LU){LU_COMPL_VLR_S_WAIT_TMSI_CNF}: state_chg to LU_COMPL_VLR_S_DONE +DVLR vlr_lu_fsm(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS +DVLR lu_compl_vlr_fsm(IMSI-901700000010650:MSISDN-42342:UTRAN-Iu:LU){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) +DVLR lu_compl_vlr_fsm(IMSI-901700000010650:MSISDN-42342:UTRAN-Iu:LU){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU) +DVLR lu_compl_vlr_fsm(IMSI-901700000010650:MSISDN-42342:UTRAN-Iu:LU){LU_COMPL_VLR_S_DONE}: Deallocated +DVLR vlr_lu_fsm(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE +DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: Received Event MSC_A_EV_AUTHENTICATED +DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: state_chg to MSC_A_ST_AUTHENTICATED +DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){MSC_A_ST_AUTHENTICATED}: - lu: now used by 1 (rx_from_ms) +DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){MSC_A_ST_AUTHENTICATED}: - rx_from_ms: now used by 0 (-) +DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){MSC_A_ST_AUTHENTICATED}: Received Event MSC_A_EV_UNUSED +DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){MSC_A_ST_AUTHENTICATED}: state_chg to MSC_A_ST_RELEASING +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){MSC_A_ST_RELEASING}: Releasing: msc_a use is 0 (-) +DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + msc_a_fsm_releasing_onenter: now used by 3 (active-conn,attached,msc_a_fsm_releasing_onenter) +DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + vlr_subscr_cancel_attach_fsm: now used by 4 (active-conn,attached,msc_a_fsm_releasing_onenter,vlr_subscr_cancel_attach_fsm) +DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - vlr_subscr_cancel_attach_fsm: now used by 3 (active-conn,attached,msc_a_fsm_releasing_onenter) +DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){MSC_A_ST_RELEASING}: + wait-Clear-Complete: now used by 1 (wait-Clear-Complete) +DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){MSC_A_ST_RELEASING}: RAN encode: CLEAR_COMMAND on UTRAN-Iu +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST +DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - msc_a_fsm_releasing_onenter: now used by 2 (active-conn,attached) + iu_release_sent == 1 +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){MSC_A_ST_RELEASING}: RAN decode: CLEAR_COMPLETE +DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){MSC_A_ST_RELEASING}: - wait-Clear-Complete: now used by 0 (-) +DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){MSC_A_ST_RELEASING}: Received Event MSC_A_EV_UNUSED +DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){MSC_A_ST_RELEASING}: state_chg to MSC_A_ST_RELEASED +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){MSC_A_ST_RELEASED}: Released: msc_a use is 0 (-) +DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){MSC_A_ST_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) +DVLR vlr_lu_fsm(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){VLR_ULA_S_DONE}: Terminating in cascade, depth 2 (cause = OSMO_FSM_TERM_PARENT, caused by: msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU)) +DVLR vlr_lu_fsm(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){VLR_ULA_S_DONE}: Removing from parent msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU) +DVLR vlr_lu_fsm(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT +DVLR vlr_lu_fsm(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){VLR_ULA_S_DONE}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU) +DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){MSC_A_ST_RELEASED}: Removing from parent msub_fsm +DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){MSC_A_ST_RELEASED}: max total use count was 3 +DMSC msub_fsm{active}: Received Event MSUB_EV_ROLE_TERMINATED +DMSC msub(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100) MSC-A terminated +DMSC msub(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100) 1 MSC-I still active +DMSC msub_fsm{active}: state_chg to terminating +DMSC msub_fsm{terminating}: Terminating in cascade, depth 2 (cause = OSMO_FSM_TERM_REGULAR, caused by: msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU)) +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){0}: Terminating in cascade, depth 3 (cause = OSMO_FSM_TERM_PARENT, caused by: msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU)) +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){0}: Removing from parent msub_fsm +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){0}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU) +DMSC msub(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100) Free +DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - active-conn: now used by 1 (attached) +DMSC msub_fsm{terminating}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU) +DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){MSC_A_ST_RELEASED}: Deallocated, including all deferred deallocations +- msub gone +- LU was successful, and the conn has already been closed + llist_count(&msub_list) == 0 + + +- after a while, a new conn sends a CM Service Request. VLR responds with Auth Req, 2nd auth vector + MSC <--UTRAN-Iu-- MS: GSM48_MT_MM_CM_SERV_REQ + new conn +DMSC msub_fsm{active}: Allocated +DMSC msc_a{MSC_A_ST_VALIDATE_L3}: Allocated +DMSC msc_a{MSC_A_ST_VALIDATE_L3}: is child of msub_fsm +DMSC msc_a(unknown:UTRAN-Iu:NONE){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_VALIDATE_L3 +DMSC dummy_msc_i{0}: Allocated +DMSC dummy_msc_i{0}: is child of msub_fsm +DREF msc_a(unknown:UTRAN-Iu:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms) +DIUCS msc_a(unknown:UTRAN-Iu:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3 +DRLL msc_a(unknown:UTRAN-Iu:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: MM GSM48_MT_MM_CM_SERV_REQ +DMM msc_a(IMSI-901700000010650:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_VALIDATE_L3}: Rx CM SERVICE REQUEST cm_service_type=Short-Messaging-Service +DREF msc_a(IMSI-901700000010650:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_VALIDATE_L3}: + cm_service_sms: now used by 2 (rx_from_ms,cm_service_sms) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:UTRAN-Iu:CM_SERVICE_REQ){PR_ARQ_S_INIT}: Allocated +DVLR Process_Access_Request_VLR(IMSI-901700000010650:UTRAN-Iu:CM_SERVICE_REQ){PR_ARQ_S_INIT}: is child of msc_a(IMSI-901700000010650:UTRAN-Iu:CM_SERVICE_REQ) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:UTRAN-Iu:CM_SERVICE_REQ){PR_ARQ_S_INIT}: rev=R99 net=UTRAN Auth+Ciph +DVLR Process_Access_Request_VLR(IMSI-901700000010650:UTRAN-Iu:CM_SERVICE_REQ){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START +DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + proc_arq_vlr_fn_init: now used by 2 (attached,proc_arq_vlr_fn_init) +DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + active-conn: now used by 3 (attached,proc_arq_vlr_fn_init,active-conn) +DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK +DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi() +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_WAIT_AUTH +DVLR VLR_Authenticate(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){VLR_SUB_AS_NEEDS_AUTH}: Allocated +DVLR VLR_Authenticate(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){VLR_SUB_AS_NEEDS_AUTH}: is child of Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ) +DVLR VLR_Authenticate(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START +DVLR VLR_Authenticate(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_WAIT_RESP +DVLR VLR_Authenticate(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){VLR_SUB_AS_WAIT_RESP}: got auth tuple: use_count=1 key_seq=1 -- will use UMTS AKA (is_r99=yes, at->vec.auth_types=0x3) +- sending UMTS Auth Request for IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ: tuple use_count=1 key_seq=1 auth_types=0x3 and... +- ...rand=c187a53a5e6b9d573cac7c74451fd46d +- ...autn=1843a645b98d00005b2d666af46c45d9 +- ...expecting res=7db47cf7f81e4dc7 +DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - proc_arq_vlr_fn_init: now used by 2 (attached,active-conn) +DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (cm_service_sms) + cm_service_result_sent == 0 + auth_request_sent == 1 +- needs auth, not yet accepted +msc_a_is_accepted() == false + requests shall be thwarted +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN decode: DTAP +DRLL msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: Dispatching 04.08 message: CC GSM48_MT_CC_SETUP +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: Message not permitted for initial conn: GSM48_MT_CC_SETUP +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN decode error (rc=-13) for DTAP from MSC-I +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN decode: DTAP +DRLL msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: Dispatching 04.08 message: MM unknown 0x33 +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: Message not permitted for initial conn: unknown 0x33 +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN decode error (rc=-13) for DTAP from MSC-I +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN decode: DTAP +DRLL msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: Dispatching 04.08 message: RR GSM48_MT_RR_SYSINFO_1 +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1 +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN decode error (rc=-13) for DTAP from MSC-I +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN decode: DTAP +DRLL msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: Dispatching 04.08 message: SMS SMS:0x01 +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: Message not permitted for initial conn: SMS:0x01 +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN decode error (rc=-13) for DTAP from MSC-I +- Encryption enabled. MS sends Authen Response, VLR accepts and sends SecurityModeControl + MSC <--UTRAN-Iu-- MS: GSM48_MT_MM_AUTH_RESP +DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: + rx_from_ms: now used by 2 (cm_service_sms,rx_from_ms) +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN decode: DTAP +DRLL msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: Dispatching 04.08 message: MM GSM48_MT_MM_AUTH_RESP +DMM msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: MM UMTS AUTHENTICATION RESPONSE (res = 7db47cf7f81e4dc7) +DVLR VLR_Authenticate(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP +DVLR SUBSCR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100) AUTH on UTRAN received RES: 7db47cf7f81e4dc7 (8 bytes) +DVLR SUBSCR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100) AUTH established UMTS security context +DVLR VLR_Authenticate(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result PASSED +DVLR VLR_Authenticate(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED +DVLR VLR_Authenticate(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) +DVLR VLR_Authenticate(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){VLR_SUB_AS_AUTHENTICATED}: Removing from parent Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: Received Event PR_ARQ_E_AUTH_RES +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2() +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: Set Ciphering Mode +DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN encode: CIPHER_MODE_COMMAND on UTRAN-Iu +- sending SecurityModeControl: ik=1159ec926a50e98c034a6b7d7c9f418d +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: state_chg to PR_ARQ_S_WAIT_CIPH +DVLR VLR_Authenticate(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){VLR_SUB_AS_AUTHENTICATED}: Deallocated +DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (cm_service_sms) + security_mode_ctrl_sent == 1 + cm_service_result_sent == 0 +- MS sends SecurityModeControl acceptance, VLR accepts; above Ciphering is an implicit CM Service Accept +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN decode: CIPHER_MODE_COMPLETE +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){PR_ARQ_S_WAIT_CIPH}: Received Event PR_ARQ_E_CIPH_RES +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_node2_post_ciph() +DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on UTRAN-Iu +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_node2_post_vlr() +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_pres() +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_trace() +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_imei() +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){PR_ARQ_S_WAIT_CIPH}: proc_arq_fsm_done(PASSED) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){PR_ARQ_S_WAIT_CIPH}: state_chg to PR_ARQ_S_DONE +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){PR_ARQ_S_DONE}: Process Access Request result: PASSED +DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: Received Event MSC_A_EV_AUTHENTICATED +DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: state_chg to MSC_A_ST_AUTHENTICATED + cm_service_result_sent == 0 +- Concluding CM Service Request +DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: - cm_service_sms: now used by 0 (-) +DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: Received Event MSC_A_EV_UNUSED +DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: state_chg to MSC_A_ST_RELEASING +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: Releasing: msc_a use is 0 (-) +DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + msc_a_fsm_releasing_onenter: now used by 3 (attached,active-conn,msc_a_fsm_releasing_onenter) +DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,active-conn,msc_a_fsm_releasing_onenter,vlr_subscr_cancel_attach_fsm) +DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,active-conn,msc_a_fsm_releasing_onenter) +DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: + wait-Clear-Complete: now used by 1 (wait-Clear-Complete) +DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: RAN encode: CLEAR_COMMAND on UTRAN-Iu +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST +DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - msc_a_fsm_releasing_onenter: now used by 2 (attached,active-conn) + iu_release_sent == 1 +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: RAN decode: CLEAR_COMPLETE +DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: - wait-Clear-Complete: now used by 0 (-) +DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: Received Event MSC_A_EV_UNUSED +DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: state_chg to MSC_A_ST_RELEASED +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_RELEASED}: Released: msc_a use is 0 (-) +DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){PR_ARQ_S_DONE}: Terminating in cascade, depth 2 (cause = OSMO_FSM_TERM_PARENT, caused by: msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ)) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){PR_ARQ_S_DONE}: Removing from parent msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){PR_ARQ_S_DONE}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ) +DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_RELEASED}: Removing from parent msub_fsm +DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_RELEASED}: max total use count was 2 +DMSC msub_fsm{active}: Received Event MSUB_EV_ROLE_TERMINATED +DMSC msub(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100) MSC-A terminated +DMSC msub(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100) 1 MSC-I still active +DMSC msub_fsm{active}: state_chg to terminating +DMSC msub_fsm{terminating}: Terminating in cascade, depth 2 (cause = OSMO_FSM_TERM_REGULAR, caused by: msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ)) +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){0}: Terminating in cascade, depth 3 (cause = OSMO_FSM_TERM_PARENT, caused by: msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ)) +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){0}: Removing from parent msub_fsm +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){0}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ) +DMSC msub(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100) Free +DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - active-conn: now used by 1 (attached) +DMSC msub_fsm{terminating}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ) +DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_RELEASED}: Deallocated, including all deferred deallocations +- msub gone +- all requests serviced, conn has been released + llist_count(&msub_list) == 0 + + +- an SMS is sent, MS is paged +DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + _test_umts_authen: now used by 2 (attached,_test_umts_authen) + llist_count(&vsub->cs.requests) == 0 +DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + SMS-receiver: now used by 3 (attached,_test_umts_authen,SMS-receiver) +DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + SMS: now used by 4 (attached,_test_umts_authen,SMS-receiver,SMS) +DLSMS trans(SMS IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 callref-0x40000003 tid-0) New transaction +DLSMS SMC(0) instance created for network +DLSMS SMR(0) instance created for network. +DLSMS trans(SMS IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 callref-0x40000003 tid-0) Going to send a MT SMS +DLSMS SMR(0) message SM-RL-DATA_REQ received in state IDLE +DLSMS SMR(0) TX SMS RP-DATA +DLSMS SMR(0) new RP state IDLE -> WAIT_FOR_RP_ACK +DLSMS SMC(0) message MNSMS-EST-REQ received in state IDLE +DLSMS SMC(0) new CP state IDLE -> MM_CONN_PENDING +DLSMS trans(SMS IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 callref-0x40000003 tid-0) Initiating Paging due to MMSMS_EST_REQ +DPAG Paging: IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 for MT-SMS: Starting paging + paging request (SIGNALLING_LOW_PRIO) to IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 on UTRAN-Iu + strcmp(paging_expecting_imsi, vsub->imsi) == 0 +DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + Paging: now used by 5 (attached,_test_umts_authen,SMS-receiver,SMS,Paging) + llist_count(&vsub->cs.requests) == 1 +DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - _test_umts_authen: now used by 4 (attached,SMS-receiver,SMS,Paging) + paging_sent == 1 +- the subscriber and its pending request should remain +DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + _test_umts_authen: now used by 5 (attached,SMS-receiver,SMS,Paging,_test_umts_authen) + llist_count(&vsub->cs.requests) == 1 +DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - _test_umts_authen: now used by 4 (attached,SMS-receiver,SMS,Paging) +- MS replies with Paging Response, and VLR sends Auth Request with third key + MSC <--UTRAN-Iu-- MS: GSM48_MT_RR_PAG_RESP + new conn +DMSC msub_fsm{active}: Allocated +DMSC msc_a{MSC_A_ST_VALIDATE_L3}: Allocated +DMSC msc_a{MSC_A_ST_VALIDATE_L3}: is child of msub_fsm +DMSC msc_a(unknown:UTRAN-Iu:NONE){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_VALIDATE_L3 +DMSC dummy_msc_i{0}: Allocated +DMSC dummy_msc_i{0}: is child of msub_fsm +DREF msc_a(unknown:UTRAN-Iu:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms) +DIUCS msc_a(unknown:UTRAN-Iu:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3 +DRLL msc_a(unknown:UTRAN-Iu:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: RR GSM48_MT_RR_PAG_RESP +DRR msc_a(IMSI-901700000010650:UTRAN-Iu:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: Rx PAGING RESPONSE IMSI-901700000010650 +DREF msc_a(IMSI-901700000010650:UTRAN-Iu:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: + paging-response: now used by 2 (rx_from_ms,paging-response) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:UTRAN-Iu:PAGING_RESP){PR_ARQ_S_INIT}: Allocated +DVLR Process_Access_Request_VLR(IMSI-901700000010650:UTRAN-Iu:PAGING_RESP){PR_ARQ_S_INIT}: is child of msc_a(IMSI-901700000010650:UTRAN-Iu:PAGING_RESP) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:UTRAN-Iu:PAGING_RESP){PR_ARQ_S_INIT}: rev=R99 net=UTRAN Auth+Ciph +DVLR Process_Access_Request_VLR(IMSI-901700000010650:UTRAN-Iu:PAGING_RESP){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START +DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + proc_arq_vlr_fn_init: now used by 5 (attached,SMS-receiver,SMS,Paging,proc_arq_vlr_fn_init) +DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + active-conn: now used by 6 (attached,SMS-receiver,SMS,Paging,proc_arq_vlr_fn_init,active-conn) +DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK +DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi() +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_WAIT_AUTH +DVLR VLR_Authenticate(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){VLR_SUB_AS_NEEDS_AUTH}: Allocated +DVLR VLR_Authenticate(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){VLR_SUB_AS_NEEDS_AUTH}: is child of Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP) +DVLR VLR_Authenticate(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START +DVLR VLR_Authenticate(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_WAIT_RESP +DVLR VLR_Authenticate(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){VLR_SUB_AS_WAIT_RESP}: got auth tuple: use_count=1 key_seq=2 -- will use UMTS AKA (is_r99=yes, at->vec.auth_types=0x3) +- sending UMTS Auth Request for IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP: tuple use_count=1 key_seq=2 auth_types=0x3 and... +- ...rand=efa9c29a9742148d5c9070348716e1bb +- ...autn=f9375e6d41e1000096e7fe4ff1c27e39 +- ...expecting res=706f996719ba609c +DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - proc_arq_vlr_fn_init: now used by 5 (attached,SMS-receiver,SMS,Paging,active-conn) +DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (paging-response) + auth_request_sent == 1 +- needs auth, not yet accepted +msc_a_is_accepted() == false + requests shall be thwarted +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: RAN decode: DTAP +DRLL msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: Dispatching 04.08 message: CC GSM48_MT_CC_SETUP +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: Message not permitted for initial conn: GSM48_MT_CC_SETUP +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: RAN decode error (rc=-13) for DTAP from MSC-I +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: RAN decode: DTAP +DRLL msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: Dispatching 04.08 message: MM unknown 0x33 +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: Message not permitted for initial conn: unknown 0x33 +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: RAN decode error (rc=-13) for DTAP from MSC-I +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: RAN decode: DTAP +DRLL msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: Dispatching 04.08 message: RR GSM48_MT_RR_SYSINFO_1 +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1 +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: RAN decode error (rc=-13) for DTAP from MSC-I +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: RAN decode: DTAP +DRLL msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: Dispatching 04.08 message: SMS SMS:0x01 +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: Message not permitted for initial conn: SMS:0x01 +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: RAN decode error (rc=-13) for DTAP from MSC-I +- Encryption enabled. MS sends Authen Response, VLR accepts and sends SecurityModeControl + MSC <--UTRAN-Iu-- MS: GSM48_MT_MM_AUTH_RESP +DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: + rx_from_ms: now used by 2 (paging-response,rx_from_ms) +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: RAN decode: DTAP +DRLL msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: Dispatching 04.08 message: MM GSM48_MT_MM_AUTH_RESP +DMM msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: MM UMTS AUTHENTICATION RESPONSE (res = 706f996719ba609c) +DVLR VLR_Authenticate(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP +DVLR SUBSCR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100) AUTH on UTRAN received RES: 706f996719ba609c (8 bytes) +DVLR SUBSCR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100) AUTH established UMTS security context +DVLR VLR_Authenticate(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result PASSED +DVLR VLR_Authenticate(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED +DVLR VLR_Authenticate(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) +DVLR VLR_Authenticate(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){VLR_SUB_AS_AUTHENTICATED}: Removing from parent Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){PR_ARQ_S_WAIT_AUTH}: Received Event PR_ARQ_E_AUTH_RES +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2() +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){PR_ARQ_S_WAIT_AUTH}: Set Ciphering Mode +DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: RAN encode: CIPHER_MODE_COMMAND on UTRAN-Iu +- sending SecurityModeControl: ik=eb50e770ddcc3060101d2f43b6c2b884 +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){PR_ARQ_S_WAIT_AUTH}: state_chg to PR_ARQ_S_WAIT_CIPH +DVLR VLR_Authenticate(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){VLR_SUB_AS_AUTHENTICATED}: Deallocated +DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (paging-response) + security_mode_ctrl_sent == 1 +- MS sends SecurityModeControl acceptance, VLR accepts and sends SMS +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: RAN decode: CIPHER_MODE_COMPLETE +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){PR_ARQ_S_WAIT_CIPH}: Received Event PR_ARQ_E_CIPH_RES +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_node2_post_ciph() +DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on UTRAN-Iu +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_node2_post_vlr() +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_pres() +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_trace() +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_imei() +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){PR_ARQ_S_WAIT_CIPH}: proc_arq_fsm_done(PASSED) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){PR_ARQ_S_WAIT_CIPH}: state_chg to PR_ARQ_S_DONE +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){PR_ARQ_S_DONE}: Process Access Request result: PASSED +DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: Received Event MSC_A_EV_AUTHENTICATED +DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: state_chg to MSC_A_ST_AUTHENTICATED +DPAG Paging: IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 for MT-SMS: Paging Response action (success) +DPAG Paging: IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 for MT-SMS: Removing Paging Request +DLSMS trans(SMS IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 callref-0x40000003 tid-0) mmsms_paging_cb(success) +DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: + sms: now used by 2 (paging-response,sms) +DLSMS SMC(0) message MMSMS-EST-CNF received in state MM_CONN_PENDING +DLSMS SMC(0) send CP data +DLSMS SMC(0) new CP state MM_CONN_PENDING -> WAIT_CP_ACK +DLSMS trans(SMS IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x40000003 tid-0) sending CP message (trans=0) +DLSMS trans(SMS IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x40000003 tid-0) GSM4.11 TX 09 01 58 01 00 07 91 44 77 58 10 06 50 00 4c 00 05 80 24 43 f2 00 00 07 10 10 00 00 00 00 44 50 79 da 1e 1e e7 41 69 37 48 5e 9e a7 c9 65 37 3d 1d 66 83 c2 70 38 3b 3d 0e d3 d3 6f f7 1c 94 9e 83 c2 20 72 79 9e 96 87 c5 ec 32 a8 1d 96 af cb f4 b4 fb 0c 7a c3 e9 e9 b7 db 05 +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: Sending DTAP: SMS SMS:0x01 +DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: RAN encode: DTAP on UTRAN-Iu +- DTAP --UTRAN-Iu--> MS: SMS:0x01: 09015801000791447758100650004c0005802443f2000007101000000000445079da1e1ee7416937485e9ea7c965373d1d6683c270383b3d0ed3d36ff71c949e83c22072799e9687c5ec32a81d96afcbf4b4fb0c7ac3e9e9b7db05 +- DTAP matches expected message +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST +DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - Paging: now used by 4 (attached,SMS-receiver,SMS,active-conn) +DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: - paging-response: now used by 1 (sms) +- SMS was delivered, no requests pending for subscr +DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + _test_umts_authen: now used by 5 (attached,SMS-receiver,SMS,active-conn,_test_umts_authen) + llist_count(&vsub->cs.requests) == 0 +DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - _test_umts_authen: now used by 4 (attached,SMS-receiver,SMS,active-conn) +- conn is still open to wait for SMS ack dance + llist_count(&msub_list) == 1 +- MS replies with CP-ACK for received SMS + MSC <--UTRAN-Iu-- MS: SMS:0x04 +DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: + rx_from_ms: now used by 2 (sms,rx_from_ms) +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: RAN decode: DTAP +DRLL msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: Dispatching 04.08 message: SMS SMS:0x04 +DLSMS trans(SMS IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x40000003 tid-0) receiving SMS message SMS:0x04 +DLSMS SMC(0) message MMSMS-DATA-IND (CP ACK) received in state WAIT_CP_ACK +DLSMS SMC(0) received CP-ACK +DLSMS SMC(0) new CP state WAIT_CP_ACK -> MM_ESTABLISHED +DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: - rx_from_ms: now used by 1 (sms) + llist_count(&msub_list) == 1 +- MS also sends RP-ACK, MSC in turn sends CP-ACK for that + MSC <--UTRAN-Iu-- MS: SMS:0x01 +DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: + rx_from_ms: now used by 2 (sms,rx_from_ms) +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: RAN decode: DTAP +DRLL msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: Dispatching 04.08 message: SMS SMS:0x01 +DLSMS trans(SMS IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x40000003 tid-0) receiving SMS message SMS:0x01 +DLSMS SMC(0) message MMSMS-DATA-IND (CP DATA) received in state MM_ESTABLISHED +DLSMS SMC(0) received CP-DATA +DLSMS trans(SMS IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x40000003 tid-0) sending CP message (trans=0) +DLSMS trans(SMS IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x40000003 tid-0) GSM4.11 TX 09 04 +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: Sending DTAP: SMS SMS:0x04 +DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: RAN encode: DTAP on UTRAN-Iu +- DTAP --UTRAN-Iu--> MS: SMS:0x04: 0904 +- DTAP matches expected message +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST +DLSMS trans(SMS IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x40000003 tid-0) MNSMS-DATA/EST-IND +DLSMS SMR(0) message MNSMS-DATA-IND received in state WAIT_FOR_RP_ACK +DLSMS SMR(0) RX SMS RP-ACK +DLSMS SMR(0) new RP state WAIT_FOR_RP_ACK -> IDLE +DLSMS trans(SMS IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x40000003 tid-0) RX SMS RP-ACK (MO) +DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - SMS-receiver: now used by 3 (attached,SMS,active-conn) +DLSMS SMR(0) TX: MNSMS-REL-REQ +DLSMS SMC(0) message MNSMS-REL-REQ received in state MM_ESTABLISHED +DLSMS SMC(0) new CP state MM_ESTABLISHED -> IDLE +DLSMS trans(SMS IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x40000003 tid-0) Got MMSMS_REL_REQ, destroying transaction. +DLSMS trans(SMS IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x40000003 tid-0) Freeing transaction +DLSMS SMR(0) clearing SMR instance +DLSMS SMC(0) clearing instance +DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - SMS: now used by 2 (attached,active-conn) +DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: - sms: now used by 1 (rx_from_ms) +DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: - rx_from_ms: now used by 0 (-) +DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: Received Event MSC_A_EV_UNUSED +DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: state_chg to MSC_A_ST_RELEASING +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_RELEASING}: Releasing: msc_a use is 0 (-) +DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + msc_a_fsm_releasing_onenter: now used by 3 (attached,active-conn,msc_a_fsm_releasing_onenter) +DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,active-conn,msc_a_fsm_releasing_onenter,vlr_subscr_cancel_attach_fsm) +DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,active-conn,msc_a_fsm_releasing_onenter) +DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_RELEASING}: + wait-Clear-Complete: now used by 1 (wait-Clear-Complete) +DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_RELEASING}: RAN encode: CLEAR_COMMAND on UTRAN-Iu +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST +DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - msc_a_fsm_releasing_onenter: now used by 2 (attached,active-conn) + dtap_tx_confirmed == 1 + iu_release_sent == 1 +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_RELEASING}: RAN decode: CLEAR_COMPLETE +DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_RELEASING}: - wait-Clear-Complete: now used by 0 (-) +DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_RELEASING}: Received Event MSC_A_EV_UNUSED +DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_RELEASING}: state_chg to MSC_A_ST_RELEASED +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_RELEASED}: Released: msc_a use is 0 (-) +DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){PR_ARQ_S_DONE}: Terminating in cascade, depth 2 (cause = OSMO_FSM_TERM_PARENT, caused by: msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP)) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){PR_ARQ_S_DONE}: Removing from parent msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP) +DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){PR_ARQ_S_DONE}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP) +DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_RELEASED}: Removing from parent msub_fsm +DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_RELEASED}: max total use count was 2 +DMSC msub_fsm{active}: Received Event MSUB_EV_ROLE_TERMINATED +DMSC msub(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100) MSC-A terminated +DMSC msub(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100) 1 MSC-I still active +DMSC msub_fsm{active}: state_chg to terminating +DMSC msub_fsm{terminating}: Terminating in cascade, depth 2 (cause = OSMO_FSM_TERM_REGULAR, caused by: msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP)) +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){0}: Terminating in cascade, depth 3 (cause = OSMO_FSM_TERM_PARENT, caused by: msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP)) +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){0}: Removing from parent msub_fsm +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){0}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP) +DMSC msub(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100) Free +DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - active-conn: now used by 1 (attached) +DMSC msub_fsm{terminating}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP) +DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_RELEASED}: Deallocated, including all deferred deallocations +- msub gone +- SMS is done, conn is gone + llist_count(&msub_list) == 0 + + +- subscriber detaches + MSC <--UTRAN-Iu-- MS: GSM48_MT_MM_IMSI_DETACH_IND + new conn +DMSC msub_fsm{active}: Allocated +DMSC msc_a{MSC_A_ST_VALIDATE_L3}: Allocated +DMSC msc_a{MSC_A_ST_VALIDATE_L3}: is child of msub_fsm +DMSC msc_a(unknown:UTRAN-Iu:NONE){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_VALIDATE_L3 +DMSC dummy_msc_i{0}: Allocated +DMSC dummy_msc_i{0}: is child of msub_fsm +DREF msc_a(unknown:UTRAN-Iu:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms) +DIUCS msc_a(unknown:UTRAN-Iu:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3 +DRLL msc_a(unknown:UTRAN-Iu:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: MM GSM48_MT_MM_IMSI_DETACH_IND +DMM IMSI DETACH INDICATION: IMSI-901700000010650 +DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + gsm48_rx_mm_imsi_detach_ind: now used by 2 (attached,gsm48_rx_mm_imsi_detach_ind) +DMM IMSI DETACH for IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 +DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + active-conn: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn) +DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn,vlr_subscr_cancel_attach_fsm) +DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) +DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - attached: now used by 2 (gsm48_rx_mm_imsi_detach_ind,active-conn) +DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - gsm48_rx_mm_imsi_detach_ind: now used by 1 (active-conn) +DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:NONE){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_CN_CLOSE +DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:NONE){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_RELEASING +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:NONE){MSC_A_ST_RELEASING}: Releasing: msc_a use is 1 (rx_from_ms) +DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + msc_a_fsm_releasing_onenter: now used by 2 (active-conn,msc_a_fsm_releasing_onenter) +DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + vlr_subscr_cancel_attach_fsm: now used by 3 (active-conn,msc_a_fsm_releasing_onenter,vlr_subscr_cancel_attach_fsm) +DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - vlr_subscr_cancel_attach_fsm: now used by 2 (active-conn,msc_a_fsm_releasing_onenter) +DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:NONE){MSC_A_ST_RELEASING}: + wait-Clear-Complete: now used by 2 (rx_from_ms,wait-Clear-Complete) +DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:NONE){MSC_A_ST_RELEASING}: RAN encode: CLEAR_COMMAND on UTRAN-Iu +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:NONE){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST +DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - msc_a_fsm_releasing_onenter: now used by 1 (active-conn) +DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:NONE){MSC_A_ST_RELEASING}: - rx_from_ms: now used by 1 (wait-Clear-Complete) + iu_release_sent == 1 +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:NONE){MSC_A_ST_RELEASING}: RAN decode: CLEAR_COMPLETE +DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:NONE){MSC_A_ST_RELEASING}: - wait-Clear-Complete: now used by 0 (-) +DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:NONE){MSC_A_ST_RELEASING}: Received Event MSC_A_EV_UNUSED +DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:NONE){MSC_A_ST_RELEASING}: state_chg to MSC_A_ST_RELEASED +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:NONE){MSC_A_ST_RELEASED}: Released: msc_a use is 0 (-) +DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:NONE){MSC_A_ST_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) +DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:NONE){MSC_A_ST_RELEASED}: Removing from parent msub_fsm +DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:NONE){MSC_A_ST_RELEASED}: max total use count was 2 +DMSC msub_fsm{active}: Received Event MSUB_EV_ROLE_TERMINATED +DMSC msub(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100) MSC-A terminated +DMSC msub(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100) 1 MSC-I still active +DMSC msub_fsm{active}: state_chg to terminating +DMSC msub_fsm{terminating}: Terminating in cascade, depth 2 (cause = OSMO_FSM_TERM_REGULAR, caused by: msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:NONE)) +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:NONE){0}: Terminating in cascade, depth 3 (cause = OSMO_FSM_TERM_PARENT, caused by: msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:NONE)) +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:NONE){0}: Removing from parent msub_fsm +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:NONE){0}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:NONE) +DMSC msub(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100) Free +DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - active-conn: now used by 0 (-) +DVLR freeing VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 (max total use count was 6) +DMSC msub_fsm{terminating}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:NONE) +DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:NONE){MSC_A_ST_RELEASED}: Deallocated, including all deferred deallocations +- msub gone + llist_count(&msub_list) == 0 +===== test_umts_auth_ciph_utran: SUCCESS ===== test_umts_authen_resync_geran - Location Update request causes a GSUP Send Auth Info request to HLR @@ -1259,13 +1895,14 @@ DREF VLR subscr IMSI-901700000010650 + active-conn: now used by 2 (_lu_fsm_assoc DMSC msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK DMSC msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH DREF VLR subscr IMSI-901700000010650 - _lu_fsm_associate_vsub: now used by 1 (active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre() DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Allocated DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU) DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START -GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f00a0101 +GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f02801020a0101 DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI DREF msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - mm_rx_loc_upd_req: now used by 2 (rx_from_ms,lu) DREF msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu) @@ -1292,7 +1929,7 @@ DBSSAP msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN decode: D DRLL msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: Dispatching 04.08 message: MM GSM48_MT_MM_AUTH_FAIL DMM msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: MM R99 AUTHENTICATION SYNCH (AUTS = 979498b1f72d3e28c59fa2e72f9c) DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_FAIL -GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f0260e979498b1f72d3e28c59fa2e72f9c201039fa2f4e3d523d8619a73b4f65c3e14d0a0101 +GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f0260e979498b1f72d3e28c59fa2e72f9c201039fa2f4e3d523d8619a73b4f65c3e14d2801020a0101 DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_SAI_RESYNC DREF msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu) gsup_tx_confirmed == 1 @@ -1313,7 +1950,7 @@ DREF VLR subscr IMSI-901700000010650 - vlr_gsup_rx: now used by 1 (active-conn) <-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT: vlr_gsupc_read_cb() returns 0 auth_request_sent == 1 lu_result_sent == 0 -- MS sends Authen Response, VLR accepts and sends GSUP LU Req to HLR +- Encryption disabled. MS sends Authen Response, VLR accepts and sends GSUP LU Req to HLR MSC <--GERAN-A-- MS: GSM48_MT_MM_AUTH_RESP DREF msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: + rx_from_ms: now used by 2 (lu,rx_from_ms) DBSSAP msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN decode: DTAP @@ -1326,9 +1963,11 @@ DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP_RESY DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP_RESYNC}: state_chg to VLR_SUB_AS_AUTHENTICATED DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU) -DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES +DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_SUCCESS DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth() DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_ciph() +DMSC msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A +DMSC dummy_msc_i(IMSI-901700000010650:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_node_4() DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD DVLR upd_hlr_vlr_fsm(IMSI-901700000010650:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated @@ -1460,9 +2099,6 @@ DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:LU){MSC_A_S DVLR freeing VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 (max total use count was 4) ===== test_umts_authen_resync_geran: SUCCESS -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 17 - ===== test_umts_authen_resync_utran - Location Update request causes a GSUP Send Auth Info request to HLR MSC <--UTRAN-Iu-- MS: GSM48_MT_MM_LOC_UPD_REQUEST @@ -1482,7 +2118,7 @@ DREF msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_VALIDATE_L3}: + mm_rx_loc_ DREF msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_VALIDATE_L3}: + lu: now used by 3 (rx_from_ms,mm_rx_loc_upd_req,lu) DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: Allocated DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: is child of msc_a(IMSI-901700000010650:UTRAN-Iu:LU) -DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: rev=R99 net=UTRAN Auth+Ciph +DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: rev=R99 net=UTRAN Auth (no Ciph) DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA DREF VLR subscr unknown + _lu_fsm_associate_vsub: now used by 1 (_lu_fsm_associate_vsub) DVLR set IMSI on subscriber; IMSI=901700000010650 id=901700000010650 @@ -1491,13 +2127,14 @@ DREF VLR subscr IMSI-901700000010650 + active-conn: now used by 2 (_lu_fsm_assoc DMSC msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK DMSC msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH DREF VLR subscr IMSI-901700000010650 - _lu_fsm_associate_vsub: now used by 1 (active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre() DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: Allocated DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU) DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START -GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f00a0101 +GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f02801020a0101 DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI DREF msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: - mm_rx_loc_upd_req: now used by 2 (rx_from_ms,lu) DREF msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu) @@ -1524,7 +2161,7 @@ DIUCS msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: RAN decode: D DRLL msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: Dispatching 04.08 message: MM GSM48_MT_MM_AUTH_FAIL DMM msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: MM R99 AUTHENTICATION SYNCH (AUTS = 979498b1f72d3e28c59fa2e72f9c) DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_FAIL -GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f0260e979498b1f72d3e28c59fa2e72f9c201039fa2f4e3d523d8619a73b4f65c3e14d0a0101 +GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f0260e979498b1f72d3e28c59fa2e72f9c201039fa2f4e3d523d8619a73b4f65c3e14d2801020a0101 DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_SAI_RESYNC DREF msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu) gsup_tx_confirmed == 1 @@ -1545,7 +2182,7 @@ DREF VLR subscr IMSI-901700000010650 - vlr_gsup_rx: now used by 1 (active-conn) <-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT: vlr_gsupc_read_cb() returns 0 auth_request_sent == 1 lu_result_sent == 0 -- MS sends Authen Response, VLR accepts and sends SecurityModeControl +- Encryption disabled. MS sends Authen Response, VLR accepts and sends SecurityModeControl MSC <--UTRAN-Iu-- MS: GSM48_MT_MM_AUTH_RESP DREF msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: + rx_from_ms: now used by 2 (lu,rx_from_ms) DIUCS msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: RAN decode: DTAP @@ -1558,7 +2195,7 @@ DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_WAIT_RESP_RES DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_WAIT_RESP_RESYNC}: state_chg to VLR_SUB_AS_AUTHENTICATED DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU) -DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES +DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_SUCCESS DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth() DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: Set Ciphering Mode DMSC msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: CIPHER_MODE_COMMAND on UTRAN-Iu @@ -1704,8 +2341,247 @@ DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){MSC_A_ DVLR freeing VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 (max total use count was 4) ===== test_umts_authen_resync_utran: SUCCESS -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 17 +===== test_umts_auth_ciph_resync_utran +- Location Update request causes a GSUP Send Auth Info request to HLR + MSC <--UTRAN-Iu-- MS: GSM48_MT_MM_LOC_UPD_REQUEST + new conn +DMSC msub_fsm{active}: Allocated +DMSC msc_a{MSC_A_ST_VALIDATE_L3}: Allocated +DMSC msc_a{MSC_A_ST_VALIDATE_L3}: is child of msub_fsm +DMSC msc_a(unknown:UTRAN-Iu:NONE){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_VALIDATE_L3 +DMSC dummy_msc_i{0}: Allocated +DMSC dummy_msc_i{0}: is child of msub_fsm +DREF msc_a(unknown:UTRAN-Iu:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms) +DIUCS msc_a(unknown:UTRAN-Iu:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3 +DRLL msc_a(unknown:UTRAN-Iu:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: MM GSM48_MT_MM_LOC_UPD_REQUEST +DMM msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_VALIDATE_L3}: LOCATION UPDATING REQUEST: MI=IMSI-901700000010650 LU-type=NORMAL +DMM msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_VALIDATE_L3}: USIM: old LAI: 1665-165-0 +DREF msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_VALIDATE_L3}: + mm_rx_loc_upd_req: now used by 2 (rx_from_ms,mm_rx_loc_upd_req) +DREF msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_VALIDATE_L3}: + lu: now used by 3 (rx_from_ms,mm_rx_loc_upd_req,lu) +DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: Allocated +DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: is child of msc_a(IMSI-901700000010650:UTRAN-Iu:LU) +DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: rev=R99 net=UTRAN Auth+Ciph +DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA +DREF VLR subscr unknown + _lu_fsm_associate_vsub: now used by 1 (_lu_fsm_associate_vsub) +DVLR set IMSI on subscriber; IMSI=901700000010650 id=901700000010650 +DVLR New subscr, IMSI: 901700000010650 +DREF VLR subscr IMSI-901700000010650 + active-conn: now used by 2 (_lu_fsm_associate_vsub,active-conn) +DMSC msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK +DMSC msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH +DREF VLR subscr IMSI-901700000010650 - _lu_fsm_associate_vsub: now used by 1 (active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) +DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre() +DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() +DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH +DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: Allocated +DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU) +DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START +GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f02801020a0101 +DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI +DREF msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: - mm_rx_loc_upd_req: now used by 2 (rx_from_ms,lu) +DREF msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu) + lu_result_sent == 0 +- from HLR, rx _SEND_AUTH_INFO_RESULT; VLR sends Auth Req to MS +<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT: 0a010809710000000156f00362201039fa2f4e3d523d8619a73b4f65c3e14d21049b36efdf2208059a4f668f6fbe39231027497388b6cb044648f396aa155b95ef2410f64735036e5871319c679f4742a75ea125108704f5ba55f30000d2ee44b22c8ea9192708e229c19e791f2e410a0101 +DREF VLR subscr IMSI-901700000010650 + vlr_gsup_rx: now used by 2 (active-conn,vlr_gsup_rx) +DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: Received Event VLR_AUTH_E_HLR_SAI_ACK +DVLR SUBSCR(IMSI-901700000010650) Received 1 auth tuples +DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: state_chg to VLR_SUB_AS_WAIT_RESP +DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_WAIT_RESP}: got auth tuple: use_count=1 key_seq=0 -- will use UMTS AKA (is_r99=yes, at->vec.auth_types=0x3) +- sending UMTS Auth Request for IMSI-901700000010650:UTRAN-Iu:LU: tuple use_count=1 key_seq=0 auth_types=0x3 and... +- ...rand=39fa2f4e3d523d8619a73b4f65c3e14d +- ...autn=8704f5ba55f30000d2ee44b22c8ea919 +- ...expecting res=e229c19e791f2e41 +DREF VLR subscr IMSI-901700000010650 - vlr_gsup_rx: now used by 1 (active-conn) +<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT: vlr_gsupc_read_cb() returns 0 + auth_request_sent == 1 + lu_result_sent == 0 +- MS sends Authen Failure with Resync cause, VLR sends GSUP to HLR to resync + MSC <--UTRAN-Iu-- MS: GSM48_MT_MM_AUTH_FAIL +DREF msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: + rx_from_ms: now used by 2 (lu,rx_from_ms) +DIUCS msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: RAN decode: DTAP +DRLL msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: Dispatching 04.08 message: MM GSM48_MT_MM_AUTH_FAIL +DMM msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: MM R99 AUTHENTICATION SYNCH (AUTS = 979498b1f72d3e28c59fa2e72f9c) +DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_FAIL +GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f0260e979498b1f72d3e28c59fa2e72f9c201039fa2f4e3d523d8619a73b4f65c3e14d2801020a0101 +DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_SAI_RESYNC +DREF msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu) + gsup_tx_confirmed == 1 + auth_request_sent == 0 + lu_result_sent == 0 +- HLR replies with new tuples +<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT: 0a010809710000000156f0036220100f1feb1623e1bf626334e37ec448ac182104efde99da220814778c855c52373023108a90c769b7272f3bb7a1c1fbb1ea9349241043ffc1cf8c89a7fd6ab94bd8d6162cbf251002a83f62e9470000660d51afc75f169d27081df5f0b4f22b696e03622010ac21d34937b4e1142a2c757af294931921047818bfdc2208d175571f41f314a42310ff8edbceb6dd24799c77c3b9a6790c102410157c39022ca9d885a7f0766a7dfee44825108a43b91898e500002cf354c6f5d1f8c32708f748a7078f5018db0a0101 +DREF VLR subscr IMSI-901700000010650 + vlr_gsup_rx: now used by 2 (active-conn,vlr_gsup_rx) +DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH_WAIT_SAI_RESYNC}: Received Event VLR_AUTH_E_HLR_SAI_ACK +DVLR SUBSCR(IMSI-901700000010650) Received 2 auth tuples +DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH_WAIT_SAI_RESYNC}: state_chg to VLR_SUB_AS_WAIT_RESP_RESYNC +DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_WAIT_RESP_RESYNC}: got auth tuple: use_count=1 key_seq=0 -- will use UMTS AKA (is_r99=yes, at->vec.auth_types=0x3) +- sending UMTS Auth Request for IMSI-901700000010650:UTRAN-Iu:LU: tuple use_count=1 key_seq=0 auth_types=0x3 and... +- ...rand=0f1feb1623e1bf626334e37ec448ac18 +- ...autn=02a83f62e9470000660d51afc75f169d +- ...expecting res=1df5f0b4f22b696e +DREF VLR subscr IMSI-901700000010650 - vlr_gsup_rx: now used by 1 (active-conn) +<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT: vlr_gsupc_read_cb() returns 0 + auth_request_sent == 1 + lu_result_sent == 0 +- Encryption enabled. MS sends Authen Response, VLR accepts and sends SecurityModeControl + MSC <--UTRAN-Iu-- MS: GSM48_MT_MM_AUTH_RESP +DREF msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: + rx_from_ms: now used by 2 (lu,rx_from_ms) +DIUCS msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: RAN decode: DTAP +DRLL msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: Dispatching 04.08 message: MM GSM48_MT_MM_AUTH_RESP +DMM msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: MM UMTS AUTHENTICATION RESPONSE (res = 1df5f0b4f22b696e) +DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_WAIT_RESP_RESYNC}: Received Event VLR_AUTH_E_MS_AUTH_RESP +DVLR SUBSCR(IMSI-901700000010650) AUTH on UTRAN received RES: 1df5f0b4f22b696e (8 bytes) +DVLR SUBSCR(IMSI-901700000010650) AUTH established UMTS security context +DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_WAIT_RESP_RESYNC}: Authentication terminating with result PASSED +DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_WAIT_RESP_RESYNC}: state_chg to VLR_SUB_AS_AUTHENTICATED +DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) +DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU) +DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_SUCCESS +DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth() +DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: Set Ciphering Mode +DMSC msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: CIPHER_MODE_COMMAND on UTRAN-Iu +- sending SecurityModeControl: ik=8a90c769b7272f3bb7a1c1fbb1ea9349 +DMSC dummy_msc_i(IMSI-901700000010650:UTRAN-Iu:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST +DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_WAIT_CIPH +DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_AUTHENTICATED}: Deallocated +DREF msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu) + security_mode_ctrl_sent == 1 + lu_result_sent == 0 +- MS sends SecurityModeControl acceptance, VLR accepts and sends GSUP LU Req to HLR +DIUCS msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: RAN decode: CIPHER_MODE_COMPLETE +DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_CIPH}: Received Event VLR_ULA_E_CIPH_RES +DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_CIPH}: vlr_loc_upd_post_ciph() +DMSC msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on UTRAN-Iu +DMSC dummy_msc_i(IMSI-901700000010650:UTRAN-Iu:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST +DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_CIPH}: vlr_loc_upd_node_4() +DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_CIPH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD +DVLR upd_hlr_vlr_fsm(IMSI-901700000010650:UTRAN-Iu:LU){UPD_HLR_VLR_S_INIT}: Allocated +DVLR upd_hlr_vlr_fsm(IMSI-901700000010650:UTRAN-Iu:LU){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU) +DVLR upd_hlr_vlr_fsm(IMSI-901700000010650:UTRAN-Iu:LU){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START +GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000000156f02801020a0101 +DVLR upd_hlr_vlr_fsm(IMSI-901700000010650:UTRAN-Iu:LU){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA + gsup_tx_confirmed == 1 + lu_result_sent == 0 +- HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT +<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: 10010809710000000156f00804032443f20a0101 +DREF VLR subscr IMSI-901700000010650 + vlr_gsup_rx: now used by 2 (active-conn,vlr_gsup_rx) +DVLR IMSI:901700000010650 has MSISDN:42342 +DVLR SUBSCR(IMSI-901700000010650:MSISDN-42342) VLR: update for IMSI=901700000010650 (MSISDN=42342) +GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000000156f00a0101 +DREF VLR subscr IMSI-901700000010650:MSISDN-42342 - vlr_gsup_rx: now used by 1 (active-conn) +<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: vlr_gsupc_read_cb() returns 0 + lu_result_sent == 0 +- HLR also sends GSUP _UPDATE_LOCATION_RESULT +<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: 06010809710000000156f00a0101 +DREF VLR subscr IMSI-901700000010650:MSISDN-42342 + vlr_gsup_rx: now used by 2 (active-conn,vlr_gsup_rx) +DVLR vlr_lu_fsm(IMSI-901700000010650:MSISDN-42342:UTRAN-Iu:LU){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES +DVLR upd_hlr_vlr_fsm(IMSI-901700000010650:UTRAN-Iu:LU){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK +DVLR upd_hlr_vlr_fsm(IMSI-901700000010650:UTRAN-Iu:LU){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE +DVLR upd_hlr_vlr_fsm(IMSI-901700000010650:UTRAN-Iu:LU){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR) +DVLR upd_hlr_vlr_fsm(IMSI-901700000010650:UTRAN-Iu:LU){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(IMSI-901700000010650:MSISDN-42342:UTRAN-Iu:LU) +DVLR vlr_lu_fsm(IMSI-901700000010650:MSISDN-42342:UTRAN-Iu:LU){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL +DVLR vlr_lu_fsm(IMSI-901700000010650:MSISDN-42342:UTRAN-Iu:LU){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL +DVLR lu_compl_vlr_fsm(IMSI-901700000010650:MSISDN-42342:UTRAN-Iu:LU){LU_COMPL_VLR_S_INIT}: Allocated +DVLR lu_compl_vlr_fsm(IMSI-901700000010650:MSISDN-42342:UTRAN-Iu:LU){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(IMSI-901700000010650:MSISDN-42342:UTRAN-Iu:LU) +DVLR lu_compl_vlr_fsm(IMSI-901700000010650:MSISDN-42342:UTRAN-Iu:LU){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START +DVLR lu_compl_vlr_fsm(IMSI-901700000010650:MSISDN-42342:UTRAN-Iu:LU){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES +DVLR lu_compl_vlr_fsm(IMSI-901700000010650:MSISDN-42342:UTRAN-Iu:LU){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL +DVLR lu_compl_vlr_fsm(IMSI-901700000010650:MSISDN-42342:UTRAN-Iu:LU){LU_COMPL_VLR_S_WAIT_SUB_PRES}: lu_compl_vlr_new_tmsi() +DVLR SUBSCR(IMSI-901700000010650:MSISDN-42342:TMSInew-0x03020100) VLR: update for IMSI=901700000010650 (MSISDN=42342) +DVLR lu_compl_vlr_fsm(IMSI-901700000010650:MSISDN-42342:UTRAN-Iu:LU){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_WAIT_TMSI_CNF +- sending LU Accept for IMSI-901700000010650:MSISDN-42342:TMSInew-0x03020100:UTRAN-Iu:LU, with TMSI 0x03020100 +DVLR upd_hlr_vlr_fsm(IMSI-901700000010650:UTRAN-Iu:LU){UPD_HLR_VLR_S_DONE}: Deallocated +DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSInew-0x03020100 - vlr_gsup_rx: now used by 1 (active-conn) +<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: vlr_gsupc_read_cb() returns 0 + lu_result_sent == 1 +- a LU Accept with a new TMSI was sent, waiting for TMSI Realloc Compl + llist_count(&msub_list) == 1 +msc_a_is_accepted() == false + requests shall be thwarted +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSInew-0x03020100:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: RAN decode: DTAP +DRLL msc_a(IMSI-901700000010650:MSISDN-42342:TMSInew-0x03020100:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: Dispatching 04.08 message: CC GSM48_MT_CC_SETUP +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSInew-0x03020100:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: Message not permitted for initial conn: GSM48_MT_CC_SETUP +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSInew-0x03020100:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: RAN decode error (rc=-13) for DTAP from MSC-I +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSInew-0x03020100:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: RAN decode: DTAP +DRLL msc_a(IMSI-901700000010650:MSISDN-42342:TMSInew-0x03020100:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: Dispatching 04.08 message: MM unknown 0x33 +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSInew-0x03020100:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: Message not permitted for initial conn: unknown 0x33 +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSInew-0x03020100:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: RAN decode error (rc=-13) for DTAP from MSC-I +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSInew-0x03020100:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: RAN decode: DTAP +DRLL msc_a(IMSI-901700000010650:MSISDN-42342:TMSInew-0x03020100:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: Dispatching 04.08 message: RR GSM48_MT_RR_SYSINFO_1 +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSInew-0x03020100:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1 +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSInew-0x03020100:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: RAN decode error (rc=-13) for DTAP from MSC-I +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSInew-0x03020100:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: RAN decode: DTAP +DRLL msc_a(IMSI-901700000010650:MSISDN-42342:TMSInew-0x03020100:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: Dispatching 04.08 message: SMS SMS:0x01 +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSInew-0x03020100:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: Message not permitted for initial conn: SMS:0x01 +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSInew-0x03020100:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: RAN decode error (rc=-13) for DTAP from MSC-I +- even though the TMSI is not acked, we can already find the subscr with it +DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSInew-0x03020100 + _test_umts_authen_resync: now used by 2 (active-conn,_test_umts_authen_resync) + vsub != NULL == 1 + strcmp(vsub->imsi, imsi) == 0 + vsub->tmsi_new == 0x03020100 + vsub->tmsi == 0xffffffff +DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSInew-0x03020100 - _test_umts_authen_resync: now used by 1 (active-conn) +- MS sends TMSI Realloc Complete + MSC <--UTRAN-Iu-- MS: GSM48_MT_MM_TMSI_REALL_COMPL +DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSInew-0x03020100:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: + rx_from_ms: now used by 2 (lu,rx_from_ms) +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSInew-0x03020100:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: RAN decode: DTAP +DRLL msc_a(IMSI-901700000010650:MSISDN-42342:TMSInew-0x03020100:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: Dispatching 04.08 message: MM GSM48_MT_MM_TMSI_REALL_COMPL +DMM msc_a(IMSI-901700000010650:MSISDN-42342:TMSInew-0x03020100:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: TMSI Reallocation Completed +DVLR vlr_lu_fsm(IMSI-901700000010650:MSISDN-42342:TMSInew-0x03020100:UTRAN-Iu:LU){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_NEW_TMSI_ACK +DVLR lu_compl_vlr_fsm(IMSI-901700000010650:MSISDN-42342:UTRAN-Iu:LU){LU_COMPL_VLR_S_WAIT_TMSI_CNF}: Received Event LU_COMPL_VLR_E_NEW_TMSI_ACK +DVLR SUBSCR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100) VLR: update for IMSI=901700000010650 (MSISDN=42342) +DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + attached: now used by 2 (active-conn,attached) +DVLR lu_compl_vlr_fsm(IMSI-901700000010650:MSISDN-42342:UTRAN-Iu:LU){LU_COMPL_VLR_S_WAIT_TMSI_CNF}: state_chg to LU_COMPL_VLR_S_DONE +DVLR vlr_lu_fsm(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS +DVLR lu_compl_vlr_fsm(IMSI-901700000010650:MSISDN-42342:UTRAN-Iu:LU){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT) +DVLR lu_compl_vlr_fsm(IMSI-901700000010650:MSISDN-42342:UTRAN-Iu:LU){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU) +DVLR lu_compl_vlr_fsm(IMSI-901700000010650:MSISDN-42342:UTRAN-Iu:LU){LU_COMPL_VLR_S_DONE}: Deallocated +DVLR vlr_lu_fsm(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE +DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: Received Event MSC_A_EV_AUTHENTICATED +DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: state_chg to MSC_A_ST_AUTHENTICATED +DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){MSC_A_ST_AUTHENTICATED}: - lu: now used by 1 (rx_from_ms) +DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){MSC_A_ST_AUTHENTICATED}: - rx_from_ms: now used by 0 (-) +DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){MSC_A_ST_AUTHENTICATED}: Received Event MSC_A_EV_UNUSED +DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){MSC_A_ST_AUTHENTICATED}: state_chg to MSC_A_ST_RELEASING +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){MSC_A_ST_RELEASING}: Releasing: msc_a use is 0 (-) +DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + msc_a_fsm_releasing_onenter: now used by 3 (active-conn,attached,msc_a_fsm_releasing_onenter) +DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + vlr_subscr_cancel_attach_fsm: now used by 4 (active-conn,attached,msc_a_fsm_releasing_onenter,vlr_subscr_cancel_attach_fsm) +DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - vlr_subscr_cancel_attach_fsm: now used by 3 (active-conn,attached,msc_a_fsm_releasing_onenter) +DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){MSC_A_ST_RELEASING}: + wait-Clear-Complete: now used by 1 (wait-Clear-Complete) +DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){MSC_A_ST_RELEASING}: RAN encode: CLEAR_COMMAND on UTRAN-Iu +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST +DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - msc_a_fsm_releasing_onenter: now used by 2 (active-conn,attached) + iu_release_sent == 1 +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){MSC_A_ST_RELEASING}: RAN decode: CLEAR_COMPLETE +DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){MSC_A_ST_RELEASING}: - wait-Clear-Complete: now used by 0 (-) +DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){MSC_A_ST_RELEASING}: Received Event MSC_A_EV_UNUSED +DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){MSC_A_ST_RELEASING}: state_chg to MSC_A_ST_RELEASED +DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){MSC_A_ST_RELEASED}: Released: msc_a use is 0 (-) +DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){MSC_A_ST_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) +DVLR vlr_lu_fsm(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){VLR_ULA_S_DONE}: Terminating in cascade, depth 2 (cause = OSMO_FSM_TERM_PARENT, caused by: msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU)) +DVLR vlr_lu_fsm(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){VLR_ULA_S_DONE}: Removing from parent msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU) +DVLR vlr_lu_fsm(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT +DVLR vlr_lu_fsm(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){VLR_ULA_S_DONE}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU) +DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){MSC_A_ST_RELEASED}: Removing from parent msub_fsm +DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){MSC_A_ST_RELEASED}: max total use count was 3 +DMSC msub_fsm{active}: Received Event MSUB_EV_ROLE_TERMINATED +DMSC msub(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100) MSC-A terminated +DMSC msub(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100) 1 MSC-I still active +DMSC msub_fsm{active}: state_chg to terminating +DMSC msub_fsm{terminating}: Terminating in cascade, depth 2 (cause = OSMO_FSM_TERM_REGULAR, caused by: msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU)) +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){0}: Terminating in cascade, depth 3 (cause = OSMO_FSM_TERM_PARENT, caused by: msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU)) +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){0}: Removing from parent msub_fsm +DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){0}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU) +DMSC msub(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100) Free +DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - active-conn: now used by 1 (attached) +DMSC msub_fsm{terminating}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU) +DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){MSC_A_ST_RELEASED}: Deallocated, including all deferred deallocations +- msub gone +- LU was successful, and the conn has already been closed + llist_count(&msub_list) == 0 +DVLR freeing VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 (max total use count was 4) +===== test_umts_auth_ciph_resync_utran: SUCCESS ===== test_umts_authen_too_short_res_geran - Location Update request causes a GSUP Send Auth Info request to HLR @@ -1735,13 +2611,14 @@ DREF VLR subscr IMSI-901700000010650 + active-conn: now used by 2 (_lu_fsm_assoc DMSC msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK DMSC msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH DREF VLR subscr IMSI-901700000010650 - _lu_fsm_associate_vsub: now used by 1 (active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre() DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Allocated DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU) DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START -GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f00a0101 +GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f02801020a0101 DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI DREF msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - mm_rx_loc_upd_req: now used by 2 (rx_from_ms,lu) DREF msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu) @@ -1770,12 +2647,12 @@ DMM msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: MM UMTS AUTHENTI DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP DVLR SUBSCR(IMSI-901700000010650) AUTH on GERAN received SRES/RES: e229c19e791f2e (7 bytes) DVLR SUBSCR(IMSI-901700000010650) AUTH SRES/RES has invalid length: 7. Expected either 4 (GSM AKA) or 8 (UMTS AKA) -DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result Illegal MS +DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result FAILURE, cause ILLEGAL_MS DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTH_FAILED GSUP --> HLR: OSMO_GSUP_MSGT_AUTH_FAIL_REPORT: 0b010809710000000156f00a0101 DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_AUTH_FAILED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_AUTH_FAILED}: Removing from parent vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU) -DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES +DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_FAILURE - sending LU Reject for IMSI-901700000010650:GERAN-A:LU, cause 3 DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_DONE DMSC msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: Received Event MSC_A_EV_CN_CLOSE @@ -1822,9 +2699,6 @@ DMSC msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_RELEASED}: Deallocated, inc llist_count(&msub_list) == 0 ===== test_umts_authen_too_short_res_geran: SUCCESS -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 17 - ===== test_umts_authen_too_short_res_utran - Location Update request causes a GSUP Send Auth Info request to HLR MSC <--UTRAN-Iu-- MS: GSM48_MT_MM_LOC_UPD_REQUEST @@ -1853,13 +2727,14 @@ DREF VLR subscr IMSI-901700000010650 + active-conn: now used by 2 (_lu_fsm_assoc DMSC msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK DMSC msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH DREF VLR subscr IMSI-901700000010650 - _lu_fsm_associate_vsub: now used by 1 (active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre() DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: Allocated DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU) DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START -GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f00a0101 +GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f02801020a0101 DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI DREF msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: - mm_rx_loc_upd_req: now used by 2 (rx_from_ms,lu) DREF msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu) @@ -1888,12 +2763,12 @@ DMM msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: MM UMTS AUTHENT DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP DVLR SUBSCR(IMSI-901700000010650) AUTH on UTRAN received RES: e229c19e791f2e (7 bytes) DVLR SUBSCR(IMSI-901700000010650) AUTH RES has invalid length: 7. Expected 8 (UMTS AKA) -DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result Illegal MS +DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result FAILURE, cause ILLEGAL_MS DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTH_FAILED GSUP --> HLR: OSMO_GSUP_MSGT_AUTH_FAIL_REPORT: 0b010809710000000156f00a0101 DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_AUTH_FAILED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_AUTH_FAILED}: Removing from parent vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU) -DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES +DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_FAILURE - sending LU Reject for IMSI-901700000010650:UTRAN-Iu:LU, cause 3 DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_DONE DMSC msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: Received Event MSC_A_EV_CN_CLOSE @@ -1940,9 +2815,6 @@ DMSC msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_RELEASED}: Deallocated, in llist_count(&msub_list) == 0 ===== test_umts_authen_too_short_res_utran: SUCCESS -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 17 - ===== test_umts_authen_too_long_res_geran - Location Update request causes a GSUP Send Auth Info request to HLR MSC <--GERAN-A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST @@ -1971,13 +2843,14 @@ DREF VLR subscr IMSI-901700000010650 + active-conn: now used by 2 (_lu_fsm_assoc DMSC msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK DMSC msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH DREF VLR subscr IMSI-901700000010650 - _lu_fsm_associate_vsub: now used by 1 (active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre() DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Allocated DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU) DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START -GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f00a0101 +GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f02801020a0101 DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI DREF msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - mm_rx_loc_upd_req: now used by 2 (rx_from_ms,lu) DREF msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu) @@ -2006,12 +2879,12 @@ DMM msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: MM UMTS AUTHENTI DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP DVLR SUBSCR(IMSI-901700000010650) AUTH on GERAN received SRES/RES: e229c19e791f2e4123 (9 bytes) DVLR SUBSCR(IMSI-901700000010650) AUTH SRES/RES has invalid length: 9. Expected either 4 (GSM AKA) or 8 (UMTS AKA) -DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result Illegal MS +DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result FAILURE, cause ILLEGAL_MS DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTH_FAILED GSUP --> HLR: OSMO_GSUP_MSGT_AUTH_FAIL_REPORT: 0b010809710000000156f00a0101 DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_AUTH_FAILED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_AUTH_FAILED}: Removing from parent vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU) -DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES +DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_FAILURE - sending LU Reject for IMSI-901700000010650:GERAN-A:LU, cause 3 DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_DONE DMSC msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: Received Event MSC_A_EV_CN_CLOSE @@ -2058,9 +2931,6 @@ DMSC msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_RELEASED}: Deallocated, inc llist_count(&msub_list) == 0 ===== test_umts_authen_too_long_res_geran: SUCCESS -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 17 - ===== test_umts_authen_too_long_res_utran - Location Update request causes a GSUP Send Auth Info request to HLR MSC <--UTRAN-Iu-- MS: GSM48_MT_MM_LOC_UPD_REQUEST @@ -2089,13 +2959,14 @@ DREF VLR subscr IMSI-901700000010650 + active-conn: now used by 2 (_lu_fsm_assoc DMSC msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK DMSC msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH DREF VLR subscr IMSI-901700000010650 - _lu_fsm_associate_vsub: now used by 1 (active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre() DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: Allocated DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU) DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START -GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f00a0101 +GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f02801020a0101 DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI DREF msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: - mm_rx_loc_upd_req: now used by 2 (rx_from_ms,lu) DREF msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu) @@ -2124,12 +2995,12 @@ DMM msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: MM UMTS AUTHENT DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP DVLR SUBSCR(IMSI-901700000010650) AUTH on UTRAN received RES: e229c19e791f2e4123 (9 bytes) DVLR SUBSCR(IMSI-901700000010650) AUTH RES has invalid length: 9. Expected 8 (UMTS AKA) -DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result Illegal MS +DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result FAILURE, cause ILLEGAL_MS DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTH_FAILED GSUP --> HLR: OSMO_GSUP_MSGT_AUTH_FAIL_REPORT: 0b010809710000000156f00a0101 DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_AUTH_FAILED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_AUTH_FAILED}: Removing from parent vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU) -DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES +DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_FAILURE - sending LU Reject for IMSI-901700000010650:UTRAN-Iu:LU, cause 3 DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_DONE DMSC msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: Received Event MSC_A_EV_CN_CLOSE @@ -2176,9 +3047,6 @@ DMSC msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_RELEASED}: Deallocated, in llist_count(&msub_list) == 0 ===== test_umts_authen_too_long_res_utran: SUCCESS -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 17 - ===== test_umts_authen_only_sres_geran - Location Update request causes a GSUP Send Auth Info request to HLR MSC <--GERAN-A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST @@ -2207,13 +3075,14 @@ DREF VLR subscr IMSI-901700000010650 + active-conn: now used by 2 (_lu_fsm_assoc DMSC msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK DMSC msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH DREF VLR subscr IMSI-901700000010650 - _lu_fsm_associate_vsub: now used by 1 (active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre() DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Allocated DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU) DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START -GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f00a0101 +GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f02801020a0101 DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI DREF msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - mm_rx_loc_upd_req: now used by 2 (rx_from_ms,lu) DREF msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu) @@ -2242,12 +3111,12 @@ DMM msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: MM GSM AUTHENTIC DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP DVLR SUBSCR(IMSI-901700000010650) AUTH on GERAN received SRES/RES: e229c19e (4 bytes) DVLR SUBSCR(IMSI-901700000010650) GSM AUTH failure: mismatching sres (expected sres=9b 36 ef df ) -DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result Illegal MS +DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result FAILURE, cause ILLEGAL_MS DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTH_FAILED GSUP --> HLR: OSMO_GSUP_MSGT_AUTH_FAIL_REPORT: 0b010809710000000156f00a0101 DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_AUTH_FAILED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_AUTH_FAILED}: Removing from parent vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU) -DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES +DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_FAILURE - sending LU Reject for IMSI-901700000010650:GERAN-A:LU, cause 3 DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_DONE DMSC msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: Received Event MSC_A_EV_CN_CLOSE @@ -2294,9 +3163,6 @@ DMSC msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_RELEASED}: Deallocated, inc llist_count(&msub_list) == 0 ===== test_umts_authen_only_sres_geran: SUCCESS -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 17 - ===== test_umts_authen_only_sres_utran - Location Update request causes a GSUP Send Auth Info request to HLR MSC <--UTRAN-Iu-- MS: GSM48_MT_MM_LOC_UPD_REQUEST @@ -2325,13 +3191,14 @@ DREF VLR subscr IMSI-901700000010650 + active-conn: now used by 2 (_lu_fsm_assoc DMSC msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK DMSC msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH DREF VLR subscr IMSI-901700000010650 - _lu_fsm_associate_vsub: now used by 1 (active-conn) +DVLR set Last E-UTRAN PLMN ID on subscriber: (none) DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre() DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1() DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: Allocated DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU) DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START -GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f00a0101 +GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f02801020a0101 DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI DREF msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: - mm_rx_loc_upd_req: now used by 2 (rx_from_ms,lu) DREF msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu) @@ -2360,12 +3227,12 @@ DMM msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: MM GSM AUTHENTI DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP DVLR SUBSCR(IMSI-901700000010650) AUTH on UTRAN received RES: e229c19e (4 bytes) DVLR SUBSCR(IMSI-901700000010650) AUTH via UTRAN, cannot allow GSM AKA (MS is R99 capable, vec has UMTS AKA tokens, res_len=4 is INVALID on UTRAN) -DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result Illegal MS +DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result FAILURE, cause ILLEGAL_MS DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTH_FAILED GSUP --> HLR: OSMO_GSUP_MSGT_AUTH_FAIL_REPORT: 0b010809710000000156f00a0101 DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_AUTH_FAILED}: Terminating (cause = OSMO_FSM_TERM_REGULAR) DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_AUTH_FAILED}: Removing from parent vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU) -DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES +DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_FAILURE - sending LU Reject for IMSI-901700000010650:UTRAN-Iu:LU, cause 3 DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_DONE DMSC msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: Received Event MSC_A_EV_CN_CLOSE @@ -2412,9 +3279,3 @@ DMSC msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_RELEASED}: Deallocated, in llist_count(&msub_list) == 0 ===== test_umts_authen_only_sres_utran: SUCCESS -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 17 - -full talloc report on 'msgb' (total 0 bytes in 1 blocks) -talloc_total_blocks(tall_bsc_ctx) == 17 - diff --git a/tests/msc_vlr/msc_vlr_tests.c b/tests/msc_vlr/msc_vlr_tests.c index 488cd198c..062d8a35b 100644 --- a/tests/msc_vlr/msc_vlr_tests.c +++ b/tests/msc_vlr/msc_vlr_tests.c @@ -41,10 +41,12 @@ #include <osmocom/msc/msc_t.h> #include <osmocom/msc/call_leg.h> #include <osmocom/msc/rtp_stream.h> +#include <osmocom/msc/codec_mapping.h> #include "msc_vlr_tests.h" void *msc_vlr_tests_ctx = NULL; +void *msgb_ctx = NULL; bool _log_lines = false; @@ -73,10 +75,20 @@ bool iu_release_sent = false; bool bssap_clear_expected = false; bool bssap_clear_sent = false; +bool bssap_assignment_expected = false; +bool bssap_assignment_sent = false; +struct gsm0808_channel_type bssap_assignment_command_last_channel_type; +bool iu_rab_assignment_expected = false; +bool iu_rab_assignment_sent = false; + uint32_t cc_to_mncc_tx_expected_msg_type = 0; const char *cc_to_mncc_tx_expected_imsi = NULL; bool cc_to_mncc_tx_confirmed = false; uint32_t cc_to_mncc_tx_got_callref = 0; +char cc_to_mncc_tx_last_sdp[1024] = {}; + +bool expecting_crcx[2] = {}; +bool got_crcx[2] = {}; extern int ran_dec_dtap_undup_pdisc_ctr_bin(uint8_t pdisc); @@ -171,7 +183,7 @@ void conn_conclude_cm_service_req(struct msub *msub, const char *cm_service_use) count = osmo_use_count_by(&msc_a->use_count, cm_service_use); OSMO_ASSERT(count > 0); - OSMO_ASSERT(osmo_use_count_get_put(&msc_a->use_count, cm_service_use, -count) == 0) + OSMO_ASSERT(osmo_use_count_get_put(&msc_a->use_count, cm_service_use, -count) == 0); ASSERT_RELEASE_CLEAR(msc_a->c.ran->type); } @@ -246,8 +258,10 @@ static int _validate_dtap(struct msgb *msg, enum osmo_rat_type to_ran) /* Mask the sequence number out before comparing */ msg->data[1] &= 0x3f; - if (!msgb_eq_data_print(msg, dtap_tx_expected->data, dtap_tx_expected->len)) + if (!msgb_eq_data_print(msg, dtap_tx_expected->data, dtap_tx_expected->len)) { + btw("Expected %s", osmo_hexdump(dtap_tx_expected->data, dtap_tx_expected->len)); abort(); + } btw("DTAP matches expected message"); @@ -296,6 +310,24 @@ static int bssap_validate_cipher_mode_cmd(const struct ran_cipher_mode_command * return 0; } +static void bssap_validate_assignment_cmd(const struct ran_assignment_command *assignment_command) +{ + OSMO_ASSERT(bssap_assignment_expected); + bssap_assignment_expected = false; + bssap_assignment_sent = true; + if (assignment_command->channel_type) + bssap_assignment_command_last_channel_type = *assignment_command->channel_type; + else + bssap_assignment_command_last_channel_type = (struct gsm0808_channel_type){}; +} + +static void iucs_validate_assignment_cmd(const struct ran_assignment_command *assignment_command) +{ + OSMO_ASSERT(iu_rab_assignment_expected); + iu_rab_assignment_expected = false; + iu_rab_assignment_sent = true; +} + static int iucs_validate_security_mode_ctrl(const struct ran_cipher_mode_command *cmd) { const char *got_ik; @@ -346,6 +378,18 @@ struct msgb *dont_ran_encode(struct osmo_fsm_inst *caller_fi, const struct ran_m OSMO_ASSERT(false); } break; + case RAN_MSG_ASSIGNMENT_COMMAND: + switch (ran_type) { + case OSMO_RAT_GERAN_A: + bssap_validate_assignment_cmd(&ran_enc_msg->assignment_command); + break; + case OSMO_RAT_UTRAN_IU: + iucs_validate_assignment_cmd(&ran_enc_msg->assignment_command); + break; + default: + OSMO_ASSERT(false); + } + break; default: break; } @@ -371,6 +415,16 @@ struct ran_infra test_ran_infra[] = { .log_subsys = DIUCS, .tdefs = msc_tdefs_utran, .ran_encode = dont_ran_encode, + .force_mgw_codecs_to_ran = { + .count = 1, + .codec = { + { + .payload_type = 96, + .subtype_name = "VND.3GPP.IUFP", + .rate = 16000, + }, + }, + }, }, }; @@ -382,7 +436,7 @@ static int fake_msc_a_ran_dec(const struct ran_msg *ran_dec_msg) return msc_a_ran_decode_cb(g_msub->role[MSC_ROLE_A], &d, ran_dec_msg); } -void rx_from_ms(struct msgb *msg) +void rx_from_ms(struct msgb *msg, const struct gsm0808_speech_codec_list *codec_list_bss_supported) { struct gsm48_hdr *gh = msgb_l3(msg); struct ran_msg ran_dec_msg; @@ -415,6 +469,7 @@ void rx_from_ms(struct msgb *msg) .compl_l3 = { .cell_id = &cell_id, .msg = msg, + .codec_list_bss_supported = codec_list_bss_supported, }, }; } else { @@ -442,7 +497,30 @@ void ms_sends_msg(const char *hex) msg = msgb_from_hex("ms_sends_msg", 1024, hex); msg->l1h = msg->l2h = msg->l3h = msg->data; - rx_from_ms(msg); + rx_from_ms(msg, NULL); + msgb_free(msg); +} + +void ms_sends_msgf(const char *fmt, ...) +{ + va_list ap; + char *hex; + + va_start(ap, fmt); + hex = talloc_vasprintf(msc_vlr_tests_ctx, fmt, ap); + va_end(ap); + + ms_sends_msg(hex); + talloc_free(hex); +} + +void ms_sends_compl_l3(const char *hex, const struct gsm0808_speech_codec_list *codec_list_bss_supported) +{ + struct msgb *msg; + + msg = msgb_from_hex("ms_sends_msg", 1024, hex); + msg->l1h = msg->l2h = msg->l3h = msg->data; + rx_from_ms(msg, codec_list_bss_supported); msgb_free(msg); } @@ -602,6 +680,14 @@ void clear_vlr() bssap_clear_sent = false; osmo_gettimeofday_override = false; + + memset(expecting_crcx, 0, sizeof(expecting_crcx)); + memset(got_crcx, 0, sizeof(got_crcx)); + + bssap_assignment_expected = false; + bssap_assignment_sent = false; + iu_rab_assignment_expected = false; + iu_rab_assignment_sent = false; } static struct log_info_cat test_categories[] = { @@ -677,8 +763,18 @@ struct gsm_mncc *on_call_release_mncc_sends_to_cc_data = NULL; int mncc_recv(struct gsm_network *net, struct msgb *msg) { struct gsm_mncc *mncc = (void*)msg->data; - log("MSC --> MNCC: callref 0x%x: %s", mncc->callref, - get_mncc_name(mncc->msg_type)); + if (mncc->msg_type == MNCC_RTP_CREATE) { + struct gsm_mncc_rtp *rtp = (void *)msg->data; + log("MSC --> MNCC: callref 0x%x: %s\n%s", rtp->callref, + get_mncc_name(rtp->msg_type), + rtp->sdp); + OSMO_STRLCPY_ARRAY(cc_to_mncc_tx_last_sdp, rtp->sdp); + } else { + log("MSC --> MNCC: callref 0x%x: %s\n%s", mncc->callref, + get_mncc_name(mncc->msg_type), + mncc->sdp); + OSMO_STRLCPY_ARRAY(cc_to_mncc_tx_last_sdp, mncc->sdp); + } if (mncc->msg_type == MNCC_REL_IND && on_call_release_mncc_sends_to_cc_data) { @@ -746,8 +842,16 @@ int __wrap_osmo_gsup_client_send(struct osmo_gsup_client *gsupc, struct msgb *ms if (len < 1) abort(); - if (!msgb_eq_data_print(msg, buf, len)) + /* Compare only the length expected. Extra data is fine, to not care about new GSUP IEs invented later. */ + if (msg->len < len) { + fprintf(stderr, "ERROR: GSUP message too short, expected '%s'\n", gsup_tx_expected); abort(); + } + + if (memcmp(msg->data, buf, len)) { + fprintf(stderr, "ERROR: GSUP message mismatch, expected it to start with '%s'\n", gsup_tx_expected); + abort(); + } talloc_free(msg); gsup_tx_confirmed = true; @@ -755,14 +859,81 @@ int __wrap_osmo_gsup_client_send(struct osmo_gsup_client *gsupc, struct msgb *ms return 0; } +struct rtp_stream fake_rtp[2] = { + { + .dir = RTP_TO_RAN, + .local = { + .ip = "10.23.42.1", + .port = 99, + }, + .remote = { + .ip = "10.23.42.2", + .port = 100, + }, + }, + { + .dir = RTP_TO_CN, + .local = { + .ip = "10.23.42.1", + .port = 23, + }, + .remote = { + .ip = "10.23.42.2", + .port = 42, + }, + }, +}; + +void expect_crcx(enum rtp_direction towards) +{ + OSMO_ASSERT(!expecting_crcx[towards]); + expecting_crcx[towards] = true; + got_crcx[towards] = false; +} + +bool crcx_scheduled(enum rtp_direction towards) +{ + return got_crcx[towards]; +} + /* override, requires '-Wl,--wrap=call_leg_ensure_ci' */ -int __real_call_leg_ensure_ci(struct call_leg *cl, enum rtp_direction dir, uint32_t call_id, struct gsm_trans *for_trans); -int __wrap_call_leg_ensure_ci(struct call_leg *cl, enum rtp_direction dir, uint32_t call_id, struct gsm_trans *for_trans) +int __real_call_leg_ensure_ci(struct call_leg *cl, enum rtp_direction dir, uint32_t call_id, struct gsm_trans *for_trans, + const struct sdp_audio_codecs *codecs_if_known, + const struct osmo_sockaddr_str *remote_addr_if_known); +int __wrap_call_leg_ensure_ci(struct call_leg *cl, enum rtp_direction dir, uint32_t call_id, struct gsm_trans *for_trans, + const struct sdp_audio_codecs *codecs_if_known, + const struct osmo_sockaddr_str *remote_addr_if_known) { - log("MS <--Call Assignment-- MSC: callref=0x%x", call_id); + if (!cl->rtp[dir]) { + log("MGW <--CRCX to %s-- MSC: call_id=0x%x codecs=%s", rtp_direction_name(dir), call_id, + codecs_if_known ? sdp_audio_codecs_to_str(codecs_if_known) : "unset"); + + OSMO_ASSERT(expecting_crcx[dir]); + expecting_crcx[dir] = false; + got_crcx[dir] = true; + + call_leg_ensure_rtp_alloc(cl, dir, call_id, for_trans); + if (codecs_if_known) + rtp_stream_set_codecs(cl->rtp[dir], codecs_if_known); + if (remote_addr_if_known && osmo_sockaddr_str_is_nonzero(remote_addr_if_known)) + rtp_stream_set_remote_addr(cl->rtp[dir], remote_addr_if_known); + } + return 0; } +void crcx_ok(enum rtp_direction dir) +{ + struct msc_a *msc_a = msub_msc_a(g_msub); + struct call_leg *cl = msc_a->cc.call_leg; + OSMO_ASSERT(cl); + OSMO_ASSERT(cl->rtp[dir]); + osmo_sockaddr_str_from_str(&cl->rtp[dir]->local, "10.23.23.1", 23); + //osmo_sockaddr_str_from_str(&cl->rtp[dir].remote, "10.42.42.1", 42); + log("MGW --CRCX OK to %s--> MSC", rtp_direction_name(dir)); + osmo_fsm_inst_dispatch(cl->fi, CALL_LEG_EV_RTP_STREAM_ADDR_AVAILABLE, cl->rtp[dir]); +} + static int fake_vlr_tx_lu_acc(void *msc_conn_ref, uint32_t send_tmsi) { struct msc_a *msc_a = msc_conn_ref; @@ -874,13 +1045,36 @@ void ms_sends_ciphering_mode_complete(const char *inner_ran_msg) g_msub = NULL; } -void ms_sends_security_mode_complete() +void ms_sends_security_mode_complete(uint8_t utran_encryption) { struct ran_msg ran_dec; ran_dec = (struct ran_msg){ .msg_type = RAN_MSG_CIPHER_MODE_COMPLETE, + .cipher_mode_complete.utran_encryption = utran_encryption, + }; + fake_msc_a_ran_dec(&ran_dec); + + if (!conn_exists(g_msub)) + g_msub = NULL; +} + +void ms_sends_assignment_complete(const char *sdp_codec_name) +{ + struct ran_msg ran_dec; + const struct codec_mapping *m = codec_mapping_by_subtype_name(sdp_codec_name); + OSMO_ASSERT(m); + OSMO_ASSERT(m->has_gsm0808_speech_codec); + + ran_dec = (struct ran_msg){ + .msg_type = RAN_MSG_ASSIGNMENT_COMPLETE, + .assignment_complete = { + .codec_present = true, + .codec = m->gsm0808_speech_codec, + .codec_with_iuup = (rx_from_ran == OSMO_RAT_UTRAN_IU), + }, }; + osmo_sockaddr_str_from_str(&ran_dec.assignment_complete.remote_rtp, "1.2.3.4", 1234); fake_msc_a_ran_dec(&ran_dec); if (!conn_exists(g_msub)) @@ -916,38 +1110,6 @@ void fake_time_start() fake_time_passes(0, 0); } -static void check_talloc(void *msgb_ctx, void *msc_vlr_tests_ctx) -{ - /* Verifying that the msgb context is empty */ - talloc_report_full(msgb_ctx, stderr); - /* Expecting these to stick around in msc_vlr_tests_ctx: - * full talloc report on 'msgb' (total 0 bytes in 1 blocks) - * talloc_total_blocks(tall_bsc_ctx) == 17 - * full talloc report on 'msc_vlr_tests_ctx' (total 6336 bytes in 17 blocks) - * struct osmo_gsup_client contains 256 bytes in 1 blocks (ref 0) 0x613000000260 - * struct gsm_network contains 4647 bytes in 9 blocks (ref 0) 0x6190000000e0 - * struct mgcp_client contains 688 bytes in 1 blocks (ref 0) 0x6180000000e0 - * struct sccp_ran_inst contains 152 bytes in 1 blocks (ref 0) 0x611000000460 - * struct sccp_ran_inst contains 152 bytes in 1 blocks (ref 0) 0x611000000320 - * struct gsup_client_mux contains 200 bytes in 2 blocks (ref 0) 0x6110000001e0 - * struct ipaccess_unit contains 64 bytes in 1 blocks (ref 0) 0x60e000023180 - * struct vlr_instance contains 248 bytes in 1 blocks (ref 0) 0x6130000000a0 - * no_gsup_server contains 15 bytes in 1 blocks (ref 0) 0x60b000000150 - * ../../../src/libosmocore/src/rate_ctr.c:234 contains 2352 bytes in 1 blocks (ref 0) 0x61e0000000e0 - * logging contains 1433 bytes in 5 blocks (ref 0) 0x60b0000000a0 - * struct log_target contains 240 bytes in 2 blocks (ref 0) 0x6120000000a0 - * struct log_category contains 72 bytes in 1 blocks (ref 0) 0x60f0000000a0 - * struct log_info contains 1192 bytes in 2 blocks (ref 0) 0x60d0000000a0 - * struct log_info_cat contains 1152 bytes in 1 blocks (ref 0) 0x61a0000000e0 - * msgb contains 0 bytes in 1 blocks (ref 0) 0x608000000100 - */ - fprintf(stderr, "talloc_total_blocks(tall_bsc_ctx) == %zu\n", - talloc_total_blocks(msc_vlr_tests_ctx)); - if (talloc_total_blocks(msc_vlr_tests_ctx) != 17) - talloc_report_full(msc_vlr_tests_ctx, stderr); - fprintf(stderr, "\n"); -} - static struct { bool verbose; int run_test_nr; @@ -999,34 +1161,46 @@ static void handle_options(int argc, char **argv) } } -void *msgb_ctx = NULL; - static void run_tests(int nr) { int test_nr; - check_talloc(msgb_ctx, msc_vlr_tests_ctx); - nr--; /* arg's first test is 1, in here it's 0 */ for (test_nr = 0; msc_vlr_tests[test_nr]; test_nr++) { + size_t talloc_blocks_before_test; + if (nr >= 0 && test_nr != nr) continue; if (cmdline_opts.verbose) fprintf(stderr, "(test nr %d)\n", test_nr + 1); + talloc_blocks_before_test = talloc_total_blocks(msc_vlr_tests_ctx); + msc_vlr_tests[test_nr](); + if (talloc_total_blocks(msc_vlr_tests_ctx) != talloc_blocks_before_test) { + fprintf(stderr, "ERROR: talloc leak: %zu blocks\n", + talloc_total_blocks(msc_vlr_tests_ctx) - talloc_blocks_before_test); + talloc_report_full(msc_vlr_tests_ctx, stderr); + fprintf(stderr, "\n"); + } + + if (talloc_total_blocks(msgb_ctx) > 1) { + fprintf(stderr, "ERROR: msgb leak:\n"); + talloc_report_full(msgb_ctx, stderr); + fprintf(stderr, "\n"); + } + if (cmdline_opts.verbose) fprintf(stderr, "(test nr %d)\n", test_nr + 1); - - check_talloc(msgb_ctx, msc_vlr_tests_ctx); } } struct gsm_network *test_net(void *ctx) { struct gsm_network *net = gsm_network_init(ctx, mncc_recv); + struct mgcp_client *client; net->gsup_server_addr_str = talloc_strdup(net, "no_gsup_server"); net->gsup_server_port = 0; @@ -1061,10 +1235,11 @@ struct gsm_network *test_net(void *ctx) INIT_LLIST_HEAD(&net->iu.sri->ran_conns); net->mgw.tdefs = g_mgw_tdefs; - mgcp_client_conf_init(&net->mgw.conf); net->mgw.tdefs = g_mgw_tdefs; - net->mgw.client = mgcp_client_init(net, &net->mgw.conf); - + net->mgw.conf = mgcp_client_conf_alloc(net); + net->mgw.mgw_pool = mgcp_client_pool_alloc(net); + client = mgcp_client_init(net, net->mgw.conf); + mgcp_client_pool_register_single(net->mgw.mgw_pool, client); return net; } @@ -1083,9 +1258,11 @@ int main(int argc, char **argv) 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_filename2(osmo_stderr_target, LOG_FILENAME_NONE); log_set_print_category(osmo_stderr_target, 1); + log_set_print_category_hex(osmo_stderr_target, 0); log_set_category_filter(osmo_stderr_target, DLSMS, 1, LOGL_DEBUG); + log_set_category_filter(osmo_stderr_target, DLMGCP, 0, LOGL_NOTICE); if (cmdline_opts.verbose) { log_set_print_filename2(osmo_stderr_target, LOG_FILENAME_BASENAME); @@ -1125,6 +1302,5 @@ int main(int argc, char **argv) printf("Done\n"); - check_talloc(msgb_ctx, msc_vlr_tests_ctx); return 0; } diff --git a/tests/msc_vlr/msc_vlr_tests.h b/tests/msc_vlr/msc_vlr_tests.h index 9df9cf049..b0605f104 100644 --- a/tests/msc_vlr/msc_vlr_tests.h +++ b/tests/msc_vlr/msc_vlr_tests.h @@ -26,16 +26,22 @@ #include <stdbool.h> #include <stdio.h> +#include <osmocom/crypt/utran_cipher.h> #include <osmocom/msc/gsm_data.h> #include <osmocom/msc/vlr.h> #include <osmocom/msc/msub.h> #include <osmocom/msc/msc_a.h> #include <osmocom/msc/mncc.h> +#include <osmocom/msc/call_leg.h> +#include <osmocom/msc/rtp_stream.h> extern bool _log_lines; +#define LOG_COLOR "\033[1;33m" +#define LOG_COLOR_OFF "\033[0;m" + #define _log(fmt, args...) do { \ if (_log_lines) \ - fprintf(stderr, " %4d:%s: " fmt "\n", \ + fprintf(stderr, LOG_COLOR " %4d:%s: " fmt LOG_COLOR_OFF "\n", \ __LINE__, __FILE__, ## args ); \ else \ fprintf(stderr, fmt "\n", ## args ); \ @@ -50,6 +56,8 @@ extern bool _log_lines; #define comment_start() fprintf(stderr, "===== %s\n", __func__); #define comment_end() fprintf(stderr, "===== %s: SUCCESS\n\n", __func__); +extern void *msc_vlr_tests_ctx; + extern struct msub *g_msub; extern struct gsm_network *net; extern void *msgb_ctx; @@ -110,6 +118,7 @@ extern uint32_t cc_to_mncc_tx_expected_msg_type; extern const char *cc_to_mncc_tx_expected_imsi; extern bool cc_to_mncc_tx_confirmed; extern uint32_t cc_to_mncc_tx_got_callref; +extern char cc_to_mncc_tx_last_sdp[1024]; extern struct gsm_mncc *on_call_release_mncc_sends_to_cc_data; @@ -140,6 +149,24 @@ static inline void expect_release_clear(enum osmo_rat_type via_ran) } } +extern bool bssap_assignment_expected; +extern bool bssap_assignment_sent; +extern struct gsm0808_channel_type bssap_assignment_command_last_channel_type; +extern bool iu_rab_assignment_expected; +extern bool iu_rab_assignment_sent; + +static inline void expect_bssap_assignment() +{ + bssap_assignment_expected = true; + bssap_assignment_sent = false; +} + +static inline void expect_iu_rab_assignment() +{ + iu_rab_assignment_expected = true; + iu_rab_assignment_sent = false; +} + struct msc_vlr_test_cmdline_opts { bool verbose; int run_test_nr; @@ -160,13 +187,17 @@ void paging_expect_imsi(const char *imsi); void paging_expect_tmsi(uint32_t tmsi); void ms_sends_msg(const char *hex); +void ms_sends_msgf(const char *fmt, ...); +void ms_sends_compl_l3(const char *hex, const struct gsm0808_speech_codec_list *codec_list_bss_supported); void ms_sends_classmark_update(const struct osmo_gsm48_classmark *classmark); void ms_sends_ciphering_mode_complete(const char *inner_nas_msg); -void ms_sends_security_mode_complete(); +void ms_sends_security_mode_complete(uint8_t utran_encryption); +void ms_sends_assignment_complete(const char *sdp_codec_name); void gsup_rx(const char *rx_hex, const char *expect_tx_hex); void send_sms(struct vlr_subscr *receiver, struct vlr_subscr *sender, char *str); +void crcx_ok(enum rtp_direction dir); void ran_sends_clear_complete(); @@ -246,5 +277,9 @@ extern const struct timeval fake_time_start_time; #define HLR_TO_VLR "0a0101" #define VLR_TO_HLR "0a0101" +#define CN_DOMAIN "280102" #define EUSE_TO_MSC_USSD "0a0103" #define MSC_USSD_TO_EUSE "0a0103" + +void expect_crcx(enum rtp_direction towards); +bool crcx_scheduled(enum rtp_direction towards); diff --git a/tests/sdp_msg/Makefile.am b/tests/sdp_msg/Makefile.am new file mode 100644 index 000000000..f86e5f7a3 --- /dev/null +++ b/tests/sdp_msg/Makefile.am @@ -0,0 +1,37 @@ +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + $(NULL) + +AM_CFLAGS = \ + -Wall \ + -ggdb3 \ + $(LIBOSMOCORE_CFLAGS) \ + $(NULL) + +AM_LDFLAGS = \ + $(COVERAGE_LDFLAGS) \ + -no-install \ + $(NULL) + +LDADD = \ + $(top_builddir)/src/libmsc/libmsc.a \ + $(LIBOSMOCORE_LIBS) \ + $(NULL) + +EXTRA_DIST = \ + sdp_msg_test.ok \ + sdp_msg_test.err \ + $(NULL) + +check_PROGRAMS = \ + sdp_msg_test \ + $(NULL) + +sdp_msg_test_SOURCES = \ + sdp_msg_test.c \ + $(NULL) + +.PHONY: update_exp +update_exp: + $(builddir)/sdp_msg_test >$(srcdir)/sdp_msg_test.ok 2>$(srcdir)/sdp_msg_test.err diff --git a/tests/sdp_msg/sdp_msg_test.c b/tests/sdp_msg/sdp_msg_test.c new file mode 100644 index 000000000..4798ae007 --- /dev/null +++ b/tests/sdp_msg/sdp_msg_test.c @@ -0,0 +1,574 @@ +#include <stdio.h> +#include <string.h> +#include <osmocom/core/utils.h> +#include <osmocom/msc/sdp_msg.h> + +struct sdp_test_data { + const char *sdp_input; + const char *expect_sdp_str; +}; + +static void dump_sdp(const char *str, const char *prefix) +{ + while (str && *str) { + const char *line_end = sdp_msg_line_end(str); + while (*line_end == '\r' || *line_end == '\n') + line_end++; + printf("%s%s\n", prefix, osmo_escape_str(str, line_end - str)); + str = line_end; + } +} + +struct sdp_test_data sdp_tests[] = { + { + "v=0\r\n" + "o=- 5628250 5628250 IN IP4 192.168.11.121\r\n" + "s=-\r\n" + "c=IN IP4 192.168.11.121\r\n" + "t=0 0\r\n" + "m=audio 10020 RTP/AVP 18 0 2 4 8 96 97 98 100 101\r\n" + "a=rtpmap:18 G729/8000\r\n" + "a=rtpmap:0 PCMU/8000\r\n" + "a=rtpmap:2 G726-32/8000\r\n" + "a=rtpmap:4 G723/8000\r\n" + "a=rtpmap:8 PCMA/8000\r\n" + "a=rtpmap:96 G726-40/8000\r\n" + "a=rtpmap:97 G726-24/8000\r\n" + "a=rtpmap:98 G726-16/8000\r\n" + "a=rtpmap:100 NSE/8000\r\n" + "a=fmtp:100 192-193\r\n" + "a=rtpmap:101 telephone-event/8000\r\n" + "a=fmtp:101 0-15\r\n" + "a=ptime:20\r\n" + "a=sendrecv\r\n" + , + "v=0\r\n" + "o=OsmoMSC 0 0 IN IP4 192.168.11.121\r\n" + "s=GSM Call\r\n" + "c=IN IP4 192.168.11.121\r\n" + "t=0 0\r\n" + "m=audio 10020 RTP/AVP 18 0 2 4 8 96 97 98 100 101\r\n" + "a=rtpmap:18 G729/8000\r\n" + "a=rtpmap:0 PCMU/8000\r\n" + "a=rtpmap:2 G726-32/8000\r\n" + "a=rtpmap:4 G723/8000\r\n" + "a=rtpmap:8 PCMA/8000\r\n" + "a=rtpmap:96 G726-40/8000\r\n" + "a=rtpmap:97 G726-24/8000\r\n" + "a=rtpmap:98 G726-16/8000\r\n" + "a=rtpmap:100 NSE/8000\r\n" + "a=fmtp:100 192-193\r\n" + "a=rtpmap:101 telephone-event/8000\r\n" + "a=fmtp:101 0-15\r\n" + "a=ptime:20\r\n" + "a=sendrecv\r\n" + , + }, + { + "v=0\r\n" + "o=FooBar 1565090289 1565090290 IN IP4 192.168.11.151\r\n" + "s=FooBar\r\n" + "c=IN IP4 192.168.11.151\r\n" + "t=0 0\r\n" + "m=audio 16398 RTP/AVP 98\r\n" + "a=rtpmap:98 AMR/8000\r\n" + "a=fmtp:98 octet-align=1; mode-set=4\r\n" + "a=ptime:20\r\n" + "a=rtcp:16399 IN IP4 192.168.11.151\r\n" + , + "v=0\r\n" + "o=OsmoMSC 0 0 IN IP4 192.168.11.151\r\n" + "s=GSM Call\r\n" + "c=IN IP4 192.168.11.151\r\n" + "t=0 0\r\n" + "m=audio 16398 RTP/AVP 98\r\n" + "a=rtpmap:98 AMR/8000\r\n" + "a=fmtp:98 octet-align=1; mode-set=4\r\n" + "a=ptime:20\r\n" + , + }, + { + "v=0\r\n" + "o=FooBar 1565090289 1565090290 IN IP4 192.168.11.151\r\n" + "s=FooBar\r\n" + "c=IN IP4 192.168.11.140\r\n" + "t=0 0\r\n" + "m=audio 30436 RTP/AVP 18 0 4 8 101\r\n" + "a=rtpmap:18 G729/8000\r\n" + "a=rtpmap:0 PCMU/8000\r\n" + "a=rtpmap:4 G723/8000\r\n" + "a=rtpmap:8 PCMA/8000\r\n" + "a=rtpmap:101 telephone-event/8000\r\n" + "a=fmtp:101 0-15\r\n" + "a=sendrecv\r\n" + "a=rtcp:30437\r\n" + "a=ptime:20\r\n" + , + "v=0\r\n" + "o=OsmoMSC 0 0 IN IP4 192.168.11.140\r\n" /* <- NOTE: loses the 'o=' address, uses only 'c=' */ + "s=GSM Call\r\n" + "c=IN IP4 192.168.11.140\r\n" + "t=0 0\r\n" + "m=audio 30436 RTP/AVP 18 0 4 8 101\r\n" + "a=rtpmap:18 G729/8000\r\n" + "a=rtpmap:0 PCMU/8000\r\n" + "a=rtpmap:4 G723/8000\r\n" + "a=rtpmap:8 PCMA/8000\r\n" + "a=rtpmap:101 telephone-event/8000\r\n" + "a=fmtp:101 0-15\r\n" + "a=ptime:20\r\n" + "a=sendrecv\r\n" + , + }, +}; + +void test_parse_and_compose() +{ + int i; + bool ok = true; + + printf("\n\n%s\n", __func__); + + for (i = 0; i < ARRAY_SIZE(sdp_tests); i++) { + struct sdp_test_data *t = &sdp_tests[i]; + struct sdp_msg sdp = {}; + char str[1024]; + printf("\n[%d]\n", i); + dump_sdp(t->sdp_input, "sdp input: "); + + OSMO_ASSERT(sdp_msg_from_sdp_str(&sdp, t->sdp_input) == 0); + sdp_msg_to_sdp_str_buf(str, sizeof(str), &sdp); + + dump_sdp(str, "sdp_msg_to_sdp_str_buf: "); + if (strcmp(str, t->expect_sdp_str)) { + int j; + ok = false; + printf("ERROR:\n"); + dump_sdp(t->expect_sdp_str, "expect_sdp_str: "); + for (j = 0; t->expect_sdp_str[j]; j++) { + if (t->expect_sdp_str[j] != str[j]) { + printf("ERROR at position %d, at:\n", j); + dump_sdp(str + j, " mismatch: "); + break; + } + } + } else + printf("[%d] ok\n", i); + } + + OSMO_ASSERT(ok); +} + +struct sdp_intersect_test_data { + const char *descr; + const char *sdp_a; + const char *sdp_b; + const char *expect_intersection; +}; + +#define SDP_1 \ + "v=0\r\n" \ + "o=OsmoMSC 0 0 IN IP4 23.42.23.42\r\n" \ + "s=GSM Call\r\n" \ + "c=IN IP4 23.42.23.42\r\n" \ + "t=0 0\r\n" \ + "m=audio 30436 RTP/AVP 112 3 111 110\r\n" \ + "a=rtpmap:112 AMR/8000\r\n" \ + "a=fmtp:112 octet-align=1\r\n" \ + "a=rtpmap:3 GSM/8000\r\n" \ + "a=rtpmap:111 GSM-HR-08/8000\r\n" \ + "a=rtpmap:110 GSM-EFR/8000\r\n" \ + "a=ptime:20\r\n" + +#define SDP_2 \ + "v=0\r\n" \ + "o=OsmoMSC 0 0 IN IP4 23.42.23.42\r\n" \ + "s=GSM Call\r\n" \ + "c=IN IP4 23.42.23.42\r\n" \ + "t=0 0\r\n" \ + "m=audio 30436 RTP/AVP 112 110\r\n" \ + "a=rtpmap:112 AMR/8000\r\n" \ + "a=fmtp:112 octet-align=1\r\n" \ + "a=rtpmap:110 GSM-EFR/8000\r\n" \ + "a=ptime:20\r\n" + +#define SDP_3 \ + "v=0\r\n" \ + "o=OsmoMSC 0 0 IN IP4 23.42.23.42\r\n" \ + "s=GSM Call\r\n" \ + "c=IN IP4 23.42.23.42\r\n" \ + "t=0 0\r\n" \ + "m=audio 30436 RTP/AVP 3 111\r\n" \ + "a=rtpmap:3 GSM/8000\r\n" \ + "a=rtpmap:111 GSM-HR-08/8000\r\n" \ + "a=ptime:20\r\n" + + +struct sdp_intersect_test_data sdp_intersect_tests[] = { + { + "identical codecs lead to no change" + , + SDP_1 + , + "c=IN IP4 5.6.7.8\r\n" \ + "m=audio 12345 RTP/AVP 112 3 111 110\r\n" + "a=rtpmap:112 AMR/8000\r\n" + "a=fmtp:112 octet-align=1\r\n" + "a=rtpmap:3 GSM/8000\r\n" + "a=rtpmap:111 GSM-HR-08/8000\r\n" + "a=rtpmap:110 GSM-EFR/8000\r\n" + , + SDP_1 + }, + { + "identical codecs in different order also lead to no change" + , + SDP_1 + , + "c=IN IP4 5.6.7.8\r\n" \ + "m=audio 12345 RTP/AVP 3 110 111 112\r\n" + "a=rtpmap:3 GSM/8000\r\n" + "a=rtpmap:110 GSM-EFR/8000\r\n" + "a=rtpmap:111 GSM-HR-08/8000\r\n" + "a=rtpmap:112 AMR/8000\r\n" + "a=fmtp:112 octet-align=1\r\n" + , + SDP_1 + }, + { + "identical codecs with mismatching payload type numbers also lead to no change" + , + SDP_1 + , + "c=IN IP4 5.6.7.8\r\n" \ + "m=audio 12345 RTP/AVP 96 97 98 99\r\n" + "a=rtpmap:96 GSM/8000\r\n" + "a=rtpmap:97 GSM-EFR/8000\r\n" + "a=rtpmap:98 GSM-HR-08/8000\r\n" + "a=rtpmap:99 AMR/8000\r\n" + "a=fmtp:99 octet-align=1\r\n" + , + SDP_1 + }, + { + "identical codecs plus some extra codecs also lead to no change" + , + SDP_1 + , + "c=IN IP4 5.6.7.8\r\n" \ + "m=audio 12345 RTP/AVP 8 0 96 97 98 99\r\n" + "a=rtpmap:8 PCMA/8000\r\n" + "a=rtpmap:0 PCMU/8000\r\n" + "a=rtpmap:96 GSM/8000\r\n" + "a=rtpmap:97 GSM-EFR/8000\r\n" + "a=rtpmap:98 GSM-HR-08/8000\r\n" + "a=rtpmap:99 AMR/8000\r\n" + "a=fmtp:99 octet-align=1\r\n" + , + SDP_1 + }, + { + "some codecs removed", + SDP_1, + SDP_2, + SDP_2, + }, + { + "other codecs removed", + SDP_1, + SDP_3, + SDP_3, + }, + { + "all codecs removed", + SDP_1 + , + "s=empty" + , + "v=0\r\n" \ + "o=OsmoMSC 0 0 IN IP4 23.42.23.42\r\n" \ + "s=GSM Call\r\n" \ + "c=IN IP4 23.42.23.42\r\n" \ + "t=0 0\r\n" \ + "m=audio 30436 RTP/AVP\r\n" \ + "a=ptime:20\r\n" + }, + { + "some real world test case" + , + "v=0\r\n" + "o=OsmoMSC 0 0 IN IP4 0.0.0.0\r\n" + "s=GSM Call\r\n" + "c=IN IP4 0.0.0.0\r\n" + "t=0 0\r\n" + "m=audio 0 RTP/AVP 112 113 110 3 111\r\n" + "a=rtpmap:112 AMR/8000\r\n" + "a=fmtp:112 octet-align=1;mode-set=0,1,2,3\r\n" + "a=rtpmap:113 AMR-WB/8000\r\n" + "a=fmtp:113 octet-align=1\r\n" + "a=rtpmap:110 GSM-EFR/8000\r\n" + "a=rtpmap:3 GSM/8000\r\n" + "a=rtpmap:111 GSM-HR-08/8000\r\n" + "a=ptime:20\r\n" + , + "v=0\r\n" + "o=OsmoMSC 0 0 IN IP4 0.0.0.0\r\n" + "s=GSM Call\r\n" + "c=IN IP4 0.0.0.0\r\n" + "t=0 0\r\n" + "m=audio 0 RTP/AVP 112 113 110 3 111\r\n" + "a=rtpmap:112 AMR/8000\r\n" + "a=fmtp:112 octet-align=1;mode-set=0,1,2,3\r\n" + "a=rtpmap:113 AMR-WB/8000\r\n" + "a=fmtp:113 octet-align=1\r\n" + "a=rtpmap:110 GSM-EFR/8000\r\n" + "a=rtpmap:3 GSM/8000\r\n" + "a=rtpmap:111 GSM-HR-08/8000\r\n" + "a=ptime:20\r\n" + , + "v=0\r\n" + "o=OsmoMSC 0 0 IN IP4 0.0.0.0\r\n" + "s=GSM Call\r\n" + "c=IN IP4 0.0.0.0\r\n" + "t=0 0\r\n" + "m=audio 0 RTP/AVP 112 113 110 3 111\r\n" + "a=rtpmap:112 AMR/8000\r\n" + "a=fmtp:112 octet-align=1;mode-set=0,1,2,3\r\n" + "a=rtpmap:113 AMR-WB/8000\r\n" + "a=fmtp:113 octet-align=1\r\n" + "a=rtpmap:110 GSM-EFR/8000\r\n" + "a=rtpmap:3 GSM/8000\r\n" + "a=rtpmap:111 GSM-HR-08/8000\r\n" + "a=ptime:20\r\n" + } +}; + +const char *sdp_msg_logstr(const struct sdp_msg *sdp) +{ + static char buf[1024]; + sdp_msg_to_sdp_str_buf(buf, sizeof(buf), sdp); + return buf; +} + +static void test_intersect() +{ + int i; + bool ok = true; + int rc; + + printf("\n\n%s\n", __func__); + + for (i = 0; i < ARRAY_SIZE(sdp_intersect_tests); i++) { + struct sdp_intersect_test_data *t = &sdp_intersect_tests[i]; + struct sdp_msg sdp_a = {}; + struct sdp_msg sdp_b = {}; + char str[1024]; + printf("\n[%d] %s\n", i, t->descr); + dump_sdp(t->sdp_a, "SDP A: "); + dump_sdp(t->sdp_b, " SDP B: "); + + rc = sdp_msg_from_sdp_str(&sdp_a, t->sdp_a); + if (rc) { + printf("ERROR parsing SDP A: %d\n", rc); + break; + } + dump_sdp(sdp_msg_logstr(&sdp_a), "parsed SDP A: "); + rc = sdp_msg_from_sdp_str(&sdp_b, t->sdp_b); + if (rc) { + printf("ERROR parsing SDP A: %d\n", rc); + break; + } + dump_sdp(sdp_msg_logstr(&sdp_b), "parsed SDP B: "); + sdp_audio_codecs_intersection(&sdp_a.audio_codecs, &sdp_b.audio_codecs, false); + sdp_msg_to_sdp_str_buf(str, sizeof(str), &sdp_a); + + dump_sdp(str, "sdp_msg_intersection(a,b): "); + if (strcmp(str, t->expect_intersection)) { + int j; + ok = false; + printf("ERROR:\n"); + dump_sdp(t->expect_intersection, "expect_intersection: "); + for (j = 0; t->expect_intersection[j]; j++) { + if (t->expect_intersection[j] != str[j]) { + printf("ERROR at position %d, at:\n", j); + dump_sdp(str + j, " mismatch: "); + break; + } + } + } else + printf("[%d] ok\n", i); + } + + OSMO_ASSERT(ok); +} + +struct sdp_select_test_data { + const char *sdp; + unsigned int select_payload_type; + const char *expect_sdp; +}; + +struct sdp_select_test_data sdp_select_tests[] = { + { + "v=0\r\n" + "o=OsmoMSC 0 0 IN IP4 23.42.23.42\r\n" + "s=GSM Call\r\n" + "c=IN IP4 23.42.23.42\r\n" + "t=0 0\r\n" + "m=audio 30436 RTP/AVP 112 3 111 110\r\n" + "a=rtpmap:112 AMR/8000\r\n" + "a=fmtp:112 octet-align=1\r\n" + "a=rtpmap:3 GSM/8000\r\n" + "a=rtpmap:111 GSM-HR-08/8000\r\n" + "a=rtpmap:110 GSM-EFR/8000\r\n" + "a=ptime:20\r\n" + , + 112, + NULL + }, + { + "v=0\r\n" + "o=OsmoMSC 0 0 IN IP4 23.42.23.42\r\n" + "s=GSM Call\r\n" + "c=IN IP4 23.42.23.42\r\n" + "t=0 0\r\n" + "m=audio 30436 RTP/AVP 112 3 111 110\r\n" + "a=rtpmap:112 AMR/8000\r\n" + "a=fmtp:112 octet-align=1\r\n" + "a=rtpmap:3 GSM/8000\r\n" + "a=rtpmap:111 GSM-HR-08/8000\r\n" + "a=rtpmap:110 GSM-EFR/8000\r\n" + "a=ptime:20\r\n" + , + 3, + "v=0\r\n" + "o=OsmoMSC 0 0 IN IP4 23.42.23.42\r\n" + "s=GSM Call\r\n" + "c=IN IP4 23.42.23.42\r\n" + "t=0 0\r\n" + "m=audio 30436 RTP/AVP 3 112 111 110\r\n" + "a=rtpmap:3 GSM/8000\r\n" + "a=rtpmap:112 AMR/8000\r\n" + "a=fmtp:112 octet-align=1\r\n" + "a=rtpmap:111 GSM-HR-08/8000\r\n" + "a=rtpmap:110 GSM-EFR/8000\r\n" + "a=ptime:20\r\n" + }, + { + "v=0\r\n" + "o=OsmoMSC 0 0 IN IP4 23.42.23.42\r\n" + "s=GSM Call\r\n" + "c=IN IP4 23.42.23.42\r\n" + "t=0 0\r\n" + "m=audio 30436 RTP/AVP 112 3 111 110\r\n" + "a=rtpmap:112 AMR/8000\r\n" + "a=fmtp:112 octet-align=1\r\n" + "a=rtpmap:3 GSM/8000\r\n" + "a=rtpmap:111 GSM-HR-08/8000\r\n" + "a=rtpmap:110 GSM-EFR/8000\r\n" + "a=ptime:20\r\n" + , + 111, + "v=0\r\n" + "o=OsmoMSC 0 0 IN IP4 23.42.23.42\r\n" + "s=GSM Call\r\n" + "c=IN IP4 23.42.23.42\r\n" + "t=0 0\r\n" + "m=audio 30436 RTP/AVP 111 112 3 110\r\n" + "a=rtpmap:111 GSM-HR-08/8000\r\n" + "a=rtpmap:112 AMR/8000\r\n" + "a=fmtp:112 octet-align=1\r\n" + "a=rtpmap:3 GSM/8000\r\n" + "a=rtpmap:110 GSM-EFR/8000\r\n" + "a=ptime:20\r\n" + }, + { + "v=0\r\n" + "o=OsmoMSC 0 0 IN IP4 23.42.23.42\r\n" + "s=GSM Call\r\n" + "c=IN IP4 23.42.23.42\r\n" + "t=0 0\r\n" + "m=audio 30436 RTP/AVP 112 3 111 110\r\n" + "a=rtpmap:112 AMR/8000\r\n" + "a=fmtp:112 octet-align=1\r\n" + "a=rtpmap:3 GSM/8000\r\n" + "a=rtpmap:111 GSM-HR-08/8000\r\n" + "a=rtpmap:110 GSM-EFR/8000\r\n" + "a=ptime:20\r\n" + , + 110, + "v=0\r\n" + "o=OsmoMSC 0 0 IN IP4 23.42.23.42\r\n" + "s=GSM Call\r\n" + "c=IN IP4 23.42.23.42\r\n" + "t=0 0\r\n" + "m=audio 30436 RTP/AVP 110 112 3 111\r\n" + "a=rtpmap:110 GSM-EFR/8000\r\n" + "a=rtpmap:112 AMR/8000\r\n" + "a=fmtp:112 octet-align=1\r\n" + "a=rtpmap:3 GSM/8000\r\n" + "a=rtpmap:111 GSM-HR-08/8000\r\n" + "a=ptime:20\r\n" + }, + +}; + +static void test_select() +{ + int i; + bool ok = true; + int rc; + + printf("\n\n%s\n", __func__); + + for (i = 0; i < ARRAY_SIZE(sdp_select_tests); i++) { + struct sdp_select_test_data *t = &sdp_select_tests[i]; + struct sdp_msg sdp = {}; + struct sdp_audio_codec *codec; + char buf[1024]; + const char *expect_sdp; + + printf("\n[%d]\n", i); + rc = sdp_msg_from_sdp_str(&sdp, t->sdp); + if (rc) { + printf("ERROR parsing SDP: %d\n", rc); + break; + } + printf("SDP: %s\n", sdp_audio_codecs_to_str(&sdp.audio_codecs)); + codec = sdp_audio_codecs_by_payload_type(&sdp.audio_codecs, t->select_payload_type, false); + OSMO_ASSERT(codec); + printf("Select: %s\n", sdp_audio_codec_to_str(codec)); + + sdp_audio_codecs_select(&sdp.audio_codecs, codec); + + printf("SDP: %s\n", sdp_audio_codecs_to_str(&sdp.audio_codecs)); + sdp_msg_to_sdp_str_buf(buf, sizeof(buf), &sdp); + + expect_sdp = t->expect_sdp ? : t->sdp; + if (strcmp(buf, expect_sdp)) { + int j; + ok = false; + printf("ERROR:\n"); + dump_sdp(buf, "selection result: "); + dump_sdp(expect_sdp, "expect result: "); + for (j = 0; expect_sdp[j]; j++) { + if (expect_sdp[j] != buf[j]) { + printf("ERROR at position %d, at:\n", j); + dump_sdp(buf + j, " mismatch: "); + break; + } + } + } else + printf("[%d] ok\n", i); + } + + OSMO_ASSERT(ok); +} + +int main(void) +{ + test_parse_and_compose(); + test_intersect(); + test_select(); + return 0; +} diff --git a/tests/sdp_msg/sdp_msg_test.err b/tests/sdp_msg/sdp_msg_test.err new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/tests/sdp_msg/sdp_msg_test.err diff --git a/tests/sdp_msg/sdp_msg_test.ok b/tests/sdp_msg/sdp_msg_test.ok new file mode 100644 index 000000000..51a236b51 --- /dev/null +++ b/tests/sdp_msg/sdp_msg_test.ok @@ -0,0 +1,592 @@ + + +test_parse_and_compose + +[0] +sdp input: v=0\r\n +sdp input: o=- 5628250 5628250 IN IP4 192.168.11.121\r\n +sdp input: s=-\r\n +sdp input: c=IN IP4 192.168.11.121\r\n +sdp input: t=0 0\r\n +sdp input: m=audio 10020 RTP/AVP 18 0 2 4 8 96 97 98 100 101\r\n +sdp input: a=rtpmap:18 G729/8000\r\n +sdp input: a=rtpmap:0 PCMU/8000\r\n +sdp input: a=rtpmap:2 G726-32/8000\r\n +sdp input: a=rtpmap:4 G723/8000\r\n +sdp input: a=rtpmap:8 PCMA/8000\r\n +sdp input: a=rtpmap:96 G726-40/8000\r\n +sdp input: a=rtpmap:97 G726-24/8000\r\n +sdp input: a=rtpmap:98 G726-16/8000\r\n +sdp input: a=rtpmap:100 NSE/8000\r\n +sdp input: a=fmtp:100 192-193\r\n +sdp input: a=rtpmap:101 telephone-event/8000\r\n +sdp input: a=fmtp:101 0-15\r\n +sdp input: a=ptime:20\r\n +sdp input: a=sendrecv\r\n +sdp_msg_to_sdp_str_buf: v=0\r\n +sdp_msg_to_sdp_str_buf: o=OsmoMSC 0 0 IN IP4 192.168.11.121\r\n +sdp_msg_to_sdp_str_buf: s=GSM Call\r\n +sdp_msg_to_sdp_str_buf: c=IN IP4 192.168.11.121\r\n +sdp_msg_to_sdp_str_buf: t=0 0\r\n +sdp_msg_to_sdp_str_buf: m=audio 10020 RTP/AVP 18 0 2 4 8 96 97 98 100 101\r\n +sdp_msg_to_sdp_str_buf: a=rtpmap:18 G729/8000\r\n +sdp_msg_to_sdp_str_buf: a=rtpmap:0 PCMU/8000\r\n +sdp_msg_to_sdp_str_buf: a=rtpmap:2 G726-32/8000\r\n +sdp_msg_to_sdp_str_buf: a=rtpmap:4 G723/8000\r\n +sdp_msg_to_sdp_str_buf: a=rtpmap:8 PCMA/8000\r\n +sdp_msg_to_sdp_str_buf: a=rtpmap:96 G726-40/8000\r\n +sdp_msg_to_sdp_str_buf: a=rtpmap:97 G726-24/8000\r\n +sdp_msg_to_sdp_str_buf: a=rtpmap:98 G726-16/8000\r\n +sdp_msg_to_sdp_str_buf: a=rtpmap:100 NSE/8000\r\n +sdp_msg_to_sdp_str_buf: a=fmtp:100 192-193\r\n +sdp_msg_to_sdp_str_buf: a=rtpmap:101 telephone-event/8000\r\n +sdp_msg_to_sdp_str_buf: a=fmtp:101 0-15\r\n +sdp_msg_to_sdp_str_buf: a=ptime:20\r\n +sdp_msg_to_sdp_str_buf: a=sendrecv\r\n +[0] ok + +[1] +sdp input: v=0\r\n +sdp input: o=FooBar 1565090289 1565090290 IN IP4 192.168.11.151\r\n +sdp input: s=FooBar\r\n +sdp input: c=IN IP4 192.168.11.151\r\n +sdp input: t=0 0\r\n +sdp input: m=audio 16398 RTP/AVP 98\r\n +sdp input: a=rtpmap:98 AMR/8000\r\n +sdp input: a=fmtp:98 octet-align=1; mode-set=4\r\n +sdp input: a=ptime:20\r\n +sdp input: a=rtcp:16399 IN IP4 192.168.11.151\r\n +sdp_msg_to_sdp_str_buf: v=0\r\n +sdp_msg_to_sdp_str_buf: o=OsmoMSC 0 0 IN IP4 192.168.11.151\r\n +sdp_msg_to_sdp_str_buf: s=GSM Call\r\n +sdp_msg_to_sdp_str_buf: c=IN IP4 192.168.11.151\r\n +sdp_msg_to_sdp_str_buf: t=0 0\r\n +sdp_msg_to_sdp_str_buf: m=audio 16398 RTP/AVP 98\r\n +sdp_msg_to_sdp_str_buf: a=rtpmap:98 AMR/8000\r\n +sdp_msg_to_sdp_str_buf: a=fmtp:98 octet-align=1; mode-set=4\r\n +sdp_msg_to_sdp_str_buf: a=ptime:20\r\n +[1] ok + +[2] +sdp input: v=0\r\n +sdp input: o=FooBar 1565090289 1565090290 IN IP4 192.168.11.151\r\n +sdp input: s=FooBar\r\n +sdp input: c=IN IP4 192.168.11.140\r\n +sdp input: t=0 0\r\n +sdp input: m=audio 30436 RTP/AVP 18 0 4 8 101\r\n +sdp input: a=rtpmap:18 G729/8000\r\n +sdp input: a=rtpmap:0 PCMU/8000\r\n +sdp input: a=rtpmap:4 G723/8000\r\n +sdp input: a=rtpmap:8 PCMA/8000\r\n +sdp input: a=rtpmap:101 telephone-event/8000\r\n +sdp input: a=fmtp:101 0-15\r\n +sdp input: a=sendrecv\r\n +sdp input: a=rtcp:30437\r\n +sdp input: a=ptime:20\r\n +sdp_msg_to_sdp_str_buf: v=0\r\n +sdp_msg_to_sdp_str_buf: o=OsmoMSC 0 0 IN IP4 192.168.11.140\r\n +sdp_msg_to_sdp_str_buf: s=GSM Call\r\n +sdp_msg_to_sdp_str_buf: c=IN IP4 192.168.11.140\r\n +sdp_msg_to_sdp_str_buf: t=0 0\r\n +sdp_msg_to_sdp_str_buf: m=audio 30436 RTP/AVP 18 0 4 8 101\r\n +sdp_msg_to_sdp_str_buf: a=rtpmap:18 G729/8000\r\n +sdp_msg_to_sdp_str_buf: a=rtpmap:0 PCMU/8000\r\n +sdp_msg_to_sdp_str_buf: a=rtpmap:4 G723/8000\r\n +sdp_msg_to_sdp_str_buf: a=rtpmap:8 PCMA/8000\r\n +sdp_msg_to_sdp_str_buf: a=rtpmap:101 telephone-event/8000\r\n +sdp_msg_to_sdp_str_buf: a=fmtp:101 0-15\r\n +sdp_msg_to_sdp_str_buf: a=ptime:20\r\n +sdp_msg_to_sdp_str_buf: a=sendrecv\r\n +[2] ok + + +test_intersect + +[0] identical codecs lead to no change +SDP A: v=0\r\n +SDP A: o=OsmoMSC 0 0 IN IP4 23.42.23.42\r\n +SDP A: s=GSM Call\r\n +SDP A: c=IN IP4 23.42.23.42\r\n +SDP A: t=0 0\r\n +SDP A: m=audio 30436 RTP/AVP 112 3 111 110\r\n +SDP A: a=rtpmap:112 AMR/8000\r\n +SDP A: a=fmtp:112 octet-align=1\r\n +SDP A: a=rtpmap:3 GSM/8000\r\n +SDP A: a=rtpmap:111 GSM-HR-08/8000\r\n +SDP A: a=rtpmap:110 GSM-EFR/8000\r\n +SDP A: a=ptime:20\r\n + SDP B: c=IN IP4 5.6.7.8\r\n + SDP B: m=audio 12345 RTP/AVP 112 3 111 110\r\n + SDP B: a=rtpmap:112 AMR/8000\r\n + SDP B: a=fmtp:112 octet-align=1\r\n + SDP B: a=rtpmap:3 GSM/8000\r\n + SDP B: a=rtpmap:111 GSM-HR-08/8000\r\n + SDP B: a=rtpmap:110 GSM-EFR/8000\r\n +parsed SDP A: v=0\r\n +parsed SDP A: o=OsmoMSC 0 0 IN IP4 23.42.23.42\r\n +parsed SDP A: s=GSM Call\r\n +parsed SDP A: c=IN IP4 23.42.23.42\r\n +parsed SDP A: t=0 0\r\n +parsed SDP A: m=audio 30436 RTP/AVP 112 3 111 110\r\n +parsed SDP A: a=rtpmap:112 AMR/8000\r\n +parsed SDP A: a=fmtp:112 octet-align=1\r\n +parsed SDP A: a=rtpmap:3 GSM/8000\r\n +parsed SDP A: a=rtpmap:111 GSM-HR-08/8000\r\n +parsed SDP A: a=rtpmap:110 GSM-EFR/8000\r\n +parsed SDP A: a=ptime:20\r\n +parsed SDP B: v=0\r\n +parsed SDP B: o=OsmoMSC 0 0 IN IP4 5.6.7.8\r\n +parsed SDP B: s=GSM Call\r\n +parsed SDP B: c=IN IP4 5.6.7.8\r\n +parsed SDP B: t=0 0\r\n +parsed SDP B: m=audio 12345 RTP/AVP 112 3 111 110\r\n +parsed SDP B: a=rtpmap:112 AMR/8000\r\n +parsed SDP B: a=fmtp:112 octet-align=1\r\n +parsed SDP B: a=rtpmap:3 GSM/8000\r\n +parsed SDP B: a=rtpmap:111 GSM-HR-08/8000\r\n +parsed SDP B: a=rtpmap:110 GSM-EFR/8000\r\n +parsed SDP B: a=ptime:20\r\n +sdp_msg_intersection(a,b): v=0\r\n +sdp_msg_intersection(a,b): o=OsmoMSC 0 0 IN IP4 23.42.23.42\r\n +sdp_msg_intersection(a,b): s=GSM Call\r\n +sdp_msg_intersection(a,b): c=IN IP4 23.42.23.42\r\n +sdp_msg_intersection(a,b): t=0 0\r\n +sdp_msg_intersection(a,b): m=audio 30436 RTP/AVP 112 3 111 110\r\n +sdp_msg_intersection(a,b): a=rtpmap:112 AMR/8000\r\n +sdp_msg_intersection(a,b): a=fmtp:112 octet-align=1\r\n +sdp_msg_intersection(a,b): a=rtpmap:3 GSM/8000\r\n +sdp_msg_intersection(a,b): a=rtpmap:111 GSM-HR-08/8000\r\n +sdp_msg_intersection(a,b): a=rtpmap:110 GSM-EFR/8000\r\n +sdp_msg_intersection(a,b): a=ptime:20\r\n +[0] ok + +[1] identical codecs in different order also lead to no change +SDP A: v=0\r\n +SDP A: o=OsmoMSC 0 0 IN IP4 23.42.23.42\r\n +SDP A: s=GSM Call\r\n +SDP A: c=IN IP4 23.42.23.42\r\n +SDP A: t=0 0\r\n +SDP A: m=audio 30436 RTP/AVP 112 3 111 110\r\n +SDP A: a=rtpmap:112 AMR/8000\r\n +SDP A: a=fmtp:112 octet-align=1\r\n +SDP A: a=rtpmap:3 GSM/8000\r\n +SDP A: a=rtpmap:111 GSM-HR-08/8000\r\n +SDP A: a=rtpmap:110 GSM-EFR/8000\r\n +SDP A: a=ptime:20\r\n + SDP B: c=IN IP4 5.6.7.8\r\n + SDP B: m=audio 12345 RTP/AVP 3 110 111 112\r\n + SDP B: a=rtpmap:3 GSM/8000\r\n + SDP B: a=rtpmap:110 GSM-EFR/8000\r\n + SDP B: a=rtpmap:111 GSM-HR-08/8000\r\n + SDP B: a=rtpmap:112 AMR/8000\r\n + SDP B: a=fmtp:112 octet-align=1\r\n +parsed SDP A: v=0\r\n +parsed SDP A: o=OsmoMSC 0 0 IN IP4 23.42.23.42\r\n +parsed SDP A: s=GSM Call\r\n +parsed SDP A: c=IN IP4 23.42.23.42\r\n +parsed SDP A: t=0 0\r\n +parsed SDP A: m=audio 30436 RTP/AVP 112 3 111 110\r\n +parsed SDP A: a=rtpmap:112 AMR/8000\r\n +parsed SDP A: a=fmtp:112 octet-align=1\r\n +parsed SDP A: a=rtpmap:3 GSM/8000\r\n +parsed SDP A: a=rtpmap:111 GSM-HR-08/8000\r\n +parsed SDP A: a=rtpmap:110 GSM-EFR/8000\r\n +parsed SDP A: a=ptime:20\r\n +parsed SDP B: v=0\r\n +parsed SDP B: o=OsmoMSC 0 0 IN IP4 5.6.7.8\r\n +parsed SDP B: s=GSM Call\r\n +parsed SDP B: c=IN IP4 5.6.7.8\r\n +parsed SDP B: t=0 0\r\n +parsed SDP B: m=audio 12345 RTP/AVP 3 110 111 112\r\n +parsed SDP B: a=rtpmap:3 GSM/8000\r\n +parsed SDP B: a=rtpmap:110 GSM-EFR/8000\r\n +parsed SDP B: a=rtpmap:111 GSM-HR-08/8000\r\n +parsed SDP B: a=rtpmap:112 AMR/8000\r\n +parsed SDP B: a=fmtp:112 octet-align=1\r\n +parsed SDP B: a=ptime:20\r\n +sdp_msg_intersection(a,b): v=0\r\n +sdp_msg_intersection(a,b): o=OsmoMSC 0 0 IN IP4 23.42.23.42\r\n +sdp_msg_intersection(a,b): s=GSM Call\r\n +sdp_msg_intersection(a,b): c=IN IP4 23.42.23.42\r\n +sdp_msg_intersection(a,b): t=0 0\r\n +sdp_msg_intersection(a,b): m=audio 30436 RTP/AVP 112 3 111 110\r\n +sdp_msg_intersection(a,b): a=rtpmap:112 AMR/8000\r\n +sdp_msg_intersection(a,b): a=fmtp:112 octet-align=1\r\n +sdp_msg_intersection(a,b): a=rtpmap:3 GSM/8000\r\n +sdp_msg_intersection(a,b): a=rtpmap:111 GSM-HR-08/8000\r\n +sdp_msg_intersection(a,b): a=rtpmap:110 GSM-EFR/8000\r\n +sdp_msg_intersection(a,b): a=ptime:20\r\n +[1] ok + +[2] identical codecs with mismatching payload type numbers also lead to no change +SDP A: v=0\r\n +SDP A: o=OsmoMSC 0 0 IN IP4 23.42.23.42\r\n +SDP A: s=GSM Call\r\n +SDP A: c=IN IP4 23.42.23.42\r\n +SDP A: t=0 0\r\n +SDP A: m=audio 30436 RTP/AVP 112 3 111 110\r\n +SDP A: a=rtpmap:112 AMR/8000\r\n +SDP A: a=fmtp:112 octet-align=1\r\n +SDP A: a=rtpmap:3 GSM/8000\r\n +SDP A: a=rtpmap:111 GSM-HR-08/8000\r\n +SDP A: a=rtpmap:110 GSM-EFR/8000\r\n +SDP A: a=ptime:20\r\n + SDP B: c=IN IP4 5.6.7.8\r\n + SDP B: m=audio 12345 RTP/AVP 96 97 98 99\r\n + SDP B: a=rtpmap:96 GSM/8000\r\n + SDP B: a=rtpmap:97 GSM-EFR/8000\r\n + SDP B: a=rtpmap:98 GSM-HR-08/8000\r\n + SDP B: a=rtpmap:99 AMR/8000\r\n + SDP B: a=fmtp:99 octet-align=1\r\n +parsed SDP A: v=0\r\n +parsed SDP A: o=OsmoMSC 0 0 IN IP4 23.42.23.42\r\n +parsed SDP A: s=GSM Call\r\n +parsed SDP A: c=IN IP4 23.42.23.42\r\n +parsed SDP A: t=0 0\r\n +parsed SDP A: m=audio 30436 RTP/AVP 112 3 111 110\r\n +parsed SDP A: a=rtpmap:112 AMR/8000\r\n +parsed SDP A: a=fmtp:112 octet-align=1\r\n +parsed SDP A: a=rtpmap:3 GSM/8000\r\n +parsed SDP A: a=rtpmap:111 GSM-HR-08/8000\r\n +parsed SDP A: a=rtpmap:110 GSM-EFR/8000\r\n +parsed SDP A: a=ptime:20\r\n +parsed SDP B: v=0\r\n +parsed SDP B: o=OsmoMSC 0 0 IN IP4 5.6.7.8\r\n +parsed SDP B: s=GSM Call\r\n +parsed SDP B: c=IN IP4 5.6.7.8\r\n +parsed SDP B: t=0 0\r\n +parsed SDP B: m=audio 12345 RTP/AVP 96 97 98 99\r\n +parsed SDP B: a=rtpmap:96 GSM/8000\r\n +parsed SDP B: a=rtpmap:97 GSM-EFR/8000\r\n +parsed SDP B: a=rtpmap:98 GSM-HR-08/8000\r\n +parsed SDP B: a=rtpmap:99 AMR/8000\r\n +parsed SDP B: a=fmtp:99 octet-align=1\r\n +parsed SDP B: a=ptime:20\r\n +sdp_msg_intersection(a,b): v=0\r\n +sdp_msg_intersection(a,b): o=OsmoMSC 0 0 IN IP4 23.42.23.42\r\n +sdp_msg_intersection(a,b): s=GSM Call\r\n +sdp_msg_intersection(a,b): c=IN IP4 23.42.23.42\r\n +sdp_msg_intersection(a,b): t=0 0\r\n +sdp_msg_intersection(a,b): m=audio 30436 RTP/AVP 112 3 111 110\r\n +sdp_msg_intersection(a,b): a=rtpmap:112 AMR/8000\r\n +sdp_msg_intersection(a,b): a=fmtp:112 octet-align=1\r\n +sdp_msg_intersection(a,b): a=rtpmap:3 GSM/8000\r\n +sdp_msg_intersection(a,b): a=rtpmap:111 GSM-HR-08/8000\r\n +sdp_msg_intersection(a,b): a=rtpmap:110 GSM-EFR/8000\r\n +sdp_msg_intersection(a,b): a=ptime:20\r\n +[2] ok + +[3] identical codecs plus some extra codecs also lead to no change +SDP A: v=0\r\n +SDP A: o=OsmoMSC 0 0 IN IP4 23.42.23.42\r\n +SDP A: s=GSM Call\r\n +SDP A: c=IN IP4 23.42.23.42\r\n +SDP A: t=0 0\r\n +SDP A: m=audio 30436 RTP/AVP 112 3 111 110\r\n +SDP A: a=rtpmap:112 AMR/8000\r\n +SDP A: a=fmtp:112 octet-align=1\r\n +SDP A: a=rtpmap:3 GSM/8000\r\n +SDP A: a=rtpmap:111 GSM-HR-08/8000\r\n +SDP A: a=rtpmap:110 GSM-EFR/8000\r\n +SDP A: a=ptime:20\r\n + SDP B: c=IN IP4 5.6.7.8\r\n + SDP B: m=audio 12345 RTP/AVP 8 0 96 97 98 99\r\n + SDP B: a=rtpmap:8 PCMA/8000\r\n + SDP B: a=rtpmap:0 PCMU/8000\r\n + SDP B: a=rtpmap:96 GSM/8000\r\n + SDP B: a=rtpmap:97 GSM-EFR/8000\r\n + SDP B: a=rtpmap:98 GSM-HR-08/8000\r\n + SDP B: a=rtpmap:99 AMR/8000\r\n + SDP B: a=fmtp:99 octet-align=1\r\n +parsed SDP A: v=0\r\n +parsed SDP A: o=OsmoMSC 0 0 IN IP4 23.42.23.42\r\n +parsed SDP A: s=GSM Call\r\n +parsed SDP A: c=IN IP4 23.42.23.42\r\n +parsed SDP A: t=0 0\r\n +parsed SDP A: m=audio 30436 RTP/AVP 112 3 111 110\r\n +parsed SDP A: a=rtpmap:112 AMR/8000\r\n +parsed SDP A: a=fmtp:112 octet-align=1\r\n +parsed SDP A: a=rtpmap:3 GSM/8000\r\n +parsed SDP A: a=rtpmap:111 GSM-HR-08/8000\r\n +parsed SDP A: a=rtpmap:110 GSM-EFR/8000\r\n +parsed SDP A: a=ptime:20\r\n +parsed SDP B: v=0\r\n +parsed SDP B: o=OsmoMSC 0 0 IN IP4 5.6.7.8\r\n +parsed SDP B: s=GSM Call\r\n +parsed SDP B: c=IN IP4 5.6.7.8\r\n +parsed SDP B: t=0 0\r\n +parsed SDP B: m=audio 12345 RTP/AVP 8 0 96 97 98 99\r\n +parsed SDP B: a=rtpmap:8 PCMA/8000\r\n +parsed SDP B: a=rtpmap:0 PCMU/8000\r\n +parsed SDP B: a=rtpmap:96 GSM/8000\r\n +parsed SDP B: a=rtpmap:97 GSM-EFR/8000\r\n +parsed SDP B: a=rtpmap:98 GSM-HR-08/8000\r\n +parsed SDP B: a=rtpmap:99 AMR/8000\r\n +parsed SDP B: a=fmtp:99 octet-align=1\r\n +parsed SDP B: a=ptime:20\r\n +sdp_msg_intersection(a,b): v=0\r\n +sdp_msg_intersection(a,b): o=OsmoMSC 0 0 IN IP4 23.42.23.42\r\n +sdp_msg_intersection(a,b): s=GSM Call\r\n +sdp_msg_intersection(a,b): c=IN IP4 23.42.23.42\r\n +sdp_msg_intersection(a,b): t=0 0\r\n +sdp_msg_intersection(a,b): m=audio 30436 RTP/AVP 112 3 111 110\r\n +sdp_msg_intersection(a,b): a=rtpmap:112 AMR/8000\r\n +sdp_msg_intersection(a,b): a=fmtp:112 octet-align=1\r\n +sdp_msg_intersection(a,b): a=rtpmap:3 GSM/8000\r\n +sdp_msg_intersection(a,b): a=rtpmap:111 GSM-HR-08/8000\r\n +sdp_msg_intersection(a,b): a=rtpmap:110 GSM-EFR/8000\r\n +sdp_msg_intersection(a,b): a=ptime:20\r\n +[3] ok + +[4] some codecs removed +SDP A: v=0\r\n +SDP A: o=OsmoMSC 0 0 IN IP4 23.42.23.42\r\n +SDP A: s=GSM Call\r\n +SDP A: c=IN IP4 23.42.23.42\r\n +SDP A: t=0 0\r\n +SDP A: m=audio 30436 RTP/AVP 112 3 111 110\r\n +SDP A: a=rtpmap:112 AMR/8000\r\n +SDP A: a=fmtp:112 octet-align=1\r\n +SDP A: a=rtpmap:3 GSM/8000\r\n +SDP A: a=rtpmap:111 GSM-HR-08/8000\r\n +SDP A: a=rtpmap:110 GSM-EFR/8000\r\n +SDP A: a=ptime:20\r\n + SDP B: v=0\r\n + SDP B: o=OsmoMSC 0 0 IN IP4 23.42.23.42\r\n + SDP B: s=GSM Call\r\n + SDP B: c=IN IP4 23.42.23.42\r\n + SDP B: t=0 0\r\n + SDP B: m=audio 30436 RTP/AVP 112 110\r\n + SDP B: a=rtpmap:112 AMR/8000\r\n + SDP B: a=fmtp:112 octet-align=1\r\n + SDP B: a=rtpmap:110 GSM-EFR/8000\r\n + SDP B: a=ptime:20\r\n +parsed SDP A: v=0\r\n +parsed SDP A: o=OsmoMSC 0 0 IN IP4 23.42.23.42\r\n +parsed SDP A: s=GSM Call\r\n +parsed SDP A: c=IN IP4 23.42.23.42\r\n +parsed SDP A: t=0 0\r\n +parsed SDP A: m=audio 30436 RTP/AVP 112 3 111 110\r\n +parsed SDP A: a=rtpmap:112 AMR/8000\r\n +parsed SDP A: a=fmtp:112 octet-align=1\r\n +parsed SDP A: a=rtpmap:3 GSM/8000\r\n +parsed SDP A: a=rtpmap:111 GSM-HR-08/8000\r\n +parsed SDP A: a=rtpmap:110 GSM-EFR/8000\r\n +parsed SDP A: a=ptime:20\r\n +parsed SDP B: v=0\r\n +parsed SDP B: o=OsmoMSC 0 0 IN IP4 23.42.23.42\r\n +parsed SDP B: s=GSM Call\r\n +parsed SDP B: c=IN IP4 23.42.23.42\r\n +parsed SDP B: t=0 0\r\n +parsed SDP B: m=audio 30436 RTP/AVP 112 110\r\n +parsed SDP B: a=rtpmap:112 AMR/8000\r\n +parsed SDP B: a=fmtp:112 octet-align=1\r\n +parsed SDP B: a=rtpmap:110 GSM-EFR/8000\r\n +parsed SDP B: a=ptime:20\r\n +sdp_msg_intersection(a,b): v=0\r\n +sdp_msg_intersection(a,b): o=OsmoMSC 0 0 IN IP4 23.42.23.42\r\n +sdp_msg_intersection(a,b): s=GSM Call\r\n +sdp_msg_intersection(a,b): c=IN IP4 23.42.23.42\r\n +sdp_msg_intersection(a,b): t=0 0\r\n +sdp_msg_intersection(a,b): m=audio 30436 RTP/AVP 112 110\r\n +sdp_msg_intersection(a,b): a=rtpmap:112 AMR/8000\r\n +sdp_msg_intersection(a,b): a=fmtp:112 octet-align=1\r\n +sdp_msg_intersection(a,b): a=rtpmap:110 GSM-EFR/8000\r\n +sdp_msg_intersection(a,b): a=ptime:20\r\n +[4] ok + +[5] other codecs removed +SDP A: v=0\r\n +SDP A: o=OsmoMSC 0 0 IN IP4 23.42.23.42\r\n +SDP A: s=GSM Call\r\n +SDP A: c=IN IP4 23.42.23.42\r\n +SDP A: t=0 0\r\n +SDP A: m=audio 30436 RTP/AVP 112 3 111 110\r\n +SDP A: a=rtpmap:112 AMR/8000\r\n +SDP A: a=fmtp:112 octet-align=1\r\n +SDP A: a=rtpmap:3 GSM/8000\r\n +SDP A: a=rtpmap:111 GSM-HR-08/8000\r\n +SDP A: a=rtpmap:110 GSM-EFR/8000\r\n +SDP A: a=ptime:20\r\n + SDP B: v=0\r\n + SDP B: o=OsmoMSC 0 0 IN IP4 23.42.23.42\r\n + SDP B: s=GSM Call\r\n + SDP B: c=IN IP4 23.42.23.42\r\n + SDP B: t=0 0\r\n + SDP B: m=audio 30436 RTP/AVP 3 111\r\n + SDP B: a=rtpmap:3 GSM/8000\r\n + SDP B: a=rtpmap:111 GSM-HR-08/8000\r\n + SDP B: a=ptime:20\r\n +parsed SDP A: v=0\r\n +parsed SDP A: o=OsmoMSC 0 0 IN IP4 23.42.23.42\r\n +parsed SDP A: s=GSM Call\r\n +parsed SDP A: c=IN IP4 23.42.23.42\r\n +parsed SDP A: t=0 0\r\n +parsed SDP A: m=audio 30436 RTP/AVP 112 3 111 110\r\n +parsed SDP A: a=rtpmap:112 AMR/8000\r\n +parsed SDP A: a=fmtp:112 octet-align=1\r\n +parsed SDP A: a=rtpmap:3 GSM/8000\r\n +parsed SDP A: a=rtpmap:111 GSM-HR-08/8000\r\n +parsed SDP A: a=rtpmap:110 GSM-EFR/8000\r\n +parsed SDP A: a=ptime:20\r\n +parsed SDP B: v=0\r\n +parsed SDP B: o=OsmoMSC 0 0 IN IP4 23.42.23.42\r\n +parsed SDP B: s=GSM Call\r\n +parsed SDP B: c=IN IP4 23.42.23.42\r\n +parsed SDP B: t=0 0\r\n +parsed SDP B: m=audio 30436 RTP/AVP 3 111\r\n +parsed SDP B: a=rtpmap:3 GSM/8000\r\n +parsed SDP B: a=rtpmap:111 GSM-HR-08/8000\r\n +parsed SDP B: a=ptime:20\r\n +sdp_msg_intersection(a,b): v=0\r\n +sdp_msg_intersection(a,b): o=OsmoMSC 0 0 IN IP4 23.42.23.42\r\n +sdp_msg_intersection(a,b): s=GSM Call\r\n +sdp_msg_intersection(a,b): c=IN IP4 23.42.23.42\r\n +sdp_msg_intersection(a,b): t=0 0\r\n +sdp_msg_intersection(a,b): m=audio 30436 RTP/AVP 3 111\r\n +sdp_msg_intersection(a,b): a=rtpmap:3 GSM/8000\r\n +sdp_msg_intersection(a,b): a=rtpmap:111 GSM-HR-08/8000\r\n +sdp_msg_intersection(a,b): a=ptime:20\r\n +[5] ok + +[6] all codecs removed +SDP A: v=0\r\n +SDP A: o=OsmoMSC 0 0 IN IP4 23.42.23.42\r\n +SDP A: s=GSM Call\r\n +SDP A: c=IN IP4 23.42.23.42\r\n +SDP A: t=0 0\r\n +SDP A: m=audio 30436 RTP/AVP 112 3 111 110\r\n +SDP A: a=rtpmap:112 AMR/8000\r\n +SDP A: a=fmtp:112 octet-align=1\r\n +SDP A: a=rtpmap:3 GSM/8000\r\n +SDP A: a=rtpmap:111 GSM-HR-08/8000\r\n +SDP A: a=rtpmap:110 GSM-EFR/8000\r\n +SDP A: a=ptime:20\r\n + SDP B: s=empty +parsed SDP A: v=0\r\n +parsed SDP A: o=OsmoMSC 0 0 IN IP4 23.42.23.42\r\n +parsed SDP A: s=GSM Call\r\n +parsed SDP A: c=IN IP4 23.42.23.42\r\n +parsed SDP A: t=0 0\r\n +parsed SDP A: m=audio 30436 RTP/AVP 112 3 111 110\r\n +parsed SDP A: a=rtpmap:112 AMR/8000\r\n +parsed SDP A: a=fmtp:112 octet-align=1\r\n +parsed SDP A: a=rtpmap:3 GSM/8000\r\n +parsed SDP A: a=rtpmap:111 GSM-HR-08/8000\r\n +parsed SDP A: a=rtpmap:110 GSM-EFR/8000\r\n +parsed SDP A: a=ptime:20\r\n +parsed SDP B: v=0\r\n +parsed SDP B: o=OsmoMSC 0 0 IN IP4 0.0.0.0\r\n +parsed SDP B: s=GSM Call\r\n +parsed SDP B: c=IN IP4 0.0.0.0\r\n +parsed SDP B: t=0 0\r\n +parsed SDP B: m=audio 0 RTP/AVP\r\n +parsed SDP B: a=ptime:20\r\n +sdp_msg_intersection(a,b): v=0\r\n +sdp_msg_intersection(a,b): o=OsmoMSC 0 0 IN IP4 23.42.23.42\r\n +sdp_msg_intersection(a,b): s=GSM Call\r\n +sdp_msg_intersection(a,b): c=IN IP4 23.42.23.42\r\n +sdp_msg_intersection(a,b): t=0 0\r\n +sdp_msg_intersection(a,b): m=audio 30436 RTP/AVP\r\n +sdp_msg_intersection(a,b): a=ptime:20\r\n +[6] ok + +[7] some real world test case +SDP A: v=0\r\n +SDP A: o=OsmoMSC 0 0 IN IP4 0.0.0.0\r\n +SDP A: s=GSM Call\r\n +SDP A: c=IN IP4 0.0.0.0\r\n +SDP A: t=0 0\r\n +SDP A: m=audio 0 RTP/AVP 112 113 110 3 111\r\n +SDP A: a=rtpmap:112 AMR/8000\r\n +SDP A: a=fmtp:112 octet-align=1;mode-set=0,1,2,3\r\n +SDP A: a=rtpmap:113 AMR-WB/8000\r\n +SDP A: a=fmtp:113 octet-align=1\r\n +SDP A: a=rtpmap:110 GSM-EFR/8000\r\n +SDP A: a=rtpmap:3 GSM/8000\r\n +SDP A: a=rtpmap:111 GSM-HR-08/8000\r\n +SDP A: a=ptime:20\r\n + SDP B: v=0\r\n + SDP B: o=OsmoMSC 0 0 IN IP4 0.0.0.0\r\n + SDP B: s=GSM Call\r\n + SDP B: c=IN IP4 0.0.0.0\r\n + SDP B: t=0 0\r\n + SDP B: m=audio 0 RTP/AVP 112 113 110 3 111\r\n + SDP B: a=rtpmap:112 AMR/8000\r\n + SDP B: a=fmtp:112 octet-align=1;mode-set=0,1,2,3\r\n + SDP B: a=rtpmap:113 AMR-WB/8000\r\n + SDP B: a=fmtp:113 octet-align=1\r\n + SDP B: a=rtpmap:110 GSM-EFR/8000\r\n + SDP B: a=rtpmap:3 GSM/8000\r\n + SDP B: a=rtpmap:111 GSM-HR-08/8000\r\n + SDP B: a=ptime:20\r\n +parsed SDP A: v=0\r\n +parsed SDP A: o=OsmoMSC 0 0 IN IP4 0.0.0.0\r\n +parsed SDP A: s=GSM Call\r\n +parsed SDP A: c=IN IP4 0.0.0.0\r\n +parsed SDP A: t=0 0\r\n +parsed SDP A: m=audio 0 RTP/AVP 112 113 110 3 111\r\n +parsed SDP A: a=rtpmap:112 AMR/8000\r\n +parsed SDP A: a=fmtp:112 octet-align=1;mode-set=0,1,2,3\r\n +parsed SDP A: a=rtpmap:113 AMR-WB/8000\r\n +parsed SDP A: a=fmtp:113 octet-align=1\r\n +parsed SDP A: a=rtpmap:110 GSM-EFR/8000\r\n +parsed SDP A: a=rtpmap:3 GSM/8000\r\n +parsed SDP A: a=rtpmap:111 GSM-HR-08/8000\r\n +parsed SDP A: a=ptime:20\r\n +parsed SDP B: v=0\r\n +parsed SDP B: o=OsmoMSC 0 0 IN IP4 0.0.0.0\r\n +parsed SDP B: s=GSM Call\r\n +parsed SDP B: c=IN IP4 0.0.0.0\r\n +parsed SDP B: t=0 0\r\n +parsed SDP B: m=audio 0 RTP/AVP 112 113 110 3 111\r\n +parsed SDP B: a=rtpmap:112 AMR/8000\r\n +parsed SDP B: a=fmtp:112 octet-align=1;mode-set=0,1,2,3\r\n +parsed SDP B: a=rtpmap:113 AMR-WB/8000\r\n +parsed SDP B: a=fmtp:113 octet-align=1\r\n +parsed SDP B: a=rtpmap:110 GSM-EFR/8000\r\n +parsed SDP B: a=rtpmap:3 GSM/8000\r\n +parsed SDP B: a=rtpmap:111 GSM-HR-08/8000\r\n +parsed SDP B: a=ptime:20\r\n +sdp_msg_intersection(a,b): v=0\r\n +sdp_msg_intersection(a,b): o=OsmoMSC 0 0 IN IP4 0.0.0.0\r\n +sdp_msg_intersection(a,b): s=GSM Call\r\n +sdp_msg_intersection(a,b): c=IN IP4 0.0.0.0\r\n +sdp_msg_intersection(a,b): t=0 0\r\n +sdp_msg_intersection(a,b): m=audio 0 RTP/AVP 112 113 110 3 111\r\n +sdp_msg_intersection(a,b): a=rtpmap:112 AMR/8000\r\n +sdp_msg_intersection(a,b): a=fmtp:112 octet-align=1;mode-set=0,1,2,3\r\n +sdp_msg_intersection(a,b): a=rtpmap:113 AMR-WB/8000\r\n +sdp_msg_intersection(a,b): a=fmtp:113 octet-align=1\r\n +sdp_msg_intersection(a,b): a=rtpmap:110 GSM-EFR/8000\r\n +sdp_msg_intersection(a,b): a=rtpmap:3 GSM/8000\r\n +sdp_msg_intersection(a,b): a=rtpmap:111 GSM-HR-08/8000\r\n +sdp_msg_intersection(a,b): a=ptime:20\r\n +[7] ok + + +test_select + +[0] +SDP: AMR:octet-align=1#112,GSM#3,GSM-HR-08#111,GSM-EFR#110 +Select: AMR:octet-align=1#112 +SDP: AMR:octet-align=1#112,GSM#3,GSM-HR-08#111,GSM-EFR#110 +[0] ok + +[1] +SDP: AMR:octet-align=1#112,GSM#3,GSM-HR-08#111,GSM-EFR#110 +Select: GSM#3 +SDP: GSM#3,AMR:octet-align=1#112,GSM-HR-08#111,GSM-EFR#110 +[1] ok + +[2] +SDP: AMR:octet-align=1#112,GSM#3,GSM-HR-08#111,GSM-EFR#110 +Select: GSM-HR-08#111 +SDP: GSM-HR-08#111,AMR:octet-align=1#112,GSM#3,GSM-EFR#110 +[2] ok + +[3] +SDP: AMR:octet-align=1#112,GSM#3,GSM-HR-08#111,GSM-EFR#110 +Select: GSM-EFR#110 +SDP: GSM-EFR#110,AMR:octet-align=1#112,GSM#3,GSM-HR-08#111 +[3] ok diff --git a/tests/smpp/Makefile.am b/tests/smpp/Makefile.am index 8d631198c..ff19d3d7c 100644 --- a/tests/smpp/Makefile.am +++ b/tests/smpp/Makefile.am @@ -11,12 +11,15 @@ AM_CFLAGS = \ $(LIBOSMOGSM_CFLAGS) \ $(LIBOSMOSCCP_CFLAGS) \ $(LIBOSMOABIS_CFLAGS) \ + $(LIBOSMOSCCP_CFLAGS) \ + $(LIBOSMOMGCPCLIENT_CFLAGS) \ $(COVERAGE_CFLAGS) \ $(LIBSMPP34_CFLAGS) \ $(NULL) AM_LDFLAGS = \ $(COVERAGE_LDFLAGS) \ + -no-install \ $(NULL) EXTRA_DIST = \ @@ -24,16 +27,16 @@ EXTRA_DIST = \ smpp_test.err \ $(NULL) -noinst_PROGRAMS = \ +check_PROGRAMS = \ smpp_test \ $(NULL) smpp_test_SOURCES = \ smpp_test.c \ - $(top_builddir)/src/libmsc/smpp_utils.c \ $(NULL) smpp_test_LDADD = \ + $(top_builddir)/src/libsmpputil/libsmpputil.a \ $(LIBOSMOCORE_LIBS) \ $(LIBOSMOGSM_LIBS) \ $(NULL) diff --git a/tests/smpp/smpp_test.c b/tests/smpp/smpp_test.c index 1abb63b01..9b94c63f4 100644 --- a/tests/smpp/smpp_test.c +++ b/tests/smpp/smpp_test.c @@ -1,5 +1,6 @@ /* * (C) 2013 by Holger Hans Peter Freyther + * (C) 2022 by Harald Welte <laforge@osmocom.org> * All Rights Reserved * * This program is free software; you can redistribute it and/or modify @@ -21,12 +22,10 @@ #include <stdio.h> #include <osmocom/msc/debug.h> - +#include <osmocom/smpp/smpp_smsc.h> #include <osmocom/core/application.h> #include <osmocom/core/backtrace.h> -#include "smpp_smsc.h" - struct coding_test { uint8_t dcs; uint8_t coding; @@ -62,6 +61,41 @@ static void test_coding_scheme(void) } } +static const char *smpp_time_tests[] = { + "\0", + "220517175524000+", + "220517175524000-", + "220517175524004+", /* 1 hour advanced compared to GMT */ + "220517175524004-", /* 1 hour retarded compared to GMT */ + "000000010000000R", /* 1 hour */ + "000001000000000R", /* 1 day */ +}; + +static void test_smpp_parse_time_format(void) +{ + time_t t_now = 1652745600; /* 2022-05-17 00:00:00 UTC */ + char *orig_tz; + + printf("Testing SMPP time format parser\n"); + + /* relative time format conversion depends on the local time */ + orig_tz = getenv("TZ"); + setenv("TZ", "UTC", 1); + + for (unsigned int i = 0; i < ARRAY_SIZE(smpp_time_tests); i++) { + time_t t = smpp_parse_time_format(smpp_time_tests[i], &t_now); + char buf[32]; + strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", gmtime(&t)); + printf("'%s': %ld == %s\n", smpp_time_tests[i], t, buf); + } + + if (orig_tz) + setenv("TZ", orig_tz, 1); + else + unsetenv("TZ"); + +} + static const struct log_info_cat smpp_mirror_default_categories[] = { [DSMPP] = { .name = "DSMPP", @@ -80,8 +114,12 @@ int main(int argc, char **argv) void *ctx = talloc_named_const(NULL, 0, "smpp_test"); osmo_init_logging2(ctx, &log_info); log_set_use_color(osmo_stderr_target, 0); - log_set_print_filename(osmo_stderr_target, 0); + log_set_print_filename2(osmo_stderr_target, LOG_FILENAME_NONE); + log_set_print_category(osmo_stderr_target, 0); + log_set_print_category_hex(osmo_stderr_target, 0); test_coding_scheme(); + test_smpp_parse_time_format(); + return EXIT_SUCCESS; } diff --git a/tests/smpp/smpp_test.ok b/tests/smpp/smpp_test.ok index fd44804d1..feb75a6ed 100644 --- a/tests/smpp/smpp_test.ok +++ b/tests/smpp/smpp_test.ok @@ -1 +1,9 @@ Testing coding scheme support +Testing SMPP time format parser +'': 0 == 1970-01-01 00:00:00 +'220517175524000+': 1652810124 == 2022-05-17 17:55:24 +'220517175524000-': 1652810124 == 2022-05-17 17:55:24 +'220517175524004+': 1652806524 == 2022-05-17 16:55:24 +'220517175524004-': 1652813724 == 2022-05-17 18:55:24 +'000000010000000R': 1652749200 == 2022-05-17 01:00:00 +'000001000000000R': 1652832000 == 2022-05-18 00:00:00 diff --git a/tests/smpp_test_runner.py b/tests/smpp_test_runner.py index f6567d9b4..b8c6e1c9b 100755 --- a/tests/smpp_test_runner.py +++ b/tests/smpp_test_runner.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python3 # (C) 2014 by Holger Hans Peter Freyther # based on vty_test_runner.py: @@ -46,8 +46,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] @@ -73,14 +73,14 @@ class TestSMPPMSC(TestVTYBase): # Enable the configuration 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('smpp', [''])) - self.assertEquals(self.vty.node(), 'config-smpp') + self.assertEqual(self.vty.node(), 'config-smpp') self.assertTrue(self.vty.verify('system-id test', [''])) self.assertTrue(self.vty.verify('local-tcp-port 2775', [''])) self.assertTrue(self.vty.verify('esme test', [''])) - self.assertEquals(self.vty.node(), 'config-smpp-esme') + self.assertEqual(self.vty.node(), 'config-smpp-esme') self.assertTrue(self.vty.verify('default-route', [''])) self.assertTrue(self.vty.verify('end', [''])) @@ -88,7 +88,7 @@ class TestSMPPMSC(TestVTYBase): sck = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sck.setblocking(1) sck.connect(('0.0.0.0', 2775)) - sck.sendall('\x00\x00\x00\x02\x00') + sck.sendall(b'\x00\x00\x00\x02\x00') sck.close() # Check if the VTY is still there @@ -98,7 +98,7 @@ class TestSMPPMSC(TestVTYBase): sck = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sck.setblocking(1) sck.connect(('0.0.0.0', 2775)) - sck.sendall('\x00\x01\x00\x01\x01') + sck.sendall(b'\x00\x01\x00\x01\x01') sck.close() self.vty.verify('enable',['']) @@ -128,9 +128,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 SMPP" + print("Running tests for specific SMPP") suite = unittest.TestSuite() suite.addTest(unittest.TestLoader().loadTestsFromTestCase(TestSMPPMSC)) res = unittest.TextTestRunner(verbosity=verbose_level).run(suite) diff --git a/tests/sms_queue/Makefile.am b/tests/sms_queue/Makefile.am index 80189c793..055a22902 100644 --- a/tests/sms_queue/Makefile.am +++ b/tests/sms_queue/Makefile.am @@ -12,9 +12,16 @@ AM_CFLAGS = \ $(LIBOSMOABIS_CFLAGS) \ $(LIBOSMOSIGTRAN_CFLAGS) \ $(LIBOSMORANAP_CFLAGS) \ + $(LIBOSMONETIF_CFLAGS) \ $(LIBASN1C_CFLAGS) \ $(LIBOSMOMGCPCLIENT_CFLAGS) \ $(LIBOSMOGSUPCLIENT_CFLAGS) \ + $(LIBSQLITE3_CFLAGS) \ + $(NULL) + +AM_LDFLAGS = \ + $(COVERAGE_LDFLAGS) \ + -no-install \ $(NULL) EXTRA_DIST = \ @@ -22,18 +29,18 @@ EXTRA_DIST = \ sms_queue_test.err \ $(NULL) -noinst_PROGRAMS = \ +check_PROGRAMS = \ sms_queue_test \ $(NULL) sms_queue_test_SOURCES = \ sms_queue_test.c \ + $(srcdir)/../stubs.c \ $(NULL) sms_queue_test_LDADD = \ $(top_builddir)/src/libmsc/libmsc.a \ $(top_builddir)/src/libvlr/libvlr.a \ - $(LIBSMPP34_LIBS) \ $(LIBOSMOCORE_LIBS) \ $(LIBOSMOGSM_LIBS) \ $(LIBOSMOVTY_LIBS) \ @@ -43,10 +50,11 @@ sms_queue_test_LDADD = \ $(LIBASN1C_LIBS) \ $(LIBOSMOMGCPCLIENT_LIBS) \ $(LIBOSMOGSUPCLIENT_LIBS) \ + $(LIBSQLITE3_LIBS) \ $(LIBRARY_GSM) \ - -ldbi \ $(NULL) sms_queue_test_LDFLAGS = \ -Wl,--wrap=db_sms_get_next_unsent_rr_msisdn \ + $(AM_LDFLAGS) \ $(NULL) diff --git a/tests/sms_queue/sms_queue_test.c b/tests/sms_queue/sms_queue_test.c index 25fc3122a..cc78e1491 100644 --- a/tests/sms_queue/sms_queue_test.c +++ b/tests/sms_queue/sms_queue_test.c @@ -158,7 +158,7 @@ void show_fake_sms_db() static void test_next_sms() { int i; - char last_msisdn[VLR_MSISDN_LENGTH+1] = ""; + char last_msisdn[GSM23003_MSISDN_MAX_DIGITS+1] = ""; printf("Testing smsq_take_next_sms()\n"); @@ -246,7 +246,7 @@ int main(int argc, char **argv) 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_filename2(osmo_stderr_target, LOG_FILENAME_NONE); log_set_print_category(osmo_stderr_target, 1); log_parse_category_mask(osmo_stderr_target, "DLOAP,1"); @@ -277,24 +277,3 @@ int main(int argc, char **argv) return 0; } - -void osmo_stream_srv_link_set_data(struct osmo_stream_srv_link *link, void *data) {} -struct osmo_fd *osmo_stream_srv_get_ofd(struct osmo_stream_srv *srv) { return NULL; } -void osmo_stream_srv_destroy(struct osmo_stream_srv *conn) {} -struct osmo_stream_srv *osmo_stream_srv_create(void *ctx, struct osmo_stream_srv_link *link, - int fd, int (*cb)(struct osmo_stream_srv *conn), - int (*closed_cb)(struct osmo_stream_srv *conn), - void *data) { return NULL; } -void osmo_stream_srv_send(struct osmo_stream_srv *conn, struct msgb *msg) {} -void osmo_stream_srv_link_set_proto(struct osmo_stream_srv_link *link, uint16_t proto) {} -struct osmo_fd *osmo_stream_srv_link_get_ofd(struct osmo_stream_srv_link *link) { return NULL; } -struct osmo_stream_srv_link *osmo_stream_srv_link_create(void *ctx) { return NULL; } -void *osmo_stream_srv_get_data(struct osmo_stream_srv *conn) { return NULL; } -void osmo_stream_srv_link_set_nodelay(struct osmo_stream_srv_link *link, bool nodelay) {} -void osmo_stream_srv_link_set_accept_cb(struct osmo_stream_srv_link *link, int (*accept_cb) - (struct osmo_stream_srv_link *link, int fd)) {} -int osmo_stream_srv_link_open(struct osmo_stream_srv_link *link) { return 0; } -void *osmo_stream_srv_link_get_data(struct osmo_stream_srv_link *link) { return NULL; } -void osmo_stream_srv_link_set_port(struct osmo_stream_srv_link *link, uint16_t port) {} -void osmo_stream_srv_link_set_addr(struct osmo_stream_srv_link *link, const char *addr) {} -int sctp_recvmsg(int sd, void *msg, size_t len, void *from, void *fromlen, void *info, int *msg_flags) { return 0; } diff --git a/tests/msc_vlr/stubs.h b/tests/stubs.c index bf55baafb..f4ccb48c7 100644 --- a/tests/msc_vlr/stubs.h +++ b/tests/stubs.c @@ -18,6 +18,9 @@ * */ +#include <osmocom/core/linuxlist.h> +#include <osmocom/netif/stream.h> + void osmo_stream_srv_link_set_data(struct osmo_stream_srv_link *link, void *data) {} struct osmo_fd *osmo_stream_srv_get_ofd(struct osmo_stream_srv *srv) { return NULL; } void osmo_stream_srv_destroy(struct osmo_stream_srv *conn) {} @@ -34,7 +37,17 @@ void osmo_stream_srv_link_set_nodelay(struct osmo_stream_srv_link *link, bool no void osmo_stream_srv_link_set_accept_cb(struct osmo_stream_srv_link *link, int (*accept_cb) (struct osmo_stream_srv_link *link, int fd)) {} int osmo_stream_srv_link_open(struct osmo_stream_srv_link *link) { return 0; } +void osmo_stream_srv_link_close(struct osmo_stream_srv_link *link) {} void *osmo_stream_srv_link_get_data(struct osmo_stream_srv_link *link) { return NULL; } +char *osmo_stream_srv_link_get_sockname(const struct osmo_stream_srv_link *link) { return NULL; } void osmo_stream_srv_link_set_port(struct osmo_stream_srv_link *link, uint16_t port) {} void osmo_stream_srv_link_set_addr(struct osmo_stream_srv_link *link, const char *addr) {} int sctp_recvmsg(int sd, void *msg, size_t len, void *from, void *fromlen, void *info, int *msg_flags) { return 0; } +struct gsm_sms; +struct msc_a; +struct gsm_trans; +struct smpp_esme; +bool smpp_route_smpp_first() { return false; } +void smpp_esme_put(struct smpp_esme *esme) { return; } +int smpp_try_deliver(struct gsm_sms *sms, struct msc_a *msc_a) { return 0; } +int sms_route_mt_sms(struct gsm_trans *trans, struct gsm_sms *gsms) { return 0; } diff --git a/tests/test_nodes.vty b/tests/test_nodes.vty index fb7b1c529..5e4b793b1 100644 --- a/tests/test_nodes.vty +++ b/tests/test_nodes.vty @@ -5,6 +5,8 @@ OsmoMSC(config)# list network msc sgs + smsc + asci mncc-int hlr ... @@ -14,23 +16,43 @@ OsmoMSC(config-net)# list ... network country code <1-999> mobile network code <0-999> - short name NAME - long name NAME - encryption a5 <0-3> [<0-3>] [<0-3>] [<0-3>] + short name .NAME + long name .NAME + encryption a5 <0-4> [<0-4>] [<0-4>] [<0-4>] [<0-4>] + encryption uea <0-2> [<0-2>] [<0-2>] authentication (optional|required) rrlp mode (none|ms-based|ms-preferred|ass-preferred) mm info (0|1) timezone <-19-19> (0|15|30|45) timezone <-19-19> (0|15|30|45) <0-2> no timezone - periodic location update <6-1530> - no periodic location update + call-waiting + no call-waiting + mgw <0-255> + no mgw <0-255> + +OsmoMSC(config-net)# encryption? + encryption Encryption options +OsmoMSC(config-net)# encryption ? + a5 GSM A5 Air Interface Encryption. + uea UTRAN (3G) encryption algorithms to allow: 0 = UEA0 (no encryption), 1 = UEA1, 2 = UEA2. + +OsmoMSC(config-net)# encryption uea ? + <0-2> UEAn Algorithm Number +OsmoMSC(config-net)# encryption uea 0 ? + [<0-2>] UEAn Algorithm Number +OsmoMSC(config-net)# encryption uea 0 1 ? + [<0-2>] UEAn Algorithm Number +OsmoMSC(config-net)# encryption uea 0 1 2 ? + <cr> OsmoMSC(config-net)# exit OsmoMSC(config)# msc OsmoMSC(config-msc)# list ... assign-tmsi + lcls-permitted + no lcls-permitted mncc internal mncc external MNCC_SOCKET_PATH mncc guard-timeout <0-255> @@ -41,20 +63,19 @@ OsmoMSC(config-msc)# list check-imei-rqd (0|1|early) cs7-instance-a <0-15> cs7-instance-iu <0-15> - paging response-timer (default|<1-65535>) emergency-call route-to-msisdn MSISDN sms-over-gsup no sms-over-gsup osmux (on|off|only) handover-number range MSISDN_FIRST MSISDN_LAST + nri bitlen <0-15> + nri add <0-32767> [<0-32767>] + nri del <0-32767> [<0-32767>] neighbor (a|iu) lac <0-65535> (ran-pc|msc-ipa-name) RAN_PC_OR_MSC_IPA_NAME neighbor (a|iu) lac-ci <0-65535> <0-65535> (ran-pc|msc-ipa-name) RAN_PC_OR_MSC_IPA_NAME neighbor (a|iu) cgi <0-999> <0-999> <0-65535> <0-65535> (ran-pc|msc-ipa-name) RAN_PC_OR_MSC_IPA_NAME no neighbor (a|iu) (ran-pc|msc-ipa-name) RAN_PC_OR_MSC_IPA_NAME - mgw local-ip A.B.C.D - mgw local-port <0-65535> - mgw remote-ip A.B.C.D - mgw remote-port <0-65535> + timer [(vlr|mgw|mncc|sccp|geran|utran|sgs)] [TNNNN] [(<0-2147483647>|default)] ... OsmoMSC(config-msc)# ncss? @@ -78,12 +99,16 @@ OsmoMSC(config-msc)# mncc external /path/not/used OsmoMSC(config-msc)# show running-config ... msc -... +... ! mncc internal mncc external /path/not/used -... +... ! mncc internal OsmoMSC(config-msc)# mncc internal OsmoMSC(config-msc)# show running-config +... +msc +... ! mncc external + mncc internal ... ! mncc external OsmoMSC(config-msc)# exit @@ -130,11 +155,13 @@ network short name OsmoMSC long name OsmoMSC encryption a5 0 + encryption uea 1 2 authentication optional rrlp mode none mm info 1 - periodic location update 30 +... msc + mncc internal mncc guard-timeout 180 ncss guard-timeout 30 assign-tmsi @@ -142,9 +169,6 @@ msc ... auth-tuple-max-reuse-count 3 auth-tuple-reuse-on-error 1 - mgw local-port 2728 - mgw remote-ip 10.23.24.1 - mgw remote-port 2427 mncc-int default-codec tch-f fr default-codec tch-h hr @@ -152,8 +176,57 @@ mncc-int hlr remote-ip 127.0.0.1 remote-port 4222 + ipa-name unnamed-MSC sgs local-port 29118 local-ip 0.0.0.0 vlr-name vlr.example.net +smsc + queue max-pending 20 + queue max-failure 1 + database delete-delivered 1 + database delete-expired 1 + validity-period minimum 1 + validity-period default 10080 +asci + disable + gcr end + +OsmoMSC# configure terminal +OsmoMSC(config)# network +OsmoMSC(config-net)# encryption uea 0 +OsmoMSC(config-net)# show running-config +... + encryption uea 0 +... + +OsmoMSC(config-net)# encryption uea 1 +OsmoMSC(config-net)# show running-config +... + encryption uea 1 +... + +OsmoMSC(config-net)# encryption uea 2 +OsmoMSC(config-net)# show running-config +... + encryption uea 2 +... + +OsmoMSC(config-net)# encryption uea 0 1 +OsmoMSC(config-net)# show running-config +... + encryption uea 0 1 +... + +OsmoMSC(config-net)# encryption uea 0 2 +OsmoMSC(config-net)# show running-config +... + encryption uea 0 2 +... + +OsmoMSC(config-net)# encryption uea 1 2 +OsmoMSC(config-net)# show running-config +... + encryption uea 1 2 +... diff --git a/tests/testsuite.at b/tests/testsuite.at index f27b60c48..fbf594b48 100644 --- a/tests/testsuite.at +++ b/tests/testsuite.at @@ -16,6 +16,14 @@ cat $abs_srcdir/sms_queue/sms_queue_test.err > experr AT_CHECK([$abs_top_builddir/tests/sms_queue/sms_queue_test], [], [expout], [experr]) AT_CLEANUP +AT_SETUP([db_sms_test]) +AT_KEYWORDS([db_sms_test]) +cat $abs_srcdir/db_sms/db_sms_test.ok > expout +cat $abs_srcdir/db_sms/db_sms_test.err > experr +# swap the output from stderr and stdout so we can drop libdbi prints to stderr when trying to load wrong drivers +AT_CHECK([$abs_top_builddir/tests/db_sms/db_sms_test 3>&1 1>&2 2>&3 | grep -v "Failed to load driver" | grep -v "cannot open shared object file"], [], [expout], [experr]) +AT_CLEANUP + AT_SETUP([msc_vlr_test_no_authen]) AT_KEYWORDS([msc_vlr_test_no_authen]) cat $abs_srcdir/msc_vlr/msc_vlr_test_no_authen.ok > expout @@ -99,3 +107,24 @@ cat $abs_srcdir/msc_vlr/msc_vlr_test_ss.ok > expout cat $abs_srcdir/msc_vlr/msc_vlr_test_ss.err > experr AT_CHECK([$abs_top_builddir/tests/msc_vlr/msc_vlr_test_ss], [], [expout], [experr]) AT_CLEANUP + +AT_SETUP([sdp_msg_test]) +AT_KEYWORDS([sdp_msg_test]) +cat $abs_srcdir/sdp_msg/sdp_msg_test.ok > expout +cat $abs_srcdir/sdp_msg/sdp_msg_test.err > experr +AT_CHECK([$abs_top_builddir/tests/sdp_msg/sdp_msg_test], [], [expout], [experr]) +AT_CLEANUP + +AT_SETUP([mncc_test]) +AT_KEYWORDS([mncc_test]) +cat $abs_srcdir/mncc/mncc_test.ok > expout +cat $abs_srcdir/mncc/mncc_test.err > experr +AT_CHECK([$abs_top_builddir/tests/mncc/mncc_test], [], [expout], [experr]) +AT_CLEANUP + +AT_SETUP([csd_test]) +AT_KEYWORDS([csd_test]) +cat $abs_srcdir/csd/csd_test.ok > expout +cat $abs_srcdir/csd/csd_test.err > experr +AT_CHECK([$abs_top_builddir/tests/csd/csd_test], [], [expout], [experr]) +AT_CLEANUP diff --git a/tests/vty_test_runner.py b/tests/vty_test_runner.py index 471ecf6c6..2dfa15534 100755 --- a/tests/vty_test_runner.py +++ b/tests/vty_test_runner.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python3 # (C) 2013 by Katerina Barone-Adesi <kat.obsc@gmail.com> # (C) 2013 by Holger Hans Peter Freyther @@ -33,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): @@ -54,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] @@ -65,7 +65,9 @@ class TestVTYBase(unittest.TestCase): if self.vty: self.vty._close_socket() self.vty = None - osmoutil.end_proc(self.proc) + rc = osmoutil.end_proc(self.proc) + if rc is not None and rc != 0: + raise Exception("Process returned %d" % rc) class TestVTYMSC(TestVTYBase): @@ -79,14 +81,14 @@ class TestVTYMSC(TestVTYBase): def testConfigNetworkTree(self, include_bsc_items=True): 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("network",[''])) - self.assertEquals(self.vty.node(), 'config-net') + self.assertEqual(self.vty.node(), 'config-net') self.checkForEndAndExit() self.vty.command("write terminal") self.assertTrue(self.vty.verify("exit",[''])) - self.assertEquals(self.vty.node(), 'config') + self.assertEqual(self.vty.node(), 'config') self.assertTrue(self.vty.verify("exit",[''])) self.assertTrue(self.vty.node() is None) @@ -107,35 +109,35 @@ class TestVTYMSC(TestVTYBase): # check the default res = self.vty.command("write terminal") - self.assert_(res.find(' no smpp-first') > 0) + self.assertTrue(res.find(' no smpp-first') > 0) self.vty.verify("smpp-first", ['']) res = self.vty.command("write terminal") - self.assert_(res.find(' smpp-first') > 0) - self.assertEquals(res.find('no smpp-first'), -1) + self.assertTrue(res.find(' smpp-first') > 0) + self.assertEqual(res.find('no smpp-first'), -1) self.vty.verify("no smpp-first", ['']) res = self.vty.command("write terminal") - self.assert_(res.find('no smpp-first') > 0) + self.assertTrue(res.find('no smpp-first') > 0) 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('mncc-int', [''])) - self.assertEquals(self.vty.node(), 'config-mncc-int') + self.assertEqual(self.vty.node(), 'config-mncc-int') self.checkForEndAndExit() self.assertTrue(self.vty.verify('exit', [''])) if self.checkForSmpp(): - self.assertEquals(self.vty.node(), 'config') + self.assertEqual(self.vty.node(), 'config') self.assertTrue(self.vty.verify('smpp', [''])) - self.assertEquals(self.vty.node(), 'config-smpp') + self.assertEqual(self.vty.node(), 'config-smpp') 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("exit", [''])) self.assertTrue(self.vty.node() is None) @@ -145,10 +147,10 @@ class TestVTYMSC(TestVTYBase): if self.checkForSmpp(): self.vty.command('smpp') - self.assertEquals(self.vty.node(), 'config-smpp') + self.assertEqual(self.vty.node(), 'config-smpp') self.vty.command('mncc-int') - self.assertEquals(self.vty.node(), 'config-mncc-int') + self.assertEqual(self.vty.node(), 'config-mncc-int') def testSi2Q(self): self.vty.enable() @@ -162,7 +164,7 @@ class TestVTYMSC(TestVTYBase): self.vty.command("si2quater neighbor-list del earfcn 1911") self.vty.command("si2quater neighbor-list del earfcn 1924") self.vty.command("si2quater neighbor-list del earfcn 2111") - self.assertEquals(before, self.vty.command("show running-config")) + self.assertEqual(before, self.vty.command("show running-config")) self.vty.command("si2quater neighbor-list add uarfcn 1976 13 1") self.vty.command("si2quater neighbor-list add uarfcn 1976 38 1") self.vty.command("si2quater neighbor-list add uarfcn 1976 44 1") @@ -185,7 +187,7 @@ class TestVTYMSC(TestVTYBase): self.vty.command("si2quater neighbor-list del uarfcn 1976 224") self.vty.command("si2quater neighbor-list del uarfcn 1976 225") self.vty.command("si2quater neighbor-list del uarfcn 1976 226") - self.assertEquals(before, self.vty.command("show running-config")) + self.assertEqual(before, self.vty.command("show running-config")) def testEnableDisablePeriodicLU(self): self.vty.enable() @@ -198,21 +200,26 @@ class TestVTYMSC(TestVTYBase): self.vty.verify("periodic location update 5", ['% Unknown command.']) self.vty.verify("periodic location update 1531", ['% Unknown command.']) - # Enable periodic lu.. - self.vty.verify("periodic location update 60", ['']) + depr_str = "% 'periodic location update' is now deprecated: " \ + "use 'timer T3212' to change subscriber expiration timeout." + set_str = "% Setting T3212 to 121 minutes (emulating the old behaviour)." + + # Enable periodic LU (deprecated command) + self.vty.verify("periodic location update 60", [depr_str, set_str]) res = self.vty.command("write terminal") - self.assert_(res.find('periodic location update 60') > 0) - self.assertEquals(res.find('no periodic location update'), -1) + self.assertTrue(res.find('timer vlr T3212 121') > 0) + self.assertEqual(res.find('periodic location update 60'), -1) + self.assertEqual(res.find('no periodic location update'), -1) - # Now disable it.. - self.vty.verify("no periodic location update", ['']) + # Now disable it (deprecated command) + self.vty.verify("no periodic location update", [depr_str]) res = self.vty.command("write terminal") - self.assertEquals(res.find('periodic location update 60'), -1) - self.assert_(res.find('no periodic location update') > 0) + self.assertEqual(res.find('no periodic location update'), -1) + self.assertEqual(res.find('timer vlr T3212 121'), -1) def testShowNetwork(self): res = self.vty.command("show network") - self.assert_(res.startswith('BSC is on Country Code') >= 0) + self.assertTrue(res.startswith('BSC is on Country Code') >= 0) def ipa_handle_small(x, verbose = False): s = data2str(x.recv(4)) @@ -220,42 +227,42 @@ def ipa_handle_small(x, verbose = False): raise Exception("expected to receive 4 bytes, but got %d (%r)" % (len(s)/2, s)) if "0001fe00" == s: if (verbose): - print "\tBSC <- NAT: PING?" + print("\tBSC <- NAT: PING?") x.send(IPA().pong()) elif "0001fe06" == s: if (verbose): - print "\tBSC <- NAT: IPA ID ACK" + print("\tBSC <- NAT: IPA ID ACK") x.send(IPA().id_ack()) elif "0001fe00" == s: if (verbose): - print "\tBSC <- NAT: PONG!" + print("\tBSC <- NAT: PONG!") else: if (verbose): - print "\tBSC <- NAT: ", s + print("\tBSC <- NAT: ", s) def ipa_handle_resp(x, tk, verbose = False, proc=None): s = data2str(x.recv(38)) if "0023fe040108010701020103010401050101010011" in s: retries = 3 while True: - print "\tsending IPA identity(%s) at %s" % (tk, time.strftime("%T")) + print("\tsending IPA identity(%s) at %s" % (tk, time.strftime("%T"))) try: x.send(IPA().id_resp(IPA().identity(name = tk.encode('utf-8')))) - print "\tdone sending IPA identity(%s) at %s" % (tk, - time.strftime("%T")) + print("\tdone sending IPA identity(%s) at %s" % (tk, + time.strftime("%T"))) break except: - print "\tfailed sending IPA identity at", time.strftime("%T") + print("\tfailed sending IPA identity at", time.strftime("%T")) if proc: - print "\tproc.poll() = %r" % proc.poll() + print("\tproc.poll() = %r" % proc.poll()) if retries < 1: - print "\tgiving up" + print("\tgiving up") raise - print "\tretrying (%d attempts left)" % retries + print("\tretrying (%d attempts left)" % retries) retries -= 1 else: if (verbose): - print "\tBSC <- NAT: ", s + print("\tBSC <- NAT: ", s) if __name__ == '__main__': import argparse @@ -283,9 +290,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() suite.addTest(unittest.TestLoader().loadTestsFromTestCase(TestVTYMSC)) |