aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.github/FUNDING.yml1
-rw-r--r--.gitignore11
-rw-r--r--Makefile.am11
-rw-r--r--README24
-rw-r--r--README.md110
-rw-r--r--README.vty-tests2
-rw-r--r--TODO-RELEASE10
-rw-r--r--configure.ac57
-rwxr-xr-xcontrib/jenkins.sh27
-rw-r--r--contrib/osmo-msc.spec.in118
-rw-r--r--contrib/systemd/osmo-msc.service4
-rw-r--r--debian/changelog585
-rw-r--r--debian/compat2
-rw-r--r--debian/control32
-rw-r--r--debian/copyright2
-rw-r--r--doc/examples/osmo-msc/osmo-msc.cfg19
-rw-r--r--doc/examples/osmo-msc/osmo-msc_custom-sccp.cfg19
-rw-r--r--doc/examples/osmo-msc/osmo-msc_multi-cs7.cfg19
-rw-r--r--doc/manuals/Makefile.am5
-rw-r--r--doc/manuals/chapters/counters_generated.adoc46
-rw-r--r--doc/manuals/chapters/running.adoc100
-rw-r--r--doc/manuals/chapters/sgs.adoc55
-rw-r--r--doc/manuals/osmomsc-usermanual.adoc12
-rw-r--r--doc/manuals/vty/msc_vty_reference.xml2841
-rw-r--r--doc/sequence_charts/Makefile.am13
-rw-r--r--doc/sequence_charts/call_reestablishment.msc33
-rwxr-xr-xdoc/sequence_charts/msc_log_to_ladder.py753
-rw-r--r--doc/sequence_charts/voice_call_external_mncc.msc124
-rw-r--r--doc/sequence_charts/voice_call_internal_mncc.msc129
-rw-r--r--include/osmocom/Makefile.am1
-rw-r--r--include/osmocom/msc/Makefile.am10
-rw-r--r--include/osmocom/msc/asci_gcr.h55
-rw-r--r--include/osmocom/msc/asci_vty.h25
-rw-r--r--include/osmocom/msc/call_leg.h4
-rw-r--r--include/osmocom/msc/cell_id_list.h6
-rw-r--r--include/osmocom/msc/codec_filter.h57
-rw-r--r--include/osmocom/msc/codec_mapping.h65
-rw-r--r--include/osmocom/msc/csd_bs.h54
-rw-r--r--include/osmocom/msc/csd_filter.h53
-rw-r--r--include/osmocom/msc/db.h9
-rw-r--r--include/osmocom/msc/debug.h4
-rw-r--r--include/osmocom/msc/gsm_04_08.h7
-rw-r--r--include/osmocom/msc/gsm_04_11.h21
-rw-r--r--include/osmocom/msc/gsm_data.h96
-rw-r--r--include/osmocom/msc/gsup_client_mux.h1
-rw-r--r--include/osmocom/msc/mncc.h42
-rw-r--r--include/osmocom/msc/mncc_call.h2
-rw-r--r--include/osmocom/msc/msc_a.h23
-rw-r--r--include/osmocom/msc/msc_common.h8
-rw-r--r--include/osmocom/msc/msc_ho.h8
-rw-r--r--include/osmocom/msc/msc_roles.h2
-rw-r--r--include/osmocom/msc/msc_t.h2
-rw-r--r--include/osmocom/msc/msc_vgcs.h228
-rw-r--r--include/osmocom/msc/msub.h4
-rw-r--r--include/osmocom/msc/paging.h1
-rw-r--r--include/osmocom/msc/ran_conn.h10
-rw-r--r--include/osmocom/msc/ran_infra.h5
-rw-r--r--include/osmocom/msc/ran_msg.h71
-rw-r--r--include/osmocom/msc/ran_msg_a.h3
-rw-r--r--include/osmocom/msc/ran_msg_iu.h3
-rw-r--r--include/osmocom/msc/ran_peer.h5
-rw-r--r--include/osmocom/msc/rtp_stream.h22
-rw-r--r--include/osmocom/msc/sccp_ran.h11
-rw-r--r--include/osmocom/msc/sdp_msg.h87
-rw-r--r--include/osmocom/msc/sgs_server.h2
-rw-r--r--include/osmocom/msc/signal.h9
-rw-r--r--include/osmocom/msc/smpp.h4
-rw-r--r--include/osmocom/msc/sms_queue.h18
-rw-r--r--include/osmocom/msc/transaction.h72
-rw-r--r--include/osmocom/msc/transaction_cc.h39
-rw-r--r--include/osmocom/msc/vlr.h54
-rw-r--r--include/osmocom/msc/vlr_sgs.h8
-rw-r--r--include/osmocom/msc/vty.h7
-rw-r--r--include/osmocom/smpp/Makefile.am4
-rw-r--r--include/osmocom/smpp/smpp.h55
-rw-r--r--include/osmocom/smpp/smpp_smsc.h (renamed from src/libmsc/smpp_smsc.h)54
-rw-r--r--m4/ax_check_compile_flag.m474
-rw-r--r--osmoappdesc.py13
-rw-r--r--src/Makefile.am16
-rw-r--r--src/libmsc/Makefile.am26
-rw-r--r--src/libmsc/asci_gcr.c175
-rw-r--r--src/libmsc/asci_vty.c434
-rw-r--r--src/libmsc/call_leg.c102
-rw-r--r--src/libmsc/cell_id_list.c14
-rw-r--r--src/libmsc/codec_filter.c163
-rw-r--r--src/libmsc/codec_mapping.c547
-rw-r--r--src/libmsc/csd_bs.c517
-rw-r--r--src/libmsc/csd_filter.c157
-rw-r--r--src/libmsc/db.c1235
-rw-r--r--src/libmsc/e_link.c2
-rw-r--r--src/libmsc/gsm_04_08.c488
-rw-r--r--src/libmsc/gsm_04_08_cc.c717
-rw-r--r--src/libmsc/gsm_04_11.c94
-rw-r--r--src/libmsc/gsm_04_11_gsup.c73
-rw-r--r--src/libmsc/gsm_04_14.c2
-rw-r--r--src/libmsc/gsm_09_11.c21
-rw-r--r--src/libmsc/gsup_client_mux.c36
-rw-r--r--src/libmsc/mncc.c42
-rw-r--r--src/libmsc/mncc_builtin.c21
-rw-r--r--src/libmsc/mncc_call.c72
-rw-r--r--src/libmsc/mncc_sock.c41
-rw-r--r--src/libmsc/msc_a.c640
-rw-r--r--src/libmsc/msc_a_remote.c4
-rw-r--r--src/libmsc/msc_ho.c104
-rw-r--r--src/libmsc/msc_i.c2
-rw-r--r--src/libmsc/msc_i_remote.c2
-rw-r--r--src/libmsc/msc_net_init.c34
-rw-r--r--src/libmsc/msc_t.c40
-rw-r--r--src/libmsc/msc_t_remote.c2
-rw-r--r--src/libmsc/msc_vgcs.c2765
-rw-r--r--src/libmsc/msc_vty.c391
-rw-r--r--src/libmsc/msub.c10
-rw-r--r--src/libmsc/neighbor_ident.c2
-rw-r--r--src/libmsc/paging.c40
-rw-r--r--src/libmsc/ran_conn.c2
-rw-r--r--src/libmsc/ran_infra.c14
-rw-r--r--src/libmsc/ran_msg.c33
-rw-r--r--src/libmsc/ran_msg_a.c871
-rw-r--r--src/libmsc/ran_msg_iu.c80
-rw-r--r--src/libmsc/ran_peer.c86
-rw-r--r--src/libmsc/rtp_stream.c182
-rw-r--r--src/libmsc/sccp_ran.c2
-rw-r--r--src/libmsc/sdp_msg.c686
-rw-r--r--src/libmsc/sgs_iface.c96
-rw-r--r--src/libmsc/silent_call.c6
-rw-r--r--src/libmsc/smpp_utils.c61
-rw-r--r--src/libmsc/sms_queue.c284
-rw-r--r--src/libmsc/smsc_vty.c214
-rw-r--r--src/libmsc/transaction.c120
-rw-r--r--src/libmsc/transaction_cc.c120
-rw-r--r--src/libsmpputil/Makefile.am25
-rw-r--r--src/libsmpputil/smpp_msc.c (renamed from src/libmsc/smpp_openbsc.c)70
-rw-r--r--src/libsmpputil/smpp_smsc.c (renamed from src/libmsc/smpp_smsc.c)325
-rw-r--r--src/libsmpputil/smpp_utils.c174
-rw-r--r--src/libsmpputil/smpp_vty.c (renamed from src/libmsc/smpp_vty.c)25
-rw-r--r--src/libvlr/vlr.c441
-rw-r--r--src/libvlr/vlr_access_req_fsm.c103
-rw-r--r--src/libvlr/vlr_auth_fsm.c118
-rw-r--r--src/libvlr/vlr_auth_fsm.h7
-rw-r--r--src/libvlr/vlr_lu_fsm.c105
-rw-r--r--src/libvlr/vlr_sgs.c29
-rw-r--r--src/libvlr/vlr_sgs_fsm.c13
-rw-r--r--src/osmo-msc/Makefile.am13
-rw-r--r--src/osmo-msc/msc_main.c286
-rw-r--r--src/utils/Makefile.am14
-rw-r--r--src/utils/smpp_mirror.c124
-rw-r--r--tests/Makefile.am39
-rw-r--r--tests/csd/Makefile.am37
-rw-r--r--tests/csd/csd_test.c44
-rw-r--r--tests/csd/csd_test.err (renamed from src/libmsc/ran_up_l2.c)0
-rw-r--r--tests/csd/csd_test.ok11
-rwxr-xr-xtests/ctrl_test_runner.py22
-rw-r--r--tests/db_sms/Makefile.am12
-rw-r--r--tests/db_sms/db_sms_test.c5
-rw-r--r--tests/mncc/Makefile.am37
-rw-r--r--tests/mncc/mncc_test.c79
-rw-r--r--tests/mncc/mncc_test.err10
-rw-r--r--tests/mncc/mncc_test.ok23
-rw-r--r--tests/msc_vlr/Makefile.am9
-rw-r--r--tests/msc_vlr/msc_vlr_test_authen_reuse.c14
-rw-r--r--tests/msc_vlr/msc_vlr_test_authen_reuse.err105
-rw-r--r--tests/msc_vlr/msc_vlr_test_call.c1135
-rw-r--r--tests/msc_vlr/msc_vlr_test_call.err5321
-rw-r--r--tests/msc_vlr/msc_vlr_test_gsm_authen.c32
-rw-r--r--tests/msc_vlr/msc_vlr_test_gsm_authen.err146
-rw-r--r--tests/msc_vlr/msc_vlr_test_gsm_ciph.c36
-rw-r--r--tests/msc_vlr/msc_vlr_test_gsm_ciph.err165
-rw-r--r--tests/msc_vlr/msc_vlr_test_hlr_reject.c30
-rw-r--r--tests/msc_vlr/msc_vlr_test_hlr_reject.err100
-rw-r--r--tests/msc_vlr/msc_vlr_test_hlr_timeout.c4
-rw-r--r--tests/msc_vlr/msc_vlr_test_hlr_timeout.err21
-rw-r--r--tests/msc_vlr/msc_vlr_test_ms_timeout.c10
-rw-r--r--tests/msc_vlr/msc_vlr_test_ms_timeout.err43
-rw-r--r--tests/msc_vlr/msc_vlr_test_no_authen.c24
-rw-r--r--tests/msc_vlr/msc_vlr_test_no_authen.err131
-rw-r--r--tests/msc_vlr/msc_vlr_test_reject_concurrency.c4
-rw-r--r--tests/msc_vlr/msc_vlr_test_reject_concurrency.err116
-rw-r--r--tests/msc_vlr/msc_vlr_test_rest.c6
-rw-r--r--tests/msc_vlr/msc_vlr_test_rest.err54
-rw-r--r--tests/msc_vlr/msc_vlr_test_ss.c2
-rw-r--r--tests/msc_vlr/msc_vlr_test_ss.err29
-rw-r--r--tests/msc_vlr/msc_vlr_test_umts_authen.c182
-rw-r--r--tests/msc_vlr/msc_vlr_test_umts_authen.err266
-rw-r--r--tests/msc_vlr/msc_vlr_tests.c274
-rw-r--r--tests/msc_vlr/msc_vlr_tests.h39
-rw-r--r--tests/sdp_msg/Makefile.am37
-rw-r--r--tests/sdp_msg/sdp_msg_test.c574
-rw-r--r--tests/sdp_msg/sdp_msg_test.err0
-rw-r--r--tests/sdp_msg/sdp_msg_test.ok592
-rw-r--r--tests/smpp/Makefile.am7
-rw-r--r--tests/smpp/smpp_test.c46
-rw-r--r--tests/smpp/smpp_test.ok8
-rwxr-xr-xtests/smpp_test_runner.py20
-rw-r--r--tests/sms_queue/Makefile.am14
-rw-r--r--tests/sms_queue/sms_queue_test.c23
-rw-r--r--tests/stubs.c10
-rw-r--r--tests/test_nodes.vty69
-rw-r--r--tests/testsuite.at21
-rwxr-xr-xtests/vty_test_runner.py97
199 files changed, 23550 insertions, 6927 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 5aa652d9b..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.2.0)
-PKG_CHECK_MODULES(LIBOSMOVTY, libosmovty >= 1.2.0)
-PKG_CHECK_MODULES(LIBOSMOCTRL, libosmoctrl >= 1.2.0)
-PKG_CHECK_MODULES(LIBOSMOGSM, libosmogsm >= 1.2.0)
-PKG_CHECK_MODULES(LIBOSMOABIS, libosmoabis >= 0.6.0)
-PKG_CHECK_MODULES(LIBOSMONETIF, libosmo-netif >= 0.6.0)
-PKG_CHECK_MODULES(LIBOSMOSIGTRAN, libosmo-sigtran >= 1.1.0)
-PKG_CHECK_MODULES(LIBOSMOSCCP, libosmo-sccp >= 1.1.0)
-PKG_CHECK_MODULES(LIBOSMOMGCPCLIENT, libosmo-mgcp-client >= 1.6.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], [
@@ -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([-Wnull-dereference], [CFLAGS="$CFLAGS -Wnull-dereference"])
-AX_CHECK_COMPILE_FLAG([-Werror=sizeof-array-argument], [CFLAGS="$CFLAGS -Werror=sizeof-array-argument"])
-AX_CHECK_COMPILE_FLAG([-Werror=sizeof-pointer-memaccess], [CFLAGS="$CFLAGS -Werror=sizeof-pointer-memaccess"])
-
# 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,9 +234,11 @@ 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
@@ -254,10 +247,14 @@ AC_OUTPUT(
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 dca33bbcb..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,18 +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 maintainer-clean
+$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 ec9671cc9..debce4e80 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,588 @@
+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 ]
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 f7a336a3e..64bb73c90 100644
--- a/debian/control
+++ b/debian/control
@@ -1,38 +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,
- libdbd-sqlite3,
+ libsqlite3-dev,
libsctp-dev,
libtalloc-dev,
libsmpp34-dev (>= 1.14.0),
libasn1c-dev (>= 0.9.30),
- libosmocore-dev (>= 1.2.0),
- libosmo-sccp-dev (>= 1.1.0),
- libosmo-sigtran-dev (>= 1.1.0),
- libosmo-abis-dev (>= 0.6.0),
- libosmo-mgcp-client-dev (>= 1.6.0),
- libosmo-gsup-client-dev (>= 1.0.0),
- libosmo-netif-dev (>= 0.6.0),
- libosmo-ranap-dev (>= 0.3.0),
- osmo-gsm-manuals-dev (>= 0.2.0)
+ 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
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/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 3b50d4e9a..14d142da3 100644
--- a/doc/manuals/Makefile.am
+++ b/doc/manuals/Makefile.am
@@ -14,6 +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 1b40d8b83..f55be27ac 100644
--- a/doc/manuals/chapters/counters_generated.adoc
+++ b/doc/manuals/chapters/counters_generated.adoc
@@ -10,29 +10,29 @@ These counters and their description based on OsmoMSC 1.4.0 (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.
-| cm_service_request:rejected | <<msc_cm_service_request:rejected>> | Rejected CM Service Request.
-| cm_service_request:accepted | <<msc_cm_service_request:accepted>> | Accepted CM Service Request.
-| paging_resp:rejected | <<msc_paging_resp:rejected>> | Rejected Paging Response.
-| paging_resp:accepted | <<msc_paging_resp:accepted>> | Accepted Paging Response.
-| 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 occurred 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.
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 d680a5119..45be140f5 100644
--- a/doc/manuals/osmomsc-usermanual.adoc
+++ b/doc/manuals/osmomsc-usermanual.adoc
@@ -22,6 +22,12 @@ 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[]
@@ -30,10 +36,16 @@ 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[]
diff --git a/doc/manuals/vty/msc_vty_reference.xml b/doc/manuals/vty/msc_vty_reference.xml
deleted file mode 100644
index 0e5d04d19..000000000
--- a/doc/manuals/vty/msc_vty_reference.xml
+++ /dev/null
@@ -1,2841 +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 &lt;0-512&gt;'>
- <params>
- <param name='terminal' doc='Set terminal line parameters' />
- <param name='length' doc='Set number of lines on a screen' />
- <param name='&lt;0-512&gt;' doc='Number of lines on screen (0 for no pausing)' />
- </params>
- </command>
- <command id='terminal no length'>
- <params>
- <param name='terminal' doc='Set terminal line parameters' />
- <param name='no' doc='Negate a command or set its defaults' />
- <param name='length' doc='Set number of lines on a screen' />
- </params>
- </command>
- <command id='who'>
- <params>
- <param name='who' doc='Display who is on vty' />
- </params>
- </command>
- <command id='show history'>
- <params>
- <param name='show' doc='Show running system information' />
- <param name='history' doc='Display the session command history' />
- </params>
- </command>
- <command id='show cs7 instance &lt;0-15&gt; users'>
- <params>
- <param name='show' doc='Show running system information' />
- <param name='cs7' doc='ITU-T Signaling System 7' />
- <param name='instance' doc='An instance of the SS7 stack' />
- <param name='&lt;0-15&gt;' doc='An instance of the SS7 stack' />
- <param name='users' doc='User Table' />
- </params>
- </command>
- <command id='show cs7 (sua|m3ua|ipa) [&lt;0-65534&gt;]'>
- <params>
- <param name='show' doc='Show running system information' />
- <param name='cs7' doc='ITU-T Signaling System 7' />
- <param name='sua' doc='SCCP User Adaptation' />
- <param name='m3ua' doc='MTP3 User Adaptation' />
- <param name='ipa' doc='IPA Multiplex (SCCP Lite)' />
- <param name='[&lt;0-65534&gt;]' doc='Port Number' />
- </params>
- </command>
- <command id='show cs7 instance &lt;0-15&gt; asp'>
- <params>
- <param name='show' doc='Show running system information' />
- <param name='cs7' doc='ITU-T Signaling System 7' />
- <param name='instance' doc='An instance of the SS7 stack' />
- <param name='&lt;0-15&gt;' doc='An instance of the SS7 stack' />
- <param name='asp' doc='Application Server Process (ASP)' />
- </params>
- </command>
- <command id='show cs7 instance &lt;0-15&gt; as (active|all|m3ua|sua)'>
- <params>
- <param name='show' doc='Show running system information' />
- <param name='cs7' doc='ITU-T Signaling System 7' />
- <param name='instance' doc='An instance of the SS7 stack' />
- <param name='&lt;0-15&gt;' doc='An instance of the SS7 stack' />
- <param name='as' doc='Application Server (AS)' />
- <param name='active' doc='Display all active ASs' />
- <param name='all' doc='Display all ASs (default)' />
- <param name='m3ua' doc='Display all m3ua ASs' />
- <param name='sua' doc='Display all SUA ASs' />
- </params>
- </command>
- <command id='show cs7 instance &lt;0-15&gt; sccp addressbook'>
- <params>
- <param name='show' doc='Show running system information' />
- <param name='cs7' doc='ITU-T Signaling System 7' />
- <param name='instance' doc='An instance of the SS7 stack' />
- <param name='&lt;0-15&gt;' doc='An instance of the SS7 stack' />
- <param name='sccp' doc='Signalling Connection Control Part' />
- <param name='addressbook' doc='List all SCCP addressbook entries' />
- </params>
- </command>
- <command id='show cs7 instance &lt;0-15&gt; sccp users'>
- <params>
- <param name='show' doc='Show running system information' />
- <param name='cs7' doc='ITU-T Signaling System 7' />
- <param name='instance' doc='An instance of the SS7 stack' />
- <param name='&lt;0-15&gt;' doc='An instance of the SS7 stack' />
- <param name='sccp' doc='Signalling Connection Control Part' />
- <param name='users' doc='Show List of SCCP Users registered' />
- </params>
- </command>
- <command id='show cs7 instance &lt;0-15&gt; sccp ssn &lt;0-65535&gt;'>
- <params>
- <param name='show' doc='Show running system information' />
- <param name='cs7' doc='ITU-T Signaling System 7' />
- <param name='instance' doc='An instance of the SS7 stack' />
- <param name='&lt;0-15&gt;' doc='An instance of the SS7 stack' />
- <param name='sccp' doc='Signalling Connection Control Part' />
- <param name='ssn' doc='Find an SCCP User registered for the given SSN' />
- <param name='&lt;0-65535&gt;' doc='Subsystem Number (SSN)' />
- </params>
- </command>
- <command id='show cs7 instance &lt;0-15&gt; sccp connections'>
- <params>
- <param name='show' doc='Show running system information' />
- <param name='cs7' doc='ITU-T Signaling System 7' />
- <param name='instance' doc='An instance of the SS7 stack' />
- <param name='&lt;0-15&gt;' doc='An instance of the SS7 stack' />
- <param name='sccp' doc='Signalling Connection Control Part' />
- <param name='connections' doc='Show List of active SCCP connections' />
- </params>
- </command>
- <command id='show cs7 instance &lt;0-15&gt; sccp timers'>
- <params>
- <param name='show' doc='Show running system information' />
- <param name='cs7' doc='ITU-T Signaling System 7' />
- <param name='instance' doc='An instance of the SS7 stack' />
- <param name='&lt;0-15&gt;' doc='An instance of the SS7 stack' />
- <param name='sccp' doc='Signaling Connection Control Part' />
- <param name='timers' doc='Show List of SCCP timers' />
- </params>
- </command>
- <command id='logging enable'>
- <params>
- <param name='logging' doc='Configure logging' />
- <param name='enable' doc='Enables logging to this vty' />
- </params>
- </command>
- <command id='logging disable'>
- <params>
- <param name='logging' doc='Configure logging' />
- <param name='disable' doc='Disables logging to this vty' />
- </params>
- </command>
- <command id='logging filter all (0|1)'>
- <params>
- <param name='logging' doc='Configure logging' />
- <param name='filter' doc='Filter log messages' />
- <param name='all' doc='Do you want to log all messages?' />
- <param name='0' doc='Only print messages matched by other filters' />
- <param name='1' doc='Bypass filter and print all messages' />
- </params>
- </command>
- <command id='logging color (0|1)'>
- <params>
- <param name='logging' doc='Configure logging' />
- <param name='color' doc='Configure color-printing for log messages' />
- <param name='0' doc='Don&apos;t use color for printing messages' />
- <param name='1' doc='Use color for printing messages' />
- </params>
- </command>
- <command id='logging timestamp (0|1)'>
- <params>
- <param name='logging' doc='Configure logging' />
- <param name='timestamp' doc='Configure log message timestamping' />
- <param name='0' doc='Don&apos;t prefix each log message' />
- <param name='1' doc='Prefix each log message with current timestamp' />
- </params>
- </command>
- <command id='logging print extended-timestamp (0|1)'>
- <params>
- <param name='logging' doc='Configure logging' />
- <param name='print' doc='Log output settings' />
- <param name='extended-timestamp' doc='Configure log message timestamping' />
- <param name='0' doc='Don&apos;t prefix each log message' />
- <param name='1' doc='Prefix each log message with current timestamp with YYYYMMDDhhmmssnnn' />
- </params>
- </command>
- <command id='logging print category (0|1)'>
- <params>
- <param name='logging' doc='Configure logging' />
- <param name='print' doc='Log output settings' />
- <param name='category' doc='Configure log message' />
- <param name='0' doc='Don&apos;t prefix each log message' />
- <param name='1' doc='Prefix each log message with category/subsystem name' />
- </params>
- </command>
- <command id='logging print category-hex (0|1)'>
- <params>
- <param name='logging' doc='Configure logging' />
- <param name='print' doc='Log output settings' />
- <param name='category-hex' doc='Configure log message' />
- <param name='0' doc='Don&apos;t prefix each log message' />
- <param name='1' doc='Prefix each log message with category/subsystem nr in hex (&apos;&lt;000b&gt;&apos;)' />
- </params>
- </command>
- <command id='logging print level (0|1)'>
- <params>
- <param name='logging' doc='Configure logging' />
- <param name='print' doc='Log output settings' />
- <param name='level' doc='Configure log message' />
- <param name='0' doc='Don&apos;t prefix each log message' />
- <param name='1' doc='Prefix each log message with the log level name' />
- </params>
- </command>
- <command id='logging print file (0|1|basename) [last]'>
- <params>
- <param name='logging' doc='Configure logging' />
- <param name='print' doc='Log output settings' />
- <param name='file' doc='Configure log message' />
- <param name='0' doc='Don&apos;t prefix each log message' />
- <param name='1' doc='Prefix each log message with the source file and line' />
- <param name='basename' doc='Prefix each log message with the source file&apos;s basename (strip leading paths) and line' />
- <param name='[last]' doc='Log source file info at the end of a log line. If omitted, log source file info just before the log text.' />
- </params>
- </command>
- <command id='logging set-log-mask MASK'>
- <params>
- <param name='logging' doc='Configure logging' />
- <param name='set-log-mask' doc='Set the logmask of this logging target' />
- <param name='MASK' doc='List of logging categories to log, e.g. &apos;abc:mno:xyz&apos;. Available log categories depend on the specific application, refer to the &apos;logging level&apos; command. Optionally add individual log levels like &apos;abc,1:mno,3:xyz,5&apos;, where the level numbers are LOGL_DEBUG=1 LOGL_INFO=3 LOGL_NOTICE=5 LOGL_ERROR=7 LOGL_FATAL=8' />
- </params>
- </command>
- <command id='logging level (rll|cc|mm|rr|mncc|pag|msc|mgcp|ho|db|ref|ctrl|smpp|ranap|vlr|iucs|bssap|sgs|lglobal|llapd|linp|lmux|lmi|lmib|lsms|lctrl|lgtp|lstats|lgsup|loap|lss7|lsccp|lsua|lm3ua|lmgcp|ljibuf|lrspro) (debug|info|notice|error|fatal)'>
- <params>
- <param name='logging' doc='Configure logging' />
- <param name='level' doc='Set the log level for a specified category' />
- <param name='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='sgs' doc='SGs Interface (SGsAP)' />
- <param name='lglobal' doc='Library-internal global log family' />
- <param name='llapd' doc='LAPD in libosmogsm' />
- <param name='linp' doc='A-bis Intput Subsystem' />
- <param name='lmux' doc='A-bis B-Subchannel TRAU Frame Multiplex' />
- <param name='lmi' doc='A-bis Input Driver for Signalling' />
- <param name='lmib' doc='A-bis Input Driver for B-Channels (voice)' />
- <param name='lsms' doc='Layer3 Short Message Service (SMS)' />
- <param name='lctrl' doc='Control Interface' />
- <param name='lgtp' doc='GPRS GTP library' />
- <param name='lstats' doc='Statistics messages and logging' />
- <param name='lgsup' doc='Generic Subscriber Update Protocol' />
- <param name='loap' doc='Osmocom Authentication Protocol' />
- <param name='lss7' doc='libosmo-sigtran Signalling System 7' />
- <param name='lsccp' doc='libosmo-sigtran SCCP Implementation' />
- <param name='lsua' doc='libosmo-sigtran SCCP User Adaptation' />
- <param name='lm3ua' doc='libosmo-sigtran MTP3 User Adaptation' />
- <param name='lmgcp' doc='libosmo-mgcp Media Gateway Control Protocol' />
- <param name='ljibuf' doc='libosmo-netif Jitter Buffer' />
- <param name='lrspro' doc='Remote SIM protocol' />
- <param name='debug' doc='Log debug messages and higher levels' />
- <param name='info' doc='Log informational messages and higher levels' />
- <param name='notice' doc='Log noticeable messages and higher levels' />
- <param name='error' doc='Log error messages and higher levels' />
- <param name='fatal' doc='Log only fatal messages' />
- </params>
- </command>
- <command id='logging level set-all (debug|info|notice|error|fatal)'>
- <params>
- <param name='logging' doc='Configure logging' />
- <param name='level' doc='Set the log level for a specified category' />
- <param name='set-all' doc='Once-off set all categories to the given log level. There is no single command to take back these changes -- each category is set to the given level, period.' />
- <param name='debug' doc='Log debug messages and higher levels' />
- <param name='info' doc='Log informational messages and higher levels' />
- <param name='notice' doc='Log noticeable messages and higher levels' />
- <param name='error' doc='Log error messages and higher levels' />
- <param name='fatal' doc='Log only fatal messages' />
- </params>
- </command>
- <command id='logging level force-all (debug|info|notice|error|fatal)'>
- <params>
- <param name='logging' doc='Configure logging' />
- <param name='level' doc='Set the log level for a specified category' />
- <param name='force-all' doc='Globally force all logging categories to a specific level. This is released by the &apos;no logging level force-all&apos; command. Note: any &apos;logging level &lt;category&gt; &lt;level&gt;&apos; commands will have no visible effect after this, until the forced level is released.' />
- <param name='debug' doc='Log debug messages and higher levels' />
- <param name='info' doc='Log informational messages and higher levels' />
- <param name='notice' doc='Log noticeable messages and higher levels' />
- <param name='error' doc='Log error messages and higher levels' />
- <param name='fatal' doc='Log only fatal messages' />
- </params>
- </command>
- <command id='no logging level force-all'>
- <params>
- <param name='no' doc='Negate a command or set its defaults' />
- <param name='logging' doc='Configure logging' />
- <param name='level' doc='Set the log level for a specified category' />
- <param name='force-all' doc='Release any globally forced log level set with &apos;logging level force-all &lt;level&gt;&apos;' />
- </params>
- </command>
- <command id='show logging vty'>
- <params>
- <param name='show' doc='Show running system information' />
- <param name='logging' doc='Show current logging configuration' />
- <param name='vty' doc='Show current logging configuration for this vty' />
- </params>
- </command>
- <command id='show alarms'>
- <params>
- <param name='show' doc='Show running system information' />
- <param name='alarms' doc='Show current logging configuration' />
- </params>
- </command>
- <command id='show talloc-context (application|all) (full|brief|DEPTH)'>
- <params>
- <param name='show' doc='Show running system information' />
- <param name='talloc-context' doc='Show talloc memory hierarchy' />
- <param name='application' doc='Application&apos;s context' />
- <param name='all' doc='All contexts, if NULL-context tracking is enabled' />
- <param name='full' doc='Display a full talloc memory hierarchy' />
- <param name='brief' doc='Display a brief talloc memory hierarchy' />
- <param name='DEPTH' doc='Specify required maximal depth value' />
- </params>
- </command>
- <command id='show talloc-context (application|all) (full|brief|DEPTH) tree ADDRESS'>
- <params>
- <param name='show' doc='Show running system information' />
- <param name='talloc-context' doc='Show talloc memory hierarchy' />
- <param name='application' doc='Application&apos;s context' />
- <param name='all' doc='All contexts, if NULL-context tracking is enabled' />
- <param name='full' doc='Display a full talloc memory hierarchy' />
- <param name='brief' doc='Display a brief talloc memory hierarchy' />
- <param name='DEPTH' doc='Specify required maximal depth value' />
- <param name='tree' doc='Display only a specific memory chunk' />
- <param name='ADDRESS' doc='Chunk address (e.g. 0xdeadbeef)' />
- </params>
- </command>
- <command id='show talloc-context (application|all) (full|brief|DEPTH) filter REGEXP'>
- <params>
- <param name='show' doc='Show running system information' />
- <param name='talloc-context' doc='Show talloc memory hierarchy' />
- <param name='application' doc='Application&apos;s context' />
- <param name='all' doc='All contexts, if NULL-context tracking is enabled' />
- <param name='full' doc='Display a full talloc memory hierarchy' />
- <param name='brief' doc='Display a brief talloc memory hierarchy' />
- <param name='DEPTH' doc='Specify required maximal depth value' />
- <param name='filter' doc='Filter chunks using regular expression' />
- <param name='REGEXP' doc='Regular expression' />
- </params>
- </command>
- <command id='show stats'>
- <params>
- <param name='show' doc='Show running system information' />
- <param name='stats' doc='Show statistical values' />
- </params>
- </command>
- <command id='show stats level (global|peer|subscriber)'>
- <params>
- <param name='show' doc='Show running system information' />
- <param name='stats' doc='Show statistical values' />
- <param name='level' doc='Set the maximum group level' />
- <param name='global' doc='Show global groups only' />
- <param name='peer' doc='Show global and network peer related groups' />
- <param name='subscriber' doc='Show global, peer, and subscriber groups' />
- </params>
- </command>
- <command id='show asciidoc counters'>
- <params>
- <param name='show' doc='Show running system information' />
- <param name='asciidoc' doc='Asciidoc generation' />
- <param name='counters' doc='Generate table of all registered counters' />
- </params>
- </command>
- <command id='show rate-counters'>
- <params>
- <param name='show' doc='Show running system information' />
- <param name='rate-counters' doc='Show all rate counters' />
- </params>
- </command>
- <command id='show 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 sgs-connections'>
- <params>
- <param name='show' doc='Show running system information' />
- <param name='sgs-connections' doc='Show SGs interface connections / MMEs' />
- </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 &apos;msisdn&apos;' />
- <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 bsc'>
- <params>
- <param name='show' doc='Show running system information' />
- <param name='bsc' doc='BSC' />
- </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 &apos;msisdn&apos;' />
- <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 &apos;msisdn&apos;' />
- <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 &apos;msisdn&apos;' />
- <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 &apos;msisdn&apos;' />
- <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/h|tch/any|sdcch) (signalling|speech-hr|speech-fr|speech-efr|speech-amr) [IP] [&lt;0-65535&gt;]'>
- <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 &apos;msisdn&apos;' />
- <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/h' doc='TCH/H channel' />
- <param name='tch/any' doc='Any TCH channel' />
- <param name='sdcch' doc='SDCCH channel' />
- <param name='signalling' doc='Signalling only' />
- <param name='speech-hr' doc='Speech with HR codec' />
- <param name='speech-fr' doc='Speech with FR codec' />
- <param name='speech-efr' doc='Speech with EFR codec' />
- <param name='speech-amr' doc='Speech with AMR codec' />
- <param name='[IP]' doc='Target IP for RTP traffic (default 127.0.0.1)' />
- <param name='[&lt;0-65535&gt;]' doc='Target port for RTP traffic (default: 4000)' />
- </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 &apos;msisdn&apos;' />
- <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 &apos;msisdn&apos;' />
- <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 &apos;msisdn&apos;' />
- <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 &apos;msisdn&apos;' />
- <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 &apos;msisdn&apos;' />
- <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 External 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 &lt;0-512&gt;'>
- <params>
- <param name='terminal' doc='Set terminal line parameters' />
- <param name='length' doc='Set number of lines on a screen' />
- <param name='&lt;0-512&gt;' doc='Number of lines on screen (0 for no pausing)' />
- </params>
- </command>
- <command id='terminal no length'>
- <params>
- <param name='terminal' doc='Set terminal line parameters' />
- <param name='no' doc='Negate a command or set its defaults' />
- <param name='length' doc='Set number of lines on a screen' />
- </params>
- </command>
- <command id='who'>
- <params>
- <param name='who' doc='Display who is on vty' />
- </params>
- </command>
- <command id='show history'>
- <params>
- <param name='show' doc='Show running system information' />
- <param name='history' doc='Display the session command history' />
- </params>
- </command>
- <command id='terminal monitor'>
- <params>
- <param name='terminal' doc='Set terminal line parameters' />
- <param name='monitor' doc='Copy debug output to the current terminal line' />
- </params>
- </command>
- <command id='terminal no monitor'>
- <params>
- <param name='terminal' doc='Set terminal line parameters' />
- <param name='no' doc='Negate a command or set its defaults' />
- <param name='monitor' doc='Copy debug output to the current terminal line' />
- </params>
- </command>
- <command id='show cs7 instance &lt;0-15&gt; users'>
- <params>
- <param name='show' doc='Show running system information' />
- <param name='cs7' doc='ITU-T Signaling System 7' />
- <param name='instance' doc='An instance of the SS7 stack' />
- <param name='&lt;0-15&gt;' doc='An instance of the SS7 stack' />
- <param name='users' doc='User Table' />
- </params>
- </command>
- <command id='show cs7 (sua|m3ua|ipa) [&lt;0-65534&gt;]'>
- <params>
- <param name='show' doc='Show running system information' />
- <param name='cs7' doc='ITU-T Signaling System 7' />
- <param name='sua' doc='SCCP User Adaptation' />
- <param name='m3ua' doc='MTP3 User Adaptation' />
- <param name='ipa' doc='IPA Multiplex (SCCP Lite)' />
- <param name='[&lt;0-65534&gt;]' doc='Port Number' />
- </params>
- </command>
- <command id='show cs7 instance &lt;0-15&gt; asp'>
- <params>
- <param name='show' doc='Show running system information' />
- <param name='cs7' doc='ITU-T Signaling System 7' />
- <param name='instance' doc='An instance of the SS7 stack' />
- <param name='&lt;0-15&gt;' doc='An instance of the SS7 stack' />
- <param name='asp' doc='Application Server Process (ASP)' />
- </params>
- </command>
- <command id='show cs7 instance &lt;0-15&gt; as (active|all|m3ua|sua)'>
- <params>
- <param name='show' doc='Show running system information' />
- <param name='cs7' doc='ITU-T Signaling System 7' />
- <param name='instance' doc='An instance of the SS7 stack' />
- <param name='&lt;0-15&gt;' doc='An instance of the SS7 stack' />
- <param name='as' doc='Application Server (AS)' />
- <param name='active' doc='Display all active ASs' />
- <param name='all' doc='Display all ASs (default)' />
- <param name='m3ua' doc='Display all m3ua ASs' />
- <param name='sua' doc='Display all SUA ASs' />
- </params>
- </command>
- <command id='show cs7 instance &lt;0-15&gt; sccp addressbook'>
- <params>
- <param name='show' doc='Show running system information' />
- <param name='cs7' doc='ITU-T Signaling System 7' />
- <param name='instance' doc='An instance of the SS7 stack' />
- <param name='&lt;0-15&gt;' doc='An instance of the SS7 stack' />
- <param name='sccp' doc='Signalling Connection Control Part' />
- <param name='addressbook' doc='List all SCCP addressbook entries' />
- </params>
- </command>
- <command id='show cs7 instance &lt;0-15&gt; sccp users'>
- <params>
- <param name='show' doc='Show running system information' />
- <param name='cs7' doc='ITU-T Signaling System 7' />
- <param name='instance' doc='An instance of the SS7 stack' />
- <param name='&lt;0-15&gt;' doc='An instance of the SS7 stack' />
- <param name='sccp' doc='Signalling Connection Control Part' />
- <param name='users' doc='Show List of SCCP Users registered' />
- </params>
- </command>
- <command id='show cs7 instance &lt;0-15&gt; sccp ssn &lt;0-65535&gt;'>
- <params>
- <param name='show' doc='Show running system information' />
- <param name='cs7' doc='ITU-T Signaling System 7' />
- <param name='instance' doc='An instance of the SS7 stack' />
- <param name='&lt;0-15&gt;' doc='An instance of the SS7 stack' />
- <param name='sccp' doc='Signalling Connection Control Part' />
- <param name='ssn' doc='Find an SCCP User registered for the given SSN' />
- <param name='&lt;0-65535&gt;' doc='Subsystem Number (SSN)' />
- </params>
- </command>
- <command id='show cs7 instance &lt;0-15&gt; sccp connections'>
- <params>
- <param name='show' doc='Show running system information' />
- <param name='cs7' doc='ITU-T Signaling System 7' />
- <param name='instance' doc='An instance of the SS7 stack' />
- <param name='&lt;0-15&gt;' doc='An instance of the SS7 stack' />
- <param name='sccp' doc='Signalling Connection Control Part' />
- <param name='connections' doc='Show List of active SCCP connections' />
- </params>
- </command>
- <command id='show cs7 instance &lt;0-15&gt; sccp timers'>
- <params>
- <param name='show' doc='Show running system information' />
- <param name='cs7' doc='ITU-T Signaling System 7' />
- <param name='instance' doc='An instance of the SS7 stack' />
- <param name='&lt;0-15&gt;' doc='An instance of the SS7 stack' />
- <param name='sccp' doc='Signaling Connection Control Part' />
- <param name='timers' doc='Show List of SCCP timers' />
- </params>
- </command>
- <command id='logging enable'>
- <params>
- <param name='logging' doc='Configure logging' />
- <param name='enable' doc='Enables logging to this vty' />
- </params>
- </command>
- <command id='logging disable'>
- <params>
- <param name='logging' doc='Configure logging' />
- <param name='disable' doc='Disables logging to this vty' />
- </params>
- </command>
- <command id='logging filter all (0|1)'>
- <params>
- <param name='logging' doc='Configure logging' />
- <param name='filter' doc='Filter log messages' />
- <param name='all' doc='Do you want to log all messages?' />
- <param name='0' doc='Only print messages matched by other filters' />
- <param name='1' doc='Bypass filter and print all messages' />
- </params>
- </command>
- <command id='logging color (0|1)'>
- <params>
- <param name='logging' doc='Configure logging' />
- <param name='color' doc='Configure color-printing for log messages' />
- <param name='0' doc='Don&apos;t use color for printing messages' />
- <param name='1' doc='Use color for printing messages' />
- </params>
- </command>
- <command id='logging timestamp (0|1)'>
- <params>
- <param name='logging' doc='Configure logging' />
- <param name='timestamp' doc='Configure log message timestamping' />
- <param name='0' doc='Don&apos;t prefix each log message' />
- <param name='1' doc='Prefix each log message with current timestamp' />
- </params>
- </command>
- <command id='logging print extended-timestamp (0|1)'>
- <params>
- <param name='logging' doc='Configure logging' />
- <param name='print' doc='Log output settings' />
- <param name='extended-timestamp' doc='Configure log message timestamping' />
- <param name='0' doc='Don&apos;t prefix each log message' />
- <param name='1' doc='Prefix each log message with current timestamp with YYYYMMDDhhmmssnnn' />
- </params>
- </command>
- <command id='logging print category (0|1)'>
- <params>
- <param name='logging' doc='Configure logging' />
- <param name='print' doc='Log output settings' />
- <param name='category' doc='Configure log message' />
- <param name='0' doc='Don&apos;t prefix each log message' />
- <param name='1' doc='Prefix each log message with category/subsystem name' />
- </params>
- </command>
- <command id='logging print category-hex (0|1)'>
- <params>
- <param name='logging' doc='Configure logging' />
- <param name='print' doc='Log output settings' />
- <param name='category-hex' doc='Configure log message' />
- <param name='0' doc='Don&apos;t prefix each log message' />
- <param name='1' doc='Prefix each log message with category/subsystem nr in hex (&apos;&lt;000b&gt;&apos;)' />
- </params>
- </command>
- <command id='logging print level (0|1)'>
- <params>
- <param name='logging' doc='Configure logging' />
- <param name='print' doc='Log output settings' />
- <param name='level' doc='Configure log message' />
- <param name='0' doc='Don&apos;t prefix each log message' />
- <param name='1' doc='Prefix each log message with the log level name' />
- </params>
- </command>
- <command id='logging print file (0|1|basename) [last]'>
- <params>
- <param name='logging' doc='Configure logging' />
- <param name='print' doc='Log output settings' />
- <param name='file' doc='Configure log message' />
- <param name='0' doc='Don&apos;t prefix each log message' />
- <param name='1' doc='Prefix each log message with the source file and line' />
- <param name='basename' doc='Prefix each log message with the source file&apos;s basename (strip leading paths) and line' />
- <param name='[last]' doc='Log source file info at the end of a log line. If omitted, log source file info just before the log text.' />
- </params>
- </command>
- <command id='logging set-log-mask MASK'>
- <params>
- <param name='logging' doc='Configure logging' />
- <param name='set-log-mask' doc='Set the logmask of this logging target' />
- <param name='MASK' doc='List of logging categories to log, e.g. &apos;abc:mno:xyz&apos;. Available log categories depend on the specific application, refer to the &apos;logging level&apos; command. Optionally add individual log levels like &apos;abc,1:mno,3:xyz,5&apos;, where the level numbers are LOGL_DEBUG=1 LOGL_INFO=3 LOGL_NOTICE=5 LOGL_ERROR=7 LOGL_FATAL=8' />
- </params>
- </command>
- <command id='logging level (rll|cc|mm|rr|mncc|pag|msc|mgcp|ho|db|ref|ctrl|smpp|ranap|vlr|iucs|bssap|sgs|lglobal|llapd|linp|lmux|lmi|lmib|lsms|lctrl|lgtp|lstats|lgsup|loap|lss7|lsccp|lsua|lm3ua|lmgcp|ljibuf|lrspro) (debug|info|notice|error|fatal)'>
- <params>
- <param name='logging' doc='Configure logging' />
- <param name='level' doc='Set the log level for a specified category' />
- <param name='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='sgs' doc='SGs Interface (SGsAP)' />
- <param name='lglobal' doc='Library-internal global log family' />
- <param name='llapd' doc='LAPD in libosmogsm' />
- <param name='linp' doc='A-bis Intput Subsystem' />
- <param name='lmux' doc='A-bis B-Subchannel TRAU Frame Multiplex' />
- <param name='lmi' doc='A-bis Input Driver for Signalling' />
- <param name='lmib' doc='A-bis Input Driver for B-Channels (voice)' />
- <param name='lsms' doc='Layer3 Short Message Service (SMS)' />
- <param name='lctrl' doc='Control Interface' />
- <param name='lgtp' doc='GPRS GTP library' />
- <param name='lstats' doc='Statistics messages and logging' />
- <param name='lgsup' doc='Generic Subscriber Update Protocol' />
- <param name='loap' doc='Osmocom Authentication Protocol' />
- <param name='lss7' doc='libosmo-sigtran Signalling System 7' />
- <param name='lsccp' doc='libosmo-sigtran SCCP Implementation' />
- <param name='lsua' doc='libosmo-sigtran SCCP User Adaptation' />
- <param name='lm3ua' doc='libosmo-sigtran MTP3 User Adaptation' />
- <param name='lmgcp' doc='libosmo-mgcp Media Gateway Control Protocol' />
- <param name='ljibuf' doc='libosmo-netif Jitter Buffer' />
- <param name='lrspro' doc='Remote SIM protocol' />
- <param name='debug' doc='Log debug messages and higher levels' />
- <param name='info' doc='Log informational messages and higher levels' />
- <param name='notice' doc='Log noticeable messages and higher levels' />
- <param name='error' doc='Log error messages and higher levels' />
- <param name='fatal' doc='Log only fatal messages' />
- </params>
- </command>
- <command id='logging level set-all (debug|info|notice|error|fatal)'>
- <params>
- <param name='logging' doc='Configure logging' />
- <param name='level' doc='Set the log level for a specified category' />
- <param name='set-all' doc='Once-off set all categories to the given log level. There is no single command to take back these changes -- each category is set to the given level, period.' />
- <param name='debug' doc='Log debug messages and higher levels' />
- <param name='info' doc='Log informational messages and higher levels' />
- <param name='notice' doc='Log noticeable messages and higher levels' />
- <param name='error' doc='Log error messages and higher levels' />
- <param name='fatal' doc='Log only fatal messages' />
- </params>
- </command>
- <command id='logging level force-all (debug|info|notice|error|fatal)'>
- <params>
- <param name='logging' doc='Configure logging' />
- <param name='level' doc='Set the log level for a specified category' />
- <param name='force-all' doc='Globally force all logging categories to a specific level. This is released by the &apos;no logging level force-all&apos; command. Note: any &apos;logging level &lt;category&gt; &lt;level&gt;&apos; commands will have no visible effect after this, until the forced level is released.' />
- <param name='debug' doc='Log debug messages and higher levels' />
- <param name='info' doc='Log informational messages and higher levels' />
- <param name='notice' doc='Log noticeable messages and higher levels' />
- <param name='error' doc='Log error messages and higher levels' />
- <param name='fatal' doc='Log only fatal messages' />
- </params>
- </command>
- <command id='no logging level force-all'>
- <params>
- <param name='no' doc='Negate a command or set its defaults' />
- <param name='logging' doc='Configure logging' />
- <param name='level' doc='Set the log level for a specified category' />
- <param name='force-all' doc='Release any globally forced log level set with &apos;logging level force-all &lt;level&gt;&apos;' />
- </params>
- </command>
- <command id='show logging vty'>
- <params>
- <param name='show' doc='Show running system information' />
- <param name='logging' doc='Show current logging configuration' />
- <param name='vty' doc='Show current logging configuration for this vty' />
- </params>
- </command>
- <command id='show alarms'>
- <params>
- <param name='show' doc='Show running system information' />
- <param name='alarms' doc='Show current logging configuration' />
- </params>
- </command>
- <command id='show talloc-context (application|all) (full|brief|DEPTH)'>
- <params>
- <param name='show' doc='Show running system information' />
- <param name='talloc-context' doc='Show talloc memory hierarchy' />
- <param name='application' doc='Application&apos;s context' />
- <param name='all' doc='All contexts, if NULL-context tracking is enabled' />
- <param name='full' doc='Display a full talloc memory hierarchy' />
- <param name='brief' doc='Display a brief talloc memory hierarchy' />
- <param name='DEPTH' doc='Specify required maximal depth value' />
- </params>
- </command>
- <command id='show talloc-context (application|all) (full|brief|DEPTH) tree ADDRESS'>
- <params>
- <param name='show' doc='Show running system information' />
- <param name='talloc-context' doc='Show talloc memory hierarchy' />
- <param name='application' doc='Application&apos;s context' />
- <param name='all' doc='All contexts, if NULL-context tracking is enabled' />
- <param name='full' doc='Display a full talloc memory hierarchy' />
- <param name='brief' doc='Display a brief talloc memory hierarchy' />
- <param name='DEPTH' doc='Specify required maximal depth value' />
- <param name='tree' doc='Display only a specific memory chunk' />
- <param name='ADDRESS' doc='Chunk address (e.g. 0xdeadbeef)' />
- </params>
- </command>
- <command id='show talloc-context (application|all) (full|brief|DEPTH) filter REGEXP'>
- <params>
- <param name='show' doc='Show running system information' />
- <param name='talloc-context' doc='Show talloc memory hierarchy' />
- <param name='application' doc='Application&apos;s context' />
- <param name='all' doc='All contexts, if NULL-context tracking is enabled' />
- <param name='full' doc='Display a full talloc memory hierarchy' />
- <param name='brief' doc='Display a brief talloc memory hierarchy' />
- <param name='DEPTH' doc='Specify required maximal depth value' />
- <param name='filter' doc='Filter chunks using regular expression' />
- <param name='REGEXP' doc='Regular expression' />
- </params>
- </command>
- <command id='show stats'>
- <params>
- <param name='show' doc='Show running system information' />
- <param name='stats' doc='Show statistical values' />
- </params>
- </command>
- <command id='show stats level (global|peer|subscriber)'>
- <params>
- <param name='show' doc='Show running system information' />
- <param name='stats' doc='Show statistical values' />
- <param name='level' doc='Set the maximum group level' />
- <param name='global' doc='Show global groups only' />
- <param name='peer' doc='Show global and network peer related groups' />
- <param name='subscriber' doc='Show global, peer, and subscriber groups' />
- </params>
- </command>
- <command id='show asciidoc counters'>
- <params>
- <param name='show' doc='Show running system information' />
- <param name='asciidoc' doc='Asciidoc generation' />
- <param name='counters' doc='Generate table of all registered counters' />
- </params>
- </command>
- <command id='show rate-counters'>
- <params>
- <param name='show' doc='Show running system information' />
- <param name='rate-counters' doc='Show all rate counters' />
- </params>
- </command>
- <command id='show 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 sgs-connections'>
- <params>
- <param name='show' doc='Show running system information' />
- <param name='sgs-connections' doc='Show SGs interface connections / MMEs' />
- </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 &apos;msisdn&apos;' />
- <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 bsc'>
- <params>
- <param name='show' doc='Show running system information' />
- <param name='bsc' doc='BSC' />
- </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 &apos;msisdn&apos;' />
- <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 &apos;msisdn&apos;' />
- <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 &apos;msisdn&apos;' />
- <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 &apos;msisdn&apos;' />
- <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/h|tch/any|sdcch) (signalling|speech-hr|speech-fr|speech-efr|speech-amr) [IP] [&lt;0-65535&gt;]'>
- <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 &apos;msisdn&apos;' />
- <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/h' doc='TCH/H channel' />
- <param name='tch/any' doc='Any TCH channel' />
- <param name='sdcch' doc='SDCCH channel' />
- <param name='signalling' doc='Signalling only' />
- <param name='speech-hr' doc='Speech with HR codec' />
- <param name='speech-fr' doc='Speech with FR codec' />
- <param name='speech-efr' doc='Speech with EFR codec' />
- <param name='speech-amr' doc='Speech with AMR codec' />
- <param name='[IP]' doc='Target IP for RTP traffic (default 127.0.0.1)' />
- <param name='[&lt;0-65535&gt;]' doc='Target port for RTP traffic (default: 4000)' />
- </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 &apos;msisdn&apos;' />
- <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 &apos;msisdn&apos;' />
- <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 &apos;msisdn&apos;' />
- <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 &apos;msisdn&apos;' />
- <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 &apos;msisdn&apos;' />
- <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 &apos;msisdn&apos;' />
- <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 &lt;1-500&gt;'>
- <params>
- <param name='sms-queue' doc='SMS Queue' />
- <param name='max-pending' doc='SMS to deliver in parallel' />
- <param name='&lt;1-500&gt;' 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 &lt;1-500&gt;'>
- <params>
- <param name='sms-queue' doc='SMS Queue' />
- <param name='max-failure' doc='Maximum amount of delivery failures' />
- <param name='&lt;1-500&gt;' 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 &apos;msisdn&apos;' />
- <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='subscriber (msisdn|extension|imsi|tmsi|id) ID sms delete-all'>
- <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 &apos;msisdn&apos;' />
- <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='delete-all' doc='Delete all SMS to be delivered to this subscriber -- WARNING: the SMS data for all unsent SMS for this subscriber WILL BE LOST.' />
- </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 External SMS Entity' />
- </params>
- </command>
- </node>
- <node id='config'>
- <name>config</name>
- <command id='hostname WORD'>
- <params>
- <param name='hostname' doc='Set system&apos;s network name' />
- <param name='WORD' doc='This system&apos;s network name' />
- </params>
- </command>
- <command id='no hostname [HOSTNAME]'>
- <params>
- <param name='no' doc='Negate a command or set its defaults' />
- <param name='hostname' doc='Reset system&apos;s network name' />
- <param name='[HOSTNAME]' doc='Host name of this router' />
- </params>
- </command>
- <command id='password (8|) WORD'>
- <params>
- <param name='password' doc='Assign the terminal connection password' />
- <param name='8' doc='Specifies a HIDDEN password will follow' />
- <param name='' doc='dummy string ' />
- <param name='WORD' doc='The HIDDEN line password string' />
- </params>
- </command>
- <command id='password LINE'>
- <params>
- <param name='password' doc='Assign the terminal connection password' />
- <param name='LINE' doc='The UNENCRYPTED (cleartext) line password' />
- </params>
- </command>
- <command id='enable password (8|) WORD'>
- <params>
- <param name='enable' doc='Modify enable password parameters' />
- <param name='password' doc='Assign the privileged level password' />
- <param name='8' doc='Specifies a HIDDEN password will follow' />
- <param name='' doc='dummy string ' />
- <param name='WORD' doc='The HIDDEN &apos;enable&apos; password string' />
- </params>
- </command>
- <command id='enable password LINE'>
- <params>
- <param name='enable' doc='Modify enable password parameters' />
- <param name='password' doc='Assign the privileged level password' />
- <param name='LINE' doc='The UNENCRYPTED (cleartext) &apos;enable&apos; password' />
- </params>
- </command>
- <command id='no enable password'>
- <params>
- <param name='no' doc='Negate a command or set its defaults' />
- <param name='enable' doc='Modify enable password parameters' />
- <param name='password' doc='Assign the privileged level password' />
- </params>
- </command>
- <command id='banner motd default'>
- <params>
- <param name='banner' doc='Set banner string' />
- <param name='motd' doc='Strings for motd' />
- <param name='default' doc='Default string' />
- </params>
- </command>
- <command id='banner motd file [FILE]'>
- <params>
- <param name='banner' doc='Set banner' />
- <param name='motd' doc='Banner for motd' />
- <param name='file' doc='Banner from a file' />
- <param name='[FILE]' doc='Filename' />
- </params>
- </command>
- <command id='no banner motd'>
- <params>
- <param name='no' doc='Negate a command or set its defaults' />
- <param name='banner' doc='Set banner string' />
- <param name='motd' doc='Strings for motd' />
- </params>
- </command>
- <command id='service terminal-length &lt;0-512&gt;'>
- <params>
- <param name='service' doc='Set up miscellaneous service' />
- <param name='terminal-length' doc='System wide terminal length configuration' />
- <param name='&lt;0-512&gt;' doc='Number of lines of VTY (0 means no line control)' />
- </params>
- </command>
- <command id='no service terminal-length [&lt;0-512&gt;]'>
- <params>
- <param name='no' doc='Negate a command or set its defaults' />
- <param name='service' doc='Set up miscellaneous service' />
- <param name='terminal-length' doc='System wide terminal length configuration' />
- <param name='[&lt;0-512&gt;]' doc='Number of lines of VTY (0 means no line control)' />
- </params>
- </command>
- <command id='line vty'>
- <params>
- <param name='line' doc='Configure a terminal line' />
- <param name='vty' doc='Virtual terminal' />
- </params>
- </command>
- <command id='service advanced-vty'>
- <params>
- <param name='service' doc='Set up miscellaneous service' />
- <param name='advanced-vty' doc='Enable advanced mode vty interface' />
- </params>
- </command>
- <command id='no service advanced-vty'>
- <params>
- <param name='no' doc='Negate a command or set its defaults' />
- <param name='service' doc='Set up miscellaneous service' />
- <param name='advanced-vty' doc='Enable advanced mode vty interface' />
- </params>
- </command>
- <command id='show history'>
- <params>
- <param name='show' doc='Show running system information' />
- <param name='history' doc='Display the session command history' />
- </params>
- </command>
- <command id='cs7 instance &lt;0-15&gt;'>
- <params>
- <param name='cs7' doc='ITU-T Signaling System 7' />
- <param name='instance' doc='Configure a SS7 Instance' />
- <param name='&lt;0-15&gt;' doc='An instance of the SS7 stack' />
- </params>
- </command>
- <command id='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 &lt;2-32700&gt;'>
- <params>
- <param name='log' doc='Configure logging sub-system' />
- <param name='alarms' doc='Logging alarms to osmo_strrb' />
- <param name='&lt;2-32700&gt;' doc='Maximum number of messages to log' />
- </params>
- </command>
- <command id='no log alarms'>
- <params>
- <param name='no' doc='Negate a command or set its defaults' />
- <param name='log' doc='Configure logging sub-system' />
- <param name='alarms' doc='Logging alarms to osmo_strrb' />
- </params>
- </command>
- <command id='log syslog (authpriv|cron|daemon|ftp|lpr|mail|news|user|uucp)'>
- <params>
- <param name='log' doc='Configure logging sub-system' />
- <param name='syslog' doc='Logging via syslog' />
- <param name='authpriv' doc='Security/authorization messages facility' />
- <param name='cron' doc='Clock daemon (cron/at) facility' />
- <param name='daemon' doc='General system daemon facility' />
- <param name='ftp' doc='Ftp daemon facility' />
- <param name='lpr' doc='Line printer facility' />
- <param name='mail' doc='Mail facility' />
- <param name='news' doc='News facility' />
- <param name='user' doc='Generic facility' />
- <param name='uucp' doc='UUCP facility' />
- </params>
- </command>
- <command id='log syslog local &lt;0-7&gt;'>
- <params>
- <param name='log' doc='Configure logging sub-system' />
- <param name='syslog' doc='Logging via syslog' />
- <param name='local' doc='Syslog LOCAL facility' />
- <param name='&lt;0-7&gt;' doc='Local facility number' />
- </params>
- </command>
- <command id='no log syslog'>
- <params>
- <param name='no' doc='Negate a command or set its defaults' />
- <param name='log' doc='Configure logging sub-system' />
- <param name='syslog' doc='Logging via syslog' />
- </params>
- </command>
- <command id='log gsmtap [HOSTNAME]'>
- <params>
- <param name='log' doc='Configure logging sub-system' />
- <param name='gsmtap' doc='Logging via GSMTAP' />
- <param name='[HOSTNAME]' doc='Host name to send the GSMTAP logging to (UDP port 4729)' />
- </params>
- </command>
- <command id='stats reporter statsd'>
- <params>
- <param name='stats' doc='Configure stats sub-system' />
- <param name='reporter' doc='Configure a stats reporter' />
- <param name='statsd' doc='Report to a STATSD server' />
- </params>
- </command>
- <command id='no stats reporter statsd'>
- <params>
- <param name='no' doc='Negate a command or set its defaults' />
- <param name='stats' doc='Configure stats sub-system' />
- <param name='reporter' doc='Configure a stats reporter' />
- <param name='statsd' doc='Report to a STATSD server' />
- </params>
- </command>
- <command id='stats reporter log'>
- <params>
- <param name='stats' doc='Configure stats sub-system' />
- <param name='reporter' doc='Configure a stats reporter' />
- <param name='log' doc='Report to the logger' />
- </params>
- </command>
- <command id='no stats reporter log'>
- <params>
- <param name='no' doc='Negate a command or set its defaults' />
- <param name='stats' doc='Configure stats sub-system' />
- <param name='reporter' doc='Configure a stats reporter' />
- <param name='log' doc='Report to the logger' />
- </params>
- </command>
- <command id='stats interval &lt;1-65535&gt;'>
- <params>
- <param name='stats' doc='Configure stats sub-system' />
- <param name='interval' doc='Set the reporting interval' />
- <param name='&lt;1-65535&gt;' doc='Interval in seconds' />
- </params>
- </command>
- <command id='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='sgs'>
- <params>
- <param name='sgs' doc='Configure the SGs interface' />
- </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&apos;t use color for printing messages' />
- <param name='1' doc='Use color for printing messages' />
- </params>
- </command>
- <command id='logging timestamp (0|1)'>
- <params>
- <param name='logging' doc='Configure logging' />
- <param name='timestamp' doc='Configure log message timestamping' />
- <param name='0' doc='Don&apos;t prefix each log message' />
- <param name='1' doc='Prefix each log message with current timestamp' />
- </params>
- </command>
- <command id='logging print extended-timestamp (0|1)'>
- <params>
- <param name='logging' doc='Configure logging' />
- <param name='print' doc='Log output settings' />
- <param name='extended-timestamp' doc='Configure log message timestamping' />
- <param name='0' doc='Don&apos;t prefix each log message' />
- <param name='1' doc='Prefix each log message with current timestamp with YYYYMMDDhhmmssnnn' />
- </params>
- </command>
- <command id='logging print category (0|1)'>
- <params>
- <param name='logging' doc='Configure logging' />
- <param name='print' doc='Log output settings' />
- <param name='category' doc='Configure log message' />
- <param name='0' doc='Don&apos;t prefix each log message' />
- <param name='1' doc='Prefix each log message with category/subsystem name' />
- </params>
- </command>
- <command id='logging print category-hex (0|1)'>
- <params>
- <param name='logging' doc='Configure logging' />
- <param name='print' doc='Log output settings' />
- <param name='category-hex' doc='Configure log message' />
- <param name='0' doc='Don&apos;t prefix each log message' />
- <param name='1' doc='Prefix each log message with category/subsystem nr in hex (&apos;&lt;000b&gt;&apos;)' />
- </params>
- </command>
- <command id='logging print level (0|1)'>
- <params>
- <param name='logging' doc='Configure logging' />
- <param name='print' doc='Log output settings' />
- <param name='level' doc='Configure log message' />
- <param name='0' doc='Don&apos;t prefix each log message' />
- <param name='1' doc='Prefix each log message with the log level name' />
- </params>
- </command>
- <command id='logging print file (0|1|basename) [last]'>
- <params>
- <param name='logging' doc='Configure logging' />
- <param name='print' doc='Log output settings' />
- <param name='file' doc='Configure log message' />
- <param name='0' doc='Don&apos;t prefix each log message' />
- <param name='1' doc='Prefix each log message with the source file and line' />
- <param name='basename' doc='Prefix each log message with the source file&apos;s basename (strip leading paths) and line' />
- <param name='[last]' doc='Log source file info at the end of a log line. If omitted, log source file info just before the log text.' />
- </params>
- </command>
- <command id='logging level (rll|cc|mm|rr|mncc|pag|msc|mgcp|ho|db|ref|ctrl|smpp|ranap|vlr|iucs|bssap|sgs|lglobal|llapd|linp|lmux|lmi|lmib|lsms|lctrl|lgtp|lstats|lgsup|loap|lss7|lsccp|lsua|lm3ua|lmgcp|ljibuf|lrspro) (debug|info|notice|error|fatal)'>
- <params>
- <param name='logging' doc='Configure logging' />
- <param name='level' doc='Set the log level for a specified category' />
- <param name='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='sgs' doc='SGs Interface (SGsAP)' />
- <param name='lglobal' doc='Library-internal global log family' />
- <param name='llapd' doc='LAPD in libosmogsm' />
- <param name='linp' doc='A-bis Intput Subsystem' />
- <param name='lmux' doc='A-bis B-Subchannel TRAU Frame Multiplex' />
- <param name='lmi' doc='A-bis Input Driver for Signalling' />
- <param name='lmib' doc='A-bis Input Driver for B-Channels (voice)' />
- <param name='lsms' doc='Layer3 Short Message Service (SMS)' />
- <param name='lctrl' doc='Control Interface' />
- <param name='lgtp' doc='GPRS GTP library' />
- <param name='lstats' doc='Statistics messages and logging' />
- <param name='lgsup' doc='Generic Subscriber Update Protocol' />
- <param name='loap' doc='Osmocom Authentication Protocol' />
- <param name='lss7' doc='libosmo-sigtran Signalling System 7' />
- <param name='lsccp' doc='libosmo-sigtran SCCP Implementation' />
- <param name='lsua' doc='libosmo-sigtran SCCP User Adaptation' />
- <param name='lm3ua' doc='libosmo-sigtran MTP3 User Adaptation' />
- <param name='lmgcp' doc='libosmo-mgcp Media Gateway Control Protocol' />
- <param name='ljibuf' doc='libosmo-netif Jitter Buffer' />
- <param name='lrspro' doc='Remote SIM protocol' />
- <param name='debug' doc='Log debug messages and higher levels' />
- <param name='info' doc='Log informational messages and higher levels' />
- <param name='notice' doc='Log noticeable messages and higher levels' />
- <param name='error' doc='Log error messages and higher levels' />
- <param name='fatal' doc='Log only fatal messages' />
- </params>
- </command>
- <command id='logging level set-all (debug|info|notice|error|fatal)'>
- <params>
- <param name='logging' doc='Configure logging' />
- <param name='level' doc='Set the log level for a specified category' />
- <param name='set-all' doc='Once-off set all categories to the given log level. There is no single command to take back these changes -- each category is set to the given level, period.' />
- <param name='debug' doc='Log debug messages and higher levels' />
- <param name='info' doc='Log informational messages and higher levels' />
- <param name='notice' doc='Log noticeable messages and higher levels' />
- <param name='error' doc='Log error messages and higher levels' />
- <param name='fatal' doc='Log only fatal messages' />
- </params>
- </command>
- <command id='logging level force-all (debug|info|notice|error|fatal)'>
- <params>
- <param name='logging' doc='Configure logging' />
- <param name='level' doc='Set the log level for a specified category' />
- <param name='force-all' doc='Globally force all logging categories to a specific level. This is released by the &apos;no logging level force-all&apos; command. Note: any &apos;logging level &lt;category&gt; &lt;level&gt;&apos; commands will have no visible effect after this, until the forced level is released.' />
- <param name='debug' doc='Log debug messages and higher levels' />
- <param name='info' doc='Log informational messages and higher levels' />
- <param name='notice' doc='Log noticeable messages and higher levels' />
- <param name='error' doc='Log error messages and higher levels' />
- <param name='fatal' doc='Log only fatal messages' />
- </params>
- </command>
- <command id='no logging level force-all'>
- <params>
- <param name='no' doc='Negate a command or set its defaults' />
- <param name='logging' doc='Configure logging' />
- <param name='level' doc='Set the log level for a specified category' />
- <param name='force-all' doc='Release any globally forced log level set with &apos;logging level force-all &lt;level&gt;&apos;' />
- </params>
- </command>
- <command id='logging filter 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 &lt;1-65535&gt;'>
- <params>
- <param name='remote-port' doc='Set the remote port to which we connect' />
- <param name='&lt;1-65535&gt;' doc='Remote port number' />
- </params>
- </command>
- <command id='mtu &lt;100-65535&gt;'>
- <params>
- <param name='mtu' doc='Set the maximum packet size' />
- <param name='&lt;100-65535&gt;' doc='Size in byte' />
- </params>
- </command>
- <command id='no mtu'>
- <params>
- <param name='no' doc='Negate a command or set its defaults' />
- <param name='mtu' doc='Set the maximum packet size' />
- </params>
- </command>
- <command id='prefix PREFIX'>
- <params>
- <param name='prefix' doc='Set the item name prefix' />
- <param name='PREFIX' doc='The prefix string' />
- </params>
- </command>
- <command id='no prefix'>
- <params>
- <param name='no' doc='Negate a command or set its defaults' />
- <param name='prefix' doc='Set the item name prefix' />
- </params>
- </command>
- <command id='level (global|peer|subscriber)'>
- <params>
- <param name='level' doc='Set the maximum group level' />
- <param name='global' doc='Report global groups only' />
- <param name='peer' doc='Report global and network peer related groups' />
- <param name='subscriber' doc='Report global, peer, and subscriber groups' />
- </params>
- </command>
- <command id='enable'>
- <params>
- <param name='enable' doc='Enable the reporter' />
- </params>
- </command>
- <command id='disable'>
- <params>
- <param name='disable' doc='Disable the reporter' />
- </params>
- </command>
- </node>
- <node id='config-line'>
- <name>config-line</name>
- <command id='login'>
- <params>
- <param name='login' doc='Enable password checking' />
- </params>
- </command>
- <command id='no login'>
- <params>
- <param name='no' doc='Negate a command or set its defaults' />
- <param name='login' doc='Enable password checking' />
- </params>
- </command>
- <command id='bind A.B.C.D [&lt;0-65535&gt;]'>
- <params>
- <param name='bind' doc='Accept VTY telnet connections on local interface' />
- <param name='A.B.C.D' doc='Local interface IP address (default: 127.0.0.1)' />
- <param name='[&lt;0-65535&gt;]' doc='Local TCP port number' />
- </params>
- </command>
- </node>
- <node id='config-ctrl'>
- <name>config-ctrl</name>
- <command id='bind A.B.C.D'>
- <params>
- <param name='bind' doc='Set bind address to listen for Control connections' />
- <param name='A.B.C.D' doc='Local IP address (default 127.0.0.1)' />
- </params>
- </command>
- </node>
- <node id='config-cs7'>
- <name>config-cs7</name>
- <command id='description .TEXT'>
- <params>
- <param name='description' doc='Save human-readable description of the object' />
- <param name='.TEXT' doc='Text until the end of the line' />
- </params>
- </command>
- <command id='network-indicator (international | national | reserved | spare)'>
- <params>
- <param name='network-indicator' doc='Configure the Network Indicator' />
- <param name='international' doc='International Network' />
- <param name='national' doc='National Network' />
- <param name='reserved' doc='Reserved Network' />
- <param name='spare' doc='Spare Network' />
- </params>
- </command>
- <command id='point-code POINT_CODE'>
- <params>
- <param name='point-code' doc='Configure the local Point Code' />
- <param name='POINT_CODE' doc='Point Code' />
- </params>
- </command>
- <command id='point-code format &lt;1-24&gt; [&lt;1-23&gt;] [&lt;1-22&gt;]'>
- <params>
- <param name='point-code' doc='Point Code' />
- <param name='format' doc='Configure Point Code Format' />
- <param name='&lt;1-24&gt;' doc='Length of first PC component' />
- <param name='[&lt;1-23&gt;]' doc='Length of second PC component' />
- <param name='[&lt;1-22&gt;]' doc='Length of third PC component' />
- </params>
- </command>
- <command id='point-code format default'>
- <params>
- <param name='point-code' doc='Point Code' />
- <param name='format' doc='Configure Point Code Format' />
- <param name='default' doc='Default Point Code Format (3.8.3)' />
- </params>
- </command>
- <command id='point-code delimiter (default|dash)'>
- <params>
- <param name='point-code' doc='Point Code' />
- <param name='delimiter' doc='Configure Point Code Delimiter' />
- <param name='default' doc='Use dot as delimiter' />
- <param name='dash' doc='User dash as delimiter' />
- </params>
- </command>
- <command id='xua rkm routing-key-allocation (static-only|dynamic-permitted)'>
- <params>
- <param name='xua' doc='SIGTRAN xxxUA related' />
- <param name='rkm' doc='Routing Key Management' />
- <param name='routing-key-allocation' doc='Routing Key Management Allocation Policy' />
- <param name='static-only' doc='Only static (pre-confgured) Routing Keys permitted' />
- <param name='dynamic-permitted' doc='Dynamically allocate Routing Keys for what ASPs request' />
- </params>
- </command>
- <command id='asp NAME &lt;0-65535&gt; &lt;0-65535&gt; (sua|m3ua|ipa)'>
- <params>
- <param name='asp' doc='Configure Application Server Process' />
- <param name='NAME' doc='Name of ASP' />
- <param name='&lt;0-65535&gt;' doc='Remote SCTP port number' />
- <param name='&lt;0-65535&gt;' doc='Local SCTP port number' />
- <param name='sua' doc='SCCP User Adaptation' />
- <param name='m3ua' doc='MTP3 User Adaptation' />
- <param name='ipa' doc='IPA Multiplex (SCCP Lite)' />
- </params>
- </command>
- <command id='no asp NAME'>
- <params>
- <param name='no' doc='Negate a command or set its defaults' />
- <param name='asp' doc='Disable Application Server Process' />
- <param name='NAME' doc='Name of ASP' />
- </params>
- </command>
- <command id='as NAME (sua|m3ua|ipa)'>
- <params>
- <param name='as' doc='Configure an Application Server' />
- <param name='NAME' doc='Name of the Application Server' />
- <param name='sua' doc='SCCP User Adaptation' />
- <param name='m3ua' doc='MTP3 User Adaptation' />
- <param name='ipa' doc='IPA Multiplex (SCCP Lite)' />
- </params>
- </command>
- <command id='no as NAME'>
- <params>
- <param name='no' doc='Negate a command or set its defaults' />
- <param name='as' doc='Disable Application Server' />
- <param name='NAME' doc='Name of AS' />
- </params>
- </command>
- <command id='sccp-address NAME'>
- <params>
- <param name='sccp-address' doc='Create/Modify an SCCP addressbook entry' />
- <param name='NAME' doc='Name of the SCCP Address' />
- </params>
- </command>
- <command id='no sccp-address NAME'>
- <params>
- <param name='no' doc='Negate a command or set its defaults' />
- <param name='sccp-address' doc='Delete an SCCP addressbook entry' />
- <param name='NAME' doc='Name of the SCCP Address' />
- </params>
- </command>
- <command id='sccp-timer (conn_est|ias|iar|rel|repeat_rel|int|guard|reset|reassembly) &lt;1-999999&gt;'>
- <params>
- <param name='sccp-timer' doc='Configure SCCP timer values, see ITU-T Q.714' />
- <param name='conn_est' doc='Waiting for connection confirm message, 1 to 2 minutes (default: 60)' />
- <param name='ias' doc='Send keep-alive: on an idle connection, delay before sending an Idle Timer message, 5 to 10 minutes (default: 420)' />
- <param name='iar' doc='Receive keep-alive: on an idle connection, delay until considering a connection as stale, 11 to 21 minutes (default: 900)' />
- <param name='rel' doc='Waiting for release complete message, 10 to 20 seconds (default: 10)' />
- <param name='repeat_rel' doc='Waiting for release complete message; or to repeat sending released message after the initial expiry, 10 to 20 seconds (default: 10)' />
- <param name='int' doc='Waiting for release complete message; or to release connection resources, freeze the LRN and alert a maintenance function after the initial expiry, extending to 1 minute (default: 60)' />
- <param name='guard' doc='Waiting to resume normal procedure for temporary connection sections during the restart procedure, 23 to 25 minutes (default: 1380)' />
- <param name='reset' doc='Waiting to release temporary connection section or alert maintenance function after reset request message is sent, 10 to 20 seconds (default: 10)' />
- <param name='reassembly' doc='Waiting to receive all the segments of the remaining segments, single segmented message after receiving the first segment, 10 to 20 seconds (default: 10)' />
- <param name='&lt;1-999999&gt;' doc='Timer value, in seconds' />
- </params>
- </command>
- </node>
- <node id='config-cs7-as'>
- <name>config-cs7-as</name>
- <command id='description .TEXT'>
- <params>
- <param name='description' doc='Save human-readable description of the object' />
- <param name='.TEXT' doc='Text until the end of the line' />
- </params>
- </command>
- <command id='asp NAME'>
- <params>
- <param name='asp' doc='Specify that a given ASP is part of this AS' />
- <param name='NAME' doc='Name of ASP to be added to AS' />
- </params>
- </command>
- <command id='no asp NAME'>
- <params>
- <param name='no' doc='Negate a command or set its defaults' />
- <param name='asp' doc='Specify ASP to be removed from this AS' />
- <param name='NAME' doc='Name of ASP to be removed' />
- </params>
- </command>
- <command id='traffic-mode (broadcast | loadshare | roundrobin | override)'>
- <params>
- <param name='traffic-mode' doc='Specifies traffic mode of operation of the ASP within the AS' />
- <param name='broadcast' doc='Broadcast to all ASP within AS' />
- <param name='loadshare' doc='Share Load among all ASP within AS' />
- <param name='roundrobin' doc='Round-Robin between all ASP within AS' />
- <param name='override' doc='Override' />
- </params>
- </command>
- <command id='recovery-timeout &lt;1-2000&gt;'>
- <params>
- <param name='recovery-timeout' doc='Specifies the recovery timeout value in milliseconds' />
- <param name='&lt;1-2000&gt;' doc='Recovery Timeout in Milliseconds' />
- </params>
- </command>
- <command id='qos-class &lt;0-255&gt;'>
- <params>
- <param name='qos-class' doc='Specity QoS Class of AS' />
- <param name='&lt;0-255&gt;' doc='QoS Class of AS' />
- </params>
- </command>
- <command id='routing-key RCONTEXT DPC'>
- <params>
- <param name='routing-key' doc='Define a routing key' />
- <param name='RCONTEXT' doc='Routing context number' />
- <param name='DPC' doc='Destination Point Code' />
- </params>
- </command>
- <command id='routing-key RCONTEXT DPC si (aal2|bicc|b-isup|h248|isup|sat-isup|sccp|tup)'>
- <params>
- <param name='routing-key' doc='Define a routing key' />
- <param name='RCONTEXT' doc='Routing context number' />
- <param name='DPC' doc='Destination Point Code' />
- <param name='si' doc='Match on Service Indicator' />
- <param name='aal2' doc='ATM Adaption Layer 2' />
- <param name='bicc' doc='Bearer Independent Call Control' />
- <param name='b-isup' doc='Broadband ISDN User Part' />
- <param name='h248' doc='H.248' />
- <param name='isup' doc='ISDN User Part' />
- <param name='sat-isup' doc='Sattelite ISDN User Part' />
- <param name='sccp' doc='Signalling Connection Control Part' />
- <param name='tup' doc='Telephony User Part' />
- </params>
- </command>
- <command id='routing-key RCONTEXT DPC ssn SSN'>
- <params>
- <param name='routing-key' doc='Define a routing key' />
- <param name='RCONTEXT' doc='Routing context number' />
- <param name='DPC' doc='Destination Point Code' />
- <param name='ssn' doc='Match on Sub-System Number' />
- <param name='SSN' doc='Sub-System Number to match on' />
- </params>
- </command>
- <command id='routing-key RCONTEXT DPC si (aal2|bicc|b-isup|h248|isup|sat-isup|sccp|tup) ssn SSN'>
- <params>
- <param name='routing-key' doc='Define a routing key' />
- <param name='RCONTEXT' doc='Routing context number' />
- <param name='DPC' doc='Destination Point Code' />
- <param name='si' doc='Match on Service Indicator' />
- <param name='aal2' doc='ATM Adaption Layer 2' />
- <param name='bicc' doc='Bearer Independent Call Control' />
- <param name='b-isup' doc='Broadband ISDN User Part' />
- <param name='h248' doc='H.248' />
- <param name='isup' doc='ISDN User Part' />
- <param name='sat-isup' doc='Sattelite ISDN User Part' />
- <param name='sccp' doc='Signalling Connection Control Part' />
- <param name='tup' doc='Telephony User Part' />
- <param name='ssn' doc='Match on Sub-System Number' />
- <param name='SSN' doc='Sub-System Number to match on' />
- </params>
- </command>
- <command id='point-code override dpc PC'>
- <params>
- <param name='point-code' doc='Point Code Specific Features' />
- <param name='override' doc='Override (force) a point-code to hard-coded value' />
- <param name='dpc' doc='Override Source Point Code' />
- <param name='PC' doc='Override Destination Point Code' />
- </params>
- </command>
- </node>
- <node id='config-cs7-asp'>
- <name>config-cs7-asp</name>
- <command id='description .TEXT'>
- <params>
- <param name='description' doc='Save human-readable description of the object' />
- <param name='.TEXT' doc='Text until the end of the line' />
- </params>
- </command>
- <command id='remote-ip A.B.C.D'>
- <params>
- <param name='remote-ip' doc='Specify Remote IP Address of ASP' />
- <param name='A.B.C.D' doc='Remote IP Address of ASP' />
- </params>
- </command>
- <command id='local-ip A.B.C.D'>
- <params>
- <param name='local-ip' doc='Specify Local IP Address from which to contact ASP' />
- <param name='A.B.C.D' doc='Local IP Address from which to contact of ASP' />
- </params>
- </command>
- <command id='qos-class &lt;0-255&gt;'>
- <params>
- <param name='qos-class' doc='Specify QoS Class of ASP' />
- <param name='&lt;0-255&gt;' doc='QoS Class of ASP' />
- </params>
- </command>
- <command id='block'>
- <params>
- <param name='block' doc='Allows a SCTP Association with ASP, but doesn&apos;t let it become active' />
- </params>
- </command>
- <command id='shutdown'>
- <params>
- <param name='shutdown' doc='Terminates SCTP association; New associations will be rejected' />
- </params>
- </command>
- </node>
- <node id='config-cs7-sccpaddr'>
- <name>config-cs7-sccpaddr</name>
- <command id='no point-code'>
- <params>
- <param name='no' doc='Negate a command or set its defaults' />
- <param name='point-code' doc='Remove point-code Number' />
- </params>
- </command>
- <command id='no subsystem-number'>
- <params>
- <param name='no' doc='Negate a command or set its defaults' />
- <param name='subsystem-number' doc='Remove Subsystem Number' />
- </params>
- </command>
- <command id='no global-title'>
- <params>
- <param name='no' doc='Negate a command or set its defaults' />
- <param name='global-title' doc='Remove Global Title' />
- </params>
- </command>
- <command id='routing-indicator (GT|PC|IP)'>
- <params>
- <param name='routing-indicator' doc='Add Routing Indicator' />
- <param name='GT' doc='by global-title' />
- <param name='PC' doc='by point-code' />
- <param name='IP' doc='by ip-address' />
- </params>
- </command>
- <command id='point-code POINT_CODE'>
- <params>
- <param name='point-code' doc='Add point-code Number' />
- <param name='POINT_CODE' doc='PC' />
- </params>
- </command>
- <command id='subsystem-number &lt;0-4294967295&gt;'>
- <params>
- <param name='subsystem-number' doc='Add Subsystem Number' />
- <param name='&lt;0-4294967295&gt;' doc='SSN' />
- </params>
- </command>
- <command id='global-title'>
- <params>
- <param name='global-title' doc='Add/Modify Global Title' />
- </params>
- </command>
- </node>
- <node id='config-cs7-sccpaddr-gt'>
- <name>config-cs7-sccpaddr-gt</name>
- <command id='global-title-indicator &lt;0-15&gt;'>
- <params>
- <param name='global-title-indicator' doc='Set Global Title Indicator' />
- <param name='&lt;0-15&gt;' doc='GTI' />
- </params>
- </command>
- <command id='translation-type &lt;0-255&gt;'>
- <params>
- <param name='translation-type' doc='Set Global Title Translation Type' />
- <param name='&lt;0-255&gt;' doc='TT' />
- </params>
- </command>
- <command id='numbering-plan-indicator &lt;0-15&gt;'>
- <params>
- <param name='numbering-plan-indicator' doc='Set Global Title Numbering Plan Indicator' />
- <param name='&lt;0-15&gt;' doc='NPI' />
- </params>
- </command>
- <command id='nature-of-address-indicator &lt;0-127&gt;'>
- <params>
- <param name='nature-of-address-indicator' doc='Set Global Title Nature of Address Indicator' />
- <param name='&lt;0-127&gt;' doc='NAI' />
- </params>
- </command>
- <command id='digits DIGITS'>
- <params>
- <param name='digits' doc='Set Global Title Digits' />
- <param name='DIGITS' doc='Number digits' />
- </params>
- </command>
- </node>
- <node id='config-net'>
- <name>config-net</name>
- <command id='network country code &lt;1-999&gt;'>
- <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='&lt;1-999&gt;' doc='Network Country Code to use' />
- </params>
- </command>
- <command id='mobile network code &lt;0-999&gt;'>
- <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='&lt;0-999&gt;' 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 &lt;0-3&gt; [&lt;0-3&gt;] [&lt;0-3&gt;] [&lt;0-3&gt;]'>
- <params>
- <param name='encryption' doc='Encryption options' />
- <param name='a5' doc='GSM A5 Air Interface Encryption' />
- <param name='&lt;0-3&gt;' doc='A5/n Algorithm Number' />
- <param name='[&lt;0-3&gt;]' doc='A5/n Algorithm Number' />
- <param name='[&lt;0-3&gt;]' doc='A5/n Algorithm Number' />
- <param name='[&lt;0-3&gt;]' 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&apos;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 &lt;-19-19&gt; (0|15|30|45)'>
- <params>
- <param name='timezone' doc='Set the Timezone Offset of the network' />
- <param name='&lt;-19-19&gt;' 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 &lt;-19-19&gt; (0|15|30|45) &lt;0-2&gt;'>
- <params>
- <param name='timezone' doc='Set the Timezone Offset of the network' />
- <param name='&lt;-19-19&gt;' 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='&lt;0-2&gt;' 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 &lt;6-1530&gt;'>
- <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='&lt;6-1530&gt;' 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 internal'>
- <params>
- <param name='mncc' doc='Configure Mobile Network Call Control' />
- <param name='internal' doc='Use internal MNCC handler (default; changes need a program restart)' />
- </params>
- </command>
- <command id='mncc external MNCC_SOCKET_PATH'>
- <params>
- <param name='mncc' doc='Configure Mobile Network Call Control' />
- <param name='external' doc='Use external MNCC handler (changes need a program restart)' />
- <param name='MNCC_SOCKET_PATH' doc='File system path to create the MNCC unix domain socket at' />
- </params>
- </command>
- <command id='mncc guard-timeout &lt;0-255&gt;'>
- <params>
- <param name='mncc' doc='Configure Mobile Network Call Control' />
- <param name='guard-timeout' doc='Set global guard timer for mncc interface activity' />
- <param name='&lt;0-255&gt;' doc='guard timer value (sec.)' />
- </params>
- </command>
- <command id='ncss guard-timeout &lt;0-255&gt;'>
- <params>
- <param name='ncss' doc='Configure call independent Supplementary Services' />
- <param name='guard-timeout' doc='Set guard timer for session activity' />
- <param name='&lt;0-255&gt;' doc='guard timer value (sec.), or 0 to disable' />
- </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 &lt;-1-2147483647&gt;'>
- <params>
- <param name='auth-tuple-max-reuse-count' doc='Configure authentication tuple re-use' />
- <param name='&lt;-1-2147483647&gt;' doc='0 to use each auth tuple at most once (default), &gt;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='Never re-use auth tuples beyond auth-tuple-max-reuse-count (default)' />
- <param name='1' doc='If the HLR does not deliver new tuples, do re-use already available old ones.' />
- </params>
- </command>
- <command id='check-imei-rqd (0|1)'>
- <params>
- <param name='check-imei-rqd' doc='Send each IMEI to the EIR to ask if it is permitted or not. The EIR is implemented as part of OsmoHLR, and can optionally save the IMEI in the HLR.' />
- <param name='0' doc='Do not send IMEIs to the EIR' />
- <param name='1' doc='Send each IMEI to the EIR' />
- </params>
- </command>
- <command id='cs7-instance-a &lt;0-15&gt;'>
- <params>
- <param name='cs7-instance-a' doc='Set SS7 to be used by the A-Interface.' />
- <param name='&lt;0-15&gt;' doc='SS7 instance reference number' />
- </params>
- </command>
- <command id='cs7-instance-iu &lt;0-15&gt;'>
- <params>
- <param name='cs7-instance-iu' doc='Set SS7 to be used by the Iu-Interface.' />
- <param name='&lt;0-15&gt;' doc='SS7 instance reference number' />
- </params>
- </command>
- <command id='paging response-timer (default|&lt;1-65535&gt;)'>
- <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='&lt;1-65535&gt;' 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='sms-over-gsup'>
- <params>
- <param name='sms-over-gsup' doc='Enable routing of SMS messages over GSUP' />
- </params>
- </command>
- <command id='no sms-over-gsup'>
- <params>
- <param name='no' doc='Negate a command or set its defaults' />
- <param name='sms-over-gsup' doc='Disable routing of SMS messages over GSUP' />
- </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 &lt;0-65535&gt;'>
- <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='&lt;0-65535&gt;' 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 &lt;0-65535&gt;'>
- <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='&lt;0-65535&gt;' doc='remote port' />
- </params>
- </command>
- <command id='mgw endpoint-domain NAME'>
- <params>
- <param name='mgw' doc='Configure MGCP connection to Media Gateway' />
- <param name='endpoint-domain' doc='Set the domain name to send in MGCP messages, e.g. the part &apos;foo&apos; in &apos;rtpbridge/*@foo&apos;.' />
- <param name='NAME' doc='Domain name, should be alphanumeric.' />
- </params>
- </command>
- <command id='iu rab-assign-addr-enc (x213|v4raw)'>
- <params>
- <param name='iu' doc='Iu interface protocol options' />
- <param name='rab-assign-addr-enc' doc='Choose RAB Assignment&apos;s Transport Layer Address encoding' />
- <param name='x213' doc='ITU-T X.213 compliant address encoding (default)' />
- <param name='v4raw' doc='32bit length raw IPv4 address (for ip.access nano3G)' />
- </params>
- </command>
- <command id='asn1 debug (1|0)'>
- <params>
- <param name='asn1' doc='ASN.1 settings' />
- <param name='debug' doc='Enable ASN.1 debug messages' />
- <param name='1' doc='Log ASN.1 debug messages to stderr' />
- <param name='0' doc='Do not log ASN.1 debug messages to stderr' />
- </params>
- </command>
- <command id='asn1 xer-print (1|0)'>
- <params>
- <param name='asn1' doc='ASN.1 settings' />
- <param name='xer-print' doc='Log human readable representations of all ASN.1 messages to stderr' />
- <param name='1' doc='Log XML representation of all ASN.1 messages to stderr' />
- <param name='0' doc='Do not log decoded ASN.1 messages to stderr' />
- </params>
- </command>
- </node>
- <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 &lt;1-65535&gt;'>
- <params>
- <param name='local-tcp-port' doc='Set the local TCP port on which we listen for SMPP' />
- <param name='&lt;1-65535&gt;' doc='TCP port number' />
- </params>
- </command>
- <command id='local-tcp-ip A.B.C.D &lt;1-65535&gt;'>
- <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='&lt;1-65535&gt;' 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 independent of system ID / password' />
- <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>
- <command id='alert-notifications'>
- <params>
- <param name='alert-notifications' doc='Disable sending of SMPP Alert Notifications for this ESME' />
- </params>
- </command>
- <command id='no alert-notifications'>
- <params>
- <param name='no' doc='Negate a command or set its defaults' />
- <param name='alert-notifications' doc='Disable sending of SMPP Alert Notifications for this ESME' />
- </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 &lt;1-65535&gt;'>
- <params>
- <param name='remote-port' doc='Remote GSUP port of the HLR' />
- <param name='&lt;1-65535&gt;' doc='Remote GSUP port (default: MSC_HLR_REMOTE_PORT_DEFAULT)' />
- </params>
- </command>
- <command id='ipa-name NAME'>
- <params>
- <param name='ipa-name' doc='Set the IPA name of this MSC' />
- <param name='NAME' doc='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 &apos;MSC-00-00-00-00-00-00&apos;.' />
- </params>
- </command>
- </node>
- <node id='config-sgs'>
- <name>config-sgs</name>
- <command id='local-ip A.B.C.D'>
- <params>
- <param name='local-ip' doc='Set the Local IP Address of the SGs interface' />
- <param name='A.B.C.D' doc='Local IP Address of the SGs interface' />
- </params>
- </command>
- <command id='local-port &lt;0-65535&gt;'>
- <params>
- <param name='local-port' doc='Set the local SCTP port of the SGs interface' />
- <param name='&lt;0-65535&gt;' doc='Local SCTP port of the SGs interface' />
- </params>
- </command>
- <command id='timer (ts5|ts6-2|ts7|ts11|ts14|ts15) &lt;1-120&gt;'>
- <params>
- <param name='timer' doc='Configure SGs Timer' />
- <param name='ts5' doc='Paging procedure guard timer' />
- <param name='ts6-2' doc='TMSI reallocation guard timer' />
- <param name='ts7' doc='Non-EPS alert procedure guard timer' />
- <param name='ts11' doc='VLR reset guard timer' />
- <param name='ts14' doc='UE fallback prcoedure timer' />
- <param name='ts15' doc='MO UE fallback procedure guard timer' />
- <param name='&lt;1-120&gt;' doc='Time in seconds' />
- </params>
- </command>
- <command id='counter (ns7|ns11) &lt;0-255&gt;'>
- <params>
- <param name='counter' doc='Configure SGs Counter' />
- <param name='ns7' doc='Non-EPS alert request retry counter' />
- <param name='ns11' doc='VLR reset retry counter' />
- <param name='&lt;0-255&gt;' doc='Counter value' />
- </params>
- </command>
- <command id='vlr-name FQDN'>
- <params>
- <param name='vlr-name' doc='Set the SGs VLR Name as per TS 29.118 9.4.22' />
- <param name='FQDN' doc='Fully-Qualified Domain Name of this VLR' />
- </params>
- </command>
- </node>
-</vtydoc>
diff --git a/doc/sequence_charts/Makefile.am b/doc/sequence_charts/Makefile.am
index f1775c8f5..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_call_fsm.msc \
+ $(srcdir)/*.msc \
$(NULL)
CLEANFILES = \
- inter_bsc_ho.png \
- inter_msc_ho.png \
- mncc_call_fsm.png \
+ $(builddir)/*.png \
$(NULL)
msc: \
$(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/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 a225b6683..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[];
@@ -74,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_addr_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 c504c7f0b..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;
@@ -46,7 +28,8 @@ int gsm411_send_sms(struct gsm_network *net,
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,
- bool sm_rp_mmts_ind);
+ 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 11b6e8237..119f093db 100644
--- a/include/osmocom/msc/gsm_data.h
+++ b/include/osmocom/msc/gsm_data.h
@@ -13,11 +13,14 @@
#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"
@@ -30,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 {
@@ -43,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,
@@ -65,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 occurred 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."},
@@ -149,10 +158,8 @@ struct gsm_network {
bool authentication_required;
int send_mm_info;
- /* Whether to use encryption on UTRAN.
- * TODO: we should offer a choice of UEA1 and/or UEA2, and probably replace this bool with a bit-mask of
- * permitted Iu encryption algorithms. See also OS#4143 and the 'encryption uea' vty command. */
- bool uea_encryption;
+ /* bit-mask of permitted encryption algorithms. LSB=UEA0, MSB=UEA7 */
+ uint8_t uea_encryption_mask;
struct rate_ctr_group *msc_ctrs;
struct osmo_stat_item_group *statg;
@@ -170,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;
@@ -204,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 */
@@ -214,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 {
@@ -233,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;
@@ -248,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 {
@@ -261,9 +263,21 @@ struct gsm_network {
/* 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,
@@ -292,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 e887cbe7a..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+
diff --git a/include/osmocom/msc/msc_a.h b/include/osmocom/msc/msc_a.h
index a4d3226ed..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,12 +37,18 @@
#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"
@@ -99,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];
@@ -118,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;
@@ -177,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__)
@@ -200,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 081c7ad4d..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[];
@@ -86,6 +106,11 @@ struct ran_assignment_command {
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 {
@@ -99,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 {
@@ -156,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 {
@@ -192,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;
@@ -209,6 +239,12 @@ 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;
@@ -217,6 +253,8 @@ struct ran_msg {
} 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;
@@ -225,7 +263,9 @@ 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;
@@ -252,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 c53c4f179..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,13 +39,14 @@ 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;
@@ -58,14 +61,19 @@ struct rtp_stream {
#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);
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_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 c7f899174..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;
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 69cd65229..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;
@@ -114,6 +149,9 @@ struct gsm_trans {
bool sm_rp_mmts_ind;
struct gsm_sms *sms;
+
+ uint8_t *gsup_source_name;
+ size_t gsup_source_name_len;
} sms;
struct {
/**
@@ -142,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,
@@ -162,6 +202,10 @@ void trans_conn_closed(const struct msc_a *msc_a);
static inline int trans_log_subsys(enum trans_type 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(enum trans_type type)
}
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 52912eb22..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 */
@@ -129,7 +134,6 @@ struct vlr_subscr {
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 */
@@ -193,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;
@@ -251,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 */
@@ -276,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;
};
@@ -299,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);
@@ -311,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);
@@ -362,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,
@@ -389,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__)
@@ -404,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);
@@ -420,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,
@@ -438,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 */
};
@@ -449,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);
@@ -465,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);
diff --git a/include/osmocom/msc/vlr_sgs.h b/include/osmocom/msc/vlr_sgs.h
index fa9d948a1..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,7 +69,7 @@ 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 */
@@ -97,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 794eda286..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,25 +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];
+ 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 (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))
+ 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);
}
@@ -335,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 241bc866e..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,598 +205,540 @@ static const char *create_stmts[] = {
")",
};
-static inline int next_row(dbi_result 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,
+};
+
+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)
{
- if (!dbi_result_has_next_row(result))
- return 0;
- return dbi_result_next_row(result);
+ LOGP(DDB, LOGL_ERROR, "SQLITE3: (%d) %s\n", err_code, msg);
+ osmo_log_backtrace(DDB, LOGL_ERROR);
}
-void db_error_func(dbi_conn conn, void *data)
+/* libsqlite3 call-back for normal logging */
+static void sql3_sql_log_cb(void *arg, sqlite3 *s3, const char *stmt, int type)
{
- const char *msg;
- dbi_conn_error(conn, &msg);
- LOGP(DDB, LOGL_ERROR, "DBI: %s\n", msg);
- osmo_log_backtrace(DDB, LOGL_ERROR);
+ 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;
+ }
}
-static int update_db_revision_2(void)
+/* remove statement bindings and reset statement to be re-executed */
+static void db_remove_reset(sqlite3_stmt *stmt)
{
- dbi_result result;
+ sqlite3_clear_bindings(stmt);
+ /* sqlite3_reset() just repeats an error code already evaluated during sqlite3_step(). */
+ /* coverity[CHECKED_RETURN] */
+ sqlite3_reset(stmt);
+}
- 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;
+/** 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)
+{
+ 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,
- "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;
+ 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);
-
- return 0;
+ return true;
}
-static void parse_tp_ud_from_result(struct gsm_sms *sms, 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)
{
- 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 = dbi_result_get_field_length(result, "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);
+ 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;
}
- sms->user_data_len = user_data_len;
-
- /* Retrieve the TP-UD (User-Data) itself */
- if (user_data_len > 0) {
- user_data = dbi_result_get_binary(result, "user_data");
- memcpy(sms->user_data, user_data, user_data_len);
+ 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;
}
+ return true;
+}
- /* Retrieve the text length (excluding '\0') */
- text_len = dbi_result_get_field_length(result, "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 */
+/** 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;
}
-
- /* Retrieve the text parsed from TP-UD (User-Data) */
- text = dbi_result_get_string(result, "text");
- if (text)
- OSMO_STRLCPY_ARRAY(sms->text, text);
+ 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;
+ }
+ return true;
}
-/**
- * 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)
+/** 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)
{
- struct gsm_sms *sms = sms_alloc();
- long long unsigned int sender_id;
- const char *daddr;
- 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, &quoted);
- 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);
-
- /* Parse TP-UD, TP-UDL and decoded text */
- parse_tp_ud_from_result(sms, result);
-
- return sms;
+ 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;
+ }
+ 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;
}
-static int update_db_revision_3(void)
+/* callback for sqlite3_exec() below */
+static int db_rev_exec_cb(void *priv, int num_cols, char **vals, char **names)
{
- dbi_result result;
- struct gsm_sms *sms;
+ char **rev_s = priv;
+ OSMO_ASSERT(!strcmp(names[0], "value"));
+ *rev_s = talloc_strdup(NULL, vals[0]);
+ return 0;
+}
- LOGP(DDB, LOGL_NOTICE, "Going to migrate from revision 3\n");
+static int check_db_revision(struct db_context *dbc)
+{
+ char *errstr = NULL;
+ char *rev_s;
+ int db_rev = 0;
+ int rc;
- result = dbi_conn_query(conn, "BEGIN EXCLUSIVE TRANSACTION");
- if (!result) {
- LOGP(DDB, LOGL_ERROR,
- "Failed to begin transaction (upgrade from rev 3)\n");
+ /* Make a query */
+ 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;
}
- 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;
- }
- 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;
+ if (!strcmp(rev_s, SCHEMA_REVISION)) {
+ /* Everything is fine */
+ talloc_free(rev_s);
+ return 0;
}
- 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);
+ LOGP(DDB, LOGL_NOTICE, "Detected DB Revision %s, expected %s\n", rev_s, SCHEMA_REVISION);
- /* 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);
+ db_rev = atoi(rev_s);
+ talloc_free(rev_s);
- result = dbi_conn_query(conn, "COMMIT TRANSACTION");
- if (!result) {
- LOGP(DDB, LOGL_ERROR,
- "Failed to commit the transaction (upgrade from rev 3)\n");
+ /* Incremental migration waterfall */
+ switch (db_rev) {
+ case 2:
+ case 3:
+ case 4:
+ 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);
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);
+//error:
+ LOGP(DDB, LOGL_FATAL, "Failed to update database from schema revision '%d'.\n", db_rev);
+ talloc_free(rev_s);
+
return -EINVAL;
}
-/* 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)
-{
- struct gsm_sms *sms = sms_alloc();
- const char *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");
+/***********************************************************************
+ * USER API
+ ***********************************************************************/
- 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");
+int db_init(void *ctx, const char *fname, bool enable_sqlite_logging)
+{
+ unsigned int i;
+ int rc;
+ bool has_sqlite_config_sqllog = false;
- /* Parse TP-UD, TP-UDL and decoded text */
- parse_tp_ud_from_result(sms, result);
+ g_dbc = talloc_zero(ctx, struct db_context);
+ OSMO_ASSERT(g_dbc);
- return sms;
-}
+ /* we are a single-threaded program; we want to avoid all the mutex/etc. overhead */
+ sqlite3_config(SQLITE_CONFIG_SINGLETHREAD);
-static int update_db_revision_4(void)
-{
- dbi_result result;
- struct gsm_sms *sms;
+ LOGP(DDB, LOGL_NOTICE, "Init database connection to '%s' using SQLite3 lib version %s\n",
+ fname, sqlite3_libversion());
- LOGP(DDB, LOGL_NOTICE, "Going to migrate from revision 4\n");
+ g_dbc->fname = talloc_strdup(g_dbc, fname);
- 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;
+ 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_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;
+ 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");
}
- 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;
+ 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");
}
- dbi_result_free(result);
- /* 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;
- }
- 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_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;
}
- dbi_result_free(result);
- /* 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;
+ /* 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 */
}
- 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;
- }
- 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);
+ 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 */
}
- /* 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);
+ 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;
-
-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)
+int db_fini(void)
{
- dbi_result result;
- const char *rev_s;
- int db_rev = 0;
-
- /* 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;
- }
+ unsigned int i;
+ int rc;
- /* Fetch the DB schema revision */
- rev_s = dbi_result_get_string(result, "value");
- if (!rev_s) {
- dbi_result_free(result);
- return -EINVAL;
- }
-
- if (!strcmp(rev_s, SCHEMA_REVISION)) {
- /* Everything is fine */
- dbi_result_free(result);
+ if (!g_dbc)
return 0;
- }
-
- db_rev = atoi(rev_s);
- dbi_result_free(result);
- /* 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;
- default:
- LOGP(DDB, LOGL_FATAL,
- "Invalid database schema revision '%d'.\n", db_rev);
- return -EINVAL;
+ for (i = 0; i < ARRAY_SIZE(g_dbc->stmt); i++) {
+ /* it is ok to call finalize on NULL */
+ sqlite3_finalize(g_dbc->stmt[i]);
}
- return 0;
-
-error:
- LOGP(DDB, LOGL_FATAL, "Failed to update database "
- "from schema revision '%d'.\n", db_rev);
- return -EINVAL;
-}
-
-static int db_configure(void)
-{
- dbi_result result;
+ /* 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));
+ }
- result = dbi_conn_query(conn,
- "PRAGMA synchronous = FULL");
- if (!result)
- return -EINVAL;
+ talloc_free(g_dbc);
+ g_dbc = NULL;
- dbi_result_free(result);
return 0;
}
-int db_init(const char *name)
+/* run (execute) a series of SQL statements */
+static int db_run_statements(struct db_context *dbc, const char **statements, size_t statements_count)
{
- dbi_initialize_r(NULL, &inst);
-
- LOGP(DDB, LOGL_NOTICE, "Init database connection to '%s' using %s\n",
- name, dbi_version());
-
- 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;
+ 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;
+ }
}
-
- dbi_conn_error_handler( conn, db_error_func, NULL );
-
- /* 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");
- */
-
- /* 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));
-
- if (dbi_conn_connect(conn) < 0)
- goto out_err;
-
return 0;
-
-out_err:
- free(db_dirname);
- free(db_basename);
- db_dirname = db_basename = NULL;
- return -1;
}
-
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 = NULL;
+ 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);
-
- /* Guard against zero-length input, as this may cause
- * buffer overruns in libdbi / libdbdsqlite3. */
- if (sms->user_data_len > 0) {
- 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)
+{
+ 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;
@@ -781,24 +747,23 @@ static struct gsm_sms *sms_from_result(struct gsm_network *net, dbi_result resul
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);
@@ -806,78 +771,72 @@ static struct gsm_sms *sms_from_result(struct gsm_network *net, dbi_result resul
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");
+ 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);
/* Parse TP-UD, TP-UDL and decoded text */
- parse_tp_ud_from_result(sms, result);
+ parse_tp_ud_from_result(sms, stmt);
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;
@@ -886,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);
-
- if (!result)
- return NULL;
+ db_bind_text(stmt, "$dest_addr", last_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);
+ sms = sms_from_result(net, stmt);
- dbi_result_free(result);
+ db_remove_reset(stmt);
return sms;
}
@@ -947,84 +888,100 @@ 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 validity_timestamp)
{
- dbi_result result;
+ OSMO_ASSERT(g_dbc);
+ sqlite3_stmt *stmt = g_dbc->stmt[DB_STMT_SMS_DEL_EXPIRED];
time_t now;
+ int rc;
now = time(NULL);
@@ -1032,51 +989,55 @@ static int delete_expired_sms(unsigned long long sms_id, time_t validity_timesta
if (validity_timestamp > now)
return -1;
- result = dbi_conn_queryf(conn, "DELETE FROM SMS WHERE id = %llu", sms_id);
- if (!result) {
+ 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 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;
+ 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 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;
}
- validity_timestamp = dbi_result_get_datetime(result, "valid_until");
+ validity_timestamp = sqlite3_column_int64(stmt, 0);
- dbi_result_free(result);
+ 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,valid_until FROM SMS "
- "ORDER BY valid_until 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 validity_timestamp;
- sms_id = dbi_result_get_ulonglong(result, "id");
- validity_timestamp = dbi_result_get_datetime(result, "valid_until");
+ 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 0bdc4fbe8..17350faad 100644
--- a/src/libmsc/gsm_04_08.c
+++ b/src/libmsc/gsm_04_08.c
@@ -36,6 +36,7 @@
#include <osmocom/msc/debug.h>
#include <osmocom/msc/gsm_data.h>
#include <osmocom/msc/gsm_04_08.h>
+#include <osmocom/msc/msc_vgcs.h>
#include <osmocom/msc/signal.h>
#include <osmocom/msc/transaction.h>
#include <osmocom/msc/vlr.h>
@@ -48,11 +49,14 @@
#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>
@@ -116,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 */
@@ -180,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,
@@ -190,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 */
@@ -212,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)
{
@@ -288,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;
@@ -298,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;
@@ -305,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;
}
@@ -313,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:
@@ -375,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->uea_encryption : 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,
@@ -631,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);
}
@@ -676,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
@@ -691,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)) {
@@ -703,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;
@@ -719,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");
@@ -739,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 */
@@ -758,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,
@@ -778,9 +813,10 @@ 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->uea_encryption : 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);
@@ -801,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);
+
+ DEBUGP(DMM, "<- CM RE-ESTABLISH REQUEST %s\n", osmo_mobile_identity_to_str_c(OTC_SELECT, &mi));
+
+ 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);
+ }
- 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);
+ /* 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__);
- /* we don't support CM call re-establishment */
- return msc_gsm48_tx_mm_serv_rej(msc_a, GSM48_REJECT_SRV_OPT_NOT_SUPPORTED);
+ /* 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)
@@ -824,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);
@@ -1125,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);
@@ -1150,9 +1303,10 @@ 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->uea_encryption : 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);
@@ -1161,8 +1315,13 @@ static int gsm48_rx_rr_pag_resp(struct msc_a *msc_a, struct msgb *msg)
* 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;
}
@@ -1177,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;
+
+ 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_mi_name(mi->val, mi->len));
+ 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)
@@ -1205,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
@@ -1232,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));
@@ -1287,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);
}
@@ -1314,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);
}
@@ -1333,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;
}
@@ -1352,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)
{
@@ -1362,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
@@ -1375,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,
@@ -1389,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)
@@ -1423,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 ed74e88bb..63b1699ab 100644
--- a/src/libmsc/gsm_04_08_cc.c
+++ b/src/libmsc/gsm_04_08_cc.c
@@ -43,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>
@@ -55,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>
@@ -126,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);
}
@@ -163,20 +166,22 @@ static void count_statistics(struct gsm_trans *trans, int new_state)
/* state incoming */
switch (new_state) {
case GSM_CSTATE_ACTIVE:
- osmo_stat_item_inc(trans->net->statg->items[MSC_STAT_ACTIVE_CALLS], 1);
- 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_stat_item_dec(trans->net->statg->items[MSC_STAT_ACTIVE_CALLS], 1);
+ 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;
}
}
@@ -226,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)
@@ -244,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;
}
@@ -269,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) {
@@ -277,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);
@@ -310,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);
@@ -329,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;
@@ -355,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)
@@ -374,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));
@@ -450,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;
@@ -494,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) {
@@ -538,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;
@@ -563,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));
@@ -620,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);
@@ -639,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);
@@ -651,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);
}
@@ -687,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;
@@ -706,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);
@@ -716,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)
@@ -733,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));
}
@@ -757,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);
@@ -786,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);
}
@@ -795,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;
@@ -810,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)
@@ -856,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);
}
@@ -896,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);
}
@@ -909,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;
@@ -1608,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;
@@ -1619,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)
{
@@ -1680,38 +2145,37 @@ int gsm48_tch_rtp_create(struct gsm_trans *trans)
struct call_leg *cl = msc_a->cc.call_leg;
struct osmo_sockaddr_str *rtp_cn_local;
struct rtp_stream *rtp_cn = cl ? cl->rtp[RTP_TO_CN] : NULL;
- uint32_t payload_type;
- int payload_msg_type;
- const struct mgcp_conn_peer *mgcp_info;
+ 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;
}
- if (!rtp_cn->codec_known) {
+ 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, no codec set up for the RTP CN side\n");
+ "Cannot RTP CREATE to MNCC, there is no codec available\n");
return -EINVAL;
}
- /* Codec */
- payload_msg_type = mgcp_codec_to_mncc_payload_msg_type(rtp_cn->codec);
-
- /* Payload Type number */
- mgcp_info = osmo_mgcpc_ep_ci_get_rtp_info(rtp_cn->ci);
- if (mgcp_info && mgcp_info->ptmap_len)
- payload_type = map_codec_to_pt(mgcp_info->ptmap, mgcp_info->ptmap_len, rtp_cn->codec);
- else
- payload_type = rtp_cn->codec;
+ /* 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, payload_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)
@@ -1719,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);
@@ -1745,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;
}
@@ -1838,7 +2292,7 @@ static 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:
@@ -1859,7 +2313,7 @@ static 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) {
@@ -1934,29 +2388,28 @@ static int mncc_tx_to_gsm_cc(struct gsm_network *net, const union mncc_msg *msg)
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;
}
+ /* 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) {
@@ -1977,9 +2430,30 @@ static 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;
@@ -1989,7 +2463,7 @@ static 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)
@@ -1999,9 +2473,6 @@ static 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 367cc6faf..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;
@@ -432,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;
}
@@ -442,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;
}
@@ -501,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)
@@ -626,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.
@@ -717,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 */
@@ -887,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);
@@ -1195,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,
@@ -1207,7 +1230,8 @@ int gsm411_send_sms(struct gsm_network *net,
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,
- bool sm_rp_mmts_ind)
+ bool sm_rp_mmts_ind, const uint8_t *gsup_source_name,
+ size_t gsup_source_name_len)
{
struct gsm_trans *trans;
struct msgb *msg;
@@ -1222,6 +1246,17 @@ int gsm411_send_rp_data(struct gsm_network *net, struct vlr_subscr *vsub,
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) {
@@ -1238,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,
@@ -1366,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 2abfc9209..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,6 +121,7 @@ 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);
}
@@ -143,14 +152,6 @@ static int gsm411_gsup_mo_handler(struct gsm_network *net, struct vlr_subscr *vs
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;
@@ -163,7 +164,8 @@ static int gsm411_gsup_mo_handler(struct gsm_network *net, struct vlr_subscr *vs
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");
@@ -180,9 +182,8 @@ static int gsm411_gsup_mo_handler(struct gsm_network *net, struct vlr_subscr *vs
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;
}
@@ -199,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);
}
@@ -216,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;
@@ -235,14 +246,6 @@ static int gsm411_gsup_mt_handler(struct gsm_network *net, struct vlr_subscr *vs
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
*
@@ -268,19 +271,20 @@ static int gsm411_gsup_mt_handler(struct gsm_network *net, struct vlr_subscr *vs
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,
- sm_rp_mmts_ind);
+ 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;
}
@@ -290,6 +294,14 @@ int gsm411_gsup_rx(struct gsup_client_mux *gcm, void *data, const struct osmo_gs
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",
@@ -317,6 +329,7 @@ int gsm411_gsup_rx(struct gsup_client_mux *gcm, void *data, const struct osmo_gs
default:
LOGP(DMM, LOGL_ERROR, "No handler found for %s, dropping message...\n",
osmo_gsup_message_type_name(gsup_msg->message_type));
+ gsup_client_mux_tx_error_reply(gcm, gsup_msg, GMM_CAUSE_MSGT_NOTEXIST_NOTIMPL);
rc = -GMM_CAUSE_MSGT_NOTEXIST_NOTIMPL;
}
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 8a13cdad6..e29389015 100644
--- a/src/libmsc/gsm_09_11.c
+++ b/src/libmsc/gsm_09_11.c
@@ -125,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
@@ -159,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_stat_item_inc(net->statg->items[MSC_STAT_ACTIVE_NC_SS], 1);
+ 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;
@@ -241,7 +241,7 @@ 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 rc;
@@ -265,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;
}
@@ -297,7 +297,7 @@ 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;
@@ -363,7 +363,7 @@ static struct gsm_trans *establish_nc_ss_trans(struct gsm_network *net,
}
/* Count active NC SS/USSD sessions */
- osmo_stat_item_inc(net->statg->items[MSC_STAT_ACTIVE_NC_SS], 1);
+ 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,
@@ -415,7 +415,8 @@ void _gsm911_nc_ss_trans_free(struct gsm_trans *trans)
osmo_timer_del(&trans->ss.timer_guard);
/* One session less */
- osmo_stat_item_dec(trans->net->statg->items[MSC_STAT_ACTIVE_NC_SS], 1);
+ 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)
@@ -440,7 +441,7 @@ int gsm0911_gsup_rx(struct gsup_client_mux *gcm, void *data, const struct osmo_g
log_set_context(LOG_CTX_VLR_SUBSCR, vsub);
/* Attempt to find DTAP-transaction */
- trans = trans_find_by_callref(net, gsup_msg->session_id);
+ trans = trans_find_by_callref(net, TRANS_USSD, gsup_msg->session_id);
/* Handle errors */
if (OSMO_GSUP_IS_MSGT_ERROR(gsup_msg->message_type)) {
@@ -474,7 +475,7 @@ int gsm0911_gsup_rx(struct gsup_client_mux *gcm, void *data, const struct osmo_g
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);
@@ -578,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 e425651af..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)
@@ -154,12 +169,15 @@ void gsup_client_mux_tx_error_reply(struct gsup_client_mux *gcm, const struct os
.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) {
diff --git a/src/libmsc/mncc.c b/src/libmsc/mncc.c
index d0b2ff263..026dae025 100644
--- a/src/libmsc/mncc.c
+++ b/src/libmsc/mncc.c
@@ -110,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;
@@ -157,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;
}
@@ -235,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)) {
@@ -262,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:
@@ -279,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 da096c64b..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;
@@ -303,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;
@@ -370,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 344b442cb..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"
@@ -106,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;
@@ -138,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)
@@ -151,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)
@@ -292,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;
@@ -321,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,
+ },
},
};
@@ -337,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;
}
@@ -435,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__);
@@ -511,23 +575,126 @@ 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 = {
@@ -535,20 +702,14 @@ static void msc_a_call_leg_ran_local_addr_available(struct msc_a *msc_a)
.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;
}
}
@@ -627,16 +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 " (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));
@@ -715,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,
};
@@ -755,6 +928,9 @@ 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),
},
};
@@ -823,6 +999,7 @@ static void msc_a_fsm_released(struct osmo_fsm_inst *fi, uint32_t event, void *d
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);
@@ -830,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[] = {
@@ -969,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)
@@ -1058,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 }
};
@@ -1084,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. */
@@ -1210,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;
@@ -1246,15 +1433,29 @@ 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;
}
@@ -1265,24 +1466,76 @@ static void msc_a_up_call_assignment_complete(struct msc_a *msc_a, const struct
return;
}
- /* Update RAN-side endpoint CI: */
- rtp_stream_set_codec(rtps_to_ran, ac->assignment_complete.codec);
+ 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;
}
@@ -1299,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) {
@@ -1323,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);
@@ -1351,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);
@@ -1404,7 +1686,25 @@ 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;
@@ -1455,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;
@@ -1463,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);
@@ -1568,21 +2005,18 @@ 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) {
- struct gsm48_hdr *gh = msgb_l3(dtap) ? : dtap->data;
- uint8_t pdisc = gsm48_hdr_pdisc(gh);
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);
@@ -1594,6 +2028,9 @@ int msc_a_tx_dtap_to_i(struct msc_a *msc_a, struct msgb *dtap)
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,
@@ -1612,57 +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 msc_i *msc_i = msc_a_msc_i(msc_a);
- struct gsm_network *net = msc_a_net(msc_a);
+ 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);
-
- /* 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;
- }
+ OSMO_ASSERT(cc_trans && cc_trans->type == TRANS_CC);
+ cl = msc_a_ensure_call_leg(msc_a, cc_trans);
+ if (!cl)
+ return -EINVAL;
- if (net->use_osmux != OSMUX_USAGE_OFF) {
- 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;
- }
+ /* 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)
@@ -1684,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:
@@ -1697,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 91b6165bd..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,26 @@
#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)
@@ -49,19 +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);
- net->uea_encryption = true;
-
- /* 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);
@@ -116,9 +130,15 @@ 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){
diff --git a/src/libmsc/msc_t.c b/src/libmsc/msc_t.c
index 6b96c26ca..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;
@@ -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;
}
@@ -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 51504ef51..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,19 +132,23 @@ 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;
}
@@ -148,12 +156,13 @@ DEFUN(cfg_net_name_long,
DEFUN(cfg_net_encryption,
cfg_net_encryption_cmd,
- "encryption a5 <0-3> [<0-3>] [<0-3>] [<0-3>]",
+ "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"
"A5/n Algorithm Number\n")
{
unsigned int i;
@@ -165,41 +174,21 @@ DEFUN(cfg_net_encryption,
return CMD_SUCCESS;
}
-/* So far just a boolean switch, a future patch might add individual config for UEA1 and UEA2, see OS#4143 */
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."
- " NOTE: the current implementation does not allow free choice of combining encryption algorithms yet."
- " The only valid settings are either 'encryption uea 0' or 'encryption uea 1 2'.\n"
+ "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;
- uint8_t mask = 0;
+ gsmnet->uea_encryption_mask = 0;
for (i = 0; i < argc; i++)
- mask |= (1 << atoi(argv[i]));
-
- if (mask == (1 << 0)) {
- /* UEA0. Disable encryption. */
- gsmnet->uea_encryption = false;
- } else if (mask == ((1 << 1) | (1 << 2))) {
- /* UEA1 and UEA2. Enable encryption. */
- gsmnet->uea_encryption = true;
- } else {
- vty_out(vty,
- "%% Error: the current implementation does not allow free choice of combining%s"
- "%% encryption algorithms yet. The only valid settings are either%s"
- "%% encryption uea 0%s"
- "%% or%s"
- "%% encryption uea 1 2%s",
- VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE);
- return CMD_WARNING;
- }
+ gsmnet->uea_encryption_mask |= (1 << atoi(argv[i]));
return CMD_SUCCESS;
}
@@ -302,32 +291,44 @@ 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")
{
- struct gsm_network *net = vty->index;
+ int minutes = atoi(argv[0]);
+ int rc;
- net->t3212 = atoi(argv[0]) / 6;
+ vty_out(vty, "%% 'periodic location update' is now deprecated. "
+ "Use 'msc' / 'timer vlr T3212' to change subscriber expiration "
+ "timeout.%s", VTY_NEWLINE);
- return CMD_SUCCESS;
+ /* 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(cfg_net_no_per_loc_upd, cfg_net_no_per_loc_upd_cmd,
- "no periodic location update",
- NO_STR
- "Periodic Location Updating Interval\n"
- "Periodic Location Updating Interval\n"
- "Periodic Location Updating Interval\n")
+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)
{
- struct gsm_network *net = vty->index;
+ int rc;
- net->t3212 = 0;
+ vty_out(vty, "%% 'periodic location update' is now deprecated: "
+ "use 'timer T3212' to change subscriber expiration "
+ "timeout.%s", VTY_NEWLINE);
- return CMD_SUCCESS;
+ 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,
@@ -370,10 +371,12 @@ static int config_write_net(struct vty *vty)
}
vty_out(vty, "%s", VTY_NEWLINE);
- if (!gsmnet->uea_encryption)
- vty_out(vty, " encryption uea 0%s", VTY_NEWLINE);
- else
- vty_out(vty, " encryption uea 1 2%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),
@@ -388,20 +391,12 @@ 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;
}
@@ -422,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",
@@ -484,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>",
@@ -549,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"
@@ -557,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")
{
+ int rat;
+ int paging_response_timer;
if (!strcmp(argv[0], "default"))
- gsmnet->paging_response_timer = MSC_PAGING_RESPONSE_TIMER_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;
}
@@ -654,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);
@@ -688,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);
@@ -716,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;
}
@@ -832,7 +942,7 @@ static void vty_dump_one_conn(struct vty *vty, const struct msub *msub,
if (vsub) {
MSC_VTY_DUMP(vty, offset, "LAC / cell ID: %u / %u%s",
- vsub->cgi.lai.lac, vsub->cgi.cell_identity,
+ msc_a->via_cell.lai.lac, msc_a->via_cell.cell_identity,
VTY_NEWLINE);
}
@@ -865,7 +975,6 @@ static void vty_dump_one_conn(struct vty *vty, const struct msub *msub,
static void vty_dump_one_subscr(struct vty *vty, struct vlr_subscr *vsub,
int offset, uint8_t dump_flags)
{
- struct gsm_network *net;
struct timespec now;
char buf[128];
@@ -939,9 +1048,7 @@ static void vty_dump_one_subscr(struct vty *vty, struct vlr_subscr *vsub,
VTY_NEWLINE);
}
- /* XXX move t3212 into struct vlr_instance? */
- net = vsub->vlr->user_ctx;
- if (!net->t3212) {
+ 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) {
@@ -1148,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 */
@@ -1217,13 +1329,12 @@ DEFUN(show_subscr, show_subscr_cmd,
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);
@@ -1624,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;
}
@@ -1652,6 +1764,7 @@ DEFUN(subscriber_mstest_open,
gsm0414_tx_open_loop_cmd(msc_a);
+ vlr_subscr_put(vsub, VSUB_USE_VTY);
return CMD_SUCCESS;
}
@@ -1711,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")
@@ -1925,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;
}
@@ -1974,10 +2042,15 @@ void msc_vty_init(struct gsm_network *msc_network)
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);
@@ -1995,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();
@@ -2013,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);
@@ -2027,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 743ce5c86..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+
@@ -84,7 +84,7 @@ 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(vsub, struct paging_request);
OSMO_ASSERT(pr);
@@ -110,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);
@@ -119,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;
@@ -137,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 7672d863d..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);
}
@@ -210,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;
@@ -226,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;
}
}
@@ -261,10 +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,
@@ -279,15 +283,7 @@ 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");
- return -EINVAL;
- }
-
- if (osmo_sockaddr_str_from_sockaddr_in(&ran_dec_msg.assignment_complete.remote_rtp, rtp_addr_in)) {
+ 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;
}
@@ -304,14 +300,27 @@ static int ran_a_decode_assignment_complete(struct ran_dec *ran_dec, struct msgb
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);
@@ -461,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) {
@@ -484,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;
}
@@ -494,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;
}
@@ -504,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;
}
@@ -578,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
@@ -655,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);
@@ -739,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];
@@ -776,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:
@@ -810,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:
@@ -898,23 +1346,33 @@ 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;
}
-static void _gsm0808_assignment_extend_osmux(struct msgb *msg, uint8_t cid)
-{
- OSMO_ASSERT(msg->l3h[1] == msgb_l3len(msg) - 2); /*TL not in len */
- msgb_tv_put(msg, GSM0808_IE_OSMO_OSMUX_CID, cid);
- msg->l3h[1] = msgb_l3len(msg) - 2;
-}
-
/* Compose a BSSAP Assignment Command.
* Passing an RTP address is optional.
* The msub is passed merely for error logging. */
@@ -926,6 +1384,7 @@ static struct msgb *ran_a_make_assignment_command(struct osmo_fsm_inst *log_fi,
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) {
@@ -933,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");
@@ -942,33 +1401,71 @@ 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;
}
}
- msg = 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)
- _gsm0808_assignment_extend_osmux(msg, ac->osmux_cid);
+ msgb_tv_put(msg, GSM0808_IE_OSMO_OSMUX_CID, ac->osmux_cid);
+ msg->l3h[1] = msgb_l3len(msg) - 2;
return msg;
}
@@ -988,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;
}
@@ -1027,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));
@@ -1044,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)
@@ -1084,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,
@@ -1109,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: "
@@ -1139,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;
}
@@ -1185,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);
@@ -1206,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));
@@ -1237,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 d5b914379..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>
@@ -39,16 +36,6 @@
#include <osmocom/msc/ran_msg_iu.h>
#include <osmocom/msc/gsm_04_11.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;
-
#define LOG_RAN_IU_DEC(RAN_DEC, level, fmt, args...) \
LOG_RAN_DEC(RAN_DEC, DIUCS, level, "RANAP: " fmt, ## args)
@@ -166,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)) {
@@ -221,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);
}
@@ -282,7 +286,7 @@ static void ran_iu_decode_ranap_msg(void *_ran_dec, ranap_message *message)
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);
@@ -376,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);
}
@@ -396,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:
@@ -445,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 77740a00b..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:
@@ -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 c3880bf7b..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,14 +75,16 @@ 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");
@@ -89,9 +92,9 @@ void rtp_stream_update_id(struct rtp_stream *rtps)
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);
@@ -107,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);
@@ -121,12 +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);
@@ -137,11 +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->use_osmux || rtps->remote_osmux_cid_sent_to_mgw)
- && rtps->codec_known)
+ && rtps->codecs_known)
rtp_stream_state_chg(rtps, RTP_STREAM_ST_ESTABLISHED);
}
@@ -168,17 +174,18 @@ static void rtp_stream_fsm_establishing_established(struct osmo_fsm_inst *fi, ui
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)
+ 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->codec_known) {
+ && rtps->codecs_known) {
LOG_RTPS(rtps, LOGL_DEBUG,
- "local ip:port set;%s%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);
}
@@ -192,7 +199,8 @@ 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);
@@ -206,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)
@@ -220,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;
}
@@ -306,15 +315,32 @@ static int rtp_stream_do_mgcp_verb(struct rtp_stream *rtps, enum mgcp_verb verb,
.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);
@@ -323,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;
@@ -356,47 +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%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));
@@ -405,6 +479,13 @@ 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)
@@ -424,7 +505,8 @@ 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 5ccded775..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,8 +372,8 @@ 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) */
@@ -398,9 +398,19 @@ static void sgs_tx_loc_upd_resp_cb(struct sgs_lu_response *response)
/* 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);
@@ -466,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");
@@ -486,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));
@@ -598,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 */
@@ -629,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);
@@ -860,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);
@@ -885,6 +915,8 @@ 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 initiated a
* service request for MO CS fallback. There is not much we can do with
@@ -895,6 +927,26 @@ static int sgs_rx_csfb_ind(struct sgs_connection *sgc, struct msgb *msg, const s
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);
@@ -958,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
@@ -1278,7 +1334,7 @@ void sgs_iface_tx_serv_abrt(struct vlr_subscr *vsub)
sgs_tx(mme->conn, msg_sgs);
}
-/*! initalize SGs new interface
+/*! 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 d60cb4a01..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;
+ 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 */
+ /* last MSISDN for which we read SMS from the database and created gsm_sms_pending records */
char last_msisdn[GSM23003_MSISDN_MAX_DIGITS+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,14 +333,14 @@ 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;
@@ -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 11cde934b..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
@@ -130,8 +200,8 @@ struct gsm_trans *trans_alloc(struct gsm_network *net,
int subsys = trans_log_subsys(type);
struct gsm_trans *trans;
- /* a valid subscriber is indispensable */
- if (vsub == NULL) {
+ /* 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;
}
@@ -146,13 +216,15 @@ struct gsm_trans *trans_alloc(struct gsm_network *net,
.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 },
},
};
- 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");
@@ -170,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;
@@ -281,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" },
@@ -291,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;
@@ -303,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 e4c3891c2..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,11 +335,11 @@ 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,
@@ -327,9 +347,7 @@ static void alert_all_esme(struct smsc *smsc, struct vlr_subscr *vsub,
continue;
}
if (esme->acl && !esme->acl->alert_notifications) {
- LOGP(DSMPP, LOGL_DEBUG,
- "[%s] is not set to receive Alert Notifications\n",
- esme->system_id);
+ 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 ca6f90de7..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;
@@ -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));
@@ -519,13 +745,11 @@ void vlr_subscr_expire_lu(void *data)
{
struct vlr_instance *vlr = data;
struct vlr_subscr *vsub, *vsub_tmp;
- struct gsm_network *net;
struct timespec now;
/* Periodic location update might be disabled from the VTY,
* so we shall not expire subscribers until explicit IMSI Detach. */
- net = vlr->user_ctx; /* XXX move t3212 into struct vlr_instance? */
- if (!net->t3212)
+ if (!vlr_timer(vlr, 3212))
goto done;
if (llist_empty(&vlr->subscribers))
@@ -541,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:
@@ -557,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 *
@@ -574,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;
}
@@ -585,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;
}
@@ -655,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);
@@ -668,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);
}
@@ -694,6 +928,8 @@ 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 */
OSMO_STRLCPY_ARRAY(gsup_msg.imsi, vsub->imsi);
return gsup_client_mux_tx(vsub->vlr->gcm, &gsup_msg);
@@ -707,6 +943,8 @@ int vlr_subscr_tx_auth_fail_rep(const struct vlr_subscr *vsub)
.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);
}
@@ -730,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;
}
@@ -740,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? */
@@ -783,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);
@@ -841,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);
@@ -856,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);
@@ -1022,6 +1266,8 @@ static int vlr_subscr_handle_cancel_req(struct vlr_subscr *vsub,
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");
@@ -1032,7 +1278,8 @@ static int vlr_subscr_handle_cancel_req(struct vlr_subscr *vsub,
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;
}
@@ -1068,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;
@@ -1118,66 +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);
}
return 0;
@@ -1212,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);
@@ -1229,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.
@@ -1264,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);
@@ -1275,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)
@@ -1353,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 2db571134..5d8f78bc2 100644
--- a/src/libvlr/vlr_lu_fsm.c
+++ b/src/libvlr/vlr_lu_fsm.c
@@ -469,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);
@@ -514,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);
@@ -642,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),
@@ -676,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;
@@ -688,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 */
@@ -818,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 */
@@ -856,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;
}
@@ -881,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,
@@ -902,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 {
@@ -1140,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,
@@ -1365,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) |
@@ -1477,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)
@@ -1485,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;
@@ -1501,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;
@@ -1516,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 49ad09a59..2771cf5ce 100644
--- a/src/libvlr/vlr_sgs_fsm.c
+++ b/src/libvlr/vlr_sgs_fsm.c
@@ -54,11 +54,15 @@ 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);
@@ -156,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);
@@ -222,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;
@@ -234,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;
@@ -355,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 3860589e7..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,9 +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.tdefs = g_mgw_tdefs;
+ 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;
}
@@ -229,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);
@@ -262,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;
@@ -269,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;
@@ -308,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,
@@ -320,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
@@ -377,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)",
@@ -467,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)
@@ -490,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;
@@ -500,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;
@@ -519,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. */
@@ -536,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);
@@ -544,13 +680,8 @@ int main(int argc, char **argv)
exit(1);
}
- ctrl_vty_init(tall_msc_ctx);
- logging_vty_add_cmds();
- 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);
@@ -584,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;
@@ -594,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;
}
@@ -624,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);
@@ -642,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);
@@ -655,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),
@@ -695,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. */
@@ -715,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);
- msc_network_shutdown(msc_network);
- osmo_signal_dispatch(SS_L_GLOBAL, S_L_GLOBAL_SHUTDOWN, NULL);
- sleep(3);
+ /* 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);
+
+ /* 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();
/**
@@ -746,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 1fad55288..7ab3c377f 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -2,6 +2,9 @@ SUBDIRS = \
sms_queue \
msc_vlr \
db_sms \
+ sdp_msg \
+ mncc \
+ csd \
$(NULL)
if BUILD_SMPP
@@ -35,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
@@ -46,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
@@ -54,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:
@@ -94,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
index 4e850679d..9dabfe719 100644
--- a/tests/db_sms/Makefile.am
+++ b/tests/db_sms/Makefile.am
@@ -14,9 +14,14 @@ AM_CFLAGS = \
$(LIBOSMOSIGTRAN_CFLAGS) \
$(LIBOSMORANAP_CFLAGS) \
$(LIBOSMONETIF_CFLAGS) \
- $(LIBSMPP34_CFLAGS) \
$(LIBOSMOMGCPCLIENT_CFLAGS) \
$(LIBOSMOGSUPCLIENT_CFLAGS) \
+ $(LIBSQLITE3_CFLAGS) \
+ $(NULL)
+
+AM_LDFLAGS = \
+ $(COVERAGE_LDFLAGS) \
+ -no-install \
$(NULL)
EXTRA_DIST = \
@@ -24,7 +29,7 @@ EXTRA_DIST = \
db_sms_test.err \
$(NULL)
-noinst_PROGRAMS = \
+check_PROGRAMS = \
db_sms_test \
$(NULL)
@@ -36,7 +41,6 @@ db_sms_test_SOURCES = \
db_sms_test_LDADD = \
$(top_builddir)/src/libmsc/libmsc.a \
$(top_builddir)/src/libvlr/libvlr.a \
- $(LIBSMPP34_LIBS) \
$(LIBOSMOCORE_LIBS) \
$(LIBOSMOGSM_LIBS) \
$(LIBOSMOVTY_LIBS) \
@@ -46,6 +50,6 @@ db_sms_test_LDADD = \
$(LIBASN1C_LIBS) \
$(LIBOSMOMGCPCLIENT_LIBS) \
$(LIBOSMOGSUPCLIENT_LIBS) \
+ $(LIBSQLITE3_LIBS) \
$(LIBRARY_GSM) \
- -ldbi \
$(NULL)
diff --git a/tests/db_sms/db_sms_test.c b/tests/db_sms/db_sms_test.c
index 24c86e533..7c015d318 100644
--- a/tests/db_sms/db_sms_test.c
+++ b/tests/db_sms/db_sms_test.c
@@ -518,7 +518,8 @@ 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_hex(osmo_stderr_target, 0);
log_set_print_category(osmo_stderr_target, 1);
log_set_print_level(osmo_stderr_target, 1);
@@ -537,7 +538,7 @@ int main(int argc, char **argv)
* 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(":memory:");
+ rc = db_init(talloc_ctx, ":memory:", true);
OSMO_ASSERT(rc == 0);
/* HACK: relax log level back to LOGL_DEBUG (see note above) */
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 0e150367c..cbdd6a409 100644
--- a/tests/msc_vlr/Makefile.am
+++ b/tests/msc_vlr/Makefile.am
@@ -8,7 +8,6 @@ AM_CFLAGS = \
-ggdb3 \
$(LIBOSMOCORE_CFLAGS) \
$(LIBOSMOGSM_CFLAGS) \
- $(LIBSMPP34_CFLAGS) \
$(LIBOSMOVTY_CFLAGS) \
$(LIBOSMOABIS_CFLAGS) \
$(LIBOSMOSIGTRAN_CFLAGS) \
@@ -17,6 +16,7 @@ AM_CFLAGS = \
$(LIBASN1C_CFLAGS) \
$(LIBOSMOMGCPCLIENT_CFLAGS) \
$(LIBOSMOGSUPCLIENT_CFLAGS) \
+ $(LIBSQLITE3_CFLAGS) \
$(NULL)
AM_LDFLAGS = \
@@ -26,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) \
@@ -41,8 +42,8 @@ LDADD = \
$(LIBASN1C_LIBS) \
$(LIBOSMOMGCPCLIENT_LIBS) \
$(LIBOSMOGSUPCLIENT_LIBS) \
+ $(LIBSQLITE3_LIBS) \
$(LIBRARY_GSM) \
- -ldbi \
$(NULL)
noinst_HEADERS = \
@@ -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 \
diff --git a/tests/msc_vlr/msc_vlr_test_authen_reuse.c b/tests/msc_vlr/msc_vlr_test_authen_reuse.c
index d73a5f8c5..870f99369 100644
--- a/tests/msc_vlr/msc_vlr_test_authen_reuse.c
+++ b/tests/msc_vlr/msc_vlr_test_authen_reuse.c
@@ -43,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 */
@@ -85,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");
@@ -98,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");
}
@@ -170,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");
}
@@ -195,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 */);
@@ -239,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 aa78cdb76..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) == 19
-
===== 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) == 19
-
===== 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) == 19
-
===== 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) == 19
-
===== 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) == 19
-
===== 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) == 19
-
===== 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) == 19
-
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 19
-
diff --git a/tests/msc_vlr/msc_vlr_test_call.c b/tests/msc_vlr/msc_vlr_test_call.c
index 065af2555..14c8ea304 100644
--- a/tests/msc_vlr/msc_vlr_test_call.c
+++ b/tests/msc_vlr/msc_vlr_test_call.c
@@ -24,12 +24,15 @@
#include "msc_vlr_tests.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)
@@ -41,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;
@@ -51,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 */
@@ -125,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");
@@ -161,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;
@@ -195,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 */
@@ -210,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 */);
@@ -264,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");
@@ -295,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);
@@ -346,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");
@@ -377,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);
@@ -396,11 +564,7 @@ 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);
+ 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));
@@ -424,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;
@@ -452,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 */
@@ -467,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 */);
@@ -485,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);
@@ -500,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;
@@ -529,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 */
@@ -544,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 */);
@@ -573,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,
@@ -580,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 bbfa61b3e..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) == 19
-
===== 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) == 19
-
===== 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) == 19
-
===== 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: 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) == 19
-
===== 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) == 19
-
===== 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) == 19
+===== 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) == 19
+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 ee5af1ecb..6d7e88a0d 100644
--- a/tests/msc_vlr/msc_vlr_test_gsm_authen.c
+++ b/tests/msc_vlr/msc_vlr_test_gsm_authen.c
@@ -34,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");
@@ -76,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");
@@ -224,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");
@@ -266,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");
@@ -438,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");
@@ -504,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");
@@ -544,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");
@@ -611,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");
@@ -653,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");
@@ -705,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");
@@ -746,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");
@@ -799,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");
@@ -840,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");
@@ -924,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 */
@@ -977,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");
@@ -1129,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 4905881c1..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) == 19
-
===== 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) == 19
-
===== 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) == 19
-
===== 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) == 19
-
===== 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
@@ -1975,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) == 19
-
===== 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
@@ -2006,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)
@@ -2070,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
@@ -2108,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
@@ -2143,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
@@ -2240,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) == 19
-
===== 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
@@ -2271,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)
@@ -2335,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
@@ -2373,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
@@ -2408,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
@@ -2547,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
@@ -2592,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) == 19
-
===== 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
@@ -2623,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)
@@ -2661,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
@@ -2824,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()
@@ -2831,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
@@ -2918,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)
@@ -2976,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()
@@ -2994,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
@@ -3030,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
@@ -3102,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
@@ -3147,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) == 19
-
===== test_wrong_sres_length
- Total time passed: 0.000000 s
- Location Update request causes a GSUP Send Auth Info request to HLR
@@ -3179,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)
@@ -3241,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
@@ -3292,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) == 19
-
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 19
-
diff --git a/tests/msc_vlr/msc_vlr_test_gsm_ciph.c b/tests/msc_vlr/msc_vlr_test_gsm_ciph.c
index 155afbe72..38a5caff0 100644
--- a/tests/msc_vlr/msc_vlr_test_gsm_ciph.c
+++ b/tests/msc_vlr/msc_vlr_test_gsm_ciph.c
@@ -40,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");
@@ -82,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");
@@ -249,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");
@@ -292,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");
@@ -484,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");
@@ -526,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");
@@ -594,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");
@@ -642,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");
@@ -695,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");
@@ -737,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");
@@ -844,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 */
@@ -922,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");
@@ -1067,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");
@@ -1111,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");
@@ -1267,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()
{
@@ -1283,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");
@@ -1327,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");
diff --git a/tests/msc_vlr/msc_vlr_test_gsm_ciph.err b/tests/msc_vlr/msc_vlr_test_gsm_ciph.err
index 4585e0fb0..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) == 19
-
===== 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) == 19
-
===== 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) == 19
-
===== 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) == 19
-
===== 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,7 +1800,7 @@ 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}: RR 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
@@ -1904,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
@@ -1949,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) == 19
-
===== 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
@@ -1980,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)
@@ -2018,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
@@ -2055,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
@@ -2089,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
@@ -2124,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
@@ -2263,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
@@ -2308,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) == 19
-
===== 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
@@ -2339,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)
@@ -2378,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
@@ -2395,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
@@ -2570,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()
@@ -2660,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)
@@ -2733,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()
@@ -2751,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
@@ -2786,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
@@ -2858,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
@@ -2903,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) == 19
-
===== 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
@@ -2934,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)
@@ -2974,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
@@ -2987,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
@@ -3001,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
@@ -3194,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()
@@ -3284,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)
@@ -3375,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()
@@ -3393,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
@@ -3428,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
@@ -3500,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
@@ -3545,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) == 19
-
===== 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
@@ -3576,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)
@@ -3616,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
@@ -3629,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
@@ -3643,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
@@ -3836,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()
@@ -3926,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)
@@ -3980,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
@@ -3995,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()
@@ -4013,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
@@ -4048,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
@@ -4120,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
@@ -4165,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) == 19
-
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 19
-
diff --git a/tests/msc_vlr/msc_vlr_test_hlr_reject.c b/tests/msc_vlr/msc_vlr_test_hlr_reject.c
index 45aaa8ca5..6cdadcb8f 100644
--- a/tests/msc_vlr/msc_vlr_test_hlr_reject.c
+++ b/tests/msc_vlr/msc_vlr_test_hlr_reject.c
@@ -31,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");
@@ -58,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");
@@ -91,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");
@@ -114,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");
@@ -147,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");
@@ -180,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");
@@ -203,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");
@@ -237,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");
@@ -266,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");
@@ -304,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");
@@ -328,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");
@@ -361,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");
@@ -373,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");
@@ -402,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");
@@ -426,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 e4ea2262a..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) == 19
-
===== 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
@@ -100,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) == 19
-
===== 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
@@ -131,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)
@@ -147,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
@@ -201,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) == 19
-
===== test_hlr_rej_auth_info_net_fail_reuse_tuples
@@ -235,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)
@@ -273,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
@@ -397,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)
@@ -435,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
@@ -527,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) == 19
-
===== test_hlr_rej_auth_info_net_fail_no_reuse_tuples
@@ -561,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)
@@ -599,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
@@ -723,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)
@@ -739,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
@@ -793,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) == 19
-
===== test_hlr_rej_auth_info_unkown_imsi_no_reuse_tuples
@@ -827,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)
@@ -865,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
@@ -990,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)
@@ -1006,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
@@ -1060,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) == 19
-
===== 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
@@ -1091,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)
@@ -1106,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
@@ -1160,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) == 19
-
===== test_hlr_rej_lu
- Location Update request causes a GSUP LU request to HLR
MSC <--GERAN-A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
@@ -1191,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
@@ -1263,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) == 19
-
===== 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
@@ -1294,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
@@ -1379,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) == 19
-
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 19
-
diff --git a/tests/msc_vlr/msc_vlr_test_hlr_timeout.c b/tests/msc_vlr/msc_vlr_test_hlr_timeout.c
index abc7c5b06..4523a7c7b 100644
--- a/tests/msc_vlr/msc_vlr_test_hlr_timeout.c
+++ b/tests/msc_vlr/msc_vlr_test_hlr_timeout.c
@@ -35,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");
@@ -73,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 5853643eb..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) == 19
-
===== 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,7 +65,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_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
@@ -109,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) == 19
-
===== test_hlr_timeout_lu_upd_loc_result
- Total time passed: 0.000000 s
- Location Update request causes a GSUP LU request to HLR
@@ -141,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
@@ -195,7 +191,6 @@ 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
@@ -236,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) == 19
-
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 19
-
diff --git a/tests/msc_vlr/msc_vlr_test_ms_timeout.c b/tests/msc_vlr/msc_vlr_test_ms_timeout.c
index 91f00ef71..11afc5196 100644
--- a/tests/msc_vlr/msc_vlr_test_ms_timeout.c
+++ b/tests/msc_vlr/msc_vlr_test_ms_timeout.c
@@ -33,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");
@@ -94,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");
@@ -125,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");
@@ -195,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");
@@ -296,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 b909f5299..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) == 19
-
===== 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,7 +84,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_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
@@ -128,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) == 19
-
===== test_ms_timeout_cm_auth_resp
- Total time passed: 0.000000 s
- Location Update request causes a GSUP Send Auth Info request to HLR
@@ -160,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)
@@ -198,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
@@ -358,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 (-)
@@ -401,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) == 19
-
===== test_ms_timeout_paging
- Total time passed: 0.000000 s
- Location Update request causes a GSUP LU request to HLR
@@ -433,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
@@ -646,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)
@@ -670,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
@@ -709,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) == 19
-
===== test_classmark_update_timeout
- Total time passed: 0.000000 s
- Location Update request causes a GSUP Send Auth Info request to HLR
@@ -741,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)
@@ -781,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
@@ -824,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
@@ -862,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) == 19
-
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 19
-
diff --git a/tests/msc_vlr/msc_vlr_test_no_authen.c b/tests/msc_vlr/msc_vlr_test_no_authen.c
index 9d506d6e7..5d3db69ae 100644
--- a/tests/msc_vlr/msc_vlr_test_no_authen.c
+++ b/tests/msc_vlr/msc_vlr_test_no_authen.c
@@ -34,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");
@@ -171,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");
@@ -316,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");
@@ -389,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");
@@ -464,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");
@@ -552,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");
@@ -628,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");
@@ -686,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");
@@ -742,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");
@@ -841,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");
@@ -915,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");
@@ -941,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 d53397621..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) == 19
-
===== 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) == 19
-
===== 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) == 19
-
===== 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) == 19
-
===== 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) == 19
-
===== 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) == 19
-
===== 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) == 19
-
===== 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) == 19
-
===== 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) == 19
-
===== 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) == 19
-
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 19
-
diff --git a/tests/msc_vlr/msc_vlr_test_reject_concurrency.c b/tests/msc_vlr/msc_vlr_test_reject_concurrency.c
index 648313f4d..dea0c291b 100644
--- a/tests/msc_vlr/msc_vlr_test_reject_concurrency.c
+++ b/tests/msc_vlr/msc_vlr_test_reject_concurrency.c
@@ -30,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");
@@ -73,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");
diff --git a/tests/msc_vlr/msc_vlr_test_reject_concurrency.err b/tests/msc_vlr/msc_vlr_test_reject_concurrency.err
index 5101b0684..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) == 19
-
===== 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) == 19
-
===== 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) == 19
-
===== 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) == 19
-
===== 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) == 19
-
===== 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) == 19
-
===== 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) == 19
-
===== 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) == 19
-
===== 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) == 19
-
===== 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) == 19
-
===== 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) == 19
-
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 19
-
diff --git a/tests/msc_vlr/msc_vlr_test_rest.c b/tests/msc_vlr/msc_vlr_test_rest.c
index 1b998adfb..029e8b5b7 100644
--- a/tests/msc_vlr/msc_vlr_test_rest.c
+++ b/tests/msc_vlr/msc_vlr_test_rest.c
@@ -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 fb10e6af5..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) == 19
-
===== 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) == 19
-
===== 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) == 19
-
===== 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) == 19
-
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 19
-
diff --git a/tests/msc_vlr/msc_vlr_test_ss.c b/tests/msc_vlr/msc_vlr_test_ss.c
index 978ceae17..772429e72 100644
--- a/tests/msc_vlr/msc_vlr_test_ss.c
+++ b/tests/msc_vlr/msc_vlr_test_ss.c
@@ -47,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 243f7e0d5..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) == 19
-
===== 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
@@ -185,6 +187,7 @@ DREF msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_CO
<-- 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
@@ -234,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) == 19
-
===== 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
@@ -265,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
@@ -397,7 +400,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)
@@ -410,6 +413,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()
@@ -423,6 +428,7 @@ 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
@@ -445,6 +451,7 @@ DREF msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHE
<-- GSUP rx OSMO_GSUP_MSGT_PROC_SS_REQUEST: 20010809710000004026f03004200001013101030a0103
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
@@ -494,9 +501,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 5)
===== test_ss_ussd_no_geran: SUCCESS
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 19
-
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 19
-
diff --git a/tests/msc_vlr/msc_vlr_test_umts_authen.c b/tests/msc_vlr/msc_vlr_test_umts_authen.c
index 761db55e2..0a2a4464b 100644
--- a/tests/msc_vlr/msc_vlr_test_umts_authen.c
+++ b/tests/msc_vlr/msc_vlr_test_umts_authen.c
@@ -50,7 +50,7 @@ static void _test_umts_authen(enum osmo_rat_type via_ran)
"d3d36ff71c949e83c22072799e9687c5ec32a81d96afcbf4b4fb"
"0c7ac3e9e9b7db05";
bool encryption = (via_ran == OSMO_RAT_GERAN_A && net->a5_encryption_mask > 0x1)
- || (via_ran == OSMO_RAT_UTRAN_IU && net->uea_encryption);
+ || (via_ran == OSMO_RAT_UTRAN_IU && net->uea_encryption_mask > (1 << OSMO_UTRAN_UEA0));
net->authentication_required = true;
net->vlr->cfg.assign_tmsi = true;
@@ -58,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 */
@@ -124,31 +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 (encryption) {
- if (via_ran == OSMO_RAT_GERAN_A) {
+ switch (via_ran) {
+ case OSMO_RAT_GERAN_A:
+ if (encryption) {
btw("Test code not implemented");
OSMO_ASSERT(false);
- } else {
- /* On UTRAN */
- btw("Encryption enabled. MS sends Authen Response, VLR accepts and sends SecurityModeControl");
- 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();
- VERBOSE_ASSERT(gsup_tx_confirmed, == true, "%d");
- VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
}
- } else {
- /* Encryption disabled */
+
btw("Encryption disabled. 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");
+ 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("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");
@@ -198,28 +205,35 @@ static void _test_umts_authen(enum osmo_rat_type via_ran)
EXPECT_ACCEPTED(false);
thwart_rx_non_initial_requests();
- if (encryption) {
- if (via_ran == OSMO_RAT_GERAN_A) {
+ switch (via_ran) {
+ case OSMO_RAT_GERAN_A:
+ if (encryption) {
btw("Test code not implemented");
OSMO_ASSERT(false);
- } else {
- /* On UTRAN */
- btw("Encryption enabled. MS sends Authen Response, VLR accepts and sends SecurityModeControl");
- 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();
- VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d");
}
- } else {
- /* Encryption disabled */
+
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");
+ 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(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 */
@@ -265,27 +279,34 @@ static void _test_umts_authen(enum osmo_rat_type via_ran)
EXPECT_ACCEPTED(false);
thwart_rx_non_initial_requests();
- if (encryption) {
- if (via_ran == OSMO_RAT_GERAN_A) {
+ switch (via_ran) {
+ case OSMO_RAT_GERAN_A:
+ if (encryption) {
btw("Test code not implemented");
OSMO_ASSERT(false);
- } else {
- /* On UTRAN */
- btw("Encryption enabled. MS sends Authen Response, VLR accepts and sends SecurityModeControl");
- 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();
}
- } else {
- /* Encryption disabled */
+
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");
+ 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(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");
@@ -333,7 +354,7 @@ static void test_umts_authen_geran()
static void test_umts_authen_utran()
{
comment_start();
- net->uea_encryption = false;
+ net->uea_encryption_mask = (1 << OSMO_UTRAN_UEA0);
_test_umts_authen(OSMO_RAT_UTRAN_IU);
comment_end();
}
@@ -341,7 +362,7 @@ static void test_umts_authen_utran()
static void test_umts_auth_ciph_utran()
{
comment_start();
- net->uea_encryption = true;
+ net->uea_encryption_mask = (1 << OSMO_UTRAN_UEA1) | (1 << OSMO_UTRAN_UEA2);
_test_umts_authen(OSMO_RAT_UTRAN_IU);
comment_end();
}
@@ -361,7 +382,7 @@ 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);
+ || (via_ran == OSMO_RAT_UTRAN_IU && net->uea_encryption_mask > (1 << OSMO_UTRAN_UEA0));
net->authentication_required = true;
net->vlr->cfg.assign_tmsi = true;
@@ -369,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 */
@@ -471,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 */);
@@ -516,31 +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 (encryption) {
- if (via_ran == OSMO_RAT_GERAN_A) {
+ switch (via_ran) {
+ case OSMO_RAT_GERAN_A:
+ if (encryption) {
btw("Test code not implemented");
OSMO_ASSERT(false);
- } else {
- /* On UTRAN */
- btw("Encryption enabled. MS sends Authen Response, VLR accepts and sends SecurityModeControl");
- 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();
- VERBOSE_ASSERT(gsup_tx_confirmed, == true, "%d");
- VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
}
- } else {
- /* Encryption disabled */
+
btw("Encryption disabled. 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" "1df5f0b4" "2104" "f22b696e");
VERBOSE_ASSERT(gsup_tx_confirmed, == true, "%d");
VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+ 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("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");
@@ -588,7 +616,7 @@ static void test_umts_authen_resync_geran()
static void test_umts_authen_resync_utran()
{
comment_start();
- net->uea_encryption = false;
+ net->uea_encryption_mask = (1 << OSMO_UTRAN_UEA0);
_test_umts_authen_resync(OSMO_RAT_UTRAN_IU);
comment_end();
}
@@ -596,7 +624,7 @@ static void test_umts_authen_resync_utran()
static void test_umts_auth_ciph_resync_utran()
{
comment_start();
- net->uea_encryption = true;
+ net->uea_encryption_mask = (1 << OSMO_UTRAN_UEA1) | (1 << OSMO_UTRAN_UEA2);
_test_umts_authen_resync(OSMO_RAT_UTRAN_IU);
comment_end();
}
@@ -609,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 */
@@ -709,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 */
@@ -809,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 */
diff --git a/tests/msc_vlr/msc_vlr_test_umts_authen.err b/tests/msc_vlr/msc_vlr_test_umts_authen.err
index cda55f50a..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) == 19
-
===== 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)
@@ -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
@@ -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)
@@ -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) == 19
-
===== 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
@@ -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
-- Encryption disabled. MS sends Authen Response, VLR accepts and sends GSUP LU Req to HLR
+- 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,20 +673,30 @@ 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}: vlr_loc_upd_post_ciph()
+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_AUTH}: vlr_loc_upd_node_4()
-DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
+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
-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)
gsup_tx_confirmed == 1
lu_result_sent == 0
- HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT
@@ -859,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
-- Encryption disabled. MS sends Authen Response, VLR accepts with a CM Service Accept
+- 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
@@ -874,24 +889,31 @@ DVLR VLR_Authenticate(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu
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}: _proc_arq_vlr_node2_post_ciph()
+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_AUTH}: _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_AUTH}: _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_AUTH}: _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_AUTH}: _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_AUTH}: 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_AUTH}: 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_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}: RAN encode: DTAP on UTRAN-Iu
-- DTAP --UTRAN-Iu--> MS: GSM48_MT_MM_CM_SERV_ACC: 0521
-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
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
-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_AUTHENTICATED}: - rx_from_ms: now used by 1 (cm_service_sms)
- cm_service_result_sent == 1
+ 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
@@ -971,7 +993,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)
@@ -1014,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
-- Encryption disabled. MS sends Authen Response, VLR accepts and sends pending SMS
+- 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
@@ -1029,36 +1051,45 @@ DVLR VLR_Authenticate(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu
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}: _proc_arq_vlr_node2_post_ciph()
+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_AUTH}: _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_AUTH}: _proc_arq_vlr_post_pres()
-DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_trace()
-DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_imei()
-DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){PR_ARQ_S_WAIT_AUTH}: proc_arq_fsm_done(PASSED)
-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_DONE
+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-0x40000002 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 3 (paging-response,rx_from_ms,sms)
+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-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
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 2 (rx_from_ms,sms)
-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_AUTHENTICATED}: - rx_from_ms: now used by 1 (sms)
- dtap_tx_confirmed == 1
+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
@@ -1086,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
@@ -1128,7 +1160,7 @@ DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x0302010
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 3
+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
@@ -1158,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
@@ -1203,9 +1236,6 @@ 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) == 19
-
===== 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
@@ -1234,13 +1264,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)
@@ -1273,7 +1304,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
@@ -1593,7 +1624,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)
@@ -1683,6 +1714,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-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
@@ -1716,6 +1748,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-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
@@ -1788,12 +1821,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
@@ -1833,9 +1867,6 @@ DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:NONE){MSC_
llist_count(&msub_list) == 0
===== test_umts_auth_ciph_utran: SUCCESS
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 19
-
===== test_umts_authen_resync_geran
- Location Update request causes a GSUP Send Auth Info request to HLR
MSC <--GERAN-A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
@@ -1864,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)
@@ -1897,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
@@ -1931,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
@@ -2065,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) == 19
-
===== 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
@@ -2096,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)
@@ -2129,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
@@ -2150,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
-- Encryption disabled. MS sends Authen Response, VLR accepts and sends GSUP LU Req to HLR
+- 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
@@ -2163,20 +2195,30 @@ 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}: vlr_loc_upd_post_ciph()
+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_AUTH}: vlr_loc_upd_node_4()
-DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
+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
-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)
gsup_tx_confirmed == 1
lu_result_sent == 0
- HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT
@@ -2299,9 +2341,6 @@ 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) == 19
-
===== 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
@@ -2330,13 +2369,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)
@@ -2363,7 +2403,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
@@ -2397,7 +2437,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
@@ -2543,9 +2583,6 @@ 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_auth_ciph_resync_utran: SUCCESS
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 19
-
===== test_umts_authen_too_short_res_geran
- Location Update request causes a GSUP Send Auth Info request to HLR
MSC <--GERAN-A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
@@ -2574,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)
@@ -2609,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
@@ -2661,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) == 19
-
===== 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
@@ -2692,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)
@@ -2727,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
@@ -2779,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) == 19
-
===== 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
@@ -2810,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)
@@ -2845,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
@@ -2897,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) == 19
-
===== 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
@@ -2928,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)
@@ -2963,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
@@ -3015,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) == 19
-
===== 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
@@ -3046,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)
@@ -3081,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
@@ -3133,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) == 19
-
===== 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
@@ -3164,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)
@@ -3199,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
@@ -3251,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) == 19
-
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 19
-
diff --git a/tests/msc_vlr/msc_vlr_tests.c b/tests/msc_vlr/msc_vlr_tests.c
index 3d69ae865..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);
@@ -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) {
@@ -763,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;
@@ -882,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))
@@ -924,40 +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) == 19
- * full talloc report on 'msc_vlr_tests_ctx' (total 6532 bytes in 19 blocks)
- * struct osmo_gsup_client contains 256 bytes in 1 blocks (ref 0) 0x56143306aa10
- * struct gsm_network contains 4775 bytes in 11 blocks (ref 0) 0x5614330697e0
- * struct mgcp_client contains 688 bytes in 1 blocks (ref 0) 0x56143306ad80
- * struct sccp_ran_inst contains 152 bytes in 1 blocks (ref 0) 0x56143306ac80
- * struct sccp_ran_inst contains 152 bytes in 1 blocks (ref 0) 0x56143306ab80
- * struct gsup_client_mux contains 152 bytes in 2 blocks (ref 0) 0x56143306a8a0
- * struct ipaccess_unit contains 64 bytes in 1 blocks (ref 0) 0x56143306a960
- * struct vlr_instance contains 248 bytes in 1 blocks (ref 0) 0x56143306a740
- * no_gsup_server contains 15 bytes in 1 blocks (ref 0) 0x56143306a6c0
- * stat_item.c:96 contains 144 bytes in 2 blocks (ref 0) 0x56143306a550
- * stat_item.c:118 contains 96 bytes in 1 blocks (ref 0) 0x56143306a5f0
- * rate_ctr.c:234 contains 2352 bytes in 1 blocks (ref 0) 0x561433069bb0
- * logging contains 1501 bytes in 5 blocks (ref 0) 0x561433068fe0
- * struct log_target contains 244 bytes in 2 blocks (ref 0) 0x561433069610
- * struct log_category contains 76 bytes in 1 blocks (ref 0) 0x561433069720
- * struct log_info contains 1256 bytes in 2 blocks (ref 0) 0x561433069050
- * struct log_info_cat contains 1216 bytes in 1 blocks (ref 0) 0x5614330690e0
- * msgb contains 0 bytes in 1 blocks (ref 0) 0x561433068f70
- */
- 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) != 19)
- talloc_report_full(msc_vlr_tests_ctx, stderr);
- fprintf(stderr, "\n");
-}
-
static struct {
bool verbose;
int run_test_nr;
@@ -1009,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;
@@ -1071,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;
}
@@ -1093,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);
@@ -1135,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 4918be233..cc78e1491 100644
--- a/tests/sms_queue/sms_queue_test.c
+++ b/tests/sms_queue/sms_queue_test.c
@@ -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/stubs.c b/tests/stubs.c
index d011a312a..f4ccb48c7 100644
--- a/tests/stubs.c
+++ b/tests/stubs.c
@@ -37,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 a4e0e15db..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,9 +16,9 @@ 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)
@@ -24,16 +26,16 @@ OsmoMSC(config-net)# list
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. NOTE: the current implementation does not allow free choice of combining encryption algorithms yet. The only valid settings are either 'encryption uea 0' or 'encryption uea 1 2'.
+ 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
@@ -49,6 +51,8 @@ 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>
@@ -59,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?
@@ -96,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
@@ -152,8 +159,9 @@ network
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
@@ -161,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
@@ -171,10 +176,21 @@ 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
@@ -186,38 +202,27 @@ OsmoMSC(config-net)# show running-config
...
OsmoMSC(config-net)# encryption uea 1
-% Error: the current implementation does not allow free choice of combining
-% encryption algorithms yet. The only valid settings are either
-% encryption uea 0
-% or
-% encryption uea 1 2
OsmoMSC(config-net)# show running-config
...
- encryption uea 0
+ encryption uea 1
...
OsmoMSC(config-net)# encryption uea 2
-% Error: the current implementation does not allow free choice of combining
-...
OsmoMSC(config-net)# show running-config
...
- encryption uea 0
+ encryption uea 2
...
OsmoMSC(config-net)# encryption uea 0 1
-% Error: the current implementation does not allow free choice of combining
-...
OsmoMSC(config-net)# show running-config
...
- encryption uea 0
+ encryption uea 0 1
...
OsmoMSC(config-net)# encryption uea 0 2
-% Error: the current implementation does not allow free choice of combining
-...
OsmoMSC(config-net)# show running-config
...
- encryption uea 0
+ encryption uea 0 2
...
OsmoMSC(config-net)# encryption uea 1 2
diff --git a/tests/testsuite.at b/tests/testsuite.at
index c0788b9ab..fbf594b48 100644
--- a/tests/testsuite.at
+++ b/tests/testsuite.at
@@ -107,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))