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.ac60
-rwxr-xr-xcontrib/jenkins.sh26
-rw-r--r--contrib/osmo-msc.spec.in118
-rw-r--r--contrib/systemd/osmo-msc.service4
-rw-r--r--debian/changelog812
-rw-r--r--debian/compat2
-rw-r--r--debian/control43
-rw-r--r--debian/copyright2
-rw-r--r--debian/osmo-msc-doc.install1
-rwxr-xr-xdebian/rules6
-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.am7
-rw-r--r--doc/manuals/chapters/counters_generated.adoc60
-rw-r--r--doc/manuals/chapters/net.adoc83
-rw-r--r--doc/manuals/chapters/osmux_msc.adoc65
-rw-r--r--doc/manuals/chapters/running.adoc100
-rw-r--r--doc/manuals/chapters/sgs.adoc55
-rw-r--r--doc/manuals/osmomsc-usermanual.adoc17
-rwxr-xr-xdoc/manuals/regen_doc.sh17
-rw-r--r--doc/manuals/vty/msc_vty_reference.xml2686
-rw-r--r--doc/sequence_charts/Makefile.am15
-rw-r--r--doc/sequence_charts/call_reestablishment.msc33
-rw-r--r--doc/sequence_charts/mncc_call_fsm.msc104
-rw-r--r--doc/sequence_charts/mncc_fsm.msc84
-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.h6
-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.h22
-rw-r--r--include/osmocom/msc/gsm_data.h118
-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.h5
-rw-r--r--include/osmocom/msc/msc_a.h24
-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.h76
-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.h32
-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_iface.h1
-rw-r--r--include/osmocom/msc/sgs_server.h2
-rw-r--r--include/osmocom/msc/signal.h11
-rw-r--r--include/osmocom/msc/smpp.h4
-rw-r--r--include/osmocom/msc/sms_queue.h18
-rw-r--r--include/osmocom/msc/transaction.h80
-rw-r--r--include/osmocom/msc/transaction_cc.h39
-rw-r--r--include/osmocom/msc/vlr.h60
-rw-r--r--include/osmocom/msc/vlr_sgs.h9
-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.c106
-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.c1247
-rw-r--r--src/libmsc/e_link.c2
-rw-r--r--src/libmsc/gsm_04_08.c509
-rw-r--r--src/libmsc/gsm_04_08_cc.c766
-rw-r--r--src/libmsc/gsm_04_11.c130
-rw-r--r--src/libmsc/gsm_04_11_gsup.c118
-rw-r--r--src/libmsc/gsm_04_14.c2
-rw-r--r--src/libmsc/gsm_09_11.c177
-rw-r--r--src/libmsc/gsup_client_mux.c50
-rw-r--r--src/libmsc/mncc.c43
-rw-r--r--src/libmsc/mncc_builtin.c25
-rw-r--r--src/libmsc/mncc_call.c72
-rw-r--r--src/libmsc/mncc_sock.c41
-rw-r--r--src/libmsc/msc_a.c691
-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.c48
-rw-r--r--src/libmsc/msc_t.c44
-rw-r--r--src/libmsc/msc_t_remote.c2
-rw-r--r--src/libmsc/msc_vgcs.c2765
-rw-r--r--src/libmsc/msc_vty.c859
-rw-r--r--src/libmsc/msub.c10
-rw-r--r--src/libmsc/neighbor_ident.c2
-rw-r--r--src/libmsc/paging.c52
-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.c896
-rw-r--r--src/libmsc/ran_msg_iu.c94
-rw-r--r--src/libmsc/ran_peer.c88
-rw-r--r--src/libmsc/rtp_stream.c218
-rw-r--r--src/libmsc/sccp_ran.c2
-rw-r--r--src/libmsc/sdp_msg.c686
-rw-r--r--src/libmsc/sgs_iface.c148
-rw-r--r--src/libmsc/silent_call.c6
-rw-r--r--src/libmsc/smpp_utils.c61
-rw-r--r--src/libmsc/sms_queue.c286
-rw-r--r--src/libmsc/smsc_vty.c214
-rw-r--r--src/libmsc/transaction.c131
-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)72
-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.c486
-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.c131
-rw-r--r--src/libvlr/vlr_sgs.c29
-rw-r--r--src/libvlr/vlr_sgs_fsm.c62
-rw-r--r--src/osmo-msc/Makefile.am13
-rw-r--r--src/osmo-msc/msc_main.c285
-rw-r--r--src/utils/Makefile.am14
-rw-r--r--src/utils/smpp_mirror.c124
-rw-r--r--tests/Makefile.am40
-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.am55
-rw-r--r--tests/db_sms/db_sms_test.c576
-rw-r--r--tests/db_sms/db_sms_test.err0
-rw-r--r--tests/db_sms/db_sms_test.ok74
-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.am23
-rw-r--r--tests/msc_vlr/msc_vlr_test_authen_reuse.c15
-rw-r--r--tests/msc_vlr/msc_vlr_test_authen_reuse.err105
-rw-r--r--tests/msc_vlr/msc_vlr_test_call.c1138
-rw-r--r--tests/msc_vlr/msc_vlr_test_call.err5323
-rw-r--r--tests/msc_vlr/msc_vlr_test_gsm_authen.c39
-rw-r--r--tests/msc_vlr/msc_vlr_test_gsm_authen.err150
-rw-r--r--tests/msc_vlr/msc_vlr_test_gsm_ciph.c47
-rw-r--r--tests/msc_vlr/msc_vlr_test_gsm_ciph.err166
-rw-r--r--tests/msc_vlr/msc_vlr_test_hlr_reject.c31
-rw-r--r--tests/msc_vlr/msc_vlr_test_hlr_reject.err106
-rw-r--r--tests/msc_vlr/msc_vlr_test_hlr_timeout.c5
-rw-r--r--tests/msc_vlr/msc_vlr_test_hlr_timeout.err23
-rw-r--r--tests/msc_vlr/msc_vlr_test_ms_timeout.c11
-rw-r--r--tests/msc_vlr/msc_vlr_test_ms_timeout.err44
-rw-r--r--tests/msc_vlr/msc_vlr_test_no_authen.c29
-rw-r--r--tests/msc_vlr/msc_vlr_test_no_authen.err131
-rw-r--r--tests/msc_vlr/msc_vlr_test_reject_concurrency.c7
-rw-r--r--tests/msc_vlr/msc_vlr_test_reject_concurrency.err116
-rw-r--r--tests/msc_vlr/msc_vlr_test_rest.c8
-rw-r--r--tests/msc_vlr/msc_vlr_test_rest.err54
-rw-r--r--tests/msc_vlr/msc_vlr_test_ss.c3
-rw-r--r--tests/msc_vlr/msc_vlr_test_ss.err80
-rw-r--r--tests/msc_vlr/msc_vlr_test_umts_authen.c145
-rw-r--r--tests/msc_vlr/msc_vlr_test_umts_authen.err1019
-rw-r--r--tests/msc_vlr/msc_vlr_tests.c284
-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.c25
-rw-r--r--tests/stubs.c (renamed from tests/msc_vlr/stubs.h)13
-rw-r--r--tests/test_nodes.vty105
-rw-r--r--tests/testsuite.at29
-rwxr-xr-xtests/vty_test_runner.py97
209 files changed, 26581 insertions, 7161 deletions
diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
new file mode 100644
index 000000000..7592debf9
--- /dev/null
+++ b/.github/FUNDING.yml
@@ -0,0 +1 @@
+open_collective: osmocom
diff --git a/.gitignore b/.gitignore
index bcd684787..412e5f164 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,11 @@
debian/*.log
+debian/autoreconf.*
+debian/*.substvars
+debian/tmp
+debian/files
+debian/.debhelper
+debian/osmo-msc*/
+
*.o
*.lo
*.a
@@ -15,6 +22,7 @@ config.h.in
*.pyc
*.gcda
*.gcno
+*~
#configure
aclocal.m4
@@ -72,3 +80,6 @@ doc/manuals/generated/
doc/manuals/osmomsc-usermanual.xml
doc/manuals/common
doc/manuals/build
+doc/manuals/vty/msc_vty_reference.xml
+
+contrib/osmo-msc.spec
diff --git a/Makefile.am b/Makefile.am
index 3f89896a3..13a7313f4 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -9,15 +9,22 @@ AM_CPPFLAGS = \
$(NULL)
SUBDIRS = \
- doc \
include \
src \
+ doc \
contrib \
tests \
$(NULL)
BUILT_SOURCES = $(top_srcdir)/.version
-EXTRA_DIST = git-version-gen osmoappdesc.py .version
+EXTRA_DIST = \
+ .version \
+ README.md \
+ contrib/osmo-msc.spec.in \
+ debian \
+ git-version-gen \
+ osmoappdesc.py \
+ $(NULL)
AM_DISTCHECK_CONFIGURE_FLAGS = \
--with-systemdsystemunitdir=$$dc_install_base/$(systemdsystemunitdir)
diff --git a/README b/README
deleted file mode 100644
index a45ef951e..000000000
--- a/README
+++ /dev/null
@@ -1,24 +0,0 @@
-About OsmoMSC
-=============
-
-OsmoMSC originated from the OpenBSC project, which started as a minimalistic
-all-in-one implementation of the GSM Network. In 2017, OpenBSC had reached
-maturity and diversity (including M3UA SIGTRAN and 3G support in the form of
-IuCS and IuPS interfaces) that naturally lead to a separation of the all-in-one
-approach to fully independent separate programs as in typical GSM networks.
-
-OsmoMSC was one of the parts split off from the old openbsc.git. Before, it was
-the libmsc part of the old OsmoNITB. Since a true A interface and IuCS for 3G
-support is available, OsmoMSC exists only as a separate standalone entity.
-
-OsmoMSC exposes
-- GSUP towards OsmoHLR (or a MAP proxy);
-- A over IP towards a BSC (e.g. OsmoBSC);
-- IuCS towards an RNC or HNB-GW (e.g. OsmoHNBGW) for 3G voice;
-- MNCC (Mobile Network Call Control derived from GSM TS 04.07);
-- SMPP 3.4 (Short Message Peer-to-Peer);
-- The Osmocom typical telnet VTY and CTRL interfaces.
-
-Find OsmoMSC issue tracker and wiki online at
-https://osmocom.org/projects/osmomsc
-https://osmocom.org/projects/osmomsc/wiki
diff --git a/README.md b/README.md
new file mode 100644
index 000000000..df1cb5fc0
--- /dev/null
+++ b/README.md
@@ -0,0 +1,110 @@
+osmo-msc - Osmocom MSC Implementation
+=====================================
+
+This repository contains a C-language implementation of a GSM **Mobile Switching
+Centre (MSC)** for 2G (GSM) and 3G (UMTS). It is part of the
+[Osmocom](https://osmocom.org/) Open Source Mobile Communications
+project.
+
+OsmoMSC exposes
+
+ * *A over IP* towards BSCs (e.g. [osmo-bsc](https://osmocom.org/projects/osmobsc/wiki): 3GPP AoIP or SCCPlite
+ * *IuCS over IP* towards RNCs / HNBGW (e.g. [osmo-hnbgw](https://osmocom.org/projects/osmohnbgw/wiki))
+ * *MGCP* towards a co-located [osmo-mgw](https://osmocom.org/projects/osmo-mgw/wiki) for the RTP streams
+ * *[GSUP](https://osmocom.org/projects/cellular-infrastructure/wiki/GSUP)* (instead of 3GPP MAP) towards [osmo-hlr](https://osmocom.org/projects/osmo-hlr/wiki)
+ * *SMPP* towards any external SMS sending/receiving applications
+ * *[MNCC](https://osmocom.org/projects/osmomsc/wiki/MNCC)* as external call-control interface towards e.g.
+ [osmo-sip-connectr](https://osmocom.org/projects/osmo-sip-conector/wiki)
+ * The Osmocom typical telnet *VTY* and *CTRL* interfaces.
+ * The Osmocom typical *statsd* exporter.
+
+OsmoMSC implements
+
+ * mobility management
+ * call control (either via built-in MNCC handler or external osmo-sip-connector)
+ * voice group call ([VGCS](https://osmocom.org/projects/cellular-infrastructure/wiki/Voice_Group_Call)) and
+ voice broadcast calls ([VBS](https://osmocom.org/projects/cellular-infrastructure/wiki/Voice_Broadcast_Call)) as used in GSM-R
+ * USSD (exposed via GSUP)
+ * SMS (either via built-in SMSC or external via GSUP)
+
+Homepage
+--------
+
+You can find the OsmoMSC home page and wiki online at
+<https://osmocom.org/projects/osmomsc/wiki>.
+
+
+GIT Repository
+--------------
+
+You can clone from the official osmo-msc.git repository using
+
+ git clone https://gitea.osmocom.org/cellular-infrastructure/osmo-msc
+
+There is a web interface at <https://gitea.osmocom.org/cellular-infrastructure/osmo-msc>
+
+
+Documentation
+-------------
+
+User Manuals and VTY reference manuals are [optionally] built in PDF form
+as part of the build process.
+
+Pre-rendered PDF version of the current "master" can be found at
+[User Manual](https://ftp.osmocom.org/docs/latest/osmomsc-usermanual.pdf)
+as well as the [VTY Reference Manual](https://ftp.osmocom.org/docs/latest/osmomsc-vty-reference.pdf)
+
+
+Forum
+-----
+
+We welcome any osmo-msc related discussions in the
+[Cellular Network Infrastructure -> 2G/3G CN](https://discourse.osmocom.org/c/cni/2g-3g-cn)
+section of the osmocom discourse (web based Forum).
+
+
+Mailing List
+------------
+
+Discussions related to osmo-msc are happening on the
+openbsc@lists.osmocom.org mailing list, please see
+<https://lists.osmocom.org/mailman/listinfo/openbsc> for subscription
+options and the list archive.
+
+Please observe the [Osmocom Mailing List
+Rules](https://osmocom.org/projects/cellular-infrastructure/wiki/Mailing_List_Rules)
+when posting.
+
+Issue Tracker
+-------------
+
+We use the [issue tracker of the osmo-msc project on osmocom.org](https://osmocom.org/projects/osmomsc/issues) for
+tracking the state of bug reports and feature requests. Feel free to submit any issues you may find, or help
+us out by resolving existing issues.
+
+
+Contributing
+------------
+
+Our coding standards are described at
+<https://osmocom.org/projects/cellular-infrastructure/wiki/Coding_standards>
+
+We us a gerrit based patch submission/review process for managing
+contributions. Please see
+<https://osmocom.org/projects/cellular-infrastructure/wiki/Gerrit> for
+more details
+
+The current patch queue for osmo-msc can be seen at
+<https://gerrit.osmocom.org/#/q/project:osmo-msc+status:open>
+
+
+History
+-------
+
+OsmoMSC originated from the [OsmoNITB](https://osmocom.org/projects/osmonitb/wiki/OsmoNITB)
+project, which started as a minimalistic all-in-one implementation of the GSM Network. In 2017, OsmoNITB had
+reached maturity and diversity (including M3UA SIGTRAN and 3G support in the form of IuCS and IuPS interfaces)
+that naturally lead to a separation of the all-in-one approach to fully independent separate programs as in
+typical GSM networks.
+
+OsmoMSC was one of the parts split off from the old openbsc.git.
diff --git a/README.vty-tests b/README.vty-tests
index 0669ea8e8..dc34916ee 100644
--- a/README.vty-tests
+++ b/README.vty-tests
@@ -1,6 +1,6 @@
To run the configuration parsing and output (VTY) test suite, first install
- git://git.osmocom.org/python/osmo-python-tests
+ https://gitea.osmocom.org/cellular-infrastructure/osmo-python-tests
and pass the following configure options here:
diff --git a/TODO-RELEASE b/TODO-RELEASE
new file mode 100644
index 000000000..8b07972f3
--- /dev/null
+++ b/TODO-RELEASE
@@ -0,0 +1,10 @@
+# When cleaning up this file: bump API version in corresponding Makefile.am and rename corresponding debian/lib*.install
+# according to https://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html#Updating-version-info
+# In short:
+# LIBVERSION=c:r:a
+# If the library source code has changed at all since the last update, then increment revision: c:r + 1:a.
+# If any interfaces have been added, removed, or changed since the last update: c + 1:0:0.
+# If any interfaces have been added since the last public release: c:r:a + 1.
+# If any interfaces have been removed or changed since the last public release: c:r:0.
+#library what description / commit summary line
+libosmogsm >1.9.0 ABI breakage in struct osmo_gsup_pdp_info, use new fields pdp_type_* and pdp_address. \ No newline at end of file
diff --git a/configure.ac b/configure.ac
index 36ff99e3c..89d37c2e6 100644
--- a/configure.ac
+++ b/configure.ac
@@ -9,6 +9,8 @@ AC_CONFIG_AUX_DIR([.])
AM_INIT_AUTOMAKE([dist-bzip2])
AC_CONFIG_TESTDIR(tests)
+CFLAGS="$CFLAGS -std=gnu11"
+
dnl kernel style compile messages
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
@@ -22,6 +24,11 @@ AC_PROG_CC
AC_PROG_INSTALL
LT_INIT
+dnl patching ${archive_cmds} to affect generation of file "libtool" to fix linking with clang
+AS_CASE(["$LD"],[*clang*],
+ [AS_CASE(["${host_os}"],
+ [*linux*],[archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'])])
+
dnl check for pkg-config (explained in detail in libosmocore/configure.ac)
AC_PATH_PROG(PKG_CONFIG_INSTALLED, pkg-config, no)
if test "x$PKG_CONFIG_INSTALLED" = "xno"; then
@@ -29,22 +36,19 @@ if test "x$PKG_CONFIG_INSTALLED" = "xno"; then
fi
PKG_PROG_PKG_CONFIG([0.20])
-dnl check for AX_CHECK_COMPILE_FLAG
-m4_ifdef([AX_CHECK_COMPILE_FLAG], [], [
- AC_MSG_ERROR([Please install autoconf-archive; re-run 'autoreconf -fi' for it to take effect.])
- ])
-
+PKG_CHECK_MODULES(LIBSQLITE3, sqlite3)
+PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore >= 1.9.0)
+PKG_CHECK_MODULES(LIBOSMOVTY, libosmovty >= 1.9.0)
+PKG_CHECK_MODULES(LIBOSMOCTRL, libosmoctrl >= 1.9.0)
+PKG_CHECK_MODULES(LIBOSMOGSM, libosmogsm >= 1.9.0)
+PKG_CHECK_MODULES(LIBOSMOABIS, libosmoabis >= 1.5.0)
+PKG_CHECK_MODULES(LIBOSMONETIF, libosmo-netif >= 1.4.0)
+PKG_CHECK_MODULES(LIBOSMOSIGTRAN, libosmo-sigtran >= 1.8.0)
+PKG_CHECK_MODULES(LIBOSMOSCCP, libosmo-sccp >= 1.8.0)
+PKG_CHECK_MODULES(LIBOSMOMGCPCLIENT, libosmo-mgcp-client >= 1.12.0)
+PKG_CHECK_MODULES(LIBOSMOGSUPCLIENT, libosmo-gsup-client >= 1.7.0)
-PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore >= 1.0.0)
-PKG_CHECK_MODULES(LIBOSMOVTY, libosmovty >= 1.0.0)
-PKG_CHECK_MODULES(LIBOSMOCTRL, libosmoctrl >= 1.0.0)
-PKG_CHECK_MODULES(LIBOSMOGSM, libosmogsm >= 1.0.0)
-PKG_CHECK_MODULES(LIBOSMOABIS, libosmoabis >= 0.6.0)
-PKG_CHECK_MODULES(LIBOSMONETIF, libosmo-netif >= 0.4.0)
-PKG_CHECK_MODULES(LIBOSMOSIGTRAN, libosmo-sigtran >= 1.0.0)
-PKG_CHECK_MODULES(LIBOSMOSCCP, libosmo-sccp >= 1.0.0)
-PKG_CHECK_MODULES(LIBOSMOMGCPCLIENT, libosmo-mgcp-client >= 1.5.0)
-PKG_CHECK_MODULES(LIBOSMOGSUPCLIENT, libosmo-gsup-client >= 1.0.0)
+AC_CHECK_FUNC([timegm], [AC_DEFINE(HAVE_TIMEGM, 1, Define if libc implements timegm)])
old_LIBS=$LIBS
AC_SEARCH_LIBS([sctp_send], [sctp], [
@@ -91,7 +95,7 @@ fi
AC_ARG_ENABLE([smpp], [AS_HELP_STRING([--enable-smpp], [Build the SMPP interface])],
[osmo_ac_build_smpp="$enableval"],[osmo_ac_build_smpp="no"])
if test "$osmo_ac_build_smpp" = "yes" ; then
- PKG_CHECK_MODULES(LIBSMPP34, libsmpp34 >= 1.13.0)
+ PKG_CHECK_MODULES(LIBSMPP34, libsmpp34 >= 1.14.0)
AC_DEFINE(BUILD_SMPP, 1, [Define if we want to build SMPP])
fi
AM_CONDITIONAL(BUILD_SMPP, test "x$osmo_ac_build_smpp" = "xyes")
@@ -102,25 +106,12 @@ AC_ARG_ENABLE([iu], [AS_HELP_STRING([--enable-iu], [Build 3G support, aka IuPS a
[osmo_ac_iu="$enableval"],[osmo_ac_iu="no"])
if test "x$osmo_ac_iu" = "xyes" ; then
PKG_CHECK_MODULES(LIBASN1C, libasn1c >= 0.9.30)
- PKG_CHECK_MODULES(LIBOSMORANAP, libosmo-ranap >= 0.3.0)
+ PKG_CHECK_MODULES(LIBOSMORANAP, libosmo-ranap >= 1.5.0)
AC_DEFINE(BUILD_IU, 1, [Define if we want to build IuPS and IuCS interfaces support])
fi
AM_CONDITIONAL(BUILD_IU, test "x$osmo_ac_iu" = "xyes")
AC_SUBST(osmo_ac_iu)
-dnl checks for header files
-AC_HEADER_STDC
-AC_CHECK_HEADERS(dbi/dbd.h,,AC_MSG_ERROR(DBI library is not installed))
-
-
-dnl Checks for typedefs, structures and compiler characteristics
-AX_CHECK_COMPILE_FLAG([-Werror=implicit], [CFLAGS="$CFLAGS -Werror=implicit"])
-AX_CHECK_COMPILE_FLAG([-Werror=maybe-uninitialized], [CFLAGS="$CFLAGS -Werror=maybe-uninitialized"])
-AX_CHECK_COMPILE_FLAG([-Werror=memset-transposed-args], [CFLAGS="$CFLAGS -Werror=memset-transposed-args"])
-AX_CHECK_COMPILE_FLAG([-Werror=null-dereference], [CFLAGS="$CFLAGS -Werror=null-dereference"])
-AX_CHECK_COMPILE_FLAG([-Werror=sizeof-array-argument], [CFLAGS="$CFLAGS -Werror=sizeof-array-argument"])
-AX_CHECK_COMPILE_FLAG([-Werror=sizeof-pointer-memaccess], [CFLAGS="$CFLAGS -Werror=sizeof-pointer-memaccess"])
-
# Coverage build taken from WebKit's configure.in
AC_MSG_CHECKING([whether to enable code coverage support])
AC_ARG_ENABLE(coverage,
@@ -168,7 +159,7 @@ if test "x$enable_ext_tests" = "xyes" ; then
AM_PATH_PYTHON
AC_CHECK_PROG(OSMOTESTEXT_CHECK,osmotestvty.py,yes)
if test "x$OSMOTESTEXT_CHECK" != "xyes" ; then
- AC_MSG_ERROR([Please install git://osmocom.org/python/osmo-python-tests to run the VTY/CTRL tests.])
+ AC_MSG_ERROR([Please install https://gitea.osmocom.org/cellular-infrastructure/osmo-python-tests to run the VTY/CTRL tests.])
fi
fi
AC_MSG_CHECKING([whether to enable VTY/CTRL tests])
@@ -243,20 +234,27 @@ AC_OUTPUT(
include/Makefile
include/osmocom/Makefile
include/osmocom/msc/Makefile
+ include/osmocom/smpp/Makefile
src/Makefile
src/libmsc/Makefile
src/libvlr/Makefile
+ src/libsmpputil/Makefile
src/osmo-msc/Makefile
src/utils/Makefile
tests/Makefile
tests/atlocal
tests/smpp/Makefile
+ tests/db_sms/Makefile
tests/sms_queue/Makefile
tests/msc_vlr/Makefile
+ tests/sdp_msg/Makefile
+ tests/mncc/Makefile
+ tests/csd/Makefile
doc/Makefile
doc/examples/Makefile
doc/manuals/Makefile
doc/sequence_charts/Makefile
contrib/Makefile
contrib/systemd/Makefile
+ contrib/osmo-msc.spec
Makefile)
diff --git a/contrib/jenkins.sh b/contrib/jenkins.sh
index be8dadcf7..c5161eff6 100755
--- a/contrib/jenkins.sh
+++ b/contrib/jenkins.sh
@@ -5,6 +5,7 @@
# * IU: configure 3G support (values: "--enable-iu", "--disable-iu")
# * WITH_MANUALS: build manual PDFs if set to "1"
# * PUBLISH: upload manuals after building if set to "1" (ignored without WITH_MANUALS = "1")
+# * IS_MASTER_BUILD: set to 1 when running from master-builds (not gerrit-verifications)
#
if ! [ -x "$(command -v osmo-build-dep.sh)" ]; then
@@ -12,6 +13,14 @@ if ! [ -x "$(command -v osmo-build-dep.sh)" ]; then
exit 2
fi
+exit_tar_workspace() {
+ if [ "$IS_MASTER_BUILD" = "1" ]; then
+ tar -cJf "/tmp/workspace.tar.xz" "$base"
+ mv /tmp/workspace.tar.xz "$base"
+ fi
+
+ cat-testlogs.sh
+}
set -ex
@@ -35,23 +44,19 @@ export PATH="$inst/bin:$PATH"
osmo-build-dep.sh libosmo-abis
osmo-build-dep.sh libosmo-netif
osmo-build-dep.sh libosmo-sccp
-PARALLEL_MAKE="" osmo-build-dep.sh libsmpp34
+osmo-build-dep.sh libsmpp34
osmo-build-dep.sh osmo-mgw
osmo-build-dep.sh osmo-hlr
-enable_werror=""
if [ "x$IU" = "x--enable-iu" ]; then
osmo-build-dep.sh libasn1c
#osmo-build-dep.sh asn1c aper-prefix # only needed for make regen in osmo-iuh
osmo-build-dep.sh osmo-iuh
-else
- enable_werror="--enable-werror"
fi
# Additional configure options and depends
CONFIG=""
if [ "$WITH_MANUALS" = "1" ]; then
- osmo-build-dep.sh osmo-gsm-manuals
CONFIG="--enable-manuals"
fi
@@ -65,17 +70,18 @@ set -x
cd "$base"
autoreconf --install --force
-./configure --enable-sanitize $enable_werror --enable-smpp $IU --enable-external-tests $CONFIG
+./configure --enable-sanitize --enable-werror --enable-smpp $IU --enable-external-tests $CONFIG
$MAKE $PARALLEL_MAKE
LD_LIBRARY_PATH="$inst/lib" $MAKE check \
- || cat-testlogs.sh
+ || exit_tar_workspace
LD_LIBRARY_PATH="$inst/lib" \
- DISTCHECK_CONFIGURE_FLAGS="$enable_werror --enable-smpp $IU --enable-external-tests $CONFIG" \
- $MAKE distcheck \
- || cat-testlogs.sh
+ DISTCHECK_CONFIGURE_FLAGS="--enable-werror --enable-smpp $IU --enable-external-tests $CONFIG" \
+ $MAKE $PARALLEL_MAKE distcheck \
+ || exit_tar_workspace
if [ "$WITH_MANUALS" = "1" ] && [ "$PUBLISH" = "1" ]; then
make -C "$base/doc/manuals" publish
fi
+$MAKE $PARALLEL_MAKE maintainer-clean
osmo-clean-workspace.sh
diff --git a/contrib/osmo-msc.spec.in b/contrib/osmo-msc.spec.in
new file mode 100644
index 000000000..de9314926
--- /dev/null
+++ b/contrib/osmo-msc.spec.in
@@ -0,0 +1,118 @@
+#
+# spec file for package osmo-msc
+#
+# Copyright (c) 2017, Martin Hauke <mardnh@gmx.de>
+#
+# All modifications and additions to the file contributed by third parties
+# remain the property of their copyright owners, unless otherwise agreed
+# upon. The license for this file, and modifications and additions to the
+# file, is the same license as for the pristine package itself (unless the
+# license for the pristine package is not an Open Source License, in which
+# case the license is the MIT License). An "Open Source License" is a
+# license that conforms to the Open Source Definition (Version 1.9)
+# published by the Open Source Initiative.
+
+## Disable LTO for now since it breaks compilation of the tests
+## https://osmocom.org/issues/4115
+%define _lto_cflags %{nil}
+
+%define with_iu 1
+Name: osmo-msc
+Version: @VERSION@
+Release: 0
+Summary: Osmocom's MSC for 2G and 3G circuit-switched mobile networks
+License: AGPL-3.0-or-later AND GPL-2.0-only
+Group: Productivity/Telephony/Servers
+URL: https://osmocom.org/projects/osmomsc
+Source: %{name}-%{version}.tar.xz
+BuildRequires: autoconf
+BuildRequires: automake
+BuildRequires: libtool
+%if 0%{?suse_version}
+BuildRequires: systemd-rpm-macros
+%endif
+BuildRequires: pkgconfig >= 0.20
+BuildRequires: pkgconfig(sqlite3)
+BuildRequires: pkgconfig(libcrypto) >= 0.9.5
+BuildRequires: pkgconfig(libosmo-gsup-client) >= 1.7.0
+BuildRequires: pkgconfig(libosmo-mgcp-client) >= 1.12.0
+BuildRequires: pkgconfig(libosmo-netif) >= 1.4.0
+BuildRequires: pkgconfig(libosmo-sccp) >= 1.8.0
+BuildRequires: pkgconfig(libosmo-sigtran) >= 1.8.0
+BuildRequires: pkgconfig(libosmoabis) >= 1.5.0
+BuildRequires: pkgconfig(libosmocore) >= 1.9.0
+BuildRequires: pkgconfig(libosmoctrl) >= 1.9.0
+BuildRequires: pkgconfig(libosmogsm) >= 1.9.0
+BuildRequires: pkgconfig(libosmovty) >= 1.9.0
+BuildRequires: pkgconfig(libsmpp34) >= 1.14.0
+####
+BuildRequires: lksctp-tools-devel
+####
+%{?systemd_requires}
+%if %{with_iu}
+BuildRequires: pkgconfig(libasn1c) >= 0.9.30
+BuildRequires: pkgconfig(libosmo-ranap) >= 1.5.0
+%endif
+
+%description
+The Mobile Switching Center (MSC) is the heart of 2G/3G
+circuit-switched services. It terminates the A-interface links from the
+Base Station Controllers (BSC) and handles the MM and CC sub-layers of
+the Layer 3 protocol from the phones (MS).
+
+This Osmocom implementation of the MSC handles A interfaces via 3GPP
+AoIP in an ASP role. It furthermore implements IETF MGCP against an
+external media gateway, such as OsmoMGW. It does *not* implement MAP
+towards a HLR, but the much simpler Osmocom GSUP protocol, which can
+be translated to MAP if needed.
+
+%prep
+%setup -q
+
+%build
+echo "%{version}" >.tarball-version
+autoreconf -fi
+%configure \
+%if %{with_iu}
+ --enable-iu \
+%endif
+ --enable-smpp \
+ --docdir=%{_docdir}/%{name} \
+ --with-systemdsystemunitdir=%{_unitdir}
+
+make %{?_smp_mflags}
+
+%install
+%make_install
+
+%if 0%{?suse_version}
+%preun
+%service_del_preun %{name}.service
+
+%postun
+%service_del_postun %{name}.service
+
+%pre
+%service_add_pre %{name}.service
+
+%post
+%service_add_post %{name}.service
+%endif
+
+%check
+make %{?_smp_mflags} check || (find . -name testsuite.log -exec cat {} +)
+
+%files
+%license COPYING
+%doc AUTHORS README.md
+%dir %{_docdir}/%{name}/examples
+%dir %{_docdir}/%{name}/examples/osmo-msc
+%{_docdir}/%{name}/examples/osmo-msc/osmo-msc.cfg
+%{_docdir}/%{name}/examples/osmo-msc/osmo-msc_custom-sccp.cfg
+%{_docdir}/%{name}/examples/osmo-msc/osmo-msc_multi-cs7.cfg
+%{_bindir}/osmo-msc
+%{_unitdir}/%{name}.service
+%dir %{_sysconfdir}/osmocom
+%config(noreplace) %{_sysconfdir}/osmocom/osmo-msc.cfg
+
+%changelog
diff --git a/contrib/systemd/osmo-msc.service b/contrib/systemd/osmo-msc.service
index 343639cf3..f21aec7b5 100644
--- a/contrib/systemd/osmo-msc.service
+++ b/contrib/systemd/osmo-msc.service
@@ -4,10 +4,14 @@ Wants=osmo-hlr.service
Wants=osmo-mgw.service
After=osmo-hlr.service
After=osmo-hnbgw.service
+After=network-online.target
+Wants=network-online.target
[Service]
Type=simple
Restart=always
+StateDirectory=osmocom
+WorkingDirectory=%S/osmocom
ExecStart=/usr/bin/osmo-msc -c /etc/osmocom/osmo-msc.cfg
RestartSec=2
diff --git a/debian/changelog b/debian/changelog
index 8aec381ed..debce4e80 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,815 @@
+osmo-msc (1.11.1) unstable; urgency=medium
+
+ [ Neels Hofmeyr ]
+ * fix codecs in internal call bridge
+ * make two functions static
+
+ [ Mychaela N. Falconia ]
+ * CC: don't start guard timer on mid-call MNCC messages
+ * gsup_client_mux: set destination_name in error reply function
+ * SMS over GSUP: correctly route GSUP responses to MT SMS
+ * SMS over GSUP: set source_name in GSUP reply messages
+
+ [ Andreas Eversberg ]
+ * ASCI: Remove duplicated CLEAR COMMAND from VGCS/VBS channel handling
+
+ -- Oliver Smith <osmith@sysmocom.de> Thu, 28 Sep 2023 13:53:07 +0200
+
+osmo-msc (1.11.0) unstable; urgency=medium
+
+ [ arehbein ]
+ * Transition to use of 'telnet_init_default'
+
+ [ Neels Hofmeyr ]
+ * sdp_msg.c: fix missing rate in sdp_audio_codecs_add()
+ * comment: clarify L3 Info processing
+ * IuCS: remove IuUP LOOPBACK hack
+ * make: doc/sequence_charts: use wildcards for EXTRA_DIST and CLEANFILES
+ * tweak MNCC logging, add RTP info
+ * msc_log_to_ladder.py: various tweaks
+ * charts: Rename voice_call_full.msc to voice_call_external_mncc.msc
+ * update doc/sequence_charts/voice_call_external_mncc.msc
+ * add voice_call_internal_mncc.msc
+ * add codec_mapping.h,c
+ * MNCC: use codec_mapping, drop mgcp_codec_to_mncc_payload_msg_type()
+ * [codecs filter] add codec_filter.h,c
+ * [codecs filter] add trans.cc.codecs
+ * [codecs filter] store BSS codec list from Compl L3
+ * [codecs filter] MO call: apply BSS codec list
+ * [codecs filter] MT call: apply BSS codec list
+ * [codecs filter] MT call: apply remote call leg codecs
+ * [codecs filter] MT call: store MS Bearer Cap from CC Call Conf
+ * msc_vlr_test_call: include RAN RTP addr in ass compl
+ * [codecs filter] apply BSS codecs from Assignment Complete
+ * add ran_infra.force_mgw_codecs_to_ran
+ * rtp_stream: allow multiple codecs / use codec filter from Assignment
+ * in ran_msg, return gsm0808_speech_codec (intra-MSC)
+ * in ran_msg, return gsm0808_speech_codec (inter-MSC)
+ * [codecs filter] use filter result in MT DTAP CC Setup
+ * [codecs filter] use filter result in Assignment
+ * [codecs filter] send + receive SDP via MNCC
+ * msc_vlr_tests: confirm crcx by RAN/CN side separately
+ * [codecs filter] use codecs filter on crcx ok
+ * do CN CRCX first
+ * mncc_recvmsg(): log caller file,line
+ * [codecs filter] msc_vlr_test_call: test codecs resolution
+ * codecs: compose HO Req Ch Type from cc.codecs
+ * HO Req: include IE Codec List (MSC Preferred)
+ * fix msc_vlr_test_call SDP mncc_rtp
+ * coverity: sdp_msg_test.c: check rc of sdp_msg_from_sdp_str()
+ * 3G: decapsulate IuUP to AMR at the MGW; allow 3G<-AMR->2G
+ * TODO-RELEASE: add note on osmo-sip-connector and SDP
+
+ [ Vadim Yanitskiy ]
+ * src/Makefile.am: remove unneeded AM_LDFLAGS with LIBS
+ * tests: use -no-install libtool flag to avoid ./lt-* scripts
+ * tests: $(BUILT_SOURCES) is not defined, depend on osmo-msc
+ * copyright: fix typo: sysmocom s/s.m.f.c./s.f.m.c./ GmbH
+ * fixup: contrib/jenkins: create workspace.tar.xz on error
+ * tests/{ctrl,vty}_test_runner.py: raise an exception if proc's rc != 0
+ * msc_vty: support spaces in short/long network name
+ * ran_a_mgcp_codec_from_sc(): cosmetic: remove unneeded breaks
+ * ran_a_mgcp_codec_from_sc(): map GSM0808_SCT_CSD to CODEC_CLEARMODE
+ * ran_a_channel_type_to_speech_codec_list(): set PI/PT for CSD
+ * codec_mapping: codec_map[]: add missing speech codec for CLEARMODE
+ * csd_bs_list_to_bearer_cap(): properly initialize bcap fields
+ * csd_bs_list_to_bearer_cap(): add default branch for safety
+
+ [ Pau Espin Pedrol ]
+ * mncc_sock: Call osmo_fd_unregister() before closing and changing bfd->fd
+ * rtp_stream: Update id after modifying fields upon Tx of MGCP msg
+ * rtp_stream: Fix remote_osmux_cid_sent_to_mgw never set to true
+ * UserManual: Include sigtran*.adoc from osmo-gsm-manuals.git
+ * Write explicit role & sctp-role fields in ASP configurations
+ * Use new mgcp_client_conf_alloc() API to alloc mgcp_client_conf
+ * Tx Loc UPD ACC: Use PLMN provided by subscr
+ * trans_lcls_compose(): Set PLMN fron cell currently in use
+
+ [ Oliver Smith ]
+ * msc_mgw_setup: use mgcp_client_pool_empty()
+ * msc_main: close SMS db on startup error
+ * debian: set compat level to 10
+ * contrib/jenkins: create workspace.tar.xz on error
+ * systemd: depend on networking-online.target
+ * codec_mapping: add clearmode
+ * ran_a_channel_type_to_speech_codec_list: add CSD
+ * codec_filter_set_ms_from_bc: prepare for CSD
+ * Cosmetic: gsm48_cc_tx_setup: tweak comment
+ * Cosmetic: gsm48_cc_tx_setup: remove TODO comment
+ * codec_filter_init: prepare for CSD
+ * codec_filter_set_ran: prepare for CSD
+ * codec_filter_set_bss: prepare for CSD
+ * codec_filter_run: prepare for CSD
+ * transaction: move cc.codecs.remote -> cc.remote
+ * transaction: move cc.codecs.result -> cc.local
+ * msc: add trans_cc_set_remote_from_bc
+ * gsm48_cc_tx_setup: set trans->bearer_cap.transfer early
+ * Add initial CSD support with external MNCC
+ * smpp_handle_bind_tx: initialize tlv
+ * sdp_msg_test: fix dereference after null check
+ * smpp_msc: submit_to_sms: check ud_len > sms_msg_len
+ * msc_ho_send_handover_request: fix check_after_deref
+ * csd_bs_list_to_gsm0808_channel_type: fix rc check
+ * gsm48_cc_tx_alerting: check rc of sdp_msg_from_sdp_str
+ * mncc_test: fix talloc_named_const
+ * gsm48_cc_tx_setup: use MNCC bcaps for CSD
+ * test: add csd_test
+ * csd_bs_list_remove: fix removal logic
+ * mncc_builtin: permit data bearer types
+ * csd_bs_to_gsm0808: add T 300 / proper ch_rate_type
+ * Cosmetic: fix typo
+ * csd_bs_list_to_gsm0808_ct: assert -> ret -EINVAL
+ * msc_ho_send_handover_request: support CSD
+ * msc_a_up_call_assignment_complete: check CSD codec
+ * gsm48_cc_tx_call_proc_…: verify bcap.transfer
+
+ [ Andreas Eversberg ]
+ * ASCI: Add log categories for GCC/BCC (call control)
+ * ASCI: Add log category for VGCS/VBS call and channel FSM
+ * ASCI: Use a unique call-id for RTP streams
+ * ASCI: rtp_stream_commit(): Also update MGW on conn mode change
+ * ASCI: Allow usage of rtp_stream with other FSM
+ * ASCI: Add transaction type to trans_find_by_callref()
+ * ASCI: Add two new transaction types for VGCS and VBS
+ * ASCI: Allow transaction without subscriber associated
+ * ASCI: Add simple implementation of Group Call Register
+ * ASCI: Add functions to transcode VGCS/VBS messages on A-interface
+ * ASCI: Add callref to assignment command
+ * ASCI: Add call control for VGCS/VBS
+ * ASCI: Add decoder for VGCS/VBS messages to msc_a.c
+ * ASCI: Add function to receive VGCS/VBS messages from BSS
+ * ASCI: Add option to switch on or off ASCI support
+ * ASCI: Check return code of osmo_mobile_identity_decode()
+ * ASCI: Remove check for trans->msc_a to be set in _assign_complete()
+ * ASCI: Add VTY to configure GCR (Group Call Register)
+ * ASCI: Add reception of UPLINK RELEASE on dedicated channel
+ * ASCI: Clear VGCS call and channel on BSSMAP reset message
+ * ASCI: Receive messages from MSC-A role related to VGCS/VBS
+ * ASCI: Null pointer bug fix in trans_create_bcc_gcc
+ * ASCI: Fix wrong check for Null pointer in vgcs_cell_fsm_null()
+ * ASCI: Check if codec mapping exists for given codec
+ * ASCI: Fix Null pointer dereference bug in gsm44068_bcc_gcc_trans_free()
+ * ASCI: Point to correct state machine when calling ran_encode_and_send()
+ * ASCI: Add debugging and error logging to VGCS/VBS call control
+ * ASCI: Add missing transaction ID to SET PARAMETER message
+
+ [ Keith Whyte ]
+ * SMPP: Fix Memory leaks
+
+ -- Pau Espin Pedrol <pespin@sysmocom.de> Tue, 12 Sep 2023 16:46:11 +0200
+
+osmo-msc (1.10.0) unstable; urgency=medium
+
+ [ Keith Whyte ]
+ * Don't let this osmo-msc operate on a libdbi database
+ * Turn off secure_delete in sqlite
+ * Update MNCC field validation mask.
+ * Change CC_CAUSE returned on unanswered MT Call
+ * LCLS: Fix Global Call Reference generation
+
+ [ Neels Hofmeyr ]
+ * fix typo in msgb name for CC SETUP
+ * missing whitespace in gsm_04_08_cc.c
+ * err log: fix reverse statement in msc_a call handling
+ * cosmetic: log actual MNCC msg in tch_rtp_connect()
+ * sdp_msg: s/_name_/_to_str_/g
+ * in sdp logging: add payload type number like 'AMR#111'
+ * sdp_msg: add sdp_audio_codecs_cmp(), add compare flags
+ * sdp_msg: s/sdp_audio_codec_/sdp_audio_codecs_
+ * msc_a,vlr: rename ciphering_required to is_ciphering_to_be_attempted
+ * msc_a,vlr: add is_ciphering_required (accurately named)
+ * vlr_lu_fsm: clarify naming of static functions
+ * vlr: auth_fsm: clarify success/failure result
+ * vlr: auth_fsm: rename AUTH_RES to AUTH_SUCCESS
+ * vlr_auth_fsm: add result no_auth_info_event
+ * vlr: implement fallback to no-auth
+ * sdp_msg: when NULL, do not crash but return empty SDP str
+ * log CC timeouts
+ * add sdp_audio_codec_is_set
+ * add some comments to sdp_msg.c,h
+ * sdp_msg.c: parse send/recv mode
+ * fix sdp_msg_to_sdp_str(), never add fmtp for unset codec
+ * rtp_stream_commit: check missing MGW ep only when ready for RTP
+ * rtp_stream: set_remote_addr: do nothing when unchanged
+
+ [ Max ]
+ * SMPP: clarify (re)start logic
+ * Ignore .deb build byproducts
+ * ESME: use osmo_sock_get_name() for logging
+ * tests: use common stubs for SMS queue test
+ * Introduce libsmpputil
+ * Add ESME-specific logging
+ * Set working directory in systemd service file
+ * Make esme struct shared
+ * Use libsmpputil functions in smpp_mirror tool
+ * cosmetic: use proper name for SMPP handlers
+ * SMPP: remove duplicate g_smsc definition
+ * smpp_mirror: fix compiler warning
+ * SMPP: use default port from libsmpp34
+ * SMPP: fix possible NULL pointer dereference
+ * SMPP: make smpp_smsc_stop() static
+ * ctrl: take both address and port from vty config
+ * SMPP: use proper type for boolean variables
+
+ [ Vadim Yanitskiy ]
+ * contrib/jenkins.sh: do not override parallel make for libsmpp34
+ * mncc: move MNCC_F_ALL from mncc.c to mncc.h
+ * mncc: cosmetic: fix coding style in mncc_prim_check_sign()
+ * libmsc: check return value of gsm0808_create_ass2()
+ * msc_main: fix wrong comment: HLR is a separate project
+ * fix msc_vty_go_parent(): add missing case for MGW_NODE
+
+ [ Pau Espin Pedrol ]
+ * tests/test_nodes.vty: Avoid listing commands provided by lib
+ * Introduce support for libosmo-mgcp-client MGW pooling
+ * vty: Make use of new mgcp_client_pool_config_write() API
+ * Use new mgcp-client VTY commands under mgw node
+ * call_leg: Fix EV_MGW_ENDPOINT_GONE not processed in RELEASE state
+ * doc: Include mgwpool.adoc from osmo-gsm-manuals
+
+ [ Oliver Smith ]
+ * contrib/jenkins.sh: use enable-werror with IU too
+
+ -- Pau Espin Pedrol <pespin@sysmocom.de> Tue, 07 Feb 2023 17:28:16 +0100
+
+osmo-msc (1.9.0) unstable; urgency=medium
+
+ [ Alexander Couzens ]
+ * utran: use new UTRAN encryption enum
+ * libmsc/gsm_04_08: refactor require ciphering into an own function
+ * ran_msg_iu: do not pass UEA0 to ranap_new_msg_sec_mod_cmd2()
+
+ [ Vadim Yanitskiy ]
+ * VTY: clarify deprecation message for cfg_net_per_loc_upd_cmd
+ * libmsc: fix memory leak (struct gsm_sms) in gsm340_rx_tpdu()
+ * libmsc: fix another memleak (struct gsm_sms) in gsm340_rx_tpdu()
+ * libvlr: vlr_set_ciph_mode(): avoid redundant check
+ * libvlr: fix is_ciph_required(): always send SecModeCmd for UTRAN
+ * libmsc: ran_iu_make_security_mode_command(): improve readability
+ * libmsc: ran_iu_make_security_mode_command(): clarify UIA mask
+ * libmsc: fix memory leak (struct msgb) in msc_i_ran_enc()
+ * tests: use 'check_PROGRAMS' instead of 'noinst_PROGRAMS'
+
+ [ Oliver Smith ]
+ * treewide: remove FSF address
+ * tests/msc_vlr/Makefile.am: drop -ldbi
+
+ [ Pau Espin Pedrol ]
+ * Announce IuFP audio codec for UTRAN conns in CRCX towards MGW
+ * Avoid setting audio codec if not available during assignment_complete (MDCX)
+ * ran_msg_iu.c: Set proper codec in Assignment Complete
+ * Drop unneeded ax_check_compile_flag.m4
+ * call_leg: local_bridge: Avoid null pointer access if CN-side not ready
+
+ [ Neels Hofmeyr ]
+ * fix crash on CM Serv Rej: fix use count mismatch
+
+ [ Harald Welte ]
+ * call rate_ctr_init() to make rate counters work properly
+ * switch sqlite3 to single-threaded mode
+ * sms_queue: Annotate each function with some comment
+ * vlr: Split vlr_subscr_rx_imsi_detach()
+ * vlr: Add rate counters and stat items
+ * sms_queue: Introduce rate_ctr / stat_item
+ * smpp: Fix use-after-free bug when ESME disconnects but has write pending
+ * smpp: don't enqueue write messages if ESME is disconnected
+ * sms_queue: refactor sms_pending add/remove code
+ * sms_queue: merge sms_pending_add into sms_pending_from
+ * tests: Remove sms.db{-wal,-shm} files, not just sms.db
+ * switch from libdbi to lbsqlite3
+ * db: Switch from 'synchronous = FULL' to 'synchronous = NORMAL'
+ * sms: Encapsulate SMS queue related config parameters
+ * sms: Give smsc its own VTY config node
+ * sms_queue: Use local variable rather than 9x pointer de-ref in function
+ * sms_queue: Make deletion of messages from DB VTY-configurable
+ * smpp: Parse and use SMPP-provided validity period
+ * sms: Make default SMS validity period configurable via VTY
+ * sms: Introduce VTY-configurable minimum SMS validity period
+ * update git URLs (git -> https; gitea)
+ * Convert + Expand README file
+ * fix RPM build failures due to README -> README.md rename
+
+ -- Pau Espin Pedrol <pespin@sysmocom.de> Wed, 29 Jun 2022 11:32:11 +0200
+
+osmo-msc (1.8.0) unstable; urgency=medium
+
+ [ Pau Espin Pedrol ]
+ * configure.ac: Depend on newer libosmo-ranap
+ * Fill Last Used E-UTRAN PLMN Id when in CSFB
+ * Use new osmo stat items/ctr APIs
+ * sgs: Use available API to set vlr subscr LastUsedEutranPLMNId
+ * vlr_sgs: Drop recorded LastEutranPlmnId when UE no longer associated
+ * sgs_iface.c: Improve logging when paging over SGs
+ * msc_a.c: Allow MSC_A_EV_CN_CLOSE in state MSC_A_ST_RELEASING
+ * cosmetic: fix typos in comments
+ * vlr_sgs.h: Set proper logic order of items in enum sgs_ue_fsm_state
+ * vlr_auth_fsm.c: Simplify function auth_fsm_wait_ai_resync
+ * vlr_sgs.c: Fix missing use_count decrease in vlr_sgs_imsi_detach
+ * vlr_sgs: Balance use_count incremented in vlr_sgs_loc_update
+ * cosmetic: Fix typo in comment
+
+ [ Oliver Smith ]
+ * contrib/osmo-msc.spec.in: depend on dbd-sqlite3
+ * contrib/osmo-msc.spec.in: require libosmo-ranap >= 0.7.0
+ * Revert "Turn some compiler warnings into errors"
+
+ [ Vadim Yanitskiy ]
+ * SMS-over-GSUP: notify sender if no transaction found
+ * msc_tx_common_id(): fix potential NULL pointer dereference
+ * libmsc: fix NULL pointer dereference in trans_lcls_compose()
+ * libmsc: struct smsc: drop 'const' qualifier from bind_addr
+ * smpp_smsc: use osmo_talloc_replace_string() in smpp_smsc_conf()
+ * mncc: rework passing GCR over the MNCC interface
+ * manuals: remove deprecated -C / --no-dbcounter options
+ * Do not mention deprecated -M / --mncc-sock-path options
+ * Do not mention deprecated -l / --database options
+
+ [ Neels Hofmeyr ]
+ * osmo-msc main: use osmo_select_shutdown()
+ * ran_msg_a.c: use gsm0808_create_cipher2()
+ * support A5/4 in Cipher Mode Command
+ * support A5/4 in inter-BSC handover
+ * improve logging on encryption, for Ciphering and HO
+ * add sequence_charts/call_reestablishment.msc
+ * add vlr_subscr_find_by_mi
+ * implement CM Re-Establish for voice calls
+
+ [ Eric Wild ]
+ * vty: allow A5/4 encryption in config
+
+ [ Philipp Maier ]
+ * running.adoc: add section about MGCP configuration
+ * msc_vlr_test: remove DLMGCP log messages from unit test output
+
+ [ Harald Welte ]
+ * smpp: Fix help string in vty for "alert-notifications"
+ * smpp_mirror: Factor-out reset of SMPP read state
+ * smpp_mirror: Don't allocate msgb's for unrealistic amounts of memory
+ * Fix enabling of UMTS UEA encryption
+ * Make UTRAN encryption algorithms configurable
+
+ [ Keith Whyte ]
+ * Add support for LCLS to the MSC
+
+ [ Alexander Couzens ]
+ * Validate the choosen UTRAN encryption algorithm
+
+ -- Pau Espin Pedrol <pespin@sysmocom.de> Tue, 16 Nov 2021 17:44:54 +0100
+
+osmo-msc (1.7.0) unstable; urgency=medium
+
+ [ Keith Whyte ]
+ * Use GSM411_RP_* and not GSM48_CC_*
+ * Trivial: code simplification, return early
+ * vty: allow configuring db path from cfg file
+ * Don't Store an SMS in the database when the ESME is not Bound
+
+ [ Pablo Neira Ayuso ]
+ * libmsc: SMS, Avoid premature RP-ACK to MS
+
+ [ Vadim Yanitskiy ]
+ * manuals/vty: update the VTY reference to reflect recent changes
+ * libvlr: remove unused 'periodic_lu_timer' from struct vlr_subscr
+ * osmo-msc: fix: properly initialize default values for MGW timers
+ * msc/signal.h: remove unused (since the NiTB split up) signals
+ * VTY: mark 'subscriber create imsi' command as deprecated
+ * VTY: add osmo_tdef introspection and configuration commands
+ * libvlr: use generic osmo_tdef API for T3250, T3260, and T3270
+ * libmsc: move subscriber expiration timer T3212 to libvlr
+ * vlr: remove unused parameter 'log_level' of auth_fsm_start()
+ * vlr_sgs_fsm: add missing break, do not call to_null() twice
+ * msc/sccp_ran.h: fix: do not pass -1 to osmo_rat_type_name()
+ * VTY: cosmetic: make struct cmd_node for GSMNET_NODE static
+ * libmsc/gsm_04_08: make use of msc_a in gsm48_rx_rr_app_info()
+ * libmsc/gsm_04_08: use DRR in gsm48_rx_rr_pag_resp(), not DMM
+ * libmsc/gsm_04_11.h: remove unused sms_deliver definition
+ * osmo-msc: use stderr to print error messages, not stdout
+ * libmsc/sdp: cosmetic: fix less-than-zero comparison of an unsigned value
+ * SMS-over-GSUP: clarify error message about unexpected MO/MT SMS
+ * SMS-over-GSUP: move net->sms_over_gsup check to gsm411_gsup_rx()
+ * SMS-over-GSUP: respond with error if net->sms_over_gsup is false
+ * SMS-over-GSUP: notify sender about unhandled GSUP messages
+ * SMS-over-GSUP: notify sender about malformed GSUP messages
+ * SMS-over-GSUP: notify sender in case of RPL delivery failure
+ * gsm_04_14: fix off-by-one error in create_gsm0414_msg()
+ * vty: fix vsub reference counting: call vlr_subscr_put()
+ * debian/control: change maintainer to the Osmocom team / mailing list
+ * mncc_builtin: cosmetic: fix coding style in int_mncc_recv()
+ * mncc_builtin: log type of unhandled message in int_mncc_recv()
+ * main: add --vty-ref-mode, use vty_dump_xml_ref_mode()
+ * submit_to_sms(): fix the use of deprecated gsm_septets2octets()
+ * ran_a_decode_cipher_mode_reject(): use gsm0808_get_cause()
+ * fix _gsm48_cc_trans_free(): send MNCC REL.ind on Clear Request
+
+ [ Neels Hofmeyr ]
+ * fix segfault: unsolicited Paging Response
+ * manual: add missing mention of MGCP in "Multiple instances"
+ * manual: Multiple Instances: tweak MNCC, add missing SGs doc
+ * manual: link to new common cs7-config.adoc, remove some dup of that
+ * vlr_subscr_rx_id_resp(): dont assert on received MI type
+ * msc_vlr_test_gsm_ciph.c: fix IMEISV MI: even number of digits, clear odd bit
+ * use new osmo_mobile_identity API everywhere
+ * add rudimentary NRI support for MSC pooling
+ * add osmo-msc --vty-ref-xml: dump VTY ref XML to stdout
+ * add comments to clarify some complete l3 details
+ * vty 'show connection': show msc_a->via_cell instead of vsub->cgi
+ * propagate Compl L3 Info Cell ID to the VLR subscriber record
+ * make vty-transcrip-test: use $VTY_TEST var like osmo-bsc
+ * refactor: move RESET Osmux TLV parsing to ran_msg_a.c
+ * sgs_tx_loc_upd_resp_cb(): fix error handling for MI encoding
+ * is_reset_msg: use proper enum for rc value
+ * manuals: generate vty reference xml at build time
+ * Clear Command: set cause value to "Call Control"
+ * fix crash for unknown MI during Paging Response
+ * fix MGCP timeout timer
+ * drop duplicate ran_peer_find() vs ran_peer_find_by_addr()
+ * fix comment in ran_peer.h
+ * msc_vlr_tests: make independent of libosmocore talloc
+ * gsm_network: drop unused neighbor_list member
+
+ [ Eric ]
+ * configure.ac: fix libtool issue with clang and sanitizer
+
+ [ Philipp Maier ]
+ * doc: do not use random ip-address for MGW
+ * msc_vty: remove emergency-call command from network
+ * msc_a: add callref as call id to ASSIGNMENT REQ.
+ * msc_ho: fix CALL IDENTIFIER in HANDOVER REQUEST
+ * mncc_call: fix memory overrun
+ * gsm_04_08: check return code of osmo_mobile_identity_decode_from_l3()
+
+ [ Harald Welte ]
+ * vlr_auth_fsm: Fix compilation with gcc-10
+ * contrib/osmo-msc.spec.in: Enable SMPP in RPM builds
+ * remove empty + unused ran_up_l2.c
+ * osmo-msc.spec.in: Use %config(noreplace) to retain current config file
+ * Send "BSSMAP CommonID" to tell BSC about the IMSI
+ * Use osmo_fd_setup() whenever applicable
+ * debian/control: Recommend installation of osmo-mgw
+ * Use osmo_fd_*_{disable,enable}
+ * README update. Explain more what it is than just the history
+
+ [ Pau Espin Pedrol ]
+ * Use OSMO_FD_* instead of deprecated BSC_FD_*
+ * ran_msg_iu.c: Avoid redefining osmo-iuh global variables
+ * configure.ac: Drop trailing whitespace
+ * Support setting rt-prio and cpu-affinity mask through VTY
+ * Change default SCTP conn NULL->127.0.0.1 to localhost->localhost
+ * Support sending IPv6 Transport Address in Assignment Command
+ * Support handling IPv6 Transport Address in Assignment Complete
+ * tests: Fix VTY results after switch to newer libosmo-mgcp-client
+ * Support handling IPv6 Transport Address in Handover Request (Ack)
+ * mncc: Support IPv6 addresses (new version mncc 7)
+ * contrib/jenkins: Enable parallel make in make distcheck
+ * main: generate coredump and exit upon SIGABRT received
+ * .gitignore: Ignore new autofoo tmp files
+ * tests: Explicitly drop category from log
+ * tests: Replace deprecated API log_set_print_filename
+
+ [ Oliver Smith ]
+ * contrib: import RPM spec
+ * contrib: integrate RPM spec
+ * Makefile.am: EXTRA_DIST: debian, contrib/*.spec.in
+ * contrib/jenkins: don't build osmo-gsm-manuals
+ * configure.ac: set -std=gnu11
+
+ [ Alexander Couzens ]
+ * Convert paging response timer into an osmocom own X4 timer
+
+ -- Pau Espin Pedrol <pespin@sysmocom.de> Tue, 23 Feb 2021 20:22:34 +0100
+
+osmo-msc (1.6.1) unstable; urgency=medium
+
+ [ Vadim Yanitskiy ]
+ * libmsc/gsm_04_08.c: fix: verify MI before calling vlr_subscr_rx_id_resp()
+
+ [ Neels Hofmeyr ]
+ * vlr_gsup_rx: fix uninitialized rc
+ * vlr.c: fix condition to check MSISDN presence
+
+ -- Pau Espin Pedrol <pespin@sysmocom.de> Thu, 09 Jan 2020 12:29:08 +0100
+
+osmo-msc (1.6.0) unstable; urgency=medium
+
+ [ Philipp Maier ]
+ * cosmetic: make function mncc_tx_to_gsm_cc static
+ * sgs_iface: do not use SGsAP-MO-CSFB-INDICATION for CSFB return
+ * msc_a: switch RAN type back to SGs when a CSFB-Call is cleared
+ * sgs_iface: Accept messages with unknown TLV elements
+ * paging: Send SGsAP-SERVICE-ABORT-REQUEST on paging timeout
+
+ [ Neels Hofmeyr ]
+ * add 'encryption uea 1 2' cfg / fix ttcn3 iu tests
+ * mncc: send payload type matching chosen codec
+ * memleak on cc setup errors
+ * cc trans: make sure bearer cap is empty
+ * fix segfault: don't send CC REL on NULL msc_a
+ * vlr_lu_fsm: ignore ID_IMEISV during VLR_ULA_S_WAIT_HLR_UPD
+ * tweak CC cause for incoming call to unattached nr
+ * log, cosmetic: add "RR" to "Ciphering Mode Complete"
+ * msc_vlr_tests: GSUP: don't care about extra IEs
+ * gsm48_tch_rtp_create(): check against NULL mgcp_info
+ * msc_a.c, CC trans: change a comment to a debug log
+ * cosmetic: fix call_leg_ensure_ci() decl. arg name to match impl.
+ * vlr: don't log about "gratuitous ID RESPONSE"
+ * ran_dec logging: log message sizes on errors
+ * msc_a fsm: ignore state chg to same state
+ * fix error on BSSMAP Cipher Mode Complete L3 msg IE
+ * catch GSUP auth result without auth_fsm
+ * LOG_TRANS for CC: always log CC state
+ * log which DTAP messages are sent to RAN
+ * log: drop duplicate MNCC log
+ * also log MNCC_SETUP_REQ
+ * BSSMAP log tweak
+ * log: RANAP encode: use RANAP message names instead of BSSAP
+ * log: ran_msg_a: tweak a message name
+ * send MNCC REL only if MNCC has actually started
+ * fsm: use deferred deallocation
+ * rtp_stream: sanely cancel MGW endpoint FSM notify
+ * use osmo_sockaddr_str_is_nonzero()
+ * CC: add error handling for CRCX responses
+ * add msc_log_to_ladder.py
+ * charts: add full MO and MT voice call diagram
+ * cc trans: remove unused tch_rtp_create
+ * fix msc_vlr_test_call.c
+ * BSSMAP: decode Codec List (BSS Supported)
+ * fail on invalid RTP address from MGW
+ * msc_a CC: add some basic sanity tests
+ * fix incoming call while Paging
+ * add sdp_msg API: SDP parsing/composition
+ * MNCC v6: add optional SDP to the socket protocol
+ * msc_vlr_tests: better err logging for dtap msgs
+ * msc_vlr_test_call.c: add MNCC logging
+ * msc_vlr_tests: log descriptions in color with -v
+ * msc_vlr_test_call: rename lu_utran_tmsi
+ * gsup: indicate CN-Domain in SendAuthInfo Requests
+ * sms db: when storing an SMS, retrieve the ID
+ * sms log tweak
+
+ [ Vadim Yanitskiy ]
+ * libvlr/vlr.c: cosmetic: move message_type assignment
+ * counters: clarify documentation for MSC_CTR_SMS_* entries
+ * counters: clarify documentation for MSC_CTR_LOC_UPDATE_* entries
+ * counters: clarify documentation for MSC_CTR_CALL_* entries
+ * counters: polish documentation of cm_service_request / paging_resp
+ * libmsc: fix potential NULL-pointer dereferences detected by GCC's LTO
+ * libmsc/gsm_04_11_gsup.c: do not init a buffer in gsm411_gsup_mo_fwd_sm_req()
+ * libmsc/gsm_04_11_gsup.c: fix SM-RP-OA encoding for MO SMS over GSUP
+
+ [ Alexander Couzens ]
+ * smpp_openbsc.c: check acl before deref it
+ * vlr: gmm_cause_to_fsm_and_mm_cause() drop fsm_cause_p argument
+ * make vlr_gmm_cause_to_mm_cause public
+ * vlr_auth_fsm: on SAI use the GSUP provided GMM cause code
+
+ [ Keith Whyte ]
+ * Implement a global switch on the network to disable call waiting.
+
+ [ Pau Espin Pedrol ]
+ * vty: fix access to wrong argv in paging response-timer
+
+ [ Oliver Smith ]
+ * tests: only check IU configs if IU is enabled
+ * osmoappdesc.py, tests: switch to python 3
+
+ [ Martin Hauke ]
+ * Fix some typos
+
+ [ Harald Welte ]
+ * check for osmo_ss7_init() error return value
+ * manual: Fix copy+paste error
+ * Check for osmo_fsm_register() error return value
+ * msc: exit(2) on unsupported positional arguments on command line
+
+ -- Pau Espin Pedrol <pespin@sysmocom.de> Fri, 03 Jan 2020 18:51:37 +0100
+
+osmo-msc (1.5.0) unstable; urgency=medium
+
+ [ Max ]
+ * Handle LCLS-NOTIFICATION message from BSS
+ * Various logging fixes
+ * VLR tests: use msgb_eq_data_print() for comparison
+ * transaction: drop meaningless ti_flag of trans_assign_trans_id()
+ * transaction: clarify magic 0xff transaction ID
+
+ [ Vadim Yanitskiy ]
+ * transaction.c: cosmetic: use 'default' branch in trans_free()
+ * libmsc/ran_conn.c: cosmetic: use tabs instead of N * 8 spaces
+ * transaction: change arguments of trans_find_by_sm_rp_mr()
+ * libmsc/gsm_04_11.c: also assign SM-RP-MR to MO transactions
+ * libmsc/gsm_04_11.c: introduce and use gsm411_assign_sm_rp_mr()
+ * libmsc/gsm_04_80.c: use gsm0480_create_release_complete()
+ * libmsc/gsm_04_80.c: add msc_send_ussd_release_complete_cause()
+ * libmsc/osmo_msc.c: move connection ref-counting code to 'ran_conn.c'
+ * transaction: fix description of trans_assign_trans_id()
+ * transaction.h: use #pragma once as include guard
+ * libmsc/gsm_09_11.c: implement guard timer for NCSS sessions
+ * libmsc/ran_conn.c: add missing 'break' to OSMO_RAT_EUTRAN_SGS
+ * libmsc/sgs_iface.c: fix SGS_STATE_NS11 counter reference
+ * libmsc/sgs_vty.c: always write server address and VLR name
+ * libmsc/msc_vty.c: drop dead comparison against null
+ * libmsc/sgs_iface.c: fix copy-paste error
+ * libmsc/sgs_iface.c: register sgs_vlr_reset_fsm on DSO load
+ * libmsc/sgs_vty.c: don't print SGs socket error twice
+ * libmsc: fix: properly initialize the SGs server
+ * libmsc/sms_queue.c: fix memleak in smsq_take_next_sms()
+ * tests/sms_queue: track the use of NULL talloc memory contexts
+ * msc/gsm_data.h: drop unused SMS_HDR_SIZE macro
+ * configure.ac: drop rudimentary check for -fvisibility=hidden
+ * configure.ac: drop useless SQLite3 dependency
+ * libmsc/db.c: print info about database name and libdbi version
+ * libmsc/gsm_04_11.c: clarify implicit CP-ACK handling
+ * libmsc/ran_peer.c: fix msgb memleak in ran_peer_rx_reset()
+ * libmsc/gsm_04_11.c: properly handle TP-User-Data-Length
+ * libmsc/gsm_04_11.c: fix double init of both SMR and SMC FSMs
+ * libmsc/gsm_04_11.c: cosmetic: restructure gsm411_mm_send()
+ * libmsc/gsm_04_08.c: fix: print proper length value
+ * libmsc/gsm_04_08.c: refactor CM Service Request parsing
+ * libmsc/gsm_04_08.c: clarify IMEI rejection in gsm48_rx_mm_serv_req()
+ * libmsc/gsm_04_11_gsup.c: cosmetic: drop useless variable
+ * tests/.../Makefile.am avoid redundant linkage with librt
+ * libmsc/sgs_server.c: do not override rc in case of SCTP_SHUTDOWN_EVENT
+ * libmsc/msc_ho.c: fix unreacheable check of MSC-T role allocation
+ * libmsc/msc_a.c: fix possible NULL-pointer dereferences
+ * sms_queue_test: assert return value of osmo_use_count_get_put()
+ * libmsc/gsm_04_11.c: fix NULL-pointer dereference in gsm340_rx_tpdu()
+ * libmsc/ran_msg_a.c: avoid ternary operator in struct initialization
+ * libmsc/ran_msg_a.c: refactor ran_a_decode_lcls_notification()
+ * libmsc/ran_msg_a.c: prevent chosen_encryption->key buffer overrun
+ * libmsc/mncc_call.c: fix uninitialized access of stack memory
+ * libmsc/ran_peer.c: fix msgb memleaks in ran_peer_down_paging()
+ * libmsc/ran_peer.c: avoid unreasonable use of goto in ran_peer_down_paging()
+ * libmsc/msc_vty.c: fix: use msub_for_vsub() in subscr_dump_full_vty()
+ * libmsc/msc_vty.c: fix documentation of 'show subscriber id'
+ * libmsc/msc_vty.c: use llist_count() in subscr_dump_full_vty()
+ * libmsc/rtp_stream.c: prevent NULL-pointer dereference
+ * libmsc/gsm_04_11.c: properly handle MMTS indication
+ * transaction: accept trans_type enum in trans_log_subsys()
+ * Use GSM23003_MSISDN_MAX_DIGITS from libosmogsm
+ * libmsc/msc_vty.c: refactor 'show subscr / conn / trans' commands
+ * libmsc/msc_vty.c: do not abuse strlen() to check char buffers
+ * tests: share stubs.h from msc_vlr_test as stubs.c
+ * Introduce initial unit test for db_sms_* API
+ * libmsc/db.c: fix storing SMS with empty TP-User-Data
+ * debian/control: add missing libdbd-sqlite3 to Build-Depends
+ * libmsc/db.c: fix potential integer overflow
+ * libmsc/db.c: introduce and use parse_sm_ud_from_result()
+ * libmsc/db.c: warn user about SMS text truncation
+ * libmsc/db.c: get rid of hard-coded SMS expiry threshold
+ * libmsc/mncc_builtin.c: drop dummy switch in int_mncc_recv()
+ * libmsc/gsm_0(4|9)_11_gsup.c: print error message if subscr is not known
+ * gsup_client_mux_tx_error_reply(): fix: do not override IMSI
+ * gsup_client_mux_tx_error_reply(): fix: do not omit session IEs
+ * gsup_client_mux_tx_error_reply(): fix: do not omit message class IE
+ * gsup_client_mux_tx_error_reply(): fix: do not omit SM-RP-MR IE
+ * libmsc/gsm_09_11.c: fix: return trans from establish_nc_ss_trans()
+ * libmsc/gsm_09_11.c: send GSUP PROS_SS ERROR message when needed
+ * libmsc/gsm_04_08.c: clean up unused leftover includes
+ * libmsc/msc_a.c: fix: remove dummy allstate_action of msc_a_fsm
+ * libmsc/paging.c: avoid double zero-initialization
+ * libmsc/paging.c: cosmetic: actually use default branch of switch
+ * libmsc/paging.c: cosmetic: remove leading space in log line
+ * libmsc/gsm_09_11.c: do not abuse LOG_TRANS() and early trans allocation
+ * libmsc/gsm_09_11.c: log network-originated session establishment error
+ * libmsc/gsm_09_11.c: drop rudimentary vsub->cgi.lai.lac check
+ * libmsc/gsm_09_11.c: drop meaningless check for concurrent paging
+ * libmsc/msc_net_init.c: pass pointer to gsm_network directly
+ * libmsc/gsm_09_11.c: inform HLR/EUSE if Paging has failed
+ * libmsc/gsm_09_11.c: properly handle OSMO_GSUP_MSGT_PROC_SS_ERROR
+ * libmsc/gsm_09_11.c: avoid double zero-initialization of gsup_msg
+ * libmsc/gsm_09_11.c: fix broken reference counting for vsub
+ * libmsc/gsm_09_11.c: do not abuse LOG_TRANS() in gsm0911_rcv_nc_ss()
+ * libmsc/gsm_09_11.c: do not suppress rc of gsup_client_mux_tx()
+ * tests/msc_vlr: fix: do not pass RAT type to expect_bssap_clear()
+ * libvlr/vlr.c: do not expire subscribers if periodic LU is disabled
+ * gsm_04_11_gsup.c: fix broken reference counting for vsub
+ * libmsc/gsm_04_11.c: do not abuse LOG_TRANS() in gsm411_alloc_mt_trans()
+ * libmsc/ran_msg_iu.c: fix: properly handle SAPI IE of RANAP_DirectTransfer
+ * Fix: add missing semicolons to OSMO_ASSERT statements
+ * libmsc/msc_vty.c: print subscriber expiration time
+
+ [ Harald Welte ]
+ * Add SGs Interface
+ * debian: depend on libsctp-dev
+ * configure.ac: Check for libsctp
+ * a_iface: Centralize/wrap BSSAP / N-DATA transmission
+ * a_iface: use 'const' qualifier for ran_conn whenever possible
+ * a_iface: Fix hexdumping of N-DATA.req
+ * a_iface: OSMO_ASSERT() if we ever want to send BSSAP with invalid length
+ * smpp_smsc: Call destroy_tlv() when using build_tlv()
+ * smpp: Make libsmpp34 use talloc for its allocations
+ * msub_check_for_release(): Initialize msc_role_a_c
+ * SMPP: Don't accept password or system-id exceeding spec length
+ * Iu: Send SMS over SAPI-3
+
+ [ Philipp Maier ]
+ * a_iface: Include CSFB Indication into BSSMAP CLEAR COMMAND
+ * silent_call: use osmo_strlcpy() instead of strncpy()
+ * msc_vty: add missing header file
+ * vlr_sgs: fix SGs IMSI detech from non EPS services
+ * vlr_sgs: start lu expiration timer on sgs eps detach
+ * sgs_iface: fix nullpointer dereference
+ * vlr_sgs_fsm: make sure vsub is marked used when LA is present
+ * sgs_iface: detect and react to VLR/HLR failure
+
+ [ Oliver Smith ]
+ * debian: depend on libdbd-sqlite3
+ * vlr_lu_fsm.c: assert for invalid events
+ * vty: make retrieve-imeisv-early configurable
+ * vlr: fix IMEI length
+ * vlr: when setting IMEISV, also set IMEI
+ * vlr: optionally send IMEI early to HLR
+ * debian: create -doc subpackage with pdf manuals
+ * contrib/jenkins.sh: run "make maintainer-clean"
+ * vlr_lu_fsm.c: don't send LU reject twice
+
+ [ Keith ]
+ * Don't deliver alert notifications to ESME not yet bound.
+ * Write configuration correctly from vty (alert notifications)
+
+ [ Neels Hofmeyr ]
+ * use only accepted ran_conns for new transactions
+ * gsm_04_11_gsup.c: drop unused conn lookup
+ * SMS queue: properly log failed attempts number
+ * vty: add cmd subscriber ID sms delete-all
+ * vlr_subscr_name(): use OSMO_STRBUF
+ * enable osmo_fsm_term_safely(), apply logging changes
+ * sms queue: avoid repeated Paging for a failed SMS
+ * vlr_subscr: use osmo_use_count
+ * add LOG_TRANS, proper context for all transactions
+ * gsm_04_08_cc: improve logging for CC trans
+ * smpp: fix vlr_subscr use count bugs
+ * vlr subscr get/put: also check against NULL
+ * fix various missing line endings in logging
+ * gsm_04_11: use gsm48_decode_bcd_number2(), evaluate rc
+ * large refactoring: support inter-BSC and inter-MSC Handover
+ * GSUP: include terminating nul in inter-MSC source/destination name
+ * rename bscconfig.h to config.h, cleanup
+ * fix regression: fix internal MNCC operation
+ * vty/cfg: add missing write-back of inter-BSC and inter-MSC HO config
+ * comment: apply function renames to message cycle explanation
+ * ran_a_make_handover_request(): allow no encryption
+ * make msc_a_vsub() and others NULL-safe
+ * no HO call forwarding if no RTP stream
+ * LOG_TRANS: store subsys in trans, unify USSD logging back to DMM
+ * call_leg: remove unused event MSC_EV_CALL_LEG_RTP_RELEASED
+ * call_leg: document the parent_event_* items
+ * add DSS logging category
+ * silence error messages about HANDOVER_END not permitted
+ * build osmo-msc: add "missing" LIBASN1C_LIBS
+ * minor comments in msc_vty.c
+ * manual: adjust and fix auth and ciph docs
+ * do not force encryption on UTRAN
+ * add msc_vlr tests for UMTS without ciphering
+ * doc/sequence_charts/mncc_fsm.msc: add SIP messages, tweak
+ * doc/sequence_charts: fix naming of mncc_fsm to mncc_call
+ * vlr_lu_fsm: fix missing event for IMEISV
+
+ [ Sylvain Munaut ]
+ * libmsc: Allow different channel types to be requested as silent calls
+ * libvlr: Allow 2G auth tuples to be re-used without going through AUTH
+ * make LOG_TRANS() NULL-safe again
+
+ [ Pau Espin Pedrol ]
+ * debian/control: Fix typo
+ * sms_queue: Print dest msisdn instead of unknown subscriber
+ * ran_peer: Move rx_reset_ack logic into its own func
+ * vty: Add option to enable osmux towards BSCs
+ * bssap: Detect BSC Osmux support on RESET (ACK) recv
+ * a_iface: Announce Osmux support on RESET (ACK) send
+ * Request Osmux CID and forward it in Assign Req and Assign Compl
+ * db: Fix call to mempcy with NULL src ptr
+ * db_sms_test: Do not print exact memcmp result
+ * db_sms_test: Remove libdbi expected driver load errors
+ * sms_queue.c: Improve misleading log line
+ * doc: Add Osmux documentation to User Manual
+ * Remove undefined param passed to logging_vty_add_cmds
+ * Fix dependency version requirements
+
+ [ Omar Ramadan ]
+ * Allow MME name preformatted as FQDN in SGsAP
+
+ [ Alexander Couzens ]
+ * remove msc specific db counters
+ * replace osmo_counter with stat_items
+
+ [ Eric Wild ]
+ * libvlr: fix sgsn tmsi creation, replace constant with define
+ * turn -Werror=null-dereference into a warning
+
+ [ Daniel Willmann ]
+ * manuals: Add script to update vty/counter documentation from docker
+ * manuals: Update counter/vty documentation
+ * manuals: Include overview chapter about counters
+
+ [ Thorsten Alteholz ]
+ * fix spelling detected by lintian
+
+ [ Keith Whyte ]
+ * Set coding in mncc_set_cause()
+
+ -- Pau Espin Pedrol <pespin@sysmocom.de> Thu, 08 Aug 2019 16:01:38 +0200
+
osmo-msc (1.3.1) unstable; urgency=medium
[ Neels Hofmeyr ]
diff --git a/debian/compat b/debian/compat
index ec635144f..f599e28b8 100644
--- a/debian/compat
+++ b/debian/compat
@@ -1 +1 @@
-9
+10
diff --git a/debian/control b/debian/control
index 54a35469c..64bb73c90 100644
--- a/debian/control
+++ b/debian/control
@@ -1,36 +1,38 @@
Source: osmo-msc
Section: net
Priority: extra
-Maintainer: Alexander Couzens <lynxis@fe80.eu>
-Build-Depends: debhelper (>=9),
+Maintainer: Osmocom team <openbsc@lists.osmocom.org>
+Build-Depends: debhelper (>= 10),
dh-autoreconf,
autotools-dev,
autoconf,
automake,
libtool,
pkg-config,
- libdbi-dev,
+ libsqlite3-dev,
libsctp-dev,
libtalloc-dev,
- libsmpp34-dev (>= 1.12),
- libasn1c-dev (>= 0.9.28),
- libosmocore-dev (>= 0.10.0),
- libosmo-sccp-dev,
- libosmo-sigtran-dev (>= 0.8.0),
- libosmo-abis-dev,
- libosmo-mgcp-client-dev (>= 1.1.0),
- libosmo-gsup-client-dev (>= 0.2.1),
- libosmo-netif-dev (>= 0.1.0),
- libosmo-ranap-dev (>= 0.2.0)
+ libsmpp34-dev (>= 1.14.0),
+ libasn1c-dev (>= 0.9.30),
+ libosmocore-dev (>= 1.9.0),
+ libosmo-sccp-dev (>= 1.8.0),
+ libosmo-sigtran-dev (>= 1.8.0),
+ libosmo-abis-dev (>= 1.5.0),
+ libosmo-mgcp-client-dev (>= 1.12.0),
+ libosmo-gsup-client-dev (>= 1.7.0),
+ libosmo-netif-dev (>= 1.4.0),
+ libosmo-ranap-dev (>= 1.5.0),
+ osmo-gsm-manuals-dev (>= 1.5.0)
Standards-Version: 3.9.8
-Vcs-Git: git://git.osmocom.org/osmo-msc.git
-Vcs-Browser: https://git.osmocom.org/osmo-msc/
+Vcs-Git: https://gitea.osmocom.org/cellular-infrastructure/osmo-msc
+Vcs-Browser: https://gitea.osmocom.org/cellular-infrastructure/osmo-msc
Homepage: https://osmocom.org/projects/osmomsc
Package: osmo-msc
Architecture: any
Multi-Arch: foreign
-Depends: ${misc:Depends}, ${shlibs:Depends}, libdbd-sqlite3
+Depends: ${misc:Depends}, ${shlibs:Depends}
+Recommends: osmo-mgw
Description: OsmoMSC: Osmocom's Mobile Switching Center for 2G and 3G circuit-switched mobile networks
The Mobile Switching Center (MSC) is the heart of 2G/3G
circuit-switched services. It terminates the A-interface links from the
@@ -62,3 +64,12 @@ Description: OsmoMSC: Osmocom's Mobile Switching Center for 2G and 3G circuit-sw
.
This package contains the debug symbols for osmo-msc in order to
generate meaningful backtraces in bug-reports.
+
+Package: osmo-msc-doc
+Architecture: all
+Section: doc
+Priority: optional
+Depends: ${misc:Depends}
+Description: ${misc:Package} PDF documentation
+ Various manuals: user manual, VTY reference manual and/or
+ protocol/interface manuals.
diff --git a/debian/copyright b/debian/copyright
index e3cd9b3cb..ac8ed52d2 100644
--- a/debian/copyright
+++ b/debian/copyright
@@ -1,6 +1,6 @@
Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: osmo-msc
-Source: git://git.osmocom.org/osmo-msc
+Source: https://gitea.osmocom.org/cellular-infrastructure/osmo-msc
Files: *
Copyright: 2008 Daniel Willmann <daniel@totalueberwachung.de>
diff --git a/debian/osmo-msc-doc.install b/debian/osmo-msc-doc.install
new file mode 100644
index 000000000..ee15cf912
--- /dev/null
+++ b/debian/osmo-msc-doc.install
@@ -0,0 +1 @@
+usr/share/doc/osmo-msc-doc/*.pdf
diff --git a/debian/rules b/debian/rules
index 1cf3a355e..5925ca976 100755
--- a/debian/rules
+++ b/debian/rules
@@ -46,7 +46,7 @@
# debmake generated override targets
# Set options for ./configure
-CONFIGURE_FLAGS += --enable-iu --enable-smpp --with-systemdsystemunitdir=/lib/systemd/system
+CONFIGURE_FLAGS += --enable-iu --enable-smpp --with-systemdsystemunitdir=/lib/systemd/system --enable-manuals
override_dh_auto_configure:
dh_auto_configure -- $(CONFIGURE_FLAGS)
#
@@ -61,3 +61,7 @@ override_dh_strip:
# Print test results in case of a failure
override_dh_auto_test:
dh_auto_test || (find . -name testsuite.log -exec cat {} \; ; false)
+
+# Don't create .pdf.gz files (barely saves space and they can't be opened directly by most pdf readers)
+override_dh_compress:
+ dh_compress -X.pdf
diff --git a/doc/examples/osmo-msc/osmo-msc.cfg b/doc/examples/osmo-msc/osmo-msc.cfg
index f80143d21..7c5fe2d55 100644
--- a/doc/examples/osmo-msc/osmo-msc.cfg
+++ b/doc/examples/osmo-msc/osmo-msc.cfg
@@ -1,21 +1,30 @@
!
! OsmoMSC configuration saved from vty
!
+log stderr
+ logging color 1
+ logging print category-hex 0
+ logging print category 1
+ logging timestamp 0
+ logging print file basename last
+ logging print level 1
+
line vty
no login
!
network
- network country code 1
- mobile network code 1
+ network country code 001
+ mobile network code 01
short name OsmoMSC
long name OsmoMSC
encryption a5 0
rrlp mode none
mm info 1
+ mgw 0
+ remote-ip 127.0.0.1
+ remote-port 2427
+ local-port 2728
msc
- mgw remote-ip 10.23.24.1
- mgw remote-port 2427
- mgw local-port 2728
assign-tmsi
auth-tuple-max-reuse-count 3
auth-tuple-reuse-on-error 1
diff --git a/doc/examples/osmo-msc/osmo-msc_custom-sccp.cfg b/doc/examples/osmo-msc/osmo-msc_custom-sccp.cfg
index 39ca9d496..503359899 100644
--- a/doc/examples/osmo-msc/osmo-msc_custom-sccp.cfg
+++ b/doc/examples/osmo-msc/osmo-msc_custom-sccp.cfg
@@ -1,6 +1,14 @@
!
! OsmoMSC configuration saved from vty
!
+log stderr
+ logging color 1
+ logging print category-hex 0
+ logging print category 1
+ logging timestamp 0
+ logging print file basename last
+ logging print level 1
+
line vty
no login
!
@@ -12,16 +20,19 @@ network
encryption a5 0
rrlp mode none
mm info 1
+ mgw 0
+ remote-ip 127.0.0.1
+ remote-port 2427
+ local-port 2728
cs7 instance 0
point-code 0.23.1
asp asp-clnt-OsmoMSC-A-Iu 2905 0 m3ua
! where to reach the STP:
remote-ip 127.0.0.5
-! local-ip 10.23.24.1
+ !local-ip 10.23.24.1
+ role asp
+ sctp-role client
msc
cs7-instance-a 0
cs7-instance-iu 0
- mgw remote-ip 10.23.24.1
- mgw remote-port 2427
- mgw local-port 2728
assign-tmsi
diff --git a/doc/examples/osmo-msc/osmo-msc_multi-cs7.cfg b/doc/examples/osmo-msc/osmo-msc_multi-cs7.cfg
index 2af17261d..22f8734de 100644
--- a/doc/examples/osmo-msc/osmo-msc_multi-cs7.cfg
+++ b/doc/examples/osmo-msc/osmo-msc_multi-cs7.cfg
@@ -1,6 +1,14 @@
!
! OsmoMSC configuration saved from vty
!
+log stderr
+ logging color 1
+ logging print category-hex 0
+ logging print category 1
+ logging timestamp 0
+ logging print file basename last
+ logging print level 1
+
line vty
no login
!
@@ -12,18 +20,23 @@ network
encryption a5 0
rrlp mode none
mm info 1
+ mgw 0
+ remote-ip 127.0.0.1
+ remote-port 2427
+ local-port 2728
cs7 instance 0
point-code 0.23.1
asp asp-clnt-OsmoMSC-A 2905 0 m3ua
remote-ip 127.0.0.5
+ role asp
+ sctp-role client
cs7 instance 1
point-code 0.23.2
asp asp-clnt-OsmoMSC-Iu 2905 0 m3ua
remote-ip 127.0.0.6
+ role asp
+ sctp-role client
msc
cs7-instance-a 0
cs7-instance-iu 1
- mgw remote-ip 10.23.24.1
- mgw remote-port 2427
- mgw local-port 2728
assign-tmsi
diff --git a/doc/manuals/Makefile.am b/doc/manuals/Makefile.am
index 42e353d03..14d142da3 100644
--- a/doc/manuals/Makefile.am
+++ b/doc/manuals/Makefile.am
@@ -1,6 +1,7 @@
EXTRA_DIST = osmomsc-usermanual.adoc \
osmomsc-usermanual-docinfo.xml \
osmomsc-vty-reference.xml \
+ regen_doc.sh \
chapters \
images \
vty
@@ -13,5 +14,11 @@ if BUILD_MANUALS
VTY_REFERENCE = osmomsc-vty-reference.xml
include $(OSMO_GSM_MANUALS_DIR)/build/Makefile.vty-reference.inc
+ BUILT_REFERENCE_XML = $(builddir)/vty/msc_vty_reference.xml
+ $(builddir)/vty/msc_vty_reference.xml: $(top_builddir)/src/osmo-msc/osmo-msc
+ mkdir -p $(builddir)/vty
+ $(top_builddir)/src/osmo-msc/osmo-msc --vty-ref-xml > $@
+
+ OSMO_REPOSITORY = osmo-msc
include $(OSMO_GSM_MANUALS_DIR)/build/Makefile.common.inc
endif
diff --git a/doc/manuals/chapters/counters_generated.adoc b/doc/manuals/chapters/counters_generated.adoc
index afeb8ffe5..f55be27ac 100644
--- a/doc/manuals/chapters/counters_generated.adoc
+++ b/doc/manuals/chapters/counters_generated.adoc
@@ -1,5 +1,8 @@
+
// autogenerated by show asciidoc counters
-These counters and their description based on OsmoMSC UNKNOWN (OsmoMSC).
+These counters and their description based on OsmoMSC 1.4.0 (OsmoMSC).
+
+=== Rate Counters
// generating tables for rate_ctr_group
// rate_ctr_group table mobile switching center
@@ -7,27 +10,41 @@ These counters and their description based on OsmoMSC UNKNOWN (OsmoMSC).
[options="header"]
|===
| Name | Reference | Description
-| loc_update_type:attach | <<msc_loc_update_type:attach>> | Received location update imsi attach requests.
-| loc_update_type:normal | <<msc_loc_update_type:normal>> | Received location update normal requests.
-| loc_update_type:periodic | <<msc_loc_update_type:periodic>> | Received location update periodic requests.
-| loc_update_type:detach | <<msc_loc_update_type:detach>> | Received location update detach indication.
-| loc_update_resp:failed | <<msc_loc_update_resp:failed>> | Rejected location updates.
-| loc_update_resp:completed | <<msc_loc_update_resp:completed>> | Successful location updates.
-| sms:submitted | <<msc_sms:submitted>> | Received a RPDU from a MS (MO).
-| sms:no_receiver | <<msc_sms:no_receiver>> | Counts SMS which couldn't routed because no receiver found.
-| sms:delivered | <<msc_sms:delivered>> | Global SMS Deliver attempts.
-| sms:rp_err_mem | <<msc_sms:rp_err_mem>> | CAUSE_MT_MEM_EXCEEDED errors of MS responses on a sms deliver attempt.
-| sms:rp_err_other | <<msc_sms:rp_err_other>> | Other error of MS responses on a sms delive attempt.
-| sms:deliver_unknown_error | <<msc_sms:deliver_unknown_error>> | Unknown error occured during sms delivery.
-| call:mo_setup | <<msc_call:mo_setup>> | Received setup requests from a MS to init a MO call.
-| call:mo_connect_ack | <<msc_call:mo_connect_ack>> | Received a connect ack from MS of a MO call. Call is now succesful connected up.
-| call:mt_setup | <<msc_call:mt_setup>> | Sent setup requests to the MS (MT).
-| call:mt_connect | <<msc_call:mt_connect>> | Sent a connect to the MS (MT).
-| call:active | <<msc_call:active>> | Count total amount of calls that ever reached active state.
-| call:complete | <<msc_call:complete>> | Count total amount of calls which got terminated by disconnect req or ind after reaching active state.
-| call:incomplete | <<msc_call:incomplete>> | Count total amount of call which got terminated by any other reason after reaching active state.
+| loc_update_type:attach | <<msc_loc_update_type:attach>> | Received Location Update (IMSI Attach) requests.
+| loc_update_type:normal | <<msc_loc_update_type:normal>> | Received Location Update (LAC change) requests.
+| loc_update_type:periodic | <<msc_loc_update_type:periodic>> | Received (periodic) Location Update requests.
+| loc_update_type:detach | <<msc_loc_update_type:detach>> | Received IMSI Detach indications.
+| loc_update_resp:failed | <<msc_loc_update_resp:failed>> | Rejected Location Updates requests.
+| loc_update_resp:completed | <<msc_loc_update_resp:completed>> | Successful Location Update procedures.
+| cm_service_request:rejected | <<msc_cm_service_request:rejected>> | Rejected CM Service Requests.
+| cm_service_request:accepted | <<msc_cm_service_request:accepted>> | Accepted CM Service Requests.
+| paging_resp:rejected | <<msc_paging_resp:rejected>> | Rejected Paging Responses.
+| paging_resp:accepted | <<msc_paging_resp:accepted>> | Accepted Paging Responses.
+| sms:submitted | <<msc_sms:submitted>> | Total MO SMS received from the MS.
+| sms:no_receiver | <<msc_sms:no_receiver>> | Failed MO SMS delivery attempts (no receiver found).
+| sms:deliver_unknown_error | <<msc_sms:deliver_unknown_error>> | Failed MO SMS delivery attempts (other reason).
+| sms:delivered | <<msc_sms:delivered>> | Total MT SMS delivery attempts.
+| sms:rp_err_mem | <<msc_sms:rp_err_mem>> | Failed MT SMS delivery attempts (no memory).
+| sms:rp_err_other | <<msc_sms:rp_err_other>> | Failed MT SMS delivery attempts (other reason).
+| call:mo_setup | <<msc_call:mo_setup>> | Received MO SETUP messages (MO call establishment).
+| call:mo_connect_ack | <<msc_call:mo_connect_ack>> | Received MO CONNECT messages (MO call establishment).
+| call:mt_setup | <<msc_call:mt_setup>> | Sent MT SETUP messages (MT call establishment).
+| call:mt_connect | <<msc_call:mt_connect>> | Sent MT CONNECT messages (MT call establishment).
+| call:active | <<msc_call:active>> | Calls that ever reached the active state.
+| call:complete | <<msc_call:complete>> | Calls terminated by DISCONNECT message after reaching the active state.
+| call:incomplete | <<msc_call:incomplete>> | Calls terminated by any other reason after reaching the active state.
+| nc_ss:mo_requests | <<msc_nc_ss:mo_requests>> | Received MS-initiated call independent SS/USSD requests.
+| nc_ss:mo_established | <<msc_nc_ss:mo_established>> | Established MS-initiated call independent SS/USSD sessions.
+| nc_ss:mt_requests | <<msc_nc_ss:mt_requests>> | Received network-initiated call independent SS/USSD requests.
+| nc_ss:mt_established | <<msc_nc_ss:mt_established>> | Established network-initiated call independent SS/USSD sessions.
+| bssmap:cipher_mode_reject | <<msc_bssmap:cipher_mode_reject>> | Number of CIPHER MODE REJECT messages processed by BSSMAP layer
+| bssmap:cipher_mode_complete | <<msc_bssmap:cipher_mode_complete>> | Number of CIPHER MODE COMPLETE messages processed by BSSMAP layer
|===
+== Osmo Stat Items
+
// generating tables for osmo_stat_items
+== Osmo Counters
+
// generating tables for osmo_counters
// ungrouped osmo_counters
.ungrouped osmo counters
@@ -35,6 +52,5 @@ These counters and their description based on OsmoMSC UNKNOWN (OsmoMSC).
|===
| Name | Reference | Description
| msc.active_calls | <<ungroup_counter_msc.active_calls>> |
+| msc.active_nc_ss | <<ungroup_counter_msc.active_nc_ss>> |
|===
-
-
diff --git a/doc/manuals/chapters/net.adoc b/doc/manuals/chapters/net.adoc
index 06be4bad2..6edb9ee3a 100644
--- a/doc/manuals/chapters/net.adoc
+++ b/doc/manuals/chapters/net.adoc
@@ -101,32 +101,56 @@ operating system on which OsmoMSC is running.
=== Authentication
-Authorized subscribers must be entered in the HLR database, see the _OsmoHLR
-reference manual_ <<userman-osmohlr>>. If authentication tokens (such as KI for
-2G, or K and OP/OPC for UMTS) are present in the HLR, OsmoMSC will only attach
-a subscriber after successful authentication.
+A subscriber's IMSI must be entered in the HLR database to be able to attach. A
+subscriber-create-on-demand feature is also available, see the _OsmoHLR
+reference manual_ <<userman-osmohlr>>.
-If no authentication keys are present in the HLR for a given subscriber,
-OsmoMSC will attach the subscriber _without_ authentication. You can reject
-subscribers that lack authentication info in the HLR with this setting:
+A known IMSI in the HLR may or may not have authentication keys associated,
+which profoundly affects the ability to attach and the algorithms used to
+negotiate authentication, as the following sections explain for 2G and 3G.
+
+==== Authentication on 2G
+
+If authentication tokens (such as KI for 2G, or K and OP/OPC for UMTS) are
+present in the HLR, OsmoMSC will only attach a subscriber after successful
+authentication. Note that the 3G authentication keys are also used on 2G when
+the MS indicates UMTS AKA capability, in which case the full UMTS style mutual
+authentication may indeed take place on 2G (GERAN).
+
+On 2G, if no authentication keys are present in the HLR for a given subscriber,
+OsmoMSC will attach the subscriber _without_ authentication. Subscribers that
+lack authentication keys can always be rejected with this setting:
----
network
authentication required
----
+==== Authentication on 3G
+
+3G (UTRAN) always requires authentication (a.k.a. Integrity Protection) by
+specification, and hence authentication keys must be present in the HLR for a
+subscriber to be able to attach on 3G.
+
+OsmoMSC always indicates UIA1 and UIA2 as permitted Integrity Protection
+algorithms on 3G.
+
=== Ciphering
To enable ciphering on the radio link, authentication must take place first:
-the Kc resulting from authentication is the key used for ciphering. Hence, all
-subscribers must have authentication tokens available in the HLR for ciphering.
+the Kc resulting from authentication is the key used for ciphering. Hence, to
+be able to use ciphering, a subscriber must have authentication tokens
+available in the HLR.
+
+==== Ciphering on 2G
The MS, BTS and MSC must agree on a ciphering algorithm to use.
- The MS sends its supported ciphering algorithms via Classmark IEs during
Location Updating.
- Typically the BSC needs to know which A5 ciphers are supported by connected
- BTSes.
+ BTSes, see the `network / encryption a5` configuration item for OsmoBSC
+ <<vty-ref-osmobsc>>.
- Finally, OsmoMSC may impose that specific A5 ciphers shall not be considered.
It is the responsibility of the BSC to then pick an A5 cipher that satisfies
@@ -143,12 +167,43 @@ network
+
----
network
- encryption a5 3
+ encryption a5 1 3
----
- Never use A5/2: it is an "export grade cipher" and has been deprecated for
its low ciphering strength.
-NOTE: At the time of writing, OsmoMSC supports setting only a single A5 cipher,
-while it should be able to allow a set of ciphers. This is subject to ongoing
-development.
+- To allow either no encryption or any of A5/1 or A5/3 based on the presence of
+ authentication keys and abilities of the MS, SIM and BSC configuration, it is
+ recommended to enable all ciphers in OsmoMSC. The highest available A5 cipher
+ will be used; the order in which the A5 options are configured does not
+ affect the choice.
++
+----
+network
+ encryption a5 0 1 3
+----
+
+==== Ciphering on 3G
+
+While authentication is always required on 3G, ciphering is optional.
+
+So far OsmoMSC allows switching ciphering on 3G either on or off -- the default
+behavior is to enable ciphering. (Individual choice of algorithms may be added
+in the future.)
+
+Disable 3G ciphering:
+
+----
+network
+ encryption uea 0
+----
+
+Enable 3G ciphering (default):
+
+----
+network
+ encryption uea 1 2
+----
+
+OsmoMSC indicates UEA1 and UEA2 as permitted encryption algorithms on 3G.
diff --git a/doc/manuals/chapters/osmux_msc.adoc b/doc/manuals/chapters/osmux_msc.adoc
new file mode 100644
index 000000000..ed722f2a0
--- /dev/null
+++ b/doc/manuals/chapters/osmux_msc.adoc
@@ -0,0 +1,65 @@
+include::{commondir}/chapters/osmux/osmux.adoc[]
+
+=== Osmux Support in {program-name}
+
+==== {program-name} in a A/IP with IPA/SCCPlite network setup
+
+In this kind of setup, the CN side of BSC co-located MGW is managed by the MSC,
+meaning the use of Osmux is transparent to BSC since MSC takes care of both peer
+MGW connections. Moreover, in this case the MSC has no dynamic information on
+Osmux support in the BSC co-located MGW until `CRCX` time, which means
+configuration on both nodes need to be carefully set up so they can work
+together.
+
+Osmux usage in {program-name} in managed through the VTY command `osmux
+(on|off|only)`. Since there's no dynamic information on Osmux support, it may be
+required in the future to have an extra VTY command which can be set per BSC to
+fine-tune which ones should use Osmux and which shouldn't.
+
+{program-name} will behave differently during call set up based on the VTY
+command presented above:
+
+* `off`: {program-name} won't include an `X-Osmux` extension to `CRCX` sent to
+ the BSC co-located MGW when configuring the CN side of the MGW endpoint. If
+ the MGW answers with a `CRCX ACK` containing an `X-Osmux`, {program-name} will
+ cancel the call establishment.
+* `on`: {program-name} will initially configure its co-located MGW to use Osmux, then
+ similarly send a `CRCX` with an `X-Osmux` extension towards the BSC co-located
+ MGW. Under this configuration, if the BSC co-located MGW didn't support Osmux,
+ it could send a `CRCX ACK` without `X-Osmux` extension or fail (depending on
+ its own configuration), and {program-name} could choose to re-create its local
+ connection as non-Osmux (RTP) (and possibly try again against BSC co-located
+ MGW), but this behavior is currently not implemented. As a result, currently
+ `on` behaves the same as `only`.
+* `only`: {program-name} will configure its co-located MGW as well as the BSC
+ co-located MGW to use Osmux by including the `X-Osmux` MGCP extension. If MGW
+ rejects to use Osmux, {program-name} will reject the call and the call
+ establishment will fail.
+
+==== {program-name} in a 3GPP AoIP network setup
+
+Osmux usage in {program-name} in managed through the VTY command `osmux
+(on|off|only)`. Once enabled (`on` or `only`), {program-name} will start
+appending the vendor specific _Osmux Support_ IE in _BSSMAP RESET_ and _BSSMAP
+RESET-ACK_ message towards the BSC in order to announce it supports Osmux, and
+BSC will do the same. This way, {program-name} can decide whether to use Osmux
+or not based on this information when setting up a call (this time using _Osmux
+CID_ IE). It should be noted that this option should not be enabled unless BSCs
+managed by {program-name} support handling this extension IE (like OsmoBSC),
+3rd-party BSCs might otherwise refuse the related _RESET_/_RESET-ACK_ messages.
+
+{program-name} will behave differently during call set up based on the VTY
+command presented above:
+
+* `off`: {program-name} won't use Osmux. That is, it will send a _BSSMAP Assign
+ Request_ without the _Osmux CID_ IE, and will send a `CRCX` without `X-Osmux`
+ extension towards its co-located MGW.
+* `on`: If BSC announced Osmux support to {program-name} during _BSSMAP RESET_
+ time, then {program-name} will set up the call to use Osmux (by adding
+ `X-Osmux` to MGCP `CRCX` and _Osmux CID_ IE to _BSSMAP Assign Request_). If
+ the BSC didn't announce Osmux support to {program-name}, then {program-name}
+ will use RTP to set up the call (by avoiding addition of previously described
+ bits).
+* `only`: Same as per `on`, except that {program-name} will allow to set up only
+ Osmux calls on the CN-side, this is, it will reject to set up voice calls for
+ BSC which didn't announce Osmux support.
diff --git a/doc/manuals/chapters/running.adoc b/doc/manuals/chapters/running.adoc
index 9d56f1fcd..3041145dc 100644
--- a/doc/manuals/chapters/running.adoc
+++ b/doc/manuals/chapters/running.adoc
@@ -5,14 +5,14 @@ arguments:
=== SYNOPSIS
-*osmo-msc* [-h|-V] [-d 'DBGMASK'] [-D] [-c 'CONFIGFILE'] [-s] [-T] [-e 'LOGLEVEL'] [-l 'DATABASE'] [-M 'SOCKETPATH'] [-C]
+*osmo-msc* [-h|-V] [-d 'DBGMASK'] [-D] [-c 'CONFIGFILE'] [-s] [-T] [-e 'LOGLEVEL']
=== OPTIONS
*-h, --help*::
Print a short help message about the supported options
*-V, --version*::
- Print the compile-time version number of the OsmoBTS program
+ Print the compile-time version number of the program
*-d, --debug 'DBGMASK','DBGLEVELS'*::
Set the log subsystems and levels for logging to stderr. This
has mostly been superseded by VTY-based logging configuration,
@@ -35,16 +35,6 @@ arguments:
Set the global log level for logging to stderr. This has mostly
been deprecated by VTY based logging configuration, see
<<logging>> for more information.
-*-l, --database 'DATABASE'*::
- Specify the file name of the SQLite3 database to use as SMS storage
-*-M, --mncc-sock-path*::
- Enable the MNCC socket for an external MNCC handler. See
- <<mncc>> for further information.
-*-m, --mncc-sock*::
- Same as option -M (deprecated).
-*-C, --no-dbcounter*::
- Deprecated. DB statistics and counter has been removed.
- This option is only valid for compatiblity and does nothing.
=== Multiple instances
@@ -74,9 +64,18 @@ smpp
More on SMPP configuration in <<smpp-config-global>>.
-The external MNCC handler is configured by the `--mncc-sock` commandline
-argument. Choose a different such socket path for each OsmoMSC instance running
-on the same file system. See more in <<mncc-external>>.
+The external MNCC handler is a UNIX domain socket that is created when external MNCC handling is configured. A separate
+path must be used per osmo-msc instance:
+
+----
+msc
+ mncc external /tmp/mncc_socket
+----
+
+More on MNCC in <<mncc-external>>.
+
+The SGs interface by default listens on 0.0.0.0:29118 (SCTP). Each instance of OsmoMSC must use a different IP address
+and/or port. For details about the configuration of the SGs interface, see section <<sgs>>.
For the following links, OsmoMSC acts as a client and does not listen/bind to a
specific interface, and will hence not encounter conflicts for multiple instances
@@ -84,55 +83,47 @@ running on the same interface:
- The SCCP/M3UA links are established by OsmoMSC contacting an STP.
- The GSUP link is established by OsmoMSC contacting an HLR.
+- The MGCP link is established by OsmoMSC contacting an MGW.
=== Configure primary links
==== Configure SCCP/M3UA to accept _A_ and _IuCS_ links
-OsmoMSC will contact an STP instance to establish an SCCP/M3UA link. BSC and
-HNBGW will then reach the MSC via this link. By default, an STP instance is
-assumed to listen on the default M3UA port (2905) on the local host.
+OsmoMSC acts as client to contact an STP instance and establish an SCCP/M3UA
+link.
-Establishing an SCCP/M3UA link towards an STP instance not on the local host
-can be configured as follows:
+An example configuration of OsmoMSC's SCCP link:
----
cs7 instance 0
- asp my-OsmoMSC 2905 0 m3ua
- ! IP address of the remote STP:
- remote-ip 10.23.24.1
+ point-code 0.23.1
+ asp asp-clnt-OsmoMSC-A-Iu 2905 0 m3ua
+ remote-ip 127.0.0.1
+ role asp
+ sctp-role client
----
+This configuration is explained in detail in <<cs7_config>>.
+
Note that _A_ and _IuCS_ may use different SCCP instances, if so desired:
----
cs7 instance 0
asp my-OsmoMSC-A 2905 0 m3ua
remote-ip 10.23.42.1
+ role asp
+ sctp-role client
cs7 instance 1
asp my-OsmoMSC-Iu 2905 0 m3ua
remote-ip 10.23.42.2
+ role asp
+ sctp-role client
msc
cs7-instance-a 0
cs7-instance-iu 1
----
-A full configuration needs an `asp` on an `as` -- an Application Server Process
-running on an Application Server -- as well as a local point code and routing
-configuration. The SCCP VTY automatically creates those parts that are missing,
-by assuming sane defaults. A complete configuration would look like this:
-
-----
-cs7 instance 0
- point-code 0.23.1
- asp my-OsmoMSC-A-Iu 2905 0 m3ua
- remote-ip 127.0.0.1
- as my-as-for-OsmoMSC-A-Iu m3ua
- asp my-OsmoMSC-A-Iu
- routing-key 0 0.23.1
-----
-
==== Configure GSUP to reach the HLR
OsmoMSC will assume a GSUP server (OsmoHLR) to run on the local host and the
@@ -146,3 +137,36 @@ hlr
! default port is 4222, optionally configurable by:
remote-port 1234
----
+
+==== Configure MGCP to connect to an MGW
+
+OsmoMSC uses a media gateway (typically OsmoMGW) to direct RTP streams. By
+default, an MGW is expected to receive MGCP requests on the IANA-registered
+default port for MGCP (2427) on local host (127.0.0.1).
+
+Here is an example configuration for a remote MGW:
+
+----
+network
+ mgw 0
+ remote-ip 10.9.8.7
+ remote-port 2427
+ reset-endpoint rtpbridge/* <1>
+----
+<1> The 'reset-endpoint' setting instructs the OsmoMGW to send a wildcarded
+DLCX to the media gateway. This helps to clear lingering calls from the
+media gateway when the OsmoMSC is restarted.
+
+OsmoMSC is also able to handle a pool of media gateways for load
+distribution. See also <<mgw_pooling>>.
+
+[NOTE]
+====
+Previous versions of OsmoMSC (1.9.0 and below) didn't have the 'mgw' VTY node and
+hence didn't support the MGW pooling feature. Therefore, historically the MGW
+related commands where placed under the `msc` VTY node. The MGW related commands
+under the `msc` VTY are still parsed and used but its use is deprecated and
+hence discouraged in favour of the new `mgw` node. Writing the config to a file
+from within OsmoMSC will automatically convert the config to use the new `mgw`
+node.
+====
diff --git a/doc/manuals/chapters/sgs.adoc b/doc/manuals/chapters/sgs.adoc
new file mode 100644
index 000000000..1f0240bed
--- /dev/null
+++ b/doc/manuals/chapters/sgs.adoc
@@ -0,0 +1,55 @@
+[[sgs]]
+== SGs interface
+
+OsmoMSC offers an SGs interface using the SGsAP protocol. The SGs interface is an
+optional interface between a 2G (GERAN) / 3G (UTRAN) MSC and an 4G (EUTRAN) MME.
+Its purpose is to facilitate both CSFB (Circuit-Switched Fall Back) and SMSoS
+(SMS over SGs). It is used for Mobility management (MM) and paging procedures
+between the EPS (Evolved Packet Services) and CS (Circuit Switched) domain.
+
+=== VTY configuration
+
+The SGs interface implementation in OsmoMSC is automatically active and requires
+only minimal configuration. When no specific configuration is provided OsmoMSC
+will listen on 0.0.0.0:29118 (SCTP) for incoming connections.
+
+This is sufficient in the most configurations, but in larger installations,
+where services are either tied to specific interfaces and/or more instances of
+OsmoMSC run in parallel, a custom configuration is necessary.
+
+The user has the option to configure the IP address (`local-ip`) and the SCTP
+port (`local-port`) and also the `vlr-name` that OsmoMSC uses to identify itself
+towards the MME. It should be noted that the `vlr-name` is usually the DNS name
+for the IP address of the VLR/MSC, so IP address used and the `vlr-name` should
+match the DNS server entry.
+
+----
+sgs
+ local-ip 127.0.0.1
+ local-port 29118
+ vlr-name vlr.example.net
+----
+
+In order to fine tune the behavior of the SGs interface the user also has
+control over the relevant timers (`ts5`, `ts6-2`, `ts7`, `ts11`, `ts14`, `ts15`)
+and counters (`ns7`, `ns11`). Each timer and counter has to be configured
+separately. In the following example we change the value of ts and ns11.
+
+----
+sgs
+ timer ts7 23
+ counter ns11 100
+----
+
+
+[NOTE]
+====
+In case multiple instances of OsmoMSC run in parallel, it is advised to use a
+different `vlr-name` for each instance. In any case it must be ensured that the
+SGs interface of each instance is bound to a different IP address and/or port.
+====
+
+=== Connection monitoring
+
+The user can use the VTY command `show sgs-connections` to list the MMEs that
+are currently connected to OsmoMSC.
diff --git a/doc/manuals/osmomsc-usermanual.adoc b/doc/manuals/osmomsc-usermanual.adoc
index 4fd0cc71e..45be140f5 100644
--- a/doc/manuals/osmomsc-usermanual.adoc
+++ b/doc/manuals/osmomsc-usermanual.adoc
@@ -14,22 +14,38 @@ include::{srcdir}/chapters/running.adoc[]
include::{srcdir}/chapters/control.adoc[]
+include::./common/chapters/counters-overview.adoc[]
+
include::{srcdir}/chapters/counters.adoc[]
include::./common/chapters/vty.adoc[]
include::./common/chapters/logging.adoc[]
+include::./common/chapters/sigtran-osmocom.adoc[]
+
+include::./common/chapters/cs7-config.adoc[]
+
+include::./common/chapters/cs7-config.adoc[]
+
include::{srcdir}/chapters/net.adoc[]
include::./common/chapters/smpp.adoc[]
include::./common/chapters/mncc.adoc[]
+include::{srcdir}/chapters/osmux_msc.adoc[]
+
+include::./common/chapters/mgwpool.adoc[]
+
+include::{srcdir}/chapters/sgs.adoc[]
+
include::./common/chapters/control_if.adoc[]
include::./common/chapters/gsup.adoc[]
+include::./common/chapters/vty_cpu_sched.adoc[]
+
include::./common/chapters/port_numbers.adoc[]
include::./common/chapters/bibliography.adoc[]
@@ -37,4 +53,3 @@ include::./common/chapters/bibliography.adoc[]
include::./common/chapters/glossary.adoc[]
include::./common/chapters/gfdl.adoc[]
-
diff --git a/doc/manuals/regen_doc.sh b/doc/manuals/regen_doc.sh
new file mode 100755
index 000000000..55cda5c4c
--- /dev/null
+++ b/doc/manuals/regen_doc.sh
@@ -0,0 +1,17 @@
+#!/bin/sh -x
+
+if [ -z "$DOCKER_PLAYGROUND" ]; then
+ echo "You need to set DOCKER_PLAYGROUND"
+ exit 1
+fi
+
+SCRIPT=$(realpath "$0")
+MANUAL_DIR=$(dirname "$SCRIPT")
+
+COMMIT=${COMMIT:-$(git log -1 --format=format:%H)}
+
+cd "$DOCKER_PLAYGROUND/scripts" || exit 1
+
+OSMO_MSC_BRANCH=$COMMIT ./regen_doc.sh osmo-msc 4254 \
+ "$MANUAL_DIR/chapters/counters_generated.adoc" \
+ "$MANUAL_DIR/vty/msc_vty_reference.xml"
diff --git a/doc/manuals/vty/msc_vty_reference.xml b/doc/manuals/vty/msc_vty_reference.xml
deleted file mode 100644
index bb7e958b2..000000000
--- a/doc/manuals/vty/msc_vty_reference.xml
+++ /dev/null
@@ -1,2686 +0,0 @@
-<vtydoc xmlns='urn:osmocom:xml:libosmocore:vty:doc:1.0'>
- <node id='_common_cmds_'>
- <name>Common Commands</name>
- <description>These commands are available on all VTY nodes. They are listed here only once, to unclutter the VTY reference.</description>
- <command id='help'>
- <params>
- <param name='help' doc='Description of the interactive help system' />
- </params>
- </command>
- <command id='list'>
- <params>
- <param name='list' doc='Print command list' />
- </params>
- </command>
- <command id='write terminal'>
- <params>
- <param name='write' doc='Write running configuration to memory, network, or terminal' />
- <param name='terminal' doc='Write to terminal' />
- </params>
- </command>
- <command id='write file'>
- <params>
- <param name='write' doc='Write running configuration to memory, network, or terminal' />
- <param name='file' doc='Write to configuration file' />
- </params>
- </command>
- <command id='write memory'>
- <params>
- <param name='write' doc='Write running configuration to memory, network, or terminal' />
- <param name='memory' doc='Write configuration to the file (same as write file)' />
- </params>
- </command>
- <command id='write'>
- <params>
- <param name='write' doc='Write running configuration to memory, network, or terminal' />
- </params>
- </command>
- <command id='show running-config'>
- <params>
- <param name='show' doc='Show running system information' />
- <param name='running-config' doc='running configuration' />
- </params>
- </command>
- <command id='exit'>
- <params>
- <param name='exit' doc='Exit current mode and down to previous mode' />
- </params>
- </command>
- <command id='end'>
- <params>
- <param name='end' doc='End current mode and change to enable mode.' />
- </params>
- </command>
- </node>
- <node id='view'>
- <name>view</name>
- <command id='show version'>
- <params>
- <param name='show' doc='Show running system information' />
- <param name='version' doc='Displays program version' />
- </params>
- </command>
- <command id='show online-help'>
- <params>
- <param name='show' doc='Show running system information' />
- <param name='online-help' doc='Online help' />
- </params>
- </command>
- <command id='enable'>
- <params>
- <param name='enable' doc='Turn on privileged mode command' />
- </params>
- </command>
- <command id='terminal length &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|lglobal|llapd|linp|lmux|lmi|lmib|lsms|lctrl|lgtp|lstats|lgsup|loap|lss7|lsccp|lsua|lm3ua|lmgcp|ljibuf) (debug|info|notice|error|fatal)'>
- <params>
- <param name='logging' doc='Configure logging' />
- <param name='level' doc='Set the log level for a specified category' />
- <param name='rll' doc='A-bis Radio Link Layer (RLL)' />
- <param name='cc' doc='Layer3 Call Control (CC)' />
- <param name='mm' doc='Layer3 Mobility Management (MM)' />
- <param name='rr' doc='Layer3 Radio Resource (RR)' />
- <param name='mncc' doc='MNCC API for Call Control application' />
- <param name='pag' doc='Paging Subsystem' />
- <param name='msc' doc='Mobile Switching Center' />
- <param name='mgcp' doc='Media Gateway Control Protocol' />
- <param name='ho' doc='Hand-Over' />
- <param name='db' doc='Database Layer' />
- <param name='ref' doc='Reference Counting' />
- <param name='ctrl' doc='Control interface' />
- <param name='smpp' doc='SMPP interface for external SMS apps' />
- <param name='ranap' doc='Radio Access Network Application Part Protocol' />
- <param name='vlr' doc='Visitor Location Register' />
- <param name='iucs' doc='Iu-CS Protocol' />
- <param name='bssap' doc='BSSAP Protocol (A Interface)' />
- <param name='lglobal' doc='Library-internal global log family' />
- <param name='llapd' doc='LAPD in libosmogsm' />
- <param name='linp' doc='A-bis Intput Subsystem' />
- <param name='lmux' doc='A-bis B-Subchannel TRAU Frame Multiplex' />
- <param name='lmi' doc='A-bis Input Driver for Signalling' />
- <param name='lmib' doc='A-bis Input Driver for B-Channels (voice)' />
- <param name='lsms' doc='Layer3 Short Message Service (SMS)' />
- <param name='lctrl' doc='Control Interface' />
- <param name='lgtp' doc='GPRS GTP library' />
- <param name='lstats' doc='Statistics messages and logging' />
- <param name='lgsup' doc='Generic Subscriber Update Protocol' />
- <param name='loap' doc='Osmocom Authentication Protocol' />
- <param name='lss7' doc='libosmo-sigtran Signalling System 7' />
- <param name='lsccp' doc='libosmo-sigtran SCCP Implementation' />
- <param name='lsua' doc='libosmo-sigtran SCCP User Adaptation' />
- <param name='lm3ua' doc='libosmo-sigtran MTP3 User Adaptation' />
- <param name='lmgcp' doc='libosmo-mgcp Media Gateway Control Protocol' />
- <param name='ljibuf' doc='libosmo-netif Jitter Buffer' />
- <param name='debug' doc='Log debug messages and higher levels' />
- <param name='info' doc='Log informational messages and higher levels' />
- <param name='notice' doc='Log noticeable messages and higher levels' />
- <param name='error' doc='Log error messages and higher levels' />
- <param name='fatal' doc='Log only fatal messages' />
- </params>
- </command>
- <command id='logging level set-all (debug|info|notice|error|fatal)'>
- <params>
- <param name='logging' doc='Configure logging' />
- <param name='level' doc='Set the log level for a specified category' />
- <param name='set-all' doc='Once-off set all categories to the given log level. There is no single command to take back these changes -- each category is set to the given level, period.' />
- <param name='debug' doc='Log debug messages and higher levels' />
- <param name='info' doc='Log informational messages and higher levels' />
- <param name='notice' doc='Log noticeable messages and higher levels' />
- <param name='error' doc='Log error messages and higher levels' />
- <param name='fatal' doc='Log only fatal messages' />
- </params>
- </command>
- <command id='logging level force-all (debug|info|notice|error|fatal)'>
- <params>
- <param name='logging' doc='Configure logging' />
- <param name='level' doc='Set the log level for a specified category' />
- <param name='force-all' doc='Globally force all logging categories to a specific level. This is released by the &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 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 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/any|sdcch)'>
- <params>
- <param name='subscriber' doc='Operations on a Subscriber' />
- <param name='msisdn' doc='Identify subscriber by MSISDN (phone number)' />
- <param name='extension' doc='Legacy alias for &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/any' doc='Any TCH channel' />
- <param name='sdcch' doc='SDCCH channel' />
- </params>
- </command>
- <command id='subscriber (msisdn|extension|imsi|tmsi|id) ID silent-call stop'>
- <params>
- <param name='subscriber' doc='Operations on a Subscriber' />
- <param name='msisdn' doc='Identify subscriber by MSISDN (phone number)' />
- <param name='extension' doc='Legacy alias for &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 Extrenal SMS Entity' />
- </params>
- </command>
- </node>
- <node id='enable'>
- <name>enable</name>
- <command id='disable'>
- <params>
- <param name='disable' doc='Turn off privileged mode command' />
- </params>
- </command>
- <command id='configure terminal'>
- <params>
- <param name='configure' doc='Configuration from vty interface' />
- <param name='terminal' doc='Configuration terminal' />
- </params>
- </command>
- <command id='copy running-config startup-config'>
- <params>
- <param name='copy' doc='Copy configuration' />
- <param name='running-config' doc='Copy running config to... ' />
- <param name='startup-config' doc='Copy running config to startup config (same as write file)' />
- </params>
- </command>
- <command id='show startup-config'>
- <params>
- <param name='show' doc='Show running system information' />
- <param name='startup-config' doc='Contentes of startup configuration' />
- </params>
- </command>
- <command id='show version'>
- <params>
- <param name='show' doc='Show running system information' />
- <param name='version' doc='Displays program version' />
- </params>
- </command>
- <command id='show online-help'>
- <params>
- <param name='show' doc='Show running system information' />
- <param name='online-help' doc='Online help' />
- </params>
- </command>
- <command id='terminal length &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|lglobal|llapd|linp|lmux|lmi|lmib|lsms|lctrl|lgtp|lstats|lgsup|loap|lss7|lsccp|lsua|lm3ua|lmgcp|ljibuf) (debug|info|notice|error|fatal)'>
- <params>
- <param name='logging' doc='Configure logging' />
- <param name='level' doc='Set the log level for a specified category' />
- <param name='rll' doc='A-bis Radio Link Layer (RLL)' />
- <param name='cc' doc='Layer3 Call Control (CC)' />
- <param name='mm' doc='Layer3 Mobility Management (MM)' />
- <param name='rr' doc='Layer3 Radio Resource (RR)' />
- <param name='mncc' doc='MNCC API for Call Control application' />
- <param name='pag' doc='Paging Subsystem' />
- <param name='msc' doc='Mobile Switching Center' />
- <param name='mgcp' doc='Media Gateway Control Protocol' />
- <param name='ho' doc='Hand-Over' />
- <param name='db' doc='Database Layer' />
- <param name='ref' doc='Reference Counting' />
- <param name='ctrl' doc='Control interface' />
- <param name='smpp' doc='SMPP interface for external SMS apps' />
- <param name='ranap' doc='Radio Access Network Application Part Protocol' />
- <param name='vlr' doc='Visitor Location Register' />
- <param name='iucs' doc='Iu-CS Protocol' />
- <param name='bssap' doc='BSSAP Protocol (A Interface)' />
- <param name='lglobal' doc='Library-internal global log family' />
- <param name='llapd' doc='LAPD in libosmogsm' />
- <param name='linp' doc='A-bis Intput Subsystem' />
- <param name='lmux' doc='A-bis B-Subchannel TRAU Frame Multiplex' />
- <param name='lmi' doc='A-bis Input Driver for Signalling' />
- <param name='lmib' doc='A-bis Input Driver for B-Channels (voice)' />
- <param name='lsms' doc='Layer3 Short Message Service (SMS)' />
- <param name='lctrl' doc='Control Interface' />
- <param name='lgtp' doc='GPRS GTP library' />
- <param name='lstats' doc='Statistics messages and logging' />
- <param name='lgsup' doc='Generic Subscriber Update Protocol' />
- <param name='loap' doc='Osmocom Authentication Protocol' />
- <param name='lss7' doc='libosmo-sigtran Signalling System 7' />
- <param name='lsccp' doc='libosmo-sigtran SCCP Implementation' />
- <param name='lsua' doc='libosmo-sigtran SCCP User Adaptation' />
- <param name='lm3ua' doc='libosmo-sigtran MTP3 User Adaptation' />
- <param name='lmgcp' doc='libosmo-mgcp Media Gateway Control Protocol' />
- <param name='ljibuf' doc='libosmo-netif Jitter Buffer' />
- <param name='debug' doc='Log debug messages and higher levels' />
- <param name='info' doc='Log informational messages and higher levels' />
- <param name='notice' doc='Log noticeable messages and higher levels' />
- <param name='error' doc='Log error messages and higher levels' />
- <param name='fatal' doc='Log only fatal messages' />
- </params>
- </command>
- <command id='logging level set-all (debug|info|notice|error|fatal)'>
- <params>
- <param name='logging' doc='Configure logging' />
- <param name='level' doc='Set the log level for a specified category' />
- <param name='set-all' doc='Once-off set all categories to the given log level. There is no single command to take back these changes -- each category is set to the given level, period.' />
- <param name='debug' doc='Log debug messages and higher levels' />
- <param name='info' doc='Log informational messages and higher levels' />
- <param name='notice' doc='Log noticeable messages and higher levels' />
- <param name='error' doc='Log error messages and higher levels' />
- <param name='fatal' doc='Log only fatal messages' />
- </params>
- </command>
- <command id='logging level force-all (debug|info|notice|error|fatal)'>
- <params>
- <param name='logging' doc='Configure logging' />
- <param name='level' doc='Set the log level for a specified category' />
- <param name='force-all' doc='Globally force all logging categories to a specific level. This is released by the &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 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 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/any|sdcch)'>
- <params>
- <param name='subscriber' doc='Operations on a Subscriber' />
- <param name='msisdn' doc='Identify subscriber by MSISDN (phone number)' />
- <param name='extension' doc='Legacy alias for &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/any' doc='Any TCH channel' />
- <param name='sdcch' doc='SDCCH channel' />
- </params>
- </command>
- <command id='subscriber (msisdn|extension|imsi|tmsi|id) ID silent-call stop'>
- <params>
- <param name='subscriber' doc='Operations on a Subscriber' />
- <param name='msisdn' doc='Identify subscriber by MSISDN (phone number)' />
- <param name='extension' doc='Legacy alias for &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='show smpp esme'>
- <params>
- <param name='show' doc='Show running system information' />
- <param name='smpp' doc='SMPP Interface' />
- <param name='esme' doc='SMPP Extrenal SMS Entity' />
- </params>
- </command>
- </node>
- <node id='config'>
- <name>config</name>
- <command id='hostname WORD'>
- <params>
- <param name='hostname' doc='Set system&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='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|lglobal|llapd|linp|lmux|lmi|lmib|lsms|lctrl|lgtp|lstats|lgsup|loap|lss7|lsccp|lsua|lm3ua|lmgcp|ljibuf) (debug|info|notice|error|fatal)'>
- <params>
- <param name='logging' doc='Configure logging' />
- <param name='level' doc='Set the log level for a specified category' />
- <param name='rll' doc='A-bis Radio Link Layer (RLL)' />
- <param name='cc' doc='Layer3 Call Control (CC)' />
- <param name='mm' doc='Layer3 Mobility Management (MM)' />
- <param name='rr' doc='Layer3 Radio Resource (RR)' />
- <param name='mncc' doc='MNCC API for Call Control application' />
- <param name='pag' doc='Paging Subsystem' />
- <param name='msc' doc='Mobile Switching Center' />
- <param name='mgcp' doc='Media Gateway Control Protocol' />
- <param name='ho' doc='Hand-Over' />
- <param name='db' doc='Database Layer' />
- <param name='ref' doc='Reference Counting' />
- <param name='ctrl' doc='Control interface' />
- <param name='smpp' doc='SMPP interface for external SMS apps' />
- <param name='ranap' doc='Radio Access Network Application Part Protocol' />
- <param name='vlr' doc='Visitor Location Register' />
- <param name='iucs' doc='Iu-CS Protocol' />
- <param name='bssap' doc='BSSAP Protocol (A Interface)' />
- <param name='lglobal' doc='Library-internal global log family' />
- <param name='llapd' doc='LAPD in libosmogsm' />
- <param name='linp' doc='A-bis Intput Subsystem' />
- <param name='lmux' doc='A-bis B-Subchannel TRAU Frame Multiplex' />
- <param name='lmi' doc='A-bis Input Driver for Signalling' />
- <param name='lmib' doc='A-bis Input Driver for B-Channels (voice)' />
- <param name='lsms' doc='Layer3 Short Message Service (SMS)' />
- <param name='lctrl' doc='Control Interface' />
- <param name='lgtp' doc='GPRS GTP library' />
- <param name='lstats' doc='Statistics messages and logging' />
- <param name='lgsup' doc='Generic Subscriber Update Protocol' />
- <param name='loap' doc='Osmocom Authentication Protocol' />
- <param name='lss7' doc='libosmo-sigtran Signalling System 7' />
- <param name='lsccp' doc='libosmo-sigtran SCCP Implementation' />
- <param name='lsua' doc='libosmo-sigtran SCCP User Adaptation' />
- <param name='lm3ua' doc='libosmo-sigtran MTP3 User Adaptation' />
- <param name='lmgcp' doc='libosmo-mgcp Media Gateway Control Protocol' />
- <param name='ljibuf' doc='libosmo-netif Jitter Buffer' />
- <param name='debug' doc='Log debug messages and higher levels' />
- <param name='info' doc='Log informational messages and higher levels' />
- <param name='notice' doc='Log noticeable messages and higher levels' />
- <param name='error' doc='Log error messages and higher levels' />
- <param name='fatal' doc='Log only fatal messages' />
- </params>
- </command>
- <command id='logging level set-all (debug|info|notice|error|fatal)'>
- <params>
- <param name='logging' doc='Configure logging' />
- <param name='level' doc='Set the log level for a specified category' />
- <param name='set-all' doc='Once-off set all categories to the given log level. There is no single command to take back these changes -- each category is set to the given level, period.' />
- <param name='debug' doc='Log debug messages and higher levels' />
- <param name='info' doc='Log informational messages and higher levels' />
- <param name='notice' doc='Log noticeable messages and higher levels' />
- <param name='error' doc='Log error messages and higher levels' />
- <param name='fatal' doc='Log only fatal messages' />
- </params>
- </command>
- <command id='logging level force-all (debug|info|notice|error|fatal)'>
- <params>
- <param name='logging' doc='Configure logging' />
- <param name='level' doc='Set the log level for a specified category' />
- <param name='force-all' doc='Globally force all logging categories to a specific level. This is released by the &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'>
- <params>
- <param name='bind' doc='Accept VTY telnet connections on local interface' />
- <param name='A.B.C.D' doc='Local interface IP address (default: 127.0.0.1)' />
- </params>
- </command>
- </node>
- <node id='config-ctrl'>
- <name>config-ctrl</name>
- <command id='bind A.B.C.D'>
- <params>
- <param name='bind' doc='Set bind address to listen for Control connections' />
- <param name='A.B.C.D' doc='Local IP address (default 127.0.0.1)' />
- </params>
- </command>
- </node>
- <node id='config-cs7'>
- <name>config-cs7</name>
- <command id='description .TEXT'>
- <params>
- <param name='description' doc='Save human-readable description of the object' />
- <param name='.TEXT' doc='Text until the end of the line' />
- </params>
- </command>
- <command id='network-indicator (international | national | reserved | spare)'>
- <params>
- <param name='network-indicator' doc='Configure the Network Indicator' />
- <param name='international' doc='International Network' />
- <param name='national' doc='National Network' />
- <param name='reserved' doc='Reserved Network' />
- <param name='spare' doc='Spare Network' />
- </params>
- </command>
- <command id='point-code POINT_CODE'>
- <params>
- <param name='point-code' doc='Configure the local Point Code' />
- <param name='POINT_CODE' doc='Point Code' />
- </params>
- </command>
- <command id='point-code format &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-guard-timeout &lt;0-255&gt;'>
- <params>
- <param name='mncc-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='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='0 = never re-use auth tuples beyond auth-tuple-max-reuse-count (default)' />
- <param name='1' doc='1 = if the HLR does not deliver new tuples, do re-use already available old ones.' />
- </params>
- </command>
- <command id='cs7-instance-a &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='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-range &lt;1-65534&gt; &lt;1-65534&gt;'>
- <params>
- <param name='mgw' doc='Configure MGCP connection to Media Gateway' />
- <param name='endpoint-range' doc='usable range of endpoint identifiers' />
- <param name='&lt;1-65534&gt;' doc='set first usable endpoint identifier' />
- <param name='&lt;1-65534&gt;' doc='set last usable endpoint identifier' />
- </params>
- </command>
- <command id='mgw bts-base &lt;0-65534&gt;'>
- <params>
- <param name='mgw' doc='Configure MGCP connection to Media Gateway' />
- <param name='bts-base' doc='First UDP port allocated for the BTS side' />
- <param name='&lt;0-65534&gt;' doc='UDP Port number' />
- </params>
- </command>
- <command id='iu rab-assign-addr-enc (x213|v4raw)'>
- <params>
- <param name='iu' doc='Iu interface protocol options' />
- <param name='rab-assign-addr-enc' doc='Choose RAB Assignment&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 independeint of system ID / passwd' />
- <param name='closed' doc='Accept only SMPP connections from ESMEs explicitly configured' />
- </params>
- </command>
- <command id='esme NAME'>
- <params>
- <param name='esme' doc='Configure a particular ESME' />
- <param name='NAME' doc='Alphanumeric System ID of the ESME to be configured' />
- </params>
- </command>
- <command id='no esme NAME'>
- <params>
- <param name='no' doc='Negate a command or set its defaults' />
- <param name='esme' doc='Remove ESME configuration' />
- <param name='NAME' doc='Alphanumeric System ID of the ESME to be removed' />
- </params>
- </command>
- </node>
- <node id='config-smpp-esme'>
- <name>config-smpp-esme</name>
- <command id='password PASSWORD'>
- <params>
- <param name='password' doc='Set the password for this ESME' />
- <param name='PASSWORD' doc='Alphanumeric password string' />
- </params>
- </command> <command id='no password'>
- <params>
- <param name='no' doc='Negate a command or set its defaults' />
- <param name='password' doc='Remove the password for this ESME' />
- </params>
- </command>
- <command id='route prefix (unknown|international|national|network|subscriber|alpha|abbrev) (unknown|isdn|x121|f69|e212|national|private|ermes|ip|wap) PREFIX'>
- <params>
- <param name='route' doc='Configure a route for MO-SMS to be sent to this ESME' />
- <param name='prefix' doc='Prefix-match route' />
- <param name='unknown' doc='Unknown type-of-number' />
- <param name='international' doc='International type-of-number' />
- <param name='national' doc='National type-of-number' />
- <param name='network' doc='Network specific type-of-number' />
- <param name='subscriber' doc='Subscriber type-of-number' />
- <param name='alpha' doc='Alphanumeric type-of-number' />
- <param name='abbrev' doc='Abbreviated type-of-number' />
- <param name='unknown' doc='Unknown numbering plan' />
- <param name='isdn' doc='ISDN (E.164) numbering plan' />
- <param name='x121' doc='X.121 numbering plan' />
- <param name='f69' doc='F.69 numbering plan' />
- <param name='e212' doc='E.212 numbering plan' />
- <param name='national' doc='National numbering plan' />
- <param name='private' doc='Private numbering plan' />
- <param name='ermes' doc='ERMES numbering plan' />
- <param name='ip' doc='IP numbering plan' />
- <param name='wap' doc='WAP numbeing plan' />
- <param name='PREFIX' doc='Destination number prefix' />
- </params>
- </command>
- <command id='no route prefix (unknown|international|national|network|subscriber|alpha|abbrev) (unknown|isdn|x121|f69|e212|national|private|ermes|ip|wap) PREFIX'>
- <params>
- <param name='no' doc='Negate a command or set its defaults' />
- <param name='route' doc='Configure a route for MO-SMS to be sent to this ESME' />
- <param name='prefix' doc='Prefix-match route' />
- <param name='unknown' doc='Unknown type-of-number' />
- <param name='international' doc='International type-of-number' />
- <param name='national' doc='National type-of-number' />
- <param name='network' doc='Network specific type-of-number' />
- <param name='subscriber' doc='Subscriber type-of-number' />
- <param name='alpha' doc='Alphanumeric type-of-number' />
- <param name='abbrev' doc='Abbreviated type-of-number' />
- <param name='unknown' doc='Unknown numbering plan' />
- <param name='isdn' doc='ISDN (E.164) numbering plan' />
- <param name='x121' doc='X.121 numbering plan' />
- <param name='f69' doc='F.69 numbering plan' />
- <param name='e212' doc='E.212 numbering plan' />
- <param name='national' doc='National numbering plan' />
- <param name='private' doc='Private numbering plan' />
- <param name='ermes' doc='ERMES numbering plan' />
- <param name='ip' doc='IP numbering plan' />
- <param name='wap' doc='WAP numbeing plan' />
- <param name='PREFIX' doc='Destination number prefix' />
- </params>
- </command>
- <command id='default-route'>
- <params>
- <param name='default-route' doc='Set this ESME as default-route for all SMS to unknown destinations' />
- </params>
- </command>
- <command id='no default-route'>
- <params>
- <param name='no' doc='Negate a command or set its defaults' />
- <param name='default-route' doc='Remove this ESME as default-route for all SMS to unknown destinations' />
- </params>
- </command>
- <command id='deliver-src-imsi'>
- <params>
- <param name='deliver-src-imsi' doc='Enable the use of IMSI as source address in DELIVER' />
- </params>
- </command>
- <command id='no deliver-src-imsi'>
- <params>
- <param name='no' doc='Negate a command or set its defaults' />
- <param name='deliver-src-imsi' doc='Disable the use of IMSI as source address in DELIVER' />
- </params>
- </command>
- <command id='osmocom-extensions'>
- <params>
- <param name='osmocom-extensions' doc='Enable the use of Osmocom SMPP Extensions for this ESME' />
- </params>
- </command>
- <command id='no osmocom-extensions'>
- <params>
- <param name='no' doc='Negate a command or set its defaults' />
- <param name='osmocom-extensions' doc='Disable the use of Osmocom SMPP Extensions for this ESME' />
- </params>
- </command>
- <command id='dcs-transparent'>
- <params>
- <param name='dcs-transparent' doc='Enable the transparent pass-through of TP-DCS to SMPP DataCoding' />
- </params>
- </command>
- <command id='no dcs-transparent'>
- <params>
- <param name='no' doc='Negate a command or set its defaults' />
- <param name='dcs-transparent' doc='Disable the transparent pass-through of TP-DCS to SMPP DataCoding' />
- </params>
- </command>
- </node>
- <node id='config-hlr'>
- <name>config-hlr</name>
- <command id='remote-ip A.B.C.D'>
- <params>
- <param name='remote-ip' doc='Remote GSUP address of the HLR' />
- <param name='A.B.C.D' doc='Remote GSUP address (default: 127.0.0.1)' />
- </params>
- </command>
- <command id='remote-port &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>
- </node>
-</vtydoc>
diff --git a/doc/sequence_charts/Makefile.am b/doc/sequence_charts/Makefile.am
index b667a6f5e..7a5277643 100644
--- a/doc/sequence_charts/Makefile.am
+++ b/doc/sequence_charts/Makefile.am
@@ -4,27 +4,26 @@ all:
charts: msc dot
EXTRA_DIST = \
- inter_bsc_ho.msc \
- inter_msc_ho.msc \
- mncc_fsm.msc \
+ $(srcdir)/*.msc \
$(NULL)
CLEANFILES = \
- inter_bsc_ho.png \
- inter_msc_ho.png \
- mncc_fsm.png \
+ $(builddir)/*.png \
$(NULL)
msc: \
- $(builddir)/mncc_fsm.png \
+ $(builddir)/mncc_call_fsm.png \
$(builddir)/inter_bsc_ho.png \
$(builddir)/inter_msc_ho.png \
+ $(builddir)/voice_call_external_mncc.png \
+ $(builddir)/voice_call_internal_mncc.png \
+ $(builddir)/call_reestablishment.png \
$(NULL)
dot: \
$(NULL)
-$(builddir)/%.png: $(srcdir)/%.msc
+$(builddir)/%.png: %.msc
mscgen -T png -o $@ $<
$(builddir)/%.png: $(srcdir)/%.dot
diff --git a/doc/sequence_charts/call_reestablishment.msc b/doc/sequence_charts/call_reestablishment.msc
new file mode 100644
index 000000000..b4d081ca2
--- /dev/null
+++ b/doc/sequence_charts/call_reestablishment.msc
@@ -0,0 +1,33 @@
+msc {
+ hscale="2";
+ ms[label="MS"],cell1[label="Cell 1 (BTS+BSC)"],cell0[label="Cell 0 (BTS+BSC)"],__msc[label="MSC"];
+
+ ms rbox __msc [label="Call Re-Establishment"];
+ ms note __msc [label="Ongoing voice call: MM is established"];
+
+ ...;
+
+ ms -x cell0 [label="radio link fails"];
+ ms x- cell0;
+
+ __msc abox __msc [label="Keep MM until timeout"];
+
+ ms => cell1 [label="Channel Required"];
+ ms <= cell1 [label="Immediate Assignment"];
+ ms => cell1 [label="Complete Layer3"];
+ cell1 => __msc [label="Complete Layer3:\nCM Re-Establishment Request"];
+
+ cell0 <= __msc [label="Clear Command"];
+ cell0 => __msc [label="Clear Complete"];
+
+ cell1 <= __msc [label="Authentication Request"];
+ cell1 => __msc [label="Authentication Response"];
+
+ cell1 <= __msc [label="Cipher Mode Commad"];
+ cell1 => __msc [label="Cipher Mode Complete"];
+
+ cell1 <= __msc [label="Assignment Request\nthis Assignment ACKs the CM Re-Establishment"];
+ ms <= cell1 [label="RR Assignment Command"];
+ ms => cell1 [label="RR Assignment Complete"];
+ cell1 => __msc [label="Assignment Complete"];
+}
diff --git a/doc/sequence_charts/mncc_call_fsm.msc b/doc/sequence_charts/mncc_call_fsm.msc
new file mode 100644
index 000000000..4a14ff738
--- /dev/null
+++ b/doc/sequence_charts/mncc_call_fsm.msc
@@ -0,0 +1,104 @@
+msc {
+ hscale=3;
+ msc1[label="osmo-msc"], mncc1[label="MNCC FSM\n(osmo-msc mncc_call.c)"], sipcon1[label="osmo-sip-connector"], sip[label="PBX"], sipcon2[label="osmo-sip-connector"], mncc2[label="MNCC FSM\n(osmo-msc mncc_call.c)"], msc2[label="osmo-msc"];
+
+ msc1 note sipcon1 [label="MO call"];
+ sipcon2 note msc2 [label="MT call"];
+
+ mncc1 abox mncc1 [label="MNCC_CALL_ST_NOT_STARTED"];
+ msc1 rbox msc1 [label="mncc_outgoing_start()"];
+ msc1 -> mncc1 [label="MNCC_CALL_EV_OUTGOING_START"];
+
+ mncc1 abox mncc1 [label="MNCC_CALL_ST_OUTGOING_WAIT_PROCEEDING"];
+ mncc1 => sipcon1 [label="MNCC_SETUP_IND
+ \n callref, IMSI, called and calling number, SDP"];
+ sipcon1 => sip [label="SIP INVITE
+ \n from, to, SDP"];
+ sipcon1 <= sip [label="SIP 100 Trying"];
+ mncc1 <= sipcon1 [label="MNCC_RTP_CREATE
+ \n callref"];
+ mncc1 rbox mncc1 [label="mncc_rx_rtp_create()"];
+ mncc1 => sipcon1 [label="MNCC_RTP_CREATE
+ \n callref, RTP IP address and port"];
+ mncc1 <= sipcon1 [label="MNCC_CALL_PROC_REQ
+ \n callref, RTP IP address and port"];
+ mncc1 abox mncc1 [label="MNCC_CALL_ST_OUTGOING_WAIT_COMPLETE"];
+
+ sip => sipcon2 [label="SIP INVITE
+ \n from, to, SDP"];
+ sipcon2 => sip [label="SIP 100 Trying"];
+ msc2 <= sipcon2 [label="MNCC_SETUP_REQ
+ \n callref, called and calling number
+ \n SDP"];
+ mncc2 abox mncc2 [label="MNCC_CALL_ST_NOT_STARTED"];
+ msc2 rbox msc2 [label="mncc_incoming_start()"];
+ msc2 -> mncc2 [label="MNCC_CALL_EV_INCOMING_START"];
+ mncc2 abox mncc2 [label="MNCC_CALL_ST_INCOMING_WAIT_COMPLETE"];
+ mncc2 => sipcon2 [label="MNCC_CALL_CONF_IND
+ \n callref, bearer capabilities, cccap and IMSI, SDP?"];
+ mncc2 <= sipcon2 [label="MNCC_RTP_CREATE
+ \n callref"];
+ mncc2 rbox mncc2 [label="mncc_rx_rtp_create()"];
+ mncc2 => sipcon2 [label="MNCC_RTP_CREATE
+ \n callref, RTP IP address and port, SDP?"];
+ mncc2 => sipcon2 [label="MNCC_ALERT_IND
+ \n callref"];
+ sipcon2 => sip [label="SIP 180 Ringing
+ \n SDP"];
+
+ sipcon1 <= sip [label="SIP 180 Ringing
+ \n SDP"];
+ mncc1 <= sipcon1 [label="MNCC_ALERT_REQ
+ \n callref and progress"];
+ sipcon1 => sip [label="SIP PRACK 180 Ringing"];
+ sipcon1 <= sip [label="SIP PRACK 200"];
+
+ mncc1 <= sipcon1 [label="MNCC_RTP_CONNECT
+ \n callref, RTP IP and port"];
+ mncc1 rbox mncc1 [label="mncc_rx_rtp_connect()"];
+ msc1 <- mncc1 [label="rtp_stream_set_remote_addr()"];
+
+ mncc2 => sipcon2 [label="MNCC_SETUP_CNF
+ \n callref, imsi and connected number, SDP?"];
+ sipcon2 => sip [label="SIP 200 OK
+ \n SDP"];
+ mncc2 <= sipcon2 [label="MNCC_RTP_CONNECT
+ \n callref, RTP IP and port"];
+ mncc2 rbox mncc2 [label="mncc_rx_rtp_connect()"];
+ mncc2 <= sipcon2 [label="MNCC_SETUP_COMPL_REQ
+ \n callref"];
+ mncc2 abox mncc2 [label="MNCC_CALL_ST_TALKING"];
+
+ sipcon1 <= sip [label="SIP 200 OK INVITE"];
+ mncc1 <= sipcon1 [label="MNCC_SETUP_RSP
+ \n callref"];
+ mncc1 => sipcon1 [label="MNCC_SETUP_COMPL_IND
+ \n callref"];
+ mncc1 abox mncc1 [label="MNCC_CALL_ST_TALKING"];
+ sipcon1 => sip [label="SIP ACK"];
+
+ ...;
+ ... [label="Call goes on for a while..."];
+ ...;
+
+ mncc1 rbox mncc1 [label="mncc_release()"];
+ mncc1 => sipcon1 [label="MNCC_DISC_IND
+ \n callref and cause"];
+ mncc1 abox mncc1 [label="MNCC_CALL_ST_WAIT_RELEASE_ACK"];
+ sipcon1 => sip [label="SIP BYE"];
+ sipcon1 <= sip [label="SIP 200 OK"];
+ mncc1 <= sipcon1 [label="MNCC_REL_REQ
+ \n callref and cause"];
+
+ sip => sipcon2 [label="SIP BYE"];
+ sip <= sipcon2 [label="SIP 200 OK"];
+ mncc2 <= sipcon2 [label="MNCC_DISC_REQ
+ \n callref and cause"];
+ mncc2 => sipcon2 [label="MNCC_REL_IND
+ \n callref and cause"];
+ mncc2 abox mncc2 [label="terminated"];
+
+ mncc1 => sipcon1 [label="MNCC_REL_CNF
+ \n callref"];
+ mncc1 abox mncc1 [label="terminated"];
+}
diff --git a/doc/sequence_charts/mncc_fsm.msc b/doc/sequence_charts/mncc_fsm.msc
deleted file mode 100644
index ae5e0a211..000000000
--- a/doc/sequence_charts/mncc_fsm.msc
+++ /dev/null
@@ -1,84 +0,0 @@
-msc {
- hscale=2;
- msc1[label="osmo-msc"], mncc1[label="MNCC FSM"], pbx[label="MNCC server (osmo-sip-connector)"], mncc2[label="MNCC FSM"], msc2[label="osmo-msc"];
-
- mncc1 note mncc1 [label="The typical progression of an outgoing call, i.e. a call initiated by osmo-msc, as
- implemented in mncc_fsm.h, mncc_fsm.c"];
- mncc2 note mncc2 [label="The typical progression of an incoming call, i.e. a call initiated by the PBX, as
- implemented in mncc_fsm.h, mncc_fsm.c"];
-
- mncc1 abox mncc1 [label="MNCC_ST_NOT_STARTED"];
- msc1 rbox msc1 [label="mncc_outgoing_start()"];
- msc1 -> mncc1 [label="MNCC_EV_OUTGOING_START"];
-
- mncc1 abox mncc1 [label="MNCC_ST_OUTGOING_WAIT_PROCEEDING"];
- mncc1 => pbx [label="MNCC_SETUP_IND
- \n callref, IMSI, called and calling number"];
- mncc1 <= pbx [label="MNCC_RTP_CREATE
- \n callref"];
- mncc1 rbox mncc1 [label="mncc_rx_rtp_create()"];
- mncc1 => pbx [label="MNCC_RTP_CREATE
- \n callref, RTP IP address and port"];
- mncc1 <= pbx [label="MNCC_CALL_PROC_REQ
- \n callref, RTP IP address and port"];
- mncc1 abox mncc1 [label="MNCC_ST_OUTGOING_WAIT_COMPLETE"];
-
- msc2 <= pbx [label="MNCC_SETUP_REQ
- \n callref, called and calling number"];
- mncc2 abox mncc2 [label="MNCC_ST_NOT_STARTED"];
- msc2 rbox msc2 [label="mncc_incoming_start()"];
- msc2 -> mncc2 [label="MNCC_EV_INCOMING_START"];
- mncc2 abox mncc2 [label="MNCC_ST_INCOMING_WAIT_COMPLETE"];
- mncc2 => pbx [label="MNCC_CALL_CONF_IND
- \n callref, bearer capabilities, cccap and IMSI"];
- mncc2 <= pbx [label="MNCC_RTP_CREATE
- \n callref"];
- mncc2 rbox mncc2 [label="mncc_rx_rtp_create()"];
- mncc2 => pbx [label="MNCC_RTP_CREATE
- \n callref, RTP IP address and port"];
- mncc2 => pbx [label="MNCC_ALERT_IND
- \n callref"];
-
- mncc1 <= pbx [label="MNCC_ALERT_REQ
- \n callref and progress"];
-
- mncc2 => pbx [label="MNCC_SETUP_CNF
- \n callref, imsi and connected number"];
- mncc2 <= pbx [label="MNCC_RTP_CONNECT
- \n callref, RTP IP and port"];
- mncc2 rbox mncc2 [label="mncc_rx_rtp_connect()"];
- mncc2 <= pbx [label="MNCC_SETUP_COMPL_REQ
- \n callref"];
- mncc2 abox mncc2 [label="MNCC_ST_TALKING"];
-
- mncc1 <= pbx [label="MNCC_RTP_CONNECT
- \n callref, RTP IP and port"];
- mncc1 rbox mncc1 [label="mncc_rx_rtp_connect()"];
- msc1 <- mncc1 [label="rtp_stream_set_remote_addr()"];
- mncc1 <= pbx [label="MNCC_SETUP_RSP
- \n callref"];
- mncc1 => pbx [label="MNCC_SETUP_COMPL_IND
- \n callref"];
- mncc1 abox mncc1 [label="MNCC_ST_TALKING"];
-
- ...;
- ... [label="Call goes on for a while..."];
- ...;
-
- mncc1 rbox mncc1 [label="mncc_release()"];
- mncc1 => pbx [label="MNCC_DISC_IND
- \n callref and cause"];
- mncc1 abox mncc1 [label="MNCC_ST_WAIT_RELEASE_ACK"];
- mncc1 <= pbx [label="MNCC_REL_REQ
- \n callref and cause"];
-
- mncc2 <= pbx [label="MNCC_DISC_REQ
- \n callref and cause"];
- mncc2 => pbx [label="MNCC_REL_IND
- \n callref and cause"];
- mncc2 abox mncc2 [label="terminated"];
-
- mncc1 => pbx [label="MNCC_REL_CNF
- \n callref"];
- mncc1 abox mncc1 [label="terminated"];
-}
diff --git a/doc/sequence_charts/msc_log_to_ladder.py b/doc/sequence_charts/msc_log_to_ladder.py
new file mode 100755
index 000000000..9bfb9c9c2
--- /dev/null
+++ b/doc/sequence_charts/msc_log_to_ladder.py
@@ -0,0 +1,753 @@
+#!/usr/bin/env python3
+doc=r'''
+Reading a log, it can be hard to figure out what is the important bit going on.
+This is a tool that reads an osmo-msc log and tries to compose a ladder diagram from it automatically.
+'''
+
+import argparse
+import sys
+import re
+import tempfile
+import os
+
+def error(*msg):
+ sys.stderr.write('%s\n' % (''.join(msg)))
+ exit(1)
+
+def quote(msg, quote='"'):
+ return '"%s"' % (msg.replace('"', r'\"'))
+
+class Entity:
+ def __init__(self, name, descr=None, attrs={}):
+ self.name = name
+ self.descr = descr
+ self.attrs = attrs
+
+class Arrow:
+ def __init__(self, mo_mt, left, arrow, right, descr=None, attrs={}, ran_conn=None, imsi=None, tmsi=None):
+ self.mo_mt = mo_mt
+ self.left = left
+ self.arrow = arrow
+ self.right = right
+ self.descr = descr
+ self.attrs = attrs
+ self.ran_conn = ran_conn
+ self.imsi = imsi
+ self.tmsi = tmsi
+
+ def __repr__(self):
+ return 'Arrow(%s %s %s %s: %s IMSI=%s)' % (self.mo_mt, self.left, self.arrow, self.right, self.descr, self.imsi)
+
+class Separator:
+ def __init__(self):
+ self.separator = None
+ self.descr = None
+ self.attrs = {}
+
+class EmptyLine:
+ def __init__(self):
+ self.count = 1
+
+MS = 'ms'
+UE = 'ms' #'ue'
+MS_UE_UNKNOWN = 'ms' #None
+MSC = 'msc'
+MGW = 'mgw'
+MNCC = 'mncc'
+
+MO = 'mo'
+MT = 'mt'
+MO_MT_UNKNOWN = None
+
+
+class OutputBase:
+ def __init__(self, write_to, start_with_re=None):
+ self._write_to = write_to
+
+ self.start_with_re = None
+ if start_with_re is not None:
+ self.start_with_re = re.compile(start_with_re)
+
+ def head(self):
+ self.writeln('# Generated by osmo-msc.git/doc/sequence_charts/msc_log_to_ladder.py')
+
+ def tail(self):
+ pass
+
+ def render(self, diagram):
+ self.head()
+ if diagram.root_attrs:
+ self.root_attrs(diagram.root_attrs)
+ self.entities(diagram.entities)
+
+ started = (self.start_with_re is None)
+
+ for line in diagram.lines:
+ if not started:
+ if hasattr(line, 'descr') and self.start_with_re.match(line.descr):
+ started = True
+ else:
+ continue
+ self.add(line)
+ self.tail()
+
+ def entities(self, entities):
+ for entity in entities:
+ self.entity(entity)
+
+ def write(self, line):
+ self._write_to.write(line)
+
+ def writeln(self, line):
+ self.write('%s\n' % line)
+
+ def emptyline(self, emptyline):
+ self.write('\n' * emptyline.count);
+
+ def add(self, thing):
+ func = getattr(self, thing.__class__.__name__.lower())
+ func(thing)
+
+
+class OutputLadder(OutputBase):
+
+ def indent_multiline(self, s):
+ return s.replace('\n', '\n\t')
+
+ def attrs_str(self, attrs, prefix=' '):
+ if not attrs:
+ return ''
+ return '%s{%s}' % (prefix or '', ','.join('%s=%s' % (k,v) for k,v in attrs.items()))
+
+ def root_attrs(self, attrs):
+ self.writeln(self.attrs_str(attrs, prefix=None))
+
+ def entity(self, entity):
+ self.writeln('%s = %s%s' % (entity.name, self.indent_multiline(entity.descr), self.attrs_str(entity.attrs)))
+
+ def arrow(self, arrow):
+ mo_mt = arrow.mo_mt or MO
+
+ def prepend_mo_mt(name):
+ if name in ('.', MNCC):
+ return name
+ return '%s%s' % (mo_mt, name)
+
+ self.writeln('%s %s %s%s%s%s'
+ % (prepend_mo_mt(arrow.left),
+ arrow.arrow,
+ prepend_mo_mt(arrow.right),
+ '\t' if arrow.descr else '',
+ self.indent_multiline(arrow.descr or ''),
+ self.attrs_str(arrow.attrs)))
+
+ def separator(self, sep_str, descr, attrs):
+ self.writeln('%s%s%s%s'
+ % (separator.separator,
+ ' ' if separator.descr else '',
+ self.indent_multiline(separator.descr or ''),
+ self.attrs_str(separator.attrs)))
+
+class OutputMscgen(OutputBase):
+ ARROWS = {
+ '>' : '=>>',
+ '->' : '=>',
+ '-->' : '>>',
+ '~>' : '->',
+ '=>' : ':>',
+ '-><' : '-x',
+
+ '<' : '<<=',
+ '<-' : '<=',
+ '<--' : '<<',
+ '<~' : '<-',
+ '<=' : '<:',
+ '><-' : 'x-',
+
+ '<>' : 'abox',
+ '()' : 'rbox',
+ '[]' : 'note',
+ }
+
+ def head(self):
+ super().head()
+ self.writeln('msc {')
+
+ def tail(self):
+ self.writeln('}')
+
+ def entities(self, entities):
+ estr = []
+ for entity in entities:
+ estr.append('%s%s' % (entity.name, self.attrs_str(self.all_attrs(entity.descr, entity.attrs), prefix='')))
+ if not estr:
+ return
+ self.writeln('%s;' % (','.join(estr)))
+
+ def attrs_list_str(self, attrs):
+ if not attrs:
+ return ''
+ def escape(s):
+ return s.replace('\n', r'\n').replace('\r', '').replace('\t', r'\t')
+ return ','.join('%s="%s"' % (k,escape(v)) for k,v in attrs.items())
+
+ def attrs_str(self, attrs, prefix=' '):
+ attrs_list_str = self.attrs_list_str(attrs)
+ if not attrs_list_str:
+ return ''
+ return '%s[%s]' % (prefix or '', attrs_list_str)
+
+ def root_attrs(self, attrs):
+ if not attrs:
+ return
+ self.writeln('%s;' % self.attrs_list_str(attrs))
+
+ def all_attrs(self, descr, attrs):
+ a = {}
+ if descr:
+ a['label'] = descr
+ a.update(attrs)
+ return a
+
+ def entity(self, entity):
+ error('OutputMscgen.entity() should not be called')
+
+ def arrow_txlate(self, arrow):
+ txlate = OutputMscgen.ARROWS.get(arrow)
+ if not txlate:
+ error('Unknown arrow: %r' % arrow)
+ return txlate
+
+ def arrow(self, arrow):
+ mo_mt = arrow.mo_mt or MO
+
+ def prepend_mo_mt(name):
+ if name in ('.', MNCC):
+ return name
+ return '%s%s' % (mo_mt, name)
+
+ l = prepend_mo_mt(arrow.left)
+ r = arrow.right
+ if r == '.':
+ r = l
+ else:
+ r = prepend_mo_mt(r)
+
+ a = {'label': arrow.descr}
+ a.update(arrow.attrs)
+ attrs = self.attrs_str(a)
+
+ self.writeln('%s %s %s%s;'
+ % (l, self.arrow_txlate(arrow.arrow), r,
+ self.attrs_str(self.all_attrs(arrow.descr, arrow.attrs), prefix='\t')))
+
+ def separator(self, sep_str, descr, attrs):
+ self.writeln('%s%s%s%s;'
+ % (separator.separator,
+ self.attrs_str(self.all_attrs(descr, attrs), prefix='\t')))
+
+ def emptyline(self, emptyline):
+ self.write('\n' * emptyline.count);
+
+
+def ms_from_ran(ran_type_or_conn):
+ if ran_type_or_conn.startswith('UTRAN-Iu'):
+ return UE
+ if ran_type_or_conn.startswith('RANAP'):
+ return UE
+ if ran_type_or_conn.startswith('GERAN-A'):
+ return MS
+ if ran_type_or_conn.startswith('BSS'):
+ return MS
+ return MS_UE_UNKNOWN
+
+class Diagram:
+ def __init__(self):
+ self.root_attrs = {}
+ self.entities = []
+ self.lines = []
+ self.mo_mt_unknown_lines = []
+
+ def add_line(self, line):
+ self.lines.append(line)
+
+ def resolve_unknown_mo_mt(self):
+
+ def try_match(a, b):
+ if a < 0 or a >= len(self.lines):
+ return False
+ if b < 0 or b >= len(self.lines):
+ return False
+ la = self.lines[a]
+ lb = self.lines[b]
+
+ if not hasattr(lb, 'mo_mt'):
+ return False
+ if lb.mo_mt == MO_MT_UNKNOWN:
+ return False
+
+ for match_attr in ('imsi', 'tmsi', 'ran_conn'):
+ if not hasattr(la, match_attr):
+ continue
+ if not hasattr(lb, match_attr):
+ continue
+ la_attr = getattr(la, match_attr)
+ if la_attr is None:
+ continue
+ lb_attr = getattr(lb, match_attr)
+ if la_attr == lb_attr:
+ la.mo_mt = lb.mo_mt
+ return True
+ return False
+
+
+ while True:
+ changes = 0
+ for i in range(len(self.lines)):
+ line = self.lines[i]
+
+ if not hasattr(line, 'mo_mt'):
+ continue
+ if line.mo_mt is not MO_MT_UNKNOWN:
+ continue
+
+ # don't know MO/MT, try to resolve from near messages
+ for j in range(1,100):
+ if try_match(i, i-j):
+ break
+ if try_match(i, i+j):
+ break
+ if line.mo_mt is not MO_MT_UNKNOWN:
+ changes += 1
+ if not changes:
+ break
+
+
+re_source_file_last = re.compile(r'(.*) \(([^):]+:[0-9]+)\)$')
+
+class Rule:
+ def __init__(self, name, re_str, handler):
+ self.name = name
+ self.re = re.compile(re_str)
+ self.handler = handler
+
+ def match(self, line):
+ m = self.re.match(line)
+ if not m:
+ return False
+ return self.handler(m)
+
+
+def mo_mt_from_l3type(l3type):
+ if l3type == 'PAGING_RESP':
+ return MT
+ elif l3type == 'CM_SERVICE_REQ':
+ return MO
+ else:
+ return MO_MT_UNKNOWN
+
+def int_to_hex(val, bits):
+ return hex((int(val) + (1 << bits)) % (1 << bits))
+
+class Callref:
+ MAX = 0x7fffffff
+ MIN = -0x80000000
+ BITS = 32
+
+ def int_to_hex(val):
+ return int_to_hex(val, Callref.BITS)
+
+ def hex_to_int(hexstr):
+ val = int(hexstr, 16)
+ if val > Callref.MAX:
+ val = Callref.MIN + (val & Callref.MAX)
+ return val
+
+class Parse:
+
+ def __init__(self, output, mask_values=False):
+
+ self.diagram = Diagram()
+ self.output = output
+ self.linenr = 0
+ self.rules = []
+ self.rules_hit = {}
+ self.seen_udtrace_mncc = False
+
+ self.callrefs_mo_mt = {}
+ self.mask_values = mask_values
+ self.masked_values = {}
+
+ for member in dir(self):
+ if not member.startswith('rule_'):
+ continue
+ func = getattr(self, member)
+ if not callable(func):
+ continue
+
+ docstr = func.__doc__
+ if not docstr:
+ continue
+ re_str = docstr.splitlines()[0]
+
+ self.rules.append(Rule(name=member, re_str=re_str, handler=func))
+ self.rules_hit[member] = 0
+
+
+
+ def error(self, *msg):
+ error('line %d: ' % self.linenr, *msg)
+
+ def start(self):
+ self.diagram.root_attrs = {'hscale': '3'}
+ for name, descr in (
+ ('moms', 'MS,BSS (MO)\\nUE,hNodeB (MO)'),
+ #('moue', 'UE,hNodeB (MO)'),
+ ('momgw', 'MGW for MSC (MO)'),
+ ('momsc', 'MSC (MO)'),
+ ('mncc', 'MNCC'),
+ ('mtmsc', 'MSC (MT)'),
+ ('mtmgw', 'MGW for MSC (MT)'),
+ ('mtms', 'BSS,MS (MT)\\nhNodeB,UE (MT)'),
+ #('mtue', 'hNodeB,UE (MT)'),
+ ):
+ self.diagram.entities.append(Entity(name, descr))
+
+ def end(self):
+ self.diagram.resolve_unknown_mo_mt()
+ self.output.render(self.diagram)
+
+ def mask_value(self, name, val):
+ if not self.mask_values:
+ return val
+ if not val:
+ return val
+ name_dict = self.masked_values.get(name)
+ if not name_dict:
+ name_dict = {}
+ self.masked_values[name] = name_dict
+
+ masked_val = name_dict.get(val)
+ if masked_val is None:
+ masked_val = '%s-%d' % (name, len(name_dict) + 1)
+ name_dict[val] = masked_val
+ return masked_val
+
+ def add_line(self, line):
+ self.linenr += 1
+ if line.endswith('\n'):
+ line = line[:-1]
+ if line.endswith('\r'):
+ line = line[:-1]
+
+ self.interpret(line)
+
+ def interpret(self, line):
+
+ m = re_source_file_last.match(line)
+ if m:
+ line = m.group(1)
+
+ for rule in self.rules:
+ if rule.match(line):
+ self.rules_hit[rule.name] = self.rules_hit.get(rule.name, 0) + 1
+ break
+
+ RE_DTAP_NAME = re.compile('.*GSM48_MT_([^_]+)_(.+)')
+
+ def rule_paging(self, m):
+ r'.*ran_peer\(([^:]+):.* Paging for ([^ ]+) on ([^ ]+)'
+ ran_type, subscr, cell = m.groups()
+
+ self.diagram.add_line(Arrow(MT, ms_from_ran(ran_type), '<', MSC, 'Paging'))
+ return True
+
+ RE_IMSI = re.compile('IMSI-([0-9]+)')
+ RE_TMSI = re.compile('TMSI-0x([0-9a-fA-F]+)')
+
+ def rule_dtap(self, m):
+ r'.*msc_a\(([^)]*):([^:]+):([^:]+)\).* (Dispatching 04.08 message|Sending DTAP): (.+)$'
+
+ subscr, ran_conn, l3type, rx_tx, dtap = m.groups()
+ tx = (rx_tx == 'Sending DTAP')
+
+ m = self.RE_DTAP_NAME.match(dtap)
+ if m:
+ dtap = '%s %s' % m.groups()
+
+ if 'IMSI_DETACH_IND' in dtap:
+ # detecting IMSI Detach separately, because this log line does not contain the IMSI.
+ # By using the rule_imsi_detach(), we can accurately put it on the MO/MT side.
+ return True
+
+ if l3type == 'NONE' and not tx and dtap.endswith('PAG_RESP'):
+ e = MT
+ else:
+ e = mo_mt_from_l3type(l3type)
+
+ imsi = None
+ for m in Parse.RE_IMSI.finditer(subscr):
+ imsi = m.group(1)
+ tmsi = None
+ for m in Parse.RE_TMSI.finditer(subscr):
+ tmsi = m.group(1)
+
+ self.diagram.add_line(Arrow(e, ms_from_ran(ran_conn), '<' if tx else '>', MSC, dtap,
+ ran_conn=ran_conn, imsi=imsi, tmsi=tmsi))
+ return True
+
+ def rule_imsi_detach(self, m):
+ r'.*IMSI DETACH for IMSI-([0-9]+):.*'
+ imsi = m.group(1)
+ e = MO_MT_UNKNOWN
+ self.diagram.add_line(Arrow(e, MS_UE_UNKNOWN, '>', MSC, 'IMSI Detach', imsi=imsi))
+ return True
+
+ def rule_mgcp_tx(self, m):
+ r'.*mgw-endp\([^)]*:([^:]+):([^:]+)\).* (rtpbridge[^ ]+) .* RTP_TO_(RAN|CN)( CI=([^:]+)|): ([^ :]+).*: Sending'
+ ran, l3type, endp, rtp_to, cond_ci, ci, verb = m.groups()
+ e = mo_mt_from_l3type(l3type)
+ if '*' not in endp:
+ endp = self.mask_value('EP', endp)
+ ci = self.mask_value('CI', ci)
+ ci_str = ''
+ if ci:
+ ci_str = ' %s' % ci
+ self.diagram.add_line(Arrow(e, MGW, '<', MSC, 'for %s: %s\\n%s%s' % (rtp_to, verb, endp, ci_str)))
+ return True
+
+ def rule_mgcp_rx(self, m):
+ r'.*mgw-endp\(([^)]+):([^:)]+):([^:)]+)\).* (rtpbridge[^ ]+) .* RTP_TO_(RAN|CN)( CI=([^:]+)|).*: received successful response to ([^:]+): RTP=[^:]+:([0-9.:]+)'
+ subscr, ran_conn, l3type, endp, rtp_to, cond_ci, ci, verb, rtp = m.groups()
+ e = mo_mt_from_l3type(l3type)
+ endp = self.mask_value('EP', endp)
+ ci = self.mask_value('CI', ci)
+ ci_str = ''
+ if ci:
+ ci_str = ' %s' % ci
+ rtp = self.mask_value('IP:port', rtp)
+ self.diagram.add_line(Arrow(e, MGW, '>', MSC, 'for %s: %s OK\\n%s%s %s' % (rtp_to, verb, endp, ci_str, rtp)))
+ return True
+
+ def rule_ran_tx(self, m):
+ r'.*msc_a\(([^)]+):([^:)]+):([^:)]+)\).* RAN encode: ([^: ]+): (.+)$'
+
+ subscr, ran_conn, l3type, ran_type, msg_type = m.groups()
+
+ if msg_type in ('DTAP', 'DirectTransfer'):
+ # will get DTAP details from rule_dtap() instead, not from BSSMAP logging
+ return True
+ if msg_type.startswith('Tx'):
+ # skip 'Tx RANAP SECURITY MODE COMMAND to RNC, ik 47...'
+ return True
+ if '=' in msg_type:
+ # skip 'RAB Assignment: rab_id=1, rtp=192.168.178.66:50008, use_x213_nsap=1'
+ return True
+
+
+ e = mo_mt_from_l3type(l3type)
+
+ imsi = None
+ for m in Parse.RE_IMSI.finditer(subscr):
+ imsi = m.group(1)
+ tmsi = None
+ for m in Parse.RE_TMSI.finditer(subscr):
+ tmsi = m.group(1)
+
+ self.diagram.add_line(Arrow(e, ms_from_ran(ran_conn), '<', MSC, '(%s) %s' % (ran_type, msg_type),
+ ran_conn=ran_conn, imsi=imsi, tmsi=tmsi))
+ return True
+
+ def rule_ran_rx(self, m):
+ r'.*msc_a\(([^)]+):([^:)]+):([^:)]+)\).* RAN decode: ([^: ]+) (.+)$'
+
+ subscr, ran_conn, l3type, ran_type, msg_type = m.groups()
+
+ if msg_type in ('DTAP', 'DirectTransfer', 'DirectTransfer RAN PDU'):
+ # will get DTAP details from rule_dtap() instead, not from BSSMAP logging
+ return True
+
+
+ e = mo_mt_from_l3type(l3type)
+
+ imsi = None
+ for m in Parse.RE_IMSI.finditer(subscr):
+ imsi = m.group(1)
+ tmsi = None
+ for m in Parse.RE_TMSI.finditer(subscr):
+ tmsi = m.group(1)
+
+ self.diagram.add_line(Arrow(e, ms_from_ran(ran_type), '>', MSC, '(%s) %s' % (ran_type, msg_type),
+ ran_conn=ran_conn, imsi=imsi, tmsi=tmsi))
+ return True
+
+ def rule_cc_state(self, m):
+ r'.*trans\(CC[^) ]* [^ )]+:([^:)]+) callref-([^ ]+) [^)]+\) new state ([^ ]+) -> ([^ ]+)'
+ l3type, callref_hex, from_state, to_state = m.groups()
+
+ e = mo_mt_from_l3type(l3type)
+ self.callrefs_mo_mt[callref_hex] = e
+
+ self.diagram.add_line(Arrow(e, MSC, '<>', '.', 'CC state:\\n%s' % to_state))
+ return True
+
+ def rule_log_mncc_no_rtp(self, m):
+ r'.*trans\(CC[^) ]* [^ )]+:([^:)]+) callref-([^ ]+) [^)]+\) (tx|rx) (MNCC_[^ ]*)$'
+ l3type, callref_hex, tx_rx, mncc_msg = m.groups()
+
+ if self.seen_udtrace_mncc:
+ # If no udtrace is present, take the MNCC logging.
+ # But if there is udtrace logging available, we should not duplicate those MNCC lines.
+ return True
+
+ tx = (tx_rx == 'tx')
+
+ try:
+ e = self.callrefs_mo_mt.get(callref_hex, MT)
+ except:
+ e = MT
+
+ self.diagram.add_line(Arrow(e, MSC, '>' if tx else '<', 'mncc', mncc_msg))
+ return True
+
+ def rule_log_mncc_with_rtp(self, m):
+ r'.*trans\(CC[^) ]* [^ )]+:([^:)]+) callref-([^ ]+) [^)]+\) (tx|rx) (MNCC_[^ ]*) \(RTP=([^){]+)(|{.*})\)$'
+ l3type, callref_hex, tx_rx, mncc_msg, rtp, codec = m.groups()
+
+ if self.seen_udtrace_mncc:
+ # If no udtrace is present, take the MNCC logging.
+ # But if there is udtrace logging available, we should not duplicate those MNCC lines.
+ return True
+
+ tx = (tx_rx == 'tx')
+
+ try:
+ e = self.callrefs_mo_mt.get(callref_hex, MT)
+ except:
+ e = MT
+
+ rtp = self.mask_value('IP:port', rtp)
+ self.diagram.add_line(Arrow(e, MSC, '>' if tx else '<', 'mncc', f'{mncc_msg}\\n{rtp}'))
+ return True
+
+ RE_MNCC_RTP = re.compile(' ip := ([^, ]+), rtp_port := ([0-9]+),')
+ RE_MNCC_CALLREF = re.compile(' callref := ([^ ,]+), ')
+
+ # detecting MNCC with udtrace has the advantage that we also get an indication whether RTP information is
+ # present
+ def rule_udtrace_mncc(self, m):
+ r'.*(write|recv).* (Tx|Rx): \{ msg_type := ([^ ]+) .* u := \{ (.*) \} \}$'
+ write_recv, tx_rx, msg_type, u = m.groups()
+
+ self.seen_udtrace_mncc = True
+
+ tx = (tx_rx == 'Tx')
+
+ callref_intstr = None
+ for m in Parse.RE_MNCC_CALLREF.finditer(u):
+ callref_intstr = m.group(1)
+ if not callref_intstr:
+ # log only MNCC that has a callref
+ return True
+
+ try:
+ e = self.callrefs_mo_mt.get(Callref.int_to_hex(callref_intstr), MT)
+ except:
+ e = MT
+
+ descr = msg_type
+
+ for m in Parse.RE_MNCC_RTP.finditer(u):
+ ip_str, port_str = m.groups()
+ try:
+ if int(ip_str) == 0 or int(port_str) == 0:
+ break
+ except:
+ break
+ ip_hex = int_to_hex(ip_str, 32)
+ ip = []
+ ip_val = int(ip_hex, 16)
+ for byte in range(4):
+ ip.insert(0, (ip_val & (0xff << (8*byte))) >> (8*byte))
+ rtp_info = '%s:%s' % ('.'.join(str(b) for b in ip), port_str)
+ rtp_info = self.mask_value('IP:port', rtp_info)
+ descr = '%s\\n%s' % (descr, rtp_info)
+ break
+
+ self.diagram.add_line(Arrow(e, MSC, '>' if tx else '<', 'mncc', descr))
+ return True
+
+ def rule_cc_timer(self, m):
+ r'.*trans\(CC.*IMSI-([0-9]+):.*\) (starting|stopping pending) (guard timer|timer T[0-9]+)( with ([0-9]+) seconds|)'
+ imsi, start_stop, t, with_cond, s = m.groups()
+ start = (start_stop == 'starting')
+ e = MO_MT_UNKNOWN
+ if start:
+ self.diagram.add_line(Arrow(e, MSC, '[]', '.', 'CC starts %s (%ss)' % (t, s), imsi=imsi))
+ else:
+ self.diagram.add_line(Arrow(e, MSC, '[]', '.', 'CC stops %s' % (t), imsi=imsi))
+ return True
+
+
+def translate(inf, outf, cmdline):
+ if cmdline.output_format == 'mscgen':
+ output = OutputMscgen(outf, cmdline.start_with_re)
+ else:
+ output = OutputLadder(outf, cmdline.start_with_re)
+ parse = Parse(output, cmdline.mask_values)
+
+ parse.start()
+
+ while inf.readable():
+ line = inf.readline()
+ if not line:
+ break;
+ parse.add_line(line)
+ parse.end()
+ if cmdline.verbose:
+ for name, count in parse.rules_hit.items():
+ print(f" {name}: {count}")
+
+def open_output(inf, cmdline):
+ if cmdline.output_file == '-':
+ translate(inf, sys.stdout, cmdline)
+ else:
+ with tempfile.NamedTemporaryFile(dir=os.path.dirname(cmdline.output_file), mode='w', encoding='utf-8') as tmp_out:
+ translate(inf, tmp_out, cmdline)
+ if os.path.exists(cmdline.output_file):
+ os.unlink(cmdline.output_file)
+ os.link(tmp_out.name, cmdline.output_file)
+
+def open_input(cmdline):
+ if cmdline.input_file == '-':
+ open_output(sys.stdin, cmdline)
+ else:
+ with open(cmdline.input_file, 'r') as f:
+ open_output(f, cmdline)
+
+def main(cmdline):
+ open_input(cmdline)
+
+
+if __name__ == '__main__':
+ parser = argparse.ArgumentParser(description=doc)
+ parser.add_argument('-i', '--input-file', dest='input_file', default="-",
+ help='Read from this file, or stdin if "-"')
+ parser.add_argument('-o', '--output-file', dest='output_file', default="-",
+ help='Write to this file, or stdout if "-"')
+ parser.add_argument('-t', '--output-format', dest='output_format', default="mscgen",
+ choices=('mscgen','ladder'),
+ help='Pick output format: mscgen format or libosmocore/contrib/ladder_to_msc.py format')
+ parser.add_argument('-m', '--mask-values', dest='mask_values', action='store_true',
+ help='Do not output specific values like IP address, port, endpoint CI, instead just indicate that a value is'
+ ' present. This makes the output reproducible across various logs.')
+ parser.add_argument('-s', '--start-with', dest='start_with_re', default=None,
+ help='Skip until the first message with this label (regex), e.g. -s "CC SETUP"')
+ parser.add_argument('-v', '--verbose', dest='verbose', action='store_true',
+ help='show some debug info, like which regex rules were hit and which were not.')
+
+ cmdline = parser.parse_args()
+
+ main(cmdline)
+
+# vim: shiftwidth=8 noexpandtab tabstop=8 autoindent nocindent
diff --git a/doc/sequence_charts/voice_call_external_mncc.msc b/doc/sequence_charts/voice_call_external_mncc.msc
new file mode 100644
index 000000000..94cedee67
--- /dev/null
+++ b/doc/sequence_charts/voice_call_external_mncc.msc
@@ -0,0 +1,124 @@
+# Generated by osmo-msc.git/doc/sequence_charts/msc_log_to_ladder.py
+msc {
+hscale="3";
+moms[label="MS,BSS (MO)\nUE,hNodeB (MO)"],momgw[label="MGW for MSC (MO)"],momsc[label="MSC (MO)"],mncc[label="MNCC"],mtmsc[label="MSC (MT)"],mtmgw[label="MGW for MSC (MT)"],mtms[label="BSS,MS (MT)\nhNodeB,UE (MT)"];
+moms =>> momsc [label="(BSSMAP) Complete Layer 3 Information"];
+moms =>> momsc [label="MM CM_SERV_REQ"];
+moms <<= momsc [label="MM AUTH_REQ"];
+moms =>> momsc [label="MM AUTH_RESP"];
+moms <<= momsc [label="(BSSMAP) CIPHER_MODE_COMMAND"];
+moms =>> momsc [label="(BSSMAP) Ciphering Mode Complete"];
+moms <<= momsc [label="(BSSMAP) COMMON_ID"];
+moms =>> momsc [label="RR CIPH_M_COMPL"];
+moms =>> momsc [label="CC SETUP"];
+momsc note momsc [label="CC starts guard timer (180s)"];
+momsc abox momsc [label="CC state:\nINITIATED"];
+momgw <<= momsc [label="for CN: CRCX\nrtpbridge/*@msc"];
+momgw =>> momsc [label="for CN: CRCX OK\nEP-1 CI-1 IP:port-1"];
+momsc =>> mncc [label="MNCC_SETUP_IND\nIP:port-1"];
+momgw <<= momsc [label="for RAN: CRCX\nEP-1"];
+momsc <<= mncc [label="MNCC_RTP_CREATE"];
+momgw =>> momsc [label="for RAN: CRCX OK\nEP-1 CI-2 IP:port-2"];
+moms <<= momsc [label="(BSSMAP) ASSIGNMENT_COMMAND"];
+moms =>> momsc [label="(BSSMAP) Assignment Complete"];
+momgw <<= momsc [label="for RAN: MDCX\nEP-1 CI-2"];
+momsc =>> mncc [label="MNCC_RTP_CREATE\nIP:port-1"];
+momsc <<= mncc [label="MNCC_CALL_PROC_REQ"];
+momsc note momsc [label="CC stops guard timer"];
+momsc note momsc [label="CC starts guard timer (180s)"];
+momsc abox momsc [label="CC state:\nMO_CALL_PROC"];
+moms <<= momsc [label="CC CALL_PROC"];
+mtmsc <<= mncc [label="MNCC_SETUP_REQ\nIP:port-1"];
+mtms <<= mtmsc [label="Paging"];
+momgw =>> momsc [label="for RAN: MDCX OK\nEP-1 CI-2 IP:port-2"];
+mtms =>> mtmsc [label="(BSSMAP) Complete Layer 3 Information"];
+mtms =>> mtmsc [label="RR PAG_RESP"];
+mtms <<= mtmsc [label="MM AUTH_REQ"];
+mtms =>> mtmsc [label="MM AUTH_RESP"];
+mtms <<= mtmsc [label="(BSSMAP) CIPHER_MODE_COMMAND"];
+mtms =>> mtmsc [label="(BSSMAP) Ciphering Mode Complete"];
+mtms <<= mtmsc [label="(BSSMAP) COMMON_ID"];
+mtmsc note mtmsc [label="CC starts timer T303 (30s)"];
+mtmsc abox mtmsc [label="CC state:\nCALL_PRESENT"];
+mtms <<= mtmsc [label="CC SETUP"];
+mtms =>> mtmsc [label="RR CIPH_M_COMPL"];
+mtms =>> mtmsc [label="CC CALL_CONF"];
+mtmsc note mtmsc [label="CC stops timer T303"];
+mtmsc note mtmsc [label="CC starts timer T310 (30s)"];
+mtmgw <<= mtmsc [label="for CN: CRCX\nrtpbridge/*@msc"];
+mtmsc abox mtmsc [label="CC state:\nMO_TERM_CALL_CONF"];
+mtmsc =>> mncc [label="MNCC_CALL_CONF_IND"];
+mtmsc <<= mncc [label="MNCC_RTP_CREATE"];
+mtmgw =>> mtmsc [label="for CN: CRCX OK\nEP-2 CI-3 IP:port-3"];
+mtmgw <<= mtmsc [label="for RAN: CRCX\nEP-2"];
+mtmgw =>> mtmsc [label="for RAN: CRCX OK\nEP-2 CI-4 IP:port-4"];
+mtms <<= mtmsc [label="(BSSMAP) ASSIGNMENT_COMMAND"];
+mtms =>> mtmsc [label="(BSSMAP) Assignment Complete"];
+mtmgw <<= mtmsc [label="for RAN: MDCX\nEP-2 CI-4"];
+mtmsc =>> mncc [label="MNCC_RTP_CREATE\nIP:port-3"];
+mtmgw =>> mtmsc [label="for RAN: MDCX OK\nEP-2 CI-4 IP:port-4"];
+mtms =>> mtmsc [label="CC ALERTING"];
+mtmsc note mtmsc [label="CC stops timer T310"];
+mtmsc note mtmsc [label="CC starts timer T301 (180s)"];
+mtmsc abox mtmsc [label="CC state:\nCALL_RECEIVED"];
+mtmsc =>> mncc [label="MNCC_ALERT_IND\nIP:port-3"];
+momsc <<= mncc [label="MNCC_ALERT_REQ"];
+momsc note momsc [label="CC stops guard timer"];
+momsc note momsc [label="CC starts guard timer (180s)"];
+momsc abox momsc [label="CC state:\nCALL_DELIVERED"];
+moms <<= momsc [label="CC ALERTING"];
+mtms =>> mtmsc [label="CC CONNECT"];
+mtmsc note mtmsc [label="CC stops timer T301"];
+mtmsc abox mtmsc [label="CC state:\nCONNECT_REQUEST"];
+mtmsc =>> mncc [label="MNCC_SETUP_CNF\nIP:port-3"];
+mtmsc <<= mncc [label="MNCC_RTP_CONNECT\nIP:port-1"];
+mtmgw <<= mtmsc [label="for CN: MDCX\nEP-2 CI-3"];
+mtmsc <<= mncc [label="MNCC_SETUP_COMPL_REQ"];
+mtmsc note mtmsc [label="CC starts guard timer (180s)"];
+mtmsc abox mtmsc [label="CC state:\nACTIVE"];
+mtmsc note mtmsc [label="CC stops guard timer"];
+mtms <<= mtmsc [label="CC CONNECT_ACK"];
+momsc <<= mncc [label="MNCC_RTP_CONNECT\nIP:port-3"];
+momgw <<= momsc [label="for CN: MDCX\nEP-1 CI-1"];
+momsc <<= mncc [label="MNCC_SETUP_RSP"];
+momsc note momsc [label="CC stops guard timer"];
+momsc note momsc [label="CC starts guard timer (180s)"];
+momsc note momsc [label="CC starts timer T313 (30s)"];
+momsc abox momsc [label="CC state:\nCONNECT_IND"];
+moms <<= momsc [label="CC CONNECT"];
+mtmgw =>> mtmsc [label="for CN: MDCX OK\nEP-2 CI-3 IP:port-3"];
+momgw =>> momsc [label="for CN: MDCX OK\nEP-1 CI-1 IP:port-1"];
+moms =>> momsc [label="CC CONNECT_ACK"];
+momsc note momsc [label="CC stops timer T313"];
+momsc abox momsc [label="CC state:\nACTIVE"];
+momsc note momsc [label="CC stops guard timer"];
+momsc =>> mncc [label="MNCC_SETUP_COMPL_IND"];
+moms =>> momsc [label="CC DISCONNECT"];
+momsc abox momsc [label="CC state:\nDISCONNECT_IND"];
+momsc =>> mncc [label="MNCC_DISC_IND"];
+momsc <<= mncc [label="MNCC_REL_REQ"];
+momsc note momsc [label="CC starts guard timer (180s)"];
+momsc note momsc [label="CC starts timer T308 (10s)"];
+momsc abox momsc [label="CC state:\nRELEASE_REQ"];
+moms <<= momsc [label="CC RELEASE"];
+mtmsc <<= mncc [label="MNCC_DISC_REQ"];
+mtmsc note mtmsc [label="CC starts guard timer (180s)"];
+mtmsc note mtmsc [label="CC starts timer T306 (30s)"];
+mtmsc abox mtmsc [label="CC state:\nDISCONNECT_IND"];
+mtms <<= mtmsc [label="CC DISCONNECT"];
+mtms =>> mtmsc [label="CC RELEASE"];
+mtmsc note mtmsc [label="CC stops timer T306"];
+mtms <<= mtmsc [label="CC RELEASE_COMPL"];
+mtmsc =>> mncc [label="MNCC_REL_IND"];
+mtmsc abox mtmsc [label="CC state:\nNULL"];
+mtmsc note mtmsc [label="CC stops guard timer"];
+mtms <<= mtmsc [label="(BSSMAP) CLEAR_COMMAND"];
+mtms =>> mtmsc [label="(BSSMAP) Clear Complete"];
+moms =>> momsc [label="CC RELEASE_COMPL"];
+momsc note momsc [label="CC stops timer T308"];
+momsc =>> mncc [label="MNCC_REL_CNF"];
+momsc abox momsc [label="CC state:\nNULL"];
+momsc note momsc [label="CC stops guard timer"];
+moms <<= momsc [label="(BSSMAP) CLEAR_COMMAND"];
+moms =>> momsc [label="(BSSMAP) Clear Complete"];
+}
diff --git a/doc/sequence_charts/voice_call_internal_mncc.msc b/doc/sequence_charts/voice_call_internal_mncc.msc
new file mode 100644
index 000000000..898c1ff9a
--- /dev/null
+++ b/doc/sequence_charts/voice_call_internal_mncc.msc
@@ -0,0 +1,129 @@
+# Generated by osmo-msc.git/doc/sequence_charts/msc_log_to_ladder.py
+msc {
+hscale="3";
+moms[label="MS,BSS (MO)\nUE,hNodeB (MO)"],momgw[label="MGW for MSC (MO)"],momsc[label="MSC (MO)"],mncc[label="MNCC"],mtmsc[label="MSC (MT)"],mtmgw[label="MGW for MSC (MT)"],mtms[label="BSS,MS (MT)\nhNodeB,UE (MT)"];
+moms =>> momsc [label="(BSSMAP) Complete Layer 3 Information"];
+moms =>> momsc [label="MM CM_SERV_REQ"];
+moms <<= momsc [label="MM AUTH_REQ"];
+moms =>> momsc [label="MM AUTH_RESP"];
+moms <<= momsc [label="(BSSMAP) CIPHER_MODE_COMMAND"];
+moms =>> momsc [label="(BSSMAP) Ciphering Mode Complete"];
+moms <<= momsc [label="(BSSMAP) COMMON_ID"];
+moms =>> momsc [label="RR CIPH_M_COMPL"];
+moms =>> momsc [label="CC SETUP"];
+momsc note momsc [label="CC starts guard timer (180s)"];
+momsc abox momsc [label="CC state:\nINITIATED"];
+momgw <<= momsc [label="for CN: CRCX\nrtpbridge/*@msc"];
+momgw =>> momsc [label="for CN: CRCX OK\nEP-1 CI-1 IP:port-1"];
+momsc =>> mncc [label="MNCC_SETUP_IND\nIP:port-1"];
+momsc <<= mncc [label="MNCC_CALL_PROC_REQ"];
+momsc note momsc [label="CC stops guard timer"];
+momsc note momsc [label="CC starts guard timer (180s)"];
+momsc abox momsc [label="CC state:\nMO_CALL_PROC"];
+moms <<= momsc [label="CC CALL_PROC"];
+momsc <<= mncc [label="MNCC_LCHAN_MODIFY"];
+momsc note momsc [label="CC stops guard timer"];
+momsc note momsc [label="CC starts guard timer (180s)"];
+mtmsc <<= mncc [label="MNCC_SETUP_REQ\nIP:port-1"];
+mtms <<= mtmsc [label="Paging"];
+momgw <<= momsc [label="for RAN: CRCX\nEP-1"];
+momgw =>> momsc [label="for RAN: CRCX OK\nEP-1 CI-2 IP:port-2"];
+moms <<= momsc [label="(BSSMAP) ASSIGNMENT_COMMAND"];
+mtms =>> mtmsc [label="(BSSMAP) Complete Layer 3 Information"];
+mtms =>> mtmsc [label="RR PAG_RESP"];
+mtms <<= mtmsc [label="MM AUTH_REQ"];
+moms =>> momsc [label="(BSSMAP) Assignment Complete"];
+momgw <<= momsc [label="for RAN: MDCX\nEP-1 CI-2"];
+momsc =>> mncc [label="MNCC_RTP_CREATE\nIP:port-1"];
+momgw =>> momsc [label="for RAN: MDCX OK\nEP-1 CI-2 IP:port-2"];
+mtms =>> mtmsc [label="MM AUTH_RESP"];
+mtms <<= mtmsc [label="(BSSMAP) CIPHER_MODE_COMMAND"];
+mtms =>> mtmsc [label="(BSSMAP) Ciphering Mode Complete"];
+mtms <<= mtmsc [label="(BSSMAP) COMMON_ID"];
+mtmsc note mtmsc [label="CC starts timer T303 (30s)"];
+mtmsc abox mtmsc [label="CC state:\nCALL_PRESENT"];
+mtms <<= mtmsc [label="CC SETUP"];
+mtms =>> mtmsc [label="RR CIPH_M_COMPL"];
+mtms =>> mtmsc [label="CC CALL_CONF"];
+mtmsc note mtmsc [label="CC stops timer T303"];
+mtmsc note mtmsc [label="CC starts timer T310 (30s)"];
+mtmgw <<= mtmsc [label="for CN: CRCX\nrtpbridge/*@msc"];
+mtmsc abox mtmsc [label="CC state:\nMO_TERM_CALL_CONF"];
+mtmsc =>> mncc [label="MNCC_CALL_CONF_IND"];
+mtmsc <<= mncc [label="MNCC_LCHAN_MODIFY"];
+mtmsc note mtmsc [label="CC starts guard timer (180s)"];
+mtmgw =>> mtmsc [label="for CN: CRCX OK\nEP-2 CI-3 IP:port-3"];
+mtmgw <<= mtmsc [label="for RAN: CRCX\nEP-2"];
+mtmgw =>> mtmsc [label="for RAN: CRCX OK\nEP-2 CI-4 IP:port-4"];
+mtms <<= mtmsc [label="(BSSMAP) ASSIGNMENT_COMMAND"];
+mtms =>> mtmsc [label="(BSSMAP) Assignment Complete"];
+mtmgw <<= mtmsc [label="for RAN: MDCX\nEP-2 CI-4"];
+mtmsc =>> mncc [label="MNCC_RTP_CREATE\nIP:port-3"];
+mtmgw =>> mtmsc [label="for RAN: MDCX OK\nEP-2 CI-4 IP:port-4"];
+mtms =>> mtmsc [label="CC ALERTING"];
+mtmsc note mtmsc [label="CC stops timer T310"];
+mtmsc note mtmsc [label="CC starts timer T301 (180s)"];
+mtmsc abox mtmsc [label="CC state:\nCALL_RECEIVED"];
+mtmsc =>> mncc [label="MNCC_ALERT_IND\nIP:port-3"];
+momsc <<= mncc [label="MNCC_ALERT_REQ\nIP:port-3"];
+momsc note momsc [label="CC stops guard timer"];
+momsc note momsc [label="CC starts guard timer (180s)"];
+momsc abox momsc [label="CC state:\nCALL_DELIVERED"];
+momgw <<= momsc [label="for CN: MDCX\nEP-1 CI-1"];
+moms <<= momsc [label="CC ALERTING"];
+momgw =>> momsc [label="for CN: MDCX OK\nEP-1 CI-1 IP:port-1"];
+mtms =>> mtmsc [label="CC CONNECT"];
+mtmsc note mtmsc [label="CC stops timer T301"];
+mtmsc abox mtmsc [label="CC state:\nCONNECT_REQUEST"];
+mtmsc =>> mncc [label="MNCC_SETUP_CNF\nIP:port-3"];
+mtmsc <<= mncc [label="MNCC_SETUP_COMPL_REQ"];
+mtmsc note mtmsc [label="CC stops guard timer"];
+mtmsc note mtmsc [label="CC starts guard timer (180s)"];
+mtmsc abox mtmsc [label="CC state:\nACTIVE"];
+mtmsc note mtmsc [label="CC stops guard timer"];
+mtms <<= mtmsc [label="CC CONNECT_ACK"];
+momsc <<= mncc [label="MNCC_SETUP_RSP\nIP:port-3"];
+momsc note momsc [label="CC stops guard timer"];
+momsc note momsc [label="CC starts guard timer (180s)"];
+momsc note momsc [label="CC starts timer T313 (30s)"];
+momsc abox momsc [label="CC state:\nCONNECT_IND"];
+moms <<= momsc [label="CC CONNECT"];
+mtmgw <<= mtmsc [label="for CN: MDCX\nEP-2 CI-3"];
+mtmgw =>> mtmsc [label="for CN: MDCX OK\nEP-2 CI-3 IP:port-3"];
+moms =>> momsc [label="CC CONNECT_ACK"];
+momsc note momsc [label="CC stops timer T313"];
+momsc abox momsc [label="CC state:\nACTIVE"];
+momsc note momsc [label="CC stops guard timer"];
+momsc =>> mncc [label="MNCC_SETUP_COMPL_IND"];
+moms =>> momsc [label="CC DISCONNECT"];
+momsc abox momsc [label="CC state:\nDISCONNECT_IND"];
+momsc =>> mncc [label="MNCC_DISC_IND"];
+momsc <<= mncc [label="MNCC_REL_REQ"];
+momsc note momsc [label="CC starts guard timer (180s)"];
+momsc note momsc [label="CC starts timer T308 (10s)"];
+momsc abox momsc [label="CC state:\nRELEASE_REQ"];
+moms <<= momsc [label="CC RELEASE"];
+mtmsc <<= mncc [label="MNCC_DISC_REQ"];
+mtmsc note mtmsc [label="CC starts guard timer (180s)"];
+mtmsc note mtmsc [label="CC starts timer T306 (30s)"];
+mtmsc abox mtmsc [label="CC state:\nDISCONNECT_IND"];
+mtms <<= mtmsc [label="CC DISCONNECT"];
+mtms =>> mtmsc [label="CC RELEASE"];
+mtmsc note mtmsc [label="CC stops timer T306"];
+mtms <<= mtmsc [label="CC RELEASE_COMPL"];
+mtmsc =>> mncc [label="MNCC_REL_IND"];
+momsc <<= mncc [label="MNCC_REL_REQ"];
+momsc note momsc [label="CC stops guard timer"];
+momsc note momsc [label="CC starts guard timer (180s)"];
+mtmsc abox mtmsc [label="CC state:\nNULL"];
+mtmsc note mtmsc [label="CC stops guard timer"];
+mtms <<= mtmsc [label="(BSSMAP) CLEAR_COMMAND"];
+mtms =>> mtmsc [label="(BSSMAP) Clear Complete"];
+moms =>> momsc [label="CC RELEASE_COMPL"];
+momsc note momsc [label="CC stops timer T308"];
+momsc =>> mncc [label="MNCC_REL_CNF"];
+momsc abox momsc [label="CC state:\nNULL"];
+momsc note momsc [label="CC stops guard timer"];
+moms <<= momsc [label="(BSSMAP) CLEAR_COMMAND"];
+moms =>> momsc [label="(BSSMAP) Clear Complete"];
+}
diff --git a/include/osmocom/Makefile.am b/include/osmocom/Makefile.am
index 4d8063711..b07a00459 100644
--- a/include/osmocom/Makefile.am
+++ b/include/osmocom/Makefile.am
@@ -1,3 +1,4 @@
SUBDIRS = \
msc \
+ smpp \
$(NULL)
diff --git a/include/osmocom/msc/Makefile.am b/include/osmocom/msc/Makefile.am
index 0d7d45ce9..a940056fc 100644
--- a/include/osmocom/msc/Makefile.am
+++ b/include/osmocom/msc/Makefile.am
@@ -1,6 +1,10 @@
noinst_HEADERS = \
call_leg.h \
cell_id_list.h \
+ codec_filter.h \
+ codec_mapping.h \
+ csd_bs.h \
+ csd_filter.h \
db.h \
debug.h \
e_link.h \
@@ -21,6 +25,7 @@ noinst_HEADERS = \
msc_a_remote.h \
msc_common.h \
msc_ho.h \
+ msc_vgcs.h \
msc_i.h \
msc_i_remote.h \
msc_roles.h \
@@ -39,15 +44,18 @@ noinst_HEADERS = \
rrlp.h \
rtp_stream.h \
sccp_ran.h \
+ sdp_msg.h \
sgs_iface.h \
sgs_server.h \
sgs_vty.h \
signal.h \
silent_call.h \
- smpp.h \
sms_queue.h \
transaction.h \
+ transaction_cc.h \
vlr.h \
vlr_sgs.h \
vty.h \
+ asci_gcr.h \
+ asci_vty.h \
$(NULL)
diff --git a/include/osmocom/msc/asci_gcr.h b/include/osmocom/msc/asci_gcr.h
new file mode 100644
index 000000000..f2160c1e0
--- /dev/null
+++ b/include/osmocom/msc/asci_gcr.h
@@ -0,0 +1,55 @@
+/* Group Call Register (GCR) */
+/*
+ * (C) 2023 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
+ * All Rights Reserved
+ *
+ * SPDX-License-Identifier: AGPL-3.0+
+ *
+ * Author: Andreas Eversberg
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#pragma once
+
+/* Group Call Register */
+struct gcr {
+ struct llist_head list;
+ enum trans_type trans_type;
+ char group_id[9];
+ uint16_t timeout;
+ bool mute_talker;
+ struct llist_head bss_list;
+};
+
+struct gcr_bss {
+ struct llist_head list;
+ int pc;
+ struct llist_head cell_list;
+};
+
+struct gcr_cell {
+ struct llist_head list;
+ uint16_t cell_id;
+};
+
+struct gcr_cell *gcr_add_cell(struct gcr_bss *bss, uint16_t cell_id);
+struct gcr_cell *gcr_find_cell(struct gcr_bss *bss, uint16_t cell_id);
+void gcr_rm_cell(struct gcr_bss *bss, uint16_t cell_id);
+struct gcr_bss *gcr_add_bss(struct gcr *gcr, int pc);
+struct gcr_bss *gcr_find_bss(struct gcr *gcr, int pc);
+void gcr_rm_bss(struct gcr *gcr, int pc);
+struct gcr *gcr_create(struct gsm_network *gsmnet, enum trans_type trans_type, const char *group_id);
+void gcr_destroy(struct gcr *gcr);
+struct gcr *gcr_by_group_id(struct gsm_network *gsmnet, enum trans_type trans_type, const char *group_id);
+struct gcr *gcr_by_callref(struct gsm_network *gsmnet, enum trans_type trans_type, uint32_t callref);
diff --git a/include/osmocom/msc/asci_vty.h b/include/osmocom/msc/asci_vty.h
new file mode 100644
index 000000000..5fe11f6f5
--- /dev/null
+++ b/include/osmocom/msc/asci_vty.h
@@ -0,0 +1,25 @@
+/*
+ * (C) 2023 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
+ * All Rights Reserved
+ *
+ * SPDX-License-Identifier: AGPL-3.0+
+ *
+ * Author: Andreas Eversberg
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+void asci_vty_init(struct gsm_network *msc_network);
diff --git a/include/osmocom/msc/call_leg.h b/include/osmocom/msc/call_leg.h
index d8380f52b..c7d3b9739 100644
--- a/include/osmocom/msc/call_leg.h
+++ b/include/osmocom/msc/call_leg.h
@@ -12,6 +12,7 @@ struct gsm_network;
struct gsm_trans;
struct rtp_stream;
enum rtp_direction;
+struct sdp_audio_codecs;
extern struct osmo_tdef g_mgw_tdefs[];
@@ -44,6 +45,8 @@ struct call_leg {
/* Prevent events from deallocating for certain release code paths, to prevent use-after-free problems. */
bool deallocating;
+
+ bool ran_peer_supports_osmux;
};
enum call_leg_event {
@@ -72,7 +75,8 @@ int call_leg_local_bridge(struct call_leg *cl1, uint32_t call_id1, struct gsm_tr
int call_leg_ensure_rtp_alloc(struct call_leg *cl, enum rtp_direction dir, uint32_t call_id,
struct gsm_trans *for_trans);
int call_leg_ensure_ci(struct call_leg *cl, enum rtp_direction dir, uint32_t call_id, struct gsm_trans *for_trans,
- const enum mgcp_codecs *codec_if_known, const struct osmo_sockaddr_str *remote_port_if_known);
+ const struct sdp_audio_codecs *codecs_if_known,
+ const struct osmo_sockaddr_str *remote_addr_if_known);
struct osmo_sockaddr_str *call_leg_local_ip(struct call_leg *cl, enum rtp_direction dir);
void call_leg_rtp_stream_gone(struct call_leg *cl, struct rtp_stream *rtps);
diff --git a/include/osmocom/msc/cell_id_list.h b/include/osmocom/msc/cell_id_list.h
index 83d05f5da..4c0c6eac4 100644
--- a/include/osmocom/msc/cell_id_list.h
+++ b/include/osmocom/msc/cell_id_list.h
@@ -1,6 +1,6 @@
/* Manage a list of struct gsm0808_cell_id */
/*
- * (C) 2019 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de>
+ * (C) 2019 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
* All Rights Reserved
*
* Author: Neels Hofmeyr
@@ -16,10 +16,6 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#pragma once
diff --git a/include/osmocom/msc/codec_filter.h b/include/osmocom/msc/codec_filter.h
new file mode 100644
index 000000000..da4a67e04
--- /dev/null
+++ b/include/osmocom/msc/codec_filter.h
@@ -0,0 +1,57 @@
+/* Filter/overlay codec selections for a voice call, across MS, RAN and CN limitations */
+/*
+ * (C) 2019-2022 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
+ * All Rights Reserved
+ *
+ * Author: Neels Hofmeyr
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#pragma once
+
+#include <osmocom/gsm/gsm_utils.h>
+#include <osmocom/gsm/mncc.h>
+#include <osmocom/mgcp_client/mgcp_client.h>
+
+#include <osmocom/msc/sdp_msg.h>
+
+struct gsm0808_speech_codec_list;
+
+/* Combine various codec selections to obtain a resulting set of codecs allowed by all of them.
+ * Members reflect the different entities/stages that select codecs in a voice call.
+ * Call codec_filter_run() and obtain the resulting set of codecs in codec_filter.result. */
+struct codec_filter {
+ /* The fixed set of codecs available on the RAN type, per definition. */
+ struct sdp_audio_codecs ran;
+ /* The codecs advertised by the MS Bearer Capabilities */
+ struct sdp_audio_codecs ms;
+ /* If known, the set of codecs the current RAN cell allows / has available.
+ * This may not be available if the BSC does not issue this information early enough.
+ * Should be ignored if empty. */
+ struct sdp_audio_codecs bss;
+
+ /* After a channel was assigned, this reflects the chosen codec. */
+ struct sdp_audio_codec assignment;
+};
+
+void codec_filter_set_ran(struct codec_filter *codec_filter, enum osmo_rat_type ran_type);
+void codec_filter_set_bss(struct codec_filter *codec_filter,
+ const struct gsm0808_speech_codec_list *codec_list_bss_supported);
+int codec_filter_run(struct codec_filter *codec_filter, struct sdp_msg *result, const struct sdp_msg *remote);
+
+int codec_filter_to_str_buf(char *buf, size_t buflen, const struct codec_filter *codec_filter,
+ const struct sdp_msg *result, const struct sdp_msg *remote);
+char *codec_filter_to_str_c(void *ctx, const struct codec_filter *codec_filter, const struct sdp_msg *result,
+ const struct sdp_msg *remote);
+const char *codec_filter_to_str(const struct codec_filter *codec_filter, const struct sdp_msg *result,
+ const struct sdp_msg *remote);
diff --git a/include/osmocom/msc/codec_mapping.h b/include/osmocom/msc/codec_mapping.h
new file mode 100644
index 000000000..3b502a913
--- /dev/null
+++ b/include/osmocom/msc/codec_mapping.h
@@ -0,0 +1,65 @@
+/* Routines for translation between codec representations: SDP, CC/BSSMAP variants, MGCP, MNCC */
+#pragma once
+
+#include <osmocom/gsm/protocol/gsm_04_08.h>
+#include <osmocom/gsm/protocol/gsm_08_08.h>
+#include <osmocom/mgcp_client/mgcp_client.h>
+#include <osmocom/msc/sdp_msg.h>
+#include <osmocom/gsm/mncc.h>
+
+#define NO_MGCP_CODEC 0xffffffff
+
+extern const struct gsm_mncc_bearer_cap bearer_cap_empty;
+
+enum codec_frhr {
+ CODEC_FRHR_NONE = 0,
+ CODEC_FRHR_FR,
+ CODEC_FRHR_HR,
+};
+
+struct codec_mapping {
+ /* The sdp.payload_type number in a mapping is not necessarily imperative, but may just reflect the usual
+ * payload type number for a given codec. */
+ struct sdp_audio_codec sdp;
+ /* The id that mgcp_client.h uses for this codec. Must be set in each mapping, because 0 means PCMU. */
+ enum mgcp_codecs mgcp;
+ /* Nr of used entries in speech_ver[] below. */
+ unsigned int speech_ver_count;
+ /* Entries to add to Speech Version lists when this codec is present, if any. */
+ enum gsm48_bcap_speech_ver speech_ver[8];
+ /* If applicable, one of GSM_TCHF_FRAME, GSM_TCHF_FRAME_EFR, GSM_TCHH_FRAME, GSM_TCH_FRAME_AMR; or zero. */
+ uint32_t mncc_payload_msg_type;
+ /* Set to true if gsm0808_speech_codec below reflects a meaningful value. */
+ bool has_gsm0808_speech_codec;
+ struct gsm0808_speech_codec gsm0808_speech_codec;
+ /* If applicable, entries to add to Permitted Speech lists when this codec is present; or zero. */
+ enum gsm0808_permitted_speech perm_speech;
+ /* If applicable, indicator whether this codec can work on a GERAN half-rate lchan, or whether full-rate is
+ * required. Leave zero when this codec does not apply to GERAN. */
+ enum codec_frhr frhr;
+};
+
+const struct codec_mapping *codec_mapping_by_speech_ver(enum gsm48_bcap_speech_ver speech_ver);
+const struct codec_mapping *codec_mapping_by_gsm0808_speech_codec_type(enum gsm0808_speech_codec_type sct);
+const struct codec_mapping *codec_mapping_by_gsm0808_speech_codec(const struct gsm0808_speech_codec *sc);
+const struct codec_mapping *codec_mapping_by_perm_speech(enum gsm0808_permitted_speech perm_speech);
+const struct codec_mapping *codec_mapping_by_subtype_name(const char *subtype_name);
+const struct codec_mapping *codec_mapping_by_mgcp_codec(enum mgcp_codecs mgcp);
+
+int bearer_cap_add_speech_ver(struct gsm_mncc_bearer_cap *bearer_cap, enum gsm48_bcap_speech_ver speech_ver);
+int sdp_audio_codec_add_to_bearer_cap(struct gsm_mncc_bearer_cap *bearer_cap, const struct sdp_audio_codec *codec);
+int sdp_audio_codecs_to_bearer_cap(struct gsm_mncc_bearer_cap *bearer_cap, const struct sdp_audio_codecs *ac);
+int bearer_cap_set_radio(struct gsm_mncc_bearer_cap *bearer_cap);
+
+struct sdp_audio_codec *sdp_audio_codecs_add_speech_ver(struct sdp_audio_codecs *ac,
+ enum gsm48_bcap_speech_ver speech_ver);
+struct sdp_audio_codec *sdp_audio_codecs_add_mgcp_codec(struct sdp_audio_codecs *ac, enum mgcp_codecs mgcp_codec);
+void sdp_audio_codecs_from_bearer_cap(struct sdp_audio_codecs *ac, const struct gsm_mncc_bearer_cap *bc);
+
+int sdp_audio_codec_to_speech_codec_list(struct gsm0808_speech_codec_list *scl, const struct sdp_audio_codec *codec);
+void sdp_audio_codecs_to_speech_codec_list(struct gsm0808_speech_codec_list *cl, const struct sdp_audio_codecs *ac);
+void sdp_audio_codecs_from_speech_codec_list(struct sdp_audio_codecs *ac, const struct gsm0808_speech_codec_list *cl);
+
+int sdp_audio_codecs_to_gsm0808_channel_type(struct gsm0808_channel_type *ct, const struct sdp_audio_codecs *ac);
+
+enum mgcp_codecs sdp_audio_codec_to_mgcp_codec(const struct sdp_audio_codec *codec);
diff --git a/include/osmocom/msc/csd_bs.h b/include/osmocom/msc/csd_bs.h
new file mode 100644
index 000000000..eee869266
--- /dev/null
+++ b/include/osmocom/msc/csd_bs.h
@@ -0,0 +1,54 @@
+/* 3GPP TS 122.002 Bearer Services */
+#pragma once
+
+#include <osmocom/gsm/mncc.h>
+#include <osmocom/gsm/protocol/gsm_08_08.h>
+
+enum csd_bs {
+ CSD_BS_NONE,
+
+ /* 3.1.1.1.2 */
+ CSD_BS_21_T_V110_0k3,
+ CSD_BS_22_T_V110_1k2,
+ CSD_BS_24_T_V110_2k4,
+ CSD_BS_25_T_V110_4k8,
+ CSD_BS_26_T_V110_9k6,
+
+ /* 3.1.1.2.2 */
+ CSD_BS_21_NT_V110_0k3,
+ CSD_BS_22_NT_V110_1k2,
+ CSD_BS_24_NT_V110_2k4,
+ CSD_BS_25_NT_V110_4k8,
+ CSD_BS_26_NT_V110_9k6,
+
+ /* 3.1.2.1.2 */
+ CSD_BS_31_T_V110_1k2,
+ CSD_BS_32_T_V110_2k4,
+ CSD_BS_33_T_V110_4k8,
+ CSD_BS_34_T_V110_9k6,
+
+ CSD_BS_MAX,
+};
+
+struct csd_bs_list {
+ unsigned int count;
+ enum csd_bs bs[CSD_BS_MAX];
+};
+
+void csd_bs_list_add_bs(struct csd_bs_list *list, enum csd_bs bs);
+int csd_bs_list_to_bearer_cap(struct gsm_mncc_bearer_cap *cap, const struct csd_bs_list *list);
+void csd_bs_list_from_bearer_cap(struct csd_bs_list *list, const struct gsm_mncc_bearer_cap *cap);
+
+int csd_bs_to_str_buf(char *buf, size_t buflen, enum csd_bs bs);
+char *csd_bs_to_str_c(void *ctx, enum csd_bs bs);
+const char *csd_bs_to_str(enum csd_bs bs);
+
+int csd_bs_list_to_str_buf(char *buf, size_t buflen, const struct csd_bs_list *list);
+char *csd_bs_list_to_str_c(void *ctx, const struct csd_bs_list *list);
+const char *csd_bs_list_to_str(const struct csd_bs_list *list);
+
+void csd_bs_list_add_bs(struct csd_bs_list *list, enum csd_bs bs);
+void csd_bs_list_remove(struct csd_bs_list *list, enum csd_bs bs);
+void csd_bs_list_intersection(struct csd_bs_list *dest, const struct csd_bs_list *other);
+
+int csd_bs_list_to_gsm0808_channel_type(struct gsm0808_channel_type *ct, const struct csd_bs_list *list);
diff --git a/include/osmocom/msc/csd_filter.h b/include/osmocom/msc/csd_filter.h
new file mode 100644
index 000000000..51ffff706
--- /dev/null
+++ b/include/osmocom/msc/csd_filter.h
@@ -0,0 +1,53 @@
+/* Filter/overlay data rates for CSD, across MS, RAN and CN limitations */
+/*
+ * (C) 2023 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
+ * All Rights Reserved
+ *
+ * Author: Oliver Smith
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#pragma once
+
+#include <osmocom/gsm/gsm_utils.h>
+#include <osmocom/gsm/mncc.h>
+#include <osmocom/mgcp_client/mgcp_client.h>
+
+#include <osmocom/msc/csd_bs.h>
+#include <osmocom/msc/sdp_msg.h>
+
+/* Combine various data rate selections to obtain a resulting set allowed by
+ * all of them. Members reflect the different entities/stages that select data
+ * rates in CSD. Call csd_filter_run() and obtain the resulting set in
+ * csd_filter.result. */
+struct csd_filter {
+ /* The fixed set available on the RAN type, per definition. */
+ struct csd_bs_list ran;
+ /* The services advertised by the MS Bearer Capabilities */
+ struct csd_bs_list ms;
+ /* If known, the set the current RAN cell allows / has available. This
+ * may not be available if the BSC does not issue this information
+ * early enough. Should be ignored if empty. */
+ struct csd_bs_list bss;
+
+ /* After a channel was assigned, this reflects the chosen BS. */
+ enum csd_bs assignment;
+};
+
+void csd_filter_set_ran(struct csd_filter *filter, enum osmo_rat_type ran_type);
+int csd_filter_run(struct csd_filter *filter, struct sdp_msg *result, const struct sdp_msg *remote);
+
+int csd_filter_to_str_buf(char *buf, size_t buflen, const struct csd_filter *filter,
+ const struct sdp_msg *result, const struct sdp_msg *remote);
+char *csd_filter_to_str_c(void *ctx, const struct csd_filter *filter, const struct sdp_msg *result, const struct sdp_msg *remote);
+const char *csd_filter_to_str(const struct csd_filter *filter, const struct sdp_msg *result, const struct sdp_msg *remote);
diff --git a/include/osmocom/msc/db.h b/include/osmocom/msc/db.h
index d9463a684..fc1781bd6 100644
--- a/include/osmocom/msc/db.h
+++ b/include/osmocom/msc/db.h
@@ -1,5 +1,6 @@
/* (C) 2008 by Jan Luebbe <jluebbe@debian.org>
* (C) 2009 by Holger Hans Peter Freyther <zecke@selfish.org>
+ * (C) 2022 by Harald Welte <laforge@osmocom.org>
* All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify
@@ -30,7 +31,7 @@ struct gsm_network;
struct gsm_sms;
/* one time initialisation */
-int db_init(const char *name);
+int db_init(void *ctx, const char *fname, bool enable_sqlite_logging);
int db_prepare(void);
int db_fini(void);
@@ -39,12 +40,12 @@ int db_sms_store(struct gsm_sms *sms);
struct gsm_sms *db_sms_get(struct gsm_network *net, unsigned long long id);
struct gsm_sms *db_sms_get_next_unsent(struct gsm_network *net,
unsigned long long min_sms_id,
- unsigned int max_failed);
+ int max_failed);
struct gsm_sms *db_sms_get_next_unsent_rr_msisdn(struct gsm_network *net,
const char *last_msisdn,
- unsigned int max_failed);
+ int max_failed);
struct gsm_sms *db_sms_get_unsent_for_subscr(struct vlr_subscr *vsub,
- unsigned int max_failed);
+ int max_failed);
int db_sms_mark_delivered(struct gsm_sms *sms);
int db_sms_inc_deliver_attempts(struct gsm_sms *sms);
int db_sms_delete_by_msisdn(const char *msisdn);
diff --git a/include/osmocom/msc/debug.h b/include/osmocom/msc/debug.h
index 3347e20d4..9925a3cb0 100644
--- a/include/osmocom/msc/debug.h
+++ b/include/osmocom/msc/debug.h
@@ -6,8 +6,11 @@
enum {
DRLL,
DCC,
+ DBCC,
+ DGCC,
DMM,
DRR,
+ DLCLS,
DMNCC,
DPAG,
DMSC,
@@ -23,5 +26,6 @@ enum {
DBSSAP,
DSGS,
DSS,
+ DASCI,
Debug_LastEntry,
};
diff --git a/include/osmocom/msc/gsm_04_08.h b/include/osmocom/msc/gsm_04_08.h
index 661da42b3..cd5074eb6 100644
--- a/include/osmocom/msc/gsm_04_08.h
+++ b/include/osmocom/msc/gsm_04_08.h
@@ -45,6 +45,11 @@ int gsm48_send_rr_app_info(struct msc_a *msc_a, uint8_t apdu_id, uint8_t apdu_le
int gsm48_send_rr_ass_cmd(struct gsm_lchan *dest_lchan, struct gsm_lchan *lchan, uint8_t power_class);
int gsm48_send_ho_cmd(struct gsm_lchan *old_lchan, struct gsm_lchan *new_lchan, uint8_t power_command, uint8_t ho_ref);
+void gsm48_cc_rx_setup_cn_local_rtp_port_known(struct gsm_trans *trans);
+void gsm48_cc_rx_call_conf_cn_local_rtp_port_known(struct gsm_trans *trans);
+int cc_on_cn_local_rtp_port_known(struct gsm_trans *trans);
+int cc_on_assignment_done(struct gsm_trans *trans);
+
int mncc_tx_to_cc(struct gsm_network *net, void *arg);
/* convert a ASCII phone number to call-control BCD */
@@ -54,8 +59,6 @@ int decode_bcd_number(char *output, int output_len, const uint8_t *bcd_lv,
int h_len);
int send_siemens_mrpci(struct gsm_lchan *lchan, uint8_t *classmark2_lv);
-int gsm48_extract_mi(uint8_t *classmark2, int length, char *mi_string, uint8_t *mi_type);
-int gsm48_paging_extract_mi(struct gsm48_pag_resp *pag, int length, char *mi_string, uint8_t *mi_type);
int gsm48_lchan_modify(struct gsm_lchan *lchan, uint8_t lchan_mode);
int gsm48_rx_rr_modif_ack(struct msgb *msg);
diff --git a/include/osmocom/msc/gsm_04_11.h b/include/osmocom/msc/gsm_04_11.h
index be8bff3c3..17a31ecdd 100644
--- a/include/osmocom/msc/gsm_04_11.h
+++ b/include/osmocom/msc/gsm_04_11.h
@@ -11,24 +11,6 @@ struct msc_a;
#define UM_SAPI_SMS 3 /* See GSM 04.05/04.06 */
-/* SMS deliver PDU */
-struct sms_deliver {
- uint8_t mti:2; /* message type indicator */
- uint8_t mms:1; /* more messages to send */
- uint8_t rp:1; /* reply path */
- uint8_t udhi:1; /* user data header indicator */
- uint8_t sri:1; /* status report indication */
- uint8_t *orig_addr; /* originating address */
- uint8_t pid; /* protocol identifier */
- uint8_t dcs; /* data coding scheme */
- /* service centre time stamp */
- uint8_t ud_len; /* user data length */
- uint8_t *user_data; /* user data */
-
- uint8_t msg_ref; /* message reference */
- uint8_t *smsc;
-};
-
struct gsm_network;
struct msgb;
@@ -45,7 +27,9 @@ int gsm411_send_sms(struct gsm_network *net,
struct gsm_sms *sms);
int gsm411_send_rp_data(struct gsm_network *net, struct vlr_subscr *vsub,
size_t sm_rp_oa_len, const uint8_t *sm_rp_oa,
- size_t sm_rp_ud_len, const uint8_t *sm_rp_ud);
+ size_t sm_rp_ud_len, const uint8_t *sm_rp_ud,
+ bool sm_rp_mmts_ind, const uint8_t *gsup_source_name,
+ size_t gsup_source_name_len);
void gsm411_sapi_n_reject(struct msc_a *msc_a);
diff --git a/include/osmocom/msc/gsm_data.h b/include/osmocom/msc/gsm_data.h
index f6e3ed99f..119f093db 100644
--- a/include/osmocom/msc/gsm_data.h
+++ b/include/osmocom/msc/gsm_data.h
@@ -10,13 +10,17 @@
#include <osmocom/core/rate_ctr.h>
#include <osmocom/core/select.h>
#include <osmocom/core/stats.h>
+#include <osmocom/core/stat_item.h>
#include <osmocom/gsm/gsm48.h>
#include <osmocom/crypt/auth.h>
+#include <osmocom/crypt/utran_cipher.h>
#include <osmocom/mgcp_client/mgcp_client.h>
+#include <osmocom/mgcp_client/mgcp_client_pool.h>
#include <osmocom/msc/msc_common.h>
#include <osmocom/msc/neighbor_ident.h>
+#include <osmocom/msc/sms_queue.h>
#include "gsm_data_shared.h"
#include "osmux.h"
@@ -29,6 +33,7 @@ struct vlr_instance;
struct vlr_subscr;
struct gsup_client_mux;
+#define SMS_DEFAULT_DB_FILE_PATH "sms.db"
#define tmsi_from_string(str) strtoul(str, NULL, 10)
enum {
@@ -42,6 +47,8 @@ enum {
MSC_CTR_CM_SERVICE_REQUEST_ACCEPTED,
MSC_CTR_PAGING_RESP_REJECTED,
MSC_CTR_PAGING_RESP_ACCEPTED,
+ MSC_CTR_CM_RE_ESTABLISH_REQ_REJECTED,
+ MSC_CTR_CM_RE_ESTABLISH_REQ_ACCEPTED,
MSC_CTR_SMS_SUBMITTED,
MSC_CTR_SMS_NO_RECEIVER,
MSC_CTR_SMS_DELIVERED,
@@ -64,30 +71,33 @@ enum {
};
static const struct rate_ctr_desc msc_ctr_description[] = {
- [MSC_CTR_LOC_UPDATE_TYPE_ATTACH] = {"loc_update_type:attach", "Received location update imsi attach requests."},
- [MSC_CTR_LOC_UPDATE_TYPE_NORMAL] = {"loc_update_type:normal", "Received location update normal requests."},
- [MSC_CTR_LOC_UPDATE_TYPE_PERIODIC] = {"loc_update_type:periodic", "Received location update periodic requests."},
- [MSC_CTR_LOC_UPDATE_TYPE_DETACH] = {"loc_update_type:detach", "Received location update detach indication."},
- [MSC_CTR_LOC_UPDATE_FAILED] = {"loc_update_resp:failed", "Rejected location updates."},
- [MSC_CTR_LOC_UPDATE_COMPLETED] = {"loc_update_resp:completed", "Successful location updates."},
- [MSC_CTR_CM_SERVICE_REQUEST_REJECTED] = {"cm_service_request:rejected", "Rejected CM Service Request."},
- [MSC_CTR_CM_SERVICE_REQUEST_ACCEPTED] = {"cm_service_request:accepted", "Accepted CM Service Request."},
- [MSC_CTR_PAGING_RESP_REJECTED] = {"paging_resp:rejected", "Rejected Paging Response."},
- [MSC_CTR_PAGING_RESP_ACCEPTED] = {"paging_resp:accepted", "Accepted Paging Response."},
- [MSC_CTR_SMS_SUBMITTED] = {"sms:submitted", "Received a RPDU from a MS (MO)."},
- [MSC_CTR_SMS_NO_RECEIVER] = {"sms:no_receiver", "Counts SMS which couldn't routed because no receiver found."},
- [MSC_CTR_SMS_DELIVERED] = {"sms:delivered", "Global SMS Deliver attempts."},
- [MSC_CTR_SMS_RP_ERR_MEM] = {"sms:rp_err_mem", "CAUSE_MT_MEM_EXCEEDED errors of MS responses on a sms deliver attempt."},
- [MSC_CTR_SMS_RP_ERR_OTHER] = {"sms:rp_err_other", "Other error of MS responses on a sms delive attempt."},
- [MSC_CTR_SMS_DELIVER_UNKNOWN_ERROR] = {"sms:deliver_unknown_error", "Unknown error occured during sms delivery."},
- /* FIXME: count also sms delivered */
- [MSC_CTR_CALL_MO_SETUP] = {"call:mo_setup", "Received setup requests from a MS to init a MO call."},
- [MSC_CTR_CALL_MO_CONNECT_ACK] = {"call:mo_connect_ack", "Received a connect ack from MS of a MO call. Call is now succesful connected up."},
- [MSC_CTR_CALL_MT_SETUP] = {"call:mt_setup", "Sent setup requests to the MS (MT)."},
- [MSC_CTR_CALL_MT_CONNECT] = {"call:mt_connect", "Sent a connect to the MS (MT)."},
- [MSC_CTR_CALL_ACTIVE] = {"call:active", "Count total amount of calls that ever reached active state."},
- [MSC_CTR_CALL_COMPLETE] = {"call:complete", "Count total amount of calls which got terminated by disconnect req or ind after reaching active state."},
- [MSC_CTR_CALL_INCOMPLETE] = {"call:incomplete", "Count total amount of call which got terminated by any other reason after reaching active state."},
+ [MSC_CTR_LOC_UPDATE_TYPE_ATTACH] = {"loc_update_type:attach", "Received Location Update (IMSI Attach) requests."},
+ [MSC_CTR_LOC_UPDATE_TYPE_NORMAL] = {"loc_update_type:normal", "Received Location Update (LAC change) requests."},
+ [MSC_CTR_LOC_UPDATE_TYPE_PERIODIC] = {"loc_update_type:periodic", "Received (periodic) Location Update requests."},
+ [MSC_CTR_LOC_UPDATE_TYPE_DETACH] = {"loc_update_type:detach", "Received IMSI Detach indications."},
+ [MSC_CTR_LOC_UPDATE_FAILED] = {"loc_update_resp:failed", "Rejected Location Update requests."},
+ [MSC_CTR_LOC_UPDATE_COMPLETED] = {"loc_update_resp:completed", "Successful Location Update procedures."},
+ [MSC_CTR_CM_SERVICE_REQUEST_REJECTED] = {"cm_service_request:rejected", "Rejected CM Service Requests."},
+ [MSC_CTR_CM_SERVICE_REQUEST_ACCEPTED] = {"cm_service_request:accepted", "Accepted CM Service Requests."},
+ [MSC_CTR_PAGING_RESP_REJECTED] = {"paging_resp:rejected", "Rejected Paging Responses."},
+ [MSC_CTR_PAGING_RESP_ACCEPTED] = {"paging_resp:accepted", "Accepted Paging Responses."},
+ [MSC_CTR_CM_RE_ESTABLISH_REQ_REJECTED] = {"cm_re_establish_request:rejected", "Rejected CM Re-Establishing Requests."},
+ [MSC_CTR_CM_RE_ESTABLISH_REQ_ACCEPTED] = {"cm_re_establish_request:accepted", "Accepted CM Re-Establishing Requests."},
+ [MSC_CTR_SMS_SUBMITTED] = {"sms:submitted", "Total MO SMS received from the MS."},
+ [MSC_CTR_SMS_NO_RECEIVER] = {"sms:no_receiver", "Failed MO SMS delivery attempts (no receiver found)."},
+ [MSC_CTR_SMS_DELIVER_UNKNOWN_ERROR] = {"sms:deliver_unknown_error", "Failed MO SMS delivery attempts (other reason)."},
+ /* FIXME: "sms:delivered" should actually count number of _successfully_ delivered MT SMS.
+ * The current description reflects its current (errorneous) behaviour. */
+ [MSC_CTR_SMS_DELIVERED] = {"sms:delivered", "Total MT SMS delivery attempts."},
+ [MSC_CTR_SMS_RP_ERR_MEM] = {"sms:rp_err_mem", "Failed MT SMS delivery attempts (no memory)."},
+ [MSC_CTR_SMS_RP_ERR_OTHER] = {"sms:rp_err_other", "Failed MT SMS delivery attempts (other reason)."},
+ [MSC_CTR_CALL_MO_SETUP] = {"call:mo_setup", "Received MO SETUP messages (MO call establishment)."},
+ [MSC_CTR_CALL_MO_CONNECT_ACK] = {"call:mo_connect_ack", "Received MO CONNECT messages (MO call establishment)."},
+ [MSC_CTR_CALL_MT_SETUP] = {"call:mt_setup", "Sent MT SETUP messages (MT call establishment)."},
+ [MSC_CTR_CALL_MT_CONNECT] = {"call:mt_connect", "Sent MT CONNECT messages (MT call establishment)."},
+ [MSC_CTR_CALL_ACTIVE] = {"call:active", "Calls that ever reached the active state."},
+ [MSC_CTR_CALL_COMPLETE] = {"call:complete", "Calls terminated by DISCONNECT message after reaching the active state."},
+ [MSC_CTR_CALL_INCOMPLETE] = {"call:incomplete", "Calls terminated by any other reason after reaching the active state."},
[MSC_CTR_NC_SS_MO_REQUESTS] = {"nc_ss:mo_requests", "Received MS-initiated call independent SS/USSD requests."},
[MSC_CTR_NC_SS_MO_ESTABLISHED] = {"nc_ss:mo_established", "Established MS-initiated call independent SS/USSD sessions."},
[MSC_CTR_NC_SS_MT_REQUESTS] = {"nc_ss:mt_requests", "Received network-initiated call independent SS/USSD requests."},
@@ -96,6 +106,11 @@ static const struct rate_ctr_desc msc_ctr_description[] = {
[MSC_CTR_BSSMAP_CIPHER_MODE_COMPLETE] = {"bssmap:cipher_mode_complete", "Number of CIPHER MODE COMPLETE messages processed by BSSMAP layer"},
};
+enum {
+ MSC_STAT_ACTIVE_CALLS,
+ MSC_STAT_ACTIVE_NC_SS,
+};
+
static const struct rate_ctr_group_desc msc_ctrg_desc = {
"msc",
"mobile switching center",
@@ -104,6 +119,19 @@ static const struct rate_ctr_group_desc msc_ctrg_desc = {
msc_ctr_description,
};
+static const struct osmo_stat_item_desc msc_stat_item_description[] = {
+ [MSC_STAT_ACTIVE_CALLS] = { "msc.active_calls", "Currently active calls " , OSMO_STAT_ITEM_NO_UNIT, 4, 0},
+ [MSC_STAT_ACTIVE_NC_SS] = { "msc.active_nc_ss", "Currently active SS/USSD sessions", OSMO_STAT_ITEM_NO_UNIT, 4, 0},
+};
+
+static const struct osmo_stat_item_group_desc msc_statg_desc = {
+ "net",
+ "network statistics",
+ OSMO_STATS_CLASS_GLOBAL,
+ ARRAY_SIZE(msc_stat_item_description),
+ msc_stat_item_description,
+};
+
#define MSC_PAGING_RESPONSE_TIMER_DEFAULT 10
struct gsm_tz {
@@ -130,9 +158,11 @@ struct gsm_network {
bool authentication_required;
int send_mm_info;
+ /* bit-mask of permitted encryption algorithms. LSB=UEA0, MSB=UEA7 */
+ uint8_t uea_encryption_mask;
+
struct rate_ctr_group *msc_ctrs;
- struct osmo_counter *active_calls;
- struct osmo_counter *active_nc_ss;
+ struct osmo_stat_item_group *statg;
/* layer 4 */
char *mncc_sock_path;
@@ -147,8 +177,6 @@ struct gsm_network {
*/
struct llist_head trans_list;
- unsigned int paging_response_timer;
-
/* Radio Resource Location Protocol (TS 04.31) */
struct {
enum rrlp_mode mode;
@@ -181,9 +209,6 @@ struct gsm_network {
struct vlr_instance *vlr;
- /* Periodic location update default value */
- uint8_t t3212;
-
/* Global MNCC guard timer value */
int mncc_guard_timeout;
/* Global guard timer value for NCSS sessions */
@@ -191,8 +216,10 @@ struct gsm_network {
struct {
struct osmo_tdef *tdefs;
- struct mgcp_client_conf conf;
- struct mgcp_client *client;
+ struct mgcp_client_conf *conf;
+ /* MGW pool, also includes the single MGCP client as fallback if no
+ * pool is configured. */
+ struct mgcp_client_pool *mgw_pool;
} mgw;
struct {
@@ -210,10 +237,6 @@ struct gsm_network {
struct sccp_ran_inst *sri;
} a;
- /* A list of neighbor BSCs. This list is defined statically via VTY and does not
- * necessarily correspond to BSCs attached to the A interface at a given moment. */
- struct neighbor_ident_list *neighbor_list;
-
struct {
/* MSISDN to which to route MO emergency calls */
char *route_to_msisdn;
@@ -225,6 +248,8 @@ struct gsm_network {
* and will be of the form 'MSC-00-00-00-00-00-00' */
char *msc_ipa_name;
+ /* A list of neighbor BSCs. This list is defined statically via VTY and does not
+ * necessarily correspond to BSCs attached to the A interface at a given moment. */
struct llist_head neighbor_ident_list;
struct {
@@ -235,9 +260,24 @@ struct gsm_network {
/* Whether we want to use Osmux against BSCs. Controlled via VTY */
enum osmux_usage use_osmux;
+
+ /* Whether to use call waiting on the network */
+ bool call_waiting;
+
+ /* Whether to use lcls on the network */
+ bool lcls_permitted;
+
+ /* SMS queue config parameters */
+ struct sms_queue_config *sms_queue_cfg;
+
+ /* ASCI feature support */
+ struct {
+ bool enable;
+ struct llist_head gcr_lists;
+ } asci;
};
-struct osmo_esme;
+struct smpp_esme;
enum gsm_sms_source_id {
SMS_SOURCE_UNKNOWN = 0,
@@ -266,7 +306,7 @@ struct gsm_sms {
} gsm411;
struct {
- struct osmo_esme *esme;
+ struct smpp_esme *esme;
uint32_t sequence_nr;
int transaction_mode;
char msg_id[16];
diff --git a/include/osmocom/msc/gsup_client_mux.h b/include/osmocom/msc/gsup_client_mux.h
index 07f17c260..501b81dbe 100644
--- a/include/osmocom/msc/gsup_client_mux.h
+++ b/include/osmocom/msc/gsup_client_mux.h
@@ -28,6 +28,7 @@ int gsup_client_mux_start(struct gsup_client_mux *gcm, const char *gsup_server_a
struct ipaccess_unit *ipa_dev);
int gsup_client_mux_tx(struct gsup_client_mux *gcm, const struct osmo_gsup_message *gsup_msg);
+void gsup_client_mux_tx_set_source(const struct gsup_client_mux *gcm, struct osmo_gsup_message *gsup_msg);
void gsup_client_mux_tx_error_reply(struct gsup_client_mux *gcm, const struct osmo_gsup_message *gsup_orig,
enum gsm48_gmm_cause cause);
diff --git a/include/osmocom/msc/mncc.h b/include/osmocom/msc/mncc.h
index 28ee9b339..d258630c5 100644
--- a/include/osmocom/msc/mncc.h
+++ b/include/osmocom/msc/mncc.h
@@ -28,6 +28,7 @@
#include <osmocom/gsm/mncc.h>
#include <stdint.h>
+#include <netinet/in.h>
struct gsm_network;
struct msgb;
@@ -53,7 +54,7 @@ struct gsm_call {
#define MNCC_SETUP_CNF 0x0104
#define MNCC_SETUP_COMPL_REQ 0x0105
#define MNCC_SETUP_COMPL_IND 0x0106
-/* MNCC_REJ_* is perfomed via MNCC_REL_* */
+/* MNCC_REJ_* is performed via MNCC_REL_* */
#define MNCC_CALL_CONF_IND 0x0107
#define MNCC_CALL_PROC_REQ 0x0108
#define MNCC_PROGRESS_REQ 0x0109
@@ -123,6 +124,15 @@ struct gsm_call {
#define MNCC_F_CCCAP 0x0800
#define MNCC_F_KEYPAD 0x1000
#define MNCC_F_SIGNAL 0x2000
+#define MNCC_F_GCR 0x4000
+#define MNCC_F_HIGHL_COMPAT 0x8000
+#define MNCC_F_LOWL_COMPAT 0x10000
+
+/* UPDATEME when adding new MNCC_F_* entries above */
+#define MNCC_F_ALL 0x1ffff
+
+#define GSM_MAX_LOWL_COMPAT 16 /* (18 with TLV) */
+#define GSM_MAX_HIGHL_COMPAT 3 /* (5 with TLV) */
struct gsm_mncc {
/* context based information */
@@ -132,7 +142,7 @@ struct gsm_mncc {
/* which fields are present */
uint32_t fields;
- /* data derived informations (MNCC_F_ based) */
+ /* data derived information (MNCC_F_ based) */
struct gsm_mncc_bearer_cap bearer_cap;
struct gsm_mncc_number called;
struct gsm_mncc_number calling;
@@ -159,6 +169,26 @@ struct gsm_mncc {
unsigned char lchan_type;
unsigned char lchan_mode;
+
+ /* Global Call Reference (encoded as per 3GPP TS 29.205) */
+ uint8_t gcr[16];
+
+ /* A buffer to contain SDP ('\0' terminated) */
+ char sdp[1024];
+
+ /* Additional information that extends current socket interface version. */
+
+ /* The content requals of Low Layer compatibility IE, described in 3GPP TS 24.008 §10.5.4.18. */
+ struct gsm_mncc_lowl_compat {
+ uint8_t len;
+ uint8_t compat[GSM_MAX_LOWL_COMPAT];
+ } llc;
+
+ /* The content requals of High Layer compatibility IE, described in 3GPP TS 24.008 §10.5.4.16. */
+ struct gsm_mncc_highl_compat {
+ uint8_t len;
+ uint8_t compat[GSM_MAX_HIGHL_COMPAT];
+ } hlc;
};
struct gsm_data_frame {
@@ -167,7 +197,7 @@ struct gsm_data_frame {
unsigned char data[0];
};
-#define MNCC_SOCK_VERSION 5
+#define MNCC_SOCK_VERSION 8
struct gsm_mncc_hello {
uint32_t msg_type;
uint32_t version;
@@ -186,10 +216,10 @@ struct gsm_mncc_hello {
struct gsm_mncc_rtp {
uint32_t msg_type;
uint32_t callref;
- uint32_t ip;
- uint16_t port;
+ struct sockaddr_storage addr;
uint32_t payload_type;
uint32_t payload_msg_type;
+ char sdp[1024];
};
struct gsm_mncc_bridge {
@@ -208,7 +238,6 @@ union mncc_msg {
const char *get_mncc_name(int value);
void mncc_set_cause(struct gsm_mncc *data, int loc, int val);
-void cc_tx_to_mncc(struct gsm_network *net, struct msgb *msg);
/* input from CC code into mncc_builtin */
int int_mncc_recv(struct gsm_network *net, struct msgb *msg);
@@ -226,6 +255,7 @@ int mncc_sock_init(struct gsm_network *net, const char *sock_path);
|| msg_type == GSM_BAD_FRAME)
int mncc_prim_check(const struct gsm_mncc *mncc_prim, unsigned int len);
+int mncc_check_sdp_termination(const char *label, const struct gsm_mncc *mncc, unsigned int len, const char *sdp);
int mncc_bearer_cap_to_channel_type(struct gsm0808_channel_type *ct, const struct gsm_mncc_bearer_cap *bc);
diff --git a/include/osmocom/msc/mncc_call.h b/include/osmocom/msc/mncc_call.h
index ad0f0f841..084edd5e1 100644
--- a/include/osmocom/msc/mncc_call.h
+++ b/include/osmocom/msc/mncc_call.h
@@ -1,6 +1,6 @@
/* Handle an MNCC managed call (external MNCC). */
/*
- * (C) 2019 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de>
+ * (C) 2019 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
* All Rights Reserved
*
* SPDX-License-Identifier: AGPL-3.0+
@@ -22,6 +22,7 @@
*/
#pragma once
+#include <osmocom/mgcp_client/mgcp_client.h>
#include <osmocom/msc/mncc.h>
#include <osmocom/msc/mncc_call.h>
@@ -138,3 +139,5 @@ int mncc_call_tx_msgt(struct mncc_call *mncc_call, uint32_t msg_type);
struct mncc_call *mncc_call_find_by_callref(uint32_t callref);
void mncc_call_release(struct mncc_call *mncc_call);
+
+uint32_t mgcp_codec_to_mncc_payload_msg_type(enum mgcp_codecs codec);
diff --git a/include/osmocom/msc/msc_a.h b/include/osmocom/msc/msc_a.h
index c732695a1..4099d4cd2 100644
--- a/include/osmocom/msc/msc_a.h
+++ b/include/osmocom/msc/msc_a.h
@@ -1,6 +1,6 @@
/* MSC-A role: main subscriber management */
/*
- * (C) 2019 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de>
+ * (C) 2019 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
* All Rights Reserved
*
* SPDX-License-Identifier: AGPL-3.0+
@@ -37,14 +37,21 @@
#include <osmocom/msc/neighbor_ident.h>
struct ran_infra;
+struct vgcs_bss;
+struct vgcs_bss_cell;
#define MSC_A_USE_LOCATION_UPDATING "lu"
#define MSC_A_USE_CM_SERVICE_CC "cm_service_cc"
+#define MSC_A_USE_CM_SERVICE_GCC "cm_service_gcc"
+#define MSC_A_USE_CM_SERVICE_BCC "cm_service_bcc"
#define MSC_A_USE_CM_SERVICE_SMS "cm_service_sms"
#define MSC_A_USE_CM_SERVICE_SS "cm_service_ss"
#define MSC_A_USE_PAGING_RESPONSE "paging-response"
+#define MSC_A_USE_GCC "gcc"
+#define MSC_A_USE_BCC "bcc"
#define MSC_A_USE_CC "cc"
#define MSC_A_USE_SMS "sms"
+#define MSC_A_USE_SMS_MMTS "sms_mmts"
#define MSC_A_USE_NC_SS "nc_ss"
#define MSC_A_USE_SILENT_CALL "silent_call"
@@ -98,6 +105,9 @@ struct msc_a {
/* After Ciphering Mode Complete on GERAN, this reflects the chosen ciphering algorithm and key */
struct geran_encr geran_encr;
+ /* Type of MI requested in MM Identity Request */
+ uint8_t mm_id_req_type;
+
/* N(SD) expected in the received frame, per flow (TS 24.007 11.2.3.2.3.2.2) */
uint8_t n_sd_next[4];
@@ -117,6 +127,9 @@ struct msc_a {
* \-------RTP--> (ISUP) <--RTP--> <--RTP-->
*/
struct {
+ /* Codec List (BSS Supported) as received during Complete Layer 3 Information */
+ struct gsm0808_speech_codec_list compl_l3_codec_list_bss_supported;
+
/* All of the RTP stream handling */
struct call_leg *call_leg;
struct mncc_call *mncc_forwarding_to_remote_ran;
@@ -176,6 +189,8 @@ struct msc_a *msc_a_for_vsub(const struct vlr_subscr *vsub, bool valid_conn_only
void msc_a_pending_cm_service_req_add(struct msc_a *msc_a, enum osmo_cm_service_type type);
unsigned int msc_a_pending_cm_service_req_count(struct msc_a *msc_a, enum osmo_cm_service_type type);
void msc_a_pending_cm_service_req_del(struct msc_a *msc_a, enum osmo_cm_service_type type);
+bool msc_a_is_ciphering_to_be_attempted(const struct msc_a *msc_a);
+bool msc_a_is_ciphering_required(const struct msc_a *msc_a);
#define msc_a_ran_down(A,B,C) \
_msc_a_ran_down(A,B,C, __FILE__, __LINE__)
@@ -199,13 +214,18 @@ void msc_a_up_ciph_res(struct msc_a *msc_a, bool success, const char *imeisv);
bool msc_a_is_accepted(const struct msc_a *msc_a);
bool msc_a_is_establishing_auth_ciph(const struct msc_a *msc_a);
+int msc_a_ensure_cn_local_rtp(struct msc_a *msc_a, struct gsm_trans *cc_trans);
int msc_a_try_call_assignment(struct gsm_trans *cc_trans);
+void msc_a_tx_assignment_cmd(struct msc_a *msc_a);
-const char *msc_a_cm_service_type_to_use(enum osmo_cm_service_type cm_service_type);
+const char *msc_a_cm_service_type_to_use(struct msc_a *msc_a, enum osmo_cm_service_type cm_service_type);
void msc_a_release_cn(struct msc_a *msc_a);
void msc_a_release_mo(struct msc_a *msc_a, enum gsm48_gsm_cause gsm_cause);
+int msc_a_rx_vgcs_bss(struct vgcs_bss *bss, struct ran_conn *from_conn, struct msgb *msg);
+int msc_a_rx_vgcs_cell(struct vgcs_bss_cell *cell, struct ran_conn *from_conn, struct msgb *msg);
+
int msc_a_ran_decode_cb(struct osmo_fsm_inst *msc_a_fi, void *data, const struct ran_msg *msg);
int msc_a_vlr_set_cipher_mode(void *_msc_a, bool umts_aka, bool retrieve_imeisv);
diff --git a/include/osmocom/msc/msc_common.h b/include/osmocom/msc/msc_common.h
index 78337f764..f3fb0e07a 100644
--- a/include/osmocom/msc/msc_common.h
+++ b/include/osmocom/msc/msc_common.h
@@ -1,5 +1,7 @@
#pragma once
+#include <osmocom/core/tdef.h>
+
#include <osmocom/gsm/protocol/gsm_04_08.h>
#include <osmocom/gsm/gsm0808.h>
@@ -7,6 +9,9 @@ struct msgb;
struct gsm_network;
struct vlr_subscr;
+extern struct osmo_tdef_group msc_tdef_group[];
+extern struct osmo_tdef msc_tdefs_vlr[];
+
#define MSC_HLR_REMOTE_IP_DEFAULT "127.0.0.1"
#define MSC_HLR_REMOTE_PORT_DEFAULT OSMO_GSUP_PORT
@@ -27,6 +32,8 @@ struct geran_encr {
uint8_t alg_id;
uint8_t key_len;
uint8_t key[MAX_A5_KEY_LEN];
+ bool kc128_present;
+ uint8_t kc128[MAX_A5_KEY_LEN];
};
enum complete_layer3_type {
@@ -34,6 +41,7 @@ enum complete_layer3_type {
COMPLETE_LAYER3_LU,
COMPLETE_LAYER3_CM_SERVICE_REQ,
COMPLETE_LAYER3_PAGING_RESP,
+ COMPLETE_LAYER3_CM_RE_ESTABLISH_REQ,
};
extern const struct value_string complete_layer3_type_names[];
diff --git a/include/osmocom/msc/msc_ho.h b/include/osmocom/msc/msc_ho.h
index 99956f1e6..aedb622dc 100644
--- a/include/osmocom/msc/msc_ho.h
+++ b/include/osmocom/msc/msc_ho.h
@@ -1,6 +1,6 @@
/* MSC Handover API */
/*
- * (C) 2019 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de>
+ * (C) 2019 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
* All Rights Reserved
*
* SPDX-License-Identifier: AGPL-3.0+
@@ -31,7 +31,7 @@
#include <osmocom/msc/neighbor_ident.h>
#include <osmocom/msc/ran_msg.h>
#include <osmocom/msc/mncc_call.h>
-
+#include <osmocom/msc/sdp_msg.h>
struct gsm0808_handover_required;
@@ -81,7 +81,7 @@ struct msc_ho_state {
struct osmo_sockaddr_str ran_remote_rtp;
/* The codec from Handover Request Acknowledge. */
bool codec_present;
- enum mgcp_codecs codec;
+ struct gsm0808_speech_codec codec;
/* Inter-MSC voice forwarding via MNCC, to the remote MSC. The Prepare Handover Response sent us the
* Handover Number the remote MSC assigned. This is a call to that Handover Number, via PBX.
@@ -92,7 +92,7 @@ struct msc_ho_state {
struct {
/* Saved RTP IP:port and codec in case we need to roll back */
struct osmo_sockaddr_str ran_remote_rtp;
- enum mgcp_codecs codec;
+ struct sdp_audio_codecs codecs;
} old_cell;
};
diff --git a/include/osmocom/msc/msc_roles.h b/include/osmocom/msc/msc_roles.h
index b22bc7b85..495717576 100644
--- a/include/osmocom/msc/msc_roles.h
+++ b/include/osmocom/msc/msc_roles.h
@@ -236,7 +236,7 @@ enum msc_a_events {
MSC_A_EV_FROM_T_SEND_END_SIGNAL_REQUEST,
/* gsm_04_08.c has successfully received a valid Complete Layer 3 message, i.e. Location Updating, CM Service
- * Request, Paging Reponse or IMSI Detach. */
+ * Request, Paging Response or IMSI Detach. */
MSC_A_EV_COMPLETE_LAYER_3_OK,
/* Received a Classmark Update -- during GERAN ciphering, msc_a may have to wait for Classmark information to
diff --git a/include/osmocom/msc/msc_t.h b/include/osmocom/msc/msc_t.h
index 39b3abca0..876c11d5e 100644
--- a/include/osmocom/msc/msc_t.h
+++ b/include/osmocom/msc/msc_t.h
@@ -30,7 +30,7 @@ struct msc_t {
struct {
struct an_apdu ho_request;
struct gsm0808_cell_id cell_id_target;
- uint32_t callref;
+ uint32_t call_id;
char handover_number[16]; /* No libosmocore definition for MSISDN_MAXLEN? */
struct call_leg *call_leg;
struct mncc_call *mncc_forwarding_to_remote_cn;
diff --git a/include/osmocom/msc/msc_vgcs.h b/include/osmocom/msc/msc_vgcs.h
new file mode 100644
index 000000000..2b2f45d31
--- /dev/null
+++ b/include/osmocom/msc/msc_vgcs.h
@@ -0,0 +1,228 @@
+/* Handle a call via VGCS/VBCS (Voice Group/Broadcast Call Service). */
+/*
+ * (C) 2023 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
+ * All Rights Reserved
+ *
+ * SPDX-License-Identifier: AGPL-3.0+
+ *
+ * Author: Andreas Eversberg
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#pragma once
+
+#include <osmocom/msc/transaction.h>
+
+#define GSM44068_ALLOC_SIZE 2048
+#define GSM44068_ALLOC_HEADROOM 256
+
+static inline struct msgb *gsm44068_msgb_alloc_name(const char *name)
+{
+ return msgb_alloc_headroom(GSM44068_ALLOC_SIZE, GSM44068_ALLOC_HEADROOM, name);
+}
+
+/* VGCS/VBS "call control" connection to each BSS */
+struct vgcs_bss {
+ struct llist_head list; /* List entry */
+ struct llist_head cell_list; /* List of cells */
+ struct gsm_trans *trans; /* Back pointer to transaction */
+ struct osmo_fsm_inst *fi; /* State machine of each BSS */
+ struct ran_conn *conn; /* RAN ("SCCP") connection */
+ enum trans_type trans_type; /* Transaction type */
+ uint32_t callref; /* Callref */
+ int pc; /* Point code for debug purpose */
+};
+
+/* VGCS/VBS "resource control" connection to each cell in BSS */
+struct vgcs_bss_cell {
+ struct llist_head list_bss; /* List entry in vgcs_bss */
+ struct llist_head list_mgw; /* List entry in MGW endpoint */
+ struct vgcs_bss *bss; /* Back pointer to vgcs_bss */
+ struct vgcs_mgw_ep *mgw; /* Back pointer to vgcs_mgw_ep */
+ struct osmo_fsm_inst *fi; /* State machine of each cell */
+ int cell_id; /* Id of cell (BTS) to use */
+ struct ran_conn *conn; /* RAN ("SCCP") connection */
+ enum trans_type trans_type; /* Transaction type */
+ uint32_t callref; /* Callref */
+ int call_id; /* Id of call (used for MGW connections) */
+ int pc; /* Point code for debug purpose */
+ bool assigned; /* Flags if assignment is complete */
+ struct rtp_stream *rtps; /* MGW connection process */
+};
+
+/* VGCS/VBS MGW endpoint for each call */
+struct vgcs_mgw_ep {
+ struct llist_head cell_list; /* List of cells with connections */
+ struct llist_head list; /* List entry */
+ struct osmo_fsm_inst *fi; /* State machine of each cell */
+ struct osmo_mgcpc_ep *mgw_ep; /* MGW endpoint */
+};
+
+/* Events for the GCC/BCC state machine.
+ * There is no primitive definition like MNGCC-* oder MNBCC-* in the standard. */
+enum vgcs_gcc_fsm_event {
+ /* The network sets up a call. */
+ VGCS_GCC_EV_NET_SETUP,
+ /* The network requests termination. */
+ VGCS_GCC_EV_NET_TERM,
+ /* The user sets up a call. */
+ VGCS_GCC_EV_USER_SETUP,
+ /* The user requests termination. */
+ VGCS_GCC_EV_USER_TERM,
+ /* BSS completed call establishment (all BSCs) */
+ VGCS_GCC_EV_BSS_ESTABLISHED,
+ /* Assignment was completed. */
+ VGCS_GCC_EV_BSS_ASSIGN_CPL,
+ /* Assignment failed. */
+ VGCS_GCC_EV_BSS_ASSIGN_FAIL,
+ /* BSS released call establishment (all BSCs) */
+ VGCS_GCC_EV_BSS_RELEASED,
+ /* Inactivity timeout */
+ VGCS_GCC_EV_TIMEOUT,
+};
+
+/* 3GPP TS 44.068 6.1.2.2 States of GCC/BCC */
+enum vgcs_gcc_fsm_state {
+ /* No call. Initial state when instance is created. */
+ VGCS_GCC_ST_N0_NULL = 0,
+ /* An MS wants to establish a call. */
+ VGCS_GCC_ST_N1_CALL_INITIATED,
+ /* Call established in at least one cell. */
+ VGCS_GCC_ST_N2_CALL_ACTIVE,
+ /* Channel activation is requested, CONNECT already sent to MS. */
+ VGCS_GCC_ST_N3_CALL_EST_PROC,
+ /* Call termination is requested, waiting for all cells to confirm. */
+ VGCS_GCC_ST_N4_TERMINATION_REQ,
+};
+
+const char *vgcs_bcc_gcc_state_name(struct osmo_fsm_inst *fi);
+
+/* Events for the VGCS/VBS "call control" state machine */
+enum vgcs_bss_fsm_event {
+ /* Start a VGCS/VBS call using VGCS/VBS SETUP message */
+ VGCS_BSS_EV_SETUP,
+ /* VGCS/VBS SETUP ACK is received */
+ VGCS_BSS_EV_SETUP_ACK,
+ /* VGCS/VBS SETUP REFUSE is received */
+ VGCS_BSS_EV_SETUP_REFUSE,
+ /* VGCS/VBS ASSIGNMENT complete or failed */
+ VGCS_BSS_EV_ACTIVE_OR_FAIL,
+ /* Talker request */
+ VGCS_BSS_EV_UL_REQUEST,
+ /* Talker established uplink */
+ VGCS_BSS_EV_UL_REQUEST_CNF,
+ /* Talker send app data */
+ VGCS_BSS_EV_UL_APP_DATA,
+ /* Talker send signaling data */
+ VGCS_BSS_EV_BSS_DTAP,
+ /* Talker becomes listener */
+ VGCS_BSS_EV_UL_RELEASE,
+ /* Release channel towards BSS */
+ VGCS_BSS_EV_CLEAR,
+ /* Channel closed from BSS */
+ VGCS_BSS_EV_CLOSE,
+ /* Release is complete */
+ VGCS_BSS_EV_RELEASED,
+};
+
+/* States of the VGCS/VBS "call control" state machine */
+enum vgcs_bss_fsm_state {
+ /* No call. Initial state when instance is created. */
+ VGCS_BSS_ST_NULL = 0,
+ /* VGCS/VBS SETUP is sent towards BSC */
+ VGCS_BSS_ST_SETUP,
+ /* VGCS/VBS ASSIGNMENT REQUEST is sent towards BSC */
+ VGCS_BSS_ST_ASSIGNMENT,
+ /* VGCS/VBS is establised */
+ VGCS_BSS_ST_ACTIVE,
+ /* CLEAR COMMAND was sent */
+ VGCS_BSS_ST_RELEASE,
+};
+
+/* Events for the VGCS/VBS "resource control" state machine */
+enum vgcs_cell_fsm_event {
+ /* RTP stream gone */
+ VGCS_CELL_EV_RTP_STREAM_GONE,
+ /* RTP stream remote addr available */
+ VGCS_CELL_EV_RTP_STREAM_ADDR_AVAILABLE,
+ /* RTP stream established */
+ VGCS_CELL_EV_RTP_STREAM_ESTABLISHED,
+ /* Start a VGCS/VBS channel using VGCS/VBS ASSIGNMENT message */
+ VGCS_CELL_EV_ASSIGN,
+ /* VGCS/VBS ASSIGNMENT RESULT is received */
+ VGCS_CELL_EV_ASSIGN_RES,
+ /* VGCS/VBS ASSIGNMENT FAILURE is received */
+ VGCS_CELL_EV_ASSIGN_FAIL,
+ /* Release channel towards BSS */
+ VGCS_CELL_EV_CLEAR,
+ /* Channel closed from BSS */
+ VGCS_CELL_EV_CLOSE,
+ /* Release is complete */
+ VGCS_CELL_EV_RELEASED,
+};
+
+/* States of the VGCS/VBS "resource control" state machine */
+enum vgcs_cell_fsm_state {
+ /* No call. Initial state when instance is created. */
+ VGCS_CELL_ST_NULL = 0,
+ /* VGCS/VBS ASSIGNMENT REQUEST is sent towards BSC */
+ VGCS_CELL_ST_ASSIGNMENT,
+ /* Channel is establised */
+ VGCS_CELL_ST_ACTIVE,
+ /* CLEAR COMMAND was sent */
+ VGCS_CELL_ST_RELEASE,
+};
+
+/* Events for the VGCS/VBS MGW endpoint state machine */
+enum vgcs_mgw_ep_fsm_event {
+ /* MGW endpoint gone */
+ VGCS_MGW_EP_EV_FREE,
+ /* Destroy MGW endpoint */
+ VGCS_MGW_EP_EV_CLEAR,
+};
+
+/* States of the VGCS/VBS MGW endpoint state machine */
+enum vgcs_mgw_ep_fsm_state {
+ VGCS_MGW_EP_ST_NULL = 0,
+ /* MGW endpoint allocated */
+ VGCS_MGW_EP_ST_ACTIVE,
+};
+
+const char *gsm44068_group_id_string(uint32_t callref);
+
+struct gcr;
+
+int gsm44068_rcv_rr(struct msc_a *msc_a, struct msgb *msg);
+int gsm44068_rcv_bcc_gcc(struct msc_a *msc_a, struct gsm_trans *trans, struct msgb *msg);
+const char *vgcs_vty_initiate(struct gsm_network *gsmnet, struct gcr *gcr);
+const char *vgcs_vty_terminate(struct gsm_network *gsmnet, struct gcr *gcr);
+void gsm44068_bcc_gcc_trans_free(struct gsm_trans *trans);
+
+void vgcs_vbs_setup_ack(struct vgcs_bss *bss, const struct ran_msg *ran_msg);
+void vgcs_vbs_setup_refuse(struct vgcs_bss *bss, const struct ran_msg *ran_msg);
+void vgcs_vbs_assign_result(struct vgcs_bss_cell *cell, const struct ran_msg *ran_msg);
+void vgcs_vbs_assign_fail(struct vgcs_bss_cell *cell, const struct ran_msg *ran_msg);
+void vgcs_vbs_queuing_ind(struct vgcs_bss_cell *cell);
+void vgcs_uplink_request(struct vgcs_bss *bss, const struct ran_msg *ran_msg);
+void vgcs_uplink_request_cnf(struct vgcs_bss *bss, const struct ran_msg *ran_msg);
+void vgcs_app_data(struct vgcs_bss *bss, const struct ran_msg *ran_msg);
+void vgcs_bss_dtap(struct vgcs_bss *bss, const struct ran_msg *ran_msg);
+void vgcs_uplink_release_ind(struct vgcs_bss *bss, const struct ran_msg *ran_msg);
+void vgcs_vbs_assign_status(struct vgcs_bss_cell *cell, const struct ran_msg *ran_msg);
+void vgcs_vbs_clear_req_channel(struct vgcs_bss_cell *cell, const struct ran_msg *ran_msg);
+void vgcs_vbs_clear_cpl_channel(struct vgcs_bss_cell *cell, const struct ran_msg *ran_msg);
+void vgcs_vbs_clear_req(struct vgcs_bss *bss, const struct ran_msg *ran_msg);
+void vgcs_vbs_clear_cpl(struct vgcs_bss *bss, const struct ran_msg *ran_msg);
+void vgcs_vbs_caller_assign_cpl(struct gsm_trans *trans);
+void vgcs_vbs_caller_assign_fail(struct gsm_trans *trans);
diff --git a/include/osmocom/msc/msub.h b/include/osmocom/msc/msub.h
index 2418febcf..14f3e76ce 100644
--- a/include/osmocom/msc/msub.h
+++ b/include/osmocom/msc/msub.h
@@ -1,5 +1,7 @@
#pragma once
+#include <osmocom/gsm/gsm48.h>
+
#include <osmocom/msc/debug.h>
#include <osmocom/msc/msc_roles.h>
@@ -64,7 +66,7 @@ int _msub_role_dispatch(struct msub *msub, enum msc_role to_role, uint32_t to_ro
const char *file, int line);
int msub_tx_an_apdu(struct msub *msub, enum msc_role from_role, enum msc_role to_role, struct an_apdu *an_apdu);
-void msub_update_id_from_mi(struct msub *msub, const uint8_t mi[], uint8_t mi_len);
+void msub_update_id_from_mi(struct msub *msub, const struct osmo_mobile_identity *mi);
void msub_update_id(struct msub *msub);
void msub_update_id_for_vsub(struct vlr_subscr *for_vsub);
diff --git a/include/osmocom/msc/paging.h b/include/osmocom/msc/paging.h
index 4de679df7..f8ebf9e3b 100644
--- a/include/osmocom/msc/paging.h
+++ b/include/osmocom/msc/paging.h
@@ -40,6 +40,7 @@ struct paging_request {
struct paging_request *paging_request_start(struct vlr_subscr *vsub, enum paging_cause cause,
paging_cb_t paging_cb, struct gsm_trans *trans,
const char *label);
+void paging_request_join_vsub(struct vlr_subscr *keep_vsub, struct vlr_subscr *discarding_vsub);
void paging_request_remove(struct paging_request *pr);
void paging_response(struct msc_a *msc_a);
diff --git a/include/osmocom/msc/ran_conn.h b/include/osmocom/msc/ran_conn.h
index 7aa50df07..cdaa02652 100644
--- a/include/osmocom/msc/ran_conn.h
+++ b/include/osmocom/msc/ran_conn.h
@@ -18,9 +18,17 @@ struct ran_conn {
uint32_t sccp_conn_id;
/* MSC role that this RAN connection belongs to. This will be either an msc_i (currently active
- * connection) or an msc_t (transitory new connection during Handover). */
+ * connection) or an msc_t (transitory new connection during Handover).
+ * Used for usual L3 ran_conn to a subscriber. */
struct osmo_fsm_inst *msc_role;
+ /* For VGCS/VBS, we have additional N connections to BSS. When receiving messages for a group call peer,
+ * dispatch to the VGCS management. */
+ struct {
+ void *bss;
+ void *cell;
+ } vgcs;
+
bool closing;
};
diff --git a/include/osmocom/msc/ran_infra.h b/include/osmocom/msc/ran_infra.h
index 38c424f09..262a9c82e 100644
--- a/include/osmocom/msc/ran_infra.h
+++ b/include/osmocom/msc/ran_infra.h
@@ -4,6 +4,7 @@
#include <osmocom/gsm/gsup.h>
#include <osmocom/msc/sccp_ran.h>
#include <osmocom/msc/ran_msg.h>
+#include <osmocom/msc/sdp_msg.h>
struct osmo_tdef;
@@ -25,6 +26,10 @@ struct ran_infra {
const ran_dec_l2_t ran_dec_l2;
const ran_encode_t ran_encode;
struct sccp_ran_inst *sri;
+ /* To always set up the MGW endpoint facing the RAN side with specific codecs, list those here. Otherwise leave
+ * empty (to use the result of codecs filtering). This exists for IuCS, to always set the MGW endpoint facing
+ * RAN to IUFP, to decapsulate the IuUP headers. */
+ struct sdp_audio_codecs force_mgw_codecs_to_ran;
};
extern struct ran_infra msc_ran_infra[];
diff --git a/include/osmocom/msc/ran_msg.h b/include/osmocom/msc/ran_msg.h
index 4d0485d43..dc1483cb5 100644
--- a/include/osmocom/msc/ran_msg.h
+++ b/include/osmocom/msc/ran_msg.h
@@ -69,6 +69,26 @@ enum ran_msg_type {
RAN_MSG_HANDOVER_SUCCEEDED,
RAN_MSG_HANDOVER_COMPLETE,
RAN_MSG_HANDOVER_FAILURE,
+ RAN_MSG_VGCS_VBS_SETUP,
+ RAN_MSG_VGCS_VBS_SETUP_ACK,
+ RAN_MSG_VGCS_VBS_SETUP_REFUSE,
+ RAN_MSG_VGCS_VBS_ASSIGN_REQ,
+ RAN_MSG_VGCS_VBS_ASSIGN_RES,
+ RAN_MSG_VGCS_VBS_ASSIGN_FAIL,
+ RAN_MSG_VGCS_VBS_QUEUING_IND,
+ RAN_MSG_UPLINK_REQUEST,
+ RAN_MSG_UPLINK_REQUEST_ACK,
+ RAN_MSG_UPLINK_REQUEST_CNF,
+ RAN_MSG_UPLINK_APPLICATION_DATA,
+ RAN_MSG_UPLINK_RELEASE_IND,
+ RAN_MSG_UPLINK_REJECT_CMD,
+ RAN_MSG_UPLINK_RELEASE_CMD,
+ RAN_MSG_UPLINK_SEIZED_CMD,
+ RAN_MSG_VGCS_ADDITIONAL_INFO,
+ RAN_MSG_VGCS_VBS_AREA_CELL_INFO,
+ RAN_MSG_VGCS_VBS_ASSIGN_STATUS,
+ RAN_MSG_VGCS_SMS,
+ RAN_MSG_NOTIFICATION_DATA,
};
extern const struct value_string ran_msg_type_names[];
@@ -84,6 +104,13 @@ struct ran_assignment_command {
const struct osmo_sockaddr_str *cn_rtp;
const struct gsm0808_channel_type *channel_type;
enum nsap_addr_enc rab_assign_addr_enc;
+ bool osmux_present;
+ uint8_t osmux_cid;
+ bool call_id_present;
+ uint32_t call_id;
+ struct osmo_lcls *lcls;
+ bool callref_present;
+ struct gsm0808_group_callref callref;
};
struct ran_cipher_mode_command {
@@ -97,6 +124,9 @@ struct ran_cipher_mode_command {
/* out-argument to return the key to the caller, pass NULL if not needed. */
struct geran_encr *chosen_key;
} geran;
+ struct {
+ uint8_t uea_encryption_mask;
+ } utran;
};
struct ran_handover_request {
@@ -154,7 +184,8 @@ struct ran_handover_request_ack {
struct osmo_sockaddr_str remote_rtp;
bool codec_present;
- enum mgcp_codecs codec;
+ struct gsm0808_speech_codec codec;
+ bool codec_with_iuup;
};
struct ran_handover_command {
@@ -190,6 +221,7 @@ struct ran_msg {
union {
struct {
const struct gsm0808_cell_id *cell_id;
+ const struct gsm0808_speech_codec_list *codec_list_bss_supported;
struct msgb *msg;
} compl_l3;
struct msgb *dtap;
@@ -207,13 +239,22 @@ struct ran_msg {
* alg_id == 1 means A5/0 i.e. no encryption, alg_id == 4 means A5/3.
* alg_id == 0 means no such IE was present. */
uint8_t alg_id;
+ /*! utran integrity protection. 0..15 */
+ int16_t utran_integrity;
+ /*! utran_integrity is in encoded format:
+ * utran_integrity == -1 means no such IE was present
+ * utran_integrity == 0 means no encryption. */
+ int16_t utran_encryption;
const char *imeisv;
+ const struct tlv_p_entry *l3_msg;
} cipher_mode_complete;
struct {
enum gsm0808_cause bssap_cause;
} cipher_mode_reject;
struct {
const char *imsi;
+ bool last_eutran_plmn_present;
+ struct osmo_plmn_id last_eutran_plmn;
} common_id;
struct {
enum gsm48_reject_value cause;
@@ -222,7 +263,11 @@ struct ran_msg {
struct {
struct osmo_sockaddr_str remote_rtp;
bool codec_present;
- enum mgcp_codecs codec;
+ struct gsm0808_speech_codec codec;
+ bool codec_with_iuup;
+ const struct gsm0808_speech_codec_list *codec_list_bss_supported;
+ bool osmux_present;
+ uint8_t osmux_cid;
} assignment_complete;
struct {
enum gsm0808_cause bssap_cause;
@@ -247,6 +292,33 @@ struct ran_msg {
} handover_failure;
struct ran_handover_request handover_request;
struct ran_handover_request_ack handover_request_ack;
+ struct gsm0808_vgcs_vbs_setup vgcs_vbs_setup;
+ struct gsm0808_vgcs_vbs_setup_ack vgcs_vbs_setup_ack;
+ struct {
+ enum gsm0808_cause cause;
+ } vgcs_vbs_setup_refuse;
+ struct gsm0808_vgcs_vbs_assign_req vgcs_vbs_assign_req;
+ struct gsm0808_vgcs_vbs_assign_res vgcs_vbs_assign_res;
+ struct gsm0808_vgcs_vbs_assign_fail vgcs_vbs_assign_fail;
+ struct gsm0808_uplink_request uplink_request;
+ struct gsm0808_uplink_request_ack uplink_request_ack;
+ struct gsm0808_uplink_request_cnf uplink_request_cnf;
+ struct gsm0808_uplink_app_data uplink_app_data;
+ struct gsm0808_uplink_release_ind uplink_release_ind;
+ struct gsm0808_uplink_seized_cmd uplink_seized_cmd;
+ struct gsm0808_uplink_reject_cmd uplink_reject_cmd;
+ struct {
+ enum gsm0808_cause cause;
+ } uplink_release_cmd;
+ struct {
+ struct gsm0808_talker_identity talker_identity;
+ } vgcs_additional_info;
+ struct gsm0808_vgcs_vbs_area_cell_info vgcs_vbs_area_cell_info;
+ struct gsm0808_vgcs_vbs_assign_stat vgcs_vbs_assign_stat;
+ struct {
+ struct gsm0808_sms_to_vgcs sms_to_vgcs;
+ } vgcs_sms;
+ struct gsm0808_notification_data notification_data;
};
};
diff --git a/include/osmocom/msc/ran_msg_a.h b/include/osmocom/msc/ran_msg_a.h
index 3ba081de2..2d045b96e 100644
--- a/include/osmocom/msc/ran_msg_a.h
+++ b/include/osmocom/msc/ran_msg_a.h
@@ -35,7 +35,8 @@ struct gsm_mncc_bearer_cap;
int ran_a_decode_l2(struct ran_dec *ran_a, struct msgb *bssap);
struct msgb *ran_a_encode(struct osmo_fsm_inst *caller_fi, const struct ran_msg *ran_enc_msg);
-enum reset_msg_type bssmap_is_reset_msg(const struct sccp_ran_inst *sri, const struct msgb *l2);
+enum reset_msg_type bssmap_is_reset_msg(const struct sccp_ran_inst *sri, struct osmo_fsm_inst *log_fi,
+ struct msgb *l2, int *supports_osmux);
struct msgb *bssmap_make_reset_msg(const struct sccp_ran_inst *sri, enum reset_msg_type type);
struct msgb *bssmap_make_paging_msg(const struct sccp_ran_inst *sri, const struct gsm0808_cell_id *page_cell_id,
const char *imsi, uint32_t tmsi, enum paging_cause cause);
diff --git a/include/osmocom/msc/ran_msg_iu.h b/include/osmocom/msc/ran_msg_iu.h
index 316a91cdb..3f3d61e4a 100644
--- a/include/osmocom/msc/ran_msg_iu.h
+++ b/include/osmocom/msc/ran_msg_iu.h
@@ -28,7 +28,8 @@
int ran_iu_decode_l2(struct ran_dec *ran_dec_iu, struct msgb *ranap);
struct msgb *ran_iu_encode(struct osmo_fsm_inst *caller_fi, const struct ran_msg *ran_enc_msg);
-enum reset_msg_type ranap_is_reset_msg(const struct sccp_ran_inst *sri, const struct msgb *l2);
+enum reset_msg_type ranap_is_reset_msg(const struct sccp_ran_inst *sri, struct osmo_fsm_inst *log_fi,
+ struct msgb *l2, int *supports_osmux);
struct msgb *ranap_make_reset_msg(const struct sccp_ran_inst *sri, enum reset_msg_type type);
struct msgb *ranap_make_paging_msg(const struct sccp_ran_inst *sri, const struct gsm0808_cell_id *page_cell_id,
const char *imsi, uint32_t tmsi, enum paging_cause cause);
diff --git a/include/osmocom/msc/ran_peer.h b/include/osmocom/msc/ran_peer.h
index 06ab50090..c936d5c5d 100644
--- a/include/osmocom/msc/ran_peer.h
+++ b/include/osmocom/msc/ran_peer.h
@@ -42,7 +42,7 @@ struct neighbor_ident_entry;
* list is kept in sccp_ran_inst. For convenience, see ran_peer_for_each_ran_conn().
*/
struct ran_peer {
- /* Entry in sccp_ran_inst->ran_conns */
+ /* Entry in sccp_ran_inst->ran_peers */
struct llist_head entry;
struct sccp_ran_inst *sri;
@@ -91,7 +91,7 @@ struct ran_peer_ev_ctx {
};
struct ran_peer *ran_peer_find_or_create(struct sccp_ran_inst *sri, const struct osmo_sccp_addr *peer_addr);
-struct ran_peer *ran_peer_find(struct sccp_ran_inst *sri, const struct osmo_sccp_addr *peer_addr);
+struct ran_peer *ran_peer_find_by_addr(struct sccp_ran_inst *sri, const struct osmo_sccp_addr *peer_addr);
void ran_peer_cells_seen_add(struct ran_peer *ran_peer, const struct gsm0808_cell_id *id);
@@ -106,4 +106,3 @@ int ran_peer_down_paging(struct ran_peer *rp, const struct gsm0808_cell_id *page
struct ran_peer *ran_peer_find_by_cell_id(struct sccp_ran_inst *sri, const struct gsm0808_cell_id *cid,
bool expecting_single_match);
-struct ran_peer *ran_peer_find_by_addr(struct sccp_ran_inst *sri, const struct osmo_sccp_addr *addr);
diff --git a/include/osmocom/msc/rtp_stream.h b/include/osmocom/msc/rtp_stream.h
index 794e8066f..5bc01440f 100644
--- a/include/osmocom/msc/rtp_stream.h
+++ b/include/osmocom/msc/rtp_stream.h
@@ -5,6 +5,7 @@
#include <osmocom/core/sockaddr_str.h>
#include <osmocom/mgcp_client/mgcp_client.h>
+#include <osmocom/msc/sdp_msg.h>
struct gsm_trans;
@@ -25,7 +26,8 @@ static inline const char *rtp_direction_name(enum rtp_direction val)
/* A single bidirectional RTP hop between remote and MGW's local RTP port. */
struct rtp_stream {
struct osmo_fsm_inst *fi;
- struct call_leg *parent_call_leg;
+ uint32_t event_avail;
+ uint32_t event_estab;
enum rtp_direction dir;
uint32_t call_id;
@@ -37,26 +39,42 @@ struct rtp_stream {
struct osmo_sockaddr_str remote;
bool remote_sent_to_mgw;
- bool codec_known;
- enum mgcp_codecs codec;
- bool codec_sent_to_mgw;
+ bool codecs_known;
+ struct sdp_audio_codecs codecs;
+ bool codecs_sent_to_mgw;
struct osmo_mgcpc_ep_ci *ci;
enum mgcp_connection_mode crcx_conn_mode;
+ bool mode_sent_to_mgw;
+
+ /* configured to use Osmux */
+ bool use_osmux;
+ /* Allocated by our MGW, negative means invalid, not yet known */
+ int local_osmux_cid;
+ /* Allocated by BSC MGW, negative means invalid, not yet known */
+ int remote_osmux_cid;
+ /* Whether remote_osmux_cid has been communicated to MGW */
+ bool remote_osmux_cid_sent_to_mgw;
};
#define RTP_STREAM_FMT "local=" RTP_IP_PORT_FMT ",remote=" RTP_IP_PORT_FMT
#define RTP_STREAM_ARGS(RS) RTP_IP_PORT_ARGS(&(RS)->local), RTP_IP_PORT_ARGS(&(RS)->remote),
-struct rtp_stream *rtp_stream_alloc(struct call_leg *parent_call_leg, enum rtp_direction dir,
- uint32_t call_id, struct gsm_trans *for_trans);
+struct rtp_stream *rtp_stream_alloc(struct osmo_fsm_inst *parent_fi, uint32_t event_gone, uint32_t event_avail,
+ uint32_t event_estab, enum rtp_direction dir, uint32_t call_id,
+ struct gsm_trans *for_trans);
int rtp_stream_ensure_ci(struct rtp_stream *rtps, struct osmo_mgcpc_ep *at_endpoint);
int rtp_stream_do_mdcx(struct rtp_stream *rtps);
-void rtp_stream_set_codec(struct rtp_stream *rtps, enum mgcp_codecs codec);
+bool rtp_stream_set_codecs_from_mgcp_codec(struct rtp_stream *rtps, enum mgcp_codecs codec);
+void rtp_stream_set_one_codec(struct rtp_stream *rtps, const struct sdp_audio_codec *codec);
+void rtp_stream_set_codecs(struct rtp_stream *rtps, const struct sdp_audio_codecs *codecs);
+void rtp_stream_set_mode(struct rtp_stream *rtps, enum mgcp_connection_mode mode);
void rtp_stream_set_remote_addr(struct rtp_stream *rtps, const struct osmo_sockaddr_str *r);
+void rtp_stream_set_remote_addr_and_codecs(struct rtp_stream *rtps, const struct sdp_msg *sdp);
+void rtp_stream_set_remote_osmux_cid(struct rtp_stream *rtps, uint8_t osmux_cid);
int rtp_stream_commit(struct rtp_stream *rtps);
void rtp_stream_release(struct rtp_stream *rtps);
diff --git a/include/osmocom/msc/sccp_ran.h b/include/osmocom/msc/sccp_ran.h
index f190d91e3..a4bd4ca61 100644
--- a/include/osmocom/msc/sccp_ran.h
+++ b/include/osmocom/msc/sccp_ran.h
@@ -189,14 +189,14 @@ struct sccp_ran_inst;
#define LOG_SCCP_RAN_CO(sri, peer_addr, conn_id, level, fmt, args...) \
LOGP((sri) && (sri)->ran? (sri)->ran->log_subsys : DMSC, level, "(%s-%u%s%s) " fmt, \
- osmo_rat_type_name((sri) && (sri)->ran? (sri)->ran->type : -1), conn_id, \
+ osmo_rat_type_name((sri) && (sri)->ran ? (sri)->ran->type : OSMO_RAT_UNKNOWN), conn_id, \
peer_addr ? " from " : "", \
peer_addr ? osmo_sccp_inst_addr_name((sri)->sccp, peer_addr) : "", \
## args)
#define LOG_SCCP_RAN_CL_CAT(sri, peer_addr, subsys, level, fmt, args...) \
LOGP(subsys, level, "(%s%s%s) " fmt, \
- osmo_rat_type_name((sri) && (sri)->ran? (sri)->ran->type : -1), \
+ osmo_rat_type_name((sri) && (sri)->ran ? (sri)->ran->type : OSMO_RAT_UNKNOWN), \
peer_addr ? " from " : "", \
peer_addr ? osmo_sccp_inst_addr_name((sri)->sccp, peer_addr) : "", \
## args)
@@ -233,8 +233,11 @@ struct sccp_ran_ops {
/* Return whether the given l2_cl message is a RESET, RESET ACKNOWLEDGE, or RESET-unrelated message.
* This callback is stored in struct sccp_ran_inst to provide RESET handling to the caller (ran_peer),
- * it is not used in sccp_ran.c. */
- enum reset_msg_type (* is_reset_msg )(const struct sccp_ran_inst *sri, const struct msgb *l2_cl);
+ * it is not used in sccp_ran.c.
+ * In supports_osmux, return 0 for no information, 1 for support detected, -1 for non-support detected.
+ */
+ enum reset_msg_type (* is_reset_msg )(const struct sccp_ran_inst *sri, struct osmo_fsm_inst *log_fi,
+ struct msgb *l2_cl, int *supports_osmux);
/* Return a RESET or RESET ACK message for this RAN type.
* This callback is stored in struct sccp_ran_inst to provide RESET handling to the caller (ran_peer),
diff --git a/include/osmocom/msc/sdp_msg.h b/include/osmocom/msc/sdp_msg.h
new file mode 100644
index 000000000..e3879f6af
--- /dev/null
+++ b/include/osmocom/msc/sdp_msg.h
@@ -0,0 +1,87 @@
+/* Minimalistic SDP parse/compose API, focused on GSM audio codecs */
+#pragma once
+
+#include <osmocom/core/utils.h>
+#include <osmocom/core/sockaddr_str.h>
+
+#include <osmocom/msc/csd_bs.h>
+
+extern const struct value_string sdp_msg_payload_type_names[];
+static inline const char *sdp_msg_payload_type_name(unsigned int payload_type)
+{ return get_value_string(sdp_msg_payload_type_names, payload_type); }
+int sdp_subtype_name_to_payload_type(const char *subtype_name);
+
+enum sdp_mode_e {
+ SDP_MODE_UNSET = 0,
+ SDP_MODE_SENDONLY = 1,
+ SDP_MODE_RECVONLY = 2,
+ SDP_MODE_SENDRECV = 3,
+ SDP_MODE_INACTIVE = 4,
+};
+
+struct sdp_audio_codec {
+ /* Payload type number, like 3 for GSM-FR. */
+ unsigned int payload_type;
+ /* Like "GSM", "AMR", "EFR", ... */
+ char subtype_name[16];
+ unsigned int rate;
+ char fmtp[256];
+};
+
+struct sdp_audio_codecs {
+ unsigned int count;
+ struct sdp_audio_codec codec[16];
+};
+
+struct sdp_msg {
+ struct osmo_sockaddr_str rtp;
+ unsigned int ptime;
+ enum sdp_mode_e mode;
+ struct sdp_audio_codecs audio_codecs;
+ struct csd_bs_list bearer_services;
+};
+
+#define sdp_audio_codecs_foreach(/* struct sdp_audio_codec* */ CODEC, \
+ /* struct sdp_audio_codecs* */ AC) \
+ for (CODEC = (AC)->codec; \
+ (CODEC - (AC)->codec) < OSMO_MIN((AC)->count, ARRAY_SIZE((AC)->codec)); \
+ CODEC++)
+
+const char *sdp_msg_line_end(const char *src);
+
+bool sdp_audio_codec_is_set(const struct sdp_audio_codec *a);
+int sdp_audio_codec_cmp(const struct sdp_audio_codec *a, const struct sdp_audio_codec *b,
+ bool cmp_fmtp, bool cmp_payload_type);
+int sdp_audio_codecs_cmp(const struct sdp_audio_codecs *a, const struct sdp_audio_codecs *b,
+ bool cmp_fmtp, bool cmp_payload_type);
+
+struct sdp_audio_codec *sdp_audio_codecs_add(struct sdp_audio_codecs *ac, unsigned int payload_type,
+ const char *subtype_name, unsigned int rate, const char *fmtp);
+struct sdp_audio_codec *sdp_audio_codecs_add_copy(struct sdp_audio_codecs *ac,
+ const struct sdp_audio_codec *codec);
+int sdp_audio_codecs_remove(struct sdp_audio_codecs *ac, const struct sdp_audio_codec *codec);
+struct sdp_audio_codec *sdp_audio_codecs_by_payload_type(struct sdp_audio_codecs *ac,
+ unsigned int payload_type, bool create);
+struct sdp_audio_codec *sdp_audio_codecs_by_descr(struct sdp_audio_codecs *ac,
+ const struct sdp_audio_codec *codec);
+
+void sdp_audio_codecs_intersection(struct sdp_audio_codecs *ac_dest, const struct sdp_audio_codecs *ac_other,
+ bool translate_payload_type_numbers);
+void sdp_audio_codecs_select(struct sdp_audio_codecs *ac, struct sdp_audio_codec *codec);
+
+int sdp_msg_to_sdp_str_buf(char *dst, size_t dst_size, const struct sdp_msg *sdp);
+int sdp_msg_from_sdp_str(struct sdp_msg *sdp, const char *src);
+
+int sdp_audio_codec_to_str_buf(char *buf, size_t buflen, const struct sdp_audio_codec *codec);
+char *sdp_audio_codec_to_str_c(void *ctx, const struct sdp_audio_codec *codec);
+const char *sdp_audio_codec_to_str(const struct sdp_audio_codec *codec);
+
+int sdp_audio_codecs_to_str_buf(char *buf, size_t buflen, const struct sdp_audio_codecs *ac);
+char *sdp_audio_codecs_to_str_c(void *ctx, const struct sdp_audio_codecs *ac);
+const char *sdp_audio_codecs_to_str(const struct sdp_audio_codecs *ac);
+
+int sdp_msg_to_str_buf(char *buf, size_t buflen, const struct sdp_msg *sdp);
+char *sdp_msg_to_str_c(void *ctx, const struct sdp_msg *sdp);
+const char *sdp_msg_to_str(const struct sdp_msg *sdp);
+
+void sdp_audio_codecs_set_csd(struct sdp_audio_codecs *ac);
diff --git a/include/osmocom/msc/sgs_iface.h b/include/osmocom/msc/sgs_iface.h
index 575468e10..a31966370 100644
--- a/include/osmocom/msc/sgs_iface.h
+++ b/include/osmocom/msc/sgs_iface.h
@@ -89,4 +89,5 @@ enum sgsap_service_ind sgs_serv_ind_from_paging_cause(enum paging_cause);
int sgs_iface_tx_paging(struct vlr_subscr *vsub, enum sgsap_service_ind serv_ind);
int sgs_iface_tx_dtap_ud(struct msc_a *msc_a, struct msgb *msg);
void sgs_iface_tx_release(struct vlr_subscr *vsub);
+void sgs_iface_tx_serv_abrt(struct vlr_subscr *vsub);
diff --git a/include/osmocom/msc/sgs_server.h b/include/osmocom/msc/sgs_server.h
index a89022d9e..400bd9e80 100644
--- a/include/osmocom/msc/sgs_server.h
+++ b/include/osmocom/msc/sgs_server.h
@@ -44,7 +44,7 @@ struct sgs_state {
char vlr_name[SGS_VLR_NAME_MAXLEN];
/* timers on VLR side */
unsigned int timer[_NUM_SGS_STATE_TIMERS];
- /* countrs on VLR side */
+ /* counters on VLR side */
unsigned int counter[_NUM_SGS_STATE_COUNTERS];
} cfg;
};
diff --git a/include/osmocom/msc/signal.h b/include/osmocom/msc/signal.h
index 16b5678db..915313131 100644
--- a/include/osmocom/msc/signal.h
+++ b/include/osmocom/msc/signal.h
@@ -70,15 +70,6 @@ enum signal_scall {
S_SCALL_DETACHED,
};
-/* SS_IPAC_NWL signals */
-enum signal_ipaccess {
- S_IPAC_NWL_COMPLETE,
-};
-
-enum signal_global {
- S_GLOBAL_BTS_CLOSE_OM,
-};
-
struct paging_signal_data {
struct vlr_subscr *vsub;
struct msc_a *msc_a;
@@ -89,7 +80,7 @@ struct scall_signal_data {
struct vty *vty;
};
struct sms_signal_data {
- /* The transaction where this occured */
+ /* The transaction where this occurred */
struct gsm_trans *trans;
/* Can be NULL for SMMA */
struct gsm_sms *sms;
diff --git a/include/osmocom/msc/smpp.h b/include/osmocom/msc/smpp.h
deleted file mode 100644
index bcdac8f0b..000000000
--- a/include/osmocom/msc/smpp.h
+++ /dev/null
@@ -1,4 +0,0 @@
-#pragma once
-
-int smpp_openbsc_alloc_init(void *ctx);
-int smpp_openbsc_start(struct gsm_network *net);
diff --git a/include/osmocom/msc/sms_queue.h b/include/osmocom/msc/sms_queue.h
index ef73baf04..a6e6aebd3 100644
--- a/include/osmocom/msc/sms_queue.h
+++ b/include/osmocom/msc/sms_queue.h
@@ -1,20 +1,32 @@
#ifndef SMS_QUEUE_H
#define SMS_QUEUE_H
+#include <stdbool.h>
+
struct gsm_network;
struct gsm_sms_queue;
struct vty;
+struct sms_queue_config {
+ char *db_file_path; /* SMS database file path */
+ int max_fail; /* maximum number of delivery failures */
+ int max_pending; /* maximum number of gsm_sms_pending in RAM */
+ bool delete_delivered; /* delete delivered SMS from DB? */
+ bool delete_expired; /* delete expired SMS from DB? */
+ unsigned int minimum_validity_mins; /* minimum validity period in minutes */
+ unsigned int default_validity_mins; /* default validity period in minutes */
+};
+
+struct sms_queue_config *sms_queue_cfg_alloc(void *ctx);
+
#define VSUB_USE_SMS_PENDING "SMS-pending"
#define MSC_A_USE_SMS_PENDING "SMS-pending"
-int sms_queue_start(struct gsm_network *, int in_flight);
+int sms_queue_start(struct gsm_network *net);
int sms_queue_trigger(struct gsm_sms_queue *);
/* vty helper functions */
int sms_queue_stats(struct gsm_sms_queue *, struct vty* vty);
-int sms_queue_set_max_pending(struct gsm_sms_queue *, int max);
-int sms_queue_set_max_failure(struct gsm_sms_queue *, int fail);
int sms_queue_clear(struct gsm_sms_queue *);
int sms_queue_sms_is_pending(struct gsm_sms_queue *smsq, unsigned long long sms_id);
diff --git a/include/osmocom/msc/transaction.h b/include/osmocom/msc/transaction.h
index 9278b6400..aa529e494 100644
--- a/include/osmocom/msc/transaction.h
+++ b/include/osmocom/msc/transaction.h
@@ -8,6 +8,8 @@
#include <osmocom/msc/mncc.h>
#include <osmocom/msc/msc_a.h>
#include <osmocom/msc/debug.h>
+#include <osmocom/msc/codec_filter.h>
+#include <osmocom/msc/csd_filter.h>
#include <osmocom/gsm/gsm0411_smc.h>
#include <osmocom/gsm/gsm0411_smr.h>
@@ -16,15 +18,18 @@ struct vty;
/* Used for late TID assignment */
#define TRANS_ID_UNASSIGNED 0xff
+#define LOG_TRANS_CAT_SRC(trans, subsys, level, file, line, fmt, args...) \
+ LOGPSRC(subsys, level, file, line, \
+ "trans(%s %s callref-0x%x tid-%u%s) " fmt, \
+ (trans) ? trans_name(trans) : "NULL", \
+ (trans) ? ((trans)->msc_a ? (trans)->msc_a->c.fi->id : vlr_subscr_name((trans)->vsub)) : "NULL", \
+ (trans) ? (trans)->callref : 0, \
+ (trans) ? (trans)->transaction_id : 0, \
+ (trans) && (trans)->paging_request ? ",PAGING" : "", \
+ ##args)
+
#define LOG_TRANS_CAT(trans, subsys, level, fmt, args...) \
- LOGP(subsys, level, \
- "trans(%s %s callref-0x%x tid-%u%s) " fmt, \
- (trans) ? trans_type_name((trans)->type) : "NULL", \
- (trans) ? ((trans)->msc_a ? (trans)->msc_a->c.fi->id : vlr_subscr_name((trans)->vsub)) : "NULL", \
- (trans) ? (trans)->callref : 0, \
- (trans) ? (trans)->transaction_id : 0, \
- (trans) && (trans)->paging_request ? ",PAGING" : "", \
- ##args)
+ LOG_TRANS_CAT_SRC(trans, subsys, level, __FILE__, __LINE__, fmt, ##args)
#define LOG_TRANS(trans, level, fmt, args...) \
LOG_TRANS_CAT(trans, (trans) ? (trans)->log_subsys : DMSC, level, fmt, ##args)
@@ -38,6 +43,8 @@ enum bridge_state {
};
enum trans_type {
+ TRANS_GCC = GSM48_PDISC_GROUP_CC,
+ TRANS_BCC = GSM48_PDISC_BCAST_CC,
TRANS_CC = GSM48_PDISC_CC,
TRANS_SMS = GSM48_PDISC_SMS,
TRANS_USSD = GSM48_PDISC_NC_SS,
@@ -78,6 +85,9 @@ struct gsm_trans {
/* reference from MNCC or other application */
uint32_t callref;
+ /* reference that may be used by MGW to identify a call */
+ uint32_t call_id;
+
/* if traffic channel receive was requested */
int tch_recv;
@@ -87,12 +97,27 @@ struct gsm_trans {
/* bearer capabilities (rate and codec) */
struct gsm_mncc_bearer_cap bearer_cap;
- /* if true, TCH_RTP_CREATE is sent after the
- * assignment is done */
- bool tch_rtp_create;
-
union {
struct {
+ /* State machine of setup process towards BSS */
+ struct osmo_fsm_inst *fi;
+ /* BSS list with all VGCS/VBS calls */
+ struct llist_head bss_list;
+ /* Inactivity timeout and timer */
+ int inactivity_to;
+ struct osmo_timer_list timer_inactivity;
+ /* If talker's downlink shall be muted */
+ bool mute_talker;
+ /* Indicator, if Uplink is used in one cell */
+ bool uplink_busy;
+ /* BSS that uses the uplink */
+ struct vgcs_bss *uplink_bss;
+ /* Cell that uses the uplink */
+ struct vgcs_bss_cell *uplink_cell;
+ /* If uplink is used by the originator */
+ bool uplink_originator;
+ } gcc;
+ struct {
/* current call state */
int state;
@@ -103,6 +128,16 @@ struct gsm_trans {
struct osmo_timer_list timer;
struct osmo_timer_list timer_guard;
struct gsm_mncc msg; /* stores setup/disconnect/release message */
+ bool mncc_initiated; /* Whether an MNCC Release is necessary on failure */
+ struct osmo_lcls *lcls;
+ /* SDP as last received from the remote call leg. */
+ struct sdp_msg remote;
+ /* Track codec/CSD choices from BSS and remote call leg */
+ struct codec_filter codecs;
+ struct csd_filter csd;
+ /* Resulting choice from codecs/bearer services and the
+ * local RTP address to be sent to the remote call leg. */
+ struct sdp_msg local;
} cc;
struct {
struct gsm411_smc_inst smc_inst;
@@ -110,8 +145,13 @@ struct gsm_trans {
/* SM-RP-MR, Message Reference (see GSM TS 04.11, section 8.2.3) */
uint8_t sm_rp_mr;
+ /* More Messages to Send (see 3GPP TS 29.002, section 7.6.8.7) */
+ bool sm_rp_mmts_ind;
struct gsm_sms *sms;
+
+ uint8_t *gsup_source_name;
+ size_t gsup_source_name_len;
} sms;
struct {
/**
@@ -140,12 +180,14 @@ struct gsm_trans {
struct gsm_trans *trans_find_by_type(const struct msc_a *msc_a, enum trans_type type);
struct gsm_trans *trans_find_by_id(const struct msc_a *msc_a,
enum trans_type type, uint8_t trans_id);
-struct gsm_trans *trans_find_by_callref(const struct gsm_network *net,
+struct gsm_trans *trans_find_by_callref(const struct gsm_network *net, enum trans_type type,
uint32_t callref);
struct gsm_trans *trans_find_by_sm_rp_mr(const struct gsm_network *net,
const struct vlr_subscr *vsub,
uint8_t sm_rp_mr);
+struct osmo_lcls *trans_lcls_compose(const struct gsm_trans *trans, bool use_lac);
+
struct gsm_trans *trans_alloc(struct gsm_network *net,
struct vlr_subscr *vsub,
enum trans_type type, uint8_t trans_id,
@@ -157,11 +199,13 @@ int trans_assign_trans_id(const struct gsm_network *net, const struct vlr_subscr
struct gsm_trans *trans_has_conn(const struct msc_a *msc_a);
void trans_conn_closed(const struct msc_a *msc_a);
-static inline int trans_log_subsys(const struct gsm_trans *trans)
+static inline int trans_log_subsys(enum trans_type type)
{
- if (!trans)
- return DMSC;
- switch (trans->type) {
+ switch (type) {
+ case TRANS_GCC:
+ return DGCC;
+ case TRANS_BCC:
+ return DBCC;
case TRANS_CC:
case TRANS_SILENT_CALL:
return DCC;
@@ -174,3 +218,5 @@ static inline int trans_log_subsys(const struct gsm_trans *trans)
}
return DMSC;
}
+
+const char *trans_name(const struct gsm_trans *trans);
diff --git a/include/osmocom/msc/transaction_cc.h b/include/osmocom/msc/transaction_cc.h
new file mode 100644
index 000000000..963cb457a
--- /dev/null
+++ b/include/osmocom/msc/transaction_cc.h
@@ -0,0 +1,39 @@
+/* Filter/overlay codec and CSD bearer service selections for voice calls/CSD,
+ * across MS, RAN and CN limitations
+ *
+ * (C) 2023 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
+ * All Rights Reserved
+ *
+ * Author: Oliver Smith
+ *
+ * SPDX-License-Identifier: AGPL-3.0+
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#include <osmocom/gsm/mncc.h>
+
+#include <osmocom/msc/codec_mapping.h>
+#include <osmocom/msc/transaction.h>
+#include <osmocom/msc/vlr.h>
+
+void trans_cc_filter_init(struct gsm_trans *trans);
+void trans_cc_filter_set_ran(struct gsm_trans *trans, enum osmo_rat_type ran_type);
+void trans_cc_filter_set_bss(struct gsm_trans *trans, struct msc_a *msc_a);
+#define trans_cc_filter_run(TRANS_CC) _trans_cc_filter_run(__FILE__, __LINE__, TRANS_CC)
+void _trans_cc_filter_run(const char *file, int line, struct gsm_trans *trans);
+void trans_cc_filter_set_ms_from_bc(struct gsm_trans *trans, const struct gsm_mncc_bearer_cap *bcap);
+void trans_cc_set_remote_from_bc(struct gsm_trans *trans, const struct gsm_mncc_bearer_cap *bcap);
diff --git a/include/osmocom/msc/vlr.h b/include/osmocom/msc/vlr.h
index b1c0d5dde..a7707fd01 100644
--- a/include/osmocom/msc/vlr.h
+++ b/include/osmocom/msc/vlr.h
@@ -5,6 +5,8 @@
#include <osmocom/core/fsm.h>
#include <osmocom/core/logging.h>
#include <osmocom/core/use_count.h>
+#include <osmocom/core/stat_item.h>
+#include <osmocom/core/rate_ctr.h>
#include <osmocom/gsm/protocol/gsm_23_003.h>
#include <osmocom/gsm/protocol/gsm_04_08_gprs.h>
#include <osmocom/gsm/gsm23003.h>
@@ -23,6 +25,7 @@
LOGP(DVLR, level, "SUBSCR(%s) " fmt, vlr_subscr_name(vsub), ## args)
struct log_target;
+struct osmo_mobile_identity;
#define VLR_SUBSCRIBER_NO_EXPIRATION 0
#define VLR_SUBSCRIBER_LU_EXPIRATION_INTERVAL 60 /* in seconds */
@@ -40,7 +43,7 @@ struct log_target;
/* VLR subscriber authentication state */
enum vlr_subscr_auth_state {
- /* subscriber needs to be autenticated */
+ /* subscriber needs to be authenticated */
VLR_SUB_AS_NEEDS_AUTH,
/* waiting for AuthInfo from HLR/AUC */
VLR_SUB_AS_NEEDS_AUTH_WAIT_AI,
@@ -64,9 +67,11 @@ enum vlr_lu_event {
VLR_ULA_E_UPDATE_LA, /* Initial trigger (LU from MS) */
VLR_ULA_E_SEND_ID_ACK, /* Result of Send-ID from PVLR */
VLR_ULA_E_SEND_ID_NACK, /* Result of Send-ID from PVLR */
- VLR_ULA_E_AUTH_RES, /* Result of auth procedure */
+ VLR_ULA_E_AUTH_SUCCESS, /* Successful result of auth procedure */
+ VLR_ULA_E_AUTH_NO_INFO, /* HLR returned SAI NACK, possibly continue without auth */
+ VLR_ULA_E_AUTH_FAILURE, /* Auth procedure failed */
VLR_ULA_E_CIPH_RES, /* Result of Ciphering Mode Command */
- VLR_ULA_E_ID_IMSI, /* IMSI recieved from MS */
+ VLR_ULA_E_ID_IMSI, /* IMSI received from MS */
VLR_ULA_E_ID_IMEI, /* IMEI received from MS */
VLR_ULA_E_ID_IMEISV, /* IMEISV received from MS */
VLR_ULA_E_HLR_IMEI_ACK, /* Check_IMEI_VLR result from HLR */
@@ -113,7 +118,6 @@ struct sgsn_mm_ctx;
struct vlr_instance;
#define VLR_NAME_LENGTH 160
-#define VLR_MSISDN_LENGTH 15
/* The VLR subscriber is the part of the GSM subscriber state in VLR (CS) or
* SGSN (PS), particularly while interacting with the HLR via GSUP */
@@ -127,10 +131,9 @@ struct vlr_subscr {
/* Data from HLR */ /* 3GPP TS 23.008 */
/* Always use vlr_subscr_set_imsi() to write to imsi[] */
char imsi[GSM23003_IMSI_MAX_DIGITS+1]; /* 2.1.1.1 */
- char msisdn[VLR_MSISDN_LENGTH+1]; /* 2.1.2 */
+ char msisdn[GSM23003_MSISDN_MAX_DIGITS+1]; /* 2.1.2 */
char name[VLR_NAME_LENGTH+1]; /* proprietary */
OSMO_LBUF_DECL(hlr, 16); /* 2.4.7 */
- uint32_t periodic_lu_timer; /* 2.4.24 */
uint32_t age_indicator; /* 2.17.1 */
/* Authentication Data */
@@ -194,6 +197,8 @@ struct vlr_subscr {
vlr_sgs_lu_mminfo_cb_t mminfo_cb;
enum sgsap_service_ind paging_serv_ind;
struct osmo_timer_list Ts5;
+ bool last_eutran_plmn_present;
+ struct osmo_plmn_id last_eutran_plmn;
} sgs;
struct osmo_gsm48_classmark classmark;
@@ -252,13 +257,8 @@ struct vlr_ops {
/* notify MSC/SGSN that the given subscriber has been associated
* with this msc_conn_ref */
int (*subscr_assoc)(void *msc_conn_ref, struct vlr_subscr *vsub);
-};
-
-enum vlr_timer {
- VLR_T_3250,
- VLR_T_3260,
- VLR_T_3270,
- _NUM_VLR_TIMERS
+ /* notify MSC that the given subscriber is no longer valid */
+ void (*subscr_inval)(void *msc_conn_ref, struct vlr_subscr *vsub);
};
/* An instance of the VLR codebase */
@@ -277,8 +277,11 @@ struct vlr_instance {
bool auth_reuse_old_sets_on_error;
bool parq_retrieve_imsi;
bool is_ps;
- uint32_t timer[_NUM_VLR_TIMERS];
+ uint8_t nri_bitlen;
+ struct osmo_nri_ranges *nri_ranges;
} cfg;
+ struct osmo_stat_item_group *statg;
+ struct rate_ctr_group *ctrg;
/* A free-form pointer for use by the caller */
void *user_ctx;
};
@@ -300,7 +303,8 @@ vlr_loc_update(struct osmo_fsm_inst *parent,
const struct osmo_location_area_id *old_lai,
const struct osmo_location_area_id *new_lai,
bool authentication_required,
- bool ciphering_required,
+ bool is_ciphering_to_be_attempted,
+ bool is_ciphering_required,
uint8_t key_seq,
bool is_r99, bool is_utran,
bool assign_tmsi);
@@ -312,7 +316,7 @@ void vlr_loc_update_cancel(struct osmo_fsm_inst *fi,
/* tell the VLR that the RAN connection is gone */
int vlr_subscr_disconnected(struct vlr_subscr *vsub);
bool vlr_subscr_expire(struct vlr_subscr *vsub);
-int vlr_subscr_rx_id_resp(struct vlr_subscr *vsub, const uint8_t *mi, size_t mi_len);
+int vlr_subscr_rx_id_resp(struct vlr_subscr *vsub, const struct osmo_mobile_identity *mi);
int vlr_subscr_rx_auth_resp(struct vlr_subscr *vsub, bool is_r99, bool is_utran,
const uint8_t *res, uint8_t res_len);
int vlr_subscr_rx_auth_fail(struct vlr_subscr *vsub, const uint8_t *auts);
@@ -363,6 +367,9 @@ const char *vlr_subscr_msisdn_or_name(const struct vlr_subscr *vsub);
#define vlr_subscr_find_by_msisdn(vlr, msisdn, USE) \
_vlr_subscr_find_by_msisdn(vlr, msisdn, USE, __FILE__, __LINE__)
+#define vlr_subscr_find_by_mi(vlr, mi, USE) \
+ _vlr_subscr_find_by_mi(vlr, mi, USE, __FILE__, __LINE__)
+
struct vlr_subscr *_vlr_subscr_find_by_imsi(struct vlr_instance *vlr,
const char *imsi,
const char *use,
@@ -390,6 +397,11 @@ struct vlr_subscr *_vlr_subscr_find_by_msisdn(struct vlr_instance *vlr,
const char *use,
const char *file, int line);
+struct vlr_subscr *_vlr_subscr_find_by_mi(struct vlr_instance *vlr,
+ const struct osmo_mobile_identity *mi,
+ const char *use,
+ const char *file, int line);
+
#define vlr_subscr_get(VSUB, USE) vlr_subscr_get_src(VSUB, USE, __FILE__, __LINE__)
#define vlr_subscr_put(VSUB, USE) vlr_subscr_put_src(VSUB, USE, __FILE__, __LINE__)
@@ -405,6 +417,8 @@ void vlr_subscr_set_imsi(struct vlr_subscr *vsub, const char *imsi);
void vlr_subscr_set_imei(struct vlr_subscr *vsub, const char *imei);
void vlr_subscr_set_imeisv(struct vlr_subscr *vsub, const char *imeisv);
void vlr_subscr_set_msisdn(struct vlr_subscr *vsub, const char *msisdn);
+void vlr_subscr_set_last_used_eutran_plmn_id(struct vlr_subscr *vsub,
+ const struct osmo_plmn_id *last_eutran_plmn);
bool vlr_subscr_matches_imsi(struct vlr_subscr *vsub, const char *imsi);
bool vlr_subscr_matches_tmsi(struct vlr_subscr *vsub, uint32_t tmsi);
@@ -421,12 +435,14 @@ void vlr_subscr_cancel_attach_fsm(struct vlr_subscr *vsub,
void vlr_subscr_enable_expire_lu(struct vlr_subscr *vsub);
-/* Process Acccess Request FSM */
+/* Process Access Request FSM */
enum proc_arq_vlr_event {
PR_ARQ_E_START,
PR_ARQ_E_ID_IMSI,
PR_ARQ_E_AUTH_RES,
+ PR_ARQ_E_AUTH_NO_INFO,
+ PR_ARQ_E_AUTH_FAILURE,
PR_ARQ_E_CIPH_RES,
PR_ARQ_E_UPD_LOC_RES,
PR_ARQ_E_TRACE_RES,
@@ -439,6 +455,7 @@ enum vlr_parq_type {
VLR_PR_ARQ_T_INVALID = 0, /* to guard against unset vars */
VLR_PR_ARQ_T_CM_SERV_REQ,
VLR_PR_ARQ_T_PAGING_RESP,
+ VLR_PR_ARQ_T_CM_RE_ESTABLISH_REQ,
/* FIXME: differentiate between services of 24.008 10.5.3.3 */
};
@@ -450,10 +467,11 @@ vlr_proc_acc_req(struct osmo_fsm_inst *parent,
void *parent_event_data,
struct vlr_instance *vlr, void *msc_conn_ref,
enum vlr_parq_type type, enum osmo_cm_service_type cm_service_type,
- const uint8_t *mi_lv,
+ const struct osmo_mobile_identity *mi,
const struct osmo_location_area_id *lai,
bool authentication_required,
- bool ciphering_required,
+ bool is_ciphering_to_be_attempted,
+ bool is_ciphering_required,
uint8_t key_seq,
bool is_r99, bool is_utran);
@@ -466,7 +484,6 @@ void vlr_parq_fsm_init(void);
int vlr_set_ciph_mode(struct vlr_instance *vlr,
struct osmo_fsm_inst *fi,
void *msc_conn_ref,
- bool ciph_required,
bool umts_aka,
bool retrieve_imeisv);
@@ -474,3 +491,6 @@ bool vlr_use_umts_aka(struct osmo_auth_vector *vec, bool is_r99);
void log_set_filter_vlr_subscr(struct log_target *target,
struct vlr_subscr *vlr_subscr);
+
+void vlr_gmm_cause_to_mm_cause(enum gsm48_gmm_cause gmm_cause,
+ enum gsm48_reject_value *gsm48_rej_p);
diff --git a/include/osmocom/msc/vlr_sgs.h b/include/osmocom/msc/vlr_sgs.h
index 00d52f7b4..aade5d342 100644
--- a/include/osmocom/msc/vlr_sgs.h
+++ b/include/osmocom/msc/vlr_sgs.h
@@ -26,14 +26,14 @@ enum vlr_lu_type;
struct vlr_subscr;
struct vlr_instance;
-#define VSUB_USE_SGS "SGs"
+#define VSUB_USE_SGS_LU "SGs-lu"
#define VSUB_USE_SGS_PAGING_REQ "SGs-paging-req"
/* See also 3GPP TS 29.118, chapter 4.2.2 States at the VLR */
enum sgs_ue_fsm_state {
SGS_UE_ST_NULL,
- SGS_UE_ST_ASSOCIATED,
SGS_UE_ST_LA_UPD_PRES,
+ SGS_UE_ST_ASSOCIATED,
};
enum vlr_sgs_state_tmr {
@@ -69,12 +69,13 @@ static inline const char *vlr_sgs_state_timer_name(enum vlr_sgs_state_tmr Ts)
extern const struct value_string sgs_state_counter_names[];
static inline const char *vlr_sgs_state_counter_name(enum vlr_sgs_state_ctr Ns)
{
- return get_value_string(sgs_state_timer_names, Ns);
+ return get_value_string(sgs_state_counter_names, Ns);
}
/* This callback function is called when an SGs location update is complete */
struct sgs_lu_response {
bool accepted;
+ bool error;
struct vlr_subscr *vsub;
};
typedef void (*vlr_sgs_lu_response_cb_t) (struct sgs_lu_response *response);
@@ -96,7 +97,7 @@ void vlr_sgs_reset(struct vlr_instance *vlr);
int vlr_sgs_loc_update(struct vlr_instance *vlr, struct vlr_sgs_cfg *cfg,
vlr_sgs_lu_response_cb_t response_cb, vlr_sgs_lu_paging_cb_t paging_cb,
vlr_sgs_lu_mminfo_cb_t mminfo_cb, char *mme_name, enum vlr_lu_type type, const char *imsi,
- struct osmo_location_area_id *new_lai);
+ struct osmo_location_area_id *new_lai, struct osmo_plmn_id *last_eutran_plmn);
void vlr_sgs_loc_update_acc_sent(struct vlr_subscr *vsub);
void vlr_sgs_loc_update_rej_sent(struct vlr_subscr *vsub);
void vlr_sgs_detach(struct vlr_instance *vlr, const char *imsi, bool eps);
diff --git a/include/osmocom/msc/vty.h b/include/osmocom/msc/vty.h
index 2a3b18bdf..a7f1db7ca 100644
--- a/include/osmocom/msc/vty.h
+++ b/include/osmocom/msc/vty.h
@@ -17,6 +17,7 @@ extern struct cmd_element cfg_no_description_cmd;
enum bsc_vty_node {
GSMNET_NODE = _LAST_OSMOVTY_NODE + 1,
+ MGW_NODE,
SUBSCR_NODE,
MSC_NODE,
MNCC_INT_NODE,
@@ -24,11 +25,17 @@ enum bsc_vty_node {
SMPP_ESME_NODE,
HLR_NODE,
CFG_SGS_NODE,
+ SMSC_NODE,
+ ASCI_NODE,
+ GCR_NODE,
+ VGC_NODE,
+ VBC_NODE,
};
int bsc_vty_init_extra(void);
void msc_vty_init(struct gsm_network *msc_network);
+void smsc_vty_init(struct gsm_network *msc_network);
struct gsm_network *gsmnet_from_vty(struct vty *vty);
diff --git a/include/osmocom/smpp/Makefile.am b/include/osmocom/smpp/Makefile.am
new file mode 100644
index 000000000..5ad34ad0d
--- /dev/null
+++ b/include/osmocom/smpp/Makefile.am
@@ -0,0 +1,4 @@
+noinst_HEADERS = \
+ smpp.h \
+ smpp_smsc.h \
+ $(NULL)
diff --git a/include/osmocom/smpp/smpp.h b/include/osmocom/smpp/smpp.h
new file mode 100644
index 000000000..a2832d304
--- /dev/null
+++ b/include/osmocom/smpp/smpp.h
@@ -0,0 +1,55 @@
+#pragma once
+
+#include <osmocom/msc/gsm_data.h>
+
+/* Length limits according to SMPP 3.4 spec including NUL-byte: */
+#define SMPP_SYS_ID_LEN 15
+#define SMPP_PASSWD_LEN 8
+
+enum esme_read_state {
+ READ_ST_IN_LEN = 0,
+ READ_ST_IN_MSG = 1,
+};
+
+/* struct representing SMPP's External Short Messaging Entity */
+struct esme {
+ uint32_t own_seq_nr;
+
+ struct osmo_wqueue wqueue;
+ enum esme_read_state read_state;
+ uint32_t read_len;
+ uint32_t read_idx;
+ struct msgb *read_msg;
+
+ uint8_t smpp_version;
+ char system_id[SMPP_SYS_ID_LEN + 1];
+ char password[SMPP_SYS_ID_LEN + 1];
+};
+
+#define LOGPESME(ESME, LEVEL, FMT, ARGS...) \
+ LOGP(DSMPP, LEVEL, "[%s] " FMT, (ESME)->system_id, ##ARGS)
+
+#define LOGPESMERR(ESME, FMT, ARGS...) \
+ LOGPESME(ESME, LOGL_ERROR, "Error (%s) " FMT, smpp34_strerror, ##ARGS)
+
+/*! \brief Ugly wrapper. libsmpp34 should do this itself! */
+#define SMPP34_UNPACK(rc, type, str, data, len) { \
+ memset(str, 0, sizeof(*str)); \
+ rc = smpp34_unpack(type, str, data, len); }
+
+#define PACK_AND_SEND(esme, ptr) pack_and_send(esme, (ptr)->command_id, ptr)
+
+/*! \brief initialize the libsmpp34 data structure for a response */
+#define INIT_RESP(type, resp, req) { \
+ memset((resp), 0, sizeof(*(resp))); \
+ (resp)->command_length = 0; \
+ (resp)->command_id = type; \
+ (resp)->command_status = ESME_ROK; \
+ (resp)->sequence_number = (req)->sequence_number; }
+
+struct esme *esme_alloc(void *ctx);
+uint32_t smpp_msgb_cmdid(struct msgb *msg);
+uint32_t esme_inc_seq_nr(struct esme *esme);
+int pack_and_send(struct esme *esme, uint32_t type, void *ptr);
+int smpp_msc_alloc_init(void *ctx);
+int smpp_msc_start(struct gsm_network *net);
diff --git a/src/libmsc/smpp_smsc.h b/include/osmocom/smpp/smpp_smsc.h
index b26d01126..6d7647589 100644
--- a/src/libmsc/smpp_smsc.h
+++ b/include/osmocom/smpp/smpp_smsc.h
@@ -1,5 +1,4 @@
-#ifndef _SMPP_SMSC_H
-#define _SMPP_SMSC_H
+#pragma once
#include <sys/socket.h>
#include <netinet/in.h>
@@ -8,24 +7,17 @@
#include <osmocom/core/msgb.h>
#include <osmocom/core/write_queue.h>
#include <osmocom/core/timer.h>
+#include <osmocom/smpp/smpp.h>
#include <smpp34.h>
#include <smpp34_structs.h>
#include <smpp34_params.h>
-#define SMPP_SYS_ID_LEN 15
-#define SMPP_PASSWD_LEN 8
-
#define MODE_7BIT 7
#define MODE_8BIT 8
struct msc_a;
-enum esme_read_state {
- READ_ST_IN_LEN = 0,
- READ_ST_IN_MSG = 1,
-};
-
struct osmo_smpp_acl;
struct osmo_smpp_addr {
@@ -34,35 +26,24 @@ struct osmo_smpp_addr {
char addr[21+1];
};
-struct osmo_esme {
+/* struct wrapping ESME struct with additional SMSC-specific things like ACL, command list etc */
+struct smpp_esme {
struct llist_head list;
struct smsc *smsc;
+ struct esme *esme;
struct osmo_smpp_acl *acl;
int use;
struct llist_head smpp_cmd_list;
- uint32_t own_seq_nr;
-
- struct osmo_wqueue wqueue;
- struct sockaddr_storage sa;
- socklen_t sa_len;
-
- enum esme_read_state read_state;
- uint32_t read_len;
- uint32_t read_idx;
- struct msgb *read_msg;
-
uint8_t smpp_version;
- char system_id[SMPP_SYS_ID_LEN+1];
-
uint8_t bind_flags;
};
struct osmo_smpp_acl {
struct llist_head list;
struct smsc *smsc;
- struct osmo_esme *esme;
+ struct smpp_esme *esme;
char *description;
char system_id[SMPP_SYS_ID_LEN+1];
char passwd[SMPP_PASSWD_LEN+1];
@@ -99,18 +80,18 @@ struct osmo_smpp_cmd {
struct osmo_timer_list response_timer;
};
-struct osmo_smpp_cmd *smpp_cmd_find_by_seqnum(struct osmo_esme *esme,
+struct osmo_smpp_cmd *smpp_cmd_find_by_seqnum(struct smpp_esme *esme,
uint32_t sequence_number);
void smpp_cmd_ack(struct osmo_smpp_cmd *cmd);
void smpp_cmd_err(struct osmo_smpp_cmd *cmd, uint32_t status);
-void smpp_cmd_flush_pending(struct osmo_esme *esme);
+void smpp_cmd_flush_pending(struct smpp_esme *esme);
struct smsc {
struct osmo_fd listen_ofd;
struct llist_head esme_list;
struct llist_head acl_list;
struct llist_head route_list;
- const char *bind_addr;
+ char *bind_addr;
uint16_t listen_port;
char system_id[SMPP_SYS_ID_LEN+1];
int accept_all;
@@ -126,27 +107,26 @@ struct smsc *smpp_smsc_alloc_init(void *ctx);
int smpp_smsc_conf(struct smsc *smsc, const char *bind_addr, uint16_t port);
int smpp_smsc_start(struct smsc *smsc, const char *bind_addr, uint16_t port);
int smpp_smsc_restart(struct smsc *smsc, const char *bind_addr, uint16_t port);
-void smpp_smsc_stop(struct smsc *smsc);
-void smpp_esme_get(struct osmo_esme *esme);
-void smpp_esme_put(struct osmo_esme *esme);
+void smpp_esme_get(struct smpp_esme *esme);
+void smpp_esme_put(struct smpp_esme *esme);
-int smpp_route(const struct smsc *smsc, const struct osmo_smpp_addr *dest, struct osmo_esme **emse);
+int smpp_route(const struct smsc *smsc, const struct osmo_smpp_addr *dest, struct smpp_esme **emse);
struct osmo_smpp_acl *smpp_acl_alloc(struct smsc *smsc, const char *sys_id);
struct osmo_smpp_acl *smpp_acl_by_system_id(struct smsc *smsc,
const char *sys_id);
void smpp_acl_delete(struct osmo_smpp_acl *acl);
-int smpp_tx_submit_r(struct osmo_esme *esme, uint32_t sequence_nr,
+int smpp_tx_submit_r(struct smpp_esme *esme, uint32_t sequence_nr,
uint32_t command_status, char *msg_id);
-int smpp_tx_alert(struct osmo_esme *esme, uint8_t ton, uint8_t npi,
+int smpp_tx_alert(struct smpp_esme *esme, uint8_t ton, uint8_t npi,
const char *addr, uint8_t avail_status);
-int smpp_tx_deliver(struct osmo_esme *esme, struct deliver_sm_t *deliver);
+int smpp_tx_deliver(struct smpp_esme *esme, struct deliver_sm_t *deliver);
-int handle_smpp_submit(struct osmo_esme *esme, struct submit_sm_t *submit,
+int handle_smpp_submit(struct smpp_esme *esme, struct submit_sm_t *submit,
struct submit_sm_resp_t *submit_r);
int smpp_route_pfx_add(struct osmo_smpp_acl *acl,
@@ -158,6 +138,7 @@ int smpp_vty_init(void);
int smpp_determine_scheme(uint8_t dcs, uint8_t *data_coding, int *mode);
+time_t smpp_parse_time_format(const char *vp, time_t *t_now);
struct gsm_sms;
@@ -165,4 +146,3 @@ struct ran_conn;
bool smpp_route_smpp_first();
int smpp_try_deliver(struct gsm_sms *sms, struct msc_a *msc_a);
-#endif
diff --git a/m4/ax_check_compile_flag.m4 b/m4/ax_check_compile_flag.m4
deleted file mode 100644
index ca3639715..000000000
--- a/m4/ax_check_compile_flag.m4
+++ /dev/null
@@ -1,74 +0,0 @@
-# ===========================================================================
-# http://www.gnu.org/software/autoconf-archive/ax_check_compile_flag.html
-# ===========================================================================
-#
-# SYNOPSIS
-#
-# AX_CHECK_COMPILE_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS], [INPUT])
-#
-# DESCRIPTION
-#
-# Check whether the given FLAG works with the current language's compiler
-# or gives an error. (Warnings, however, are ignored)
-#
-# ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on
-# success/failure.
-#
-# If EXTRA-FLAGS is defined, it is added to the current language's default
-# flags (e.g. CFLAGS) when the check is done. The check is thus made with
-# the flags: "CFLAGS EXTRA-FLAGS FLAG". This can for example be used to
-# force the compiler to issue an error when a bad flag is given.
-#
-# INPUT gives an alternative input source to AC_COMPILE_IFELSE.
-#
-# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this
-# macro in sync with AX_CHECK_{PREPROC,LINK}_FLAG.
-#
-# LICENSE
-#
-# Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de>
-# Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.com>
-#
-# This program is free software: you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by the
-# Free Software Foundation, either version 3 of the License, or (at your
-# option) any later version.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
-# Public License for more details.
-#
-# You should have received a copy of the GNU General Public License along
-# with this program. If not, see <http://www.gnu.org/licenses/>.
-#
-# As a special exception, the respective Autoconf Macro's copyright owner
-# gives unlimited permission to copy, distribute and modify the configure
-# scripts that are the output of Autoconf when processing the Macro. You
-# need not follow the terms of the GNU General Public License when using
-# or distributing such scripts, even though portions of the text of the
-# Macro appear in them. The GNU General Public License (GPL) does govern
-# all other use of the material that constitutes the Autoconf Macro.
-#
-# This special exception to the GPL applies to versions of the Autoconf
-# Macro released by the Autoconf Archive. When you make and distribute a
-# modified version of the Autoconf Macro, you may extend this special
-# exception to the GPL to apply to your modified version as well.
-
-#serial 4
-
-AC_DEFUN([AX_CHECK_COMPILE_FLAG],
-[AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_IF
-AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_[]_AC_LANG_ABBREV[]flags_$4_$1])dnl
-AC_CACHE_CHECK([whether _AC_LANG compiler accepts $1], CACHEVAR, [
- ax_check_save_flags=$[]_AC_LANG_PREFIX[]FLAGS
- _AC_LANG_PREFIX[]FLAGS="$[]_AC_LANG_PREFIX[]FLAGS $4 $1"
- AC_COMPILE_IFELSE([m4_default([$5],[AC_LANG_PROGRAM()])],
- [AS_VAR_SET(CACHEVAR,[yes])],
- [AS_VAR_SET(CACHEVAR,[no])])
- _AC_LANG_PREFIX[]FLAGS=$ax_check_save_flags])
-AS_VAR_IF(CACHEVAR,yes,
- [m4_default([$2], :)],
- [m4_default([$3], :)])
-AS_VAR_POPDEF([CACHEVAR])dnl
-])dnl AX_CHECK_COMPILE_FLAGS
diff --git a/osmoappdesc.py b/osmoappdesc.py
index 886c682a7..b7a274c92 100644
--- a/osmoappdesc.py
+++ b/osmoappdesc.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
# (C) 2013 by Katerina Barone-Adesi <kat.obsc@gmail.com>
# This program is free software: you can redistribute it and/or modify
@@ -14,13 +14,16 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>
+import os
+
app_configs = {
- "msc": ["doc/examples/osmo-msc/osmo-msc.cfg",
- "doc/examples/osmo-msc/osmo-msc_custom-sccp.cfg",
- "doc/examples/osmo-msc/osmo-msc_multi-cs7.cfg",
- ],
+ "msc": ["doc/examples/osmo-msc/osmo-msc.cfg"],
}
+if os.environ["IU"] == "1":
+ app_configs["msc"] += ["doc/examples/osmo-msc/osmo-msc_custom-sccp.cfg",
+ "doc/examples/osmo-msc/osmo-msc_multi-cs7.cfg"]
+
apps = [(4254, "src/osmo-msc/osmo-msc", "OsmoMSC", "msc"),
]
diff --git a/src/Makefile.am b/src/Makefile.am
index 4e7cea19b..746c80d0f 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -13,20 +13,22 @@ AM_CFLAGS = \
$(COVERAGE_CFLAGS) \
$(NULL)
-AM_LDFLAGS = \
- $(LIBOSMOCORE_LIBS) \
- $(LIBOSMOGSM_LIBS) \
- $(COVERAGE_LDFLAGS) \
- $(NULL)
-
# Libraries
SUBDIRS = \
libvlr \
libmsc \
$(NULL)
+if BUILD_SMPP
+
+SUBDIRS += \
+ libsmpputil \
+ utils \
+ $(NULL)
+
+endif
+
# Programs
SUBDIRS += \
osmo-msc \
- utils \
$(NULL)
diff --git a/src/libmsc/Makefile.am b/src/libmsc/Makefile.am
index d83489680..dff4b2db0 100644
--- a/src/libmsc/Makefile.am
+++ b/src/libmsc/Makefile.am
@@ -20,9 +20,6 @@ AM_CFLAGS = \
$(LIBOSMONETIF_CFLAGS) \
$(NULL)
-noinst_HEADERS = \
- $(NULL)
-
noinst_LIBRARIES = \
libmsc.a \
$(NULL)
@@ -30,6 +27,10 @@ noinst_LIBRARIES = \
libmsc_a_SOURCES = \
call_leg.c \
cell_id_list.c \
+ codec_filter.c \
+ codec_mapping.c \
+ csd_bs.c \
+ csd_filter.c \
sccp_ran.c \
msc_vty.c \
db.c \
@@ -54,6 +55,7 @@ libmsc_a_SOURCES = \
msc_t.c \
msc_t_remote.c \
msc_ho.c \
+ msc_vgcs.c \
neighbor_ident.c \
neighbor_ident_vty.c \
paging.c \
@@ -64,14 +66,19 @@ libmsc_a_SOURCES = \
ran_peer.c \
rrlp.c \
rtp_stream.c \
+ sdp_msg.c \
silent_call.c \
sms_queue.c \
+ smsc_vty.c \
transaction.c \
+ transaction_cc.c \
msc_net_init.c \
ctrl_commands.c \
sgs_iface.c \
sgs_server.c \
sgs_vty.c \
+ asci_gcr.c \
+ asci_vty.c \
$(NULL)
if BUILD_IU
@@ -79,16 +86,3 @@ libmsc_a_SOURCES += \
ran_msg_iu.c \
$(NULL)
endif
-
-if BUILD_SMPP
-noinst_HEADERS += \
- smpp_smsc.h \
- $(NULL)
-
-libmsc_a_SOURCES += \
- smpp_smsc.c \
- smpp_openbsc.c \
- smpp_vty.c \
- smpp_utils.c \
- $(NULL)
-endif
diff --git a/src/libmsc/asci_gcr.c b/src/libmsc/asci_gcr.c
new file mode 100644
index 000000000..220815136
--- /dev/null
+++ b/src/libmsc/asci_gcr.c
@@ -0,0 +1,175 @@
+/* Group Call Register (GCR) */
+/*
+ * (C) 2023 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
+ * All Rights Reserved
+ *
+ * SPDX-License-Identifier: AGPL-3.0+
+ *
+ * Author: Andreas Eversberg
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <osmocom/msc/gsm_data.h>
+#include <osmocom/msc/transaction.h>
+
+#include <osmocom/msc/asci_gcr.h>
+
+#define GCR_DEFAULT_TIMEOUT 60
+
+static uint32_t pow10[9] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000 };
+
+/* Add cell to BSS list. */
+struct gcr_cell *gcr_add_cell(struct gcr_bss *bss, uint16_t cell_id)
+{
+ struct gcr_cell *c;
+
+ c = talloc_zero(bss, struct gcr_cell);
+ if (!c)
+ return NULL;
+ c->cell_id = cell_id;
+ llist_add_tail(&c->list, &bss->cell_list);
+
+ return c;
+}
+
+/* Find cell entry in BSS list. */
+struct gcr_cell *gcr_find_cell(struct gcr_bss *bss, uint16_t cell_id)
+{
+ struct gcr_cell *c;
+
+ llist_for_each_entry(c, &bss->cell_list, list) {
+ if (c->cell_id == cell_id)
+ return c;
+ }
+
+ return NULL;
+}
+
+/* Remove cell entry from BSS list. */
+void gcr_rm_cell(struct gcr_bss *bss, uint16_t cell_id)
+{
+ struct gcr_cell *c = gcr_find_cell(bss, cell_id);
+
+ if (c) {
+ llist_del(&c->list);
+ talloc_free(c);
+ }
+}
+
+/* Add BSS to GCR list. */
+struct gcr_bss *gcr_add_bss(struct gcr *gcr, int pc)
+{
+ struct gcr_bss *b;
+
+ b = talloc_zero(gcr, struct gcr_bss);
+ if (!b)
+ return NULL;
+ INIT_LLIST_HEAD(&b->cell_list);
+ b->pc = pc;
+ llist_add_tail(&b->list, &gcr->bss_list);
+
+ return b;
+}
+
+/* Find BSS entry in GCR list. */
+struct gcr_bss *gcr_find_bss(struct gcr *gcr, int pc)
+{
+ struct gcr_bss *b;
+
+ llist_for_each_entry(b, &gcr->bss_list, list) {
+ if (b->pc == pc)
+ return b;
+ }
+
+ return NULL;
+}
+
+/* Remove BSS entry from GCR list. */
+void gcr_rm_bss(struct gcr *gcr, int pc)
+{
+ struct gcr_bss *b = gcr_find_bss(gcr, pc);
+
+ if (b) {
+ /* All cell definitons will be removed, as they are attached to BSS. */
+ llist_del(&b->list);
+ talloc_free(b);
+ }
+}
+
+/* Create a new (empty) GCR list. */
+struct gcr *gcr_create(struct gsm_network *gsmnet, enum trans_type trans_type, const char *group_id)
+{
+ struct gcr *gcr;
+
+ gcr = talloc_zero(gsmnet, struct gcr);
+ if (!gcr)
+ return NULL;
+
+ INIT_LLIST_HEAD(&gcr->bss_list);
+ gcr->trans_type = trans_type;
+ gcr->timeout = GCR_DEFAULT_TIMEOUT;
+ gcr->mute_talker = true;
+ osmo_strlcpy(gcr->group_id, group_id, sizeof(gcr->group_id));
+ llist_add_tail(&gcr->list, &gsmnet->asci.gcr_lists);
+
+ return gcr;
+}
+
+/* Destroy a GCR list. */
+void gcr_destroy(struct gcr *gcr)
+{
+ /* All BSS definitons will be removed, as they are attached to GCR. */
+ llist_del(&gcr->list);
+ talloc_free(gcr);
+}
+
+/* Find GCR list by group ID. */
+struct gcr *gcr_by_group_id(struct gsm_network *gsmnet, enum trans_type trans_type, const char *group_id)
+{
+ struct gcr *gcr;
+
+ llist_for_each_entry(gcr, &gsmnet->asci.gcr_lists, list) {
+ if (gcr->trans_type == trans_type && !strcmp(gcr->group_id, group_id))
+ return gcr;
+ }
+
+ return NULL;
+}
+
+/* Find GCR list by callref. */
+struct gcr *gcr_by_callref(struct gsm_network *gsmnet, enum trans_type trans_type, uint32_t callref)
+{
+ struct gcr *most_specific_gcr = NULL, *gcr;
+ int a, b;
+ size_t most_specific_len = 0, l;
+
+ llist_for_each_entry(gcr, &gsmnet->asci.gcr_lists, list) {
+ /* Compare only the digits in Group ID with the digits in callref.
+ * callref is an integer. Only the remainder, based on Group ID length, is checked. */
+ l = strlen(gcr->group_id);
+ a = atoi(gcr->group_id);
+ OSMO_ASSERT(l < ARRAY_SIZE(pow10));
+ b = callref % pow10[l];
+ if (gcr->trans_type == trans_type && a == b) {
+ /* Get most specific GROUP ID, no matter what order they are stored. */
+ if (l > most_specific_len) {
+ most_specific_gcr = gcr;
+ most_specific_len = l;
+ }
+ }
+ }
+
+ return most_specific_gcr;
+}
diff --git a/src/libmsc/asci_vty.c b/src/libmsc/asci_vty.c
new file mode 100644
index 000000000..a138eda51
--- /dev/null
+++ b/src/libmsc/asci_vty.c
@@ -0,0 +1,434 @@
+/* GCR interface to VTY */
+/*
+ * (C) 2023 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
+ * All Rights Reserved
+ *
+ * SPDX-License-Identifier: AGPL-3.0+
+ *
+ * Author: Andreas Eversberg
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <osmocom/msc/vty.h>
+#include <osmocom/msc/transaction.h>
+#include <osmocom/msc/msc_vgcs.h>
+#include <osmocom/msc/asci_vty.h>
+#include <osmocom/msc/asci_gcr.h>
+
+static struct gsm_network *gsmnet;
+
+/***********************************************************************
+ * ASCI Node
+ ***********************************************************************/
+
+#define ASCI_STR "Advanced Speech Call Items\n"
+
+static void asci_disabled(struct vty *vty)
+{
+ vty_out(vty, "%%Advanced Speech Call Items are disabled.%s", VTY_NEWLINE);
+}
+
+DEFUN(asci_call, asci_call_cmd,
+ "asci (initiate|terminate) (vgc|vbc) CALLREF",
+ ASCI_STR "Initiate a call\nTerminate a call\nVoice Group Call\nVoice Broadcast Call\nCall reference")
+{
+ struct gcr *gcr;
+ const char *error;
+
+ if (!gsmnet->asci.enable) {
+ asci_disabled(vty);
+ return CMD_WARNING;
+ }
+
+ gcr = gcr_by_group_id(gsmnet, (argv[1][1] == 'g') ? TRANS_GCC : TRANS_BCC, argv[2]);
+ if (!gcr) {
+ vty_out(vty, "%%Given call ref does not exist in GCR.%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ if (argv[0][0] == 'i')
+ error = vgcs_vty_initiate(gsmnet, gcr);
+ else
+ error = vgcs_vty_terminate(gsmnet, gcr);
+ if (error) {
+ vty_out(vty, "%%%s%s", error, VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ return CMD_SUCCESS;
+}
+
+DEFUN(asci_show, asci_show_cmd,
+ "show asci calls",
+ SHOW_STR ASCI_STR "Show all Voice Group/Broadcast Calls")
+{
+ struct gsm_trans *trans;
+ const char *typestr;
+ struct vgcs_bss *bss;
+ struct vgcs_bss_cell *cell;
+
+ if (!gsmnet->asci.enable) {
+ asci_disabled(vty);
+ return CMD_WARNING;
+ }
+
+ llist_for_each_entry(trans, &gsmnet->trans_list, entry) {
+ if (trans->type == TRANS_GCC)
+ typestr = "Group";
+ else if (trans->type == TRANS_BCC)
+ typestr = "Broadcast";
+ else
+ continue;
+ vty_out(vty, "Call Reference %s (Voice %s Call).%s", gsm44068_group_id_string(trans->callref),
+ typestr, VTY_NEWLINE);
+ vty_out(vty, " Call state : %s%s", vgcs_bcc_gcc_state_name(trans->gcc.fi), VTY_NEWLINE);
+ vty_out(vty, " Uplink state: %s%s", (trans->gcc.uplink_busy) ? "busy" : "free", VTY_NEWLINE);
+ if (trans->gcc.uplink_busy)
+ vty_out(vty, " Talker : %s subscriber%s",
+ (trans->gcc.uplink_originator) ? "calling" : "other", VTY_NEWLINE);
+ llist_for_each_entry(bss, &trans->gcc.bss_list, list) {
+ vty_out(vty, " BSS %8s: listening%s%s", osmo_ss7_pointcode_print(NULL, bss->pc),
+ (trans->gcc.uplink_busy && bss == trans->gcc.uplink_bss) ? "+talking" : "",
+ VTY_NEWLINE);
+ llist_for_each_entry(cell, &bss->cell_list, list_bss) {
+ vty_out(vty, " Cell %6d: listening%s%s", cell->cell_id,
+ (trans->gcc.uplink_busy && cell == trans->gcc.uplink_cell) ? "+talking" : "",
+ VTY_NEWLINE);
+ }
+ }
+ }
+
+ return CMD_SUCCESS;
+}
+
+/***********************************************************************
+ * GCR Config Node
+ ***********************************************************************/
+
+static struct cmd_node asci_node = {
+ ASCI_NODE,
+ "%s(config-asci)# ",
+ 1,
+};
+
+static struct cmd_node gcr_node = {
+ GCR_NODE,
+ "%s(config-gcr)# ",
+ 1,
+};
+
+char conf_prompt[64];
+
+static struct cmd_node vgc_node = {
+ VGC_NODE,
+ conf_prompt,
+ 1,
+};
+
+static struct cmd_node vbc_node = {
+ VBC_NODE,
+ conf_prompt,
+ 1,
+};
+
+DEFUN(cfg_asci, cfg_asci_cmd,
+ "asci", "Enable and configure " ASCI_STR)
+{
+ vty->node = ASCI_NODE;
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_enable_disable, cfg_enable_disable_cmd,
+ "(enable|disable)", "Enable " ASCI_STR "Disable " ASCI_STR)
+{
+ gsmnet->asci.enable = (argv[0][0] == 'e');
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_gcr, cfg_gcr_cmd,
+ "gcr", "Configure Group Call Register")
+{
+ vty->node = GCR_NODE;
+ return CMD_SUCCESS;
+}
+
+static bool valid_group_id(const char *id, struct vty *vty)
+{
+ int i;
+
+ if (strlen(id) < 1 || strlen(id) > 8) {
+ vty_out(vty, "%%Given group ID is not valid. Use up to 8 numeric digits!%s", VTY_NEWLINE);
+ return false;
+ }
+ for (i = 0; i < strlen(id); i++) {
+ if (id[i] < '0' || id[i] > '9') {
+ vty_out(vty, "%%Given group ID is not valid. Use numeric digits only!%s", VTY_NEWLINE);
+ return false;
+ }
+ }
+
+ return true;
+}
+
+DEFUN(cfg_vgc, cfg_vgc_cmd,
+ "vgc ID", "Configure Voice Group Call\n" "Group ID")
+{
+ struct gcr *gcr;
+
+ if (!valid_group_id(argv[0], vty))
+ return CMD_WARNING;
+
+ gcr = gcr_by_group_id(gsmnet, TRANS_GCC, argv[0]);
+ if (!gcr)
+ gcr = gcr_create(gsmnet, TRANS_GCC, argv[0]);
+ if (!gcr)
+ return CMD_WARNING;
+
+ sprintf(conf_prompt, "%%s(vgc-%s)# ", gcr->group_id);
+ vty->node = VGC_NODE;
+ vty->index = gcr;
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_no_vgc, cfg_no_vgc_cmd,
+ "no vgc ID", NO_STR "Configure Voice Group Call\n" "Group ID")
+{
+ struct gcr *gcr;
+
+ if (!valid_group_id(argv[0], vty))
+ return CMD_WARNING;
+
+ gcr = gcr_by_group_id(gsmnet, TRANS_GCC, argv[0]);
+ if (!gcr) {
+ vty_out(vty, "%%Voice group call with given group ID does not exit!%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ gcr_destroy(gcr);
+
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_vbc, cfg_vbc_cmd,
+ "vbc ID", "Configure Voice Broadcast Call\n" "Group ID")
+{
+ struct gcr *gcr;
+
+ if (!valid_group_id(argv[0], vty))
+ return CMD_WARNING;
+
+ gcr = gcr_by_group_id(gsmnet, TRANS_BCC, argv[0]);
+ if (!gcr)
+ gcr = gcr_create(gsmnet, TRANS_BCC, argv[0]);
+ if (!gcr)
+ return CMD_WARNING;
+
+ sprintf(conf_prompt, "%%s(vbc-%s)# ", gcr->group_id);
+ vty->node = VBC_NODE;
+ vty->index = gcr;
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_no_vbc, cfg_no_vbc_cmd,
+ "no vbc ID", NO_STR "Configure Voice Broadcast Call\n" "Group ID")
+{
+ struct gcr *gcr;
+
+ if (!valid_group_id(argv[0], vty))
+ return CMD_WARNING;
+
+ gcr = gcr_by_group_id(gsmnet, TRANS_BCC, argv[0]);
+ if (!gcr) {
+ vty_out(vty, "%%Voice broadcast call with given group ID does not exit!%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ gcr_destroy(gcr);
+
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_mute, cfg_mute_cmd,
+ "mute-talker", "Mute talker's downlink")
+{
+ struct gcr *gcr = vty->index;
+
+ gcr->mute_talker = true;
+
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_unmute, cfg_unmute_cmd,
+ "unmute-talker", "Unmute talker's downlink")
+{
+ struct gcr *gcr = vty->index;
+
+ gcr->mute_talker = false;
+
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_timeout, cfg_timeout_cmd,
+ "timeout <1-65535>", "Set inactivity timer\n" "Timeout in seconds")
+{
+ struct gcr *gcr = vty->index;
+
+ gcr->timeout = atoi(argv[0]);
+
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_no_timeout, cfg_no_timeout_cmd,
+ "no timeout", NO_STR "Unset inactivity timer")
+{
+ struct gcr *gcr = vty->index;
+
+ gcr->timeout = 0;
+
+ return CMD_SUCCESS;
+}
+
+#define PC_ID_STR "Point code of MSC\nCell ID of BTS"
+
+DEFUN(cfg_no_cell, cfg_no_cell_cmd,
+ "no cell POINT_CODE [<0-65535>]", NO_STR "Remove BSS/cell from current group\n" PC_ID_STR)
+{
+ struct osmo_ss7_instance *ss7 = osmo_ss7_instance_find(0);
+ struct gcr *gcr = vty->index;
+ struct gcr_bss *bss;
+ int pc = osmo_ss7_pointcode_parse(ss7, argv[0]);
+ uint16_t cell_id;
+
+ if (pc < 0 || !osmo_ss7_pc_is_valid((uint32_t)pc)) {
+ vty_out(vty, "Invalid point code (%s)%s", argv[0], VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ bss = gcr_find_bss(gcr, pc);
+ if (!bss) {
+ vty_out(vty, "%%Given BSS point code does not exit in list!%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ if (argc > 1) {
+ cell_id = atoi(argv[1]);
+ if (!gcr_find_cell(bss, cell_id)) {
+ vty_out(vty, "%%Given cell does not exit in list!%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ /* Remove cell only. Exit if there are still cells for this BSS. */
+ gcr_rm_cell(bss, cell_id);
+ if (!llist_empty(&bss->cell_list))
+ return CMD_SUCCESS;
+ }
+
+ gcr_rm_bss(gcr, pc);
+
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_cell, cfg_cell_cmd,
+ "cell POINT_CODE <0-65535>", "Add cell to current group\n" PC_ID_STR)
+{
+ struct osmo_ss7_instance *ss7 = osmo_ss7_instance_find(0);
+ struct gcr *gcr = vty->index;
+ struct gcr_bss *bss;
+ int pc = osmo_ss7_pointcode_parse(ss7, argv[0]);
+ uint16_t cell_id = atoi(argv[1]);
+
+ if (pc < 0 || !osmo_ss7_pc_is_valid((uint32_t)pc)) {
+ vty_out(vty, "Invalid point code (%s)%s", argv[0], VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ bss = gcr_find_bss(gcr, pc);
+ if (!bss)
+ bss = gcr_add_bss(gcr, pc);
+ if (!bss)
+ return CMD_WARNING;
+
+ if (gcr_find_cell(bss, cell_id))
+ return CMD_SUCCESS;
+
+ gcr_add_cell(bss, cell_id);
+
+ return CMD_SUCCESS;
+}
+
+static int config_write_asci(struct vty *vty)
+{
+ struct osmo_ss7_instance *ss7 = osmo_ss7_instance_find(0);
+ struct gcr *gcr;
+ struct gcr_bss *b;
+ struct gcr_cell *c;
+
+ vty_out(vty, "asci%s", VTY_NEWLINE);
+
+ vty_out(vty, " %s%s", (gsmnet->asci.enable) ? "enable" : "disable", VTY_NEWLINE);
+
+ vty_out(vty, " gcr%s", VTY_NEWLINE);
+
+ llist_for_each_entry(gcr, &gsmnet->asci.gcr_lists, list) {
+ vty_out(vty, " %s %s%s", (gcr->trans_type == TRANS_GCC) ? "vgc" : "vbc", gcr->group_id, VTY_NEWLINE);
+ if (gcr->trans_type == TRANS_GCC) {
+ if (gcr->timeout)
+ vty_out(vty, " timeout %d%s", gcr->timeout, VTY_NEWLINE);
+ else
+ vty_out(vty, " no timeout%s", VTY_NEWLINE);
+ }
+ if (gcr->mute_talker)
+ vty_out(vty, " mute-talker%s", VTY_NEWLINE);
+ else
+ vty_out(vty, " unmute-talker%s", VTY_NEWLINE);
+ if (llist_empty(&gcr->bss_list))
+ vty_out(vty, " ! Please add cell(s) here!%s", VTY_NEWLINE);
+ llist_for_each_entry(b, &gcr->bss_list, list) {
+ llist_for_each_entry(c, &b->cell_list, list)
+ vty_out(vty, " cell %s %d%s", osmo_ss7_pointcode_print(ss7, b->pc), c->cell_id, VTY_NEWLINE);
+ }
+ }
+
+ return CMD_SUCCESS;
+}
+
+void asci_vty_init(struct gsm_network *msc_network)
+{
+ OSMO_ASSERT(gsmnet == NULL);
+ gsmnet = msc_network;
+
+ install_element_ve(&asci_show_cmd);
+ /* enable node */
+ install_element(ENABLE_NODE, &asci_call_cmd);
+ /* Config node */
+ install_element(CONFIG_NODE, &cfg_asci_cmd);
+ install_node(&asci_node, config_write_asci);
+ install_element(ASCI_NODE, &cfg_enable_disable_cmd);
+ install_element(ASCI_NODE, &cfg_gcr_cmd);
+ install_node(&gcr_node, NULL);
+ install_element(GCR_NODE, &cfg_vgc_cmd);
+ install_element(GCR_NODE, &cfg_no_vgc_cmd);
+ install_node(&vgc_node, NULL);
+ install_element(GCR_NODE, &cfg_vbc_cmd);
+ install_element(GCR_NODE, &cfg_no_vbc_cmd);
+ install_node(&vbc_node, NULL);
+ install_element(VGC_NODE, &cfg_mute_cmd);
+ install_element(VGC_NODE, &cfg_unmute_cmd);
+ install_element(VGC_NODE, &cfg_timeout_cmd);
+ install_element(VGC_NODE, &cfg_no_timeout_cmd);
+ install_element(VGC_NODE, &cfg_cell_cmd);
+ install_element(VGC_NODE, &cfg_no_cell_cmd);
+ /* Add all VGC_NODEs again for VBC_NODEs. */
+ install_element(VBC_NODE, &cfg_mute_cmd);
+ install_element(VBC_NODE, &cfg_unmute_cmd);
+ install_element(VBC_NODE, &cfg_cell_cmd);
+ install_element(VBC_NODE, &cfg_no_cell_cmd);
+}
diff --git a/src/libmsc/call_leg.c b/src/libmsc/call_leg.c
index 46405bcaa..59f2f636d 100644
--- a/src/libmsc/call_leg.c
+++ b/src/libmsc/call_leg.c
@@ -1,25 +1,21 @@
/* Implementation to manage two RTP streams that make up an MO or MT call leg's RTP forwarding. */
/*
- * (C) 2019 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de>
+ * (C) 2019 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
* All Rights Reserved
*
* Author: Neels Hofmeyr
*
- * SPDX-License-Identifier: GPL-2.0+
+ * SPDX-License-Identifier: AGPL-3.0+
*
* This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ * GNU Affero General Public License for more details.
*/
#include <osmocom/core/fsm.h>
#include <osmocom/mgcp_client/mgcp_client_endpoint_fsm.h>
@@ -43,7 +39,7 @@ enum call_leg_state {
};
struct osmo_tdef g_mgw_tdefs[] = {
- { .T=-1, .default_val=4, .desc="MGCP response timeout" },
+ { .T=-2427, .default_val=4, .desc="MGCP response timeout" },
{ .T=-2, .default_val=30, .desc="RTP stream establishing timeout" },
{}
};
@@ -126,7 +122,13 @@ void call_leg_release(struct call_leg *cl)
static void call_leg_mgw_endpoint_gone(struct call_leg *cl)
{
+ struct mgcp_client *mgcp_client;
int i;
+
+ /* Put MGCP client back into MGW pool */
+ mgcp_client = osmo_mgcpc_ep_client(cl->mgw_endpoint);
+ mgcp_client_pool_put(mgcp_client);
+
cl->mgw_endpoint = NULL;
for (i = 0; i < ARRAY_SIZE(cl->rtp); i++) {
if (!cl->rtp[i])
@@ -156,7 +158,8 @@ static void call_leg_fsm_establishing_established(struct osmo_fsm_inst *fi, uint
}
if (!established)
break;
- call_leg_state_chg(cl, CALL_LEG_ST_ESTABLISHED);
+ if (cl->fi->state != CALL_LEG_ST_ESTABLISHED)
+ call_leg_state_chg(cl, CALL_LEG_ST_ESTABLISHED);
break;
case CALL_LEG_EV_RTP_STREAM_ADDR_AVAILABLE:
@@ -186,6 +189,12 @@ void call_leg_fsm_established_onenter(struct osmo_fsm_inst *fi, uint32_t prev_st
void call_leg_fsm_releasing_onenter(struct osmo_fsm_inst *fi, uint32_t prev_state)
{
+ /* Trigger termination of children FSMs (rtp_stream(s)) before
+ * terminating ourselves, otherwise we are not able to receive
+ * CALL_LEG_EV_MGW_ENDPOINT_GONE from cl->mgw_endpoint (call_leg =>
+ * rtp_stream => mgw_endpoint), because osmo_fsm disabled dispatching
+ * events to an FSM in process of terminating. */
+ osmo_fsm_inst_term_children(fi, OSMO_FSM_TERM_PARENT, NULL);
osmo_fsm_inst_term(fi, OSMO_FSM_TERM_REGULAR, NULL);
}
@@ -279,16 +288,24 @@ int call_leg_ensure_rtp_alloc(struct call_leg *cl, enum rtp_direction dir, uint3
if (cl->rtp[dir])
return 0;
- if (!cl->mgw_endpoint)
+ if (!cl->mgw_endpoint) {
+ struct mgcp_client *mgcp_client = mgcp_client_pool_get(gsmnet->mgw.mgw_pool);
+ if (!mgcp_client) {
+ LOG_CALL_LEG(cl, LOGL_ERROR,
+ "cannot ensure MGW endpoint -- no MGW configured, check configuration!\n");
+ return -ENODEV;
+ }
cl->mgw_endpoint = osmo_mgcpc_ep_alloc(cl->fi, CALL_LEG_EV_MGW_ENDPOINT_GONE,
- gsmnet->mgw.client, gsmnet->mgw.tdefs, cl->fi->id,
- "%s", mgcp_client_rtpbridge_wildcard(gsmnet->mgw.client));
+ mgcp_client, gsmnet->mgw.tdefs, cl->fi->id,
+ "%s", mgcp_client_rtpbridge_wildcard(mgcp_client));
+ }
if (!cl->mgw_endpoint) {
LOG_CALL_LEG(cl, LOGL_ERROR, "failed to setup MGW endpoint\n");
return -EIO;
}
- cl->rtp[dir] = rtp_stream_alloc(cl, dir, call_id, for_trans);
+ cl->rtp[dir] = rtp_stream_alloc(cl->fi, CALL_LEG_EV_RTP_STREAM_GONE, CALL_LEG_EV_RTP_STREAM_ADDR_AVAILABLE,
+ CALL_LEG_EV_RTP_STREAM_ESTABLISHED, dir, call_id, for_trans);
OSMO_ASSERT(cl->rtp[dir]);
return 0;
}
@@ -301,7 +318,7 @@ struct osmo_sockaddr_str *call_leg_local_ip(struct call_leg *cl, enum rtp_direct
rtps = cl->rtp[dir];
if (!rtps)
return NULL;
- if (!osmo_sockaddr_str_is_set(&rtps->local))
+ if (!osmo_sockaddr_str_is_nonzero(&rtps->local))
return NULL;
return &rtps->local;
}
@@ -309,21 +326,26 @@ struct osmo_sockaddr_str *call_leg_local_ip(struct call_leg *cl, enum rtp_direct
/* Make sure an MGW endpoint CI is set up for an RTP connection.
* This is the one-stop for all to either completely set up a new endpoint connection, or to modify an existing one.
* If not yet present, allocate the rtp_stream for the given direction.
- * Then, call rtp_stream_set_codec() if codec_if_known is non-NULL, and/or rtp_stream_set_remote_addr() if
+ * Then, call rtp_stream_set_codecs() if codecs_if_known is non-NULL, and/or rtp_stream_set_remote_addr() if
* remote_addr_if_known is non-NULL.
* Finally make sure that a CRCX is sent out for this direction, if this has not already happened.
* If the CRCX has already happened but new codec / remote_addr data was passed, call rtp_stream_commit() to trigger an
* MDCX.
*/
int call_leg_ensure_ci(struct call_leg *cl, enum rtp_direction dir, uint32_t call_id, struct gsm_trans *for_trans,
- const enum mgcp_codecs *codec_if_known, const struct osmo_sockaddr_str *remote_addr_if_known)
+ const struct sdp_audio_codecs *codecs_if_known,
+ const struct osmo_sockaddr_str *remote_addr_if_known)
{
if (call_leg_ensure_rtp_alloc(cl, dir, call_id, for_trans))
return -EIO;
- cl->rtp[dir]->crcx_conn_mode = cl->crcx_conn_mode[dir];
- if (codec_if_known)
- rtp_stream_set_codec(cl->rtp[dir], *codec_if_known);
- if (remote_addr_if_known && osmo_sockaddr_str_is_set(remote_addr_if_known))
+ rtp_stream_set_mode(cl->rtp[dir], cl->crcx_conn_mode[dir]);
+ if (dir == RTP_TO_RAN && cl->ran_peer_supports_osmux) {
+ cl->rtp[dir]->use_osmux = true;
+ cl->rtp[dir]->remote_osmux_cid = -1; /* wildcard */
+ }
+ if (codecs_if_known)
+ rtp_stream_set_codecs(cl->rtp[dir], codecs_if_known);
+ if (remote_addr_if_known && osmo_sockaddr_str_is_nonzero(remote_addr_if_known))
rtp_stream_set_remote_addr(cl->rtp[dir], remote_addr_if_known);
return rtp_stream_ensure_ci(cl->rtp[dir], cl->mgw_endpoint);
}
@@ -331,22 +353,46 @@ int call_leg_ensure_ci(struct call_leg *cl, enum rtp_direction dir, uint32_t cal
int call_leg_local_bridge(struct call_leg *cl1, uint32_t call_id1, struct gsm_trans *trans1,
struct call_leg *cl2, uint32_t call_id2, struct gsm_trans *trans2)
{
- enum mgcp_codecs codec;
+ struct sdp_audio_codecs *cn_codecs = NULL;
cl1->local_bridge = cl2;
cl2->local_bridge = cl1;
- /* We may just copy the codec info we have for the RAN side of the first leg to the CN side of both legs. This
- * also means that if both legs use different codecs the MGW must perform transcoding on the second leg. */
- if (!cl1->rtp[RTP_TO_RAN] || !cl1->rtp[RTP_TO_RAN]->codec_known) {
- LOG_CALL_LEG(cl1, LOGL_ERROR, "RAN-side RTP stream codec is not known, not ready for bridging\n");
+ /* Marry the two CN sides of the call legs. Call establishment should have made all efforts for these to be
+ * compatible. However, for local bridging, the codecs and payload type numbers must be exactly identical on
+ * both sides. Both sides may so far have different payload type numbers or slightly differing codecs, but it
+ * will only work when the SDP on the RTP_TO_CN sides of the call legs talk the same payload type numbers.
+ * So, simply take the SDP from one RTP_TO_CN side, and overwrite the other RTP_TO_CN side's SDP with it.
+ * If all goes to plan, the codecs will be identical, or possibly the MGW will do a conversion like AMR-BE to
+ * AMR-OA. In the worst case, the other call leg cannot transcode, and the call fails -- because codec
+ * negotiation did not do a good enough job.
+ *
+ * Copy one call leg's CN config to the other:
+ *
+ * call leg 1 call leg 2
+ * ---MGW-ep------- ---MGW-ep-------
+ * RAN CN CN RAN
+ * AMR:112 AMR:112 AMR:96 AMR:96
+ * |
+ * +-------+
+ * |
+ * V
+ * AMR:112 AMR:112 AMR:112 AMR:96
+ * ^MGW-endpoint converts payload type numbers between 112 and 96.
+ */
+ if (cl1->rtp[RTP_TO_CN] && cl1->rtp[RTP_TO_CN]->codecs_known)
+ cn_codecs = &cl1->rtp[RTP_TO_CN]->codecs;
+ else if (cl2->rtp[RTP_TO_CN] && cl2->rtp[RTP_TO_CN]->codecs_known)
+ cn_codecs = &cl2->rtp[RTP_TO_CN]->codecs;
+ if (!cn_codecs) {
+ LOG_CALL_LEG(cl1, LOGL_ERROR, "RAN-side CN stream codec is not known, not ready for bridging\n");
+ LOG_CALL_LEG(cl2, LOGL_ERROR, "RAN-side CN stream codec is not known, not ready for bridging\n");
return -EINVAL;
}
- codec = cl1->rtp[RTP_TO_RAN]->codec;
call_leg_ensure_ci(cl1, RTP_TO_CN, call_id1, trans1,
- &codec, &cl2->rtp[RTP_TO_CN]->local);
+ cn_codecs, &cl2->rtp[RTP_TO_CN]->local);
call_leg_ensure_ci(cl2, RTP_TO_CN, call_id2, trans2,
- &codec, &cl1->rtp[RTP_TO_CN]->local);
+ cn_codecs, &cl1->rtp[RTP_TO_CN]->local);
return 0;
}
diff --git a/src/libmsc/cell_id_list.c b/src/libmsc/cell_id_list.c
index ca7a6d43b..4bf3a76de 100644
--- a/src/libmsc/cell_id_list.c
+++ b/src/libmsc/cell_id_list.c
@@ -1,25 +1,21 @@
/* Manage a list of struct gsm0808_cell_id */
/*
- * (C) 2019 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de>
+ * (C) 2019 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
* All Rights Reserved
*
* Author: Neels Hofmeyr
*
- * SPDX-License-Identifier: GPL-2.0+
+ * SPDX-License-Identifier: AGPL-3.0+
*
* This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ * GNU Affero General Public License for more details.
*/
#include <osmocom/msc/cell_id_list.h>
diff --git a/src/libmsc/codec_filter.c b/src/libmsc/codec_filter.c
new file mode 100644
index 000000000..7511f9026
--- /dev/null
+++ b/src/libmsc/codec_filter.c
@@ -0,0 +1,163 @@
+/* Filter/overlay codec selections for a voice call, across MS, RAN and CN limitations */
+/*
+ * (C) 2019-2023 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
+ * All Rights Reserved
+ *
+ * Author: Neels Hofmeyr
+ *
+ * SPDX-License-Identifier: AGPL-3.0+
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <osmocom/gsm/protocol/gsm_08_08.h>
+
+#include <osmocom/msc/codec_filter.h>
+#include <osmocom/msc/codec_mapping.h>
+#include <osmocom/msc/debug.h>
+
+/* Add all known payload types encountered in GSM networks */
+static void sdp_add_all_geran_codecs(struct sdp_audio_codecs *ac)
+{
+ /* In order of preference. TODO: make configurable */
+ static const enum gsm48_bcap_speech_ver mobile_codecs[] = {
+ GSM48_BCAP_SV_AMR_F /*!< 4 GSM FR V3 (FR AMR) */,
+ GSM48_BCAP_SV_AMR_H /*!< 5 GSM HR V3 (HR_AMR) */,
+ GSM48_BCAP_SV_EFR /*!< 2 GSM FR V2 (GSM EFR) */,
+ GSM48_BCAP_SV_FR /*!< 0 GSM FR V1 (GSM FR) */,
+ GSM48_BCAP_SV_HR /*!< 1 GSM HR V1 (GSM HR) */,
+ };
+ int i;
+ for (i = 0; i < ARRAY_SIZE(mobile_codecs); i++)
+ sdp_audio_codecs_add_speech_ver(ac, mobile_codecs[i]);
+}
+
+/* Add all known AMR payload types encountered in UTRAN networks */
+static void sdp_add_all_utran_codecs(struct sdp_audio_codecs *ac)
+{
+ /* In order of preference. TODO: make configurable */
+ static const enum gsm48_bcap_speech_ver utran_codecs[] = {
+ GSM48_BCAP_SV_AMR_F /*!< 4 GSM FR V3 (FR AMR) */,
+ GSM48_BCAP_SV_AMR_H /*!< 5 GSM HR V3 (HR_AMR) */,
+ GSM48_BCAP_SV_AMR_OH /*!< 11 GSM HR V6 (OHR AMR) */,
+ GSM48_BCAP_SV_AMR_FW /*!< 8 GSM FR V5 (FR AMR-WB) */,
+ GSM48_BCAP_SV_AMR_OFW /*!< 6 GSM FR V4 (OFR AMR-WB) */,
+ GSM48_BCAP_SV_AMR_OHW /*!< 7 GSM HR V4 (OHR AMR-WB) */,
+ };
+ int i;
+ for (i = 0; i < ARRAY_SIZE(utran_codecs); i++)
+ sdp_audio_codecs_add_speech_ver(ac, utran_codecs[i]);
+}
+
+void codec_filter_set_ran(struct codec_filter *codec_filter, enum osmo_rat_type ran_type)
+{
+ codec_filter->ran = (struct sdp_audio_codecs){};
+
+ switch (ran_type) {
+ default:
+ case OSMO_RAT_GERAN_A:
+ sdp_add_all_geran_codecs(&codec_filter->ran);
+ break;
+
+ case OSMO_RAT_UTRAN_IU:
+ sdp_add_all_utran_codecs(&codec_filter->ran);
+ break;
+ }
+}
+
+void codec_filter_set_bss(struct codec_filter *codec_filter,
+ const struct gsm0808_speech_codec_list *codec_list_bss_supported)
+{
+ codec_filter->bss = (struct sdp_audio_codecs){};
+ if (codec_list_bss_supported)
+ sdp_audio_codecs_from_speech_codec_list(&codec_filter->bss, codec_list_bss_supported);
+}
+
+/* Render intersections of all known audio codec constraints to reach a resulting choice of favorite audio codec, plus
+ * possible set of alternative audio codecs, in codec_filter->result. (The result.rtp address remains unchanged.) */
+int codec_filter_run(struct codec_filter *codec_filter, struct sdp_msg *result, const struct sdp_msg *remote)
+{
+ struct sdp_audio_codecs *r = &result->audio_codecs;
+ struct sdp_audio_codec *a = &codec_filter->assignment;
+ *r = codec_filter->ran;
+ if (codec_filter->ms.count)
+ sdp_audio_codecs_intersection(r, &codec_filter->ms, false);
+ if (codec_filter->bss.count)
+ sdp_audio_codecs_intersection(r, &codec_filter->bss, false);
+ if (remote->audio_codecs.count)
+ sdp_audio_codecs_intersection(r, &remote->audio_codecs, true);
+
+ if (sdp_audio_codec_is_set(a)) {
+ /* Assignment has completed, the chosen codec should be the first of the resulting SDP.
+ * If present, make sure this is listed in first place.
+ * If 'select' is NULL, the assigned codec is not present in the intersection of possible choices for
+ * TFO. Just omit the assigned codec from the filter result, and it is the CC code's responsibility to
+ * detect this and assign a working codec instead. */
+ struct sdp_audio_codec *select = sdp_audio_codecs_by_descr(r, a);
+ if (select)
+ sdp_audio_codecs_select(r, select);
+ }
+ return 0;
+}
+
+int codec_filter_to_str_buf(char *buf, size_t buflen, const struct codec_filter *codec_filter,
+ const struct sdp_msg *result, const struct sdp_msg *remote)
+{
+ struct osmo_strbuf sb = { .buf = buf, .len = buflen };
+ OSMO_STRBUF_APPEND(sb, sdp_msg_to_str_buf, result);
+ OSMO_STRBUF_PRINTF(sb, " (from:");
+
+ if (sdp_audio_codec_is_set(&codec_filter->assignment)) {
+ OSMO_STRBUF_PRINTF(sb, " assigned=");
+ OSMO_STRBUF_APPEND(sb, sdp_audio_codec_to_str_buf, &codec_filter->assignment);
+ }
+
+ if (remote->audio_codecs.count
+ || osmo_sockaddr_str_is_nonzero(&remote->rtp)) {
+ OSMO_STRBUF_PRINTF(sb, " remote=");
+ OSMO_STRBUF_APPEND(sb, sdp_msg_to_str_buf, remote);
+ }
+
+ if (codec_filter->ms.count) {
+ OSMO_STRBUF_PRINTF(sb, " MS={");
+ OSMO_STRBUF_APPEND(sb, sdp_audio_codecs_to_str_buf, &codec_filter->ms);
+ OSMO_STRBUF_PRINTF(sb, "}");
+ }
+
+ if (codec_filter->bss.count) {
+ OSMO_STRBUF_PRINTF(sb, " bss={");
+ OSMO_STRBUF_APPEND(sb, sdp_audio_codecs_to_str_buf, &codec_filter->bss);
+ OSMO_STRBUF_PRINTF(sb, "}");
+ }
+
+ OSMO_STRBUF_PRINTF(sb, " RAN={");
+ OSMO_STRBUF_APPEND(sb, sdp_audio_codecs_to_str_buf, &codec_filter->ran);
+ OSMO_STRBUF_PRINTF(sb, "}");
+
+ OSMO_STRBUF_PRINTF(sb, ")");
+
+ return sb.chars_needed;
+}
+
+char *codec_filter_to_str_c(void *ctx, const struct codec_filter *codec_filter, const struct sdp_msg *result,
+ const struct sdp_msg *remote)
+{
+ OSMO_NAME_C_IMPL(ctx, 128, "codec_filter_to_str_c-ERROR", codec_filter_to_str_buf, codec_filter, result, remote)
+}
+
+const char *codec_filter_to_str(const struct codec_filter *codec_filter, const struct sdp_msg *result,
+ const struct sdp_msg *remote)
+{
+ return codec_filter_to_str_c(OTC_SELECT, codec_filter, result, remote);
+}
diff --git a/src/libmsc/codec_mapping.c b/src/libmsc/codec_mapping.c
new file mode 100644
index 000000000..bb5968f0e
--- /dev/null
+++ b/src/libmsc/codec_mapping.c
@@ -0,0 +1,547 @@
+/* Routines for translation between codec representations: SDP, CC/BSSMAP variants, MGCP, MNCC */
+/*
+ * (C) 2019-2023 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
+ * All Rights Reserved
+ *
+ * Author: Neels Hofmeyr
+ *
+ * SPDX-License-Identifier: AGPL-3.0+
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <string.h>
+
+#include <osmocom/gsm/mncc.h>
+
+#include <osmocom/msc/sdp_msg.h>
+#include <osmocom/msc/codec_mapping.h>
+#include <osmocom/msc/mncc.h>
+
+const struct codec_mapping codec_map[] = {
+ /* FIXME: sdp.fmtp handling is not done properly yet, proper mode-set and octet-align handling will follow in
+ * separate patches. */
+ {
+ .sdp = {
+ .payload_type = 0,
+ .subtype_name = "PCMU",
+ .rate = 8000,
+ },
+ .mgcp = CODEC_PCMU_8000_1,
+ },
+ {
+ .sdp = {
+ .payload_type = 3,
+ .subtype_name = "GSM",
+ .rate = 8000,
+ },
+ .mgcp = CODEC_GSM_8000_1,
+ .speech_ver_count = 1,
+ .speech_ver = { GSM48_BCAP_SV_FR },
+ .mncc_payload_msg_type = GSM_TCHF_FRAME,
+ .has_gsm0808_speech_codec = true,
+ .gsm0808_speech_codec = {
+ .fi = true,
+ .type = GSM0808_SCT_FR1,
+ },
+ .perm_speech = GSM0808_PERM_FR1,
+ .frhr = CODEC_FRHR_FR,
+ },
+ {
+ .sdp = {
+ .payload_type = 8,
+ .subtype_name = "PCMA",
+ .rate = 8000,
+ },
+ .mgcp = CODEC_PCMA_8000_1,
+ },
+ {
+ .sdp = {
+ .payload_type = 18,
+ .subtype_name = "G729",
+ .rate = 8000,
+ },
+ .mgcp = CODEC_G729_8000_1,
+ },
+ {
+ .sdp = {
+ .payload_type = 110,
+ .subtype_name = "GSM-EFR",
+ .rate = 8000,
+ },
+ .mgcp = CODEC_GSMEFR_8000_1,
+ .speech_ver_count = 1,
+ .speech_ver = { GSM48_BCAP_SV_EFR },
+ .mncc_payload_msg_type = GSM_TCHF_FRAME_EFR,
+ .has_gsm0808_speech_codec = true,
+ .gsm0808_speech_codec = {
+ .fi = true,
+ .type = GSM0808_SCT_FR2,
+ },
+ .perm_speech = GSM0808_PERM_FR2,
+ .frhr = CODEC_FRHR_FR,
+ },
+ {
+ .sdp = {
+ .payload_type = 111,
+ .subtype_name = "GSM-HR-08",
+ .rate = 8000,
+ },
+ .mgcp = CODEC_GSMHR_8000_1,
+ .speech_ver_count = 1,
+ .speech_ver = { GSM48_BCAP_SV_HR },
+ .mncc_payload_msg_type = GSM_TCHH_FRAME,
+ .has_gsm0808_speech_codec = true,
+ .gsm0808_speech_codec = {
+ .fi = true,
+ .type = GSM0808_SCT_HR1,
+ },
+ .perm_speech = GSM0808_PERM_HR1,
+ .frhr = CODEC_FRHR_HR,
+ },
+ {
+ .sdp = {
+ /* 112 is just what we use by default. The other call leg may impose a different number. */
+ .payload_type = 112,
+ .subtype_name = "AMR",
+ .rate = 8000,
+ /* AMR is always octet-aligned in 2G and 3G RAN, so this fmtp is signalled to remote call legs.
+ * So far, fmtp is ignored in incoming SIP SDP, so an incoming SDP without 'octet-align=1' will
+ * match with this entry; we will still reply with 'octet-align=1', which often works out. */
+ .fmtp = "octet-align=1",
+ },
+ .mgcp = CODEC_AMR_8000_1,
+ .speech_ver_count = 1,
+ .speech_ver = { GSM48_BCAP_SV_AMR_F },
+ .mncc_payload_msg_type = GSM_TCH_FRAME_AMR,
+ .has_gsm0808_speech_codec = true,
+ .gsm0808_speech_codec = {
+ .fi = true,
+ .type = GSM0808_SCT_FR3,
+ .cfg = GSM0808_SC_CFG_DEFAULT_FR_AMR,
+ },
+ .perm_speech = GSM0808_PERM_FR3,
+ .frhr = CODEC_FRHR_FR,
+ },
+ {
+ /* Another entry like the above, to map HR3 to AMR, too. */
+ .sdp = {
+ .payload_type = 112,
+ .subtype_name = "AMR",
+ .rate = 8000,
+ .fmtp = "octet-align=1",
+ },
+ .mgcp = CODEC_AMR_8000_1,
+ .speech_ver_count = 2,
+ .speech_ver = { GSM48_BCAP_SV_AMR_H, GSM48_BCAP_SV_AMR_OH },
+ .mncc_payload_msg_type = GSM_TCH_FRAME_AMR,
+ .has_gsm0808_speech_codec = true,
+ .gsm0808_speech_codec = {
+ .fi = true,
+ .type = GSM0808_SCT_HR3,
+ .cfg = GSM0808_SC_CFG_DEFAULT_HR_AMR,
+ },
+ .perm_speech = GSM0808_PERM_HR3,
+ .frhr = CODEC_FRHR_HR,
+ },
+ {
+ .sdp = {
+ .payload_type = 113,
+ .subtype_name = "AMR-WB",
+ .rate = 16000,
+ .fmtp = "octet-align=1",
+ },
+ .mgcp = CODEC_AMRWB_16000_1,
+ .speech_ver_count = 2,
+ .speech_ver = { GSM48_BCAP_SV_AMR_OFW, GSM48_BCAP_SV_AMR_FW },
+ .mncc_payload_msg_type = GSM_TCH_FRAME_AMR,
+ .has_gsm0808_speech_codec = true,
+ .gsm0808_speech_codec = {
+ .fi = true,
+ .type = GSM0808_SCT_FR5,
+ .cfg = GSM0808_SC_CFG_DEFAULT_FR_AMR_WB,
+ },
+ .perm_speech = GSM0808_PERM_FR5,
+ .frhr = CODEC_FRHR_FR,
+ },
+ {
+ /* Another entry like the above, to map HR4 to AMR-WB, too. */
+ .sdp = {
+ .payload_type = 113,
+ .subtype_name = "AMR-WB",
+ .rate = 16000,
+ .fmtp = "octet-align=1",
+ },
+ .mgcp = CODEC_AMRWB_16000_1,
+ .speech_ver_count = 1,
+ .speech_ver = { GSM48_BCAP_SV_AMR_OHW },
+ .mncc_payload_msg_type = GSM_TCH_FRAME_AMR,
+ .has_gsm0808_speech_codec = true,
+ .gsm0808_speech_codec = {
+ .fi = true,
+ .type = GSM0808_SCT_HR4,
+ .cfg = GSM0808_SC_CFG_DEFAULT_OHR_AMR_WB,
+ },
+ .perm_speech = GSM0808_PERM_HR4,
+ .frhr = CODEC_FRHR_HR,
+ },
+ {
+ .sdp = {
+ .payload_type = 96,
+ .subtype_name = "VND.3GPP.IUFP",
+ .rate = 16000,
+ },
+ .mgcp = CODEC_IUFP,
+ },
+ {
+ .sdp = {
+ .payload_type = 120,
+ .subtype_name = "CLEARMODE",
+ .rate = 8000,
+ },
+ .has_gsm0808_speech_codec = true,
+ .gsm0808_speech_codec = {
+ .pi = true, /* PI indicates CSDoIP is supported */
+ .pt = false, /* PT indicates CSDoTDM is not supported */
+ .type = GSM0808_SCT_CSD,
+ .cfg = 0, /* R2/R3 not set (redundancy not supported) */
+ },
+ .mgcp = CODEC_CLEARMODE,
+ },
+};
+
+#define foreach_codec_mapping(CODEC_MAPPING) \
+ for ((CODEC_MAPPING) = codec_map; (CODEC_MAPPING) < codec_map + ARRAY_SIZE(codec_map); (CODEC_MAPPING)++)
+
+const struct gsm_mncc_bearer_cap bearer_cap_empty = {
+ .speech_ver = { -1 },
+ };
+
+const struct codec_mapping *codec_mapping_by_speech_ver(enum gsm48_bcap_speech_ver speech_ver)
+{
+ const struct codec_mapping *m;
+ foreach_codec_mapping(m) {
+ int i;
+ for (i = 0; i < m->speech_ver_count; i++)
+ if (m->speech_ver[i] == speech_ver)
+ return m;
+ }
+ return NULL;
+}
+
+const struct codec_mapping *codec_mapping_by_gsm0808_speech_codec_type(enum gsm0808_speech_codec_type sct)
+{
+ const struct codec_mapping *m;
+ foreach_codec_mapping(m) {
+ if (!m->has_gsm0808_speech_codec)
+ continue;
+ if (m->gsm0808_speech_codec.type == sct)
+ return m;
+ }
+ return NULL;
+}
+
+const struct codec_mapping *codec_mapping_by_gsm0808_speech_codec(const struct gsm0808_speech_codec *sc)
+{
+ const struct codec_mapping *m;
+ foreach_codec_mapping(m) {
+ if (!m->has_gsm0808_speech_codec)
+ continue;
+ if (m->gsm0808_speech_codec.type != sc->type)
+ continue;
+ /* Return only those where sc->cfg is a subset of m->gsm0808_speech_codec.cfg. */
+ if ((m->gsm0808_speech_codec.cfg & sc->cfg) != sc->cfg)
+ continue;
+ return m;
+ }
+ return NULL;
+}
+
+const struct codec_mapping *codec_mapping_by_perm_speech(enum gsm0808_permitted_speech perm_speech)
+{
+ const struct codec_mapping *m;
+ foreach_codec_mapping(m) {
+ if (m->perm_speech == perm_speech)
+ return m;
+ }
+ return NULL;
+}
+
+const struct codec_mapping *codec_mapping_by_subtype_name(const char *subtype_name)
+{
+ const struct codec_mapping *m;
+ foreach_codec_mapping(m) {
+ if (!strcmp(m->sdp.subtype_name, subtype_name))
+ return m;
+ }
+ return NULL;
+}
+
+const struct codec_mapping *codec_mapping_by_mgcp_codec(enum mgcp_codecs mgcp)
+{
+ const struct codec_mapping *m;
+ foreach_codec_mapping(m) {
+ if (m->mgcp == mgcp)
+ return m;
+ }
+ return NULL;
+}
+
+/* Append given Speech Version to the end of the Bearer Capabilities Speech Version array. Return 1 if added, zero
+ * otherwise (as in, return the number of items added). */
+int bearer_cap_add_speech_ver(struct gsm_mncc_bearer_cap *bearer_cap, enum gsm48_bcap_speech_ver speech_ver)
+{
+ int i;
+ for (i = 0; i < ARRAY_SIZE(bearer_cap->speech_ver) - 1; i++) {
+ if (bearer_cap->speech_ver[i] == speech_ver)
+ return 0;
+ if (bearer_cap->speech_ver[i] == -1) {
+ bearer_cap->speech_ver[i] = speech_ver;
+ bearer_cap->speech_ver[i+1] = -1;
+ return 1;
+ }
+ }
+ return 0;
+}
+
+/* From the current speech_ver list present in the bearer_cap, set the bearer_cap.radio.
+ * If a HR speech_ver is present, set to GSM48_BCAP_RRQ_DUAL_FR, otherwise set to GSM48_BCAP_RRQ_FR_ONLY. */
+int bearer_cap_set_radio(struct gsm_mncc_bearer_cap *bearer_cap)
+{
+ bool hr_present = false;
+ int i;
+ for (i = 0; i < ARRAY_SIZE(bearer_cap->speech_ver) - 1; i++) {
+ const struct codec_mapping *m;
+
+ if (bearer_cap->speech_ver[i] == -1)
+ break;
+
+ m = codec_mapping_by_speech_ver(bearer_cap->speech_ver[i]);
+
+ if (!m)
+ continue;
+
+ if (m->frhr == CODEC_FRHR_HR)
+ hr_present = true;
+ }
+
+ if (hr_present)
+ bearer_cap->radio = GSM48_BCAP_RRQ_DUAL_FR;
+ else
+ bearer_cap->radio = GSM48_BCAP_RRQ_FR_ONLY;
+
+ return 0;
+}
+
+/* Try to convert the SDP audio codec name to Speech Versions to append to Bearer Capabilities.
+ * Return the number of Speech Version entries added (some may add more than one, others may be unknown/unapplicable and
+ * return 0). */
+int sdp_audio_codec_add_to_bearer_cap(struct gsm_mncc_bearer_cap *bearer_cap, const struct sdp_audio_codec *codec)
+{
+ const struct codec_mapping *m;
+ int added = 0;
+ foreach_codec_mapping(m) {
+ int i;
+ if (strcmp(m->sdp.subtype_name, codec->subtype_name))
+ continue;
+ /* TODO also match rate and fmtp? */
+ for (i = 0; i < m->speech_ver_count; i++)
+ added += bearer_cap_add_speech_ver(bearer_cap, m->speech_ver[i]);
+ }
+ return added;
+}
+
+/* Append all audio codecs found in given sdp_msg to Bearer Capability, by traversing all codec entries with
+ * sdp_audio_codec_add_to_bearer_cap(). Return the number of Speech Version entries added.
+ * Note that Speech Version entries are only appended, no previous entries are removed.
+ * Note that only the Speech Version entries are modified; to make a valid Bearer Capabiliy, at least bearer_cap->radio
+ * must also be set (before or after this function); see also bearer_cap_set_radio(). */
+int sdp_audio_codecs_to_bearer_cap(struct gsm_mncc_bearer_cap *bearer_cap, const struct sdp_audio_codecs *ac)
+{
+ const struct sdp_audio_codec *codec;
+ int added = 0;
+
+ sdp_audio_codecs_foreach(codec, ac) {
+ added += sdp_audio_codec_add_to_bearer_cap(bearer_cap, codec);
+ }
+
+ return added;
+}
+
+/* Convert Speech Version to SDP audio codec and append to SDP message struct. */
+struct sdp_audio_codec *sdp_audio_codecs_add_speech_ver(struct sdp_audio_codecs *ac,
+ enum gsm48_bcap_speech_ver speech_ver)
+{
+ const struct codec_mapping *m;
+ struct sdp_audio_codec *ret = NULL;
+ foreach_codec_mapping(m) {
+ int i;
+ for (i = 0; i < m->speech_ver_count; i++) {
+ if (m->speech_ver[i] == speech_ver) {
+ ret = sdp_audio_codecs_add_copy(ac, &m->sdp);
+ break;
+ }
+ }
+ }
+ return ret;
+}
+
+struct sdp_audio_codec *sdp_audio_codecs_add_mgcp_codec(struct sdp_audio_codecs *ac, enum mgcp_codecs mgcp_codec)
+{
+ const struct codec_mapping *m = codec_mapping_by_mgcp_codec(mgcp_codec);
+ if (!m)
+ return NULL;
+ return sdp_audio_codecs_add_copy(ac, &m->sdp);
+}
+
+void sdp_audio_codecs_from_bearer_cap(struct sdp_audio_codecs *ac, const struct gsm_mncc_bearer_cap *bc)
+{
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(bc->speech_ver); i++) {
+ if (bc->speech_ver[i] == -1)
+ break;
+ sdp_audio_codecs_add_speech_ver(ac, bc->speech_ver[i]);
+ }
+}
+
+/* Append an entry for the given sdp_audio_codec to the gsm0808_speech_codec_list.
+ * Return 0 if an entry was added, -ENOENT when there is no mapping to gsm0808_speech_codec for the given
+ * sdp_audio_codec, and -ENOSPC when scl is full and nothing could be added. */
+int sdp_audio_codec_to_speech_codec_list(struct gsm0808_speech_codec_list *scl, const struct sdp_audio_codec *codec)
+{
+ const struct codec_mapping *m = codec_mapping_by_subtype_name(codec->subtype_name);
+ if (!m)
+ return -ENOENT;
+ if (!m->has_gsm0808_speech_codec)
+ return -ENOENT;
+ if (scl->len >= ARRAY_SIZE(scl->codec))
+ return -ENOSPC;
+ scl->codec[scl->len] = m->gsm0808_speech_codec;
+ /* FIXME: apply AMR configuration according to codec->fmtp */
+ scl->len++;
+ return 0;
+}
+
+void sdp_audio_codecs_to_speech_codec_list(struct gsm0808_speech_codec_list *scl, const struct sdp_audio_codecs *ac)
+{
+ const struct sdp_audio_codec *codec;
+
+ *scl = (struct gsm0808_speech_codec_list){};
+
+ sdp_audio_codecs_foreach(codec, ac) {
+ int rc = sdp_audio_codec_to_speech_codec_list(scl, codec);
+ if (rc == -ENOSPC)
+ break;
+ }
+}
+
+void sdp_audio_codecs_from_speech_codec_list(struct sdp_audio_codecs *ac, const struct gsm0808_speech_codec_list *cl)
+{
+ int i;
+ for (i = 0; i < cl->len; i++) {
+ const struct gsm0808_speech_codec *sc = &cl->codec[i];
+ const struct codec_mapping *m = codec_mapping_by_gsm0808_speech_codec(sc);
+ if (!m)
+ continue;
+ sdp_audio_codecs_add_copy(ac, &m->sdp);
+ /* FIXME: for AMR, apply sc->cfg to the added codec's fmtp */
+ }
+}
+
+int sdp_audio_codecs_to_gsm0808_channel_type(struct gsm0808_channel_type *ct, const struct sdp_audio_codecs *ac)
+{
+ const struct sdp_audio_codec *codec;
+ bool fr_present = false;
+ int first_fr_idx = -1;
+ bool hr_present = false;
+ int first_hr_idx = -1;
+ int idx = -1;
+
+ *ct = (struct gsm0808_channel_type){
+ .ch_indctr = GSM0808_CHAN_SPEECH,
+ };
+
+ sdp_audio_codecs_foreach(codec, ac) {
+ const struct codec_mapping *m;
+ int i;
+ bool dup;
+ idx++;
+ foreach_codec_mapping(m) {
+ if (strcmp(m->sdp.subtype_name, codec->subtype_name))
+ continue;
+
+ switch (m->perm_speech) {
+ default:
+ continue;
+
+ case GSM0808_PERM_FR1:
+ case GSM0808_PERM_FR2:
+ case GSM0808_PERM_FR3:
+ case GSM0808_PERM_FR4:
+ case GSM0808_PERM_FR5:
+ fr_present = true;
+ if (first_fr_idx < 0)
+ first_fr_idx = idx;
+ break;
+
+ case GSM0808_PERM_HR1:
+ case GSM0808_PERM_HR2:
+ case GSM0808_PERM_HR3:
+ case GSM0808_PERM_HR4:
+ case GSM0808_PERM_HR6:
+ hr_present = true;
+ if (first_hr_idx < 0)
+ first_hr_idx = idx;
+ break;
+ }
+
+ /* Avoid duplicates */
+ dup = false;
+ for (i = 0; i < ct->perm_spch_len; i++) {
+ if (ct->perm_spch[i] == m->perm_speech) {
+ dup = true;
+ break;
+ }
+ }
+ if (dup)
+ continue;
+
+ ct->perm_spch[ct->perm_spch_len] = m->perm_speech;
+ ct->perm_spch_len++;
+ }
+ }
+
+ if (fr_present && hr_present) {
+ if (first_fr_idx <= first_hr_idx)
+ ct->ch_rate_type = GSM0808_SPEECH_FULL_PREF;
+ else
+ ct->ch_rate_type = GSM0808_SPEECH_HALF_PREF;
+ } else if (fr_present && !hr_present)
+ ct->ch_rate_type = GSM0808_SPEECH_FULL_BM;
+ else if (!fr_present && hr_present)
+ ct->ch_rate_type = GSM0808_SPEECH_HALF_LM;
+ else
+ return -EINVAL;
+ return 0;
+}
+
+enum mgcp_codecs sdp_audio_codec_to_mgcp_codec(const struct sdp_audio_codec *codec)
+{
+ const struct codec_mapping *m;
+ foreach_codec_mapping(m) {
+ if (!sdp_audio_codec_cmp(&m->sdp, codec, false, false))
+ return m->mgcp;
+ }
+ return NO_MGCP_CODEC;
+}
diff --git a/src/libmsc/csd_bs.c b/src/libmsc/csd_bs.c
new file mode 100644
index 000000000..ab0b64309
--- /dev/null
+++ b/src/libmsc/csd_bs.c
@@ -0,0 +1,517 @@
+/* 3GPP TS 122.002 Bearer Services */
+/*
+ * (C) 2023 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
+ * All Rights Reserved
+ *
+ * Author: Oliver Smith
+ *
+ * SPDX-License-Identifier: AGPL-3.0+
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <errno.h>
+
+#include <osmocom/msc/csd_bs.h>
+#include <osmocom/msc/debug.h>
+
+/* csd_bs related below */
+
+struct csd_bs_map {
+ /* BS number (20, 21, ...) */
+ unsigned int num;
+ /* Access Structure (1: asynchronous, 0: synchronous) */
+ bool async;
+ /* QoS Attribute (1: transparent, 0: non-transparent) */
+ bool transp;
+ /* Rate Adaption (V110, V120 etc.) */
+ enum gsm48_bcap_ra ra;
+ /* Fixed Network User Rate */
+ unsigned int rate;
+};
+
+static const struct csd_bs_map bs_map[] = {
+ /* 3.1.1.1.2 */
+ [CSD_BS_21_T_V110_0k3] = {
+ .num = 21,
+ .async = true,
+ .transp = true,
+ .ra = GSM48_BCAP_RA_V110_X30,
+ .rate = 300,
+ },
+ [CSD_BS_22_T_V110_1k2] = {
+ .num = 22,
+ .async = true,
+ .transp = true,
+ .ra = GSM48_BCAP_RA_V110_X30,
+ .rate = 1200,
+ },
+ [CSD_BS_24_T_V110_2k4] = {
+ .num = 24,
+ .async = true,
+ .transp = true,
+ .ra = GSM48_BCAP_RA_V110_X30,
+ .rate = 2400,
+ },
+ [CSD_BS_25_T_V110_4k8] = {
+ .num = 25,
+ .async = true,
+ .transp = true,
+ .ra = GSM48_BCAP_RA_V110_X30,
+ .rate = 4800,
+ },
+ [CSD_BS_26_T_V110_9k6] = {
+ .num = 26,
+ .async = true,
+ .transp = true,
+ .ra = GSM48_BCAP_RA_V110_X30,
+ .rate = 9600,
+ },
+
+ /* 3.1.1.2.2 */
+ [CSD_BS_21_NT_V110_0k3] = {
+ .num = 21,
+ .async = true,
+ .transp = false,
+ .ra = GSM48_BCAP_RA_V110_X30,
+ .rate = 300,
+ },
+ [CSD_BS_22_NT_V110_1k2] = {
+ .num = 22,
+ .async = true,
+ .transp = false,
+ .ra = GSM48_BCAP_RA_V110_X30,
+ .rate = 1200,
+ },
+ [CSD_BS_24_NT_V110_2k4] = {
+ .num = 24,
+ .async = true,
+ .transp = false,
+ .ra = GSM48_BCAP_RA_V110_X30,
+ .rate = 2400,
+ },
+ [CSD_BS_25_NT_V110_4k8] = {
+ .num = 25,
+ .async = true,
+ .transp = false,
+ .ra = GSM48_BCAP_RA_V110_X30,
+ .rate = 4800,
+ },
+ [CSD_BS_26_NT_V110_9k6] = {
+ .num = 26,
+ .async = true,
+ .transp = false,
+ .ra = GSM48_BCAP_RA_V110_X30,
+ .rate = 9600,
+ },
+
+ /* 3.1.2.1.2 */
+ [CSD_BS_31_T_V110_1k2] = {
+ .num = 31,
+ .async = false,
+ .transp = true,
+ .ra = GSM48_BCAP_RA_V110_X30,
+ .rate = 1200,
+ },
+ [CSD_BS_32_T_V110_2k4] = {
+ .num = 32,
+ .async = false,
+ .transp = true,
+ .ra = GSM48_BCAP_RA_V110_X30,
+ .rate = 2400,
+ },
+ [CSD_BS_33_T_V110_4k8] = {
+ .num = 33,
+ .async = false,
+ .transp = true,
+ .ra = GSM48_BCAP_RA_V110_X30,
+ .rate = 4800,
+ },
+ [CSD_BS_34_T_V110_9k6] = {
+ .num = 34,
+ .async = false,
+ .transp = true,
+ .ra = GSM48_BCAP_RA_V110_X30,
+ .rate = 9600,
+ },
+};
+
+osmo_static_assert(ARRAY_SIZE(bs_map) == CSD_BS_MAX, _invalid_size_bs_map);
+
+bool csd_bs_is_transp(enum csd_bs bs)
+{
+ return bs_map[bs].transp;
+}
+
+/* Short single-line representation, convenient for logging.
+ * Like "BS25NT" */
+int csd_bs_to_str_buf(char *buf, size_t buflen, enum csd_bs bs)
+{
+ struct osmo_strbuf sb = { .buf = buf, .len = buflen };
+ const struct csd_bs_map *map = &bs_map[bs];
+
+ OSMO_STRBUF_PRINTF(sb, "BS%u%s",
+ map->num,
+ map->transp ? "T" : "NT");
+
+ if (map->ra != GSM48_BCAP_RA_V110_X30)
+ OSMO_STRBUF_PRINTF(sb, "-RA=%d", map->ra);
+
+ return sb.chars_needed;
+}
+
+char *csd_bs_to_str_c(void *ctx, enum csd_bs bs)
+{
+ OSMO_NAME_C_IMPL(ctx, 32, "csd_bs_to_str_c-ERROR", csd_bs_to_str_buf, bs)
+}
+
+const char *csd_bs_to_str(enum csd_bs bs)
+{
+ return csd_bs_to_str_c(OTC_SELECT, bs);
+}
+
+static int csd_bs_to_gsm0808_data_rate_transp(enum csd_bs bs, uint8_t *ch_rate_type)
+{
+ switch (bs_map[bs].rate) {
+ case 300:
+ *ch_rate_type = GSM0808_DATA_FULL_PREF;
+ return GSM0808_DATA_RATE_TRANSP_600;
+ case 1200:
+ *ch_rate_type = GSM0808_DATA_FULL_PREF;
+ return GSM0808_DATA_RATE_TRANSP_1k2;
+ case 2400:
+ *ch_rate_type = GSM0808_DATA_FULL_PREF;
+ return GSM0808_DATA_RATE_TRANSP_2k4;
+ case 4800:
+ *ch_rate_type = GSM0808_DATA_FULL_PREF;
+ return GSM0808_DATA_RATE_TRANSP_4k8;
+ case 9600:
+ *ch_rate_type = GSM0808_DATA_FULL_BM;
+ return GSM0808_DATA_RATE_TRANSP_9k6;
+ }
+ return -EINVAL;
+}
+
+static int csd_bs_to_gsm0808_data_rate_non_transp(enum csd_bs bs, uint8_t *ch_rate_type)
+{
+ uint16_t rate = bs_map[bs].rate;
+
+ if (rate < 6000) {
+ *ch_rate_type = GSM0808_DATA_FULL_PREF;
+ return GSM0808_DATA_RATE_NON_TRANSP_6k0;
+ }
+ if (rate < 12000) {
+ *ch_rate_type = GSM0808_DATA_FULL_BM;
+ return GSM0808_DATA_RATE_NON_TRANSP_12k0;
+ }
+
+ return -EINVAL;
+}
+
+static int csd_bs_to_gsm0808_data_rate_non_transp_allowed(enum csd_bs bs)
+{
+ uint16_t rate = bs_map[bs].rate;
+
+ if (rate < 6000)
+ return GSM0808_DATA_RATE_NON_TRANSP_ALLOWED_6k0;
+ if (rate < 12000)
+ return GSM0808_DATA_RATE_NON_TRANSP_ALLOWED_12k0;
+
+ return -EINVAL;
+}
+
+enum csd_bs csd_bs_from_bearer_cap(const struct gsm_mncc_bearer_cap *cap, bool transp)
+{
+ enum gsm48_bcap_ra ra = cap->data.rate_adaption;
+ enum gsm48_bcap_user_rate rate = cap->data.user_rate;
+ bool async = cap->data.async;
+
+ /* 3.1kHz CSD calls won't have the rate adaptation field set
+ but do require rate adaptation. */
+ if (cap->data.interm_rate && !ra)
+ ra = GSM48_BCAP_RA_V110_X30;
+
+ if (ra == GSM48_BCAP_RA_V110_X30 && async && transp) {
+ switch (rate) {
+ case GSM48_BCAP_UR_300:
+ return CSD_BS_21_T_V110_0k3;
+ case GSM48_BCAP_UR_1200:
+ return CSD_BS_22_T_V110_1k2;
+ case GSM48_BCAP_UR_2400:
+ return CSD_BS_24_T_V110_2k4;
+ case GSM48_BCAP_UR_4800:
+ return CSD_BS_25_T_V110_4k8;
+ case GSM48_BCAP_UR_9600:
+ return CSD_BS_26_T_V110_9k6;
+ default:
+ return CSD_BS_NONE;
+ }
+ }
+
+ if (ra == GSM48_BCAP_RA_V110_X30 && async && !transp) {
+ switch (rate) {
+ case GSM48_BCAP_UR_300:
+ return CSD_BS_21_NT_V110_0k3;
+ case GSM48_BCAP_UR_1200:
+ return CSD_BS_22_NT_V110_1k2;
+ case GSM48_BCAP_UR_2400:
+ return CSD_BS_24_NT_V110_2k4;
+ case GSM48_BCAP_UR_4800:
+ return CSD_BS_25_NT_V110_4k8;
+ case GSM48_BCAP_UR_9600:
+ return CSD_BS_26_NT_V110_9k6;
+ default:
+ return CSD_BS_NONE;
+ }
+ }
+
+ if (ra == GSM48_BCAP_RA_V110_X30 && !async && transp) {
+ switch (rate) {
+ case GSM48_BCAP_UR_1200:
+ return CSD_BS_31_T_V110_1k2;
+ case GSM48_BCAP_UR_2400:
+ return CSD_BS_32_T_V110_2k4;
+ case GSM48_BCAP_UR_4800:
+ return CSD_BS_33_T_V110_4k8;
+ case GSM48_BCAP_UR_9600:
+ return CSD_BS_34_T_V110_9k6;
+ default:
+ return CSD_BS_NONE;
+ }
+ }
+
+ return CSD_BS_NONE;
+}
+
+/* csd_bs_list related below */
+
+int csd_bs_list_to_str_buf(char *buf, size_t buflen, const struct csd_bs_list *list)
+{
+ struct osmo_strbuf sb = { .buf = buf, .len = buflen };
+ int i;
+
+ if (!list->count)
+ OSMO_STRBUF_PRINTF(sb, "(no-bearer-services)");
+
+ for (i = 0; i < list->count; i++) {
+ if (i)
+ OSMO_STRBUF_PRINTF(sb, ",");
+
+ OSMO_STRBUF_APPEND(sb, csd_bs_to_str_buf, list->bs[i]);
+ }
+ return sb.chars_needed;
+}
+
+char *csd_bs_list_to_str_c(void *ctx, const struct csd_bs_list *list)
+{
+ OSMO_NAME_C_IMPL(ctx, 128, "csd_bs_list_to_str_c-ERROR", csd_bs_list_to_str_buf, list)
+}
+
+const char *csd_bs_list_to_str(const struct csd_bs_list *list)
+{
+ return csd_bs_list_to_str_c(OTC_SELECT, list);
+}
+
+bool csd_bs_list_has_bs(const struct csd_bs_list *list, enum csd_bs bs)
+{
+ int i;
+
+ for (i = 0; i < list->count; i++) {
+ if (list->bs[i] == bs)
+ return true;
+ }
+
+ return false;
+}
+
+void csd_bs_list_add_bs(struct csd_bs_list *list, enum csd_bs bs)
+{
+ int i;
+
+ if (!bs)
+ return;
+
+ for (i = 0; i < list->count; i++) {
+ if (list->bs[i] == bs)
+ return;
+ }
+
+ list->bs[i] = bs;
+ list->count++;
+}
+
+void csd_bs_list_remove(struct csd_bs_list *list, enum csd_bs bs)
+{
+ int i;
+ bool found = false;
+
+ for (i = 0; i < list->count; i++) {
+ if (list->bs[i] == bs)
+ found = true;
+ if (found && i + 1 < list->count)
+ list->bs[i] = list->bs[i + 1];
+ }
+
+ if (found)
+ list->count--;
+}
+
+void csd_bs_list_intersection(struct csd_bs_list *dest, const struct csd_bs_list *other)
+{
+ int i;
+
+ for (i = 0; i < dest->count; i++) {
+ if (csd_bs_list_has_bs(other, dest->bs[i]))
+ continue;
+ csd_bs_list_remove(dest, dest->bs[i]);
+ i--;
+ }
+}
+
+int csd_bs_list_to_gsm0808_channel_type(struct gsm0808_channel_type *ct, const struct csd_bs_list *list)
+{
+ int i;
+ int rc;
+
+ *ct = (struct gsm0808_channel_type){
+ .ch_indctr = GSM0808_CHAN_DATA,
+ };
+
+ if (!list->count)
+ return -EINVAL;
+
+ if (csd_bs_is_transp(list->bs[0])) {
+ ct->data_transparent = true;
+ rc = csd_bs_to_gsm0808_data_rate_transp(list->bs[0], &ct->ch_rate_type);
+ } else {
+ rc = csd_bs_to_gsm0808_data_rate_non_transp(list->bs[0], &ct->ch_rate_type);
+ }
+
+ if (rc < 0)
+ return -EINVAL;
+
+ ct->data_rate = rc;
+
+ /* Other possible data rates allowed (3GPP TS 48.008 § 3.2.2.11, 5a) */
+ if (!ct->data_transparent && list->count > 1) {
+ for (i = 1; i < list->count; i++) {
+ if (!csd_bs_is_transp(list->bs[i]))
+ continue;
+
+ rc = csd_bs_to_gsm0808_data_rate_non_transp_allowed(list->bs[i]);
+ if (rc < 0) {
+ LOGP(DMSC, LOGL_DEBUG, "Failed to convert %s to allowed r i/f rate\n",
+ csd_bs_to_str(list->bs[i]));
+ continue;
+ }
+
+ ct->data_rate_allowed |= rc;
+ }
+ if (ct->data_rate_allowed)
+ ct->data_rate_allowed_is_set = true;
+ }
+
+ return 0;
+}
+
+int csd_bs_list_to_bearer_cap(struct gsm_mncc_bearer_cap *cap, const struct csd_bs_list *list)
+{
+ *cap = (struct gsm_mncc_bearer_cap){
+ .transfer = GSM_MNCC_BCAP_UNR_DIG,
+ .mode = GSM48_BCAP_TMOD_CIRCUIT,
+ .coding = GSM48_BCAP_CODING_GSM_STD,
+ .radio = GSM48_BCAP_RRQ_FR_ONLY,
+ };
+ enum csd_bs bs;
+ int i;
+
+ for (i = 0; i < list->count; i++) {
+ bs = list->bs[i];
+
+ cap->data.rate_adaption = GSM48_BCAP_RA_V110_X30;
+ cap->data.sig_access = GSM48_BCAP_SA_I440_I450;
+ cap->data.async = bs_map[bs].async;
+ if (bs_map[bs].transp)
+ cap->data.transp = GSM48_BCAP_TR_TRANSP;
+ else
+ cap->data.transp = GSM48_BCAP_TR_RLP;
+
+ /* FIXME: proper values for sync/async (current: 8N1) */
+ cap->data.nr_data_bits = 8;
+ cap->data.parity = GSM48_BCAP_PAR_NONE;
+ cap->data.nr_stop_bits = 1;
+ cap->data.modem_type = GSM48_BCAP_MT_NONE;
+
+ switch (bs_map[bs].rate) {
+ case 300:
+ cap->data.user_rate = GSM48_BCAP_UR_300;
+ cap->data.interm_rate = GSM48_BCAP_IR_8k;
+ break;
+ case 1200:
+ cap->data.user_rate = GSM48_BCAP_UR_1200;
+ cap->data.interm_rate = GSM48_BCAP_IR_8k;
+ break;
+ case 2400:
+ cap->data.user_rate = GSM48_BCAP_UR_2400;
+ cap->data.interm_rate = GSM48_BCAP_IR_8k;
+ break;
+ case 4800:
+ cap->data.user_rate = GSM48_BCAP_UR_4800;
+ cap->data.interm_rate = GSM48_BCAP_IR_8k;
+ break;
+ case 9600:
+ cap->data.user_rate = GSM48_BCAP_UR_9600;
+ cap->data.interm_rate = GSM48_BCAP_IR_16k;
+ break;
+ default:
+ LOGP(DMSC, LOGL_ERROR,
+ "%s(): bs=%d (rate=%u) is not implemented\n",
+ __func__, bs, bs_map[bs].rate);
+ continue;
+ }
+
+ /* FIXME: handle more than one list entry */
+ return 1;
+ }
+
+ return 0;
+}
+
+void csd_bs_list_from_bearer_cap(struct csd_bs_list *list, const struct gsm_mncc_bearer_cap *cap)
+{
+ *list = (struct csd_bs_list){};
+
+ switch (cap->data.transp) {
+ case GSM48_BCAP_TR_TRANSP:
+ csd_bs_list_add_bs(list, csd_bs_from_bearer_cap(cap, true));
+ break;
+ case GSM48_BCAP_TR_RLP: /* NT */
+ csd_bs_list_add_bs(list, csd_bs_from_bearer_cap(cap, false));
+ break;
+ case GSM48_BCAP_TR_TR_PREF:
+ csd_bs_list_add_bs(list, csd_bs_from_bearer_cap(cap, true));
+ csd_bs_list_add_bs(list, csd_bs_from_bearer_cap(cap, false));
+ break;
+ case GSM48_BCAP_TR_RLP_PREF:
+ csd_bs_list_add_bs(list, csd_bs_from_bearer_cap(cap, false));
+ csd_bs_list_add_bs(list, csd_bs_from_bearer_cap(cap, true));
+ break;
+ }
+
+ if (!list->count) {
+ LOGP(DMSC, LOGL_ERROR, "Failed to get bearer service from bearer capabilities ra=%d, async=%d,"
+ " transp=%d, user_rate=%d\n", cap->data.rate_adaption, cap->data.async, cap->data.transp,
+ cap->data.user_rate);
+ return;
+ }
+}
diff --git a/src/libmsc/csd_filter.c b/src/libmsc/csd_filter.c
new file mode 100644
index 000000000..0f428cffe
--- /dev/null
+++ b/src/libmsc/csd_filter.c
@@ -0,0 +1,157 @@
+/* Filter/overlay bearer service selections across MS, RAN and CN limitations */
+/*
+ * (C) 2023 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
+ * All Rights Reserved
+ *
+ * Author: Oliver Smith
+ *
+ * SPDX-License-Identifier: AGPL-3.0+
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <osmocom/mgcp_client/mgcp_client.h>
+
+#include <osmocom/msc/csd_filter.h>
+
+static void add_all_geran_bs(struct csd_bs_list *list)
+{
+ /* See 3GPP TS 122.002 Bearer Services */
+ /* In order of preference. TODO: make configurable */
+
+ /* GSM-R */
+ csd_bs_list_add_bs(list, CSD_BS_24_T_V110_2k4);
+ csd_bs_list_add_bs(list, CSD_BS_25_T_V110_4k8);
+ csd_bs_list_add_bs(list, CSD_BS_26_T_V110_9k6);
+
+ /* Other */
+ csd_bs_list_add_bs(list, CSD_BS_21_T_V110_0k3);
+ csd_bs_list_add_bs(list, CSD_BS_22_T_V110_1k2);
+ csd_bs_list_add_bs(list, CSD_BS_21_NT_V110_0k3);
+ csd_bs_list_add_bs(list, CSD_BS_22_NT_V110_1k2);
+ csd_bs_list_add_bs(list, CSD_BS_24_NT_V110_2k4);
+ csd_bs_list_add_bs(list, CSD_BS_25_NT_V110_4k8);
+ csd_bs_list_add_bs(list, CSD_BS_26_NT_V110_9k6);
+ csd_bs_list_add_bs(list, CSD_BS_31_T_V110_1k2);
+ csd_bs_list_add_bs(list, CSD_BS_32_T_V110_2k4);
+ csd_bs_list_add_bs(list, CSD_BS_33_T_V110_4k8);
+ csd_bs_list_add_bs(list, CSD_BS_34_T_V110_9k6);
+}
+
+static void add_all_utran_bs(struct csd_bs_list *list)
+{
+ /* See 3GPP TS 122.002 Bearer Services */
+ /* In order of preference. TODO: make configurable */
+ csd_bs_list_add_bs(list, CSD_BS_21_NT_V110_0k3);
+ csd_bs_list_add_bs(list, CSD_BS_22_NT_V110_1k2);
+ csd_bs_list_add_bs(list, CSD_BS_24_NT_V110_2k4);
+ csd_bs_list_add_bs(list, CSD_BS_25_NT_V110_4k8);
+ csd_bs_list_add_bs(list, CSD_BS_26_NT_V110_9k6);
+}
+
+void csd_filter_set_ran(struct csd_filter *filter, enum osmo_rat_type ran_type)
+{
+ filter->ran = (struct csd_bs_list){};
+
+ switch (ran_type) {
+ default:
+ case OSMO_RAT_GERAN_A:
+ add_all_geran_bs(&filter->ran);
+ break;
+ case OSMO_RAT_UTRAN_IU:
+ add_all_utran_bs(&filter->ran);
+ break;
+ }
+}
+
+int csd_filter_run(struct csd_filter *filter, struct sdp_msg *result, const struct sdp_msg *remote)
+{
+ struct csd_bs_list *r = &result->bearer_services;
+ enum csd_bs a = filter->assignment;
+
+ *r = filter->ran;
+
+ if (filter->ms.count)
+ csd_bs_list_intersection(r, &filter->ms);
+ if (filter->bss.count)
+ csd_bs_list_intersection(r, &filter->bss);
+ if (remote->bearer_services.count)
+ csd_bs_list_intersection(r, &remote->bearer_services);
+
+ /* Future: If osmo-msc were able to trigger a re-assignment [...] see
+ * comment in codec_filter_run(). */
+
+ if (a) {
+ *r = (struct csd_bs_list){};
+ csd_bs_list_add_bs(r, a);
+ }
+
+ result->audio_codecs.count = 1;
+ result->audio_codecs.codec[0] = (struct sdp_audio_codec){
+ .payload_type = CODEC_CLEARMODE,
+ .subtype_name = "CLEARMODE",
+ .rate = 8000,
+ };
+
+ return 0;
+}
+
+
+int csd_filter_to_str_buf(char *buf, size_t buflen, const struct csd_filter *filter,
+ const struct sdp_msg *result, const struct sdp_msg *remote)
+{
+ struct osmo_strbuf sb = { .buf = buf, .len = buflen };
+ OSMO_STRBUF_APPEND(sb, sdp_msg_to_str_buf, result);
+ OSMO_STRBUF_PRINTF(sb, " (from:");
+
+ if (filter->assignment) {
+ OSMO_STRBUF_PRINTF(sb, " assigned=");
+ OSMO_STRBUF_APPEND(sb, csd_bs_to_str_buf, filter->assignment);
+ }
+
+ if (remote->bearer_services.count || osmo_sockaddr_str_is_nonzero(&remote->rtp)) {
+ OSMO_STRBUF_PRINTF(sb, " remote=");
+ OSMO_STRBUF_APPEND(sb, sdp_msg_to_str_buf, remote);
+ }
+
+ if (filter->ms.count) {
+ OSMO_STRBUF_PRINTF(sb, " MS={");
+ OSMO_STRBUF_APPEND(sb, csd_bs_list_to_str_buf, &filter->ms);
+ OSMO_STRBUF_PRINTF(sb, "}");
+ }
+
+ if (filter->bss.count) {
+ OSMO_STRBUF_PRINTF(sb, " bss={");
+ OSMO_STRBUF_APPEND(sb, csd_bs_list_to_str_buf, &filter->bss);
+ OSMO_STRBUF_PRINTF(sb, "}");
+ }
+
+ OSMO_STRBUF_PRINTF(sb, " RAN={");
+ OSMO_STRBUF_APPEND(sb, csd_bs_list_to_str_buf, &filter->ran);
+ OSMO_STRBUF_PRINTF(sb, "}");
+
+ OSMO_STRBUF_PRINTF(sb, ")");
+
+ return sb.chars_needed;
+}
+
+char *csd_filter_to_str_c(void *ctx, const struct csd_filter *filter, const struct sdp_msg *result, const struct sdp_msg *remote)
+{
+ OSMO_NAME_C_IMPL(ctx, 128, "csd_filter_to_str_c-ERROR", csd_filter_to_str_buf, filter, result, remote)
+}
+
+const char *csd_filter_to_str(const struct csd_filter *filter, const struct sdp_msg *result, const struct sdp_msg *remote)
+{
+ return csd_filter_to_str_c(OTC_SELECT, filter, result, remote);
+}
diff --git a/src/libmsc/db.c b/src/libmsc/db.c
index c2d833939..d12f04c13 100644
--- a/src/libmsc/db.c
+++ b/src/libmsc/db.c
@@ -1,7 +1,7 @@
-/* Simple HLR/VLR database backend using dbi */
+/* Simple HLR/VLR database backend using sqlite3 */
/* (C) 2008 by Jan Luebbe <jluebbe@debian.org>
* (C) 2009 by Holger Hans Peter Freyther <zecke@selfish.org>
- * (C) 2009 by Harald Welte <laforge@gnumonks.org>
+ * (C) 2009,2022 by Harald Welte <laforge@gnumonks.org>
* All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify
@@ -28,7 +28,7 @@
#include <string.h>
#include <errno.h>
#include <time.h>
-#include <dbi/dbi.h>
+#include <sqlite3.h>
#include <osmocom/msc/gsm_data.h>
#include <osmocom/msc/gsm_subscriber.h>
@@ -43,12 +43,36 @@
#include <osmocom/core/rate_ctr.h>
#include <osmocom/core/utils.h>
-static char *db_basename = NULL;
-static char *db_dirname = NULL;
-static dbi_conn conn;
-static dbi_inst inst;
+enum stmt_idx {
+ DB_STMT_SMS_STORE,
+ DB_STMT_SMS_GET,
+ DB_STMT_SMS_GET_NEXT_UNSENT,
+ DB_STMT_SMS_GET_UNSENT_FOR_SUBSCR,
+ DB_STMT_SMS_GET_NEXT_UNSENT_RR_MSISDN,
+ DB_STMT_SMS_MARK_DELIVERED,
+ DB_STMT_SMS_INC_DELIVER_ATTEMPTS,
+ DB_STMT_SMS_DEL_BY_MSISDN,
+ DB_STMT_SMS_DEL_BY_ID,
+ DB_STMT_SMS_DEL_EXPIRED,
+ DB_STMT_SMS_GET_VALID_UNTIL_BY_ID,
+ DB_STMT_SMS_GET_OLDEST_EXPIRED,
+ _NUM_DB_STMT
+};
+
+struct db_context {
+ char *fname;
+ sqlite3 *db;
+ sqlite3_stmt *stmt[_NUM_DB_STMT];
+};
+
+static struct db_context *g_dbc;
-#define SCHEMA_REVISION "5"
+
+/***********************************************************************
+ * DATABASE SCHEMA AND MIGRATION
+ ***********************************************************************/
+
+#define SCHEMA_REVISION "6"
enum {
SCHEMA_META,
@@ -181,677 +205,638 @@ static const char *create_stmts[] = {
")",
};
-static inline int next_row(dbi_result result)
-{
- if (!dbi_result_has_next_row(result))
- return 0;
- return dbi_result_next_row(result);
-}
+/***********************************************************************
+ * PREPARED STATEMENTS
+ ***********************************************************************/
+
+/* don't change this order as the code assumes this ordering when dereferencing
+ * database query results! */
+#define SEL_COLUMNS \
+ "id," \
+ "strftime('%s',created)," \
+ "sent," \
+ "deliver_attempts," \
+ "strftime('%s', valid_until)," \
+ "reply_path_req," \
+ "status_rep_req," \
+ "is_report," \
+ "msg_ref," \
+ "protocol_id," \
+ "data_coding_scheme," \
+ "ud_hdr_ind," \
+ "src_addr," \
+ "src_ton," \
+ "src_npi," \
+ "dest_addr," \
+ "dest_ton," \
+ "dest_npi," \
+ "user_data," \
+ "header," \
+ "text"
+
+enum db_sms_column_idx {
+ COL_ID,
+ COL_CREATED,
+ COL_SENT,
+ COL_DELIVER_ATTEMPTS,
+ COL_VALID_UNTIL,
+ COL_REPLY_PATH_REQ,
+ COL_STATUS_REP_REQ,
+ COL_IS_REPORT,
+ COL_MSG_REF,
+ COL_PROTOCOL_ID,
+ COL_DATA_CODING_SCHEME,
+ COL_UD_HDR_IND,
+ COL_SRC_ADDR,
+ COL_SRC_TON,
+ COL_SRC_NPI,
+ COL_DEST_ADDR,
+ COL_DEST_TON,
+ COL_DEST_NPI,
+ COL_USER_DATA,
+ COL_HEADER,
+ COL_TEXT,
+};
-void db_error_func(dbi_conn conn, void *data)
+static const char *stmt_sql[] = {
+ [DB_STMT_SMS_STORE] =
+ "INSERT INTO SMS "
+ "(created, valid_until, reply_path_req, status_rep_req, is_report, "
+ " msg_ref, protocol_id, data_coding_scheme, ud_hdr_ind, user_data, text, "
+ " dest_addr, dest_ton, dest_npi, src_addr, src_ton, src_npi) "
+ "VALUES "
+ "(datetime($created, 'unixepoch'), datetime($valid_until, 'unixepoch'), "
+ "$reply_path_req, $status_rep_req, $is_report, "
+ "$msg_ref, $protocol_id, $data_coding_scheme, $ud_hdr_ind, $user_data, $text, "
+ "$dest_addr, $dest_ton, $dest_npi, $src_addr, $src_ton, $src_npi)",
+ [DB_STMT_SMS_GET] = "SELECT " SEL_COLUMNS " FROM SMS WHERE SMS.id = $id",
+ [DB_STMT_SMS_GET_NEXT_UNSENT] =
+ "SELECT " SEL_COLUMNS " FROM SMS"
+ " WHERE sent IS NULL"
+ " AND id >= $id"
+ " AND deliver_attempts <= $attempts"
+ " ORDER BY id LIMIT 1",
+ [DB_STMT_SMS_GET_UNSENT_FOR_SUBSCR] =
+ "SELECT " SEL_COLUMNS " FROM SMS"
+ " WHERE sent IS NULL"
+ " AND dest_addr = $dest_addr"
+ " AND deliver_attempts <= $attempts"
+ " ORDER BY id LIMIT 1",
+ [DB_STMT_SMS_GET_NEXT_UNSENT_RR_MSISDN] =
+ "SELECT " SEL_COLUMNS " FROM SMS"
+ " WHERE sent IS NULL"
+ " AND dest_addr > $dest_addr"
+ " AND deliver_attempts <= $attempts"
+ " ORDER BY dest_addr, id LIMIT 1",
+ [DB_STMT_SMS_MARK_DELIVERED] =
+ "UPDATE SMS "
+ " SET sent = datetime('now') "
+ " WHERE id = $id",
+ [DB_STMT_SMS_INC_DELIVER_ATTEMPTS] =
+ "UPDATE SMS "
+ " SET deliver_attempts = deliver_attempts + 1 "
+ " WHERE id = $id",
+ [DB_STMT_SMS_DEL_BY_MSISDN] =
+ "DELETE FROM SMS WHERE src_addr=$src_addr OR dest_addr=$dest_addr",
+ [DB_STMT_SMS_DEL_BY_ID] =
+ "DELETE FROM SMS WHERE id = $id AND sent is NOT NULL",
+ [DB_STMT_SMS_DEL_EXPIRED] =
+ "DELETE FROM SMS WHERE id = $id",
+ [DB_STMT_SMS_GET_VALID_UNTIL_BY_ID] =
+ "SELECT strftime('%s', valid_until) FROM SMS WHERE id = $id",
+ [DB_STMT_SMS_GET_OLDEST_EXPIRED] =
+ "SELECT id, strftime('%s', valid_until) FROM SMS ORDER BY valid_until LIMIT 1",
+};
+
+/***********************************************************************
+ * libsqlite3 helpers
+ ***********************************************************************/
+
+/* libsqlite3 call-back for error logging */
+static void sql3_error_log_cb(void *arg, int err_code, const char *msg)
{
- const char *msg;
- dbi_conn_error(conn, &msg);
- LOGP(DDB, LOGL_ERROR, "DBI: %s\n", msg);
+ LOGP(DDB, LOGL_ERROR, "SQLITE3: (%d) %s\n", err_code, msg);
osmo_log_backtrace(DDB, LOGL_ERROR);
}
-static int update_db_revision_2(void)
+/* libsqlite3 call-back for normal logging */
+static void sql3_sql_log_cb(void *arg, sqlite3 *s3, const char *stmt, int type)
{
- dbi_result result;
-
- result = dbi_conn_query(conn,
- "ALTER TABLE Subscriber "
- "ADD COLUMN expire_lu "
- "TIMESTAMP DEFAULT NULL");
- if (!result) {
- LOGP(DDB, LOGL_ERROR,
- "Failed to alter table Subscriber (upgrade from rev 2).\n");
- return -EINVAL;
- }
- dbi_result_free(result);
-
- result = dbi_conn_query(conn,
- "UPDATE Meta "
- "SET value = '3' "
- "WHERE key = 'revision'");
- if (!result) {
- LOGP(DDB, LOGL_ERROR,
- "Failed to update DB schema revision (upgrade from rev 2).\n");
- return -EINVAL;
+ switch (type) {
+ case 0:
+ LOGP(DDB, LOGL_DEBUG, "Opened database\n");
+ break;
+ case 1:
+ LOGP(DDB, LOGL_DEBUG, "%s\n", stmt);
+ break;
+ case 2:
+ LOGP(DDB, LOGL_DEBUG, "Closed database\n");
+ break;
+ default:
+ LOGP(DDB, LOGL_DEBUG, "Unknown %d\n", type);
+ break;
}
- dbi_result_free(result);
-
- return 0;
}
-/**
- * Copied from the normal sms_from_result_v3 to avoid having
- * to make sure that the real routine will remain backward
- * compatible.
- */
-static struct gsm_sms *sms_from_result_v3(dbi_result result)
+/* remove statement bindings and reset statement to be re-executed */
+static void db_remove_reset(sqlite3_stmt *stmt)
{
- struct gsm_sms *sms = sms_alloc();
- long long unsigned int sender_id;
- const char *text, *daddr;
- const unsigned char *user_data;
- char buf[32];
- char *quoted;
- dbi_result result2;
- const char *extension;
-
- if (!sms)
- return NULL;
-
- sms->id = dbi_result_get_ulonglong(result, "id");
-
- /* find extension by id, assuming that the subscriber still exists in
- * the db */
- sender_id = dbi_result_get_ulonglong(result, "sender_id");
- snprintf(buf, sizeof(buf), "%llu", sender_id);
-
- dbi_conn_quote_string_copy(conn, buf, &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);
-
- sms->user_data_len = dbi_result_get_field_length(result, "user_data");
- user_data = dbi_result_get_binary(result, "user_data");
- if (sms->user_data_len > sizeof(sms->user_data))
- sms->user_data_len = (uint8_t) sizeof(sms->user_data);
- memcpy(sms->user_data, user_data, sms->user_data_len);
-
- text = dbi_result_get_string(result, "text");
- if (text)
- OSMO_STRLCPY_ARRAY(sms->text, text);
- return sms;
+ sqlite3_clear_bindings(stmt);
+ /* sqlite3_reset() just repeats an error code already evaluated during sqlite3_step(). */
+ /* coverity[CHECKED_RETURN] */
+ sqlite3_reset(stmt);
}
-static int update_db_revision_3(void)
+/** bind blob arg and do proper cleanup in case of failure. If param_name is
+ * NULL, bind to the first parameter (useful for SQL statements that have only
+ * one parameter). */
+static bool db_bind_blob(sqlite3_stmt *stmt, const char *param_name,
+ const uint8_t *blob, size_t blob_len)
{
- dbi_result result;
- struct gsm_sms *sms;
-
- LOGP(DDB, LOGL_NOTICE, "Going to migrate from revision 3\n");
-
- result = dbi_conn_query(conn, "BEGIN EXCLUSIVE TRANSACTION");
- if (!result) {
- LOGP(DDB, LOGL_ERROR,
- "Failed to begin transaction (upgrade from rev 3)\n");
- return -EINVAL;
+ int rc;
+ int idx = param_name ? sqlite3_bind_parameter_index(stmt, param_name) : 1;
+ if (idx < 1) {
+ LOGP(DDB, LOGL_ERROR, "Error composing SQL, cannot bind parameter '%s'\n",
+ param_name);
+ return false;
}
- dbi_result_free(result);
-
- /* Rename old SMS table to be able create a new one */
- result = dbi_conn_query(conn, "ALTER TABLE SMS RENAME TO SMS_3");
- if (!result) {
- LOGP(DDB, LOGL_ERROR,
- "Failed to rename the old SMS table (upgrade from rev 3).\n");
- goto rollback;
+ rc = sqlite3_bind_blob(stmt, idx, blob, blob_len, SQLITE_STATIC);
+ if (rc != SQLITE_OK) {
+ LOGP(DDB, LOGL_ERROR, "Error binding blob to SQL parameter %s: %d\n",
+ param_name ? param_name : "#1", rc);
+ db_remove_reset(stmt);
+ return false;
}
- dbi_result_free(result);
-
- /* Create new SMS table with all the bells and whistles! */
- result = dbi_conn_query(conn, create_stmts[SCHEMA_SMS]);
- if (!result) {
- LOGP(DDB, LOGL_ERROR,
- "Failed to create a new SMS table (upgrade from rev 3).\n");
- goto rollback;
- }
- dbi_result_free(result);
-
- /* Cycle through old messages and convert them to the new format */
- result = dbi_conn_query(conn, "SELECT * FROM SMS_3");
- if (!result) {
- LOGP(DDB, LOGL_ERROR,
- "Failed fetch messages from the old SMS table (upgrade from rev 3).\n");
- goto rollback;
- }
- while (next_row(result)) {
- sms = sms_from_result_v3(result);
- if (db_sms_store(sms) != 0) {
- LOGP(DDB, LOGL_ERROR, "Failed to store message to the new SMS table(upgrade from rev 3).\n");
- sms_free(sms);
- dbi_result_free(result);
- goto rollback;
- }
- sms_free(sms);
- }
- dbi_result_free(result);
-
- /* Remove the temporary table */
- result = dbi_conn_query(conn, "DROP TABLE SMS_3");
- if (!result) {
- LOGP(DDB, LOGL_ERROR,
- "Failed to drop the old SMS table (upgrade from rev 3).\n");
- goto rollback;
- }
- dbi_result_free(result);
-
- /* We're done. Bump DB Meta revision to 4 */
- result = dbi_conn_query(conn,
- "UPDATE Meta "
- "SET value = '4' "
- "WHERE key = 'revision'");
- if (!result) {
- LOGP(DDB, LOGL_ERROR,
- "Failed to update DB schema revision (upgrade from rev 3).\n");
- goto rollback;
- }
- dbi_result_free(result);
-
- result = dbi_conn_query(conn, "COMMIT TRANSACTION");
- if (!result) {
- LOGP(DDB, LOGL_ERROR,
- "Failed to commit the transaction (upgrade from rev 3)\n");
- return -EINVAL;
- } else {
- dbi_result_free(result);
- }
-
- /* Shrink DB file size by actually wiping out SMS_3 table data */
- result = dbi_conn_query(conn, "VACUUM");
- if (!result)
- LOGP(DDB, LOGL_ERROR,
- "VACUUM failed. Ignoring it (upgrade from rev 3).\n");
- else
- dbi_result_free(result);
-
- return 0;
-
-rollback:
- result = dbi_conn_query(conn, "ROLLBACK TRANSACTION");
- if (!result)
- LOGP(DDB, LOGL_ERROR,
- "Rollback failed (upgrade from rev 3).\n");
- else
- dbi_result_free(result);
- return -EINVAL;
+ return true;
}
-/* Just like v3, but there is a new message reference field for status reports,
- * that is set to zero for existing entries since there is no way we can infer
- * this.
- */
-static struct gsm_sms *sms_from_result_v4(dbi_result result)
+/** bind text arg and do proper cleanup in case of failure. If param_name is
+ * NULL, bind to the first parameter (useful for SQL statements that have only
+ * one parameter). */
+static bool db_bind_text(sqlite3_stmt *stmt, const char *param_name, const char *text)
{
- struct gsm_sms *sms = sms_alloc();
- const unsigned char *user_data;
- const char *text, *addr;
-
- if (!sms)
- return NULL;
-
- sms->id = dbi_result_get_ulonglong(result, "id");
-
- sms->reply_path_req = dbi_result_get_ulonglong(result, "reply_path_req");
- sms->status_rep_req = dbi_result_get_ulonglong(result, "status_rep_req");
- sms->ud_hdr_ind = dbi_result_get_ulonglong(result, "ud_hdr_ind");
- sms->protocol_id = dbi_result_get_ulonglong(result, "protocol_id");
- sms->data_coding_scheme = dbi_result_get_ulonglong(result,
- "data_coding_scheme");
-
- addr = dbi_result_get_string(result, "src_addr");
- OSMO_STRLCPY_ARRAY(sms->src.addr, addr);
- sms->src.ton = dbi_result_get_ulonglong(result, "src_ton");
- sms->src.npi = dbi_result_get_ulonglong(result, "src_npi");
-
- addr = dbi_result_get_string(result, "dest_addr");
- OSMO_STRLCPY_ARRAY(sms->dst.addr, addr);
- sms->dst.ton = dbi_result_get_ulonglong(result, "dest_ton");
- sms->dst.npi = dbi_result_get_ulonglong(result, "dest_npi");
-
- sms->user_data_len = dbi_result_get_field_length(result, "user_data");
- user_data = dbi_result_get_binary(result, "user_data");
- if (sms->user_data_len > sizeof(sms->user_data))
- sms->user_data_len = (uint8_t) sizeof(sms->user_data);
- memcpy(sms->user_data, user_data, sms->user_data_len);
-
- text = dbi_result_get_string(result, "text");
- if (text)
- OSMO_STRLCPY_ARRAY(sms->text, text);
- return sms;
-}
-
-static int update_db_revision_4(void)
-{
- dbi_result result;
- struct gsm_sms *sms;
-
- LOGP(DDB, LOGL_NOTICE, "Going to migrate from revision 4\n");
-
- result = dbi_conn_query(conn, "BEGIN EXCLUSIVE TRANSACTION");
- if (!result) {
- LOGP(DDB, LOGL_ERROR,
- "Failed to begin transaction (upgrade from rev 4)\n");
- return -EINVAL;
+ int rc;
+ int idx = param_name ? sqlite3_bind_parameter_index(stmt, param_name) : 1;
+ if (idx < 1) {
+ LOGP(DDB, LOGL_ERROR, "Error composing SQL, cannot bind parameter '%s'\n",
+ param_name);
+ return false;
}
- dbi_result_free(result);
-
- /* Rename old SMS table to be able create a new one */
- result = dbi_conn_query(conn, "ALTER TABLE SMS RENAME TO SMS_4");
- if (!result) {
- LOGP(DDB, LOGL_ERROR,
- "Failed to rename the old SMS table (upgrade from rev 4).\n");
- goto rollback;
- }
- dbi_result_free(result);
-
- /* Create new SMS table with all the bells and whistles! */
- result = dbi_conn_query(conn, create_stmts[SCHEMA_SMS]);
- if (!result) {
- LOGP(DDB, LOGL_ERROR,
- "Failed to create a new SMS table (upgrade from rev 4).\n");
- goto rollback;
+ rc = sqlite3_bind_text(stmt, idx, text, -1, SQLITE_STATIC);
+ if (rc != SQLITE_OK) {
+ LOGP(DDB, LOGL_ERROR, "Error binding text to SQL parameter %s: %d\n",
+ param_name ? param_name : "#1", rc);
+ db_remove_reset(stmt);
+ return false;
}
- dbi_result_free(result);
+ return true;
+}
- /* Cycle through old messages and convert them to the new format */
- result = dbi_conn_query(conn, "SELECT * FROM SMS_4");
- if (!result) {
- LOGP(DDB, LOGL_ERROR,
- "Failed fetch messages from the old SMS table (upgrade from rev 4).\n");
- goto rollback;
+/** bind int arg and do proper cleanup in case of failure. If param_name is
+ * NULL, bind to the first parameter (useful for SQL statements that have only
+ * one parameter). */
+static bool db_bind_int(sqlite3_stmt *stmt, const char *param_name, int nr)
+{
+ int rc;
+ int idx = param_name ? sqlite3_bind_parameter_index(stmt, param_name) : 1;
+ if (idx < 1) {
+ LOGP(DDB, LOGL_ERROR, "Error composing SQL, cannot bind parameter '%s'\n",
+ param_name);
+ return false;
}
- while (next_row(result)) {
- sms = sms_from_result_v4(result);
- if (db_sms_store(sms) != 0) {
- LOGP(DDB, LOGL_ERROR, "Failed to store message to the new SMS table(upgrade from rev 4).\n");
- sms_free(sms);
- dbi_result_free(result);
- goto rollback;
- }
- sms_free(sms);
+ rc = sqlite3_bind_int(stmt, idx, nr);
+ if (rc != SQLITE_OK) {
+ LOGP(DDB, LOGL_ERROR, "Error binding int64 to SQL parameter %s: %d\n",
+ param_name ? param_name : "#1", rc);
+ db_remove_reset(stmt);
+ return false;
}
- dbi_result_free(result);
+ return true;
+}
- /* Remove the temporary table */
- result = dbi_conn_query(conn, "DROP TABLE SMS_4");
- if (!result) {
- LOGP(DDB, LOGL_ERROR,
- "Failed to drop the old SMS table (upgrade from rev 4).\n");
- goto rollback;
- }
- dbi_result_free(result);
-
- /* We're done. Bump DB Meta revision to 4 */
- result = dbi_conn_query(conn,
- "UPDATE Meta "
- "SET value = '5' "
- "WHERE key = 'revision'");
- if (!result) {
- LOGP(DDB, LOGL_ERROR,
- "Failed to update DB schema revision (upgrade from rev 4).\n");
- goto rollback;
+/** bind int64 arg and do proper cleanup in case of failure. If param_name is
+ * NULL, bind to the first parameter (useful for SQL statements that have only
+ * one parameter). */
+static bool db_bind_int64(sqlite3_stmt *stmt, const char *param_name, int64_t nr)
+{
+ int rc;
+ int idx = param_name ? sqlite3_bind_parameter_index(stmt, param_name) : 1;
+ if (idx < 1) {
+ LOGP(DDB, LOGL_ERROR, "Error composing SQL, cannot bind parameter '%s'\n",
+ param_name);
+ return false;
}
- dbi_result_free(result);
-
- result = dbi_conn_query(conn, "COMMIT TRANSACTION");
- if (!result) {
- LOGP(DDB, LOGL_ERROR,
- "Failed to commit the transaction (upgrade from rev 4)\n");
- return -EINVAL;
- } else {
- dbi_result_free(result);
+ rc = sqlite3_bind_int64(stmt, idx, nr);
+ if (rc != SQLITE_OK) {
+ LOGP(DDB, LOGL_ERROR, "Error binding int64 to SQL parameter %s: %d\n",
+ param_name ? param_name : "#1", rc);
+ db_remove_reset(stmt);
+ return false;
}
+ return true;
+}
- /* Shrink DB file size by actually wiping out SMS_4 table data */
- result = dbi_conn_query(conn, "VACUUM");
- if (!result)
- LOGP(DDB, LOGL_ERROR,
- "VACUUM failed. Ignoring it (upgrade from rev 4).\n");
- else
- dbi_result_free(result);
-
+/* callback for sqlite3_exec() below */
+static int db_rev_exec_cb(void *priv, int num_cols, char **vals, char **names)
+{
+ char **rev_s = priv;
+ OSMO_ASSERT(!strcmp(names[0], "value"));
+ *rev_s = talloc_strdup(NULL, vals[0]);
return 0;
-
-rollback:
- result = dbi_conn_query(conn, "ROLLBACK TRANSACTION");
- if (!result)
- LOGP(DDB, LOGL_ERROR,
- "Rollback failed (upgrade from rev 4).\n");
- else
- dbi_result_free(result);
- return -EINVAL;
}
-static int check_db_revision(void)
+static int check_db_revision(struct db_context *dbc)
{
- dbi_result result;
- const char *rev_s;
+ char *errstr = NULL;
+ char *rev_s;
int db_rev = 0;
+ int rc;
/* Make a query */
- result = dbi_conn_query(conn,
- "SELECT value FROM Meta "
- "WHERE key = 'revision'");
-
- if (!result)
- return -EINVAL;
-
- if (!next_row(result)) {
- dbi_result_free(result);
- return -EINVAL;
- }
-
- /* Fetch the DB schema revision */
- rev_s = dbi_result_get_string(result, "value");
- if (!rev_s) {
- dbi_result_free(result);
+ rc = sqlite3_exec(dbc->db, "SELECT value FROM Meta WHERE key = 'revision'",
+ db_rev_exec_cb, &rev_s, &errstr);
+ if (rc != SQLITE_OK) {
+ LOGP(DDB, LOGL_ERROR, "Cannot execute SELECT value from META: %s\n", errstr);
+ sqlite3_free(errstr);
return -EINVAL;
}
if (!strcmp(rev_s, SCHEMA_REVISION)) {
/* Everything is fine */
- dbi_result_free(result);
+ talloc_free(rev_s);
return 0;
}
+ LOGP(DDB, LOGL_NOTICE, "Detected DB Revision %s, expected %s\n", rev_s, SCHEMA_REVISION);
+
db_rev = atoi(rev_s);
- dbi_result_free(result);
+ talloc_free(rev_s);
/* Incremental migration waterfall */
switch (db_rev) {
case 2:
- if (update_db_revision_2())
- goto error;
- /* fall through */
case 3:
- if (update_db_revision_3())
- goto error;
- /* fall through */
case 4:
- if (update_db_revision_4())
- goto error;
-
- /* The end of waterfall */
- break;
+ LOGP(DDB, LOGL_FATAL, "You must use osmo-msc 1.1.0 to 1.8.0 to upgrade database "
+ "schema from '%u' to '5', sorry\n", db_rev);
+ break;
+ case 5:
+ LOGP(DDB, LOGL_FATAL, "The storage format of BINARY data in the database "
+ "has changed. In order to deliver any pending SMS in your database, "
+ "you must manually convert your database from "
+ "'%u' to '6'. Alternatively you can use a fresh, blank database "
+ "with this version of osmo-msc, sorry.\n", db_rev);
+ return -1;
+ break;
default:
- LOGP(DDB, LOGL_FATAL,
- "Invalid database schema revision '%d'.\n", db_rev);
+ LOGP(DDB, LOGL_FATAL, "Invalid database schema revision '%d'.\n", db_rev);
return -EINVAL;
}
return 0;
-error:
- LOGP(DDB, LOGL_FATAL, "Failed to update database "
- "from schema revision '%d'.\n", db_rev);
+//error:
+ LOGP(DDB, LOGL_FATAL, "Failed to update database from schema revision '%d'.\n", db_rev);
+ talloc_free(rev_s);
+
return -EINVAL;
}
-static int db_configure(void)
+/***********************************************************************
+ * USER API
+ ***********************************************************************/
+
+int db_init(void *ctx, const char *fname, bool enable_sqlite_logging)
{
- dbi_result result;
+ unsigned int i;
+ int rc;
+ bool has_sqlite_config_sqllog = false;
- result = dbi_conn_query(conn,
- "PRAGMA synchronous = FULL");
- if (!result)
- return -EINVAL;
+ g_dbc = talloc_zero(ctx, struct db_context);
+ OSMO_ASSERT(g_dbc);
- dbi_result_free(result);
- return 0;
-}
+ /* we are a single-threaded program; we want to avoid all the mutex/etc. overhead */
+ sqlite3_config(SQLITE_CONFIG_SINGLETHREAD);
-int db_init(const char *name)
-{
- dbi_initialize_r(NULL, &inst);
+ LOGP(DDB, LOGL_NOTICE, "Init database connection to '%s' using SQLite3 lib version %s\n",
+ fname, sqlite3_libversion());
- LOGP(DDB, LOGL_NOTICE, "Init database connection to '%s' using %s\n",
- name, dbi_version());
+ g_dbc->fname = talloc_strdup(g_dbc, fname);
- conn = dbi_conn_new_r("sqlite3", inst);
- if (conn == NULL) {
- LOGP(DDB, LOGL_FATAL, "Failed to create database connection to sqlite3 db '%s'; "
- "Is the sqlite3 database driver for libdbi installed on this system?\n", name);
- return 1;
+ for (i = 0; i < 0xfffff; i++) {
+ const char *o = sqlite3_compileoption_get(i);
+ if (!o)
+ break;
+ LOGP(DDB, LOGL_DEBUG, "SQLite3 compiled with '%s'\n", o);
+ if (!strcmp(o, "ENABLE_SQLLOG"))
+ has_sqlite_config_sqllog = true;
}
- dbi_conn_error_handler( conn, db_error_func, NULL );
+ if (enable_sqlite_logging) {
+ rc = sqlite3_config(SQLITE_CONFIG_LOG, sql3_error_log_cb, NULL);
+ if (rc != SQLITE_OK)
+ LOGP(DDB, LOGL_NOTICE, "Unable to set SQLite3 error log callback\n");
+ }
- /* MySQL
- dbi_conn_set_option(conn, "host", "localhost");
- dbi_conn_set_option(conn, "username", "your_name");
- dbi_conn_set_option(conn, "password", "your_password");
- dbi_conn_set_option(conn, "dbname", "your_dbname");
- dbi_conn_set_option(conn, "encoding", "UTF-8");
- */
+ if (has_sqlite_config_sqllog) {
+ rc = sqlite3_config(SQLITE_CONFIG_SQLLOG, sql3_sql_log_cb, NULL);
+ if (rc != SQLITE_OK)
+ LOGP(DDB, LOGL_NOTICE, "Unable to set SQLite3 SQL log callback\n");
+ } else {
+ LOGP(DDB, LOGL_DEBUG, "Not setting SQL log callback:"
+ " SQLite3 compiled without support for it\n");
+ }
- /* SqLite 3 */
- db_basename = strdup(name);
- db_dirname = strdup(name);
- dbi_conn_set_option(conn, "sqlite3_dbdir", dirname(db_dirname));
- dbi_conn_set_option(conn, "dbname", basename(db_basename));
+ rc = sqlite3_open(g_dbc->fname, &g_dbc->db);
+ if (rc != SQLITE_OK) {
+ LOGP(DDB, LOGL_ERROR, "Unable to open DB; rc =%d\n", rc);
+ talloc_free(g_dbc);
+ return -1;
+ }
+
+ /* enable extended result codes */
+ rc = sqlite3_extended_result_codes(g_dbc->db, 1);
+ if (rc != SQLITE_OK) {
+ LOGP(DDB, LOGL_ERROR, "Unable to enable SQLite3 extended result codes\n");
+ /* non-fatal */
+ }
- if (dbi_conn_connect(conn) < 0)
- goto out_err;
+ char *err_msg;
+ rc = sqlite3_exec(g_dbc->db, "PRAGMA journal_mode=WAL; PRAGMA synchronous = NORMAL;", 0, 0, &err_msg);
+ if (rc != SQLITE_OK) {
+ LOGP(DDB, LOGL_ERROR, "Unable to set Write-Ahead Logging: %s\n", err_msg);
+ sqlite3_free(err_msg);
+ /* non-fatal */
+ }
+
+ rc = sqlite3_exec(g_dbc->db, "PRAGMA secure_delete=0;", 0, 0, &err_msg);
+ if (rc != SQLITE_OK) {
+ LOGP(DDB, LOGL_ERROR, "Unable to disable SECURE_DELETE: %s\n", err_msg);
+ sqlite3_free(err_msg);
+ /* non-fatal */
+ }
return 0;
+}
+
+int db_fini(void)
+{
+ unsigned int i;
+ int rc;
+
+ if (!g_dbc)
+ return 0;
+
+ for (i = 0; i < ARRAY_SIZE(g_dbc->stmt); i++) {
+ /* it is ok to call finalize on NULL */
+ sqlite3_finalize(g_dbc->stmt[i]);
+ }
-out_err:
- free(db_dirname);
- free(db_basename);
- db_dirname = db_basename = NULL;
- return -1;
+ /* Ask sqlite3 to close DB */
+ rc = sqlite3_close(g_dbc->db);
+ if (rc != SQLITE_OK) { /* Make sure it's actually closed! */
+ LOGP(DDB, LOGL_ERROR, "Couldn't close database: (rc=%d) %s\n",
+ rc, sqlite3_errmsg(g_dbc->db));
+ }
+
+ talloc_free(g_dbc);
+ g_dbc = NULL;
+
+ return 0;
}
+/* run (execute) a series of SQL statements */
+static int db_run_statements(struct db_context *dbc, const char **statements, size_t statements_count)
+{
+ int i;
+ for (i = 0; i < statements_count; i++) {
+ const char *stmt_str = statements[i];
+ char *errmsg = NULL;
+ int rc;
+
+ rc = sqlite3_exec(dbc->db, stmt_str, NULL, NULL, &errmsg);
+ if (rc != SQLITE_OK) {
+ LOGP(DDB, LOGL_ERROR, "SQL error during SQL statement '%s': %s\n", stmt_str, errmsg);
+ sqlite3_free(errmsg);
+ return -1;
+ }
+ }
+ return 0;
+}
int db_prepare(void)
{
- dbi_result result;
- int i;
+ unsigned int i;
+ int rc;
- for (i = 0; i < ARRAY_SIZE(create_stmts); i++) {
- result = dbi_conn_query(conn, create_stmts[i]);
- if (!result) {
- LOGP(DDB, LOGL_ERROR,
- "Failed to create some table.\n");
- return 1;
- }
- dbi_result_free(result);
+ OSMO_ASSERT(g_dbc);
+ rc = db_run_statements(g_dbc, create_stmts, ARRAY_SIZE(create_stmts));
+ if (rc < 0) {
+ LOGP(DDB, LOGL_ERROR, "Failed to create some table.\n");
+ return 1;
}
- if (check_db_revision() < 0) {
+ if (check_db_revision(g_dbc) < 0) {
LOGP(DDB, LOGL_FATAL, "Database schema revision invalid, "
"please update your database schema\n");
return -1;
}
- db_configure();
-
- return 0;
-}
-
-int db_fini(void)
-{
- dbi_conn_close(conn);
- dbi_shutdown_r(inst);
+ /* prepare all SQL statements */
+ for (i = 0; i < ARRAY_SIZE(g_dbc->stmt); i++) {
+ rc = sqlite3_prepare_v2(g_dbc->db, stmt_sql[i], -1,
+ &g_dbc->stmt[i], NULL);
+ if (rc != SQLITE_OK) {
+ LOGP(DDB, LOGL_ERROR, "Unable to prepare SQL statement '%s'\n", stmt_sql[i]);
+ return -1;
+ }
+ }
- free(db_dirname);
- free(db_basename);
return 0;
}
/* store an [unsent] SMS to the database */
int db_sms_store(struct gsm_sms *sms)
{
- dbi_result result;
- char *q_text, *q_daddr, *q_saddr;
- unsigned char *q_udata;
+ OSMO_ASSERT(g_dbc);
+ sqlite3_stmt *stmt = g_dbc->stmt[DB_STMT_SMS_STORE];
time_t now, validity_timestamp;
-
- dbi_conn_quote_string_copy(conn, (char *)sms->text, &q_text);
- dbi_conn_quote_string_copy(conn, (char *)sms->dst.addr, &q_daddr);
- dbi_conn_quote_string_copy(conn, (char *)sms->src.addr, &q_saddr);
- dbi_conn_quote_binary_copy(conn, sms->user_data, sms->user_data_len,
- &q_udata);
+ int rc;
now = time(NULL);
validity_timestamp = now + sms->validity_minutes * 60;
- result = dbi_conn_queryf(conn,
- "INSERT INTO SMS "
- "(created, valid_until, "
- "reply_path_req, status_rep_req, is_report, "
- "msg_ref, protocol_id, data_coding_scheme, "
- "ud_hdr_ind, "
- "user_data, text, "
- "dest_addr, dest_ton, dest_npi, "
- "src_addr, src_ton, src_npi) VALUES "
- "(datetime('%lld', 'unixepoch'), datetime('%lld', 'unixepoch'), "
- "%u, %u, %u, "
- "%u, %u, %u, "
- "%u, "
- "%s, %s, "
- "%s, %u, %u, "
- "%s, %u, %u)",
- (int64_t)now, (int64_t)validity_timestamp,
- sms->reply_path_req, sms->status_rep_req, sms->is_report,
- sms->msg_ref, sms->protocol_id, sms->data_coding_scheme,
- sms->ud_hdr_ind,
- q_udata, q_text,
- q_daddr, sms->dst.ton, sms->dst.npi,
- q_saddr, sms->src.ton, sms->src.npi);
- free(q_text);
- free(q_udata);
- free(q_daddr);
- free(q_saddr);
-
- if (!result)
+ db_bind_int64(stmt, "$created", (int64_t) now);
+ db_bind_int64(stmt, "$valid_until", (int64_t) validity_timestamp);
+ db_bind_int(stmt, "$reply_path_req", sms->reply_path_req);
+ db_bind_int(stmt, "$status_rep_req", sms->status_rep_req);
+ db_bind_int(stmt, "$is_report", sms->is_report);
+ db_bind_int(stmt, "$msg_ref", sms->msg_ref);
+ db_bind_int(stmt, "$protocol_id", sms->protocol_id);
+ db_bind_int(stmt, "$data_coding_scheme", sms->data_coding_scheme);
+ db_bind_int(stmt, "$ud_hdr_ind", sms->ud_hdr_ind);
+ /* FIXME: do we need to use legacy DBI compatible quoting of sms->user_data? */
+ db_bind_blob(stmt, "$user_data", sms->user_data, sms->user_data_len);
+ db_bind_text(stmt, "$text", (char *)sms->text);
+ db_bind_text(stmt, "$dest_addr", (char *)sms->dst.addr);
+ db_bind_int(stmt, "$dest_ton", sms->dst.ton);
+ db_bind_int(stmt, "$dest_npi", sms->dst.npi);
+ db_bind_text(stmt, "$src_addr", (char *)sms->src.addr);
+ db_bind_int(stmt, "$src_ton", sms->src.ton);
+ db_bind_int(stmt, "$src_npi", sms->src.npi);
+
+ /* execute statement */
+ rc = sqlite3_step(stmt);
+ db_remove_reset(stmt);
+ if (rc != SQLITE_DONE) {
+ LOGP(DDB, LOGL_ERROR, "Cannot create SMS: SQL error: (%d) %s\n", rc, sqlite3_errmsg(g_dbc->db));
return -EIO;
+ }
+
+ sms->id = sqlite3_last_insert_rowid(g_dbc->db);
+
+ LOGP(DLSMS, LOGL_INFO, "Stored SMS id=%llu in DB\n", sms->id);
- dbi_result_free(result);
return 0;
}
-static struct gsm_sms *sms_from_result(struct gsm_network *net, dbi_result result)
+static void parse_tp_ud_from_result(struct gsm_sms *sms, sqlite3_stmt *stmt)
{
- struct gsm_sms *sms = sms_alloc();
- const char *text, *daddr, *saddr;
const unsigned char *user_data;
+ unsigned int user_data_len;
+ unsigned int text_len;
+ const char *text;
+
+ /* Retrieve TP-UDL (User-Data-Length) in octets (regardless of DCS) */
+ user_data_len = sqlite3_column_bytes(stmt, COL_USER_DATA);
+ if (user_data_len > sizeof(sms->user_data)) {
+ LOGP(DDB, LOGL_ERROR,
+ "SMS TP-UD length %u is too big, truncating to %zu\n",
+ user_data_len, sizeof(sms->user_data));
+ user_data_len = (uint8_t) sizeof(sms->user_data);
+ }
+ sms->user_data_len = user_data_len;
+
+ /* Retrieve the TP-UD (User-Data) itself */
+ if (user_data_len > 0) {
+ user_data = sqlite3_column_blob(stmt, COL_USER_DATA);
+ memcpy(sms->user_data, user_data, user_data_len);
+ }
+
+ /* Retrieve the text length (excluding '\0') */
+ text_len = sqlite3_column_bytes(stmt, COL_TEXT);
+ if (text_len >= sizeof(sms->text)) {
+ LOGP(DDB, LOGL_ERROR,
+ "SMS text length %u is too big, truncating to %zu\n",
+ text_len, sizeof(sms->text) - 1);
+ /* OSMO_STRLCPY_ARRAY() does truncation for us */
+ }
+
+ /* Retrieve the text parsed from TP-UD (User-Data) */
+ text = (const char *)sqlite3_column_text(stmt, COL_TEXT);
+ if (text)
+ OSMO_STRLCPY_ARRAY(sms->text, text);
+}
+
+static struct gsm_sms *sms_from_result(struct gsm_network *net, sqlite3_stmt *stmt)
+{
+ struct gsm_sms *sms = sms_alloc();
+ const char *daddr, *saddr;
time_t validity_timestamp;
if (!sms)
return NULL;
- sms->id = dbi_result_get_ulonglong(result, "id");
+ sms->id = sqlite3_column_int64(stmt, COL_ID);
+
+ sms->created = sqlite3_column_int64(stmt, COL_CREATED);
+ validity_timestamp = sqlite3_column_int64(stmt, COL_VALID_UNTIL);
- sms->created = dbi_result_get_datetime(result, "created");
- validity_timestamp = dbi_result_get_datetime(result, "valid_until");
sms->validity_minutes = (validity_timestamp - sms->created) / 60;
- /* FIXME: those should all be get_uchar, but sqlite3 is braindead */
- sms->reply_path_req = dbi_result_get_ulonglong(result, "reply_path_req");
- sms->status_rep_req = dbi_result_get_ulonglong(result, "status_rep_req");
- sms->is_report = dbi_result_get_ulonglong(result, "is_report");
- sms->msg_ref = dbi_result_get_ulonglong(result, "msg_ref");
- sms->ud_hdr_ind = dbi_result_get_ulonglong(result, "ud_hdr_ind");
- sms->protocol_id = dbi_result_get_ulonglong(result, "protocol_id");
- sms->data_coding_scheme = dbi_result_get_ulonglong(result,
- "data_coding_scheme");
-
- sms->dst.npi = dbi_result_get_ulonglong(result, "dest_npi");
- sms->dst.ton = dbi_result_get_ulonglong(result, "dest_ton");
- daddr = dbi_result_get_string(result, "dest_addr");
+ sms->reply_path_req = sqlite3_column_int(stmt, COL_REPLY_PATH_REQ);
+ sms->status_rep_req = sqlite3_column_int(stmt, COL_STATUS_REP_REQ);
+ sms->is_report = sqlite3_column_int(stmt, COL_IS_REPORT);
+ sms->msg_ref = sqlite3_column_int(stmt, COL_MSG_REF);
+ sms->ud_hdr_ind = sqlite3_column_int(stmt, COL_UD_HDR_IND);
+ sms->protocol_id = sqlite3_column_int(stmt, COL_PROTOCOL_ID);
+ sms->data_coding_scheme = sqlite3_column_int(stmt, COL_DATA_CODING_SCHEME);
+
+ sms->dst.npi = sqlite3_column_int(stmt, COL_DEST_NPI);
+ sms->dst.ton = sqlite3_column_int(stmt, COL_DEST_TON);
+ daddr = (const char *)sqlite3_column_text(stmt, COL_DEST_ADDR);
if (daddr)
OSMO_STRLCPY_ARRAY(sms->dst.addr, daddr);
- sms->receiver = vlr_subscr_find_by_msisdn(net->vlr, sms->dst.addr, VSUB_USE_SMS_RECEIVER);
- sms->src.npi = dbi_result_get_ulonglong(result, "src_npi");
- sms->src.ton = dbi_result_get_ulonglong(result, "src_ton");
- saddr = dbi_result_get_string(result, "src_addr");
+ if (net != NULL) /* db_sms_test passes NULL, so we need to be tolerant */
+ sms->receiver = vlr_subscr_find_by_msisdn(net->vlr, sms->dst.addr,
+ VSUB_USE_SMS_RECEIVER);
+
+ sms->src.npi = sqlite3_column_int(stmt, COL_SRC_NPI);
+ sms->src.ton = sqlite3_column_int(stmt, COL_SRC_TON);
+ saddr = (const char *)sqlite3_column_text(stmt, COL_SRC_ADDR);
if (saddr)
OSMO_STRLCPY_ARRAY(sms->src.addr, saddr);
- sms->user_data_len = dbi_result_get_field_length(result, "user_data");
- user_data = dbi_result_get_binary(result, "user_data");
- if (sms->user_data_len > sizeof(sms->user_data))
- sms->user_data_len = (uint8_t) sizeof(sms->user_data);
- memcpy(sms->user_data, user_data, sms->user_data_len);
+ /* Parse TP-UD, TP-UDL and decoded text */
+ parse_tp_ud_from_result(sms, stmt);
- text = dbi_result_get_string(result, "text");
- if (text)
- OSMO_STRLCPY_ARRAY(sms->text, text);
return sms;
}
struct gsm_sms *db_sms_get(struct gsm_network *net, unsigned long long id)
{
- dbi_result result;
+ OSMO_ASSERT(g_dbc);
+ sqlite3_stmt *stmt = g_dbc->stmt[DB_STMT_SMS_GET];
struct gsm_sms *sms;
+ int rc;
- result = dbi_conn_queryf(conn,
- "SELECT * FROM SMS WHERE SMS.id = %llu", id);
- if (!result)
- return NULL;
+ db_bind_int64(stmt, "$id", id);
- if (!next_row(result)) {
- dbi_result_free(result);
+ rc = sqlite3_step(stmt);
+ if (rc != SQLITE_ROW) {
+ db_remove_reset(stmt);
return NULL;
}
- sms = sms_from_result(net, result);
-
- dbi_result_free(result);
+ sms = sms_from_result(net, stmt);
+ db_remove_reset(stmt);
return sms;
}
struct gsm_sms *db_sms_get_next_unsent(struct gsm_network *net,
unsigned long long min_sms_id,
- unsigned int max_failed)
+ int max_failed)
{
- dbi_result result;
+ OSMO_ASSERT(g_dbc);
+ sqlite3_stmt *stmt = g_dbc->stmt[DB_STMT_SMS_GET_NEXT_UNSENT];
struct gsm_sms *sms;
+ int rc;
- result = dbi_conn_queryf(conn,
- "SELECT * FROM SMS"
- " WHERE sent IS NULL"
- " AND id >= %llu"
- " AND deliver_attempts <= %u"
- " ORDER BY id LIMIT 1",
- min_sms_id, max_failed);
+ db_bind_int64(stmt, "$id", min_sms_id);
+ db_bind_int(stmt, "$attempts", max_failed);
- if (!result)
- return NULL;
-
- if (!next_row(result)) {
- dbi_result_free(result);
+ rc = sqlite3_step(stmt);
+ if (rc != SQLITE_ROW) {
+ db_remove_reset(stmt);
return NULL;
}
- sms = sms_from_result(net, result);
-
- dbi_result_free(result);
+ sms = sms_from_result(net, stmt);
+ db_remove_reset(stmt);
return sms;
}
/* retrieve the next unsent SMS for a given subscriber */
struct gsm_sms *db_sms_get_unsent_for_subscr(struct vlr_subscr *vsub,
- unsigned int max_failed)
+ int max_failed)
{
+ OSMO_ASSERT(g_dbc);
+ sqlite3_stmt *stmt = g_dbc->stmt[DB_STMT_SMS_GET_UNSENT_FOR_SUBSCR];
struct gsm_network *net = vsub->vlr->user_ctx;
- dbi_result result;
struct gsm_sms *sms;
- char *q_msisdn;
+ int rc;
if (!vsub->lu_complete)
return NULL;
@@ -860,60 +845,42 @@ struct gsm_sms *db_sms_get_unsent_for_subscr(struct vlr_subscr *vsub,
if (*vsub->msisdn == '\0')
return NULL;
- dbi_conn_quote_string_copy(conn, vsub->msisdn, &q_msisdn);
- result = dbi_conn_queryf(conn,
- "SELECT * FROM SMS"
- " WHERE sent IS NULL"
- " AND dest_addr = %s"
- " AND deliver_attempts <= %u"
- " ORDER BY id LIMIT 1",
- q_msisdn, max_failed);
- free(q_msisdn);
-
- if (!result)
- return NULL;
+ db_bind_text(stmt, "$dest_addr", vsub->msisdn);
+ db_bind_int(stmt, "$attempts", max_failed);
- if (!next_row(result)) {
- dbi_result_free(result);
+ rc = sqlite3_step(stmt);
+ if (rc != SQLITE_ROW) {
+ db_remove_reset(stmt);
return NULL;
}
- sms = sms_from_result(net, result);
-
- dbi_result_free(result);
+ sms = sms_from_result(net, stmt);
+ db_remove_reset(stmt);
return sms;
}
struct gsm_sms *db_sms_get_next_unsent_rr_msisdn(struct gsm_network *net,
const char *last_msisdn,
- unsigned int max_failed)
+ int max_failed)
{
- dbi_result result;
+ OSMO_ASSERT(g_dbc);
+ sqlite3_stmt *stmt = g_dbc->stmt[DB_STMT_SMS_GET_NEXT_UNSENT_RR_MSISDN];
struct gsm_sms *sms;
- char *q_last_msisdn;
+ int rc;
- dbi_conn_quote_string_copy(conn, last_msisdn, &q_last_msisdn);
- result = dbi_conn_queryf(conn,
- "SELECT * FROM SMS"
- " WHERE sent IS NULL"
- " AND dest_addr > %s"
- " AND deliver_attempts <= %u"
- " ORDER BY dest_addr, id LIMIT 1",
- q_last_msisdn, max_failed);
- free(q_last_msisdn);
+ db_bind_text(stmt, "$dest_addr", last_msisdn);
+ db_bind_int(stmt, "$attempts", max_failed);
- if (!result)
- return NULL;
-
- if (!next_row(result)) {
- dbi_result_free(result);
+ rc = sqlite3_step(stmt);
+ if (rc != SQLITE_ROW) {
+ db_remove_reset(stmt);
return NULL;
}
- sms = sms_from_result(net, result);
+ sms = sms_from_result(net, stmt);
- dbi_result_free(result);
+ db_remove_reset(stmt);
return sms;
}
@@ -921,142 +888,156 @@ struct gsm_sms *db_sms_get_next_unsent_rr_msisdn(struct gsm_network *net,
/* mark a given SMS as delivered */
int db_sms_mark_delivered(struct gsm_sms *sms)
{
- dbi_result result;
+ sqlite3_stmt *stmt;
+ int rc;
- result = dbi_conn_queryf(conn,
- "UPDATE SMS "
- "SET sent = datetime('now') "
- "WHERE id = %llu", sms->id);
- if (!result) {
+ /* this only happens in unit tests that don't db_init() */
+ if (!g_dbc)
+ return 0;
+
+ stmt = g_dbc->stmt[DB_STMT_SMS_MARK_DELIVERED];
+ db_bind_int64(stmt, "$id", sms->id);
+
+ rc = sqlite3_step(stmt);
+ if (rc != SQLITE_DONE) {
+ db_remove_reset(stmt);
LOGP(DDB, LOGL_ERROR, "Failed to mark SMS %llu as sent.\n", sms->id);
return 1;
}
- dbi_result_free(result);
+ db_remove_reset(stmt);
return 0;
}
/* increase the number of attempted deliveries */
int db_sms_inc_deliver_attempts(struct gsm_sms *sms)
{
- dbi_result result;
+ sqlite3_stmt *stmt;
+ int rc;
- result = dbi_conn_queryf(conn,
- "UPDATE SMS "
- "SET deliver_attempts = deliver_attempts + 1 "
- "WHERE id = %llu", sms->id);
- if (!result) {
- LOGP(DDB, LOGL_ERROR, "Failed to inc deliver attempts for "
- "SMS %llu.\n", sms->id);
+ /* this only happens in unit tests that don't db_init() */
+ if (!g_dbc)
+ return 0;
+
+ stmt = g_dbc->stmt[DB_STMT_SMS_INC_DELIVER_ATTEMPTS];
+ db_bind_int64(stmt, "$id", sms->id);
+
+ rc = sqlite3_step(stmt);
+ if (rc != SQLITE_DONE) {
+ db_remove_reset(stmt);
+ LOGP(DDB, LOGL_ERROR, "Failed to inc deliver attempts for SMS %llu.\n", sms->id);
return 1;
}
- dbi_result_free(result);
+ db_remove_reset(stmt);
return 0;
}
/* Drop all pending SMS to or from the given extension */
int db_sms_delete_by_msisdn(const char *msisdn)
{
- dbi_result result;
- char *q_msisdn;
+ OSMO_ASSERT(g_dbc);
+ sqlite3_stmt *stmt = g_dbc->stmt[DB_STMT_SMS_DEL_BY_MSISDN];
+ int rc;
+
if (!msisdn || !*msisdn)
return 0;
- dbi_conn_quote_string_copy(conn, msisdn, &q_msisdn);
- result = dbi_conn_queryf(conn,
- "DELETE FROM SMS WHERE src_addr=%s OR dest_addr=%s",
- q_msisdn, q_msisdn);
- free(q_msisdn);
+ db_bind_text(stmt, "$src_addr", msisdn);
+ db_bind_text(stmt, "$dest_addr", msisdn);
- if (!result) {
- LOGP(DDB, LOGL_ERROR,
- "Failed to delete SMS for %s\n", msisdn);
+ rc = sqlite3_step(stmt);
+ if (rc != SQLITE_DONE) {
+ db_remove_reset(stmt);
+ LOGP(DDB, LOGL_ERROR, "Failed to delete SMS for %s\n", msisdn);
return -1;
}
- dbi_result_free(result);
+
+ db_remove_reset(stmt);
return 0;
}
int db_sms_delete_sent_message_by_id(unsigned long long sms_id)
{
- dbi_result result;
+ OSMO_ASSERT(g_dbc);
+ sqlite3_stmt *stmt = g_dbc->stmt[DB_STMT_SMS_DEL_BY_ID];
+ int rc;
+
+ db_bind_int64(stmt, "$id", sms_id);
- result = dbi_conn_queryf(conn,
- "DELETE FROM SMS WHERE id = %llu AND sent is NOT NULL",
- sms_id);
- if (!result) {
+ rc = sqlite3_step(stmt);
+ if (rc != SQLITE_DONE) {
+ db_remove_reset(stmt);
LOGP(DDB, LOGL_ERROR, "Failed to delete SMS %llu.\n", sms_id);
return 1;
}
- dbi_result_free(result);
+ db_remove_reset(stmt);
return 0;
}
-
-static int delete_expired_sms(unsigned long long sms_id, time_t created, time_t validity_timestamp)
+static int delete_expired_sms(unsigned long long sms_id, time_t validity_timestamp)
{
- dbi_result result;
- time_t now, min_created;
+ OSMO_ASSERT(g_dbc);
+ sqlite3_stmt *stmt = g_dbc->stmt[DB_STMT_SMS_DEL_EXPIRED];
+ time_t now;
+ int rc;
now = time(NULL);
+
+ /* Net yet expired */
if (validity_timestamp > now)
return -1;
- /* Our SMS expiry threshold is hard-coded to roughly 2 weeks at the moment. */
- min_created = now - (time_t)(60 * 60 * 24 * 7 * 2);
- if (min_created < 0) /* bogus system clock? */
- return -1;
- if (created >= min_created) /* not yet expired */
- return -1;
+ db_bind_int64(stmt, "$id", sms_id);
- result = dbi_conn_queryf(conn, "DELETE FROM SMS WHERE id = %llu", sms_id);
- if (!result) {
+ rc = sqlite3_step(stmt);
+ if (rc != SQLITE_DONE) {
+ db_remove_reset(stmt);
LOGP(DDB, LOGL_ERROR, "Failed to delete SMS %llu.\n", sms_id);
return -1;
}
- dbi_result_free(result);
+
+ db_remove_reset(stmt);
return 0;
}
int db_sms_delete_expired_message_by_id(unsigned long long sms_id)
{
- dbi_result result;
- time_t created, validity_timestamp;
+ OSMO_ASSERT(g_dbc);
+ sqlite3_stmt *stmt = g_dbc->stmt[DB_STMT_SMS_GET_VALID_UNTIL_BY_ID];
+ time_t validity_timestamp;
+ int rc;
- result = dbi_conn_queryf(conn, "SELECT created,valid_until FROM SMS WHERE id = %llu", sms_id);
- if (!result)
- return -1;
- if (!next_row(result)) {
- dbi_result_free(result);
+ db_bind_int64(stmt, "$id", sms_id);
+
+ rc = sqlite3_step(stmt);
+ if (rc != SQLITE_ROW) {
+ db_remove_reset(stmt);
return -1;
}
- created = dbi_result_get_datetime(result, "created");
- validity_timestamp = dbi_result_get_datetime(result, "valid_until");
+ validity_timestamp = sqlite3_column_int64(stmt, 0);
- dbi_result_free(result);
- return delete_expired_sms(sms_id, created, validity_timestamp);
+ db_remove_reset(stmt);
+ return delete_expired_sms(sms_id, validity_timestamp);
}
void db_sms_delete_oldest_expired_message(void)
{
- dbi_result result;
-
- result = dbi_conn_queryf(conn, "SELECT id,created,valid_until FROM SMS ORDER BY created LIMIT 1");
- if (!result)
- return;
+ OSMO_ASSERT(g_dbc);
+ sqlite3_stmt *stmt = g_dbc->stmt[DB_STMT_SMS_GET_OLDEST_EXPIRED];
+ int rc;
- if (next_row(result)) {
+ rc = sqlite3_step(stmt);
+ if (rc == SQLITE_ROW) {
unsigned long long sms_id;
- time_t created, validity_timestamp;
+ time_t validity_timestamp;
- sms_id = dbi_result_get_ulonglong(result, "id");
- created = dbi_result_get_datetime(result, "created");
- validity_timestamp = dbi_result_get_datetime(result, "valid_until");
- delete_expired_sms(sms_id, created, validity_timestamp);
+ sms_id = sqlite3_column_int64(stmt, 0);
+ validity_timestamp = sqlite3_column_int64(stmt, 1);
+ delete_expired_sms(sms_id, validity_timestamp);
}
- dbi_result_free(result);
+ db_remove_reset(stmt);
}
diff --git a/src/libmsc/e_link.c b/src/libmsc/e_link.c
index 0a2be795c..b26f53bc5 100644
--- a/src/libmsc/e_link.c
+++ b/src/libmsc/e_link.c
@@ -1,6 +1,6 @@
/* E-interface messaging over a GSUP connection */
/*
- * (C) 2019 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de>
+ * (C) 2019 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
* All Rights Reserved
*
* SPDX-License-Identifier: AGPL-3.0+
diff --git a/src/libmsc/gsm_04_08.c b/src/libmsc/gsm_04_08.c
index 68b12c03a..17350faad 100644
--- a/src/libmsc/gsm_04_08.c
+++ b/src/libmsc/gsm_04_08.c
@@ -29,43 +29,34 @@
#include <errno.h>
#include <time.h>
#include <netinet/in.h>
-#include <regex.h>
#include <sys/types.h>
#include "config.h"
-#include <osmocom/msc/db.h>
#include <osmocom/msc/debug.h>
#include <osmocom/msc/gsm_data.h>
-#include <osmocom/msc/gsm_subscriber.h>
-#include <osmocom/msc/gsm_04_11.h>
#include <osmocom/msc/gsm_04_08.h>
-#include <osmocom/msc/gsm_04_80.h>
-#include <osmocom/msc/gsm_04_14.h>
-#include <osmocom/msc/gsm_09_11.h>
+#include <osmocom/msc/msc_vgcs.h>
#include <osmocom/msc/signal.h>
#include <osmocom/msc/transaction.h>
-#include <osmocom/msc/silent_call.h>
-#include <osmocom/msc/mncc_int.h>
-#include <osmocom/abis/e1_input.h>
-#include <osmocom/core/bitvec.h>
#include <osmocom/msc/vlr.h>
#include <osmocom/msc/msc_a.h>
-#include <osmocom/msc/paging.h>
#include <osmocom/gsm/gsm48.h>
-#include <osmocom/gsm/gsm0480.h>
#include <osmocom/gsm/gsm_utils.h>
#include <osmocom/gsm/protocol/gsm_04_08.h>
#include <osmocom/core/msgb.h>
#include <osmocom/core/talloc.h>
#include <osmocom/core/utils.h>
#include <osmocom/core/byteswap.h>
+#include <osmocom/core/fsm.h>
#include <osmocom/gsm/tlv.h>
#include <osmocom/crypt/auth.h>
+#include <osmocom/crypt/utran_cipher.h>
#include <osmocom/msc/msub.h>
#include <osmocom/msc/msc_roles.h>
+#include <osmocom/msc/call_leg.h>
#include <assert.h>
@@ -129,42 +120,44 @@ static int gsm0408_loc_upd_acc(struct msc_a *msc_a, uint32_t send_tmsi)
struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 LOC UPD ACC");
struct gsm48_hdr *gh;
struct gsm48_loc_area_id *lai;
- uint8_t *mid;
- struct gsm_network *net = msc_a_net(msc_a);
struct vlr_subscr *vsub = msc_a_vsub(msc_a);
- struct osmo_location_area_id laid = {
- .plmn = net->plmn,
- .lac = vsub->cgi.lai.lac,
- };
+ uint8_t *l;
+ int rc;
+ struct osmo_mobile_identity mi = {};
gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
gh->proto_discr = GSM48_PDISC_MM;
gh->msg_type = GSM48_MT_MM_LOC_UPD_ACCEPT;
lai = (struct gsm48_loc_area_id *) msgb_put(msg, sizeof(*lai));
- gsm48_generate_lai2(lai, &laid);
+ gsm48_generate_lai2(lai, &vsub->cgi.lai);
if (send_tmsi == GSM_RESERVED_TMSI) {
/* we did not allocate a TMSI to the MS, so we need to
* include the IMSI in order for the MS to delete any
* old TMSI that might still be allocated */
- uint8_t mi[10];
- int len;
- len = gsm48_generate_mid_from_imsi(mi, vsub->imsi);
- mid = msgb_put(msg, len);
- memcpy(mid, mi, len);
+ mi.type = GSM_MI_TYPE_IMSI;
+ OSMO_STRLCPY_ARRAY(mi.imsi, vsub->imsi);
DEBUGP(DMM, "-> %s LOCATION UPDATE ACCEPT\n",
vlr_subscr_name(vsub));
} else {
/* Include the TMSI, which means that the MS will send a
* TMSI REALLOCATION COMPLETE, and we should wait for
* that until T3250 expiration */
- mid = msgb_put(msg, GSM48_MID_TMSI_LEN);
- gsm48_generate_mid_from_tmsi(mid, send_tmsi);
+ mi.type = GSM_MI_TYPE_TMSI;
+ mi.tmsi = send_tmsi;
DEBUGP(DMM, "-> %s LOCATION UPDATE ACCEPT (TMSI = 0x%08x)\n",
vlr_subscr_name(vsub),
send_tmsi);
}
+ l = msgb_tl_put(msg, GSM48_IE_MOBILE_ID);
+ rc = osmo_mobile_identity_encode_msgb(msg, &mi, false);
+ if (rc < 0) {
+ msgb_free(msg);
+ return -EINVAL;
+ }
+ *l = rc;
+
/* TODO: Follow-on proceed */
/* TODO: CTS permission */
/* TODO: Equivalent PLMNs */
@@ -193,9 +186,11 @@ static int mm_tx_identity_req(struct msc_a *msc_a, uint8_t id_type)
static int mm_rx_id_resp(struct msc_a *msc_a, struct msgb *msg)
{
struct gsm48_hdr *gh = msgb_l3(msg);
- uint8_t *mi = gh->data+1;
+ uint8_t *mi_data = gh->data+1;
uint8_t mi_len = gh->data[0];
struct vlr_subscr *vsub = msc_a_vsub(msc_a);
+ struct osmo_mobile_identity mi;
+ int rc;
if (!vsub) {
LOGP(DMM, LOGL_ERROR,
@@ -203,11 +198,33 @@ static int mm_rx_id_resp(struct msc_a *msc_a, struct msgb *msg)
return -EINVAL;
}
- DEBUGP(DMM, "IDENTITY RESPONSE: MI=%s\n", osmo_mi_name(mi, mi_len));
+ /* There muct be at least one octet with MI type */
+ if (!mi_len) {
+ LOGP(DMM, LOGL_NOTICE, "MM Identity Response contains "
+ "malformed Mobile Identity\n");
+ return -EINVAL;
+ }
+
+ rc = osmo_mobile_identity_decode(&mi, mi_data, mi_len, false);
+ if (rc) {
+ LOGP(DMM, LOGL_ERROR, "Failure to decode Mobile Identity in MM Identity Response (rc=%d)\n", rc);
+ return -EINVAL;
+ }
+
+ /* Make sure we got what we expected */
+ if (mi.type != msc_a->mm_id_req_type) {
+ LOGP(DMM, LOGL_NOTICE, "MM Identity Response contains unexpected "
+ "Mobile Identity type %s (extected %s)\n",
+ gsm48_mi_type_name(mi.type),
+ gsm48_mi_type_name(msc_a->mm_id_req_type));
+ return -EINVAL;
+ }
+
+ DEBUGP(DMM, "IDENTITY RESPONSE: %s\n", osmo_mobile_identity_to_str_c(OTC_SELECT, &mi));
osmo_signal_dispatch(SS_SUBSCR, S_SUBSCR_IDENTITY, gh->data);
- return vlr_subscr_rx_id_resp(vsub, mi, mi_len);
+ return vlr_subscr_rx_id_resp(vsub, &mi);
}
/* 9.2.5 CM service accept */
@@ -225,7 +242,9 @@ static int msc_gsm48_tx_mm_serv_ack(struct msc_a *msc_a)
return msc_a_tx_dtap_to_i(msc_a, msg);
}
-/* 9.2.6 CM service reject */
+/* 9.2.6 CM service reject.
+ * For an active and valid CM Service Request, instead use msc_vlr_tx_cm_serv_rej(), which also takes care of
+ * decrementing the use token for that service type. */
static int msc_gsm48_tx_mm_serv_rej(struct msc_a *msc_a,
enum gsm48_reject_value value)
{
@@ -301,8 +320,6 @@ static int mm_rx_loc_upd_req(struct msc_a *msc_a, struct msgb *msg)
{
struct gsm48_hdr *gh = msgb_l3(msg);
struct gsm48_loc_upd_req *lu;
- uint8_t mi_type;
- char mi_string[GSM48_MI_SIZE];
enum vlr_lu_type vlr_lu_type = VLR_LU_TYPE_REGULAR;
uint32_t tmsi;
char *imsi;
@@ -311,6 +328,15 @@ static int mm_rx_loc_upd_req(struct msc_a *msc_a, struct msgb *msg)
bool is_utran;
struct gsm_network *net = msc_a_net(msc_a);
struct vlr_subscr *vsub;
+ struct osmo_mobile_identity mi;
+ int rc;
+
+ rc = osmo_mobile_identity_decode_from_l3(&mi, msg, false);
+ if (rc) {
+ LOG_MSC_A_CAT(msc_a, DMM, LOGL_ERROR,
+ "Failed to decode Mobile Identity in Location Updating Request\n");
+ return -EINVAL;
+ }
lu = (struct gsm48_loc_upd_req *) gh->data;
@@ -318,7 +344,7 @@ static int mm_rx_loc_upd_req(struct msc_a *msc_a, struct msgb *msg)
LOG_MSC_A_CAT(msc_a, DMM, LOGL_ERROR,
"Cannot accept another LU, conn already busy establishing authenticity;"
" extraneous LOCATION UPDATING REQUEST: MI=%s LU-type=%s\n",
- osmo_mi_name(lu->mi, lu->mi_len), osmo_lu_type_name(lu->type));
+ osmo_mobile_identity_to_str_c(OTC_SELECT, &mi), osmo_lu_type_name(lu->type));
return -EINVAL;
}
@@ -326,47 +352,46 @@ static int mm_rx_loc_upd_req(struct msc_a *msc_a, struct msgb *msg)
LOG_MSC_A_CAT(msc_a, DMM, LOGL_ERROR,
"Cannot accept another LU, conn already established;"
" extraneous LOCATION UPDATING REQUEST: MI=%s LU-type=%s\n",
- osmo_mi_name(lu->mi, lu->mi_len), osmo_lu_type_name(lu->type));
+ osmo_mobile_identity_to_str_c(OTC_SELECT, &mi), osmo_lu_type_name(lu->type));
return -EINVAL;
}
msc_a->complete_layer3_type = COMPLETE_LAYER3_LU;
- msub_update_id_from_mi(msc_a->c.msub, lu->mi, lu->mi_len);
+
+ msub_update_id_from_mi(msc_a->c.msub, &mi);
LOG_MSC_A_CAT(msc_a, DMM, LOGL_DEBUG, "LOCATION UPDATING REQUEST: MI=%s LU-type=%s\n",
- osmo_mi_name(lu->mi, lu->mi_len), osmo_lu_type_name(lu->type));
+ osmo_mobile_identity_to_str_c(OTC_SELECT, &mi), osmo_lu_type_name(lu->type));
- osmo_signal_dispatch(SS_SUBSCR, S_SUBSCR_IDENTITY, &lu->mi_len);
+ osmo_signal_dispatch(SS_SUBSCR, S_SUBSCR_IDENTITY, &mi);
switch (lu->type) {
case GSM48_LUPD_NORMAL:
- rate_ctr_inc(&net->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_NORMAL]);
+ rate_ctr_inc(rate_ctr_group_get_ctr(net->msc_ctrs, MSC_CTR_LOC_UPDATE_TYPE_NORMAL));
vlr_lu_type = VLR_LU_TYPE_REGULAR;
break;
case GSM48_LUPD_IMSI_ATT:
- rate_ctr_inc(&net->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_ATTACH]);
+ rate_ctr_inc(rate_ctr_group_get_ctr(net->msc_ctrs, MSC_CTR_LOC_UPDATE_TYPE_ATTACH));
vlr_lu_type = VLR_LU_TYPE_IMSI_ATTACH;
break;
case GSM48_LUPD_PERIODIC:
- rate_ctr_inc(&net->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_PERIODIC]);
+ rate_ctr_inc(rate_ctr_group_get_ctr(net->msc_ctrs, MSC_CTR_LOC_UPDATE_TYPE_PERIODIC));
vlr_lu_type = VLR_LU_TYPE_PERIODIC;
break;
}
/* TODO: 10.5.1.6 MS Classmark for UMTS / Classmark 2 */
- /* TODO: 10.5.3.14 Aditional update parameters (CS fallback calls) */
+ /* TODO: 10.5.3.14 Additional update parameters (CS fallback calls) */
/* TODO: 10.5.7.8 Device properties */
/* TODO: 10.5.1.15 MS network feature support */
- mi_type = lu->mi[0] & GSM_MI_TYPE_MASK;
- gsm48_mi_to_string(mi_string, sizeof(mi_string), lu->mi, lu->mi_len);
- switch (mi_type) {
+ switch (mi.type) {
case GSM_MI_TYPE_IMSI:
tmsi = GSM_RESERVED_TMSI;
- imsi = mi_string;
+ imsi = mi.imsi;
break;
case GSM_MI_TYPE_TMSI:
- tmsi = tmsi_from_string(mi_string);
+ tmsi = mi.tmsi;
imsi = NULL;
break;
default:
@@ -388,7 +413,8 @@ static int mm_rx_loc_upd_req(struct msc_a *msc_a, struct msgb *msg)
net->vlr, msc_a, vlr_lu_type, tmsi, imsi,
&old_lai, &msc_a->via_cell.lai,
is_utran || net->authentication_required,
- is_utran || net->a5_encryption_mask > 0x01,
+ msc_a_is_ciphering_to_be_attempted(msc_a),
+ msc_a_is_ciphering_required(msc_a),
lu->key_seq,
osmo_gsm48_classmark1_is_r99(&lu->classmark1),
is_utran,
@@ -402,7 +428,7 @@ static int mm_rx_loc_upd_req(struct msc_a *msc_a, struct msgb *msg)
/* From vlr_loc_update() we expect an implicit dispatch of
* VLR_ULA_E_UPDATE_LA, and thus we expect msc_vlr_subscr_assoc() to
- * already have been called and completed. Has an error occured? */
+ * already have been called and completed. Has an error occurred? */
vsub = msc_a_vsub(msc_a);
if (!vsub) {
@@ -644,44 +670,36 @@ int gsm48_tx_mm_auth_rej(struct msc_a *msc_a)
static int msc_vlr_tx_cm_serv_rej(void *msc_conn_ref, enum osmo_cm_service_type cm_service_type,
enum gsm48_reject_value cause);
-static int cm_serv_reuse_conn(struct msc_a *msc_a, const uint8_t *mi_lv, enum osmo_cm_service_type cm_serv_type)
+static int cm_serv_reuse_conn(struct msc_a *msc_a, const struct osmo_mobile_identity *mi, enum osmo_cm_service_type cm_serv_type)
{
- uint8_t mi_type;
- char mi_string[GSM48_MI_SIZE];
- uint32_t tmsi;
struct gsm_network *net = msc_a_net(msc_a);
struct vlr_subscr *vsub = msc_a_vsub(msc_a);
- gsm48_mi_to_string(mi_string, sizeof(mi_string), mi_lv+1, mi_lv[0]);
- mi_type = mi_lv[1] & GSM_MI_TYPE_MASK;
-
- switch (mi_type) {
+ switch (mi->type) {
case GSM_MI_TYPE_IMSI:
- if (vlr_subscr_matches_imsi(vsub, mi_string))
+ if (vlr_subscr_matches_imsi(vsub, mi->imsi))
goto accept_reuse;
break;
case GSM_MI_TYPE_TMSI:
- tmsi = osmo_load32be(mi_lv+2);
- if (vlr_subscr_matches_tmsi(vsub, tmsi))
+ if (vlr_subscr_matches_tmsi(vsub, mi->tmsi))
goto accept_reuse;
break;
case GSM_MI_TYPE_IMEI:
- if (vlr_subscr_matches_imei(vsub, mi_string))
+ if (vlr_subscr_matches_imei(vsub, mi->imei))
goto accept_reuse;
break;
default:
break;
}
- LOG_MSC_A_CAT(msc_a, DMM, LOGL_ERROR, "CM Service Request with mismatching mobile identity: %s %s\n",
- gsm48_mi_type_name(mi_type), mi_string);
+ LOG_MSC_A_CAT(msc_a, DMM, LOGL_ERROR, "CM Service Request with mismatching mobile identity: %s\n",
+ osmo_mobile_identity_to_str_c(OTC_SELECT, mi));
msc_vlr_tx_cm_serv_rej(msc_a, cm_serv_type, GSM48_REJECT_ILLEGAL_MS);
return -EINVAL;
accept_reuse:
LOG_MSC_A_CAT(msc_a, DMM, LOGL_DEBUG, "re-using already accepted connection\n");
- msc_a_get(msc_a, msc_a_cm_service_type_to_use(cm_serv_type));
msub_update_id(msc_a->c.msub);
return net->vlr->ops.tx_cm_serv_acc(msc_a, cm_serv_type);
}
@@ -689,7 +707,7 @@ accept_reuse:
/*
* Handle CM Service Requests
* a) Verify that the packet is long enough to contain the information
- * we require otherwsie reject with INCORRECT_MESSAGE
+ * we require otherwise reject with INCORRECT_MESSAGE
* b) Try to parse the TMSI. If we do not have one reject
* c) Check that we know the subscriber with the TMSI otherwise reject
* with a HLR cause
@@ -704,10 +722,18 @@ int gsm48_rx_mm_serv_req(struct msc_a *msc_a, struct msgb *msg)
struct gsm48_service_request *req;
struct gsm48_classmark2 *cm2;
uint8_t *cm2_buf, cm2_len;
- uint8_t *mi_buf, mi_len;
- uint8_t *mi, mi_type;
bool is_utran;
struct vlr_subscr *vsub;
+ struct osmo_mobile_identity mi;
+ int rc;
+
+ /* There are two ways to respond with a CM Service Reject:
+ * Directly and only send the CM Service Reject with msc_gsm48_tx_mm_serv_rej().
+ * Decrement the CM Service use count token and send the message with msc_vlr_tx_cm_serv_rej().
+ *
+ * Until we accept the CM Service Request message as such, there is no use count placed for the service type.
+ * So in here use msc_gsm48_tx_mm_serv_rej() to respond.
+ */
/* Make sure that both header and CM Service Request fit into the buffer */
if (msgb_l3len(msg) < sizeof(*gh) + sizeof(*req)) {
@@ -716,6 +742,12 @@ int gsm48_rx_mm_serv_req(struct msc_a *msc_a, struct msgb *msg)
return msc_gsm48_tx_mm_serv_rej(msc_a, GSM48_REJECT_INCORRECT_MESSAGE);
}
+ rc = osmo_mobile_identity_decode_from_l3(&mi, msg, false);
+ if (rc) {
+ LOG_MSC_A(msc_a, LOGL_ERROR, "Rx CM SERVICE REQUEST: unable to decode Mobile Identity\n");
+ return msc_gsm48_tx_mm_serv_rej(msc_a, GSM48_REJECT_INCORRECT_MESSAGE);
+ }
+
gh = (struct gsm48_hdr *) msgb_l3(msg);
req = (struct gsm48_service_request *) gh->data;
@@ -732,18 +764,6 @@ int gsm48_rx_mm_serv_req(struct msc_a *msc_a, struct msgb *msg)
return msc_gsm48_tx_mm_serv_rej(msc_a, GSM48_REJECT_INCORRECT_MESSAGE);
}
- /* MI (Mobile Identity) LV follows the Classmark2 */
- mi_buf = cm2_buf + cm2_len;
- mi_len = mi_buf[0];
- mi = mi_buf + 1;
-
- /* Prevent buffer overrun: check the length of MI */
- if (mi_buf + mi_len > msg->tail) {
- LOG_MSC_A(msc_a, LOGL_ERROR, "Rx CM SERVICE REQUEST: Mobile Identity "
- "length=%u is too big\n", cm2_len);
- return msc_gsm48_tx_mm_serv_rej(msc_a, GSM48_REJECT_INCORRECT_MESSAGE);
- }
-
if (msc_a_is_establishing_auth_ciph(msc_a)) {
LOG_MSC_A(msc_a, LOGL_ERROR,
"Cannot accept CM Service Request, conn already busy establishing authenticity\n");
@@ -752,12 +772,11 @@ int gsm48_rx_mm_serv_req(struct msc_a *msc_a, struct msgb *msg)
}
msc_a->complete_layer3_type = COMPLETE_LAYER3_CM_SERVICE_REQ;
- msub_update_id_from_mi(msc_a->c.msub, mi, mi_len);
+ msub_update_id_from_mi(msc_a->c.msub, &mi);
LOG_MSC_A_CAT(msc_a, DMM, LOGL_DEBUG, "Rx CM SERVICE REQUEST cm_service_type=%s\n",
osmo_cm_service_type_name(req->cm_service_type));
- mi_type = (mi && mi_len) ? (mi[0] & GSM_MI_TYPE_MASK) : GSM_MI_TYPE_NONE;
- switch (mi_type) {
+ switch (mi.type) {
case GSM_MI_TYPE_IMSI:
case GSM_MI_TYPE_TMSI:
/* continue below */
@@ -771,19 +790,22 @@ int gsm48_rx_mm_serv_req(struct msc_a *msc_a, struct msgb *msg)
}
/* fall-through for non-emergency setup */
default:
- LOG_MSC_A(msc_a, LOGL_ERROR, "MI type is not expected: %s\n", gsm48_mi_type_name(mi_type));
+ LOG_MSC_A(msc_a, LOGL_ERROR, "MI type is not expected: %s\n", gsm48_mi_type_name(mi.type));
return msc_gsm48_tx_mm_serv_rej(msc_a, GSM48_REJECT_INCORRECT_MESSAGE);
}
- if (!msc_a_cm_service_type_to_use(req->cm_service_type))
+ if (!msc_a_cm_service_type_to_use(msc_a, req->cm_service_type))
return msc_gsm48_tx_mm_serv_rej(msc_a, GSM48_REJECT_SRV_OPT_NOT_SUPPORTED);
- if (msc_a_is_accepted(msc_a))
- return cm_serv_reuse_conn(msc_a, mi_buf, req->cm_service_type);
+ /* At this point, the CM Service Request message is being accepted.
+ * Increment the matching use token, and from here on use msc_vlr_tx_cm_serv_rej() to respond in case of
+ * failure. */
+ msc_a_get(msc_a, msc_a_cm_service_type_to_use(msc_a, req->cm_service_type));
- osmo_signal_dispatch(SS_SUBSCR, S_SUBSCR_IDENTITY, mi_buf);
+ if (msc_a_is_accepted(msc_a))
+ return cm_serv_reuse_conn(msc_a, &mi, req->cm_service_type);
- msc_a_get(msc_a, msc_a_cm_service_type_to_use(req->cm_service_type));
+ osmo_signal_dispatch(SS_SUBSCR, S_SUBSCR_IDENTITY, &mi);
is_utran = (msc_a->c.ran->type == OSMO_RAT_UTRAN_IU);
vlr_proc_acc_req(msc_a->c.fi,
@@ -791,15 +813,16 @@ int gsm48_rx_mm_serv_req(struct msc_a *msc_a, struct msgb *msg)
net->vlr, msc_a,
VLR_PR_ARQ_T_CM_SERV_REQ,
req->cm_service_type,
- mi-1, &msc_a->via_cell.lai,
+ &mi, &msc_a->via_cell.lai,
is_utran || net->authentication_required,
- is_utran || net->a5_encryption_mask > 0x01,
+ msc_a_is_ciphering_to_be_attempted(msc_a),
+ msc_a_is_ciphering_required(msc_a),
req->cipher_key_seq,
osmo_gsm48_classmark2_is_r99(cm2, cm2_len),
is_utran);
/* From vlr_proc_acc_req() we expect an implicit dispatch of PR_ARQ_E_START we expect
- * msc_vlr_subscr_assoc() to already have been called and completed. Has an error occured? */
+ * msc_vlr_subscr_assoc() to already have been called and completed. Has an error occurred? */
vsub = msc_a_vsub(msc_a);
if (!vsub) {
LOG_MSC_A(msc_a, LOGL_ERROR, "subscriber not allowed to do a CM Service Request\n");
@@ -814,21 +837,129 @@ int gsm48_rx_mm_serv_req(struct msc_a *msc_a, struct msgb *msg)
/* Receive a CM Re-establish Request */
static int gsm48_rx_cm_reest_req(struct msc_a *msc_a, struct msgb *msg)
{
- uint8_t mi_type;
- char mi_string[GSM48_MI_SIZE];
- struct gsm48_hdr *gh = msgb_l3(msg);
+ struct gsm_network *net = msc_a_net(msc_a);
+ struct gsm48_hdr *gh;
+ struct gsm48_service_request *req;
+ struct gsm48_classmark2 *cm2;
+ uint8_t *cm2_buf, cm2_len;
+ bool is_utran;
+ struct vlr_subscr *vsub;
+ struct osmo_mobile_identity mi;
+ struct msub *prev_msub;
+ struct msc_a *prev_msc_a;
- uint8_t classmark2_len = gh->data[1];
- uint8_t *classmark2 = gh->data+2;
- uint8_t mi_len = *(classmark2 + classmark2_len);
- uint8_t *mi = (classmark2 + classmark2_len + 1);
+ int rc = osmo_mobile_identity_decode_from_l3(&mi, msg, false);
+ if (rc) {
+ LOGP(DMM, LOGL_ERROR, "CM RE-ESTABLISH REQUEST: cannot decode Mobile Identity\n");
+ return -EINVAL;
+ }
+
+ msc_a->complete_layer3_type = COMPLETE_LAYER3_CM_RE_ESTABLISH_REQ;
+ msub_update_id_from_mi(msc_a->c.msub, &mi);
- gsm48_mi_to_string(mi_string, sizeof(mi_string), mi, mi_len);
- mi_type = mi[0] & GSM_MI_TYPE_MASK;
- DEBUGP(DMM, "<- CM RE-ESTABLISH REQUEST MI(%s)=%s\n", gsm48_mi_type_name(mi_type), mi_string);
+ DEBUGP(DMM, "<- CM RE-ESTABLISH REQUEST %s\n", osmo_mobile_identity_to_str_c(OTC_SELECT, &mi));
- /* we don't support CM call re-establishment */
- return msc_gsm48_tx_mm_serv_rej(msc_a, GSM48_REJECT_SRV_OPT_NOT_SUPPORTED);
+ gh = (struct gsm48_hdr *) msgb_l3(msg);
+ req = (struct gsm48_service_request *) gh->data;
+
+ /* Unfortunately in Phase1 the Classmark2 length is variable, so we cannot
+ * just use gsm48_service_request struct, and need to parse it manually. */
+ cm2_len = gh->data[1];
+ cm2_buf = gh->data + 2;
+ cm2 = (struct gsm48_classmark2 *) cm2_buf;
+
+ /* Prevent buffer overrun: check the length of Classmark2 */
+ if (cm2_buf + cm2_len > msg->tail) {
+ LOG_MSC_A(msc_a, LOGL_ERROR, "Rx CM SERVICE REQUEST: Classmark2 "
+ "length=%u is too big\n", cm2_len);
+ return msc_gsm48_tx_mm_serv_rej(msc_a, GSM48_REJECT_INCORRECT_MESSAGE);
+ }
+
+ /* Look up the other, previously active connection for this subscriber */
+ vsub = vlr_subscr_find_by_mi(net->vlr, &mi, __func__);
+ prev_msub = msub_for_vsub(vsub);
+ prev_msc_a = msub_msc_a(prev_msub);
+ if (!vsub || !prev_msub || !prev_msc_a) {
+ LOG_MSC_A(msc_a, LOGL_ERROR, "CM Re-Establish Request for unknown subscriber: %s\n",
+ osmo_mobile_identity_to_str_c(OTC_SELECT, &mi));
+ if (vsub)
+ vlr_subscr_put(vsub, __func__);
+ return msc_gsm48_tx_mm_serv_rej(msc_a, GSM48_REJECT_CALL_CAN_NOT_BE_IDENTIFIED);
+ }
+
+ LOG_MSC_A(msc_a, LOGL_NOTICE, "New conn requesting Re-Establishment\n");
+ LOG_MSC_A(prev_msc_a, LOGL_NOTICE, "Old conn matching Re-Establishment request (%s)\n",
+ osmo_use_count_to_str_c(OTC_SELECT, &prev_msc_a->use_count));
+
+ if (!prev_msc_a->cc.call_leg || !prev_msc_a->cc.active_trans) {
+ LOG_MSC_A(msc_a, LOGL_ERROR, "CM Re-Establish Request only supported for voice calls\n");
+ if (vsub)
+ vlr_subscr_put(vsub, __func__);
+ return msc_gsm48_tx_mm_serv_rej(msc_a, GSM48_REJECT_CALL_CAN_NOT_BE_IDENTIFIED);
+ }
+
+ msc_a_get(prev_msc_a, __func__);
+
+ /* Move the call_leg and active CC trans over to the new msc_a */
+ call_leg_reparent(prev_msc_a->cc.call_leg,
+ msc_a->c.fi,
+ MSC_EV_CALL_LEG_TERM,
+ MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE,
+ MSC_EV_CALL_LEG_RTP_COMPLETE);
+ msc_a->cc.call_leg = prev_msc_a->cc.call_leg;
+ prev_msc_a->cc.call_leg = NULL;
+
+ msc_a->cc.active_trans = prev_msc_a->cc.active_trans;
+ msc_a->cc.active_trans->msc_a = msc_a;
+ msc_a_get(msc_a, MSC_A_USE_CC);
+ prev_msc_a->cc.active_trans = NULL;
+ msc_a_put(prev_msc_a, MSC_A_USE_CC);
+
+ /* Dis-associate the VLR subscriber from the previous msc_a, so that we can start a new Process Access Request
+ * on the new msc_a. */
+ if (vsub->proc_arq_fsm) {
+ osmo_fsm_inst_term(vsub->proc_arq_fsm, OSMO_FSM_TERM_REGULAR, NULL);
+ vsub->proc_arq_fsm = NULL;
+ }
+ if (prev_msub->vsub) {
+ vlr_subscr_put(prev_msub->vsub, VSUB_USE_MSUB);
+ prev_msub->vsub = NULL;
+ }
+
+ /* Clear the previous conn.
+ * FIXME: we are clearing the previous conn before having authenticated the new conn. That means anyone can send
+ * CM Re-Establishing requests with arbitrary mobile identities without having to authenticate, and can freely
+ * Clear any connections at will. */
+ msc_a_release_cn(prev_msc_a);
+ msc_a_put(prev_msc_a, __func__);
+ prev_msc_a = NULL;
+
+ /* Kick off Authentication and Ciphering for the new conn. */
+ is_utran = (msc_a->c.ran->type == OSMO_RAT_UTRAN_IU);
+ vlr_proc_acc_req(msc_a->c.fi,
+ MSC_A_EV_AUTHENTICATED, MSC_A_EV_CN_CLOSE, NULL,
+ net->vlr, msc_a,
+ VLR_PR_ARQ_T_CM_RE_ESTABLISH_REQ, 0,
+ &mi, &msc_a->via_cell.lai,
+ is_utran || net->authentication_required,
+ msc_a_is_ciphering_to_be_attempted(msc_a),
+ msc_a_is_ciphering_required(msc_a),
+ req->cipher_key_seq,
+ osmo_gsm48_classmark2_is_r99(cm2, cm2_len),
+ is_utran);
+ vlr_subscr_put(vsub, __func__);
+
+ /* From vlr_proc_acc_req() we expect an implicit dispatch of PR_ARQ_E_START, and we expect
+ * msc_vlr_subscr_assoc() to already have been called and completed. Has an error occurred? */
+ vsub = msc_a_vsub(msc_a);
+ if (!vsub) {
+ LOG_MSC_A(msc_a, LOGL_ERROR, "subscriber not allowed to do a CM Service Request\n");
+ return -EIO;
+ }
+
+ vsub->classmark.classmark2 = *cm2;
+ vsub->classmark.classmark2_len = cm2_len;
+ return 0;
}
static int gsm48_rx_mm_imsi_detach_ind(struct msc_a *msc_a, struct msgb *msg)
@@ -837,39 +968,41 @@ static int gsm48_rx_mm_imsi_detach_ind(struct msc_a *msc_a, struct msgb *msg)
struct gsm48_hdr *gh = msgb_l3(msg);
struct gsm48_imsi_detach_ind *idi =
(struct gsm48_imsi_detach_ind *) gh->data;
- uint8_t mi_type = idi->mi[0] & GSM_MI_TYPE_MASK;
- char mi_string[GSM48_MI_SIZE];
+ struct osmo_mobile_identity mi;
struct vlr_subscr *vsub = NULL;
- gsm48_mi_to_string(mi_string, sizeof(mi_string), idi->mi, idi->mi_len);
- DEBUGP(DMM, "IMSI DETACH INDICATION: MI(%s)=%s\n",
- gsm48_mi_type_name(mi_type), mi_string);
+ int rc = osmo_mobile_identity_decode_from_l3(&mi, msg, false);
+ if (rc) {
+ LOGP(DMM, LOGL_ERROR, "IMSI DETACH INDICATION: cannot decode Mobile Identity\n");
+ return -EINVAL;
+ }
+
+ DEBUGP(DMM, "IMSI DETACH INDICATION: %s\n", osmo_mobile_identity_to_str_c(OTC_SELECT, &mi));
- rate_ctr_inc(&net->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_DETACH]);
+ rate_ctr_inc(rate_ctr_group_get_ctr(net->msc_ctrs, MSC_CTR_LOC_UPDATE_TYPE_DETACH));
- switch (mi_type) {
+ switch (mi.type) {
case GSM_MI_TYPE_TMSI:
- vsub = vlr_subscr_find_by_tmsi(net->vlr,
- tmsi_from_string(mi_string), __func__);
+ vsub = vlr_subscr_find_by_tmsi(net->vlr, mi.tmsi, __func__);
break;
case GSM_MI_TYPE_IMSI:
- vsub = vlr_subscr_find_by_imsi(net->vlr, mi_string, __func__);
+ vsub = vlr_subscr_find_by_imsi(net->vlr, mi.imsi, __func__);
break;
case GSM_MI_TYPE_IMEI:
case GSM_MI_TYPE_IMEISV:
/* no sim card... FIXME: what to do ? */
- LOGP(DMM, LOGL_ERROR, "MI(%s)=%s: unimplemented mobile identity type\n",
- gsm48_mi_type_name(mi_type), mi_string);
+ LOGP(DMM, LOGL_ERROR, "%s: unimplemented mobile identity type\n",
+ osmo_mobile_identity_to_str_c(OTC_SELECT, &mi));
break;
default:
- LOGP(DMM, LOGL_ERROR, "MI(%s)=%s: unknown mobile identity type\n",
- gsm48_mi_type_name(mi_type), mi_string);
+ LOGP(DMM, LOGL_ERROR, "%s: unknown mobile identity type\n",
+ osmo_mobile_identity_to_str_c(OTC_SELECT, &mi));
break;
}
if (!vsub) {
- LOGP(DMM, LOGL_ERROR, "IMSI DETACH for unknown subscriber MI(%s)=%s\n",
- gsm48_mi_type_name(mi_type), mi_string);
+ LOGP(DMM, LOGL_ERROR, "IMSI DETACH for unknown subscriber %s\n",
+ osmo_mobile_identity_to_str_c(OTC_SELECT, &mi));
} else {
LOGP(DMM, LOGL_INFO, "IMSI DETACH for %s\n", vlr_subscr_name(vsub));
msub_set_vsub(msc_a->c.msub, vsub);
@@ -1138,24 +1271,31 @@ static int gsm48_rx_rr_pag_resp(struct msc_a *msc_a, struct msgb *msg)
uint8_t classmark2_len = gh->data[1];
uint8_t *classmark2_buf = gh->data+2;
struct gsm48_classmark2 *cm2 = (void*)classmark2_buf;
- uint8_t *mi_lv = classmark2_buf + classmark2_len;
bool is_utran;
struct vlr_subscr *vsub;
+ struct osmo_mobile_identity mi;
+ int rc;
if (msc_a_is_establishing_auth_ciph(msc_a)) {
- LOG_MSC_A_CAT(msc_a, DMM, LOGL_ERROR,
+ LOG_MSC_A_CAT(msc_a, DRR, LOGL_ERROR,
"Ignoring Paging Response, conn already busy establishing authenticity\n");
return 0;
}
if (msc_a_is_accepted(msc_a)) {
- LOG_MSC_A_CAT(msc_a, DMM, LOGL_ERROR, "Ignoring Paging Response, conn already established\n");
+ LOG_MSC_A_CAT(msc_a, DRR, LOGL_ERROR, "Ignoring Paging Response, conn already established\n");
return 0;
}
+ rc = osmo_mobile_identity_decode_from_l3(&mi, msg, false);
+ if (rc) {
+ LOG_MSC_A_CAT(msc_a, DRR, LOGL_ERROR, "Paging Response: cannot decode Mobile Identity\n");
+ return -EINVAL;
+ }
+
msc_a->complete_layer3_type = COMPLETE_LAYER3_PAGING_RESP;
- msub_update_id_from_mi(msc_a->c.msub, mi_lv + 1, *mi_lv);
- LOG_MSC_A_CAT(msc_a, DRR, LOGL_DEBUG, "Rx PAGING RESPONSE\n");
+ msub_update_id_from_mi(msc_a->c.msub, &mi);
+ LOG_MSC_A_CAT(msc_a, DRR, LOGL_DEBUG, "Rx PAGING RESPONSE %s\n", osmo_mobile_identity_to_str_c(OTC_SELECT, &mi));
msc_a_get(msc_a, MSC_A_USE_PAGING_RESPONSE);
@@ -1163,19 +1303,25 @@ static int gsm48_rx_rr_pag_resp(struct msc_a *msc_a, struct msgb *msg)
vlr_proc_acc_req(msc_a->c.fi,
MSC_A_EV_AUTHENTICATED, MSC_A_EV_CN_CLOSE, NULL,
net->vlr, msc_a,
- VLR_PR_ARQ_T_PAGING_RESP, 0, mi_lv, &msc_a->via_cell.lai,
+ VLR_PR_ARQ_T_PAGING_RESP, 0, &mi, &msc_a->via_cell.lai,
is_utran || net->authentication_required,
- is_utran || net->a5_encryption_mask > 0x01,
+ msc_a_is_ciphering_to_be_attempted(msc_a),
+ msc_a_is_ciphering_required(msc_a),
pr->key_seq,
osmo_gsm48_classmark2_is_r99(cm2, classmark2_len),
is_utran);
/* From vlr_proc_acc_req() we expect an implicit dispatch of PR_ARQ_E_START we expect
- * msc_vlr_subscr_assoc() to already have been called and completed. Has an error occured? */
+ * msc_vlr_subscr_assoc() to already have been called and completed. Has an error occurred? */
vsub = msc_a_vsub(msc_a);
if (!vsub) {
- LOG_MSC_A(msc_a, LOGL_ERROR, "subscriber not allowed to do a Paging Response\n");
- msc_a_put(msc_a, MSC_A_USE_PAGING_RESPONSE);
+ LOG_MSC_A_CAT(msc_a, DRR, LOGL_ERROR, "subscriber not allowed to do a Paging Response\n");
+
+ /* Above MSC_A_USE_PAGING_RESPONSE may already have been removed by a forced release, put that use only
+ * if it still exists. (see msc_a_fsm_releasing_onenter()) */
+ if (osmo_use_count_by(&msc_a->use_count, MSC_A_USE_PAGING_RESPONSE))
+ msc_a_put(msc_a, MSC_A_USE_PAGING_RESPONSE);
+
return -EIO;
}
@@ -1190,21 +1336,37 @@ static int gsm48_rx_rr_ciphering_mode_complete(struct msc_a *msc_a, struct msgb
struct gsm48_hdr *gh = msgb_l3(msg);
unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
struct tlv_parsed tp;
- struct tlv_p_entry *mi;
+ struct tlv_p_entry *mi_tlv;
+ struct osmo_mobile_identity mi;
tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len, 0, 0);
- mi = TLVP_GET(&tp, GSM48_IE_MOBILE_ID);
+ mi_tlv = TLVP_GET(&tp, GSM48_IE_MOBILE_ID);
- if (!mi)
+ /* IMEI(SV) is optional for this message */
+ if (!mi_tlv)
return 0;
+ if (!mi_tlv->len)
+ return -EINVAL;
- LOG_MSC_A(msc_a, LOGL_DEBUG, "Ciphering Mode Complete contains Mobile Identity: %s\n",
- osmo_mi_name(mi->val, mi->len));
+ if (osmo_mobile_identity_decode(&mi, mi_tlv->val, mi_tlv->len, false)) {
+ LOGP(DMM, LOGL_ERROR, "RR Ciphering Mode Complete contains invalid Mobile Identity %s\n",
+ osmo_hexdump(mi_tlv->val, mi_tlv->len));
+ return -EINVAL;
+ }
+ if (mi.type != GSM_MI_TYPE_IMEISV) {
+ LOGP(DMM, LOGL_ERROR, "RR Ciphering Mode Complete contains "
+ "unexpected Mobile Identity type %s\n",
+ osmo_mobile_identity_to_str_c(OTC_SELECT, &mi));
+ return -EINVAL;
+ }
+
+ LOG_MSC_A(msc_a, LOGL_DEBUG, "RR Ciphering Mode Complete contains Mobile Identity: %s\n",
+ osmo_mobile_identity_to_str_c(OTC_SELECT, &mi));
if (!vsub)
return 0;
- return vlr_subscr_rx_id_resp(vsub, mi->val, mi->len);
+ return vlr_subscr_rx_id_resp(vsub, &mi);
}
static int gsm48_rx_rr_app_info(struct msc_a *msc_a, struct msgb *msg)
@@ -1218,8 +1380,9 @@ static int gsm48_rx_rr_app_info(struct msc_a *msc_a, struct msgb *msg)
apdu_len = gh->data[1];
apdu_data = gh->data+2;
- DEBUGP(DRR, "RX APPLICATION INFO id/flags=0x%02x apdu_len=%u apdu=%s\n",
- apdu_id_flags, apdu_len, osmo_hexdump(apdu_data, apdu_len));
+ LOG_MSC_A_CAT(msc_a, DRR, LOGL_DEBUG, "Rx RR APPLICATION INFO "
+ "(id/flags=0x%02x apdu_len=%u apdu=%s)\n",
+ apdu_id_flags, apdu_len, osmo_hexdump(apdu_data, apdu_len));
/* we're not using the app info blob anywhere, so ignore. */
#if 0
@@ -1245,6 +1408,9 @@ int gsm0408_rcv_rr(struct msc_a *msc_a, struct msgb *msg)
case GSM48_MT_RR_APP_INFO:
rc = gsm48_rx_rr_app_info(msc_a, msg);
break;
+ case GSM48_MT_RR_UPLINK_RELEASE:
+ rc = gsm44068_rcv_rr(msc_a, msg);
+ break;
default:
LOG_MSC_A_CAT(msc_a, DRR, LOGL_NOTICE, "MSC: Unimplemented %s GSM 04.08 RR "
"message\n", gsm48_rr_msg_name(gh->msg_type));
@@ -1300,6 +1466,10 @@ static int msc_vlr_tx_auth_rej(void *msc_conn_ref)
static int msc_vlr_tx_id_req(void *msc_conn_ref, uint8_t mi_type)
{
struct msc_a *msc_a = msc_conn_ref;
+
+ /* Store requested MI type, so we can check the response */
+ msc_a->mm_id_req_type = mi_type;
+
return mm_tx_identity_req(msc_a, mi_type);
}
@@ -1327,12 +1497,19 @@ int msc_vlr_tx_cm_serv_acc(void *msc_conn_ref, enum osmo_cm_service_type cm_serv
static int msc_vlr_tx_common_id(void *msc_conn_ref)
{
struct msc_a *msc_a = msc_conn_ref;
+ struct vlr_subscr *vsub = msc_a_vsub(msc_a);
struct ran_msg msg = {
.msg_type = RAN_MSG_COMMON_ID,
.common_id = {
- .imsi = msc_a_vsub(msc_a)->imsi,
+ .imsi = vsub->imsi,
+ .last_eutran_plmn_present = vsub->sgs.last_eutran_plmn_present,
},
};
+ if (vsub->sgs.last_eutran_plmn_present) {
+ memcpy(&msg.common_id.last_eutran_plmn, &vsub->sgs.last_eutran_plmn,
+ sizeof(vsub->sgs.last_eutran_plmn));
+ }
+
return msc_a_ran_down(msc_a, MSC_ROLE_I, &msg);
}
@@ -1346,13 +1523,14 @@ static int msc_vlr_tx_mm_info(void *msc_conn_ref)
return gsm48_tx_mm_info(msc_a);
}
-/* VLR asks us to transmit a CM Service Reject */
+/* VLR asks us to transmit a CM Service Reject.
+ * Decrement the CM Service type's use token and send the CM Service Reject message. */
static int msc_vlr_tx_cm_serv_rej(void *msc_conn_ref, enum osmo_cm_service_type cm_service_type,
enum gsm48_reject_value cause)
{
struct msc_a *msc_a = msc_conn_ref;
msc_gsm48_tx_mm_serv_rej(msc_a, cause);
- msc_a_put(msc_a, msc_a_cm_service_type_to_use(cm_service_type));
+ msc_a_put(msc_a, msc_a_cm_service_type_to_use(msc_a, cm_service_type));
return 0;
}
@@ -1365,7 +1543,9 @@ static void msc_vlr_subscr_update(struct vlr_subscr *subscr)
msub_update_id(msub);
}
-/* VLR informs us that the subscriber has been associated with a conn */
+/* VLR informs us that the subscriber has been associated with a conn.
+ * The subscriber has *not* been authenticated yet, so the vsub should be protected from potentially invalid information
+ * from the msc_a. */
static int msc_vlr_subscr_assoc(void *msc_conn_ref,
struct vlr_subscr *vsub)
{
@@ -1375,6 +1555,10 @@ static int msc_vlr_subscr_assoc(void *msc_conn_ref,
if (msub_set_vsub(msub, vsub))
return -EINVAL;
+
+ /* FIXME: would be better to modify vsub->* only after the subscriber is authenticated, in
+ * evaluate_acceptance_outcome(conn_accepted == true). */
+
vsub->cs.attached_via_ran = msc_a->c.ran->type;
/* In case we have already received Classmark Information before the VLR Subscriber was
@@ -1388,6 +1572,24 @@ static int msc_vlr_subscr_assoc(void *msc_conn_ref,
return 0;
}
+static void msc_vlr_subscr_inval(void *msc_conn_ref, struct vlr_subscr *vsub)
+{
+ /* Search vsub backwards to make sure msc_conn_ref is a valid msc_a instance. */
+ struct msub *msub;
+ OSMO_ASSERT(vsub);
+ llist_for_each_entry(msub, &msub_list, entry) {
+ struct msc_a *msc_a;
+ if (msub->vsub != vsub)
+ continue;
+
+ msc_a = msub_msc_a(msub);
+ if (msc_a)
+ msc_a_release_cn(msc_a);
+
+ msub->vsub = NULL;
+ }
+}
+
/* operations that we need to implement for libvlr */
const struct vlr_ops msc_vlr_ops = {
.tx_auth_req = msc_vlr_tx_auth_req,
@@ -1402,6 +1604,7 @@ const struct vlr_ops msc_vlr_ops = {
.tx_mm_info = msc_vlr_tx_mm_info,
.subscr_update = msc_vlr_subscr_update,
.subscr_assoc = msc_vlr_subscr_assoc,
+ .subscr_inval = msc_vlr_subscr_inval,
};
struct msgb *gsm48_create_mm_serv_rej(enum gsm48_reject_value value)
@@ -1436,27 +1639,3 @@ struct msgb *gsm48_create_loc_upd_rej(uint8_t cause)
gh->data[0] = cause;
return msg;
}
-
-int gsm48_extract_mi(uint8_t *classmark2_lv, int length, char *mi_string, uint8_t *mi_type)
-{
- /* Check the size for the classmark */
- if (length < 1 + *classmark2_lv)
- return -1;
-
- uint8_t *mi_lv = classmark2_lv + *classmark2_lv + 1;
- if (length < 2 + *classmark2_lv + mi_lv[0])
- return -2;
-
- *mi_type = mi_lv[1] & GSM_MI_TYPE_MASK;
- return gsm48_mi_to_string(mi_string, GSM48_MI_SIZE, mi_lv+1, *mi_lv);
-}
-
-int gsm48_paging_extract_mi(struct gsm48_pag_resp *resp, int length,
- char *mi_string, uint8_t *mi_type)
-{
- static const uint32_t classmark_offset =
- offsetof(struct gsm48_pag_resp, classmark2);
- uint8_t *classmark2_lv = (uint8_t *) &resp->classmark2;
- return gsm48_extract_mi(classmark2_lv, length - classmark_offset,
- mi_string, mi_type);
-}
diff --git a/src/libmsc/gsm_04_08_cc.c b/src/libmsc/gsm_04_08_cc.c
index 2869bba12..63b1699ab 100644
--- a/src/libmsc/gsm_04_08_cc.c
+++ b/src/libmsc/gsm_04_08_cc.c
@@ -30,6 +30,8 @@
#include <regex.h>
#include <sys/types.h>
+#include <osmocom/mgcp_client/mgcp_client_endpoint_fsm.h>
+
#include <osmocom/msc/db.h>
#include <osmocom/msc/debug.h>
#include <osmocom/msc/gsm_data.h>
@@ -41,6 +43,7 @@
#include <osmocom/msc/gsm_09_11.h>
#include <osmocom/msc/signal.h>
#include <osmocom/msc/transaction.h>
+#include <osmocom/msc/transaction_cc.h>
#include <osmocom/msc/silent_call.h>
#include <osmocom/msc/mncc_int.h>
#include <osmocom/abis/e1_input.h>
@@ -53,6 +56,8 @@
#include <osmocom/msc/rtp_stream.h>
#include <osmocom/msc/mncc_call.h>
#include <osmocom/msc/msc_t.h>
+#include <osmocom/msc/sdp_msg.h>
+#include <osmocom/msc/codec_mapping.h>
#include <osmocom/gsm/gsm48.h>
#include <osmocom/gsm/gsm0480.h>
@@ -124,7 +129,7 @@ static void gsm48_start_guard_timer(struct gsm_trans *trans)
/* Call Control */
-void cc_tx_to_mncc(struct gsm_network *net, struct msgb *msg)
+static void cc_tx_to_mncc(struct gsm_network *net, struct msgb *msg)
{
net->mncc_recv(net, msg);
}
@@ -161,20 +166,22 @@ static void count_statistics(struct gsm_trans *trans, int new_state)
/* state incoming */
switch (new_state) {
case GSM_CSTATE_ACTIVE:
- osmo_counter_inc(trans->net->active_calls);
- rate_ctr_inc(&msc->ctr[MSC_CTR_CALL_ACTIVE]);
+ osmo_stat_item_inc(osmo_stat_item_group_get_item(trans->net->statg, MSC_STAT_ACTIVE_CALLS),
+ 1);
+ rate_ctr_inc(rate_ctr_group_get_ctr(msc, MSC_CTR_CALL_ACTIVE));
break;
}
/* state outgoing */
switch (old_state) {
case GSM_CSTATE_ACTIVE:
- osmo_counter_dec(trans->net->active_calls);
+ osmo_stat_item_dec(osmo_stat_item_group_get_item(trans->net->statg, MSC_STAT_ACTIVE_CALLS),
+ 1);
if (new_state == GSM_CSTATE_DISCONNECT_REQ ||
new_state == GSM_CSTATE_DISCONNECT_IND)
- rate_ctr_inc(&msc->ctr[MSC_CTR_CALL_COMPLETE]);
+ rate_ctr_inc(rate_ctr_group_get_ctr(msc, MSC_CTR_CALL_COMPLETE));
else
- rate_ctr_inc(&msc->ctr[MSC_CTR_CALL_INCOMPLETE]);
+ rate_ctr_inc(rate_ctr_group_get_ctr(msc, MSC_CTR_CALL_INCOMPLETE));
break;
}
}
@@ -224,15 +231,82 @@ static void gsm48_stop_cc_timer(struct gsm_trans *trans)
}
}
-static int mncc_recvmsg(struct gsm_network *net, struct gsm_trans *trans,
- int msg_type, struct gsm_mncc *mncc)
+/* Log the MNCC tx and rx events.
+ * Depending on msg_type, also log whether RTP information is passed on.
+ * (This is particularly interesting for the doc/sequence_charts/msc_log_to_ladder.py)
+ */
+#define log_mncc_rx_tx(ARGS...) _log_mncc_rx_tx(__FILE__, __LINE__, ##ARGS)
+static void _log_mncc_rx_tx(const char *file, int line,
+ struct gsm_trans *trans, const char *rx_tx, const union mncc_msg *mncc)
+{
+ const char *sdp = NULL;
+ struct sdp_msg sdp_msg = {};
+ struct osmo_sockaddr addr = {};
+
+ if (!log_check_level(DMNCC, LOGL_DEBUG))
+ return;
+
+ switch (mncc->msg_type) {
+ case MNCC_RTP_CREATE:
+ case MNCC_RTP_CONNECT:
+ addr = (struct osmo_sockaddr){ .u.sas = mncc->rtp.addr };
+ sdp = mncc->rtp.sdp;
+ break;
+
+ case MNCC_SETUP_IND:
+ case MNCC_SETUP_REQ:
+ case MNCC_SETUP_COMPL_IND:
+ case MNCC_SETUP_COMPL_REQ:
+ case MNCC_SETUP_RSP:
+ case MNCC_SETUP_CNF:
+ case MNCC_CALL_CONF_IND:
+ case MNCC_CALL_PROC_REQ:
+ case MNCC_ALERT_IND:
+ case MNCC_ALERT_REQ:
+ sdp = mncc->signal.sdp;
+ break;
+
+ default:
+ break;
+ }
+
+ if (sdp && sdp[0]) {
+ int rc = sdp_msg_from_sdp_str(&sdp_msg, sdp);
+ if (rc != 0) {
+ LOG_TRANS_CAT_SRC(trans, DMNCC, LOGL_ERROR, file, line, "%s %s: invalid SDP message (trying anyway)\n",
+ rx_tx,
+ get_mncc_name(mncc->msg_type));
+ LOG_TRANS_CAT_SRC(trans, DMNCC, LOGL_DEBUG, file, line, "erratic SDP: %s\n",
+ osmo_quote_cstr_c(OTC_SELECT, sdp, -1));
+ return;
+ }
+ LOG_TRANS_CAT_SRC(trans, DMNCC, LOGL_DEBUG, file, line, "%s %s (RTP=%s)\n",
+ rx_tx,
+ get_mncc_name(mncc->msg_type),
+ sdp_msg_to_str(&sdp_msg));
+ return;
+ }
+
+ if (osmo_sockaddr_is_any(&addr) == 0) {
+ LOG_TRANS_CAT_SRC(trans, DMNCC, LOGL_DEBUG, file, line, "%s %s (RTP=%s)\n",
+ rx_tx,
+ get_mncc_name(mncc->msg_type),
+ osmo_sockaddr_to_str_c(OTC_SELECT, &addr));
+ return;
+ }
+
+ LOG_TRANS_CAT_SRC(trans, DMNCC, LOGL_DEBUG, file, line, "%s %s\n", rx_tx, get_mncc_name(mncc->msg_type));
+}
+
+#define mncc_recvmsg(ARGS...) _mncc_recvmsg(__FILE__, __LINE__, ##ARGS)
+static int _mncc_recvmsg(const char *file, int line,
+ struct gsm_network *net, struct gsm_trans *trans, int msg_type, struct gsm_mncc *mncc)
{
struct msgb *msg;
unsigned char *data;
- LOG_TRANS_CAT(trans, DMNCC, LOGL_DEBUG, "tx %s\n", get_mncc_name(msg_type));
-
mncc->msg_type = msg_type;
+ log_mncc_rx_tx(trans, "tx", (union mncc_msg *)mncc);
msg = msgb_alloc(sizeof(struct gsm_mncc), "MNCC");
if (!msg)
@@ -242,6 +316,9 @@ static int mncc_recvmsg(struct gsm_network *net, struct gsm_trans *trans,
memcpy(data, mncc, sizeof(struct gsm_mncc));
cc_tx_to_mncc(net, msg);
+ /* trans may be NULL when sending an MNCC error reply upon an invalid MNCC request */
+ if (trans)
+ trans->cc.mncc_initiated = true;
return 0;
}
@@ -267,6 +344,15 @@ void _gsm48_cc_trans_free(struct gsm_trans *trans)
/* send release to L4, if callref still exists */
if (trans->callref) {
+ /* Send MNCC REL.ind (cause='Resource unavailable') */
+ if (trans->cc.mncc_initiated) {
+ mncc_release_ind(trans->net, trans, trans->callref,
+ GSM48_CAUSE_LOC_PRN_S_LU,
+ (trans->cc.state == GSM_CSTATE_CALL_RECEIVED) ?
+ GSM48_CC_CAUSE_USER_NOTRESPOND :
+ GSM48_CC_CAUSE_RESOURCE_UNAVAIL);
+ }
+
/* FIXME: currently, a CC trans that would not yet be in state GSM_CSTATE_RELEASE_REQ fails to send a
* CC Release to the MS if it gets freed here. Hack it to do so. */
if (trans->cc.state != GSM_CSTATE_RELEASE_REQ) {
@@ -275,10 +361,6 @@ void _gsm48_cc_trans_free(struct gsm_trans *trans)
mncc_set_cause(&rel, GSM48_CAUSE_LOC_PRN_S_LU, GSM48_CC_CAUSE_RESOURCE_UNAVAIL);
gsm48_cc_tx_release(trans, &rel);
}
- /* Ressource unavailable */
- mncc_release_ind(trans->net, trans, trans->callref,
- GSM48_CAUSE_LOC_PRN_S_LU,
- GSM48_CC_CAUSE_RESOURCE_UNAVAIL);
/* This is a final freeing of the transaction. The MNCC release may have triggered the
* T308 release timer, but we don't have the luxury of graceful CC Release here. */
gsm48_stop_cc_timer(trans);
@@ -308,6 +390,20 @@ static void cc_paging_cb(struct msc_a *msc_a, struct gsm_trans *trans)
msc_a_get(msc_a, MSC_A_USE_CC);
trans->msc_a = msc_a;
trans->paging_request = NULL;
+
+ /* Get the GCR from the MO call leg (if any). */
+ if (!trans->cc.lcls)
+ trans->cc.lcls = trans_lcls_compose(trans, true);
+ if (trans->cc.lcls && trans->cc.msg.fields & MNCC_F_GCR) {
+ int rc = osmo_dec_gcr(&trans->cc.lcls->gcr,
+ &trans->cc.msg.gcr[0],
+ sizeof(trans->cc.msg.gcr));
+ if (rc < 0)
+ LOG_TRANS(trans, LOGL_ERROR, "Failed to parse GCR\n");
+ else
+ trans->cc.lcls->gcr_available = true;
+ }
+
osmo_fsm_inst_dispatch(msc_a->c.fi, MSC_A_EV_TRANSACTION_ACCEPTED, trans);
/* send SETUP request to called party */
gsm48_cc_tx_setup(trans, &trans->cc.msg);
@@ -327,8 +423,8 @@ static void cc_paging_cb(struct msc_a *msc_a, struct gsm_trans *trans)
/* bridge channels of two transactions */
static int tch_bridge(struct gsm_network *net, const struct gsm_mncc_bridge *bridge)
{
- struct gsm_trans *trans1 = trans_find_by_callref(net, bridge->callref[0]);
- struct gsm_trans *trans2 = trans_find_by_callref(net, bridge->callref[1]);
+ struct gsm_trans *trans1 = trans_find_by_callref(net, TRANS_CC, bridge->callref[0]);
+ struct gsm_trans *trans2 = trans_find_by_callref(net, TRANS_CC, bridge->callref[1]);
struct call_leg *cl1;
struct call_leg *cl2;
@@ -353,7 +449,7 @@ static int tch_bridge(struct gsm_network *net, const struct gsm_mncc_bridge *bri
cl1 = trans1->msc_a->cc.call_leg;
cl2 = trans2->msc_a->cc.call_leg;
- return call_leg_local_bridge(cl1, trans1->callref, trans1, cl2, trans2->callref, trans2);
+ return call_leg_local_bridge(cl1, trans1->call_id, trans1, cl2, trans2->call_id, trans2);
}
static int gsm48_cc_rx_status_enq(struct gsm_trans *trans, struct msgb *msg)
@@ -372,6 +468,8 @@ static void gsm48_cc_timeout(void *arg)
int l4_location = GSM48_CAUSE_LOC_PRN_S_LU;
struct gsm_mncc mo_rel, l4_rel;
+ LOG_TRANS(trans, LOGL_INFO, "Timeout of T%x\n", trans->cc.Tcurrent);
+
memset(&mo_rel, 0, sizeof(struct gsm_mncc));
mo_rel.callref = trans->callref;
memset(&l4_rel, 0, sizeof(struct gsm_mncc));
@@ -448,8 +546,8 @@ static void gsm48_cc_timeout(void *arg)
static inline void disconnect_bridge(struct gsm_network *net,
const struct gsm_mncc_bridge *bridge, int err)
{
- struct gsm_trans *trans0 = trans_find_by_callref(net, bridge->callref[0]);
- struct gsm_trans *trans1 = trans_find_by_callref(net, bridge->callref[1]);
+ struct gsm_trans *trans0 = trans_find_by_callref(net, TRANS_CC, bridge->callref[0]);
+ struct gsm_trans *trans1 = trans_find_by_callref(net, TRANS_CC, bridge->callref[1]);
struct gsm_mncc mx_rel;
if (!trans0 || !trans1)
return;
@@ -492,6 +590,26 @@ static int gsm48_cc_rx_setup(struct gsm_trans *trans, struct msgb *msg)
memset(&setup, 0, sizeof(struct gsm_mncc));
setup.callref = trans->callref;
+ /* New Global Call Reference */
+ if (!trans->cc.lcls)
+ trans->cc.lcls = trans_lcls_compose(trans, true);
+
+ /* Pass the LCLS GCR on to the MT call leg via MNCC */
+ if (trans->cc.lcls) {
+ struct msgb *gcr_msg = msgb_alloc(sizeof(setup.gcr), "MNCC GCR");
+ const struct osmo_gcr_parsed *gcr = &trans->cc.lcls->gcr;
+ int rc;
+
+ if (gcr_msg != NULL && (rc = osmo_enc_gcr(gcr_msg, gcr)) > 0) {
+ memcpy(&setup.gcr[0], gcr_msg->data, rc);
+ setup.fields |= MNCC_F_GCR;
+ } else
+ LOG_TRANS(trans, LOGL_ERROR, "Failed to encode GCR\n");
+ msgb_free(gcr_msg);
+ }
+
+ OSMO_ASSERT(trans->msc_a);
+
tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len, 0, 0);
/* emergency setup is identified by msg_type */
if (msg_type == GSM48_MT_CC_EMERG_SETUP) {
@@ -536,6 +654,20 @@ static int gsm48_cc_rx_setup(struct gsm_trans *trans, struct msgb *msg)
gsm48_decode_called(&setup.called,
TLVP_VAL(&tp, GSM48_IE_CALLED_BCD)-1);
}
+ /* low layer compatibility */
+ if (TLVP_PRESENT(&tp, GSM48_IE_LOWL_COMPAT) && TLVP_LEN(&tp, GSM48_IE_LOWL_COMPAT) > 0 &&
+ TLVP_LEN(&tp, GSM48_IE_LOWL_COMPAT) <= sizeof(setup.llc.compat)) {
+ setup.fields |= MNCC_F_LOWL_COMPAT;
+ setup.llc.len = TLVP_LEN(&tp, GSM48_IE_LOWL_COMPAT);
+ memcpy(setup.llc.compat, TLVP_VAL(&tp, GSM48_IE_LOWL_COMPAT), setup.llc.len);
+ }
+ /* high layer compatibility */
+ if (TLVP_PRESENT(&tp, GSM48_IE_HIGHL_COMPAT) && TLVP_LEN(&tp, GSM48_IE_HIGHL_COMPAT) > 0 &&
+ TLVP_LEN(&tp, GSM48_IE_HIGHL_COMPAT) <= sizeof(setup.hlc.compat)) {
+ setup.fields |= MNCC_F_HIGHL_COMPAT;
+ setup.hlc.len = TLVP_LEN(&tp, GSM48_IE_HIGHL_COMPAT);
+ memcpy(setup.hlc.compat, TLVP_VAL(&tp, GSM48_IE_HIGHL_COMPAT), setup.hlc.len);
+ }
/* user-user */
if (TLVP_PRESENT(&tp, GSM48_IE_USER_USER)) {
setup.fields |= MNCC_F_USERUSER;
@@ -561,28 +693,145 @@ static int gsm48_cc_rx_setup(struct gsm_trans *trans, struct msgb *msg)
TLVP_VAL(&tp, GSM48_IE_CC_CAP)-1);
}
- new_cc_state(trans, GSM_CSTATE_INITIATED);
+ /* MO call leg starting, gather all codec information so far known: */
+ trans_cc_filter_init(trans);
+ trans_cc_filter_set_ran(trans, trans->msc_a->c.ran->type);
+ trans_cc_filter_set_bss(trans, trans->msc_a);
+ if (setup.fields & MNCC_F_BEARER_CAP)
+ trans_cc_filter_set_ms_from_bc(trans, &trans->bearer_cap);
+ trans_cc_filter_run(trans);
LOG_TRANS(trans, setup.emergency ? LOGL_NOTICE : LOGL_INFO, "%sSETUP to %s\n",
setup.emergency ? "EMERGENCY_" : "", setup.called.number);
- rate_ctr_inc(&trans->net->msc_ctrs->ctr[MSC_CTR_CALL_MO_SETUP]);
+ rate_ctr_inc(rate_ctr_group_get_ctr(trans->net->msc_ctrs, MSC_CTR_CALL_MO_SETUP));
+
+ new_cc_state(trans, GSM_CSTATE_INITIATED);
+
+ /* To complete the MNCC_SETUP_IND, we need to provide an RTP address and port. First instruct the MGW to create
+ * a CN-side RTP conn, and continue with MNCC_SETUP_IND once that is done. Leave trans.cc in GSM_CSTATE_NULL and
+ * note down the msg_type to indicate that we indeed composed an MNCC_SETUP_IND for later. */
+ setup.msg_type = MNCC_SETUP_IND;
+ trans->cc.msg = setup;
+ return msc_a_try_call_assignment(trans);
+ /* continue in gsm48_cc_rx_setup_cn_local_rtp_port_known() */
+}
+
+/* Callback for MNCC_SETUP_IND waiting for the core network RTP port to be established by the MGW (via msc_a) */
+void gsm48_cc_rx_setup_cn_local_rtp_port_known(struct gsm_trans *trans)
+{
+ struct msc_a *msc_a = trans->msc_a;
+ struct gsm_mncc setup = trans->cc.msg;
+ struct osmo_sockaddr_str *rtp_cn_local;
+ struct sdp_msg *sdp;
+ int rc;
+
+ if (trans->cc.state != GSM_CSTATE_INITIATED
+ || setup.msg_type != MNCC_SETUP_IND) {
+ LOG_TRANS(trans, LOGL_ERROR,
+ "Unexpected CC state. Expected GSM_CSTATE_INITIATED and a buffered MNCC_SETUP_IND message,"
+ " found CC state %d and msg_type %s\n",
+ trans->cc.state, get_mncc_name(setup.msg_type));
+ trans->callref = 0;
+ trans_free(trans);
+ return;
+ }
+
+ if (!msc_a) {
+ LOG_TRANS(trans, LOGL_ERROR, "No connection for CC trans\n");
+ trans->callref = 0;
+ trans_free(trans);
+ return;
+ }
+
+ /* 'setup' above has taken the value of trans->cc.msg, we can now clear that. */
+ trans->cc.msg = (struct gsm_mncc){};
+
+ /* Insert the CN side RTP port now available into SDP and compose SDP string */
+ rtp_cn_local = call_leg_local_ip(msc_a->cc.call_leg, RTP_TO_CN);
+ if (!osmo_sockaddr_str_is_nonzero(rtp_cn_local)) {
+ LOG_TRANS(trans, LOGL_ERROR, "Cannot compose SDP for MNCC_SETUP_IND: no RTP set up for the CN side\n");
+ trans_free(trans);
+ return;
+ }
+ trans->cc.local.rtp = *rtp_cn_local;
+
+ sdp = trans->cc.local.audio_codecs.count ? &trans->cc.local : NULL;
+ rc = sdp_msg_to_sdp_str_buf(setup.sdp, sizeof(setup.sdp), sdp);
+ if (rc >= sizeof(setup.sdp)) {
+ LOG_TRANS(trans, LOGL_ERROR, "MNCC_SETUP_IND: SDP too long (%d > %zu bytes)\n", rc, sizeof(setup.sdp));
+ trans_free(trans);
+ return;
+ }
/* indicate setup to MNCC */
mncc_recvmsg(trans->net, trans, MNCC_SETUP_IND, &setup);
+}
- /* MNCC code will modify the channel asynchronously, we should
- * ipaccess-bind only after the modification has been made to the
- * lchan->tch_mode */
- return 0;
+static void rx_mncc_sdp(struct gsm_trans *trans, uint32_t mncc_msg_type, const char *sdp,
+ const struct gsm_mncc_bearer_cap *bcap)
+{
+ struct codec_filter *codecs = &trans->cc.codecs;
+ struct call_leg *cl = trans->msc_a ? trans->msc_a->cc.call_leg : NULL;
+ struct rtp_stream *rtp_cn = cl ? cl->rtp[RTP_TO_CN] : NULL;
+
+ if (sdp[0]) {
+ int rc = sdp_msg_from_sdp_str(&trans->cc.remote, sdp);
+ if (rc)
+ LOG_TRANS_CAT(trans, DMNCC, LOGL_ERROR, "rx %s: Failed to parse SDP: %d. Trying anyway.\n",
+ get_mncc_name(mncc_msg_type), rc);
+ }
+
+ /* if there is no SDP information or we failed to parse it, try using the Bearer Cap from MNCC, if any. */
+ if (!trans->cc.remote.audio_codecs.count && bcap) {
+ trans->cc.remote = (struct sdp_msg){};
+ trans_cc_set_remote_from_bc(trans, bcap);
+ LOG_TRANS_CAT(trans, DMNCC, LOGL_DEBUG, "rx %s Bearer Cap: remote=%s\n",
+ get_mncc_name(mncc_msg_type), sdp_msg_to_str(&trans->cc.remote));
+ }
+
+ if (!trans->cc.remote.audio_codecs.count)
+ LOG_TRANS(trans, LOGL_INFO,
+ "Got no information of remote audio codecs: neither SDP nor Bearer Capability. Trying anyway.\n");
+
+ trans_cc_filter_run(trans);
+ if (rtp_cn) {
+ rtp_stream_set_remote_addr_and_codecs(rtp_cn, &trans->cc.remote);
+ rtp_stream_commit(rtp_cn);
+ }
+
+ /* See if we need to switch codecs to maintain TFO: has the remote side changed the codecs information? If we
+ * have already assigned a specific codec here, but the remote call leg has now chosen a different codec, we
+ * need to re-assign this call leg to match the remote leg. */
+ if (!sdp_audio_codec_is_set(&codecs->assignment)) {
+ /* Voice channel assignment has not completed. Do not interfere. */
+ return;
+ }
+ if (!trans->cc.remote.audio_codecs.count) {
+ /* Don't know remote codecs, nothing to do. */
+ return;
+ }
+ if (sdp_audio_codecs_by_descr(&trans->cc.remote.audio_codecs, &codecs->assignment)) {
+ /* The assigned codec is part of the remote codec set. All is well. */
+ /* TODO: maybe this should require exactly the *first* remote codec to match, because we cannot flexibly
+ * transcode, and assume the actual payload we will receive is listed in the first place? */
+ return;
+ }
+
+ /* We've already completed Assignment of a voice channel (some time ago), and now the remote side has changed
+ * to a mismatching codec (list). Try to re-assign this side to a matching codec. */
+ LOG_TRANS(trans, LOGL_INFO, "Remote call leg mismatches assigned codec: %s\n",
+ codec_filter_to_str(&trans->cc.codecs, &trans->cc.local, &trans->cc.remote));
+ msc_a_tx_assignment_cmd(trans->msc_a);
}
static int gsm48_cc_tx_setup(struct gsm_trans *trans, void *arg)
{
- struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 CC STUP");
+ struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 CC SETUP");
struct gsm48_hdr *gh;
struct gsm_mncc *setup = arg;
int rc, trans_id;
+ struct gsm_mncc_bearer_cap bearer_cap;
gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
@@ -596,6 +845,7 @@ static int gsm48_cc_tx_setup(struct gsm_trans *trans, void *arg)
GSM48_CC_CAUSE_RESOURCE_UNAVAIL);
trans->callref = 0;
trans_free(trans);
+ msgb_free(msg);
return rc;
}
@@ -608,6 +858,7 @@ static int gsm48_cc_tx_setup(struct gsm_trans *trans, void *arg)
GSM48_CC_CAUSE_RESOURCE_UNAVAIL);
trans->callref = 0;
trans_free(trans);
+ msgb_free(msg);
return rc;
}
trans->transaction_id = trans_id;
@@ -616,13 +867,102 @@ static int gsm48_cc_tx_setup(struct gsm_trans *trans, void *arg)
gsm48_start_cc_timer(trans, 0x303, GSM48_T303);
- /* bearer capability */
- if (setup->fields & MNCC_F_BEARER_CAP) {
- /* Create a copy of the bearer capability in the transaction struct, so we
- * can use this information later */
- memcpy(&trans->bearer_cap, &setup->bearer_cap, sizeof(trans->bearer_cap));
- gsm48_encode_bearer_cap(msg, 0, &setup->bearer_cap);
+ /* MT call leg is starting. Gather all codecs information so far known.
+ * (Usually) paging has succeeded, and now we're processing the MNCC Setup from the remote MO call leg.
+ * Initialize the codecs filter with this side's BSS' codec list, received at Complete Layer 3.
+ * We haven't received the MT MS's Bearer Capabilities yet; the Bearer Capabilities handled here are
+ * actually the remote call leg's Bearer Capabilities. */
+ trans_cc_filter_init(trans);
+ trans_cc_filter_set_ran(trans, trans->msc_a->c.ran->type);
+ trans_cc_filter_set_bss(trans, trans->msc_a);
+ if (setup->fields & MNCC_F_BEARER_CAP)
+ trans->bearer_cap.transfer = setup->bearer_cap.transfer;
+
+ switch (trans->bearer_cap.transfer) {
+ case GSM48_BCAP_ITCAP_SPEECH:
+ /* if SDP is included in the MNCC, take that as definitive list of remote audio codecs. */
+ rx_mncc_sdp(trans, setup->msg_type, setup->sdp,
+ (setup->fields & MNCC_F_BEARER_CAP) ? &setup->bearer_cap : NULL);
+ /* rx_mncc_sdp() has called trans_cc_filter_run(trans); */
+ break;
+ case GSM48_BCAP_ITCAP_3k1_AUDIO:
+ case GSM48_BCAP_ITCAP_FAX_G3:
+ case GSM48_BCAP_ITCAP_UNR_DIG_INF:
+ if (setup->fields & MNCC_F_BEARER_CAP) {
+ trans->cc.remote = (struct sdp_msg){};
+ trans_cc_set_remote_from_bc(trans, &setup->bearer_cap);
+ LOG_TRANS_CAT(trans, DMNCC, LOGL_DEBUG, "rx %s Bearer Cap: remote=%s\n",
+ get_mncc_name(setup->msg_type), sdp_msg_to_str(&trans->cc.remote));
+ } else {
+ LOG_TRANS(trans, LOGL_INFO,
+ "Got no information of remote Bearer Capability. Trying anyway.\n");
+ sdp_audio_codecs_set_csd(&trans->cc.codecs.ms);
+ }
+ trans_cc_filter_run(trans);
+ break;
+ default:
+ LOG_TRANS(trans, LOGL_ERROR, "Handling of information transfer capability %d not implemented\n",
+ trans->bearer_cap.transfer);
+ break;
}
+
+ /* Compose Bearer Capability information that reflects only the codecs (Speech Versions) / CSD bearer services
+ * remaining after intersecting MS, BSS and remote call leg restrictions. To store in trans for later use, and
+ * to include in the outgoing CC Setup message. */
+ switch (trans->bearer_cap.transfer) {
+ case GSM48_BCAP_ITCAP_SPEECH:
+ bearer_cap = (struct gsm_mncc_bearer_cap){
+ .speech_ver = { -1 },
+ };
+ sdp_audio_codecs_to_bearer_cap(&bearer_cap, &trans->cc.local.audio_codecs);
+ rc = bearer_cap_set_radio(&bearer_cap);
+ if (rc) {
+ LOG_TRANS(trans, LOGL_ERROR, "Error composing Bearer Capability for CC Setup\n");
+ trans_free(trans);
+ msgb_free(msg);
+ return rc;
+ }
+ /* If no resulting codecs remain, error out. We cannot find a codec that matches both call legs. If the MGW were
+ * able to transcode, we could use non-identical codecs on each conn of the MGW endpoint, but we are aiming for
+ * finding a matching codec. */
+ if (bearer_cap.speech_ver[0] == -1) {
+ LOG_TRANS(trans, LOGL_ERROR, "%s: no codec match possible: %s\n",
+ get_mncc_name(setup->msg_type),
+ codec_filter_to_str(&trans->cc.codecs, &trans->cc.local, &trans->cc.remote));
+
+ /* incompatible codecs */
+ rc = mncc_release_ind(trans->net, trans, trans->callref,
+ GSM48_CAUSE_LOC_PRN_S_LU,
+ GSM48_CC_CAUSE_INCOMPAT_DEST /* TODO: correct cause code? */);
+ trans->callref = 0;
+ trans_free(trans);
+ msgb_free(msg);
+ return rc;
+ }
+ break;
+ case GSM48_BCAP_ITCAP_3k1_AUDIO:
+ case GSM48_BCAP_ITCAP_FAX_G3:
+ case GSM48_BCAP_ITCAP_UNR_DIG_INF:
+ if (csd_bs_list_to_bearer_cap(&bearer_cap, &trans->cc.local.bearer_services) == 0) {
+ LOG_TRANS(trans, LOGL_ERROR, "Error composing Bearer Capability for CC Setup\n");
+
+ /* incompatible codecs */
+ rc = mncc_release_ind(trans->net, trans, trans->callref,
+ GSM48_CAUSE_LOC_PRN_S_LU,
+ GSM48_CC_CAUSE_INCOMPAT_DEST /* TODO: correct cause code? */);
+ trans->callref = 0;
+ trans_free(trans);
+ msgb_free(msg);
+ return rc;
+ }
+ break;
+ }
+
+ /* Create a copy of the bearer capability in the transaction struct, so we can use this information later */
+ trans->bearer_cap = bearer_cap;
+
+ gsm48_encode_bearer_cap(msg, 0, &bearer_cap);
+
/* facility */
if (setup->fields & MNCC_F_FACILITY)
gsm48_encode_facility(msg, 0, &setup->facility);
@@ -635,6 +975,12 @@ static int gsm48_cc_tx_setup(struct gsm_trans *trans, void *arg)
/* called party BCD number */
if (setup->fields & MNCC_F_CALLED)
gsm48_encode_called(msg, &setup->called);
+ /* low layer compatibility */
+ if (setup->fields & MNCC_F_LOWL_COMPAT && setup->llc.len > 0 && setup->llc.len <= sizeof(setup->llc.compat))
+ msgb_tlv_put(msg, GSM48_IE_LOWL_COMPAT, setup->llc.len, setup->llc.compat);
+ /* high layer compatibility */
+ if (setup->fields & MNCC_F_HIGHL_COMPAT && setup->hlc.len > 0 && setup->hlc.len <= sizeof(setup->hlc.compat))
+ msgb_tlv_put(msg, GSM48_IE_HIGHL_COMPAT, setup->hlc.len, setup->hlc.compat);
/* user-user */
if (setup->fields & MNCC_F_USERUSER)
gsm48_encode_useruser(msg, 0, &setup->useruser);
@@ -647,7 +993,7 @@ static int gsm48_cc_tx_setup(struct gsm_trans *trans, void *arg)
new_cc_state(trans, GSM_CSTATE_CALL_PRESENT);
- rate_ctr_inc(&trans->net->msc_ctrs->ctr[MSC_CTR_CALL_MT_SETUP]);
+ rate_ctr_inc(rate_ctr_group_get_ctr(trans->net->msc_ctrs, MSC_CTR_CALL_MT_SETUP));
return trans_tx_gsm48(trans, msg);
}
@@ -683,9 +1029,14 @@ static int gsm48_cc_rx_call_conf(struct gsm_trans *trans, struct msgb *msg)
/* Create a copy of the bearer capability
* in the transaction struct, so we can use
* this information later */
- memcpy(&trans->bearer_cap,&call_conf.bearer_cap,
+ memcpy(&trans->bearer_cap, &call_conf.bearer_cap,
sizeof(trans->bearer_cap));
+
+ /* This is the MT call leg's Call Conf, containing the MS Bearer Capabilities of the MT MS.
+ * Store in codecs filter. */
+ trans_cc_filter_set_ms_from_bc(trans, &call_conf.bearer_cap);
}
+
/* cause */
if (TLVP_PRESENT(&tp, GSM48_IE_CAUSE)) {
call_conf.fields |= MNCC_F_CAUSE;
@@ -702,8 +1053,6 @@ static int gsm48_cc_rx_call_conf(struct gsm_trans *trans, struct msgb *msg)
/* IMSI of called subscriber */
OSMO_STRLCPY_ARRAY(call_conf.imsi, trans->vsub->imsi);
- new_cc_state(trans, GSM_CSTATE_MO_TERM_CALL_CONF);
-
/* Assign call (if not done yet) */
rc = msc_a_try_call_assignment(trans);
@@ -712,8 +1061,47 @@ static int gsm48_cc_rx_call_conf(struct gsm_trans *trans, struct msgb *msg)
if (rc)
return rc;
- return mncc_recvmsg(trans->net, trans, MNCC_CALL_CONF_IND,
- &call_conf);
+ /* Directly ack with MNCC_CALL_CONF_IND, not yet containing SDP or RTP IP:port information. */
+ new_cc_state(trans, GSM_CSTATE_MO_TERM_CALL_CONF);
+ return mncc_recvmsg(trans->net, trans, MNCC_CALL_CONF_IND, &call_conf);
+}
+
+static int mncc_recv_rtp(struct gsm_network *net, struct gsm_trans *trans, uint32_t callref,
+ int cmd, struct osmo_sockaddr_str *rtp_addr, uint32_t payload_type,
+ uint32_t payload_msg_type, const struct sdp_msg *sdp);
+
+static int gsm48_cc_mt_rtp_port_and_codec_known(struct gsm_trans *trans)
+{
+ struct msc_a *msc_a = trans->msc_a;
+ struct osmo_sockaddr_str *rtp_cn_local;
+ struct gsm_mncc_rtp;
+
+ if (!msc_a) {
+ LOG_TRANS(trans, LOGL_ERROR, "No connection for CC trans\n");
+ trans->callref = 0;
+ trans_free(trans);
+ return -EINVAL;
+ }
+
+ /* Insert the CN side RTP port now available into SDP */
+ rtp_cn_local = call_leg_local_ip(msc_a->cc.call_leg, RTP_TO_CN);
+ if (!rtp_cn_local) {
+ LOG_TRANS(trans, LOGL_ERROR, "Cannot compose SDP for MNCC_RTP_CREATE: no RTP set up for the CN side\n");
+ trans_free(trans);
+ return -EINVAL;
+ }
+ trans->cc.local.rtp = *rtp_cn_local;
+
+ trans_cc_filter_run(trans);
+
+ /* If we haven't completed Assignment yet, don't sent MNCC_RTP_CREATE */
+ if (!sdp_audio_codec_is_set(&trans->cc.codecs.assignment)) {
+ LOG_TRANS(trans, LOGL_DEBUG, "no codec confirmed by Assignment yet\n");
+ return 0;
+ }
+
+ return mncc_recv_rtp(msc_a_net(msc_a), trans, trans->callref, MNCC_RTP_CREATE, rtp_cn_local, 0, 0,
+ &trans->cc.local);
}
static int gsm48_cc_tx_call_proc_and_assign(struct gsm_trans *trans, void *arg)
@@ -729,6 +1117,14 @@ static int gsm48_cc_tx_call_proc_and_assign(struct gsm_trans *trans, void *arg)
/* bearer capability */
if (proceeding->fields & MNCC_F_BEARER_CAP) {
+ /* MNCC should not switch from e.g. CSD to speech */
+ if (proceeding->bearer_cap.transfer != trans->bearer_cap.transfer) {
+ LOG_TRANS(trans, LOGL_ERROR, "Unexpected Information Transfer Capability %d from MNCC,"
+ " transaction has %d\n",
+ proceeding->bearer_cap.transfer,
+ trans->bearer_cap.transfer);
+ return -EINVAL;
+ }
gsm48_encode_bearer_cap(msg, 0, &proceeding->bearer_cap);
memcpy(&trans->bearer_cap, &proceeding->bearer_cap, sizeof(trans->bearer_cap));
}
@@ -753,6 +1149,7 @@ static int gsm48_cc_rx_alerting(struct gsm_trans *trans, struct msgb *msg)
unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
struct tlv_parsed tp;
struct gsm_mncc alerting;
+ int rc;
gsm48_stop_cc_timer(trans);
gsm48_start_cc_timer(trans, 0x301, GSM48_T301);
@@ -782,6 +1179,15 @@ static int gsm48_cc_rx_alerting(struct gsm_trans *trans, struct msgb *msg)
new_cc_state(trans, GSM_CSTATE_CALL_RECEIVED);
+ trans_cc_filter_run(trans);
+ rc = sdp_msg_to_sdp_str_buf(alerting.sdp, sizeof(alerting.sdp), &trans->cc.local);
+ if (rc >= sizeof(alerting.sdp)) {
+ LOG_TRANS(trans, LOGL_ERROR, "MNCC_ALERT_IND: SDP too long (%d > %zu bytes)\n",
+ rc, sizeof(alerting.sdp));
+ trans_free(trans);
+ return -EINVAL;
+ }
+
return mncc_recvmsg(trans->net, trans, MNCC_ALERT_IND,
&alerting);
}
@@ -791,6 +1197,7 @@ static int gsm48_cc_tx_alerting(struct gsm_trans *trans, void *arg)
struct gsm_mncc *alerting = arg;
struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 CC ALERT");
struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
+ int rc;
gh->msg_type = GSM48_MT_CC_ALERTING;
@@ -806,7 +1213,13 @@ static int gsm48_cc_tx_alerting(struct gsm_trans *trans, void *arg)
new_cc_state(trans, GSM_CSTATE_CALL_DELIVERED);
- return trans_tx_gsm48(trans, msg);
+ if (alerting->sdp[0])
+ rx_mncc_sdp(trans, alerting->msg_type, alerting->sdp,
+ (alerting->fields & MNCC_F_BEARER_CAP) ? &alerting->bearer_cap : NULL);
+
+ /* handle the MNCC event */
+ rc = trans_tx_gsm48(trans, msg);
+ return rc;
}
static int gsm48_cc_tx_progress(struct gsm_trans *trans, void *arg)
@@ -852,6 +1265,10 @@ static int gsm48_cc_tx_connect(struct gsm_trans *trans, void *arg)
new_cc_state(trans, GSM_CSTATE_CONNECT_IND);
+ if (connect->sdp[0])
+ rx_mncc_sdp(trans, connect->msg_type, connect->sdp,
+ (connect->fields & MNCC_F_BEARER_CAP) ? &connect->bearer_cap : NULL);
+
return trans_tx_gsm48(trans, msg);
}
@@ -892,8 +1309,10 @@ static int gsm48_cc_rx_connect(struct gsm_trans *trans, struct msgb *msg)
}
new_cc_state(trans, GSM_CSTATE_CONNECT_REQUEST);
- rate_ctr_inc(&trans->net->msc_ctrs->ctr[MSC_CTR_CALL_MT_CONNECT]);
+ rate_ctr_inc(rate_ctr_group_get_ctr(trans->net->msc_ctrs, MSC_CTR_CALL_MT_CONNECT));
+ trans_cc_filter_run(trans);
+ sdp_msg_to_sdp_str_buf(connect.sdp, sizeof(connect.sdp), &trans->cc.local);
return mncc_recvmsg(trans->net, trans, MNCC_SETUP_CNF, &connect);
}
@@ -905,7 +1324,7 @@ static int gsm48_cc_rx_connect_ack(struct gsm_trans *trans, struct msgb *msg)
gsm48_stop_cc_timer(trans);
new_cc_state(trans, GSM_CSTATE_ACTIVE);
- rate_ctr_inc(&trans->net->msc_ctrs->ctr[MSC_CTR_CALL_MO_CONNECT_ACK]);
+ rate_ctr_inc(rate_ctr_group_get_ctr(trans->net->msc_ctrs, MSC_CTR_CALL_MO_CONNECT_ACK));
memset(&connect_ack, 0, sizeof(struct gsm_mncc));
connect_ack.callref = trans->callref;
@@ -1072,8 +1491,16 @@ static int gsm48_cc_rx_release(struct gsm_trans *trans, struct msgb *msg)
static int gsm48_cc_tx_release(struct gsm_trans *trans, void *arg)
{
struct gsm_mncc *rel = arg;
- struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 CC REL");
- struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
+ struct msgb *msg;
+ struct gsm48_hdr *gh;
+
+ if (!trans->msc_a) {
+ LOG_TRANS(trans, LOGL_DEBUG, "Cannot send CC REL, there is no MSC-A connection\n");
+ return -EINVAL;
+ }
+
+ msg = gsm48_msgb_alloc_name("GSM 04.08 CC REL");
+ gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
gh->msg_type = GSM48_MT_CC_RELEASE;
@@ -1596,7 +2023,7 @@ static int gsm48_cc_rx_userinfo(struct gsm_trans *trans, struct msgb *msg)
static int mncc_recv_rtp(struct gsm_network *net, struct gsm_trans *trans, uint32_t callref,
int cmd, struct osmo_sockaddr_str *rtp_addr, uint32_t payload_type,
- uint32_t payload_msg_type)
+ uint32_t payload_msg_type, const struct sdp_msg *sdp)
{
uint8_t data[sizeof(struct gsm_mncc)];
struct gsm_mncc_rtp *rtp;
@@ -1607,56 +2034,106 @@ static int mncc_recv_rtp(struct gsm_network *net, struct gsm_trans *trans, uint3
rtp->callref = callref;
rtp->msg_type = cmd;
if (rtp_addr) {
- rtp->ip = osmo_htonl(inet_addr(rtp_addr->ip));
- rtp->port = rtp_addr->port;
+ if (osmo_sockaddr_str_to_sockaddr(rtp_addr, &rtp->addr) < 0)
+ return -EINVAL;
}
rtp->payload_type = payload_type;
rtp->payload_msg_type = payload_msg_type;
+ if (sdp)
+ sdp_msg_to_sdp_str_buf(rtp->sdp, sizeof(rtp->sdp), sdp);
return mncc_recvmsg(net, trans, cmd, (struct gsm_mncc *)data);
}
static void mncc_recv_rtp_err(struct gsm_network *net, struct gsm_trans *trans, uint32_t callref, int cmd)
{
- mncc_recv_rtp(net, trans, callref, cmd, NULL, 0, 0);
+ mncc_recv_rtp(net, trans, callref, cmd, NULL, 0, 0, NULL);
}
-static int tch_rtp_create(struct gsm_network *net, uint32_t callref)
+static int tch_rtp_create(struct gsm_network *net, const struct gsm_mncc_rtp *rtp)
{
struct gsm_trans *trans;
/* Find callref */
- trans = trans_find_by_callref(net, callref);
+ trans = trans_find_by_callref(net, TRANS_CC, rtp->callref);
if (!trans) {
LOG_TRANS_CAT(trans, DMNCC, LOGL_ERROR, "RTP create for non-existing trans\n");
- mncc_recv_rtp_err(net, trans, callref, MNCC_RTP_CREATE);
+ mncc_recv_rtp_err(net, trans, rtp->callref, MNCC_RTP_CREATE);
return -EIO;
}
log_set_context(LOG_CTX_VLR_SUBSCR, trans->vsub);
if (!trans->msc_a) {
LOG_TRANS_CAT(trans, DMNCC, LOGL_NOTICE, "RTP create for trans without conn\n");
- mncc_recv_rtp_err(net, trans, callref, MNCC_RTP_CREATE);
+ mncc_recv_rtp_err(net, trans, rtp->callref, MNCC_RTP_CREATE);
return 0;
}
- LOG_TRANS_CAT(trans, DMNCC, LOGL_DEBUG, "rx %s\n", get_mncc_name(MNCC_RTP_CREATE));
-
- /* When we call msc_mgcp_call_assignment() we will trigger, depending
- * on the RAN type the call assignment on the A or Iu interface.
- * msc_mgcp_call_assignment() also takes care about sending the CRCX
- * command to the MGCP-GW. The CRCX will return the port number,
- * where the PBX (e.g. Asterisk) will send its RTP stream to. We
- * have to return this port number back to the MNCC by sending
- * it back with the TCH_RTP_CREATE message. To make sure that
- * this message is sent AFTER the response to CRCX from the
- * MGCP-GW has arrived, we need will instruct msc_mgcp_call_assignment()
- * to take care of this by setting trans->tch_rtp_create to true.
- * This will make sure that gsm48_tch_rtp_create() (below) is
- * called as soon as the local port number has become known. */
- trans->tch_rtp_create = true;
+ log_mncc_rx_tx(trans, "rx", (const union mncc_msg *)rtp);
/* Assign call (if not done yet) */
return msc_a_try_call_assignment(trans);
}
+int cc_on_cn_local_rtp_port_known(struct gsm_trans *cc_trans)
+{
+ /* Depending on MO or MT call, dispatch the event differently */
+ switch (cc_trans->cc.state) {
+ case GSM_CSTATE_INITIATED:
+ if (cc_trans->cc.msg.msg_type != MNCC_SETUP_IND) {
+ LOG_TRANS(cc_trans, LOGL_ERROR, "Assuming MO call, expected MNCC_SETUP_IND to be prepared\n");
+ return -EINVAL;
+ }
+ /* This is the MO call leg, waiting for a CN RTP be able to send initial MNCC_SETUP_IND. */
+ gsm48_cc_rx_setup_cn_local_rtp_port_known(cc_trans);
+ return 0;
+
+ case GSM_CSTATE_MO_TERM_CALL_CONF:
+ /* This is the MT call leg, waiting for a CN RTP to be able to send MNCC_CALL_CONF_IND. */
+ return gsm48_cc_mt_rtp_port_and_codec_known(cc_trans);
+
+ default:
+ LOG_TRANS(cc_trans, LOGL_ERROR, "CN RTP address available, but in unexpected state %d\n",
+ cc_trans->cc.state);
+ return -EINVAL;
+ }
+}
+
+int cc_on_assignment_done(struct gsm_trans *trans)
+{
+ struct msc_a *msc_a = trans->msc_a;
+
+ switch (trans->cc.state) {
+ case GSM_CSTATE_INITIATED:
+ case GSM_CSTATE_MO_CALL_PROC:
+ /* MO call, send ACK in form of an MNCC_RTP_CREATE (below) */
+ break;
+
+ case GSM_CSTATE_CALL_RECEIVED:
+ case GSM_CSTATE_MO_TERM_CALL_CONF:
+ /* MT call, send ACK in form of an MNCC_RTP_CREATE (below) */
+ break;
+
+ case GSM_CSTATE_ACTIVE:
+ /* already active. We decided to re-assign later on during the call - at time of writing this never
+ * happens. */
+ case GSM_CSTATE_CALL_DELIVERED:
+ case GSM_CSTATE_CONNECT_IND:
+ /* MNCC has progressed past the initial assignment. Usually it means that this happened: after
+ * MNCC_ALERT_REQ, MO has triggered a re-assignment, to adjust MO's codec to MT's codec. */
+ LOG_TRANS(trans, LOGL_DEBUG, "Re-Assignment complete\n");
+ return 0;
+
+ default:
+ LOG_TRANS(trans, LOGL_ERROR, "Assignment done in unexpected CC state: %d\n", trans->cc.state);
+ return -EINVAL;
+ }
+
+ if (!call_leg_local_ip(msc_a->cc.call_leg, RTP_TO_CN)) {
+ LOG_TRANS(trans, LOGL_DEBUG,
+ "Assignment complete, but still waiting for the CRCX OK on the CN side RTP\n");
+ return 0;
+ }
+ return gsm48_tch_rtp_create(trans);
+}
+
/* Trigger TCH_RTP_CREATE acknowledgement */
int gsm48_tch_rtp_create(struct gsm_trans *trans)
{
@@ -1667,26 +2144,38 @@ int gsm48_tch_rtp_create(struct gsm_trans *trans)
struct gsm_network *net = msc_a_net(msc_a);
struct call_leg *cl = msc_a->cc.call_leg;
struct osmo_sockaddr_str *rtp_cn_local;
- /* FIXME: This has to be set to some meaningful value,
- * before the MSC-Split, this value was pulled from
- * lchan->abis_ip.rtp_payload */
- uint32_t payload_type = 0;
- int msg_type;
-
- /* FIXME This has to be set to some meaningful value.
- * Possible options are:
- * GSM_TCHF_FRAME, GSM_TCHF_FRAME_EFR,
- * GSM_TCHH_FRAME, GSM_TCH_FRAME_AMR
- * (0 if unknown) */
- msg_type = GSM_TCHF_FRAME;
+ struct rtp_stream *rtp_cn = cl ? cl->rtp[RTP_TO_CN] : NULL;
+ int mncc_payload_msg_type;
+ struct sdp_audio_codec *codec;
+ const struct codec_mapping *m;
+ struct sdp_audio_codecs *codecs;
+
+ if (!rtp_cn) {
+ LOG_TRANS_CAT(trans, DMNCC, LOGL_ERROR, "Cannot RTP CREATE to MNCC, no RTP set up for the CN side\n");
+ return -EINVAL;
+ }
+
+ trans_cc_filter_run(trans);
+ codecs = &trans->cc.local.audio_codecs;
+ if (!codecs->count) {
+ LOG_TRANS_CAT(trans, DMNCC, LOGL_ERROR,
+ "Cannot RTP CREATE to MNCC, there is no codec available\n");
+ return -EINVAL;
+ }
+
+ /* Populate the legacy MNCC codec elements: payload_type and payload_msg_type */
+ codec = &codecs->codec[0];
+ m = codec_mapping_by_subtype_name(codec->subtype_name);
+ mncc_payload_msg_type = m ? m->mncc_payload_msg_type : 0;
rtp_cn_local = call_leg_local_ip(cl, RTP_TO_CN);
if (!rtp_cn_local) {
- LOG_TRANS_CAT(trans, DMNCC, LOGL_ERROR, "Cannot RTP CREATE to MNCC, no local RTP IP:port set up\n");
+ LOG_TRANS_CAT(trans, DMNCC, LOGL_ERROR, "Cannot RTP CREATE to MNCC, no local RTP IP:port to CN set up\n");
return -EINVAL;
}
- return mncc_recv_rtp(net, trans, trans->callref, MNCC_RTP_CREATE, rtp_cn_local, payload_type, msg_type);
+ return mncc_recv_rtp(net, trans, trans->callref, MNCC_RTP_CREATE, rtp_cn_local,
+ codec->payload_type, mncc_payload_msg_type, &trans->cc.local);
}
static int tch_rtp_connect(struct gsm_network *net, const struct gsm_mncc_rtp *rtp)
@@ -1694,20 +2183,9 @@ static int tch_rtp_connect(struct gsm_network *net, const struct gsm_mncc_rtp *r
struct gsm_trans *trans;
struct call_leg *cl;
struct rtp_stream *rtps;
- struct osmo_sockaddr_str rtp_addr;
-
- /* FIXME: in *rtp we should get the codec information of the remote
- * leg. We will have to populate trans->conn->rtp.codec_cn with a
- * meaningful value based on this information but unfortunately we
- * can't do that yet because the mncc API can not signal dynamic
- * payload types yet. This must be fixed first. Also there may be
- * additional members necessary in trans->conn->rtp because we
- * somehow need to deal with dynamic payload types that do not
- * comply to 3gpp's assumptions of payload type numbers on the A
- * interface. See also related tickets: OS#3399 and OS1683 */
/* Find callref */
- trans = trans_find_by_callref(net, rtp->callref);
+ trans = trans_find_by_callref(net, TRANS_CC, rtp->callref);
if (!trans) {
LOG_TRANS_CAT(trans, DMNCC, LOGL_ERROR, "RTP connect for non-existing trans\n");
mncc_recv_rtp_err(net, trans, rtp->callref, MNCC_RTP_CONNECT);
@@ -1720,22 +2198,23 @@ static int tch_rtp_connect(struct gsm_network *net, const struct gsm_mncc_rtp *r
return -EIO;
}
- LOG_TRANS_CAT(trans, DMNCC, LOGL_DEBUG, "rx %s\n", get_mncc_name(MNCC_RTP_CONNECT));
+ log_mncc_rx_tx(trans, "rx", (const union mncc_msg *)rtp);
+
+ rx_mncc_sdp(trans, rtp->msg_type, rtp->sdp, NULL);
cl = trans->msc_a->cc.call_leg;
rtps = cl ? cl->rtp[RTP_TO_CN] : NULL;
-
- if (!rtps) {
- LOG_TRANS_CAT(trans, DMNCC, LOGL_ERROR, "RTP connect for trans without ongoing call\n");
- mncc_recv_rtp_err(net, trans, rtp->callref, MNCC_RTP_CONNECT);
- return -EINVAL;
+ if (rtps && !osmo_sockaddr_str_is_nonzero(&rtps->remote)) {
+ /* Didn't get an IP address from SDP. Try legacy MNCC IP address */
+ struct osmo_sockaddr_str rtp_addr;
+ if (osmo_sockaddr_str_from_sockaddr(&rtp_addr, &rtp->addr) < 0) {
+ LOG_TRANS_CAT(trans, DMNCC, LOGL_ERROR, "RTP connect with invalid IP addr\n");
+ mncc_recv_rtp_err(net, trans, rtp->callref, MNCC_RTP_CONNECT);
+ return -EINVAL;
+ }
+ rtp_stream_set_remote_addr(rtps, &rtp_addr);
+ rtp_stream_commit(rtps);
}
-
- LOG_TRANS_CAT(trans, DMNCC, LOGL_DEBUG, "rx %s\n", get_mncc_name(MNCC_RTP_CONNECT));
-
- osmo_sockaddr_str_from_32n(&rtp_addr, rtp->ip, rtp->port);
- rtp_stream_set_remote_addr(rtps, &rtp_addr);
- rtp_stream_commit(rtps);
return 0;
}
@@ -1798,7 +2277,7 @@ static struct downstate {
(sizeof(downstatelist) / sizeof(struct downstate))
-int mncc_tx_to_gsm_cc(struct gsm_network *net, const union mncc_msg *msg)
+static int mncc_tx_to_gsm_cc(struct gsm_network *net, const union mncc_msg *msg)
{
int i, rc = 0;
struct msc_a *msc_a = NULL;
@@ -1813,7 +2292,7 @@ int mncc_tx_to_gsm_cc(struct gsm_network *net, const union mncc_msg *msg)
disconnect_bridge(net, &msg->bridge, -rc);
return rc;
case MNCC_RTP_CREATE:
- return tch_rtp_create(net, msg->rtp.callref);
+ return tch_rtp_create(net, &msg->rtp);
case MNCC_RTP_CONNECT:
return tch_rtp_connect(net, &msg->rtp);
case MNCC_RTP_FREE:
@@ -1834,7 +2313,7 @@ int mncc_tx_to_gsm_cc(struct gsm_network *net, const union mncc_msg *msg)
data = &msg->signal;
/* Find callref */
- trans = trans_find_by_callref(net, data->callref);
+ trans = trans_find_by_callref(net, TRANS_CC, data->callref);
/* Callref unknown */
if (!trans) {
@@ -1870,7 +2349,7 @@ int mncc_tx_to_gsm_cc(struct gsm_network *net, const union mncc_msg *msg)
}
if (!vsub)
return mncc_release_ind(net, NULL, data->callref, GSM48_CAUSE_LOC_PRN_S_LU,
- GSM48_CC_CAUSE_UNASSIGNED_NR);
+ GSM48_CC_CAUSE_USER_NOTRESPOND);
/* update the subscriber we deal with */
log_set_context(LOG_CTX_VLR_SUBSCR, vsub);
@@ -1884,38 +2363,53 @@ int mncc_tx_to_gsm_cc(struct gsm_network *net, const union mncc_msg *msg)
GSM48_CAUSE_LOC_PRN_S_LU,
GSM48_CC_CAUSE_DEST_OOO);
}
+
+ /* Find valid conn */
+ msc_a = msc_a_for_vsub(vsub, true);
+
+ /* If subscriber is BUSY and we do not DO call in call aka "call-waiting" */
+ if (!net->call_waiting && msc_a) {
+ struct gsm_trans *existing_cc_trans = trans_find_by_type(msc_a, TRANS_CC);
+ if (existing_cc_trans && existing_cc_trans->cc.state != GSM_CSTATE_NULL) {
+ LOG_TRANS_CAT(existing_cc_trans, DCC, LOGL_NOTICE,
+ "rx '%s' for subscriber %s with trans state (%s)"
+ " rejecting with USER_BUSY\n",
+ get_mncc_name(msg->msg_type), data->called.number,
+ gsm48_cc_state_name(existing_cc_trans->cc.state));
+ return mncc_release_ind(net, NULL, data->callref,
+ GSM48_CAUSE_LOC_PRN_S_LU,
+ GSM48_CC_CAUSE_USER_BUSY);
+ }
+ }
+
/* Create transaction */
trans = trans_alloc(net, vsub, TRANS_CC,
TRANS_ID_UNASSIGNED, data->callref);
if (!trans) {
LOG_TRANS(trans, LOGL_ERROR, "No memory for trans.\n");
vlr_subscr_put(vsub, __func__);
- /* Ressource unavailable */
+ /* Resource unavailable */
mncc_release_ind(net, NULL, data->callref,
GSM48_CAUSE_LOC_PRN_S_LU,
GSM48_CC_CAUSE_RESOURCE_UNAVAIL);
return -ENOMEM;
}
- /* Find valid conn */
- msc_a = msc_a_for_vsub(vsub, true);
+ /* Remember remote SDP, if any */
+ rx_mncc_sdp(trans, data->msg_type, data->sdp,
+ (data->fields & MNCC_F_BEARER_CAP) ? &data->bearer_cap : NULL);
/* If subscriber has no conn */
if (!msc_a) {
-
- if (vsub->cs.is_paging) {
- LOG_TRANS(trans, LOGL_DEBUG,
- "rx %s, subscriber not yet connected, paging already started\n",
- get_mncc_name(msg->msg_type));
- vlr_subscr_put(vsub, __func__);
- trans_free(trans);
- return 0;
- }
+ /* This condition will return before the common logging of the received MNCC message below, so
+ * log it now. */
+ log_mncc_rx_tx(trans, "rx", msg);
/* store setup information until paging succeeds */
memcpy(&trans->cc.msg, data, sizeof(struct gsm_mncc));
- /* Request a channel */
+ /* Request a channel. If Paging already started, paging_request_start() will append the new
+ * trans to the already ongoing Paging. */
trans->paging_request = paging_request_start(vsub, PAGING_CAUSE_CALL_CONVERSATIONAL,
cc_paging_cb, trans, "MNCC: establish call");
if (!trans->paging_request) {
@@ -1936,9 +2430,30 @@ int mncc_tx_to_gsm_cc(struct gsm_network *net, const union mncc_msg *msg)
log_set_context(LOG_CTX_VLR_SUBSCR, trans->vsub);
}
- LOG_TRANS_CAT(trans, DMNCC, LOGL_DEBUG, "rx %s\n", get_mncc_name(msg->msg_type));
+ log_mncc_rx_tx(trans, "rx", msg);
- gsm48_start_guard_timer(trans);
+ /*
+ * The step of gsm48_start_guard_timer() needs to be done for
+ * major state-impacting MNCC messages, but not for those
+ * that are a mere pass-through to CC messages to MS.
+ */
+ switch (msg->msg_type) {
+ case MNCC_PROGRESS_REQ:
+ case MNCC_NOTIFY_REQ:
+ case MNCC_FACILITY_REQ:
+ case MNCC_START_DTMF_RSP:
+ case MNCC_START_DTMF_REJ:
+ case MNCC_STOP_DTMF_RSP:
+ case MNCC_HOLD_CNF:
+ case MNCC_HOLD_REJ:
+ case MNCC_RETRIEVE_CNF:
+ case MNCC_RETRIEVE_REJ:
+ case MNCC_USERINFO_REQ:
+ break;
+ default:
+ gsm48_start_guard_timer(trans);
+ }
+ trans->cc.mncc_initiated = true;
if (trans->msc_a)
msc_a = trans->msc_a;
@@ -1948,7 +2463,7 @@ int mncc_tx_to_gsm_cc(struct gsm_network *net, const union mncc_msg *msg)
struct gsm_mncc rel = {
.callref = data->callref,
};
- LOG_TRANS(trans, LOGL_DEBUG, "rx %s in paging state\n", get_mncc_name(msg->msg_type));
+ LOG_TRANS(trans, LOGL_DEBUG, "still paging\n");
mncc_set_cause(&rel, GSM48_CAUSE_LOC_PRN_S_LU,
GSM48_CC_CAUSE_NORM_CALL_CLEAR);
if (msg->msg_type == MNCC_REL_REQ)
@@ -1958,9 +2473,6 @@ int mncc_tx_to_gsm_cc(struct gsm_network *net, const union mncc_msg *msg)
trans->callref = 0;
trans_free(trans);
return rc;
- } else {
- LOG_TRANS(trans, LOGL_DEBUG, "rx %s in state %s\n",
- get_mncc_name(msg->msg_type), gsm48_cc_state_name(trans->cc.state));
}
/* Find function for current state and message */
diff --git a/src/libmsc/gsm_04_11.c b/src/libmsc/gsm_04_11.c
index a3b383068..aa87a192a 100644
--- a/src/libmsc/gsm_04_11.c
+++ b/src/libmsc/gsm_04_11.c
@@ -58,7 +58,7 @@
#include <osmocom/msc/paging.h>
#ifdef BUILD_SMPP
-#include "smpp_smsc.h"
+#include <osmocom/smpp/smpp_smsc.h>
#endif
void *tall_gsms_ctx;
@@ -129,6 +129,28 @@ static int gsm411_sendmsg(struct gsm_trans *trans, struct msgb *msg)
return msc_a_tx_dtap_to_i(trans->msc_a, msg);
}
+/* Handle MMTS (More Messages to Send) indication */
+static void gsm411_handle_mmts_ind(const struct gsm_trans *trans)
+{
+ int32_t use_count;
+
+ OSMO_ASSERT(trans);
+ OSMO_ASSERT(trans->msc_a);
+
+ use_count = osmo_use_count_by(&trans->msc_a->use_count, MSC_A_USE_SMS_MMTS);
+ OSMO_ASSERT(use_count >= 0); /* Shall not be negative */
+
+ if (trans->sms.sm_rp_mmts_ind && use_count == 0) {
+ LOG_TRANS(trans, LOGL_INFO, "Multi-part SMS delivery is initiated\n");
+ msc_a_get(trans->msc_a, MSC_A_USE_SMS_MMTS);
+ } else if (trans->sms.sm_rp_mmts_ind && use_count > 0) {
+ LOG_TRANS(trans, LOGL_INFO, "Continuing multi-part SMS delivery\n");
+ } else if (!trans->sms.sm_rp_mmts_ind && use_count > 0) {
+ LOG_TRANS(trans, LOGL_INFO, "Multi-part SMS delivery has been completed\n");
+ msc_a_put(trans->msc_a, MSC_A_USE_SMS_MMTS);
+ }
+}
+
/* Paging callback for MT SMS (Paging is triggered by SMC) */
static void mmsms_paging_cb(struct msc_a *msc_a, struct gsm_trans *trans)
{
@@ -141,6 +163,10 @@ static void mmsms_paging_cb(struct msc_a *msc_a, struct gsm_trans *trans)
/* Associate transaction with established connection */
msc_a_get(msc_a, MSC_A_USE_SMS);
trans->msc_a = msc_a;
+
+ /* Multi-part SMS: handle MMTS (More Messages to Send) indication */
+ gsm411_handle_mmts_ind(trans);
+
/* Confirm successful connection establishment */
gsm411_smc_recv(&trans->sms.smc_inst, GSM411_MMSMS_EST_CNF, NULL, 0);
} else {
@@ -406,7 +432,7 @@ static int sms_route_mt_sms(struct gsm_trans *trans, struct gsm_sms *gsms)
LOG_TRANS(trans, LOGL_ERROR, "SMS delivery error: %d\n", rc);
rc = GSM411_RP_CAUSE_MO_TEMP_FAIL;
/* rc will be logged by gsm411_send_rp_error() */
- rate_ctr_inc(&net->msc_ctrs->ctr[MSC_CTR_SMS_DELIVER_UNKNOWN_ERROR]);
+ rate_ctr_inc(rate_ctr_group_get_ctr(net->msc_ctrs, MSC_CTR_SMS_DELIVER_UNKNOWN_ERROR));
}
return rc;
}
@@ -416,29 +442,29 @@ try_local:
/* determine gsms->receiver based on dialled number */
gsms->receiver = vlr_subscr_find_by_msisdn(net->vlr, gsms->dst.addr, VSUB_USE_SMS_RECEIVER);
- if (!gsms->receiver) {
+ if (gsms->receiver)
+ return 0;
+
#ifdef BUILD_SMPP
- /* Avoid a second look-up */
- if (smpp_route_smpp_first()) {
- rate_ctr_inc(&net->msc_ctrs->ctr[MSC_CTR_SMS_NO_RECEIVER]);
- return GSM411_RP_CAUSE_MO_NUM_UNASSIGNED;
- }
+ /* Avoid a second look-up */
+ if (smpp_route_smpp_first()) {
+ rate_ctr_inc(rate_ctr_group_get_ctr(net->msc_ctrs, MSC_CTR_SMS_NO_RECEIVER));
+ return GSM411_RP_CAUSE_MO_NUM_UNASSIGNED;
+ }
- rc = smpp_try_deliver(gsms, msc_a);
- if (rc == GSM411_RP_CAUSE_MO_NUM_UNASSIGNED) {
- rate_ctr_inc(&net->msc_ctrs->ctr[MSC_CTR_SMS_NO_RECEIVER]);
- } else if (rc < 0) {
- LOG_TRANS(trans, LOGL_ERROR, "SMS delivery error: %d\n", rc);
- rc = GSM411_RP_CAUSE_MO_TEMP_FAIL;
- /* rc will be logged by gsm411_send_rp_error() */
- rate_ctr_inc(&net->msc_ctrs->ctr[MSC_CTR_SMS_DELIVER_UNKNOWN_ERROR]);
- }
+ rc = smpp_try_deliver(gsms, msc_a);
+ if (rc == GSM411_RP_CAUSE_MO_NUM_UNASSIGNED) {
+ rate_ctr_inc(rate_ctr_group_get_ctr(net->msc_ctrs, MSC_CTR_SMS_NO_RECEIVER));
+ } else if (rc < 0) {
+ LOG_TRANS(trans, LOGL_ERROR, "SMS delivery error: %d\n", rc);
+ rc = GSM411_RP_CAUSE_MO_TEMP_FAIL;
+ /* rc will be logged by gsm411_send_rp_error() */
+ rate_ctr_inc(rate_ctr_group_get_ctr(net->msc_ctrs, MSC_CTR_SMS_DELIVER_UNKNOWN_ERROR));
+ }
#else
- rc = GSM411_RP_CAUSE_MO_NUM_UNASSIGNED;
- rate_ctr_inc(&net->msc_ctrs->ctr[MSC_CTR_SMS_NO_RECEIVER]);
+ rc = GSM411_RP_CAUSE_MO_NUM_UNASSIGNED;
+ rate_ctr_inc(rate_ctr_group_get_ctr(net->msc_ctrs, MSC_CTR_SMS_NO_RECEIVER));
#endif
- } else
- rc = 0;
return rc;
}
@@ -475,7 +501,7 @@ static int gsm340_rx_tpdu(struct gsm_trans *trans, struct msgb *msg,
}
/* FIXME: should we do this on success, after all checks? */
- rate_ctr_inc(&net->msc_ctrs->ctr[MSC_CTR_SMS_SUBMITTED]);
+ rate_ctr_inc(rate_ctr_group_get_ctr(net->msc_ctrs, MSC_CTR_SMS_SUBMITTED));
gsms = sms_alloc();
if (!gsms)
@@ -600,9 +626,30 @@ static int gsm340_rx_tpdu(struct gsm_trans *trans, struct msgb *msg,
osmo_hexdump(gsms->user_data, gsms->user_data_len));
gsms->validity_minutes = gsm340_validity_period(sms_vpf, sms_vp);
+ if (gsms->validity_minutes < net->sms_queue_cfg->minimum_validity_mins) {
+ LOG_TRANS(trans, LOGL_INFO, "Overriding user-provided validity period (%lu) "
+ "with minimum SMSC validity period (%u) minutes\n", gsms->validity_minutes,
+ net->sms_queue_cfg->minimum_validity_mins);
+ gsms->validity_minutes = net->sms_queue_cfg->minimum_validity_mins;
+ }
rc = sms_route_mt_sms(trans, gsms);
+ /* This SMS got routed through SMPP and we are waiting on the response. */
+ if (gsms->smpp.esme) {
+ rc = -EINPROGRESS;
+ goto out;
+ }
+
+ /* This SMS got routed through SMPP, but the configured ESME was
+ * unavailable at this time. This is an OOO condition.
+ * Don't store this SMS in the database as we may never be
+ * able to deliver it. (we would need to process the stored SMS and
+ * attempt re-submission to the ESME)
+ */
+ if (rc == GSM411_RP_CAUSE_MO_NET_OUT_OF_ORDER)
+ goto out; /* free() the message */
+
/*
* This SMS got routed through SMPP or no receiver exists.
* In any case, we store it in the database for further processing.
@@ -691,8 +738,10 @@ static int gsm411_rx_rp_ud(struct msgb *msg, struct gsm_trans *trans,
return gsm411_send_rp_ack(trans, rph->msg_ref);
else if (rc > 0)
return gsm411_send_rp_error(trans, rph->msg_ref, rc);
- else
- return rc;
+ else if (rc == -EINPROGRESS)
+ rc = 0;
+
+ return rc;
}
/* Receive a 04.11 RP-DATA message in accordance with Section 7.3.1.2 */
@@ -861,10 +910,10 @@ static int gsm411_rx_rp_error(struct gsm_trans *trans,
* to store this in our database and wait for a SMMA message */
/* FIXME */
send_signal(S_SMS_MEM_EXCEEDED, trans, sms, 0);
- rate_ctr_inc(&net->msc_ctrs->ctr[MSC_CTR_SMS_RP_ERR_MEM]);
+ rate_ctr_inc(rate_ctr_group_get_ctr(net->msc_ctrs, MSC_CTR_SMS_RP_ERR_MEM));
} else {
send_signal(S_SMS_UNKNOWN_ERROR, trans, sms, 0);
- rate_ctr_inc(&net->msc_ctrs->ctr[MSC_CTR_SMS_RP_ERR_OTHER]);
+ rate_ctr_inc(rate_ctr_group_get_ctr(net->msc_ctrs, MSC_CTR_SMS_RP_ERR_OTHER));
}
sms_free(sms);
@@ -1071,13 +1120,13 @@ static struct gsm_trans *gsm411_alloc_mt_trans(struct gsm_network *net,
struct vlr_subscr *vsub)
{
struct msc_a *msc_a;
- struct gsm_trans *trans = NULL;
+ struct gsm_trans *trans;
int tid;
/* Generate a new transaction ID */
tid = trans_assign_trans_id(net, vsub, TRANS_SMS);
if (tid == -1) {
- LOG_TRANS(trans, LOGL_ERROR, "No available transaction IDs\n");
+ LOGP(DLSMS, LOGL_ERROR, "No available transaction IDs\n");
return NULL;
}
@@ -1169,7 +1218,7 @@ int gsm411_send_sms(struct gsm_network *net,
/* Store a pointer to abstract SMS representation */
trans->sms.sms = sms;
- rate_ctr_inc(&net->msc_ctrs->ctr[MSC_CTR_SMS_DELIVERED]);
+ rate_ctr_inc(rate_ctr_group_get_ctr(net->msc_ctrs, MSC_CTR_SMS_DELIVERED));
db_sms_inc_deliver_attempts(trans->sms.sms);
return gsm411_rp_sendmsg(&trans->sms.smr_inst, msg,
@@ -1180,7 +1229,9 @@ int gsm411_send_sms(struct gsm_network *net,
/* Low-level function to send raw RP-DATA to a given subscriber */
int gsm411_send_rp_data(struct gsm_network *net, struct vlr_subscr *vsub,
size_t sm_rp_oa_len, const uint8_t *sm_rp_oa,
- size_t sm_rp_ud_len, const uint8_t *sm_rp_ud)
+ size_t sm_rp_ud_len, const uint8_t *sm_rp_ud,
+ bool sm_rp_mmts_ind, const uint8_t *gsup_source_name,
+ size_t gsup_source_name_len)
{
struct gsm_trans *trans;
struct msgb *msg;
@@ -1190,6 +1241,22 @@ int gsm411_send_rp_data(struct gsm_network *net, struct vlr_subscr *vsub,
if (!trans)
return -ENOMEM;
+ /* Multi-part SMS: handle MMTS (More Messages to Send) indication */
+ trans->sms.sm_rp_mmts_ind = sm_rp_mmts_ind;
+ if (trans->msc_a != NULL)
+ gsm411_handle_mmts_ind(trans);
+
+ /* Save GSUP source_name for subsequent response messages */
+ if (gsup_source_name && gsup_source_name_len) {
+ trans->sms.gsup_source_name = talloc_memdup(trans, gsup_source_name,
+ gsup_source_name_len);
+ if (!trans->sms.gsup_source_name) {
+ trans_free(trans);
+ return -ENOMEM;
+ }
+ trans->sms.gsup_source_name_len = gsup_source_name_len;
+ }
+
/* Allocate a message buffer for to be encoded SMS */
msg = gsm411_msgb_alloc();
if (!msg) {
@@ -1206,7 +1273,7 @@ int gsm411_send_rp_data(struct gsm_network *net, struct vlr_subscr *vsub,
/* Encode RP-UD itself (SM TPDU) */
msgb_lv_put(msg, sm_rp_ud_len, sm_rp_ud);
- rate_ctr_inc(&net->msc_ctrs->ctr[MSC_CTR_SMS_DELIVERED]);
+ rate_ctr_inc(rate_ctr_group_get_ctr(net->msc_ctrs, MSC_CTR_SMS_DELIVERED));
return gsm411_rp_sendmsg(&trans->sms.smr_inst, msg,
GSM411_MT_RP_DATA_MT, trans->sms.sm_rp_mr,
@@ -1334,4 +1401,3 @@ void gsm411_sapi_n_reject(struct msc_a *msc_a)
trans_free(trans);
}
}
-
diff --git a/src/libmsc/gsm_04_11_gsup.c b/src/libmsc/gsm_04_11_gsup.c
index 9f5175b3a..1afdfabbc 100644
--- a/src/libmsc/gsm_04_11_gsup.c
+++ b/src/libmsc/gsm_04_11_gsup.c
@@ -1,5 +1,5 @@
/*
- * (C) 2018 by Vadim Yanitskiy <axilirator@gmail.com>
+ * (C) 2018-2019 by Vadim Yanitskiy <axilirator@gmail.com>
*
* All Rights Reserved
*
@@ -33,6 +33,7 @@
#include <osmocom/msc/vlr.h>
#include <osmocom/msc/msub.h>
#include <osmocom/msc/gsup_client_mux.h>
+#include <osmocom/msc/msc_a.h>
/* Common helper for preparing to be encoded GSUP message */
static void gsup_sm_msg_init(struct osmo_gsup_message *gsup_msg,
@@ -53,7 +54,7 @@ static void gsup_sm_msg_init(struct osmo_gsup_message *gsup_msg,
int gsm411_gsup_mo_fwd_sm_req(struct gsm_trans *trans, struct msgb *msg,
uint8_t sm_rp_mr, uint8_t *sm_rp_da, uint8_t sm_rp_da_len)
{
- uint8_t bcd_buf[GSM48_MI_SIZE] = { 0 };
+ uint8_t bcd_buf[GSM48_MI_SIZE];
struct osmo_gsup_message gsup_msg;
size_t bcd_len;
@@ -65,22 +66,28 @@ int gsm411_gsup_mo_fwd_sm_req(struct gsm_trans *trans, struct msgb *msg,
/* Assign SM-RP-MR to transaction state */
trans->sms.sm_rp_mr = sm_rp_mr;
- /* Encode subscriber's MSISDN */
+ /* Encode subscriber's MSISDN as LHV (with room for ToN/NPI header) */
bcd_len = gsm48_encode_bcd_number(bcd_buf, sizeof(bcd_buf),
- 0, trans->vsub->msisdn);
+ 1, trans->vsub->msisdn);
if (bcd_len <= 0 || bcd_len > sizeof(bcd_buf)) {
LOG_TRANS(trans, LOGL_ERROR, "Failed to encode subscriber's MSISDN\n");
return -EINVAL;
}
+ /* NOTE: assuming default ToN/NPI values as we don't have this info */
+ bcd_buf[1] = 0x01 /* NPI: ISDN/Telephony Numbering (ITU-T Rec. E.164 / ITU-T Rec. E.163) */
+ | (0x01 << 4) /* ToN: International Number */
+ | (0x01 << 7); /* No Extension */
+
/* Initialize a new GSUP message */
gsup_sm_msg_init(&gsup_msg, OSMO_GSUP_MSGT_MO_FORWARD_SM_REQUEST,
trans->vsub->imsi, &sm_rp_mr);
- /* According to 12.2.3, the MSISDN from VLR is inserted here */
+ /* According to 12.2.3, the MSISDN from VLR is inserted here.
+ * NOTE: redundant BCD length octet is not included. */
gsup_msg.sm_rp_oa_type = OSMO_GSUP_SMS_SM_RP_ODA_MSISDN;
- gsup_msg.sm_rp_oa_len = bcd_len;
- gsup_msg.sm_rp_oa = bcd_buf;
+ gsup_msg.sm_rp_oa_len = bcd_len - 1;
+ gsup_msg.sm_rp_oa = bcd_buf + 1;
/* SM-RP-DA should (already) contain SMSC address */
gsup_msg.sm_rp_da_type = OSMO_GSUP_SMS_SM_RP_ODA_SMSC_ADDR;
@@ -91,6 +98,7 @@ int gsm411_gsup_mo_fwd_sm_req(struct gsm_trans *trans, struct msgb *msg,
gsup_msg.sm_rp_ui_len = msgb_l4len(msg);
gsup_msg.sm_rp_ui = (uint8_t *) msgb_sms(msg);
+ gsup_client_mux_tx_set_source(trans->net->gcm, &gsup_msg);
return gsup_client_mux_tx(trans->net->gcm, &gsup_msg);
}
@@ -113,23 +121,18 @@ int gsm411_gsup_mo_ready_for_sm_req(struct gsm_trans *trans, uint8_t sm_rp_mr)
/* Indicate SMMA as the Alert Reason */
gsup_msg.sm_alert_rsn = OSMO_GSUP_SMS_SM_ALERT_RSN_MEM_AVAIL;
+ gsup_client_mux_tx_set_source(trans->net->gcm, &gsup_msg);
return gsup_client_mux_tx(trans->net->gcm, &gsup_msg);
}
/* Triggers either RP-ACK or RP-ERROR on response from SMSC */
-static int gsm411_gsup_mo_handler(struct vlr_subscr *vsub,
- const struct osmo_gsup_message *gsup_msg)
+static int gsm411_gsup_mo_handler(struct gsm_network *net, struct vlr_subscr *vsub,
+ const struct osmo_gsup_message *gsup_msg)
{
- struct vlr_instance *vlr;
- struct gsm_network *net;
struct gsm_trans *trans;
const char *msg_name;
bool msg_is_err;
- /* Obtain required pointers */
- vlr = vsub->vlr;
- net = (struct gsm_network *) vlr->user_ctx;
-
/* Associate logging messages with this subscriber */
log_set_context(LOG_CTX_VLR_SUBSCR, vsub);
@@ -149,14 +152,6 @@ static int gsm411_gsup_mo_handler(struct vlr_subscr *vsub,
OSMO_ASSERT(0);
}
- /* Make sure that 'SMS over GSUP' is expected */
- if (!net->sms_over_gsup) {
- /* TODO: notify sender about that? */
- LOGP(DLSMS, LOGL_NOTICE, "Unexpected MO SMS over GSUP, "
- "ignoring message...\n");
- return -EIO;
- }
-
/* Verify GSUP message */
if (!gsup_msg->sm_rp_mr)
goto msg_error;
@@ -169,7 +164,8 @@ static int gsm411_gsup_mo_handler(struct vlr_subscr *vsub,
LOGP(DLSMS, LOGL_NOTICE, "No transaction found for %s, "
"ignoring %s-%s message...\n", vlr_subscr_name(vsub),
msg_name, msg_is_err ? "Err" : "Res");
- return -EIO; /* TODO: notify sender about that? */
+ gsup_client_mux_tx_error_reply(net->gcm, gsup_msg, GMM_CAUSE_NO_PDP_ACTIVATED);
+ return -EIO;
}
LOG_TRANS(trans, LOGL_DEBUG, "RX %s-%s\n", msg_name, msg_is_err ? "Err" : "Res");
@@ -186,9 +182,8 @@ static int gsm411_gsup_mo_handler(struct vlr_subscr *vsub,
return 0;
msg_error:
- /* TODO: notify sender about that? */
- LOGP(DLSMS, LOGL_NOTICE, "RX malformed %s-%s\n",
- msg_name, msg_is_err ? "Err" : "Res");
+ LOGP(DLSMS, LOGL_NOTICE, "RX malformed %s-%s\n", msg_name, msg_is_err ? "Err" : "Res");
+ gsup_client_mux_tx_error_reply(net->gcm, gsup_msg, GMM_CAUSE_INV_MAND_INFO);
return -EINVAL;
}
@@ -205,6 +200,11 @@ int gsm411_gsup_mt_fwd_sm_res(struct gsm_trans *trans, uint8_t sm_rp_mr)
gsup_sm_msg_init(&gsup_msg, OSMO_GSUP_MSGT_MT_FORWARD_SM_RESULT,
trans->vsub->imsi, &sm_rp_mr);
+ /* Ensure routing through OsmoHLR to the MT-sending SMSC */
+ gsup_msg.destination_name = trans->sms.gsup_source_name;
+ gsup_msg.destination_name_len = trans->sms.gsup_source_name_len;
+ gsup_client_mux_tx_set_source(trans->net->gcm, &gsup_msg);
+
return gsup_client_mux_tx(trans->net->gcm, &gsup_msg);
}
@@ -222,6 +222,11 @@ int gsm411_gsup_mt_fwd_sm_err(struct gsm_trans *trans,
gsup_sm_msg_init(&gsup_msg, OSMO_GSUP_MSGT_MT_FORWARD_SM_ERROR,
trans->vsub->imsi, &sm_rp_mr);
+ /* Ensure routing through OsmoHLR to the MT-sending SMSC */
+ gsup_msg.destination_name = trans->sms.gsup_source_name;
+ gsup_msg.destination_name_len = trans->sms.gsup_source_name_len;
+ gsup_client_mux_tx_set_source(trans->net->gcm, &gsup_msg);
+
/* SM-RP-Cause value */
gsup_msg.sm_rp_cause = &cause;
@@ -230,28 +235,17 @@ int gsm411_gsup_mt_fwd_sm_err(struct gsm_trans *trans,
}
/* Handles MT SMS (and triggers Paging Request if required) */
-static int gsm411_gsup_mt_handler(struct vlr_subscr *vsub,
- const struct osmo_gsup_message *gsup_msg)
+static int gsm411_gsup_mt_handler(struct gsm_network *net, struct vlr_subscr *vsub,
+ const struct osmo_gsup_message *gsup_msg)
{
- struct gsm_network *net;
+ bool sm_rp_mmts_ind;
int rc;
- /* Obtain required pointers */
- net = (struct gsm_network *) vsub->vlr->user_ctx;
-
/* Associate logging messages with this subscriber */
log_set_context(LOG_CTX_VLR_SUBSCR, vsub);
LOGP(DLSMS, LOGL_DEBUG, "RX MT-forwardSM-Req\n");
- /* Make sure that 'SMS over GSUP' is expected */
- if (!net->sms_over_gsup) {
- LOGP(DLSMS, LOGL_NOTICE, "Unexpected MT SMS over GSUP, "
- "ignoring message...\n");
- /* TODO: notify sender about that? */
- return -EIO;
- }
-
/**
* Verify GSUP message
*
@@ -267,31 +261,51 @@ static int gsm411_gsup_mt_handler(struct vlr_subscr *vsub,
if (gsup_msg->sm_rp_oa_type != OSMO_GSUP_SMS_SM_RP_ODA_SMSC_ADDR)
goto msg_error;
+ /* MMS (More Messages to Send) IE is optional */
+ if (gsup_msg->sm_rp_mms)
+ sm_rp_mmts_ind = *gsup_msg->sm_rp_mms > 0;
+ else
+ sm_rp_mmts_ind = false;
+
/* Send RP-DATA */
rc = gsm411_send_rp_data(net, vsub,
gsup_msg->sm_rp_oa_len, gsup_msg->sm_rp_oa,
- gsup_msg->sm_rp_ui_len, gsup_msg->sm_rp_ui);
+ gsup_msg->sm_rp_ui_len, gsup_msg->sm_rp_ui,
+ sm_rp_mmts_ind, gsup_msg->source_name,
+ gsup_msg->source_name_len);
if (rc) {
LOGP(DLSMS, LOGL_NOTICE, "Failed to send MT SMS, "
"ignoring MT-forwardSM-Req message...\n");
- /* TODO: notify sender about that? */
+ gsup_client_mux_tx_error_reply(net->gcm, gsup_msg, GMM_CAUSE_NET_FAIL);
return rc;
}
return 0;
msg_error:
- /* TODO: notify sender about that? */
LOGP(DLSMS, LOGL_NOTICE, "RX malformed MT-forwardSM-Req\n");
+ gsup_client_mux_tx_error_reply(net->gcm, gsup_msg, GMM_CAUSE_INV_MAND_INFO);
return -EINVAL;
}
int gsm411_gsup_rx(struct gsup_client_mux *gcm, void *data, const struct osmo_gsup_message *gsup_msg)
{
- struct vlr_instance *vlr = data;
- struct vlr_subscr *vsub = vlr_subscr_find_by_imsi(vlr, gsup_msg->imsi, __func__);
+ struct gsm_network *net = (struct gsm_network *) data;
+ struct vlr_subscr *vsub;
+ int rc;
+ /* Make sure that 'SMS over GSUP' is expected */
+ if (!net->sms_over_gsup) {
+ LOGP(DLSMS, LOGL_NOTICE, "Unexpected MO/MT SMS over GSUP "
+ "(sms-over-gsup is not enabled), ignoring message...\n");
+ gsup_client_mux_tx_error_reply(gcm, gsup_msg, GMM_CAUSE_GPRS_NOTALLOWED);
+ return -EIO;
+ }
+
+ vsub = vlr_subscr_find_by_imsi(net->vlr, gsup_msg->imsi, __func__);
if (!vsub) {
+ LOGP(DLSMS, LOGL_ERROR, "Rx %s for unknown subscriber, rejecting\n",
+ osmo_gsup_message_type_name(gsup_msg->message_type));
gsup_client_mux_tx_error_reply(gcm, gsup_msg, GMM_CAUSE_IMSI_UNKNOWN);
return -GMM_CAUSE_IMSI_UNKNOWN;
}
@@ -303,16 +317,22 @@ int gsm411_gsup_rx(struct gsup_client_mux *gcm, void *data, const struct osmo_gs
case OSMO_GSUP_MSGT_READY_FOR_SM_ERROR:
case OSMO_GSUP_MSGT_READY_FOR_SM_RESULT:
DEBUGP(DMSC, "Routed to GSM 04.11 MO handler\n");
- return gsm411_gsup_mo_handler(vsub, gsup_msg);
+ rc = gsm411_gsup_mo_handler(net, vsub, gsup_msg);
+ break;
/* GSM 04.11 code implementing MT SMS */
case OSMO_GSUP_MSGT_MT_FORWARD_SM_REQUEST:
DEBUGP(DMSC, "Routed to GSM 04.11 MT handler\n");
- return gsm411_gsup_mt_handler(vsub, gsup_msg);
+ rc = gsm411_gsup_mt_handler(net, vsub, gsup_msg);
+ break;
default:
LOGP(DMM, LOGL_ERROR, "No handler found for %s, dropping message...\n",
osmo_gsup_message_type_name(gsup_msg->message_type));
- return -GMM_CAUSE_MSGT_NOTEXIST_NOTIMPL;
+ gsup_client_mux_tx_error_reply(gcm, gsup_msg, GMM_CAUSE_MSGT_NOTEXIST_NOTIMPL);
+ rc = -GMM_CAUSE_MSGT_NOTEXIST_NOTIMPL;
}
+
+ vlr_subscr_put(vsub, __func__);
+ return rc;
}
diff --git a/src/libmsc/gsm_04_14.c b/src/libmsc/gsm_04_14.c
index 811655813..03c06fde9 100644
--- a/src/libmsc/gsm_04_14.c
+++ b/src/libmsc/gsm_04_14.c
@@ -43,7 +43,7 @@ static struct msgb *create_gsm0414_msg(uint8_t msg_type)
struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.14");
struct gsm48_hdr *gh;
- gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh) + 1);
+ gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
gh->proto_discr = GSM48_PDISC_TEST;
gh->msg_type = msg_type;
return msg;
diff --git a/src/libmsc/gsm_09_11.c b/src/libmsc/gsm_09_11.c
index 6558272a8..e29389015 100644
--- a/src/libmsc/gsm_09_11.c
+++ b/src/libmsc/gsm_09_11.c
@@ -32,6 +32,7 @@
#include <osmocom/core/linuxlist.h>
#include <osmocom/core/rate_ctr.h>
+#include <osmocom/core/stat_item.h>
#include <osmocom/core/utils.h>
#include <osmocom/core/msgb.h>
@@ -57,7 +58,7 @@ static uint32_t new_callref = 0x20000001;
static void ncss_session_timeout_handler(void *_trans)
{
struct gsm_trans *trans = (struct gsm_trans *) _trans;
- struct osmo_gsup_message gsup_msg = { 0 };
+ struct osmo_gsup_message gsup_msg;
/* The timeout might be disabled from the VTY */
if (trans->net->ncss_guard_timeout == 0)
@@ -124,7 +125,7 @@ int gsm0911_rcv_nc_ss(struct msc_a *msc_a, struct msgb *msg)
trans = trans_find_by_id(msc_a, TRANS_USSD, tid);
if (!trans) {
/* Count MS-initiated attempts to establish a NC SS/USSD session */
- rate_ctr_inc(&net->msc_ctrs->ctr[MSC_CTR_NC_SS_MO_REQUESTS]);
+ rate_ctr_inc(rate_ctr_group_get_ctr(net->msc_ctrs, MSC_CTR_NC_SS_MO_REQUESTS));
/**
* According to GSM TS 04.80, section 2.4.2 "Register
@@ -135,8 +136,9 @@ int gsm0911_rcv_nc_ss(struct msc_a *msc_a, struct msgb *msg)
* a supplementary service.
*/
if (msg_type != GSM0480_MTYPE_REGISTER) {
- LOG_TRANS(trans, LOGL_ERROR, "Rx wrong SS/USSD message type for new transaction: %s\n",
- gsm48_pdisc_msgtype_name(GSM48_PDISC_NC_SS, msg_type));
+ LOGP(DSS, LOGL_ERROR, "Rx %s message for non-existing transaction (tid-%u)\n",
+ gsm48_pdisc_msgtype_name(GSM48_PDISC_NC_SS, msg_type),
+ gsm48_hdr_trans_id(gh));
gsm48_tx_simple(msc_a,
GSM48_PDISC_NC_SS | (tid << 4),
GSM0480_MTYPE_RELEASE_COMPLETE);
@@ -145,7 +147,7 @@ int gsm0911_rcv_nc_ss(struct msc_a *msc_a, struct msgb *msg)
trans = trans_alloc(net, vsub, TRANS_USSD, tid, new_callref++);
if (!trans) {
- LOG_TRANS(trans, LOGL_ERROR, " -> No memory for trans\n");
+ LOGP(DSS, LOGL_ERROR, " -> No memory for trans\n");
gsm48_tx_simple(msc_a,
GSM48_PDISC_NC_SS | (tid << 4),
GSM0480_MTYPE_RELEASE_COMPLETE);
@@ -157,7 +159,7 @@ int gsm0911_rcv_nc_ss(struct msc_a *msc_a, struct msgb *msg)
ncss_session_timeout_handler, trans);
/* Count active NC SS/USSD sessions */
- osmo_counter_inc(net->active_nc_ss);
+ osmo_stat_item_inc(osmo_stat_item_group_get_item(net->statg, MSC_STAT_ACTIVE_NC_SS), 1);
trans->dlci = OMSC_LINKID_CB(msg);
trans->msc_a = msc_a;
@@ -239,9 +241,9 @@ int gsm0911_rcv_nc_ss(struct msc_a *msc_a, struct msgb *msg)
/* Count established MS-initiated NC SS/USSD sessions */
if (msg_type == GSM0480_MTYPE_REGISTER)
- rate_ctr_inc(&net->msc_ctrs->ctr[MSC_CTR_NC_SS_MO_ESTABLISHED]);
+ rate_ctr_inc(rate_ctr_group_get_ctr(net->msc_ctrs, MSC_CTR_NC_SS_MO_ESTABLISHED));
- return 0;
+ return rc;
error:
/* Abort transaction on DTAP-interface */
@@ -263,7 +265,7 @@ static void ss_paging_cb(struct msc_a *msc_a, struct gsm_trans *trans)
if (trans->msc_a) {
LOG_MSC_A_CAT(msc_a, DPAG, LOGL_ERROR,
- "Handle paging error: transaction already associated with subsciber,"
+ "Handle paging error: transaction already associated with subscriber,"
" apparently it was already handled. Skip.\n");
return;
}
@@ -295,11 +297,27 @@ static void ss_paging_cb(struct msc_a *msc_a, struct gsm_trans *trans)
trans->ss.msg = NULL;
/* Count established network-initiated NC SS/USSD sessions */
- rate_ctr_inc(&net->msc_ctrs->ctr[MSC_CTR_NC_SS_MT_ESTABLISHED]);
+ rate_ctr_inc(rate_ctr_group_get_ctr(net->msc_ctrs, MSC_CTR_NC_SS_MT_ESTABLISHED));
} else {
+ struct osmo_gsup_message gsup_msg;
+
LOG_MSC_A_CAT(msc_a, DSS, LOGL_DEBUG, "Paging expired\n");
- /* TODO: inform HLR about this failure */
+ gsup_msg = (struct osmo_gsup_message){
+ .message_class = OSMO_GSUP_MESSAGE_CLASS_USSD,
+ .message_type = OSMO_GSUP_MSGT_PROC_SS_ERROR,
+
+ .session_state = OSMO_GSUP_SESSION_STATE_END,
+ .session_id = trans->callref,
+ /* FIXME: we need message class specific cause values */
+ .cause = GMM_CAUSE_IMPL_DETACHED,
+ };
+
+ /* Fill in subscriber's IMSI */
+ OSMO_STRLCPY_ARRAY(gsup_msg.imsi, trans->vsub->imsi);
+
+ /* Inform HLR/EUSE about the failure */
+ gsup_client_mux_tx(trans->net->gcm, &gsup_msg);
msgb_free(trans->ss.msg);
trans->ss.msg = NULL;
@@ -314,55 +332,38 @@ static struct gsm_trans *establish_nc_ss_trans(struct gsm_network *net,
struct vlr_subscr *vsub, const struct osmo_gsup_message *gsup_msg)
{
struct msc_a *msc_a;
- struct gsm_trans *trans, *transt;
+ struct gsm_trans *trans;
int tid;
- /* Allocate transaction first, for log context */
- trans = trans_alloc(net, vsub, TRANS_USSD,
- TRANS_ID_UNASSIGNED, gsup_msg->session_id);
-
- if (!trans) {
- LOG_TRANS(trans, LOGL_ERROR, " -> No memory for trans\n");
- return NULL;
- }
-
if (gsup_msg->session_state != OSMO_GSUP_SESSION_STATE_BEGIN) {
- LOG_TRANS(trans, LOGL_ERROR, "Received non-BEGIN message "
- "for non-existing transaction\n");
- trans_free(trans);
+ LOGP(DSS, LOGL_ERROR, "Received non-BEGIN message for non-existing transaction\n");
return NULL;
}
+ LOGP(DSS, LOGL_DEBUG, "(%s) Establishing a network-originated session (id=0x%x)\n",
+ vlr_subscr_name(vsub), gsup_msg->session_id);
+
if (!gsup_msg->ss_info || gsup_msg->ss_info_len < 2) {
- LOG_TRANS(trans, LOGL_ERROR, "Missing mandatory Facility IE\n");
- trans_free(trans);
+ LOGP(DSS, LOGL_ERROR, "Missing mandatory Facility IE\n");
return NULL;
}
- /* If subscriber is not "attached" */
- if (!vsub->cgi.lai.lac) {
- LOG_TRANS(trans, LOGL_ERROR, "Network-originated session "
- "rejected - subscriber is not attached\n");
- trans_free(trans);
+ /* Obtain an unused transaction ID */
+ tid = trans_assign_trans_id(net, vsub, TRANS_USSD);
+ if (tid < 0) {
+ LOGP(DSS, LOGL_ERROR, "No free transaction ID\n");
return NULL;
}
- LOG_TRANS(trans, LOGL_DEBUG, "Establishing network-originated session\n");
-
- /* Count active NC SS/USSD sessions */
- osmo_counter_inc(net->active_nc_ss);
-
- /* Assign transaction ID */
- tid = trans_assign_trans_id(trans->net, trans->vsub, TRANS_USSD);
- if (tid < 0) {
- LOG_TRANS(trans, LOGL_ERROR, "No free transaction ID\n");
- /* TODO: inform HLR about this */
- /* TODO: release connection with subscriber */
- trans->callref = 0;
- trans_free(trans);
+ /* Allocate a new NCSS transaction */
+ trans = trans_alloc(net, vsub, TRANS_USSD, tid, gsup_msg->session_id);
+ if (!trans) {
+ LOGP(DSS, LOGL_ERROR, " -> No memory for trans\n");
return NULL;
}
- trans->transaction_id = tid;
+
+ /* Count active NC SS/USSD sessions */
+ osmo_stat_item_inc(osmo_stat_item_group_get_item(net->statg, MSC_STAT_ACTIVE_NC_SS), 1);
/* Init inactivity timer */
osmo_timer_setup(&trans->ss.timer_guard,
@@ -380,20 +381,6 @@ static struct gsm_trans *establish_nc_ss_trans(struct gsm_network *net,
LOG_TRANS(trans, LOGL_DEBUG, "Triggering Paging Request\n");
- /* Find transaction with this subscriber already paging */
- llist_for_each_entry(transt, &net->trans_list, entry) {
- /* Transaction of our conn? */
- if (transt == trans || transt->vsub != vsub)
- continue;
-
- LOG_TRANS(trans, LOGL_ERROR, "Paging already started, "
- "rejecting message...\n");
- trans_free(trans);
- /* FIXME: WTF IS THIS!? This is completely insane. Presence of a trans doesn't indicate Paging, and even
- * if, why drop the current request??? */
- return NULL;
- }
-
/* Trigger Paging Request */
trans->paging_request = paging_request_start(vsub, PAGING_CAUSE_SIGNALLING_HIGH_PRIO,
ss_paging_cb, trans, "GSM 09.11 SS/USSD");
@@ -409,7 +396,7 @@ static struct gsm_trans *establish_nc_ss_trans(struct gsm_network *net,
msgb_tlv_put(trans->ss.msg, GSM0480_IE_FACILITY,
gsup_msg->ss_info_len, gsup_msg->ss_info);
- return NULL;
+ return trans;
}
/* NC SS specific transaction release.
@@ -428,21 +415,24 @@ void _gsm911_nc_ss_trans_free(struct gsm_trans *trans)
osmo_timer_del(&trans->ss.timer_guard);
/* One session less */
- osmo_counter_dec(trans->net->active_nc_ss);
+ osmo_stat_item_dec(osmo_stat_item_group_get_item(trans->net->statg, MSC_STAT_ACTIVE_NC_SS),
+ 1);
}
int gsm0911_gsup_rx(struct gsup_client_mux *gcm, void *data, const struct osmo_gsup_message *gsup_msg)
{
- struct vlr_instance *vlr = data;
- struct gsm_network *net;
+ struct gsm_network *net = (struct gsm_network *) data;
struct gsm_trans *trans;
struct gsm48_hdr *gh;
struct msgb *ss_msg;
bool trans_end;
struct msc_a *msc_a;
- struct vlr_subscr *vsub = vlr_subscr_find_by_imsi(vlr, gsup_msg->imsi, __func__);
+ struct vlr_subscr *vsub;
+ vsub = vlr_subscr_find_by_imsi(net->vlr, gsup_msg->imsi, __func__);
if (!vsub) {
+ LOGP(DSS, LOGL_ERROR, "Rx %s for unknown subscriber, rejecting\n",
+ osmo_gsup_message_type_name(gsup_msg->message_type));
gsup_client_mux_tx_error_reply(gcm, gsup_msg, GMM_CAUSE_IMSI_UNKNOWN);
return -GMM_CAUSE_IMSI_UNKNOWN;
}
@@ -450,38 +440,64 @@ int gsm0911_gsup_rx(struct gsup_client_mux *gcm, void *data, const struct osmo_g
/* Associate logging messages with this subscriber */
log_set_context(LOG_CTX_VLR_SUBSCR, vsub);
- /* Obtain pointer to vlr_instance */
- vlr = vsub->vlr;
- OSMO_ASSERT(vlr);
-
- /* Obtain pointer to gsm_network */
- net = (struct gsm_network *) vlr->user_ctx;
- OSMO_ASSERT(net);
+ /* Attempt to find DTAP-transaction */
+ trans = trans_find_by_callref(net, TRANS_USSD, gsup_msg->session_id);
/* Handle errors */
if (OSMO_GSUP_IS_MSGT_ERROR(gsup_msg->message_type)) {
- /* FIXME: handle this error somehow! */
+ LOGP(DSS, LOGL_NOTICE, "Rx %s from HLR/EUSE (cause=0x%02x, sid=0x%x)\n",
+ osmo_gsup_message_type_name(gsup_msg->message_type),
+ gsup_msg->cause, gsup_msg->session_id);
+
+ /* We don't need subscriber info anymore */
+ vlr_subscr_put(vsub, __func__);
+
+ if (!trans) {
+ LOGP(DSS, LOGL_ERROR, "No transaction found for "
+ "sid=0x%x, nothing to abort\n", gsup_msg->session_id);
+ return -ENODEV;
+ }
+
+ LOG_TRANS(trans, LOGL_NOTICE, "Aborting the session: sending RELEASE COMPLETE\n");
+
+ /* Indicate connection release to subscriber (if active) */
+ if (trans->msc_a != NULL) {
+ /* TODO: implement GSUP - GSM 04.80 cause mapping */
+ msc_send_ussd_release_complete_cause(trans->msc_a, trans->transaction_id,
+ GSM48_CAUSE_LOC_PUN_S_LU, GSM48_CC_CAUSE_TEMP_FAILURE);
+ }
+
+ /* Terminate transaction */
+ trans_free(trans);
+
return 0;
}
- /* Attempt to find DTAP-transaction */
- trans = trans_find_by_callref(net, gsup_msg->session_id);
if (!trans) {
/* Count network-initiated attempts to establish a NC SS/USSD session */
- rate_ctr_inc(&net->msc_ctrs->ctr[MSC_CTR_NC_SS_MT_REQUESTS]);
+ rate_ctr_inc(rate_ctr_group_get_ctr(net->msc_ctrs, MSC_CTR_NC_SS_MT_REQUESTS));
/* Attempt to establish a new transaction */
trans = establish_nc_ss_trans(net, vsub, gsup_msg);
if (!trans) {
- /* FIXME: send ERROR back to the HLR */
+ LOGP(DSS, LOGL_ERROR, "Failed to establish a network-originated "
+ "SS/USSD transaction, rejecting %s\n",
+ osmo_gsup_message_type_name(gsup_msg->message_type));
+ gsup_client_mux_tx_error_reply(gcm, gsup_msg, GMM_CAUSE_NET_FAIL);
+ vlr_subscr_put(vsub, __func__);
return -EINVAL;
}
/* Wait for Paging Response */
- if (trans->paging_request)
+ if (trans->paging_request) {
+ vlr_subscr_put(vsub, __func__);
return 0;
+ }
}
+ /* We don't need subscriber info anymore */
+ vlr_subscr_put(vsub, __func__);
+
/* (Re)schedule the inactivity timer */
if (net->ncss_guard_timeout > 0) {
osmo_timer_schedule(&trans->ss.timer_guard,
@@ -518,7 +534,7 @@ int gsm0911_gsup_rx(struct gsup_client_mux *gcm, void *data, const struct osmo_g
default:
LOG_TRANS(trans, LOGL_ERROR, "Unexpected session state %d\n",
gsup_msg->session_state);
- /* FIXME: send ERROR back to the HLR */
+ gsup_client_mux_tx_error_reply(gcm, gsup_msg, GMM_CAUSE_MSGT_INCOMP_P_STATE);
msgb_free(ss_msg);
return -EINVAL;
}
@@ -528,7 +544,7 @@ int gsm0911_gsup_rx(struct gsup_client_mux *gcm, void *data, const struct osmo_g
if (!gsup_msg->ss_info || gsup_msg->ss_info_len < 2) {
LOG_TRANS(trans, LOGL_ERROR, "Missing mandatory Facility IE "
"for mapped 0x%02x message\n", gh->msg_type);
- /* FIXME: send ERROR back to the HLR */
+ gsup_client_mux_tx_error_reply(gcm, gsup_msg, GMM_CAUSE_INV_MAND_INFO);
msgb_free(ss_msg);
return -EINVAL;
}
@@ -551,6 +567,7 @@ int gsm0911_gsup_rx(struct gsup_client_mux *gcm, void *data, const struct osmo_g
msc_a = trans->msc_a;
if (!msc_a) {
LOG_TRANS(trans, LOGL_ERROR, "Cannot send SS message, no local MSC-A role defined for subscriber\n");
+ gsup_client_mux_tx_error_reply(gcm, gsup_msg, GMM_CAUSE_NET_FAIL);
msgb_free(ss_msg);
return -EINVAL;
}
@@ -562,7 +579,7 @@ int gsm0911_gsup_rx(struct gsup_client_mux *gcm, void *data, const struct osmo_g
/* Count established network-initiated NC SS/USSD sessions */
if (gsup_msg->session_state == OSMO_GSUP_SESSION_STATE_BEGIN)
- rate_ctr_inc(&net->msc_ctrs->ctr[MSC_CTR_NC_SS_MT_ESTABLISHED]);
+ rate_ctr_inc(rate_ctr_group_get_ctr(net->msc_ctrs, MSC_CTR_NC_SS_MT_ESTABLISHED));
return 0;
}
diff --git a/src/libmsc/gsup_client_mux.c b/src/libmsc/gsup_client_mux.c
index 7ec1712e7..e27b6645d 100644
--- a/src/libmsc/gsup_client_mux.c
+++ b/src/libmsc/gsup_client_mux.c
@@ -1,25 +1,21 @@
/* Directing individual GSUP messages to their respective handlers. */
/*
- * (C) 2019 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de>
+ * (C) 2019 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
* All Rights Reserved
*
* Author: Neels Hofmeyr
*
- * SPDX-License-Identifier: GPL-2.0+
+ * SPDX-License-Identifier: AGPL-3.0+
*
* This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ * GNU Affero General Public License for more details.
*/
#include <errno.h>
@@ -140,6 +136,25 @@ int gsup_client_mux_tx(struct gsup_client_mux *gcm, const struct osmo_gsup_messa
return osmo_gsup_client_send(gcm->gsup_client, msg);
}
+/* Set GSUP source_name to our local IPA name */
+void gsup_client_mux_tx_set_source(const struct gsup_client_mux *gcm,
+ struct osmo_gsup_message *gsup_msg)
+{
+ const char *local_msc_name;
+
+ if (!gcm)
+ return;
+ if (!gcm->gsup_client)
+ return;
+ if (!gcm->gsup_client->ipa_dev)
+ return;
+ local_msc_name = gcm->gsup_client->ipa_dev->serno;
+ if (!local_msc_name)
+ return;
+ gsup_msg->source_name = (const uint8_t *) local_msc_name;
+ gsup_msg->source_name_len = strlen(local_msc_name) + 1;
+}
+
/* Transmit GSUP error in response to original message */
void gsup_client_mux_tx_error_reply(struct gsup_client_mux *gcm, const struct osmo_gsup_message *gsup_orig,
enum gsm48_gmm_cause cause)
@@ -150,13 +165,26 @@ void gsup_client_mux_tx_error_reply(struct gsup_client_mux *gcm, const struct os
if (!OSMO_GSUP_IS_MSGT_REQUEST(gsup_orig->message_type))
return;
- OSMO_STRLCPY_ARRAY(gsup_reply.imsi, gsup_orig->imsi);
-
gsup_reply = (struct osmo_gsup_message){
.cause = cause,
.message_type = OSMO_GSUP_TO_MSGT_ERROR(gsup_orig->message_type),
+ .message_class = gsup_orig->message_class,
+ .destination_name = gsup_orig->source_name,
+ .destination_name_len = gsup_orig->source_name_len,
+
+ /* RP-Message-Reference is mandatory for SM Service */
+ .sm_rp_mr = gsup_orig->sm_rp_mr,
};
+ OSMO_STRLCPY_ARRAY(gsup_reply.imsi, gsup_orig->imsi);
+ gsup_client_mux_tx_set_source(gcm, &gsup_reply);
+
+ /* For SS/USSD, it's important to keep both session state and ID IEs */
+ if (gsup_orig->session_state != OSMO_GSUP_SESSION_STATE_NONE) {
+ gsup_reply.session_state = OSMO_GSUP_SESSION_STATE_END;
+ gsup_reply.session_id = gsup_orig->session_id;
+ }
+
if (osmo_gsup_client_enc_send(gcm->gsup_client, &gsup_reply))
LOGP(DLGSUP, LOGL_ERROR, "Failed to send Error reply (imsi=%s)\n",
osmo_quote_str(gsup_orig->imsi, -1));
diff --git a/src/libmsc/mncc.c b/src/libmsc/mncc.c
index 8c95ecb14..026dae025 100644
--- a/src/libmsc/mncc.c
+++ b/src/libmsc/mncc.c
@@ -100,6 +100,7 @@ const char *get_mncc_name(int value)
void mncc_set_cause(struct gsm_mncc *data, int loc, int val)
{
data->fields |= MNCC_F_CAUSE;
+ data->cause.coding = GSM48_CAUSE_CODING_GSM;
data->cause.location = loc;
data->cause.value = val;
}
@@ -109,8 +110,6 @@ void mncc_set_cause(struct gsm_mncc *data, int loc, int val)
* MNCC validation code. Move to libosmocore once headers are merged
************************************************************************/
-#define MNCC_F_ALL 0x3fff
-
static int check_string_terminated(const char *str, unsigned int size)
{
int i;
@@ -156,7 +155,7 @@ static int mncc_prim_check_sign(const struct gsm_mncc *mncc_prim)
{
int rc;
- if (mncc_prim->fields & ~ MNCC_F_ALL) {
+ if (mncc_prim->fields & ~MNCC_F_ALL) {
LOGP(DMNCC, LOGL_ERROR, "Unknown MNCC field mask 0x%x\n", mncc_prim->fields);
return -EINVAL;
}
@@ -234,6 +233,34 @@ static int mncc_prim_check_sign(const struct gsm_mncc *mncc_prim)
return 0;
}
+/* Make sure that the SDP section has a terminating \0. The MNCC message may end after that \0, and if SDP is omitted it
+ * must contain at least one \0 byte. */
+int mncc_check_sdp_termination(const char *label, const struct gsm_mncc *mncc, unsigned int len, const char *sdp)
+{
+ size_t sdp_offset;
+ size_t sdp_data_len;
+ size_t sdp_str_len;
+
+ OSMO_ASSERT(((char*)mncc) < sdp);
+
+ sdp_offset = sdp - (char*)mncc;
+ if (len < sdp_offset)
+ goto too_short;
+
+ sdp_data_len = len - sdp_offset;
+ if (sdp_data_len < 1)
+ goto too_short;
+
+ sdp_str_len = strnlen(sdp, sdp_data_len);
+ /* There must be a \0, so sdp_str_len must be at most sdp_data_len - 1 */
+ if (sdp_str_len >= sdp_data_len)
+ goto too_short;
+ return 0;
+too_short:
+ LOGP(DMNCC, LOGL_ERROR, "Short %s\n", label);
+ return -EINVAL;
+}
+
int mncc_prim_check(const struct gsm_mncc *mncc_prim, unsigned int len)
{
if (len < sizeof(mncc_prim->msg_type)) {
@@ -261,11 +288,7 @@ int mncc_prim_check(const struct gsm_mncc *mncc_prim, unsigned int len)
case MNCC_RTP_FREE:
case MNCC_RTP_CONNECT:
case MNCC_RTP_CREATE:
- if (len < sizeof(struct gsm_mncc_rtp)) {
- LOGP(DMNCC, LOGL_ERROR, "Short MNCC RTP\n");
- return -EINVAL;
- }
- break;
+ return mncc_check_sdp_termination("MNCC RTP", mncc_prim, len, ((struct gsm_mncc_rtp*)mncc_prim)->sdp);
case MNCC_LCHAN_MODIFY:
case MNCC_FRAME_DROP:
case MNCC_FRAME_RECV:
@@ -278,10 +301,8 @@ int mncc_prim_check(const struct gsm_mncc *mncc_prim, unsigned int len)
}
break;
default:
- if (len < sizeof(struct gsm_mncc)) {
- LOGP(DMNCC, LOGL_ERROR, "Short MNCC Signalling\n");
+ if (mncc_check_sdp_termination("MNCC Signalling", mncc_prim, len, mncc_prim->sdp))
return -EINVAL;
- }
return mncc_prim_check_sign(mncc_prim);
}
return 0;
diff --git a/src/libmsc/mncc_builtin.c b/src/libmsc/mncc_builtin.c
index 575497654..647420155 100644
--- a/src/libmsc/mncc_builtin.c
+++ b/src/libmsc/mncc_builtin.c
@@ -15,10 +15,6 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
*/
@@ -89,10 +85,16 @@ static int mncc_setup_ind(struct gsm_call *call,
goto out_reject;
}
- /* we currently only do speech */
- if (setup->bearer_cap.transfer != GSM_MNCC_BCAP_SPEECH) {
+ /* we currently only do speech and CSD */
+ switch (setup->bearer_cap.transfer) {
+ case GSM_MNCC_BCAP_SPEECH:
+ case GSM_MNCC_BCAP_AUDIO:
+ case GSM_MNCC_BCAP_FAX_G3:
+ case GSM_MNCC_BCAP_UNR_DIG:
+ break;
+ default:
LOGP(DMNCC, LOGL_NOTICE, "(call %x) We only support "
- "voice calls\n", call->callref);
+ "voice calls and CSD\n", call->callref);
mncc_set_cause(&mncc, GSM48_CAUSE_LOC_PRN_S_LU,
GSM48_CC_CAUSE_BEARER_CA_UNAVAIL);
goto out_reject;
@@ -263,10 +265,6 @@ int int_mncc_recv(struct gsm_network *net, struct msgb *msg)
struct gsm_call *call = NULL, *callt;
int rc = 0;
- /* Special messages */
- switch(msg_type) {
- }
-
/* find callref */
callref = data->callref;
llist_for_each_entry(callt, &call_list, entry) {
@@ -307,7 +305,7 @@ int int_mncc_recv(struct gsm_network *net, struct msgb *msg)
DEBUGP(DMNCC, "(call %x) Received message %s\n", call->callref,
get_mncc_name(msg_type));
- switch(msg_type) {
+ switch (msg_type) {
case MNCC_SETUP_IND:
rc = mncc_setup_ind(call, arg);
break;
@@ -374,7 +372,8 @@ int int_mncc_recv(struct gsm_network *net, struct msgb *msg)
rc = mncc_tx_to_cc(net, data);
break;
default:
- LOGP(DMNCC, LOGL_NOTICE, "(call %x) Message unhandled\n", callref);
+ LOGP(DMNCC, LOGL_NOTICE, "(call %x) Message '%s' unhandled\n",
+ callref, get_mncc_name(msg_type));
break;
}
diff --git a/src/libmsc/mncc_call.c b/src/libmsc/mncc_call.c
index 5ca91d022..557f2d749 100644
--- a/src/libmsc/mncc_call.c
+++ b/src/libmsc/mncc_call.c
@@ -2,7 +2,7 @@
/* At the time of writing, this is only used for inter-MSC handover: forward a voice stream to a remote MSC.
* Maybe it makes sense to also use it for all "normal" external call management at some point. */
/*
- * (C) 2019 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de>
+ * (C) 2019 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
* All Rights Reserved
*
* SPDX-License-Identifier: AGPL-3.0+
@@ -35,6 +35,7 @@
#include <osmocom/msc/rtp_stream.h>
#include <osmocom/msc/msub.h>
#include <osmocom/msc/vlr.h>
+#include <osmocom/msc/codec_mapping.h>
struct osmo_fsm mncc_call_fsm;
static bool mncc_call_tx_rtp_create(struct mncc_call *mncc_call);
@@ -60,7 +61,7 @@ struct gsm_network *gsmnet = NULL;
void mncc_call_fsm_init(struct gsm_network *net)
{
- osmo_fsm_register(&mncc_call_fsm);
+ OSMO_ASSERT(osmo_fsm_register(&mncc_call_fsm) == 0);
gsmnet = net;
}
@@ -192,7 +193,7 @@ int mncc_call_set_rtp_stream(struct mncc_call *mncc_call, struct rtp_stream *rtp
/* Disassociate the rtp_stream from this MNCC call instance, and clear the remote RTP IP:port info.
* When the MNCC FSM ends for any reason, it will release the RTP stream (which usually triggers complete tear down of
- * the call_leg and CC transaction). If the RTP stream should still remain in use, e.g. during Subseqent inter-MSC
+ * the call_leg and CC transaction). If the RTP stream should still remain in use, e.g. during Subsequent inter-MSC
* Handover where this MNCC was a forwarding to a remote MSC that is no longer needed, this function must be called
* before the MNCC FSM instance terminates. Call this *before* setting a new remote RTP address on the rtp_stream, since
* this clears the rtp_stream->remote ip:port information. */
@@ -208,24 +209,25 @@ void mncc_call_detach_rtp_stream(struct mncc_call *mncc_call)
static void mncc_call_tx_setup_ind(struct mncc_call *mncc_call)
{
- struct gsm_mncc mncc_msg = mncc_call->outgoing_req;
- mncc_msg.msg_type = MNCC_SETUP_IND;
- mncc_msg.callref = mncc_call->callref;
+ union mncc_msg mncc_msg;
+ mncc_msg.signal = mncc_call->outgoing_req;
+ mncc_msg.signal.msg_type = MNCC_SETUP_IND;
+ mncc_msg.signal.callref = mncc_call->callref;
- OSMO_STRLCPY_ARRAY(mncc_msg.imsi, mncc_call->vsub->imsi);
+ OSMO_STRLCPY_ARRAY(mncc_msg.signal.imsi, mncc_call->vsub->imsi);
if (!(mncc_call->outgoing_req.fields & MNCC_F_CALLING)) {
/* No explicit calling number set, use the local subscriber */
- mncc_msg.fields |= MNCC_F_CALLING;
- OSMO_STRLCPY_ARRAY(mncc_msg.calling.number, mncc_call->vsub->msisdn);
+ mncc_msg.signal.fields |= MNCC_F_CALLING;
+ OSMO_STRLCPY_ARRAY(mncc_msg.signal.calling.number, mncc_call->vsub->msisdn);
}
mncc_call->local_msisdn_present = true;
- mncc_call->local_msisdn = mncc_msg.calling;
+ mncc_call->local_msisdn = mncc_msg.signal.calling;
- rate_ctr_inc(&gsmnet->msc_ctrs->ctr[MSC_CTR_CALL_MO_SETUP]);
+ rate_ctr_inc(rate_ctr_group_get_ctr(gsmnet->msc_ctrs, MSC_CTR_CALL_MO_SETUP));
- mncc_call_tx(mncc_call, (union mncc_msg*)&mncc_msg);
+ mncc_call_tx(mncc_call, &mncc_msg);
}
static void mncc_call_rx_setup_req(struct mncc_call *mncc_call, const struct gsm_mncc *incoming_req)
@@ -256,45 +258,26 @@ static bool mncc_call_rx_rtp_create(struct mncc_call *mncc_call)
return true;
}
- if (!osmo_sockaddr_str_is_set(&mncc_call->rtps->local)) {
+ if (!osmo_sockaddr_str_is_nonzero(&mncc_call->rtps->local)) {
LOG_MNCC_CALL(mncc_call, LOGL_DEBUG, "Got RTP_CREATE, but RTP stream has no local address\n");
return true;
}
- if (!mncc_call->rtps->codec_known) {
+ if (!mncc_call->rtps->codecs_known) {
LOG_MNCC_CALL(mncc_call, LOGL_DEBUG, "Got RTP_CREATE, but RTP stream has no codec set\n");
return true;
}
LOG_MNCC_CALL(mncc_call, LOGL_DEBUG, "Got RTP_CREATE, responding with " OSMO_SOCKADDR_STR_FMT " %s\n",
OSMO_SOCKADDR_STR_FMT_ARGS(&mncc_call->rtps->local),
- osmo_mgcpc_codec_name(mncc_call->rtps->codec));
+ sdp_audio_codecs_to_str(&mncc_call->rtps->codecs));
/* Already know what RTP IP:port to tell the MNCC. Send it. */
return mncc_call_tx_rtp_create(mncc_call);
}
-/* Convert enum mgcp_codecs to an gsm_mncc_rtp->payload_msg_type value. */
-uint32_t mgcp_codec_to_mncc_payload_msg_type(enum mgcp_codecs codec)
-{
- switch (codec) {
- default:
- /* disclaimer: i have no idea what i'm doing. */
- case CODEC_GSM_8000_1:
- return GSM_TCHF_FRAME;
- case CODEC_GSMEFR_8000_1:
- return GSM_TCHF_FRAME_EFR;
- case CODEC_GSMHR_8000_1:
- return GSM_TCHH_FRAME;
- case CODEC_AMR_8000_1:
- case CODEC_AMRWB_16000_1:
- //return GSM_TCHF_FRAME;
- return GSM_TCH_FRAME_AMR;
- }
-}
-
static bool mncc_call_tx_rtp_create(struct mncc_call *mncc_call)
{
- if (!mncc_call->rtps || !osmo_sockaddr_str_is_set(&mncc_call->rtps->local)) {
+ if (!mncc_call->rtps || !osmo_sockaddr_str_is_nonzero(&mncc_call->rtps->local)) {
mncc_call_error(mncc_call, "Cannot send RTP_CREATE, no local RTP address set up\n");
return false;
}
@@ -303,19 +286,26 @@ static bool mncc_call_tx_rtp_create(struct mncc_call *mncc_call)
.rtp = {
.msg_type = MNCC_RTP_CREATE,
.callref = mncc_call->callref,
- .port = rtp_local->port,
},
};
- if (osmo_sockaddr_str_to_32n(rtp_local, &mncc_msg.rtp.ip)) {
+ if (osmo_sockaddr_str_to_sockaddr(rtp_local, &mncc_msg.rtp.addr)) {
mncc_call_error(mncc_call, "Failed to compose IP address " OSMO_SOCKADDR_STR_FMT "\n",
OSMO_SOCKADDR_STR_FMT_ARGS(rtp_local));
return false;
}
- if (mncc_call->rtps->codec_known) {
- mncc_msg.rtp.payload_type = 0; /* ??? */
- mncc_msg.rtp.payload_msg_type = mgcp_codec_to_mncc_payload_msg_type(mncc_call->rtps->codec);
+ if (mncc_call->rtps->codecs_known) {
+ struct sdp_audio_codec *codec = &mncc_call->rtps->codecs.codec[0];
+ const struct codec_mapping *m = codec_mapping_by_subtype_name(codec->subtype_name);
+
+ if (!m) {
+ mncc_call_error(mncc_call, "Failed to resolve audio codec '%s'\n",
+ sdp_audio_codec_to_str(codec));
+ return false;
+ }
+ mncc_msg.rtp.payload_type = codec->payload_type;
+ mncc_msg.rtp.payload_msg_type = m->mncc_payload_msg_type;
}
if (mncc_call_tx(mncc_call, &mncc_msg))
@@ -332,7 +322,7 @@ static bool mncc_call_rx_rtp_connect(struct mncc_call *mncc_call, const struct g
return true;
}
- if (osmo_sockaddr_str_from_32n(&rtp, mncc_msg->ip, mncc_msg->port)) {
+ if (osmo_sockaddr_str_from_sockaddr(&rtp, &mncc_msg->addr)) {
mncc_call_error(mncc_call, "Cannot RTP-CONNECT, invalid RTP IP:port in incoming MNCC message\n");
return false;
}
diff --git a/src/libmsc/mncc_sock.c b/src/libmsc/mncc_sock.c
index 0a4e99b92..410449d6d 100644
--- a/src/libmsc/mncc_sock.c
+++ b/src/libmsc/mncc_sock.c
@@ -6,18 +6,14 @@
* All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ * GNU Affero General Public License for more details.
*
*/
@@ -65,7 +61,7 @@ int mncc_sock_from_cc(struct gsm_network *net, struct msgb *msg)
/* Actually enqueue the message and mark socket write need */
msgb_enqueue(&net->upqueue, msg);
- net->mncc_state->conn_bfd.when |= BSC_FD_WRITE;
+ osmo_fd_write_enable(&net->mncc_state->conn_bfd);
return 0;
}
@@ -75,14 +71,14 @@ static void mncc_sock_close(struct mncc_sock_state *state)
LOGP(DMNCC, LOGL_NOTICE, "MNCC Socket has LOST connection\n");
+ osmo_fd_unregister(bfd);
close(bfd->fd);
bfd->fd = -1;
- osmo_fd_unregister(bfd);
/* re-enable the generation of ACCEPT for new connections */
- state->listen_bfd.when |= BSC_FD_READ;
+ osmo_fd_read_enable(&state->listen_bfd);
- /* release all exisitng calls */
+ /* release all existing calls */
gsm0408_clear_all_trans(state->net, TRANS_CC);
/* flush the queue */
@@ -146,7 +142,7 @@ static int mncc_sock_write(struct osmo_fd *bfd)
msg = llist_entry(net->upqueue.next, struct msgb, list);
mncc_prim = (struct gsm_mncc *)msg->data;
- bfd->when &= ~BSC_FD_WRITE;
+ osmo_fd_write_disable(bfd);
/* bug hunter 8-): maybe someone forgot msgb_put(...) ? */
if (!msgb_length(msg)) {
@@ -161,7 +157,7 @@ static int mncc_sock_write(struct osmo_fd *bfd)
goto close;
if (rc < 0) {
if (errno == EAGAIN) {
- bfd->when |= BSC_FD_WRITE;
+ osmo_fd_write_enable(bfd);
break;
}
goto close;
@@ -185,12 +181,12 @@ static int mncc_sock_cb(struct osmo_fd *bfd, unsigned int flags)
{
int rc = 0;
- if (flags & BSC_FD_READ)
+ if (flags & OSMO_FD_READ)
rc = mncc_sock_read(bfd);
if (rc < 0)
return rc;
- if (flags & BSC_FD_WRITE)
+ if (flags & OSMO_FD_WRITE)
rc = mncc_sock_write(bfd);
return rc;
@@ -222,7 +218,7 @@ static void queue_hello(struct mncc_sock_state *mncc)
hello->lchan_type_offset = offsetof(struct gsm_mncc, lchan_type);
msgb_enqueue(&mncc->net->upqueue, msg);
- mncc->conn_bfd.when |= BSC_FD_WRITE;
+ osmo_fd_write_enable(&mncc->conn_bfd);
}
/* accept a new connection */
@@ -245,16 +241,12 @@ static int mncc_sock_accept(struct osmo_fd *bfd, unsigned int flags)
LOGP(DMNCC, LOGL_NOTICE, "MNCC app connects but we already have "
"another active connection ?!?\n");
/* We already have one MNCC app connected, this is all we support */
- state->listen_bfd.when &= ~BSC_FD_READ;
+ osmo_fd_read_disable(&state->listen_bfd);
close(rc);
return 0;
}
- conn_bfd->fd = rc;
- conn_bfd->when = BSC_FD_READ;
- conn_bfd->cb = mncc_sock_cb;
- conn_bfd->data = state;
-
+ osmo_fd_setup(conn_bfd, rc, OSMO_FD_READ, mncc_sock_cb, state, 0);
if (osmo_fd_register(conn_bfd) != 0) {
LOGP(DMNCC, LOGL_ERROR, "Failed to register new connection fd\n");
close(conn_bfd->fd);
@@ -294,10 +286,7 @@ int mncc_sock_init(struct gsm_network *net, const char *sock_path)
return -1;
}
- bfd->when = BSC_FD_READ;
- bfd->cb = mncc_sock_accept;
- bfd->data = state;
-
+ osmo_fd_setup(bfd, bfd->fd, OSMO_FD_READ, mncc_sock_accept, state, 0);
rc = osmo_fd_register(bfd);
if (rc < 0) {
LOGP(DMNCC, LOGL_ERROR, "Could not register listen fd: %d\n", rc);
diff --git a/src/libmsc/msc_a.c b/src/libmsc/msc_a.c
index cfba545be..db1d9983a 100644
--- a/src/libmsc/msc_a.c
+++ b/src/libmsc/msc_a.c
@@ -1,6 +1,6 @@
/* Code to manage a subscriber's MSC-A role */
/*
- * (C) 2019 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de>
+ * (C) 2019 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
* All Rights Reserved
*
* SPDX-License-Identifier: AGPL-3.0+
@@ -36,6 +36,7 @@
#include <osmocom/msc/signal.h>
#include <osmocom/msc/vlr.h>
#include <osmocom/msc/transaction.h>
+#include <osmocom/msc/transaction_cc.h>
#include <osmocom/msc/ran_peer.h>
#include <osmocom/msc/ran_msg_a.h>
#include <osmocom/msc/ran_msg_iu.h>
@@ -46,6 +47,8 @@
#include <osmocom/msc/call_leg.h>
#include <osmocom/msc/rtp_stream.h>
#include <osmocom/msc/msc_ho.h>
+#include <osmocom/msc/codec_mapping.h>
+#include <osmocom/msc/msc_vgcs.h>
#define MSC_A_USE_WAIT_CLEAR_COMPLETE "wait-Clear-Complete"
@@ -63,9 +66,15 @@ static const struct osmo_tdef_state_timeout msc_a_fsm_timeouts[32] = {
/* Transition to a state, using the T timer defined in msc_a_fsm_timeouts.
* The actual timeout value is in turn obtained from network->T_defs.
* Assumes local variable fi exists. */
-#define msc_a_state_chg(msc_a, state) \
+#define msc_a_state_chg_always(msc_a, state) \
osmo_tdef_fsm_inst_state_chg((msc_a)->c.fi, state, msc_a_fsm_timeouts, (msc_a)->c.ran->tdefs, 5)
+/* Same as msc_a_state_chg_always() but ignore if the msc_a already is in the target state. */
+#define msc_a_state_chg(msc_a, STATE) do { \
+ if ((msc_a)->c.fi->state != STATE) \
+ msc_a_state_chg_always(msc_a, STATE); \
+ } while(0)
+
struct gsm_network *msc_a_net(const struct msc_a *msc_a)
{
return msub_net(msc_a->c.msub);
@@ -100,25 +109,46 @@ struct msc_a *msc_a_fi_priv(struct osmo_fsm_inst *fi)
return fi->priv;
}
+bool msc_a_is_ciphering_to_be_attempted(const struct msc_a *msc_a)
+{
+ struct gsm_network *net = msc_a_net(msc_a);
+ bool is_utran = (msc_a->c.ran->type == OSMO_RAT_UTRAN_IU);
+ if (is_utran)
+ return net->uea_encryption_mask > (1 << OSMO_UTRAN_UEA0);
+ else
+ return net->a5_encryption_mask > 0x1;
+}
+
+bool msc_a_is_ciphering_required(const struct msc_a *msc_a)
+{
+ struct gsm_network *net = msc_a_net(msc_a);
+ bool is_utran = (msc_a->c.ran->type == OSMO_RAT_UTRAN_IU);
+ if (is_utran)
+ return net->uea_encryption_mask
+ && ((net->uea_encryption_mask & (1 << OSMO_UTRAN_UEA0)) == 0);
+ else
+ return net->a5_encryption_mask
+ && ((net->a5_encryption_mask & 0x1) == 0);
+}
+
static void update_counters(struct osmo_fsm_inst *fi, bool conn_accepted)
{
struct msc_a *msc_a = fi->priv;
struct gsm_network *net = msc_a_net(msc_a);
switch (msc_a->complete_layer3_type) {
case COMPLETE_LAYER3_LU:
- rate_ctr_inc(&net->msc_ctrs->ctr[
- conn_accepted ? MSC_CTR_LOC_UPDATE_COMPLETED
- : MSC_CTR_LOC_UPDATE_FAILED]);
+ rate_ctr_inc(rate_ctr_group_get_ctr(net->msc_ctrs, conn_accepted ? MSC_CTR_LOC_UPDATE_COMPLETED : MSC_CTR_LOC_UPDATE_FAILED));
break;
case COMPLETE_LAYER3_CM_SERVICE_REQ:
- rate_ctr_inc(&net->msc_ctrs->ctr[
- conn_accepted ? MSC_CTR_CM_SERVICE_REQUEST_ACCEPTED
- : MSC_CTR_CM_SERVICE_REQUEST_REJECTED]);
+ rate_ctr_inc(rate_ctr_group_get_ctr(net->msc_ctrs, conn_accepted ? MSC_CTR_CM_SERVICE_REQUEST_ACCEPTED : MSC_CTR_CM_SERVICE_REQUEST_REJECTED));
break;
case COMPLETE_LAYER3_PAGING_RESP:
- rate_ctr_inc(&net->msc_ctrs->ctr[
- conn_accepted ? MSC_CTR_PAGING_RESP_ACCEPTED
- : MSC_CTR_PAGING_RESP_REJECTED]);
+ rate_ctr_inc(rate_ctr_group_get_ctr(net->msc_ctrs, conn_accepted ? MSC_CTR_PAGING_RESP_ACCEPTED : MSC_CTR_PAGING_RESP_REJECTED));
+ break;
+ case COMPLETE_LAYER3_CM_RE_ESTABLISH_REQ:
+ rate_ctr_inc(rate_ctr_group_get_ctr(net->msc_ctrs,
+ conn_accepted ? MSC_CTR_CM_RE_ESTABLISH_REQ_ACCEPTED
+ : MSC_CTR_CM_RE_ESTABLISH_REQ_REJECTED));
break;
default:
break;
@@ -132,6 +162,12 @@ static void evaluate_acceptance_outcome(struct osmo_fsm_inst *fi, bool conn_acce
update_counters(fi, conn_accepted);
+ if (conn_accepted) {
+ /* Record the Cell ID seen in Complete Layer 3 Information in the VLR, so that it also shows in vty
+ * 'show' output. */
+ vsub->cgi = msc_a->via_cell;
+ }
+
/* Trigger transactions that we paged for */
if (msc_a->complete_layer3_type == COMPLETE_LAYER3_PAGING_RESP) {
if (conn_accepted)
@@ -145,6 +181,15 @@ static void evaluate_acceptance_outcome(struct osmo_fsm_inst *fi, bool conn_acce
if (msc_a->complete_layer3_type == COMPLETE_LAYER3_LU)
msc_a_put(msc_a, MSC_A_USE_LOCATION_UPDATING);
+
+ if (conn_accepted && msc_a->complete_layer3_type == COMPLETE_LAYER3_CM_RE_ESTABLISH_REQ) {
+ /* Trigger new Assignment to recommence the voice call. A little dance here because normally we verify
+ * that no CC trans is already active. */
+ struct gsm_trans *cc_trans = msc_a->cc.active_trans;
+ msc_a->cc.active_trans = NULL;
+ osmo_fsm_inst_dispatch(msc_a->c.fi, MSC_A_EV_TRANSACTION_ACCEPTED, cc_trans);
+ msc_a_try_call_assignment(cc_trans);
+ }
}
bool msc_a_is_accepted(const struct msc_a *msc_a)
@@ -286,6 +331,14 @@ int msc_a_vlr_set_cipher_mode(void *_msc_a, bool umts_aka, bool retrieve_imeisv)
return msc_a_ran_enc_ciphering(msc_a, umts_aka, retrieve_imeisv);
}
+static uint8_t filter_a5(uint8_t a5_mask, bool umts_aka)
+{
+ /* With GSM AKA: allow A5/0, 1, 3 = 0b00001011 = 0xb.
+ * UMTS aka: allow A5/0, 1, 3, 4 = 0b00011011 = 0x1b.
+ */
+ return a5_mask & (umts_aka ? 0x1b : 0x0b);
+}
+
static int msc_a_ran_enc_ciphering(struct msc_a *msc_a, bool umts_aka, bool retrieve_imeisv)
{
struct gsm_network *net;
@@ -315,11 +368,14 @@ static int msc_a_ran_enc_ciphering(struct msc_a *msc_a, bool umts_aka, bool retr
.geran = {
.umts_aka = umts_aka,
.retrieve_imeisv = retrieve_imeisv,
- .a5_encryption_mask = net->a5_encryption_mask,
+ .a5_encryption_mask = filter_a5(net->a5_encryption_mask, umts_aka),
/* for ran_a.c to store the GERAN key that is actually used */
.chosen_key = &msc_a->geran_encr,
},
+ .utran = {
+ .uea_encryption_mask = net->uea_encryption_mask,
+ },
},
};
@@ -331,8 +387,12 @@ static int msc_a_ran_enc_ciphering(struct msc_a *msc_a, bool umts_aka, bool retr
}
if (msc_a->geran_encr.key_len)
- LOG_MSC_A(msc_a, LOGL_DEBUG, "RAN encoding chose ciphering key %s\n",
- osmo_hexdump_nospc(msc_a->geran_encr.key, msc_a->geran_encr.key_len));
+ LOG_MSC_A(msc_a, LOGL_DEBUG, "RAN encoding chose ciphering: A5/%d kc %s kc128 %s\n",
+ msc_a->geran_encr.alg_id - 1,
+ osmo_hexdump_nospc_c(OTC_SELECT, msc_a->geran_encr.key, msc_a->geran_encr.key_len),
+ msc_a->geran_encr.kc128_present ?
+ osmo_hexdump_nospc_c(OTC_SELECT, msc_a->geran_encr.kc128, sizeof(msc_a->geran_encr.kc128))
+ : "-");
return 0;
}
@@ -429,6 +489,16 @@ static bool msc_a_fsm_has_active_transactions(struct osmo_fsm_inst *fi)
__func__);
return true;
}
+ if (osmo_use_count_by(&msc_a->use_count, MSC_A_USE_CM_SERVICE_GCC)) {
+ LOG_MSC_A(msc_a, LOGL_DEBUG, "%s: still awaiting MO GCC request after a CM Service Request\n",
+ __func__);
+ return true;
+ }
+ if (osmo_use_count_by(&msc_a->use_count, MSC_A_USE_CM_SERVICE_BCC)) {
+ LOG_MSC_A(msc_a, LOGL_DEBUG, "%s: still awaiting MO BCC request after a CM Service Request\n",
+ __func__);
+ return true;
+ }
if (osmo_use_count_by(&msc_a->use_count, MSC_A_USE_CM_SERVICE_SMS)) {
LOG_MSC_A(msc_a, LOGL_DEBUG, "%s: still awaiting MO SMS after a CM Service Request\n",
__func__);
@@ -505,42 +575,141 @@ static void msc_a_fsm_authenticated(struct osmo_fsm_inst *fi, uint32_t event, vo
}
}
+static struct call_leg *msc_a_ensure_call_leg(struct msc_a *msc_a, struct gsm_trans *for_cc_trans)
+{
+ struct call_leg *cl = msc_a->cc.call_leg;
+ struct gsm_network *net = msc_a_net(msc_a);
+
+ /* Ensure that events about RTP endpoints coming from the msc_a->cc.call_leg know which gsm_trans to abort on
+ * error */
+ if (!msc_a->cc.active_trans)
+ msc_a->cc.active_trans = for_cc_trans;
+ if (msc_a->cc.active_trans != for_cc_trans) {
+ LOG_TRANS(for_cc_trans, LOGL_ERROR,
+ "Cannot create call leg, another trans is already active for this conn\n");
+ return NULL;
+ }
+
+ if (!cl) {
+ cl = msc_a->cc.call_leg = call_leg_alloc(msc_a->c.fi,
+ MSC_EV_CALL_LEG_TERM,
+ MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE,
+ MSC_EV_CALL_LEG_RTP_COMPLETE);
+ OSMO_ASSERT(cl);
+
+ if (net->use_osmux != OSMUX_USAGE_OFF) {
+ struct msc_i *msc_i = msc_a_msc_i(msc_a);
+ if (msc_i->c.remote_to) {
+ /* TODO: investigate what to do in this case */
+ LOG_MSC_A(msc_a, LOGL_ERROR, "Osmux not yet supported for inter-MSC");
+ } else {
+ cl->ran_peer_supports_osmux = msc_i->ran_conn->ran_peer->remote_supports_osmux;
+ }
+ }
+
+ }
+ return cl;
+}
+
+int msc_a_ensure_cn_local_rtp(struct msc_a *msc_a, struct gsm_trans *cc_trans)
+{
+ struct call_leg *cl;
+ struct rtp_stream *rtp_to_ran;
+
+ cl = msc_a_ensure_call_leg(msc_a, cc_trans);
+ if (!cl)
+ return -EINVAL;
+ rtp_to_ran = cl->rtp[RTP_TO_RAN];
+
+ if (call_leg_local_ip(cl, RTP_TO_CN)) {
+ /* Already has an RTP address and port towards the CN, continue right away. */
+ return osmo_fsm_inst_dispatch(msc_a->c.fi, MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE, cl->rtp[RTP_TO_CN]);
+ }
+
+ /* No CN RTP address available yet, ask the MGW to create one.
+ * Set a codec to be used: if Assignment on the RAN side is already done, take the same codec as the RTP_TO_RAN.
+ * If no RAN side RTP is established, try to guess a preliminary codec from SDP -- before Assignment, picking a
+ * codec from the SDP is more politeness/avoiding confusion than necessity. The actual codec to be used would be
+ * determined later. If no codec could be determined, pass none for the time being. */
+ return call_leg_ensure_ci(cl, RTP_TO_CN, cc_trans->call_id, cc_trans,
+ rtp_to_ran->codecs_known ? &rtp_to_ran->codecs : NULL, NULL);
+}
+
/* The MGW has given us a local IP address for the RAN side. Ready to start the Assignment of a voice channel. */
-static void msc_a_call_leg_ran_local_addr_available(struct msc_a *msc_a)
+void msc_a_tx_assignment_cmd(struct msc_a *msc_a)
{
struct ran_msg msg;
struct gsm_trans *cc_trans = msc_a->cc.active_trans;
struct gsm0808_channel_type channel_type;
- /* Once a CI is known, we could also CRCX the CN side of the MGW endpoint, but it makes sense to wait for the
- * codec to be determined by the Assignment Complete message, first. */
+ if (!cc_trans) {
+ LOG_MSC_A(msc_a, LOGL_ERROR, "No CC transaction active\n");
+ call_leg_release(msc_a->cc.call_leg);
+ return;
+ }
+
+ trans_cc_filter_run(cc_trans);
+ LOG_TRANS(cc_trans, LOGL_DEBUG, "Sending Assignment Command\n");
+
+ switch (cc_trans->bearer_cap.transfer) {
+ case GSM48_BCAP_ITCAP_SPEECH:
+ if (!cc_trans->cc.local.audio_codecs.count) {
+ LOG_TRANS(cc_trans, LOGL_ERROR, "Assignment not possible, no matching codec: %s\n",
+ codec_filter_to_str(&cc_trans->cc.codecs, &cc_trans->cc.local, &cc_trans->cc.remote));
+ call_leg_release(msc_a->cc.call_leg);
+ return;
+ }
+
+ /* Compose 48.008 Channel Type from the current set of codecs
+ * determined from both local and remote codec capabilities. */
+ if (sdp_audio_codecs_to_gsm0808_channel_type(&channel_type, &cc_trans->cc.local.audio_codecs)) {
+ LOG_MSC_A(msc_a, LOGL_ERROR, "Cannot compose Channel Type (Permitted Speech) from codecs: %s\n",
+ codec_filter_to_str(&cc_trans->cc.codecs, &cc_trans->cc.local, &cc_trans->cc.remote));
+ trans_free(cc_trans);
+ return;
+ }
+ break;
+ case GSM48_BCAP_ITCAP_3k1_AUDIO:
+ case GSM48_BCAP_ITCAP_FAX_G3:
+ case GSM48_BCAP_ITCAP_UNR_DIG_INF:
+ if (!cc_trans->cc.local.bearer_services.count) {
+ LOG_TRANS(cc_trans, LOGL_ERROR, "Assignment not possible, no matching bearer service: %s\n",
+ csd_filter_to_str(&cc_trans->cc.csd, &cc_trans->cc.local, &cc_trans->cc.remote));
+ call_leg_release(msc_a->cc.call_leg);
+ return;
+ }
- if (mncc_bearer_cap_to_channel_type(&channel_type, &cc_trans->bearer_cap)) {
- LOG_MSC_A(msc_a, LOGL_ERROR, "Cannot compose Channel Type from bearer capabilities\n");
- /* FIXME: ERROR HANDLING */
+ /* Compose 48.008 Channel Type from the current set of bearer
+ * services determined from local and remote capabilities. */
+ if (csd_bs_list_to_gsm0808_channel_type(&channel_type, &cc_trans->cc.local.bearer_services)) {
+ LOG_MSC_A(msc_a, LOGL_ERROR, "Cannot compose channel type from: %s\n",
+ csd_filter_to_str(&cc_trans->cc.csd, &cc_trans->cc.local, &cc_trans->cc.remote));
+ return;
+ }
+ break;
+ default:
+ LOG_TRANS(cc_trans, LOGL_ERROR, "Assignment not possible for information transfer capability %d\n",
+ cc_trans->bearer_cap.transfer);
+ call_leg_release(msc_a->cc.call_leg);
return;
}
- /* The RAN side RTP address is known, so the voice Assignment can commence. */
+ /* The RAN side RTP address is known, so the voice/CSD Assignment can commence. */
msg = (struct ran_msg){
.msg_type = RAN_MSG_ASSIGNMENT_COMMAND,
.assignment_command = {
.cn_rtp = &msc_a->cc.call_leg->rtp[RTP_TO_RAN]->local,
.channel_type = &channel_type,
+ .osmux_present = msc_a->cc.call_leg->rtp[RTP_TO_RAN]->use_osmux,
+ .osmux_cid = msc_a->cc.call_leg->rtp[RTP_TO_RAN]->local_osmux_cid,
+ .call_id_present = true,
+ .call_id = cc_trans->call_id,
+ .lcls = cc_trans->cc.lcls,
},
};
if (msc_a_ran_down(msc_a, MSC_ROLE_I, &msg)) {
LOG_MSC_A(msc_a, LOGL_ERROR, "Cannot send Assignment\n");
- /* FIXME: ERROR HANDLING */
- return;
- }
-}
-
-static void msc_a_call_leg_cn_local_addr_available(struct msc_a *msc_a, struct gsm_trans *cc_trans)
-{
- if (gsm48_tch_rtp_create(cc_trans)) {
- LOG_MSC_A(msc_a, LOGL_ERROR, "Cannot inform MNCC of RTP address\n");
- /* FIXME: ERROR HANDLING */
+ trans_free(cc_trans);
return;
}
}
@@ -619,15 +788,26 @@ static void msc_a_fsm_communicating(struct osmo_fsm_inst *fi, uint32_t event, vo
LOG_MSC_A(msc_a, LOGL_ERROR, "Invalid data for %s\n", osmo_fsm_event_name(fi->fsm, event));
return;
}
+ if (!msc_a->cc.call_leg) {
+ LOG_MSC_A(msc_a, LOGL_ERROR, "No call leg active\n");
+ return;
+ }
+ if (!osmo_sockaddr_str_is_nonzero(&rtps->local)) {
+ LOG_MSC_A(msc_a, LOGL_ERROR, "Invalid RTP address received from MGW: " OSMO_SOCKADDR_STR_FMT "\n",
+ OSMO_SOCKADDR_STR_FMT_ARGS(&rtps->local));
+ call_leg_release(msc_a->cc.call_leg);
+ return;
+ }
LOG_MSC_A(msc_a, LOGL_DEBUG,
- "MGW endpoint's RTP address available for the CI %s: " OSMO_SOCKADDR_STR_FMT "\n",
- rtp_direction_name(rtps->dir), OSMO_SOCKADDR_STR_FMT_ARGS(&rtps->local));
+ "MGW endpoint's RTP address available for the CI %s: " OSMO_SOCKADDR_STR_FMT " (osmux=%s:%d)\n",
+ rtp_direction_name(rtps->dir), OSMO_SOCKADDR_STR_FMT_ARGS(&rtps->local),
+ rtps->use_osmux ? "yes" : "no", rtps->local_osmux_cid);
switch (rtps->dir) {
case RTP_TO_RAN:
- msc_a_call_leg_ran_local_addr_available(msc_a);
+ msc_a_tx_assignment_cmd(msc_a);
return;
case RTP_TO_CN:
- msc_a_call_leg_cn_local_addr_available(msc_a, rtps->for_trans);
+ cc_on_cn_local_rtp_port_known(rtps->for_trans);
return;
default:
LOG_MSC_A(msc_a, LOGL_ERROR, "Invalid data for %s\n", osmo_fsm_event_name(fi->fsm, event));
@@ -706,6 +886,8 @@ static void msc_a_fsm_releasing_onenter(struct osmo_fsm_inst *fi, uint32_t prev_
MSC_A_USE_CM_SERVICE_CC,
MSC_A_USE_CM_SERVICE_SMS,
MSC_A_USE_CM_SERVICE_SS,
+ MSC_A_USE_CM_SERVICE_GCC,
+ MSC_A_USE_CM_SERVICE_BCC,
MSC_A_USE_PAGING_RESPONSE,
};
@@ -746,11 +928,19 @@ static void msc_a_fsm_releasing_onenter(struct osmo_fsm_inst *fi, uint32_t prev_
struct ran_msg msg = {
.msg_type = RAN_MSG_CLEAR_COMMAND,
.clear_command = {
+ /* "Call Control" is the only cause code listed in 3GPP TS 48.008 3.2.1.21 CLEAR COMMAND
+ * that qualifies for a normal release situation. (OS#4664) */
+ .gsm0808_cause = GSM0808_CAUSE_CALL_CONTROL,
.csfb_ind = (vsub && vsub->sgs_fsm->state == SGS_UE_ST_ASSOCIATED),
},
};
msc_a_get(msc_a, MSC_A_USE_WAIT_CLEAR_COMPLETE);
msc_a_ran_down(msc_a, MSC_ROLE_I, &msg);
+
+ /* The connection is cleared. The MS will now go back to 4G,
+ Switch the RAN type back to SGS. */
+ if (vsub && vsub->sgs_fsm->state == SGS_UE_ST_ASSOCIATED)
+ vsub->cs.attached_via_ran = OSMO_RAT_EUTRAN_SGS;
}
if (vsub)
@@ -806,19 +996,10 @@ static void msc_a_fsm_released(struct osmo_fsm_inst *fi, uint32_t event, void *d
osmo_fsm_inst_term(fi, OSMO_FSM_TERM_REGULAR, fi);
}
-void msc_a_fsm_allstate_action(struct osmo_fsm_inst *fi, uint32_t event, void *data)
-{
- //struct msc_a *a = msc_a_fi_priv(fi);
- switch (event) {
-
- default:
- return;
- }
-}
-
void msc_a_fsm_cleanup(struct osmo_fsm_inst *fi, enum osmo_fsm_term_cause cause)
{
struct msc_a *msc_a = msc_a_fi_priv(fi);
+ struct vlr_subscr *vsub = msc_a_vsub(msc_a);
trans_conn_closed(msc_a);
@@ -826,6 +1007,10 @@ void msc_a_fsm_cleanup(struct osmo_fsm_inst *fi, enum osmo_fsm_term_cause cause)
LOG_MSC_A(msc_a, LOGL_ERROR, "Deallocating active transactions failed\n");
LOG_MSC_A_CAT(msc_a, DREF, LOGL_DEBUG, "max total use count was %d\n", msc_a->max_total_use_count);
+
+ /* Invalidate the active conn in VLR subscriber state, if any. */
+ if (vsub && vsub->msc_conn_ref == msc_a)
+ vsub->msc_conn_ref = NULL;
}
const struct value_string msc_a_fsm_event_names[] = {
@@ -965,6 +1150,7 @@ static const struct osmo_fsm_state msc_a_fsm_states[] = {
| S(MSC_EV_CALL_LEG_TERM)
| S(MSC_MNCC_EV_CALL_ENDED)
| S(MSC_A_EV_HANDOVER_END)
+ | S(MSC_A_EV_CN_CLOSE)
,
.out_state_mask = 0
| S(MSC_A_ST_RELEASED)
@@ -988,9 +1174,6 @@ static struct osmo_fsm msc_a_fsm = {
.num_states = ARRAY_SIZE(msc_a_fsm_states),
.log_subsys = DMSC,
.event_names = msc_a_fsm_event_names,
- .allstate_action = msc_a_fsm_allstate_action,
- .allstate_event_mask = 0
- ,
.timer_cb = msc_a_fsm_timer_cb,
.cleanup = msc_a_fsm_cleanup,
};
@@ -1041,7 +1224,7 @@ struct msc_a *msc_a_alloc(struct msub *msub, struct ran_infra *ran)
};
osmo_use_count_make_static_entries(&msc_a->use_count, msc_a->use_count_buf, ARRAY_SIZE(msc_a->use_count_buf));
/* Start timeout for first state */
- msc_a_state_chg(msc_a, MSC_A_ST_VALIDATE_L3);
+ msc_a_state_chg_always(msc_a, MSC_A_ST_VALIDATE_L3);
return msc_a;
}
@@ -1057,6 +1240,7 @@ const struct value_string complete_layer3_type_names[] = {
{ COMPLETE_LAYER3_LU, "LU" },
{ COMPLETE_LAYER3_CM_SERVICE_REQ, "CM_SERVICE_REQ" },
{ COMPLETE_LAYER3_PAGING_RESP, "PAGING_RESP" },
+ { COMPLETE_LAYER3_CM_RE_ESTABLISH_REQ, "CM_RE_ESTABLISH_REQ" },
{ 0, NULL }
};
@@ -1083,9 +1267,9 @@ const struct value_string complete_layer3_type_names[] = {
/* Compose an ID almost like gsm48_mi_to_string(), but print the MI type along, and print a TMSI as hex. */
-void msc_a_update_id_from_mi(struct msc_a *msc_a, const uint8_t mi[], uint8_t mi_len)
+void msc_a_update_id_from_mi(struct msc_a *msc_a, const struct osmo_mobile_identity *mi)
{
- _msc_a_update_id(msc_a, "%s", osmo_mi_name(mi, mi_len));
+ _msc_a_update_id(msc_a, "%s", osmo_mobile_identity_to_str_c(OTC_SELECT, mi));
}
/* Update msc_a->fi id string from current msc_a->vsub and msc_a->complete_layer3_type. */
@@ -1209,6 +1393,10 @@ int msc_a_up_l3(struct msc_a *msc_a, struct msgb *msg)
#endif
switch (pdisc) {
+ case GSM48_PDISC_GROUP_CC:
+ case GSM48_PDISC_BCAST_CC:
+ rc = gsm44068_rcv_bcc_gcc(msc_a, NULL, msg);
+ break;
case GSM48_PDISC_CC:
rc = gsm0408_rcv_cc(msc_a, msg);
break;
@@ -1245,32 +1433,109 @@ int msc_a_up_l3(struct msc_a *msc_a, struct msgb *msg)
static void msc_a_up_call_assignment_complete(struct msc_a *msc_a, const struct ran_msg *ac)
{
- struct gsm_trans *cc_trans = msc_a->cc.active_trans;
+ struct gsm_trans *cc_trans = msc_a->cc.active_trans, *gcc_trans;
struct rtp_stream *rtps_to_ran = msc_a->cc.call_leg ? msc_a->cc.call_leg->rtp[RTP_TO_RAN] : NULL;
+ const struct gsm0808_speech_codec *codec_if_known = ac->assignment_complete.codec_present ?
+ &ac->assignment_complete.codec : NULL;
+
+ /* For a voice group call, handling is performed by VGCS FSM */
+ gcc_trans = trans_find_by_type(msc_a, TRANS_GCC);
+ if (gcc_trans) {
+ vgcs_vbs_caller_assign_cpl(gcc_trans);
+ return;
+ }
+ gcc_trans = trans_find_by_type(msc_a, TRANS_BCC);
+ if (gcc_trans) {
+ vgcs_vbs_caller_assign_cpl(gcc_trans);
+ return;
+ }
if (!rtps_to_ran) {
LOG_MSC_A(msc_a, LOGL_ERROR, "Rx Assignment Complete, but no RTP stream is set up\n");
return;
}
if (!cc_trans) {
- LOG_MSC_A(msc_a, LOGL_ERROR, "Rx Assignment Complete, but CC transaction is active\n");
+ LOG_MSC_A(msc_a, LOGL_ERROR, "Rx Assignment Complete, but no CC transaction is active\n");
return;
}
- /* Update RAN-side endpoint CI: */
- rtp_stream_set_codec(rtps_to_ran, ac->assignment_complete.codec);
+ if (rtps_to_ran->use_osmux != ac->assignment_complete.osmux_present) {
+ LOG_MSC_A_CAT(msc_a, DCC, LOGL_ERROR, "Osmux usage ass request and complete don't match: %d vs %d\n",
+ rtps_to_ran->use_osmux, ac->assignment_complete.osmux_present);
+ call_leg_release(msc_a->cc.call_leg);
+ return;
+ }
+
+ if (codec_if_known) {
+ const struct codec_mapping *codec_assigned;
+
+ /* Check for unexpected codec with CSD */
+ switch (cc_trans->bearer_cap.transfer) {
+ case GSM48_BCAP_ITCAP_FAX_G3:
+ case GSM48_BCAP_ITCAP_3k1_AUDIO:
+ case GSM48_BCAP_ITCAP_UNR_DIG_INF:
+ if (codec_if_known->type == GSM0808_SCT_CSD)
+ break; /* we're good */
+ LOG_TRANS(cc_trans, LOGL_ERROR, "Unexpected codec in Assignment Complete for CSD: %s\n",
+ gsm0808_speech_codec_type_name(codec_if_known->type));
+ call_leg_release(msc_a->cc.call_leg);
+ return;
+ default:
+ break;
+ }
+
+ /* For 2G:
+ * - The Assignment Complete has returned a specific codec (e.g. FR3 for AMR FR).
+ * - Set this codec at the MGW endpoint facing the RAN.
+ * - Also set this codec at the MGW endpoint facing the CN -- we require an exact match on both call
+ * legs.
+ * - TODO: be aware of transcoding that the MGW is capable of, e.g. AMR octet-aligned to AMR
+ * bandwidth-efficient...
+ *
+ * For 3G:
+ * - ran_infra->force_mgw_codecs_to_ran sets VND.3GPP.IUFP as single codec at the MGW towards RAN.
+ * - ran_msg_iu.c always returns FR3 (AMR FR) for the assigned codec. Set that at the MGW towards CN.
+ * - So the MGW decapsulates IuUP <-> AMR
+ */
+ codec_assigned = codec_mapping_by_gsm0808_speech_codec_type(codec_if_known->type);
+ /* TODO: use codec_mapping_by_gsm0808_speech_codec() to also match on codec_if_known->cfg */
+ if (!codec_assigned) {
+ LOG_TRANS(cc_trans, LOGL_ERROR, "Unknown codec in Assignment Complete: %s\n",
+ gsm0808_speech_codec_type_name(codec_if_known->type));
+ call_leg_release(msc_a->cc.call_leg);
+ return;
+ }
+
+ /* Update RAN-side endpoint CI from Assignment result -- unless it is forced by the ran_infra, in which
+ * case it remains unchanged as passed to the earlier call of call_leg_ensure_ci(). */
+ if (msc_a->c.ran->force_mgw_codecs_to_ran.count == 0)
+ rtp_stream_set_one_codec(rtps_to_ran, &codec_assigned->sdp);
+
+ /* Update codec filter with Assignment result, for the CN side */
+ cc_trans->cc.codecs.assignment = codec_assigned->sdp;
+ } else {
+ /* No codec passed in Assignment Complete, set 'codecs.assignment' to none. */
+ cc_trans->cc.codecs.assignment = (struct sdp_audio_codec){};
+ LOG_TRANS(cc_trans, LOGL_INFO, "Assignment Complete without voice codec\n");
+ }
+
rtp_stream_set_remote_addr(rtps_to_ran, &ac->assignment_complete.remote_rtp);
+ if (rtps_to_ran->use_osmux)
+ rtp_stream_set_remote_osmux_cid(rtps_to_ran,
+ ac->assignment_complete.osmux_cid);
rtp_stream_commit(rtps_to_ran);
- /* Setup CN side endpoint CI:
- * Now that
- * - the first CI has been created and a definitive endpoint name is assigned to the call_leg's MGW
- * endpoint,
- * - the Assignment has chosen a speech codec
- * go on to create the CN side RTP stream's CI. */
- if (call_leg_ensure_ci(msc_a->cc.call_leg, RTP_TO_CN, cc_trans->callref, cc_trans,
- &ac->assignment_complete.codec, NULL)) {
- LOG_MSC_A_CAT(msc_a, DCC, LOGL_ERROR, "Error creating MGW CI towards CN\n");
+ /* Remember the Codec List (BSS Supported) */
+ if (ac->assignment_complete.codec_list_bss_supported)
+ codec_filter_set_bss(&cc_trans->cc.codecs, ac->assignment_complete.codec_list_bss_supported);
+
+ trans_cc_filter_run(cc_trans);
+ LOG_TRANS(cc_trans, LOGL_INFO, "Assignment Complete: RAN: %s, CN: %s\n",
+ sdp_audio_codecs_to_str(&rtps_to_ran->codecs),
+ sdp_audio_codecs_to_str(&cc_trans->cc.local.audio_codecs));
+
+ if (cc_on_assignment_done(cc_trans)) {
+ /* If an error occurred, it was logged in cc_assignment_done() */
call_leg_release(msc_a->cc.call_leg);
return;
}
@@ -1287,6 +1552,18 @@ static void msc_a_up_call_assignment_failure(struct msc_a *msc_a, const struct r
return;
}
+ /* For a voice group call, release is performed by VGCS FSM */
+ trans = trans_find_by_type(msc_a, TRANS_GCC);
+ if (trans) {
+ vgcs_vbs_caller_assign_fail(trans);
+ return;
+ }
+ trans = trans_find_by_type(msc_a, TRANS_BCC);
+ if (trans) {
+ vgcs_vbs_caller_assign_fail(trans);
+ return;
+ }
+
/* Otherwise, a silent call might be active */
trans = trans_find_by_type(msc_a, TRANS_SILENT_CALL);
if (trans) {
@@ -1311,7 +1588,7 @@ static void msc_a_up_classmark_update(struct msc_a *msc_a, const struct osmo_gsm
dst = &vsub->classmark;
}
- LOG_MSC_A(msc_a, LOGL_DEBUG, "A5 capabilities recived from Classmark Update: %s\n",
+ LOG_MSC_A(msc_a, LOGL_DEBUG, "A5 capabilities received from Classmark Update: %s\n",
osmo_gsm48_classmark_a5_name(classmark));
osmo_gsm48_classmark_update(dst, classmark);
@@ -1339,16 +1616,33 @@ static int msc_a_up_ho(struct msc_a *msc_a, const struct msc_a_ran_dec_data *d,
int msc_a_ran_dec_from_msc_i(struct msc_a *msc_a, struct msc_a_ran_dec_data *d)
{
struct vlr_subscr *vsub = msc_a_vsub(msc_a);
+ struct gsm_network *net = msc_a_net(msc_a);
const struct ran_msg *msg = d->ran_dec;
int rc = -99;
switch (msg->msg_type) {
case RAN_MSG_COMPL_L3:
+ /* In case the cell_id from Complete Layer 3 Information lacks a PLMN, write the configured PLMN code
+ * into msc_a->via_cell. Then overwrite with those bits obtained from Complete Layer 3 Information. */
msc_a->via_cell = (struct osmo_cell_global_id){
.lai.plmn = msc_a_net(msc_a)->plmn,
};
gsm0808_cell_id_to_cgi(&msc_a->via_cell, msg->compl_l3.cell_id);
+
+ /* If a codec list was sent along in the RAN_MSG_COMPL_L3, remember it for any upcoming codec
+ * resolution. */
+ if (msg->compl_l3.codec_list_bss_supported) {
+ msc_a->cc.compl_l3_codec_list_bss_supported = *msg->compl_l3.codec_list_bss_supported;
+ if (log_check_level(msc_a->c.ran->log_subsys, LOGL_DEBUG)) {
+ struct sdp_audio_codecs ac = {};
+ sdp_audio_codecs_from_speech_codec_list(&ac, &msc_a->cc.compl_l3_codec_list_bss_supported);
+ LOG_MSC_A(msc_a, LOGL_DEBUG, "Complete Layer 3: Codec List (BSS Supported): %s\n",
+ sdp_audio_codecs_to_str(&ac));
+ }
+ }
+
+ /* Submit the Complete Layer 3 Information DTAP */
rc = msc_a_up_l3(msc_a, msg->compl_l3.msg);
if (!rc) {
struct ran_conn *conn = msub_ran_conn(msc_a->c.msub);
@@ -1392,9 +1686,39 @@ int msc_a_ran_dec_from_msc_i(struct msc_a *msc_a, struct msc_a_ran_dec_data *d)
msc_a->geran_encr.alg_id = msg->cipher_mode_complete.alg_id;
LOG_MSC_A(msc_a, LOGL_DEBUG, "Cipher Mode Complete: chosen encryption algorithm: A5/%u\n",
msc_a->geran_encr.alg_id - 1);
- };
+ }
+
+ if (msc_a->c.ran->type == OSMO_RAT_UTRAN_IU) {
+ int16_t utran_encryption;
+
+ /* utran: ensure chosen ciphering mode is allowed
+ * If the IE is missing (utran_encryption == -1), parse it as no encryption */
+ utran_encryption = msg->cipher_mode_complete.utran_encryption;
+ if (utran_encryption == -1)
+ utran_encryption = 0;
+ if ((net->uea_encryption_mask & (1 << utran_encryption)) == 0) {
+ /* cipher disallowed */
+ LOG_MSC_A(msc_a, LOGL_ERROR, "Cipher Mode Complete: RNC chosen forbidden ciphering UEA%d\n",
+ msg->cipher_mode_complete.utran_encryption);
+ vlr_subscr_rx_ciph_res(vsub, VLR_CIPH_REJECT);
+ rc = 0;
+ break;
+ }
+ }
vlr_subscr_rx_ciph_res(vsub, VLR_CIPH_COMPL);
rc = 0;
+
+ /* Evaluate enclosed L3 message, typically Identity Response (IMEISV) */
+ if (msg->cipher_mode_complete.l3_msg) {
+ unsigned char *data = (unsigned char*)(msg->cipher_mode_complete.l3_msg->val);
+ uint16_t len = msg->cipher_mode_complete.l3_msg->len;
+ struct msgb *dtap = msgb_alloc(len, "DTAP from Cipher Mode Complete");
+ unsigned char *pos = msgb_put(dtap, len);
+ memcpy(pos, data, len);
+ dtap->l3h = pos;
+ rc = msc_a_up_l3(msc_a, dtap);
+ msgb_free(dtap);
+ }
break;
case RAN_MSG_CIPHER_MODE_REJECT:
@@ -1431,6 +1755,13 @@ int msc_a_ran_dec_from_msc_i(struct msc_a *msc_a, struct msc_a_ran_dec_data *d)
rc = msc_a_up_ho(msc_a, d, MSC_HO_EV_RX_FAILURE);
break;
+ case RAN_MSG_LCLS_STATUS:
+ /* The BSS sends us LCLS_STATUS. We do nothing for now, but it is not an error. */
+ LOG_MSC_A(msc_a, LOGL_DEBUG, "LCLS_STATUS (%s) received from MSC-I\n",
+ gsm0808_lcls_status_name(msg->lcls_status.status));
+ rc = 0;
+ break;
+
default:
LOG_MSC_A(msc_a, LOGL_ERROR, "Message from MSC-I not implemented: %s\n", ran_msg_type_name(msg->msg_type));
rc = -ENOTSUP;
@@ -1439,6 +1770,136 @@ int msc_a_ran_dec_from_msc_i(struct msc_a *msc_a, struct msc_a_ran_dec_data *d)
return rc;
}
+static int msc_a_rx_vgcs_bss_decoded(struct osmo_fsm_inst *caller_fi, void *caller_data, const struct ran_msg *msg)
+{
+ struct vgcs_bss *bss = caller_data;
+ struct msc_a *msc_a = (bss->trans) ? bss->trans->msc_a : NULL;
+ int rc = 0;
+
+ switch (msg->msg_type) {
+ case RAN_MSG_VGCS_VBS_SETUP_ACK:
+ /* The BSS accepts VGCS/VBS and sends us supported features. */
+ vgcs_vbs_setup_ack(bss, msg);
+ break;
+ case RAN_MSG_VGCS_VBS_SETUP_REFUSE:
+ /* The BSS refuses VGCS/VBS. */
+ vgcs_vbs_setup_refuse(bss, msg);
+ break;
+ case RAN_MSG_UPLINK_REQUEST:
+ /* A mobile station requests the uplink on a VGCS channel. */
+ vgcs_uplink_request(bss, msg);
+ break;
+ case RAN_MSG_UPLINK_REQUEST_CNF:
+ /* The uplink on a VGCS channel has been established. */
+ vgcs_uplink_request_cnf(bss, msg);
+ break;
+ case RAN_MSG_UPLINK_APPLICATION_DATA:
+ /* Application data received on the uplink of a VGCS channel. */
+ vgcs_app_data(bss, msg);
+ break;
+ case RAN_MSG_DTAP:
+ /* BSS confirms the release of the channel. */
+ vgcs_bss_dtap(bss, msg);
+ break;
+ case RAN_MSG_UPLINK_RELEASE_IND:
+ /* A mobile station releases the uplink on a VGCS channel. */
+ vgcs_uplink_release_ind(bss, msg);
+ break;
+ case RAN_MSG_CLEAR_REQUEST:
+ /* BSS indicated that the channel has been released. */
+ vgcs_vbs_clear_req(bss, msg);
+ break;
+ case RAN_MSG_CLEAR_COMPLETE:
+ /* BSS confirms the release of the channel. */
+ vgcs_vbs_clear_cpl(bss, msg);
+ break;
+ default:
+ LOG_MSC_A(msc_a, LOGL_ERROR, "VGCS message from BSS not implemented: %s\n",
+ ran_msg_type_name(msg->msg_type));
+ rc = -ENOTSUP;
+ break;
+ }
+ return rc;
+}
+
+int msc_a_rx_vgcs_bss(struct vgcs_bss *bss, struct ran_conn *from_conn, struct msgb *msg)
+{
+ struct ran_dec ran_dec;
+
+ /* Feed through the decoding mechanism ran_msg. The decoded message arrives in msc_a_rx_vgcs_decoded() */
+ ran_dec = (struct ran_dec) {
+ .caller_data = bss,
+ .decode_cb = msc_a_rx_vgcs_bss_decoded,
+ };
+ struct ran_peer *ran_peer = from_conn->ran_peer;
+ struct ran_infra *ran = ran_peer->sri->ran;
+ if (!ran->ran_dec_l2) {
+ LOGP(DMSC, LOGL_ERROR, "No ran_dec_l2() defined for RAN type %s\n",
+ osmo_rat_type_name(ran->type));
+ return -ENOTSUP;
+ }
+ return ran->ran_dec_l2(&ran_dec, msg);
+}
+
+static int msc_a_rx_vgcs_cell_decoded(struct osmo_fsm_inst *caller_fi, void *caller_data, const struct ran_msg *msg)
+{
+ struct vgcs_bss_cell *cell = caller_data;
+ struct msc_a *msc_a = (cell->bss && cell->bss->trans) ? cell->bss->trans->msc_a : NULL;
+ int rc = 0;
+
+ switch (msg->msg_type) {
+ case RAN_MSG_VGCS_VBS_ASSIGN_RES:
+ /* The BSS accepts VGCS/VBS channel assignment. */
+ vgcs_vbs_assign_result(cell, msg);
+ break;
+ case RAN_MSG_VGCS_VBS_ASSIGN_FAIL:
+ /* The BSS refuses VGCS/VBS channel assignment. */
+ vgcs_vbs_assign_fail(cell, msg);
+ break;
+ case RAN_MSG_VGCS_VBS_QUEUING_IND:
+ /* The BSS needs more time for VGCS/VBS channel assignment. */
+ vgcs_vbs_queuing_ind(cell);
+ break;
+ case RAN_MSG_VGCS_VBS_ASSIGN_STATUS:
+ /* The BSS gives cell status about VGCS/VBS channel. */
+ vgcs_vbs_assign_status(cell, msg);
+ break;
+ case RAN_MSG_CLEAR_REQUEST:
+ /* BSS indicated that the channel has been released. */
+ vgcs_vbs_clear_req_channel(cell, msg);
+ break;
+ case RAN_MSG_CLEAR_COMPLETE:
+ /* BSS confirms the release of the channel. */
+ vgcs_vbs_clear_cpl_channel(cell, msg);
+ break;
+ default:
+ LOG_MSC_A(msc_a, LOGL_ERROR, "Message from BSS leg not implemented: %s\n",
+ ran_msg_type_name(msg->msg_type));
+ rc = -ENOTSUP;
+ break;
+ }
+ return rc;
+}
+
+int msc_a_rx_vgcs_cell(struct vgcs_bss_cell *cell, struct ran_conn *from_conn, struct msgb *msg)
+{
+ struct ran_dec ran_dec;
+
+ /* Feed through the decoding mechanism ran_msg. The decoded message arrives in msc_a_rx_vgcs_decoded() */
+ ran_dec = (struct ran_dec) {
+ .caller_data = cell,
+ .decode_cb = msc_a_rx_vgcs_cell_decoded,
+ };
+ struct ran_peer *ran_peer = from_conn->ran_peer;
+ struct ran_infra *ran = ran_peer->sri->ran;
+ if (!ran->ran_dec_l2) {
+ LOGP(DMSC, LOGL_ERROR, "No ran_dec_l2() defined for RAN type %s\n",
+ osmo_rat_type_name(ran->type));
+ return -ENOTSUP;
+ }
+ return ran->ran_dec_l2(&ran_dec, msg);
+}
+
static int msc_a_ran_dec_from_msc_t(struct msc_a *msc_a, struct msc_a_ran_dec_data *d)
{
struct msc_t *msc_t = msc_a_msc_t(msc_a);
@@ -1544,23 +2005,32 @@ int _msc_a_msg_down(struct msc_a *msc_a, enum msc_role to_role, uint32_t to_role
.an_proto = msc_a->c.ran->an_proto,
.msg = msc_role_ran_encode(msc_a->c.fi, ran_msg),
};
- int rc;
if (!an_apdu.msg)
return -EIO;
- rc = _msub_role_dispatch(msc_a->c.msub, to_role, to_role_event, &an_apdu, file, line);
- msgb_free(an_apdu.msg);
- return rc;
+ return _msub_role_dispatch(msc_a->c.msub, to_role, to_role_event, &an_apdu, file, line);
}
int msc_a_tx_dtap_to_i(struct msc_a *msc_a, struct msgb *dtap)
{
struct ran_msg ran_msg;
+ struct gsm48_hdr *gh = msgb_l3(dtap) ? : dtap->data;
+ uint8_t pdisc = gsm48_hdr_pdisc(gh);
+
+ if (!msc_a) {
+ LOGP(DMSC, LOGL_ERROR, "Attempt to send DTAP to NULL MSC-A, dropping message: %s %s\n",
+ gsm48_pdisc_name(pdisc), gsm48_pdisc_msgtype_name(pdisc, gsm48_hdr_msg_type(gh)));
+ msgb_free(dtap);
+ return -EIO;
+ }
if (msc_a->c.ran->type == OSMO_RAT_EUTRAN_SGS) {
/* The SGs connection to the MME always is at the MSC-A. */
return sgs_iface_tx_dtap_ud(msc_a, dtap);
}
+ LOG_MSC_A(msc_a, LOGL_DEBUG, "Sending DTAP: %s %s\n",
+ gsm48_pdisc_name(pdisc), gsm48_pdisc_msgtype_name(pdisc, gsm48_hdr_msg_type(gh)));
+
ran_msg = (struct ran_msg){
.msg_type = RAN_MSG_DTAP,
.dtap = dtap,
@@ -1579,45 +2049,68 @@ struct msc_a *msc_a_for_vsub(const struct vlr_subscr *vsub, bool valid_conn_only
int msc_tx_common_id(struct msc_a *msc_a, enum msc_role to_role)
{
struct vlr_subscr *vsub = msc_a_vsub(msc_a);
+ if (vsub == NULL)
+ return -ENODEV;
struct ran_msg msg = {
.msg_type = RAN_MSG_COMMON_ID,
.common_id = {
.imsi = vsub->imsi,
+ .last_eutran_plmn_present = vsub->sgs.last_eutran_plmn_present,
},
};
+ if (vsub->sgs.last_eutran_plmn_present) {
+ memcpy(&msg.common_id.last_eutran_plmn, &vsub->sgs.last_eutran_plmn,
+ sizeof(vsub->sgs.last_eutran_plmn));
+ }
return msc_a_ran_down(msc_a, to_role, &msg);
}
static int msc_a_start_assignment(struct msc_a *msc_a, struct gsm_trans *cc_trans)
{
- struct call_leg *cl = msc_a->cc.call_leg;
+ struct call_leg *cl;
+ bool cn_rtp_available;
+ bool ran_rtp_available;
OSMO_ASSERT(!msc_a->cc.active_trans);
msc_a->cc.active_trans = cc_trans;
- OSMO_ASSERT(cc_trans && cc_trans->type == TRANS_CC);
+ cc_trans->cc.codecs.assignment = (struct sdp_audio_codec){};
- if (!cl) {
- cl = msc_a->cc.call_leg = call_leg_alloc(msc_a->c.fi,
- MSC_EV_CALL_LEG_TERM,
- MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE,
- MSC_EV_CALL_LEG_RTP_COMPLETE);
- OSMO_ASSERT(cl);
+ OSMO_ASSERT(cc_trans && cc_trans->type == TRANS_CC);
+ cl = msc_a_ensure_call_leg(msc_a, cc_trans);
+ if (!cl)
+ return -EINVAL;
- /* HACK: We put the connection in loopback mode at the beginnig to
- * trick the hNodeB into doing the IuUP negotiation with itself.
- * This is a hack we need because osmo-mgw does not support IuUP yet, see OS#2459. */
- if (msc_a->c.ran->type == OSMO_RAT_UTRAN_IU)
- cl->crcx_conn_mode[RTP_TO_RAN] = MGCP_CONN_LOOPBACK;
+ /* See if we can set a preliminary codec. If not, pass none for the time being. */
+ trans_cc_filter_run(cc_trans);
+
+ cn_rtp_available = call_leg_local_ip(cl, RTP_TO_CN);
+ ran_rtp_available = call_leg_local_ip(cl, RTP_TO_RAN);
+
+ /* Set up RTP ports for both RAN and CN side. Even though we ask for both at the same time, the
+ * osmo_mgcpc_ep_fsm automagically waits for the first CRCX to complete before firing the second CRCX. The one
+ * issued first here will also be the first CRCX sent to the MGW. Usually both still need to be set up. */
+ if (!cn_rtp_available)
+ call_leg_ensure_ci(cl, RTP_TO_CN, cc_trans->call_id, cc_trans,
+ &cc_trans->cc.local.audio_codecs, NULL);
+ if (!ran_rtp_available) {
+ struct sdp_audio_codecs *codecs;
+ if (msc_a->c.ran->force_mgw_codecs_to_ran.count)
+ codecs = &msc_a->c.ran->force_mgw_codecs_to_ran;
+ else
+ codecs = &cc_trans->cc.local.audio_codecs;
+ return call_leg_ensure_ci(cl, RTP_TO_RAN, cc_trans->call_id, cc_trans, codecs, NULL);
}
- /* This will lead to either MSC_EV_CALL_LEG_LOCAL_ADDR_AVAILABLE or MSC_EV_CALL_LEG_TERM.
- * If the local address is already known, then immediately trigger. */
- if (call_leg_local_ip(cl, RTP_TO_RAN))
+ /* Should these already be set up, immediately continue by retriggering the events signalling that the RTP
+ * ports are available. The ordering is: first CN, then RAN. */
+ if (cn_rtp_available && ran_rtp_available)
return osmo_fsm_inst_dispatch(msc_a->c.fi, MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE, cl->rtp[RTP_TO_RAN]);
- else
- return call_leg_ensure_ci(msc_a->cc.call_leg, RTP_TO_RAN, cc_trans->callref, cc_trans, NULL, NULL);
+ else if (cn_rtp_available)
+ return osmo_fsm_inst_dispatch(msc_a->c.fi, MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE, cl->rtp[RTP_TO_CN]);
+ /* Otherwise wait for MGCP response and continue from there. */
+ return 0;
}
int msc_a_try_call_assignment(struct gsm_trans *cc_trans)
@@ -1626,7 +2119,7 @@ int msc_a_try_call_assignment(struct gsm_trans *cc_trans)
OSMO_ASSERT(cc_trans->type == TRANS_CC);
if (msc_a->cc.active_trans == cc_trans) {
- /* Assignment for this trans already started earlier. */
+ LOG_MSC_A(msc_a, LOGL_DEBUG, "Assignment for this trans already started earlier\n");
return 0;
}
@@ -1639,8 +2132,14 @@ int msc_a_try_call_assignment(struct gsm_trans *cc_trans)
return msc_a_start_assignment(msc_a, cc_trans);
}
-const char *msc_a_cm_service_type_to_use(enum osmo_cm_service_type cm_service_type)
+/* Map CM Service type to use token.
+ * Given a CM Service type, return a matching token intended for osmo_use_count.
+ * For unknown service type, return NULL.
+ */
+const char *msc_a_cm_service_type_to_use(struct msc_a *msc_a, enum osmo_cm_service_type cm_service_type)
{
+ struct gsm_network *net = msc_a_net(msc_a);
+
switch (cm_service_type) {
case GSM48_CMSERV_MO_CALL_PACKET:
case GSM48_CMSERV_EMERGENCY:
@@ -1652,6 +2151,18 @@ const char *msc_a_cm_service_type_to_use(enum osmo_cm_service_type cm_service_ty
case GSM48_CMSERV_SUP_SERV:
return MSC_A_USE_CM_SERVICE_SS;
+ case GSM48_CMSERV_VGCS:
+ if (net->asci.enable)
+ return MSC_A_USE_CM_SERVICE_GCC;
+ else
+ return NULL;
+
+ case GSM48_CMSERV_VBS:
+ if (net->asci.enable)
+ return MSC_A_USE_CM_SERVICE_BCC;
+ else
+ return NULL;
+
default:
return NULL;
}
diff --git a/src/libmsc/msc_a_remote.c b/src/libmsc/msc_a_remote.c
index 84eff0730..3b9693e59 100644
--- a/src/libmsc/msc_a_remote.c
+++ b/src/libmsc/msc_a_remote.c
@@ -1,6 +1,6 @@
/* The MSC-A role implementation variant that forwards requests to/from a remote MSC. */
/*
- * (C) 2019 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de>
+ * (C) 2019 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
* All Rights Reserved
*
* SPDX-License-Identifier: AGPL-3.0+
@@ -179,8 +179,6 @@ static void msc_a_remote_send_handover_failure(struct msc_a *msc_a, enum gsm0808
return;
msc_a_remote_msg_up_to_remote_msc(msc_a, MSC_ROLE_T, OSMO_GSUP_MSGT_E_PREPARE_HANDOVER_ERROR, &an_apdu);
- msgb_free(an_apdu.msg);
- return;
}
/* [MSC-A---------------------] [MSC-B---------------------]
diff --git a/src/libmsc/msc_ho.c b/src/libmsc/msc_ho.c
index 615b8cd70..54a959d2c 100644
--- a/src/libmsc/msc_ho.c
+++ b/src/libmsc/msc_ho.c
@@ -1,25 +1,21 @@
/* MSC Handover implementation */
/*
- * (C) 2019 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de>
+ * (C) 2019 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
* All Rights Reserved
*
* Author: Neels Hofmeyr
*
- * SPDX-License-Identifier: GPL-2.0+
+ * SPDX-License-Identifier: AGPL-3.0+
*
* This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ * GNU Affero General Public License for more details.
*/
#include <osmocom/core/fsm.h>
@@ -43,6 +39,7 @@
#include <osmocom/msc/call_leg.h>
#include <osmocom/msc/rtp_stream.h>
#include <osmocom/msc/mncc_call.h>
+#include <osmocom/msc/codec_mapping.h>
struct osmo_fsm msc_ho_fsm;
@@ -62,14 +59,17 @@ static const struct osmo_tdef_state_timeout msc_ho_fsm_timeouts[32] = {
static __attribute__((constructor)) void msc_ho_fsm_init()
{
- osmo_fsm_register(&msc_ho_fsm);
+ OSMO_ASSERT(osmo_fsm_register(&msc_ho_fsm) == 0);
}
void msc_ho_down_required_reject(struct msc_a *msc_a, enum gsm0808_cause cause)
{
- struct msc_i *msc_i = msc_a_msc_i(msc_a);
+ struct msc_i *msc_i;
uint32_t event;
+ msc_i = msc_a_msc_i(msc_a);
+ OSMO_ASSERT(msc_i);
+
struct ran_msg ran_enc_msg = {
.msg_type = RAN_MSG_HANDOVER_REQUIRED_REJECT,
.handover_required_reject = {
@@ -380,6 +380,8 @@ static void msc_ho_send_handover_request(struct msc_a *msc_a)
struct vlr_subscr *vsub = msc_a_vsub(msc_a);
struct gsm_network *net = msc_a_net(msc_a);
struct gsm0808_channel_type channel_type;
+ struct gsm0808_speech_codec_list scl = {};
+ struct gsm_trans *cc_trans = msc_a->cc.active_trans;
struct ran_msg ran_enc_msg = {
.msg_type = RAN_MSG_HANDOVER_REQUEST,
.handover_request = {
@@ -402,13 +404,57 @@ static void msc_ho_send_handover_request(struct msc_a *msc_a)
},
};
- if (msc_a->cc.active_trans) {
- if (mncc_bearer_cap_to_channel_type(&channel_type, &msc_a->cc.active_trans->bearer_cap)) {
- msc_ho_failed(msc_a, GSM0808_CAUSE_EQUIPMENT_FAILURE,
- "Failed to encode Bearer Cap to Channel Type\n");
+ if (msc_a->geran_encr.key_len)
+ LOG_MSC_A(msc_a, LOGL_DEBUG, "HO Request with ciphering: A5/%d kc %s kc128 %s\n",
+ msc_a->geran_encr.alg_id - 1,
+ osmo_hexdump_nospc_c(OTC_SELECT, msc_a->geran_encr.key, msc_a->geran_encr.key_len),
+ msc_a->geran_encr.kc128_present ?
+ osmo_hexdump_nospc_c(OTC_SELECT, msc_a->geran_encr.kc128, sizeof(msc_a->geran_encr.kc128))
+ : "-");
+
+ if (cc_trans) {
+ switch (cc_trans->bearer_cap.transfer) {
+ case GSM48_BCAP_ITCAP_SPEECH:
+ if (sdp_audio_codecs_to_gsm0808_channel_type(&channel_type,
+ &cc_trans->cc.local.audio_codecs)) {
+ msc_ho_failed(msc_a, GSM0808_CAUSE_EQUIPMENT_FAILURE,
+ "Failed to determine Channel Type for Handover Request message (speech)\n");
+ return;
+ }
+ break;
+ case GSM48_BCAP_ITCAP_3k1_AUDIO:
+ case GSM48_BCAP_ITCAP_FAX_G3:
+ case GSM48_BCAP_ITCAP_UNR_DIG_INF:
+ if (csd_bs_list_to_gsm0808_channel_type(&channel_type, &cc_trans->cc.local.bearer_services)) {
+ msc_ho_failed(msc_a, GSM0808_CAUSE_EQUIPMENT_FAILURE,
+ "Failed to determine Channel Type for Handover Request message (CSD)\n");
+ return;
+ }
+ break;
+ default:
+ msc_ho_failed(msc_a, GSM0808_CAUSE_EQUIPMENT_FAILURE, "Failed to create"
+ " Handover Request message for information transfer capability %d\n",
+ cc_trans->bearer_cap.transfer);
return;
}
+
ran_enc_msg.handover_request.geran.channel_type = &channel_type;
+ ran_enc_msg.handover_request.call_id_present = true;
+ ran_enc_msg.handover_request.call_id = cc_trans->call_id;
+
+ /* Call assignment is now capable of re-assigning to overcome a codec mismatch with the remote call leg.
+ * But for inter-MSC handover, that is not supported yet. So keep here the old limitation of only
+ * offering the assigned codec. */
+ if (sdp_audio_codec_is_set(&cc_trans->cc.codecs.assignment))
+ sdp_audio_codec_to_speech_codec_list(&scl, &cc_trans->cc.codecs.assignment);
+ else
+ sdp_audio_codecs_to_speech_codec_list(&scl, &cc_trans->cc.local.audio_codecs);
+ if (!scl.len) {
+ msc_ho_failed(msc_a, GSM0808_CAUSE_EQUIPMENT_FAILURE, "Failed to compose"
+ " Codec List (MSC Preferred) for Handover Request message\n");
+ return;
+ }
+ ran_enc_msg.handover_request.codec_list_msc_preferred = &scl;
}
gsm0808_cell_id_from_cgi(&ran_enc_msg.handover_request.cell_id_serving, CELL_IDENT_WHOLE_GLOBAL, &vsub->cgi);
@@ -560,7 +606,7 @@ static int msc_ho_start_inter_msc_call_forwarding(struct msc_a *msc_a, struct ms
/* Backup old cell's RTP IP:port and codec data */
msc_a->ho.old_cell.ran_remote_rtp = rtp_to_ran->remote;
- msc_a->ho.old_cell.codec = rtp_to_ran->codec;
+ msc_a->ho.old_cell.codecs = rtp_to_ran->codecs;
/* Blindly taken over from an MNCC trace of existing code: send an all-zero CCCAP: */
outgoing_call_req.fields |= MNCC_F_CCCAP;
@@ -661,7 +707,7 @@ static void msc_ho_rx_request_ack(struct msc_a *msc_a, struct msc_a_ran_dec_data
}
msc_a->ho.new_cell.ran_remote_rtp = hra->ran_dec->handover_request_ack.remote_rtp;
- if (osmo_sockaddr_str_is_set(&msc_a->ho.new_cell.ran_remote_rtp)) {
+ if (osmo_sockaddr_str_is_nonzero(&msc_a->ho.new_cell.ran_remote_rtp)) {
LOG_HO(msc_a, LOGL_DEBUG, "Request Ack contains cell's RTP address " OSMO_SOCKADDR_STR_FMT "\n",
OSMO_SOCKADDR_STR_FMT_ARGS(&msc_a->ho.new_cell.ran_remote_rtp));
}
@@ -670,7 +716,7 @@ static void msc_ho_rx_request_ack(struct msc_a *msc_a, struct msc_a_ran_dec_data
msc_a->ho.new_cell.codec = hra->ran_dec->handover_request_ack.codec;
if (hra->ran_dec->handover_request_ack.codec_present) {
LOG_HO(msc_a, LOGL_DEBUG, "Request Ack contains codec %s\n",
- osmo_mgcpc_codec_name(msc_a->ho.new_cell.codec));
+ gsm0808_speech_codec_type_name(msc_a->ho.new_cell.codec.type));
}
}
@@ -684,7 +730,7 @@ static void msc_ho_rtp_switch_to_new_cell(struct msc_a *msc_a)
return;
}
- if (!osmo_sockaddr_str_is_set(&msc_a->ho.new_cell.ran_remote_rtp)) {
+ if (!osmo_sockaddr_str_is_nonzero(&msc_a->ho.new_cell.ran_remote_rtp)) {
LOG_HO(msc_a, LOGL_DEBUG, "New cell's RTP IP:port not yet known, not switching RTP stream\n");
return;
}
@@ -697,7 +743,7 @@ static void msc_ho_rtp_switch_to_new_cell(struct msc_a *msc_a)
/* Backup old cell's RTP IP:port and codec data */
msc_a->ho.old_cell.ran_remote_rtp = rtp_to_ran->remote;
- msc_a->ho.old_cell.codec = rtp_to_ran->codec;
+ msc_a->ho.old_cell.codecs = rtp_to_ran->codecs;
LOG_HO(msc_a, LOGL_DEBUG, "Switching RTP stream to new cell: from " OSMO_SOCKADDR_STR_FMT " to " OSMO_SOCKADDR_STR_FMT "\n",
OSMO_SOCKADDR_STR_FMT_ARGS(&msc_a->ho.old_cell.ran_remote_rtp),
@@ -716,10 +762,18 @@ static void msc_ho_rtp_switch_to_new_cell(struct msc_a *msc_a)
/* Switch over to the new peer */
rtp_stream_set_remote_addr(rtp_to_ran, &msc_a->ho.new_cell.ran_remote_rtp);
- if (msc_a->ho.new_cell.codec_present)
- rtp_stream_set_codec(rtp_to_ran, msc_a->ho.new_cell.codec);
- else
+ if (msc_a->ho.new_cell.codec_present) {
+ const struct codec_mapping *m;
+ m = codec_mapping_by_gsm0808_speech_codec_type(msc_a->ho.new_cell.codec.type);
+ /* TODO: use codec_mapping_by_gsm0808_speech_codec() to also match on codec.cfg */
+ if (!m)
+ LOG_HO(msc_a, LOGL_ERROR, "Cannot resolve codec: %s\n",
+ gsm0808_speech_codec_type_name(msc_a->ho.new_cell.codec.type));
+ else
+ rtp_stream_set_one_codec(rtp_to_ran, &m->sdp);
+ } else {
LOG_HO(msc_a, LOGL_ERROR, "No codec is set\n");
+ }
rtp_stream_commit(rtp_to_ran);
}
@@ -738,7 +792,7 @@ static void msc_ho_rtp_rollback_to_old_cell(struct msc_a *msc_a)
return;
}
- if (!osmo_sockaddr_str_is_set(&msc_a->ho.old_cell.ran_remote_rtp)) {
+ if (!osmo_sockaddr_str_is_nonzero(&msc_a->ho.old_cell.ran_remote_rtp)) {
LOG_HO(msc_a, LOGL_DEBUG, "Have no RTP IP:port for the old cell, not switching back to\n");
return;
}
@@ -758,7 +812,7 @@ static void msc_ho_rtp_rollback_to_old_cell(struct msc_a *msc_a)
/* Switch back to the old cell */
rtp_stream_set_remote_addr(rtp_to_ran, &msc_a->ho.old_cell.ran_remote_rtp);
- rtp_stream_set_codec(rtp_to_ran, msc_a->ho.old_cell.codec);
+ rtp_stream_set_codecs(rtp_to_ran, &msc_a->ho.old_cell.codecs);
rtp_stream_commit(rtp_to_ran);
}
diff --git a/src/libmsc/msc_i.c b/src/libmsc/msc_i.c
index f7aab0db1..d3616f3ae 100644
--- a/src/libmsc/msc_i.c
+++ b/src/libmsc/msc_i.c
@@ -1,6 +1,6 @@
/* Code to manage a subscriber's MSC-I role */
/*
- * (C) 2019 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de>
+ * (C) 2019 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
* All Rights Reserved
*
* SPDX-License-Identifier: AGPL-3.0+
diff --git a/src/libmsc/msc_i_remote.c b/src/libmsc/msc_i_remote.c
index 7b9598423..c5d22a2e3 100644
--- a/src/libmsc/msc_i_remote.c
+++ b/src/libmsc/msc_i_remote.c
@@ -1,6 +1,6 @@
/* The MSC-I role implementation variant that forwards requests to/from a remote MSC. */
/*
- * (C) 2019 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de>
+ * (C) 2019 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
* All Rights Reserved
*
* SPDX-License-Identifier: AGPL-3.0+
diff --git a/src/libmsc/msc_net_init.c b/src/libmsc/msc_net_init.c
index 637ee74ea..1fc712aff 100644
--- a/src/libmsc/msc_net_init.c
+++ b/src/libmsc/msc_net_init.c
@@ -24,6 +24,7 @@
#include "config.h"
#include <osmocom/core/tdef.h>
+#include <osmocom/crypt/utran_cipher.h>
#include <osmocom/msc/gsm_data.h>
#include <osmocom/msc/vlr.h>
@@ -31,10 +32,28 @@
#include <osmocom/msc/gsm_04_11_gsup.h>
#include <osmocom/msc/gsm_09_11.h>
+/* TODO: would be great to have all timer declarations in one place */
+#include <osmocom/msc/ran_infra.h>
+#include <osmocom/msc/sccp_ran.h>
+#include <osmocom/msc/call_leg.h>
+
struct osmo_tdef mncc_tdefs[] = {
{}
};
+struct osmo_tdef_group msc_tdef_group[] = {
+ { .name = "vlr", .tdefs = msc_tdefs_vlr, .desc = "VLR (Visitors Location Register)" },
+ { .name = "mgw", .tdefs = g_mgw_tdefs, .desc = "MGW (Media Gateway) interface" },
+ { .name = "mncc", .tdefs = mncc_tdefs, .desc = "MNCC (Mobile Network Call Control) interface" },
+ { .name = "sccp", .tdefs = g_sccp_tdefs, .desc = "SCCP (Signalling Connection Control Part)" },
+ { .name = "geran", .tdefs = msc_tdefs_geran, .desc = "GERAN (GSM EDGE Radio Access Network)" },
+ { .name = "utran", .tdefs = msc_tdefs_utran, .desc = "UTRAN (UMTS Terrestrial Radio Access Network)" },
+ { .name = "sgs", .tdefs = msc_tdefs_sgs, .desc = "SGs interface towards MME" },
+ { /* terminator */ }
+};
+
+#include <osmocom/core/stat_item.h>
+
struct gsm_network *gsm_network_init(void *ctx, mncc_recv_cb_t mncc_recv)
{
struct gsm_network *net;
@@ -47,18 +66,16 @@ struct gsm_network *gsm_network_init(void *ctx, mncc_recv_cb_t mncc_recv)
/* Permit a compile-time default of A5/3 and A5/1 */
net->a5_encryption_mask = (1 << 3) | (1 << 1);
-
- /* Use 30 min periodic update interval as sane default */
- net->t3212 = 5;
+ /* Permit a compile-time default of UEA2 and UEA1 */
+ net->uea_encryption_mask = (1 << OSMO_UTRAN_UEA2) | (1 << OSMO_UTRAN_UEA1);
net->mncc_guard_timeout = 180;
net->ncss_guard_timeout = 30;
- net->paging_response_timer = MSC_PAGING_RESPONSE_TIMER_DEFAULT;
-
INIT_LLIST_HEAD(&net->trans_list);
INIT_LLIST_HEAD(&net->upqueue);
INIT_LLIST_HEAD(&net->neighbor_ident_list);
+ INIT_LLIST_HEAD(&net->asci.gcr_lists);
/* init statistics */
net->msc_ctrs = rate_ctr_group_alloc(net, &msc_ctrg_desc, 0);
@@ -66,8 +83,13 @@ struct gsm_network *gsm_network_init(void *ctx, mncc_recv_cb_t mncc_recv)
talloc_free(net);
return NULL;
}
- net->active_calls = osmo_counter_alloc("msc.active_calls");
- net->active_nc_ss = osmo_counter_alloc("msc.active_nc_ss");
+
+ net->statg = osmo_stat_item_group_alloc(net, &msc_statg_desc, 0);
+ if (!net->statg) {
+ rate_ctr_group_free(net->msc_ctrs);
+ talloc_free(net);
+ return NULL;
+ }
net->mncc_tdefs = mncc_tdefs;
net->mncc_recv = mncc_recv;
@@ -108,17 +130,23 @@ int msc_gsup_client_start(struct gsm_network *net)
net->gcm = gsup_client_mux_alloc(net);
OSMO_ASSERT(net->gcm);
+ /* If no IPA name is configured, we need to provide a default
+ * right here, in order for the defaulted name to get inserted
+ * as source_name in GSUP response messages. */
+ if (!net->msc_ipa_name)
+ net->msc_ipa_name = "unnamed-MSC";
+
ipa_dev = talloc_zero(net->gcm, struct ipaccess_unit);
ipa_dev->unit_name = "MSC";
- ipa_dev->serno = net->msc_ipa_name; /* NULL unless configured via VTY */
+ ipa_dev->serno = net->msc_ipa_name;
ipa_dev->swversion = PACKAGE_NAME "-" PACKAGE_VERSION;
*net->gcm = (struct gsup_client_mux){
.rx_cb = {
/* vlr.c sets up its own cb and data */
/* MSC-A and MSC-B set up their own cb and data */
- [OSMO_GSUP_MESSAGE_CLASS_SMS] = { .func = gsm411_gsup_rx, .data = net->vlr },
- [OSMO_GSUP_MESSAGE_CLASS_USSD] = { .func = gsm0911_gsup_rx, .data = net->vlr },
+ [OSMO_GSUP_MESSAGE_CLASS_SMS] = { .func = gsm411_gsup_rx, .data = net },
+ [OSMO_GSUP_MESSAGE_CLASS_USSD] = { .func = gsm0911_gsup_rx, .data = net },
},
};
diff --git a/src/libmsc/msc_t.c b/src/libmsc/msc_t.c
index 8eefccc71..eb6c79784 100644
--- a/src/libmsc/msc_t.c
+++ b/src/libmsc/msc_t.c
@@ -1,6 +1,6 @@
/* The MSC-T role, a transitional RAN connection during Handover. */
/*
- * (C) 2019 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de>
+ * (C) 2019 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
* All Rights Reserved
*
* SPDX-License-Identifier: AGPL-3.0+
@@ -38,6 +38,7 @@
#include <osmocom/msc/vlr.h>
#include <osmocom/msc/msc_i.h>
#include <osmocom/msc/gsm_data.h>
+#include <osmocom/msc/codec_mapping.h>
static struct osmo_fsm msc_t_fsm;
@@ -75,7 +76,7 @@ static int msc_t_assign_handover_number(struct msc_t *msc_t)
int rc;
uint64_t started_at;
uint64_t ho_nr;
- char ho_nr_str[VLR_MSISDN_LENGTH+1];
+ char ho_nr_str[GSM23003_MSISDN_MAX_DIGITS+1];
struct gsm_network *net = msc_t_net(msc_t);
bool usable = false;
@@ -145,7 +146,6 @@ static void msc_t_send_handover_failure(struct msc_t *msc_t, enum gsm0808_cause
return;
msub_role_dispatch(msc_t->c.msub, MSC_ROLE_A, MSC_A_EV_FROM_T_PREPARE_HANDOVER_FAILURE, &an_apdu);
- msgb_free(an_apdu.msg);
}
static int msc_t_ho_request_decode_and_store_cb(struct osmo_fsm_inst *msc_t_fi, void *data,
@@ -160,7 +160,7 @@ static int msc_t_ho_request_decode_and_store_cb(struct osmo_fsm_inst *msc_t_fi,
}
msc_t->inter_msc.cell_id_target = ran_dec->handover_request.cell_id_target;
- msc_t->inter_msc.callref = ran_dec->handover_request.call_id;
+ msc_t->inter_msc.call_id = ran_dec->handover_request.call_id;
/* TODO other parameters...?
* Global Call Reference
@@ -238,7 +238,6 @@ static int msc_t_find_ran_peer_from_ho_request(struct msc_t *msc_t)
static int msc_t_send_stored_ho_request__decode_cb(struct osmo_fsm_inst *msc_t_fi, void *data,
const struct ran_msg *ran_dec)
{
- int rc;
struct an_apdu an_apdu;
struct msc_t *msc_t = msc_t_priv(msc_t_fi);
struct osmo_sockaddr_str *rtp_ran_local = data;
@@ -263,9 +262,7 @@ static int msc_t_send_stored_ho_request__decode_cb(struct osmo_fsm_inst *msc_t_f
};
if (!an_apdu.msg)
return -EIO;
- rc = msc_t_down_l2_co(msc_t, &an_apdu, true);
- msgb_free(an_apdu.msg);
- return rc;
+ return msc_t_down_l2_co(msc_t, &an_apdu, true);
}
/* The MGW endpoint is created, we know our AoIP Transport Layer Address and can send the Handover Request to the RAN
@@ -361,8 +358,8 @@ void msc_t_fsm_wait_local_rtp_onenter(struct osmo_fsm_inst *fi, uint32_t prev_st
MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE,
MSC_EV_CALL_LEG_RTP_COMPLETE);
if (!msc_t->inter_msc.call_leg
- || call_leg_ensure_ci(msc_t->inter_msc.call_leg, RTP_TO_RAN, msc_t->inter_msc.callref, NULL, NULL, NULL)
- || call_leg_ensure_ci(msc_t->inter_msc.call_leg, RTP_TO_CN, msc_t->inter_msc.callref, NULL, NULL, NULL)) {
+ || call_leg_ensure_ci(msc_t->inter_msc.call_leg, RTP_TO_RAN, msc_t->inter_msc.call_id, NULL, NULL, NULL)
+ || call_leg_ensure_ci(msc_t->inter_msc.call_leg, RTP_TO_CN, msc_t->inter_msc.call_id, NULL, NULL, NULL)) {
msc_t_error("Failed to set up call leg\n");
return;
}
@@ -417,7 +414,7 @@ static int msc_t_patch_and_send_ho_request_ack(struct msc_t *msc_t, const struct
struct rtp_stream *rtp_cn = msc_t->inter_msc.call_leg? msc_t->inter_msc.call_leg->rtp[RTP_TO_CN] : NULL;
/* Since it's BCD, it needs rounded-up half the char* length of an MSISDN plus a type byte.
* But no need to introduce obscure math to save a few stack bytes, just have more. */
- uint8_t msisdn_enc_buf[VLR_MSISDN_LENGTH + 1];
+ uint8_t msisdn_enc_buf[GSM23003_MSISDN_MAX_DIGITS+1];
/* Copy an_apdu and an_apdu->e_info in "copy-on-write" method, because they are const and we
* need to add the Handover Number to e_info. */
const struct ran_handover_request_ack *r = &ran_dec->handover_request_ack;
@@ -444,7 +441,7 @@ static int msc_t_patch_and_send_ho_request_ack(struct msc_t *msc_t, const struct
/* Also need to fetch the RTP IP:port from AoIP Transport Address IE to tell the MGW about it */
if (rtp_ran) {
- if (osmo_sockaddr_str_is_set(&r->remote_rtp)) {
+ if (osmo_sockaddr_str_is_nonzero(&r->remote_rtp)) {
LOG_MSC_T(msc_t, LOGL_DEBUG, "From Handover Request Ack, got " OSMO_SOCKADDR_STR_FMT "\n",
OSMO_SOCKADDR_STR_FMT_ARGS(&r->remote_rtp));
rtp_stream_set_remote_addr(rtp_ran, &r->remote_rtp);
@@ -452,11 +449,20 @@ static int msc_t_patch_and_send_ho_request_ack(struct msc_t *msc_t, const struct
LOG_MSC_T(msc_t, LOGL_DEBUG, "No RTP IP:port in Handover Request Ack\n");
}
if (r->codec_present) {
- LOG_MSC_T(msc_t, LOGL_DEBUG, "From Handover Request Ack, got %s\n",
- osmo_mgcpc_codec_name(r->codec));
- rtp_stream_set_codec(rtp_ran, r->codec);
- if (rtp_cn)
- rtp_stream_set_codec(rtp_cn, r->codec);
+ const struct codec_mapping *m = codec_mapping_by_gsm0808_speech_codec_type(r->codec.type);
+ /* TODO: use codec_mapping_by_gsm0808_speech_codec() to also match on codec.cfg */
+ if (!m) {
+ LOG_MSC_T(msc_t, LOGL_ERROR, "Cannot resolve codec in Handover Request Ack: %s / %s\n",
+ gsm0808_speech_codec_type_name(r->codec.type),
+ m ? sdp_audio_codec_to_str(&m->sdp) : "(unknown)");
+ } else {
+ LOG_MSC_T(msc_t, LOGL_DEBUG, "From Handover Request Ack, got codec %s / %s\n",
+ gsm0808_speech_codec_type_name(r->codec.type),
+ sdp_audio_codec_to_str(&m->sdp));
+ rtp_stream_set_one_codec(rtp_ran, &m->sdp);
+ if (rtp_cn)
+ rtp_stream_set_one_codec(rtp_cn, &m->sdp);
+ }
} else {
LOG_MSC_T(msc_t, LOGL_DEBUG, "No codec in Handover Request Ack\n");
}
@@ -472,9 +478,7 @@ static int msc_t_patch_and_send_ho_request_ack(struct msc_t *msc_t, const struct
if (!an_apdu.msg)
return -EIO;
/* Send to remote MSC via msc_a_remote role */
- rc = msub_role_dispatch(msc_t->c.msub, MSC_ROLE_A, MSC_A_EV_FROM_T_PREPARE_HANDOVER_RESPONSE, &an_apdu);
- msgb_free(an_apdu.msg);
- return rc;
+ return msub_role_dispatch(msc_t->c.msub, MSC_ROLE_A, MSC_A_EV_FROM_T_PREPARE_HANDOVER_RESPONSE, &an_apdu);
}
static int msc_t_wait_ho_request_ack_decode_cb(struct osmo_fsm_inst *msc_t_fi, void *data,
diff --git a/src/libmsc/msc_t_remote.c b/src/libmsc/msc_t_remote.c
index 22c4e22fd..aea763337 100644
--- a/src/libmsc/msc_t_remote.c
+++ b/src/libmsc/msc_t_remote.c
@@ -1,6 +1,6 @@
/* The MSC-T role implementation variant that forwards requests to/from a remote MSC. */
/*
- * (C) 2019 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de>
+ * (C) 2019 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
* All Rights Reserved
*
* SPDX-License-Identifier: AGPL-3.0+
diff --git a/src/libmsc/msc_vgcs.c b/src/libmsc/msc_vgcs.c
new file mode 100644
index 000000000..264fa4953
--- /dev/null
+++ b/src/libmsc/msc_vgcs.c
@@ -0,0 +1,2765 @@
+/* Handle VGCS/VBCS calls. (Voice Group/Broadcast Call Service). */
+/*
+ * (C) 2023 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
+ * All Rights Reserved
+ *
+ * SPDX-License-Identifier: AGPL-3.0+
+ *
+ * Author: Andreas Eversberg
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* The process consists of four state machines:
+ *
+ * The call control state machine "GCC" handles the voice group/broadcast call.
+ * There is one instance for every call. It is mainly controlled by the calling
+ * subscriber. The state machine is described in 3GPP TS 44.068 / 44.069.
+ * One SCCP connection to the calling subscriber is associated with the state
+ * machine. Once the calling subscriber leaves or is assigned to the VGCS/VBS
+ * channel, the association to the MSC-A role is removed and the SCCP connection
+ * is closed. The state machine with the transaction still exists until the end
+ * of the call.
+ *
+ * The BSS control state machine "vgcs_bss_fsm" handles the call in each BSC.
+ * There are as many instances as there are BSCs where the call is placed to.
+ * The instances are linked to the call control in a 1:n relation.
+ * One SCCP connection for every BSC is associated with the state machine.
+ * It sets up the call in the BSC and handles the uplink control and signaling
+ * with the talking phone.
+ *
+ * The resource controling state machine "vgcs_cell_fsm" handles the channel for
+ * each BTS that has a VGCS for the call. The instances are linked to the BSS
+ * control in a 1:n relation.
+ * One SCCP connection for every cell is associated with each list entry.
+ * It assigns the VGCS/VBS channel and the conference bridge in the MGW.
+ *
+ * The MGW endpoint state machine "vgcs_mgw_ep_fsm" handles the endpoint
+ * connection for each call. It controls the clearing of the MGW connections
+ * in case of endpoint failure. All instances of the resource controlling state
+ * machine are linked to this state machine in a 1:n relation.
+ *
+ * Setup of a call:
+ *
+ * When the calling subscriber dials a group/broadcast call, the GCR is checked
+ * for an existing Group ID. If it exists, the call is setup towards the a given
+ * list of MSCs for this Group ID. Also the channels are assigned for a given
+ * list of cells for this Group ID.
+ * The call can also be initiated via VTY.
+ *
+ * Then the calling subscriber is assigned to the VGCS channel of the same cell
+ * where the call was initialized. Afterwards the call is connected. The calling
+ * subscriber may then stay on the uplink or release it.
+ *
+ * Uplink control:
+ *
+ * Any BSC may indicate a talking subscriber. If there is no talking subscriber
+ * yet, the uplink is granted, otherwise it is rejected. If the uplink is in
+ * use on one BSC, all other BSCs will be blocked. If the uplink becomes free,
+ * all other BSCs will be unblocked.
+ *
+ * Termination of the call:
+ *
+ * The calling subscriber accesses the uplink. The it sends a termination
+ * request. This request is acknowledged by a termination command towards
+ * the calling subscriber. The call is cleared.
+ * The call can also be terminated via VTY and/or a timeout.
+ *
+ */
+
+#include <osmocom/core/utils.h>
+#include <osmocom/core/fsm.h>
+#include <osmocom/gsm/protocol/gsm_44_068.h>
+#include <osmocom/sigtran/sccp_helpers.h>
+#include <osmocom/mgcp_client/mgcp_client_endpoint_fsm.h>
+
+#include <osmocom/msc/gsm_data.h>
+#include <osmocom/msc/sccp_ran.h>
+#include <osmocom/msc/ran_infra.h>
+#include <osmocom/msc/ran_peer.h>
+#include <osmocom/msc/ran_msg_a.h>
+#include <osmocom/msc/msub.h>
+#include <osmocom/msc/debug.h>
+#include <osmocom/msc/msc_a.h>
+#include <osmocom/msc/vlr.h>
+#include <osmocom/msc/rtp_stream.h>
+#include <osmocom/msc/codec_mapping.h>
+#include <osmocom/msc/msc_vgcs.h>
+#include <osmocom/msc/asci_gcr.h>
+
+#define S(x) (1 << (x))
+
+#define LOG_GCC(trans, level, fmt, args...) \
+ LOGP((trans) ? ((trans->type == TRANS_GCC) ? DGCC : DBCC) : DASCI, level, \
+ (trans) ? ((trans->type == TRANS_GCC) ? ("GCC callref %s: " fmt) : ("BCC callref %s: " fmt)) : "%s" fmt, \
+ (trans) ? gsm44068_group_id_string(trans->callref) : "", ##args)
+#define LOG_BSS(bss, level, fmt, args...) \
+ LOGP(DASCI, level, \
+ (bss->trans_type == TRANS_GCC) ? ("GCC callref %s, BSS #%s: " fmt) : ("BCC callref %s, BSS #%s: " fmt), \
+ gsm44068_group_id_string(bss->callref), osmo_ss7_pointcode_print(NULL, bss->pc), ##args)
+#define LOG_CELL(cell, level, fmt, args...) \
+ LOGP(DASCI, level, \
+ (cell->trans_type == TRANS_GCC) ? ("GCC callref %s, BSS #%s, CID %d: " fmt) \
+ : ("BCC callref %s, BSS #%s, CID %d: " fmt), \
+ gsm44068_group_id_string(cell->callref), osmo_ss7_pointcode_print(NULL, cell->pc), cell->cell_id, ##args)
+
+static struct osmo_fsm vgcs_bcc_fsm;
+static struct osmo_fsm vgcs_gcc_fsm;
+static struct osmo_fsm vgcs_bss_fsm;
+static struct osmo_fsm vgcs_cell_fsm;
+static struct osmo_fsm vgcs_mgw_ep_fsm;
+
+static __attribute__((constructor)) void vgcs_fsm_init(void)
+{
+ OSMO_ASSERT(osmo_fsm_register(&vgcs_bcc_fsm) == 0);
+ OSMO_ASSERT(osmo_fsm_register(&vgcs_gcc_fsm) == 0);
+ OSMO_ASSERT(osmo_fsm_register(&vgcs_bss_fsm) == 0);
+ OSMO_ASSERT(osmo_fsm_register(&vgcs_cell_fsm) == 0);
+ OSMO_ASSERT(osmo_fsm_register(&vgcs_mgw_ep_fsm) == 0);
+}
+
+const char *gsm44068_group_id_string(uint32_t callref)
+{
+ static char string[9];
+
+ snprintf(string, sizeof(string), "%08u", callref);
+ string[sizeof(string) - 1] = '\0';
+
+ return string;
+}
+
+/* Resolve ran peer from point-code */
+static struct ran_peer *ran_peer_for_pc(struct gsm_network *msc_network, int pc)
+{
+ struct sccp_ran_inst *sri;
+ struct osmo_sccp_addr addr = {};
+ struct ran_peer *rp;
+
+ sri = msc_network->a.sri;
+ if (!osmo_sccp_get_ss7(sri->sccp)) {
+ LOGP(DASCI, LOGL_ERROR, "No SS7???\n");
+ return NULL;
+ }
+ osmo_sccp_make_addr_pc_ssn(&addr, pc, sri->ran->ssn);
+ rp = ran_peer_find_by_addr(sri, &addr);
+
+ return rp;
+}
+
+/* Encode message and send towards BSC. */
+int ran_encode_and_send(struct osmo_fsm_inst *fi, struct ran_msg *ran_msg, struct ran_conn *conn, bool initial)
+{
+ struct msgb *l3_msg;
+ int rc;
+
+ l3_msg = ran_a_encode(fi, ran_msg);
+ if (!l3_msg) {
+ LOGP(DASCI, LOGL_ERROR, "ran_a_encode() failed.\n");
+ return -EINVAL;
+ }
+ rc = ran_conn_down_l2_co(conn, l3_msg, initial);
+ msgb_free(l3_msg);
+
+ return rc;
+}
+
+/* Transmit DTAP message to talker
+ * This is used for sending group/broadcast call control messages. */
+int tx_dtap_to_talker(struct vgcs_bss *bss, struct msgb *l3_msg)
+{
+ struct ran_msg ran_msg;
+ struct gsm48_hdr *gh = msgb_l3(l3_msg) ? : l3_msg->data;
+ uint8_t pdisc = gsm48_hdr_pdisc(gh);
+ int rc;
+
+
+ LOG_BSS(bss, LOGL_DEBUG, "Sending DTAP: %s %s\n",
+ gsm48_pdisc_name(pdisc), gsm48_pdisc_msgtype_name(pdisc, gsm48_hdr_msg_type(gh)));
+
+ ran_msg = (struct ran_msg){
+ .msg_type = RAN_MSG_DTAP,
+ .dtap = l3_msg,
+ };
+
+ rc = ran_encode_and_send(bss->fi, &ran_msg, bss->conn, false);
+
+ return rc;
+}
+
+/*
+ * GCC/BCC Message transcoding
+ */
+
+static void _add_cause_ie(struct msgb *msg, uint8_t cause, uint8_t *diag, uint8_t diag_len)
+{
+ uint8_t *ie = msgb_put(msg, 2 + diag_len);
+
+ ie[0] = 1 + diag_len;
+ ie[1] = cause;
+ if (diag && diag_len) {
+ ie[1] |= 0x80;
+ memcpy(ie + 2, diag, diag_len);
+ }
+}
+
+static void _add_callref_ie(struct msgb *msg, uint32_t callref, bool with_prio, uint8_t prio)
+{
+ uint32_t ie;
+
+ ie = callref << 5;
+ if (with_prio)
+ ie |= 0x10 | (prio << 1);
+ msgb_put_u32(msg, ie);
+}
+
+static int _msg_too_short(void)
+{
+ LOGP(DASCI, LOGL_ERROR, "MSG too short.\n");
+ return -EINVAL;
+}
+
+static int _ie_invalid(void)
+{
+ LOGP(DASCI, LOGL_ERROR, "IE invalid.\n");
+ return -EINVAL;
+}
+
+static int _rx_callref(uint8_t *ie, unsigned int remaining_len, uint32_t *callref, bool *with_prio, uint8_t *prio)
+{
+ uint8_t ie_len;
+
+ ie_len = sizeof(uint32_t);
+ if (remaining_len < ie_len)
+ return _msg_too_short();
+ *callref = osmo_load32be(ie) >> 5;
+ if (ie[3] & 0x10) {
+ *with_prio = true;
+ *prio = (ie[3] >> 1) & 0x7;
+ } else
+ *with_prio = false;
+
+ return ie_len;
+}
+
+/* 3GPP TS 44.068 Clause 8.1 */
+static int gsm44068_tx_connect(struct gsm_trans *trans, uint8_t pdisc, uint32_t callref, bool with_prio, uint8_t prio,
+ uint8_t oi, uint8_t talker_prio, bool with_sms, uint8_t sms_dc, uint8_t sms_gp)
+{
+ struct msgb *msg = gsm44068_msgb_alloc_name("GSM 44.068 TX CONNECT");
+ struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
+ uint8_t ie;
+
+ gh->proto_discr = pdisc;
+ gh->msg_type = OSMO_GSM44068_MSGT_CONNECT;
+ _add_callref_ie(msg, callref, with_prio, prio);
+ ie = (talker_prio << 4) | oi;
+ msgb_put_u8(msg, ie);
+ if (with_sms) {
+ ie = OSMO_GSM44068_IEI_SMS_INDICATIONS | (sms_dc << 1) | sms_gp;
+ msgb_put_u8(msg, ie);
+ }
+
+ /* Send to calling subscriber, depending on the link he is. */
+ if (trans->msc_a)
+ return msc_a_tx_dtap_to_i(trans->msc_a, msg);
+ if (trans->gcc.uplink_bss)
+ return tx_dtap_to_talker(trans->gcc.uplink_bss, msg);
+ msgb_free(msg);
+ return -EIO;
+}
+
+/* The Get Status procedure is not used by the current implementation.
+ * It is commented out, so it can be used in the future.
+ * The idea is to have a complete set of GCC/BCC message transcoding.
+ */
+#if 0
+/* 3GPP TS 44.068 Clause 8.2 */
+static int gsm44068_tx_get_status(struct gsm_trans *trans, uint8_t pdisc, struct osmo_mobile_identity *mi)
+{
+ struct msgb *msg = gsm44068_msgb_alloc_name("GSM 44.068 TX GET STATUS");
+ struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
+
+ gh->proto_discr = pdisc;
+ gh->msg_type = OSMO_GSM44068_MSGT_GET_STATUS;
+ if (mi) {
+ uint8_t *l;
+ int rc;
+
+ l = msgb_tl_put(msg, OSMO_GSM44068_IEI_MOBILE_IDENTITY);
+ rc = osmo_mobile_identity_encode_msgb(msg, mi, false);
+ if (rc < 0) {
+ msgb_free(msg);
+ return -EINVAL;
+ }
+ *l = rc;
+ }
+
+ /* Send to calling subscriber, depending on the link he is. */
+ if (trans->msc_a)
+ return msc_a_tx_dtap_to_i(trans->msc_a, msg);
+ if (trans->gcc.uplink_bss)
+ return tx_dtap_to_talker(trans->gcc.uplink_bss, msg);
+ msgb_free(msg);
+ return -EIO;
+}
+#endif
+
+/* 3GPP TS 44.068 Clause 8.3 and 8.3a */
+static int gsm44068_rx_immediate_setup(struct msgb *msg, uint8_t *talker_prio, uint8_t *key_seq,
+ struct gsm48_classmark2 *cm2, struct osmo_mobile_identity *mi,
+ uint32_t *callref, bool *with_prio, uint8_t *prio, char *user_user)
+{
+ struct gsm48_hdr *gh = msgb_l3(msg);
+ unsigned int remaining_len = msgb_l3len(msg) - sizeof(*gh);
+ uint8_t *ie = gh->data;
+ uint8_t ie_len;
+ uint64_t otdi;
+ int i;
+ int rc;
+
+ /* Talker priority / Cyphering key sequence */
+ if (remaining_len < 1)
+ return _msg_too_short();
+ *talker_prio = ie[0] & 0x07;
+ *key_seq = (ie[0] >> 4) & 0x07;
+ remaining_len -= 1;
+ ie += 1;
+
+ /* Mobile station classmark 2 */
+ if (remaining_len < 4)
+ return _msg_too_short();
+ ie_len = ie[0];
+ if (remaining_len < ie_len + 1)
+ return _msg_too_short();
+ if (ie_len != 3)
+ return _ie_invalid();
+ memcpy(cm2, ie + 1, ie_len);
+ remaining_len -= ie_len + 1;
+ ie += ie_len + 1;
+
+ /* Mobile indentity */
+ if (gh->msg_type == OSMO_GSM44068_MSGT_IMMEDIATE_SETUP) {
+ /* IMMEDIATE SETUP uses IMSI/TMSI */
+ if (remaining_len < 2)
+ return _msg_too_short();
+ ie_len = ie[0];
+ if (remaining_len < ie_len + 1)
+ return _msg_too_short();
+ rc = osmo_mobile_identity_decode(mi, ie + 1, ie_len, false);
+ if (rc) {
+ LOGP(DMM, LOGL_ERROR, "Failure to decode Mobile Identity in GCC/BCC IMMEDDIATE SETUP"
+ " (rc=%d)\n", rc);
+ return -EINVAL;
+ }
+ remaining_len -= ie_len + 1;
+ ie += ie_len + 1;
+ } else {
+ /* IMMEDIATE SETUP 2 uses TMSI only */
+ if (remaining_len < 4)
+ return _msg_too_short();
+ mi->type = GSM_MI_TYPE_TMSI;
+ mi->tmsi = osmo_load32be(ie);
+ remaining_len -= 4;
+ ie += 4;
+ }
+
+ /* Call reference */
+ rc = _rx_callref(ie, remaining_len, callref, with_prio, prio);
+ if (rc < 0)
+ return rc;
+ remaining_len -= rc;
+ ie += rc;
+
+ /* OTID */
+ if (gh->msg_type == OSMO_GSM44068_MSGT_IMMEDIATE_SETUP_2 && user_user) {
+ ie_len = 5;
+ if (remaining_len < ie_len)
+ return _msg_too_short();
+ otdi = osmo_load32be(ie + 1) | ((uint64_t)ie[0] << 32);
+
+ for (i = 0; i < 12; i++) {
+ user_user[i] = (otdi % 10) + '0';
+ otdi /= 10;
+ }
+ user_user[i] = '\0';
+ remaining_len -= ie_len;
+ ie += ie_len;
+ } else if (user_user)
+ user_user[0] = '\0';
+
+ return 0;
+}
+
+/* 3GPP TS 44.068 Clause 8.4 */
+static int gsm44068_tx_set_parameter(struct gsm_trans *trans, uint8_t pdisc, uint8_t da, uint8_t ua, uint8_t comm,
+ uint8_t oi)
+{
+ struct msgb *msg = gsm44068_msgb_alloc_name("GSM 44.068 TX SET PARAMETER");
+ struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
+ uint8_t ie;
+
+ gh->proto_discr = pdisc;
+ gh->msg_type = OSMO_GSM44068_MSGT_SET_PARAMETER;
+ ie = (da << 3) | (ua << 2) | (comm << 1) | oi;
+ msgb_put_u8(msg, ie);
+
+ /* Send to calling subscriber, depending on the link he is. */
+ if (trans->msc_a)
+ return msc_a_tx_dtap_to_i(trans->msc_a, msg);
+ if (trans->gcc.uplink_bss)
+ return tx_dtap_to_talker(trans->gcc.uplink_bss, msg);
+ msgb_free(msg);
+ return -EIO;
+}
+
+/* 3GPP TS 44.068 Clause 8.5 */
+static int gsm44068_rx_setup(struct msgb *msg, bool *with_talker_prio, uint8_t *talker_prio,
+ uint32_t *callref, bool *with_prio, uint8_t *prio, char *user_user)
+{
+ struct gsm48_hdr *gh = msgb_l3(msg);
+ unsigned int remaining_len = msgb_l3len(msg) - sizeof(*gh);
+ uint8_t *ie = gh->data;
+ struct tlv_parsed tp;
+ struct tlv_p_entry *tlv;
+ int rc;
+
+ /* Call reference */
+ rc = _rx_callref(ie, remaining_len, callref, with_prio, prio);
+ if (rc < 0)
+ return rc;
+ remaining_len -= rc;
+ ie += rc;
+
+ rc = tlv_parse(&tp, &osmo_gsm44068_att_tlvdef, ie, remaining_len, 0, 0);
+ if (rc < 0)
+ return _ie_invalid();
+
+ /* User-user */
+ tlv = TLVP_GET(&tp, OSMO_GSM44068_IEI_USER_USER);
+ if (tlv && tlv->len && tlv->len <= 1 + 12 && user_user) {
+ memcpy(user_user, tlv->val, tlv->len - 1);
+ user_user[tlv->len - 1] = '\0';
+ }
+
+ /* Talker priority */
+ tlv = TLVP_GET(&tp, OSMO_GSM44068_IEI_TALKER_PRIORITY);
+ if (tlv && tlv->len) {
+ *with_talker_prio = true;
+ *talker_prio = tlv->val[0] & 0x07;
+ } else
+ *with_talker_prio = false;
+
+ return 0;
+}
+
+/* 3GPP TS 44.068 Clause 8.6 */
+static int gsm44068_rx_status(struct msgb *msg, uint8_t *cause, uint8_t *diag, uint8_t *diag_len,
+ bool *with_call_state, enum osmo_gsm44068_call_state *call_state,
+ bool *with_state_attrs, uint8_t *da, uint8_t *ua, uint8_t *comm, uint8_t *oi)
+{
+ struct gsm48_hdr *gh = msgb_l3(msg);
+ unsigned int remaining_len = msgb_l3len(msg) - sizeof(*gh);
+ uint8_t *ie = gh->data;
+ uint8_t ie_len;
+ struct tlv_parsed tp;
+ struct tlv_p_entry *tlv;
+ int rc;
+
+ /* Cause */
+ if (remaining_len < 2 || ie[0] < remaining_len - 2)
+ return _msg_too_short();
+ ie_len = ie[0];
+ if (remaining_len < ie_len + 1)
+ return _msg_too_short();
+ if (ie_len < 1)
+ return _ie_invalid();
+ *cause = ie[1] & 0x7f;
+ *diag_len = ie_len - 1;
+ if (*diag_len)
+ memcpy(diag, ie + 2, ie_len - 1);
+ remaining_len -= ie_len + 1;
+ ie += ie_len + 1;
+
+ rc = tlv_parse(&tp, &osmo_gsm44068_att_tlvdef, ie, remaining_len, 0, 0);
+ if (rc < 0)
+ return _ie_invalid();
+
+ /* Call state */
+ tlv = TLVP_GET(&tp, OSMO_GSM44068_IEI_CALL_STATE);
+ if (tlv) {
+ *with_call_state = true;
+ *call_state = tlv->val[0] & 0x7;
+ } else
+ *with_call_state = false;
+
+ /* State attributes */
+ tlv = TLVP_GET(&tp, OSMO_GSM44068_IEI_STATE_ATTRIBUTES);
+ if (tlv) {
+ *with_state_attrs = true;
+ *da = (tlv->val[0] >> 3) & 0x1;
+ *ua = (tlv->val[0] >> 2) & 0x1;
+ *comm = (tlv->val[0] >> 1) & 0x1;
+ *oi = tlv->val[0] & 0x1;
+ } else
+ *with_state_attrs = false;
+
+ return 0;
+}
+
+/* 3GPP TS 44.068 Clause 8.7 and 8.8 */
+static int gsm44068_tx_termination(struct msc_a *msc_a, struct vgcs_bss *bss, uint8_t pdisc, uint8_t msg_type,
+ uint8_t cause, uint8_t *diag, uint8_t diag_len)
+{
+ struct msgb *msg = gsm44068_msgb_alloc_name("GSM 44.068 TX TERMINATION");
+ struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
+
+ gh->proto_discr = pdisc;
+ gh->msg_type = msg_type;
+ _add_cause_ie(msg, cause, diag, diag_len);
+
+ /* Send to calling subscriber, depending on the link he is. */
+ if (msc_a)
+ return msc_a_tx_dtap_to_i(msc_a, msg);
+ if (bss)
+ return tx_dtap_to_talker(bss, msg);
+ msgb_free(msg);
+ return -EIO;
+}
+
+/* 3GPP TS 44.068 Clause 8.9 */
+static int gsm44068_rx_termination_req(struct msgb *msg, uint32_t *callref, bool *with_prio, uint8_t *prio,
+ bool *with_talker_prio, uint8_t *talker_prio)
+{
+ struct gsm48_hdr *gh = msgb_l3(msg);
+ unsigned int remaining_len = msgb_l3len(msg) - sizeof(*gh);
+ uint8_t *ie = gh->data;
+ struct tlv_parsed tp;
+ struct tlv_p_entry *tlv;
+ int rc;
+
+ /* Call reference */
+ rc = _rx_callref(ie, remaining_len, callref, with_prio, prio);
+ if (rc < 0)
+ return rc;
+ remaining_len -= rc;
+ ie += rc;
+
+ rc = tlv_parse(&tp, &osmo_gsm44068_att_tlvdef, ie, remaining_len, 0, 0);
+ if (rc < 0)
+ return _ie_invalid();
+
+ /* Talker priority */
+ tlv = TLVP_GET(&tp, OSMO_GSM44068_IEI_TALKER_PRIORITY);
+ if (tlv && tlv->len) {
+ *with_talker_prio = true;
+ *talker_prio = tlv->val[0] & 0x07;
+ } else
+ *with_talker_prio = false;
+
+ return 0;
+}
+
+/*
+ * GCC/BCC state machine - handles calling subscriber process
+ */
+
+static const struct value_string vgcs_gcc_fsm_event_names[] = {
+ OSMO_VALUE_STRING(VGCS_GCC_EV_NET_SETUP),
+ OSMO_VALUE_STRING(VGCS_GCC_EV_NET_TERM),
+ OSMO_VALUE_STRING(VGCS_GCC_EV_USER_SETUP),
+ OSMO_VALUE_STRING(VGCS_GCC_EV_USER_TERM),
+ OSMO_VALUE_STRING(VGCS_GCC_EV_BSS_ESTABLISHED),
+ OSMO_VALUE_STRING(VGCS_GCC_EV_BSS_ASSIGN_CPL),
+ OSMO_VALUE_STRING(VGCS_GCC_EV_BSS_ASSIGN_FAIL),
+ OSMO_VALUE_STRING(VGCS_GCC_EV_BSS_RELEASED),
+ OSMO_VALUE_STRING(VGCS_GCC_EV_TIMEOUT),
+ { }
+};
+
+static int gcc_establish_bss(struct gsm_trans *trans)
+{
+ struct gsm_network *net = trans->net;
+ struct vgcs_mgw_ep *mgw = NULL;
+ struct mgcp_client *mgcp_client;
+ struct gcr *gcr;
+ struct gcr_bss *b;
+ struct gcr_cell *c;
+ struct vgcs_bss *bss;
+ struct vgcs_bss_cell *cell;
+ struct osmo_fsm_inst *fi;
+ struct ran_peer *rp;
+
+ /* Failure should not happen, because it has been checked before. */
+ gcr = gcr_by_callref(trans->net, trans->type, trans->callref);
+ if (!gcr)
+ return -EINVAL;
+
+ /* Allocate MGW endpoint. */
+ mgcp_client = mgcp_client_pool_get(trans->net->mgw.mgw_pool);
+ if (!mgcp_client) {
+ LOG_GCC(trans, LOGL_ERROR, "No MGW client, please check config.\n");
+ goto err_mgw;
+ }
+ fi = osmo_fsm_inst_alloc(&vgcs_mgw_ep_fsm, net, NULL, LOGL_DEBUG, NULL);
+ if (!fi) {
+ LOG_GCC(trans, LOGL_ERROR, "No memory for VGCS MSG state machine.\n");
+ goto err_mgw;
+ }
+ osmo_fsm_inst_update_id(fi, "vgcs-mgw-ep");
+ osmo_fsm_inst_state_chg(fi, VGCS_MGW_EP_ST_ACTIVE, 0, 0);
+ mgw = talloc_zero(fi, struct vgcs_mgw_ep);
+ if (!mgw) {
+ LOG_GCC(trans, LOGL_ERROR, "No memory for MGW ep structure.\n");
+ osmo_fsm_inst_free(fi);
+ goto err_mgw;
+ }
+ mgw->fi = fi;
+ fi->priv = mgw;
+ INIT_LLIST_HEAD(&mgw->cell_list);
+ mgw->mgw_ep = osmo_mgcpc_ep_alloc(mgw->fi, VGCS_MGW_EP_EV_FREE,
+ mgcp_client, trans->net->mgw.tdefs, mgw->fi->id,
+ "%s", mgcp_client_rtpbridge_wildcard(mgcp_client));
+ if (!mgw->mgw_ep) {
+ LOG_GCC(trans, LOGL_ERROR, "No memory for MGW endpoint state machine.\n");
+ goto err_mgw;
+ }
+
+ /* Create BSS list structures. */
+ LOG_GCC(trans, LOGL_DEBUG, "Creating BSS list structure with cell list structures.\n");
+ llist_for_each_entry(b, &gcr->bss_list, list) {
+ LOG_GCC(trans, LOGL_DEBUG, " -> BSS with PC %s.\n", osmo_ss7_pointcode_print(NULL, b->pc));
+ /* Resolve ran_peer. */
+ rp = ran_peer_for_pc(trans->net, b->pc);
+ if (!rp) {
+ LOG_GCC(trans, LOGL_ERROR, "Failed to resolve point code %s, skipping BSS!\n",
+ osmo_ss7_pointcode_print(NULL, b->pc));
+ continue;
+ }
+ /* Create state machine. */
+ fi = osmo_fsm_inst_alloc(&vgcs_bss_fsm, net, NULL, LOGL_DEBUG, NULL);
+ if (!fi) {
+ LOG_GCC(trans, LOGL_ERROR, "No memory for state machine.\n");
+ break;
+ }
+ /* Create call structure. */
+ bss = talloc_zero(fi, struct vgcs_bss);
+ if (!bss) {
+ LOG_GCC(trans, LOGL_ERROR, "No memory for BSS call structure.\n");
+ osmo_fsm_inst_free(fi);
+ break;
+ }
+ bss->fi = fi;
+ fi->priv = bss;
+ INIT_LLIST_HEAD(&bss->cell_list);
+ bss->trans = trans;
+ bss->trans_type = trans->type;
+ bss->callref = trans->callref;
+ bss->pc = b->pc;
+ /* Create ran connection. */
+ bss->conn = ran_conn_create_outgoing(rp);
+ if (!bss->conn) {
+ LOG_GCC(trans, LOGL_ERROR, "Failed to create RAN connection.\n");
+ osmo_fsm_inst_free(bss->fi);
+ continue;
+ }
+ bss->conn->vgcs.bss = bss;
+ /* Create cell list structures. */
+ llist_for_each_entry(c, &b->cell_list, list) {
+ LOG_GCC(trans, LOGL_DEBUG, " -> Cell ID %d.\n", c->cell_id);
+ /* Create state machine. */
+ fi = osmo_fsm_inst_alloc(&vgcs_cell_fsm, net, NULL, LOGL_DEBUG, NULL);
+ if (!fi) {
+ LOG_GCC(trans, LOGL_ERROR, "No memory for state machine.\n");
+ break;
+ }
+ /* Create cell structure. */
+ cell = talloc_zero(fi, struct vgcs_bss_cell);
+ if (!cell) {
+ LOG_GCC(trans, LOGL_ERROR, "No memory for BSS cell structure.\n");
+ osmo_fsm_inst_free(fi);
+ break;
+ }
+ cell->fi = fi;
+ fi->priv = cell;
+ osmo_fsm_inst_update_id_f(cell->fi, "vgcs-cell-%d", c->cell_id);
+ cell->trans_type = trans->type;
+ cell->callref = trans->callref;
+ cell->pc = b->pc;
+ cell->cell_id = c->cell_id;
+ cell->call_id = trans->call_id;
+ /* Create ran connection. */
+ cell->conn = ran_conn_create_outgoing(rp);
+ if (!cell->conn) {
+ LOG_GCC(trans, LOGL_ERROR, "Failed to create RAN connection.\n");
+ osmo_fsm_inst_free(cell->fi);
+ continue;
+ }
+ cell->conn->vgcs.cell = cell;
+ /* Attach to cell list of BSS and MGW endpoint */
+ llist_add_tail(&cell->list_bss, &bss->cell_list);
+ cell->bss = bss;
+ llist_add_tail(&cell->list_mgw, &mgw->cell_list);
+ cell->mgw = mgw;
+ }
+ /* No cell? */
+ if (llist_empty(&bss->cell_list)) {
+ LOG_GCC(trans, LOGL_DEBUG, " -> No Cell in this BSS.\n");
+ osmo_fsm_inst_free(bss->fi);
+ break;
+ }
+ /* Attach to transaction list */
+ llist_add_tail(&bss->list, &trans->gcc.bss_list);
+ /* Trigger VGCS/VBS SETUP */
+ osmo_fsm_inst_dispatch(bss->fi, VGCS_BSS_EV_SETUP, NULL);
+ }
+ /* No BSS? */
+ if (llist_empty(&trans->gcc.bss_list)) {
+ /* Also destroy MGW, because this list is empty too! */
+ LOG_GCC(trans, LOGL_NOTICE, "No BSS found, please check your VTY configuration and add cells.\n");
+ goto err_mgw;
+ }
+ return 0;
+
+err_mgw:
+ if (mgw) {
+ if (mgw->mgw_ep) {
+ /* This will also free FSM instance and vgcs_mgw_ep structure. */
+ osmo_fsm_inst_dispatch(mgw->fi, VGCS_MGW_EP_EV_CLEAR, NULL);
+ return -EINVAL;
+ }
+ osmo_fsm_inst_free(mgw->fi);
+ }
+ return -EINVAL;
+}
+
+/* Send Assignment Request to the calling subscriber.
+ * This is used to assign the subscriber from early assigned channel to the VGCS/VBS channel. */
+static int gcc_assign(struct gsm_trans *trans)
+{
+ struct ran_msg tx_ran_msg;
+ struct gsm0808_channel_type channel_type;
+ struct vgcs_bss *bss = NULL, *b;
+
+ /* No assignment, because the calling subscriber is already assigned or there is no calling subscriber. */
+ if (!trans->msc_a)
+ return 0;
+
+ /* Check calling subscriber's MSC */
+ struct ran_conn *conn = msub_ran_conn(trans->msc_a->c.msub);
+ if (!conn) {
+ LOG_GCC(trans, LOGL_ERROR, "Calling subscriber has no ran_conn????\n");
+ return -EINVAL;
+ }
+ llist_for_each_entry(b, &trans->gcc.bss_list, list) {
+ if (osmo_sccp_addr_ri_cmp(&conn->ran_peer->peer_addr, &b->conn->ran_peer->peer_addr))
+ continue;
+ bss = b;
+ break;
+ }
+ if (!bss) {
+ LOG_GCC(trans, LOGL_ERROR, "Calling subscriber comes from BSC that has no VGCS call.\n");
+ return -EINVAL;
+ }
+
+ /* For now we support GSM/FR V1 only. This shall be supported by all MS. */
+ channel_type = (struct gsm0808_channel_type) {
+ .ch_indctr = GSM0808_CHAN_SPEECH,
+ .ch_rate_type = GSM0808_SPEECH_FULL_BM,
+ .perm_spch_len = 1,
+ .perm_spch[0] = GSM0808_PERM_FR1,
+ };
+
+ /* Send assignment to VGCS channel */
+ tx_ran_msg = (struct ran_msg) {
+ .msg_type = RAN_MSG_ASSIGNMENT_COMMAND,
+ .assignment_command = {
+ .channel_type = &channel_type,
+ .callref_present = true,
+ .callref = {
+ .sf = (trans->type == TRANS_GCC),
+ },
+ },
+ };
+ osmo_store32be_ext(trans->callref >> 3, &tx_ran_msg.assignment_command.callref.call_ref_hi, 3);
+ tx_ran_msg.assignment_command.callref.call_ref_lo = trans->callref & 0x7;
+ if (msc_a_ran_down(trans->msc_a, MSC_ROLE_I, &tx_ran_msg)) {
+ LOG_GCC(trans, LOGL_ERROR, "Cannot send Assignment\n");
+ return -EIO;
+ }
+
+ /* Assign Talker to BSS of the calling subscriber. */
+ trans->gcc.uplink_bss = bss;
+
+ return 0;
+}
+
+/* Send CONNECT to the calling subscriber. */
+static void gcc_connect(struct gsm_trans *trans)
+{
+ uint8_t pdisc = (trans->type == TRANS_GCC) ? GSM48_PDISC_GROUP_CC : GSM48_PDISC_BCAST_CC;
+ int rc;
+
+ /* Send CONNECT towards MS. */
+ rc = gsm44068_tx_connect(trans,
+ pdisc | (trans->transaction_id << 4),
+ trans->callref, 0, 0, 1, 0, 0, 0, 0);
+ if (rc < 0)
+ LOG_GCC(trans, LOGL_ERROR, "Failed to send CONNECT towards MS. Continue anyway.\n");
+}
+
+/* Release dedicated (SDCCH) channel of calling subscriber after assigning to VGCS */
+static void release_msc_a(struct gsm_trans *trans)
+{
+ struct msc_a *msc_a = trans->msc_a;
+
+ if (!msc_a)
+ return;
+
+ trans->msc_a = NULL;
+ switch (trans->type) {
+ case TRANS_GCC:
+ msc_a_put(msc_a, MSC_A_USE_GCC);
+ break;
+ case TRANS_BCC:
+ msc_a_put(msc_a, MSC_A_USE_BCC);
+ break;
+ default:
+ break;
+ }
+}
+
+/* Send TERMINATE to the calling/talking subscriber, then destroy transaction. */
+static void gcc_terminate_and_destroy(struct gsm_trans *trans, enum osmo_gsm44068_cause cause)
+{
+ uint8_t pdisc = (trans->type == TRANS_GCC) ? GSM48_PDISC_GROUP_CC : GSM48_PDISC_BCAST_CC;
+ int rc;
+
+ /* Send TERMINATION towards MS. */
+ rc = gsm44068_tx_termination(trans->msc_a, trans->gcc.uplink_bss,
+ pdisc | (trans->transaction_id << 4),
+ OSMO_GSM44068_MSGT_TERMINATION,
+ cause, NULL, 0);
+ if (rc < 0)
+ LOG_GCC(trans, LOGL_ERROR, "Failed to send TERMINATION towards MS. Continue anyway.\n");
+
+ /* Destroy transaction, note that also _gsm44068_gcc_trans_free() will be called by trans_free().
+ * There the complete state machine is destroyed. */
+ trans->callref = 0;
+ trans_free(trans);
+}
+
+/* Send TERMINATION REJECT to the calling/talking subscriber. */
+static void gcc_termination_reject(struct gsm_trans *trans, enum osmo_gsm44068_cause cause)
+{
+ uint8_t pdisc = (trans->type == TRANS_GCC) ? GSM48_PDISC_GROUP_CC : GSM48_PDISC_BCAST_CC;
+ int rc;
+
+ /* Send TERMINATION towards MS. */
+ rc = gsm44068_tx_termination(trans->msc_a, trans->gcc.uplink_bss,
+ pdisc | (trans->transaction_id << 4),
+ OSMO_GSM44068_MSGT_TERMINATION_REJECT,
+ cause, NULL, 0);
+ if (rc < 0)
+ LOG_GCC(trans, LOGL_ERROR, "Failed to send TERMINATION REJECT towards MS.\n");
+}
+
+/* Start inactivity timer.
+ * This timer is used to terminate the call, if the radio connection to the caller gets lost. */
+static void start_inactivity_timer(struct gsm_trans *trans)
+{
+ if (trans->gcc.inactivity_to) {
+ LOG_GCC(trans, LOGL_DEBUG, "Set inactivity timer to %d seconds.\n", trans->gcc.inactivity_to);
+ osmo_timer_schedule(&trans->gcc.timer_inactivity, trans->gcc.inactivity_to, 0);
+ }
+}
+
+static void stop_inactivity_timer(struct gsm_trans *trans)
+{
+ if (osmo_timer_pending(&trans->gcc.timer_inactivity)) {
+ LOG_GCC(trans, LOGL_DEBUG, "Stop pending inactivity timer.\n");
+ osmo_timer_del(&trans->gcc.timer_inactivity);
+ }
+}
+
+static void inactivity_timer_cb(void *data)
+{
+ struct gsm_trans *trans = data;
+
+ osmo_fsm_inst_dispatch(trans->gcc.fi, VGCS_GCC_EV_TIMEOUT, NULL);
+}
+
+/* Set the parameters of the talker. (downlink mute/unmute, uplink unmute, COMM=T, originator) */
+static int set_parameter(struct gsm_trans *trans)
+{
+ uint8_t pdisc = (trans->type == TRANS_GCC) ? GSM48_PDISC_GROUP_CC : GSM48_PDISC_BCAST_CC;
+ int rc;
+
+ rc = gsm44068_tx_set_parameter(trans, pdisc | (trans->transaction_id << 4),
+ !trans->gcc.mute_talker, 1, 1, trans->gcc.uplink_originator);
+ if (rc < 0)
+ LOG_GCC(trans, LOGL_ERROR, "Failed to send SET PARAMETER towards MS.\n");
+ return rc;
+}
+
+/* Check in which cell the uplink is used and set "uplink_cell". */
+static int set_uplink_cell(struct vgcs_bss *bss, struct gsm0808_cell_id *cell_id_ie, uint16_t cell_id)
+{
+ struct vgcs_bss_cell *cell;
+
+ if (cell_id_ie) {
+ /* Get cell ID to determine talker channel. */
+ switch (cell_id_ie->id_discr) {
+ case CELL_IDENT_CI:
+ cell_id = cell_id_ie->id.ci;
+ break;
+ case CELL_IDENT_LAC_AND_CI:
+ cell_id = cell_id_ie->id.lac_and_ci.ci;
+ break;
+ default:
+ LOG_BSS(bss, LOGL_DEBUG, "Cannot idenitfy cell, please fix!\n");
+ return -EINVAL;
+ }
+ }
+
+ /* Search for cell ID. */
+ bss->trans->gcc.uplink_cell = NULL;
+ llist_for_each_entry(cell, &bss->cell_list, list_bss) {
+ if (cell->cell_id == cell_id) {
+ LOG_BSS(bss, LOGL_DEBUG, "Talker is talking on cell %d.\n", cell->cell_id);
+ bss->trans->gcc.uplink_cell = cell;
+ return 0;
+ }
+ }
+
+ LOG_BSS(bss, LOGL_DEBUG, "Cell ID %d is not in list of current BSS, please fix!\n", cell_id);
+ return -EINVAL;
+}
+
+/* Set the MGW conference mode.
+ * All cells are listening to the conference. If there is a talker, this cell is also transmitting to the conference. */
+static int set_mgw_conference(struct gsm_trans *trans)
+{
+ struct vgcs_bss *bss;
+ struct vgcs_bss_cell *cell;
+ struct rtp_stream *rtps;
+ int rc;
+
+ /* All cells without talker are listening */
+ llist_for_each_entry(bss, &trans->gcc.bss_list, list) {
+ llist_for_each_entry(cell, &bss->cell_list, list_bss) {
+ if (!(rtps = cell->rtps))
+ continue;
+ if (rtps->crcx_conn_mode != MGCP_CONN_SEND_ONLY) {
+ LOG_CELL(cell, LOGL_DEBUG, "Setting cell %d into listening mode.\n", cell->cell_id);
+ rtp_stream_set_mode(rtps, MGCP_CONN_SEND_ONLY);
+ rc = rtp_stream_commit(rtps);
+ if (rc < 0)
+ LOG_CELL(cell, LOGL_ERROR, "Failed to commit parameters to RTP stream "
+ "for cell %d.\n", cell->cell_id);
+ }
+ }
+ }
+
+ if (trans->gcc.uplink_cell && trans->gcc.uplink_cell->rtps) {
+ cell = trans->gcc.uplink_cell;
+ rtps = cell->rtps;
+ LOG_CELL(cell, LOGL_DEBUG, "Setting cell %d into listening mode.\n", cell->cell_id);
+ rtp_stream_set_mode(rtps, MGCP_CONN_CONFECHO);
+ rc = rtp_stream_commit(rtps);
+ if (rc < 0)
+ LOG_CELL(cell, LOGL_ERROR, "Failed to commit parameters to RTP stream "
+ "for cell %d.\n", cell->cell_id);
+ }
+
+ return 0;
+}
+
+static void _assign_complete(struct gsm_trans *trans, bool send_connect)
+{
+ uint16_t cell_id;
+
+ OSMO_ASSERT(trans->msc_a);
+
+ /* Change state. */
+ osmo_fsm_inst_state_chg(trans->gcc.fi, VGCS_GCC_ST_N2_CALL_ACTIVE, 0, 0);
+ /* Get cell ID. */
+ cell_id = trans->msc_a->via_cell.cell_identity;
+ /* Releasing dedicated channel. */
+ release_msc_a(trans);
+ /* Send CONNECT to the calling subscriber. */
+ if (send_connect)
+ gcc_connect(trans);
+ /* Set parameter. */
+ set_parameter(trans);
+ /* Start inactivity timer, if uplink is free. */
+ if (!trans->gcc.uplink_busy)
+ start_inactivity_timer(trans);
+ /* Set cell of current talker. */
+ set_uplink_cell(trans->gcc.uplink_bss, NULL, cell_id);
+ /* Set MGW conference. */
+ set_mgw_conference(trans);
+}
+
+#define CONNECT_OPTION false
+
+static void vgcs_gcc_fsm_n0_null(struct osmo_fsm_inst *fi, uint32_t event, void *data)
+{
+ struct gsm_trans *trans = fi->priv;
+ int rc;
+
+ switch (event) {
+ case VGCS_GCC_EV_NET_SETUP:
+ /* Establish call towards all BSSs. */
+ LOG_GCC(trans, LOGL_DEBUG, "Setup by network, trying to establish cells.\n");
+ rc = gcc_establish_bss(trans);
+ if (rc < 0) {
+ LOG_GCC(trans, LOGL_NOTICE, "Failed to setup call to any cell.\n");
+ gcc_terminate_and_destroy(trans, OSMO_GSM44068_CAUSE_NETWORK_FAILURE);
+ break;
+ }
+ /* Keep state until established or released. */
+ break;
+ case VGCS_GCC_EV_NET_TERM:
+ LOG_GCC(trans, LOGL_DEBUG, "Termination by network, destroying call.\n");
+ /* Destroy group call in all cells. */
+ gcc_terminate_and_destroy(trans, OSMO_GSM44068_CAUSE_NORMAL_CALL_CLEARING);
+ break;
+ case VGCS_GCC_EV_USER_SETUP:
+ LOG_GCC(trans, LOGL_DEBUG, "Setup by MS, trying to establish cells.\n");
+ /* Change state. */
+ osmo_fsm_inst_state_chg(fi, VGCS_GCC_ST_N1_CALL_INITIATED, 0, 0);
+ /* Establish call towards all BSSs. */
+ rc = gcc_establish_bss(trans);
+ if (rc < 0) {
+ LOG_GCC(trans, LOGL_NOTICE, "Failed to setup call to any cell.\n");
+ gcc_terminate_and_destroy(trans, OSMO_GSM44068_CAUSE_NETWORK_FAILURE);
+ break;
+ }
+ if (CONNECT_OPTION) {
+ /* Send CONNECT to the calling subscriber. */
+ gcc_connect(trans);
+ /* Change state. */
+ osmo_fsm_inst_state_chg(fi, VGCS_GCC_ST_N3_CALL_EST_PROC, 0, 0);
+ }
+ break;
+ case VGCS_GCC_EV_BSS_ESTABLISHED:
+ LOG_GCC(trans, LOGL_DEBUG, "All cells establised, for a group call, sending CONNECT to caller.\n");
+ /* Change state. */
+ osmo_fsm_inst_state_chg(fi, VGCS_GCC_ST_N2_CALL_ACTIVE, 0, 0);
+ /* Start inactivity timer, if uplink is free. */
+ if (!trans->gcc.uplink_busy)
+ start_inactivity_timer(trans);
+ break;
+ case VGCS_GCC_EV_BSS_RELEASED:
+ LOG_GCC(trans, LOGL_DEBUG, "All group call in all cells failed, destroying call.\n");
+ /* Send TERMINATE to the calling subscriber. */
+ gcc_terminate_and_destroy(trans, OSMO_GSM44068_CAUSE_NETWORK_FAILURE);
+ break;
+ default:
+ OSMO_ASSERT(false);
+ }
+}
+
+static void vgcs_gcc_fsm_n1_call_initiated(struct osmo_fsm_inst *fi, uint32_t event, void *data)
+{
+ struct gsm_trans *trans = fi->priv;
+ int rc;
+
+ switch (event) {
+ case VGCS_GCC_EV_NET_TERM:
+ LOG_GCC(trans, LOGL_DEBUG, "Termination by network, destroying call.\n");
+ /* Destroy group call in all cells. */
+ gcc_terminate_and_destroy(trans, OSMO_GSM44068_CAUSE_NORMAL_CALL_CLEARING);
+ break;
+ case VGCS_GCC_EV_USER_TERM:
+ LOG_GCC(trans, LOGL_DEBUG, "Termination by user, destroying call.\n");
+ /* Send TERMINATE to the calling subscriber and destroy group call in all cells. */
+ gcc_terminate_and_destroy(trans, OSMO_GSM44068_CAUSE_NORMAL_CALL_CLEARING);
+ break;
+ case VGCS_GCC_EV_BSS_ESTABLISHED:
+ LOG_GCC(trans, LOGL_DEBUG, "All cells establised, for a group call, assign caller to VGCS.\n");
+ /* Send assignment to the calling subscriber. */
+ rc = gcc_assign(trans);
+ if (rc < 0) {
+ gcc_terminate_and_destroy(trans, OSMO_GSM44068_CAUSE_NETWORK_FAILURE);
+ break;
+ }
+ break;
+ case VGCS_GCC_EV_BSS_ASSIGN_CPL:
+ LOG_GCC(trans, LOGL_DEBUG, "Assignment complete, sending CONNECT to caller, releasing channel.\n");
+ /* Handle assignment complete */
+ _assign_complete(trans, true);
+ break;
+ case VGCS_GCC_EV_BSS_ASSIGN_FAIL:
+ LOG_GCC(trans, LOGL_DEBUG, "Assignment failed, releasing call.\n");
+ /* Send TERMINATE to the calling subscriber. */
+ gcc_terminate_and_destroy(trans, OSMO_GSM44068_CAUSE_NETWORK_FAILURE);
+ break;
+ case VGCS_GCC_EV_BSS_RELEASED:
+ LOG_GCC(trans, LOGL_DEBUG, "All group call in all cells failed, destroying call.\n");
+ /* Send TERMINATE to the calling subscriber. */
+ gcc_terminate_and_destroy(trans, OSMO_GSM44068_CAUSE_NETWORK_FAILURE);
+ break;
+ default:
+ OSMO_ASSERT(false);
+ }
+}
+
+static void vgcs_gcc_fsm_n2_call_active(struct osmo_fsm_inst *fi, uint32_t event, void *data)
+{
+ struct gsm_trans *trans = fi->priv;
+
+ switch (event) {
+ case VGCS_GCC_EV_NET_TERM:
+ LOG_GCC(trans, LOGL_DEBUG, "Termination by network, destroying call.\n");
+ /* Destroy group call in all cells. */
+ gcc_terminate_and_destroy(trans, OSMO_GSM44068_CAUSE_NORMAL_CALL_CLEARING);
+ break;
+ case VGCS_GCC_EV_USER_TERM:
+ if (!trans->gcc.uplink_originator) {
+ LOG_GCC(trans, LOGL_ERROR, "Termination by user, but it is not the originator.\n");
+ gcc_termination_reject(trans, OSMO_GSM44068_CAUSE_USER_NOT_ORIGINATOR);
+ break;
+ }
+ LOG_GCC(trans, LOGL_DEBUG, "Termination by user, destroying call.\n");
+ /* Send TERMINATE to the calling subscriber and destroy group call in all cells. */
+ gcc_terminate_and_destroy(trans, OSMO_GSM44068_CAUSE_NORMAL_CALL_CLEARING);
+ break;
+ case VGCS_GCC_EV_BSS_RELEASED:
+ LOG_GCC(trans, LOGL_DEBUG, "All group call in all cells failed, destroying call.\n");
+ /* Send TERMINATE to the calling subscriber. */
+ gcc_terminate_and_destroy(trans, OSMO_GSM44068_CAUSE_NETWORK_FAILURE);
+ break;
+ case VGCS_GCC_EV_TIMEOUT:
+ LOG_GCC(trans, LOGL_DEBUG, "Termination by inactivity timer, destroying call.\n");
+ /* Destroy group call in all cells. */
+ gcc_terminate_and_destroy(trans, OSMO_GSM44068_CAUSE_NORMAL_CALL_CLEARING);
+ break;
+ default:
+ OSMO_ASSERT(false);
+ }
+}
+
+static void vgcs_gcc_fsm_n3_call_est_proc(struct osmo_fsm_inst *fi, uint32_t event, void *data)
+{
+ struct gsm_trans *trans = fi->priv;
+ int rc;
+
+ switch (event) {
+ case VGCS_GCC_EV_NET_TERM:
+ LOG_GCC(trans, LOGL_DEBUG, "Termination by network, destroying call.\n");
+ /* Destroy group call in all cells. */
+ gcc_terminate_and_destroy(trans, OSMO_GSM44068_CAUSE_NORMAL_CALL_CLEARING);
+ break;
+ case VGCS_GCC_EV_USER_TERM:
+ LOG_GCC(trans, LOGL_DEBUG, "Termination by user, destroying call.\n");
+ /* Send TERMINATE to the calling subscriber and destroy group call in all cells. */
+ gcc_terminate_and_destroy(trans, OSMO_GSM44068_CAUSE_NORMAL_CALL_CLEARING);
+ break;
+ case VGCS_GCC_EV_BSS_ESTABLISHED:
+ LOG_GCC(trans, LOGL_DEBUG, "All cells establised, for a group call, assign caller to VGCS.\n");
+ /* Send assignment to the calling subscriber. */
+ rc = gcc_assign(trans);
+ if (rc < 0) {
+ gcc_terminate_and_destroy(trans, OSMO_GSM44068_CAUSE_NETWORK_FAILURE);
+ break;
+ }
+ break;
+ case VGCS_GCC_EV_BSS_ASSIGN_CPL:
+ LOG_GCC(trans, LOGL_DEBUG, "Assignment complete, sending CONNECT to caller, releasing channel.\n");
+ /* Handle assignment complete */
+ _assign_complete(trans, false);
+ break;
+ case VGCS_GCC_EV_BSS_ASSIGN_FAIL:
+ LOG_GCC(trans, LOGL_DEBUG, "Assignment failed, releasing call.\n");
+ /* Send TERMINATE to the calling subscriber. */
+ gcc_terminate_and_destroy(trans, OSMO_GSM44068_CAUSE_NETWORK_FAILURE);
+ break;
+ case VGCS_GCC_EV_BSS_RELEASED:
+ LOG_GCC(trans, LOGL_DEBUG, "All group call in all cells failed, destroying call.\n");
+ /* Send TERMINATE to the calling subscriber. */
+ gcc_terminate_and_destroy(trans, OSMO_GSM44068_CAUSE_NETWORK_FAILURE);
+ break;
+ default:
+ OSMO_ASSERT(false);
+ }
+}
+
+static const struct osmo_fsm_state vgcs_gcc_fsm_states[] = {
+ [VGCS_GCC_ST_N0_NULL] = {
+ .name = "NULL (N0)",
+ .in_event_mask = S(VGCS_GCC_EV_NET_SETUP) |
+ S(VGCS_GCC_EV_NET_TERM) |
+ S(VGCS_GCC_EV_USER_SETUP) |
+ S(VGCS_GCC_EV_BSS_ESTABLISHED) |
+ S(VGCS_GCC_EV_BSS_RELEASED),
+ .out_state_mask = S(VGCS_GCC_ST_N1_CALL_INITIATED) |
+ S(VGCS_GCC_ST_N2_CALL_ACTIVE),
+ .action = vgcs_gcc_fsm_n0_null,
+ },
+ [VGCS_GCC_ST_N1_CALL_INITIATED] = {
+ .name = "CALL INITATED (N1)",
+ .in_event_mask = S(VGCS_GCC_EV_NET_TERM) |
+ S(VGCS_GCC_EV_USER_TERM) |
+ S(VGCS_GCC_EV_BSS_ESTABLISHED) |
+ S(VGCS_GCC_EV_BSS_ASSIGN_CPL) |
+ S(VGCS_GCC_EV_BSS_ASSIGN_FAIL) |
+ S(VGCS_GCC_EV_BSS_RELEASED),
+ .out_state_mask = S(VGCS_GCC_ST_N0_NULL) |
+ S(VGCS_GCC_ST_N2_CALL_ACTIVE) |
+ S(VGCS_GCC_ST_N3_CALL_EST_PROC),
+ .action = vgcs_gcc_fsm_n1_call_initiated,
+ },
+ [VGCS_GCC_ST_N2_CALL_ACTIVE] = {
+ .name = "CALL ACTIVE (N2)",
+ .in_event_mask = S(VGCS_GCC_EV_NET_TERM) |
+ S(VGCS_GCC_EV_USER_TERM) |
+ S(VGCS_GCC_EV_BSS_RELEASED) |
+ S(VGCS_GCC_EV_TIMEOUT),
+ .out_state_mask = S(VGCS_GCC_ST_N0_NULL),
+ .action = vgcs_gcc_fsm_n2_call_active,
+ },
+ [VGCS_GCC_ST_N3_CALL_EST_PROC] = {
+ .name = "CALL EST PROCEEDING (N3)",
+ .in_event_mask = S(VGCS_GCC_EV_NET_TERM) |
+ S(VGCS_GCC_EV_USER_TERM) |
+ S(VGCS_GCC_EV_BSS_ESTABLISHED) |
+ S(VGCS_GCC_EV_BSS_ASSIGN_CPL) |
+ S(VGCS_GCC_EV_BSS_ASSIGN_FAIL) |
+ S(VGCS_GCC_EV_BSS_RELEASED),
+ .out_state_mask = S(VGCS_GCC_ST_N2_CALL_ACTIVE) |
+ S(VGCS_GCC_ST_N0_NULL),
+ .action = vgcs_gcc_fsm_n3_call_est_proc,
+ },
+ // We don't need a state to wait for the group call to be terminated in all cells
+};
+
+static struct osmo_fsm vgcs_bcc_fsm = {
+ .name = "bcc",
+ .states = vgcs_gcc_fsm_states,
+ .num_states = ARRAY_SIZE(vgcs_gcc_fsm_states),
+ .log_subsys = DBCC,
+ .event_names = vgcs_gcc_fsm_event_names,
+};
+
+static struct osmo_fsm vgcs_gcc_fsm = {
+ .name = "gcc",
+ .states = vgcs_gcc_fsm_states,
+ .num_states = ARRAY_SIZE(vgcs_gcc_fsm_states),
+ .log_subsys = DGCC,
+ .event_names = vgcs_gcc_fsm_event_names,
+};
+
+const char *vgcs_bcc_gcc_state_name(struct osmo_fsm_inst *fi)
+{
+ return vgcs_gcc_fsm_states[fi->state].name;
+}
+
+static int update_uplink_state(struct vgcs_bss *bss, bool uplink_busy);
+
+/* Receive RR messages from calling subscriber, prior assignment to VGCS/VBS. */
+int gsm44068_rcv_rr(struct msc_a *msc_a, struct msgb *msg)
+{
+ struct gsm_trans *trans = NULL;
+ struct gsm48_hdr *gh;
+ uint8_t msg_type;
+
+ gh = msgb_l3(msg);
+ msg_type = gsm48_hdr_msg_type(gh);
+
+ /* Find transaction. */
+ trans = trans_find_by_type(msc_a, TRANS_GCC);
+ if (!trans)
+ trans = trans_find_by_type(msc_a, TRANS_BCC);
+
+ if (!trans) {
+ LOG_GCC(trans, LOGL_ERROR, "No VGCS/VBS transaction.\n");
+ return -EINVAL;
+ }
+
+ /* In case the phone releases uplink prior being assigned to a VGCS */
+ if (msg_type == GSM48_MT_RR_UPLINK_RELEASE) {
+ struct vgcs_bss *bss;
+
+ LOG_GCC(trans, LOGL_INFO, "Received UPLINK RELEASE on initial channel.\n");
+ /* Clear the busy flag and unblock all cells. */
+ trans->gcc.uplink_bss = NULL;
+ trans->gcc.uplink_cell = NULL;
+ trans->gcc.uplink_busy = false;
+ llist_for_each_entry(bss, &trans->gcc.bss_list, list) {
+ /* Update uplink state. */
+ update_uplink_state(bss, trans->gcc.uplink_busy);
+ }
+ /* Start inactivity timer. */
+ start_inactivity_timer(bss->trans);
+ /* Next, the MS will switch to the VGCS as listener. Nothing else to do here. */
+ }
+
+ return 0;
+}
+
+/* Allocation of transaction for group call */
+static struct gsm_trans *trans_alloc_vgcs(struct gsm_network *net,
+ struct vlr_subscr *vsub,
+ enum trans_type trans_type, uint8_t transaction_id,
+ uint32_t callref,
+ struct gcr *gcr,
+ bool uplink_busy)
+{
+ struct gsm_trans *trans;
+
+ trans = trans_alloc(net, vsub, trans_type, transaction_id, callref);
+ if (!trans) {
+ LOG_GCC(trans, LOGL_ERROR, "No memory for trans.\n");
+ return NULL;
+ }
+ /* The uplink is busy when the call is started until the calling subscriber releases. */
+ trans->gcc.uplink_busy = uplink_busy;
+ trans->gcc.uplink_originator = true;
+ INIT_LLIST_HEAD(&trans->gcc.bss_list);
+ trans->gcc.inactivity_to = gcr->timeout;
+ trans->gcc.mute_talker = gcr->mute_talker;
+ trans->gcc.timer_inactivity.data = trans;
+ trans->gcc.timer_inactivity.cb = inactivity_timer_cb;
+ trans->gcc.fi = osmo_fsm_inst_alloc((trans_type == TRANS_GCC) ? &vgcs_gcc_fsm : &vgcs_bcc_fsm,
+ trans, trans, LOGL_DEBUG, NULL);
+ if (!trans->gcc.fi) {
+ LOG_GCC(trans, LOGL_ERROR, "No memory for state machine.\n");
+ trans_free(trans);
+ return NULL;
+ }
+
+ return trans;
+}
+
+/* Create transaction from incoming voice group/broadcast call. */
+static struct gsm_trans *trans_create_bcc_gcc(struct msc_a *msc_a, enum trans_type trans_type, uint8_t transaction_id,
+ uint8_t pdisc, uint8_t msg_type, uint32_t callref)
+{
+ struct gsm_network *net;
+ struct vlr_subscr *vsub;
+ struct gsm_trans *trans = NULL;
+ struct gcr *gcr;
+ int rc;
+
+ if (!msc_a) {
+ LOG_GCC(trans, LOGL_ERROR, "Invalid conn: no msc_a\n");
+ return NULL;
+ }
+ net = msc_a_net(msc_a);
+ vsub = msc_a_vsub(msc_a);
+
+ if (!vsub) {
+ LOG_GCC(trans, LOGL_ERROR, "Invalid conn: no subscriber\n");
+ return NULL;
+ }
+
+ /* An earlier CM Service Request for this CC message now has concluded */
+ if (!osmo_use_count_by(&msc_a->use_count,
+ (trans_type == TRANS_GCC) ? MSC_A_USE_CM_SERVICE_GCC : MSC_A_USE_CM_SERVICE_BCC))
+ LOG_MSC_A(msc_a, LOGL_ERROR,
+ "Creating new %s transaction without prior CM Service Request.\n",
+ get_value_string(trans_type_names, trans_type));
+ else
+ msc_a_put(msc_a,
+ (trans_type == TRANS_GCC) ? MSC_A_USE_CM_SERVICE_GCC : MSC_A_USE_CM_SERVICE_BCC);
+
+ /* A transaction must be created with a SETUP message. */
+ if (msg_type != OSMO_GSM44068_MSGT_IMMEDIATE_SETUP
+ && msg_type != OSMO_GSM44068_MSGT_SETUP
+ && msg_type != OSMO_GSM44068_MSGT_IMMEDIATE_SETUP_2) {
+ LOG_GCC(trans, LOGL_ERROR, "No transaction and message is not a SETUP.\n");
+ return NULL;
+ }
+
+ /* Check if callref already exists. */
+ trans = trans_find_by_callref(net, trans_type, callref);
+ if (trans) {
+ LOG_GCC(trans, LOGL_INFO, "Call to existing %s with callref %s, rejecting!\n",
+ trans_type_name(trans_type), gsm44068_group_id_string(callref));
+ rc = gsm44068_tx_termination(msc_a, NULL,
+ pdisc | (transaction_id << 4),
+ OSMO_GSM44068_MSGT_TERMINATION,
+ OSMO_GSM44068_CAUSE_BUSY, NULL, 0);
+ if (rc < 0)
+ LOG_GCC(trans, LOGL_ERROR, "Failed to send TERMINATION towards MS.\n");
+ return 0;
+ }
+
+ /* Check GCR for Group ID. */
+ gcr = gcr_by_callref(net, trans_type, callref);
+ if (!gcr) {
+ LOG_GCC(trans, LOGL_INFO, "No Group configured for %s callref %s, rejecting!\n",
+ trans_type_name(trans_type), gsm44068_group_id_string(callref));
+ // FIXME: Better cause value for a group that does not exist ?
+ rc = gsm44068_tx_termination(msc_a, NULL,
+ pdisc | (transaction_id << 4),
+ OSMO_GSM44068_MSGT_TERMINATION,
+ OSMO_GSM44068_CAUSE_REQUESTED_SERVICE_NOT_SUB, NULL, 0);
+ if (rc < 0)
+ LOG_GCC(trans, LOGL_ERROR, "Failed to send TERMINATION towards MS.\n");
+ return 0;
+ }
+
+ /* Create transaction, uplink is busy. */
+ trans = trans_alloc_vgcs(net, vsub, trans_type, transaction_id, callref, gcr, true);
+ if (!trans) {
+ rc = gsm44068_tx_termination(msc_a, NULL,
+ pdisc | (transaction_id << 4),
+ OSMO_GSM44068_MSGT_TERMINATION,
+ OSMO_GSM44068_CAUSE_NETWORK_FAILURE, NULL, 0);
+ if (rc < 0)
+ LOG_GCC(trans, LOGL_ERROR, "Failed to send TERMINATION towards MS.\n");
+ return NULL;
+ }
+
+ if (osmo_fsm_inst_dispatch(msc_a->c.fi, MSC_A_EV_TRANSACTION_ACCEPTED, trans)) {
+ LOG_MSC_A(msc_a, LOGL_ERROR, "Not allowed to accept %s transaction.\n",
+ get_value_string(trans_type_names, trans_type));
+ gcc_terminate_and_destroy(trans, OSMO_GSM44068_CAUSE_NETWORK_FAILURE);
+ return NULL;
+ }
+
+ /* Assign transaction */
+ msc_a_get(msc_a, (trans_type == TRANS_GCC) ? MSC_A_USE_GCC : MSC_A_USE_BCC);
+ trans->msc_a = msc_a;
+ trans->dlci = 0; /* main DCCH */
+
+ return trans;
+}
+
+/* Receive GCC/BCC messages from calling subscriber, depending on the PDISC used. */
+int gsm44068_rcv_bcc_gcc(struct msc_a *msc_a, struct gsm_trans *trans, struct msgb *msg)
+{
+ struct gsm48_hdr *gh = msgb_l3(msg);
+ uint8_t msg_type = gsm48_hdr_msg_type(gh);
+ uint8_t pdisc = gsm48_hdr_pdisc(gh);
+ uint8_t transaction_id = gsm48_hdr_trans_id_flip_ti(gh);
+ enum trans_type trans_type = (pdisc == GSM48_PDISC_GROUP_CC) ? TRANS_GCC : TRANS_BCC;
+
+ uint8_t key_seq;
+ bool talker_prio_requested;
+ bool with_talker_prio;
+ uint8_t talker_prio;
+ struct gsm48_classmark2 cm2;
+ struct osmo_mobile_identity mi;
+ uint32_t callref;
+ bool with_prio;
+ uint8_t prio;
+ char user_user[64] = "";
+ uint8_t cause;
+ uint8_t diag[256];
+ uint8_t diag_len;
+ bool with_call_state;
+ enum osmo_gsm44068_call_state call_state;
+ bool with_state_attrs;
+ uint8_t da, ua, comm, oi;
+ int rc = 0;
+
+ /* Remove sequence number (bit 7) from message type. */
+ msg_type &= 0xbf;
+
+ /* Parse messages. */
+ switch (msg_type) {
+ case OSMO_GSM44068_MSGT_SETUP:
+ rc = gsm44068_rx_setup(msg, &talker_prio_requested, &talker_prio, &callref, &with_prio, &prio,
+ user_user);
+ break;
+ case OSMO_GSM44068_MSGT_IMMEDIATE_SETUP:
+ case OSMO_GSM44068_MSGT_IMMEDIATE_SETUP_2:
+ rc = gsm44068_rx_immediate_setup(msg, &talker_prio, &key_seq, &cm2, &mi, &callref, &with_prio, &prio,
+ user_user);
+ break;
+ case OSMO_GSM44068_MSGT_STATUS:
+ rc = gsm44068_rx_status(msg, &cause, diag, &diag_len, &with_call_state, &call_state,
+ &with_state_attrs, &da, &ua, &comm, &oi);
+ break;
+ case OSMO_GSM44068_MSGT_TERMINATION_REQUEST:
+ rc = gsm44068_rx_termination_req(msg, &callref, &with_prio, &prio, &with_talker_prio, &talker_prio);
+ break;
+ default:
+ LOG_GCC(trans, LOGL_ERROR, "Invalid message type: 0x%02x\n", msg_type);
+ return -EINVAL;
+ }
+ if (rc < 0)
+ return rc;
+
+ /* Find transaction, if called from msc_a. */
+ if (!trans)
+ trans = trans_find_by_id(msc_a, trans_type, transaction_id);
+
+ /* Create transaction for SETUP message. */
+ if (!trans) {
+ trans = trans_create_bcc_gcc(msc_a, trans_type, transaction_id, pdisc, msg_type, callref);
+ if (!trans)
+ return -EINVAL;
+ } else {
+ /* A phone may not call while a VGCS is already active */
+ if (msg_type == OSMO_GSM44068_MSGT_IMMEDIATE_SETUP
+ || msg_type == OSMO_GSM44068_MSGT_SETUP
+ || msg_type == OSMO_GSM44068_MSGT_IMMEDIATE_SETUP_2) {
+ LOG_GCC(trans, LOGL_ERROR, "Received SETUP while call is already set up, rejecting.\n");
+ rc = gsm44068_tx_termination(msc_a, NULL,
+ pdisc | (transaction_id << 4),
+ OSMO_GSM44068_MSGT_TERMINATION,
+ OSMO_GSM44068_CAUSE_NETWORK_FAILURE, NULL, 0);
+ if (rc < 0)
+ LOG_GCC(trans, LOGL_ERROR, "Failed to send TERMINATION towards MS.\n");
+ return -EINVAL;
+ }
+ }
+
+ /* Handle received GCC messages (trigger state machine). */
+ switch (msg_type) {
+ case OSMO_GSM44068_MSGT_IMMEDIATE_SETUP:
+ case OSMO_GSM44068_MSGT_SETUP:
+ case OSMO_GSM44068_MSGT_IMMEDIATE_SETUP_2:
+ LOG_GCC(trans, LOGL_INFO, "Received SETUP.\n");
+ osmo_fsm_inst_dispatch(trans->gcc.fi, VGCS_GCC_EV_USER_SETUP, NULL);
+ break;
+ case OSMO_GSM44068_MSGT_STATUS:
+ LOG_GCC(trans, LOGL_NOTICE, "Received STATUS with cause %d (%s).\n", cause,
+ get_value_string(osmo_gsm44068_cause_names, cause));
+ if (diag_len)
+ LOG_GCC(trans, LOGL_NOTICE, " -> diagnostics: %s\n", osmo_hexdump(diag, diag_len));
+ if (with_call_state)
+ LOG_GCC(trans, LOGL_NOTICE, " -> call state %s\n",
+ get_value_string(osmo_gsm44068_call_state_names, call_state));
+ break;
+ case OSMO_GSM44068_MSGT_TERMINATION_REQUEST:
+ LOG_GCC(trans, LOGL_INFO, "Received TERMINATRION REQUEST.\n");
+ if (callref != trans->callref) {
+ LOG_GCC(trans, LOGL_NOTICE, "Received callref 0x%x does not match!\n", callref);
+ break;
+ }
+ osmo_fsm_inst_dispatch(trans->gcc.fi, VGCS_GCC_EV_USER_TERM, NULL);
+ break;
+ }
+
+ return 0;
+}
+
+static void bss_clear(struct vgcs_bss *bss, uint8_t cause, bool notify_trans);
+
+/* Call Control Specific transaction release.
+ * gets called by trans_free, DO NOT CALL YOURSELF! */
+void gsm44068_bcc_gcc_trans_free(struct gsm_trans *trans)
+{
+ struct vgcs_bss *bss, *bss2;
+
+ /* Free FSM. */
+ if (trans->gcc.fi) {
+ osmo_fsm_inst_state_chg(trans->gcc.fi, VGCS_GCC_ST_N0_NULL, 0, 0);
+ osmo_fsm_inst_term(trans->gcc.fi, OSMO_FSM_TERM_REGULAR, NULL);
+ }
+
+ /* Remove relations to cells.
+ * We must loop safe, because bss_clear() will detach every call control instance from list. */
+ llist_for_each_entry_safe(bss, bss2, &trans->gcc.bss_list, list)
+ osmo_fsm_inst_dispatch(bss->fi, VGCS_BSS_EV_CLEAR, NULL);
+
+ /* Stop inactivity timer. */
+ stop_inactivity_timer(trans);
+}
+
+/* Create a new call from VTY command. */
+const char *vgcs_vty_initiate(struct gsm_network *gsmnet, struct gcr *gcr)
+{
+ enum trans_type trans_type;
+ uint32_t callref;
+ struct gsm_trans *trans;
+
+ /* Get callref from stored suffix. Caller cannot choose a prefix. */
+ trans_type = gcr->trans_type;
+ callref = atoi(gcr->group_id);
+
+ /* Check if callref already exists. */
+ trans = trans_find_by_callref(gsmnet, trans_type, callref);
+ if (trans) {
+ LOG_GCC(trans, LOGL_INFO, "Call to existing %s with callref %s, rejecting!\n",
+ trans_type_name(trans_type), gsm44068_group_id_string(callref));
+ return "Call already exists.";
+ }
+
+ /* Create transaction, uplink is free. */
+ trans = trans_alloc_vgcs(gsmnet, NULL, trans_type, 0, callref, gcr, false);
+ if (!trans) {
+ LOG_GCC(trans, LOGL_ERROR, "No memory for trans.\n");
+ return "Failed to create call.";
+ }
+
+ LOG_GCC(trans, LOGL_INFO, "VTY initiates call.\n");
+ osmo_fsm_inst_dispatch(trans->gcc.fi, VGCS_GCC_EV_NET_SETUP, NULL);
+
+ return NULL;
+}
+
+/* Destroy a call from VTY command. */
+const char *vgcs_vty_terminate(struct gsm_network *gsmnet, struct gcr *gcr)
+{
+ enum trans_type trans_type;
+ uint32_t callref;
+ struct gsm_trans *trans;
+
+ /* Get callref from stored suffix. Caller cannot choose a prefix. */
+ trans_type = gcr->trans_type;
+ callref = atoi(gcr->group_id);
+
+ /* Check if callref exists. */
+ trans = trans_find_by_callref(gsmnet, trans_type, callref);
+ if (!trans)
+ return "Call does not exist.";
+
+ LOG_GCC(trans, LOGL_INFO, "VTY terminates call.\n");
+ osmo_fsm_inst_dispatch(trans->gcc.fi, VGCS_GCC_EV_NET_TERM, NULL);
+
+ return NULL;
+}
+
+/*
+ * BSS state machine - handles all BSS "call control" instances
+ */
+
+static const struct value_string vgcs_bss_fsm_event_names[] = {
+ OSMO_VALUE_STRING(VGCS_BSS_EV_SETUP),
+ OSMO_VALUE_STRING(VGCS_BSS_EV_SETUP_ACK),
+ OSMO_VALUE_STRING(VGCS_BSS_EV_SETUP_REFUSE),
+ OSMO_VALUE_STRING(VGCS_BSS_EV_ACTIVE_OR_FAIL),
+ OSMO_VALUE_STRING(VGCS_BSS_EV_UL_REQUEST),
+ OSMO_VALUE_STRING(VGCS_BSS_EV_UL_REQUEST_CNF),
+ OSMO_VALUE_STRING(VGCS_BSS_EV_UL_APP_DATA),
+ OSMO_VALUE_STRING(VGCS_BSS_EV_BSS_DTAP),
+ OSMO_VALUE_STRING(VGCS_BSS_EV_UL_RELEASE),
+ OSMO_VALUE_STRING(VGCS_BSS_EV_CLEAR),
+ OSMO_VALUE_STRING(VGCS_BSS_EV_CLOSE),
+ OSMO_VALUE_STRING(VGCS_BSS_EV_RELEASED),
+ { }
+};
+
+/* Blocks or unblocks uplinks of a BSS. */
+static int update_uplink_state(struct vgcs_bss *bss, bool uplink_busy)
+{
+ struct ran_msg ran_msg;
+ int rc;
+
+ if (uplink_busy) {
+ /* Send UPLINK SEIZED COMMAND to BSS. */
+ LOG_BSS(bss, LOGL_DEBUG, "Sending (VGCS) UPLINK SEIZED COMMAND towards BSS.\n");
+ ran_msg = (struct ran_msg){
+ .msg_type = RAN_MSG_UPLINK_SEIZED_CMD,
+ .uplink_seized_cmd = {
+ .cause = GSM0808_CAUSE_CALL_CONTROL,
+ },
+ };
+ } else {
+ /* Send UPLINK RELEASE COMMAND to BSS. */
+ LOG_BSS(bss, LOGL_DEBUG, "Sending (VGCS) UPLINK RELEASE COMMAND towards BSS.\n");
+ ran_msg = (struct ran_msg){
+ .msg_type = RAN_MSG_UPLINK_RELEASE_CMD,
+ .uplink_release_cmd = {
+ .cause = GSM0808_CAUSE_CALL_CONTROL,
+ },
+ };
+ }
+
+ rc = ran_encode_and_send(bss->fi, &ran_msg, bss->conn, false);
+
+ return rc;
+}
+
+/* Clear the connection towards BSS.
+ * The instance is removed soon, so it is detached from transaction and cells. */
+static void bss_clear(struct vgcs_bss *bss, uint8_t cause, bool notify_trans)
+{
+ struct ran_msg ran_msg;
+ struct gsm_trans *trans = bss->trans;
+ struct vgcs_bss_cell *cell, *cell2;
+
+ /* Must detach us from transaction. */
+ if (bss->trans) {
+ /* Remove pointer to talking BSS and cell. */
+ if (bss == bss->trans->gcc.uplink_bss) {
+ bss->trans->gcc.uplink_bss = NULL;
+ bss->trans->gcc.uplink_cell = NULL;
+ }
+ llist_del(&bss->list);
+ bss->trans = NULL;
+ }
+
+ /* Change state. */
+ osmo_fsm_inst_state_chg(bss->fi, VGCS_BSS_ST_RELEASE, 0, 0);
+
+ /* Send Clear Command to BSS. */
+ ran_msg = (struct ran_msg){
+ .msg_type = RAN_MSG_CLEAR_COMMAND,
+ .clear_command = {
+ .gsm0808_cause = cause,
+ },
+ };
+ if (bss->conn) {
+ LOG_BSS(bss, LOGL_DEBUG, "Sending CLEAR COMMAND for call controling channel.\n");
+ ran_encode_and_send(bss->fi, &ran_msg, bss->conn, false);
+ }
+
+ /* Trigger clear of all cells. Be safe, because the process will remove cells from list. */
+ llist_for_each_entry_safe(cell, cell2, &bss->cell_list, list_bss)
+ osmo_fsm_inst_dispatch(cell->fi, VGCS_CELL_EV_CLEAR, NULL);
+
+ /* Detach us from all BSS, if still linked */
+ llist_for_each_entry_safe(cell, cell2, &bss->cell_list, list_bss) {
+ llist_del(&cell->list_bss);
+ cell->bss = NULL;
+ }
+
+ /* If all BS are gone, notify calling subscriber process. */
+ if (notify_trans && trans && llist_empty(&trans->gcc.bss_list)) {
+ LOG_BSS(bss, LOGL_DEBUG, "Notify calling user process, that all BSSs are cleared.\n");
+ osmo_fsm_inst_dispatch(trans->gcc.fi, VGCS_GCC_EV_BSS_RELEASED, NULL);
+ }
+}
+
+/* When finally the BSS connection is released. (CLEAR COMPLETE response)
+ * The instance is removed, so it is detached from transaction and cells, if not already. */
+static void bss_destroy(struct vgcs_bss *bss)
+{
+ struct vgcs_bss_cell *cell, *cell2;
+
+ LOG_BSS(bss, LOGL_DEBUG, "Removing BSS call controling instance.\n");
+
+ /* Must detach us from transaction, if not already. */
+ if (bss->trans) {
+ /* Remove pointer to talking BSS and cell. */
+ if (bss == bss->trans->gcc.uplink_bss) {
+ bss->trans->gcc.uplink_bss = NULL;
+ bss->trans->gcc.uplink_cell = NULL;
+ }
+ llist_del(&bss->list);
+ bss->trans = NULL;
+ }
+
+ /* Detach us from RAN connection. */
+ if (bss->conn) {
+ if (bss->conn->vgcs.bss == bss)
+ bss->conn->vgcs.bss = NULL;
+ if (bss->conn->vgcs.cell == bss)
+ bss->conn->vgcs.cell = NULL;
+ ran_conn_close(bss->conn);
+ bss->conn = NULL;
+ }
+
+ /* Detach us from all BSS, if still linked */
+ llist_for_each_entry_safe(cell, cell2, &bss->cell_list, list_bss) {
+ llist_del(&cell->list_bss);
+ cell->bss = NULL;
+ }
+
+ /* Free FSM. (should be allocated) */
+ osmo_fsm_inst_state_chg(bss->fi, VGCS_BSS_ST_NULL, 0, 0);
+ osmo_fsm_inst_term(bss->fi, OSMO_FSM_TERM_REGULAR, NULL);
+}
+
+/* Get identity of talker.
+ * This is required to detect if the talker is the calling subscriber. */
+static int talker_identity(struct vgcs_bss *bss, uint8_t *l3, int l3_len)
+{
+ struct osmo_mobile_identity mi;
+ int rc;
+
+ rc = osmo_mobile_identity_decode_from_l3_buf(&mi, l3, l3_len, false);
+ if (rc < 0) {
+ LOG_BSS(bss, LOGL_DEBUG, "Talker's Identity cannot be decoded.\n");
+ return rc;
+ }
+
+ switch (mi.type) {
+ case GSM_MI_TYPE_IMSI:
+ if (!bss->trans->vsub)
+ break;
+ LOG_BSS(bss, LOGL_DEBUG, "Talker's sends IMSI %s, originator has IMSI %s.\n",
+ mi.imsi, bss->trans->vsub->imsi);
+ if (!strcmp(mi.imsi, bss->trans->vsub->imsi))
+ return 1;
+ break;
+ case GSM_MI_TYPE_TMSI:
+ if (!bss->trans->vsub)
+ break;
+ LOG_BSS(bss, LOGL_DEBUG, "Talker's sends TMSI 0x%08x, originator has TMSI 0x%08x.\n",
+ mi.tmsi, bss->trans->vsub->tmsi);
+ if (mi.tmsi == bss->trans->vsub->tmsi)
+ return 1;
+ break;
+ default:
+ LOG_BSS(bss, LOGL_DEBUG, "Talker's Identity is not IMSI nor TMSI.\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static void vgcs_bss_fsm_null(struct osmo_fsm_inst *fi, uint32_t event, void *data)
+{
+ struct vgcs_bss *bss = fi->priv;
+ struct ran_msg ran_msg;
+
+ switch (event) {
+ case VGCS_BSS_EV_SETUP:
+ /* Change state. */
+ osmo_fsm_inst_state_chg(fi, VGCS_BSS_ST_SETUP, 0, 0);
+ /* Send VGCS/VBS SETUP to BSS. */
+ LOG_BSS(bss, LOGL_DEBUG, "Sending VGCS/VBS SETUP towards BSS.\n");
+ ran_msg = (struct ran_msg){
+ .msg_type = RAN_MSG_VGCS_VBS_SETUP,
+ .vgcs_vbs_setup = {
+ .callref = {
+ .sf = (bss->trans->type == TRANS_GCC),
+ },
+ .vgcs_feature_flags_present = true,
+ },
+ };
+ osmo_store32be_ext(bss->callref >> 3, &ran_msg.vgcs_vbs_setup.callref.call_ref_hi, 3);
+ ran_msg.vgcs_vbs_setup.callref.call_ref_lo = bss->callref & 0x7;
+ /* First message, so we must set "initial" to "true". */
+ ran_encode_and_send(fi, &ran_msg, bss->conn, true);
+ break;
+ case VGCS_BSS_EV_CLEAR:
+ /* The calling user process requested clearing of VGCS/VBS call. */
+ LOG_BSS(bss, LOGL_DEBUG, "Received clearing from calling user process.\n");
+ bss_clear(bss, GSM0808_CAUSE_CALL_CONTROL, false);
+ break;
+ default:
+ OSMO_ASSERT(false);
+ }
+}
+
+static void vgcs_bss_fsm_setup(struct osmo_fsm_inst *fi, uint32_t event, void *data)
+{
+ struct vgcs_bss *bss = fi->priv;
+ struct vgcs_bss_cell *cell, *cell2;
+
+ switch (event) {
+ case VGCS_BSS_EV_SETUP_ACK:
+ /* Receive VGCS/VBS SETUP ACK from BSS. */
+ LOG_BSS(bss, LOGL_DEBUG, "Received VGCS/VBS SETUP ACK from BSS.\n");
+ /* Send current uplink state to this BSS. */
+ if (bss->trans)
+ update_uplink_state(bss, bss->trans->gcc.uplink_busy);
+ /* Change state. */
+ osmo_fsm_inst_state_chg(fi, VGCS_BSS_ST_ASSIGNMENT, 0, 0);
+ /* Trigger VGCS/VBS ASSIGNMENT */
+ llist_for_each_entry_safe(cell, cell2, &bss->cell_list, list_bss)
+ osmo_fsm_inst_dispatch(cell->fi, VGCS_CELL_EV_ASSIGN, NULL);
+ /* If all failed, clear call. */
+ if (llist_empty(&bss->cell_list)) {
+ LOG_BSS(bss, LOGL_NOTICE, "All VGCS/VBS assignments failed.\n");
+ bss_clear(bss, GSM0808_CAUSE_PROTOCOL_ERROR_BETWEEN_BSS_AND_MSC, true);
+ break;
+ }
+ break;
+ case VGCS_BSS_EV_SETUP_REFUSE:
+ /* Received VGCS/VBS SETUP REFUSE from BSS. */
+ LOG_BSS(bss, LOGL_NOTICE, "Received VGCS/VBS SETUP REFUSE from BSS.\n");
+ bss_clear(bss, GSM0808_CAUSE_PROTOCOL_ERROR_BETWEEN_BSS_AND_MSC, true);
+ break;
+ case VGCS_BSS_EV_CLEAR:
+ /* The calling user process requested clearing of VGCS/VBS call. */
+ LOG_BSS(bss, LOGL_DEBUG, "Received clearing from calling user process.\n");
+ bss_clear(bss, GSM0808_CAUSE_CALL_CONTROL, false);
+ break;
+ case VGCS_BSS_EV_CLOSE:
+ /* The SCCP connection from the MSC has been closed. */
+ LOG_BSS(bss, LOGL_NOTICE, "Received SCCP connecting closing from MSC.\n");
+ if (bss->conn) {
+ bss->conn->vgcs.bss = NULL;
+ bss->conn = NULL;
+ }
+ bss_clear(bss, GSM0808_CAUSE_PROTOCOL_ERROR_BETWEEN_BSS_AND_MSC, true);
+ break;
+ default:
+ OSMO_ASSERT(false);
+ }
+}
+
+static void vgcs_bss_fsm_assignment(struct osmo_fsm_inst *fi, uint32_t event, void *data)
+{
+ struct vgcs_bss *bss = fi->priv;
+ struct vgcs_bss_cell *c;
+ bool assigned;
+
+ switch (event) {
+ case VGCS_BSS_EV_ACTIVE_OR_FAIL:
+ /* If all gone, clear call. */
+ if (llist_empty(&bss->cell_list)) {
+ LOG_BSS(bss, LOGL_NOTICE, "All VGCS/VBS assignments failed.\n");
+ bss_clear(bss, GSM0808_CAUSE_PROTOCOL_ERROR_BETWEEN_BSS_AND_MSC, true);
+ break;
+ }
+ /* Is there a response for all cells?
+ * This means that all the channels have a positive response
+ * There is no channel with negative response, because a
+ * negative response will remove the channel. */
+ assigned = true;
+ llist_for_each_entry(c, &bss->cell_list, list_bss) {
+ if (!c->assigned)
+ assigned = false;
+ }
+ if (!assigned)
+ break;
+ LOG_BSS(bss, LOGL_DEBUG, "All VGCS/VBS assignments have responded.\n");
+ /* Change state. */
+ osmo_fsm_inst_state_chg(fi, VGCS_BSS_ST_ACTIVE, 0, 0);
+ /* Notify calling subscriber process. */
+ LOG_BSS(bss, LOGL_DEBUG, "Notify calling user process, that all BSSs are connected.\n");
+ if (bss->trans)
+ osmo_fsm_inst_dispatch(bss->trans->gcc.fi, VGCS_GCC_EV_BSS_ESTABLISHED, NULL);
+ break;
+ case VGCS_BSS_EV_CLEAR:
+ /* The calling user process requested clearing of VGCS/VBS call. */
+ LOG_BSS(bss, LOGL_DEBUG, "Received clearing from calling user process.\n");
+ bss_clear(bss, GSM0808_CAUSE_CALL_CONTROL, false);
+ break;
+ case VGCS_BSS_EV_CLOSE:
+ /* The SCCP connection from the MSC has been closed. */
+ LOG_BSS(bss, LOGL_NOTICE, "Received SCCP connecting closing from MSC.\n");
+ if (bss->conn) {
+ bss->conn->vgcs.bss = NULL;
+ bss->conn = NULL;
+ }
+ bss_clear(bss, GSM0808_CAUSE_PROTOCOL_ERROR_BETWEEN_BSS_AND_MSC, true);
+ break;
+ default:
+ OSMO_ASSERT(false);
+ }
+}
+
+static void vgcs_bss_fsm_active(struct osmo_fsm_inst *fi, uint32_t event, void *data)
+{
+ struct vgcs_bss *bss = fi->priv, *other;
+ struct ran_msg *rx_ran_msg = data;
+ struct ran_msg tx_ran_msg;
+ int rc;
+
+ switch (event) {
+ case VGCS_BSS_EV_UL_REQUEST:
+ LOG_BSS(bss, LOGL_DEBUG, "Listener changed to talker.\n");
+ if (!bss->trans)
+ break;
+ /* Someone is talking. Check if there is no other uplink already busy.
+ * This should not happen, since all other cells are blocked (SEIZED) as soon as the uplink was
+ * requested. This may happen due to a race condition, where the uplink was requested before the
+ * UPLINK SEIZED COMMAND has been received by BSS. */
+ if (bss->trans->gcc.uplink_busy) {
+ /* Send UPLINK REJECT COMMAND to BSS. */
+ LOG_BSS(bss, LOGL_DEBUG, "Sending (VGCS) UPLINK REJECT COMMAND towards BSS.\n");
+ tx_ran_msg = (struct ran_msg){
+ .msg_type = RAN_MSG_UPLINK_REJECT_CMD,
+ .uplink_reject_cmd = {
+ .cause = GSM0808_CAUSE_CALL_CONTROL,
+ },
+ };
+ ran_encode_and_send(fi, &tx_ran_msg, bss->conn, false);
+ break;
+ }
+ /* Send UPLINK REQUEST ACKNOWLEDGE to BSS. */
+ LOG_BSS(bss, LOGL_DEBUG, "Sending (VGCS) UPLINK REQUEST ACKNOWLEDGE towards BSS.\n");
+ tx_ran_msg = (struct ran_msg){
+ .msg_type = RAN_MSG_UPLINK_REQUEST_ACK,
+ };
+ ran_encode_and_send(fi, &tx_ran_msg, bss->conn, false);
+ /* Set the busy flag and block all other cells. */
+ bss->trans->gcc.uplink_bss = bss;
+ bss->trans->gcc.uplink_busy = true;
+ bss->trans->gcc.uplink_originator = false;
+ llist_for_each_entry(other, &bss->trans->gcc.bss_list, list) {
+ if (other == bss)
+ continue;
+ /* Update uplink state. */
+ update_uplink_state(bss, bss->trans->gcc.uplink_busy);
+ }
+ /* Stop inactivity timer. */
+ stop_inactivity_timer(bss->trans);
+ break;
+ case VGCS_BSS_EV_UL_REQUEST_CNF:
+ LOG_BSS(bss, LOGL_DEBUG, "Talker established uplink.\n");
+ if (!bss->trans)
+ break;
+ if (!bss->trans->gcc.uplink_busy || bss->trans->gcc.uplink_bss != bss) {
+ LOG_BSS(bss, LOGL_ERROR, "Got UL REQUEST CNF, but we did not granted uplink.\n");
+ break;
+ }
+ /* Determine if talker is the originator of the call. */
+ rc = talker_identity(bss, rx_ran_msg->uplink_request_cnf.l3.l3,
+ rx_ran_msg->uplink_request_cnf.l3.l3_len);
+ if (rc > 0) {
+ bss->trans->gcc.uplink_originator = true;
+ LOG_BSS(bss, LOGL_DEBUG, "Talker is the originator of the call.\n");
+ }
+ /* Set parameter. */
+ set_parameter(bss->trans);
+ /* Set cell of current talker. */
+ set_uplink_cell(bss, &rx_ran_msg->uplink_request_cnf.cell_identifier, 0);
+ /* Set MGW conference. */
+ set_mgw_conference(bss->trans);
+ break;
+ case VGCS_BSS_EV_UL_APP_DATA:
+ LOG_BSS(bss, LOGL_DEBUG, "Talker sends application data on uplink.\n");
+ if (!bss->trans)
+ break;
+ if (!bss->trans->gcc.uplink_busy || bss->trans->gcc.uplink_bss != bss) {
+ LOG_BSS(bss, LOGL_ERROR, "Got UP APP DATA, but we did not granted uplink.\n");
+ break;
+ }
+ // FIXME: Use L3 info and feed to app.
+ break;
+ case VGCS_BSS_EV_BSS_DTAP:
+ LOG_BSS(bss, LOGL_DEBUG, "Talker sends DTAP message.\n");
+ if (!bss->trans)
+ break;
+ if (!bss->trans->gcc.uplink_busy || bss->trans->gcc.uplink_bss != bss) {
+ LOG_BSS(bss, LOGL_ERROR, "Got DTAP from BSS, but we did not granted uplink.\n");
+ break;
+ }
+ gsm44068_rcv_bcc_gcc(NULL, bss->trans, rx_ran_msg->dtap);
+ break;
+ case VGCS_BSS_EV_UL_RELEASE:
+ LOG_BSS(bss, LOGL_DEBUG, "Talker released uplink.\n");
+ if (!bss->trans)
+ break;
+ if (bss->trans->type == TRANS_BCC) {
+ LOG_BSS(bss, LOGL_DEBUG, "This is a broadcast call, terminating call.\n");
+ gcc_terminate_and_destroy(bss->trans, OSMO_GSM44068_CAUSE_NORMAL_CALL_CLEARING);
+ break;
+ }
+ if (!bss->trans->gcc.uplink_busy) {
+ LOG_BSS(bss, LOGL_NOTICE, "Got uplink release, but no uplink busy.\n");
+ break;
+ }
+ /* Talker release the uplink. Ignore, if not from the current talking cell. */
+ if (bss->trans->gcc.uplink_bss != bss) {
+ LOG_BSS(bss, LOGL_NOTICE, "Got uplink release, but uplink busy in other cell.\n");
+ break;
+ }
+ /* Clear the busy flag and unblock all other cells. */
+ bss->trans->gcc.uplink_bss = NULL;
+ bss->trans->gcc.uplink_cell = NULL;
+ bss->trans->gcc.uplink_busy = false;
+ llist_for_each_entry(other, &bss->trans->gcc.bss_list, list) {
+ if (other == bss)
+ continue;
+ /* Update uplink state. */
+ if (bss->trans)
+ update_uplink_state(bss, bss->trans->gcc.uplink_busy);
+ }
+ /* Set MGW conference. */
+ set_mgw_conference(bss->trans);
+ /* Start inactivity timer. */
+ start_inactivity_timer(bss->trans);
+ break;
+ case VGCS_BSS_EV_CLEAR:
+ /* The calling user process requested clearing of VGCS/VBS call. */
+ LOG_BSS(bss, LOGL_DEBUG, "Received clearing from calling user process.\n");
+ bss_clear(bss, GSM0808_CAUSE_CALL_CONTROL, false);
+ break;
+ case VGCS_BSS_EV_CLOSE:
+ /* The SCCP connection from the MSC has been closed. */
+ LOG_BSS(bss, LOGL_NOTICE, "Received SCCP connecting closing from MSC.\n");
+ if (bss->conn) {
+ bss->conn->vgcs.bss = NULL;
+ bss->conn = NULL;
+ }
+ bss_clear(bss, GSM0808_CAUSE_PROTOCOL_ERROR_BETWEEN_BSS_AND_MSC, true);
+ break;
+ default:
+ OSMO_ASSERT(false);
+ }
+}
+
+static void vgcs_bss_fsm_release(struct osmo_fsm_inst *fi, uint32_t event, void *data)
+{
+ struct vgcs_bss *bss = fi->priv;
+
+ switch (event) {
+ case VGCS_BSS_EV_CLOSE:
+ /* The SCCP connection from the MSC has been closed while waitring fro CLEAR COMPLETE. */
+ LOG_BSS(bss, LOGL_NOTICE, "Received SCCP closing collision.\n");
+ bss_destroy(bss);
+ break;
+ case VGCS_BSS_EV_RELEASED:
+ LOG_BSS(bss, LOGL_DEBUG, "Received CLEAR COMPLETE from BSS, we are done!\n");
+ bss_destroy(bss);
+ break;
+ default:
+ OSMO_ASSERT(false);
+ }
+}
+
+static const struct osmo_fsm_state vgcs_bss_fsm_states[] = {
+ [VGCS_BSS_ST_NULL] = {
+ .name = "NULL",
+ .in_event_mask = S(VGCS_BSS_EV_SETUP) |
+ S(VGCS_BSS_EV_CLEAR),
+ .out_state_mask = S(VGCS_BSS_ST_SETUP),
+ .action = vgcs_bss_fsm_null,
+ },
+ [VGCS_BSS_ST_SETUP] = {
+ .name = "SETUP sent",
+ .in_event_mask = S(VGCS_BSS_EV_SETUP_ACK) |
+ S(VGCS_BSS_EV_SETUP_REFUSE) |
+ S(VGCS_BSS_EV_CLEAR) |
+ S(VGCS_BSS_EV_CLOSE),
+ .out_state_mask = S(VGCS_BSS_ST_ASSIGNMENT) |
+ S(VGCS_BSS_ST_RELEASE),
+ .action = vgcs_bss_fsm_setup,
+ },
+ [VGCS_BSS_ST_ASSIGNMENT] = {
+ .name = "ASSIGNMENT Sent",
+ .in_event_mask = S(VGCS_BSS_EV_ACTIVE_OR_FAIL) |
+ S(VGCS_BSS_EV_CLEAR) |
+ S(VGCS_BSS_EV_CLOSE),
+ .out_state_mask = S(VGCS_BSS_ST_ACTIVE) |
+ S(VGCS_BSS_ST_RELEASE),
+ .action = vgcs_bss_fsm_assignment,
+ },
+ [VGCS_BSS_ST_ACTIVE] = {
+ .name = "VGCS/VBS Active",
+ .in_event_mask = S(VGCS_BSS_EV_UL_REQUEST) |
+ S(VGCS_BSS_EV_UL_REQUEST_CNF) |
+ S(VGCS_BSS_EV_UL_APP_DATA) |
+ S(VGCS_BSS_EV_BSS_DTAP) |
+ S(VGCS_BSS_EV_UL_RELEASE) |
+ S(VGCS_BSS_EV_CLEAR) |
+ S(VGCS_BSS_EV_CLOSE),
+ .out_state_mask = S(VGCS_BSS_ST_RELEASE),
+ .action = vgcs_bss_fsm_active,
+ },
+ [VGCS_BSS_ST_RELEASE] = {
+ .name = "Releasing VGCS/VBS control",
+ .in_event_mask = S(VGCS_BSS_EV_CLEAR) |
+ S(VGCS_BSS_EV_RELEASED),
+ .out_state_mask = S(VGCS_BSS_ST_NULL),
+ .action = vgcs_bss_fsm_release,
+ },
+};
+
+static struct osmo_fsm vgcs_bss_fsm = {
+ .name = "vgcs_bss",
+ .states = vgcs_bss_fsm_states,
+ .num_states = ARRAY_SIZE(vgcs_bss_fsm_states),
+ .log_subsys = DASCI,
+ .event_names = vgcs_bss_fsm_event_names,
+};
+
+/* The BSS accepts VGCS/VBS and sends us supported features. */
+void vgcs_vbs_setup_ack(struct vgcs_bss *bss, const struct ran_msg *ran_msg)
+{
+ if (!bss->trans)
+ return;
+ osmo_fsm_inst_dispatch(bss->fi, VGCS_BSS_EV_SETUP_ACK, (void *)ran_msg);
+}
+
+/* The BSS refuses VGCS/VBS. */
+void vgcs_vbs_setup_refuse(struct vgcs_bss *bss, const struct ran_msg *ran_msg)
+{
+ if (!bss->trans)
+ return;
+ osmo_fsm_inst_dispatch(bss->fi, VGCS_BSS_EV_SETUP_REFUSE, (void *)ran_msg);
+}
+
+/* The BSS needs more time for VGCS/VBS channel assignment. */
+void vgcs_vbs_queuing_ind(struct vgcs_bss_cell *cell)
+{
+ if (!cell->bss)
+ return;
+}
+
+/* A mobile station requests the uplink on a VGCS channel. */
+void vgcs_uplink_request(struct vgcs_bss *bss, const struct ran_msg *ran_msg)
+{
+ if (!bss->trans)
+ return;
+ osmo_fsm_inst_dispatch(bss->fi, VGCS_BSS_EV_UL_REQUEST, (void *)ran_msg);
+}
+
+/* The uplink on a VGCS channel has been established. */
+void vgcs_uplink_request_cnf(struct vgcs_bss *bss, const struct ran_msg *ran_msg)
+{
+ if (!bss->trans)
+ return;
+ osmo_fsm_inst_dispatch(bss->fi, VGCS_BSS_EV_UL_REQUEST_CNF, (void *)ran_msg);
+}
+
+/* Application data received on the uplink of a VGCS channel. */
+void vgcs_app_data(struct vgcs_bss *bss, const struct ran_msg *ran_msg)
+{
+ if (!bss->trans)
+ return;
+ osmo_fsm_inst_dispatch(bss->fi, VGCS_BSS_EV_UL_APP_DATA, (void *)ran_msg);
+}
+
+/* Application data received on the uplink of a VGCS channel. */
+void vgcs_bss_dtap(struct vgcs_bss *bss, const struct ran_msg *ran_msg)
+{
+ if (!bss->trans)
+ return;
+ osmo_fsm_inst_dispatch(bss->fi, VGCS_BSS_EV_BSS_DTAP, (void *)ran_msg);
+}
+
+/* A mobile station releases the uplink on a VGCS channel. */
+void vgcs_uplink_release_ind(struct vgcs_bss *bss, const struct ran_msg *ran_msg)
+{
+ if (!bss->trans)
+ return;
+ osmo_fsm_inst_dispatch(bss->fi, VGCS_BSS_EV_UL_RELEASE, (void *)ran_msg);
+}
+
+/* The BSS gives cell status about VGCS/VBS channel. */
+void vgcs_vbs_assign_status(struct vgcs_bss_cell *cell, const struct ran_msg *ran_msg)
+{
+ if (!cell->bss)
+ return;
+}
+
+void vgcs_vbs_caller_assign_cpl(struct gsm_trans *trans)
+{
+ osmo_fsm_inst_dispatch(trans->gcc.fi, VGCS_GCC_EV_BSS_ASSIGN_CPL, NULL);
+}
+
+void vgcs_vbs_caller_assign_fail(struct gsm_trans *trans)
+{
+ osmo_fsm_inst_dispatch(trans->gcc.fi, VGCS_GCC_EV_BSS_ASSIGN_FAIL, NULL);
+}
+
+/* BSS indicated that the channel has been released. */
+void vgcs_vbs_clear_req(struct vgcs_bss *bss, const struct ran_msg *ran_msg)
+{
+ osmo_fsm_inst_dispatch(bss->fi, VGCS_BSS_EV_CLOSE, (void *)ran_msg);
+}
+
+/* BSS indicated that the channel has been released. */
+void vgcs_vbs_clear_cpl(struct vgcs_bss *bss, const struct ran_msg *ran_msg)
+{
+ osmo_fsm_inst_dispatch(bss->fi, VGCS_BSS_EV_RELEASED, (void *)ran_msg);
+}
+
+/*
+ * Cell resource state machine - handles all "resource control" instances
+ */
+
+static const struct value_string vgcs_cell_fsm_event_names[] = {
+ OSMO_VALUE_STRING(VGCS_CELL_EV_RTP_STREAM_GONE),
+ OSMO_VALUE_STRING(VGCS_CELL_EV_RTP_STREAM_ADDR_AVAILABLE),
+ OSMO_VALUE_STRING(VGCS_CELL_EV_RTP_STREAM_ESTABLISHED),
+ OSMO_VALUE_STRING(VGCS_CELL_EV_ASSIGN),
+ OSMO_VALUE_STRING(VGCS_CELL_EV_ASSIGN_RES),
+ OSMO_VALUE_STRING(VGCS_CELL_EV_ASSIGN_FAIL),
+ OSMO_VALUE_STRING(VGCS_CELL_EV_CLEAR),
+ OSMO_VALUE_STRING(VGCS_CELL_EV_CLOSE),
+ OSMO_VALUE_STRING(VGCS_CELL_EV_RELEASED),
+ { }
+};
+
+static void cell_destroy(struct vgcs_bss_cell *cell);
+
+/* Clear the connection towards BSS.
+ * Relations to the BSS and transaction is removed. */
+static void cell_clear(struct vgcs_bss_cell *cell, uint8_t cause)
+{
+ struct ran_msg ran_msg;
+
+ /* Must detach us from BSS. */
+ if (cell->bss) {
+ /* Remove pointer to talking channel. */
+ if (cell->bss->trans && cell->bss->trans->gcc.uplink_cell == cell)
+ cell->bss->trans->gcc.uplink_cell = NULL;
+ llist_del(&cell->list_bss);
+ cell->bss = NULL;
+ }
+
+ /* Change state. */
+ if (cell->fi->state != VGCS_CELL_ST_RELEASE)
+ osmo_fsm_inst_state_chg(cell->fi, VGCS_CELL_ST_RELEASE, 0, 0);
+
+ /* If there is no event to wait for, we can just destroy. */
+ if (!cell->conn && !cell->rtps) {
+ cell_destroy(cell);
+ return;
+ }
+
+ /* Send Clear Command to BSS. */
+ if (cell->conn) {
+ ran_msg = (struct ran_msg){
+ .msg_type = RAN_MSG_CLEAR_COMMAND,
+ .clear_command = {
+ .gsm0808_cause = cause,
+ },
+ };
+ LOG_CELL(cell, LOGL_DEBUG, "Sending CLEAR COMMAND for call controling channel.\n");
+ ran_encode_and_send(cell->fi, &ran_msg, cell->conn, false);
+ }
+
+ /* Clear RTP stream. This may trigger VGCS_CELL_EV_RTP_STREAM_GONE within this release function. */
+ if (cell->rtps)
+ rtp_stream_release(cell->rtps);
+}
+
+/* When finally the BSS connection is released. (CLEAR COMPLETE response)
+ * Relations to the BSS and transaction is removed, if not already. */
+static void cell_destroy(struct vgcs_bss_cell *cell)
+{
+ struct vgcs_mgw_ep *mgw;
+
+ /* close RAN conn */
+ if (cell->conn) {
+ cell->conn->vgcs.cell = NULL;
+ ran_conn_close(cell->conn);
+ cell->conn = NULL;
+ }
+
+ /* Detach from BSS now. Check, to prevent race condition. */
+ if (cell->bss) {
+ /* Remove pointer to talking channel. */
+ if (cell->bss->trans && cell->bss->trans->gcc.uplink_cell == cell)
+ cell->bss->trans->gcc.uplink_cell = NULL;
+ llist_del(&cell->list_bss);
+ cell->bss = NULL;
+ }
+
+ /* Detach from MGW now. Check, to prevent race condition. */
+ if (cell->mgw) {
+ mgw = cell->mgw;
+ llist_del(&cell->list_mgw);
+ cell->mgw = NULL;
+ /* Destroy MGW endpoint, if list is empty. */
+ if (llist_empty(&mgw->cell_list))
+ osmo_fsm_inst_dispatch(mgw->fi, VGCS_MGW_EP_EV_CLEAR, NULL);
+ }
+
+ LOG_CELL(cell, LOGL_DEBUG, "Detroy connection to cell.\n");
+
+ /* Free FSM. (should be allocated) */
+ osmo_fsm_inst_state_chg(cell->fi, VGCS_CELL_ST_NULL, 0, 0);
+ osmo_fsm_inst_term(cell->fi, OSMO_FSM_TERM_REGULAR, NULL);
+}
+
+static void vgcs_cell_fsm_null(struct osmo_fsm_inst *fi, uint32_t event, void *data)
+{
+ struct vgcs_bss_cell *cell = fi->priv;
+ const struct codec_mapping *cm;
+ int rc;
+
+ switch (event) {
+ case VGCS_CELL_EV_ASSIGN:
+ LOG_CELL(cell, LOGL_DEBUG, "Received assignment from BSS controling process.\n");
+ /* Allocate rtps stream. */
+ cell->rtps = rtp_stream_alloc(cell->fi, VGCS_CELL_EV_RTP_STREAM_GONE,
+ VGCS_CELL_EV_RTP_STREAM_ADDR_AVAILABLE,
+ VGCS_CELL_EV_RTP_STREAM_ESTABLISHED, RTP_TO_RAN, cell->call_id,
+ NULL);
+ if (!cell->rtps) {
+ LOG_CELL(cell, LOGL_DEBUG, "Failed to allocate RTP stream, cannot continue.\n");
+ cell_destroy(cell);
+ break;
+ }
+ /* Hard coded codec: GSM V1 */
+ cm = codec_mapping_by_gsm0808_speech_codec_type(GSM0808_SCT_FR1);
+ if (!cm) {
+ LOG_CELL(cell, LOGL_DEBUG, "Selected codec not supported, cannot continue.\n");
+ cell_clear(cell, GSM0808_CAUSE_PROTOCOL_ERROR_BETWEEN_BSS_AND_MSC);
+ break;
+ }
+ rtp_stream_set_one_codec(cell->rtps, &cm->sdp);
+ /* Set initial mode. */
+ rtp_stream_set_mode(cell->rtps, MGCP_CONN_RECV_ONLY);
+ /* Commit RTP stream. */
+ if (!cell->bss || !cell->bss->trans) {
+ LOG_CELL(cell, LOGL_DEBUG, "No BSS/transaction, cannot continue.\n");
+ cell_clear(cell, GSM0808_CAUSE_PROTOCOL_ERROR_BETWEEN_BSS_AND_MSC);
+ break;
+ }
+ if (!cell->mgw || !cell->mgw->mgw_ep) {
+ LOG_CELL(cell, LOGL_DEBUG, "No MGW endpoint, cannot continue.\n");
+ cell_clear(cell, GSM0808_CAUSE_PROTOCOL_ERROR_BETWEEN_BSS_AND_MSC);
+ break;
+ }
+ rc = rtp_stream_ensure_ci(cell->rtps, cell->mgw->mgw_ep);
+ if (rc < 0) {
+ LOG_CELL(cell, LOGL_DEBUG, "Failed to trigger RTP stream CI.\n");
+ cell_clear(cell, GSM0808_CAUSE_PROTOCOL_ERROR_BETWEEN_BSS_AND_MSC);
+ break;
+ }
+ /* Change state. */
+ osmo_fsm_inst_state_chg(fi, VGCS_CELL_ST_ASSIGNMENT, 0, 0);
+ break;
+ case VGCS_CELL_EV_CLEAR:
+ /* The calling user process requested clearing of VGCS/VBS call. */
+ LOG_CELL(cell, LOGL_DEBUG, "Received clearing from BSS controling process.\n");
+ cell_clear(cell, GSM0808_CAUSE_CALL_CONTROL);
+ break;
+ default:
+ OSMO_ASSERT(false);
+ }
+}
+
+static void vgcs_cell_fsm_assignment(struct osmo_fsm_inst *fi, uint32_t event, void *data)
+{
+ struct vgcs_bss_cell *cell = fi->priv;
+ struct ran_msg *rx_ran_msg = data;
+ struct ran_msg tx_ran_msg;
+ struct osmo_sockaddr_str ss;
+ const struct codec_mapping *cm;
+ struct vgcs_bss *bss;
+ int rc;
+
+ switch (event) {
+ case VGCS_CELL_EV_RTP_STREAM_GONE:
+ /* The RTP stream failed. */
+ LOG_CELL(cell, LOGL_ERROR, "RTP stream of MGW failed.\n");
+ cell->rtps = NULL;
+ goto channel_fail;
+ break;
+ case VGCS_CELL_EV_RTP_STREAM_ADDR_AVAILABLE:
+ /* The RTP stream sends its peer. */
+ if (!osmo_sockaddr_str_is_nonzero(&cell->rtps->local)) {
+ LOG_CELL(cell, LOGL_ERROR, "Invalid RTP address received from MGW: " OSMO_SOCKADDR_STR_FMT "\n",
+ OSMO_SOCKADDR_STR_FMT_ARGS(&cell->rtps->local));
+ goto channel_fail;
+ }
+ LOG_CELL(cell, LOGL_DEBUG,
+ "MGW endpoint's RTP address available for the CI %s: " OSMO_SOCKADDR_STR_FMT " (osmux=%s:%d)\n",
+ rtp_direction_name(cell->rtps->dir), OSMO_SOCKADDR_STR_FMT_ARGS(&cell->rtps->local),
+ cell->rtps->use_osmux ? "yes" : "no", cell->rtps->local_osmux_cid);
+ /* Send VGCS/VBS ASSIGNMENT REQUEST to BSS */
+ LOG_CELL(cell, LOGL_DEBUG, "Sending VGCS/VBS ASSIGNMENT REQUEST towards BSS.\n");
+ tx_ran_msg = (struct ran_msg) {
+ .msg_type = RAN_MSG_VGCS_VBS_ASSIGN_REQ,
+ .vgcs_vbs_assign_req = {
+ /* For now we support GSM/FR V1 only. This shall be supported by all MS. */
+ .channel_type = {
+ .ch_indctr = GSM0808_CHAN_SPEECH,
+ .ch_rate_type = GSM0808_SPEECH_FULL_BM,
+ .perm_spch_len = 1,
+ .perm_spch[0] = GSM0808_PERM_FR1,
+ },
+ /* For now we want a channel without any delay. */
+ .ass_req = GSM0808_ASRQ_IMMEDIATE,
+ .callref = {
+ .sf = (cell->trans_type == TRANS_GCC),
+ },
+ /* We need to identify the cell only. */
+ .cell_identifier = {
+ .id_discr = CELL_IDENT_CI,
+ .id.ci = cell->cell_id,
+ },
+ .aoip_transport_layer_present = true,
+ .call_id_present = true,
+ .call_id = cell->call_id,
+ .codec_list_present = true,
+ .codec_list_msc_preferred = {
+ .len = 1,
+ .codec[0] = {
+ .fi = 1,
+ .type = GSM0808_SCT_FR1,
+ .cfg = 0,
+ },
+ },
+ },
+ };
+ osmo_store32be_ext(cell->callref >> 3, &tx_ran_msg.vgcs_vbs_assign_req.callref.call_ref_hi, 3);
+ tx_ran_msg.vgcs_vbs_assign_req.callref.call_ref_lo = cell->callref & 0x7;
+ osmo_sockaddr_str_to_sockaddr(&cell->rtps->local, &tx_ran_msg.vgcs_vbs_assign_req.aoip_transport_layer);
+ /* First message, so we must set "initial" to "true". */
+ ran_encode_and_send(fi, &tx_ran_msg, cell->conn, true);
+ break;
+ case VGCS_CELL_EV_RTP_STREAM_ESTABLISHED:
+ /* The RTP stream established. */
+ LOG_CELL(cell, LOGL_DEBUG, "RTP stream is established.\n");
+ break;
+ case VGCS_CELL_EV_ASSIGN_RES:
+ /* Receive VGCS/VBS ASSIGNMENT RESULT from BSS. */
+ LOG_CELL(cell, LOGL_DEBUG, "Received VGCS/VBS ASSIGNMENT RESULT from BSS.\n");
+ cell->assigned = true;
+ if (!rx_ran_msg->vgcs_vbs_assign_res.aoip_transport_layer_present
+ && !rx_ran_msg->vgcs_vbs_assign_res.codec_present
+ && !rx_ran_msg->vgcs_vbs_assign_res.call_id_present) {
+ LOG_CELL(cell, LOGL_ERROR, "Mandatory IEs missing.\n");
+ goto channel_fail;
+ }
+ /* Send remote peer to RTP stream. */
+ if (osmo_sockaddr_str_from_sockaddr(&ss, &rx_ran_msg->vgcs_vbs_assign_res.aoip_transport_layer)) {
+ LOG_CELL(cell, LOGL_ERROR, "Cannot RTP-CONNECT, invalid RTP IP:port in incoming MNCC "
+ "message\n");
+ goto channel_fail;
+ }
+ rtp_stream_set_remote_addr(cell->rtps, &ss);
+ /* Send remote codec to RTP stream. */
+ cm = codec_mapping_by_gsm0808_speech_codec_type(rx_ran_msg->vgcs_vbs_assign_res.codec_msc_chosen.type);
+ if (!cm) {
+ LOG_CELL(cell, LOGL_ERROR, "Chosen codec by BSC is not supported by MSC.\n");
+ goto channel_fail;
+ }
+ rtp_stream_set_one_codec(cell->rtps, &cm->sdp);
+ /* Set listening mode. */
+ rtp_stream_set_mode(cell->rtps, MGCP_CONN_SEND_ONLY);
+ /* Commit RTP stream. */
+ rc = rtp_stream_commit(cell->rtps);
+ if (rc < 0) {
+ LOG_CELL(cell, LOGL_ERROR, "Failed to commit parameters to RTP stream.\n");
+ goto channel_fail;
+ }
+ /* Change state. */
+ osmo_fsm_inst_state_chg(fi, VGCS_CELL_ST_ACTIVE, 0, 0);
+ /* Notify BSS FSM about channel activation. */
+ if (cell->bss)
+ osmo_fsm_inst_dispatch(cell->bss->fi, VGCS_BSS_EV_ACTIVE_OR_FAIL, NULL);
+ break;
+ case VGCS_CELL_EV_ASSIGN_FAIL:
+ /* Received VGCS/VBS ASSIGNMENT FAILURE from BSS. */
+ LOG_CELL(cell, LOGL_NOTICE, "Received VGCS/VBS ASSIGNMENT FAILURE from BSS.\n");
+channel_fail:
+ bss = cell->bss;
+ cell_clear(cell, GSM0808_CAUSE_PROTOCOL_ERROR_BETWEEN_BSS_AND_MSC);
+ /* Notify BSS FSM about channel failure. */
+ if (bss)
+ osmo_fsm_inst_dispatch(bss->fi, VGCS_BSS_EV_ACTIVE_OR_FAIL, NULL);
+ break;
+ case VGCS_CELL_EV_CLEAR:
+ /* The calling user process requested clearing of VGCS/VBS call. */
+ LOG_CELL(cell, LOGL_DEBUG, "Received clearing from BSS controling process.\n");
+ cell_clear(cell, GSM0808_CAUSE_CALL_CONTROL);
+ break;
+ case VGCS_CELL_EV_CLOSE:
+ /* The SCCP connection from the MSC has been closed. */
+ LOG_CELL(cell, LOGL_NOTICE, "Received SCCP connecting closing from MSC.\n");
+ if (cell->conn) {
+ cell->conn->vgcs.bss = NULL;
+ cell->conn = NULL;
+ }
+ cell_clear(cell, GSM0808_CAUSE_PROTOCOL_ERROR_BETWEEN_BSS_AND_MSC);
+ break;
+ default:
+ OSMO_ASSERT(false);
+ }
+}
+
+static void vgcs_cell_fsm_active(struct osmo_fsm_inst *fi, uint32_t event, void *data)
+{
+ struct vgcs_bss_cell *cell = fi->priv;
+
+ switch (event) {
+ case VGCS_CELL_EV_RTP_STREAM_GONE:
+ /* The RTP stream failed. */
+ LOG_CELL(cell, LOGL_ERROR, "RTP stream of MGW failed.\n");
+ cell->rtps = NULL;
+ cell_clear(cell, GSM0808_CAUSE_PROTOCOL_ERROR_BETWEEN_BSS_AND_MSC);
+ break;
+ case VGCS_CELL_EV_RTP_STREAM_ESTABLISHED:
+ /* The RTP stream established. */
+ LOG_CELL(cell, LOGL_DEBUG, "RTP stream is established.\n");
+ break;
+ case VGCS_CELL_EV_CLEAR:
+ /* The calling user process requested clearing of VGCS/VBS call. */
+ LOG_CELL(cell, LOGL_DEBUG, "Received clearing from BSS controling process.\n");
+ cell_clear(cell, GSM0808_CAUSE_CALL_CONTROL);
+ break;
+ case VGCS_CELL_EV_CLOSE:
+ /* The SCCP connection from the MSC has been closed. */
+ LOG_CELL(cell, LOGL_NOTICE, "Received SCCP connecting closing from MSC.\n");
+ if (cell->conn) {
+ cell->conn->vgcs.bss = NULL;
+ cell->conn = NULL;
+ }
+ cell_clear(cell, GSM0808_CAUSE_PROTOCOL_ERROR_BETWEEN_BSS_AND_MSC);
+ break;
+ default:
+ OSMO_ASSERT(false);
+ }
+}
+
+static void vgcs_cell_fsm_release(struct osmo_fsm_inst *fi, uint32_t event, void *data)
+{
+ struct vgcs_bss_cell *cell = fi->priv;
+
+ switch (event) {
+ case VGCS_CELL_EV_RTP_STREAM_GONE:
+ /* The RTP stream gone. */
+ LOG_CELL(cell, LOGL_ERROR, "RTP stream gone.\n");
+ cell->rtps = NULL;
+ /* Wait for RAN conn. */
+ if (cell->conn)
+ break;
+ cell_destroy(cell);
+ break;
+ case VGCS_CELL_EV_CLEAR:
+ case VGCS_CELL_EV_RELEASED:
+ if (event == VGCS_CELL_EV_CLEAR) {
+ /* The SCCP connection from the MSC has been closed while waiting for CLEAR COMPLETE. */
+ LOG_CELL(cell, LOGL_NOTICE, "Received SCCP closing collision.\n");
+ } else
+ LOG_CELL(cell, LOGL_DEBUG, "Received CLEAR COMPLETE from BSS, we are done!\n");
+ /* Wait for RTP stream. */
+ if (cell->rtps) {
+ /* close RAN conn */
+ if (cell->conn) {
+ cell->conn->vgcs.cell = NULL;
+ ran_conn_close(cell->conn);
+ cell->conn = NULL;
+ }
+ break;
+ }
+ cell_destroy(cell);
+ break;
+ default:
+ OSMO_ASSERT(false);
+ }
+}
+
+static const struct osmo_fsm_state vgcs_cell_fsm_states[] = {
+ [VGCS_CELL_ST_NULL] = {
+ .name = "NULL",
+ .in_event_mask = S(VGCS_CELL_EV_ASSIGN) |
+ S(VGCS_CELL_EV_CLEAR),
+ .out_state_mask = S(VGCS_CELL_ST_ASSIGNMENT),
+ .action = vgcs_cell_fsm_null,
+ },
+ [VGCS_CELL_ST_ASSIGNMENT] = {
+ .name = "ASSIGNMENT Sent",
+ .in_event_mask = S(VGCS_CELL_EV_RTP_STREAM_GONE) |
+ S(VGCS_CELL_EV_RTP_STREAM_ADDR_AVAILABLE) |
+ S(VGCS_CELL_EV_RTP_STREAM_ESTABLISHED) |
+ S(VGCS_CELL_EV_ASSIGN_RES) |
+ S(VGCS_CELL_EV_ASSIGN_FAIL) |
+ S(VGCS_CELL_EV_CLEAR) |
+ S(VGCS_CELL_EV_CLOSE),
+ .out_state_mask = S(VGCS_CELL_ST_ACTIVE) |
+ S(VGCS_CELL_ST_RELEASE),
+ .action = vgcs_cell_fsm_assignment,
+ },
+ [VGCS_CELL_ST_ACTIVE] = {
+ .name = "VGCS/VBS channel active",
+ .in_event_mask = S(VGCS_CELL_EV_RTP_STREAM_GONE) |
+ S(VGCS_CELL_EV_RTP_STREAM_ESTABLISHED) |
+ S(VGCS_CELL_EV_CLEAR) |
+ S(VGCS_CELL_EV_CLOSE),
+ .out_state_mask = S(VGCS_CELL_ST_RELEASE),
+ .action = vgcs_cell_fsm_active,
+ },
+ [VGCS_CELL_ST_RELEASE] = {
+ .name = "Releasing VGCS/VBS channel",
+ .in_event_mask = S(VGCS_CELL_EV_RTP_STREAM_GONE) |
+ S(VGCS_CELL_EV_CLEAR) |
+ S(VGCS_CELL_EV_RELEASED),
+ .out_state_mask = S(VGCS_CELL_ST_NULL),
+ .action = vgcs_cell_fsm_release,
+ },
+};
+
+static struct osmo_fsm vgcs_cell_fsm = {
+ .name = "vgcs_cell",
+ .states = vgcs_cell_fsm_states,
+ .num_states = ARRAY_SIZE(vgcs_cell_fsm_states),
+ .log_subsys = DASCI,
+ .event_names = vgcs_cell_fsm_event_names,
+};
+
+/* The BSS accepts VGCS/VBS channel assignment. */
+void vgcs_vbs_assign_result(struct vgcs_bss_cell *cell, const struct ran_msg *ran_msg)
+{
+ osmo_fsm_inst_dispatch(cell->fi, VGCS_CELL_EV_ASSIGN_RES, (void *)ran_msg);
+}
+
+/* The BSS refuses VGCS/VBS channel assignment. */
+void vgcs_vbs_assign_fail(struct vgcs_bss_cell *cell, const struct ran_msg *ran_msg)
+{
+ osmo_fsm_inst_dispatch(cell->fi, VGCS_CELL_EV_ASSIGN_FAIL, (void *)ran_msg);
+}
+
+/* BSS indicated that the channel has been released. */
+void vgcs_vbs_clear_req_channel(struct vgcs_bss_cell *cell, const struct ran_msg *ran_msg)
+{
+ LOG_CELL(cell, LOGL_DEBUG, "Received CLEAR REQUEST for resource controling channel from BSS.\n");
+ osmo_fsm_inst_dispatch(cell->fi, VGCS_CELL_EV_CLOSE, (void *)ran_msg);
+}
+
+/* BSS confirms the release of channel. */
+void vgcs_vbs_clear_cpl_channel(struct vgcs_bss_cell *cell, const struct ran_msg *ran_msg)
+{
+ LOG_CELL(cell, LOGL_DEBUG, "Received CLEAR COMPLETE for resource controling channel from BSS.\n");
+ osmo_fsm_inst_dispatch(cell->fi, VGCS_CELL_EV_RELEASED, (void *)ran_msg);
+}
+
+/*
+ * MGW endpoint FSM
+ */
+
+static const struct value_string vgcs_mgw_ep_fsm_event_names[] = {
+ OSMO_VALUE_STRING(VGCS_MGW_EP_EV_FREE),
+ OSMO_VALUE_STRING(VGCS_MGW_EP_EV_CLEAR),
+ { }
+};
+
+static void vgcs_mgw_ep_fsm_active(struct osmo_fsm_inst *fi, uint32_t event, void *data)
+{
+ struct vgcs_mgw_ep *mgw = fi->priv;
+ struct vgcs_bss_cell *cell, *cell2;
+ struct mgcp_client *mgcp_client;
+
+ switch (event) {
+ case VGCS_MGW_EP_EV_FREE:
+ LOGP(DASCI, LOGL_DEBUG, "MGW connection closed, removing all cell instances.\n");
+ llist_for_each_entry_safe(cell, cell2, &mgw->cell_list, list_mgw) {
+ if (cell->rtps)
+ cell->rtps->ci = NULL;
+ llist_del(&cell->list_mgw);
+ cell->mgw = NULL;
+ }
+ /* Put MGCP client back into MGW pool. */
+ mgcp_client = osmo_mgcpc_ep_client(mgw->mgw_ep);
+ mgcp_client_pool_put(mgcp_client);
+ /* Destroy this instance. */
+ osmo_fsm_inst_term_children(fi, OSMO_FSM_TERM_PARENT, NULL);
+ osmo_fsm_inst_term(fi, OSMO_FSM_TERM_REGULAR, NULL);
+ break;
+ case VGCS_MGW_EP_EV_CLEAR:
+ if (!llist_empty(&mgw->cell_list))
+ break;
+ LOGP(DASCI, LOGL_DEBUG, "Cell list of MGW instance is now empty, dropping.\n");
+ /* Destroy this instance. */
+ osmo_fsm_inst_term_children(fi, OSMO_FSM_TERM_PARENT, NULL);
+ osmo_fsm_inst_term(fi, OSMO_FSM_TERM_REGULAR, NULL);
+ break;
+ default:
+ OSMO_ASSERT(false);
+ }
+}
+
+static const struct osmo_fsm_state vgcs_mgw_ep_fsm_states[] = {
+ [VGCS_MGW_EP_ST_NULL] = {
+ .name = "NULL",
+ .out_state_mask = S(VGCS_MGW_EP_ST_ACTIVE),
+ },
+ [VGCS_MGW_EP_ST_ACTIVE] = {
+ .name = "MGW endpoint allocated",
+ .in_event_mask = S(VGCS_MGW_EP_EV_FREE) |
+ S(VGCS_MGW_EP_EV_CLEAR),
+ .out_state_mask = S(VGCS_MGW_EP_ST_NULL),
+ .action = vgcs_mgw_ep_fsm_active,
+ },
+};
+
+static struct osmo_fsm vgcs_mgw_ep_fsm = {
+ .name = "vgcs_mgw_ep",
+ .states = vgcs_mgw_ep_fsm_states,
+ .num_states = ARRAY_SIZE(vgcs_mgw_ep_fsm_states),
+ .log_subsys = DASCI,
+ .event_names = vgcs_mgw_ep_fsm_event_names,
+};
diff --git a/src/libmsc/msc_vty.c b/src/libmsc/msc_vty.c
index 0c07bc217..1f389f455 100644
--- a/src/libmsc/msc_vty.c
+++ b/src/libmsc/msc_vty.c
@@ -1,5 +1,5 @@
/* MSC interface to quagga VTY */
-/* (C) 2016-2018 by sysmocom s.m.f.c. GmbH <info@sysmocom.de>
+/* (C) 2016-2018 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>
* Based on OpenBSC interface to quagga VTY (libmsc/vty_interface_layer3.c)
* (C) 2009-2017 by Harald Welte <laforge@gnumonks.org>
* (C) 2009-2011 by Holger Hans Peter Freyther
@@ -33,9 +33,11 @@
#include <osmocom/gsm/protocol/gsm_08_58.h>
#include <osmocom/gsm/protocol/gsm_04_14.h>
#include <osmocom/gsm/protocol/gsm_08_08.h>
+#include <osmocom/gsm/gsm23236.h>
#include <osmocom/sigtran/sccp_helpers.h>
+#include <osmocom/vty/tdef_vty.h>
#include <osmocom/vty/command.h>
#include <osmocom/vty/logging.h>
#include <osmocom/vty/misc.h>
@@ -65,10 +67,12 @@
#include <osmocom/msc/sgs_vty.h>
#include <osmocom/msc/sccp_ran.h>
#include <osmocom/msc/ran_peer.h>
+#include <osmocom/msc/ran_infra.h>
+#include <osmocom/msc/asci_vty.h>
static struct gsm_network *gsmnet = NULL;
-struct cmd_node net_node = {
+static struct cmd_node net_node = {
GSMNET_NODE,
"%s(config-net)# ",
1,
@@ -128,27 +132,34 @@ DEFUN(cfg_net_mnc,
DEFUN(cfg_net_name_short,
cfg_net_name_short_cmd,
- "short name NAME",
+ "short name .NAME",
"Set the short GSM network name\n" NAME_CMD_STR NAME_STR)
{
- osmo_talloc_replace_string(gsmnet, &gsmnet->name_short, argv[0]);
+ if (gsmnet->name_short != NULL)
+ talloc_free(gsmnet->name_short);
+ gsmnet->name_short = argv_concat(argv, argc, 0);
return CMD_SUCCESS;
}
DEFUN(cfg_net_name_long,
cfg_net_name_long_cmd,
- "long name NAME",
+ "long name .NAME",
"Set the long GSM network name\n" NAME_CMD_STR NAME_STR)
{
- osmo_talloc_replace_string(gsmnet, &gsmnet->name_long, argv[0]);
+ if (gsmnet->name_long != NULL)
+ talloc_free(gsmnet->name_long);
+ gsmnet->name_long = argv_concat(argv, argc, 0);
return CMD_SUCCESS;
}
+#define ENCRYPTION_STR "Encryption options\n"
+
DEFUN(cfg_net_encryption,
cfg_net_encryption_cmd,
- "encryption a5 <0-3> [<0-3>] [<0-3>] [<0-3>]",
- "Encryption options\n"
- "GSM A5 Air Interface Encryption\n"
+ "encryption a5 <0-4> [<0-4>] [<0-4>] [<0-4>] [<0-4>]",
+ ENCRYPTION_STR
+ "GSM A5 Air Interface Encryption.\n"
+ "A5/n Algorithm Number\n"
"A5/n Algorithm Number\n"
"A5/n Algorithm Number\n"
"A5/n Algorithm Number\n"
@@ -163,6 +174,25 @@ DEFUN(cfg_net_encryption,
return CMD_SUCCESS;
}
+DEFUN(cfg_net_encryption_uea,
+ cfg_net_encryption_uea_cmd,
+ "encryption uea <0-2> [<0-2>] [<0-2>]",
+ ENCRYPTION_STR
+ "UTRAN (3G) encryption algorithms to allow: 0 = UEA0 (no encryption), 1 = UEA1, 2 = UEA2.\n"
+ "UEAn Algorithm Number\n"
+ "UEAn Algorithm Number\n"
+ "UEAn Algorithm Number\n"
+ )
+{
+ unsigned int i;
+
+ gsmnet->uea_encryption_mask = 0;
+ for (i = 0; i < argc; i++)
+ gsmnet->uea_encryption_mask |= (1 << atoi(argv[i]));
+
+ return CMD_SUCCESS;
+}
+
DEFUN(cfg_net_authentication,
cfg_net_authentication_cmd,
"authentication (optional|required)",
@@ -261,30 +291,65 @@ DEFUN(cfg_net_no_timezone,
return CMD_SUCCESS;
}
-DEFUN(cfg_net_per_loc_upd, cfg_net_per_loc_upd_cmd,
- "periodic location update <6-1530>",
- "Periodic Location Updating Interval\n"
- "Periodic Location Updating Interval\n"
- "Periodic Location Updating Interval\n"
- "Periodic Location Updating Interval in Minutes\n")
+/* NOTE: actually this is subscriber expiration timeout */
+#define PER_LOC_UPD_STR "Periodic Location Updating Interval\n"
+
+DEFUN_DEPRECATED(cfg_net_per_loc_upd, cfg_net_per_loc_upd_cmd,
+ "periodic location update <6-1530>",
+ PER_LOC_UPD_STR PER_LOC_UPD_STR PER_LOC_UPD_STR
+ "Periodic Location Updating Interval in Minutes\n")
+{
+ int minutes = atoi(argv[0]);
+ int rc;
+
+ vty_out(vty, "%% 'periodic location update' is now deprecated. "
+ "Use 'msc' / 'timer vlr T3212' to change subscriber expiration "
+ "timeout.%s", VTY_NEWLINE);
+
+ /* We used to double this value and add a minute when scheduling the
+ * expiration timer. Let's emulate the old behaviour here. */
+ minutes = minutes * 2 + 1;
+ vty_out(vty, "%% Setting T3212 to %d minutes "
+ "(emulating the old behaviour).%s",
+ minutes, VTY_NEWLINE);
+
+ rc = osmo_tdef_set(msc_tdefs_vlr, 3212, minutes, OSMO_TDEF_M);
+ return rc ? CMD_WARNING : CMD_SUCCESS;
+}
+
+DEFUN_DEPRECATED(cfg_net_no_per_loc_upd, cfg_net_no_per_loc_upd_cmd,
+ "no periodic location update",
+ NO_STR PER_LOC_UPD_STR PER_LOC_UPD_STR PER_LOC_UPD_STR)
+{
+ int rc;
+
+ vty_out(vty, "%% 'periodic location update' is now deprecated: "
+ "use 'timer T3212' to change subscriber expiration "
+ "timeout.%s", VTY_NEWLINE);
+
+ rc = osmo_tdef_set(msc_tdefs_vlr, 3212, 0, OSMO_TDEF_M);
+ return rc ? CMD_WARNING : CMD_SUCCESS;
+}
+
+DEFUN(cfg_net_call_wait, cfg_net_call_wait_cmd,
+ "call-waiting",
+ "Enable Call Waiting on the Network\n")
{
struct gsm_network *net = vty->index;
- net->t3212 = atoi(argv[0]) / 6;
+ net->call_waiting = true;
return CMD_SUCCESS;
}
-DEFUN(cfg_net_no_per_loc_upd, cfg_net_no_per_loc_upd_cmd,
- "no periodic location update",
+DEFUN(cfg_net_no_call_wait, cfg_net_no_call_wait_cmd,
+ "no call-waiting",
NO_STR
- "Periodic Location Updating Interval\n"
- "Periodic Location Updating Interval\n"
- "Periodic Location Updating Interval\n")
+ "Disable Call Waiting on the Network\n")
{
struct gsm_network *net = vty->index;
- net->t3212 = 0;
+ net->call_waiting = false;
return CMD_SUCCESS;
}
@@ -305,6 +370,13 @@ static int config_write_net(struct vty *vty)
vty_out(vty, " %u", i);
}
vty_out(vty, "%s", VTY_NEWLINE);
+
+ vty_out(vty, " encryption uea");
+ for (i = 0; i < 8; i++) {
+ if (gsmnet->uea_encryption_mask & (1 << i))
+ vty_out(vty, " %u", i);
+ }
+ vty_out(vty, "%s", VTY_NEWLINE);
vty_out(vty, " authentication %s%s",
gsmnet->authentication_required ? "required" : "optional", VTY_NEWLINE);
vty_out(vty, " rrlp mode %s%s", msc_rrlp_mode_name(gsmnet->rrlp.mode),
@@ -319,16 +391,11 @@ static int config_write_net(struct vty *vty)
vty_out(vty, " timezone %d %d%s",
gsmnet->tz.hr, gsmnet->tz.mn, VTY_NEWLINE);
}
- if (gsmnet->t3212 == 0)
- vty_out(vty, " no periodic location update%s", VTY_NEWLINE);
- else
- vty_out(vty, " periodic location update %u%s",
- gsmnet->t3212 * 6, VTY_NEWLINE);
- if (gsmnet->emergency.route_to_msisdn) {
- vty_out(vty, " emergency-call route-to-msisdn %s%s",
- gsmnet->emergency.route_to_msisdn, VTY_NEWLINE);
- }
+ if (!gsmnet->call_waiting)
+ vty_out(vty, " no call-waiting%s", VTY_NEWLINE);
+
+ mgcp_client_pool_config_write(vty, " ");
return CMD_SUCCESS;
}
@@ -350,6 +417,15 @@ DEFUN(cfg_msc, cfg_msc_cmd,
#define MNCC_GUARD_TIMEOUT_STR "Set global guard timer for mncc interface activity\n"
#define MNCC_GUARD_TIMEOUT_VALUE_STR "guard timer value (sec.)\n"
+DEFUN_DEPRECATED(cfg_sms_database, cfg_sms_database_cmd,
+ "sms-database PATH",
+ "Set the path to the MSC-SMS database file\n"
+ "Relative or absolute file system path to the database file (default is '" SMS_DEFAULT_DB_FILE_PATH "')\n")
+{
+ osmo_talloc_replace_string(gsmnet, &gsmnet->sms_queue_cfg->db_file_path, argv[0]);
+ return CMD_SUCCESS;
+}
+
DEFUN(cfg_msc_mncc_internal,
cfg_msc_mncc_internal_cmd,
"mncc internal",
@@ -412,6 +488,24 @@ DEFUN(cfg_msc_no_assign_tmsi, cfg_msc_no_assign_tmsi_cmd,
return CMD_SUCCESS;
}
+DEFUN_ATTR(cfg_msc_lcls_disable, cfg_msc_lcls_disable_cmd,
+ "lcls-permitted",
+ "Globally allow LCLS (Local Call Local Switch) for all calls on this MSC.\n",
+ CMD_ATTR_IMMEDIATE)
+{
+ gsmnet->lcls_permitted = true;
+ return CMD_SUCCESS;
+}
+
+DEFUN_ATTR(cfg_msc_no_lcls_disable, cfg_msc_no_lcls_disable_cmd,
+ "no lcls-permitted",
+ NO_STR "Globally disable LCLS (Local Call Local Switch) for all calls on this MSC.\n",
+ CMD_ATTR_IMMEDIATE)
+{
+ gsmnet->lcls_permitted = false;
+ return CMD_SUCCESS;
+}
+
DEFUN(cfg_msc_cs7_instance_a,
cfg_msc_cs7_instance_a_cmd,
"cs7-instance-a <0-15>",
@@ -477,7 +571,7 @@ DEFUN(cfg_msc_check_imei_rqd, cfg_msc_check_imei_rqd_cmd,
return CMD_SUCCESS;
}
-DEFUN(cfg_msc_paging_response_timer, cfg_msc_paging_response_timer_cmd,
+DEFUN_DEPRECATED(cfg_msc_paging_response_timer, cfg_msc_paging_response_timer_cmd,
"paging response-timer (default|<1-65535>)",
"Configure Paging\n"
"Set Paging timeout, the minimum time to pass between (unsuccessful) Pagings sent towards"
@@ -485,10 +579,22 @@ DEFUN(cfg_msc_paging_response_timer, cfg_msc_paging_response_timer_cmd,
"Set to default timeout (" OSMO_STRINGIFY_VAL(MSC_PAGING_RESPONSE_TIMER_DEFAULT) " seconds)\n"
"Set paging timeout in seconds\n")
{
- if (!strcmp(argv[1], "default"))
- gsmnet->paging_response_timer = MSC_PAGING_RESPONSE_TIMER_DEFAULT;
+ int rat;
+ int paging_response_timer;
+ if (!strcmp(argv[0], "default"))
+ paging_response_timer = MSC_PAGING_RESPONSE_TIMER_DEFAULT;
else
- gsmnet->paging_response_timer = atoi(argv[0]);
+ paging_response_timer = atoi(argv[0]);
+
+ for (rat = 0; rat < OSMO_RAT_COUNT; rat++) {
+ osmo_tdef_set(msc_ran_infra[rat].tdefs, -4, paging_response_timer, OSMO_TDEF_S);
+ }
+
+ vty_out(vty, "%% paging response-timer is deprecated.%s"
+ "%% All ran timer has been modified.%s"
+ "%% use 'timer <geran|utran|sgs> X4 %s' instead%s",
+ VTY_NEWLINE, VTY_NEWLINE, argv[0], VTY_NEWLINE);
+
return CMD_SUCCESS;
}
@@ -582,17 +688,91 @@ DEFUN(cfg_msc_osmux,
return CMD_SUCCESS;
}
+#define NRI_STR "Mapping of Network Resource Indicators to this MSC, for MSC pooling\n"
+DEFUN(cfg_msc_nri_bitlen, cfg_msc_nri_bitlen_cmd,
+ "nri bitlen <0-15>",
+ NRI_STR
+ "Set number of NRI bits to place in TMSI identities (always starting just after the most significant octet)\n"
+ "bit count (default: " OSMO_STRINGIFY_VAL(NRI_BITLEN_DEFAULT) ")\n")
+{
+ gsmnet->vlr->cfg.nri_bitlen = atoi(argv[0]);
+ return CMD_SUCCESS;
+}
+
+#define NRI_STR "Mapping of Network Resource Indicators to this MSC, for MSC pooling\n"
+#define NRI_ARGS_TO_STR_FMT "%s%s%s"
+#define NRI_ARGS_TO_STR_ARGS(ARGC, ARGV) ARGV[0], (ARGC>1)? ".." : "", (ARGC>1)? ARGV[1] : ""
+#define NRI_FIRST_LAST_STR "First value of the NRI value range, should not surpass the configured 'nri bitlen'.\n" \
+ "Last value of the NRI value range, should not surpass the configured 'nri bitlen' and be larger than the" \
+ " first value; if omitted, apply only the first value.\n"
+
+DEFUN(cfg_msc_nri_add, cfg_msc_nri_add_cmd,
+ "nri add <0-32767> [<0-32767>]",
+ NRI_STR "Add NRI value or range to the NRI mapping for this MSC\n"
+ NRI_FIRST_LAST_STR)
+{
+ const char *message;
+ int rc = osmo_nri_ranges_vty_add(&message, NULL, gsmnet->vlr->cfg.nri_ranges, argc, argv, gsmnet->vlr->cfg.nri_bitlen);
+ if (message) {
+ vty_out(vty, "%% %s: " NRI_ARGS_TO_STR_FMT, message, NRI_ARGS_TO_STR_ARGS(argc, argv));
+ }
+ if (rc < 0)
+ return CMD_WARNING;
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_msc_nri_del, cfg_msc_nri_del_cmd,
+ "nri del <0-32767> [<0-32767>]",
+ NRI_STR "Remove NRI value or range from the NRI mapping for this MSC\n"
+ NRI_FIRST_LAST_STR)
+{
+ const char *message;
+ int rc = osmo_nri_ranges_vty_del(&message, NULL, gsmnet->vlr->cfg.nri_ranges, argc, argv);
+ if (message) {
+ vty_out(vty, "%% %s: " NRI_ARGS_TO_STR_FMT, message, NRI_ARGS_TO_STR_ARGS(argc, argv));
+ }
+ if (rc < 0)
+ return CMD_WARNING;
+ return CMD_SUCCESS;
+}
+
+static void msc_write_nri(struct vty *vty)
+{
+ struct osmo_nri_range *r;
+
+ llist_for_each_entry(r, &gsmnet->vlr->cfg.nri_ranges->entries, entry) {
+ if (osmo_nri_range_validate(r, 255))
+ vty_out(vty, " %% INVALID RANGE:");
+ vty_out(vty, " nri add %d", r->first);
+ if (r->first != r->last)
+ vty_out(vty, " %d", r->last);
+ vty_out(vty, "%s", VTY_NEWLINE);
+ }
+}
+
+DEFUN(show_nri, show_nri_cmd,
+ "show nri",
+ SHOW_STR NRI_STR)
+{
+ msc_write_nri(vty);
+ return CMD_SUCCESS;
+}
+
static int config_write_msc(struct vty *vty)
{
vty_out(vty, "msc%s", VTY_NEWLINE);
if (gsmnet->mncc_sock_path)
vty_out(vty, " mncc external %s%s", gsmnet->mncc_sock_path, VTY_NEWLINE);
+ else
+ vty_out(vty, " mncc internal%s", VTY_NEWLINE);
vty_out(vty, " mncc guard-timeout %i%s",
gsmnet->mncc_guard_timeout, VTY_NEWLINE);
vty_out(vty, " ncss guard-timeout %i%s",
gsmnet->ncss_guard_timeout, VTY_NEWLINE);
vty_out(vty, " %sassign-tmsi%s",
gsmnet->vlr->cfg.assign_tmsi? "" : "no ", VTY_NEWLINE);
+ if (gsmnet->lcls_permitted)
+ vty_out(vty, " lcls-permitted%s", VTY_NEWLINE);
vty_out(vty, " cs7-instance-a %u%s", gsmnet->a.cs7_instance,
VTY_NEWLINE);
@@ -616,9 +796,6 @@ static int config_write_msc(struct vty *vty)
vty_out(vty, " check-imei-rqd 1%s", VTY_NEWLINE);
}
- if (gsmnet->paging_response_timer != MSC_PAGING_RESPONSE_TIMER_DEFAULT)
- vty_out(vty, " paging response-timer %u%s", gsmnet->paging_response_timer, VTY_NEWLINE);
-
if (gsmnet->emergency.route_to_msisdn) {
vty_out(vty, " emergency-call route-to-msisdn %s%s",
gsmnet->emergency.route_to_msisdn, VTY_NEWLINE);
@@ -644,6 +821,11 @@ static int config_write_msc(struct vty *vty)
neighbor_ident_vty_write(vty);
+ /* Timer introspection commands (generic osmo_tdef API) */
+ osmo_tdef_vty_groups_write(vty, " ");
+
+ msc_write_nri(vty);
+
return CMD_SUCCESS;
}
@@ -661,58 +843,6 @@ DEFUN(show_bsc, show_bsc_cmd,
return CMD_SUCCESS;
}
-/*
-_Subscriber_______________________________________ _LAC_ _RAN___________________ _MSC-A_state_________ _MSC-A_use_
-IMSI-123456789012345:MSISDN-12345:TMSI-0x12345678 1 GERAN-A-4294967295:A5-3 WAIT_CLASSMARK_UPDATE 2=cm_service,trans_cc
-IMSI-123456789012356:MSISDN-234567:TMSI-0x123ABC78 65535 UTRAN-Iu-4294967295 COMMUNICATING 2=cm_service,trans_sms
-IMSI-123456789012367:MSISDN-98712345890:TMSI-0xF.. - EUTRAN-SGs RELEASING 0=none
-IMSI-123456789012378:HONR-12345432101 2 MSC-901-700-423:9876 REMOTE_MSC_A 1=inter_msc
-*/
-static void vty_dump_one_conn(struct vty *vty, const struct msub *msub, int *idx)
-{
- struct msc_a *msc_a = msub_msc_a(msub);
- struct vlr_subscr *vsub = msub_vsub(msub);
- char buf[128];
-
- if (!(*idx))
- vty_out(vty,
- "_Subscriber_______________________________________ _LAC_ _RAN___________________"
- " _MSC-A_state_________ _MSC-A_use_%s",
- VTY_NEWLINE);
- (*idx)++;
-
- vty_out(vty, "%50s %5u %23s %20s %d=%s%s",
- vlr_subscr_short_name(msub_vsub(msub), 50),
- vsub ? vsub->cgi.lai.lac : 0,
- msub_ran_conn_name(msub),
- osmo_fsm_inst_state_name(msc_a->c.fi),
- osmo_use_count_total(&msc_a->use_count),
- osmo_use_count_name_buf(buf, sizeof(buf), &msc_a->use_count),
- VTY_NEWLINE);
-}
-
-DEFUN(show_msc_conn, show_msc_conn_cmd,
- "show connection", SHOW_STR "Subscriber Connections\n")
-{
- struct msub *msub;
- int idx = 0;
- llist_for_each_entry(msub, &msub_list, entry) {
- vty_dump_one_conn(vty, msub, &idx);
- }
- return CMD_SUCCESS;
-}
-
-static void vty_trans_hdr(struct vty *vty)
-{
- if (llist_empty(&gsmnet->trans_list))
- return;
-
- vty_out(vty,
- "_Subscriber_______________________________________ _RAN___________________"
- " _P__ TI CallRef_ _state_%s",
- VTY_NEWLINE);
-}
-
static const char *get_trans_proto_str(const struct gsm_trans *trans)
{
static char buf[256];
@@ -725,146 +855,326 @@ static const char *get_trans_proto_str(const struct gsm_trans *trans)
trans->cc.T308_second);
break;
case TRANS_SMS:
- snprintf(buf, sizeof(buf), "%s %s",
+ snprintf(buf, sizeof(buf), "CP:%s RP:%s",
gsm411_cp_state_name(trans->sms.smc_inst.cp_state),
gsm411_rp_state_name(trans->sms.smr_inst.rp_state));
break;
default:
- buf[0] = '\0';
- break;
+ return NULL;
}
return buf;
}
-static void vty_dump_one_trans(struct vty *vty, const struct gsm_trans *trans)
+/* Prefix a given format string with a given amount of spaces */
+#define MSC_VTY_DUMP(vty, offset, fmt, args...) \
+ vty_out(vty, "%*s" fmt, offset, "", ##args)
+
+/* Print value of a named flag, prefixed with a given amount of spaces */
+#define MSC_VTY_DUMP_FLAG(vty, offset, name, flag) \
+ MSC_VTY_DUMP(vty, offset + 2, "%s: %*s%s%s", \
+ name, 30 - (int)strlen(name), "", \
+ flag ? "true" : "false", \
+ VTY_NEWLINE)
+
+enum msc_vty_dump_flags {
+ MSC_VTY_DUMP_F_SUBSCR = (1 << 0),
+ MSC_VTY_DUMP_F_CONNECTION = (1 << 1),
+ MSC_VTY_DUMP_F_TRANSACTION = (1 << 2),
+};
+
+static void vty_dump_one_trans(struct vty *vty, const struct gsm_trans *trans,
+ int offset, uint8_t dump_flags)
{
- vty_out(vty, "%50s %23s %4s %02u %08x %s%s",
- vlr_subscr_short_name(msc_a_vsub(trans->msc_a), 50),
- msub_ran_conn_name(trans->msc_a->c.msub),
- trans_type_name(trans->type),
- trans->transaction_id,
- trans->callref,
- get_trans_proto_str(trans),
- VTY_NEWLINE);
+ const char *proto_str;
+
+ if (dump_flags & MSC_VTY_DUMP_F_SUBSCR) {
+ MSC_VTY_DUMP(vty, offset, "Subscriber: %s%s",
+ vlr_subscr_name(msc_a_vsub(trans->msc_a)),
+ VTY_NEWLINE);
+ }
+
+ if (dump_flags & MSC_VTY_DUMP_F_CONNECTION) {
+ /* (If msc_a exists, there *must* be a non-null msc_a->c.msub) */
+ MSC_VTY_DUMP(vty, offset, "RAN connection: %s%s",
+ trans->msc_a ? msub_ran_conn_name(trans->msc_a->c.msub)
+ : "(not established)",
+ VTY_NEWLINE);
+ }
+
+ MSC_VTY_DUMP(vty, offset, "Unique (global) identifier: 0x%08x%s",
+ trans->callref, VTY_NEWLINE);
+ MSC_VTY_DUMP(vty, offset, "GSM 04.07 identifier (%s): %u%s",
+ (trans->transaction_id & 0x08) ? "MO" : "MT",
+ trans->transaction_id,
+ VTY_NEWLINE);
+
+ MSC_VTY_DUMP(vty, offset, "Type: %s%s",
+ trans_type_name(trans->type),
+ VTY_NEWLINE);
+
+ if ((proto_str = get_trans_proto_str(trans))) {
+ MSC_VTY_DUMP(vty, offset, "Protocol specific: %s%s",
+ proto_str, VTY_NEWLINE);
+ }
}
-DEFUN(show_msc_transaction, show_msc_transaction_cmd,
- "show transaction", SHOW_STR "Transactions\n")
+static void vty_dump_one_conn(struct vty *vty, const struct msub *msub,
+ int offset, uint8_t dump_flags)
{
- struct gsm_trans *trans;
+ struct vlr_subscr *vsub = msub_vsub(msub);
+ struct msc_a *msc_a = msub_msc_a(msub);
+ char buf[128];
- vty_trans_hdr(vty);
- llist_for_each_entry(trans, &gsmnet->trans_list, entry)
- vty_dump_one_trans(vty, trans);
+ if (dump_flags & MSC_VTY_DUMP_F_SUBSCR) {
+ dump_flags = dump_flags &~ MSC_VTY_DUMP_F_SUBSCR;
+ MSC_VTY_DUMP(vty, offset, "Subscriber: %s%s",
+ vlr_subscr_name(vsub),
+ VTY_NEWLINE);
+ }
- return CMD_SUCCESS;
+ MSC_VTY_DUMP(vty, offset, "RAN connection: %s%s",
+ msub_ran_conn_name(msub),
+ VTY_NEWLINE);
+ MSC_VTY_DUMP(vty, offset, "RAN connection state: %s%s",
+ osmo_fsm_inst_state_name(msc_a->c.fi),
+ VTY_NEWLINE);
+
+ if (vsub) {
+ MSC_VTY_DUMP(vty, offset, "LAC / cell ID: %u / %u%s",
+ msc_a->via_cell.lai.lac, msc_a->via_cell.cell_identity,
+ VTY_NEWLINE);
+ }
+
+ MSC_VTY_DUMP(vty, offset, "Use count total: %d%s",
+ osmo_use_count_total(&msc_a->use_count),
+ VTY_NEWLINE);
+ MSC_VTY_DUMP(vty, offset, "Use count: %s%s",
+ osmo_use_count_name_buf(buf, sizeof(buf), &msc_a->use_count),
+ VTY_NEWLINE);
+
+ /* Transactions of this connection */
+ if (dump_flags & MSC_VTY_DUMP_F_TRANSACTION) {
+ struct gsm_trans *trans;
+ unsigned int i = 0;
+
+ /* Both subscriber and connection info is already printed */
+ dump_flags = dump_flags &~ MSC_VTY_DUMP_F_CONNECTION;
+ dump_flags = dump_flags &~ MSC_VTY_DUMP_F_SUBSCR;
+
+ llist_for_each_entry(trans, &gsmnet->trans_list, entry) {
+ if (trans->msc_a != msc_a)
+ continue;
+ MSC_VTY_DUMP(vty, offset, "Transaction #%02u: %s",
+ i++, VTY_NEWLINE);
+ vty_dump_one_trans(vty, trans, offset + 2, dump_flags);
+ }
+ }
}
-static void subscr_dump_full_vty(struct vty *vty, struct vlr_subscr *vsub)
+static void vty_dump_one_subscr(struct vty *vty, struct vlr_subscr *vsub,
+ int offset, uint8_t dump_flags)
{
- struct gsm_trans *trans;
+ struct timespec now;
char buf[128];
- if (strlen(vsub->name))
- vty_out(vty, " Name: '%s'%s", vsub->name, VTY_NEWLINE);
- if (strlen(vsub->msisdn))
- vty_out(vty, " Extension: %s%s", vsub->msisdn,
- VTY_NEWLINE);
- vty_out(vty, " LAC: %d/0x%x%s",
- vsub->cgi.lai.lac, vsub->cgi.lai.lac, VTY_NEWLINE);
- vty_out(vty, " RAN: %s%s",
- osmo_rat_type_name(vsub->cs.attached_via_ran), VTY_NEWLINE);
- vty_out(vty, " IMSI: %s%s", vsub->imsi, VTY_NEWLINE);
- if (vsub->tmsi != GSM_RESERVED_TMSI)
- vty_out(vty, " TMSI: %08X%s", vsub->tmsi,
- VTY_NEWLINE);
- if (vsub->tmsi_new != GSM_RESERVED_TMSI)
- vty_out(vty, " new TMSI: %08X%s", vsub->tmsi_new,
- VTY_NEWLINE);
- if (vsub->imei[0] != '\0')
- vty_out(vty, " IMEI: %s%s", vsub->imei, VTY_NEWLINE);
- if (vsub->imeisv[0] != '\0')
- vty_out(vty, " IMEISV: %s%s", vsub->imeisv, VTY_NEWLINE);
-
- vty_out(vty, " Flags: %s", VTY_NEWLINE);
- vty_out(vty, " IMSI detached: %s%s",
- vsub->imsi_detached_flag ? "true" : "false", VTY_NEWLINE);
- vty_out(vty, " Conf. by radio contact: %s%s",
- vsub->conf_by_radio_contact_ind ? "true" : "false",
- VTY_NEWLINE);
- vty_out(vty, " Subscr. data conf. by HLR: %s%s",
- vsub->sub_dataconf_by_hlr_ind ? "true" : "false", VTY_NEWLINE);
- vty_out(vty, " Location conf. in HLR: %s%s",
- vsub->loc_conf_in_hlr_ind ? "true" : "false", VTY_NEWLINE);
- vty_out(vty, " Subscriber dormant: %s%s",
- vsub->dormant_ind ? "true" : "false", VTY_NEWLINE);
- vty_out(vty, " Received cancel locataion: %s%s",
- vsub->cancel_loc_rx ? "true" : "false", VTY_NEWLINE);
- vty_out(vty, " MS not reachable: %s%s",
- vsub->ms_not_reachable_flag ? "true" : "false", VTY_NEWLINE);
- vty_out(vty, " LA allowed: %s%s",
- vsub->la_allowed ? "true" : "false", VTY_NEWLINE);
+ if (vsub->name[0] != '\0') {
+ MSC_VTY_DUMP(vty, offset, "Name: '%s'%s",
+ vsub->name, VTY_NEWLINE);
+ }
+ if (vsub->msisdn[0] != '\0') {
+ MSC_VTY_DUMP(vty, offset, "MSISDN: %s%s",
+ vsub->msisdn, VTY_NEWLINE);
+ }
+
+ MSC_VTY_DUMP(vty, offset, "LAC / cell ID: %u / %u%s",
+ vsub->cgi.lai.lac, vsub->cgi.cell_identity,
+ VTY_NEWLINE);
+ MSC_VTY_DUMP(vty, offset, "RAN type: %s%s",
+ osmo_rat_type_name(vsub->cs.attached_via_ran),
+ VTY_NEWLINE);
+
+ MSC_VTY_DUMP(vty, offset, "IMSI: %s%s",
+ vsub->imsi, VTY_NEWLINE);
+ if (vsub->tmsi != GSM_RESERVED_TMSI) {
+ MSC_VTY_DUMP(vty, offset, "TMSI: %08X%s",
+ vsub->tmsi, VTY_NEWLINE);
+ }
+ if (vsub->tmsi_new != GSM_RESERVED_TMSI) {
+ MSC_VTY_DUMP(vty, offset, "New TMSI: %08X%s",
+ vsub->tmsi_new, VTY_NEWLINE);
+ }
+ if (vsub->imei[0] != '\0') {
+ MSC_VTY_DUMP(vty, offset, "IMEI: %s%s",
+ vsub->imei, VTY_NEWLINE);
+ }
+ if (vsub->imeisv[0] != '\0') {
+ MSC_VTY_DUMP(vty, offset, "IMEISV: %s%s",
+ vsub->imeisv, VTY_NEWLINE);
+ }
+
+ MSC_VTY_DUMP(vty, offset, "Flags: %s", VTY_NEWLINE);
+ MSC_VTY_DUMP_FLAG(vty, offset, "IMSI detached",
+ vsub->imsi_detached_flag);
+ MSC_VTY_DUMP_FLAG(vty, offset, "Conf. by radio contact",
+ vsub->conf_by_radio_contact_ind);
+ MSC_VTY_DUMP_FLAG(vty, offset, "Subscr. data conf. by HLR",
+ vsub->sub_dataconf_by_hlr_ind);
+ MSC_VTY_DUMP_FLAG(vty, offset, "Location conf. in HLR",
+ vsub->loc_conf_in_hlr_ind);
+ MSC_VTY_DUMP_FLAG(vty, offset, "Subscriber dormant",
+ vsub->dormant_ind);
+ MSC_VTY_DUMP_FLAG(vty, offset, "Received cancel location",
+ vsub->cancel_loc_rx);
+ MSC_VTY_DUMP_FLAG(vty, offset, "MS not reachable",
+ vsub->ms_not_reachable_flag);
+ MSC_VTY_DUMP_FLAG(vty, offset, "LA allowed",
+ vsub->la_allowed);
if (vsub->last_tuple) {
struct vlr_auth_tuple *t = vsub->last_tuple;
- vty_out(vty, " A3A8 last tuple (used %d times):%s",
- t->use_count, VTY_NEWLINE);
- vty_out(vty, " seq # : %d%s",
- t->key_seq, VTY_NEWLINE);
- vty_out(vty, " RAND : %s%s",
- osmo_hexdump(t->vec.rand, sizeof(t->vec.rand)),
- VTY_NEWLINE);
- vty_out(vty, " SRES : %s%s",
- osmo_hexdump(t->vec.sres, sizeof(t->vec.sres)),
- VTY_NEWLINE);
- vty_out(vty, " Kc : %s%s",
- osmo_hexdump(t->vec.kc, sizeof(t->vec.kc)),
- VTY_NEWLINE);
+ MSC_VTY_DUMP(vty, offset, "A3A8 last tuple (used %d times): %s",
+ t->use_count, VTY_NEWLINE);
+ MSC_VTY_DUMP(vty, offset + 2, "seq # : %d%s",
+ t->key_seq, VTY_NEWLINE);
+ MSC_VTY_DUMP(vty, offset + 2, "RAND : %s%s",
+ osmo_hexdump(t->vec.rand, sizeof(t->vec.rand)),
+ VTY_NEWLINE);
+ MSC_VTY_DUMP(vty, offset + 2, "SRES : %s%s",
+ osmo_hexdump(t->vec.sres, sizeof(t->vec.sres)),
+ VTY_NEWLINE);
+ MSC_VTY_DUMP(vty, offset + 2, "Kc : %s%s",
+ osmo_hexdump(t->vec.kc, sizeof(t->vec.kc)),
+ VTY_NEWLINE);
}
- vty_out(vty, " Paging: %s paging for %d requests%s",
- vsub->cs.is_paging ? "is" : "not",
- llist_count(&vsub->cs.requests),
- VTY_NEWLINE);
-
- /* SGs related */
- vty_out(vty, " SGs-state: %s%s",
- osmo_fsm_inst_state_name(vsub->sgs_fsm), VTY_NEWLINE);
- if (strlen(vsub->sgs.mme_name))
- vty_out(vty, " SGs-MME: %s%s", vsub->sgs.mme_name, VTY_NEWLINE);
- else
- vty_out(vty, " SGs-MME: (none)%s", VTY_NEWLINE);
+ if (!vlr_timer(vsub->vlr, 3212)) {
+ MSC_VTY_DUMP(vty, offset, "Expires: never (T3212 is disabled)%s",
+ VTY_NEWLINE);
+ } else if (vsub->expire_lu == VLR_SUBSCRIBER_NO_EXPIRATION) {
+ MSC_VTY_DUMP(vty, offset, "Expires: never%s",
+ VTY_NEWLINE);
+ } else if (osmo_clock_gettime(CLOCK_MONOTONIC, &now) == 0) {
+ MSC_VTY_DUMP(vty, offset, "Expires: in %ld min %ld sec%s",
+ (vsub->expire_lu - now.tv_sec) / 60,
+ (vsub->expire_lu - now.tv_sec) % 60,
+ VTY_NEWLINE);
+ }
- vty_out(vty, " Use: %s%s", osmo_use_count_name_buf(buf, sizeof(buf), &vsub->use_count), VTY_NEWLINE);
+ MSC_VTY_DUMP(vty, offset, "Paging: %s paging for %d requests%s",
+ vsub->cs.is_paging ? "is" : "not",
+ llist_count(&vsub->cs.requests),
+ VTY_NEWLINE);
- /* Connection */
- if (vsub->msc_conn_ref) {
+ /* SGs related */
+ MSC_VTY_DUMP(vty, offset, "SGs-state: %s%s",
+ osmo_fsm_inst_state_name(vsub->sgs_fsm),
+ VTY_NEWLINE);
+ MSC_VTY_DUMP(vty, offset, "SGs-MME: %s%s",
+ vsub->sgs.mme_name[0] != '\0' ? vsub->sgs.mme_name : "(none)",
+ VTY_NEWLINE);
+
+ MSC_VTY_DUMP(vty, offset, "Use count total: %d%s",
+ osmo_use_count_total(&vsub->use_count),
+ VTY_NEWLINE);
+ MSC_VTY_DUMP(vty, offset, "Use count: %s%s",
+ osmo_use_count_name_buf(buf, sizeof(buf), &vsub->use_count),
+ VTY_NEWLINE);
+
+ /* Connection(s) and/or transactions of this subscriber */
+ if (dump_flags & MSC_VTY_DUMP_F_CONNECTION) {
struct msub *msub = msub_for_vsub(vsub);
- int idx = 0;
- if (msub) {
- vty_dump_one_conn(vty, msub, &idx);
+ if (!msub)
+ return;
+
+ /* Subscriber info is already printed */
+ dump_flags = dump_flags &~ MSC_VTY_DUMP_F_SUBSCR;
+
+ MSC_VTY_DUMP(vty, offset, "Connection: %s", VTY_NEWLINE);
+ vty_dump_one_conn(vty, msub, offset + 2, dump_flags);
+ } else if (dump_flags & MSC_VTY_DUMP_F_TRANSACTION) {
+ struct gsm_trans *trans;
+ unsigned int i = 0;
+
+ /* Subscriber info is already printed */
+ dump_flags = dump_flags &~ MSC_VTY_DUMP_F_SUBSCR;
+ /* Do not print connection info, but mention it */
+ dump_flags |= MSC_VTY_DUMP_F_CONNECTION;
+
+ llist_for_each_entry(trans, &gsmnet->trans_list, entry) {
+ if (trans->vsub != vsub)
+ continue;
+ MSC_VTY_DUMP(vty, offset, "Transaction #%02u: %s",
+ i++, VTY_NEWLINE);
+ vty_dump_one_trans(vty, trans, offset + 2, dump_flags);
}
}
+}
+
+DEFUN(show_msc_transaction, show_msc_transaction_cmd,
+ "show transaction",
+ SHOW_STR "Transactions\n")
+{
+ struct gsm_trans *trans;
+ uint8_t flags = 0x00;
+ unsigned int i = 0;
+
+ flags |= MSC_VTY_DUMP_F_CONNECTION;
+ flags |= MSC_VTY_DUMP_F_SUBSCR;
- /* Transactions */
- vty_trans_hdr(vty);
llist_for_each_entry(trans, &gsmnet->trans_list, entry) {
- if (trans->vsub != vsub)
- continue;
- vty_dump_one_trans(vty, trans);
+ vty_out(vty, " Transaction #%02u: %s", i++, VTY_NEWLINE);
+ vty_dump_one_trans(vty, trans, 4, flags);
+ }
+
+ return CMD_SUCCESS;
+}
+
+DEFUN(show_msc_conn, show_msc_conn_cmd,
+ "show connection [trans]",
+ SHOW_STR "Subscriber Connections\n"
+ "Show child transactions of each connection\n")
+{
+ uint8_t flags = 0x00;
+ unsigned int i = 0;
+ struct msub *msub;
+
+ if (argc > 0)
+ flags |= MSC_VTY_DUMP_F_TRANSACTION;
+ flags |= MSC_VTY_DUMP_F_SUBSCR;
+
+ llist_for_each_entry(msub, &msub_list, entry) {
+ vty_out(vty, " Connection #%02u: %s", i++, VTY_NEWLINE);
+ vty_dump_one_conn(vty, msub, 4, flags);
}
+
+ return CMD_SUCCESS;
}
+#define SUBSCR_FLAGS "[(conn|trans|conn+trans)]"
+#define SUBSCR_FLAGS_HELP \
+ "Show child connections\n" \
+ "Show child transactions\n" \
+ "Show child connections and transactions\n"
+
/* Subscriber */
-DEFUN(show_subscr_cache,
- show_subscr_cache_cmd,
- "show subscriber cache",
+DEFUN(show_subscr_cache, show_subscr_cache_cmd,
+ "show subscriber cache " SUBSCR_FLAGS,
SHOW_STR "Show information about subscribers\n"
- "Display contents of subscriber cache\n")
+ "Display contents of subscriber cache\n"
+ SUBSCR_FLAGS_HELP)
{
struct vlr_subscr *vsub;
- int count = 0;
+ unsigned int count = 0;
+ uint8_t flags = 0x00;
+ unsigned int i = 0;
+
+ if (argc && strcmp(argv[0], "conn") == 0)
+ flags |= MSC_VTY_DUMP_F_CONNECTION;
+ else if (argc && strcmp(argv[0], "trans") == 0)
+ flags |= MSC_VTY_DUMP_F_TRANSACTION;
+ else if (argc && strcmp(argv[0], "conn+trans") == 0)
+ flags |= MSC_VTY_DUMP_F_CONNECTION | MSC_VTY_DUMP_F_TRANSACTION;
llist_for_each_entry(vsub, &gsmnet->vlr->subscribers, list) {
if (++count > 100) {
@@ -872,8 +1182,8 @@ DEFUN(show_subscr_cache,
" stopping here.%s", count-1, VTY_NEWLINE);
break;
}
- vty_out(vty, " Subscriber:%s", VTY_NEWLINE);
- subscr_dump_full_vty(vty, vsub);
+ vty_out(vty, " Subscriber #%02u: %s", i++, VTY_NEWLINE);
+ vty_dump_one_subscr(vty, vsub, 4, flags);
}
return CMD_SUCCESS;
@@ -945,6 +1255,11 @@ static int _send_sms_str(struct vlr_subscr *receiver,
struct gsm_sms *sms;
sms = sms_from_text(receiver, sender_msisdn, 0, str);
+ if (!sms) {
+ LOGP(DLSMS, LOGL_ERROR, "Failed to allocate SMS\n");
+ return CMD_WARNING;
+ }
+
sms->protocol_id = tp_pid;
/* store in database for the queue */
@@ -982,14 +1297,14 @@ static struct vlr_subscr *get_vsub_by_argv(struct gsm_network *gsmnet,
"Legacy alias for 'imsi'\n" \
"Identifier for the subscriber\n"
-DEFUN(show_subscr,
- show_subscr_cmd,
- "show subscriber " SUBSCR_TYPES " ID",
- SHOW_STR SUBSCR_HELP)
+DEFUN(show_subscr, show_subscr_cmd,
+ "show subscriber " SUBSCR_TYPES " ID " SUBSCR_FLAGS,
+ SHOW_STR SUBSCR_HELP SUBSCR_FLAGS_HELP)
{
- struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0],
- argv[1]);
+ struct vlr_subscr *vsub;
+ uint8_t flags = 0x00;
+ vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
if (!vsub) {
vty_out(vty, "%% No subscriber found for %s %s%s",
argv[0], argv[1], VTY_NEWLINE);
@@ -1001,18 +1316,25 @@ DEFUN(show_subscr,
* this, and since this is not multi-threaded, this vlr_subscr_put() cannot possibly reach a count of 0. */
vlr_subscr_put(vsub, VSUB_USE_VTY);
- subscr_dump_full_vty(vty, vsub);
+ if (argc > 2 && strcmp(argv[2], "conn") == 0)
+ flags |= MSC_VTY_DUMP_F_CONNECTION;
+ else if (argc > 2 && strcmp(argv[2], "trans") == 0)
+ flags |= MSC_VTY_DUMP_F_TRANSACTION;
+ else if (argc > 2 && strcmp(argv[2], "conn+trans") == 0)
+ flags |= MSC_VTY_DUMP_F_CONNECTION | MSC_VTY_DUMP_F_TRANSACTION;
+
+ vty_out(vty, " Subscriber: %s", VTY_NEWLINE);
+ vty_dump_one_subscr(vty, vsub, 4, flags);
return CMD_SUCCESS;
}
-DEFUN(subscriber_create,
- subscriber_create_cmd,
- "subscriber create imsi ID",
- "Operations on a Subscriber\n" \
- "Create new subscriber\n" \
- "Identify the subscriber by his IMSI\n" \
- "Identifier for the subscriber\n")
+DEFUN_DEPRECATED(subscriber_create, subscriber_create_cmd,
+ "subscriber create imsi ID",
+ "Operations on a Subscriber\n"
+ "Create new subscriber\n"
+ "Identify the subscriber by his IMSI\n"
+ "Identifier for the subscriber\n")
{
vty_out(vty, "%% 'subscriber create' now needs to be done at osmo-hlr%s",
VTY_NEWLINE);
@@ -1413,6 +1735,7 @@ DEFUN(subscriber_mstest_close,
gsm0414_tx_close_tch_loop_cmd(msc_a, loop_mode);
+ vlr_subscr_put(vsub, VSUB_USE_VTY);
return CMD_SUCCESS;
}
@@ -1441,6 +1764,7 @@ DEFUN(subscriber_mstest_open,
gsm0414_tx_open_loop_cmd(msc_a);
+ vlr_subscr_put(vsub, VSUB_USE_VTY);
return CMD_SUCCESS;
}
@@ -1500,94 +1824,49 @@ DEFUN(show_stats,
SHOW_STR "Display network statistics\n")
{
vty_out(vty, "Location Update : %" PRIu64 " attach, %" PRIu64 " normal, %" PRIu64 " periodic%s",
- gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_ATTACH].current,
- gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_NORMAL].current,
- gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_PERIODIC].current,
+ rate_ctr_group_get_ctr(gsmnet->msc_ctrs, MSC_CTR_LOC_UPDATE_TYPE_ATTACH)->current,
+ rate_ctr_group_get_ctr(gsmnet->msc_ctrs, MSC_CTR_LOC_UPDATE_TYPE_NORMAL)->current,
+ rate_ctr_group_get_ctr(gsmnet->msc_ctrs, MSC_CTR_LOC_UPDATE_TYPE_PERIODIC)->current,
VTY_NEWLINE);
vty_out(vty, "IMSI Detach Indications : %" PRIu64 "%s",
- gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_DETACH].current,
+ rate_ctr_group_get_ctr(gsmnet->msc_ctrs, MSC_CTR_LOC_UPDATE_TYPE_DETACH)->current,
VTY_NEWLINE);
vty_out(vty, "Location Updating Results: %" PRIu64 " completed, %" PRIu64 " failed%s",
- gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_COMPLETED].current,
- gsmnet->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_FAILED].current,
+ rate_ctr_group_get_ctr(gsmnet->msc_ctrs, MSC_CTR_LOC_UPDATE_COMPLETED)->current,
+ rate_ctr_group_get_ctr(gsmnet->msc_ctrs, MSC_CTR_LOC_UPDATE_FAILED)->current,
VTY_NEWLINE);
vty_out(vty, "SMS MO : %" PRIu64 " submitted, %" PRIu64 " no receiver%s",
- gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_SUBMITTED].current,
- gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_NO_RECEIVER].current,
+ rate_ctr_group_get_ctr(gsmnet->msc_ctrs, MSC_CTR_SMS_SUBMITTED)->current,
+ rate_ctr_group_get_ctr(gsmnet->msc_ctrs, MSC_CTR_SMS_NO_RECEIVER)->current,
VTY_NEWLINE);
vty_out(vty, "SMS MT : %" PRIu64 " delivered, %" PRIu64 " no memory, %" PRIu64 " other error%s",
- gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_DELIVERED].current,
- gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_RP_ERR_MEM].current,
- gsmnet->msc_ctrs->ctr[MSC_CTR_SMS_RP_ERR_OTHER].current,
+ rate_ctr_group_get_ctr(gsmnet->msc_ctrs, MSC_CTR_SMS_DELIVERED)->current,
+ rate_ctr_group_get_ctr(gsmnet->msc_ctrs, MSC_CTR_SMS_RP_ERR_MEM)->current,
+ rate_ctr_group_get_ctr(gsmnet->msc_ctrs, MSC_CTR_SMS_RP_ERR_OTHER)->current,
VTY_NEWLINE);
vty_out(vty, "MO Calls : %" PRIu64 " setup, %" PRIu64 " connect ack%s",
- gsmnet->msc_ctrs->ctr[MSC_CTR_CALL_MO_SETUP].current,
- gsmnet->msc_ctrs->ctr[MSC_CTR_CALL_MO_CONNECT_ACK].current,
+ rate_ctr_group_get_ctr(gsmnet->msc_ctrs, MSC_CTR_CALL_MO_SETUP)->current,
+ rate_ctr_group_get_ctr(gsmnet->msc_ctrs, MSC_CTR_CALL_MO_CONNECT_ACK)->current,
VTY_NEWLINE);
vty_out(vty, "MT Calls : %" PRIu64 " setup, %" PRIu64 " connect%s",
- gsmnet->msc_ctrs->ctr[MSC_CTR_CALL_MT_SETUP].current,
- gsmnet->msc_ctrs->ctr[MSC_CTR_CALL_MT_CONNECT].current,
+ rate_ctr_group_get_ctr(gsmnet->msc_ctrs, MSC_CTR_CALL_MT_SETUP)->current,
+ rate_ctr_group_get_ctr(gsmnet->msc_ctrs, MSC_CTR_CALL_MT_CONNECT)->current,
VTY_NEWLINE);
vty_out(vty, "MO NC SS/USSD : %" PRIu64 " requests, %" PRIu64 " established, %" PRIu64 " rejected%s",
- gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MO_REQUESTS].current,
- gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MO_ESTABLISHED].current,
- gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MO_REQUESTS].current
- - gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MO_ESTABLISHED].current,
+ rate_ctr_group_get_ctr(gsmnet->msc_ctrs, MSC_CTR_NC_SS_MO_REQUESTS)->current,
+ rate_ctr_group_get_ctr(gsmnet->msc_ctrs, MSC_CTR_NC_SS_MO_ESTABLISHED)->current,
+ rate_ctr_group_get_ctr(gsmnet->msc_ctrs, MSC_CTR_NC_SS_MO_REQUESTS)->current
+ - rate_ctr_group_get_ctr(gsmnet->msc_ctrs, MSC_CTR_NC_SS_MO_ESTABLISHED)->current,
VTY_NEWLINE);
vty_out(vty, "MT NC SS/USSD : %" PRIu64 " requests, %" PRIu64 " established, %" PRIu64 " rejected%s",
- gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MT_REQUESTS].current,
- gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MT_ESTABLISHED].current,
- gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MT_REQUESTS].current
- - gsmnet->msc_ctrs->ctr[MSC_CTR_NC_SS_MT_ESTABLISHED].current,
+ rate_ctr_group_get_ctr(gsmnet->msc_ctrs, MSC_CTR_NC_SS_MT_REQUESTS)->current,
+ rate_ctr_group_get_ctr(gsmnet->msc_ctrs, MSC_CTR_NC_SS_MT_ESTABLISHED)->current,
+ rate_ctr_group_get_ctr(gsmnet->msc_ctrs, MSC_CTR_NC_SS_MT_REQUESTS)->current
+ - rate_ctr_group_get_ctr(gsmnet->msc_ctrs, MSC_CTR_NC_SS_MT_ESTABLISHED)->current,
VTY_NEWLINE);
return CMD_SUCCESS;
}
-DEFUN(show_smsqueue,
- show_smsqueue_cmd,
- "show sms-queue",
- SHOW_STR "Display SMSqueue statistics\n")
-{
- sms_queue_stats(gsmnet->sms_queue, vty);
- return CMD_SUCCESS;
-}
-
-DEFUN(smsqueue_trigger,
- smsqueue_trigger_cmd,
- "sms-queue trigger",
- "SMS Queue\n" "Trigger sending messages\n")
-{
- sms_queue_trigger(gsmnet->sms_queue);
- return CMD_SUCCESS;
-}
-
-DEFUN(smsqueue_max,
- smsqueue_max_cmd,
- "sms-queue max-pending <1-500>",
- "SMS Queue\n" "SMS to deliver in parallel\n" "Amount\n")
-{
- sms_queue_set_max_pending(gsmnet->sms_queue, atoi(argv[0]));
- return CMD_SUCCESS;
-}
-
-DEFUN(smsqueue_clear,
- smsqueue_clear_cmd,
- "sms-queue clear",
- "SMS Queue\n" "Clear the queue of pending SMS\n")
-{
- sms_queue_clear(gsmnet->sms_queue);
- return CMD_SUCCESS;
-}
-
-DEFUN(smsqueue_fail,
- smsqueue_fail_cmd,
- "sms-queue max-failure <1-500>",
- "SMS Queue\n" "Maximum amount of delivery failures\n" "Amount\n")
-{
- sms_queue_set_max_failure(gsmnet->sms_queue, atoi(argv[0]));
- return CMD_SUCCESS;
-}
-
DEFUN(cfg_mncc_int, cfg_mncc_int_cmd,
"mncc-int", "Configure internal MNCC handler")
@@ -1714,11 +1993,11 @@ DEFUN(cfg_hlr_ipa_name,
"Set the IPA name of this MSC\n"
"A unique name for this MSC. For example: PLMN + redundancy server number: MSC-901-70-0. "
"This name is used for GSUP routing and must be set if more than one MSC is connected to the HLR. "
- "The default is 'MSC-00-00-00-00-00-00'.\n")
+ "The default is 'unnamed-MSC'.\n")
{
if (vty->type != VTY_FILE) {
vty_out(vty, "The IPA name cannot be changed at run-time; "
- "It can only be set in the configuraton file.%s", VTY_NEWLINE);
+ "It can only be set in the configuration file.%s", VTY_NEWLINE);
return CMD_WARNING;
}
@@ -1752,6 +2031,7 @@ void msc_vty_init(struct gsm_network *msc_network)
install_element(GSMNET_NODE, &cfg_net_name_short_cmd);
install_element(GSMNET_NODE, &cfg_net_name_long_cmd);
install_element(GSMNET_NODE, &cfg_net_encryption_cmd);
+ install_element(GSMNET_NODE, &cfg_net_encryption_uea_cmd);
install_element(GSMNET_NODE, &cfg_net_authentication_cmd);
install_element(GSMNET_NODE, &cfg_net_rrlp_mode_cmd);
install_element(GSMNET_NODE, &cfg_net_mm_info_cmd);
@@ -1760,10 +2040,17 @@ void msc_vty_init(struct gsm_network *msc_network)
install_element(GSMNET_NODE, &cfg_net_no_timezone_cmd);
install_element(GSMNET_NODE, &cfg_net_per_loc_upd_cmd);
install_element(GSMNET_NODE, &cfg_net_no_per_loc_upd_cmd);
+ install_element(GSMNET_NODE, &cfg_net_call_wait_cmd);
+ install_element(GSMNET_NODE, &cfg_net_no_call_wait_cmd);
+ mgcp_client_pool_vty_init(GSMNET_NODE, MGW_NODE, NULL, msc_network->mgw.mgw_pool);
+
install_element(CONFIG_NODE, &cfg_msc_cmd);
install_node(&msc_node, config_write_msc);
+ install_element(MSC_NODE, &cfg_sms_database_cmd);
install_element(MSC_NODE, &cfg_msc_assign_tmsi_cmd);
+ install_element(MSC_NODE, &cfg_msc_lcls_disable_cmd);
+ install_element(MSC_NODE, &cfg_msc_no_lcls_disable_cmd);
install_element(MSC_NODE, &cfg_msc_mncc_internal_cmd);
install_element(MSC_NODE, &cfg_msc_mncc_external_cmd);
install_element(MSC_NODE, &cfg_msc_mncc_guard_timeout_cmd);
@@ -1781,14 +2068,24 @@ void msc_vty_init(struct gsm_network *msc_network)
install_element(MSC_NODE, &cfg_msc_no_sms_over_gsup_cmd);
install_element(MSC_NODE, &cfg_msc_osmux_cmd);
install_element(MSC_NODE, &cfg_msc_handover_number_range_cmd);
+ install_element(MSC_NODE, &cfg_msc_nri_bitlen_cmd);
+ install_element(MSC_NODE, &cfg_msc_nri_add_cmd);
+ install_element(MSC_NODE, &cfg_msc_nri_del_cmd);
neighbor_ident_vty_init(msc_network);
- mgcp_client_vty_init(msc_network, MSC_NODE, &msc_network->mgw.conf);
+ /* Timer configuration commands (generic osmo_tdef API) */
+ osmo_tdef_vty_groups_init(MSC_NODE, msc_tdef_group);
+
+ /* Deprecated: Old MGCP config without pooling support in MSC node: */
+ mgcp_client_vty_init(msc_network, MSC_NODE, msc_network->mgw.conf);
+
#ifdef BUILD_IU
ranap_iu_vty_init(MSC_NODE, (enum ranap_nsap_addr_enc*)&msc_network->iu.rab_assign_addr_enc);
#endif
sgs_vty_init();
+ smsc_vty_init(msc_network);
+ asci_vty_init(msc_network);
osmo_fsm_vty_add_cmds();
@@ -1799,6 +2096,7 @@ void msc_vty_init(struct gsm_network *msc_network)
install_element_ve(&show_bsc_cmd);
install_element_ve(&show_msc_conn_cmd);
install_element_ve(&show_msc_transaction_cmd);
+ install_element_ve(&show_nri_cmd);
install_element_ve(&sms_send_pend_cmd);
install_element_ve(&sms_delete_expired_cmd);
@@ -1813,14 +2111,9 @@ void msc_vty_init(struct gsm_network *msc_network)
install_element_ve(&subscriber_mstest_open_cmd);
install_element_ve(&subscriber_paging_cmd);
install_element_ve(&show_stats_cmd);
- install_element_ve(&show_smsqueue_cmd);
install_element_ve(&logging_fltr_imsi_cmd);
install_element(ENABLE_NODE, &ena_subscr_expire_cmd);
- install_element(ENABLE_NODE, &smsqueue_trigger_cmd);
- install_element(ENABLE_NODE, &smsqueue_max_cmd);
- install_element(ENABLE_NODE, &smsqueue_clear_cmd);
- install_element(ENABLE_NODE, &smsqueue_fail_cmd);
install_element(ENABLE_NODE, &subscriber_send_pending_sms_cmd);
install_element(ENABLE_NODE, &subscriber_sms_delete_all_cmd);
diff --git a/src/libmsc/msub.c b/src/libmsc/msub.c
index 2021ed827..ac93665a7 100644
--- a/src/libmsc/msub.c
+++ b/src/libmsc/msub.c
@@ -1,6 +1,6 @@
/* Manage all MSC roles of a connected subscriber (MSC-A, MSC-I, MSC-T) */
/*
- * (C) 2019 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de>
+ * (C) 2019 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
* All Rights Reserved
*
* SPDX-License-Identifier: AGPL-3.0+
@@ -488,9 +488,9 @@ static void _msub_update_id(struct msub *msub, const char *subscr_name)
}
/* Compose an ID almost like gsm48_mi_to_string(), but print the MI type along, and print a TMSI as hex. */
-void msub_update_id_from_mi(struct msub *msub, const uint8_t mi[], uint8_t mi_len)
+void msub_update_id_from_mi(struct msub *msub, const struct osmo_mobile_identity *mi)
{
- _msub_update_id(msub, osmo_mi_name(mi, mi_len));
+ _msub_update_id(msub, osmo_mobile_identity_to_str_c(OTC_SELECT, mi));
}
/* Update msub->fi id string from current msub->vsub and msub->complete_layer3_type. */
@@ -544,6 +544,8 @@ void msc_role_forget_conn(struct osmo_fsm_inst *role, struct ran_conn *conn)
*conn_p = NULL;
}
+/* NOTE: the resulting message buffer will be attached to OTC_SELECT, so its lifetime
+ * is limited by the current select() loop iteration. Use talloc_steal() to avoid this. */
struct msgb *msc_role_ran_encode(struct osmo_fsm_inst *fi, const struct ran_msg *ran_msg)
{
struct msc_role_common *c = fi->priv;
@@ -556,6 +558,8 @@ struct msgb *msc_role_ran_encode(struct osmo_fsm_inst *fi, const struct ran_msg
msg = c->ran->ran_encode(fi, ran_msg);
if (!msg)
LOGPFSML(fi, LOGL_ERROR, "Failed to encode %s\n", ran_msg_type_name(ran_msg->msg_type));
+ else
+ talloc_steal(OTC_SELECT, msg);
return msg;
}
diff --git a/src/libmsc/neighbor_ident.c b/src/libmsc/neighbor_ident.c
index 5120e168e..b3cdf17c4 100644
--- a/src/libmsc/neighbor_ident.c
+++ b/src/libmsc/neighbor_ident.c
@@ -1,6 +1,6 @@
/* Manage identity of neighboring BSS cells for inter-MSC handover. */
/*
- * (C) 2018-2019 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de>
+ * (C) 2018-2019 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
* All Rights Reserved
*
* SPDX-License-Identifier: AGPL-3.0+
diff --git a/src/libmsc/paging.c b/src/libmsc/paging.c
index 5baa0dca0..9b3dad5d2 100644
--- a/src/libmsc/paging.c
+++ b/src/libmsc/paging.c
@@ -1,5 +1,5 @@
/*
- * (C) 2019 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de>
+ * (C) 2019 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
* All Rights Reserved
*
* SPDX-License-Identifier: AGPL-3.0+
@@ -49,6 +49,10 @@ const struct value_string paging_cause_names[] = {
static void paging_response_timer_cb(void *data)
{
struct vlr_subscr *vsub = data;
+
+ if (vsub->cs.attached_via_ran == OSMO_RAT_EUTRAN_SGS)
+ sgs_iface_tx_serv_abrt(vsub);
+
paging_expired(vsub);
}
@@ -69,11 +73,9 @@ static int msc_paging_request(struct paging_request *pr, struct vlr_subscr *vsub
case OSMO_RAT_EUTRAN_SGS:
return sgs_iface_tx_paging(vsub, sgs_serv_ind_from_paging_cause(pr->cause));
default:
- break;
+ LOG_PAGING(vsub, pr, LOGL_ERROR, "Cannot page, subscriber not attached\n");
+ return -EINVAL;
}
-
- LOG_PAGING(vsub, pr, LOGL_ERROR, " Cannot page, subscriber not attached\n");
- return -EINVAL;
}
struct paging_request *paging_request_start(struct vlr_subscr *vsub, enum paging_cause cause,
@@ -82,9 +84,9 @@ struct paging_request *paging_request_start(struct vlr_subscr *vsub, enum paging
{
int rc;
struct paging_request *pr;
- struct gsm_network *net = vsub->vlr->user_ctx;
+ int paging_response_timer;
- pr = talloc_zero(vsub, struct paging_request);
+ pr = talloc(vsub, struct paging_request);
OSMO_ASSERT(pr);
*pr = (struct paging_request){
.label = label,
@@ -108,8 +110,9 @@ struct paging_request *paging_request_start(struct vlr_subscr *vsub, enum paging
/* reduced on the first paging callback */
vlr_subscr_get(vsub, VSUB_USE_PAGING);
vsub->cs.is_paging = true;
+ paging_response_timer = osmo_tdef_get(msc_ran_infra[vsub->cs.attached_via_ran].tdefs, -4, OSMO_TDEF_S, 10);
osmo_timer_setup(&vsub->cs.paging_response_timer, paging_response_timer_cb, vsub);
- osmo_timer_schedule(&vsub->cs.paging_response_timer, net->paging_response_timer, 0);
+ osmo_timer_schedule(&vsub->cs.paging_response_timer, paging_response_timer, 0);
}
llist_add_tail(&pr->entry, &vsub->cs.requests);
@@ -117,6 +120,34 @@ struct paging_request *paging_request_start(struct vlr_subscr *vsub, enum paging
return pr;
}
+/* Two subscribers (e.g. an old TMSI and a new TMSI) turn out to have the same identity, so in order to discard one of
+ * them, transfer any pending Paging requests to the vsub that will survive. */
+void paging_request_join_vsub(struct vlr_subscr *keep_vsub, struct vlr_subscr *discarding_vsub)
+{
+ struct paging_request *pr;
+
+ if (!discarding_vsub->cs.is_paging)
+ return;
+
+ /* transfer all Paging Response callbacks */
+ while ((pr = llist_first_entry_or_null(&discarding_vsub->cs.requests, struct paging_request, entry))) {
+ llist_del(&pr->entry);
+ talloc_steal(keep_vsub, pr);
+ llist_add_tail(&pr->entry, &keep_vsub->cs.requests);
+ }
+
+ /* make sure a Paging use count is present on keep_vsub, if needed */
+ if (!keep_vsub->cs.is_paging && !llist_empty(&keep_vsub->cs.requests)) {
+ vlr_subscr_get(keep_vsub, VSUB_USE_PAGING);
+ keep_vsub->cs.is_paging = true;
+ }
+
+ /* Already made sure at the top of this function that discarding_vsub->cs.is_paging == true */
+ discarding_vsub->cs.is_paging = false;
+ osmo_timer_del(&discarding_vsub->cs.paging_response_timer);
+ vlr_subscr_put(discarding_vsub, VSUB_USE_PAGING);
+}
+
void paging_request_remove(struct paging_request *pr)
{
struct gsm_trans *trans = pr->trans;
@@ -135,6 +166,11 @@ static void paging_concludes(struct vlr_subscr *vsub, struct msc_a *msc_a)
struct paging_request *pr, *pr_next;
struct paging_signal_data sig_data;
+ if (!vsub) {
+ /* A Paging Response has no subscriber. (Related: OS#4449) */
+ return;
+ }
+
osmo_timer_del(&vsub->cs.paging_response_timer);
llist_for_each_entry_safe(pr, pr_next, &vsub->cs.requests, entry) {
diff --git a/src/libmsc/ran_conn.c b/src/libmsc/ran_conn.c
index 8418c9eb5..07638016a 100644
--- a/src/libmsc/ran_conn.c
+++ b/src/libmsc/ran_conn.c
@@ -1,7 +1,7 @@
/* MSC RAN connection implementation */
/*
- * (C) 2016-2018 by sysmocom s.m.f.c. <info@sysmocom.de>
+ * (C) 2016-2018 by sysmocom s.f.m.c. <info@sysmocom.de>
* All Rights Reserved
*
* Author: Neels Hofmeyr
diff --git a/src/libmsc/ran_infra.c b/src/libmsc/ran_infra.c
index af4054149..6a178403f 100644
--- a/src/libmsc/ran_infra.c
+++ b/src/libmsc/ran_infra.c
@@ -1,6 +1,6 @@
/* Lookup table for various RAN implementations */
/*
- * (C) 2019 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de>
+ * (C) 2019 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
* All Rights Reserved
*
* SPDX-License-Identifier: AGPL-3.0+
@@ -43,6 +43,7 @@ const struct value_string an_proto_names[] = {
{ .T = -1, .default_val = 5, .desc = "RAN connection Complete Layer 3, Authentication and Ciphering timeout" }, \
{ .T = -2, .default_val = 30, .desc = "RAN connection release sanity timeout" }, \
{ .T = -3, .default_val = 10, .desc = "Timeout to find a target BSS after Handover Required" }, \
+ { .T = -4, .default_val = 10, .desc = "Paging response timeout" }, \
struct osmo_tdef msc_tdefs_geran[] = {
RAN_TDEFS
@@ -55,6 +56,7 @@ struct osmo_tdef msc_tdefs_utran[] = {
};
struct osmo_tdef msc_tdefs_sgs[] = {
+ { .T = -4, .default_val = 10, .desc = "Paging response timeout" },
{}
};
@@ -106,6 +108,16 @@ struct ran_infra msc_ran_infra[] = {
.ran_dec_l2 = ran_iu_decode_l2,
.ran_encode = ran_iu_encode,
#endif
+ .force_mgw_codecs_to_ran = {
+ .count = 1,
+ .codec = {
+ {
+ .payload_type = 96,
+ .subtype_name = "VND.3GPP.IUFP",
+ .rate = 16000,
+ },
+ },
+ },
},
[OSMO_RAT_EUTRAN_SGS] = {
.type = OSMO_RAT_EUTRAN_SGS,
diff --git a/src/libmsc/ran_msg.c b/src/libmsc/ran_msg.c
index 46816a961..3e4b20c50 100644
--- a/src/libmsc/ran_msg.c
+++ b/src/libmsc/ran_msg.c
@@ -1,25 +1,21 @@
/* Common bits for RAN message handling */
/*
- * (C) 2019 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de>
+ * (C) 2019 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
* All Rights Reserved
*
* Author: Neels Hofmeyr
*
- * SPDX-License-Identifier: GPL-2.0+
+ * SPDX-License-Identifier: AGPL-3.0+
*
* This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ * GNU Affero General Public License for more details.
*/
#include <osmocom/core/utils.h>
@@ -55,6 +51,25 @@ const struct value_string ran_msg_type_names[] = {
{ RAN_MSG_HANDOVER_DETECT, "HANDOVER_DETECT" },
{ RAN_MSG_HANDOVER_COMPLETE, "HANDOVER_COMPLETE" },
{ RAN_MSG_HANDOVER_FAILURE, "HANDOVER_FAILURE" },
+ { RAN_MSG_VGCS_VBS_SETUP, "VGCS_VBS_SETUP" },
+ { RAN_MSG_VGCS_VBS_SETUP_ACK, "VGCS_VBS_SETUP_ACK" },
+ { RAN_MSG_VGCS_VBS_SETUP_REFUSE, "VGCS_VBS_SETUP_REFUSE" },
+ { RAN_MSG_VGCS_VBS_ASSIGN_REQ, "VGCS_VBS_ASSIGN_REQ" },
+ { RAN_MSG_VGCS_VBS_ASSIGN_RES, "VGCS_VBS_ASSIGN_RES" },
+ { RAN_MSG_VGCS_VBS_ASSIGN_FAIL, "VGCS_VBS_ASSIGN_FAIL" },
+ { RAN_MSG_VGCS_VBS_QUEUING_IND, "VGCS_VBS_QUEUING_IND" },
+ { RAN_MSG_UPLINK_REQUEST, "UPLINK_REQUEST" },
+ { RAN_MSG_UPLINK_REQUEST_ACK, "UPLINK_REQUEST_ACK" },
+ { RAN_MSG_UPLINK_REQUEST_CNF, "UPLINK_REQUEST_CNF" },
+ { RAN_MSG_UPLINK_APPLICATION_DATA, "UPLINK_APPLICATION_DATA" },
+ { RAN_MSG_UPLINK_RELEASE_IND, "UPLINK_RELEASE_IND" },
+ { RAN_MSG_UPLINK_REJECT_CMD, "UPLINK_REJECT_CMD" },
+ { RAN_MSG_UPLINK_RELEASE_CMD, "UPLINK_RELEASE_CMD" },
+ { RAN_MSG_UPLINK_SEIZED_CMD, "UPLINK_SEIZED_CMD" },
+ { RAN_MSG_VGCS_ADDITIONAL_INFO, "VGCS_ADDITIONAL_INFO" },
+ { RAN_MSG_VGCS_VBS_AREA_CELL_INFO, "VGCS_VBS_AREA_CELL_INFO" },
+ { RAN_MSG_VGCS_VBS_ASSIGN_STATUS, "VGCS_VBS_ASSIGN_STATUS" },
+ { RAN_MSG_VGCS_SMS, "VGCS_SMS" },
{}
};
diff --git a/src/libmsc/ran_msg_a.c b/src/libmsc/ran_msg_a.c
index 64590a1fe..d9041204a 100644
--- a/src/libmsc/ran_msg_a.c
+++ b/src/libmsc/ran_msg_a.c
@@ -1,30 +1,27 @@
/* BSSAP/BSSMAP encoding and decoding for MSC */
/*
- * (C) 2019 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de>
+ * (C) 2019 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
* All Rights Reserved
*
* Author: Neels Hofmeyr
*
- * SPDX-License-Identifier: GPL-2.0+
+ * SPDX-License-Identifier: AGPL-3.0+
*
* This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ * GNU Affero General Public License for more details.
*/
#include <osmocom/core/byteswap.h>
#include <osmocom/crypt/auth.h>
+#include <osmocom/crypt/kdf.h>
#include <osmocom/gsm/tlv.h>
#include <osmocom/gsm/gsm0808.h>
@@ -52,9 +49,11 @@ static int ran_a_decode_l3_compl(struct ran_dec *ran_dec, struct msgb *msg, stru
struct gsm0808_cell_id cell_id;
struct tlv_p_entry *ie_cell_id = TLVP_GET(tp, GSM0808_IE_CELL_IDENTIFIER);
struct tlv_p_entry *ie_l3_info = TLVP_GET(tp, GSM0808_IE_LAYER_3_INFORMATION);
+ struct tlv_p_entry *ie_codec_list_bss_supported = TLVP_GET(tp, GSM0808_IE_SPEECH_CODEC_LIST);
+ struct gsm0808_speech_codec_list codec_list_bss_supported;
struct ran_msg ran_dec_msg = {
.msg_type = RAN_MSG_COMPL_L3,
- .msg_name = "BSSMAP Complete Layer 3",
+ .msg_name = "BSSMAP Complete Layer 3 Information",
.compl_l3 = {
.cell_id = &cell_id,
.msg = msg,
@@ -105,7 +104,7 @@ static int ran_a_decode_l3_compl(struct ran_dec *ran_dec, struct msgb *msg, stru
.id = cil.id_list[0],
};
- /* Parse Layer 3 Information element */
+ /* Parse Layer 3 Information element; point ran_dec_msg->compl_l3.msg to the L3 Info data */
msg->l3h = (uint8_t*)ie_l3_info->val;
msgb_l3trim(msg, ie_l3_info->len);
@@ -114,6 +113,19 @@ static int ran_a_decode_l3_compl(struct ran_dec *ran_dec, struct msgb *msg, stru
return -ENODATA;
}
+ /* Decode Codec List (BSS Supported) */
+ if (ie_codec_list_bss_supported) {
+ rc = gsm0808_dec_speech_codec_list(&codec_list_bss_supported,
+ ie_codec_list_bss_supported->val, ie_codec_list_bss_supported->len);
+ if (rc < 0) {
+ LOG_RAN_A_DEC_MSG(LOGL_ERROR,
+ "Complete Layer 3 Information: unable to decode IE Codec List (BSS Supported)"
+ " (rc=%d), continuing anyway\n", rc);
+ /* This IE is not critical, do not abort with error. */
+ } else
+ ran_dec_msg.compl_l3.codec_list_bss_supported = &codec_list_bss_supported;
+ }
+
return ran_decoded(ran_dec, &ran_dec_msg);
}
@@ -194,18 +206,10 @@ static int ran_a_decode_cipher_mode_complete(struct ran_dec *ran_dec, struct msg
ran_dec_msg.cipher_mode_complete.alg_id = ie_chosen_encr_alg->val[0];
}
- rc = ran_decoded(ran_dec, &ran_dec_msg);
+ if (ie_l3_msg)
+ ran_dec_msg.cipher_mode_complete.l3_msg = ie_l3_msg;
- if (ie_l3_msg) {
- msg->l3h = (uint8_t*)ie_l3_msg->val;
- msgb_l3trim(msg, ie_l3_msg->len);
- ran_dec_msg = (struct ran_msg){
- .msg_type = RAN_MSG_DTAP,
- .msg_name = "BSSMAP Ciphering Mode Complete (L3 Message Contents)",
- .dtap = msg,
- };
- ran_decoded(ran_dec, &ran_dec_msg);
- }
+ rc = ran_decoded(ran_dec, &ran_dec_msg);
return rc;
}
@@ -218,7 +222,7 @@ static int ran_a_decode_cipher_mode_reject(struct ran_dec *ran_dec, struct msgb
.msg_name = "BSSMAP Ciphering Mode Reject",
};
- rc = gsm0808_get_cipher_reject_cause(tp);
+ rc = gsm0808_get_cause(tp);
if (rc < 0) {
LOG_RAN_A_DEC_MSG(LOGL_ERROR, "failed to extract Cause\n");
ran_dec_msg.cipher_mode_reject.bssap_cause = GSM0808_CAUSE_EQUIPMENT_FAILURE;
@@ -234,34 +238,26 @@ enum mgcp_codecs ran_a_mgcp_codec_from_sc(const struct gsm0808_speech_codec *sc)
switch (sc->type) {
case GSM0808_SCT_FR1:
return CODEC_GSM_8000_1;
- break;
case GSM0808_SCT_FR2:
return CODEC_GSMEFR_8000_1;
- break;
case GSM0808_SCT_FR3:
return CODEC_AMR_8000_1;
- break;
case GSM0808_SCT_FR4:
return CODEC_AMRWB_16000_1;
- break;
case GSM0808_SCT_FR5:
return CODEC_AMRWB_16000_1;
- break;
case GSM0808_SCT_HR1:
return CODEC_GSMHR_8000_1;
- break;
case GSM0808_SCT_HR3:
return CODEC_AMR_8000_1;
- break;
case GSM0808_SCT_HR4:
return CODEC_AMRWB_16000_1;
- break;
case GSM0808_SCT_HR6:
return CODEC_AMRWB_16000_1;
- break;
+ case GSM0808_SCT_CSD:
+ return CODEC_CLEARMODE;
default:
return CODEC_PCMU_8000_1;
- break;
}
}
@@ -269,9 +265,10 @@ static int ran_a_decode_assignment_complete(struct ran_dec *ran_dec, struct msgb
{
struct tlv_p_entry *ie_aoip_transp_addr = TLVP_GET(tp, GSM0808_IE_AOIP_TRASP_ADDR);
struct tlv_p_entry *ie_speech_codec = TLVP_GET(tp, GSM0808_IE_SPEECH_CODEC);
+ struct tlv_p_entry *ie_codec_list_bss_supported = TLVP_GET(tp, GSM0808_IE_SPEECH_CODEC_LIST);
+ struct tlv_p_entry *ie_osmux_cid = TLVP_GET(tp, GSM0808_IE_OSMO_OSMUX_CID);
struct sockaddr_storage rtp_addr;
- struct sockaddr_in *rtp_addr_in;
- struct gsm0808_speech_codec sc;
+ struct gsm0808_speech_codec_list codec_list_bss_supported;
int rc;
struct ran_msg ran_dec_msg = {
.msg_type = RAN_MSG_ASSIGNMENT_COMPLETE,
@@ -286,30 +283,44 @@ static int ran_a_decode_assignment_complete(struct ran_dec *ran_dec, struct msgb
return -EINVAL;
}
- rtp_addr_in = (struct sockaddr_in*)&rtp_addr;
-
- if (rtp_addr.ss_family != AF_INET) {
- LOG_RAN_A_DEC_MSG(LOGL_ERROR, "Assignment Complete: IE AoIP Transport Address:"
- " unsupported addressing scheme (only IPV4 supported)\n");
+ if (osmo_sockaddr_str_from_sockaddr(&ran_dec_msg.assignment_complete.remote_rtp, &rtp_addr)) {
+ LOG_RAN_A_DEC_MSG(LOGL_ERROR, "Assignment Complete: unable to decode remote RTP IP address\n");
return -EINVAL;
}
+ }
- if (osmo_sockaddr_str_from_sockaddr_in(&ran_dec_msg.assignment_complete.remote_rtp, rtp_addr_in)) {
- LOG_RAN_A_DEC_MSG(LOGL_ERROR, "Assignment Complete: unable to decode remote RTP IP address\n");
+ if (ie_osmux_cid) {
+ rc = gsm0808_dec_osmux_cid(&ran_dec_msg.assignment_complete.osmux_cid, ie_osmux_cid->val, ie_osmux_cid->len);
+ if (rc < 0) {
+ LOG_RAN_A_DEC_MSG(LOGL_ERROR, "Unable to decode Osmux CID\n");
return -EINVAL;
}
+ ran_dec_msg.assignment_complete.osmux_present = true;
}
if (ie_speech_codec) {
/* Decode Speech Codec (Chosen) element */
- rc = gsm0808_dec_speech_codec(&sc, ie_speech_codec->val, ie_speech_codec->len);
+ rc = gsm0808_dec_speech_codec(&ran_dec_msg.assignment_complete.codec,
+ ie_speech_codec->val, ie_speech_codec->len);
if (rc < 0) {
LOG_RAN_A_DEC_MSG(LOGL_ERROR, "Assignment Complete: unable to decode IE Speech Codec (Chosen)"
" (rc=%d).\n", rc);
return -EINVAL;
}
ran_dec_msg.assignment_complete.codec_present = true;
- ran_dec_msg.assignment_complete.codec = ran_a_mgcp_codec_from_sc(&sc);
+ }
+
+ if (ie_codec_list_bss_supported) {
+ /* Decode Codec List (BSS Supported) */
+ rc = gsm0808_dec_speech_codec_list(&codec_list_bss_supported,
+ ie_codec_list_bss_supported->val, ie_codec_list_bss_supported->len);
+ if (rc < 0) {
+ LOG_RAN_A_DEC_MSG(LOGL_ERROR,
+ "Assignment Complete: unable to decode IE Codec List (BSS Supported)"
+ " (rc=%d), continuing anyway\n", rc);
+ /* This IE is not critical, do not abort with error. */
+ } else
+ ran_dec_msg.assignment_complete.codec_list_bss_supported = &codec_list_bss_supported;
}
return ran_decoded(ran_dec, &ran_dec_msg);
@@ -459,13 +470,13 @@ static int ran_a_decode_handover_request(struct ran_dec *ran_dec, const struct m
const struct tlv_p_entry *ie_aoip_transp_addr = TLVP_GET(tp, GSM0808_IE_AOIP_TRASP_ADDR);
const struct tlv_p_entry *ie_codec_list_msc_preferred = TLVP_GET(tp, GSM0808_IE_SPEECH_CODEC_LIST);
const struct tlv_p_entry *ie_call_id = TLVP_GET(tp, GSM0808_IE_CALL_ID);
+ const struct tlv_p_entry *ie_kc128 = TLVP_GET(tp, GSM0808_IE_KC_128);
const struct tlv_p_entry *ie_global_call_ref = TLVP_GET(tp, GSM0808_IE_GLOBAL_CALL_REF);
struct gsm0808_channel_type channel_type;
struct gsm0808_encrypt_info encr_info;
struct gsm0808_speech_codec_list scl;
struct geran_encr geran_encr = {};
- char imsi[OSMO_IMSI_BUF_SIZE];
struct osmo_sockaddr_str rtp_ran_local;
if (!ie_channel_type) {
@@ -482,7 +493,7 @@ static int ran_a_decode_handover_request(struct ran_dec *ran_dec, const struct m
int i;
if (gsm0808_dec_encrypt_info(&encr_info, ie_encryption_information->val, ie_encryption_information->len)
<= 0) {
- LOG_RAN_A_DEC_MSG(LOGL_ERROR, "Failed to decode Encryption Informaiton IE\n");
+ LOG_RAN_A_DEC_MSG(LOGL_ERROR, "Failed to decode Encryption Information IE\n");
return -EINVAL;
}
@@ -492,7 +503,7 @@ static int ran_a_decode_handover_request(struct ran_dec *ran_dec, const struct m
}
if (encr_info.key_len > sizeof(geran_encr.key)) {
- LOG_RAN_A_DEC_MSG(LOGL_ERROR, "Failed to decode Encryption Informaiton IE:"
+ LOG_RAN_A_DEC_MSG(LOGL_ERROR, "Failed to decode Encryption Information IE:"
" encryption key is too long: %u\n", geran_encr.key_len);
return -EINVAL;
}
@@ -502,6 +513,11 @@ static int ran_a_decode_handover_request(struct ran_dec *ran_dec, const struct m
geran_encr.key_len = encr_info.key_len;
}
+ if (ie_kc128) {
+ memcpy(geran_encr.kc128, ie_kc128->val, 16);
+ geran_encr.kc128_present = true;
+ }
+
r->geran.chosen_encryption = &geran_encr;
}
@@ -576,28 +592,22 @@ static int ran_a_decode_handover_request(struct ran_dec *ran_dec, const struct m
}
if (ie_imsi) {
- gsm48_mi_to_string(imsi, sizeof(imsi), ie_imsi->val, ie_imsi->len);
- r->imsi = imsi;
+ struct osmo_mobile_identity mi;
+ if (osmo_mobile_identity_decode(&mi, ie_imsi->val, ie_imsi->len, false)
+ || mi.type != GSM_MI_TYPE_IMSI)
+ LOG_RAN_A_DEC_MSG(LOGL_ERROR, "IE IMSI: cannot decode IMSI identity\n");
+ else
+ r->imsi = mi.imsi;
}
if (ie_aoip_transp_addr) {
- do {
- struct sockaddr_storage rtp_addr;
- if (gsm0808_dec_aoip_trasp_addr(&rtp_addr, ie_aoip_transp_addr->val, ie_aoip_transp_addr->len) < 0) {
- LOG_RAN_A_DEC_MSG(LOGL_ERROR, "unable to decode AoIP transport address\n");
- break;
- }
- if (rtp_addr.ss_family != AF_INET) {
- LOG_RAN_A_DEC_MSG(LOGL_ERROR, "IE AoIP Transport Address:"
- " unsupported addressing scheme (only IPV4 supported)\n");
- break;
- }
- if (osmo_sockaddr_str_from_sockaddr_in(&rtp_ran_local, (struct sockaddr_in*)&rtp_addr)) {
- LOG_RAN_A_DEC_MSG(LOGL_ERROR, "unable to decode remote RTP IP address\n");
- break;
- }
+ struct sockaddr_storage rtp_addr;
+ if (gsm0808_dec_aoip_trasp_addr(&rtp_addr, ie_aoip_transp_addr->val, ie_aoip_transp_addr->len) < 0)
+ LOG_RAN_A_DEC_MSG(LOGL_ERROR, "unable to decode AoIP transport address\n");
+ else if (osmo_sockaddr_str_from_sockaddr(&rtp_ran_local, &rtp_addr) < 0)
+ LOG_RAN_A_DEC_MSG(LOGL_ERROR, "unable to decode remote RTP IP address\n");
+ else
r->rtp_ran_local = &rtp_ran_local;
- } while(0);
}
if (ie_codec_list_msc_preferred
@@ -653,45 +663,32 @@ static int ran_a_decode_handover_request_ack(struct ran_dec *ran_dec, const stru
}
if (ie_chosen_speech_version) {
- struct gsm0808_speech_codec sc;
ran_dec_msg.handover_request_ack.chosen_speech_version = ie_chosen_speech_version->val[0];
/* the codec may be extrapolated from this Speech Version or below from Speech Codec */
- gsm0808_speech_codec_from_chan_type(&sc, ran_dec_msg.handover_request_ack.chosen_speech_version);
- ran_dec_msg.handover_request_ack.codec_present = true;
- ran_dec_msg.handover_request_ack.codec = ran_a_mgcp_codec_from_sc(&sc);
+ if (gsm0808_speech_codec_from_chan_type(&ran_dec_msg.handover_request_ack.codec,
+ ran_dec_msg.handover_request_ack.chosen_speech_version) == 0)
+ ran_dec_msg.handover_request_ack.codec_present = true;
}
if (ie_aoip_transp_addr) {
- do {
- struct sockaddr_storage rtp_addr;
- if (gsm0808_dec_aoip_trasp_addr(&rtp_addr, ie_aoip_transp_addr->val, ie_aoip_transp_addr->len) < 0) {
- LOG_RAN_A_DEC_MSG(LOGL_ERROR, "unable to decode AoIP transport address\n");
- break;
- }
- if (rtp_addr.ss_family != AF_INET) {
- LOG_RAN_A_DEC_MSG(LOGL_ERROR, "IE AoIP Transport Address:"
- " unsupported addressing scheme (only IPV4 supported)\n");
- break;
- }
- if (osmo_sockaddr_str_from_sockaddr_in(&ran_dec_msg.handover_request_ack.remote_rtp,
- (struct sockaddr_in*)&rtp_addr)) {
- LOG_RAN_A_DEC_MSG(LOGL_ERROR, "unable to decode remote RTP IP address\n");
- ran_dec_msg.handover_request_ack.remote_rtp = (struct osmo_sockaddr_str){};
- break;
- }
- } while(0);
+ struct sockaddr_storage rtp_addr;
+ if (gsm0808_dec_aoip_trasp_addr(&rtp_addr, ie_aoip_transp_addr->val, ie_aoip_transp_addr->len) < 0) {
+ LOG_RAN_A_DEC_MSG(LOGL_ERROR, "unable to decode AoIP transport address\n");
+ } else if (osmo_sockaddr_str_from_sockaddr(&ran_dec_msg.handover_request_ack.remote_rtp,
+ &rtp_addr)) {
+ LOG_RAN_A_DEC_MSG(LOGL_ERROR, "unable to decode remote RTP IP address\n");
+ ran_dec_msg.handover_request_ack.remote_rtp = (struct osmo_sockaddr_str){};
+ }
}
if (ie_speech_codec) {
- struct gsm0808_speech_codec sc;
- if (gsm0808_dec_speech_codec(&sc, ie_speech_codec->val, ie_speech_codec->len) < 0)
+ /* the codec may be extrapolated from above Speech Version or from this Speech Codec */
+ if (gsm0808_dec_speech_codec(&ran_dec_msg.handover_request_ack.codec,
+ ie_speech_codec->val, ie_speech_codec->len) < 0)
LOG_RAN_A_DEC_MSG(LOGL_ERROR, "unable to decode IE Speech Codec (Chosen)\n");
- else {
- /* the codec may be extrapolated from above Speech Version or from this Speech Codec */
+ else
ran_dec_msg.handover_request_ack.codec_present = true;
- ran_dec_msg.handover_request_ack.codec = ran_a_mgcp_codec_from_sc(&sc);
- }
}
return ran_decoded(ran_dec, &ran_dec_msg);
@@ -737,6 +734,439 @@ static int ran_a_decode_handover_failure(struct ran_dec *ran_dec, const struct m
return ran_decoded(ran_dec, &ran_dec_msg);
}
+static int ran_a_decode_vgcs_vbs_setup_ack(struct ran_dec *ran_dec, const struct msgb *msg, const struct tlv_parsed *tp)
+{
+ struct ran_msg ran_dec_msg = {
+ .msg_type = RAN_MSG_VGCS_VBS_SETUP_ACK,
+ .msg_name = "BSSMAP VGCS/VBS SETUP ACKNOWLEDGE",
+ };
+ struct gsm0808_vgcs_vbs_setup_ack *r = &ran_dec_msg.vgcs_vbs_setup_ack;
+ int rc;
+
+ const struct tlv_p_entry *ie_flags = TLVP_GET(tp, GSM0808_IE_VGCS_FEATURE_FLAGS);
+
+ /* VGCS Feature Flags, 3.2.2.88 */
+ if (ie_flags) {
+ rc = gsm0808_dec_vgcs_feature_flags(&r->flags, ie_flags->val, ie_flags->len);
+ if (rc < 0) {
+ LOG_RAN_A_DEC_MSG(LOGL_ERROR, "Unable to decode VGCS/VBS Feature Flags\n");
+ return -EINVAL;
+ }
+ r->vgcs_feature_flags_present = true;
+ }
+
+ return ran_decoded(ran_dec, &ran_dec_msg);
+}
+
+static int ran_a_decode_vgcs_vbs_setup_refuse(struct ran_dec *ran_dec, const struct msgb *msg,
+ const struct tlv_parsed *tp)
+{
+ struct ran_msg ran_dec_msg = {
+ .msg_type = RAN_MSG_VGCS_VBS_SETUP_REFUSE,
+ .msg_name = "BSSMAP VGCS/VBS SETUP REFUSE",
+ };
+
+ const struct tlv_p_entry *ie_cause = TLVP_GET(tp, GSM0808_IE_CAUSE);
+
+ /* Cause, 3.2.2.5 */
+ if (!ie_cause || ie_cause->len < 1) {
+ LOG_RAN_A_DEC_MSG(LOGL_ERROR, "Mandatory IE missing: Cause\n");
+ return -EINVAL;
+ }
+ ran_dec_msg.vgcs_vbs_setup_refuse.cause = ie_cause->val[0];
+
+ return ran_decoded(ran_dec, &ran_dec_msg);
+}
+
+static int ran_a_decode_vgcs_vbs_assign_res(struct ran_dec *ran_dec, const struct msgb *msg,
+ const struct tlv_parsed *tp)
+{
+ struct ran_msg ran_dec_msg = {
+ .msg_type = RAN_MSG_VGCS_VBS_ASSIGN_RES,
+ .msg_name = "BSSMAP VGCS/VBS ASSIGNMENT RESULT",
+ };
+ struct gsm0808_vgcs_vbs_assign_res *r = &ran_dec_msg.vgcs_vbs_assign_res;
+ int rc;
+
+ const struct tlv_p_entry *ie_channel_type = TLVP_GET(tp, GSM0808_IE_CHANNEL_TYPE);
+ const struct tlv_p_entry *ie_cell_id = TLVP_GET(tp, GSM0808_IE_CELL_IDENTIFIER);
+ const struct tlv_p_entry *ie_chosen_channel = TLVP_GET(tp, GSM0808_IE_CHOSEN_CHANNEL);
+ const struct tlv_p_entry *ie_cic = TLVP_GET(tp, GSM0808_IE_CIRCUIT_IDENTITY_CODE);
+ const struct tlv_p_entry *ie_circuit_pool = TLVP_GET(tp, GSM0808_IE_CIRCUIT_POOL);
+ const struct tlv_p_entry *ie_aoip = TLVP_GET(tp, GSM0808_IE_AOIP_TRASP_ADDR);
+ const struct tlv_p_entry *ie_call_id = TLVP_GET(tp, GSM0808_IE_CALL_ID);
+
+ /* Channel Type, 3.2.2.11 */
+ if (!ie_channel_type) {
+ LOG_RAN_A_DEC_MSG(LOGL_ERROR, "Mandatory IE missing: Channel Type\n");
+ return -EINVAL;
+ }
+ if (gsm0808_dec_channel_type(&r->channel_type, ie_channel_type->val, ie_channel_type->len) <= 0) {
+ LOG_RAN_A_DEC_MSG(LOGL_ERROR, "Failed to decode Channel Type IE\n");
+ return -EINVAL;
+ }
+
+ /* Cell Identifier, 3.2.2.17 */
+ if (!ie_cell_id) {
+ LOG_RAN_A_DEC_MSG(LOGL_ERROR, "Mandatory IE missing: Cell Identifier\n");
+ return -EINVAL;
+ }
+ rc = gsm0808_dec_cell_id(&r->cell_identifier, ie_cell_id->val, ie_cell_id->len);
+ if (rc < 0) {
+ LOG_RAN_A_DEC_MSG(LOGL_ERROR, "Decoding Cell Identifier gave rc=%d\n", rc);
+ return -EINVAL;
+ }
+
+ /* Chosen Channel, 3.2.2.33 */
+ if (ie_chosen_channel) {
+ r->chosen_channel = ie_chosen_channel->val[0];
+ r->chosen_channel_present = true;
+ }
+
+ /* Circuit Identity Code, 3.2.2.2 */
+ if (ie_cic) {
+ if (ie_cic->len != 2) {
+ LOG_RAN_A_DEC_MSG(LOGL_ERROR, "Circuit Identity Code has invalid length.\n");
+ return -EINVAL;
+ }
+ r->cic = *(uint16_t *)ie_cic->val;
+ r->cic_present = true;
+ }
+
+ /* Circuit Pool, 3.2.2.45 */
+ if (ie_circuit_pool) {
+ r->circuit_pool = ie_circuit_pool->val[0];
+ r->circuit_pool_present = true;
+ }
+
+ /* AoIP Transport Layer Address (BSS), 3.2.2.102 */
+ if (ie_aoip) {
+ if (gsm0808_dec_aoip_trasp_addr(&r->aoip_transport_layer, ie_aoip->val, ie_aoip->len) < 0) {
+ LOG_RAN_A_DEC_MSG(LOGL_ERROR, "unable to decode AoIP transport address\n");
+ return -EINVAL;
+ }
+ r->aoip_transport_layer_present = true;
+ }
+
+ if (ie_call_id) {
+ if (ie_call_id->len != 4) {
+ LOG_RAN_A_DEC_MSG(LOGL_ERROR, "Call Identifier has invalid length.\n");
+ return -EINVAL;
+ }
+ r->call_id = osmo_load32le(ie_call_id->val);
+ r->call_id_present = true;
+ }
+
+ return ran_decoded(ran_dec, &ran_dec_msg);
+}
+
+static int ran_a_decode_vgcs_vbs_assign_fail(struct ran_dec *ran_dec, const struct msgb *msg,
+ const struct tlv_parsed *tp)
+{
+ struct ran_msg ran_dec_msg = {
+ .msg_type = RAN_MSG_VGCS_VBS_ASSIGN_FAIL,
+ .msg_name = "BSSMAP VGCS/VBS ASSIGNMENT FAILURE",
+ };
+ struct gsm0808_vgcs_vbs_assign_fail *r = &ran_dec_msg.vgcs_vbs_assign_fail;
+ int rc;
+
+ const struct tlv_p_entry *ie_cause = TLVP_GET(tp, GSM0808_IE_CAUSE);
+ const struct tlv_p_entry *ie_circuit_pool = TLVP_GET(tp, GSM0808_IE_CIRCUIT_POOL);
+ const struct tlv_p_entry *ie_circuit_pool_list = TLVP_GET(tp, GSM0808_IE_CIRCUIT_POOL_LIST);
+ const struct tlv_p_entry *ie_codec_list_bss_supported = TLVP_GET(tp, GSM0808_IE_SPEECH_CODEC_LIST);
+
+ /* Cause, 3.2.2.5 */
+ if (!ie_cause || ie_cause->len < 1) {
+ LOG_RAN_A_DEC_MSG(LOGL_ERROR, "Mandatory IE missing: Cause\n");
+ return -EINVAL;
+ }
+ r->cause = ie_cause->val[0];
+
+ /* Circuit Pool, 3.2.2.45 */
+ if (ie_circuit_pool) {
+ r->circuit_pool = ie_circuit_pool->val[0];
+ r->circuit_pool_present = true;
+ }
+
+ /* Circuit Pool List, 3.2.2.46 */
+ if (ie_circuit_pool_list && ie_circuit_pool_list->len) {
+ if (ie_circuit_pool_list->len > CIRCUIT_POOL_LIST_MAXLEN) {
+ LOG_RAN_A_DEC_MSG(LOGL_ERROR, "Circuit Pool List has invalid length.\n");
+ return -EINVAL;
+ }
+ memcpy(r->cpl.pool, ie_circuit_pool_list->val, ie_circuit_pool_list->len);
+ r->cpl.list_len = ie_circuit_pool_list->len;
+ r->cpl_present = true;
+ }
+
+ /* Codec List (BSS Supported) 3.2.2.103 */
+ if (ie_codec_list_bss_supported) {
+ rc = gsm0808_dec_speech_codec_list(&r->codec_list_bss_supported,
+ ie_codec_list_bss_supported->val, ie_codec_list_bss_supported->len);
+ if (rc < 0) {
+ LOG_RAN_A_DEC_MSG(LOGL_ERROR,
+ "Complete Layer 3 Information: unable to decode IE Codec List (BSS Supported)"
+ " (rc=%d), continuing anyway\n", rc);
+ /* This IE is not critical, do not abort with error. */
+ } else
+ r->codec_list_present = true;
+ }
+
+ return ran_decoded(ran_dec, &ran_dec_msg);
+}
+
+static int ran_a_decode_vgcs_vbs_queuing_ind(struct ran_dec *ran_dec, const struct msgb *msg,
+ const struct tlv_parsed *tp)
+{
+ struct ran_msg ran_dec_msg = {
+ .msg_type = RAN_MSG_VGCS_VBS_QUEUING_IND,
+ .msg_name = "BSSMAP VGCS/VBS QUEUING INDICATION",
+ };
+
+ return ran_decoded(ran_dec, &ran_dec_msg);
+}
+
+static int ran_a_decode_uplink_request(struct ran_dec *ran_dec, const struct msgb *msg, const struct tlv_parsed *tp)
+{
+ struct ran_msg ran_dec_msg = {
+ .msg_type = RAN_MSG_UPLINK_REQUEST,
+ .msg_name = "BSSMAP UPLINK REQUEST",
+ };
+ struct gsm0808_uplink_request *r = &ran_dec_msg.uplink_request;
+ int rc;
+
+ const struct tlv_p_entry *ie_talker_priority = TLVP_GET(tp, GSM0808_IE_TALKER_PRIORITY);
+ const struct tlv_p_entry *ie_cell_id = TLVP_GET(tp, GSM0808_IE_CELL_IDENTIFIER);
+ const struct tlv_p_entry *ie_l3_info = TLVP_GET(tp, GSM0808_IE_LAYER_3_INFORMATION);
+ const struct tlv_p_entry *ie_mi = TLVP_GET(tp, GSM0808_IE_MOBILE_IDENTITY);
+
+ /* Talker Priority, 3.2.2.89 */
+ if (ie_talker_priority) {
+ r->talker_priority = ie_talker_priority->val[0] & 0x03;
+ r->talker_priority_present = true;
+ }
+
+ /* Cell Identifier, 3.2.2.17 */
+ if (ie_cell_id) {
+ rc = gsm0808_dec_cell_id(&r->cell_identifier, ie_cell_id->val, ie_cell_id->len);
+ if (rc < 0) {
+ LOG_RAN_A_DEC_MSG(LOGL_ERROR, "Decoding Cell Identifier gave rc=%d\n", rc);
+ return -EINVAL;
+ }
+ }
+
+ /* Layer 3 Information, 3.2.2.24 */
+ if (ie_l3_info && ie_l3_info->len) {
+ if (ie_l3_info->len > LAYER_3_INFORMATION_MAXLEN) {
+ LOG_RAN_A_DEC_MSG(LOGL_ERROR, "Call Identifier has invalid length.\n");
+ return -EINVAL;
+ }
+ memcpy(r->l3.l3, ie_l3_info->val, ie_l3_info->len);
+ r->l3.l3_len = ie_l3_info->len;
+ r->l3_present = true;
+ }
+
+ /* Mobile Identity, 3.2.2.41 */
+ if (ie_mi) {
+ rc = osmo_mobile_identity_decode(&r->mi, ie_mi->val, ie_mi->len, false);
+ if (rc < 0) {
+ LOG_RAN_A_DEC_MSG(LOGL_ERROR, "Decoding Mobile Identity gave rc=%d\n", rc);
+ return -EINVAL;
+ }
+ r->mi_present = true;
+ }
+
+ return ran_decoded(ran_dec, &ran_dec_msg);
+}
+
+static int ran_a_decode_uplink_request_cnf(struct ran_dec *ran_dec, const struct msgb *msg, const struct tlv_parsed *tp)
+{
+ struct ran_msg ran_dec_msg = {
+ .msg_type = RAN_MSG_UPLINK_REQUEST_CNF,
+ .msg_name = "BSSMAP UPLINK REQUEST CONFIRM",
+ };
+ struct gsm0808_uplink_request_cnf *r = &ran_dec_msg.uplink_request_cnf;
+ int rc;
+
+ const struct tlv_p_entry *ie_cell_id = TLVP_GET(tp, GSM0808_IE_CELL_IDENTIFIER);
+ const struct tlv_p_entry *ie_talker_identity = TLVP_GET(tp, GSM0808_IE_TALKER_IDENTITY);
+ const struct tlv_p_entry *ie_l3_info = TLVP_GET(tp, GSM0808_IE_LAYER_3_INFORMATION);
+
+ /* Cell Identifier, 3.2.2.17 */
+ if (!ie_cell_id) {
+ LOG_RAN_A_DEC_MSG(LOGL_ERROR, "Mandatory IE missing: Cell Identifier\n");
+ return -EINVAL;
+ }
+ rc = gsm0808_dec_cell_id(&r->cell_identifier, ie_cell_id->val, ie_cell_id->len);
+ if (rc < 0) {
+ LOG_RAN_A_DEC_MSG(LOGL_ERROR, "Decoding Cell Identifier gave rc=%d\n", rc);
+ return -EINVAL;
+ }
+
+ /* Talker Identity, 3.2.2.91 */
+ if (ie_talker_identity) {
+ rc = gsm0808_dec_talker_identity(&r->talker_identity, ie_talker_identity->val, ie_talker_identity->len);
+ if (rc < 0) {
+ LOG_RAN_A_DEC_MSG(LOGL_ERROR, "Decoding Talker Identity gave rc=%d\n", rc);
+ return -EINVAL;
+ }
+ r->talker_identity_present = true;
+ }
+
+ /* Layer 3 Information, 3.2.2.24 */
+ if (!ie_l3_info) {
+ LOG_RAN_A_DEC_MSG(LOGL_ERROR, "Mandatory IE missing: Layer 3 Information\n");
+ return -EINVAL;
+ }
+ if (ie_l3_info->len > LAYER_3_INFORMATION_MAXLEN) {
+ LOG_RAN_A_DEC_MSG(LOGL_ERROR, "Call Identifier has invalid length.\n");
+ return -EINVAL;
+ }
+ memcpy(r->l3.l3, ie_l3_info->val, ie_l3_info->len);
+ r->l3.l3_len = ie_l3_info->len;
+
+ return ran_decoded(ran_dec, &ran_dec_msg);
+}
+
+static int ran_a_decode_uplink_application_data(struct ran_dec *ran_dec, const struct msgb *msg,
+ const struct tlv_parsed *tp)
+{
+ struct ran_msg ran_dec_msg = {
+ .msg_type = RAN_MSG_UPLINK_APPLICATION_DATA,
+ .msg_name = "BSSMAP UPLINK APPLICATION DATA",
+ };
+ struct gsm0808_uplink_app_data *r = &ran_dec_msg.uplink_app_data;
+ int rc;
+
+ const struct tlv_p_entry *ie_cell_id = TLVP_GET(tp, GSM0808_IE_CELL_IDENTIFIER);
+ const struct tlv_p_entry *ie_l3_info = TLVP_GET(tp, GSM0808_IE_LAYER_3_INFORMATION);
+ const struct tlv_p_entry *ie_app_data = TLVP_GET(tp, GSM0808_IE_APP_DATA);
+
+ /* Cell Identifier, 3.2.2.17 */
+ if (!ie_cell_id) {
+ LOG_RAN_A_DEC_MSG(LOGL_ERROR, "Mandatory IE missing: Cell Identifier\n");
+ return -EINVAL;
+ }
+ rc = gsm0808_dec_cell_id(&r->cell_identifier, ie_cell_id->val, ie_cell_id->len);
+ if (rc < 0) {
+ LOG_RAN_A_DEC_MSG(LOGL_ERROR, "Decoding Cell Identifier gave rc=%d\n", rc);
+ return -EINVAL;
+ }
+
+ /* Layer 3 Information, 3.2.2.24 */
+ if (!ie_l3_info) {
+ LOG_RAN_A_DEC_MSG(LOGL_ERROR, "Mandatory IE missing: Layer 3 Information\n");
+ return -EINVAL;
+ }
+ if (ie_l3_info->len > LAYER_3_INFORMATION_MAXLEN) {
+ LOG_RAN_A_DEC_MSG(LOGL_ERROR, "Call Identifier has invalid length.\n");
+ return -EINVAL;
+ }
+ memcpy(r->l3.l3, ie_l3_info->val, ie_l3_info->len);
+ r->l3.l3_len = ie_l3_info->len;
+
+ /* Application Data Information, 3.2.2.100 */
+ if (!ie_app_data || ie_app_data->len < 1) {
+ LOG_RAN_A_DEC_MSG(LOGL_ERROR, "Mandatory IE missing: Application Data Information\n");
+ return -EINVAL;
+ }
+ r->bt_ind = ie_app_data->val[0] & 0x01;
+
+ return ran_decoded(ran_dec, &ran_dec_msg);
+}
+
+static int ran_a_decode_uplink_release_ind(struct ran_dec *ran_dec, const struct msgb *msg, const struct tlv_parsed *tp)
+{
+ struct ran_msg ran_dec_msg = {
+ .msg_type = RAN_MSG_UPLINK_RELEASE_IND,
+ .msg_name = "BSSMAP UPLINK RELEASE INDICATION",
+ };
+ struct gsm0808_uplink_release_ind *r = &ran_dec_msg.uplink_release_ind;
+
+ const struct tlv_p_entry *ie_cause = TLVP_GET(tp, GSM0808_IE_CAUSE);
+ const struct tlv_p_entry *ie_talker_priority = TLVP_GET(tp, GSM0808_IE_TALKER_PRIORITY);
+
+ /* Cause, 3.2.2.5 */
+ if (!ie_cause || ie_cause->len < 1) {
+ LOG_RAN_A_DEC_MSG(LOGL_ERROR, "Mandatory IE missing: Cause\n");
+ return -EINVAL;
+ }
+ r->cause = ie_cause->val[0];
+
+ /* Talker Priority, 3.2.2.89 */
+ if (ie_talker_priority) {
+ r->talker_priority = ie_talker_priority->val[0] & 0x03;
+ r->talker_priority_present = true;
+ }
+
+ return ran_decoded(ran_dec, &ran_dec_msg);
+}
+
+static int ran_a_decode_vgcs_vbs_assign_status(struct ran_dec *ran_dec, const struct msgb *msg,
+ const struct tlv_parsed *tp)
+{
+ struct ran_msg ran_dec_msg = {
+ .msg_type = RAN_MSG_VGCS_VBS_ASSIGN_STATUS,
+ .msg_name = "BSSMAP VGCS/VBS ASSIGNMENT STATUS",
+ };
+ struct gsm0808_vgcs_vbs_assign_stat *r = &ran_dec_msg.vgcs_vbs_assign_stat;
+ int rc;
+
+ const struct tlv_p_entry *ie_cils_est = TLVP_GET(tp, GSM0808_IE_CELL_ID_LIST_SEG_EST_CELLS);
+ const struct tlv_p_entry *ie_cils_tbe = TLVP_GET(tp, GSM0808_IE_CELL_ID_LIST_SEG_CELLS_TBE);
+ const struct tlv_p_entry *ie_cils_rel = TLVP_GET(tp, GSM0808_IE_CELL_ID_LIST_SEG_REL_CELLS);
+ const struct tlv_p_entry *ie_cils_ne = TLVP_GET(tp, GSM0808_IE_CELL_ID_LIST_SEG_NE_CELLS);
+ const struct tlv_p_entry *ie_cell_status = TLVP_GET(tp, GSM0808_IE_VGCS_VBS_CELL_STATUS);
+
+ /* Cell Identifier List Segment, 3.2.2.27b */
+ if (ie_cils_est) {
+ rc = gsm0808_dec_cell_id_list_segment(&r->cils_est, ie_cils_est->val, ie_cils_est->len);
+ if (rc < 0) {
+ LOG_RAN_A_DEC_MSG(LOGL_ERROR, "Decoding Cell Identifier gave rc=%d\n", rc);
+ return -EINVAL;
+ }
+ r->cils_est_present = true;
+ }
+
+ /* Cell Identifier List Segment, 3.2.2.27c */
+ if (ie_cils_tbe) {
+ rc = gsm0808_dec_cell_id_list_segment(&r->cils_tbe, ie_cils_tbe->val, ie_cils_tbe->len);
+ if (rc < 0) {
+ LOG_RAN_A_DEC_MSG(LOGL_ERROR, "Decoding Cell Identifier gave rc=%d\n", rc);
+ return -EINVAL;
+ }
+ r->cils_tbe_present = true;
+ }
+
+ /* Cell Identifier List Segment, 3.2.2.27e */
+ if (ie_cils_rel) {
+ rc = gsm0808_dec_cell_id_list_segment(&r->cils_rel, ie_cils_rel->val, ie_cils_rel->len);
+ if (rc < 0) {
+ LOG_RAN_A_DEC_MSG(LOGL_ERROR, "Decoding Cell Identifier gave rc=%d\n", rc);
+ return -EINVAL;
+ }
+ r->cils_rel_present = true;
+ }
+
+ /* Cell Identifier List Segment, 3.2.2.27f */
+ if (ie_cils_ne) {
+ rc = gsm0808_dec_cell_id_list_segment(&r->cils_ne, ie_cils_ne->val, ie_cils_ne->len);
+ if (rc < 0) {
+ LOG_RAN_A_DEC_MSG(LOGL_ERROR, "Decoding Cell Identifier gave rc=%d\n", rc);
+ return -EINVAL;
+ }
+ r->cils_ne_present = true;
+ }
+
+ /* VGCS/VBS Cell Status, 3.2.2.94 */
+ if (ie_cell_status && ie_cell_status->len) {
+ r->cell_status = ie_cell_status->val[0] & 0x73;
+ r->cell_status_present = true;
+ }
+
+ return ran_decoded(ran_dec, &ran_dec_msg);
+}
+
static int ran_a_decode_bssmap(struct ran_dec *ran_dec, struct msgb *bssmap)
{
struct tlv_parsed tp[2];
@@ -751,13 +1181,17 @@ static int ran_a_decode_bssmap(struct ran_dec *ran_dec, struct msgb *bssmap)
}
if (msgb_l3len(bssmap) < h->length) {
- LOG_RAN_A_DEC(ran_dec, LOGL_ERROR, "BSSMAP data truncated, discarding message\n");
+ LOG_RAN_A_DEC(ran_dec, LOGL_ERROR, "BSSMAP data truncated, discarding message:"
+ " msgb_l3len(bssmap) == %u < bssmap_header->length == %u\n",
+ msgb_l3len(bssmap), h->length);
return -1;
}
if (msgb_l3len(bssmap) > h->length) {
- LOG_RAN_A_DEC(ran_dec, LOGL_NOTICE, "There are %u extra bytes after the BSSMAP data, truncating\n",
- msgb_l3len(bssmap) - h->length);
+ LOG_RAN_A_DEC(ran_dec, LOGL_NOTICE, "There are %u extra bytes after the BSSMAP data, truncating:"
+ " msgb_l3len(bssmap) == %u > bssmap_header->length == %u\n",
+ msgb_l3len(bssmap) - h->length,
+ msgb_l3len(bssmap), h->length);
msgb_l3trim(bssmap, h->length);
}
@@ -770,7 +1204,7 @@ static int ran_a_decode_bssmap(struct ran_dec *ran_dec, struct msgb *bssmap)
return -EINVAL;
}
- LOG_RAN_A_DEC(ran_dec, LOGL_DEBUG, "Rx BSSMAP DT1 %s\n", gsm0808_bssmap_name(msg_type));
+ LOG_RAN_A_DEC(ran_dec, LOGL_DEBUG, "%s\n", gsm0808_bssmap_name(msg_type));
switch (msg_type) {
case BSS_MAP_MSG_COMPLETE_LAYER_3:
@@ -804,6 +1238,26 @@ static int ran_a_decode_bssmap(struct ran_dec *ran_dec, struct msgb *bssmap)
return ran_a_decode_sapi_n_reject(ran_dec, bssmap, tp);
case BSS_MAP_MSG_LCLS_NOTIFICATION:
return ran_a_decode_lcls_notification(ran_dec, bssmap, tp);
+ case BSS_MAP_MSG_VGCS_VBS_SETUP_ACK:
+ return ran_a_decode_vgcs_vbs_setup_ack(ran_dec, bssmap, tp);
+ case BSS_MAP_MSG_VGCS_VBS_SETUP_REFUSE:
+ return ran_a_decode_vgcs_vbs_setup_refuse(ran_dec, bssmap, tp);
+ case BSS_MAP_MSG_VGCS_VBS_ASSIGNMENT_RESULT:
+ return ran_a_decode_vgcs_vbs_assign_res(ran_dec, bssmap, tp);
+ case BSS_MAP_MSG_VGCS_VBS_ASSIGNMENT_FAILURE:
+ return ran_a_decode_vgcs_vbs_assign_fail(ran_dec, bssmap, tp);
+ case BSS_MAP_MSG_VGCS_VBS_QUEUING_INDICATION:
+ return ran_a_decode_vgcs_vbs_queuing_ind(ran_dec, bssmap, tp);
+ case BSS_MAP_MSG_UPLINK_RQST:
+ return ran_a_decode_uplink_request(ran_dec, bssmap, tp);
+ case BSS_MAP_MSG_UPLINK_RQST_CONFIRMATION:
+ return ran_a_decode_uplink_request_cnf(ran_dec, bssmap, tp);
+ case BSS_MAP_MSG_UPLINK_APP_DATA:
+ return ran_a_decode_uplink_application_data(ran_dec, bssmap, tp);
+ case BSS_MAP_MSG_UPLINK_RELEASE_INDICATION:
+ return ran_a_decode_uplink_release_ind(ran_dec, bssmap, tp);
+ case BSS_MAP_MSG_VGCS_VBS_ASSIGNMENT_STATUS:
+ return ran_a_decode_vgcs_vbs_assign_status(ran_dec, bssmap, tp);
/* From current RAN peer, the Handover origin: */
case BSS_MAP_MSG_HANDOVER_REQUIRED:
@@ -892,12 +1346,29 @@ static int ran_a_channel_type_to_speech_codec_list(struct gsm0808_speech_codec_l
int rc;
memset(scl, 0, sizeof(*scl));
- for (i = 0; i < ct->perm_spch_len; i++) {
- rc = gsm0808_speech_codec_from_chan_type(&scl->codec[i], ct->perm_spch[i]);
- if (rc != 0)
- return -EINVAL;
+
+ switch (ct->ch_indctr) {
+ case GSM0808_CHAN_DATA:
+ scl->codec[0] = (struct gsm0808_speech_codec) {
+ .pi = true, /* PI indicates CSDoIP is supported */
+ .pt = false, /* PT indicates CSDoTDM is not supported */
+ .type = GSM0808_SCT_CSD,
+ .cfg = 0, /* R2/R3 not set (redundancy not supported) */
+ };
+ scl->len = 1;
+ break;
+ case GSM0808_CHAN_SPEECH:
+ for (i = 0; i < ct->perm_spch_len; i++) {
+ rc = gsm0808_speech_codec_from_chan_type(&scl->codec[i], ct->perm_spch[i]);
+ if (rc != 0)
+ return -EINVAL;
+ }
+ scl->len = i;
+ break;
+ default:
+ OSMO_ASSERT(0);
+ break;
}
- scl->len = i;
return 0;
}
@@ -912,6 +1383,8 @@ static struct msgb *ran_a_make_assignment_command(struct osmo_fsm_inst *log_fi,
struct gsm0808_speech_codec_list *use_scl = NULL;
struct sockaddr_storage rtp_addr;
struct sockaddr_storage *use_rtp_addr = NULL;
+ struct msgb *msg;
+ const uint32_t *call_id = NULL;
int rc;
if (!ac->channel_type) {
@@ -919,7 +1392,7 @@ static struct msgb *ran_a_make_assignment_command(struct osmo_fsm_inst *log_fi,
return NULL;
}
- if (ac->channel_type->ch_indctr == GSM0808_CHAN_SPEECH) {
+ if (ac->channel_type->ch_indctr == GSM0808_CHAN_SPEECH || ac->channel_type->ch_indctr == GSM0808_CHAN_DATA) {
rc = ran_a_channel_type_to_speech_codec_list(&scl, ac->channel_type);
if (rc < 0) {
LOG_RAN_A_ENC(log_fi, LOGL_ERROR, "Assignment Command: Cannot translate Channel Type to Speech Codec List\n");
@@ -928,31 +1401,72 @@ static struct msgb *ran_a_make_assignment_command(struct osmo_fsm_inst *log_fi,
use_scl = &scl;
/* Package RTP-Address data */
- if (osmo_sockaddr_str_is_set(ac->cn_rtp)) {
- struct sockaddr_in rtp_addr_in;
-
- memset(&rtp_addr_in, 0, sizeof(rtp_addr_in));
- rtp_addr_in.sin_family = AF_INET;
- rtp_addr_in.sin_port = osmo_htons(ac->cn_rtp->port),
- rtp_addr_in.sin_addr.s_addr = inet_addr(ac->cn_rtp->ip);
-
- if (rtp_addr_in.sin_addr.s_addr == INADDR_NONE) {
- LOG_RAN_A_ENC(log_fi, LOGL_ERROR, "Assignment Command: Invalid RTP-Address\n");
- return NULL;
- }
- if (rtp_addr_in.sin_port == 0) {
- LOG_RAN_A_ENC(log_fi, LOGL_ERROR, "Assignment Command: Invalid RTP-Port\n");
+ if (osmo_sockaddr_str_is_nonzero(ac->cn_rtp)) {
+ struct sockaddr_in *sin;
+ struct sockaddr_in6 *sin6;
+ int family = osmo_ip_str_type(ac->cn_rtp->ip);
+ switch (family) {
+ case AF_INET:
+ sin = (struct sockaddr_in *)&rtp_addr;
+ sin->sin_family = AF_INET;
+ sin->sin_port = osmo_htons(ac->cn_rtp->port);
+ if (inet_pton(AF_INET, ac->cn_rtp->ip, &sin->sin_addr) != 1) {
+ LOG_RAN_A_ENC(log_fi, LOGL_ERROR,
+ "Assignment Command: Invalid RTP-Address %s\n",
+ ac->cn_rtp->ip);
+ return NULL;
+ }
+ if (sin->sin_port == 0) {
+ LOG_RAN_A_ENC(log_fi, LOGL_ERROR,
+ "Assignment Command: Invalid RTP-Port\n");
+ return NULL;
+ }
+ break;
+ case AF_INET6:
+ sin6 = (struct sockaddr_in6 *)&rtp_addr;
+ sin6->sin6_family = AF_INET6;
+ sin6->sin6_port = osmo_htons(ac->cn_rtp->port);
+ if (inet_pton(AF_INET6, ac->cn_rtp->ip, &sin6->sin6_addr) != 1) {
+ LOG_RAN_A_ENC(log_fi, LOGL_ERROR,
+ "Assignment Command: Invalid RTP-Address %s\n",
+ ac->cn_rtp->ip);
+ return NULL;
+ }
+ if (sin6->sin6_port == 0) {
+ LOG_RAN_A_ENC(log_fi, LOGL_ERROR,
+ "Assignment Command: Invalid RTP-Port\n");
+ return NULL;
+ }
+ break;
+ default:
+ LOG_RAN_A_ENC(log_fi, LOGL_ERROR,
+ "Assignment Command: Invalid RTP-Address type for %s\n",
+ ac->cn_rtp->ip);
return NULL;
}
-
- memset(&rtp_addr, 0, sizeof(rtp_addr));
- memcpy(&rtp_addr, &rtp_addr_in, sizeof(rtp_addr_in));
-
use_rtp_addr = &rtp_addr;
}
}
- return gsm0808_create_ass(ac->channel_type, NULL, use_rtp_addr, use_scl, NULL);
+ if(ac->call_id_present == true)
+ call_id = &ac->call_id;
+
+ msg = gsm0808_create_ass2(ac->channel_type, NULL, use_rtp_addr, use_scl, call_id,
+ NULL, ac->lcls);
+ if (msg == NULL) {
+ LOG_RAN_A_ENC(log_fi, LOGL_ERROR,
+ "Failed to encode BSSMAP Assignment Request message\n");
+ return NULL;
+ }
+
+ /* Append optional IEs: Group Call Reference and Osmux CID */
+ OSMO_ASSERT(msg->l3h[1] == msgb_l3len(msg) - 2); /* TL not in len */
+ if (ac->callref_present)
+ gsm0808_enc_group_callref(msg, &ac->callref);
+ if (ac->osmux_present)
+ msgb_tv_put(msg, GSM0808_IE_OSMO_OSMUX_CID, ac->osmux_cid);
+ msg->l3h[1] = msgb_l3len(msg) - 2;
+ return msg;
}
/* For an A5/N number a5_n set dst to the matching GSM0808_ALG_ID_A5_<n>. */
@@ -971,6 +1485,9 @@ static int a5_n_to_gsm0808_chosen_enc_alg(uint8_t *dst, int a5_n)
case 3:
*dst = GSM0808_ALG_ID_A5_3;
return 0;
+ case 4:
+ *dst = GSM0808_ALG_ID_A5_4;
+ return 0;
default:
return -ENOTSUP;
}
@@ -1010,14 +1527,17 @@ osmo_static_assert(sizeof(((struct gsm0808_encrypt_info*)0)->key) >= sizeof(((st
gsm0808_encrypt_info_key_fits_osmo_auth_vec_kc);
static struct msgb *ran_a_make_cipher_mode_command(struct osmo_fsm_inst *fi, const struct ran_cipher_mode_command *cm)
{
- struct gsm0808_encrypt_info ei = {};
+ struct gsm0808_cipher_mode_command cmc = {
+ .cipher_response_mode_present = true,
+ .cipher_response_mode = 1, /* 1: include IMEISV (3GPP TS 48.008 3.2.2.34) */
+ };
+ struct gsm0808_encrypt_info *ei = &cmc.ei;
char buf[16 * 2 + 1];
- const uint8_t cipher_response_mode = 1;
- if (make_encrypt_info_perm_algo(fi, &ei, cm->geran.a5_encryption_mask, cm->classmark))
+ if (make_encrypt_info_perm_algo(fi, ei, cm->geran.a5_encryption_mask, cm->classmark))
return NULL;
- if (ei.perm_algo_len == 0) {
+ if (ei->perm_algo_len == 0) {
LOG_RAN_A_ENC(fi, LOGL_ERROR, "cannot start ciphering, no intersection between MSC-configured"
" and MS-supported A5 algorithms. MSC: 0x%02x MS: %s\n",
cm->geran.a5_encryption_mask, osmo_gsm48_classmark_a5_name(cm->classmark));
@@ -1027,27 +1547,45 @@ static struct msgb *ran_a_make_cipher_mode_command(struct osmo_fsm_inst *fi, con
/* In case of UMTS AKA, the Kc for ciphering must be derived from the 3G auth
* tokens. vec->kc was calculated from the GSM algorithm and is not
* necessarily a match for the UMTS AKA tokens. */
- if (cm->geran.umts_aka)
- osmo_auth_c3(ei.key, cm->vec->ck, cm->vec->ik);
- else
- memcpy(ei.key, cm->vec->kc, sizeof(cm->vec->kc));
- ei.key_len = sizeof(cm->vec->kc);
+ if (cm->geran.umts_aka) {
+ int i;
+ osmo_auth_c3(ei->key, cm->vec->ck, cm->vec->ik);
+
+ for (i = 0; i < ei->perm_algo_len; i++) {
+ if (ei->perm_algo[i] != GSM0808_ALG_ID_A5_4)
+ continue;
+ /* A5/4 is included, so need to generate Kc128 */
+ osmo_kdf_kc128(cm->vec->ck, cm->vec->ik, cmc.kc128);
+ cmc.kc128_present = true;
+ break;
+ }
+ } else {
+ memcpy(ei->key, cm->vec->kc, sizeof(cm->vec->kc));
+ }
+ ei->key_len = sizeof(cm->vec->kc);
/* Store chosen GERAN key where the caller asked it to be stored.
* alg_id remains unknown until we receive a Cipher Mode Complete from the BSC */
if (cm->geran.chosen_key) {
- if (ei.key_len > sizeof(cm->geran.chosen_key->key)) {
+ *cm->geran.chosen_key = (struct geran_encr){0};
+
+ if (ei->key_len > sizeof(cm->geran.chosen_key->key)) {
LOG_RAN_A_ENC(fi, LOGL_ERROR, "Chosen key is larger than I can store\n");
return NULL;
}
- memcpy(cm->geran.chosen_key->key, ei.key, ei.key_len);
- cm->geran.chosen_key->key_len = ei.key_len;
+ memcpy(cm->geran.chosen_key->key, ei->key, ei->key_len);
+ cm->geran.chosen_key->key_len = ei->key_len;
+
+ if (cmc.kc128_present) {
+ memcpy(cm->geran.chosen_key->kc128, cmc.kc128, 16);
+ cm->geran.chosen_key->kc128_present = true;
+ }
}
LOG_RAN_A_ENC(fi, LOGL_DEBUG, "Tx BSSMAP CIPHER MODE COMMAND to BSC, %u ciphers (%s) key %s\n",
- ei.perm_algo_len, osmo_hexdump_nospc(ei.perm_algo, ei.perm_algo_len),
- osmo_hexdump_buf(buf, sizeof(buf), ei.key, ei.key_len, NULL, false));
- return gsm0808_create_cipher(&ei, cm->geran.retrieve_imeisv ? &cipher_response_mode : NULL);
+ ei->perm_algo_len, osmo_hexdump_nospc(ei->perm_algo, ei->perm_algo_len),
+ osmo_hexdump_buf(buf, sizeof(buf), ei->key, ei->key_len, NULL, false));
+ return gsm0808_create_cipher2(&cmc);
}
struct msgb *ran_a_make_handover_request(struct osmo_fsm_inst *log_fi, const struct ran_handover_request *n)
@@ -1067,6 +1605,7 @@ struct msgb *ran_a_make_handover_request(struct osmo_fsm_inst *log_fi, const str
.imsi = n->imsi,
.codec_list_msc_preferred = n->codec_list_msc_preferred,
+ .call_id_present = n->call_id_present,
.call_id = n->call_id,
.global_call_reference = n->global_call_reference,
.global_call_reference_len = n->global_call_reference_len,
@@ -1092,12 +1631,18 @@ struct msgb *ran_a_make_handover_request(struct osmo_fsm_inst *log_fi, const str
n->geran.chosen_encryption->key, n->geran.chosen_encryption->key_len);
r.encryption_information.key_len = n->geran.chosen_encryption->key_len;
r.chosen_encryption_algorithm_serving = n->geran.chosen_encryption->alg_id;
+
+ if (n->geran.chosen_encryption->kc128_present) {
+ r.more_items = true;
+ memcpy(r.kc128, n->geran.chosen_encryption->kc128, sizeof(r.kc128));
+ r.kc128_present = true;
+ }
}
if (n->classmark)
r.classmark_information = *n->classmark;
- if (osmo_sockaddr_str_is_set(n->rtp_ran_local)) {
+ if (osmo_sockaddr_str_is_nonzero(n->rtp_ran_local)) {
if (osmo_sockaddr_str_to_sockaddr(n->rtp_ran_local, &ss)) {
LOG_RAN_A_ENC(log_fi, LOGL_ERROR,
"Handover Request: invalid AoIP Transport Layer address/port: "
@@ -1122,7 +1667,7 @@ static struct msgb *ran_a_make_handover_request_ack(struct osmo_fsm_inst *caller
.chosen_speech_version = r->chosen_speech_version,
};
- if (osmo_sockaddr_str_is_set(&r->remote_rtp)) {
+ if (osmo_sockaddr_str_is_nonzero(&r->remote_rtp)) {
osmo_sockaddr_str_to_sockaddr(&r->remote_rtp, &ss);
params.aoip_transport_layer = &ss;
}
@@ -1168,6 +1713,13 @@ static struct msgb *_ran_a_encode(struct osmo_fsm_inst *caller_fi, const struct
case RAN_MSG_ASSIGNMENT_COMMAND:
return ran_a_make_assignment_command(caller_fi, &ran_enc_msg->assignment_command);
+ case RAN_MSG_COMMON_ID:
+ return gsm0808_create_common_id(ran_enc_msg->common_id.imsi, NULL,
+ ran_enc_msg->common_id.last_eutran_plmn_present ?
+ &ran_enc_msg->common_id.last_eutran_plmn :
+ NULL
+ );
+
case RAN_MSG_CIPHER_MODE_COMMAND:
return ran_a_make_cipher_mode_command(caller_fi, &ran_enc_msg->cipher_mode_command);
@@ -1189,6 +1741,36 @@ static struct msgb *_ran_a_encode(struct osmo_fsm_inst *caller_fi, const struct
case RAN_MSG_HANDOVER_FAILURE:
return ran_a_make_handover_failure(caller_fi, ran_enc_msg);
+ case RAN_MSG_VGCS_VBS_SETUP:
+ return gsm0808_create_vgcs_vbs_setup(&ran_enc_msg->vgcs_vbs_setup);
+
+ case RAN_MSG_VGCS_VBS_ASSIGN_REQ:
+ return gsm0808_create_vgcs_vbs_assign_req(&ran_enc_msg->vgcs_vbs_assign_req);
+
+ case RAN_MSG_UPLINK_REQUEST_ACK:
+ return gsm0808_create_uplink_request_ack(&ran_enc_msg->uplink_request_ack);
+
+ case RAN_MSG_UPLINK_REJECT_CMD:
+ return gsm0808_create_uplink_reject_cmd(&ran_enc_msg->uplink_reject_cmd);
+
+ case RAN_MSG_UPLINK_RELEASE_CMD:
+ return gsm0808_create_uplink_release_cmd(ran_enc_msg->uplink_release_cmd.cause);
+
+ case RAN_MSG_UPLINK_SEIZED_CMD:
+ return gsm0808_create_uplink_seized_cmd(&ran_enc_msg->uplink_seized_cmd);
+
+ case RAN_MSG_VGCS_ADDITIONAL_INFO:
+ return gsm0808_create_vgcs_additional_info(&ran_enc_msg->vgcs_additional_info.talker_identity);
+
+ case RAN_MSG_VGCS_VBS_AREA_CELL_INFO:
+ return gsm0808_create_vgcs_vbs_area_cell_info(&ran_enc_msg->vgcs_vbs_area_cell_info);
+
+ case RAN_MSG_VGCS_SMS:
+ return gsm0808_create_vgcs_sms(&ran_enc_msg->vgcs_sms.sms_to_vgcs);
+
+ case RAN_MSG_NOTIFICATION_DATA:
+ return gsm0808_create_notification_data(&ran_enc_msg->notification_data);
+
default:
LOG_RAN_A_ENC(caller_fi, LOGL_ERROR, "Unimplemented RAN-encode message type: %s\n",
ran_msg_type_name(ran_enc_msg->msg_type));
@@ -1220,20 +1802,50 @@ struct msgb *ran_a_encode(struct osmo_fsm_inst *caller_fi, const struct ran_msg
return msg;
}
-/* Return 1 for a RESET, 2 for a RESET ACK message, 0 otherwise */
-enum reset_msg_type bssmap_is_reset_msg(const struct sccp_ran_inst *sri, const struct msgb *l2)
+static void cl_parse_osmux(struct osmo_fsm_inst *log_fi, struct msgb *msg, int *supports_osmux)
+{
+ struct tlv_parsed tp;
+ int rc;
+
+ if (supports_osmux == NULL)
+ return;
+
+ rc = tlv_parse(&tp, gsm0808_att_tlvdef(), msgb_l3(msg) + 1, msgb_l3len(msg) - 1, 0, 0);
+ if (rc < 0) {
+ LOGPFSMSL(log_fi, DBSSAP, LOGL_ERROR, "BSSMAP: Failed parsing TLV looking for Osmux support\n");
+ return;
+ }
+
+ if (TLVP_PRESENT(&tp, GSM0808_IE_OSMO_OSMUX_SUPPORT)) {
+ *supports_osmux = true;
+ } else {
+ *supports_osmux = false;
+ }
+}
+
+/* Return 1 for a RESET, 2 for a RESET ACK message, 0 otherwise.
+ * In supports_osmux, return 0 for no information, 1 for support detected, -1 for non-support detected. */
+enum reset_msg_type bssmap_is_reset_msg(const struct sccp_ran_inst *sri, struct osmo_fsm_inst *log_fi,
+ struct msgb *l2, int *supports_osmux)
{
struct bssmap_header *bs = (struct bssmap_header *)msgb_l2(l2);
+ if (supports_osmux != NULL)
+ *supports_osmux = 0;
+
if (!bs
|| msgb_l2len(l2) < (sizeof(*bs) + 1)
|| bs->type != BSSAP_MSG_BSS_MANAGEMENT)
return SCCP_RAN_MSG_NON_RESET;
- switch (l2->l2h[sizeof(*bs)]) {
+ l2->l3h = l2->l2h + sizeof(struct bssmap_header);
+
+ switch (l2->l3h[0]) {
case BSS_MAP_MSG_RESET:
+ cl_parse_osmux(log_fi, l2, supports_osmux);
return SCCP_RAN_MSG_RESET;
case BSS_MAP_MSG_RESET_ACKNOWLEDGE:
+ cl_parse_osmux(log_fi, l2, supports_osmux);
return SCCP_RAN_MSG_RESET_ACK;
default:
return SCCP_RAN_MSG_NON_RESET;
diff --git a/src/libmsc/ran_msg_iu.c b/src/libmsc/ran_msg_iu.c
index f4439449d..37cdf1065 100644
--- a/src/libmsc/ran_msg_iu.c
+++ b/src/libmsc/ran_msg_iu.c
@@ -1,25 +1,21 @@
/* RANAP encoding and decoding for MSC */
/*
- * (C) 2019 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de>
+ * (C) 2019 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
* All Rights Reserved
*
* Author: Neels Hofmeyr
*
- * SPDX-License-Identifier: GPL-2.0+
+ * SPDX-License-Identifier: AGPL-3.0+
*
* This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ * GNU Affero General Public License for more details.
*/
#include <asn1c/asn1helpers.h>
@@ -27,6 +23,7 @@
#include <osmocom/core/prim.h>
#include <osmocom/core/byteswap.h>
#include <osmocom/crypt/auth.h>
+#include <osmocom/crypt/utran_cipher.h>
#include <osmocom/gsm/gsm48.h>
#include <osmocom/ranap/ranap_common_cn.h>
@@ -37,16 +34,7 @@
#include <osmocom/msc/msc_common.h>
#include <osmocom/msc/sccp_ran.h>
#include <osmocom/msc/ran_msg_iu.h>
-
-/* Implement the extern talloc_asn1_ctx from libasn1c as talloc ctx for ASN.1 message composition */
-void *talloc_asn1_ctx = NULL;
-
-/* Implement the extern asn_debug from libasn1c to indicate whether to print asn.1 debug messages. */
-int asn_debug = 0;
-
-/* Implement the extern asn1_xer_print to indicate whether the ASN.1 binary code decoded and encoded during Iu
- * communication should be logged to stderr (see asn.1 generated code in osmo-iuh). */
-int asn1_xer_print = 0;
+#include <osmocom/msc/gsm_04_11.h>
#define LOG_RAN_IU_DEC(RAN_DEC, level, fmt, args...) \
LOG_RAN_DEC(RAN_DEC, DIUCS, level, "RANAP: " fmt, ## args)
@@ -92,8 +80,11 @@ static void ran_iu_decode_l3_initial(struct ran_dec *ran_iu_decode, const RANAP_
msgb_free(ran);
}
-static void ran_iu_decode_l3(struct ran_dec *ran_iu_decode, const RANAP_NAS_PDU_t *nas_pdu, const char *msg_name)
+static void ran_iu_decode_l3(struct ran_dec *ran_iu_decode,
+ const RANAP_DirectTransferIEs_t *ies,
+ const char *msg_name)
{
+ const RANAP_NAS_PDU_t *nas_pdu = &ies->nas_pdu;
struct msgb *ran = msgb_alloc(256, msg_name);
struct ran_msg ran_dec_msg;
@@ -101,6 +92,12 @@ static void ran_iu_decode_l3(struct ran_dec *ran_iu_decode, const RANAP_NAS_PDU_
ran->l3h = msgb_put(ran, nas_pdu->size);
memcpy(ran->l3h, nas_pdu->buf, nas_pdu->size);
+ /* Handle optional SAPI IE */
+ if (ies->presenceMask & DIRECTTRANSFERIES_RANAP_SAPI_PRESENT) {
+ if (ies->sapi == RANAP_SAPI_sapi_3)
+ OMSC_LINKID_CB(ran) = UM_SAPI_SMS;
+ }
+
ran_dec_msg = (struct ran_msg){
.msg_type = RAN_MSG_DTAP,
.msg_name = msg_name,
@@ -156,7 +153,16 @@ static int ran_iu_decode_rab_assignment_response_decode_setup_ies(struct ran_dec
.msg_type = RAN_MSG_ASSIGNMENT_COMPLETE,
.msg_name = "RANAP RAB Assignment Response",
.assignment_complete = {
- .codec = CODEC_AMR_8000_1,
+ /* For codec compatibility resolution, indicate AMR-FR */
+ .codec_present = true,
+ .codec = {
+ .fi = true,
+ .type = GSM0808_SCT_FR3,
+ .cfg = GSM0808_SC_CFG_DEFAULT_FR_AMR,
+ },
+ /* Indicate that (at least) the first MGW endpoint towards RAN needs to expect VND.3GPP.IUFP
+ * that encapsulates the AMR-FR RTP payload. */
+ .codec_with_iuup = true,
},
};
if (osmo_sockaddr_str_from_str(&ran_dec_msg->assignment_complete.remote_rtp, addr, port)) {
@@ -211,12 +217,20 @@ success:
ranap_free_rab_setupormodifieditemies(&setup_ies);
}
-static void ran_iu_decode_security_mode_complete(struct ran_dec *ran_iu_decode)
+static void ran_iu_decode_security_mode_complete(struct ran_dec *ran_iu_decode, const RANAP_SecurityModeCompleteIEs_t *ies)
{
struct ran_msg ran_dec_msg = {
.msg_type = RAN_MSG_CIPHER_MODE_COMPLETE,
.msg_name = "RANAP SecurityModeControl successfulOutcome",
+ .cipher_mode_complete = {
+ .utran_integrity = ies->chosenIntegrityProtectionAlgorithm,
+ .utran_encryption = -1,
+ },
};
+
+ if (ies->presenceMask & SECURITYMODECOMPLETEIES_RANAP_CHOSENENCRYPTIONALGORITHM_PRESENT)
+ ran_dec_msg.cipher_mode_complete.utran_encryption = ies->chosenEncryptionAlgorithm;
+
ran_decoded(ran_iu_decode, &ran_dec_msg);
}
@@ -266,13 +280,13 @@ static void ran_iu_decode_ranap_msg(void *_ran_dec, ranap_message *message)
return;
case RANAP_ProcedureCode_id_DirectTransfer:
- ran_iu_decode_l3(ran_iu_decode, &message->msg.directTransferIEs.nas_pdu, "RANAP DirectTransfer RAN PDU");
+ ran_iu_decode_l3(ran_iu_decode, &message->msg.directTransferIEs, "RANAP DirectTransfer RAN PDU");
return;
case RANAP_ProcedureCode_id_SecurityModeControl:
switch (message->direction) {
case RANAP_RANAP_PDU_PR_successfulOutcome:
- ran_iu_decode_security_mode_complete(ran_iu_decode);
+ ran_iu_decode_security_mode_complete(ran_iu_decode, &message->msg.securityModeCompleteIEs);
return;
case RANAP_RANAP_PDU_PR_unsuccessfulOutcome:
ran_iu_decode_security_mode_reject(ran_iu_decode);
@@ -366,10 +380,21 @@ static struct msgb *ran_iu_make_rab_assignment(struct osmo_fsm_inst *caller_fi,
static struct msgb *ran_iu_make_security_mode_command(struct osmo_fsm_inst *caller_fi,
const struct ran_cipher_mode_command *cm)
{
-
- LOG_RAN_IU_ENC(caller_fi, LOGL_DEBUG, "Tx RANAP SECURITY MODE COMMAND to RNC, ik %s\n",
- osmo_hexdump_nospc(cm->vec->ik, 16));
- return ranap_new_msg_sec_mod_cmd(cm->vec->ik, NULL, RANAP_KeyStatus_new);
+ /* TODO: make the choice of available UIA algorithms configurable */
+ const uint8_t uia_mask = (1 << OSMO_UTRAN_UIA1) | (1 << OSMO_UTRAN_UIA2);
+ const uint8_t uea_mask = cm->utran.uea_encryption_mask & ~(1 << OSMO_UTRAN_UEA0);
+ bool use_encryption = uea_mask != 0x00;
+
+ LOG_RAN_IU_ENC(caller_fi, LOGL_DEBUG, "Tx RANAP SECURITY MODE COMMAND to RNC, IK=%s, CK=%s\n",
+ osmo_hexdump_nospc(cm->vec->ik, 16),
+ use_encryption ? osmo_hexdump_nospc(cm->vec->ck, 16) : "NONE");
+ /* TODO: Do we need to check if the UE supports all of the algorithms and build an intersection like
+ * in the case of A5? */
+ return ranap_new_msg_sec_mod_cmd2(cm->vec->ik,
+ use_encryption ? cm->vec->ck : NULL,
+ RANAP_KeyStatus_new,
+ (uia_mask << 1), /* API treats LSB as UIA0 */
+ uea_mask);
}
@@ -386,25 +411,28 @@ static struct msgb *ran_iu_make_release_command(struct osmo_fsm_inst *caller_fi,
struct msgb *ran_iu_encode(struct osmo_fsm_inst *caller_fi, const struct ran_msg *ran_enc_msg)
{
- LOG_RAN_IU_ENC(caller_fi, LOGL_DEBUG, "%s\n", ran_msg_type_name(ran_enc_msg->msg_type));
-
switch (ran_enc_msg->msg_type) {
case RAN_MSG_DTAP:
+ LOG_RAN_IU_ENC(caller_fi, LOGL_DEBUG, "DirectTransfer\n");
return ran_iu_wrap_dtap(ran_enc_msg->dtap);
// TODO: RAN_MSG_CLASSMARK_REQUEST ??
case RAN_MSG_CIPHER_MODE_COMMAND:
+ LOG_RAN_IU_ENC(caller_fi, LOGL_DEBUG, "SecurityModeCommand\n");
return ran_iu_make_security_mode_command(caller_fi, &ran_enc_msg->cipher_mode_command);
case RAN_MSG_ASSIGNMENT_COMMAND:
+ LOG_RAN_IU_ENC(caller_fi, LOGL_DEBUG, "RAB AssignmentRequest\n");
return ran_iu_make_rab_assignment(caller_fi, &ran_enc_msg->assignment_command);
case RAN_MSG_COMMON_ID:
+ LOG_RAN_IU_ENC(caller_fi, LOGL_DEBUG, "CommonId\n");
return ranap_new_msg_common_id(ran_enc_msg->common_id.imsi);
case RAN_MSG_CLEAR_COMMAND:
+ LOG_RAN_IU_ENC(caller_fi, LOGL_DEBUG, "Iu Release\n");
return ran_iu_make_release_command(caller_fi, &ran_enc_msg->clear_command);
default:
@@ -435,11 +463,15 @@ static void ranap_handle_cl(void *ctx, ranap_message *message)
}
}
-enum reset_msg_type ranap_is_reset_msg(const struct sccp_ran_inst *sri, const struct msgb *l2)
+enum reset_msg_type ranap_is_reset_msg(const struct sccp_ran_inst *sri, struct osmo_fsm_inst *log_fi,
+ struct msgb *l2, int *supports_osmux)
{
int ret = SCCP_RAN_MSG_NON_RESET;
int rc;
+ if (supports_osmux != NULL)
+ *supports_osmux = -1;
+
rc = ranap_cn_rx_cl(ranap_handle_cl, &ret, msgb_l2(l2), msgb_l2len(l2));
if (rc)
return 0;
diff --git a/src/libmsc/ran_peer.c b/src/libmsc/ran_peer.c
index ce26794cd..860444334 100644
--- a/src/libmsc/ran_peer.c
+++ b/src/libmsc/ran_peer.c
@@ -1,5 +1,5 @@
/*
- * (C) 2019 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de>
+ * (C) 2019 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
* All Rights Reserved
*
* SPDX-License-Identifier: AGPL-3.0+
@@ -33,6 +33,7 @@
#include <osmocom/msc/vlr.h>
#include <osmocom/msc/ran_conn.h>
#include <osmocom/msc/cell_id_list.h>
+#include <osmocom/msc/msc_vgcs.h>
static struct osmo_fsm ran_peer_fsm;
@@ -80,13 +81,13 @@ static struct ran_peer *ran_peer_alloc(struct sccp_ran_inst *sri, const struct o
struct ran_peer *ran_peer_find_or_create(struct sccp_ran_inst *sri, const struct osmo_sccp_addr *peer_addr)
{
- struct ran_peer *rp = ran_peer_find(sri, peer_addr);
+ struct ran_peer *rp = ran_peer_find_by_addr(sri, peer_addr);
if (rp)
return rp;
return ran_peer_alloc(sri, peer_addr);
}
-struct ran_peer *ran_peer_find(struct sccp_ran_inst *sri, const struct osmo_sccp_addr *peer_addr)
+struct ran_peer *ran_peer_find_by_addr(struct sccp_ran_inst *sri, const struct osmo_sccp_addr *peer_addr)
{
struct ran_peer *rp;
llist_for_each_entry(rp, &sri->ran_peers, entry) {
@@ -118,29 +119,28 @@ void ran_peer_discard_all_conns(struct ran_peer *rp)
struct ran_conn *conn, *next;
ran_peer_for_each_ran_conn_safe(conn, next, rp) {
- ran_conn_discard(conn);
+ /* Tell VGCS FSM that the connections have been cleared. */
+ if (conn->vgcs.bss)
+ vgcs_vbs_clear_cpl(conn->vgcs.bss, NULL);
+ else if (conn->vgcs.cell)
+ vgcs_vbs_clear_cpl_channel(conn->vgcs.cell, NULL);
+ else ran_conn_discard(conn);
}
}
-/* TODO: create an sccp_ran_ops.rx_reset(_ack) to handle this differently on 2g and 3G */
-/* We expect RAN peer to provide use with an Osmocom extension TLV in BSSMAP_RESET to
- * announce Osmux support */
-static void ran_peer_update_osmux_support(struct ran_peer *rp, struct msgb *msg)
+static void ran_peer_update_osmux_support(struct ran_peer *rp, int supports_osmux)
{
- struct tlv_parsed tp;
- int rc;
bool old_value = rp->remote_supports_osmux;
- OSMO_ASSERT(msg);
- msg->l3h = msg->l2h + sizeof(struct bssmap_header);
- rc = tlv_parse(&tp, gsm0808_att_tlvdef(), msg->l3h + 1, msgb_l3len(msg) - 1, 0, 0);
- if (rc < 0)
- LOG_RAN_PEER(rp, LOGL_NOTICE, "Failed parsing TLV looking for Osmux support\n");
-
- if (TLVP_PRESENT(&tp, GSM0808_IE_OSMO_OSMUX_SUPPORT)) {
+ switch (supports_osmux) {
+ case 1:
rp->remote_supports_osmux = true;
- } else {
+ break;
+ case -1:
rp->remote_supports_osmux = false;
+ break;
+ default:
+ return;
}
if (old_value != rp->remote_supports_osmux)
@@ -155,8 +155,6 @@ static void ran_peer_rx_reset(struct ran_peer *rp, struct msgb* msg)
ran_peer_discard_all_conns(rp);
- ran_peer_update_osmux_support(rp, msg);
-
reset_ack = rp->sri->ran->sccp_ran_ops.make_reset_msg(rp->sri, SCCP_RAN_MSG_RESET_ACK);
if (!reset_ack) {
@@ -183,7 +181,6 @@ static void ran_peer_rx_reset(struct ran_peer *rp, struct msgb* msg)
static void ran_peer_rx_reset_ack(struct ran_peer *rp, struct msgb* msg)
{
ran_peer_state_chg(rp, RAN_PEER_ST_READY);
- ran_peer_update_osmux_support(rp, msg);
}
void ran_peer_reset(struct ran_peer *rp)
@@ -213,14 +210,18 @@ void ran_peer_allstate_action(struct osmo_fsm_inst *fi, uint32_t event, void *da
struct ran_peer *rp = fi->priv;
struct ran_peer_ev_ctx *ctx = data;
struct msgb *msg = ctx->msg;
+ enum reset_msg_type is_reset;
+ int supports_osmux;
switch (event) {
case RAN_PEER_EV_MSG_UP_CL:
- switch (rp->sri->ran->sccp_ran_ops.is_reset_msg(rp->sri, msg)) {
- case 1:
+ is_reset = rp->sri->ran->sccp_ran_ops.is_reset_msg(rp->sri, fi, msg, &supports_osmux);
+ ran_peer_update_osmux_support(rp, supports_osmux);
+ switch (is_reset) {
+ case SCCP_RAN_MSG_RESET:
osmo_fsm_inst_dispatch(fi, RAN_PEER_EV_RX_RESET, msg);
return;
- case 2:
+ case SCCP_RAN_MSG_RESET_ACK:
osmo_fsm_inst_dispatch(fi, RAN_PEER_EV_RX_RESET_ACK, msg);
return;
default:
@@ -370,7 +371,7 @@ void ran_peer_st_ready(struct osmo_fsm_inst *fi, uint32_t event, void *data)
case RAN_PEER_EV_MSG_UP_CO_INITIAL:
ctx = data;
- OSMO_ASSERT(ctx)
+ OSMO_ASSERT(ctx);
OSMO_ASSERT(!ctx->conn);
OSMO_ASSERT(ctx->msg);
@@ -398,18 +399,22 @@ void ran_peer_st_ready(struct osmo_fsm_inst *fi, uint32_t event, void *data)
OSMO_ASSERT(ctx->conn);
OSMO_ASSERT(ctx->msg);
- if (!ctx->conn->msc_role) {
+ if (ctx->conn->msc_role) {
+ /* "normal" A connection, dispatch to MSC-I or MSC-T */
+ an_apdu = (struct an_apdu){
+ .an_proto = rp->sri->ran->an_proto,
+ .msg = ctx->msg,
+ };
+ osmo_fsm_inst_dispatch(ctx->conn->msc_role, MSC_EV_FROM_RAN_UP_L2, &an_apdu);
+ } else if (ctx->conn->vgcs.bss) {
+ /* VGCS call related */
+ msc_a_rx_vgcs_bss(ctx->conn->vgcs.bss, ctx->conn, ctx->msg);
+ } else if (ctx->conn->vgcs.cell) {
+ /* VGCS channel related */
+ msc_a_rx_vgcs_cell(ctx->conn->vgcs.cell, ctx->conn, ctx->msg);
+ } else
LOG_RAN_PEER(rp, LOGL_ERROR,
"Rx CO message on conn that is not associated with any MSC role\n");
- return;
- }
-
- an_apdu = (struct an_apdu){
- .an_proto = rp->sri->ran->an_proto,
- .msg = ctx->msg,
- };
-
- osmo_fsm_inst_dispatch(ctx->conn->msc_role, MSC_EV_FROM_RAN_UP_L2, &an_apdu);
return;
case RAN_PEER_EV_MSG_DOWN_CO_INITIAL:
@@ -629,17 +634,6 @@ struct ran_peer *ran_peer_find_by_cell_id(struct sccp_ran_inst *sri, const struc
return found;
}
-struct ran_peer *ran_peer_find_by_addr(struct sccp_ran_inst *sri, const struct osmo_sccp_addr *addr)
-{
- struct ran_peer *rp;
-
- llist_for_each_entry(rp, &sri->ran_peers, entry) {
- if (!osmo_sccp_addr_ri_cmp(addr, &rp->peer_addr))
- return rp;
- }
- return NULL;
-}
-
int ran_peers_down_paging(struct sccp_ran_inst *sri, enum CELL_IDENT page_where, struct vlr_subscr *vsub,
enum paging_cause cause)
{
@@ -650,7 +644,7 @@ int ran_peers_down_paging(struct sccp_ran_inst *sri, enum CELL_IDENT page_where,
switch (page_where) {
case CELL_IDENT_NO_CELL:
- LOG_SCCP_RAN_CAT(sri, DPAG, LOGL_ERROR, "Asked to page on NO_CELL, wich doesn't make sense.\n");
+ LOG_SCCP_RAN_CAT(sri, DPAG, LOGL_ERROR, "Asked to page on NO_CELL, which doesn't make sense.\n");
return 0;
case CELL_IDENT_UTRAN_PLMN_LAC_RNC:
diff --git a/src/libmsc/rtp_stream.c b/src/libmsc/rtp_stream.c
index afe24ad51..eb9ba7e52 100644
--- a/src/libmsc/rtp_stream.c
+++ b/src/libmsc/rtp_stream.c
@@ -1,5 +1,5 @@
/*
- * (C) 2019 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de>
+ * (C) 2019 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
* All Rights Reserved
*
* SPDX-License-Identifier: AGPL-3.0+
@@ -28,6 +28,7 @@
#include <osmocom/msc/transaction.h>
#include <osmocom/msc/call_leg.h>
#include <osmocom/msc/rtp_stream.h>
+#include <osmocom/msc/codec_mapping.h>
#define LOG_RTPS(rtps, level, fmt, args...) \
LOGPFSML(rtps->fi, level, fmt, ##args)
@@ -74,19 +75,29 @@ void rtp_stream_update_id(struct rtp_stream *rtps)
OSMO_STRBUF_PRINTF(sb, ":no-CI");
} else {
OSMO_STRBUF_PRINTF(sb, ":CI-%s", osmo_mgcpc_ep_ci_id(rtps->ci));
- if (!osmo_sockaddr_str_is_set(&rtps->remote))
+ if (!osmo_sockaddr_str_is_nonzero(&rtps->remote))
OSMO_STRBUF_PRINTF(sb, ":no-remote-port");
else if (!rtps->remote_sent_to_mgw)
OSMO_STRBUF_PRINTF(sb, ":remote-port-not-sent");
- if (!rtps->codec_known)
- OSMO_STRBUF_PRINTF(sb, ":no-codec");
- else if (!rtps->codec_sent_to_mgw)
- OSMO_STRBUF_PRINTF(sb, ":codec-not-sent");
+ if (!rtps->codecs_known)
+ OSMO_STRBUF_PRINTF(sb, ":no-codecs");
+ else if (!rtps->codecs_sent_to_mgw)
+ OSMO_STRBUF_PRINTF(sb, ":codecs-not-sent");
+ if (!rtps->codecs_sent_to_mgw)
+ OSMO_STRBUF_PRINTF(sb, ":mode-not-sent");
+ if (rtps->use_osmux) {
+ if (rtps->remote_osmux_cid < 0)
+ OSMO_STRBUF_PRINTF(sb, ":no-remote-osmux-cid");
+ else if (!rtps->remote_osmux_cid_sent_to_mgw)
+ OSMO_STRBUF_PRINTF(sb, ":remote-osmux-cid-not-sent");
+ }
}
- if (osmo_sockaddr_str_is_set(&rtps->local))
+ if (osmo_sockaddr_str_is_nonzero(&rtps->local))
OSMO_STRBUF_PRINTF(sb, ":local-%s-%u", rtps->local.ip, rtps->local.port);
- if (osmo_sockaddr_str_is_set(&rtps->remote))
+ if (osmo_sockaddr_str_is_nonzero(&rtps->remote))
OSMO_STRBUF_PRINTF(sb, ":remote-%s-%u", rtps->remote.ip, rtps->remote.port);
+ if (rtps->use_osmux)
+ OSMO_STRBUF_PRINTF(sb, ":osmux-%d-%d", rtps->local_osmux_cid, rtps->remote_osmux_cid);
/* Replace any dots in the IP address, dots not allowed as FSM instance name */
for (p = buf; *p; p++)
@@ -99,13 +110,14 @@ void rtp_stream_update_id(struct rtp_stream *rtps)
/* Allocate RTP stream under a call leg. This is one RTP connection from some remote entity with address and port to a
* local RTP address and port. call_id is stored for sending in MGCP transactions and as logging context. for_trans is
* optional, merely stored for reference by callers, and appears as log context if not NULL. */
-struct rtp_stream *rtp_stream_alloc(struct call_leg *parent_call_leg, enum rtp_direction dir,
- uint32_t call_id, struct gsm_trans *for_trans)
+struct rtp_stream *rtp_stream_alloc(struct osmo_fsm_inst *parent_fi, uint32_t event_gone, uint32_t event_avail,
+ uint32_t event_estab, enum rtp_direction dir, uint32_t call_id,
+ struct gsm_trans *for_trans)
{
struct osmo_fsm_inst *fi;
struct rtp_stream *rtps;
- fi = osmo_fsm_inst_alloc_child(&rtp_stream_fsm, parent_call_leg->fi, CALL_LEG_EV_RTP_STREAM_GONE);
+ fi = osmo_fsm_inst_alloc_child(&rtp_stream_fsm, parent_fi, event_gone);
OSMO_ASSERT(fi);
rtps = talloc(fi, struct rtp_stream);
@@ -113,10 +125,14 @@ struct rtp_stream *rtp_stream_alloc(struct call_leg *parent_call_leg, enum rtp_d
fi->priv = rtps;
*rtps = (struct rtp_stream){
.fi = fi,
- .parent_call_leg = parent_call_leg,
+ .event_avail = event_avail,
+ .event_estab = event_estab,
.call_id = call_id,
.for_trans = for_trans,
.dir = dir,
+ .local_osmux_cid = -2,
+ .remote_osmux_cid = -2,
+ .crcx_conn_mode = MGCP_CONN_NONE, /* Use connection's default mode. */
};
rtp_stream_update_id(rtps);
@@ -127,10 +143,11 @@ struct rtp_stream *rtp_stream_alloc(struct call_leg *parent_call_leg, enum rtp_d
static void check_established(struct rtp_stream *rtps)
{
if (rtps->fi->state != RTP_STREAM_ST_ESTABLISHED
- && osmo_sockaddr_str_is_set(&rtps->local)
- && osmo_sockaddr_str_is_set(&rtps->remote)
+ && osmo_sockaddr_str_is_nonzero(&rtps->local)
+ && osmo_sockaddr_str_is_nonzero(&rtps->remote)
&& rtps->remote_sent_to_mgw
- && rtps->codec_known)
+ && (!rtps->use_osmux || rtps->remote_osmux_cid_sent_to_mgw)
+ && rtps->codecs_known)
rtp_stream_state_chg(rtps, RTP_STREAM_ST_ESTABLISHED);
}
@@ -148,17 +165,28 @@ static void rtp_stream_fsm_establishing_established(struct osmo_fsm_inst *fi, ui
}
osmo_sockaddr_str_from_str(&rtps->local, crcx_info->addr, crcx_info->port);
+ if (rtps->use_osmux != crcx_info->x_osmo_osmux_use) {
+ LOG_RTPS(rtps, LOGL_ERROR, "Osmux usage request and response don't match: %d vs %d",
+ rtps->use_osmux, crcx_info->x_osmo_osmux_use);
+ /* TODO: proper failure path */
+ OSMO_ASSERT(rtps->use_osmux != crcx_info->x_osmo_osmux_use);
+ }
+ if (crcx_info->x_osmo_osmux_use)
+ rtps->local_osmux_cid = crcx_info->x_osmo_osmux_cid;
rtp_stream_update_id(rtps);
- osmo_fsm_inst_dispatch(fi->proc.parent, CALL_LEG_EV_RTP_STREAM_ADDR_AVAILABLE, rtps);
+ osmo_fsm_inst_dispatch(fi->proc.parent, rtps->event_avail, rtps);
check_established(rtps);
- if ((!rtps->remote_sent_to_mgw || !rtps->codec_sent_to_mgw)
- && osmo_sockaddr_str_is_set(&rtps->remote)
- && rtps->codec_known) {
+ if ((!rtps->remote_sent_to_mgw || !rtps->codecs_sent_to_mgw || !rtps->mode_sent_to_mgw)
+ && osmo_sockaddr_str_is_nonzero(&rtps->remote)
+ && (!rtps->use_osmux || rtps->remote_osmux_cid_sent_to_mgw)
+ && rtps->codecs_known) {
LOG_RTPS(rtps, LOGL_DEBUG,
- "local ip:port set;%s%s triggering MDCX to send the new settings\n",
- (!rtps->remote_sent_to_mgw)? " remote ip:port not yet sent," : "",
- (!rtps->codec_sent_to_mgw)? " codec not yet sent," : "");
+ "local ip:port set;%s%s%s%s triggering MDCX to send the new settings\n",
+ (!rtps->remote_sent_to_mgw) ? " remote ip:port not yet sent," : "",
+ (!rtps->codecs_sent_to_mgw) ? " codecs not yet sent," : "",
+ (!rtps->mode_sent_to_mgw) ? " mode not yet sent," : "",
+ (rtps->use_osmux && !rtps->remote_osmux_cid_sent_to_mgw) ? "Osmux CID not yet sent,": "");
rtp_stream_do_mdcx(rtps);
}
return;
@@ -171,7 +199,9 @@ static void rtp_stream_fsm_establishing_established(struct osmo_fsm_inst *fi, ui
case RTP_STREAM_EV_CRCX_FAIL:
case RTP_STREAM_EV_MDCX_FAIL:
rtps->remote_sent_to_mgw = false;
- rtps->codec_sent_to_mgw = false;
+ rtps->codecs_sent_to_mgw = false;
+ rtps->mode_sent_to_mgw = false;
+ rtps->remote_osmux_cid_sent_to_mgw = false;
rtp_stream_update_id(rtps);
rtp_stream_state_chg(rtps, RTP_STREAM_ST_DISCARDING);
return;
@@ -184,7 +214,7 @@ static void rtp_stream_fsm_establishing_established(struct osmo_fsm_inst *fi, ui
void rtp_stream_fsm_established_onenter(struct osmo_fsm_inst *fi, uint32_t prev_state)
{
struct rtp_stream *rtps = fi->priv;
- osmo_fsm_inst_dispatch(fi->proc.parent, CALL_LEG_EV_RTP_STREAM_ESTABLISHED, rtps);
+ osmo_fsm_inst_dispatch(fi->proc.parent, rtps->event_estab, rtps);
}
static int rtp_stream_fsm_timer_cb(struct osmo_fsm_inst *fi)
@@ -198,6 +228,7 @@ static void rtp_stream_fsm_cleanup(struct osmo_fsm_inst *fi, enum osmo_fsm_term_
{
struct rtp_stream *rtps = fi->priv;
if (rtps->ci) {
+ osmo_mgcpc_ep_cancel_notify(osmo_mgcpc_ep_ci_ep(rtps->ci), fi);
osmo_mgcpc_ep_ci_dlcx(rtps->ci);
rtps->ci = NULL;
}
@@ -280,17 +311,36 @@ static int rtp_stream_do_mgcp_verb(struct rtp_stream *rtps, enum mgcp_verb verb,
verb_info = (struct mgcp_conn_peer){
.call_id = rtps->call_id,
.ptime = 20,
+ .x_osmo_osmux_use = rtps->use_osmux,
+ .x_osmo_osmux_cid = rtps->remote_osmux_cid,
};
- if (verb == MGCP_VERB_CRCX)
- verb_info.conn_mode = rtps->crcx_conn_mode;
-
- if (rtps->codec_known) {
- verb_info.codecs[0] = rtps->codec;
- verb_info.codecs_len = 1;
- rtps->codec_sent_to_mgw = true;
+ verb_info.conn_mode = rtps->crcx_conn_mode;
+
+ if (rtps->codecs_known) {
+ /* Send the list of codecs to the MGW. Ideally we would just feed the SDP directly, but for legacy
+ * reasons we still need to translate to a struct mgcp_conn_peer representation to send it. */
+ struct sdp_audio_codec *codec;
+ int i = 0;
+ sdp_audio_codecs_foreach(codec, &rtps->codecs) {
+ const struct codec_mapping *m = codec_mapping_by_subtype_name(codec->subtype_name);
+ if (!m) {
+ LOG_RTPS(rtps, LOGL_ERROR, "Cannot map codec '%s' to MGCP: codec is unknown\n",
+ codec->subtype_name);
+ continue;
+ }
+ verb_info.codecs[i] = m->mgcp;
+ verb_info.ptmap[i] = (struct ptmap){
+ .codec = m->mgcp,
+ .pt = codec->payload_type,
+ };
+ i++;
+ verb_info.codecs_len = i;
+ verb_info.ptmap_len = i;
+ }
+ rtps->codecs_sent_to_mgw = true;
}
- if (osmo_sockaddr_str_is_set(&rtps->remote)) {
+ if (osmo_sockaddr_str_is_nonzero(&rtps->remote)) {
int rc = osmo_strlcpy(verb_info.addr, rtps->remote.ip, sizeof(verb_info.addr));
if (rc <= 0 || rc >= sizeof(verb_info.addr)) {
LOG_RTPS(rtps, LOGL_ERROR, "Failure to write IP address to MGCP message (rc=%d)\n", rc);
@@ -299,6 +349,10 @@ static int rtp_stream_do_mgcp_verb(struct rtp_stream *rtps, enum mgcp_verb verb,
verb_info.port = rtps->remote.port;
rtps->remote_sent_to_mgw = true;
}
+ rtps->mode_sent_to_mgw = true;
+ if (rtps->use_osmux && rtps->remote_osmux_cid >= 0)
+ rtps->remote_osmux_cid_sent_to_mgw = true;
+ rtp_stream_update_id(rtps);
osmo_mgcpc_ep_ci_request(rtps->ci, verb, &verb_info, rtps->fi, ok_event, fail_event, NULL);
return 0;
@@ -332,46 +386,91 @@ void rtp_stream_release(struct rtp_stream *rtps)
}
/* After setting up a remote RTP address or a new codec, call this to trigger an MDCX.
- * The MDCX will only trigger if all data needed by an endpoint is available (both RTP address and codec) and if at
+ * The MDCX will only trigger if all data needed by an endpoint is available (RTP address, codecs and mode) and if at
* least one of them has not yet been sent to the MGW in a previous CRCX or MDCX. */
int rtp_stream_commit(struct rtp_stream *rtps)
{
- if (!rtps->ci) {
- LOG_RTPS(rtps, LOGL_DEBUG, "Not committing: no MGW endpoint CI set up\n");
- return -1;
- }
- if (!osmo_sockaddr_str_is_set(&rtps->remote)) {
+ if (!osmo_sockaddr_str_is_nonzero(&rtps->remote)) {
LOG_RTPS(rtps, LOGL_DEBUG, "Not committing: no remote RTP address known\n");
return -1;
}
- if (!rtps->codec_known) {
- LOG_RTPS(rtps, LOGL_DEBUG, "Not committing: no codec known\n");
+ if (!rtps->codecs_known) {
+ LOG_RTPS(rtps, LOGL_DEBUG, "Not committing: no codecs known\n");
return -1;
}
- if (rtps->remote_sent_to_mgw && rtps->codec_sent_to_mgw) {
- LOG_RTPS(rtps, LOGL_DEBUG, "Not committing: both remote RTP address and codec already set up at MGW\n");
+ if (rtps->remote_sent_to_mgw && rtps->codecs_sent_to_mgw && rtps->mode_sent_to_mgw) {
+ LOG_RTPS(rtps, LOGL_DEBUG,
+ "Not committing: remote RTP address, codecs and mode are already set up at MGW\n");
return 0;
}
+ if (!rtps->ci) {
+ LOG_RTPS(rtps, LOGL_DEBUG, "Not committing: no MGW endpoint CI set up\n");
+ return -1;
+ }
- LOG_RTPS(rtps, LOGL_DEBUG, "Committing: Tx MDCX to update the MGW: updating%s%s\n",
+ LOG_RTPS(rtps, LOGL_DEBUG, "Committing: Tx MDCX to update the MGW: updating%s%s%s%s\n",
rtps->remote_sent_to_mgw ? "" : " remote-RTP-IP-port",
- rtps->codec_sent_to_mgw ? "" : " codec");
+ rtps->codecs_sent_to_mgw ? "" : " codecs",
+ rtps->mode_sent_to_mgw ? "" : " mode",
+ (!rtps->use_osmux || rtps->remote_osmux_cid_sent_to_mgw) ? "" : " remote-Osmux-CID");
return rtp_stream_do_mdcx(rtps);
}
-void rtp_stream_set_codec(struct rtp_stream *rtps, enum mgcp_codecs codec)
+void rtp_stream_set_codecs(struct rtp_stream *rtps, const struct sdp_audio_codecs *codecs)
+{
+ if (!codecs || !codecs->count)
+ return;
+ if (sdp_audio_codecs_cmp(&rtps->codecs, codecs, false, true) == 0) {
+ LOG_RTPS(rtps, LOGL_DEBUG, "no change: codecs already set to %s\n",
+ sdp_audio_codecs_to_str(&rtps->codecs));
+ return;
+ }
+ if (rtps->fi->state == RTP_STREAM_ST_ESTABLISHED)
+ rtp_stream_state_chg(rtps, RTP_STREAM_ST_ESTABLISHING);
+ LOG_RTPS(rtps, LOGL_DEBUG, "setting codecs to %s\n", sdp_audio_codecs_to_str(codecs));
+ rtps->codecs = *codecs;
+ rtps->codecs_known = true;
+ rtps->codecs_sent_to_mgw = false;
+ rtp_stream_update_id(rtps);
+}
+
+void rtp_stream_set_mode(struct rtp_stream *rtps, enum mgcp_connection_mode mode)
{
+ if (rtps->crcx_conn_mode == mode)
+ return;
if (rtps->fi->state == RTP_STREAM_ST_ESTABLISHED)
rtp_stream_state_chg(rtps, RTP_STREAM_ST_ESTABLISHING);
- LOG_RTPS(rtps, LOGL_DEBUG, "setting codec to %s\n", osmo_mgcpc_codec_name(codec));
- rtps->codec = codec;
- rtps->codec_known = true;
- rtps->codec_sent_to_mgw = false;
+ LOG_RTPS(rtps, LOGL_DEBUG, "setting mode to %s\n", mgcp_client_cmode_name(mode));
+ rtps->mode_sent_to_mgw = false;
+ rtps->crcx_conn_mode = mode;
rtp_stream_update_id(rtps);
}
+/* Convenience shortcut to call rtp_stream_set_codecs() with a list of only one sdp_audio_codec record. */
+void rtp_stream_set_one_codec(struct rtp_stream *rtps, const struct sdp_audio_codec *codec)
+{
+ struct sdp_audio_codecs codecs = {};
+ sdp_audio_codecs_add_copy(&codecs, codec);
+ rtp_stream_set_codecs(rtps, &codecs);
+}
+
+/* For legacy, rather use rtp_stream_set_codecs() with a full codecs list. */
+bool rtp_stream_set_codecs_from_mgcp_codec(struct rtp_stream *rtps, enum mgcp_codecs codec)
+{
+ struct sdp_audio_codecs codecs = {};
+ if (!sdp_audio_codecs_add_mgcp_codec(&codecs, codec))
+ return false;
+ rtp_stream_set_codecs(rtps, &codecs);
+ return true;
+}
+
void rtp_stream_set_remote_addr(struct rtp_stream *rtps, const struct osmo_sockaddr_str *r)
{
+ if (osmo_sockaddr_str_cmp(&rtps->remote, r) == 0) {
+ LOG_RTPS(rtps, LOGL_DEBUG, "remote addr already " OSMO_SOCKADDR_STR_FMT ", no change\n",
+ OSMO_SOCKADDR_STR_FMT_ARGS(r));
+ return;
+ }
if (rtps->fi->state == RTP_STREAM_ST_ESTABLISHED)
rtp_stream_state_chg(rtps, RTP_STREAM_ST_ESTABLISHING);
LOG_RTPS(rtps, LOGL_DEBUG, "setting remote addr to " OSMO_SOCKADDR_STR_FMT "\n", OSMO_SOCKADDR_STR_FMT_ARGS(r));
@@ -380,6 +479,23 @@ void rtp_stream_set_remote_addr(struct rtp_stream *rtps, const struct osmo_socka
rtp_stream_update_id(rtps);
}
+void rtp_stream_set_remote_addr_and_codecs(struct rtp_stream *rtps, const struct sdp_msg *sdp)
+{
+ rtp_stream_set_codecs(rtps, &sdp->audio_codecs);
+ if (osmo_sockaddr_str_is_nonzero(&sdp->rtp))
+ rtp_stream_set_remote_addr(rtps, &sdp->rtp);
+}
+
+void rtp_stream_set_remote_osmux_cid(struct rtp_stream *rtps, uint8_t osmux_cid)
+{
+ if (rtps->fi->state == RTP_STREAM_ST_ESTABLISHED)
+ rtp_stream_state_chg(rtps, RTP_STREAM_ST_ESTABLISHING);
+ LOG_RTPS(rtps, LOGL_DEBUG, "setting remote Osmux CID to %u\n", osmux_cid);
+ rtps->remote_osmux_cid = osmux_cid;
+ rtps->remote_osmux_cid_sent_to_mgw = false;
+ rtp_stream_update_id(rtps);
+}
+
bool rtp_stream_is_established(struct rtp_stream *rtps)
{
if (!rtps)
@@ -389,7 +505,9 @@ bool rtp_stream_is_established(struct rtp_stream *rtps)
if (rtps->fi->state != RTP_STREAM_ST_ESTABLISHED)
return false;
if (!rtps->remote_sent_to_mgw
- || !rtps->codec_sent_to_mgw)
+ || !rtps->codecs_sent_to_mgw
+ || !rtps->mode_sent_to_mgw
+ || (rtps->use_osmux && !rtps->remote_osmux_cid_sent_to_mgw))
return false;
return true;
}
diff --git a/src/libmsc/sccp_ran.c b/src/libmsc/sccp_ran.c
index 99317b500..9907f200d 100644
--- a/src/libmsc/sccp_ran.c
+++ b/src/libmsc/sccp_ran.c
@@ -1,5 +1,5 @@
/*
- * (C) 2019 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de>
+ * (C) 2019 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
* All Rights Reserved
*
* SPDX-License-Identifier: AGPL-3.0+
diff --git a/src/libmsc/sdp_msg.c b/src/libmsc/sdp_msg.c
new file mode 100644
index 000000000..9b4cd988c
--- /dev/null
+++ b/src/libmsc/sdp_msg.c
@@ -0,0 +1,686 @@
+/* Minimalistic SDP parse/compose implementation, focused on GSM audio codecs */
+/*
+ * (C) 2019 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
+ * All Rights Reserved
+ *
+ * SPDX-License-Identifier: AGPL-3.0+
+ *
+ * Author: Neels Hofmeyr
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <string.h>
+#include <errno.h>
+
+#include <osmocom/core/utils.h>
+#include <osmocom/core/logging.h>
+
+#include <osmocom/msc/debug.h>
+#include <osmocom/msc/sdp_msg.h>
+
+bool sdp_audio_codec_is_set(const struct sdp_audio_codec *a)
+{
+ return a && a->subtype_name[0];
+}
+
+/* Compare name, rate and fmtp, returning typical cmp result: 0 on match, and -1 / 1 on mismatch.
+ * If cmp_fmtp is false, do *not* compare the fmtp string; if true, compare fmtp 1:1 as strings.
+ * If cmp_payload_type is false, do *not* compare the payload_type number.
+ * The fmtp is only string-compared -- e.g. if AMR parameters appear in a different order, it amounts to a mismatch even
+ * though all parameters are the same. */
+int sdp_audio_codec_cmp(const struct sdp_audio_codec *a, const struct sdp_audio_codec *b,
+ bool cmp_fmtp, bool cmp_payload_type)
+{
+ int cmp;
+ if (a == b)
+ return 0;
+ if (!a)
+ return -1;
+ if (!b)
+ return 1;
+ cmp = strncmp(a->subtype_name, b->subtype_name, sizeof(a->subtype_name));
+ if (cmp)
+ return cmp;
+ cmp = OSMO_CMP(a->rate, b->rate);
+ if (cmp)
+ return cmp;
+ if (cmp_fmtp) {
+ cmp = strncmp(a->fmtp, b->fmtp, sizeof(a->fmtp));
+ if (cmp)
+ return cmp;
+ }
+ if (cmp_payload_type) {
+ cmp = OSMO_CMP(a->payload_type, b->payload_type);
+ if (cmp)
+ return cmp;
+ }
+ return 0;
+}
+
+/* Compare two lists of audio codecs, returning typical cmp result: 0 on match, and -1 / 1 on mismatch.
+ * The ordering in the two lists may differ, except that the first codec in 'a' must also be the first codec in 'b'.
+ * This is because the first codec typically expresses the preferred codec to use.
+ * If cmp_fmtp is false, do *not* compare the fmtp strings; if true, compare fmtp 1:1 as strings.
+ * If cmp_payload_type is false, do *not* compare the payload_type numbers.
+ * The fmtp is only string-compared -- e.g. if AMR parameters appear in a different order, it amounts to a mismatch even
+ * though all parameters are the same. */
+int sdp_audio_codecs_cmp(const struct sdp_audio_codecs *a, const struct sdp_audio_codecs *b,
+ bool cmp_fmtp, bool cmp_payload_type)
+{
+ const struct sdp_audio_codec *codec_a;
+ const struct sdp_audio_codec *codec_b;
+ int cmp;
+ if (a == b)
+ return 0;
+ if (!a)
+ return -1;
+ if (!b)
+ return 1;
+
+ cmp = OSMO_CMP(a->count, b->count);
+ if (cmp)
+ return cmp;
+
+ if (!a->count)
+ return 0;
+
+ /* The first codec is the "chosen" codec and should match. The others may appear in different order. */
+ cmp = sdp_audio_codec_cmp(&a->codec[0], &b->codec[0], cmp_fmtp, cmp_payload_type);
+ if (cmp)
+ return cmp;
+
+ /* See if each codec in a is also present in b */
+ sdp_audio_codecs_foreach(codec_a, a) {
+ bool match_found = false;
+ sdp_audio_codecs_foreach(codec_b, b) {
+ if (!sdp_audio_codec_cmp(codec_a, codec_b, cmp_fmtp, cmp_payload_type)) {
+ match_found = true;
+ break;
+ }
+ }
+ if (!match_found)
+ return -1;
+ }
+
+ return 0;
+}
+
+/* Given a predefined fixed payload_type number, add an SDP audio codec entry, if not present yet.
+ * The payload_type must exist in sdp_msg_payload_type_names.
+ * Return the audio codec created or already existing for this payload type number.
+ */
+struct sdp_audio_codec *sdp_audio_codecs_add(struct sdp_audio_codecs *ac, unsigned int payload_type,
+ const char *subtype_name, unsigned int rate, const char *fmtp)
+{
+ struct sdp_audio_codec *codec;
+
+ /* Does an entry already exist? */
+ codec = sdp_audio_codecs_by_payload_type(ac, payload_type, false);
+ if (codec) {
+ /* Already exists, sanity check */
+ if (!codec->subtype_name[0])
+ OSMO_STRLCPY_ARRAY(codec->subtype_name, subtype_name);
+ else if (strcmp(codec->subtype_name, subtype_name)) {
+ /* There already is an entry with this payload_type number but a mismatching subtype_name. That is
+ * weird, rather abort. */
+ return NULL;
+ }
+ if (codec->rate != rate
+ || (fmtp && strcmp(fmtp, codec->fmtp))) {
+ /* Mismatching details. Rather abort */
+ return NULL;
+ }
+ return codec;
+ }
+
+ /* None exists, create codec entry for this payload type number */
+ codec = sdp_audio_codecs_by_payload_type(ac, payload_type, true);
+ /* NULL means unable to add an entry */
+ if (!codec)
+ return NULL;
+
+ OSMO_STRLCPY_ARRAY(codec->subtype_name, subtype_name);
+ if (fmtp)
+ OSMO_STRLCPY_ARRAY(codec->fmtp, fmtp);
+ codec->rate = rate;
+ return codec;
+}
+
+struct sdp_audio_codec *sdp_audio_codecs_add_copy(struct sdp_audio_codecs *ac, const struct sdp_audio_codec *codec)
+{
+ return sdp_audio_codecs_add(ac, codec->payload_type, codec->subtype_name, codec->rate,
+ codec->fmtp[0] ? codec->fmtp : NULL);
+}
+
+/* Find or create an entry for the given payload_type number in the given list of codecs.
+ * If the given payload_type number is already present in ac, return the first matching entry.
+ * If no such payload_type number is present: a) return NULL if create == false;
+ * b) If create == true, add a mostly empty codec entry to the end of ac with the given payload_type number, and return
+ * the created entry.
+ * If create == true, a NULL return value means that there was no unused entry left in ac to add this payload_type.
+ */
+struct sdp_audio_codec *sdp_audio_codecs_by_payload_type(struct sdp_audio_codecs *ac, unsigned int payload_type,
+ bool create)
+{
+ struct sdp_audio_codec *codec;
+ sdp_audio_codecs_foreach(codec, ac) {
+ if (codec->payload_type == payload_type)
+ return codec;
+ }
+ if (!create)
+ return NULL;
+
+ if (ac->count >= ARRAY_SIZE(ac->codec))
+ return NULL;
+
+ codec = &ac->codec[ac->count];
+ *codec = (struct sdp_audio_codec){
+ .payload_type = payload_type,
+ .rate = 8000,
+ };
+ ac->count++;
+ return codec;
+}
+
+/* Return a given sdp_msg's codec entry that matches the subtype_name and rate of the given codec, or NULL if no
+ * match is found. Comparison is made by sdp_audio_codec_cmp(cmp_payload_type=false). */
+struct sdp_audio_codec *sdp_audio_codecs_by_descr(struct sdp_audio_codecs *ac, const struct sdp_audio_codec *codec)
+{
+ struct sdp_audio_codec *i;
+ sdp_audio_codecs_foreach(i, ac) {
+ if (!sdp_audio_codec_cmp(i, codec, false, false))
+ return i;
+ }
+ return NULL;
+}
+
+/* Remove the codec entry pointed at by 'codec'. 'codec' must point at an entry of 'ac'.
+ * To use any external codec instance, use sdp_audio_codecs_remove(ac, sdp_audio_codecs_by_descr(ac, codec)).
+ * Return 0 on success, -ENOENT if codec does not point at the sdp->codec array. */
+int sdp_audio_codecs_remove(struct sdp_audio_codecs *ac, const struct sdp_audio_codec *codec)
+{
+ struct sdp_audio_codec *i;
+ if ((codec < ac->codec)
+ || ((codec - ac->codec) >= OSMO_MIN(ac->count, ARRAY_SIZE(ac->codec))))
+ return -ENOENT;
+
+ /* Move all following entries one up */
+ ac->count--;
+ sdp_audio_codecs_foreach(i, ac) {
+ if (i < codec)
+ continue;
+ *i = *(i+1);
+ }
+ return 0;
+}
+
+static const char * const sdp_mode_str[] = {
+ [SDP_MODE_UNSET] = "-",
+ [SDP_MODE_SENDONLY] = "sendonly",
+ [SDP_MODE_RECVONLY] = "recvonly",
+ [SDP_MODE_SENDRECV] = "sendrecv",
+ [SDP_MODE_INACTIVE] = "inactive",
+};
+
+/* Convert struct sdp_msg to the actual SDP protocol representation */
+int sdp_msg_to_sdp_str_buf(char *dst, size_t dst_size, const struct sdp_msg *sdp)
+{
+ const struct sdp_audio_codec *codec;
+ struct osmo_strbuf sb = { .buf = dst, .len = dst_size };
+ const char *ip;
+ char ipv;
+
+ if (!sdp) {
+ OSMO_STRBUF_PRINTF(sb, "%s", "");
+ return sb.chars_needed;
+ }
+
+ ip = sdp->rtp.ip[0] ? sdp->rtp.ip : "0.0.0.0";
+ ipv = (osmo_ip_str_type(ip) == AF_INET6) ? '6' : '4';
+
+ OSMO_STRBUF_PRINTF(sb,
+ "v=0\r\n"
+ "o=OsmoMSC 0 0 IN IP%c %s\r\n"
+ "s=GSM Call\r\n"
+ "c=IN IP%c %s\r\n"
+ "t=0 0\r\n"
+ "m=audio %d RTP/AVP",
+ ipv, ip, ipv, ip,
+ sdp->rtp.port);
+
+ /* Append all payload type numbers to 'm=audio <port> RTP/AVP 3 4 112' line */
+ sdp_audio_codecs_foreach(codec, &sdp->audio_codecs)
+ OSMO_STRBUF_PRINTF(sb, " %d", codec->payload_type);
+ OSMO_STRBUF_PRINTF(sb, "\r\n");
+
+ /* Add details for all codecs */
+ sdp_audio_codecs_foreach(codec, &sdp->audio_codecs) {
+ if (!sdp_audio_codec_is_set(codec))
+ continue;
+ OSMO_STRBUF_PRINTF(sb, "a=rtpmap:%d %s/%d\r\n", codec->payload_type, codec->subtype_name,
+ codec->rate > 0 ? codec->rate : 8000);
+ if (codec->fmtp[0])
+ OSMO_STRBUF_PRINTF(sb, "a=fmtp:%d %s\r\n", codec->payload_type, codec->fmtp);
+ }
+
+ OSMO_STRBUF_PRINTF(sb, "a=ptime:%d\r\n", sdp->ptime > 0? sdp->ptime : 20);
+
+ if (sdp->mode != SDP_MODE_UNSET && sdp->mode < ARRAY_SIZE(sdp_mode_str))
+ OSMO_STRBUF_PRINTF(sb, "a=%s\r\n", sdp_mode_str[sdp->mode]);
+
+ return sb.chars_needed;
+}
+
+/* Return the first line ending (or the end of the string) at or after the given string position. */
+const char *sdp_msg_line_end(const char *src)
+{
+ const char *line_end = strchr(src, '\r');
+ if (!line_end)
+ line_end = strchr(src, '\n');
+ if (!line_end)
+ line_end = src + strlen(src);
+ return line_end;
+}
+
+/* parse a line like 'a=rtpmap:0 PCMU/8000', 'a=fmtp:112 octet-align=1; mode-set=4', 'a=ptime:20'.
+ * The src should point at the character after 'a=', e.g. at the start of 'rtpmap', 'fmtp', 'ptime'
+ */
+int sdp_parse_attrib(struct sdp_msg *sdp, const char *src)
+{
+ unsigned int payload_type;
+ struct sdp_audio_codec *codec;
+#define A_RTPMAP "rtpmap:"
+#define A_FMTP "fmtp:"
+#define A_PTIME "ptime:"
+#define A_RTCP "rtcp:"
+
+ if (osmo_str_startswith(src, A_RTPMAP)) {
+ /* "a=rtpmap:3 GSM/8000" */
+ char *audio_name;
+ unsigned int channels = 1;
+ if (sscanf(src, A_RTPMAP "%u", &payload_type) != 1)
+ return -EINVAL;
+
+ audio_name = strchr(src, ' ');
+ if (!audio_name || audio_name >= sdp_msg_line_end(src))
+ return -EINVAL;
+
+ codec = sdp_audio_codecs_by_payload_type(&sdp->audio_codecs, payload_type, true);
+ if (!codec)
+ return -ENOSPC;
+
+ if (sscanf(audio_name, " %31[^/]/%u/%u", codec->subtype_name, &codec->rate, &channels) < 1)
+ return -EINVAL;
+
+ if (channels != 1)
+ return -ENOTSUP;
+ }
+
+ else if (osmo_str_startswith(src, A_FMTP)) {
+ /* "a=fmtp:112 octet-align=1;mode-set=0,1,2,3" */
+ char *fmtp_str;
+ const char *line_end = sdp_msg_line_end(src);
+ if (sscanf(src, A_FMTP "%u", &payload_type) != 1)
+ return -EINVAL;
+
+ fmtp_str = strchr(src, ' ');
+ if (!fmtp_str)
+ return -EINVAL;
+ fmtp_str++;
+ if (fmtp_str >= line_end)
+ return -EINVAL;
+
+ codec = sdp_audio_codecs_by_payload_type(&sdp->audio_codecs, payload_type, true);
+ if (!codec)
+ return -ENOSPC;
+
+ /* (+1 because osmo_strlcpy() interprets it as size including the '\0') */
+ osmo_strlcpy(codec->fmtp, fmtp_str, line_end - fmtp_str + 1);
+ }
+
+ else if (osmo_str_startswith(src, A_PTIME)) {
+ /* "a=ptime:20" */
+ if (sscanf(src, A_PTIME "%u", &sdp->ptime) != 1)
+ return -EINVAL;
+
+ }
+
+ else if (osmo_str_startswith(src, A_RTCP)) {
+ /* TODO? */
+ }
+
+ else if (osmo_str_startswith(src, sdp_mode_str[SDP_MODE_SENDRECV])) {
+ /* "a=sendrecv" */
+ sdp->mode = SDP_MODE_SENDRECV;
+ }
+
+ else if (osmo_str_startswith(src, sdp_mode_str[SDP_MODE_SENDONLY])) {
+ /* "a=sendonly" */
+ sdp->mode = SDP_MODE_SENDONLY;
+ }
+
+ else if (osmo_str_startswith(src, sdp_mode_str[SDP_MODE_RECVONLY])) {
+ /* "a=recvonly" */
+ sdp->mode = SDP_MODE_RECVONLY;
+ }
+
+ else if (osmo_str_startswith(src, sdp_mode_str[SDP_MODE_INACTIVE])) {
+ /* "a=inactive" */
+ sdp->mode = SDP_MODE_INACTIVE;
+ }
+
+ return 0;
+}
+
+const struct value_string sdp_msg_payload_type_names[] = {
+ { 0, "PCMU" },
+ { 3, "GSM" },
+ { 8, "PCMA" },
+ { 18, "G729" },
+ { 110, "GSM-EFR" },
+ { 111, "GSM-HR-08" },
+ { 112, "AMR" },
+ { 113, "AMR-WB" },
+ {}
+};
+
+/* Return payload type number matching given string ("AMR", "GSM", ...) or negative if not found. */
+int sdp_subtype_name_to_payload_type(const char *subtype_name)
+{
+ return get_string_value(sdp_msg_payload_type_names, subtype_name);
+}
+
+/* Parse a line like 'm=audio 16398 RTP/AVP 0 3 8 96 112', starting after the '=' */
+static int sdp_parse_media_description(struct sdp_msg *sdp, const char *src)
+{
+ unsigned int port;
+ int i;
+ const char *payload_type_str;
+ const char *line_end = sdp_msg_line_end(src);
+ if (sscanf(src, "audio %u RTP/AVP", &port) < 1)
+ return -ENOTSUP;
+
+ if (port > 0xffff)
+ return -EINVAL;
+
+ sdp->rtp.port = port;
+
+ /* skip "audio 12345 RTP/AVP ", i.e. 3 spaces on */
+ payload_type_str = src;
+ for (i = 0; i < 3; i++) {
+ payload_type_str = strchr(payload_type_str, ' ');
+ if (!payload_type_str)
+ return -EINVAL;
+ while (*payload_type_str == ' ')
+ payload_type_str++;
+ if (payload_type_str >= line_end)
+ return -EINVAL;
+ }
+
+ /* Parse listing of payload type numbers after "RTP/AVP" */
+ while (payload_type_str < line_end) {
+ unsigned int payload_type;
+ struct sdp_audio_codec *codec;
+ const char *subtype_name;
+ if (sscanf(payload_type_str, "%u", &payload_type) < 1)
+ return -EINVAL;
+
+ codec = sdp_audio_codecs_by_payload_type(&sdp->audio_codecs, payload_type, true);
+ if (!codec)
+ return -ENOSPC;
+
+ /* Fill in subtype name for fixed payload types */
+ subtype_name = get_value_string_or_null(sdp_msg_payload_type_names, codec->payload_type);
+ if (subtype_name)
+ OSMO_STRLCPY_ARRAY(codec->subtype_name, subtype_name);
+
+ payload_type_str = strchr(payload_type_str, ' ');
+ if (!payload_type_str)
+ payload_type_str = line_end;
+ while (*payload_type_str == ' ')
+ payload_type_str++;
+ }
+
+ return 0;
+}
+
+/* parse a line like 'c=IN IP4 192.168.11.151' starting after the '=' */
+static int sdp_parse_connection_info(struct sdp_msg *sdp, const char *src)
+{
+ char ipv[10];
+ char addr_str[INET6_ADDRSTRLEN];
+ if (sscanf(src, "IN %s %s", ipv, addr_str) < 2)
+ return -EINVAL;
+
+ /* supporting only IPv4 */
+ if (strcmp(ipv, "IP4"))
+ return -ENOTSUP;
+
+ osmo_sockaddr_str_from_str(&sdp->rtp, addr_str, sdp->rtp.port);
+ return 0;
+}
+
+/* Parse SDP string into struct sdp_msg. Return 0 on success, negative on error. */
+int sdp_msg_from_sdp_str(struct sdp_msg *sdp, const char *src)
+{
+ const char *pos;
+ *sdp = (struct sdp_msg){};
+
+ for (pos = src; pos && *pos; pos++) {
+ char attrib;
+ int rc = 0;
+
+ if (*pos == '\r' || *pos == '\n')
+ continue;
+
+ /* Expecting only lines starting with 'X='. Not being too strict about it is probably alright. */
+ if (pos[1] != '=')
+ goto next_line;
+
+ attrib = *pos;
+ pos += 2;
+ switch (attrib) {
+ /* a=... */
+ case 'a':
+ rc = sdp_parse_attrib(sdp, pos);
+ break;
+ case 'm':
+ rc = sdp_parse_media_description(sdp, pos);
+ break;
+ case 'c':
+ rc = sdp_parse_connection_info(sdp, pos);
+ break;
+ default:
+ /* ignore any other parameters */
+ break;
+ }
+
+ if (rc) {
+ size_t line_len;
+ const char *line_end = sdp_msg_line_end(pos);
+ pos -= 2;
+ line_len = line_end - pos;
+ switch (rc) {
+ case -EINVAL:
+ LOGP(DMNCC, LOGL_ERROR,
+ "Failed to parse SDP: invalid line: %s\n", osmo_quote_str(pos, line_len));
+ break;
+ case -ENOSPC:
+ LOGP(DMNCC, LOGL_ERROR,
+ "Failed to parse SDP: no more space for: %s\n", osmo_quote_str(pos, line_len));
+ break;
+ case -ENOTSUP:
+ LOGP(DMNCC, LOGL_ERROR,
+ "Failed to parse SDP: not supported: %s\n", osmo_quote_str(pos, line_len));
+ break;
+ default:
+ LOGP(DMNCC, LOGL_ERROR,
+ "Failed to parse SDP: %s\n", osmo_quote_str(pos, line_len));
+ break;
+ }
+ return rc;
+ }
+next_line:
+ pos = strstr(pos, "\r\n");
+ if (!pos)
+ break;
+ }
+
+ return 0;
+}
+
+/* Leave only those codecs in 'ac_dest' that are also present in 'ac_other'.
+ * The matching is made by sdp_audio_codec_cmp(cmp_payload_type=false), i.e. payload_type numbers are not compared and
+ * fmtp parameters are compared 1:1 as plain strings.
+ * If translate_payload_type_numbers has an effect if ac_dest and ac_other have mismatching payload_type numbers for the
+ * same SDP codec descriptions. If translate_payload_type_numbers is true, take the payload_type numbers from ac_other.
+ * If false, keep payload_type numbers in ac_dest unchanged. */
+void sdp_audio_codecs_intersection(struct sdp_audio_codecs *ac_dest, const struct sdp_audio_codecs *ac_other,
+ bool translate_payload_type_numbers)
+{
+ int i;
+ for (i = 0; i < ac_dest->count; i++) {
+ struct sdp_audio_codec *codec = &ac_dest->codec[i];
+ struct sdp_audio_codec *other;
+ OSMO_ASSERT(i < ARRAY_SIZE(ac_dest->codec));
+
+ other = sdp_audio_codecs_by_descr((struct sdp_audio_codecs *)ac_other, codec);
+
+ if (!other) {
+ OSMO_ASSERT(sdp_audio_codecs_remove(ac_dest, codec) == 0);
+ i--;
+ continue;
+ }
+
+ /* Doing payload_type number translation of part of the intersection because it makes the algorithm
+ * simpler: we already know ac_dest is a subset of ac_other, and there is no need to resolve payload
+ * type number conflicts. */
+ if (translate_payload_type_numbers)
+ codec->payload_type = other->payload_type;
+ }
+}
+
+/* Make sure the given codec is listed as the first codec. 'codec' must be an actual codec entry of the given audio
+ * codecs list. */
+void sdp_audio_codecs_select(struct sdp_audio_codecs *ac, struct sdp_audio_codec *codec)
+{
+ struct sdp_audio_codec tmp;
+ struct sdp_audio_codec *pos;
+ OSMO_ASSERT((codec >= ac->codec)
+ && ((codec - ac->codec) < OSMO_MIN(ac->count, ARRAY_SIZE(ac->codec))));
+
+ /* Already the first? */
+ if (codec == ac->codec)
+ return;
+
+ tmp = *codec;
+ for (pos = codec - 1; pos >= ac->codec; pos--)
+ pos[1] = pos[0];
+
+ ac->codec[0] = tmp;
+ return;
+}
+
+/* Short single-line representation of an SDP audio codec, convenient for logging.
+ * Like "AMR/8000:octet-align=1#122" */
+int sdp_audio_codec_to_str_buf(char *buf, size_t buflen, const struct sdp_audio_codec *codec)
+{
+ struct osmo_strbuf sb = { .buf = buf, .len = buflen };
+ OSMO_STRBUF_PRINTF(sb, "%s", codec->subtype_name);
+ if (codec->rate != 8000)
+ OSMO_STRBUF_PRINTF(sb, "/%u", codec->rate);
+ if (codec->fmtp[0])
+ OSMO_STRBUF_PRINTF(sb, ":%s", codec->fmtp);
+ OSMO_STRBUF_PRINTF(sb, "#%d", codec->payload_type);
+ return sb.chars_needed;
+}
+
+char *sdp_audio_codec_to_str_c(void *ctx, const struct sdp_audio_codec *codec)
+{
+ OSMO_NAME_C_IMPL(ctx, 32, "sdp_audio_codec_to_str_c-ERROR", sdp_audio_codec_to_str_buf, codec)
+}
+
+const char *sdp_audio_codec_to_str(const struct sdp_audio_codec *codec)
+{
+ return sdp_audio_codec_to_str_c(OTC_SELECT, codec);
+}
+
+/* Short single-line representation of a list of SDP audio codecs, convenient for logging */
+int sdp_audio_codecs_to_str_buf(char *buf, size_t buflen, const struct sdp_audio_codecs *ac)
+{
+ struct osmo_strbuf sb = { .buf = buf, .len = buflen };
+ const struct sdp_audio_codec *codec;
+ if (!ac->count)
+ OSMO_STRBUF_PRINTF(sb, "(no-codecs)");
+ sdp_audio_codecs_foreach(codec, ac) {
+ bool first = (codec == ac->codec);
+ if (!first)
+ OSMO_STRBUF_PRINTF(sb, ",");
+ OSMO_STRBUF_APPEND(sb, sdp_audio_codec_to_str_buf, codec);
+ }
+ return sb.chars_needed;
+}
+
+char *sdp_audio_codecs_to_str_c(void *ctx, const struct sdp_audio_codecs *ac)
+{
+ OSMO_NAME_C_IMPL(ctx, 128, "sdp_audio_codecs_to_str_c-ERROR", sdp_audio_codecs_to_str_buf, ac)
+}
+
+const char *sdp_audio_codecs_to_str(const struct sdp_audio_codecs *ac)
+{
+ return sdp_audio_codecs_to_str_c(OTC_SELECT, ac);
+}
+
+/* Short single-line representation of an SDP message, convenient for logging */
+int sdp_msg_to_str_buf(char *buf, size_t buflen, const struct sdp_msg *sdp)
+{
+ struct osmo_strbuf sb = { .buf = buf, .len = buflen };
+ if (!sdp) {
+ OSMO_STRBUF_PRINTF(sb, "NULL");
+ return sb.chars_needed;
+ }
+
+ OSMO_STRBUF_PRINTF(sb, OSMO_SOCKADDR_STR_FMT, OSMO_SOCKADDR_STR_FMT_ARGS(&sdp->rtp));
+ OSMO_STRBUF_PRINTF(sb, "{");
+ OSMO_STRBUF_APPEND(sb, sdp_audio_codecs_to_str_buf, &sdp->audio_codecs);
+ if (sdp->bearer_services.count) {
+ OSMO_STRBUF_PRINTF(sb, ",");
+ OSMO_STRBUF_APPEND(sb, csd_bs_list_to_str_buf, &sdp->bearer_services);
+ }
+ OSMO_STRBUF_PRINTF(sb, "}");
+ return sb.chars_needed;
+}
+
+char *sdp_msg_to_str_c(void *ctx, const struct sdp_msg *sdp)
+{
+ OSMO_NAME_C_IMPL(ctx, 128, "sdp_msg_to_str_c-ERROR", sdp_msg_to_str_buf, sdp)
+}
+
+const char *sdp_msg_to_str(const struct sdp_msg *sdp)
+{
+ return sdp_msg_to_str_c(OTC_SELECT, sdp);
+}
+
+void sdp_audio_codecs_set_csd(struct sdp_audio_codecs *ac)
+{
+ *ac = (struct sdp_audio_codecs){
+ .count = 1,
+ .codec = {{
+ .payload_type = 120,
+ .subtype_name = "CLEARMODE",
+ .rate = 8000,
+ }},
+ };
+}
diff --git a/src/libmsc/sgs_iface.c b/src/libmsc/sgs_iface.c
index d83a730ef..a845ab84b 100644
--- a/src/libmsc/sgs_iface.c
+++ b/src/libmsc/sgs_iface.c
@@ -124,7 +124,7 @@ static void subscr_conn_toss(struct vlr_subscr *vsub)
LOG_MSUB(msub, LOGL_ERROR, "Force releasing previous subscriber connection: an SGs connection for this"
" subscriber is being initiated\n");
- msc_a_release_mo(msub_msc_a(msub), GSM48_REJECT_CONGESTION);
+ msc_a_release_mo(msub_msc_a(msub), GSM_CAUSE_AUTH_FAILED);
/* TODO: is this strong enough? After this, it should be completely disassociated with this subscriber. */
}
@@ -336,7 +336,7 @@ const char *subscr_info(const char *imsi)
}
/* Comfortable status message generator that also generates some basic
- * context-dependent dependand log output */
+ * context-dependent log output */
static int sgs_tx_status(struct sgs_connection *sgc, const char *imsi, enum sgsap_sgs_cause cause, struct msgb *msg,
int sgsap_iei)
{
@@ -352,7 +352,7 @@ static int sgs_tx_status(struct sgs_connection *sgc, const char *imsi, enum sgsa
LOGSGC_VSUB(sgc, subscr_info(imsi), LOGL_ERROR, "Rx %s with invalid mandatory %s IEI!\n",
sgsap_msg_type_name(msg->data[0]), sgsap_iei_name(sgsap_iei));
} else if (cause == SGSAP_SGS_CAUSE_COND_IE_ERROR) {
- LOGSGC_VSUB(sgc, subscr_info(imsi), LOGL_ERROR, "Rx %s with errornous conditional %s IEI!\n",
+ LOGSGC_VSUB(sgc, subscr_info(imsi), LOGL_ERROR, "Rx %s with erroneous conditional %s IEI!\n",
sgsap_msg_type_name(msg->data[0]), sgsap_iei_name(sgsap_iei));
} else {
LOGSGC_VSUB(sgc, subscr_info(imsi), LOGL_ERROR, "Rx %s failed with cause %s at %s IEI!\n",
@@ -364,7 +364,7 @@ static int sgs_tx_status(struct sgs_connection *sgc, const char *imsi, enum sgsa
return 0;
}
-/* Called by VLR via callback, transmits the the location update response or
+/* Called by VLR via callback, transmits the location update response or
* reject, depending on the outcome of the location update. */
static void sgs_tx_loc_upd_resp_cb(struct sgs_lu_response *response)
{
@@ -372,24 +372,45 @@ static void sgs_tx_loc_upd_resp_cb(struct sgs_lu_response *response)
struct vlr_subscr *vsub = response->vsub;
struct sgs_mme_ctx *mme;
uint8_t new_id[2 + GSM48_TMSI_LEN];
- uint8_t *new_id_ptr = new_id;
- unsigned int new_id_len = 0;
+ uint8_t *new_id_ptr = NULL;
+ int new_id_len = 0;
uint8_t resp_msg_type;
+ /* Determine message type that is sent next (needed for logging) */
if (response->accepted)
resp_msg_type = SGSAP_MSGT_LOC_UPD_ACK;
+ else if (response->error)
+ resp_msg_type = SGSAP_MSGT_RESET_IND;
else
resp_msg_type = SGSAP_MSGT_LOC_UPD_REJ;
+ /* Determine MME */
mme = sgs_mme_ctx_by_vsub(vsub, resp_msg_type);
if (!mme)
return;
+ /* Handle error (HLR failure) */
+ if (response->error) {
+ osmo_fsm_inst_dispatch(mme->fi, SGS_VLRR_E_START_RESET, NULL);
+ return;
+ }
+
+ /* Handle LU accept/reject */
if (response->accepted) {
if (vsub->tmsi_new != GSM_RESERVED_TMSI) {
- new_id_len = gsm48_generate_mid_from_tmsi(new_id, vsub->tmsi_new);
- new_id_ptr = new_id + 2;
- new_id_len -= 2;
+ struct osmo_mobile_identity tmsi_mi = {
+ .type = GSM_MI_TYPE_TMSI,
+ .tmsi = vsub->tmsi_new,
+ };
+ new_id_len = osmo_mobile_identity_encode_buf(new_id, sizeof(new_id), &tmsi_mi, false);
+ if (new_id_len > 0) {
+ new_id_ptr = new_id;
+ } else {
+ /* Failure to encode the TMSI is not actually possible here, this is just for paranoia
+ * and coverity scan. */
+ new_id_len = 0;
+ LOGPFSMSL(vsub->sgs_fsm, DMM, LOGL_ERROR, "Cannot encode TMSI Mobile Identity\n");
+ }
}
resp = gsm29118_create_lu_ack(vsub->imsi, &vsub->sgs.lai, new_id_ptr, new_id_len);
sgs_tx(mme->conn, resp);
@@ -455,9 +476,6 @@ int sgs_iface_tx_paging(struct vlr_subscr *vsub, enum sgsap_service_ind serv_ind
struct gsm29118_paging_req paging_params;
struct sgs_mme_ctx *mme;
- LOGP(DMSC, LOGL_NOTICE, "XXXXXXXXXX state == %d conf_by_radio_contact_ind == %d\n",
- vsub->sgs_fsm->state, vsub->conf_by_radio_contact_ind);
-
/* See also: 3GPP TS 29.118, chapter 5.1.2.2 Paging Initiation */
if (vsub->sgs_fsm->state == SGS_UE_ST_NULL && vsub->conf_by_radio_contact_ind == true) {
LOGPFSMSL(vsub->sgs_fsm, DPAG, LOGL_ERROR, "Will not Page (conf_by_radio_contact_ind == true)\n");
@@ -475,6 +493,9 @@ int sgs_iface_tx_paging(struct vlr_subscr *vsub, enum sgsap_service_ind serv_ind
if (vlr_sgs_pag_pend(vsub))
return 0;
+ LOGMME(mme, LOGL_INFO, "Paging on SGs: %s for %s (conf_by_radio_contact_ind=%d)\n",
+ vlr_subscr_name(vsub), sgsap_service_ind_name(serv_ind), vsub->conf_by_radio_contact_ind);
+
memset(&paging_params, 0, sizeof(paging_params));
osmo_strlcpy(paging_params.imsi, vsub->imsi, sizeof(paging_params.imsi));
osmo_strlcpy(paging_params.vlr_name, mme->sgs->cfg.vlr_name, sizeof(paging_params.vlr_name));
@@ -587,12 +608,14 @@ static int sgs_rx_loc_upd_req(struct sgs_connection *sgc, struct msgb *msg, cons
char *mme_name;
struct vlr_sgs_cfg vlr_sgs_cfg;
struct vlr_subscr *vsub;
+ struct osmo_plmn_id last_eutran_plmn_buf, *last_eutran_plmn = NULL;
/* Check for lingering connections */
vsub = vlr_subscr_find_by_imsi(gsm_network->vlr, imsi, __func__);
if (vsub) {
subscr_conn_toss(vsub);
vlr_subscr_put(vsub, __func__);
+ vsub = NULL;
}
/* Determine MME-Name */
@@ -618,11 +641,29 @@ static int sgs_rx_loc_upd_req(struct sgs_connection *sgc, struct msgb *msg, cons
return sgs_tx_status(sgc, imsi, SGSAP_SGS_CAUSE_MISSING_MAND_IE, msg, SGSAP_IE_LAI);
gsm48_decode_lai2(gsm48_lai, &new_lai);
+ /* 3GPP TS 23.272 sec 4.3.3 (CSFB):
+ * "During the SGs location update procedure, obtaining the last used LTE PLMN ID via TAI"
+ */
+ if (TLVP_PRES_LEN(tp, SGSAP_IE_TAI, 3)) {
+ last_eutran_plmn = &last_eutran_plmn_buf;
+ osmo_plmn_from_bcd(TLVP_VAL(tp, SGSAP_IE_TAI), last_eutran_plmn);
+ /* TODO: we could also gather the TAC from here, but we don't need it yet */
+ } else if (TLVP_PRES_LEN(tp, SGSAP_IE_EUTRAN_CGI, 3)) {
+ /* Since TAI is optional, let's try harder getting Last Used
+ * E-UTRAN PLMN ID by fetching it from E-UTRAN CGI */
+ last_eutran_plmn = &last_eutran_plmn_buf;
+ osmo_plmn_from_bcd(TLVP_VAL(tp, SGSAP_IE_EUTRAN_CGI), last_eutran_plmn);
+ /* TODO: we could also gather the ECI from here, but we don't need it yet */
+ } else {
+ LOGSGC(sgc, LOGL_INFO, "Receiving SGsAP-LOCATION-UPDATE-REQUEST without TAI nor "
+ "E-CGI IEs, fast fallback GERAN->EUTRAN won't be possible!\n");
+ }
+
/* Perform actual location update */
memcpy(vlr_sgs_cfg.timer, sgc->sgs->cfg.timer, sizeof(vlr_sgs_cfg.timer));
memcpy(vlr_sgs_cfg.counter, sgc->sgs->cfg.counter, sizeof(vlr_sgs_cfg.counter));
rc = vlr_sgs_loc_update(gsm_network->vlr, &vlr_sgs_cfg, sgs_tx_loc_upd_resp_cb, sgs_iface_tx_paging,
- sgs_tx_mm_info_cb, mme_name, type, imsi, &new_lai);
+ sgs_tx_mm_info_cb, mme_name, type, imsi, &new_lai, last_eutran_plmn);
if (rc != 0) {
resp = gsm29118_create_lu_rej(imsi, SGSAP_SGS_CAUSE_IMSI_UNKNOWN, NULL);
sgs_tx(sgc, resp);
@@ -849,7 +890,7 @@ static int sgs_rx_ul_ud(struct sgs_connection *sgc, struct msgb *msg, const stru
vlr_subscr_put(vsub, __func__);
/* If we do not find an existing connection and allocating a new one
- * faild, give up and return status. */
+ * failed, give up and return status. */
if (!msc_a)
return sgs_tx_status(sgc, imsi, SGSAP_SGS_CAUSE_MSG_INCOMP_STATE, msg, 0);
@@ -874,19 +915,41 @@ static int sgs_rx_ul_ud(struct sgs_connection *sgc, struct msgb *msg, const stru
static int sgs_rx_csfb_ind(struct sgs_connection *sgc, struct msgb *msg, const struct tlv_parsed *tp, char *imsi)
{
struct vlr_subscr *vsub;
+ struct osmo_plmn_id last_eutran_plmn_buf;
+ const struct osmo_plmn_id *last_eutran_plmn = &last_eutran_plmn_buf;
- /* The MME informs us with this message that the UE has returned back
- * to the 4G network, so we use the SGs interface again for further
- * communication with the UE. */
+ /* The MME informs us with this message that the UE has initiated a
+ * service request for MO CS fallback. There is not much we can do with
+ * this information, however, we can check if the subscriber actually
+ * exists in the VLR and if there are any lingering connections open.*/
vsub = vlr_subscr_find_by_imsi(gsm_network->vlr, imsi, __func__);
if (!vsub)
return sgs_tx_status(sgc, imsi, SGSAP_SGS_CAUSE_IMSI_UNKNOWN, msg, SGSAP_IE_IMSI);
+ /* 3GPP TS 23.272 sec 4.3.3 (CSFB):
+ * "During the SGs location update procedure, obtaining the last used LTE PLMN ID via TAI"
+ */
+ if (TLVP_PRES_LEN(tp, SGSAP_IE_TAI, 3)) {
+ osmo_plmn_from_bcd(TLVP_VAL(tp, SGSAP_IE_TAI), &last_eutran_plmn_buf);
+ /* TODO: we could also gather the TAC from here, but we don't need it yet */
+ } else if (TLVP_PRES_LEN(tp, SGSAP_IE_EUTRAN_CGI, 3)) {
+ /* Since TAI is optional, let's try harder getting Last Used
+ * E-UTRAN PLMN ID by fetching it from E-UTRAN CGI */
+ osmo_plmn_from_bcd(TLVP_VAL(tp, SGSAP_IE_EUTRAN_CGI), &last_eutran_plmn_buf);
+ /* TODO: we could also gather the ECI from here, but we don't need it yet */
+ } else {
+ LOGSGC(sgc, LOGL_INFO, "Receiving SGsAP-MO-CSFB-INDICATION without TAI nor "
+ "E-CGI IEs, and they are not known from previous SGsAP-LOCATION-UPDATE-REQUEST. "
+ "Fast fallback GERAN->EUTRAN won't be possible!\n");
+ last_eutran_plmn = NULL;
+ }
+
+ vlr_subscr_set_last_used_eutran_plmn_id(vsub, last_eutran_plmn);
+
/* Check for lingering connections */
subscr_conn_toss(vsub);
- vsub->cs.attached_via_ran = OSMO_RAT_EUTRAN_SGS;
vlr_subscr_put(vsub, __func__);
return 0;
}
@@ -934,10 +997,8 @@ int sgs_iface_rx(struct sgs_connection *sgc, struct msgb *msg)
/* Parse TLV elements */
rc = tlv_parse(&tp, &sgsap_ie_tlvdef, msgb_l2(msg) + 1, msgb_l2len(msg) - 1, 0, 0);
- if (rc < 0) {
- TX_STATUS_AND_LOG(sgc, msg_type, SGSAP_SGS_CAUSE_SEMANT_INCORR_MSG, "SGsAP Message %s parsing error\n");
- goto error;
- }
+ if (rc < 0)
+ LOGSGC(sgc, LOGL_NOTICE, "SGsAP Message %s contains unknown TLV IEs\n", sgsap_msg_type_name(msg_type));
/* Most of the messages contain an IMSI as mandatory IE, parse it right here */
if (!TLVP_PRESENT(&tp, SGSAP_IE_IMSI) &&
@@ -949,16 +1010,20 @@ int sgs_iface_rx(struct sgs_connection *sgc, struct msgb *msg)
}
if (TLVP_PRESENT(&tp, SGSAP_IE_IMSI)) {
- gsm48_mi_to_string(imsi, sizeof(imsi), TLVP_VAL(&tp, SGSAP_IE_IMSI), TLVP_LEN(&tp, SGSAP_IE_IMSI));
- if (strlen(imsi) < GSM23003_IMSI_MIN_DIGITS) {
+ struct osmo_mobile_identity mi;
+ if (osmo_mobile_identity_decode(&mi,
+ TLVP_VAL(&tp, SGSAP_IE_IMSI),
+ TLVP_LEN(&tp, SGSAP_IE_IMSI), false)
+ || mi.type != GSM_MI_TYPE_IMSI) {
TX_STATUS_AND_LOG(sgc, msg_type, SGSAP_SGS_CAUSE_INVALID_MAND_IE,
- "SGsAP Message %s with short IMSI, dropping\n");
+ "SGsAP Message %s with invalid IMSI, dropping\n");
goto error;
}
+ OSMO_STRLCPY_ARRAY(imsi, mi.imsi);
}
- /* Some messages contain an MME-NAME as mandatore IE, parse it right here. The
- * MME-NAME is als immediately registered with the sgc, so it will be implicitly
+ /* Some messages contain an MME-NAME as mandatory IE, parse it right here. The
+ * MME-NAME is also immediately registered with the sgc, so it will be implicitly
* known to all functions that have access to the sgc context. */
if (!TLVP_PRESENT(&tp, SGSAP_IE_MME_NAME)
&& (msg_type == SGSAP_MSGT_RESET_IND || msg_type == SGSAP_MSGT_RESET_ACK
@@ -1120,6 +1185,10 @@ static void sgs_vlr_reset_fsm_allstate(struct osmo_fsm_inst *fi, uint32_t event,
reset_params.vlr_name_present = true;
reset_ind = gsm29118_create_reset_ind(&reset_params);
sgs_tx(sgc, reset_ind);
+
+ /* Perform a reset of the SGS FSM of all subscribers that are present in the VLR */
+ vlr_sgs_reset(gsm_network->vlr);
+
osmo_fsm_inst_state_chg(fi, SGS_VLRR_ST_WAIT_ACK, sgs->cfg.timer[SGS_STATE_TS11], 11);
break;
default:
@@ -1187,6 +1256,7 @@ static const struct osmo_fsm_state sgs_vlr_reset_fsm_states[] = {
static struct osmo_fsm sgs_vlr_reset_fsm = {
.name = "SGs-VLR-RESET",
.states = sgs_vlr_reset_fsm_states,
+ .num_states = ARRAY_SIZE(sgs_vlr_reset_fsm_states),
.allstate_event_mask = S(SGS_VLRR_E_START_RESET),
.allstate_action = sgs_vlr_reset_fsm_allstate,
.timer_cb = sgs_vlr_reset_fsm_timer_cb,
@@ -1242,7 +1312,29 @@ void sgs_iface_tx_release(struct vlr_subscr *vsub)
sgs_tx(mme->conn, msg_sgs);
}
-/*! initalize SGs new interface
+/*! Send SGsAP-SERVICE-ABORT-REQUEST message to MME
+ * \param[in] vsub subscriber context */
+void sgs_iface_tx_serv_abrt(struct vlr_subscr *vsub)
+{
+ struct msgb *msg_sgs;
+ struct sgs_mme_ctx *mme;
+
+ OSMO_ASSERT(vsub);
+
+ /* The service abort procedure is only defined for MT calls,
+ * see also 3GPP TS 29.118, chapter 5.13.2 */
+ if (vsub->sgs.paging_serv_ind != SGSAP_SERV_IND_CS_CALL)
+ return;
+
+ mme = sgs_mme_ctx_by_vsub(vsub, SGSAP_MSGT_DL_UD);
+ if (!mme)
+ return;
+
+ msg_sgs = gsm29118_create_service_abort_req(vsub->imsi);
+ sgs_tx(mme->conn, msg_sgs);
+}
+
+/*! initialize SGs new interface
* \param[in] ctx talloc context
* \param[in] network associated gsm network
* \returns returns allocated sgs_stae, NULL in case of error. */
diff --git a/src/libmsc/silent_call.c b/src/libmsc/silent_call.c
index 3b95a901f..4de12b9e2 100644
--- a/src/libmsc/silent_call.c
+++ b/src/libmsc/silent_call.c
@@ -140,7 +140,11 @@ int gsm_silent_call_start(struct vlr_subscr *vsub,
struct vty *vty)
{
struct gsm_network *net = vsub->vlr->user_ctx;
- struct gsm_trans *trans = trans_alloc(net, vsub, TRANS_SILENT_CALL, 0, 0);
+ struct gsm_trans *trans;
+
+ trans = trans_alloc(net, vsub, TRANS_SILENT_CALL, 0, 0);
+ if (trans == NULL)
+ return -ENODEV;
trans->silent_call.ct = *ct;
if (traffic_dst_ip) {
diff --git a/src/libmsc/smpp_utils.c b/src/libmsc/smpp_utils.c
deleted file mode 100644
index 7fffdd27a..000000000
--- a/src/libmsc/smpp_utils.c
+++ /dev/null
@@ -1,61 +0,0 @@
-
-/* (C) 2012-2013 by Harald Welte <laforge@gnumonks.org>
- *
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#include "smpp_smsc.h"
-#include <osmocom/core/logging.h>
-
-int smpp_determine_scheme(uint8_t dcs, uint8_t *data_coding, int *mode)
-{
- if ((dcs & 0xF0) == 0xF0) {
- if (dcs & 0x04) {
- /* bit 2 == 1: 8bit data */
- *data_coding = 0x02;
- *mode = MODE_8BIT;
- } else {
- /* bit 2 == 0: default alphabet */
- *data_coding = 0x01;
- *mode = MODE_7BIT;
- }
- } else if ((dcs & 0xE0) == 0) {
- switch (dcs & 0xC) {
- case 0:
- *data_coding = 0x01;
- *mode = MODE_7BIT;
- break;
- case 4:
- *data_coding = 0x02;
- *mode = MODE_8BIT;
- break;
- case 8:
- *data_coding = 0x08; /* UCS-2 */
- *mode = MODE_8BIT;
- break;
- default:
- goto unknown_mo;
- }
- } else {
-unknown_mo:
- LOGP(DLSMS, LOGL_ERROR, "SMPP MO Unknown Data Coding 0x%02x\n", dcs);
- return -1;
- }
-
- return 0;
-
-}
diff --git a/src/libmsc/sms_queue.c b/src/libmsc/sms_queue.c
index 2c380b294..9f18f4feb 100644
--- a/src/libmsc/sms_queue.c
+++ b/src/libmsc/sms_queue.c
@@ -1,4 +1,4 @@
-/* SMS queue to continously attempt to deliver SMS */
+/* SMS queue to continuously attempt to deliver SMS */
/*
* (C) 2010 by Holger Hans Peter Freyther <zecke@selfish.org>
* All Rights Reserved
@@ -40,38 +40,113 @@
#include <osmocom/msc/vlr.h>
#include <osmocom/core/talloc.h>
+#include <osmocom/core/utils.h>
+#include <osmocom/core/rate_ctr.h>
+#include <osmocom/core/stat_item.h>
#include <osmocom/vty/vty.h>
-/*
- * One pending SMS that we wait for.
- */
+enum smsq_stat_item_idx {
+ SMSQ_STAT_SMS_RAM_PENDING,
+};
+
+static const struct osmo_stat_item_desc smsq_stat_item_desc[] = {
+ [SMSQ_STAT_SMS_RAM_PENDING] = { "ram:pending",
+ "Number of SMSs in the in-RAM pending delivery queue" },
+};
+
+static const struct osmo_stat_item_group_desc smsq_statg_desc = {
+ "sms_queue",
+ "SMS queue",
+ OSMO_STATS_CLASS_GLOBAL,
+ ARRAY_SIZE(smsq_stat_item_desc),
+ smsq_stat_item_desc,
+};
+
+enum smsq_rate_ctr_idx {
+ SMSQ_CTR_SMS_DELIVERY_ATTEMPTS,
+ SMSQ_CTR_SMS_DELIVERY_ACK,
+ SMSQ_CTR_SMS_DELIVERY_ERR,
+ SMSQ_CTR_SMS_DELIVERY_NOMEM,
+ SMSQ_CTR_SMS_DELIVERY_TIMEOUT,
+};
+
+static const struct rate_ctr_desc smsq_ctr_desc[] = {
+ [SMSQ_CTR_SMS_DELIVERY_ATTEMPTS] = { "delivery:attempts",
+ "Attempted MT SMS deliveries to subscriber" },
+ [SMSQ_CTR_SMS_DELIVERY_ACK] = { "deliver:ack",
+ "Successful MT SMS delivery to subscriber" },
+ [SMSQ_CTR_SMS_DELIVERY_ERR] = { "deliver:error",
+ "Erroneous MT SMS delivery" },
+ [SMSQ_CTR_SMS_DELIVERY_NOMEM] = { "deliver:no_memory",
+ "Failed MT SMS delivery due to no memory on MS" },
+ [SMSQ_CTR_SMS_DELIVERY_TIMEOUT] = { "deliver:paging_timeout",
+ "Failed MT SMS delivery due to paging timeout (MS gone?)" },
+};
+
+static const struct rate_ctr_group_desc smsq_ctrg_desc = {
+ "sms_queue",
+ "SMS queue",
+ OSMO_STATS_CLASS_GLOBAL,
+ ARRAY_SIZE(smsq_ctr_desc),
+ smsq_ctr_desc,
+};
+
+#define smsq_rate_ctr_inc(smsq, idx) \
+ rate_ctr_inc(rate_ctr_group_get_ctr((smsq)->ctrg, idx))
+#define smsq_rate_ctr_add(smsq, idx, val) \
+ rate_ctr_add(rate_ctr_group_get_ctr((smsq)->ctrg, idx), val)
+
+#define smsq_stat_item_inc(smsq, idx) \
+ osmo_stat_item_inc(osmo_stat_item_group_get_item((smsq)->statg, idx), 1)
+#define smsq_stat_item_dec(smsq, idx) \
+ osmo_stat_item_dec(osmo_stat_item_group_get_item((smsq)->statg, idx), 1)
+#define smsq_stat_item_set(smsq, idx, val) \
+ osmo_stat_item_set(osmo_stat_item_group_get_item((smsq)->statg, idx), val)
+
+
+/* One in-RAM record of a "pending SMS". This is not the SMS itself, but merely
+ * a pointer to the database record. It holds a reference on the vlr_subscriber
+ * and some counters. While this object exists in RAM, we are regularly attempting
+ * to deliver the related SMS. */
struct gsm_sms_pending {
- struct llist_head entry;
+ struct llist_head entry; /* gsm_sms_queue.pending_sms */
- struct vlr_subscr *vsub;
- struct msc_a *msc_a;
- unsigned long long sms_id;
- int failed_attempts;
- int resend;
+ struct vlr_subscr *vsub; /* destination subscriber for this SMS */
+ struct msc_a *msc_a; /* MSC_A associated with this SMS */
+ unsigned long long sms_id; /* unique ID (in SQL database) of this SMS */
+ int failed_attempts; /* count of failed deliver attempts so far */
+ int resend; /* should we try re-sending it (now) ? */
};
+/* (global) state of the SMS queue. */
struct gsm_sms_queue {
- struct osmo_timer_list resend_pending;
- struct osmo_timer_list push_queue;
+ struct osmo_timer_list resend_pending; /* timer triggering sms_resend_pending() */
+ struct osmo_timer_list push_queue; /* timer triggering sms_submit_pending() */
struct gsm_network *network;
- int max_fail;
- int max_pending;
- int pending;
+ struct llist_head pending_sms; /* list of gsm_sms_pending */
+ struct sms_queue_config *cfg;
+ int pending; /* current number of gsm_sms_pending in RAM */
- struct llist_head pending_sms;
+ /* last MSISDN for which we read SMS from the database and created gsm_sms_pending records */
+ char last_msisdn[GSM23003_MSISDN_MAX_DIGITS+1];
- char last_msisdn[VLR_MSISDN_LENGTH+1];
+ /* statistics / counters */
+ struct osmo_stat_item_group *statg;
+ struct rate_ctr_group *ctrg;
};
+/* private wrapper function to make sure we count all SMS delivery attempts */
+static void _gsm411_send_sms(struct gsm_network *net, struct vlr_subscr *vsub, struct gsm_sms *sms)
+{
+ smsq_rate_ctr_inc(net->sms_queue, SMSQ_CTR_SMS_DELIVERY_ATTEMPTS);
+ gsm411_send_sms(net, vsub, sms);
+}
+
static int sms_subscr_cb(unsigned int, unsigned int, void *, void *);
static int sms_sms_cb(unsigned int, unsigned int, void *, void *);
+/* look-up a 'gsm_sms_pending' for the given sms_id; return NULL if none */
static struct gsm_sms_pending *sms_find_pending(struct gsm_sms_queue *smsq,
unsigned long long sms_id)
{
@@ -85,11 +160,13 @@ static struct gsm_sms_pending *sms_find_pending(struct gsm_sms_queue *smsq,
return NULL;
}
+/* do we currently have a gsm_sms_pending object for the given SMS id? */
int sms_queue_sms_is_pending(struct gsm_sms_queue *smsq, unsigned long long sms_id)
{
return sms_find_pending(smsq, sms_id) != NULL;
}
+/* find the first pending SMS (in RAM) for the given subscriber */
static struct gsm_sms_pending *sms_subscriber_find_pending(
struct gsm_sms_queue *smsq,
struct vlr_subscr *vsub)
@@ -104,12 +181,14 @@ static struct gsm_sms_pending *sms_subscriber_find_pending(
return NULL;
}
+/* do we have any pending SMS (in RAM) for the given subscriber? */
static int sms_subscriber_is_pending(struct gsm_sms_queue *smsq,
struct vlr_subscr *vsub)
{
return sms_subscriber_find_pending(smsq, vsub) != NULL;
}
+/* allocate a new gsm_sms_pending record and fill it with information from 'sms' */
static struct gsm_sms_pending *sms_pending_from(struct gsm_sms_queue *smsq,
struct gsm_sms *sms)
{
@@ -122,16 +201,26 @@ static struct gsm_sms_pending *sms_pending_from(struct gsm_sms_queue *smsq,
vlr_subscr_get(sms->receiver, VSUB_USE_SMS_PENDING);
pending->vsub = sms->receiver;
pending->sms_id = sms->id;
+ llist_add_tail(&pending->entry, &smsq->pending_sms);
+
+ smsq->pending += 1;
+ smsq_stat_item_inc(smsq, SMSQ_STAT_SMS_RAM_PENDING);
+
return pending;
}
-static void sms_pending_free(struct gsm_sms_pending *pending)
+/* release a gsm_sms_pending object */
+static void sms_pending_free(struct gsm_sms_queue *smsq, struct gsm_sms_pending *pending)
{
+ smsq->pending -= 1;
+ smsq_stat_item_dec(smsq, SMSQ_STAT_SMS_RAM_PENDING);
vlr_subscr_put(pending->vsub, VSUB_USE_SMS_PENDING);
llist_del(&pending->entry);
talloc_free(pending);
}
+/* this sets the 'resend' flag of the gsm_sms_pending and schedules
+ * the timer for re-sending */
static void sms_pending_resend(struct gsm_sms_pending *pending)
{
struct gsm_network *net = pending->vsub->vlr->user_ctx;
@@ -148,6 +237,8 @@ static void sms_pending_resend(struct gsm_sms_pending *pending)
osmo_timer_schedule(&smsq->resend_pending, 1, 0);
}
+/* call-back when a pending SMS has failed; try another re-send if number of
+ * attempts is < smsq->max_fail */
static void sms_pending_failed(struct gsm_sms_pending *pending, int paging_error)
{
struct gsm_network *net = pending->vsub->vlr->user_ctx;
@@ -158,17 +249,16 @@ static void sms_pending_failed(struct gsm_sms_pending *pending, int paging_error
pending->sms_id, pending->failed_attempts);
smsq = net->sms_queue;
- if (pending->failed_attempts < smsq->max_fail)
+ if (pending->failed_attempts < smsq->cfg->max_fail)
return sms_pending_resend(pending);
- sms_pending_free(pending);
- smsq->pending -= 1;
+ sms_pending_free(smsq, pending);
}
-/*
- * Resend all SMS that are scheduled for a resend. This is done to
- * avoid an immediate failure.
- */
+/* Resend all SMS that are scheduled for a resend. This is done to
+ * avoid an immediate failure. This iterates over all the (in RAM)
+ * pending_sms records, checks for resend == true, reads them from the
+ * DB and attempts to send them via _gsm411_send_sms() */
static void sms_resend_pending(void *_data)
{
struct gsm_sms_pending *pending, *tmp;
@@ -183,12 +273,11 @@ static void sms_resend_pending(void *_data)
/* the sms is gone? Move to the next */
if (!sms) {
- sms_pending_free(pending);
- smsq->pending -= 1;
+ sms_pending_free(smsq, pending);
sms_queue_trigger(smsq);
} else {
pending->resend = 0;
- gsm411_send_sms(smsq->network, sms->receiver, sms);
+ _gsm411_send_sms(smsq->network, sms->receiver, sms);
}
}
}
@@ -244,19 +333,19 @@ struct gsm_sms *smsq_take_next_sms(struct gsm_network *net,
return NULL;
}
-/**
- * I will submit up to max_pending - pending SMS to the
- * subsystem.
- */
+/* read up to 'max_pending' pending SMS from the database and add them to the in-memory
+ * sms_queue; trigger the first delivery attempt. 'submit' in this context means
+ * "read from the database and add to the in-memory gsm_sms_queue" and is not to be
+ * confused with the SMS SUBMIT operation a MS performs when sending a MO-SMS. */
static void sms_submit_pending(void *_data)
{
struct gsm_sms_queue *smsq = _data;
- int attempts = smsq->max_pending - smsq->pending;
+ int attempts = smsq->cfg->max_pending - smsq->pending;
int initialized = 0;
unsigned long long first_sub = 0;
int attempted = 0, rounds = 0;
- LOGP(DLSMS, LOGL_DEBUG, "Attempting to send %d SMS\n", attempts);
+ LOGP(DLSMS, LOGL_DEBUG, "Attempting to send up to %d SMS\n", attempts);
do {
struct gsm_sms_pending *pending;
@@ -272,7 +361,7 @@ static void sms_submit_pending(void *_data)
}
rounds += 1;
- LOGP(DLSMS, LOGL_DEBUG, "Sending SMS round %d\n", rounds);
+ LOGP(DLSMS, LOGL_DEBUG, "Checking whether to send SMS %llu\n", sms->id);
/*
* This code needs to detect a loop. It assumes that no SMS
@@ -309,6 +398,7 @@ static void sms_submit_pending(void *_data)
continue;
}
+ /* allocate a new gsm_sms_pending object in RAM */
pending = sms_pending_from(smsq, sms);
if (!pending) {
LOGP(DLSMS, LOGL_ERROR,
@@ -318,17 +408,16 @@ static void sms_submit_pending(void *_data)
}
attempted += 1;
- smsq->pending += 1;
- llist_add_tail(&pending->entry, &smsq->pending_sms);
- gsm411_send_sms(smsq->network, sms->receiver, sms);
+ _gsm411_send_sms(smsq->network, sms->receiver, sms);
} while (attempted < attempts && rounds < 1000);
LOGP(DLSMS, LOGL_DEBUG, "SMSqueue added %d messages in %d rounds\n", attempted, rounds);
}
-/**
- * Send the next SMS or trigger the queue
- */
+/* obtain the next pending SMS for given subscriber from database,
+ * create gsm_sms_pending object and attempt first delivery. If there
+ * are no SMS pending for the given subscriber, call sms_submit_pending()
+ * to read more SMS (for any subscriber) into the in-RAM pending queue */
static void sms_send_next(struct vlr_subscr *vsub)
{
struct gsm_network *net = vsub->vlr->user_ctx;
@@ -340,7 +429,7 @@ static void sms_send_next(struct vlr_subscr *vsub)
OSMO_ASSERT(!sms_subscriber_is_pending(smsq, vsub));
/* check for more messages for this subscriber */
- sms = db_sms_get_unsent_for_subscr(vsub, UINT_MAX);
+ sms = db_sms_get_unsent_for_subscr(vsub, INT_MAX);
if (!sms)
goto no_pending_sms;
@@ -356,9 +445,7 @@ static void sms_send_next(struct vlr_subscr *vsub)
goto no_pending_sms;
}
- smsq->pending += 1;
- llist_add_tail(&pending->entry, &smsq->pending_sms);
- gsm411_send_sms(smsq->network, sms->receiver, sms);
+ _gsm411_send_sms(smsq->network, sms->receiver, sms);
return;
no_pending_sms:
@@ -366,9 +453,7 @@ no_pending_sms:
sms_submit_pending(net->sms_queue);
}
-/*
- * Kick off the queue again.
- */
+/* Trigger a call to sms_submit_pending() in one second */
int sms_queue_trigger(struct gsm_sms_queue *smsq)
{
LOGP(DLSMS, LOGL_DEBUG, "Triggering SMS queue\n");
@@ -379,7 +464,26 @@ int sms_queue_trigger(struct gsm_sms_queue *smsq)
return 0;
}
-int sms_queue_start(struct gsm_network *network, int max_pending)
+/* allocate + initialize SMS queue configuration with some default values */
+struct sms_queue_config *sms_queue_cfg_alloc(void *ctx)
+{
+ struct sms_queue_config *sqcfg = talloc_zero(ctx, struct sms_queue_config);
+ OSMO_ASSERT(sqcfg);
+
+ sqcfg->max_pending = 20;
+ sqcfg->max_fail = 1;
+ sqcfg->delete_delivered = true;
+ sqcfg->delete_expired = true;
+ sqcfg->default_validity_mins = 7 * 24 * 60; /* 7 days */
+ sqcfg->minimum_validity_mins = 1;
+ sqcfg->db_file_path = talloc_strdup(ctx, SMS_DEFAULT_DB_FILE_PATH);
+
+ return sqcfg;
+}
+
+/* initialize the sms_queue subsystem and read the first batch of SMS from
+ * the database for delivery */
+int sms_queue_start(struct gsm_network *network)
{
struct gsm_sms_queue *sms = talloc_zero(network, struct gsm_sms_queue);
if (!sms) {
@@ -387,22 +491,48 @@ int sms_queue_start(struct gsm_network *network, int max_pending)
return -1;
}
- osmo_signal_register_handler(SS_SUBSCR, sms_subscr_cb, network);
- osmo_signal_register_handler(SS_SMS, sms_sms_cb, network);
+ sms->cfg = network->sms_queue_cfg;
+ sms->statg = osmo_stat_item_group_alloc(sms, &smsq_statg_desc, 0);
+ if (!sms->statg)
+ goto err_free;
+
+ sms->ctrg = rate_ctr_group_alloc(sms, &smsq_ctrg_desc, 0);
+ if (!sms->ctrg)
+ goto err_statg;
network->sms_queue = sms;
INIT_LLIST_HEAD(&sms->pending_sms);
- sms->max_fail = 1;
sms->network = network;
- sms->max_pending = max_pending;
osmo_timer_setup(&sms->push_queue, sms_submit_pending, sms);
osmo_timer_setup(&sms->resend_pending, sms_resend_pending, sms);
+ osmo_signal_register_handler(SS_SUBSCR, sms_subscr_cb, network);
+ osmo_signal_register_handler(SS_SMS, sms_sms_cb, network);
+
+ if (db_init(sms, sms->cfg->db_file_path, true)) {
+ LOGP(DMSC, LOGL_FATAL, "DB: Failed to init database: %s\n",
+ osmo_quote_str(sms->cfg->db_file_path, -1));
+ return -1;
+ }
+
+ if (db_prepare()) {
+ LOGP(DMSC, LOGL_FATAL, "DB: Failed to prepare database.\n");
+ return -1;
+ }
+
sms_submit_pending(sms);
return 0;
+
+err_statg:
+ osmo_stat_item_group_free(sms->statg);
+err_free:
+ talloc_free(sms);
+
+ return -ENOMEM;
}
+/* call-back: Given subscriber is now ready for short messages. */
static int sub_ready_for_sm(struct gsm_network *net, struct vlr_subscr *vsub)
{
struct gsm_sms *sms;
@@ -432,14 +562,15 @@ static int sub_ready_for_sm(struct gsm_network *net, struct vlr_subscr *vsub)
}
/* Now try to deliver any pending SMS to this sub */
- sms = db_sms_get_unsent_for_subscr(vsub, UINT_MAX);
+ sms = db_sms_get_unsent_for_subscr(vsub, INT_MAX);
if (!sms)
return -1;
- gsm411_send_sms(net, vsub, sms);
+ _gsm411_send_sms(net, vsub, sms);
return 0;
}
+/* call-back for SS_SUBSCR signals */
static int sms_subscr_cb(unsigned int subsys, unsigned int signal,
void *handler_data, void *signal_data)
{
@@ -452,10 +583,12 @@ static int sms_subscr_cb(unsigned int subsys, unsigned int signal,
return sub_ready_for_sm(handler_data, vsub);
}
+/* call-back for SS_SMS signals */
static int sms_sms_cb(unsigned int subsys, unsigned int signal,
void *handler_data, void *signal_data)
{
struct gsm_network *network = handler_data;
+ struct gsm_sms_queue *smq = network->sms_queue;
struct sms_signal_data *sig_sms = signal_data;
struct gsm_sms_pending *pending;
struct vlr_subscr *vsub;
@@ -463,7 +596,7 @@ static int sms_sms_cb(unsigned int subsys, unsigned int signal,
/* We got a new SMS and maybe should launch the queue again. */
if (signal == S_SMS_SUBMITTED || signal == S_SMS_SMMA) {
/* TODO: For SMMA we might want to re-use the radio connection. */
- sms_queue_trigger(network->sms_queue);
+ sms_queue_trigger(smq);
return 0;
}
@@ -476,26 +609,27 @@ static int sms_sms_cb(unsigned int subsys, unsigned int signal,
* sms that are not in our control as we just have a channel
* open anyway.
*/
- pending = sms_find_pending(network->sms_queue, sig_sms->sms->id);
+ pending = sms_find_pending(smq, sig_sms->sms->id);
if (!pending)
return 0;
switch (signal) {
case S_SMS_DELIVERED:
+ smsq_rate_ctr_inc(smq, SMSQ_CTR_SMS_DELIVERY_ACK);
/* Remember the subscriber and clear the pending entry */
- network->sms_queue->pending -= 1;
vsub = pending->vsub;
vlr_subscr_get(vsub, __func__);
- db_sms_delete_sent_message_by_id(pending->sms_id);
- sms_pending_free(pending);
+ if (smq->cfg->delete_delivered)
+ db_sms_delete_sent_message_by_id(pending->sms_id);
+ sms_pending_free(smq, pending);
/* Attempt to send another SMS to this subscriber */
sms_send_next(vsub);
vlr_subscr_put(vsub, __func__);
break;
case S_SMS_MEM_EXCEEDED:
- network->sms_queue->pending -= 1;
- sms_pending_free(pending);
- sms_queue_trigger(network->sms_queue);
+ smsq_rate_ctr_inc(smq, SMSQ_CTR_SMS_DELIVERY_NOMEM);
+ sms_pending_free(smq, pending);
+ sms_queue_trigger(smq);
break;
case S_SMS_UNKNOWN_ERROR:
/*
@@ -509,10 +643,12 @@ static int sms_sms_cb(unsigned int subsys, unsigned int signal,
* should flag the SMS as bad.
*/
if (sig_sms->paging_result) {
+ smsq_rate_ctr_inc(smq, SMSQ_CTR_SMS_DELIVERY_ERR);
/* BAD SMS? */
db_sms_inc_deliver_attempts(sig_sms->sms);
sms_pending_failed(pending, 0);
} else {
+ smsq_rate_ctr_inc(smq, SMSQ_CTR_SMS_DELIVERY_TIMEOUT);
sms_pending_failed(pending, 1);
}
break;
@@ -522,7 +658,8 @@ static int sms_sms_cb(unsigned int subsys, unsigned int signal,
}
/* While here, attempt to remove an expired SMS from the DB. */
- db_sms_delete_oldest_expired_message();
+ if (smq->cfg->delete_expired)
+ db_sms_delete_oldest_expired_message();
return 0;
}
@@ -533,7 +670,7 @@ int sms_queue_stats(struct gsm_sms_queue *smsq, struct vty *vty)
struct gsm_sms_pending *pending;
vty_out(vty, "SMSqueue with max_pending: %d pending: %d%s",
- smsq->max_pending, smsq->pending, VTY_NEWLINE);
+ smsq->cfg->max_pending, smsq->pending, VTY_NEWLINE);
llist_for_each_entry(pending, &smsq->pending_sms, entry)
vty_out(vty, " SMS Pending for Subscriber: %llu SMS: %llu Failed: %d.%s",
@@ -542,22 +679,6 @@ int sms_queue_stats(struct gsm_sms_queue *smsq, struct vty *vty)
return 0;
}
-int sms_queue_set_max_pending(struct gsm_sms_queue *smsq, int max_pending)
-{
- LOGP(DLSMS, LOGL_NOTICE, "SMSqueue old max: %d new: %d\n",
- smsq->max_pending, max_pending);
- smsq->max_pending = max_pending;
- return 0;
-}
-
-int sms_queue_set_max_failure(struct gsm_sms_queue *smsq, int max_fail)
-{
- LOGP(DLSMS, LOGL_NOTICE, "SMSqueue max failure old: %d new: %d\n",
- smsq->max_fail, max_fail);
- smsq->max_fail = max_fail;
- return 0;
-}
-
int sms_queue_clear(struct gsm_sms_queue *smsq)
{
struct gsm_sms_pending *pending, *tmp;
@@ -565,9 +686,8 @@ int sms_queue_clear(struct gsm_sms_queue *smsq)
llist_for_each_entry_safe(pending, tmp, &smsq->pending_sms, entry) {
LOGP(DLSMS, LOGL_NOTICE,
"SMSqueue clearing for sub %llu\n", pending->vsub->id);
- sms_pending_free(pending);
+ sms_pending_free(smsq, pending);
}
- smsq->pending = 0;
return 0;
}
diff --git a/src/libmsc/smsc_vty.c b/src/libmsc/smsc_vty.c
new file mode 100644
index 000000000..f30907f4b
--- /dev/null
+++ b/src/libmsc/smsc_vty.c
@@ -0,0 +1,214 @@
+/* SMSC interface to VTY */
+/* (C) 2016-2018 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>
+ * Based on OpenBSC interface to quagga VTY (libmsc/vty_interface_layer3.c)
+ * (C) 2009-2022 by Harald Welte <laforge@gnumonks.org>
+ * (C) 2009-2011 by Holger Hans Peter Freyther
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "config.h"
+
+#include <osmocom/vty/command.h>
+#include <osmocom/vty/logging.h>
+#include <osmocom/vty/misc.h>
+
+#include <osmocom/msc/vty.h>
+#include <osmocom/msc/gsm_data.h>
+#include <osmocom/msc/sms_queue.h>
+
+
+static struct gsm_network *gsmnet;
+static struct sms_queue_config *smqcfg;
+
+/***********************************************************************
+ * SMSC Config Node
+ ***********************************************************************/
+
+static struct cmd_node smsc_node = {
+ SMSC_NODE,
+ "%s(config-smsc)# ",
+ 1,
+};
+
+DEFUN(cfg_smsc, cfg_smsc_cmd,
+ "smsc", "Configure SMSC options")
+{
+ vty->node = SMSC_NODE;
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_sms_database, cfg_sms_database_cmd,
+ "database PATH",
+ "Set the path to the MSC-SMS database file\n"
+ "Relative or absolute file system path to the database file (default is '" SMS_DEFAULT_DB_FILE_PATH "')\n")
+{
+ osmo_talloc_replace_string(smqcfg, &smqcfg->db_file_path, argv[0]);
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_sms_queue_max, cfg_sms_queue_max_cmd,
+ "queue max-pending <1-500>",
+ "SMS Queue\n" "SMS to deliver in parallel\n" "Amount\n")
+{
+ smqcfg->max_pending = atoi(argv[0]);
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_sms_queue_fail, cfg_sms_queue_fail_cmd,
+ "queue max-failure <1-500>",
+ "SMS Queue\n" "Maximum number of delivery failures before giving up\n" "Amount\n")
+{
+ smqcfg->max_fail = atoi(argv[0]);
+ return CMD_SUCCESS;
+}
+
+#define DB_STR "SMS Database Configuration\n"
+
+DEFUN(cfg_sms_db_del_delivered, cfg_sms_db_del_delivered_cmd,
+ "database delete-delivered (0|1)",
+ DB_STR "Configure if delivered SMS are deleted from DB\n"
+ "Do not delete SMS after delivery\n"
+ "Delete SMS after delivery\n")
+{
+ smqcfg->delete_delivered = atoi(argv[0]);
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_sms_db_del_expired, cfg_sms_db_del_expired_cmd,
+ "database delete-expired (0|1)",
+ DB_STR "Configure if expired SMS are deleted from DB\n"
+ "Do not delete SMS after expiration of validity period\n"
+ "Delete SMS after expiration of validity period\n")
+{
+ smqcfg->delete_expired = atoi(argv[0]);
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_sms_def_val_per, cfg_sms_def_val_per_cmd,
+ "validity-period (minimum|default) <1-5256000>",
+ "Configure validity period for SMS\n"
+ "Minimum SMS validity period in minutes\n"
+ "Default SMS validity period in minutes\n"
+ "Validity period in minutes\n")
+{
+ if (!strcmp(argv[0], "minimum"))
+ smqcfg->minimum_validity_mins = atoi(argv[1]);
+ else
+ smqcfg->default_validity_mins = atoi(argv[1]);
+ return CMD_SUCCESS;
+}
+
+
+/***********************************************************************
+ * View / Enable Node
+ ***********************************************************************/
+
+DEFUN(show_smsqueue,
+ show_smsqueue_cmd,
+ "show sms-queue",
+ SHOW_STR "Display SMSqueue statistics\n")
+{
+ sms_queue_stats(gsmnet->sms_queue, vty);
+ return CMD_SUCCESS;
+}
+
+DEFUN(smsqueue_trigger,
+ smsqueue_trigger_cmd,
+ "sms-queue trigger",
+ "SMS Queue\n" "Trigger sending messages\n")
+{
+ sms_queue_trigger(gsmnet->sms_queue);
+ return CMD_SUCCESS;
+}
+
+DEFUN(smsqueue_max,
+ smsqueue_max_cmd,
+ "sms-queue max-pending <1-500>",
+ "SMS Queue\n" "SMS to deliver in parallel\n" "Amount\n")
+{
+ int max_pending = atoi(argv[0]);
+ vty_out(vty, "%% SMSqueue old max: %d new: %d%s",
+ smqcfg->max_pending, max_pending, VTY_NEWLINE);
+ smqcfg->max_pending = max_pending;
+ return CMD_SUCCESS;
+}
+
+DEFUN(smsqueue_clear,
+ smsqueue_clear_cmd,
+ "sms-queue clear",
+ "SMS Queue\n" "Clear the queue of pending SMS\n")
+{
+ sms_queue_clear(gsmnet->sms_queue);
+ return CMD_SUCCESS;
+}
+
+DEFUN(smsqueue_fail,
+ smsqueue_fail_cmd,
+ "sms-queue max-failure <1-500>",
+ "SMS Queue\n" "Maximum amount of delivery failures\n" "Amount\n")
+{
+ int max_fail = atoi(argv[0]);
+ vty_out(vty, "%% SMSqueue max failure old: %d new: %d%s",
+ smqcfg->max_fail, max_fail, VTY_NEWLINE);
+ smqcfg->max_fail = max_fail;
+ return CMD_SUCCESS;
+}
+
+static int config_write_smsc(struct vty *vty)
+{
+ vty_out(vty, "smsc%s", VTY_NEWLINE);
+
+ if (smqcfg->db_file_path && strcmp(smqcfg->db_file_path, SMS_DEFAULT_DB_FILE_PATH))
+ vty_out(vty, " database %s%s", smqcfg->db_file_path, VTY_NEWLINE);
+
+ vty_out(vty, " queue max-pending %u%s", smqcfg->max_pending, VTY_NEWLINE);
+ vty_out(vty, " queue max-failure %u%s", smqcfg->max_fail, VTY_NEWLINE);
+
+ vty_out(vty, " database delete-delivered %u%s", smqcfg->delete_delivered, VTY_NEWLINE);
+ vty_out(vty, " database delete-expired %u%s", smqcfg->delete_expired, VTY_NEWLINE);
+
+ vty_out(vty, " validity-period minimum %u%s", smqcfg->minimum_validity_mins, VTY_NEWLINE);
+ vty_out(vty, " validity-period default %u%s", smqcfg->default_validity_mins, VTY_NEWLINE);
+
+ return 0;
+}
+
+void smsc_vty_init(struct gsm_network *msc_network)
+{
+ OSMO_ASSERT(gsmnet == NULL);
+ gsmnet = msc_network;
+ smqcfg = msc_network->sms_queue_cfg;
+
+ /* config node */
+ install_element(CONFIG_NODE, &cfg_smsc_cmd);
+ install_node(&smsc_node, config_write_smsc);
+ install_element(SMSC_NODE, &cfg_sms_database_cmd);
+ install_element(SMSC_NODE, &cfg_sms_queue_max_cmd);
+ install_element(SMSC_NODE, &cfg_sms_queue_fail_cmd);
+ install_element(SMSC_NODE, &cfg_sms_db_del_delivered_cmd);
+ install_element(SMSC_NODE, &cfg_sms_db_del_expired_cmd);
+ install_element(SMSC_NODE, &cfg_sms_def_val_per_cmd);
+
+ /* enable node */
+ install_element(ENABLE_NODE, &smsqueue_trigger_cmd);
+ install_element(ENABLE_NODE, &smsqueue_max_cmd);
+ install_element(ENABLE_NODE, &smsqueue_clear_cmd);
+ install_element(ENABLE_NODE, &smsqueue_fail_cmd);
+
+ /* view / enable node */
+ install_element_ve(&show_smsqueue_cmd);
+}
diff --git a/src/libmsc/transaction.c b/src/libmsc/transaction.c
index d6f8c3b17..7ae4c7d92 100644
--- a/src/libmsc/transaction.c
+++ b/src/libmsc/transaction.c
@@ -29,6 +29,7 @@
#include <osmocom/msc/msub.h>
#include <osmocom/msc/paging.h>
#include <osmocom/msc/silent_call.h>
+#include <osmocom/msc/msc_vgcs.h>
void *tall_trans_ctx;
@@ -73,16 +74,17 @@ struct gsm_trans *trans_find_by_id(const struct msc_a *msc_a,
/*! Find a transaction by call reference
* \param[in] net Network in which we should search
+ * \param[in] type Transaction type (e.g. TRANS_CC)
* \param[in] callref Call Reference of transaction
* \returns Matching transaction, if any
*/
-struct gsm_trans *trans_find_by_callref(const struct gsm_network *net,
+struct gsm_trans *trans_find_by_callref(const struct gsm_network *net, enum trans_type type,
uint32_t callref)
{
struct gsm_trans *trans;
llist_for_each_entry(trans, &net->trans_list, entry) {
- if (trans->callref == callref)
+ if (trans->callref == callref && trans->type == type)
return trans;
}
return NULL;
@@ -110,13 +112,81 @@ struct gsm_trans *trans_find_by_sm_rp_mr(const struct gsm_network *net,
return NULL;
}
+struct osmo_lcls *trans_lcls_compose(const struct gsm_trans *trans, bool use_lac)
+{
+ if (!trans) {
+ LOGP(DCC, LOGL_ERROR, "LCLS: unable to fill parameters for unallocated transaction\n");
+ return NULL;
+ }
+
+ if (!trans->net->a.sri->sccp)
+ return NULL;
+
+ struct osmo_ss7_instance *ss7 = osmo_sccp_get_ss7(trans->net->a.sri->sccp);
+ struct osmo_lcls *lcls;
+ uint8_t w = osmo_ss7_pc_width(&ss7->cfg.pc_fmt);
+
+ if (!trans->net->lcls_permitted) {
+ LOGP(DCC, LOGL_NOTICE, "LCLS disabled globally\n");
+ return NULL;
+ }
+
+ if (!trans->msc_a) {
+ LOGP(DCC, LOGL_ERROR, "LCLS: unable to fill parameters for transaction without connection\n");
+ return NULL;
+ }
+
+ if (trans->msc_a->c.ran->type != OSMO_RAT_GERAN_A) {
+ LOGP(DCC, LOGL_ERROR, "LCLS: only A interface is supported at the moment\n");
+ return NULL;
+ }
+
+ lcls = talloc_zero(trans, struct osmo_lcls);
+ if (!lcls) {
+ LOGP(DCC, LOGL_ERROR, "LCLS: failed to allocate osmo_lcls\n");
+ return NULL;
+ }
+
+ LOGP(DCC, LOGL_INFO, "LCLS: using %u bits (%u bytes) for node ID\n", w, w / 8);
+
+ lcls->gcr.net_len = 3;
+ lcls->gcr.node = ss7->cfg.primary_pc;
+
+ /* net id from Q.1902.3 3-5 bytes, this function gives 3 bytes exactly */
+ osmo_plmn_to_bcd(lcls->gcr.net, &trans->msc_a->via_cell.lai.plmn);
+
+
+ /* TS 29.205 Table B.2.1.9.2 Call Reference ID
+ * 3 octets Call ID + 2 octets BSS ID
+ */
+ lcls->gcr.cr[2] = (trans->callref >> 0) & 0xff;
+ lcls->gcr.cr[1] = (trans->callref >> 8) & 0xff;
+ lcls->gcr.cr[0] = (trans->callref >> 16) & 0xff;
+ osmo_store16be(use_lac ? trans->msc_a->via_cell.lai.lac : trans->msc_a->via_cell.cell_identity, &lcls->gcr.cr[3]);
+
+ LOGP(DCC, LOGL_INFO, "LCLS: allocated %s-based CR-ID %sfor callref 0x%04x\n", use_lac ? "LAC" : "CI",
+ osmo_hexdump(lcls->gcr.cr, 5), trans->callref);
+
+ lcls->config = GSM0808_LCLS_CFG_BOTH_WAY;
+ lcls->control = GSM0808_LCLS_CSC_CONNECT;
+ lcls->corr_needed = true;
+ lcls->gcr_available = true;
+
+ LOGP(DCC, LOGL_DEBUG, "Filled %s\n", osmo_lcls_dump(lcls));
+ LOGP(DCC, LOGL_DEBUG, "Filled %s\n", osmo_gcr_dump(lcls));
+
+ return lcls;
+}
+
static const char *trans_vsub_use(enum trans_type type)
{
return get_value_string_or_null(trans_type_names, type) ? : "trans-type-unknown";
}
+static uint32_t new_call_id = 1;
+
/*! Allocate a new transaction and add it to network list
- * \param[in] net Netwokr in which we allocate transaction
+ * \param[in] net Network in which we allocate transaction
* \param[in] subscr Subscriber for which we allocate transaction
* \param[in] protocol Protocol (CC/SMS/...)
* \param[in] callref Call Reference
@@ -127,11 +197,12 @@ struct gsm_trans *trans_alloc(struct gsm_network *net,
enum trans_type type, uint8_t trans_id,
uint32_t callref)
{
- struct gsm_trans *trans = NULL; /* (NULL for LOG_TRANS() before allocation) */
+ int subsys = trans_log_subsys(type);
+ struct gsm_trans *trans;
- /* a valid subscriber is indispensable */
- if (vsub == NULL) {
- LOG_TRANS(trans, LOGL_ERROR, "unable to alloc transaction, invalid subscriber (NULL)\n");
+ /* A valid subscriber is indispensable, except for voice group/broadcast calls. */
+ if (vsub == NULL && type != TRANS_GCC && type != TRANS_BCC) {
+ LOGP(subsys, LOGL_ERROR, "unable to alloc transaction, invalid subscriber (NULL)\n");
return NULL;
}
@@ -142,12 +213,18 @@ struct gsm_trans *trans_alloc(struct gsm_network *net,
*trans = (struct gsm_trans){
.vsub = vsub,
.type = type,
+ .log_subsys = subsys,
.transaction_id = trans_id,
.callref = callref,
+ .call_id = new_call_id++,
.net = net,
+ /* empty bearer_cap: make sure the speech_ver array is empty */
+ .bearer_cap = {
+ .speech_ver = { -1 },
+ },
};
- trans->log_subsys = trans_log_subsys(trans);
- vlr_subscr_get(vsub, trans_vsub_use(type));
+ if (vsub)
+ vlr_subscr_get(vsub, trans_vsub_use(type));
llist_add_tail(&trans->entry, &net->trans_list);
LOG_TRANS(trans, LOGL_DEBUG, "New transaction\n");
@@ -165,6 +242,14 @@ void trans_free(struct gsm_trans *trans)
LOG_TRANS(trans, LOGL_DEBUG, "Freeing transaction\n");
switch (trans->type) {
+ case TRANS_GCC:
+ gsm44068_bcc_gcc_trans_free(trans);
+ usage_token = MSC_A_USE_GCC;
+ break;
+ case TRANS_BCC:
+ gsm44068_bcc_gcc_trans_free(trans);
+ usage_token = MSC_A_USE_BCC;
+ break;
case TRANS_CC:
_gsm48_cc_trans_free(trans);
usage_token = MSC_A_USE_CC;
@@ -276,6 +361,8 @@ void trans_conn_closed(const struct msc_a *msc_a)
}
const struct value_string trans_type_names[] = {
+ { TRANS_GCC, "GCC" },
+ { TRANS_BCC, "BCC" },
{ TRANS_CC, "CC" },
{ TRANS_SMS, "SMS" },
{ TRANS_USSD, "NCSS" },
@@ -286,6 +373,10 @@ const struct value_string trans_type_names[] = {
uint8_t trans_type_to_gsm48_proto(enum trans_type type)
{
switch (type) {
+ case TRANS_GCC:
+ return GSM48_PDISC_GROUP_CC;
+ case TRANS_BCC:
+ return GSM48_PDISC_BCAST_CC;
case TRANS_CC:
case TRANS_SILENT_CALL:
return GSM48_PDISC_CC;
@@ -298,3 +389,25 @@ uint8_t trans_type_to_gsm48_proto(enum trans_type type)
}
}
+
+const char *trans_name(const struct gsm_trans *trans)
+{
+ static char namebuf[32];
+ if (!trans)
+ return "NULL";
+ switch (trans->type) {
+ case TRANS_CC:
+ snprintf(namebuf, sizeof(namebuf), "%s:%s",
+ trans_type_name(trans->type), gsm48_cc_state_name(trans->cc.state));
+ return namebuf;
+
+ case TRANS_GCC:
+ case TRANS_BCC:
+ snprintf(namebuf, sizeof(namebuf), "%s:%s",
+ trans_type_name(trans->type), gsm44068_group_id_string(trans->callref));
+ return namebuf;
+
+ default:
+ return trans_type_name(trans->type);
+ }
+}
diff --git a/src/libmsc/transaction_cc.c b/src/libmsc/transaction_cc.c
new file mode 100644
index 000000000..2a540bfa5
--- /dev/null
+++ b/src/libmsc/transaction_cc.c
@@ -0,0 +1,120 @@
+/* Filter/overlay codec and CSD bearer service selections for voice calls/CSD,
+ * across MS, RAN and CN limitations
+ *
+ * (C) 2023 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
+ * All Rights Reserved
+ *
+ * Author: Oliver Smith
+ *
+ * SPDX-License-Identifier: AGPL-3.0+
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <osmocom/msc/transaction_cc.h>
+#include <osmocom/msc/codec_filter.h>
+#include <osmocom/msc/csd_filter.h>
+
+void trans_cc_filter_init(struct gsm_trans *trans)
+{
+ trans->cc.codecs = (struct codec_filter){};
+ trans->cc.csd = (struct csd_filter){};
+}
+
+void trans_cc_filter_set_ran(struct gsm_trans *trans, enum osmo_rat_type ran_type)
+{
+ codec_filter_set_ran(&trans->cc.codecs, ran_type);
+ csd_filter_set_ran(&trans->cc.csd, ran_type);
+}
+
+void trans_cc_filter_set_bss(struct gsm_trans *trans, struct msc_a *msc_a)
+{
+ codec_filter_set_bss(&trans->cc.codecs, &msc_a->cc.compl_l3_codec_list_bss_supported);
+
+ /* For CSD, there is no list of supported bearer services passed in
+ * Complete Layer 3. TODO: make it configurable? */
+}
+
+void _trans_cc_filter_run(const char *file, int line, struct gsm_trans *trans)
+{
+ switch (trans->bearer_cap.transfer) {
+ case GSM48_BCAP_ITCAP_SPEECH:
+ codec_filter_run(&trans->cc.codecs, &trans->cc.local, &trans->cc.remote);
+ LOG_TRANS_CAT_SRC(trans, DCC, LOGL_DEBUG, file, line, "codecs: %s\n",
+ codec_filter_to_str(&trans->cc.codecs, &trans->cc.local, &trans->cc.remote));
+ break;
+ case GSM48_BCAP_ITCAP_3k1_AUDIO:
+ case GSM48_BCAP_ITCAP_FAX_G3:
+ case GSM48_BCAP_ITCAP_UNR_DIG_INF:
+ csd_filter_run(&trans->cc.csd, &trans->cc.local, &trans->cc.remote);
+ LOG_TRANS_CAT_SRC(trans, DCC, LOGL_DEBUG, file, line, "codec/BS: %s\n",
+ csd_filter_to_str(&trans->cc.csd, &trans->cc.local, &trans->cc.remote));
+ break;
+ default:
+ LOG_TRANS_CAT_SRC(trans, DCC, LOGL_ERROR, file, line,
+ "Handling of information transfer capability %d not implemented\n",
+ trans->bearer_cap.transfer);
+ break;
+ }
+}
+
+void trans_cc_filter_set_ms_from_bc(struct gsm_trans *trans, const struct gsm_mncc_bearer_cap *bcap)
+{
+ trans->cc.codecs.ms = (struct sdp_audio_codecs){0};
+ trans->cc.csd.ms = (struct csd_bs_list){0};
+
+ if (!bcap)
+ return;
+
+ switch (bcap->transfer) {
+ case GSM48_BCAP_ITCAP_SPEECH:
+ sdp_audio_codecs_from_bearer_cap(&trans->cc.codecs.ms, bcap);
+ break;
+ case GSM48_BCAP_ITCAP_3k1_AUDIO:
+ case GSM48_BCAP_ITCAP_FAX_G3:
+ case GSM48_BCAP_ITCAP_UNR_DIG_INF:
+ sdp_audio_codecs_set_csd(&trans->cc.codecs.ms);
+ csd_bs_list_from_bearer_cap(&trans->cc.csd.ms, bcap);
+ break;
+ default:
+ LOG_TRANS(trans, LOGL_ERROR, "Handling of information transfer capability %d not implemented\n",
+ bcap->transfer);
+ break;
+ }
+}
+
+void trans_cc_set_remote_from_bc(struct gsm_trans *trans, const struct gsm_mncc_bearer_cap *bcap)
+{
+ trans->cc.remote.audio_codecs = (struct sdp_audio_codecs){0};
+ trans->cc.remote.bearer_services = (struct csd_bs_list){0};
+
+ if (!bcap)
+ return;
+
+ switch (bcap->transfer) {
+ case GSM48_BCAP_ITCAP_SPEECH:
+ sdp_audio_codecs_from_bearer_cap(&trans->cc.remote.audio_codecs, bcap);
+ break;
+ case GSM48_BCAP_ITCAP_3k1_AUDIO:
+ case GSM48_BCAP_ITCAP_FAX_G3:
+ case GSM48_BCAP_ITCAP_UNR_DIG_INF:
+ sdp_audio_codecs_set_csd(&trans->cc.remote.audio_codecs);
+ csd_bs_list_from_bearer_cap(&trans->cc.remote.bearer_services, bcap);
+ break;
+ default:
+ LOG_TRANS(trans, LOGL_ERROR, "Handling of information transfer capability %d not implemented\n",
+ bcap->transfer);
+ break;
+ }
+}
diff --git a/src/libsmpputil/Makefile.am b/src/libsmpputil/Makefile.am
new file mode 100644
index 000000000..b180ddf6f
--- /dev/null
+++ b/src/libsmpputil/Makefile.am
@@ -0,0 +1,25 @@
+AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir)
+AM_CFLAGS= \
+ -Wall \
+ $(LIBOSMOCORE_CFLAGS) \
+ $(LIBOSMOVTY_CFLAGS) \
+ $(LIBOSMOSCCP_CFLAGS) \
+ $(LIBOSMOGSM_CFLAGS) \
+ $(LIBOSMONETIF_CFLAGS) \
+ $(LIBOSMOMGCPCLIENT_CFLAGS) \
+ $(LIBOSMOGSUPCLIENT_CFLAGS) \
+ $(LIBSMPP34_CFLAGS) \
+ $(COVERAGE_CFLAGS) \
+ $(NULL)
+
+noinst_HEADERS = \
+ $(NULL)
+
+noinst_LIBRARIES = libsmpputil.a
+
+libsmpputil_a_SOURCES = \
+ smpp_utils.c \
+ smpp_vty.c \
+ smpp_msc.c \
+ smpp_smsc.c \
+ $(NULL)
diff --git a/src/libmsc/smpp_openbsc.c b/src/libsmpputil/smpp_msc.c
index bbfc5008f..0c2a9282f 100644
--- a/src/libmsc/smpp_openbsc.c
+++ b/src/libsmpputil/smpp_msc.c
@@ -1,6 +1,6 @@
/* OpenBSC SMPP 3.4 interface, SMSC-side implementation */
-/* (C) 2012-2013 by Harald Welte <laforge@gnumonks.org>
+/* (C) 2012-2022 by Harald Welte <laforge@gnumonks.org>
*
* All Rights Reserved
*
@@ -24,6 +24,7 @@
#include <string.h>
#include <stdint.h>
#include <errno.h>
+#include <time.h>
#include <smpp34.h>
#include <smpp34_structs.h>
@@ -47,8 +48,7 @@
#include <osmocom/msc/gsm_subscriber.h>
#include <osmocom/msc/vlr.h>
#include <osmocom/msc/msc_a.h>
-
-#include "smpp_smsc.h"
+#include <osmocom/smpp/smpp_smsc.h>
#define VSUB_USE_SMPP "SMPP"
#define VSUB_USE_SMPP_CMD "SMPP-cmd"
@@ -122,6 +122,8 @@ static int smpp34_submit_tlv_msg_payload(const struct tlv_t *t,
static int submit_to_sms(struct gsm_sms **psms, struct gsm_network *net,
const struct submit_sm_t *submit)
{
+ time_t t_now = time(NULL);
+ time_t t_validity_absolute;
const uint8_t *sms_msg = NULL;
unsigned int sms_msg_len = 0;
struct vlr_subscr *dest;
@@ -239,10 +241,16 @@ static int submit_to_sms(struct gsm_sms **psms, struct gsm_network *net,
}
if (mode == MODE_7BIT) {
- uint8_t ud_len = 0, padbits = 0;
+ unsigned int ud_len = 0, padbits = 0;
sms->data_coding_scheme = GSM338_DCS_1111_7BIT;
if (sms->ud_hdr_ind) {
ud_len = *sms_msg + 1;
+ if (ud_len > sms_msg_len) {
+ sms_free(sms);
+ LOGP(DLSMS, LOGL_ERROR, "invalid ud_len=%u > sms_msg_len=%u\n", ud_len,
+ sms_msg_len);
+ return ESME_RINVPARLEN;
+ }
printf("copying %u bytes user data...\n", ud_len);
memcpy(sms->user_data, sms_msg,
OSMO_MIN(ud_len, sizeof(sms->user_data)));
@@ -250,8 +258,7 @@ static int submit_to_sms(struct gsm_sms **psms, struct gsm_network *net,
sms_msg_len -= ud_len;
padbits = 7 - (ud_len % 7);
}
- gsm_septets2octets(sms->user_data+ud_len, sms_msg,
- sms_msg_len, padbits);
+ gsm_septet_pack(sms->user_data+ud_len, sms_msg, sms_msg_len, padbits);
sms->user_data_len = (ud_len*8 + padbits)/7 + sms_msg_len;/* SEPTETS */
/* FIXME: sms->text */
} else {
@@ -259,12 +266,25 @@ static int submit_to_sms(struct gsm_sms **psms, struct gsm_network *net,
sms->user_data_len = sms_msg_len;
}
+ t_validity_absolute = smpp_parse_time_format((const char *) submit->validity_period, &t_now);
+ if (!t_validity_absolute)
+ sms->validity_minutes = net->sms_queue_cfg->default_validity_mins;
+ else
+ sms->validity_minutes = (t_validity_absolute - t_now) / 60;
+
+ if (sms->validity_minutes < net->sms_queue_cfg->minimum_validity_mins) {
+ LOGP(DLSMS, LOGL_INFO, "SMS to %s: Overriding ESME-provided validity period (%lu) "
+ "with minimum SMSC validity period (%u) minutes\n", submit->destination_addr,
+ sms->validity_minutes, net->sms_queue_cfg->minimum_validity_mins);
+ sms->validity_minutes = net->sms_queue_cfg->minimum_validity_mins;
+ }
+
*psms = sms;
return ESME_ROK;
}
/*! \brief handle incoming libsmpp34 ssubmit_sm_t from remote ESME */
-int handle_smpp_submit(struct osmo_esme *esme, struct submit_sm_t *submit,
+int handle_smpp_submit(struct smpp_esme *esme, struct submit_sm_t *submit,
struct submit_sm_resp_t *submit_r)
{
struct gsm_sms *sms;
@@ -315,21 +335,19 @@ int handle_smpp_submit(struct osmo_esme *esme, struct submit_sm_t *submit,
static void alert_all_esme(struct smsc *smsc, struct vlr_subscr *vsub,
uint8_t smpp_avail_status)
{
- struct osmo_esme *esme;
+ struct smpp_esme *esme;
llist_for_each_entry(esme, &smsc->esme_list, list) {
/* we currently send an alert notification to each ESME that is
- * connected, and do not require a (non-existant) delivery
+ * connected, and do not require a (non-existent) delivery
* pending flag to be set before. */
if (!esme->bind_flags) {
LOGP(DSMPP, LOGL_DEBUG,
"ESME is not (yet) bound, skipping alert\n");
continue;
}
- if (!esme->acl->alert_notifications) {
- LOGP(DSMPP, LOGL_DEBUG,
- "[%s] is not set to receive Alert Notifications\n",
- esme->system_id);
+ if (esme->acl && !esme->acl->alert_notifications) {
+ LOGPESME(esme->esme, LOGL_DEBUG, "is not set to receive Alert Notifications\n");
continue;
}
if (esme->acl && esme->acl->deliver_src_imsi) {
@@ -367,7 +385,7 @@ static int smpp_sms_cb(unsigned int subsys, unsigned int signal,
* to the ESME */
case S_SMS_UNKNOWN_ERROR:
if (sms->smpp.transaction_mode) {
- /* Send back the SUBMIT-SM response with apropriate error */
+ /* Send back the SUBMIT-SM response with appropriate error */
LOGP(DLSMS, LOGL_INFO, "SMPP SUBMIT-SM: Error\n");
rc = smpp_tx_submit_r(sms->smpp.esme,
sms->smpp.sequence_nr,
@@ -573,7 +591,7 @@ static void smpp_cmd_free(struct osmo_smpp_cmd *cmd)
talloc_free(cmd);
}
-void smpp_cmd_flush_pending(struct osmo_esme *esme)
+void smpp_cmd_flush_pending(struct smpp_esme *esme)
{
struct osmo_smpp_cmd *cmd, *next;
@@ -641,7 +659,7 @@ static void smpp_deliver_sm_cb(void *data)
smpp_cmd_err(data, ESME_RSYSERR);
}
-static int smpp_cmd_enqueue(struct osmo_esme *esme,
+static int smpp_cmd_enqueue(struct smpp_esme *esme,
struct vlr_subscr *vsub, struct gsm_sms *sms,
uint32_t sequence_number)
{
@@ -670,7 +688,7 @@ static int smpp_cmd_enqueue(struct osmo_esme *esme,
return 0;
}
-struct osmo_smpp_cmd *smpp_cmd_find_by_seqnum(struct osmo_esme *esme,
+struct osmo_smpp_cmd *smpp_cmd_find_by_seqnum(struct smpp_esme *esme,
uint32_t sequence_nr)
{
struct osmo_smpp_cmd *cmd;
@@ -682,7 +700,7 @@ struct osmo_smpp_cmd *smpp_cmd_find_by_seqnum(struct osmo_esme *esme,
return NULL;
}
-static int deliver_to_esme(struct osmo_esme *esme, struct gsm_sms *sms,
+static int deliver_to_esme(struct smpp_esme *esme, struct gsm_sms *sms,
struct msc_a *msc_a)
{
struct deliver_sm_t deliver;
@@ -770,15 +788,18 @@ static int deliver_to_esme(struct osmo_esme *esme, struct gsm_sms *sms,
sms->msg_ref);
ret = smpp_tx_deliver(esme, &deliver);
+ destroy_tlv(deliver.tlv);
if (ret < 0)
return ret;
+ OSMO_ASSERT(!sms->smpp.esme);
+ smpp_esme_get(esme);
+ sms->smpp.esme = esme;
+
return smpp_cmd_enqueue(esme, vsub, sms,
deliver.sequence_number);
}
-static struct smsc *g_smsc;
-
bool smpp_route_smpp_first()
{
return (bool)(g_smsc->smpp_first);
@@ -786,7 +807,7 @@ bool smpp_route_smpp_first()
int smpp_try_deliver(struct gsm_sms *sms, struct msc_a *msc_a)
{
- struct osmo_esme *esme;
+ struct smpp_esme *esme;
struct osmo_smpp_addr dst;
int rc;
@@ -808,8 +829,8 @@ struct smsc *smsc_from_vty(struct vty *v)
return g_smsc;
}
-/*! \brief Allocate the OpenBSC SMPP interface struct and init VTY. */
-int smpp_openbsc_alloc_init(void *ctx)
+/*! \brief Allocate the OsmoMSC SMPP interface struct and init VTY. */
+int smpp_msc_alloc_init(void *ctx)
{
g_smsc = smpp_smsc_alloc_init(ctx);
if (!g_smsc) {
@@ -820,9 +841,9 @@ int smpp_openbsc_alloc_init(void *ctx)
return smpp_vty_init();
}
-/*! \brief Launch the OpenBSC SMPP interface with the parameters set from VTY.
+/*! \brief Launch the OsmoMSC SMPP interface with the parameters set from VTY.
*/
-int smpp_openbsc_start(struct gsm_network *net)
+int smpp_msc_start(struct gsm_network *net)
{
int rc;
g_smsc->priv = net;
@@ -843,4 +864,3 @@ int smpp_openbsc_start(struct gsm_network *net)
return 0;
}
-
diff --git a/src/libmsc/smpp_smsc.c b/src/libsmpputil/smpp_smsc.c
index 3bfb81a3d..34e24c513 100644
--- a/src/libmsc/smpp_smsc.c
+++ b/src/libsmpputil/smpp_smsc.c
@@ -38,16 +38,11 @@
#include <osmocom/core/logging.h>
#include <osmocom/core/write_queue.h>
#include <osmocom/core/talloc.h>
-
-#include "smpp_smsc.h"
+#include <osmocom/gsm/protocol/gsm_04_11.h>
#include <osmocom/msc/debug.h>
#include <osmocom/msc/gsm_data.h>
-
-/*! \brief Ugly wrapper. libsmpp34 should do this itself! */
-#define SMPP34_UNPACK(rc, type, str, data, len) \
- memset(str, 0, sizeof(*str)); \
- rc = smpp34_unpack(type, str, data, len)
+#include <osmocom/smpp/smpp_smsc.h>
enum emse_bind {
ESME_BIND_RX = 0x01,
@@ -164,12 +159,12 @@ void smpp_acl_delete(struct osmo_smpp_acl *acl)
/* kill any active ESMEs */
if (acl->esme) {
- struct osmo_esme *esme = acl->esme;
+ struct esme *esme = acl->esme->esme;
osmo_fd_unregister(&esme->wqueue.bfd);
close(esme->wqueue.bfd.fd);
esme->wqueue.bfd.fd = -1;
- esme->acl = NULL;
- smpp_esme_put(esme);
+ smpp_esme_put(acl->esme);
+ acl->esme = NULL;
}
/* delete all routes for this ACL */
@@ -236,17 +231,17 @@ int smpp_route_pfx_del(struct osmo_smpp_acl *acl,
/*! \brief increaes the use/reference count */
-void smpp_esme_get(struct osmo_esme *esme)
+void smpp_esme_get(struct smpp_esme *esme)
{
esme->use++;
}
-static void esme_destroy(struct osmo_esme *esme)
+static void esme_destroy(struct smpp_esme *esme)
{
- osmo_wqueue_clear(&esme->wqueue);
- if (esme->wqueue.bfd.fd >= 0) {
- osmo_fd_unregister(&esme->wqueue.bfd);
- close(esme->wqueue.bfd.fd);
+ osmo_wqueue_clear(&esme->esme->wqueue);
+ if (esme->esme->wqueue.bfd.fd >= 0) {
+ osmo_fd_unregister(&esme->esme->wqueue.bfd);
+ close(esme->esme->wqueue.bfd.fd);
}
smpp_cmd_flush_pending(esme);
llist_del(&esme->list);
@@ -255,7 +250,7 @@ static void esme_destroy(struct osmo_esme *esme)
talloc_free(esme);
}
-static uint32_t esme_inc_seq_nr(struct osmo_esme *esme)
+uint32_t esme_inc_seq_nr(struct esme *esme)
{
esme->own_seq_nr++;
if (esme->own_seq_nr > 0x7fffffff)
@@ -265,7 +260,7 @@ static uint32_t esme_inc_seq_nr(struct osmo_esme *esme)
}
/*! \brief decrease the use/reference count, free if it is 0 */
-void smpp_esme_put(struct osmo_esme *esme)
+void smpp_esme_put(struct smpp_esme *esme)
{
esme->use--;
if (esme->use <= 0)
@@ -273,7 +268,7 @@ void smpp_esme_put(struct osmo_esme *esme)
}
/*! \brief try to find a SMPP route (ESME) for given destination */
-int smpp_route(const struct smsc *smsc, const struct osmo_smpp_addr *dest, struct osmo_esme **pesme)
+int smpp_route(const struct smsc *smsc, const struct osmo_smpp_addr *dest, struct smpp_esme **pesme)
{
struct osmo_smpp_route *r;
struct osmo_smpp_acl *acl = NULL;
@@ -313,56 +308,48 @@ int smpp_route(const struct smsc *smsc, const struct osmo_smpp_addr *dest, struc
}
if (acl && acl->esme) {
- struct osmo_esme *esme;
+ struct smpp_esme *esme;
DEBUGP(DSMPP, "ACL even has ESME, we can route to it!\n");
esme = acl->esme;
if (esme->bind_flags & ESME_BIND_RX) {
*pesme = esme;
return 0;
} else
- LOGP(DSMPP, LOGL_NOTICE, "[%s] is matching route, "
- "but not bound for Rx, discarding MO SMS\n",
- esme->system_id);
+ LOGPESME(esme->esme, LOGL_NOTICE, "is matching route, but not bound for Rx, discarding MO SMS\n");
}
*pesme = NULL;
if (acl)
- return GSM48_CC_CAUSE_NETWORK_OOO;
+ return GSM411_RP_CAUSE_MO_NET_OUT_OF_ORDER;
else
- return GSM48_CC_CAUSE_UNASSIGNED_NR;
-}
-
-
-/*! \brief initialize the libsmpp34 data structure for a response */
-#define INIT_RESP(type, resp, req) { \
- memset((resp), 0, sizeof(*(resp))); \
- (resp)->command_length = 0; \
- (resp)->command_id = type; \
- (resp)->command_status = ESME_ROK; \
- (resp)->sequence_number = (req)->sequence_number; \
+ return GSM411_RP_CAUSE_MO_NUM_UNASSIGNED;
}
/*! \brief pack a libsmpp34 data strcutrure and send it to the ESME */
-#define PACK_AND_SEND(esme, ptr) pack_and_send(esme, (ptr)->command_id, ptr)
-static int pack_and_send(struct osmo_esme *esme, uint32_t type, void *ptr)
+int pack_and_send(struct esme *esme, uint32_t type, void *ptr)
{
- struct msgb *msg = msgb_alloc(4096, "SMPP_Tx");
+ struct msgb *msg;
int rc, rlen;
+
+ /* the socket was closed. Avoid allocating + enqueueing msgb, see
+ * https://osmocom.org/issues/3278 */
+ if (esme->wqueue.bfd.fd == -1)
+ return -EIO;
+
+ msg = msgb_alloc(4096, "SMPP_Tx");
if (!msg)
return -ENOMEM;
rc = smpp34_pack(type, msg->tail, msgb_tailroom(msg), &rlen, ptr);
if (rc != 0) {
- LOGP(DSMPP, LOGL_ERROR, "[%s] Error during smpp34_pack(): %s\n",
- esme->system_id, smpp34_strerror);
+ LOGPESMERR(esme, "during smpp34_pack()\n");
msgb_free(msg);
return -EINVAL;
}
msgb_put(msg, rlen);
if (osmo_wqueue_enqueue(&esme->wqueue, msg) != 0) {
- LOGP(DSMPP, LOGL_ERROR, "[%s] Write queue full. Dropping message\n",
- esme->system_id);
+ LOGPESME(esme, LOGL_ERROR, "Write queue full. Dropping message\n");
msgb_free(msg);
return -EAGAIN;
}
@@ -370,7 +357,7 @@ static int pack_and_send(struct osmo_esme *esme, uint32_t type, void *ptr)
}
/*! \brief transmit a generic NACK to a remote ESME */
-static int smpp_tx_gen_nack(struct osmo_esme *esme, uint32_t seq, uint32_t status)
+static int smpp_tx_gen_nack(struct esme *esme, uint32_t seq, uint32_t status)
{
struct generic_nack_t nack;
char buf[SMALL_BUFF];
@@ -380,19 +367,11 @@ static int smpp_tx_gen_nack(struct osmo_esme *esme, uint32_t seq, uint32_t statu
nack.sequence_number = seq;
nack.command_status = status;
- LOGP(DSMPP, LOGL_ERROR, "[%s] Tx GENERIC NACK: %s\n",
- esme->system_id, str_command_status(status, buf));
+ LOGPESME(esme, LOGL_ERROR, "Tx GENERIC NACK: %s\n", str_command_status(status, buf));
return PACK_AND_SEND(esme, &nack);
}
-/*! \brief retrieve SMPP command ID from a msgb */
-static inline uint32_t smpp_msgb_cmdid(struct msgb *msg)
-{
- uint8_t *tmp = msgb_data(msg) + 4;
- return ntohl(*(uint32_t *)tmp);
-}
-
/*! \brief retrieve SMPP sequence number from a msgb */
static inline uint32_t smpp_msgb_seq(struct msgb *msg)
{
@@ -401,7 +380,7 @@ static inline uint32_t smpp_msgb_seq(struct msgb *msg)
}
/*! \brief handle an incoming SMPP generic NACK */
-static int smpp_handle_gen_nack(struct osmo_esme *esme, struct msgb *msg)
+static int smpp_handle_gen_nack(struct esme *esme, struct msgb *msg)
{
struct generic_nack_t nack;
char buf[SMALL_BUFF];
@@ -410,18 +389,16 @@ static int smpp_handle_gen_nack(struct osmo_esme *esme, struct msgb *msg)
SMPP34_UNPACK(rc, GENERIC_NACK, &nack, msgb_data(msg),
msgb_length(msg));
if (rc < 0) {
- LOGP(DSMPP, LOGL_ERROR, "[%s] Error in smpp34_unpack():%s\n",
- esme->system_id, smpp34_strerror);
+ LOGPESMERR(esme, "in smpp34_unpack()\n");
return rc;
}
- LOGP(DSMPP, LOGL_ERROR, "[%s] Rx GENERIC NACK: %s\n",
- esme->system_id, str_command_status(nack.command_status, buf));
+ LOGPESME(esme, LOGL_ERROR, "Rx GENERIC NACK: %s\n", str_command_status(nack.command_status, buf));
return 0;
}
-static int _process_bind(struct osmo_esme *esme, uint8_t if_version,
+static int _process_bind(struct smpp_esme *esme, uint8_t if_version,
uint32_t bind_flags, const char *sys_id,
const char *passwd)
{
@@ -434,9 +411,9 @@ static int _process_bind(struct osmo_esme *esme, uint8_t if_version,
return ESME_RALYBND;
esme->smpp_version = if_version;
- snprintf(esme->system_id, sizeof(esme->system_id), "%s", sys_id);
+ snprintf(esme->esme->system_id, sizeof(esme->esme->system_id), "%s", sys_id);
- acl = smpp_acl_by_system_id(esme->smsc, esme->system_id);
+ acl = smpp_acl_by_system_id(esme->smsc, esme->esme->system_id);
if (!esme->smsc->accept_all) {
if (!acl) {
/* This system is unknown */
@@ -460,7 +437,7 @@ static int _process_bind(struct osmo_esme *esme, uint8_t if_version,
/*! \brief handle an incoming SMPP BIND RECEIVER */
-static int smpp_handle_bind_rx(struct osmo_esme *esme, struct msgb *msg)
+static int smpp_handle_bind_rx(struct smpp_esme *esme, struct msgb *msg)
{
struct bind_receiver_t bind;
struct bind_receiver_resp_t bind_r;
@@ -469,8 +446,7 @@ static int smpp_handle_bind_rx(struct osmo_esme *esme, struct msgb *msg)
SMPP34_UNPACK(rc, BIND_RECEIVER, &bind, msgb_data(msg),
msgb_length(msg));
if (rc < 0) {
- LOGP(DSMPP, LOGL_ERROR, "[%s] Error in smpp34_unpack():%s\n",
- esme->system_id, smpp34_strerror);
+ LOGPESMERR(esme->esme, "in smpp34_unpack()\n");
return rc;
}
@@ -483,22 +459,21 @@ static int smpp_handle_bind_rx(struct osmo_esme *esme, struct msgb *msg)
(const char *)bind.system_id, (const char *)bind.password);
bind_r.command_status = rc;
- return PACK_AND_SEND(esme, &bind_r);
+ return PACK_AND_SEND(esme->esme, &bind_r);
}
/*! \brief handle an incoming SMPP BIND TRANSMITTER */
-static int smpp_handle_bind_tx(struct osmo_esme *esme, struct msgb *msg)
+static int smpp_handle_bind_tx(struct smpp_esme *esme, struct msgb *msg)
{
struct bind_transmitter_t bind;
struct bind_transmitter_resp_t bind_r;
- struct tlv_t tlv;
+ struct tlv_t tlv = {};
int rc;
SMPP34_UNPACK(rc, BIND_TRANSMITTER, &bind, msgb_data(msg),
msgb_length(msg));
if (rc < 0) {
- LOGP(DSMPP, LOGL_ERROR, "[%s] Error in smpp34_unpack():%s\n",
- esme->system_id, smpp34_strerror);
+ LOGPESMERR(esme->esme, "in smpp34_unpack()\n");
return rc;
}
@@ -520,13 +495,13 @@ static int smpp_handle_bind_tx(struct osmo_esme *esme, struct msgb *msg)
tlv.value.val16 = esme->smpp_version;
build_tlv(&bind_r.tlv, &tlv);
- rc = PACK_AND_SEND(esme, &bind_r);
+ rc = PACK_AND_SEND(esme->esme, &bind_r);
destroy_tlv(bind_r.tlv);
return rc;
}
/*! \brief handle an incoming SMPP BIND TRANSCEIVER */
-static int smpp_handle_bind_trx(struct osmo_esme *esme, struct msgb *msg)
+static int smpp_handle_bind_trx(struct smpp_esme *esme, struct msgb *msg)
{
struct bind_transceiver_t bind;
struct bind_transceiver_resp_t bind_r;
@@ -535,8 +510,7 @@ static int smpp_handle_bind_trx(struct osmo_esme *esme, struct msgb *msg)
SMPP34_UNPACK(rc, BIND_TRANSCEIVER, &bind, msgb_data(msg),
msgb_length(msg));
if (rc < 0) {
- LOGP(DSMPP, LOGL_ERROR, "[%s] Error in smpp34_unpack():%s\n",
- esme->system_id, smpp34_strerror);
+ LOGPESMERR(esme->esme, "in smpp34_unpack()\n");
return rc;
}
@@ -549,11 +523,11 @@ static int smpp_handle_bind_trx(struct osmo_esme *esme, struct msgb *msg)
(const char *)bind.system_id, (const char *)bind.password);
bind_r.command_status = rc;
- return PACK_AND_SEND(esme, &bind_r);
+ return PACK_AND_SEND(esme->esme, &bind_r);
}
/*! \brief handle an incoming SMPP UNBIND */
-static int smpp_handle_unbind(struct osmo_esme *esme, struct msgb *msg)
+static int smpp_handle_unbind(struct smpp_esme *esme, struct msgb *msg)
{
struct unbind_t unbind;
struct unbind_resp_t unbind_r;
@@ -562,14 +536,13 @@ static int smpp_handle_unbind(struct osmo_esme *esme, struct msgb *msg)
SMPP34_UNPACK(rc, UNBIND, &unbind, msgb_data(msg),
msgb_length(msg));
if (rc < 0) {
- LOGP(DSMPP, LOGL_ERROR, "[%s] Error in smpp34_unpack():%s\n",
- esme->system_id, smpp34_strerror);
+ LOGPESMERR(esme->esme, "in smpp34_unpack()\n");
return rc;
}
INIT_RESP(UNBIND_RESP, &unbind_r, &unbind);
- LOGP(DSMPP, LOGL_INFO, "[%s] Rx UNBIND\n", esme->system_id);
+ LOGPESME(esme->esme, LOGL_INFO, "Rx UNBIND\n");
if (esme->bind_flags == 0) {
unbind_r.command_status = ESME_RINVBNDSTS;
@@ -578,11 +551,11 @@ static int smpp_handle_unbind(struct osmo_esme *esme, struct msgb *msg)
esme->bind_flags = 0;
err:
- return PACK_AND_SEND(esme, &unbind_r);
+ return PACK_AND_SEND(esme->esme, &unbind_r);
}
/*! \brief handle an incoming SMPP ENQUIRE LINK */
-static int smpp_handle_enq_link(struct osmo_esme *esme, struct msgb *msg)
+static int smpp_handle_enq_link(struct smpp_esme *esme, struct msgb *msg)
{
struct enquire_link_t enq;
struct enquire_link_resp_t enq_r;
@@ -591,22 +564,21 @@ static int smpp_handle_enq_link(struct osmo_esme *esme, struct msgb *msg)
SMPP34_UNPACK(rc, ENQUIRE_LINK, &enq, msgb_data(msg),
msgb_length(msg));
if (rc < 0) {
- LOGP(DSMPP, LOGL_ERROR, "[%s] Error in smpp34_unpack():%s\n",
- esme->system_id, smpp34_strerror);
+ LOGPESMERR(esme->esme, "in smpp34_unpack()\n");
return rc;
}
- LOGP(DSMPP, LOGL_DEBUG, "[%s] Rx Enquire Link\n", esme->system_id);
+ LOGPESME(esme->esme, LOGL_DEBUG, "Rx Enquire Link\n");
INIT_RESP(ENQUIRE_LINK_RESP, &enq_r, &enq);
- LOGP(DSMPP, LOGL_DEBUG, "[%s] Tx Enquire Link Response\n", esme->system_id);
+ LOGPESME(esme->esme, LOGL_DEBUG, "Tx Enquire Link Response\n");
- return PACK_AND_SEND(esme, &enq_r);
+ return PACK_AND_SEND(esme->esme, &enq_r);
}
/*! \brief send a SUBMIT-SM RESPONSE to a remote ESME */
-int smpp_tx_submit_r(struct osmo_esme *esme, uint32_t sequence_nr,
+int smpp_tx_submit_r(struct smpp_esme *esme, uint32_t sequence_nr,
uint32_t command_status, char *msg_id)
{
struct submit_sm_resp_t submit_r;
@@ -618,7 +590,7 @@ int smpp_tx_submit_r(struct osmo_esme *esme, uint32_t sequence_nr,
submit_r.sequence_number= sequence_nr;
snprintf((char *) submit_r.message_id, sizeof(submit_r.message_id), "%s", msg_id);
- return PACK_AND_SEND(esme, &submit_r);
+ return PACK_AND_SEND(esme->esme, &submit_r);
}
static const struct value_string smpp_avail_strs[] = {
@@ -629,7 +601,7 @@ static const struct value_string smpp_avail_strs[] = {
};
/*! \brief send an ALERT_NOTIFICATION to a remote ESME */
-int smpp_tx_alert(struct osmo_esme *esme, uint8_t ton, uint8_t npi,
+int smpp_tx_alert(struct smpp_esme *esme, uint8_t ton, uint8_t npi,
const char *addr, uint8_t avail_status)
{
struct alert_notification_t alert;
@@ -640,7 +612,7 @@ int smpp_tx_alert(struct osmo_esme *esme, uint8_t ton, uint8_t npi,
alert.command_length = 0;
alert.command_id = ALERT_NOTIFICATION;
alert.command_status = ESME_ROK;
- alert.sequence_number = esme_inc_seq_nr(esme);
+ alert.sequence_number = esme_inc_seq_nr(esme->esme);
alert.source_addr_ton = ton;
alert.source_addr_npi = npi;
snprintf((char *)alert.source_addr, sizeof(alert.source_addr), "%s", addr);
@@ -650,29 +622,28 @@ int smpp_tx_alert(struct osmo_esme *esme, uint8_t ton, uint8_t npi,
tlv.value.val08 = avail_status;
build_tlv(&alert.tlv, &tlv);
- LOGP(DSMPP, LOGL_DEBUG, "[%s] Tx ALERT_NOTIFICATION (%s/%u/%u): %s\n",
- esme->system_id, alert.source_addr, alert.source_addr_ton,
- alert.source_addr_npi,
- get_value_string(smpp_avail_strs, avail_status));
+ LOGPESME(esme->esme, LOGL_DEBUG, "Tx ALERT_NOTIFICATION (%s/%u/%u): %s\n",
+ alert.source_addr, alert.source_addr_ton,
+ alert.source_addr_npi,
+ get_value_string(smpp_avail_strs, avail_status));
- rc = PACK_AND_SEND(esme, &alert);
+ rc = PACK_AND_SEND(esme->esme, &alert);
destroy_tlv(alert.tlv);
return rc;
}
/* \brief send a DELIVER-SM message to given ESME */
-int smpp_tx_deliver(struct osmo_esme *esme, struct deliver_sm_t *deliver)
+int smpp_tx_deliver(struct smpp_esme *esme, struct deliver_sm_t *deliver)
{
- deliver->sequence_number = esme_inc_seq_nr(esme);
+ deliver->sequence_number = esme_inc_seq_nr(esme->esme);
- LOGP(DSMPP, LOGL_DEBUG, "[%s] Tx DELIVER-SM (from %s)\n",
- esme->system_id, deliver->source_addr);
+ LOGPESME(esme->esme, LOGL_DEBUG, "Tx DELIVER-SM (from %s)\n", deliver->source_addr);
- return PACK_AND_SEND(esme, deliver);
+ return PACK_AND_SEND(esme->esme, deliver);
}
/*! \brief handle an incoming SMPP DELIVER-SM RESPONSE */
-static int smpp_handle_deliver_resp(struct osmo_esme *esme, struct msgb *msg)
+static int smpp_handle_deliver_resp(struct smpp_esme *esme, struct msgb *msg)
{
struct deliver_sm_resp_t deliver_r;
struct osmo_smpp_cmd *cmd;
@@ -682,16 +653,14 @@ static int smpp_handle_deliver_resp(struct osmo_esme *esme, struct msgb *msg)
SMPP34_UNPACK(rc, DELIVER_SM_RESP, &deliver_r, msgb_data(msg),
msgb_length(msg));
if (rc < 0) {
- LOGP(DSMPP, LOGL_ERROR, "[%s] Error in smpp34_unpack():%s\n",
- esme->system_id, smpp34_strerror);
+ LOGPESMERR(esme->esme, "in smpp34_unpack()\n");
return rc;
}
cmd = smpp_cmd_find_by_seqnum(esme, deliver_r.sequence_number);
if (!cmd) {
- LOGP(DSMPP, LOGL_ERROR, "[%s] Rx DELIVER-SM RESP !? (%s)\n",
- esme->system_id, get_value_string(smpp_status_strs,
- deliver_r.command_status));
+ LOGPESME(esme->esme, LOGL_ERROR, "Rx DELIVER-SM RESP !? (%s)\n",
+ get_value_string(smpp_status_strs, deliver_r.command_status));
return -1;
}
@@ -700,15 +669,14 @@ static int smpp_handle_deliver_resp(struct osmo_esme *esme, struct msgb *msg)
else
smpp_cmd_err(cmd, deliver_r.command_status);
- LOGP(DSMPP, LOGL_INFO, "[%s] Rx DELIVER-SM RESP (%s)\n",
- esme->system_id, get_value_string(smpp_status_strs,
- deliver_r.command_status));
+ LOGPESME(esme->esme, LOGL_INFO, "Rx DELIVER-SM RESP (%s)\n",
+ get_value_string(smpp_status_strs, deliver_r.command_status));
return 0;
}
/*! \brief handle an incoming SMPP SUBMIT-SM */
-static int smpp_handle_submit(struct osmo_esme *esme, struct msgb *msg)
+static int smpp_handle_submit(struct smpp_esme *esme, struct msgb *msg)
{
struct submit_sm_t submit;
struct submit_sm_resp_t submit_r;
@@ -718,8 +686,7 @@ static int smpp_handle_submit(struct osmo_esme *esme, struct msgb *msg)
SMPP34_UNPACK(rc, SUBMIT_SM, &submit, msgb_data(msg),
msgb_length(msg));
if (rc < 0) {
- LOGP(DSMPP, LOGL_ERROR, "[%s] Error in smpp34_unpack():%s\n",
- esme->system_id, smpp34_strerror);
+ LOGPESMERR(esme->esme, "in smpp34_unpack()\n");
return rc;
}
@@ -727,34 +694,34 @@ static int smpp_handle_submit(struct osmo_esme *esme, struct msgb *msg)
if (!(esme->bind_flags & ESME_BIND_TX)) {
submit_r.command_status = ESME_RINVBNDSTS;
- return PACK_AND_SEND(esme, &submit_r);
+ destroy_tlv(submit.tlv);
+ return PACK_AND_SEND(esme->esme, &submit_r);
}
- LOGP(DSMPP, LOGL_INFO, "[%s] Rx SUBMIT-SM (%s/%u/%u)\n",
- esme->system_id, submit.destination_addr,
- submit.dest_addr_ton, submit.dest_addr_npi);
+ LOGPESME(esme->esme, LOGL_INFO, "Rx SUBMIT-SM (%s/%u/%u)\n",
+ submit.destination_addr, submit.dest_addr_ton, submit.dest_addr_npi);
INIT_RESP(SUBMIT_SM_RESP, &submit_r, &submit);
rc = handle_smpp_submit(esme, &submit, &submit_r);
+ destroy_tlv(submit.tlv);
if (rc == 0)
- return PACK_AND_SEND(esme, &submit_r);
+ return PACK_AND_SEND(esme->esme, &submit_r);
return rc;
}
/*! \brief one complete SMPP PDU from the ESME has been received */
-static int smpp_pdu_rx(struct osmo_esme *esme, struct msgb *msg __uses)
+static int smpp_pdu_rx(struct smpp_esme *esme, struct msgb *msg __uses)
{
uint32_t cmd_id = smpp_msgb_cmdid(msg);
int rc = 0;
- LOGP(DSMPP, LOGL_DEBUG, "[%s] smpp_pdu_rx(%s)\n", esme->system_id,
- msgb_hexdump(msg));
+ LOGPESME(esme->esme, LOGL_DEBUG, "smpp_pdu_rx(%s)\n", msgb_hexdump(msg));
switch (cmd_id) {
case GENERIC_NACK:
- rc = smpp_handle_gen_nack(esme, msg);
+ rc = smpp_handle_gen_nack(esme->esme, msg);
break;
case BIND_RECEIVER:
rc = smpp_handle_bind_rx(esme, msg);
@@ -785,13 +752,11 @@ static int smpp_pdu_rx(struct osmo_esme *esme, struct msgb *msg __uses)
case QUERY_SM:
case REPLACE_SM:
case SUBMIT_MULTI:
- LOGP(DSMPP, LOGL_NOTICE, "[%s] Unimplemented PDU Command "
- "0x%08x\n", esme->system_id, cmd_id);
+ LOGPESME(esme->esme, LOGL_NOTICE, "Unimplemented PDU Command 0x%08x\n", cmd_id);
break;
default:
- LOGP(DSMPP, LOGL_ERROR, "[%s] Unknown PDU Command 0x%08x\n",
- esme->system_id, cmd_id);
- rc = smpp_tx_gen_nack(esme, smpp_msgb_seq(msg), ESME_RINVCMDID);
+ LOGPESME(esme->esme, LOGL_ERROR, "Unknown PDU Command 0x%08x\n", cmd_id);
+ rc = smpp_tx_gen_nack(esme->esme, smpp_msgb_seq(msg), ESME_RINVCMDID);
break;
}
@@ -818,7 +783,8 @@ static int smpp_pdu_rx(struct osmo_esme *esme, struct msgb *msg __uses)
/* !\brief call-back when per-ESME TCP socket has some data to be read */
static int esme_link_read_cb(struct osmo_fd *ofd)
{
- struct osmo_esme *esme = ofd->data;
+ struct smpp_esme *e = ofd->data;
+ struct esme *esme = e->esme;
uint32_t len;
uint8_t *lenptr = (uint8_t *) &len;
uint8_t *cur;
@@ -830,8 +796,7 @@ static int esme_link_read_cb(struct osmo_fd *ofd)
rdlen = sizeof(uint32_t) - esme->read_idx;
rc = read(ofd->fd, lenptr + esme->read_idx, rdlen);
if (rc < 0)
- LOGP(DSMPP, LOGL_ERROR, "[%s] read returned %zd (%s)\n",
- esme->system_id, rc, strerror(errno));
+ LOGPESME(esme, LOGL_ERROR, "read returned %zd (%s)\n", rc, strerror(errno));
OSMO_FD_CHECK_READ(rc, dead_socket);
esme->read_idx += rc;
@@ -839,8 +804,7 @@ static int esme_link_read_cb(struct osmo_fd *ofd)
if (esme->read_idx >= sizeof(uint32_t)) {
esme->read_len = ntohl(len);
if (esme->read_len < 8 || esme->read_len > UINT16_MAX) {
- LOGP(DSMPP, LOGL_ERROR, "[%s] length invalid %u\n",
- esme->system_id, esme->read_len);
+ LOGPESME(esme, LOGL_ERROR, "length invalid %u\n", esme->read_len);
goto dead_socket;
}
@@ -859,15 +823,15 @@ static int esme_link_read_cb(struct osmo_fd *ofd)
rdlen = esme->read_len - esme->read_idx;
rc = read(ofd->fd, msg->tail, OSMO_MIN(rdlen, msgb_tailroom(msg)));
if (rc < 0)
- LOGP(DSMPP, LOGL_ERROR, "[%s] read returned %zd (%s)\n",
- esme->system_id, rc, strerror(errno));
+ LOGPESME(esme, LOGL_ERROR, "read returned %zd (%s)\n",
+ rc, strerror(errno));
OSMO_FD_CHECK_READ(rc, dead_socket);
esme->read_idx += rc;
msgb_put(msg, rc);
if (esme->read_idx >= esme->read_len) {
- rc = smpp_pdu_rx(esme, esme->read_msg);
+ rc = smpp_pdu_rx(e, esme->read_msg);
msgb_free(esme->read_msg);
esme->read_msg = NULL;
esme->read_idx = 0;
@@ -883,66 +847,77 @@ dead_socket:
osmo_fd_unregister(&esme->wqueue.bfd);
close(esme->wqueue.bfd.fd);
esme->wqueue.bfd.fd = -1;
- if (esme->acl)
- esme->acl->esme = NULL;
- smpp_esme_put(esme);
+ if (e->acl)
+ e->acl->esme = NULL;
+ smpp_esme_put(e);
- return 0;
+ return -EBADF;
}
/* call-back of write queue once it wishes to write a message to the socket */
static int esme_link_write_cb(struct osmo_fd *ofd, struct msgb *msg)
{
- struct osmo_esme *esme = ofd->data;
+ struct smpp_esme *esme = ofd->data;
int rc;
rc = write(ofd->fd, msgb_data(msg), msgb_length(msg));
if (rc == 0) {
- osmo_fd_unregister(&esme->wqueue.bfd);
- close(esme->wqueue.bfd.fd);
- esme->wqueue.bfd.fd = -1;
+ osmo_fd_unregister(&esme->esme->wqueue.bfd);
+ close(esme->esme->wqueue.bfd.fd);
+ esme->esme->wqueue.bfd.fd = -1;
if (esme->acl)
esme->acl->esme = NULL;
smpp_esme_put(esme);
} else if (rc < msgb_length(msg)) {
- LOGP(DSMPP, LOGL_ERROR, "[%s] Short write\n", esme->system_id);
+ LOGPESME(esme->esme, LOGL_ERROR, "Short write\n");
return -1;
}
return 0;
}
+struct esme *esme_alloc(void *ctx)
+{
+ struct esme *e = talloc_zero(ctx, struct esme);
+ if (!e)
+ return NULL;
+
+ e->own_seq_nr = rand();
+ esme_inc_seq_nr(e);
+ osmo_wqueue_init(&e->wqueue, 10);
+
+ return e;
+}
+
/* callback for already-accepted new TCP socket */
static int link_accept_cb(struct smsc *smsc, int fd,
struct sockaddr_storage *s, socklen_t s_len)
{
- struct osmo_esme *esme = talloc_zero(smsc, struct osmo_esme);
+ struct smpp_esme *esme = talloc_zero(smsc, struct smpp_esme);
if (!esme) {
close(fd);
return -ENOMEM;
}
+ esme->esme = esme_alloc(esme);
+ if (!esme->esme) {
+ close(fd);
+ return -ENOMEM;
+ }
+
INIT_LLIST_HEAD(&esme->smpp_cmd_list);
smpp_esme_get(esme);
- esme->own_seq_nr = rand();
- esme_inc_seq_nr(esme);
esme->smsc = smsc;
- osmo_wqueue_init(&esme->wqueue, 10);
- esme->wqueue.bfd.fd = fd;
- esme->wqueue.bfd.data = esme;
- esme->wqueue.bfd.when = BSC_FD_READ;
+ osmo_fd_setup(&esme->esme->wqueue.bfd, fd, OSMO_FD_READ, osmo_wqueue_bfd_cb, esme, 0);
- if (osmo_fd_register(&esme->wqueue.bfd) != 0) {
+ if (osmo_fd_register(&esme->esme->wqueue.bfd) != 0) {
close(fd);
talloc_free(esme);
return -EIO;
}
- esme->wqueue.read_cb = esme_link_read_cb;
- esme->wqueue.write_cb = esme_link_write_cb;
-
- esme->sa_len = OSMO_MIN(sizeof(esme->sa), s_len);
- memcpy(&esme->sa, s, esme->sa_len);
+ esme->esme->wqueue.read_cb = esme_link_read_cb;
+ esme->esme->wqueue.write_cb = esme_link_write_cb;
llist_add_tail(&esme->list, &smsc->esme_list);
@@ -988,17 +963,21 @@ int smpp_smsc_conf(struct smsc *smsc, const char *bind_addr, uint16_t port)
/* Avoid use-after-free if bind_addr == smsc->bind_addr */
if (smsc->bind_addr == bind_addr)
return 0;
+ osmo_talloc_replace_string(smsc, &smsc->bind_addr, bind_addr);
- talloc_free((void*)smsc->bind_addr);
- smsc->bind_addr = NULL;
- if (bind_addr) {
- smsc->bind_addr = bind_addr ? talloc_strdup(smsc, bind_addr) : NULL;
- if (!smsc->bind_addr)
- return -ENOMEM;
- }
return 0;
}
+/*! /brief Close SMPP connection. */
+static void smpp_smsc_stop(struct smsc *smsc)
+{
+ if (smsc->listen_ofd.fd > 0) {
+ close(smsc->listen_ofd.fd);
+ smsc->listen_ofd.fd = 0;
+ osmo_fd_unregister(&smsc->listen_ofd);
+ }
+}
+
/*! \brief Bind to given address and port and accept connections.
* \param[in] bind_addr Local IP address, may be NULL for any.
* \param[in] port TCP port number, may be 0 for default SMPP (2775).
@@ -1007,23 +986,17 @@ int smpp_smsc_start(struct smsc *smsc, const char *bind_addr, uint16_t port)
{
int rc;
- /* default port for SMPP */
- if (!port)
- port = 2775;
-
- smpp_smsc_stop(smsc);
-
LOGP(DSMPP, LOGL_NOTICE, "SMPP at %s %d\n",
- bind_addr? bind_addr : "0.0.0.0", port);
+ bind_addr ? bind_addr : "0.0.0.0", port ? port : SMPP_PORT);
rc = osmo_sock_init_ofd(&smsc->listen_ofd, AF_UNSPEC, SOCK_STREAM,
- IPPROTO_TCP, bind_addr, port,
+ IPPROTO_TCP, bind_addr, port ? port : SMPP_PORT,
OSMO_SOCK_F_BIND);
if (rc < 0)
return rc;
/* store new address and port */
- rc = smpp_smsc_conf(smsc, bind_addr, port);
+ rc = smpp_smsc_conf(smsc, bind_addr, port ? port : SMPP_PORT);
if (rc)
smpp_smsc_stop(smsc);
return rc;
@@ -1035,19 +1008,11 @@ int smpp_smsc_restart(struct smsc *smsc, const char *bind_addr, uint16_t port)
{
int rc;
+ smpp_smsc_stop(smsc);
+
rc = smpp_smsc_start(smsc, bind_addr, port);
if (rc)
/* if there is an error, try to re-bind to the old port */
return smpp_smsc_start(smsc, smsc->bind_addr, smsc->listen_port);
return 0;
}
-
-/*! /brief Close SMPP connection. */
-void smpp_smsc_stop(struct smsc *smsc)
-{
- if (smsc->listen_ofd.fd > 0) {
- close(smsc->listen_ofd.fd);
- smsc->listen_ofd.fd = 0;
- osmo_fd_unregister(&smsc->listen_ofd);
- }
-}
diff --git a/src/libsmpputil/smpp_utils.c b/src/libsmpputil/smpp_utils.c
new file mode 100644
index 000000000..bada97217
--- /dev/null
+++ b/src/libsmpputil/smpp_utils.c
@@ -0,0 +1,174 @@
+
+/* (C) 2012-2022 by Harald Welte <laforge@gnumonks.org>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include <time.h>
+
+#include <osmocom/core/logging.h>
+#include <osmocom/netif/stream.h>
+#include <osmocom/smpp/smpp_smsc.h>
+
+/*! \brief retrieve SMPP command ID from a msgb */
+uint32_t smpp_msgb_cmdid(struct msgb *msg)
+{
+ uint8_t *tmp = msgb_data(msg) + 4;
+ return ntohl(*(uint32_t *)tmp);
+}
+
+int smpp_determine_scheme(uint8_t dcs, uint8_t *data_coding, int *mode)
+{
+ if ((dcs & 0xF0) == 0xF0) {
+ if (dcs & 0x04) {
+ /* bit 2 == 1: 8bit data */
+ *data_coding = 0x02;
+ *mode = MODE_8BIT;
+ } else {
+ /* bit 2 == 0: default alphabet */
+ *data_coding = 0x01;
+ *mode = MODE_7BIT;
+ }
+ } else if ((dcs & 0xE0) == 0) {
+ switch (dcs & 0xC) {
+ case 0:
+ *data_coding = 0x01;
+ *mode = MODE_7BIT;
+ break;
+ case 4:
+ *data_coding = 0x02;
+ *mode = MODE_8BIT;
+ break;
+ case 8:
+ *data_coding = 0x08; /* UCS-2 */
+ *mode = MODE_8BIT;
+ break;
+ default:
+ goto unknown_mo;
+ }
+ } else {
+unknown_mo:
+ LOGP(DLSMS, LOGL_ERROR, "SMPP MO Unknown Data Coding 0x%02x\n", dcs);
+ return -1;
+ }
+
+ return 0;
+
+}
+
+/* convert a 'struct tm' holding relative time to an absolute one by adding it to t_now */
+static void relative2absolute(struct tm *tm, time_t t_now)
+{
+ struct tm tm_now;
+
+ localtime_r(&t_now, &tm_now);
+
+ tm->tm_year += tm_now.tm_year;
+ tm->tm_mon += tm_now.tm_mon;
+ tm->tm_mday += tm_now.tm_mday;
+ tm->tm_hour += tm_now.tm_hour;
+ tm->tm_min += tm_now.tm_min;
+ tm->tm_sec += tm_now.tm_sec;
+}
+
+#ifndef HAVE_TIMEGM
+/* for systems without a timegm() function, provide a reimplementation */
+static time_t timegm(struct tm *tm)
+{
+ const char *orig_tz = getenv("TZ");
+ time_t ret;
+
+ setenv("TZ", "UTC", 1);
+
+ ret = mktime(tm);
+
+ if (orig_tz)
+ setenv("TZ", orig_tz, 1);
+ else
+ unsetenv("TZ");
+
+ return ret;
+}
+#endif
+
+
+/*! Parse a SMPP time format as defined in SMPP v3.4 7.1.1.
+ * \param[in] vp string containing the time as encoded in SMPP v3.4
+ * \param[in] t_now pointer to a time value for 'now'. Can be NULL, then we call time() ourselves.
+ * \returns time_t value in seconds since the epoch of the absolute decoded time */
+time_t smpp_parse_time_format(const char *vp, time_t *t_now)
+{
+ unsigned int year, month, day, hour, minute, second, tenth, gmt_off_quarter;
+ char plus_minus_relative;
+ int gmt_off_minutes;
+ struct tm tm;
+ time_t ret;
+ int rc;
+
+ memset(&tm, 0, sizeof(tm));
+
+ if (vp[0] == '\0')
+ return 0;
+
+ /* YYMMDDhhmmsstnnp (where p can be -, + or R) */
+ rc = sscanf(vp, "%2u%2u%2u%2u%2u%2u%1u%2u%c", &year, &month, &day, &hour, &minute,
+ &second, &tenth, &gmt_off_quarter, &plus_minus_relative);
+ if (rc != 9)
+ return (time_t) -1;
+
+ tm.tm_year = year;
+ /* month handling differs between absolute/relative below... */
+ tm.tm_mday = day;
+ tm.tm_hour = hour;
+ tm.tm_min = minute;
+ tm.tm_sec = second;
+ tm.tm_isdst = 0;
+
+ switch (plus_minus_relative) {
+ case '+': /* time is in quarter hours advanced compared to UTC */
+ if (year < 70)
+ tm.tm_year += 100;
+ tm.tm_mon = month - 1;
+ gmt_off_minutes = 15 * gmt_off_quarter;
+ tm.tm_min -= gmt_off_minutes;
+ ret = timegm(&tm);
+ break;
+ case '-': /* time is in quarter hours retared compared to UTC */
+ if (year < 70)
+ tm.tm_year += 100;
+ tm.tm_mon = month - 1;
+ gmt_off_minutes = 15 * gmt_off_quarter;
+ tm.tm_min += gmt_off_minutes;
+ ret = timegm(&tm);
+ break;
+ case 'R':
+ /* relative time */
+ tm.tm_mon = month;
+ if (t_now)
+ relative2absolute(&tm, *t_now);
+ else
+ relative2absolute(&tm, time(NULL));
+ /* here we do want local time, as we're passing local time in above! */
+ ret = mktime(&tm);
+ break;
+ default:
+ return (time_t) -1;
+ }
+
+ return ret;
+}
diff --git a/src/libmsc/smpp_vty.c b/src/libsmpputil/smpp_vty.c
index 9026f6cf5..c6e642161 100644
--- a/src/libmsc/smpp_vty.c
+++ b/src/libsmpputil/smpp_vty.c
@@ -30,11 +30,11 @@
#include <osmocom/core/linuxlist.h>
#include <osmocom/core/utils.h>
+#include <osmocom/core/socket.h>
#include <osmocom/core/talloc.h>
#include <osmocom/msc/vty.h>
-
-#include "smpp_smsc.h"
+#include <osmocom/smpp/smpp_smsc.h>
struct smsc *smsc_from_vty(struct vty *v);
@@ -80,8 +80,8 @@ static int smpp_local_tcp(struct vty *vty,
const char *bind_addr, uint16_t port)
{
struct smsc *smsc = smsc_from_vty(vty);
- int is_running = smsc->listen_ofd.fd > 0;
- int same_bind_addr;
+ bool is_running = smsc->listen_ofd.fd > 0;
+ bool same_bind_addr;
int rc;
/* If it is not up yet, don't rebind, just set values. */
@@ -501,7 +501,7 @@ DEFUN(cfg_esme_no_dcs_transp, cfg_esme_no_dcs_transp_cmd,
DEFUN(cfg_esme_alert_notif, cfg_esme_alert_notif_cmd,
"alert-notifications",
- "Disable sending of SMPP Alert Notifications for this ESME")
+ "Enable sending of SMPP Alert Notifications for this ESME")
{
struct osmo_smpp_acl *acl = vty->index;
@@ -522,19 +522,12 @@ DEFUN(cfg_esme_no_alert_notif, cfg_esme_no_alert_notif_cmd,
}
-static void dump_one_esme(struct vty *vty, struct osmo_esme *esme)
+static void dump_one_esme(struct vty *vty, struct smpp_esme *esme)
{
- char host[128], serv[128];
-
- host[0] = 0;
- serv[0] = 0;
- getnameinfo((const struct sockaddr *) &esme->sa, esme->sa_len,
- host, sizeof(host), serv, sizeof(serv), NI_NUMERICSERV);
-
vty_out(vty, "ESME System ID: %s, Password: %s, SMPP Version %02x%s",
- esme->system_id, esme->acl ? esme->acl->passwd : "",
+ esme->esme->system_id, esme->acl ? esme->acl->passwd : "",
esme->smpp_version, VTY_NEWLINE);
- vty_out(vty, " Connected from: %s:%s%s", host, serv, VTY_NEWLINE);
+ vty_out(vty, " Connection %s%s", osmo_sock_get_name(tall_vty_ctx, esme->esme->wqueue.bfd.fd), VTY_NEWLINE);
if (esme->smsc->def_route == esme->acl)
vty_out(vty, " Is current default route%s", VTY_NEWLINE);
}
@@ -544,7 +537,7 @@ DEFUN(show_esme, show_esme_cmd,
SHOW_STR "SMPP Interface\n" "SMPP External SMS Entity\n")
{
struct smsc *smsc = smsc_from_vty(vty);
- struct osmo_esme *esme;
+ struct smpp_esme *esme;
llist_for_each_entry(esme, &smsc->esme_list, list)
dump_one_esme(vty, esme);
diff --git a/src/libvlr/vlr.c b/src/libvlr/vlr.c
index b156b430b..cb5794f30 100644
--- a/src/libvlr/vlr.c
+++ b/src/libvlr/vlr.c
@@ -23,7 +23,9 @@
#include <osmocom/core/fsm.h>
#include <osmocom/core/utils.h>
#include <osmocom/core/timer.h>
+#include <osmocom/core/tdef.h>
#include <osmocom/gsm/protocol/gsm_04_08_gprs.h>
+#include <osmocom/gsm/gsm23236.h>
#include <osmocom/gsm/gsup.h>
#include <osmocom/gsm/apn.h>
#include <osmocom/gsm/gsm48.h>
@@ -34,6 +36,7 @@
#include <osmocom/msc/vlr.h>
#include <osmocom/msc/debug.h>
#include <osmocom/msc/gsup_client_mux.h>
+#include <osmocom/msc/paging.h>
#include <netinet/in.h>
#include <arpa/inet.h>
@@ -49,10 +52,139 @@
#define SGSN_SUBSCR_MAX_RETRIES 3
#define SGSN_SUBSCR_RETRY_INTERVAL 10
+enum vlr_stat_item_idx {
+ VLR_STAT_SUBSCRIBER_COUNT,
+ VLR_STAT_PDP_COUNT,
+};
+
+static const struct osmo_stat_item_desc vlr_stat_item_desc[] = {
+ [VLR_STAT_SUBSCRIBER_COUNT] = { "subscribers",
+ "Number of subscribers present in VLR" },
+ [VLR_STAT_PDP_COUNT] = { "pdp",
+ "Number of PDP records present in VLR" },
+};
+
+static const struct osmo_stat_item_group_desc vlr_statg_desc = {
+ "vlr",
+ "visitor location register",
+ OSMO_STATS_CLASS_GLOBAL,
+ ARRAY_SIZE(vlr_stat_item_desc),
+ vlr_stat_item_desc,
+};
+
+enum vlr_rate_ctr_idx {
+ VLR_CTR_GSUP_RX_UNKNOWN_IMSI,
+ VLR_CTR_GSUP_RX_PURGE_NO_SUBSCR,
+ VLR_CTR_GSUP_RX_TUPLES,
+ VLR_CTR_GSUP_RX_UL_RES,
+ VLR_CTR_GSUP_RX_UL_ERR,
+ VLR_CTR_GSUP_RX_SAI_RES,
+ VLR_CTR_GSUP_RX_SAI_ERR,
+ VLR_CTR_GSUP_RX_ISD_REQ,
+ VLR_CTR_GSUP_RX_CANCEL_REQ,
+ VLR_CTR_GSUP_RX_CHECK_IMEI_RES,
+ VLR_CTR_GSUP_RX_CHECK_IMEI_ERR,
+ VLR_CTR_GSUP_RX_PURGE_MS_RES,
+ VLR_CTR_GSUP_RX_PURGE_MS_ERR,
+ VLR_CTR_GSUP_RX_DELETE_DATA_REQ,
+ VLR_CTR_GSUP_RX_UNKNOWN,
+
+ VLR_CTR_GSUP_TX_UL_REQ,
+ VLR_CTR_GSUP_TX_ISD_RES,
+ VLR_CTR_GSUP_TX_SAI_REQ,
+ VLR_CTR_GSUP_TX_PURGE_MS_REQ,
+ VLR_CTR_GSUP_TX_CHECK_IMEI_REQ,
+ VLR_CTR_GSUP_TX_AUTH_FAIL_REP,
+ VLR_CTR_GSUP_TX_CANCEL_RES,
+
+ VLR_CTR_DETACH_BY_REQ,
+ VLR_CTR_DETACH_BY_CANCEL,
+ VLR_CTR_DETACH_BY_T3212,
+};
+
+static const struct rate_ctr_desc vlr_ctr_desc[] = {
+ [VLR_CTR_GSUP_RX_UNKNOWN_IMSI] = { "gsup:rx:unknown_imsi",
+ "Received GSUP messages for unknown IMSI" },
+ [VLR_CTR_GSUP_RX_PURGE_NO_SUBSCR] = { "gsup:rx:purge_no_subscr",
+ "Received GSUP purge for unknown subscriber" },
+ [VLR_CTR_GSUP_RX_TUPLES] = { "gsup:rx:auth_tuples",
+ "Received GSUP authentication tuples" },
+ [VLR_CTR_GSUP_RX_UL_RES] = { "gsup:rx:upd_loc:res",
+ "Received GSUP Update Location Result messages" },
+ [VLR_CTR_GSUP_RX_UL_ERR] = { "gsup:rx:upd_loc:err",
+ "Received GSUP Update Location Error messages" },
+ [VLR_CTR_GSUP_RX_SAI_RES] = { "gsup:rx:send_auth_info:res",
+ "Received GSUP Send Auth Info Result messages" },
+ [VLR_CTR_GSUP_RX_SAI_ERR] = { "gsup:rx:send_auth_info:err",
+ "Received GSUP Send Auth Info Error messages" },
+ [VLR_CTR_GSUP_RX_ISD_REQ] = { "gsup:rx:ins_sub_data:req",
+ "Received GSUP Insert Subscriber Data Request messages" },
+ [VLR_CTR_GSUP_RX_CANCEL_REQ] = { "gsup:rx:cancel:req",
+ "Received GSUP Cancel Subscriber messages" },
+ [VLR_CTR_GSUP_RX_CHECK_IMEI_RES] = { "gsup:rx:check_imei:res",
+ "Received GSUP Check IMEI Result messages" },
+ [VLR_CTR_GSUP_RX_CHECK_IMEI_ERR] = { "gsup:rx:check_imei:err",
+ "Received GSUP Check IMEI Error messages" },
+ [VLR_CTR_GSUP_RX_PURGE_MS_RES] = { "gsup:rx:purge_ms:res",
+ "Received GSUP Purge MS Result messages" },
+ [VLR_CTR_GSUP_RX_PURGE_MS_ERR] = { "gsup:rx:purge_ms:err",
+ "Received GSUP Purge MS Error messages" },
+ [VLR_CTR_GSUP_RX_DELETE_DATA_REQ] = { "gsup:rx:del_sub_data:req",
+ "Received GSUP Delete Subscriber Data Request messages" },
+ [VLR_CTR_GSUP_RX_UNKNOWN] = { "gsup:rx:unknown_msgtype",
+ "Received GSUP message of unknown type" },
+
+ [VLR_CTR_GSUP_TX_UL_REQ] = { "gsup:tx:upd_loc:req",
+ "Transmitted GSUP Update Location Request messages" },
+ [VLR_CTR_GSUP_TX_ISD_RES] = { "gsup:tx:ins_sub_data:res",
+ "Transmitted GSUP Insert Subscriber Data Result messages" },
+ [VLR_CTR_GSUP_TX_SAI_REQ] = { "gsup:tx:send_auth_info:res",
+ "Transmitted GSUP Send Auth Info Request messages" },
+ [VLR_CTR_GSUP_TX_PURGE_MS_REQ] = { "gsup:tx:purge_ms:req",
+ "Transmitted GSUP Purge MS Request messages" },
+ [VLR_CTR_GSUP_TX_CHECK_IMEI_REQ] = { "gsup:tx:check_imei:req",
+ "Transmitted GSUP Check IMEI Request messages" },
+ [VLR_CTR_GSUP_TX_AUTH_FAIL_REP] = { "gsup:tx:auth_fail:rep",
+ "Transmitted GSUP Auth Fail Report messages" },
+ [VLR_CTR_GSUP_TX_CANCEL_RES] = { "gsup:tx:cancel:res",
+ "Transmitted GSUP Cancel Result messages" },
+
+ [VLR_CTR_DETACH_BY_REQ] = { "detach:imsi_det_req",
+ "VLR Subscriber Detach by IMSI DETACH REQ" },
+ [VLR_CTR_DETACH_BY_CANCEL] = { "detach:gsup_cancel_req",
+ "VLR Subscriber Detach by GSUP CANCEL REQ" },
+ [VLR_CTR_DETACH_BY_T3212] = { "detach:t3212_timeout",
+ "VLR Subscriber Detach by T3212 timeout" },
+};
+
+static const struct rate_ctr_group_desc vlr_ctrg_desc = {
+ "vlr",
+ "visitor location register",
+ OSMO_STATS_CLASS_GLOBAL,
+ ARRAY_SIZE(vlr_ctr_desc),
+ vlr_ctr_desc,
+};
+
+
+#define vlr_rate_ctr_inc(vlr, idx) \
+ rate_ctr_inc(rate_ctr_group_get_ctr((vlr)->ctrg, idx))
+#define vlr_rate_ctr_add(vlr, idx, val) \
+ rate_ctr_add(rate_ctr_group_get_ctr((vlr)->ctrg, idx), val)
+
+#define vlr_stat_item_inc(vlr, idx) \
+ osmo_stat_item_inc(osmo_stat_item_group_get_item((vlr)->statg, idx), 1)
+#define vlr_stat_item_dec(vlr, idx) \
+ osmo_stat_item_dec(osmo_stat_item_group_get_item((vlr)->statg, idx), 1)
+#define vlr_stat_item_set(vlr, idx, val) \
+ osmo_stat_item_set(osmo_stat_item_group_get_item((vlr)->statg, idx), val)
+
+
/***********************************************************************
* Convenience functions
***********************************************************************/
+static int vlr_subscr_detach(struct vlr_subscr *vsub);
+
const struct value_string vlr_ciph_names[] = {
OSMO_VALUE_STRING(VLR_CIPH_NONE),
OSMO_VALUE_STRING(VLR_CIPH_A5_1),
@@ -61,24 +193,23 @@ const struct value_string vlr_ciph_names[] = {
{ 0, NULL }
};
+/* 3GPP TS 24.008, table 11.2 Mobility management timers (network-side) */
+struct osmo_tdef msc_tdefs_vlr[] = {
+ { .T = 3212, .default_val = 60, .unit = OSMO_TDEF_M, .desc = "Subscriber expiration timeout" },
+ { .T = 3250, .default_val = 12, .desc = "TMSI Reallocation procedure" },
+ { .T = 3260, .default_val = 12, .desc = "Authentication procedure" },
+ { .T = 3270, .default_val = 12, .desc = "Identification procedure" },
+ { /* terminator */ }
+};
+
+/* This is just a wrapper around the osmo_tdef API.
+ * TODO: we should start using osmo_tdef_fsm_inst_state_chg() */
uint32_t vlr_timer(struct vlr_instance *vlr, uint32_t timer)
{
- uint32_t tidx = 0xffffffff;
-
- switch (timer) {
- case 3270:
- tidx = VLR_T_3270;
- break;
- case 3260:
- tidx = VLR_T_3260;
- break;
- case 3250:
- tidx = VLR_T_3250;
- break;
- }
-
- OSMO_ASSERT(tidx < sizeof(vlr->cfg.timer));
- return vlr->cfg.timer[tidx];
+ /* NOTE: since we usually do not need more than one instance of the VLR,
+ * and since libosmocore's osmo_tdef API does not (yet) support dynamic
+ * configuration, we always use the global instance of msc_tdefs_vlr. */
+ return osmo_tdef_get(msc_tdefs_vlr, timer, OSMO_TDEF_S, 0);
}
/* return static buffer with printable name of VLR subscriber */
@@ -142,7 +273,8 @@ struct vlr_subscr *_vlr_subscr_find_by_imsi(struct vlr_instance *vlr,
llist_for_each_entry(vsub, &vlr->subscribers, list) {
if (vlr_subscr_matches_imsi(vsub, imsi)) {
- vlr_subscr_get_src(vsub, use, file, line);
+ if (use)
+ vlr_subscr_get_src(vsub, use, file, line);
return vsub;
}
}
@@ -187,6 +319,21 @@ struct vlr_subscr *_vlr_subscr_find_by_msisdn(struct vlr_instance *vlr,
return NULL;
}
+struct vlr_subscr *_vlr_subscr_find_by_mi(struct vlr_instance *vlr,
+ const struct osmo_mobile_identity *mi,
+ const char *use,
+ const char *file, int line)
+{
+ switch (mi->type) {
+ case GSM_MI_TYPE_IMSI:
+ return _vlr_subscr_find_by_imsi(vlr, mi->imsi, use, file, line);
+ case GSM_MI_TYPE_TMSI:
+ return _vlr_subscr_find_by_tmsi(vlr, mi->tmsi, use, file, line);
+ default:
+ return NULL;
+ }
+}
+
/* Transmit GSUP message for subscriber to HLR, using IMSI from subscriber */
static int vlr_subscr_tx_gsup_message(const struct vlr_subscr *vsub,
struct osmo_gsup_message *gsup_msg)
@@ -264,6 +411,7 @@ static struct vlr_subscr *_vlr_subscr_alloc(struct vlr_instance *vlr)
vlr_sgs_fsm_create(vsub);
llist_add_tail(&vsub->list, &vlr->subscribers);
+ vlr_stat_item_inc(vlr, VLR_STAT_SUBSCRIBER_COUNT);
return vsub;
}
@@ -274,6 +422,8 @@ int vlr_subscr_purge(struct vlr_subscr *vsub)
{
struct osmo_gsup_message gsup_msg = {0};
+ vlr_rate_ctr_inc(vsub->vlr, VLR_CTR_GSUP_TX_PURGE_MS_REQ);
+
gsup_msg.message_type = OSMO_GSUP_MSGT_PURGE_MS_REQUEST;
/* provide HLR number in case we know it */
@@ -302,6 +452,7 @@ void vlr_subscr_cancel_attach_fsm(struct vlr_subscr *vsub,
void vlr_subscr_free(struct vlr_subscr *vsub)
{
llist_del(&vsub->list);
+ vlr_stat_item_dec(vsub->vlr, VLR_STAT_SUBSCRIBER_COUNT);
DEBUGP(DVLR, "freeing VLR subscr %s (max total use count was %d)\n", vlr_subscr_name(vsub),
vsub->max_total_use_count);
@@ -329,6 +480,15 @@ int vlr_subscr_alloc_tmsi(struct vlr_subscr *vsub)
LOGP(DDB, LOGL_ERROR, "osmo_get_rand_id() failed: %s\n", strerror(-rc));
return rc;
}
+
+ if (!llist_empty(&vlr->cfg.nri_ranges->entries)) {
+ int16_t nri_v;
+ osmo_tmsi_nri_v_limit_by_ranges(&tmsi, vlr->cfg.nri_ranges, vlr->cfg.nri_bitlen);
+ osmo_tmsi_nri_v_get(&nri_v, tmsi, vlr->cfg.nri_bitlen);
+ LOGP(DVLR, LOGL_DEBUG, "New NRI from range [%s] = 0x%x --> TMSI 0x%08x\n",
+ osmo_nri_ranges_to_str_c(OTC_SELECT, vlr->cfg.nri_ranges), nri_v, tmsi);
+ }
+
/* throw the dice again, if the TSMI doesn't fit */
if (tmsi == GSM_RESERVED_TMSI)
continue;
@@ -336,11 +496,11 @@ int vlr_subscr_alloc_tmsi(struct vlr_subscr *vsub)
/* Section 2.4 of 23.003: MSC has two MSB 00/01/10, SGSN 11 */
if (vlr->cfg.is_ps) {
/* SGSN */
- tmsi |= 0xC000000;
+ tmsi |= GSM23003_TMSI_SGSN_MASK;
} else {
/* MSC */
- if ((tmsi & 0xC0000000) == 0xC0000000)
- tmsi &= ~0xC0000000;
+ if ((tmsi & GSM23003_TMSI_SGSN_MASK) == GSM23003_TMSI_SGSN_MASK)
+ tmsi &= ~GSM23003_TMSI_SGSN_MASK;
}
/* If this TMSI is already in use, try another one. */
@@ -360,7 +520,7 @@ int vlr_subscr_alloc_tmsi(struct vlr_subscr *vsub)
}
/* Find subscriber by IMSI, or create new subscriber if not found.
- * \param[in] vlr VLR instace.
+ * \param[in] vlr VLR instance.
* \param[in] imsi IMSI string.
* \param[out] created if non-NULL, returns whether a new entry was created. */
struct vlr_subscr *_vlr_subscr_find_or_create_by_imsi(struct vlr_instance *vlr,
@@ -390,7 +550,7 @@ struct vlr_subscr *_vlr_subscr_find_or_create_by_imsi(struct vlr_instance *vlr,
}
/* Find subscriber by TMSI, or create new subscriber if not found.
- * \param[in] vlr VLR instace.
+ * \param[in] vlr VLR instance.
* \param[in] tmsi TMSI.
* \param[out] created if non-NULL, returns whether a new entry was created. */
struct vlr_subscr *_vlr_subscr_find_or_create_by_tmsi(struct vlr_instance *vlr,
@@ -419,11 +579,63 @@ struct vlr_subscr *_vlr_subscr_find_or_create_by_tmsi(struct vlr_instance *vlr,
return vsub;
}
+static void dedup_vsub(struct vlr_subscr *exists, struct vlr_subscr *vsub)
+{
+ struct vlr_instance *vlr = exists->vlr;
+ int i;
+ int j;
+ LOGP(DVLR, LOGL_NOTICE,
+ "There is an existing subscriber for IMSI %s used by %s, replacing with new VLR subscr: %s used by %s\n",
+ exists->imsi, osmo_use_count_to_str_c(OTC_SELECT, &exists->use_count),
+ vlr_subscr_name(vsub),
+ osmo_use_count_to_str_c(OTC_SELECT, &vsub->use_count));
+
+ /* Take over some state from the previous vsub */
+ paging_request_join_vsub(vsub, exists);
+ if (!vsub->msisdn[0])
+ OSMO_STRLCPY_ARRAY(vsub->msisdn, exists->msisdn);
+ if (!vsub->name[0])
+ OSMO_STRLCPY_ARRAY(vsub->name, exists->name);
+ /* Copy valid auth tuples we may already have, to reduce the need to ask for new ones from the HLR */
+ for (i = 0; i < ARRAY_SIZE(exists->auth_tuples); i++) {
+ if (exists->auth_tuples[i].key_seq == VLR_KEY_SEQ_INVAL)
+ continue;
+ for (j = 0; j < ARRAY_SIZE(vsub->auth_tuples); j++) {
+ if (vsub->auth_tuples[j].key_seq != VLR_KEY_SEQ_INVAL)
+ continue;
+ vsub->auth_tuples[j] = exists->auth_tuples[i];
+ }
+ }
+
+ if (exists->msc_conn_ref)
+ LOGVSUBP(LOGL_ERROR, vsub,
+ "There is an existing VLR entry for this same subscriber with an active connection."
+ " That should not be possible. Discarding old subscriber entry %s.\n",
+ exists->imsi);
+
+ if (vlr->ops.subscr_inval)
+ vlr->ops.subscr_inval(exists->msc_conn_ref, exists);
+ vlr_subscr_free(exists);
+}
+
void vlr_subscr_set_imsi(struct vlr_subscr *vsub, const char *imsi)
{
+ struct vlr_subscr *exists;
if (!vsub)
return;
+ /* If the same IMSI is already set, nothing changes. */
+ if (!strcmp(vsub->imsi, imsi))
+ return;
+
+ /* We've just learned about this new IMSI, our primary key in the VLR. make sure to invalidate any prior VLR
+ * entries for this IMSI. */
+ exists = vlr_subscr_find_by_imsi(vsub->vlr, imsi, NULL);
+
+ if (exists)
+ dedup_vsub(exists, vsub);
+
+ /* Set the IMSI on the new subscriber, here. */
if (OSMO_STRLCPY_ARRAY(vsub->imsi, imsi) >= sizeof(vsub->imsi)) {
LOGP(DVLR, LOGL_NOTICE, "IMSI was truncated: full IMSI=%s, truncated IMSI=%s\n",
imsi, vsub->imsi);
@@ -466,6 +678,23 @@ void vlr_subscr_set_msisdn(struct vlr_subscr *vsub, const char *msisdn)
vsub->imsi, vsub->msisdn);
}
+void vlr_subscr_set_last_used_eutran_plmn_id(struct vlr_subscr *vsub,
+ const struct osmo_plmn_id *last_eutran_plmn)
+{
+ if (!vsub)
+ return;
+ if (last_eutran_plmn) {
+ vsub->sgs.last_eutran_plmn_present = true;
+ memcpy(&vsub->sgs.last_eutran_plmn, last_eutran_plmn, sizeof(*last_eutran_plmn));
+ } else {
+ vsub->sgs.last_eutran_plmn_present = false;
+ }
+ DEBUGP(DVLR, "set Last E-UTRAN PLMN ID on subscriber: %s\n",
+ vsub->sgs.last_eutran_plmn_present ?
+ osmo_plmn_name(&vsub->sgs.last_eutran_plmn) :
+ "(none)");
+}
+
bool vlr_subscr_matches_imsi(struct vlr_subscr *vsub, const char *imsi)
{
return vsub && imsi && vsub->imsi[0] && !strcmp(vsub->imsi, imsi);
@@ -499,14 +728,11 @@ int vlr_subscr_changed(struct vlr_subscr *vsub)
void vlr_subscr_enable_expire_lu(struct vlr_subscr *vsub)
{
- struct gsm_network *net = vsub->vlr->user_ctx; /* XXX move t3212 into struct vlr_instance? */
struct timespec now;
- /* The T3212 timeout value field is coded as the binary representation of the timeout
- * value for periodic updating in decihours. Mark the subscriber as inactive if it missed
- * two consecutive location updates. Timeout is twice the t3212 value plus one minute. */
+ /* Mark the subscriber as inactive if it stopped to do periodical location updates. */
if (osmo_clock_gettime(CLOCK_MONOTONIC, &now) == 0) {
- vsub->expire_lu = now.tv_sec + (net->t3212 * 60 * 6 * 2) + 60;
+ vsub->expire_lu = now.tv_sec + vlr_timer(vsub->vlr, 3212);
} else {
LOGP(DVLR, LOGL_ERROR,
"%s: Could not enable Location Update expiry: unable to read current time\n", vlr_subscr_name(vsub));
@@ -521,6 +747,11 @@ void vlr_subscr_expire_lu(void *data)
struct vlr_subscr *vsub, *vsub_tmp;
struct timespec now;
+ /* Periodic location update might be disabled from the VTY,
+ * so we shall not expire subscribers until explicit IMSI Detach. */
+ if (!vlr_timer(vlr, 3212))
+ goto done;
+
if (llist_empty(&vlr->subscribers))
goto done;
@@ -534,7 +765,8 @@ void vlr_subscr_expire_lu(void *data)
continue;
LOGP(DVLR, LOGL_DEBUG, "%s: Location Update expired\n", vlr_subscr_name(vsub));
- vlr_subscr_rx_imsi_detach(vsub);
+ vlr_rate_ctr_inc(vlr, VLR_CTR_DETACH_BY_T3212);
+ vlr_subscr_detach(vsub);
}
done:
@@ -550,13 +782,15 @@ done:
/* see GSM 09.02, 17.7.1, PDP-Context and GPRSSubscriptionData */
/* see GSM 09.02, B.1, gprsSubscriptionData */
struct sgsn_subscriber_pdp_data {
- struct llist_head list;
-
- unsigned int context_id;
- uint16_t pdp_type;
- char apn_str[GSM_APN_LENGTH];
- uint8_t qos_subscribed[20];
- size_t qos_subscribed_len;
+ struct llist_head list;
+
+ unsigned int context_id;
+ enum gsm48_pdp_type_org pdp_type_org;
+ enum gsm48_pdp_type_nr pdp_type_nr;
+ struct osmo_sockaddr pdp_address[2];
+ char apn_str[GSM_APN_LENGTH];
+ uint8_t qos_subscribed[20];
+ size_t qos_subscribed_len;
};
struct sgsn_subscriber_pdp_data *
@@ -567,6 +801,7 @@ vlr_subscr_pdp_data_alloc(struct vlr_subscr *vsub)
pdata = talloc_zero(vsub, struct sgsn_subscriber_pdp_data);
llist_add_tail(&pdata->list, &vsub->ps.pdp_list);
+ vlr_stat_item_inc(vsub->vlr, VLR_STAT_PDP_COUNT);
return pdata;
}
@@ -578,6 +813,7 @@ static int vlr_subscr_pdp_data_clear(struct vlr_subscr *vsub)
llist_for_each_entry_safe(pdp, pdp2, &vsub->ps.pdp_list, list) {
llist_del(&pdp->list);
+ vlr_stat_item_dec(vsub->vlr, VLR_STAT_PDP_COUNT);
talloc_free(pdp);
count += 1;
}
@@ -648,6 +884,8 @@ int vlr_subscr_req_lu(struct vlr_subscr *vsub)
struct osmo_gsup_message gsup_msg = {0};
int rc;
+ vlr_rate_ctr_inc(vsub->vlr, VLR_CTR_GSUP_TX_UL_REQ);
+
gsup_msg.message_type = OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST;
gsup_msg.cn_domain = vsub->vlr->cfg.is_ps ? OSMO_GSUP_CN_DOMAIN_PS : OSMO_GSUP_CN_DOMAIN_CS;
rc = vlr_subscr_tx_gsup_message(vsub, &gsup_msg);
@@ -661,9 +899,12 @@ int vlr_subscr_req_sai(struct vlr_subscr *vsub,
{
struct osmo_gsup_message gsup_msg = {0};
+ vlr_rate_ctr_inc(vsub->vlr, VLR_CTR_GSUP_TX_SAI_REQ);
+
gsup_msg.message_type = OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST;
gsup_msg.auts = auts;
gsup_msg.rand = auts_rand;
+ gsup_msg.cn_domain = OSMO_GSUP_CN_DOMAIN_CS;
return vlr_subscr_tx_gsup_message(vsub, &gsup_msg);
}
@@ -673,6 +914,7 @@ int vlr_subscr_tx_req_check_imei(const struct vlr_subscr *vsub)
{
struct osmo_gsup_message gsup_msg = {
.message_class = OSMO_GSUP_MESSAGE_CLASS_SUBSCRIBER_MANAGEMENT,
+ .message_type = OSMO_GSUP_MSGT_CHECK_IMEI_REQUEST,
};
uint8_t imei_enc[GSM23003_IMEI_NUM_DIGITS+2]; /* +2: IE header */
int len;
@@ -686,8 +928,9 @@ int vlr_subscr_tx_req_check_imei(const struct vlr_subscr *vsub)
gsup_msg.imei_enc = imei_enc;
gsup_msg.imei_enc_len = len;
+ vlr_rate_ctr_inc(vsub->vlr, VLR_CTR_GSUP_TX_CHECK_IMEI_REQ);
+
/* Send CHECK_IMEI_REQUEST */
- gsup_msg.message_type = OSMO_GSUP_MSGT_CHECK_IMEI_REQUEST;
OSMO_STRLCPY_ARRAY(gsup_msg.imsi, vsub->imsi);
return gsup_client_mux_tx(vsub->vlr->gcm, &gsup_msg);
}
@@ -697,9 +940,11 @@ int vlr_subscr_tx_auth_fail_rep(const struct vlr_subscr *vsub)
{
struct osmo_gsup_message gsup_msg = {
.message_class = OSMO_GSUP_MESSAGE_CLASS_SUBSCRIBER_MANAGEMENT,
+ .message_type = OSMO_GSUP_MSGT_AUTH_FAIL_REPORT,
};
- gsup_msg.message_type = OSMO_GSUP_MSGT_AUTH_FAIL_REPORT;
+ vlr_rate_ctr_inc(vsub->vlr, VLR_CTR_GSUP_TX_AUTH_FAIL_REP);
+
OSMO_STRLCPY_ARRAY(gsup_msg.imsi, vsub->imsi);
return gsup_client_mux_tx(vsub->vlr->gcm, &gsup_msg);
}
@@ -723,7 +968,7 @@ void vlr_subscr_update_tuples(struct vlr_subscr *vsub,
if (key_seq >= ARRAY_SIZE(vsub->auth_tuples)) {
LOGVSUBP(LOGL_NOTICE, vsub,
- "Skipping auth tuple wih invalid cksn %zu\n",
+ "Skipping auth tuple with invalid cksn %zu\n",
key_seq);
continue;
}
@@ -733,6 +978,7 @@ void vlr_subscr_update_tuples(struct vlr_subscr *vsub,
}
LOGVSUBP(LOGL_DEBUG, vsub, "Received %u auth tuples\n", got_tuples);
+ vlr_rate_ctr_add(vsub->vlr, VLR_CTR_GSUP_RX_TUPLES, got_tuples);
if (!got_tuples) {
/* FIXME what now? */
@@ -750,6 +996,12 @@ static int vlr_subscr_handle_sai_res(struct vlr_subscr *vsub,
struct osmo_fsm_inst *auth_fi = vsub->auth_fsm;
void *data = (void *) gsup;
+ if (!auth_fi) {
+ LOGVSUBP(LOGL_ERROR, vsub, "Received GSUP %s, but there is no auth_fsm\n",
+ osmo_gsup_message_type_name(gsup->message_type));
+ return -1;
+ }
+
switch (gsup->message_type) {
case OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT:
osmo_fsm_inst_dispatch(auth_fi, VLR_AUTH_E_HLR_SAI_ACK, data);
@@ -770,7 +1022,7 @@ static void vlr_subscr_gsup_insert_data(struct vlr_subscr *vsub,
unsigned idx;
int rc;
- if (gsup_msg->msisdn_enc) {//FIXME: vlr_subscr_set_msisdn()?
+ if (gsup_msg->msisdn_enc_len) {//FIXME: vlr_subscr_set_msisdn()?
gsm48_decode_bcd_number2(vsub->msisdn, sizeof(vsub->msisdn),
gsup_msg->msisdn_enc,
gsup_msg->msisdn_enc_len, 0);
@@ -828,7 +1080,10 @@ static void vlr_subscr_gsup_insert_data(struct vlr_subscr *vsub,
}
OSMO_ASSERT(pdp_data != NULL);
- pdp_data->pdp_type = pdp_info->pdp_type;
+ pdp_data->pdp_type_org = pdp_info->pdp_type_org;
+ pdp_data->pdp_type_nr = pdp_info->pdp_type_nr;
+ memcpy(&pdp_data->pdp_address[0], &pdp_info->pdp_address[0], sizeof(pdp_data->pdp_address[0]));
+ memcpy(&pdp_data->pdp_address[1], &pdp_info->pdp_address[1], sizeof(pdp_data->pdp_address[1]));
osmo_apn_to_str(pdp_data->apn_str,
pdp_info->apn_enc, pdp_info->apn_enc_len);
memcpy(pdp_data->qos_subscribed, pdp_info->qos_enc, pdp_info->qos_enc_len);
@@ -843,6 +1098,8 @@ static int vlr_subscr_handle_isd_req(struct vlr_subscr *vsub,
{
struct osmo_gsup_message gsup_reply = {0};
+ vlr_rate_ctr_inc(vsub->vlr, VLR_CTR_GSUP_TX_ISD_RES);
+
vlr_subscr_gsup_insert_data(vsub, gsup);
vsub->vlr->ops.subscr_update(vsub);
@@ -854,7 +1111,7 @@ static int vlr_subscr_handle_isd_req(struct vlr_subscr *vsub,
static int vlr_subscr_handle_lu_res(struct vlr_subscr *vsub,
const struct osmo_gsup_message *gsup)
{
- struct sgs_lu_response sgs_lu_response;
+ struct sgs_lu_response sgs_lu_response = {0};
bool sgs_lu_in_progress = false;
if (vsub->sgs_fsm->state == SGS_UE_ST_LA_UPD_PRES)
@@ -885,7 +1142,7 @@ static int vlr_subscr_handle_lu_res(struct vlr_subscr *vsub,
static int vlr_subscr_handle_lu_err(struct vlr_subscr *vsub,
const struct osmo_gsup_message *gsup)
{
- struct sgs_lu_response sgs_lu_response;
+ struct sgs_lu_response sgs_lu_response = {0};
bool sgs_lu_in_progress = false;
if (vsub->sgs_fsm->state == SGS_UE_ST_LA_UPD_PRES)
@@ -910,11 +1167,9 @@ static int vlr_subscr_handle_lu_err(struct vlr_subscr *vsub,
return 0;
}
-static void gmm_cause_to_fsm_and_mm_cause(enum gsm48_gmm_cause gmm_cause,
- enum osmo_fsm_term_cause *fsm_cause_p,
- enum gsm48_reject_value *gsm48_rej_p)
+void vlr_gmm_cause_to_mm_cause(enum gsm48_gmm_cause gmm_cause,
+ enum gsm48_reject_value *gsm48_rej_p)
{
- enum osmo_fsm_term_cause fsm_cause = OSMO_FSM_TERM_ERROR;
enum gsm48_reject_value gsm48_rej = GSM48_REJECT_NETWORK_FAILURE;
switch (gmm_cause) {
case GMM_CAUSE_IMSI_UNKNOWN:
@@ -997,16 +1252,8 @@ static void gmm_cause_to_fsm_and_mm_cause(enum gsm48_gmm_cause gmm_cause,
gsm48_rej = GSM48_REJECT_NETWORK_FAILURE;
break;
}
- switch (gmm_cause) {
- /* refine any error causes here? */
- default:
- fsm_cause = OSMO_FSM_TERM_ERROR;
- break;
- }
- if (fsm_cause_p)
- *fsm_cause_p = fsm_cause;
- if (gsm48_rej_p)
- *gsm48_rej_p = gsm48_rej;
+
+ *gsm48_rej_p = gsm48_rej;
}
/* Handle LOCATION CANCEL request from HLR */
@@ -1014,11 +1261,13 @@ static int vlr_subscr_handle_cancel_req(struct vlr_subscr *vsub,
const struct osmo_gsup_message *gsup_msg)
{
enum gsm48_reject_value gsm48_rej;
- enum osmo_fsm_term_cause fsm_cause;
+ enum osmo_fsm_term_cause fsm_cause = OSMO_FSM_TERM_ERROR;
struct osmo_gsup_message gsup_reply = {0};
int rc, is_update_procedure = !gsup_msg->cancel_type ||
gsup_msg->cancel_type == OSMO_GSUP_CANCEL_TYPE_UPDATE;
+ vlr_rate_ctr_inc(vsub->vlr, VLR_CTR_GSUP_TX_CANCEL_RES);
+
LOGVSUBP(LOGL_INFO, vsub, "Cancelling MS subscriber (%s)\n",
is_update_procedure ?
"update procedure" : "subscription withdraw");
@@ -1026,10 +1275,11 @@ static int vlr_subscr_handle_cancel_req(struct vlr_subscr *vsub,
gsup_reply.message_type = OSMO_GSUP_MSGT_LOCATION_CANCEL_RESULT;
rc = vlr_subscr_tx_gsup_message(vsub, &gsup_reply);
- gmm_cause_to_fsm_and_mm_cause(gsup_msg->cause, &fsm_cause, &gsm48_rej);
+ vlr_gmm_cause_to_mm_cause(gsup_msg->cause, &gsm48_rej);
vlr_subscr_cancel_attach_fsm(vsub, fsm_cause, gsm48_rej);
- vlr_subscr_rx_imsi_detach(vsub);
+ vlr_rate_ctr_inc(vsub->vlr, VLR_CTR_DETACH_BY_CANCEL);
+ vlr_subscr_detach(vsub);
return rc;
}
@@ -1065,49 +1315,65 @@ int vlr_gsup_rx(struct gsup_client_mux *gcm, void *data, const struct osmo_gsup_
{
struct vlr_instance *vlr = data;
struct vlr_subscr *vsub;
- int rc;
+ int rc = 0;
vsub = vlr_subscr_find_by_imsi(vlr, gsup->imsi, __func__);
if (!vsub) {
switch (gsup->message_type) {
case OSMO_GSUP_MSGT_PURGE_MS_RESULT:
case OSMO_GSUP_MSGT_PURGE_MS_ERROR:
+ vlr_rate_ctr_inc(vlr, VLR_CTR_GSUP_RX_PURGE_NO_SUBSCR);
return vlr_rx_gsup_purge_no_subscr(vlr, gsup);
default:
+ vlr_rate_ctr_inc(vlr, VLR_CTR_GSUP_RX_UNKNOWN_IMSI);
return vlr_rx_gsup_unknown_imsi(vlr, gsup);
}
}
switch (gsup->message_type) {
case OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT:
+ vlr_rate_ctr_inc(vlr, VLR_CTR_GSUP_RX_SAI_RES);
+ rc = vlr_subscr_handle_sai_res(vsub, gsup);
+ break;
case OSMO_GSUP_MSGT_SEND_AUTH_INFO_ERROR:
+ vlr_rate_ctr_inc(vlr, VLR_CTR_GSUP_RX_SAI_ERR);
rc = vlr_subscr_handle_sai_res(vsub, gsup);
break;
case OSMO_GSUP_MSGT_INSERT_DATA_REQUEST:
+ vlr_rate_ctr_inc(vlr, VLR_CTR_GSUP_RX_ISD_REQ);
rc = vlr_subscr_handle_isd_req(vsub, gsup);
break;
case OSMO_GSUP_MSGT_LOCATION_CANCEL_REQUEST:
+ vlr_rate_ctr_inc(vlr, VLR_CTR_GSUP_RX_CANCEL_REQ);
rc = vlr_subscr_handle_cancel_req(vsub, gsup);
break;
case OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT:
+ vlr_rate_ctr_inc(vlr, VLR_CTR_GSUP_RX_UL_RES);
rc = vlr_subscr_handle_lu_res(vsub, gsup);
break;
case OSMO_GSUP_MSGT_UPDATE_LOCATION_ERROR:
+ vlr_rate_ctr_inc(vlr, VLR_CTR_GSUP_RX_UL_ERR);
rc = vlr_subscr_handle_lu_err(vsub, gsup);
break;
case OSMO_GSUP_MSGT_PURGE_MS_ERROR:
+ vlr_rate_ctr_inc(vlr, VLR_CTR_GSUP_RX_PURGE_MS_ERR);
+ goto out_unimpl;
case OSMO_GSUP_MSGT_PURGE_MS_RESULT:
+ vlr_rate_ctr_inc(vlr, VLR_CTR_GSUP_RX_PURGE_MS_RES);
+ goto out_unimpl;
case OSMO_GSUP_MSGT_DELETE_DATA_REQUEST:
- LOGVSUBP(LOGL_ERROR, vsub,
- "Rx GSUP msg_type=%d not yet implemented\n",
- gsup->message_type);
- rc = -GMM_CAUSE_MSGT_NOTEXIST_NOTIMPL;
- break;
+ vlr_rate_ctr_inc(vlr, VLR_CTR_GSUP_RX_DELETE_DATA_REQ);
+ goto out_unimpl;
case OSMO_GSUP_MSGT_CHECK_IMEI_ERROR:
+ vlr_rate_ctr_inc(vlr, VLR_CTR_GSUP_RX_CHECK_IMEI_ERR);
+ rc = vlr_subscr_handle_check_imei(vsub, gsup);
+ break;
case OSMO_GSUP_MSGT_CHECK_IMEI_RESULT:
+ vlr_rate_ctr_inc(vlr, VLR_CTR_GSUP_RX_CHECK_IMEI_RES);
rc = vlr_subscr_handle_check_imei(vsub, gsup);
break;
default:
+ vlr_rate_ctr_inc(vlr, VLR_CTR_GSUP_RX_UNKNOWN);
LOGP(DLGSUP, LOGL_ERROR, "GSUP Message type not handled by VLR: %d\n", gsup->message_type);
rc = -EINVAL;
break;
@@ -1115,68 +1381,57 @@ int vlr_gsup_rx(struct gsup_client_mux *gcm, void *data, const struct osmo_gsup_
vlr_subscr_put(vsub, __func__);
return rc;
+
+out_unimpl:
+ LOGVSUBP(LOGL_ERROR, vsub, "Rx GSUP msg_type=%d not yet implemented\n", gsup->message_type);
+ vlr_subscr_put(vsub, __func__);
+ return -GMM_CAUSE_MSGT_NOTEXIST_NOTIMPL;
}
/* MSC->VLR: Subscriber has provided IDENTITY RESPONSE */
-int vlr_subscr_rx_id_resp(struct vlr_subscr *vsub,
- const uint8_t *mi, size_t mi_len)
+int vlr_subscr_rx_id_resp(struct vlr_subscr *vsub, const struct osmo_mobile_identity *mi)
{
- char mi_string[GSM48_MI_SIZE];
- uint8_t mi_type = mi[0] & GSM_MI_TYPE_MASK;
-
- gsm48_mi_to_string(mi_string, sizeof(mi_string), mi, mi_len);
-
/* update the vlr_subscr with the given identity */
- switch (mi_type) {
+ switch (mi->type) {
case GSM_MI_TYPE_IMSI:
- if (strlen(mi_string) >= sizeof(vsub->imsi)) {
- LOGVSUBP(LOGL_ERROR, vsub, "IMSI in ID RESP too long (>%zu bytes): %s\n",
- sizeof(vsub->imsi) - 1, mi_string);
- return -ENOSPC; /* ignore message; do not avance LU FSM */
- } else if (vsub->imsi[0]
- && !vlr_subscr_matches_imsi(vsub, mi_string)) {
+ if (vsub->imsi[0]
+ && !vlr_subscr_matches_imsi(vsub, mi->imsi)) {
LOGVSUBP(LOGL_ERROR, vsub, "IMSI in ID RESP differs:"
- " %s\n", mi_string);
+ " %s\n", mi->imsi);
/* XXX Should we return an error, e.g. -EINVAL ? */
} else
- vlr_subscr_set_imsi(vsub, mi_string);
+ vlr_subscr_set_imsi(vsub, mi->imsi);
break;
case GSM_MI_TYPE_IMEI:
- vlr_subscr_set_imei(vsub, mi_string);
+ vlr_subscr_set_imei(vsub, mi->imei);
break;
case GSM_MI_TYPE_IMEISV:
- vlr_subscr_set_imeisv(vsub, mi_string);
+ vlr_subscr_set_imeisv(vsub, mi->imeisv);
break;
+ default:
+ return -EINVAL;
}
if (vsub->auth_fsm) {
- switch (mi_type) {
+ switch (mi->type) {
case GSM_MI_TYPE_IMSI:
- osmo_fsm_inst_dispatch(vsub->auth_fsm,
- VLR_AUTH_E_MS_ID_IMSI, mi_string);
+ return osmo_fsm_inst_dispatch(vsub->auth_fsm,
+ VLR_AUTH_E_MS_ID_IMSI, (void*)mi->imsi);
break;
}
}
if (vsub->lu_fsm) {
- uint32_t event = 0;
- switch (mi_type) {
+ switch (mi->type) {
case GSM_MI_TYPE_IMSI:
- event = VLR_ULA_E_ID_IMSI;
- break;
+ return osmo_fsm_inst_dispatch(vsub->lu_fsm, VLR_ULA_E_ID_IMSI, (void*)mi->imsi);
case GSM_MI_TYPE_IMEI:
- event = VLR_ULA_E_ID_IMEI;
- break;
+ return osmo_fsm_inst_dispatch(vsub->lu_fsm, VLR_ULA_E_ID_IMEI, (void*)mi->imei);
case GSM_MI_TYPE_IMEISV:
- event = VLR_ULA_E_ID_IMEISV;
- break;
+ return osmo_fsm_inst_dispatch(vsub->lu_fsm, VLR_ULA_E_ID_IMEISV, (void*)mi->imeisv);
default:
- OSMO_ASSERT(0);
- break;
+ return -EINVAL;
}
- osmo_fsm_inst_dispatch(vsub->lu_fsm, event, mi_string);
- } else {
- LOGVSUBP(LOGL_NOTICE, vsub, "gratuitous ID RESPONSE?!?\n");
}
return 0;
@@ -1211,8 +1466,7 @@ bool vlr_subscr_expire(struct vlr_subscr *vsub)
return false;
}
-/* See TS 23.012 version 9.10.0 4.3.2.1 "Process Detach_IMSI_VLR" */
-int vlr_subscr_rx_imsi_detach(struct vlr_subscr *vsub)
+static int vlr_subscr_detach(struct vlr_subscr *vsub)
{
/* paranoia: should any LU or PARQ FSMs still be running, stop them. */
vlr_subscr_cancel_attach_fsm(vsub, OSMO_FSM_TERM_ERROR, GSM48_REJECT_CONGESTION);
@@ -1228,6 +1482,13 @@ int vlr_subscr_rx_imsi_detach(struct vlr_subscr *vsub)
return 0;
}
+/* See TS 23.012 version 9.10.0 4.3.2.1 "Process Detach_IMSI_VLR" */
+int vlr_subscr_rx_imsi_detach(struct vlr_subscr *vsub)
+{
+ vlr_rate_ctr_inc(vsub->vlr, VLR_CTR_DETACH_BY_REQ);
+ return vlr_subscr_detach(vsub);
+}
+
/* Tear down any running FSMs due to MSC connection timeout.
* Visit all vsub->*_fsm pointers and give them a queue to send a final reject
* message before the entire connection is torn down.
@@ -1263,6 +1524,19 @@ struct vlr_instance *vlr_alloc(void *ctx, const struct vlr_ops *ops)
/* defaults */
vlr->cfg.assign_tmsi = true;
+ vlr->cfg.nri_bitlen = OSMO_NRI_BITLEN_DEFAULT;
+ vlr->cfg.nri_ranges = osmo_nri_ranges_alloc(vlr);
+
+ vlr->statg = osmo_stat_item_group_alloc(vlr, &vlr_statg_desc, 0);
+ if (!vlr->statg)
+ goto err_free;
+
+ vlr->ctrg = rate_ctr_group_alloc(vlr, &vlr_ctrg_desc, 0);
+ if (!vlr->ctrg)
+ goto err_statg;
+
+ /* reset shared timer definitions */
+ osmo_tdefs_reset(msc_tdefs_vlr);
/* osmo_auth_fsm.c */
OSMO_ASSERT(osmo_fsm_register(&vlr_auth_fsm) == 0);
@@ -1274,6 +1548,12 @@ struct vlr_instance *vlr_alloc(void *ctx, const struct vlr_ops *ops)
vlr_sgs_fsm_init();
return vlr;
+
+err_statg:
+ osmo_stat_item_group_free(vlr->statg);
+err_free:
+ talloc_free(vlr);
+ return NULL;
}
int vlr_start(struct vlr_instance *vlr, struct gsup_client_mux *gcm)
@@ -1352,13 +1632,9 @@ void vlr_subscr_rx_ciph_res(struct vlr_subscr *vsub, enum vlr_ciph_result_cause
int vlr_set_ciph_mode(struct vlr_instance *vlr,
struct osmo_fsm_inst *fi,
void *msc_conn_ref,
- bool ciph_required,
bool umts_aka,
bool retrieve_imeisv)
{
- if (!ciph_required)
- return 0;
-
LOGPFSML(fi, LOGL_DEBUG, "Set Ciphering Mode\n");
return vlr->ops.set_ciph_mode(msc_conn_ref, umts_aka, retrieve_imeisv);
}
diff --git a/src/libvlr/vlr_access_req_fsm.c b/src/libvlr/vlr_access_req_fsm.c
index 7684d02f0..629625ea4 100644
--- a/src/libvlr/vlr_access_req_fsm.c
+++ b/src/libvlr/vlr_access_req_fsm.c
@@ -40,6 +40,8 @@ static const struct value_string proc_arq_vlr_event_names[] = {
OSMO_VALUE_STRING(PR_ARQ_E_START),
OSMO_VALUE_STRING(PR_ARQ_E_ID_IMSI),
OSMO_VALUE_STRING(PR_ARQ_E_AUTH_RES),
+ OSMO_VALUE_STRING(PR_ARQ_E_AUTH_NO_INFO),
+ OSMO_VALUE_STRING(PR_ARQ_E_AUTH_FAILURE),
OSMO_VALUE_STRING(PR_ARQ_E_CIPH_RES),
OSMO_VALUE_STRING(PR_ARQ_E_UPD_LOC_RES),
OSMO_VALUE_STRING(PR_ARQ_E_TRACE_RES),
@@ -67,7 +69,12 @@ struct proc_arq_priv {
uint32_t tmsi;
struct osmo_location_area_id lai;
bool authentication_required;
- bool ciphering_required;
+ /* is_ciphering_to_be_attempted: true when any A5/n > 0 are enabled. Ciphering is allowed, always attempt to get Auth Info from
+ * the HLR. */
+ bool is_ciphering_to_be_attempted;
+ /* is_ciphering_required: true when A5/0 is disabled. If we cannot get Auth Info from the HLR, reject the
+ * subscriber. */
+ bool is_ciphering_required;
uint8_t key_seq;
bool is_r99;
bool is_utran;
@@ -246,16 +253,13 @@ static void _proc_arq_vlr_node2_post_ciph(struct osmo_fsm_inst *fi)
{
struct proc_arq_priv *par = fi->priv;
struct vlr_subscr *vsub = par->vsub;
+ int rc;
LOGPFSM(fi, "%s()\n", __func__);
- if (par->is_utran) {
- int rc;
- rc = par->vlr->ops.tx_common_id(par->msc_conn_ref);
- if (rc)
- LOGPFSML(fi, LOGL_ERROR,
- "Error while sending Common ID (%d)\n", rc);
- }
+ rc = par->vlr->ops.tx_common_id(par->msc_conn_ref);
+ if (rc)
+ LOGPFSML(fi, LOGL_ERROR, "Error while sending Common ID (%d)\n", rc);
vsub->conf_by_radio_contact_ind = true;
if (vsub->loc_conf_in_hlr_ind == false) {
@@ -270,9 +274,12 @@ static void _proc_arq_vlr_node2_post_ciph(struct osmo_fsm_inst *fi)
_proc_arq_vlr_node2_post_vlr(fi);
}
-static bool is_ciph_required(struct proc_arq_priv *par)
+/* Return true when CipherModeCmd / SecurityModeCmd should be attempted. */
+static bool is_cmc_smc_to_be_attempted(struct proc_arq_priv *par)
{
- return par->ciphering_required;
+ /* UTRAN: always send SecModeCmd, even if ciphering is not required.
+ * GERAN: avoid sending CiphModeCmd if ciphering is not required. */
+ return par->is_utran || par->is_ciphering_to_be_attempted;
}
static void _proc_arq_vlr_node2(struct osmo_fsm_inst *fi)
@@ -283,7 +290,10 @@ static void _proc_arq_vlr_node2(struct osmo_fsm_inst *fi)
LOGPFSM(fi, "%s()\n", __func__);
- if (!is_ciph_required(par)) {
+ /* Continue with ciphering, if enabled.
+ * If auth/ciph is optional and the HLR returned no auth info, continue without ciphering. */
+ if (!is_cmc_smc_to_be_attempted(par)
+ || (vsub->sec_ctx == VLR_SEC_CTX_NONE && !par->is_ciphering_required)) {
_proc_arq_vlr_node2_post_ciph(fi);
return;
}
@@ -302,7 +312,6 @@ static void _proc_arq_vlr_node2(struct osmo_fsm_inst *fi)
}
if (vlr_set_ciph_mode(vsub->vlr, fi, par->msc_conn_ref,
- par->ciphering_required,
umts_aka,
vsub->vlr->cfg.retrieve_imeisv_ciphered)) {
LOGPFSML(fi, LOGL_ERROR,
@@ -315,13 +324,13 @@ static void _proc_arq_vlr_node2(struct osmo_fsm_inst *fi)
osmo_fsm_inst_state_chg(fi, PR_ARQ_S_WAIT_CIPH, 0, 0);
}
-static bool is_auth_required(struct proc_arq_priv *par)
+static bool is_auth_to_be_attempted(struct proc_arq_priv *par)
{
/* The cases where the authentication procedure should be used
* are defined in 3GPP TS 33.102 */
/* For now we use a default value passed in to vlr_lu_fsm(). */
return par->authentication_required ||
- (par->ciphering_required && !auth_try_reuse_tuple(par->vsub, par->key_seq));
+ (par->is_ciphering_to_be_attempted && !auth_try_reuse_tuple(par->vsub, par->key_seq));
}
/* after the IMSI is known */
@@ -335,11 +344,13 @@ static void proc_arq_vlr_fn_post_imsi(struct osmo_fsm_inst *fi)
OSMO_ASSERT(vsub);
/* TODO: Identity IMEI -> System Failure */
- if (is_auth_required(par)) {
+ if (is_auth_to_be_attempted(par)) {
osmo_fsm_inst_state_chg(fi, PR_ARQ_S_WAIT_AUTH,
0, 0);
- vsub->auth_fsm = auth_fsm_start(vsub, fi->log_level, fi,
+ vsub->auth_fsm = auth_fsm_start(vsub, fi,
PR_ARQ_E_AUTH_RES,
+ PR_ARQ_E_AUTH_NO_INFO,
+ PR_ARQ_E_AUTH_FAILURE,
par->is_r99,
par->is_utran);
} else {
@@ -432,17 +443,34 @@ static void proc_arq_vlr_fn_w_obt_imsi(struct osmo_fsm_inst *fi,
static void proc_arq_vlr_fn_w_auth(struct osmo_fsm_inst *fi,
uint32_t event, void *data)
{
+ struct proc_arq_priv *par = fi->priv;
enum gsm48_reject_value *cause = data;
- OSMO_ASSERT(event == PR_ARQ_E_AUTH_RES);
+ switch (event) {
+ case PR_ARQ_E_AUTH_RES:
+ /* Node 2 */
+ _proc_arq_vlr_node2(fi);
+ return;
- if (!cause || *cause) {
- proc_arq_fsm_done(fi, cause? *cause : GSM48_REJECT_NETWORK_FAILURE);
+ case PR_ARQ_E_AUTH_FAILURE:
+ proc_arq_fsm_done(fi, cause ? *cause : GSM48_REJECT_NETWORK_FAILURE);
return;
- }
- /* Node 2 */
- _proc_arq_vlr_node2(fi);
+ case PR_ARQ_E_AUTH_NO_INFO:
+ /* HLR returned no auth info for the subscriber. Continue only if authentication is optional. */
+ if (par->authentication_required) {
+ proc_arq_fsm_done(fi, cause ? *cause : GSM48_REJECT_NETWORK_FAILURE);
+ return;
+ }
+ LOGPFSML(fi, LOGL_INFO,
+ "Attaching subscriber without auth (auth is optional, and no auth info received from HLR)\n");
+ /* Node 2 */
+ _proc_arq_vlr_node2(fi);
+ return;
+
+ default:
+ OSMO_ASSERT(false);
+ }
}
static void proc_arq_vlr_fn_w_ciph(struct osmo_fsm_inst *fi,
@@ -547,7 +575,9 @@ static const struct osmo_fsm_state proc_arq_vlr_states[] = {
},
[PR_ARQ_S_WAIT_AUTH] = {
.name = OSMO_STRINGIFY(PR_ARQ_S_WAIT_AUTH),
- .in_event_mask = S(PR_ARQ_E_AUTH_RES),
+ .in_event_mask = S(PR_ARQ_E_AUTH_RES) |
+ S(PR_ARQ_E_AUTH_NO_INFO) |
+ S(PR_ARQ_E_AUTH_FAILURE),
.out_state_mask = S(PR_ARQ_S_DONE) |
S(PR_ARQ_S_WAIT_CIPH) |
S(PR_ARQ_S_WAIT_UPD_LOC_CHILD) |
@@ -632,17 +662,19 @@ vlr_proc_acc_req(struct osmo_fsm_inst *parent,
void *parent_event_data,
struct vlr_instance *vlr, void *msc_conn_ref,
enum vlr_parq_type type, enum osmo_cm_service_type cm_service_type,
- const uint8_t *mi_lv,
+ const struct osmo_mobile_identity *mi,
const struct osmo_location_area_id *lai,
bool authentication_required,
- bool ciphering_required,
+ bool is_ciphering_to_be_attempted,
+ bool is_ciphering_required,
uint8_t key_seq,
bool is_r99, bool is_utran)
{
struct osmo_fsm_inst *fi;
struct proc_arq_priv *par;
- char mi_string[GSM48_MI_SIZE];
- uint8_t mi_type;
+
+ if (is_ciphering_required)
+ OSMO_ASSERT(is_ciphering_to_be_attempted);
fi = osmo_fsm_inst_alloc_child(&proc_arq_vlr_fsm, parent,
parent_event_failure);
@@ -660,7 +692,8 @@ vlr_proc_acc_req(struct osmo_fsm_inst *parent,
par->parent_event_failure = parent_event_failure;
par->parent_event_data = parent_event_data;
par->authentication_required = authentication_required;
- par->ciphering_required = ciphering_required;
+ par->is_ciphering_to_be_attempted = is_ciphering_to_be_attempted;
+ par->is_ciphering_required = is_ciphering_required;
par->key_seq = key_seq;
par->is_r99 = is_r99;
par->is_utran = is_utran;
@@ -668,26 +701,24 @@ vlr_proc_acc_req(struct osmo_fsm_inst *parent,
LOGPFSM(fi, "rev=%s net=%s%s%s\n",
is_r99 ? "R99" : "GSM",
is_utran ? "UTRAN" : "GERAN",
- (authentication_required || ciphering_required)?
+ (authentication_required || is_ciphering_to_be_attempted) ?
" Auth" : " (no Auth)",
- (authentication_required || ciphering_required)?
- (ciphering_required? "+Ciph" : " (no Ciph)")
+ (authentication_required || is_ciphering_to_be_attempted) ?
+ (is_ciphering_to_be_attempted ? "+Ciph" : " (no Ciph)")
: "");
if (is_utran && !authentication_required)
LOGPFSML(fi, LOGL_ERROR,
"Authentication off on UTRAN network. Good luck.\n");
- gsm48_mi_to_string(mi_string, sizeof(mi_string), mi_lv+1, mi_lv[0]);
- mi_type = mi_lv[1] & GSM_MI_TYPE_MASK;
- switch (mi_type) {
+ switch (mi->type) {
case GSM_MI_TYPE_IMSI:
- osmo_strlcpy(par->imsi, mi_string, sizeof(par->imsi));
+ OSMO_STRLCPY_ARRAY(par->imsi, mi->imsi);
par->by_tmsi = false;
break;
case GSM_MI_TYPE_TMSI:
par->by_tmsi = true;
- par->tmsi = osmo_load32be(mi_lv+2);
+ par->tmsi = mi->tmsi;
break;
case GSM_MI_TYPE_IMEI:
/* TODO: IMEI (emergency call) */
diff --git a/src/libvlr/vlr_auth_fsm.c b/src/libvlr/vlr_auth_fsm.c
index 60265104d..b5052b072 100644
--- a/src/libvlr/vlr_auth_fsm.c
+++ b/src/libvlr/vlr_auth_fsm.c
@@ -1,4 +1,4 @@
-/* Osmocom Visitor Location Register (VLR) Autentication FSM */
+/* Osmocom Visitor Location Register (VLR) Authentication FSM */
/* (C) 2016 by Harald Welte <laforge@gnumonks.org>
*
@@ -51,6 +51,10 @@ struct auth_fsm_priv {
bool auth_requested;
int auth_tuple_max_reuse_count; /* see vlr->cfg instead */
+
+ uint32_t parent_event_success;
+ uint32_t parent_event_no_auth_info;
+ uint32_t parent_event_failure;
};
/***********************************************************************
@@ -230,27 +234,50 @@ static void auth_fsm_onenter_failed(struct osmo_fsm_inst *fi, uint32_t prev_stat
}
}
-static const char *vlr_auth_fsm_result_name(enum gsm48_reject_value result)
-{
- if (!result)
- return "PASSED";
- return get_value_string(gsm48_gmm_cause_names, result);
-}
+enum auth_fsm_result {
+ /* Authentication verified the subscriber. */
+ AUTH_FSM_PASSED = 0,
+ /* HLR does not have authentication info for this subscriber. */
+ AUTH_FSM_NO_AUTH_INFO,
+ /* Authentication was attempted but failed. */
+ AUTH_FSM_FAILURE,
+};
+
+const char *auth_fsm_result_str[] = {
+ [AUTH_FSM_PASSED] = "PASSED",
+ [AUTH_FSM_NO_AUTH_INFO] = "NO_AUTH_INFO",
+ [AUTH_FSM_FAILURE] = "FAILURE",
+};
/* Terminate the Auth FSM Instance and notify parent */
-static void auth_fsm_term(struct osmo_fsm_inst *fi, enum gsm48_reject_value result)
+static void auth_fsm_term(struct osmo_fsm_inst *fi, enum auth_fsm_result result, enum gsm48_reject_value cause)
{
- LOGPFSM(fi, "Authentication terminating with result %s\n",
- vlr_auth_fsm_result_name(result));
+ struct auth_fsm_priv *afp = fi->priv;
+
+ LOGPFSM(fi, "Authentication terminating with result %s%s%s\n",
+ auth_fsm_result_str[result],
+ cause ? ", cause " : "",
+ cause ? gsm48_reject_value_name(cause) : "");
- /* Do one final state transition (mostly for logging purpose) */
- if (!result)
+ /* Do one final state transition (mostly for logging purpose)
+ * and set the parent_term_event according to result */
+ switch (result) {
+ case AUTH_FSM_PASSED:
osmo_fsm_inst_state_chg(fi, VLR_SUB_AS_AUTHENTICATED, 0, 0);
- else
+ fi->proc.parent_term_event = afp->parent_event_success;
+ break;
+ case AUTH_FSM_NO_AUTH_INFO:
+ osmo_fsm_inst_state_chg(fi, VLR_SUB_AS_AUTH_FAILED, 0, 0);
+ fi->proc.parent_term_event = afp->parent_event_no_auth_info;
+ break;
+ case AUTH_FSM_FAILURE:
osmo_fsm_inst_state_chg(fi, VLR_SUB_AS_AUTH_FAILED, 0, 0);
+ fi->proc.parent_term_event = afp->parent_event_failure;
+ break;
+ }
/* return the result to the parent FSM */
- osmo_fsm_inst_term(fi, OSMO_FSM_TERM_REGULAR, &result);
+ osmo_fsm_inst_term(fi, OSMO_FSM_TERM_REGULAR, &cause);
}
static void auth_fsm_cleanup(struct osmo_fsm_inst *fi, enum osmo_fsm_term_cause cause)
@@ -275,7 +302,7 @@ static int _vlr_subscr_authenticate(struct osmo_fsm_inst *fi)
LOGPFSML(fi, LOGL_ERROR, "A previous check ensured that an"
" auth tuple was available, but now there is in fact"
" none.\n");
- auth_fsm_term(fi, GSM48_REJECT_NETWORK_FAILURE);
+ auth_fsm_term(fi, AUTH_FSM_FAILURE, GSM48_REJECT_NETWORK_FAILURE);
return -1;
}
@@ -331,6 +358,7 @@ static void auth_fsm_wait_ai(struct osmo_fsm_inst *fi, uint32_t event,
struct auth_fsm_priv *afp = fi->priv;
struct vlr_subscr *vsub = afp->vsub;
struct osmo_gsup_message *gsup = data;
+ enum gsm48_reject_value gsm48_rej;
if (event == VLR_AUTH_E_HLR_SAI_NACK)
LOGPFSM(fi, "GSUP: rx Auth Info Error cause: %d: %s\n",
@@ -350,21 +378,25 @@ static void auth_fsm_wait_ai(struct osmo_fsm_inst *fi, uint32_t event,
afp->auth_tuple_max_reuse_count = -1;
goto pass;
}
- /* result = procedure error */
- auth_fsm_term(fi, GSM48_REJECT_NETWORK_FAILURE);
- return;
}
switch (event) {
case VLR_AUTH_E_HLR_SAI_ACK:
+ if (!gsup->num_auth_vectors) {
+ auth_fsm_term(fi, AUTH_FSM_FAILURE, GSM48_REJECT_NETWORK_FAILURE);
+ return;
+ }
vlr_subscr_update_tuples(vsub, gsup);
goto pass;
- break;
case VLR_AUTH_E_HLR_SAI_NACK:
- auth_fsm_term(fi,
- gsup->cause == GMM_CAUSE_IMSI_UNKNOWN?
- GSM48_REJECT_IMSI_UNKNOWN_IN_HLR
- : GSM48_REJECT_NETWORK_FAILURE);
+ /* HLR did not return Auth Info, hence cannot authenticate. (The caller may still decide to permit
+ * attaching without authentication) */
+ vlr_gmm_cause_to_mm_cause(gsup->cause, &gsm48_rej);
+ auth_fsm_term(fi, AUTH_FSM_NO_AUTH_INFO, gsm48_rej);
+ break;
+ case VLR_AUTH_E_HLR_SAI_ABORT:
+ vlr_gmm_cause_to_mm_cause(gsup->cause, &gsm48_rej);
+ auth_fsm_term(fi, AUTH_FSM_FAILURE, gsm48_rej);
break;
}
@@ -397,10 +429,10 @@ static void auth_fsm_wait_auth_resp(struct osmo_fsm_inst *fi, uint32_t event,
VLR_SUB_AS_WAIT_ID_IMSI,
vlr_timer(vlr, 3270), 3270);
} else {
- auth_fsm_term(fi, GSM48_REJECT_ILLEGAL_MS);
+ auth_fsm_term(fi, AUTH_FSM_FAILURE, GSM48_REJECT_ILLEGAL_MS);
}
} else {
- auth_fsm_term(fi, 0);
+ auth_fsm_term(fi, AUTH_FSM_PASSED, 0);
}
break;
case VLR_AUTH_E_MS_AUTH_FAIL:
@@ -412,7 +444,7 @@ static void auth_fsm_wait_auth_resp(struct osmo_fsm_inst *fi, uint32_t event,
VLR_SUB_AS_NEEDS_AUTH_WAIT_SAI_RESYNC,
GSM_29002_TIMER_M, 0);
} else
- auth_fsm_term(fi, GSM48_REJECT_ILLEGAL_MS);
+ auth_fsm_term(fi, AUTH_FSM_FAILURE, GSM48_REJECT_ILLEGAL_MS);
break;
}
}
@@ -432,26 +464,23 @@ static void auth_fsm_wait_ai_resync(struct osmo_fsm_inst *fi,
gsup->cause != GMM_CAUSE_IMSI_UNKNOWN) ||
(event == VLR_AUTH_E_HLR_SAI_ABORT)) {
/* result = procedure error */
- auth_fsm_term(fi, GSM48_REJECT_NETWORK_FAILURE);
+ auth_fsm_term(fi, AUTH_FSM_FAILURE, GSM48_REJECT_NETWORK_FAILURE);
}
switch (event) {
case VLR_AUTH_E_HLR_SAI_ACK:
vlr_subscr_update_tuples(vsub, gsup);
- goto pass;
+ osmo_fsm_inst_state_chg(fi, VLR_SUB_AS_WAIT_RESP_RESYNC,
+ vlr_timer(vsub->vlr, 3260), 3260);
+ _vlr_subscr_authenticate(fi);
break;
case VLR_AUTH_E_HLR_SAI_NACK:
auth_fsm_term(fi,
+ AUTH_FSM_FAILURE,
gsup->cause == GMM_CAUSE_IMSI_UNKNOWN?
GSM48_REJECT_IMSI_UNKNOWN_IN_HLR
: GSM48_REJECT_NETWORK_FAILURE);
break;
}
-
- return;
-pass:
- osmo_fsm_inst_state_chg(fi, VLR_SUB_AS_WAIT_RESP_RESYNC,
- vlr_timer(vsub->vlr, 3260), 3260);
- _vlr_subscr_authenticate(fi);
}
/* Waiting for AUTH RESP from MS (re-sync case) */
@@ -477,16 +506,16 @@ static void auth_fsm_wait_auth_resp_resync(struct osmo_fsm_inst *fi,
vlr_timer(vlr, 3270), 3270);
} else {
/* Result = Aborted */
- auth_fsm_term(fi, GSM48_REJECT_SYNCH_FAILURE);
+ auth_fsm_term(fi, AUTH_FSM_FAILURE, GSM48_REJECT_SYNCH_FAILURE);
}
} else {
/* Result = Pass */
- auth_fsm_term(fi, 0);
+ auth_fsm_term(fi, AUTH_FSM_PASSED, 0);
}
break;
case VLR_AUTH_E_MS_AUTH_FAIL:
/* Second failure: Result = Fail */
- auth_fsm_term(fi, GSM48_REJECT_SYNCH_FAILURE);
+ auth_fsm_term(fi, AUTH_FSM_FAILURE, GSM48_REJECT_SYNCH_FAILURE);
break;
}
}
@@ -595,25 +624,25 @@ struct osmo_fsm vlr_auth_fsm = {
/* MSC->VLR: Start Procedure Authenticate_VLR (TS 23.012 Ch. 4.1.2.2) */
struct osmo_fsm_inst *auth_fsm_start(struct vlr_subscr *vsub,
- uint32_t log_level,
struct osmo_fsm_inst *parent,
- uint32_t parent_term_event,
+ uint32_t parent_event_success,
+ uint32_t parent_event_no_auth_info,
+ uint32_t parent_event_failure,
bool is_r99,
bool is_utran)
{
struct osmo_fsm_inst *fi;
struct auth_fsm_priv *afp;
- fi = osmo_fsm_inst_alloc_child(&vlr_auth_fsm, parent,
- parent_term_event);
+ fi = osmo_fsm_inst_alloc_child(&vlr_auth_fsm, parent, parent_event_failure);
if (!fi) {
- osmo_fsm_inst_dispatch(parent, parent_term_event, 0);
+ osmo_fsm_inst_dispatch(parent, parent_event_failure, 0);
return NULL;
}
afp = talloc_zero(fi, struct auth_fsm_priv);
if (!afp) {
- osmo_fsm_inst_dispatch(parent, parent_term_event, 0);
+ osmo_fsm_inst_dispatch(parent, parent_event_failure, 0);
return NULL;
}
@@ -622,6 +651,9 @@ struct osmo_fsm_inst *auth_fsm_start(struct vlr_subscr *vsub,
afp->by_imsi = true;
afp->is_r99 = is_r99;
afp->is_utran = is_utran;
+ afp->parent_event_success = parent_event_success;
+ afp->parent_event_no_auth_info = parent_event_no_auth_info;
+ afp->parent_event_failure = parent_event_failure;
fi->priv = afp;
vsub->auth_fsm = fi;
diff --git a/src/libvlr/vlr_auth_fsm.h b/src/libvlr/vlr_auth_fsm.h
index 1f2cb4969..828384206 100644
--- a/src/libvlr/vlr_auth_fsm.h
+++ b/src/libvlr/vlr_auth_fsm.h
@@ -27,12 +27,13 @@ enum vlr_fsm_auth_event {
VLR_AUTH_E_MS_ID_IMSI,
};
-struct osmo_fsm vlr_auth_fsm;
+extern struct osmo_fsm vlr_auth_fsm;
struct osmo_fsm_inst *auth_fsm_start(struct vlr_subscr *vsub,
- uint32_t log_level,
struct osmo_fsm_inst *parent,
- uint32_t parent_term_event,
+ uint32_t parent_event_success,
+ uint32_t parent_event_no_auth_info,
+ uint32_t parent_event_failure,
bool is_r99,
bool is_utran);
diff --git a/src/libvlr/vlr_lu_fsm.c b/src/libvlr/vlr_lu_fsm.c
index 9dff4aa2d..5d8f78bc2 100644
--- a/src/libvlr/vlr_lu_fsm.c
+++ b/src/libvlr/vlr_lu_fsm.c
@@ -366,13 +366,6 @@ static void vlr_lu_compl_fsm_success(struct osmo_fsm_inst *fi)
vlr_sgs_fsm_update_id(vsub);
}
-static void vlr_lu_compl_fsm_failure(struct osmo_fsm_inst *fi, uint8_t cause)
-{
- struct lu_compl_vlr_priv *lcvp = lu_compl_vlr_fi_priv(fi);
- lcvp->vsub->vlr->ops.tx_lu_rej(lcvp->msc_conn_ref, cause);
- _vlr_lu_compl_fsm_done(fi, VLR_FSM_RESULT_FAILURE, cause);
-}
-
static void vlr_lu_compl_fsm_dispatch_result(struct osmo_fsm_inst *fi,
uint32_t prev_state)
{
@@ -434,8 +427,7 @@ static void lu_compl_vlr_new_tmsi(struct osmo_fsm_inst *fi)
LOGPFSM(fi, "%s()\n", __func__);
if (vlr_subscr_alloc_tmsi(vsub)) {
- vlr_lu_compl_fsm_failure(fi,
- GSM48_REJECT_SRV_OPT_TMP_OUT_OF_ORDER);
+ _vlr_lu_compl_fsm_done(fi, VLR_FSM_RESULT_FAILURE, GSM48_REJECT_SRV_OPT_TMP_OUT_OF_ORDER);
return;
}
@@ -477,6 +469,8 @@ static void lu_compl_vlr_wait_subscr_pres(struct osmo_fsm_inst *fi,
lu_compl_vlr_new_tmsi(fi);
return;
}
+ /* else, any previously used TMSI is now invalid. */
+ vsub->tmsi = GSM_RESERVED_TMSI;
/* Location Updating Accept */
vlr->ops.tx_lu_acc(lcvp->msc_conn_ref, GSM_RESERVED_TMSI);
@@ -495,15 +489,14 @@ static void lu_compl_vlr_wait_imei(struct osmo_fsm_inst *fi, uint32_t event,
case LU_COMPL_VLR_E_IMEI_CHECK_ACK:
if (!vsub->imei[0]) {
/* Abort: Do nothing */
- vlr_lu_compl_fsm_failure(fi,
- GSM48_REJECT_PROTOCOL_ERROR);
+ _vlr_lu_compl_fsm_done(fi, VLR_FSM_RESULT_FAILURE, GSM48_REJECT_PROTOCOL_ERROR);
return;
}
/* Pass */
break;
case LU_COMPL_VLR_E_IMEI_CHECK_NACK:
- vlr_lu_compl_fsm_failure(fi, GSM48_REJECT_ILLEGAL_ME);
+ _vlr_lu_compl_fsm_done(fi, VLR_FSM_RESULT_FAILURE, GSM48_REJECT_ILLEGAL_ME);
/* FIXME: IMEI Check Fail to VLR Application (Detach IMSI VLR) */
return;
}
@@ -523,6 +516,8 @@ static void lu_compl_vlr_wait_imei(struct osmo_fsm_inst *fi, uint32_t event,
/* Wait for TMSI ack */
return;
}
+ /* else, any previously used TMSI is now invalid. */
+ vsub->tmsi = GSM_RESERVED_TMSI;
/* No TMSI needed, accept now. */
vlr->ops.tx_lu_acc(lcvp->msc_conn_ref, GSM_RESERVED_TMSI);
@@ -544,7 +539,7 @@ static void lu_compl_vlr_wait_tmsi(struct osmo_fsm_inst *fi, uint32_t event,
LOGPFSML(fi, LOGL_ERROR, "TMSI Realloc Compl implies that"
" the subscriber has a new TMSI allocated, but"
" the new TMSI is unset.\n");
- vlr_lu_compl_fsm_failure(fi, GSM48_REJECT_NETWORK_FAILURE);
+ _vlr_lu_compl_fsm_done(fi, VLR_FSM_RESULT_FAILURE, GSM48_REJECT_NETWORK_FAILURE);
return;
}
@@ -651,7 +646,9 @@ static const struct value_string fsm_lu_event_names[] = {
OSMO_VALUE_STRING(VLR_ULA_E_UPDATE_LA),
OSMO_VALUE_STRING(VLR_ULA_E_SEND_ID_ACK),
OSMO_VALUE_STRING(VLR_ULA_E_SEND_ID_NACK),
- OSMO_VALUE_STRING(VLR_ULA_E_AUTH_RES),
+ OSMO_VALUE_STRING(VLR_ULA_E_AUTH_SUCCESS),
+ OSMO_VALUE_STRING(VLR_ULA_E_AUTH_NO_INFO),
+ OSMO_VALUE_STRING(VLR_ULA_E_AUTH_FAILURE),
OSMO_VALUE_STRING(VLR_ULA_E_CIPH_RES),
OSMO_VALUE_STRING(VLR_ULA_E_ID_IMSI),
OSMO_VALUE_STRING(VLR_ULA_E_ID_IMEI),
@@ -685,7 +682,12 @@ struct lu_fsm_priv {
struct osmo_location_area_id old_lai;
struct osmo_location_area_id new_lai;
bool authentication_required;
- bool ciphering_required;
+ /* is_ciphering_to_be_attempted: true when any A5/n > 0 are enabled. Ciphering is allowed, always attempt to get Auth Info from
+ * the HLR. */
+ bool is_ciphering_to_be_attempted;
+ /* is_ciphering_required: true when A5/0 is disabled. If we cannot get Auth Info from the HLR, reject the
+ * subscriber. */
+ bool is_ciphering_required;
uint8_t key_seq;
bool is_r99;
bool is_utran;
@@ -697,24 +699,26 @@ struct lu_fsm_priv {
static bool lai_in_this_vlr(struct vlr_instance *vlr,
const struct osmo_location_area_id *lai)
{
- /* TODO: VLR needs to keep a locally configued list of LAIs */
+ /* TODO: VLR needs to keep a locally configured list of LAIs */
return true;
}
-/* Determine if authentication is required */
-static bool is_auth_required(struct lu_fsm_priv *lfp)
+/* Return true when authentication should be attempted. */
+static bool try_auth(struct lu_fsm_priv *lfp)
{
/* The cases where the authentication procedure should be used
* are defined in 3GPP TS 33.102 */
/* For now we use a default value passed in to vlr_lu_fsm(). */
return lfp->authentication_required ||
- (lfp->ciphering_required && !auth_try_reuse_tuple(lfp->vsub, lfp->key_seq));
+ (lfp->is_ciphering_to_be_attempted && !auth_try_reuse_tuple(lfp->vsub, lfp->key_seq));
}
-/* Determine if ciphering is required */
-static bool is_ciph_required(struct lu_fsm_priv *lfp)
+/* Return true when CipherModeCmd / SecurityModeCmd should be attempted. */
+static bool is_cmc_smc_to_be_attempted(struct lu_fsm_priv *lfp)
{
- return lfp->ciphering_required;
+ /* UTRAN: always send SecModeCmd, even if ciphering is not required.
+ * GERAN: avoid sending CiphModeCmd if ciphering is not required. */
+ return lfp->is_utran || lfp->is_ciphering_to_be_attempted;
}
/* Determine if a HLR Update is required */
@@ -827,18 +831,15 @@ static void vlr_loc_upd_post_ciph(struct osmo_fsm_inst *fi)
{
struct lu_fsm_priv *lfp = lu_fsm_fi_priv(fi);
struct vlr_subscr *vsub = lfp->vsub;
+ int rc;
LOGPFSM(fi, "%s()\n", __func__);
OSMO_ASSERT(vsub);
- if (lfp->is_utran) {
- int rc;
- rc = lfp->vlr->ops.tx_common_id(lfp->msc_conn_ref);
- if (rc)
- LOGPFSML(fi, LOGL_ERROR,
- "Error while sending Common ID (%d)\n", rc);
- }
+ rc = lfp->vlr->ops.tx_common_id(lfp->msc_conn_ref);
+ if (rc)
+ LOGPFSML(fi, LOGL_ERROR, "Error while sending Common ID (%d)\n", rc);
vsub->conf_by_radio_contact_ind = true;
/* Update LAI */
@@ -865,7 +866,10 @@ static void vlr_loc_upd_post_auth(struct osmo_fsm_inst *fi)
OSMO_ASSERT(vsub);
- if (!is_ciph_required(lfp)) {
+ /* Continue with ciphering, if enabled.
+ * If auth/ciph is optional and the HLR returned no auth info, continue without ciphering. */
+ if (!is_cmc_smc_to_be_attempted(lfp)
+ || (vsub->sec_ctx == VLR_SEC_CTX_NONE && !lfp->is_ciphering_required)) {
vlr_loc_upd_post_ciph(fi);
return;
}
@@ -890,7 +894,6 @@ static void vlr_loc_upd_post_auth(struct osmo_fsm_inst *fi)
}
if (vlr_set_ciph_mode(vsub->vlr, fi, lfp->msc_conn_ref,
- lfp->ciphering_required,
umts_aka,
vsub->vlr->cfg.retrieve_imeisv_ciphered)) {
LOGPFSML(fi, LOGL_ERROR,
@@ -911,12 +914,15 @@ static void vlr_loc_upd_node1(struct osmo_fsm_inst *fi)
OSMO_ASSERT(vsub);
- if (is_auth_required(lfp)) {
+ if (try_auth(lfp)) {
/* Authenticate_VLR */
osmo_fsm_inst_state_chg(fi, VLR_ULA_S_WAIT_AUTH,
LU_TIMEOUT_LONG, 0);
- vsub->auth_fsm = auth_fsm_start(lfp->vsub, fi->log_level,
- fi, VLR_ULA_E_AUTH_RES,
+ vsub->auth_fsm = auth_fsm_start(lfp->vsub,
+ fi,
+ VLR_ULA_E_AUTH_SUCCESS,
+ VLR_ULA_E_AUTH_NO_INFO,
+ VLR_ULA_E_AUTH_FAILURE,
lfp->is_r99,
lfp->is_utran);
} else {
@@ -1149,17 +1155,32 @@ static void lu_fsm_wait_auth(struct osmo_fsm_inst *fi, uint32_t event,
struct lu_fsm_priv *lfp = lu_fsm_fi_priv(fi);
enum gsm48_reject_value *res = data;
- OSMO_ASSERT(event == VLR_ULA_E_AUTH_RES);
-
lfp->upd_hlr_vlr_fsm = NULL;
- if (!res || *res) {
- lu_fsm_failure(fi, res? *res : GSM48_REJECT_NETWORK_FAILURE);
+ switch (event) {
+ case VLR_ULA_E_AUTH_SUCCESS:
+ /* Result == Pass */
+ vlr_loc_upd_post_auth(fi);
+ return;
+
+ case VLR_ULA_E_AUTH_FAILURE:
+ lu_fsm_failure(fi, res ? *res : GSM48_REJECT_NETWORK_FAILURE);
return;
- }
- /* Result == Pass */
- vlr_loc_upd_post_auth(fi);
+ case VLR_ULA_E_AUTH_NO_INFO:
+ /* HLR returned no auth info for the subscriber. Continue only if authentication is optional. */
+ if (lfp->authentication_required || lfp->is_ciphering_required) {
+ lu_fsm_failure(fi, res ? *res : GSM48_REJECT_NETWORK_FAILURE);
+ return;
+ }
+ LOGPFSML(fi, LOGL_INFO,
+ "Attaching subscriber without auth (auth is optional, and no auth info received from HLR)\n");
+ vlr_loc_upd_post_auth(fi);
+ return;
+
+ default:
+ OSMO_ASSERT(false);
+ }
}
static void lu_fsm_wait_ciph(struct osmo_fsm_inst *fi, uint32_t event,
@@ -1243,6 +1264,10 @@ static void lu_fsm_wait_hlr_ul_res(struct osmo_fsm_inst *fi, uint32_t event,
}
}
break;
+ case VLR_ULA_E_ID_IMEI:
+ case VLR_ULA_E_ID_IMEISV:
+ /* Got the IMEI from ME, nothing to do right now though. */
+ break;
default:
OSMO_ASSERT(0);
break;
@@ -1262,6 +1287,7 @@ static void lu_fsm_wait_lu_compl(struct osmo_fsm_inst *fi, uint32_t event,
LU_COMPL_VLR_E_NEW_TMSI_ACK, NULL);
break;
case VLR_ULA_E_ID_IMEI:
+ case VLR_ULA_E_ID_IMEISV:
/* Got the IMEI from ME, now send it to HLR */
vlr_subscr_tx_req_check_imei(lfp->vsub);
break;
@@ -1369,7 +1395,9 @@ static const struct osmo_fsm_state vlr_lu_fsm_states[] = {
.action = lu_fsm_wait_pvlr,
},
[VLR_ULA_S_WAIT_AUTH] = {
- .in_event_mask = S(VLR_ULA_E_AUTH_RES),
+ .in_event_mask = S(VLR_ULA_E_AUTH_SUCCESS) |
+ S(VLR_ULA_E_AUTH_NO_INFO) |
+ S(VLR_ULA_E_AUTH_FAILURE),
.out_state_mask = S(VLR_ULA_S_WAIT_CIPH) |
S(VLR_ULA_S_WAIT_LU_COMPL) |
S(VLR_ULA_S_WAIT_HLR_UPD) |
@@ -1408,7 +1436,9 @@ static const struct osmo_fsm_state vlr_lu_fsm_states[] = {
},
[VLR_ULA_S_WAIT_HLR_UPD] = {
.in_event_mask = S(VLR_ULA_E_HLR_LU_RES) |
- S(VLR_ULA_E_UPD_HLR_COMPL),
+ S(VLR_ULA_E_UPD_HLR_COMPL) |
+ S(VLR_ULA_E_ID_IMEI) |
+ S(VLR_ULA_E_ID_IMEISV),
.out_state_mask = S(VLR_ULA_S_WAIT_LU_COMPL) |
S(VLR_ULA_S_WAIT_LU_COMPL_STANDALONE) |
S(VLR_ULA_S_DONE),
@@ -1479,7 +1509,8 @@ vlr_loc_update(struct osmo_fsm_inst *parent,
const struct osmo_location_area_id *old_lai,
const struct osmo_location_area_id *new_lai,
bool authentication_required,
- bool ciphering_required,
+ bool is_ciphering_to_be_attempted,
+ bool is_ciphering_required,
uint8_t key_seq,
bool is_r99, bool is_utran,
bool assign_tmsi)
@@ -1487,6 +1518,9 @@ vlr_loc_update(struct osmo_fsm_inst *parent,
struct osmo_fsm_inst *fi;
struct lu_fsm_priv *lfp;
+ if (is_ciphering_required)
+ OSMO_ASSERT(is_ciphering_to_be_attempted);
+
fi = osmo_fsm_inst_alloc_child(&vlr_lu_fsm, parent, parent_event_failure);
if (!fi)
return NULL;
@@ -1503,7 +1537,8 @@ vlr_loc_update(struct osmo_fsm_inst *parent,
lfp->parent_event_failure = parent_event_failure;
lfp->parent_event_data = parent_event_data;
lfp->authentication_required = authentication_required;
- lfp->ciphering_required = ciphering_required;
+ lfp->is_ciphering_to_be_attempted = is_ciphering_to_be_attempted;
+ lfp->is_ciphering_required = is_ciphering_required;
lfp->key_seq = key_seq;
lfp->is_r99 = is_r99;
lfp->is_utran = is_utran;
@@ -1518,10 +1553,10 @@ vlr_loc_update(struct osmo_fsm_inst *parent,
LOGPFSM(fi, "rev=%s net=%s%s%s\n",
is_r99 ? "R99" : "GSM",
is_utran ? "UTRAN" : "GERAN",
- (authentication_required || ciphering_required)?
+ (authentication_required || is_ciphering_to_be_attempted) ?
" Auth" : " (no Auth)",
- (authentication_required || ciphering_required)?
- (ciphering_required? "+Ciph" : " (no Ciph)")
+ (authentication_required || is_ciphering_to_be_attempted) ?
+ (is_ciphering_to_be_attempted ? "+Ciph" : " (no Ciph)")
: "");
if (is_utran && !authentication_required)
diff --git a/src/libvlr/vlr_sgs.c b/src/libvlr/vlr_sgs.c
index 452de2cca..61db585b6 100644
--- a/src/libvlr/vlr_sgs.c
+++ b/src/libvlr/vlr_sgs.c
@@ -44,7 +44,7 @@ const struct value_string sgs_state_counter_names[] = {
};
/* Reset all SGs-Associations back to zero.
- * \param[in] vlr VLR instace. */
+ * \param[in] vlr VLR instance. */
void vlr_sgs_reset(struct vlr_instance *vlr)
{
struct vlr_subscr *vsub;
@@ -59,20 +59,21 @@ void vlr_sgs_reset(struct vlr_instance *vlr)
}
/*! Perform an SGs location update.
- * \param[in] vlr VLR instace.
+ * \param[in] vlr VLR instance.
* \param[in] cfg SGs interface configuration parameters.
- * \param[in] response_cb calback function that is called when LU is done.
- * \param[in] paging_cb calback function that is called when LU needs to page.
- * \param[in] mminfo_cb calback function that is called to provide MM info to the UE.
+ * \param[in] response_cb callback function that is called when LU is done.
+ * \param[in] paging_cb callback function that is called when LU needs to page.
+ * \param[in] mminfo_cb callback function that is called to provide MM info to the UE.
* \param[in] mme_name fqdn of the requesting MME (mme-name).
* \param[in] type location update type (normal or IMSI attach).
* \param[in] imsi mobile identity (IMSI).
* \param[in] new_lai identifier of the new location area.
+ * \param[in] last_eutran_plnm_id Last E-UTRAN PLMN ID (can be NULL).
* \returns 0 in case of success, -EINVAL in case of error. */
int vlr_sgs_loc_update(struct vlr_instance *vlr, struct vlr_sgs_cfg *cfg,
vlr_sgs_lu_response_cb_t response_cb, vlr_sgs_lu_paging_cb_t paging_cb,
vlr_sgs_lu_mminfo_cb_t mminfo_cb, char *mme_name, enum vlr_lu_type type, const char *imsi,
- struct osmo_location_area_id *new_lai)
+ struct osmo_location_area_id *new_lai, struct osmo_plmn_id *last_eutran_plmn)
{
struct vlr_subscr *vsub = NULL;
@@ -82,7 +83,7 @@ int vlr_sgs_loc_update(struct vlr_instance *vlr, struct vlr_sgs_cfg *cfg,
OSMO_ASSERT(cfg);
OSMO_ASSERT(imsi);
- vsub = vlr_subscr_find_or_create_by_imsi(vlr, imsi, VSUB_USE_SGS, NULL);
+ vsub = vlr_subscr_find_or_create_by_imsi(vlr, imsi, VSUB_USE_SGS_LU, NULL);
if (!vsub) {
LOGP(DSGS, LOGL_ERROR, "VLR subscriber allocation failed\n");
return -EINVAL;
@@ -93,6 +94,7 @@ int vlr_sgs_loc_update(struct vlr_instance *vlr, struct vlr_sgs_cfg *cfg,
vsub->sgs.paging_cb = paging_cb;
vsub->sgs.mminfo_cb = mminfo_cb;
vlr_subscr_set_imsi(vsub, imsi);
+ vlr_subscr_set_last_used_eutran_plmn_id(vsub, last_eutran_plmn);
osmo_strlcpy(vsub->sgs.mme_name, mme_name, sizeof(vsub->sgs.mme_name));
osmo_fsm_inst_dispatch(vsub->sgs_fsm, SGS_UE_E_RX_LU_FROM_MME, NULL);
@@ -117,6 +119,9 @@ void vlr_sgs_loc_update_acc_sent(struct vlr_subscr *vsub)
{
osmo_fsm_inst_dispatch(vsub->sgs_fsm, SGS_UE_E_TX_LU_ACCEPT, NULL);
+ /* Balance vlr_subscr_find_or_create_by_imsi() in vlr_sgs_loc_update() */
+ vlr_subscr_put(vsub, VSUB_USE_SGS_LU);
+
/* FIXME: At this point we need to check the status of Ts5 and if
* it is still running this means the LU has interrupted the paging,
* and we need to start paging again. 3GPP TS 29.118,
@@ -128,6 +133,8 @@ void vlr_sgs_loc_update_acc_sent(struct vlr_subscr *vsub)
void vlr_sgs_loc_update_rej_sent(struct vlr_subscr *vsub)
{
osmo_fsm_inst_dispatch(vsub->sgs_fsm, SGS_UE_E_TX_LU_REJECT, NULL);
+ /* Balance vlr_subscr_find_or_create_by_imsi() in vlr_sgs_loc_update() */
+ vlr_subscr_put(vsub, VSUB_USE_SGS_LU);
}
/*! Perform an SGs IMSI detach.
@@ -146,8 +153,10 @@ void vlr_sgs_imsi_detach(struct vlr_instance *vlr, const char *imsi, enum sgsap_
/* See also: 3GPP TS 29.118, 5.6.3 Procedures in the VLR: In case of
* an implicit detach, we are supposed to check if the state of the
* SGs-association, and only when it is not SGs-NULL, we may proceed. */
- if (vsub->sgs_fsm->state == SGS_UE_ST_NULL && type == SGSAP_ID_NONEPS_T_IMPLICIT_UE_EPS_NONEPS)
+ if (vsub->sgs_fsm->state == SGS_UE_ST_NULL && type == SGSAP_ID_NONEPS_T_IMPLICIT_UE_EPS_NONEPS) {
+ vlr_subscr_put(vsub, __func__);
return;
+ }
switch (type) {
case SGSAP_ID_NONEPS_T_EXPLICIT_UE_NONEPS:
@@ -299,7 +308,7 @@ static void Ts5_timeout_cb(void *arg)
{
struct vlr_subscr *vsub = arg;
- /* 3GPP TS 29.118 does not specify a specif action that has to happen
+ /* 3GPP TS 29.118 does not specify a specific action that has to happen
* in case Ts5 times out. The timeout just indicates that the paging
* failed. Other actions may check the status of Ts5 to see if a paging
* is still ongoing or not. */
@@ -327,7 +336,7 @@ void vlr_sgs_pag(struct vlr_subscr *vsub, enum sgsap_service_ind serv_ind)
/* Note: 3GPP TS 29.118, chapter 4.2.2 mentions paging in the FSM
* diagram, but paging never causes a state transition except when
* an explicit failure is indicated (MME actively rejects paging).
- * Apparantly it is also possible that an LU happens while the paging
+ * Apparently it is also possible that an LU happens while the paging
* is still ongoing and Ts5 is running. (chapter 5.1.2.3). This means
* that the paging procedure is intended to run in parallel to the
* SGs FSM and given that the benaviour around Ts5 must be implemented
diff --git a/src/libvlr/vlr_sgs_fsm.c b/src/libvlr/vlr_sgs_fsm.c
index 13639ca3c..2771cf5ce 100644
--- a/src/libvlr/vlr_sgs_fsm.c
+++ b/src/libvlr/vlr_sgs_fsm.c
@@ -48,35 +48,21 @@ static const struct value_string sgs_ue_fsm_event_names[] = {
{0, NULL}
};
-/* Initiate location update and change to SGS_UE_ST_LA_UPD_PRES state */
-static void perform_lu(struct osmo_fsm_inst *fi)
-{
- struct vlr_subscr *vsub = fi->priv;
- int rc;
- osmo_fsm_inst_state_chg(fi, SGS_UE_ST_LA_UPD_PRES, 0, 0);
- vsub->ms_not_reachable_flag = false;
-
- /* Note: At the moment we allocate a new TMSI on each LU. */
- rc = vlr_subscr_alloc_tmsi(vsub);
- if (rc != 0)
- LOGPFSML(fi, LOGL_ERROR, "(sub %s) VLR LU tmsi allocation failed\n", vlr_subscr_name(vsub));
-
- rc = vlr_subscr_req_lu(vsub);
- if (rc != 0)
- LOGPFSML(fi, LOGL_ERROR, "(sub %s) HLR LU request failed\n", vlr_subscr_name(vsub));
-}
-
/* Send the SGs Association to NULL state immediately */
static void to_null(struct osmo_fsm_inst *fi)
{
struct vlr_subscr *vsub = fi->priv;
osmo_fsm_inst_state_chg(fi, SGS_UE_ST_NULL, 0, 0);
- /* Note: This is only relevent for cases where we are in the middle
+ /* Note: This is only relevant for cases where we are in the middle
* of an TMSI reallocation procedure. Should a failure of some sort
* put us to NULL state, we have to free the pending TMSI */
vsub->tmsi_new = GSM_RESERVED_TMSI;
+ /* Make sure we remove recorded Last EUTRAN PLMN Id when UE ceases to be
+ * available over SGs */
+ vlr_subscr_set_last_used_eutran_plmn_id(vsub, NULL);
+
/* Make sure any ongoing paging is aborted. */
if (vsub->cs.is_paging)
paging_expired(vsub);
@@ -86,6 +72,37 @@ static void to_null(struct osmo_fsm_inst *fi)
osmo_timer_del(&vsub->sgs.Ts5);
}
+/* Initiate location update and change to SGS_UE_ST_LA_UPD_PRES state */
+static void perform_lu(struct osmo_fsm_inst *fi)
+{
+ struct vlr_subscr *vsub = fi->priv;
+ struct sgs_lu_response sgs_lu_response = {0};
+ int rc;
+
+ /* Note: At the moment we allocate a new TMSI on each LU. */
+ rc = vlr_subscr_alloc_tmsi(vsub);
+ if (rc != 0) {
+ LOGPFSML(fi, LOGL_ERROR, "(sub %s) VLR LU tmsi allocation failed\n", vlr_subscr_name(vsub));
+ goto error;
+ }
+
+ rc = vlr_subscr_req_lu(vsub);
+ if (rc != 0) {
+ LOGPFSML(fi, LOGL_ERROR, "(sub %s) HLR LU request failed\n", vlr_subscr_name(vsub));
+ goto error;
+ }
+
+ osmo_fsm_inst_state_chg(fi, SGS_UE_ST_LA_UPD_PRES, 0, 0);
+ vsub->ms_not_reachable_flag = false;
+ return;
+
+error:
+ to_null(fi);
+ sgs_lu_response.error = true;
+ sgs_lu_response.vsub = vsub;
+ vsub->sgs.response_cb(&sgs_lu_response);
+}
+
/* Respawn a pending paging (Timer is reset and a new paging request is sent) */
static void respawn_paging(struct vlr_subscr *vsub)
{
@@ -143,7 +160,7 @@ static void sgs_ue_fsm_lau_present(struct osmo_fsm_inst *fi, uint32_t event, voi
/* Check if we expect a TMSI REALLOCATION COMPLETE message from the MME
* by checking the tmsi_new flag. If this flag is not GSM_RESERVED_TMSI
* we know that we have a TMSI pending and need to wait for the MME
- * to acknowlege first */
+ * to acknowledge first */
if (vsub->tmsi_new != GSM_RESERVED_TMSI) {
osmo_fsm_inst_state_chg(fi, SGS_UE_ST_ASSOCIATED, vsub->sgs.cfg.timer[SGS_STATE_TS6_2],
SGS_STATE_TS6_2);
@@ -209,7 +226,7 @@ static void sgs_ue_fsm_associated(struct osmo_fsm_inst *fi, uint32_t event, void
/* Note: We are already in SGS_UE_ST_ASSOCIATED but the
* transition that lead us here had is guarded with Ts6-1,
- * wo we change the state now once more without timeout
+ * so we change the state now once more without timeout
* to ensure the timer is stopped */
osmo_fsm_inst_state_chg(fi, SGS_UE_ST_ASSOCIATED, 0, 0);
break;
@@ -221,6 +238,7 @@ static void sgs_ue_fsm_associated(struct osmo_fsm_inst *fi, uint32_t event, void
if (*cause == SGSAP_SGS_CAUSE_MT_CSFB_REJ_USER)
break;
to_null(fi);
+ break;
case SGS_UE_E_RX_ALERT_FAILURE:
to_null(fi);
break;
@@ -342,7 +360,7 @@ static struct osmo_fsm sgs_ue_fsm = {
.event_names = sgs_ue_fsm_event_names,
};
-/*! Initalize/Register SGs FSM in osmo-fsm subsystem */
+/*! Initialize/Register SGs FSM in osmo-fsm subsystem */
void vlr_sgs_fsm_init(void)
{
if (osmo_fsm_find_by_name(sgs_ue_fsm.name) != &sgs_ue_fsm)
diff --git a/src/osmo-msc/Makefile.am b/src/osmo-msc/Makefile.am
index 7b56c7458..0380d5d1f 100644
--- a/src/osmo-msc/Makefile.am
+++ b/src/osmo-msc/Makefile.am
@@ -19,6 +19,7 @@ AM_CFLAGS = \
$(LIBOSMOSIGTRAN_CFLAGS) \
$(LIBOSMOMGCPCLIENT_CFLAGS) \
$(LIBOSMOGSUPCLIENT_CFLAGS) \
+ $(LIBSQLITE3_CFLAGS) \
$(NULL)
AM_LDFLAGS = \
@@ -42,12 +43,20 @@ osmo_msc_LDADD = \
$(LIBOSMOCTRL_LIBS) \
$(LIBOSMOABIS_LIBS) \
$(LIBOSMONETIF_LIBS) \
- $(LIBSMPP34_LIBS) \
$(LIBOSMORANAP_LIBS) \
$(LIBASN1C_LIBS) \
$(LIBOSMOSIGTRAN_LIBS) \
$(LIBOSMOMGCPCLIENT_LIBS) \
$(LIBOSMOGSUPCLIENT_LIBS) \
- -ldbi \
+ $(LIBSQLITE3_LIBS) \
-lsctp \
$(NULL)
+
+if BUILD_SMPP
+
+osmo_msc_LDADD += \
+ $(top_builddir)/src/libsmpputil/libsmpputil.a \
+ $(LIBSMPP34_LIBS) \
+ $(NULL)
+
+endif
diff --git a/src/osmo-msc/msc_main.c b/src/osmo-msc/msc_main.c
index 9da26fba0..913bd212f 100644
--- a/src/osmo-msc/msc_main.c
+++ b/src/osmo-msc/msc_main.c
@@ -1,4 +1,4 @@
-/* OsmoMSC - Circuit-Switched Core Network (MSC+VLR+HLR+SMSC) implementation
+/* OsmoMSC - Circuit-Switched Core Network (MSC+VLR+SMSC) implementation
*/
/* (C) 2016-2019 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>
@@ -26,6 +26,7 @@
#include <stdbool.h>
#include <unistd.h>
+#include <stdio.h>
#include <time.h>
#include <errno.h>
#include <signal.h>
@@ -52,13 +53,14 @@
#include <osmocom/vty/ports.h>
#include <osmocom/vty/logging.h>
#include <osmocom/vty/misc.h>
+#include <osmocom/vty/cpu_sched_vty.h>
#include <osmocom/msc/vty.h>
#include <osmocom/msc/mncc.h>
#include <osmocom/msc/rrlp.h>
#include <osmocom/ctrl/control_if.h>
#include <osmocom/ctrl/control_vty.h>
#include <osmocom/ctrl/ports.h>
-#include <osmocom/msc/smpp.h>
+#include <osmocom/smpp/smpp.h>
#include <osmocom/sigtran/osmo_ss7.h>
#include <osmocom/mgcp_client/mgcp_client.h>
#include <osmocom/msc/sgs_iface.h>
@@ -98,12 +100,10 @@ void *tall_map_ctx = NULL;
/* end deps from libbsc legacy. */
static struct {
- const char *database_name;
const char *config_file;
int daemonize;
const char *mncc_sock_path;
} msc_cmdline_config = {
- .database_name = "sms.db",
.config_file = "osmo-msc.cfg",
};
@@ -119,35 +119,65 @@ static void print_usage()
static void print_help()
{
- printf(" Some useful help...\n");
+ printf("Some useful options:\n");
printf(" -h --help This text.\n");
printf(" -d option --debug=DCC:DMM:DRR: Enable debugging.\n");
printf(" -D --daemonize Fork the process into a background daemon.\n");
printf(" -c --config-file filename The config file to use.\n");
printf(" -s --disable-color\n");
- printf(" -l --database db-name The database to use.\n");
printf(" -T --timestamp Prefix every log line with a timestamp.\n");
printf(" -V --version Print the version of OsmoMSC.\n");
printf(" -e --log-level number Set a global loglevel.\n");
- printf(" -M --mncc-sock-path PATH Disable built-in MNCC handler and offer socket.\n");
+
+ printf("\nVTY reference generation:\n");
+ printf(" --vty-ref-mode MODE VTY reference generation mode (e.g. 'expert').\n");
+ printf(" --vty-ref-xml Generate the VTY reference XML output and exit.\n");
+}
+
+static void handle_long_options(const char *prog_name, const int long_option)
+{
+ static int vty_ref_mode = VTY_REF_GEN_MODE_DEFAULT;
+
+ switch (long_option) {
+ case 1:
+ vty_ref_mode = get_string_value(vty_ref_gen_mode_names, optarg);
+ if (vty_ref_mode < 0) {
+ fprintf(stderr, "%s: Unknown VTY reference generation "
+ "mode '%s'\n", prog_name, optarg);
+ exit(2);
+ }
+ break;
+ case 2:
+ fprintf(stderr, "Generating the VTY reference in mode '%s' (%s)\n",
+ get_value_string(vty_ref_gen_mode_names, vty_ref_mode),
+ get_value_string(vty_ref_gen_mode_desc, vty_ref_mode));
+ vty_dump_xml_ref_mode(stdout, (enum vty_ref_gen_mode) vty_ref_mode);
+ exit(0);
+ default:
+ fprintf(stderr, "%s: error parsing cmdline options\n", prog_name);
+ exit(2);
+ }
}
static void handle_options(int argc, char **argv)
{
while (1) {
int option_index = 0, c;
+ static int long_option = 0;
static struct option long_options[] = {
{"help", 0, 0, 'h'},
{"debug", 1, 0, 'd'},
{"daemonize", 0, 0, 'D'},
{"config-file", 1, 0, 'c'},
{"disable-color", 0, 0, 's'},
- {"database", 1, 0, 'l'},
+ {"database", 1, 0, 'l'}, /* deprecated */
{"timestamp", 0, 0, 'T'},
{"version", 0, 0, 'V' },
{"log-level", 1, 0, 'e'},
- {"mncc-sock-path", 1, 0, 'M'},
+ {"mncc-sock-path", 1, 0, 'M'}, /* deprecated */
{"no-dbcounter", 0, 0, 'C'}, /* deprecated */
+ {"vty-ref-mode", 1, &long_option, 1},
+ {"vty-ref-xml", 0, &long_option, 2},
{0, 0, 0, 0}
};
@@ -161,6 +191,9 @@ static void handle_options(int argc, char **argv)
print_usage();
print_help();
exit(0);
+ case 0:
+ handle_long_options(argv[0], long_option);
+ break;
case 's':
log_set_use_color(osmo_stderr_target, 0);
break;
@@ -171,7 +204,9 @@ static void handle_options(int argc, char **argv)
msc_cmdline_config.daemonize = 1;
break;
case 'l':
- msc_cmdline_config.database_name = optarg;
+ fprintf(stderr, "Command line argument '-%c' is deprecated, use VTY "
+ "parameter 'smsc' / 'database %s' instead.\n", c, optarg);
+ exit(2);
break;
case 'c':
msc_cmdline_config.config_file = optarg;
@@ -184,6 +219,8 @@ static void handle_options(int argc, char **argv)
break;
case 'M':
msc_cmdline_config.mncc_sock_path = optarg;
+ fprintf(stderr, "Command line argument '-%c' is deprecated, use VTY "
+ "parameter 'msc' / 'mncc external %s' instead.\n", c, optarg);
break;
case 'C':
fprintf(stderr, "-C is deprecated and does nothing.");
@@ -198,10 +235,15 @@ static void handle_options(int argc, char **argv)
exit(-1);
}
}
+
+ if (argc > optind) {
+ fprintf(stderr, "Unsupported positional arguments on command line\n");
+ exit(2);
+ }
}
-struct gsm_network *msc_network_alloc(void *ctx,
- mncc_recv_cb_t mncc_recv)
+static struct gsm_network *msc_network_alloc(void *ctx,
+ mncc_recv_cb_t mncc_recv)
{
struct gsm_network *net = gsm_network_init(ctx, mncc_recv);
if (!net)
@@ -214,8 +256,14 @@ struct gsm_network *msc_network_alloc(void *ctx,
MSC_HLR_REMOTE_IP_DEFAULT);
net->gsup_server_port = MSC_HLR_REMOTE_PORT_DEFAULT;
- mgcp_client_conf_init(&net->mgw.conf);
+ net->mgw.mgw_pool = mgcp_client_pool_alloc(net);
+ net->mgw.conf = mgcp_client_conf_alloc(net);
+ net->call_waiting = true;
+ net->lcls_permitted = false;
+
net->mgw.tdefs = g_mgw_tdefs;
+ osmo_tdefs_reset(net->mgw.tdefs);
+ net->sms_queue_cfg = sms_queue_cfg_alloc(ctx);
return net;
}
@@ -228,20 +276,29 @@ void msc_network_shutdown(struct gsm_network *net)
static struct gsm_network *msc_network = NULL;
extern void *tall_vty_ctx;
-static void signal_handler(int signal)
+static void signal_handler(int signum)
{
- fprintf(stdout, "signal %u received\n", signal);
+ fprintf(stdout, "signal %u received\n", signum);
- switch (signal) {
+ switch (signum) {
case SIGINT:
case SIGTERM:
- LOGP(DMSC, LOGL_NOTICE, "Terminating due to signal %d\n", signal);
+ LOGP(DMSC, LOGL_NOTICE, "Terminating due to signal %d\n", signum);
quit++;
break;
case SIGABRT:
osmo_generate_backtrace();
- /* in case of abort, we want to obtain a talloc report
- * and then return to the caller, who will abort the process */
+ /* in case of abort, we want to obtain a talloc report and
+ * then run default SIGABRT handler, who will generate coredump
+ * and abort the process. abort() should do this for us after we
+ * return, but program wouldn't exit if an external SIGABRT is
+ * received.
+ */
+ talloc_report(tall_vty_ctx, stderr);
+ talloc_report_full(tall_msc_ctx, stderr);
+ signal(SIGABRT, SIG_DFL);
+ raise(SIGABRT);
+ break;
case SIGUSR1:
talloc_report(tall_vty_ctx, stderr);
talloc_report_full(tall_msc_ctx, stderr);
@@ -261,6 +318,11 @@ static int msc_vty_go_parent(struct vty *vty)
vty->node = CONFIG_NODE;
vty->index = NULL;
break;
+ case MGW_NODE:
+ OSMO_ASSERT(msc_network != NULL);
+ vty->node = GSMNET_NODE;
+ vty->index = msc_network;
+ break;
case SMPP_ESME_NODE:
vty->node = SMPP_NODE;
vty->index = NULL;
@@ -268,9 +330,19 @@ static int msc_vty_go_parent(struct vty *vty)
case SMPP_NODE:
case MSC_NODE:
case MNCC_INT_NODE:
+ case ASCI_NODE:
vty->node = CONFIG_NODE;
vty->index = NULL;
break;
+ case GCR_NODE:
+ vty->node = ASCI_NODE;
+ vty->index = NULL;
+ break;
+ case VGC_NODE:
+ case VBC_NODE:
+ vty->node = GCR_NODE;
+ vty->index = NULL;
+ break;
case SUBSCR_NODE:
vty->node = ENABLE_NODE;
vty->index = NULL;
@@ -307,7 +379,8 @@ static struct vty_app_info msc_vty_info = {
.is_config_node = msc_vty_is_config_node,
};
-#define DEFAULT_M3UA_REMOTE_IP "127.0.0.1"
+#define DEFAULT_M3UA_LOCAL_IP "localhost"
+#define DEFAULT_M3UA_REMOTE_IP "localhost"
#define DEFAULT_PC "0.23.1"
static struct osmo_sccp_instance *sccp_setup(void *ctx, uint32_t cs7_instance,
@@ -319,7 +392,7 @@ static struct osmo_sccp_instance *sccp_setup(void *ctx, uint32_t cs7_instance,
return osmo_sccp_simple_client_on_ss7_id(ctx, cs7_instance, label, default_pc,
OSMO_SS7_ASP_PROT_M3UA,
- 0, NULL, /* local: use arbitrary port and 0.0.0.0. */
+ 0, DEFAULT_M3UA_LOCAL_IP, /* local: use arbitrary port and 0.0.0.0. */
0, /* remote: use protocol default port */
DEFAULT_M3UA_REMOTE_IP);
/* Note: If a differing remote IP is to be used, it was already entered in the vty config at
@@ -376,6 +449,18 @@ static const struct log_info_cat msc_default_categories[] = {
.color = "\033[1;32m",
.enabled = 1, .loglevel = LOGL_NOTICE,
},
+ [DBCC] = {
+ .name = "DBCC",
+ .description = "Layer3 Broadcast Call Control (BCC)",
+ .color = "\033[1;32m",
+ .enabled = 1, .loglevel = LOGL_NOTICE,
+ },
+ [DGCC] = {
+ .name = "DGCC",
+ .description = "Layer3 Group Call Control (GCC)",
+ .color = "\033[1;32m",
+ .enabled = 1, .loglevel = LOGL_NOTICE,
+ },
[DMM] = {
.name = "DMM",
.description = "Layer3 Mobility Management (MM)",
@@ -466,6 +551,11 @@ static const struct log_info_cat msc_default_categories[] = {
.description = "Supplementary Services",
.enabled = 1, .loglevel = LOGL_NOTICE,
},
+ [DASCI] = {
+ .name = "DASCI",
+ .description = "Advanced Speech Call Items",
+ .enabled = 1, .loglevel = LOGL_NOTICE,
+ },
};
static int filter_fn(const struct log_context *ctx, struct log_target *tar)
@@ -489,9 +579,49 @@ extern void *tall_gsms_ctx;
extern void *tall_call_ctx;
extern void *tall_trans_ctx;
+static int msc_mgw_setup(void)
+{
+ struct mgcp_client *mgcp_client_single;
+ unsigned int pool_members_initalized;
+
+ /* Initialize MGW pool. This initalizes and connects all MGCP clients that are currently configured in
+ * the pool. Adding additional MGCP clients to the pool is possible but the user has to configure and
+ * (re)connect them manually from the VTY. */
+ if (!mgcp_client_pool_empty(msc_network->mgw.mgw_pool)) {
+ pool_members_initalized = mgcp_client_pool_connect(msc_network->mgw.mgw_pool);
+ if (!pool_members_initalized) {
+ LOGP(DMSC, LOGL_ERROR, "MGW pool failed to initialize any pool members\n");
+ return -EINVAL;
+ }
+ LOGP(DMSC, LOGL_NOTICE,
+ "MGW pool with %u pool members configured, (ignoring MGW configuration in VTY node 'msc').\n",
+ pool_members_initalized);
+ return 0;
+ }
+
+ /* Initialize and connect a single MGCP client. This MGCP client will appear as the one and only pool
+ * member if there is no MGW pool configured. */
+ LOGP(DMSC, LOGL_NOTICE, "No MGW pool configured, using MGW configuration in VTY node 'msc'\n");
+ mgcp_client_single = mgcp_client_init(msc_network, msc_network->mgw.conf);
+ if (!mgcp_client_single) {
+ LOGP(DMSC, LOGL_ERROR, "MGW (single) client initalization failed\n");
+ return -EINVAL;
+ }
+ if (mgcp_client_connect(mgcp_client_single)) {
+ LOGP(DMSC, LOGL_ERROR, "MGW (single) connect failed at (%s:%u)\n",
+ msc_network->mgw.conf->remote_addr,
+ msc_network->mgw.conf->remote_port);
+ return -EINVAL;
+ }
+ mgcp_client_pool_register_single(msc_network->mgw.mgw_pool, mgcp_client_single);
+
+ return 0;
+}
+
int main(int argc, char **argv)
{
int rc;
+ int ret = 0;
struct osmo_sccp_instance *sccp_a;
struct osmo_sccp_instance *sccp_iu;
@@ -499,7 +629,7 @@ int main(int argc, char **argv)
/* Track the use of talloc NULL memory contexts */
talloc_enable_null_tracking();
- osmo_fsm_term_safely(true);
+ osmo_fsm_set_dealloc_ctx(OTC_SELECT);
msc_vty_info.copyright = osmomsc_copyright;
@@ -518,16 +648,18 @@ int main(int argc, char **argv)
osmo_fsm_log_addr(true);
osmo_stats_init(tall_msc_ctx);
+ rate_ctr_init(tall_msc_ctx);
/* For --version, vty_init() must be called before handling options */
vty_init(&msc_vty_info);
- osmo_ss7_init();
+ OSMO_ASSERT(osmo_ss7_init() == 0);
osmo_ss7_vty_init_asp(tall_msc_ctx);
osmo_sccp_vty_init();
-
- /* Parse options */
- handle_options(argc, argv);
+ ctrl_vty_init(tall_msc_ctx);
+ logging_vty_add_cmds();
+ osmo_talloc_vty_add_cmds();
+ osmo_cpu_sched_vty_init(tall_msc_ctx);
/* Allocate global gsm_network struct.
* At first set the internal MNCC as default, may be changed below according to cfg or cmdline option. */
@@ -535,6 +667,11 @@ int main(int argc, char **argv)
if (!msc_network)
return -ENOMEM;
+ msc_vty_init(msc_network);
+
+ /* Parse options */
+ handle_options(argc, argv);
+
call_leg_init(msc_network);
mncc_call_fsm_init(msc_network);
@@ -543,13 +680,8 @@ int main(int argc, char **argv)
exit(1);
}
- ctrl_vty_init(tall_msc_ctx);
- logging_vty_add_cmds(&log_info);
- osmo_talloc_vty_add_cmds();
- msc_vty_init(msc_network);
-
#ifdef BUILD_SMPP
- if (smpp_openbsc_alloc_init(tall_msc_ctx) < 0)
+ if (smpp_msc_alloc_init(tall_msc_ctx) < 0)
return -1;
#endif
sgs_iface_init(tall_msc_ctx, msc_network);
@@ -583,8 +715,7 @@ int main(int argc, char **argv)
DEBUGP(DMNCC, "Using internal MNCC handler.\n");
/* start telnet after reading config for vty_get_bind_addr() */
- rc = telnet_init_dynif(tall_msc_ctx, &msc_network,
- vty_get_bind_addr(), OSMO_VTY_PORT_MSC);
+ rc = telnet_init_default(tall_msc_ctx, &msc_network, OSMO_VTY_PORT_MSC);
if (rc < 0)
return 2;
@@ -593,28 +724,27 @@ int main(int argc, char **argv)
* following code until iu_init() is legacy. */
#ifdef BUILD_SMPP
- smpp_openbsc_start(msc_network);
+ smpp_msc_start(msc_network);
#endif
/* start control interface after reading config for
* ctrl_vty_get_bind_addr() */
- msc_network->ctrl = ctrl_interface_setup_dynip(msc_network, ctrl_vty_get_bind_addr(),
- OSMO_CTRL_PORT_MSC, NULL);
+ msc_network->ctrl = ctrl_interface_setup(msc_network, OSMO_CTRL_PORT_MSC, NULL);
if (!msc_network->ctrl) {
- printf("Failed to initialize control interface. Exiting.\n");
+ fprintf(stderr, "Failed to initialize control interface. Exiting.\n");
return -1;
}
#if 0
TODO: we probably want some of the _net_ ctrl commands from bsc_base_ctrl_cmds_install().
if (bsc_base_ctrl_cmds_install() != 0) {
- printf("Failed to initialize the BSC control commands.\n");
+ fprintf(stderr, "Failed to initialize the BSC control commands.\n");
return -1;
}
#endif
if (msc_ctrl_cmds_install(msc_network) != 0) {
- printf("Failed to initialize the MSC control commands.\n");
+ fprintf(stderr, "Failed to initialize the MSC control commands.\n");
return -1;
}
@@ -623,12 +753,6 @@ TODO: we probably want some of the _net_ ctrl commands from bsc_base_ctrl_cmds_i
/* TODO: is this used for crypto?? Improve randomness, at least we
* should try to use the nanoseconds part of the current time. */
- if (db_init(msc_cmdline_config.database_name)) {
- printf("DB: Failed to init database: %s\n",
- msc_cmdline_config.database_name);
- return 4;
- }
-
if (msc_gsup_client_start(msc_network)) {
fprintf(stderr, "Failed to start GSUP client\n");
exit(1);
@@ -641,11 +765,6 @@ TODO: we probably want some of the _net_ ctrl commands from bsc_base_ctrl_cmds_i
exit(1);
}
- if (db_prepare()) {
- printf("DB: Failed to prepare database.\n");
- return 5;
- }
-
signal(SIGINT, &signal_handler);
signal(SIGTERM, &signal_handler);
signal(SIGABRT, &signal_handler);
@@ -654,33 +773,35 @@ TODO: we probably want some of the _net_ ctrl commands from bsc_base_ctrl_cmds_i
osmo_init_ignore_signals();
/* start the SMS queue */
- if (sms_queue_start(msc_network, 20) != 0)
- return -1;
-
- msc_network->mgw.client = mgcp_client_init(
- msc_network, &msc_network->mgw.conf);
+ if (sms_queue_start(msc_network) != 0) {
+ ret = -1;
+ goto error;
+ }
- if (mgcp_client_connect(msc_network->mgw.client)) {
- printf("MGCPGW connect failed\n");
- return 7;
+ if (msc_mgw_setup() != 0) {
+ ret = 7;
+ goto error;
}
if (ss7_setup(tall_msc_ctx, &sccp_a, &sccp_iu)) {
- printf("Setting up SCCP client failed.\n");
- return 8;
+ fprintf(stderr, "Setting up SCCP client failed.\n");
+ ret = 8;
+ goto error;
}
if (sgs_server_open(g_sgs)) {
- printf("Starting SGs server failed\n");
- return 9;
+ fprintf(stderr, "Starting SGs server failed\n");
+ ret = 9;
+ goto error;
}
msc_network->a.sri = sccp_ran_init(msc_network, sccp_a, OSMO_SCCP_SSN_BSSAP,
"OsmoMSC-A", &msc_ran_infra[OSMO_RAT_GERAN_A],
msc_network);
if (!msc_network->a.sri) {
- printf("Setting up A receiver failed\n");
- return 10;
+ fprintf(stderr, "Setting up A receiver failed\n");
+ ret = 10;
+ goto error;
}
LOGP(DMSC, LOGL_NOTICE, "A-interface: SCCP user %s, cs7-instance %u (%s)\n",
osmo_sccp_user_name(msc_network->a.sri->scu),
@@ -694,8 +815,9 @@ TODO: we probably want some of the _net_ ctrl commands from bsc_base_ctrl_cmds_i
"OsmoMSC-IuCS", &msc_ran_infra[OSMO_RAT_UTRAN_IU],
msc_network);
if (!msc_network->iu.sri) {
- printf("Setting up IuCS receiver failed\n");
- return 11;
+ fprintf(stderr, "Setting up IuCS receiver failed\n");
+ ret = 11;
+ goto error;
}
/* Compatibility with legacy osmo-hnbgw that was unable to properly handle RESET messages. */
@@ -714,19 +836,32 @@ TODO: we probably want some of the _net_ ctrl commands from bsc_base_ctrl_cmds_i
rc = osmo_daemonize();
if (rc < 0) {
perror("Error during daemonize");
- return 6;
+ ret = 6;
+ goto error;
}
}
- while (!quit) {
+ do {
log_reset_context();
- osmo_select_main(0);
- }
+ osmo_select_main_ctx(0);
+
+ /* If the user hits Ctrl-C the third time, just terminate immediately. */
+ if (quit >= 3)
+ break;
+
+ /* Has SIGTERM been received (and not yet been handled)? */
+ if (quit && !osmo_select_shutdown_requested()) {
+ msc_network_shutdown(msc_network);
+ osmo_signal_dispatch(SS_L_GLOBAL, S_L_GLOBAL_SHUTDOWN, NULL);
- msc_network_shutdown(msc_network);
- osmo_signal_dispatch(SS_L_GLOBAL, S_L_GLOBAL_SHUTDOWN, NULL);
- sleep(3);
+ /* Request write-only mode in osmo_select_main_ctx() */
+ osmo_select_shutdown_request();
+ /* continue the main select loop until all write queues are serviced. */
+ }
+ } while (!osmo_select_shutdown_done());
+error:
+ db_fini();
log_fini();
/**
@@ -745,5 +880,5 @@ TODO: we probably want some of the _net_ ctrl commands from bsc_base_ctrl_cmds_i
*/
talloc_report_full(NULL, stderr);
talloc_disable_null_tracking();
- return 0;
+ return ret;
}
diff --git a/src/utils/Makefile.am b/src/utils/Makefile.am
index cb0faf69f..606967245 100644
--- a/src/utils/Makefile.am
+++ b/src/utils/Makefile.am
@@ -34,12 +34,26 @@ smpp_mirror_SOURCES = \
smpp_mirror_CFLAGS = \
$(LIBOSMOCORE_CFLAGS) \
+ $(LIBOSMOSCCP_CFLAGS) \
+ $(LIBOSMOMGCPCLIENT_CFLAGS) \
$(LIBSMPP34_CFLAGS) \
$(NULL)
smpp_mirror_LDADD = \
+ $(top_builddir)/src/libsmpputil/libsmpputil.a \
+ $(top_builddir)/src/libmsc/libmsc.a \
+ $(top_builddir)/src/libvlr/libvlr.a \
$(LIBOSMOCORE_LIBS) \
$(LIBOSMOGSM_LIBS) \
+ $(LIBOSMOVTY_LIBS) \
+ $(LIBOSMONETIF_LIBS) \
$(LIBSMPP34_LIBS) \
+ $(LIBOSMORANAP_LIBS) \
+ $(LIBASN1C_LIBS) \
+ $(LIBOSMOSIGTRAN_LIBS) \
+ $(LIBOSMOMGCPCLIENT_LIBS) \
+ $(LIBOSMOGSUPCLIENT_LIBS) \
+ $(LIBSQLITE3_LIBS) \
+ -lsctp \
$(NULL)
endif
diff --git a/src/utils/smpp_mirror.c b/src/utils/smpp_mirror.c
index 30535535b..3356468ae 100644
--- a/src/utils/smpp_mirror.c
+++ b/src/utils/smpp_mirror.c
@@ -19,80 +19,9 @@
#include <osmocom/core/write_queue.h>
#include <osmocom/msc/debug.h>
+#include <osmocom/smpp/smpp.h>
-/* FIXME: merge with smpp_smsc.c */
-#define SMPP_SYS_ID_LEN 16
-enum esme_read_state {
- READ_ST_IN_LEN = 0,
- READ_ST_IN_MSG = 1,
-};
-/* FIXME: merge with smpp_smsc.c */
-
-struct esme {
- struct osmo_fd ofd;
-
- uint32_t own_seq_nr;
-
- struct osmo_wqueue wqueue;
- enum esme_read_state read_state;
- uint32_t read_len;
- uint32_t read_idx;
- struct msgb *read_msg;
-
- uint8_t smpp_version;
- char system_id[SMPP_SYS_ID_LEN+1];
- char password[SMPP_SYS_ID_LEN+1];
-};
-
-/* FIXME: merge with smpp_smsc.c */
-#define SMPP34_UNPACK(rc, type, str, data, len) \
- memset(str, 0, sizeof(*str)); \
- rc = smpp34_unpack(type, str, data, len)
-#define INIT_RESP(type, resp, req) { \
- memset((resp), 0, sizeof(*(resp))); \
- (resp)->command_length = 0; \
- (resp)->command_id = type; \
- (resp)->command_status = ESME_ROK; \
- (resp)->sequence_number = (req)->sequence_number; \
-}
-#define PACK_AND_SEND(esme, ptr) pack_and_send(esme, (ptr)->command_id, ptr)
-static inline uint32_t smpp_msgb_cmdid(struct msgb *msg)
-{
- uint8_t *tmp = msgb_data(msg) + 4;
- return ntohl(*(uint32_t *)tmp);
-}
-static uint32_t esme_inc_seq_nr(struct esme *esme)
-{
- esme->own_seq_nr++;
- if (esme->own_seq_nr > 0x7fffffff)
- esme->own_seq_nr = 1;
- return esme->own_seq_nr;
-}
-static int pack_and_send(struct esme *esme, uint32_t type, void *ptr)
-{
- struct msgb *msg = msgb_alloc(4096, "SMPP_Tx");
- int rc, rlen;
- if (!msg)
- return -ENOMEM;
-
- rc = smpp34_pack(type, msg->tail, msgb_tailroom(msg), &rlen, ptr);
- if (rc != 0) {
- LOGP(DSMPP, LOGL_ERROR, "[%s] Error during smpp34_pack(): %s\n",
- esme->system_id, smpp34_strerror);
- msgb_free(msg);
- return -EINVAL;
- }
- msgb_put(msg, rlen);
-
- if (osmo_wqueue_enqueue(&esme->wqueue, msg) != 0) {
- LOGP(DSMPP, LOGL_ERROR, "[%s] Write queue full. Dropping message\n",
- esme->system_id);
- msgb_free(msg);
- return -EAGAIN;
- }
- return 0;
-}
/* FIXME: merge with smpp_smsc.c */
static struct tlv_t *find_tlv(struct tlv_t *head, uint16_t tag)
@@ -188,8 +117,8 @@ static int bind_transceiver(struct esme *esme)
memset(&bind, 0, sizeof(bind));
bind.command_id = BIND_TRANSCEIVER;
bind.sequence_number = esme_inc_seq_nr(esme);
- snprintf((char *)bind.system_id, sizeof(bind.system_id), "%s", esme->system_id);
- snprintf((char *)bind.password, sizeof(bind.password), "%s", esme->password);
+ snprintf((char *)bind.system_id, SMPP_SYS_ID_LEN + 1, "%s", esme->system_id);
+ snprintf((char *)bind.password, SMPP_SYS_ID_LEN + 1, "%s", esme->password);
snprintf((char *)bind.system_type, sizeof(bind.system_type), "mirror");
bind.interface_version = esme->smpp_version;
@@ -214,6 +143,14 @@ static int smpp_pdu_rx(struct esme *esme, struct msgb *msg)
return rc;
}
+static void esme_read_state_reset(struct esme *esme)
+{
+ esme->read_msg = NULL;
+ esme->read_idx = 0;
+ esme->read_len = 0;
+ esme->read_state = READ_ST_IN_LEN;
+}
+
/* FIXME: merge with smpp_smsc.c */
static int esme_read_cb(struct osmo_fd *ofd)
{
@@ -230,14 +167,17 @@ static int esme_read_cb(struct osmo_fd *ofd)
rdlen = sizeof(uint32_t) - esme->read_idx;
rc = read(ofd->fd, lenptr + esme->read_idx, rdlen);
if (rc < 0) {
- LOGP(DSMPP, LOGL_ERROR, "[%s] read returned %d\n",
- esme->system_id, rc);
+ LOGPESME(esme, LOGL_ERROR, "read returned %d\n", rc);
} else if (rc == 0) {
goto dead_socket;
} else
esme->read_idx += rc;
if (esme->read_idx >= sizeof(uint32_t)) {
esme->read_len = ntohl(len);
+ if (esme->read_len > 65535) {
+ /* unrealistic */
+ goto dead_socket;
+ }
msg = msgb_alloc(esme->read_len, "SMPP Rx");
if (!msg)
return -ENOMEM;
@@ -253,8 +193,7 @@ static int esme_read_cb(struct osmo_fd *ofd)
rdlen = esme->read_len - esme->read_idx;
rc = read(ofd->fd, msg->tail, OSMO_MIN(rdlen, msgb_tailroom(msg)));
if (rc < 0) {
- LOGP(DSMPP, LOGL_ERROR, "[%s] read returned %d\n",
- esme->system_id, rc);
+ LOGPESME(esme, LOGL_ERROR, "read returned %d\n", rc);
} else if (rc == 0) {
goto dead_socket;
} else {
@@ -264,10 +203,7 @@ static int esme_read_cb(struct osmo_fd *ofd)
if (esme->read_idx >= esme->read_len) {
rc = smpp_pdu_rx(esme, esme->read_msg);
- esme->read_msg = NULL;
- esme->read_idx = 0;
- esme->read_len = 0;
- esme->read_state = READ_ST_IN_LEN;
+ esme_read_state_reset(esme);
}
break;
}
@@ -278,6 +214,7 @@ dead_socket:
osmo_fd_unregister(&esme->wqueue.bfd);
close(esme->wqueue.bfd.fd);
esme->wqueue.bfd.fd = -1;
+ esme_read_state_reset(esme);
exit(2342);
return 0;
@@ -295,7 +232,7 @@ static int esme_write_cb(struct osmo_fd *ofd, struct msgb *msg)
esme->wqueue.bfd.fd = -1;
exit(99);
} else if (rc < msgb_length(msg)) {
- LOGP(DSMPP, LOGL_ERROR, "[%s] Short write\n", esme->system_id);
+ LOGPESME(esme, LOGL_ERROR, "Short write\n");
return 0;
}
@@ -307,11 +244,8 @@ static int smpp_esme_init(struct esme *esme, const char *host, uint16_t port)
int rc;
if (port == 0)
- port = 2775;
+ port = SMPP_PORT;
- esme->own_seq_nr = rand();
- esme_inc_seq_nr(esme);
- osmo_wqueue_init(&esme->wqueue, 10);
esme->wqueue.bfd.data = esme;
esme->wqueue.read_cb = esme_read_cb;
esme->wqueue.write_cb = esme_write_cb;
@@ -339,7 +273,7 @@ const struct log_info log_info = {
int main(int argc, char **argv)
{
- struct esme esme;
+ struct esme *esme;
char *host = "localhost";
int port = 0;
int rc;
@@ -347,20 +281,22 @@ int main(int argc, char **argv)
msgb_talloc_ctx_init(ctx, 0);
- memset(&esme, 0, sizeof(esme));
-
osmo_init_logging2(ctx, &log_info);
- snprintf((char *) esme.system_id, sizeof(esme.system_id), "mirror");
- snprintf((char *) esme.password, sizeof(esme.password), "mirror");
- esme.smpp_version = 0x34;
+ esme = esme_alloc(ctx);
+ if (!esme)
+ exit(2);
+
+ snprintf((char *) esme->system_id, sizeof(esme->system_id), "mirror");
+ snprintf((char *) esme->password, sizeof(esme->password), "mirror");
+ esme->smpp_version = 0x34;
if (argc >= 2)
host = argv[1];
if (argc >= 3)
port = atoi(argv[2]);
- rc = smpp_esme_init(&esme, host, port);
+ rc = smpp_esme_init(esme, host, port);
if (rc < 0)
exit(1);
diff --git a/tests/Makefile.am b/tests/Makefile.am
index ee4f47a0c..7ab3c377f 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -1,6 +1,10 @@
SUBDIRS = \
sms_queue \
msc_vlr \
+ db_sms \
+ sdp_msg \
+ mncc \
+ csd \
$(NULL)
if BUILD_SMPP
@@ -34,7 +38,7 @@ EXTRA_DIST = \
vty_test_runner.py \
ctrl_test_runner.py \
smpp_test_runner.py \
- test_nodes.vty \
+ $(srcdir)/*.vty \
$(NULL)
TESTSUITE = $(srcdir)/testsuite
@@ -45,7 +49,7 @@ DISTCLEANFILES = \
if ENABLE_EXT_TESTS
# don't run multiple tests concurrently so that the ports don't conflict
-python-tests: $(BUILT_SOURCES)
+python-tests:
$(MAKE) vty-test
$(MAKE) ctrl-test
if BUILD_SMPP
@@ -53,34 +57,42 @@ if BUILD_SMPP
endif
else
-python-tests: $(BUILT_SOURCES)
+python-tests:
echo "Not running python-based tests (determined at configure-time)"
endif
-vty-python-test: $(BUILT_SOURCES)
- osmotestvty.py -p $(abs_top_srcdir) -w $(abs_top_builddir) -v
- osmotestconfig.py -p $(abs_top_srcdir) -w $(abs_top_builddir) -v
+vty-python-test: $(top_builddir)/src/osmo-msc/osmo-msc
+if BUILD_IU
+ IU=1 osmotestvty.py -p $(abs_top_srcdir) -w $(abs_top_builddir) -v
+ IU=1 osmotestconfig.py -p $(abs_top_srcdir) -w $(abs_top_builddir) -v
+else
+ IU=0 osmotestvty.py -p $(abs_top_srcdir) -w $(abs_top_builddir) -v
+ IU=0 osmotestconfig.py -p $(abs_top_srcdir) -w $(abs_top_builddir) -v
+endif
$(srcdir)/vty_test_runner.py -w $(abs_top_builddir) -v
- rm -f $(top_builddir)/sms.db
+ rm -f $(top_builddir)/sms.db*
+
+# Run a specific transcript test with: 'make vty-transcript-test VTY_TEST=osmo-msc.vty'
+VTY_TEST ?= *.vty
# To update the VTY script from current application behavior,
# pass -u to vty_script_runner.py by doing:
# make vty-transcript-test U=-u
-vty-transcript-test:
+vty-transcript-test: $(top_builddir)/src/osmo-msc/osmo-msc
osmo_verify_transcript_vty.py -v \
-n OsmoMSC -p 4254 \
-r "$(top_builddir)/src/osmo-msc/osmo-msc -c $(top_srcdir)/doc/examples/osmo-msc/osmo-msc.cfg" \
- $(U) $${T:-$(srcdir)/*.vty}
- rm -f $(builddir)/sms.db
+ $(U) $(srcdir)/$(VTY_TEST)
+ rm -f $(builddir)/sms.db*
# don't run multiple tests concurrently so that the ports don't conflict
vty-test:
$(MAKE) vty-python-test
$(MAKE) vty-transcript-test
-ctrl-python-test: $(BUILT_SOURCES)
+ctrl-python-test: $(top_builddir)/src/osmo-msc/osmo-msc
$(srcdir)/ctrl_test_runner.py -w $(abs_top_builddir) -v
- rm -f $(top_builddir)/sms.db
+ rm -f $(top_builddir)/sms.db*
# To update the CTRL script from current application behavior,
# pass -u to ctrl_script_runner.py by doing:
@@ -93,9 +105,9 @@ ctrl-test:
$(MAKE) ctrl-python-test
$(MAKE) ctrl-transcript-test
-smpp-test:
+smpp-test:$(top_builddir)/src/osmo-msc/osmo-msc
$(srcdir)/smpp_test_runner.py -w $(abs_top_builddir) -v
- rm -f $(top_builddir)/sms.db
+ rm -f $(top_builddir)/sms.db*
check-local: atconfig $(TESTSUITE)
$(SHELL) '$(TESTSUITE)' $(TESTSUITEFLAGS)
diff --git a/tests/csd/Makefile.am b/tests/csd/Makefile.am
new file mode 100644
index 000000000..581f7d402
--- /dev/null
+++ b/tests/csd/Makefile.am
@@ -0,0 +1,37 @@
+AM_CPPFLAGS = \
+ $(all_includes) \
+ -I$(top_srcdir)/include \
+ $(NULL)
+
+AM_CFLAGS = \
+ -Wall \
+ -ggdb3 \
+ $(LIBOSMOCORE_CFLAGS) \
+ $(NULL)
+
+AM_LDFLAGS = \
+ $(COVERAGE_LDFLAGS) \
+ -no-install \
+ $(NULL)
+
+LDADD = \
+ $(top_builddir)/src/libmsc/libmsc.a \
+ $(LIBOSMOCORE_LIBS) \
+ $(NULL)
+
+EXTRA_DIST = \
+ csd_test.ok \
+ csd_test.err \
+ $(NULL)
+
+check_PROGRAMS = \
+ csd_test \
+ $(NULL)
+
+csd_test_SOURCES = \
+ csd_test.c \
+ $(NULL)
+
+.PHONY: update_exp
+update_exp:
+ $(builddir)/csd_test >$(srcdir)/csd_test.ok 2>$(srcdir)/csd_test.err
diff --git a/tests/csd/csd_test.c b/tests/csd/csd_test.c
new file mode 100644
index 000000000..ad3b0daf4
--- /dev/null
+++ b/tests/csd/csd_test.c
@@ -0,0 +1,44 @@
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <osmocom/core/application.h>
+#include <osmocom/msc/csd_bs.h>
+#include <osmocom/msc/debug.h>
+
+void test_csd_bs_list_remove(void)
+{
+ struct csd_bs_list list = {
+ .count = 3,
+ .bs = {
+ CSD_BS_21_T_V110_0k3,
+ CSD_BS_22_T_V110_1k2,
+ CSD_BS_24_T_V110_2k4,
+ },
+ };
+
+ printf("=== %s ===\n", __func__);
+ printf("initial:\n");
+ printf(" %s\n", csd_bs_list_to_str(&list));
+
+ printf("removing BS25T (not in the list):\n");
+ csd_bs_list_remove(&list, CSD_BS_25_T_V110_4k8);
+ printf(" %s\n", csd_bs_list_to_str(&list));
+
+ printf("removing BS22T:\n");
+ csd_bs_list_remove(&list, CSD_BS_22_T_V110_1k2);
+ printf(" %s\n", csd_bs_list_to_str(&list));
+
+ printf("removing BS24T:\n");
+ csd_bs_list_remove(&list, CSD_BS_24_T_V110_2k4);
+ printf(" %s\n", csd_bs_list_to_str(&list));
+
+ printf("removing BS21T:\n");
+ csd_bs_list_remove(&list, CSD_BS_21_T_V110_0k3);
+ printf(" %s\n", csd_bs_list_to_str(&list));
+}
+
+int main(void)
+{
+ test_csd_bs_list_remove();
+ return 0;
+}
diff --git a/src/libmsc/ran_up_l2.c b/tests/csd/csd_test.err
index e69de29bb..e69de29bb 100644
--- a/src/libmsc/ran_up_l2.c
+++ b/tests/csd/csd_test.err
diff --git a/tests/csd/csd_test.ok b/tests/csd/csd_test.ok
new file mode 100644
index 000000000..0beac462a
--- /dev/null
+++ b/tests/csd/csd_test.ok
@@ -0,0 +1,11 @@
+=== test_csd_bs_list_remove ===
+initial:
+ BS21T,BS22T,BS24T
+removing BS25T (not in the list):
+ BS21T,BS22T,BS24T
+removing BS22T:
+ BS21T,BS24T
+removing BS24T:
+ BS21T
+removing BS21T:
+ (no-bearer-services)
diff --git a/tests/ctrl_test_runner.py b/tests/ctrl_test_runner.py
index f652a6729..16d1e7cca 100755
--- a/tests/ctrl_test_runner.py
+++ b/tests/ctrl_test_runner.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2
+#!/usr/bin/env python3
# (C) 2013 by Jacob Erlbeck <jerlbeck@sysmocom.de>
# (C) 2014 by Holger Hans Peter Freyther
@@ -53,8 +53,8 @@ class TestCtrlBase(unittest.TestCase):
try:
self.proc = osmoutil.popen_devnull(osmo_ctrl_cmd)
except OSError:
- print >> sys.stderr, "Current directory: %s" % os.getcwd()
- print >> sys.stderr, "Consider setting -b"
+ print("Current directory: %s" % os.getcwd(), file=sys.stderr)
+ print("Consider setting -b", file=sys.stderr)
time.sleep(2)
appstring = self.ctrl_app()[2]
@@ -64,7 +64,9 @@ class TestCtrlBase(unittest.TestCase):
def tearDown(self):
self.disconnect()
- osmoutil.end_proc(self.proc)
+ rc = osmoutil.end_proc(self.proc)
+ if rc is not None and rc != 0:
+ raise Exception("Process returned %d" % rc)
def disconnect(self):
if not (self.sock is None):
@@ -72,7 +74,7 @@ class TestCtrlBase(unittest.TestCase):
def connect(self, host, port):
if verbose:
- print "Connecting to host %s:%i" % (host, port)
+ print("Connecting to host %s:%i" % (host, port))
retries = 30
while True:
@@ -92,7 +94,7 @@ class TestCtrlBase(unittest.TestCase):
def send(self, data):
if verbose:
- print "Sending \"%s\"" %(data)
+ print("Sending \"%s\"" %(data))
data = Ctrl().add_header(data)
return self.sock.send(data) == len(data)
@@ -123,7 +125,7 @@ class TestCtrlBase(unittest.TestCase):
(head, data) = IPA().split_combined(data)
answer = Ctrl().rem_header(head)
if verbose:
- print "Got message:", answer
+ print("Got message:", answer)
(mtype, id, msg) = answer.split(None, 2)
id = int(id)
rsp = {'mtype': mtype, 'id': id}
@@ -139,7 +141,7 @@ class TestCtrlBase(unittest.TestCase):
responses[id] = rsp
if verbose:
- print "Decoded replies: ", responses
+ print("Decoded replies: ", responses)
return responses
@@ -183,9 +185,9 @@ if __name__ == '__main__':
if args.p:
confpath = args.p
- print "confpath %s, workdir %s" % (confpath, workdir)
+ print("confpath %s, workdir %s" % (confpath, workdir))
os.chdir(workdir)
- print "Running tests for specific control commands"
+ print("Running tests for specific control commands")
suite = unittest.TestSuite()
suite.addTest(unittest.TestLoader().loadTestsFromTestCase(TestCtrlMSC))
res = unittest.TextTestRunner(verbosity=verbose_level).run(suite)
diff --git a/tests/db_sms/Makefile.am b/tests/db_sms/Makefile.am
new file mode 100644
index 000000000..9dabfe719
--- /dev/null
+++ b/tests/db_sms/Makefile.am
@@ -0,0 +1,55 @@
+AM_CPPFLAGS = \
+ $(all_includes) \
+ -I$(top_srcdir)/include \
+ $(NULL)
+
+AM_CFLAGS = \
+ -Wall \
+ -ggdb3 \
+ $(LIBOSMOCORE_CFLAGS) \
+ $(LIBOSMOGSM_CFLAGS) \
+ $(LIBASN1C_CFLAGS) \
+ $(LIBOSMOVTY_CFLAGS) \
+ $(LIBOSMOABIS_CFLAGS) \
+ $(LIBOSMOSIGTRAN_CFLAGS) \
+ $(LIBOSMORANAP_CFLAGS) \
+ $(LIBOSMONETIF_CFLAGS) \
+ $(LIBOSMOMGCPCLIENT_CFLAGS) \
+ $(LIBOSMOGSUPCLIENT_CFLAGS) \
+ $(LIBSQLITE3_CFLAGS) \
+ $(NULL)
+
+AM_LDFLAGS = \
+ $(COVERAGE_LDFLAGS) \
+ -no-install \
+ $(NULL)
+
+EXTRA_DIST = \
+ db_sms_test.ok \
+ db_sms_test.err \
+ $(NULL)
+
+check_PROGRAMS = \
+ db_sms_test \
+ $(NULL)
+
+db_sms_test_SOURCES = \
+ db_sms_test.c \
+ $(srcdir)/../stubs.c \
+ $(NULL)
+
+db_sms_test_LDADD = \
+ $(top_builddir)/src/libmsc/libmsc.a \
+ $(top_builddir)/src/libvlr/libvlr.a \
+ $(LIBOSMOCORE_LIBS) \
+ $(LIBOSMOGSM_LIBS) \
+ $(LIBOSMOVTY_LIBS) \
+ $(LIBOSMOABIS_LIBS) \
+ $(LIBOSMOSIGTRAN_LIBS) \
+ $(LIBOSMORANAP_LIBS) \
+ $(LIBASN1C_LIBS) \
+ $(LIBOSMOMGCPCLIENT_LIBS) \
+ $(LIBOSMOGSUPCLIENT_LIBS) \
+ $(LIBSQLITE3_LIBS) \
+ $(LIBRARY_GSM) \
+ $(NULL)
diff --git a/tests/db_sms/db_sms_test.c b/tests/db_sms/db_sms_test.c
new file mode 100644
index 000000000..7c015d318
--- /dev/null
+++ b/tests/db_sms/db_sms_test.c
@@ -0,0 +1,576 @@
+/*
+ * Test the storage API of the internal SMS Centre.
+ *
+ * (C) 2019 by Vadim Yanitskiy <axilirator@gmail.com>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <inttypes.h>
+#include <stdbool.h>
+#include <string.h>
+#include <stdio.h>
+
+#include <osmocom/core/application.h>
+#include <osmocom/core/utils.h>
+
+#include <osmocom/gsm/protocol/gsm_03_40.h>
+
+#include <osmocom/msc/gsm_data.h>
+#include <osmocom/msc/debug.h>
+#include <osmocom/msc/vlr.h>
+#include <osmocom/msc/db.h>
+
+/* Talloc context of this unit test */
+static void *talloc_ctx = NULL;
+
+static const struct sms_tp_ud {
+ /* Data Coding Scheme */
+ uint8_t dcs;
+ /* TP User-Data-Length (depends on DCS) */
+ uint8_t length;
+ /* Static TP User-Data filler (0 means disabled) */
+ uint8_t filler_byte;
+ /* TP User-Data */
+ uint8_t data[GSM340_UDL_OCT_MAX];
+ /* Decoded text (for 7-bit default alphabet only) */
+ char dec_text[GSM340_UDL_SPT_MAX + 1];
+} sms_tp_ud_set[] = {
+ {
+ .dcs = 0x00, /* Default GSM 7-bit alphabet */
+ .length = 9, /* in septets */
+ .dec_text = "Mahlzeit!",
+ .data = {
+ 0xcd, 0x30, 0x9a, 0xad, 0x2f, 0xa7, 0xe9, 0x21,
+ },
+ },
+ {
+ .dcs = 0x08, /* UCS-2 (16-bit) / UTF-16 */
+ .length = 120, /* in octets */
+ .data = {
+ 0x04, 0x23, 0x04, 0x32, 0x04, 0x30, 0x04, 0x36,
+ 0x04, 0x30, 0x04, 0x35, 0x04, 0x3c, 0x04, 0x4b,
+ 0x04, 0x39, 0x00, 0x20, 0x04, 0x3a, 0x04, 0x3b,
+ 0x04, 0x38, 0x04, 0x35, 0x04, 0x3d, 0x04, 0x42,
+ 0x00, 0x21, 0x00, 0x20, 0x04, 0x1d, 0x04, 0x30,
+ 0x04, 0x41, 0x04, 0x42, 0x04, 0x40, 0x04, 0x3e,
+ 0x04, 0x39, 0x04, 0x3a, 0x04, 0x38, 0x00, 0x20,
+ 0x00, 0x49, 0x00, 0x6e, 0x00, 0x74, 0x00, 0x65,
+ 0x00, 0x72, 0x00, 0x6e, 0x00, 0x65, 0x00, 0x74,
+ 0x00, 0x20, 0x04, 0x38, 0x00, 0x20, 0x00, 0x4d,
+ 0x00, 0x4d, 0x00, 0x53, 0x00, 0x20, 0x04, 0x31,
+ 0x04, 0x43, 0x04, 0x34, 0x04, 0x43, 0x04, 0x42,
+ 0x00, 0x20, 0x04, 0x34, 0x04, 0x3e, 0x04, 0x41,
+ 0x04, 0x42, 0x04, 0x30, 0x04, 0x32, 0x04, 0x3b,
+ 0x04, 0x35, 0x04, 0x3d, 0x04, 0x4b, 0x00, 0x2e,
+ },
+ },
+ {
+ .dcs = 0x04, /* 8-bit data */
+ .length = 12, /* in octets */
+ .data = {
+ /* User-Data-Header */
+ 0x1e, /* Buffer-overflow! (should be 0x05) */
+ /* Concatenated SM, 8-bit reference number */
+ 0x00, 0x03, 0x5a, 0x05, 0x01,
+
+ /* Dummy payload... */
+ 0x05, 0x04, 0x0b, 0x84, 0x0b, 0x84,
+ },
+ },
+ {
+ .dcs = 0x00, /* Default GSM 7-bit alphabet */
+ .length = 160, /* maximum, in septets */
+ .filler_byte = 0x41,
+ },
+ {
+ .dcs = 0x04, /* 8-bit data */
+ .length = 140, /* maximum, in octets */
+ .filler_byte = 0x42,
+ },
+ {
+ .dcs = 0x00, /* Default GSM 7-bit alphabet */
+ .length = 200, /* invalid, buffer overflow */
+ .filler_byte = 0x41,
+ },
+ {
+ .dcs = 0x04, /* 8-bit data */
+ .length = 0xff, /* invalid, buffer overflow */
+ .filler_byte = 0x42,
+ },
+};
+
+#define SMS_ADDR(addr) \
+ { 0x00, 0x00, addr }
+
+static struct sms_test {
+ /* Human-readable name of particular test message */
+ const char *name;
+ /* Whether we expect db_sms_store() to fail */
+ bool exp_db_sms_store_fail;
+ /* Whether we expect db_sms_get() to fail */
+ bool exp_db_sms_get_fail;
+ /* SM TP-User-Data from sms_tp_ud_set[] */
+ const struct sms_tp_ud *ud;
+ /* The message itself */
+ struct gsm_sms sms;
+} sms_test_set[] = {
+ {
+ .name = "Regular MO SMS",
+ .sms = {
+ .msg_ref = 0xde,
+ .src = SMS_ADDR("123456"),
+ .dst = SMS_ADDR("654321"),
+ .validity_minutes = 10,
+ .protocol_id = 0x00,
+ /* SM TP-User-Data is taken from sms_tp_ud_set[] */
+ },
+ .ud = &sms_tp_ud_set[0],
+ },
+ {
+ .name = "Regular MT SMS",
+ .sms = {
+ .msg_ref = 0xbe,
+ .src = SMS_ADDR("654321"),
+ .dst = SMS_ADDR("123456"),
+ .validity_minutes = 180,
+ .protocol_id = 0x00,
+ /* SM TP-User-Data is taken from sms_tp_ud_set[] */
+ },
+ .ud = &sms_tp_ud_set[1],
+ },
+ {
+ .name = "Complete TP-UD (160 septets, 7-bit encoding)",
+ .sms = {
+ .msg_ref = 0xee,
+ .src = SMS_ADDR("266753837248772"),
+ .dst = SMS_ADDR("266753837248378"),
+ .validity_minutes = 360,
+ .protocol_id = 0x00,
+ /* SM TP-User-Data is taken from sms_tp_ud_set[] */
+ },
+ .ud = &sms_tp_ud_set[3],
+ },
+ {
+ .name = "Complete TP-UD (140 octets, 8-bit encoding)",
+ .sms = {
+ .msg_ref = 0xee,
+ .src = SMS_ADDR("266753838248772"),
+ .dst = SMS_ADDR("266753838248378"),
+ .validity_minutes = 360,
+ .protocol_id = 0xaa,
+ /* SM TP-User-Data is taken from sms_tp_ud_set[] */
+ },
+ .ud = &sms_tp_ud_set[4],
+ },
+ {
+ .name = "TP-UD buffer overflow (UDH-Length > UD-Length)",
+ .sms = {
+ .msg_ref = 0x88,
+ .src = SMS_ADDR("834568373569772"),
+ .dst = SMS_ADDR("834568373569378"),
+ .validity_minutes = 200,
+ .protocol_id = 0xbb,
+ .ud_hdr_ind = 0x01,
+ /* SM TP-User-Data is taken from sms_tp_ud_set[] */
+ },
+ .ud = &sms_tp_ud_set[2],
+ },
+ {
+ .name = "Truncated TP-UD (200 septets, 7-bit encoding)",
+ .sms = {
+ .msg_ref = 0xee,
+ .src = { 0x01, 0x00, "8786228337248772" },
+ .dst = { 0x00, 0x01, "8786228337248378" },
+ .validity_minutes = 360,
+ .protocol_id = 0xcc,
+ /* SM TP-User-Data is taken from sms_tp_ud_set[] */
+ },
+ .ud = &sms_tp_ud_set[5],
+ },
+ {
+ .name = "Truncated TP-UD (255 octets, 8-bit encoding)",
+ .sms = {
+ .msg_ref = 0xee,
+ .src = { 0x01, 0x01, "8786228338248772" },
+ .dst = { 0xaa, 0xff, "8786228338248378" },
+ .validity_minutes = 360,
+ .protocol_id = 0xbb,
+ /* SM TP-User-Data is taken from sms_tp_ud_set[] */
+ },
+ .ud = &sms_tp_ud_set[6],
+ },
+ {
+ .name = "Same MSISDN #1",
+ .sms = {
+ .msg_ref = 0x11,
+ .src = SMS_ADDR("72631"),
+ .dst = SMS_ADDR("72632"),
+ .validity_minutes = 10,
+ /* SM TP-User-Data is taken from sms_tp_ud_set[] */
+ },
+ .ud = &sms_tp_ud_set[0],
+ },
+ {
+ .name = "Same MSISDN #2",
+ .sms = {
+ .msg_ref = 0x12,
+ .src = SMS_ADDR("72632"),
+ .dst = SMS_ADDR("72631"),
+ .validity_minutes = 10,
+ /* SM TP-User-Data is taken from sms_tp_ud_set[] */
+ },
+ .ud = &sms_tp_ud_set[0],
+ },
+ {
+ .name = "Expired SMS",
+ .sms = {
+ .msg_ref = 0xde,
+ .src = SMS_ADDR("3974733772"),
+ .dst = SMS_ADDR("3974733378"),
+ .validity_minutes = 0,
+ /* SM TP-User-Data is taken from sms_tp_ud_set[] */
+ },
+ .ud = &sms_tp_ud_set[0],
+ },
+ {
+ .name = "Empty TP-UD",
+ .sms = {
+ .msg_ref = 0x38,
+ .src = SMS_ADDR("3678983772"),
+ .dst = SMS_ADDR("3678983378"),
+ .validity_minutes = 450,
+ .is_report = true,
+ .reply_path_req = 0x01,
+ .status_rep_req = 0x01,
+ .protocol_id = 0x55,
+ .data_coding_scheme = 0x08,
+ .ud_hdr_ind = 0x00,
+ .user_data_len = 0x00,
+ /* No TP-User-Data */
+ },
+ .ud = NULL,
+ },
+};
+
+static void prepare_sms_test_set(void)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(sms_test_set); i++) {
+ struct sms_test *test = &sms_test_set[i];
+ const struct sms_tp_ud *ud = test->ud;
+
+ /* ID auto-increment */
+ test->sms.id = i + 1;
+
+ if (ud == NULL)
+ continue;
+
+ test->sms.data_coding_scheme = ud->dcs;
+ test->sms.user_data_len = ud->length;
+
+ if (ud->filler_byte) {
+ memset(test->sms.user_data, ud->filler_byte,
+ sizeof(test->sms.user_data));
+ } else {
+ memcpy(test->sms.user_data, ud->data, sizeof(ud->data));
+ if (ud->dec_text[0] != '\0')
+ strcpy(test->sms.text, ud->dec_text);
+ }
+ }
+}
+
+static void test_db_sms_store(void)
+{
+ int rc, i;
+
+ LOGP(DDB, LOGL_INFO, "Testing db_sms_store()...\n");
+
+ /* Store test SMS messages */
+ for (i = 0; i < ARRAY_SIZE(sms_test_set); i++) {
+ struct sms_test *test = &sms_test_set[i];
+
+ LOGP(DDB, LOGL_NOTICE, "%s('%s'): ", __func__, test->name);
+
+ rc = db_sms_store(&test->sms);
+ if (!test->exp_db_sms_store_fail && rc == 0)
+ LOGPC(DDB, LOGL_INFO, "success, as expected\n");
+ else if (test->exp_db_sms_store_fail && rc != 0)
+ LOGPC(DDB, LOGL_INFO, "failure, as expected\n");
+ else
+ LOGPC(DDB, LOGL_ERROR, "unexpected rc=%d\n", rc);
+ }
+}
+
+static int verify_sms(const struct sms_test *test, const struct gsm_sms *sms)
+{
+ int rc;
+
+ LOGP(DDB, LOGL_NOTICE, "%s('%s'): ", __func__, test->name);
+
+#define MATCH_SMS_ADDR(ADDR) \
+ if (strcmp(sms->ADDR.addr, test->sms.ADDR.addr) \
+ || sms->ADDR.npi != test->sms.ADDR.npi \
+ || sms->ADDR.ton != test->sms.ADDR.ton) { \
+ LOGPC(DDB, LOGL_ERROR, #ADDR " address mismatch\n"); \
+ return -EINVAL; \
+ }
+
+ MATCH_SMS_ADDR(src);
+ MATCH_SMS_ADDR(dst);
+
+#define MATCH_SMS_PARAM(PARAM, FMT) \
+ if (sms->PARAM != test->sms.PARAM) { \
+ LOGPC(DDB, LOGL_ERROR, \
+ #PARAM " mismatch: E%" FMT " vs A%" FMT "\n", \
+ test->sms.PARAM, sms->PARAM); \
+ return -EINVAL; \
+ }
+
+ MATCH_SMS_PARAM(id, "llu");
+ MATCH_SMS_PARAM(validity_minutes, "lu");
+ MATCH_SMS_PARAM(is_report, "i");
+ MATCH_SMS_PARAM(reply_path_req, PRIu8);
+ MATCH_SMS_PARAM(status_rep_req, PRIu8);
+ MATCH_SMS_PARAM(ud_hdr_ind, PRIu8);
+ MATCH_SMS_PARAM(protocol_id, PRIu8);
+ MATCH_SMS_PARAM(data_coding_scheme, PRIu8);
+ MATCH_SMS_PARAM(msg_ref, PRIu8);
+ MATCH_SMS_PARAM(user_data_len, PRIu8);
+
+ /* Compare TP-User-Data */
+ rc = memcmp(sms->user_data, test->sms.user_data,
+ sizeof(sms->user_data));
+ if (rc) {
+ LOGPC(DDB, LOGL_ERROR, "TP-User-Data mismatch\n");
+ return -EINVAL;
+ }
+
+ /* Compare decoded text */
+ rc = strncmp(sms->text, test->sms.text, sizeof(sms->text));
+ if (rc) {
+ LOGPC(DDB, LOGL_ERROR, "TP-User-Data (text) mismatch\n");
+ return -EINVAL;
+ }
+
+ LOGPC(DDB, LOGL_NOTICE, "match\n");
+ return 0;
+}
+
+static void test_db_sms_get(void)
+{
+ struct gsm_sms *sms;
+ int i;
+
+ LOGP(DDB, LOGL_INFO, "Testing db_sms_get()...\n");
+
+ /* Retrieve stored SMS messages */
+ for (i = 0; i < ARRAY_SIZE(sms_test_set); i++) {
+ const struct sms_test *test = &sms_test_set[i];
+
+ LOGP(DDB, LOGL_NOTICE, "%s('%s'): ", __func__, test->name);
+
+ sms = db_sms_get(NULL, test->sms.id);
+ if (!test->exp_db_sms_get_fail && sms != NULL)
+ LOGPC(DDB, LOGL_INFO, "success, as expected\n");
+ else if (test->exp_db_sms_get_fail && sms == NULL)
+ LOGPC(DDB, LOGL_INFO, "failure, as expected\n");
+ else
+ LOGPC(DDB, LOGL_ERROR, "unexpected result\n");
+
+ if (sms) {
+ verify_sms(test, sms);
+ talloc_free(sms);
+ }
+ }
+}
+
+static void test_db_sms_delivery(void)
+{
+ struct gsm_sms *sms1, *sms2;
+ struct gsm_sms *sms;
+ int rc;
+
+ LOGP(DDB, LOGL_INFO, "Testing db_sms_get_next_unsent() "
+ "and db_sms_mark_delivered()...\n");
+
+ /* Retrieve both #1 and #2 */
+ sms1 = db_sms_get_next_unsent(NULL, 1, 0);
+ LOGP(DDB, LOGL_NOTICE, "db_sms_get_next_unsent(#1): %s\n",
+ sms1 ? "found" : "not found");
+ if (sms1 != NULL)
+ verify_sms(&sms_test_set[0], sms1);
+
+ sms2 = db_sms_get_next_unsent(NULL, 2, 0);
+ LOGP(DDB, LOGL_NOTICE, "db_sms_get_next_unsent(#2): %s\n",
+ sms2 ? "found" : "not found");
+ if (sms2 != NULL)
+ verify_sms(&sms_test_set[1], sms2);
+
+ /* Mark both #1 and #2 and delivered, release memory */
+ if (sms1) {
+ LOGP(DDB, LOGL_DEBUG, "Marking #%llu as delivered: ", sms1->id);
+ rc = db_sms_mark_delivered(sms1);
+ LOGPC(DDB, LOGL_DEBUG, "rc=%d\n", rc);
+ talloc_free(sms1);
+ }
+
+ if (sms2) {
+ LOGP(DDB, LOGL_DEBUG, "Marking #%llu as delivered: ", sms2->id);
+ rc = db_sms_mark_delivered(sms2);
+ LOGPC(DDB, LOGL_DEBUG, "rc=%d\n", rc);
+ talloc_free(sms2);
+ }
+
+ /* Expect #3 as the next undelivered */
+ sms = db_sms_get_next_unsent(NULL, 1, 0);
+ LOGP(DDB, LOGL_NOTICE, "db_sms_get_next_unsent(starting from #1): %s\n",
+ sms ? "found" : "not found");
+ if (sms) {
+ verify_sms(&sms_test_set[2], sms);
+ talloc_free(sms);
+ }
+}
+
+static void test_db_sms_delete(void)
+{
+ int rc;
+
+ LOGP(DDB, LOGL_INFO, "Testing db_sms_delete_sent_message_by_id()...\n");
+
+ /* Delete #1, which is marked as sent */
+ LOGP(DDB, LOGL_NOTICE, "db_sms_delete_sent_message_by_id(#1, sent): ");
+ rc = db_sms_delete_sent_message_by_id(1);
+ LOGPC(DDB, LOGL_NOTICE, "rc=%d\n", rc);
+ /* Don't expect to retrieve this message anymore */
+ sms_test_set[0].exp_db_sms_get_fail = true;
+
+ /* Try to delete #3, which is not marked as sent */
+ LOGP(DDB, LOGL_NOTICE, "db_sms_delete_sent_message_by_id(#3, not sent): ");
+ rc = db_sms_delete_sent_message_by_id(3);
+ LOGPC(DDB, LOGL_NOTICE, "rc=%d\n", rc);
+ /* Do expect to retrieve this message anyway */
+ sms_test_set[2].exp_db_sms_get_fail = false;
+
+ LOGP(DDB, LOGL_INFO, "Testing db_sms_delete_by_msisdn()...\n");
+
+ LOGP(DDB, LOGL_NOTICE, "db_sms_delete_by_msisdn('72631'): ");
+ rc = db_sms_delete_by_msisdn("72631");
+ LOGPC(DDB, LOGL_NOTICE, "rc=%d\n", rc);
+
+ /* Don't expect both #8 and #9 anymore */
+ sms_test_set[7].exp_db_sms_get_fail = true;
+ sms_test_set[8].exp_db_sms_get_fail = true;
+
+ LOGP(DDB, LOGL_INFO, "Testing db_sms_delete_oldest_expired_message()...\n");
+
+ LOGP(DDB, LOGL_NOTICE, "db_sms_delete_oldest_expired_message()\n");
+ db_sms_delete_oldest_expired_message();
+
+ /* Don't expect #10 anymore */
+ sms_test_set[9].exp_db_sms_get_fail = true;
+
+ /* We need to make sure that we removed exactly what we expected to remove */
+ LOGP(DDB, LOGL_INFO, "Expectations updated, retrieving all messages again\n");
+ test_db_sms_get();
+}
+
+static struct log_info_cat db_sms_test_categories[] = {
+ [DDB] = {
+ .name = "DDB",
+ .description = "Database Layer",
+ .enabled = 1, .loglevel = LOGL_DEBUG,
+ },
+};
+
+static struct log_info info = {
+ .cat = db_sms_test_categories,
+ .num_cat = ARRAY_SIZE(db_sms_test_categories),
+};
+
+int main(int argc, char **argv)
+{
+ void *logging_ctx;
+ int rc;
+
+ /* Track the use of talloc NULL memory contexts */
+ talloc_enable_null_tracking();
+
+ talloc_ctx = talloc_named_const(NULL, 0, "db_sms_test");
+ logging_ctx = talloc_named_const(talloc_ctx, 0, "logging");
+ osmo_init_logging2(logging_ctx, &info);
+
+ OSMO_ASSERT(osmo_stderr_target);
+ log_set_use_color(osmo_stderr_target, 0);
+ log_set_print_timestamp(osmo_stderr_target, 0);
+ log_set_print_filename2(osmo_stderr_target, LOG_FILENAME_NONE);
+ log_set_print_category_hex(osmo_stderr_target, 0);
+ log_set_print_category(osmo_stderr_target, 1);
+ log_set_print_level(osmo_stderr_target, 1);
+
+#if 0
+ /* Having the database stored in a regular file may be useful
+ * for debugging, but this comes at the price of performance. */
+ FILE *dbf = fopen("db_sms_test.db", "wb");
+ OSMO_ASSERT(dbf != NULL);
+ fclose(dbf);
+#endif
+
+ /* Init a volatile database in RAM */
+ LOGP(DDB, LOGL_DEBUG, "Init a new database\n");
+
+ /* HACK: db_init() prints libdbi version using LOGL_NOTICE, so
+ * the test output is not deterministic. Let's suppress this
+ * message by increasing the log level to LOGL_ERROR. */
+ log_parse_category_mask(osmo_stderr_target, "DDB,7");
+ rc = db_init(talloc_ctx, ":memory:", true);
+ OSMO_ASSERT(rc == 0);
+
+ /* HACK: relax log level back to LOGL_DEBUG (see note above) */
+ log_parse_category_mask(osmo_stderr_target, "DDB,1");
+
+ /* Prepare some tables */
+ rc = db_prepare();
+ OSMO_ASSERT(rc == 0);
+ LOGP(DDB, LOGL_DEBUG, "Init complete\n");
+
+ /* Prepare the test set */
+ prepare_sms_test_set();
+
+ test_db_sms_store();
+ test_db_sms_get();
+
+ test_db_sms_delivery();
+ test_db_sms_delete();
+
+ /* Close the database */
+ db_fini();
+
+ /* Deinit logging */
+ log_fini();
+
+ /* Check for memory leaks */
+ rc = talloc_total_blocks(talloc_ctx);
+ OSMO_ASSERT(rc == 2); /* db_sms_test + logging */
+ talloc_free(talloc_ctx);
+
+ talloc_report_full(NULL, stderr);
+ talloc_disable_null_tracking();
+
+ return 0;
+}
diff --git a/tests/db_sms/db_sms_test.err b/tests/db_sms/db_sms_test.err
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/tests/db_sms/db_sms_test.err
diff --git a/tests/db_sms/db_sms_test.ok b/tests/db_sms/db_sms_test.ok
new file mode 100644
index 000000000..486dcc356
--- /dev/null
+++ b/tests/db_sms/db_sms_test.ok
@@ -0,0 +1,74 @@
+DDB DEBUG Init a new database
+DDB DEBUG Init complete
+DDB INFO Testing db_sms_store()...
+DDB NOTICE test_db_sms_store('Regular MO SMS'): success, as expected
+DDB NOTICE test_db_sms_store('Regular MT SMS'): success, as expected
+DDB NOTICE test_db_sms_store('Complete TP-UD (160 septets, 7-bit encoding)'): success, as expected
+DDB NOTICE test_db_sms_store('Complete TP-UD (140 octets, 8-bit encoding)'): success, as expected
+DDB NOTICE test_db_sms_store('TP-UD buffer overflow (UDH-Length > UD-Length)'): success, as expected
+DDB NOTICE test_db_sms_store('Truncated TP-UD (200 septets, 7-bit encoding)'): success, as expected
+DDB NOTICE test_db_sms_store('Truncated TP-UD (255 octets, 8-bit encoding)'): success, as expected
+DDB NOTICE test_db_sms_store('Same MSISDN #1'): success, as expected
+DDB NOTICE test_db_sms_store('Same MSISDN #2'): success, as expected
+DDB NOTICE test_db_sms_store('Expired SMS'): success, as expected
+DDB NOTICE test_db_sms_store('Empty TP-UD'): success, as expected
+DDB INFO Testing db_sms_get()...
+DDB NOTICE test_db_sms_get('Regular MO SMS'): success, as expected
+DDB NOTICE verify_sms('Regular MO SMS'): match
+DDB NOTICE test_db_sms_get('Regular MT SMS'): success, as expected
+DDB NOTICE verify_sms('Regular MT SMS'): match
+DDB NOTICE test_db_sms_get('Complete TP-UD (160 septets, 7-bit encoding)'): success, as expected
+DDB NOTICE verify_sms('Complete TP-UD (160 septets, 7-bit encoding)'): TP-User-Data mismatch
+DDB NOTICE test_db_sms_get('Complete TP-UD (140 octets, 8-bit encoding)'): success, as expected
+DDB NOTICE verify_sms('Complete TP-UD (140 octets, 8-bit encoding)'): TP-User-Data mismatch
+DDB NOTICE test_db_sms_get('TP-UD buffer overflow (UDH-Length > UD-Length)'): success, as expected
+DDB NOTICE verify_sms('TP-UD buffer overflow (UDH-Length > UD-Length)'): match
+DDB NOTICE test_db_sms_get('Truncated TP-UD (200 septets, 7-bit encoding)'): success, as expected
+DDB NOTICE verify_sms('Truncated TP-UD (200 septets, 7-bit encoding)'): TP-User-Data mismatch
+DDB NOTICE test_db_sms_get('Truncated TP-UD (255 octets, 8-bit encoding)'): success, as expected
+DDB NOTICE verify_sms('Truncated TP-UD (255 octets, 8-bit encoding)'): TP-User-Data mismatch
+DDB NOTICE test_db_sms_get('Same MSISDN #1'): success, as expected
+DDB NOTICE verify_sms('Same MSISDN #1'): match
+DDB NOTICE test_db_sms_get('Same MSISDN #2'): success, as expected
+DDB NOTICE verify_sms('Same MSISDN #2'): match
+DDB NOTICE test_db_sms_get('Expired SMS'): success, as expected
+DDB NOTICE verify_sms('Expired SMS'): match
+DDB NOTICE test_db_sms_get('Empty TP-UD'): success, as expected
+DDB NOTICE verify_sms('Empty TP-UD'): match
+DDB INFO Testing db_sms_get_next_unsent() and db_sms_mark_delivered()...
+DDB NOTICE db_sms_get_next_unsent(#1): found
+DDB NOTICE verify_sms('Regular MO SMS'): match
+DDB NOTICE db_sms_get_next_unsent(#2): found
+DDB NOTICE verify_sms('Regular MT SMS'): match
+DDB DEBUG Marking #1 as delivered: rc=0
+DDB DEBUG Marking #2 as delivered: rc=0
+DDB NOTICE db_sms_get_next_unsent(starting from #1): found
+DDB NOTICE verify_sms('Complete TP-UD (160 septets, 7-bit encoding)'): TP-User-Data mismatch
+DDB INFO Testing db_sms_delete_sent_message_by_id()...
+DDB NOTICE db_sms_delete_sent_message_by_id(#1, sent): rc=0
+DDB NOTICE db_sms_delete_sent_message_by_id(#3, not sent): rc=0
+DDB INFO Testing db_sms_delete_by_msisdn()...
+DDB NOTICE db_sms_delete_by_msisdn('72631'): rc=0
+DDB INFO Testing db_sms_delete_oldest_expired_message()...
+DDB NOTICE db_sms_delete_oldest_expired_message()
+DDB INFO Expectations updated, retrieving all messages again
+DDB INFO Testing db_sms_get()...
+DDB NOTICE test_db_sms_get('Regular MO SMS'): failure, as expected
+DDB NOTICE test_db_sms_get('Regular MT SMS'): success, as expected
+DDB NOTICE verify_sms('Regular MT SMS'): match
+DDB NOTICE test_db_sms_get('Complete TP-UD (160 septets, 7-bit encoding)'): success, as expected
+DDB NOTICE verify_sms('Complete TP-UD (160 septets, 7-bit encoding)'): TP-User-Data mismatch
+DDB NOTICE test_db_sms_get('Complete TP-UD (140 octets, 8-bit encoding)'): success, as expected
+DDB NOTICE verify_sms('Complete TP-UD (140 octets, 8-bit encoding)'): TP-User-Data mismatch
+DDB NOTICE test_db_sms_get('TP-UD buffer overflow (UDH-Length > UD-Length)'): success, as expected
+DDB NOTICE verify_sms('TP-UD buffer overflow (UDH-Length > UD-Length)'): match
+DDB NOTICE test_db_sms_get('Truncated TP-UD (200 septets, 7-bit encoding)'): success, as expected
+DDB NOTICE verify_sms('Truncated TP-UD (200 septets, 7-bit encoding)'): TP-User-Data mismatch
+DDB NOTICE test_db_sms_get('Truncated TP-UD (255 octets, 8-bit encoding)'): success, as expected
+DDB NOTICE verify_sms('Truncated TP-UD (255 octets, 8-bit encoding)'): TP-User-Data mismatch
+DDB NOTICE test_db_sms_get('Same MSISDN #1'): failure, as expected
+DDB NOTICE test_db_sms_get('Same MSISDN #2'): failure, as expected
+DDB NOTICE test_db_sms_get('Expired SMS'): failure, as expected
+DDB NOTICE test_db_sms_get('Empty TP-UD'): success, as expected
+DDB NOTICE verify_sms('Empty TP-UD'): match
+full talloc report on 'null_context' (total 0 bytes in 1 blocks)
diff --git a/tests/mncc/Makefile.am b/tests/mncc/Makefile.am
new file mode 100644
index 000000000..a4c296008
--- /dev/null
+++ b/tests/mncc/Makefile.am
@@ -0,0 +1,37 @@
+AM_CPPFLAGS = \
+ $(all_includes) \
+ -I$(top_srcdir)/include \
+ $(NULL)
+
+AM_CFLAGS = \
+ -Wall \
+ -ggdb3 \
+ $(LIBOSMOCORE_CFLAGS) \
+ $(NULL)
+
+AM_LDFLAGS = \
+ $(COVERAGE_LDFLAGS) \
+ -no-install \
+ $(NULL)
+
+LDADD = \
+ $(top_builddir)/src/libmsc/libmsc.a \
+ $(LIBOSMOCORE_LIBS) \
+ $(NULL)
+
+EXTRA_DIST = \
+ mncc_test.ok \
+ mncc_test.err \
+ $(NULL)
+
+check_PROGRAMS = \
+ mncc_test \
+ $(NULL)
+
+mncc_test_SOURCES = \
+ mncc_test.c \
+ $(NULL)
+
+.PHONY: update_exp
+update_exp:
+ $(builddir)/mncc_test >$(srcdir)/mncc_test.ok 2>$(srcdir)/mncc_test.err
diff --git a/tests/mncc/mncc_test.c b/tests/mncc/mncc_test.c
new file mode 100644
index 000000000..9532846f4
--- /dev/null
+++ b/tests/mncc/mncc_test.c
@@ -0,0 +1,79 @@
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <osmocom/core/application.h>
+#include <osmocom/core/logging.h>
+#include <osmocom/msc/debug.h>
+#include <osmocom/msc/mncc.h>
+
+#define _test_sdp_termination(LABEL, MNCC, MNCC_MSG_LEN, RC) do { \
+ int sdp_len = ((int)(MNCC_MSG_LEN)) - ((MNCC)->sdp - (char*)MNCC); \
+ size_t sdp_strlen = strnlen(MNCC->sdp, sizeof(MNCC->sdp)); \
+ int rc = mncc_check_sdp_termination("<" LABEL ">", (struct gsm_mncc*)MNCC, MNCC_MSG_LEN, MNCC->sdp); \
+ printf("%s: len=%d sdplen=%d sdp=%s rc=%d\n", \
+ LABEL, (int)(MNCC_MSG_LEN), sdp_len, \
+ sdp_len > 0? osmo_quote_str((MNCC)->sdp, OSMO_MIN(sdp_len, sdp_strlen+1)) : "-", rc); \
+ if (RC != rc) \
+ printf("ERROR!\n"); \
+ } while (0)
+
+#define test_sdp_termination_cases(MNCC) \
+ _test_sdp_termination("empty SDP", MNCC, sizeof(*MNCC), 0); \
+ _test_sdp_termination("empty SDP, shortest possible", MNCC, MNCC->sdp - ((char*)MNCC) + 1, 0); \
+ _test_sdp_termination("empty SDP, zero len", MNCC, MNCC->sdp - ((char*)MNCC), -EINVAL); \
+ OSMO_STRLCPY_ARRAY(MNCC->sdp, "Privacy is a desirable marketing option"); \
+ _test_sdp_termination("terminated SDP str", MNCC, sizeof(*MNCC), 0); \
+ _test_sdp_termination("terminated SDP str, shortest possible", MNCC, \
+ MNCC->sdp - ((char*)MNCC) + strlen(MNCC->sdp) + 1, 0); \
+ _test_sdp_termination("terminated SDP str, but len excludes nul", MNCC, \
+ MNCC->sdp - ((char*)MNCC) + strlen(MNCC->sdp), -EINVAL); \
+ _test_sdp_termination("terminated SDP str, but len too short", MNCC, \
+ MNCC->sdp - ((char*)MNCC) + 23, -EINVAL); \
+ _test_sdp_termination("len way too short", MNCC, 10, -EINVAL); \
+ _test_sdp_termination("len zero", MNCC, 0, -EINVAL);
+
+
+void test_sdp_termination(void)
+{
+ struct gsm_mncc _mncc = {};
+ struct gsm_mncc_rtp _mncc_rtp = {};
+
+ struct gsm_mncc *mncc = &_mncc;
+ struct gsm_mncc_rtp *mncc_rtp = &_mncc_rtp;
+
+ printf("%s()\n", __func__);
+ printf("\nstruct gsm_mncc:\n");
+ test_sdp_termination_cases(mncc);
+
+ _mncc = (struct gsm_mncc){};
+ _mncc_rtp = (struct gsm_mncc_rtp){};
+ printf("\nstruct gsm_mncc_rtp:\n");
+ test_sdp_termination_cases(mncc_rtp);
+}
+
+static const struct log_info_cat default_categories[] = {
+ [DMNCC] = {
+ .name = "DMNCC",
+ .description = "MNCC API for Call Control application",
+ .color = "\033[1;39m",
+ .enabled = 1, .loglevel = LOGL_NOTICE,
+ },
+};
+
+const struct log_info log_info = {
+ .cat = default_categories,
+ .num_cat = ARRAY_SIZE(default_categories),
+};
+
+int main(void)
+{
+ void *ctx = talloc_named_const(NULL, 0, "mncc_test");
+ osmo_init_logging2(ctx, &log_info);
+ log_set_use_color(osmo_stderr_target, 0);
+ log_set_print_filename2(osmo_stderr_target, LOG_FILENAME_NONE);
+ log_set_print_category(osmo_stderr_target, 1);
+ log_set_print_category_hex(osmo_stderr_target, 0);
+
+ test_sdp_termination();
+ return 0;
+}
diff --git a/tests/mncc/mncc_test.err b/tests/mncc/mncc_test.err
new file mode 100644
index 000000000..5ee7e2cc3
--- /dev/null
+++ b/tests/mncc/mncc_test.err
@@ -0,0 +1,10 @@
+DMNCC Short <empty SDP, zero len>
+DMNCC Short <terminated SDP str, but len excludes nul>
+DMNCC Short <terminated SDP str, but len too short>
+DMNCC Short <len way too short>
+DMNCC Short <len zero>
+DMNCC Short <empty SDP, zero len>
+DMNCC Short <terminated SDP str, but len excludes nul>
+DMNCC Short <terminated SDP str, but len too short>
+DMNCC Short <len way too short>
+DMNCC Short <len zero>
diff --git a/tests/mncc/mncc_test.ok b/tests/mncc/mncc_test.ok
new file mode 100644
index 000000000..ca3ac6484
--- /dev/null
+++ b/tests/mncc/mncc_test.ok
@@ -0,0 +1,23 @@
+test_sdp_termination()
+
+struct gsm_mncc:
+empty SDP: len=1896 sdplen=1046 sdp="\0" rc=0
+empty SDP, shortest possible: len=851 sdplen=1 sdp="\0" rc=0
+empty SDP, zero len: len=850 sdplen=0 sdp=- rc=-22
+terminated SDP str: len=1896 sdplen=1046 sdp="Privacy is a desirable marketing option\0" rc=0
+terminated SDP str, shortest possible: len=890 sdplen=40 sdp="Privacy is a desirable marketing option\0" rc=0
+terminated SDP str, but len excludes nul: len=889 sdplen=39 sdp="Privacy is a desirable marketing option" rc=-22
+terminated SDP str, but len too short: len=873 sdplen=23 sdp="Privacy is a desirable " rc=-22
+len way too short: len=10 sdplen=-840 sdp=- rc=-22
+len zero: len=0 sdplen=-850 sdp=- rc=-22
+
+struct gsm_mncc_rtp:
+empty SDP: len=1168 sdplen=1024 sdp="\0" rc=0
+empty SDP, shortest possible: len=145 sdplen=1 sdp="\0" rc=0
+empty SDP, zero len: len=144 sdplen=0 sdp=- rc=-22
+terminated SDP str: len=1168 sdplen=1024 sdp="Privacy is a desirable marketing option\0" rc=0
+terminated SDP str, shortest possible: len=184 sdplen=40 sdp="Privacy is a desirable marketing option\0" rc=0
+terminated SDP str, but len excludes nul: len=183 sdplen=39 sdp="Privacy is a desirable marketing option" rc=-22
+terminated SDP str, but len too short: len=167 sdplen=23 sdp="Privacy is a desirable " rc=-22
+len way too short: len=10 sdplen=-134 sdp=- rc=-22
+len zero: len=0 sdplen=-144 sdp=- rc=-22
diff --git a/tests/msc_vlr/Makefile.am b/tests/msc_vlr/Makefile.am
index f9a922465..cbdd6a409 100644
--- a/tests/msc_vlr/Makefile.am
+++ b/tests/msc_vlr/Makefile.am
@@ -8,14 +8,15 @@ AM_CFLAGS = \
-ggdb3 \
$(LIBOSMOCORE_CFLAGS) \
$(LIBOSMOGSM_CFLAGS) \
- $(LIBSMPP34_CFLAGS) \
$(LIBOSMOVTY_CFLAGS) \
$(LIBOSMOABIS_CFLAGS) \
$(LIBOSMOSIGTRAN_CFLAGS) \
$(LIBOSMORANAP_CFLAGS) \
+ $(LIBOSMONETIF_CFLAGS) \
$(LIBASN1C_CFLAGS) \
$(LIBOSMOMGCPCLIENT_CFLAGS) \
$(LIBOSMOGSUPCLIENT_CFLAGS) \
+ $(LIBSQLITE3_CFLAGS) \
$(NULL)
AM_LDFLAGS = \
@@ -25,12 +26,13 @@ AM_LDFLAGS = \
-Wl,--wrap=osmo_get_rand_id \
-Wl,--wrap=ran_peers_down_paging \
-Wl,--wrap=call_leg_ensure_ci \
+ $(COVERAGE_LDFLAGS) \
+ -no-install \
$(NULL)
LDADD = \
$(top_builddir)/src/libmsc/libmsc.a \
$(top_builddir)/src/libvlr/libvlr.a \
- $(LIBSMPP34_LIBS) \
$(LIBOSMOCORE_LIBS) \
$(LIBOSMOGSM_LIBS) \
$(LIBOSMOVTY_LIBS) \
@@ -40,13 +42,12 @@ LDADD = \
$(LIBASN1C_LIBS) \
$(LIBOSMOMGCPCLIENT_LIBS) \
$(LIBOSMOGSUPCLIENT_LIBS) \
+ $(LIBSQLITE3_LIBS) \
$(LIBRARY_GSM) \
- -ldbi \
$(NULL)
noinst_HEADERS = \
msc_vlr_tests.h \
- stubs.h \
$(NULL)
EXTRA_DIST = \
@@ -76,7 +77,7 @@ EXTRA_DIST = \
msc_vlr_test_ss.err \
$(NULL)
-noinst_PROGRAMS = \
+check_PROGRAMS = \
msc_vlr_test_no_authen \
msc_vlr_test_gsm_authen \
msc_vlr_test_gsm_ciph \
@@ -94,61 +95,73 @@ noinst_PROGRAMS = \
msc_vlr_test_no_authen_SOURCES = \
msc_vlr_test_no_authen.c \
msc_vlr_tests.c \
+ $(srcdir)/../stubs.c \
$(NULL)
msc_vlr_test_gsm_authen_SOURCES = \
msc_vlr_test_gsm_authen.c \
msc_vlr_tests.c \
+ $(srcdir)/../stubs.c \
$(NULL)
msc_vlr_test_gsm_ciph_SOURCES = \
msc_vlr_test_gsm_ciph.c \
msc_vlr_tests.c \
+ $(srcdir)/../stubs.c \
$(NULL)
msc_vlr_test_umts_authen_SOURCES = \
msc_vlr_test_umts_authen.c \
msc_vlr_tests.c \
+ $(srcdir)/../stubs.c \
$(NULL)
msc_vlr_test_authen_reuse_SOURCES = \
msc_vlr_test_authen_reuse.c \
msc_vlr_tests.c \
+ $(srcdir)/../stubs.c \
$(NULL)
msc_vlr_test_hlr_reject_SOURCES = \
msc_vlr_test_hlr_reject.c \
msc_vlr_tests.c \
+ $(srcdir)/../stubs.c \
$(NULL)
msc_vlr_test_hlr_timeout_SOURCES = \
msc_vlr_test_hlr_timeout.c \
msc_vlr_tests.c \
+ $(srcdir)/../stubs.c \
$(NULL)
msc_vlr_test_ms_timeout_SOURCES = \
msc_vlr_test_ms_timeout.c \
msc_vlr_tests.c \
+ $(srcdir)/../stubs.c \
$(NULL)
msc_vlr_test_reject_concurrency_SOURCES = \
msc_vlr_test_reject_concurrency.c \
msc_vlr_tests.c \
+ $(srcdir)/../stubs.c \
$(NULL)
msc_vlr_test_call_SOURCES = \
msc_vlr_test_call.c \
msc_vlr_tests.c \
+ $(srcdir)/../stubs.c \
$(NULL)
msc_vlr_test_rest_SOURCES = \
msc_vlr_test_rest.c \
msc_vlr_tests.c \
+ $(srcdir)/../stubs.c \
$(NULL)
msc_vlr_test_ss_SOURCES = \
msc_vlr_test_ss.c \
msc_vlr_tests.c \
+ $(srcdir)/../stubs.c \
$(NULL)
.PHONY: update_exp
diff --git a/tests/msc_vlr/msc_vlr_test_authen_reuse.c b/tests/msc_vlr/msc_vlr_test_authen_reuse.c
index 9eadec7f9..870f99369 100644
--- a/tests/msc_vlr/msc_vlr_test_authen_reuse.c
+++ b/tests/msc_vlr/msc_vlr_test_authen_reuse.c
@@ -24,7 +24,6 @@
/* NOTE that further auth re-use tests exist in msc_vlr_test_hlr_reject.c */
#include "msc_vlr_tests.h"
-#include "stubs.h"
static void _test_auth_reuse(enum osmo_rat_type via_ran,
int set_max_reuse_count,
@@ -44,7 +43,7 @@ static void _test_auth_reuse(enum osmo_rat_type via_ran,
btw("Location Update request causes a GSUP Send Auth Info request to HLR");
lu_result_sent = RES_NONE;
- gsup_expect_tx("080108" "09710000000156f0" VLR_TO_HLR);
+ gsup_expect_tx("080108" "09710000000156f0" CN_DOMAIN VLR_TO_HLR);
ms_sends_msg("0508" /* MM LU */
"7" /* ciph key seq: no key available */
"0" /* LU type: normal */
@@ -86,7 +85,7 @@ static void _test_auth_reuse(enum osmo_rat_type via_ran,
if (via_ran == OSMO_RAT_GERAN_A) {
btw("MS sends Authen Response, VLR accepts and sends GSUP LU Req to HLR");
- gsup_expect_tx("04010809710000000156f0280102" VLR_TO_HLR);
+ gsup_expect_tx("04010809710000000156f0" CN_DOMAIN VLR_TO_HLR);
ms_sends_msg("0554" "e229c19e" "2104" "791f2e41");
VERBOSE_ASSERT(gsup_tx_confirmed, == true, "%d");
VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
@@ -99,8 +98,8 @@ static void _test_auth_reuse(enum osmo_rat_type via_ran,
VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
btw("MS sends SecurityModeControl acceptance, VLR accepts and sends GSUP LU Req to HLR");
- gsup_expect_tx("04010809710000000156f0280102" VLR_TO_HLR);
- ms_sends_security_mode_complete();
+ gsup_expect_tx("04010809710000000156f0" CN_DOMAIN VLR_TO_HLR);
+ ms_sends_security_mode_complete(1);
VERBOSE_ASSERT(gsup_tx_confirmed, == true, "%d");
VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
}
@@ -171,7 +170,7 @@ static void _test_auth_reuse(enum osmo_rat_type via_ran,
VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d");
btw("MS sends SecurityModeControl acceptance, VLR accepts; above Ciphering is an implicit CM Service Accept");
- ms_sends_security_mode_complete();
+ ms_sends_security_mode_complete(1);
VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d");
}
@@ -196,7 +195,7 @@ static void _test_auth_reuse(enum osmo_rat_type via_ran,
" and needs to request a second auth vector from HLR");
auth_request_sent = false;
cm_service_result_sent = RES_NONE;
- gsup_expect_tx("080108" "09710000000156f0" VLR_TO_HLR);
+ gsup_expect_tx("080108" "09710000000156f0" CN_DOMAIN VLR_TO_HLR);
ms_sends_msg("052474"
"03575886" /* classmark 2 */
"089910070000106005" /* IMSI */);
@@ -240,7 +239,7 @@ static void _test_auth_reuse(enum osmo_rat_type via_ran,
VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d");
btw("MS sends SecurityModeControl acceptance, VLR accepts; above Ciphering is an implicit CM Service Accept");
- ms_sends_security_mode_complete();
+ ms_sends_security_mode_complete(1);
VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d");
}
diff --git a/tests/msc_vlr/msc_vlr_test_authen_reuse.err b/tests/msc_vlr/msc_vlr_test_authen_reuse.err
index ea156de99..1f8afb07f 100644
--- a/tests/msc_vlr/msc_vlr_test_authen_reuse.err
+++ b/tests/msc_vlr/msc_vlr_test_authen_reuse.err
@@ -1,7 +1,3 @@
-DLMGCP MGCP client: using endpoint domain '@mgw'
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 17
-
===== test_auth_use_twice_geran
- Location Update request causes a GSUP Send Auth Info request to HLR
MSC <--GERAN-A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
@@ -30,13 +26,14 @@ DREF VLR subscr IMSI-901700000010650 + active-conn: now used by 2 (_lu_fsm_assoc
DMSC msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK
DMSC msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH
DREF VLR subscr IMSI-901700000010650 - _lu_fsm_associate_vsub: now used by 1 (active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre()
DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH
DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Allocated
DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU)
DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
-GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f00a0101
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f02801020a0101
DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
DREF msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - mm_rx_loc_upd_req: now used by 2 (rx_from_ms,lu)
DREF msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu)
@@ -69,9 +66,11 @@ DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: Au
DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU)
-DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES
+DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_SUCCESS
DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth()
DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_ciph()
+DMSC msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000010650:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_node_4()
DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
DVLR upd_hlr_vlr_fsm(IMSI-901700000010650:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated
@@ -261,6 +260,8 @@ DVLR VLR_Authenticate(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:
DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: Received Event PR_ARQ_E_AUTH_RES
DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2()
DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2_post_ciph()
+DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2_post_vlr()
DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_pres()
DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_trace()
@@ -268,6 +269,7 @@ DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x0302010
DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: proc_arq_fsm_done(PASSED)
DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: state_chg to PR_ARQ_S_DONE
DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_DONE}: Process Access Request result: PASSED
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: Sending DTAP: MM GSM48_MT_MM_CM_SERV_ACC
DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN encode: DTAP on GERAN-A
- DTAP --GERAN-A--> MS: GSM48_MT_MM_CM_SERV_ACC: 0521
DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
@@ -350,7 +352,7 @@ DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x0302010
DVLR VLR_Authenticate(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){VLR_SUB_AS_NEEDS_AUTH}: Allocated
DVLR VLR_Authenticate(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){VLR_SUB_AS_NEEDS_AUTH}: is child of Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ)
DVLR VLR_Authenticate(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
-GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f00a0101
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f02801020a0101
DVLR VLR_Authenticate(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - proc_arq_vlr_fn_init: now used by 2 (attached,active-conn)
DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (cm_service_sms)
@@ -388,6 +390,8 @@ DVLR VLR_Authenticate(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:
DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: Received Event PR_ARQ_E_AUTH_RES
DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2()
DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2_post_ciph()
+DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2_post_vlr()
DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_pres()
DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_trace()
@@ -395,6 +399,7 @@ DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x0302010
DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: proc_arq_fsm_done(PASSED)
DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: state_chg to PR_ARQ_S_DONE
DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_DONE}: Process Access Request result: PASSED
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: Sending DTAP: MM GSM48_MT_MM_CM_SERV_ACC
DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN encode: DTAP on GERAN-A
- DTAP --GERAN-A--> MS: GSM48_MT_MM_CM_SERV_ACC: 0521
DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
@@ -456,12 +461,13 @@ DMSC dummy_msc_i{0}: is child of msub_fsm
DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms)
DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3
DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: MM GSM48_MT_MM_IMSI_DETACH_IND
-DMM IMSI DETACH INDICATION: MI(IMSI)=901700000010650
+DMM IMSI DETACH INDICATION: IMSI-901700000010650
DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + gsm48_rx_mm_imsi_detach_ind: now used by 2 (attached,gsm48_rx_mm_imsi_detach_ind)
DMM IMSI DETACH for IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100
DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + active-conn: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn)
DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn,vlr_subscr_cancel_attach_fsm)
DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - attached: now used by 2 (gsm48_rx_mm_imsi_detach_ind,active-conn)
DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - gsm48_rx_mm_imsi_detach_ind: now used by 1 (active-conn)
DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_CN_CLOSE
@@ -501,9 +507,6 @@ DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:NONE){MSC_A
llist_count(&msub_list) == 0
===== test_auth_use_twice_geran: SUCCESS
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 17
-
===== test_auth_use_twice_utran
- Location Update request causes a GSUP Send Auth Info request to HLR
MSC <--UTRAN-Iu-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
@@ -532,13 +535,14 @@ DREF VLR subscr IMSI-901700000010650 + active-conn: now used by 2 (_lu_fsm_assoc
DMSC msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK
DMSC msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH
DREF VLR subscr IMSI-901700000010650 - _lu_fsm_associate_vsub: now used by 1 (active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre()
DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH
DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: Allocated
DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU)
DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
-GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f00a0101
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f02801020a0101
DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
DREF msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: - mm_rx_loc_upd_req: now used by 2 (rx_from_ms,lu)
DREF msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu)
@@ -571,7 +575,7 @@ DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_WAIT_RESP}: A
DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU)
-DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES
+DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_SUCCESS
DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth()
DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: Set Ciphering Mode
DMSC msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: CIPHER_MODE_COMMAND on UTRAN-Iu
@@ -873,7 +877,7 @@ DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x0302010
DVLR VLR_Authenticate(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){VLR_SUB_AS_NEEDS_AUTH}: Allocated
DVLR VLR_Authenticate(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){VLR_SUB_AS_NEEDS_AUTH}: is child of Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ)
DVLR VLR_Authenticate(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
-GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f00a0101
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f02801020a0101
DVLR VLR_Authenticate(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - proc_arq_vlr_fn_init: now used by 2 (attached,active-conn)
DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (cm_service_sms)
@@ -988,12 +992,13 @@ DMSC dummy_msc_i{0}: is child of msub_fsm
DREF msc_a(unknown:UTRAN-Iu:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms)
DIUCS msc_a(unknown:UTRAN-Iu:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3
DRLL msc_a(unknown:UTRAN-Iu:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: MM GSM48_MT_MM_IMSI_DETACH_IND
-DMM IMSI DETACH INDICATION: MI(IMSI)=901700000010650
+DMM IMSI DETACH INDICATION: IMSI-901700000010650
DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + gsm48_rx_mm_imsi_detach_ind: now used by 2 (attached,gsm48_rx_mm_imsi_detach_ind)
DMM IMSI DETACH for IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100
DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + active-conn: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn)
DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn,vlr_subscr_cancel_attach_fsm)
DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - attached: now used by 2 (gsm48_rx_mm_imsi_detach_ind,active-conn)
DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - gsm48_rx_mm_imsi_detach_ind: now used by 1 (active-conn)
DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:NONE){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_CN_CLOSE
@@ -1033,9 +1038,6 @@ DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:NONE){MSC_
llist_count(&msub_list) == 0
===== test_auth_use_twice_utran: SUCCESS
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 17
-
===== test_auth_use_infinitely_geran
- Location Update request causes a GSUP Send Auth Info request to HLR
MSC <--GERAN-A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
@@ -1064,13 +1066,14 @@ DREF VLR subscr IMSI-901700000010650 + active-conn: now used by 2 (_lu_fsm_assoc
DMSC msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK
DMSC msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH
DREF VLR subscr IMSI-901700000010650 - _lu_fsm_associate_vsub: now used by 1 (active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre()
DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH
DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Allocated
DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU)
DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
-GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f00a0101
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f02801020a0101
DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
DREF msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - mm_rx_loc_upd_req: now used by 2 (rx_from_ms,lu)
DREF msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu)
@@ -1103,9 +1106,11 @@ DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: Au
DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU)
-DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES
+DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_SUCCESS
DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth()
DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_ciph()
+DMSC msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000010650:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_node_4()
DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
DVLR upd_hlr_vlr_fsm(IMSI-901700000010650:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated
@@ -1295,6 +1300,8 @@ DVLR VLR_Authenticate(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:
DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: Received Event PR_ARQ_E_AUTH_RES
DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2()
DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2_post_ciph()
+DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2_post_vlr()
DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_pres()
DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_trace()
@@ -1302,6 +1309,7 @@ DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x0302010
DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: proc_arq_fsm_done(PASSED)
DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: state_chg to PR_ARQ_S_DONE
DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_DONE}: Process Access Request result: PASSED
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: Sending DTAP: MM GSM48_MT_MM_CM_SERV_ACC
DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN encode: DTAP on GERAN-A
- DTAP --GERAN-A--> MS: GSM48_MT_MM_CM_SERV_ACC: 0521
DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
@@ -1410,6 +1418,8 @@ DVLR VLR_Authenticate(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:
DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: Received Event PR_ARQ_E_AUTH_RES
DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2()
DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2_post_ciph()
+DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2_post_vlr()
DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_pres()
DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_trace()
@@ -1417,6 +1427,7 @@ DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x0302010
DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: proc_arq_fsm_done(PASSED)
DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: state_chg to PR_ARQ_S_DONE
DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_DONE}: Process Access Request result: PASSED
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: Sending DTAP: MM GSM48_MT_MM_CM_SERV_ACC
DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN encode: DTAP on GERAN-A
- DTAP --GERAN-A--> MS: GSM48_MT_MM_CM_SERV_ACC: 0521
DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
@@ -1525,6 +1536,8 @@ DVLR VLR_Authenticate(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:
DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: Received Event PR_ARQ_E_AUTH_RES
DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2()
DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2_post_ciph()
+DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2_post_vlr()
DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_pres()
DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_trace()
@@ -1532,6 +1545,7 @@ DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x0302010
DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: proc_arq_fsm_done(PASSED)
DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: state_chg to PR_ARQ_S_DONE
DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_DONE}: Process Access Request result: PASSED
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: Sending DTAP: MM GSM48_MT_MM_CM_SERV_ACC
DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN encode: DTAP on GERAN-A
- DTAP --GERAN-A--> MS: GSM48_MT_MM_CM_SERV_ACC: 0521
DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
@@ -1593,12 +1607,13 @@ DMSC dummy_msc_i{0}: is child of msub_fsm
DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms)
DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3
DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: MM GSM48_MT_MM_IMSI_DETACH_IND
-DMM IMSI DETACH INDICATION: MI(IMSI)=901700000010650
+DMM IMSI DETACH INDICATION: IMSI-901700000010650
DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + gsm48_rx_mm_imsi_detach_ind: now used by 2 (attached,gsm48_rx_mm_imsi_detach_ind)
DMM IMSI DETACH for IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100
DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + active-conn: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn)
DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn,vlr_subscr_cancel_attach_fsm)
DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - attached: now used by 2 (gsm48_rx_mm_imsi_detach_ind,active-conn)
DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - gsm48_rx_mm_imsi_detach_ind: now used by 1 (active-conn)
DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_CN_CLOSE
@@ -1638,9 +1653,6 @@ DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:NONE){MSC_A
llist_count(&msub_list) == 0
===== test_auth_use_infinitely_geran: SUCCESS
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 17
-
===== test_auth_use_infinitely_utran
- Location Update request causes a GSUP Send Auth Info request to HLR
MSC <--UTRAN-Iu-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
@@ -1669,13 +1681,14 @@ DREF VLR subscr IMSI-901700000010650 + active-conn: now used by 2 (_lu_fsm_assoc
DMSC msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK
DMSC msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH
DREF VLR subscr IMSI-901700000010650 - _lu_fsm_associate_vsub: now used by 1 (active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre()
DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH
DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: Allocated
DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU)
DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
-GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f00a0101
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f02801020a0101
DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
DREF msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: - mm_rx_loc_upd_req: now used by 2 (rx_from_ms,lu)
DREF msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu)
@@ -1708,7 +1721,7 @@ DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_WAIT_RESP}: A
DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU)
-DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES
+DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_SUCCESS
DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth()
DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: Set Ciphering Mode
DMSC msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: CIPHER_MODE_COMMAND on UTRAN-Iu
@@ -2237,12 +2250,13 @@ DMSC dummy_msc_i{0}: is child of msub_fsm
DREF msc_a(unknown:UTRAN-Iu:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms)
DIUCS msc_a(unknown:UTRAN-Iu:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3
DRLL msc_a(unknown:UTRAN-Iu:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: MM GSM48_MT_MM_IMSI_DETACH_IND
-DMM IMSI DETACH INDICATION: MI(IMSI)=901700000010650
+DMM IMSI DETACH INDICATION: IMSI-901700000010650
DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + gsm48_rx_mm_imsi_detach_ind: now used by 2 (attached,gsm48_rx_mm_imsi_detach_ind)
DMM IMSI DETACH for IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100
DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + active-conn: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn)
DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn,vlr_subscr_cancel_attach_fsm)
DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - attached: now used by 2 (gsm48_rx_mm_imsi_detach_ind,active-conn)
DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - gsm48_rx_mm_imsi_detach_ind: now used by 1 (active-conn)
DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:NONE){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_CN_CLOSE
@@ -2282,9 +2296,6 @@ DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:NONE){MSC_
llist_count(&msub_list) == 0
===== test_auth_use_infinitely_utran: SUCCESS
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 17
-
===== test_no_auth_reuse_geran
- Location Update request causes a GSUP Send Auth Info request to HLR
MSC <--GERAN-A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
@@ -2313,13 +2324,14 @@ DREF VLR subscr IMSI-901700000010650 + active-conn: now used by 2 (_lu_fsm_assoc
DMSC msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK
DMSC msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH
DREF VLR subscr IMSI-901700000010650 - _lu_fsm_associate_vsub: now used by 1 (active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre()
DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH
DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Allocated
DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU)
DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
-GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f00a0101
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f02801020a0101
DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
DREF msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - mm_rx_loc_upd_req: now used by 2 (rx_from_ms,lu)
DREF msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu)
@@ -2352,9 +2364,11 @@ DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: Au
DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU)
-DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES
+DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_SUCCESS
DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth()
DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_ciph()
+DMSC msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000010650:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_node_4()
DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
DVLR upd_hlr_vlr_fsm(IMSI-901700000010650:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated
@@ -2518,7 +2532,7 @@ DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x0302010
DVLR VLR_Authenticate(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){VLR_SUB_AS_NEEDS_AUTH}: Allocated
DVLR VLR_Authenticate(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){VLR_SUB_AS_NEEDS_AUTH}: is child of Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ)
DVLR VLR_Authenticate(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
-GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f00a0101
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f02801020a0101
DVLR VLR_Authenticate(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - proc_arq_vlr_fn_init: now used by 2 (attached,active-conn)
DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (cm_service_sms)
@@ -2556,6 +2570,8 @@ DVLR VLR_Authenticate(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:
DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: Received Event PR_ARQ_E_AUTH_RES
DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2()
DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2_post_ciph()
+DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2_post_vlr()
DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_pres()
DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_trace()
@@ -2563,6 +2579,7 @@ DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x0302010
DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: proc_arq_fsm_done(PASSED)
DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: state_chg to PR_ARQ_S_DONE
DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_DONE}: Process Access Request result: PASSED
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: Sending DTAP: MM GSM48_MT_MM_CM_SERV_ACC
DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN encode: DTAP on GERAN-A
- DTAP --GERAN-A--> MS: GSM48_MT_MM_CM_SERV_ACC: 0521
DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
@@ -2624,12 +2641,13 @@ DMSC dummy_msc_i{0}: is child of msub_fsm
DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms)
DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3
DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: MM GSM48_MT_MM_IMSI_DETACH_IND
-DMM IMSI DETACH INDICATION: MI(IMSI)=901700000010650
+DMM IMSI DETACH INDICATION: IMSI-901700000010650
DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + gsm48_rx_mm_imsi_detach_ind: now used by 2 (attached,gsm48_rx_mm_imsi_detach_ind)
DMM IMSI DETACH for IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100
DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + active-conn: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn)
DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn,vlr_subscr_cancel_attach_fsm)
DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - attached: now used by 2 (gsm48_rx_mm_imsi_detach_ind,active-conn)
DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - gsm48_rx_mm_imsi_detach_ind: now used by 1 (active-conn)
DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_CN_CLOSE
@@ -2669,9 +2687,6 @@ DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:NONE){MSC_A
llist_count(&msub_list) == 0
===== test_no_auth_reuse_geran: SUCCESS
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 17
-
===== test_no_auth_reuse_utran
- Location Update request causes a GSUP Send Auth Info request to HLR
MSC <--UTRAN-Iu-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
@@ -2700,13 +2715,14 @@ DREF VLR subscr IMSI-901700000010650 + active-conn: now used by 2 (_lu_fsm_assoc
DMSC msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK
DMSC msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH
DREF VLR subscr IMSI-901700000010650 - _lu_fsm_associate_vsub: now used by 1 (active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre()
DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH
DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: Allocated
DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU)
DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
-GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f00a0101
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f02801020a0101
DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
DREF msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: - mm_rx_loc_upd_req: now used by 2 (rx_from_ms,lu)
DREF msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu)
@@ -2739,7 +2755,7 @@ DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_WAIT_RESP}: A
DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU)
-DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES
+DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_SUCCESS
DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth()
DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: Set Ciphering Mode
DMSC msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: CIPHER_MODE_COMMAND on UTRAN-Iu
@@ -2917,7 +2933,7 @@ DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x0302010
DVLR VLR_Authenticate(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){VLR_SUB_AS_NEEDS_AUTH}: Allocated
DVLR VLR_Authenticate(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){VLR_SUB_AS_NEEDS_AUTH}: is child of Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ)
DVLR VLR_Authenticate(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
-GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f00a0101
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f02801020a0101
DVLR VLR_Authenticate(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - proc_arq_vlr_fn_init: now used by 2 (attached,active-conn)
DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (cm_service_sms)
@@ -3032,12 +3048,13 @@ DMSC dummy_msc_i{0}: is child of msub_fsm
DREF msc_a(unknown:UTRAN-Iu:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms)
DIUCS msc_a(unknown:UTRAN-Iu:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3
DRLL msc_a(unknown:UTRAN-Iu:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: MM GSM48_MT_MM_IMSI_DETACH_IND
-DMM IMSI DETACH INDICATION: MI(IMSI)=901700000010650
+DMM IMSI DETACH INDICATION: IMSI-901700000010650
DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + gsm48_rx_mm_imsi_detach_ind: now used by 2 (attached,gsm48_rx_mm_imsi_detach_ind)
DMM IMSI DETACH for IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100
DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + active-conn: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn)
DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn,vlr_subscr_cancel_attach_fsm)
DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - attached: now used by 2 (gsm48_rx_mm_imsi_detach_ind,active-conn)
DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - gsm48_rx_mm_imsi_detach_ind: now used by 1 (active-conn)
DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:NONE){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_CN_CLOSE
@@ -3077,9 +3094,3 @@ DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:NONE){MSC_
llist_count(&msub_list) == 0
===== test_no_auth_reuse_utran: SUCCESS
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 17
-
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 17
-
diff --git a/tests/msc_vlr/msc_vlr_test_call.c b/tests/msc_vlr/msc_vlr_test_call.c
index b31239e48..14c8ea304 100644
--- a/tests/msc_vlr/msc_vlr_test_call.c
+++ b/tests/msc_vlr/msc_vlr_test_call.c
@@ -22,15 +22,17 @@
*/
#include "msc_vlr_tests.h"
-#include "stubs.h"
#include <osmocom/msc/gsm_04_08.h>
+#include <osmocom/msc/codec_mapping.h>
-static void mncc_sends_to_cc(uint32_t msg_type, struct gsm_mncc *mncc)
-{
- mncc->msg_type = msg_type;
- mncc_tx_to_cc(net, mncc);
-}
+#define mncc_sends_to_cc(MSG_TYPE, MNCC) do { \
+ (MNCC)->msg_type = MSG_TYPE; \
+ log("MSC <-- MNCC: callref 0x%x: %s\n%s", (MNCC)->callref, \
+ get_mncc_name((MNCC)->msg_type), \
+ (MNCC)->sdp); \
+ mncc_tx_to_cc(net, MNCC); \
+ } while(0)
/*
static void on_call_release_mncc_sends_to_cc(uint32_t msg_type, struct gsm_mncc *mncc)
@@ -42,7 +44,7 @@ static void on_call_release_mncc_sends_to_cc(uint32_t msg_type, struct gsm_mncc
#define IMSI "901700000010650"
-static void standard_lu()
+static void lu_utran_tmsi()
{
struct vlr_subscr *vsub;
@@ -52,7 +54,7 @@ static void standard_lu()
btw("Location Update request causes a GSUP Send Auth Info request to HLR");
lu_result_sent = RES_NONE;
- gsup_expect_tx("080108" "09710000000156f0" VLR_TO_HLR);
+ gsup_expect_tx("080108" "09710000000156f0" CN_DOMAIN VLR_TO_HLR);
ms_sends_msg("0508" /* MM LU */
"7" /* ciph key seq: no key available */
"0" /* LU type: normal */
@@ -126,8 +128,8 @@ static void standard_lu()
VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
btw("MS sends SecurityModeControl acceptance, VLR accepts and sends GSUP LU Req to HLR");
- gsup_expect_tx("04010809710000000156f0280102" VLR_TO_HLR);
- ms_sends_security_mode_complete();
+ gsup_expect_tx("04010809710000000156f0" CN_DOMAIN VLR_TO_HLR);
+ ms_sends_security_mode_complete(1);
VERBOSE_ASSERT(gsup_tx_confirmed, == true, "%d");
VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
@@ -162,17 +164,56 @@ static void standard_lu()
vlr_subscr_put(vsub, __func__);
}
+static void lu_geran_noauth(void)
+{
+ rx_from_ran = OSMO_RAT_GERAN_A;
+ net->authentication_required = false;
+ net->vlr->cfg.assign_tmsi = false;
+
+ btw("Location Update request causes a GSUP LU request to HLR");
+ lu_result_sent = RES_NONE;
+ gsup_expect_tx("04010809710000000156f0280102" VLR_TO_HLR);
+ ms_sends_msg("0508" /* MM LU */
+ "7" /* ciph key seq: no key available */
+ "0" /* LU type: normal */
+ "09f107" "0017" /* LAI, LAC */
+ "57" /* classmark 1: R99, early classmark, no power lvl */
+ "089910070000106005" /* IMSI */
+ "3303575886" /* classmark 2 */
+ );
+ OSMO_ASSERT(gsup_tx_confirmed);
+ VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+ btw("HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT");
+ gsup_rx("10010809710000000156f00804036470f1" HLR_TO_VLR,
+ "12010809710000000156f0" VLR_TO_HLR);
+ VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+ btw("HLR also sends GSUP _UPDATE_LOCATION_RESULT");
+ expect_bssap_clear();
+ gsup_rx("06010809710000000156f0" HLR_TO_VLR, NULL);
+
+ btw("LU was successful, and the conn has already been closed");
+ VERBOSE_ASSERT(lu_result_sent, == RES_ACCEPT, "%d");
+ VERBOSE_ASSERT(bssap_clear_sent, == true, "%d");
+
+ ran_sends_clear_complete();
+ EXPECT_CONN_COUNT(0);
+}
+
+
static void test_call_mo()
{
struct gsm_mncc mncc = {
.imsi = IMSI,
};
+ struct gsm_mncc_rtp mncc_rtp = {};
comment_start();
fake_time_start();
- standard_lu();
+ lu_utran_tmsi();
BTW("after a while, a new conn sends a CM Service Request. VLR responds with Auth Req, 2nd auth vector");
auth_request_sent = false;
@@ -196,13 +237,14 @@ static void test_call_mo()
VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d");
btw("MS sends SecurityModeControl acceptance, VLR accepts; above Ciphering is an implicit CM Service Accept");
- ms_sends_security_mode_complete();
+ ms_sends_security_mode_complete(1);
VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d");
BTW("a call is initiated");
- btw("SETUP gets forwarded to MNCC");
- cc_to_mncc_expect_tx(IMSI, MNCC_SETUP_IND);
+ btw("CC SETUP causes CRCX towards CN and RAN");
+ expect_crcx(RTP_TO_CN);
+ expect_crcx(RTP_TO_RAN);
ms_sends_msg("0385" /* CC, seq = 2 -> 0x80 | CC Setup = 0x5 */
"0406600402000581" /* Bearer Capability */
"5e038121f3" /* Called Number BCD */
@@ -211,8 +253,27 @@ static void test_call_mo()
"04026000" /* UMTS: AMR 2 | AMR */
"00021f00" /* GSM: HR AMR | FR AMR | GSM EFR | GSM HR | GSM FR */
);
+ OSMO_ASSERT(crcx_scheduled(RTP_TO_CN));
+ OSMO_ASSERT(crcx_scheduled(RTP_TO_RAN));
+
+ btw("As soon as the MGW port towards CN is created, MNCC_SETUP_IND is triggered");
+ cc_to_mncc_expect_tx(IMSI, MNCC_SETUP_IND);
+ crcx_ok(RTP_TO_CN);
+ OSMO_ASSERT(cc_to_mncc_tx_confirmed);
+ mncc.callref = mncc_rtp.callref = cc_to_mncc_tx_got_callref;
+
+ btw("MNCC replies with MNCC_RTP_CREATE");
+ mncc_sends_to_cc(MNCC_RTP_CREATE, &mncc_rtp);
+
+ btw("MGW acknowledges the CRCX, triggering Assignment");
+ expect_iu_rab_assignment();
+ crcx_ok(RTP_TO_RAN);
+ OSMO_ASSERT(iu_rab_assignment_sent);
+
+ btw("Assignment succeeds, triggering MNCC_RTP_CREATE ack to MNCC");
+ cc_to_mncc_expect_tx("", MNCC_RTP_CREATE);
+ ms_sends_assignment_complete("AMR");
OSMO_ASSERT(cc_to_mncc_tx_confirmed);
- mncc.callref = cc_to_mncc_tx_got_callref;
btw("MNCC says that's fine");
dtap_expect_tx("8302" /* CC: Call Proceeding */);
@@ -265,19 +326,48 @@ static void test_call_mt()
struct gsm_mncc mncc = {
.imsi = IMSI,
.callref = 0x423,
+ .fields = MNCC_F_BEARER_CAP,
+ .bearer_cap = {
+ .speech_ver = {
+ GSM48_BCAP_SV_AMR_F,
+ GSM48_BCAP_SV_EFR,
+ GSM48_BCAP_SV_FR,
+ GSM48_BCAP_SV_AMR_H,
+ GSM48_BCAP_SV_HR,
+ -1 },
+ },
+ /* NOTE: below SDP includes only AMR, above bearer_cap includes more codecs. Ideally, these would match,
+ * but in reality the bearer cap in MNCC was never implemented properly. This test shows that above
+ * bearer_cap is ignored when SDP is present: In the CC Setup below, the Bearer Capability is only
+ * "04 04 60 04 05 8b" with speech versions '04' == GSM48_BCAP_SV_AMR_F and '05' == GSM48_BCAP_SV_AMR_H.
+ */
+ .sdp = "v=0\r\n"
+ "o=OsmoMSC 0 0 IN IP4 10.23.23.1\r\n"
+ "s=GSM Call\r\n"
+ "c=IN IP4 10.23.23.1\r\n"
+ "t=0 0\r\n"
+ "m=audio 23 RTP/AVP 112\r\n"
+ "a=rtpmap:112 AMR/8000\r\n"
+ "a=fmtp:112 octet-align=1\r\n"
+ "a=ptime:20\r\n",
+ };
+
+ struct gsm_mncc_rtp mncc_rtp = {
+ .callref = 0x423,
};
comment_start();
fake_time_start();
- standard_lu();
+ lu_utran_tmsi();
BTW("after a while, MNCC asks us to setup a call, causing Paging");
paging_expect_imsi(IMSI);
paging_sent = false;
mncc_sends_to_cc(MNCC_SETUP_REQ, &mncc);
+ mncc.sdp[0] = '\0';
VERBOSE_ASSERT(paging_sent, == true, "%d");
@@ -296,24 +386,49 @@ static void test_call_mt()
VERBOSE_ASSERT(security_mode_ctrl_sent, == true, "%d");
btw("MS sends SecurityModeControl acceptance, VLR accepts, sends CC Setup");
- dtap_expect_tx("0305" /* CC: Setup */);
- ms_sends_security_mode_complete();
+ dtap_expect_tx("0305" /* CC: Setup */ "04 04 60 04 05 8b" /* Bearer Cap, speech ver of AMR-FR and AMR-HR */);
+ ms_sends_security_mode_complete(1);
+ btw("MS confirms call, we create a RAN-side RTP and forward MNCC_CALL_CONF_IND");
+ expect_crcx(RTP_TO_CN);
+ expect_crcx(RTP_TO_RAN);
cc_to_mncc_expect_tx(IMSI, MNCC_CALL_CONF_IND);
ms_sends_msg("8348" /* CC: Call Confirmed */
"0406600402000581" /* Bearer Capability */
"15020100" /* Call Control Capabilities */
"40080402600400021f00" /* Supported Codec List */);
+ OSMO_ASSERT(crcx_scheduled(RTP_TO_CN));
+ OSMO_ASSERT(crcx_scheduled(RTP_TO_RAN));
+ OSMO_ASSERT(cc_to_mncc_tx_confirmed);
+
+ btw("MGW acknowledges the CRCX to RAN, triggering Assignment");
+ expect_iu_rab_assignment();
+ crcx_ok(RTP_TO_RAN);
+ OSMO_ASSERT(iu_rab_assignment_sent);
+
+ btw("Assignment completes, triggering CRCX to CN");
+ expect_crcx(RTP_TO_CN);
+ ms_sends_assignment_complete("AMR");
+
+ btw("MNCC sends MNCC_RTP_CREATE, which first waits for the CN side RTP");
+ mncc_sends_to_cc(MNCC_RTP_CREATE, &mncc_rtp);
+
+ btw("When the CN side RTP address is known, ack MNCC_RTP_CREATE with full SDP");
+ cc_to_mncc_expect_tx("", MNCC_RTP_CREATE);
+ crcx_ok(RTP_TO_CN);
+ OSMO_ASSERT(cc_to_mncc_tx_confirmed);
fake_time_passes(1, 23);
cc_to_mncc_expect_tx("", MNCC_ALERT_IND);
ms_sends_msg("8381" /* CC: Alerting */);
+ OSMO_ASSERT(cc_to_mncc_tx_confirmed);
fake_time_passes(1, 23);
cc_to_mncc_expect_tx(IMSI, MNCC_SETUP_CNF);
ms_sends_msg("83c7" /* CC: Connect */);
+ OSMO_ASSERT(cc_to_mncc_tx_confirmed);
dtap_expect_tx("030f" /* CC: Connect Acknowledge */);
mncc_sends_to_cc(MNCC_SETUP_COMPL_REQ, &mncc);
@@ -347,13 +462,44 @@ static void test_call_mt2()
struct gsm_mncc mncc = {
.imsi = IMSI,
.callref = 0x423,
+ .fields = MNCC_F_BEARER_CAP,
+ .bearer_cap = {
+ .speech_ver = { GSM48_BCAP_SV_FR, -1, },
+ },
+ /* NOTE: below SDP includes only AMR, above bearer_cap includes only GSM-FR. Ideally, these would match,
+ * but in reality the bearer cap in MNCC was never implemented properly. This test shows that above
+ * bearer_cap is ignored when SDP is present: In the CC Setup below, the Bearer Capability is only
+ * "04 04 60 04 05 8b" with speech versions '04' == GSM48_BCAP_SV_AMR_F and '05' == GSM48_BCAP_SV_AMR_H.
+ */
+ .sdp = "v=0\r\n"
+ "o=OsmoMSC 0 0 IN IP4 10.23.23.1\r\n"
+ "s=GSM Call\r\n"
+ "c=IN IP4 10.23.23.1\r\n"
+ "t=0 0\r\n"
+ "m=audio 23 RTP/AVP 112\r\n"
+ "a=rtpmap:112 AMR/8000\r\n"
+ "a=fmtp:112 octet-align=1\r\n"
+ "a=ptime:20\r\n",
+ };
+
+ struct gsm_mncc_rtp mncc_rtp = {
+ .callref = 0x423,
+ .sdp = "v=0\r\n"
+ "o=OsmoMSC 0 0 IN IP4 10.23.23.1\r\n"
+ "s=GSM Call\r\n"
+ "c=IN IP4 10.23.23.1\r\n"
+ "t=0 0\r\n"
+ "m=audio 23 RTP/AVP 112\r\n"
+ "a=rtpmap:112 AMR/8000\r\n"
+ "a=fmtp:112 octet-align=1\r\n"
+ "a=ptime:20\r\n",
};
comment_start();
fake_time_start();
- standard_lu();
+ lu_utran_tmsi();
BTW("after a while, MNCC asks us to setup a call, causing Paging");
@@ -378,14 +524,35 @@ static void test_call_mt2()
VERBOSE_ASSERT(security_mode_ctrl_sent, == true, "%d");
btw("MS sends SecurityModeControl acceptance, VLR accepts, sends CC Setup");
- dtap_expect_tx("0305" /* CC: Setup */);
- ms_sends_security_mode_complete();
+ dtap_expect_tx("0305" /* CC: Setup */ "04 04 60 04 05 8b" /* Bearer Cap, speech ver of AMR-FR and AMR-HR */);
+ ms_sends_security_mode_complete(1);
+ btw("MS confirms call, we create a RAN-side RTP and forward MNCC_CALL_CONF_IND");
+ expect_crcx(RTP_TO_CN);
+ expect_crcx(RTP_TO_RAN);
cc_to_mncc_expect_tx(IMSI, MNCC_CALL_CONF_IND);
ms_sends_msg("8348" /* CC: Call Confirmed */
"0406600402000581" /* Bearer Capability */
"15020100" /* Call Control Capabilities */
"40080402600400021f00" /* Supported Codec List */);
+ OSMO_ASSERT(crcx_scheduled(RTP_TO_CN));
+ OSMO_ASSERT(crcx_scheduled(RTP_TO_RAN));
+ OSMO_ASSERT(cc_to_mncc_tx_confirmed);
+
+ btw("MNCC sends MNCC_RTP_CREATE, which first waits for the CN side RTP");
+ mncc_sends_to_cc(MNCC_RTP_CREATE, &mncc_rtp);
+
+ btw("MGW acknowledges the CRCX to RAN, triggering Assignment");
+ expect_iu_rab_assignment();
+ crcx_ok(RTP_TO_RAN);
+ OSMO_ASSERT(iu_rab_assignment_sent);
+
+ btw("Assignment completes, triggering CRCX to CN");
+ ms_sends_assignment_complete("AMR");
+
+ btw("When the CN side RTP address is known, ack MNCC_RTP_CREATE with full SDP");
+ cc_to_mncc_expect_tx("", MNCC_RTP_CREATE);
+ crcx_ok(RTP_TO_CN);
OSMO_ASSERT(cc_to_mncc_tx_confirmed);
fake_time_passes(1, 23);
@@ -397,12 +564,8 @@ static void test_call_mt2()
fake_time_passes(15, 23);
btw("The call failed, the BSC sends a BSSMAP Clear Request");
- /* FIXME: in this scenario, we send an MNCC_REL_CNF even though MNCC never asked us to MNCC_REL_REQ. Legacy
- * behavior did get to both MNCC_REL_IND, then an MNCC_REL_REQ from MNCC as well as a final MNCC_REL_CNF, but
- * this only worked synchronously, i.e. only with internal MNCC. Instead of mimicking that, we need a proper
- * async solution that also works with a PBX. */
- cc_to_mncc_expect_tx("", MNCC_REL_CNF);
- dtap_expect_tx("032d080281af"); /* CC: Release */
+ cc_to_mncc_expect_tx("", MNCC_REL_IND);
+ dtap_expect_tx("032d0802e1af"); /* CC: Release */
expect_iu_release();
msc_a_release_cn(msub_msc_a(g_msub));
OSMO_ASSERT(dtap_tx_confirmed);
@@ -425,11 +588,13 @@ static void test_call_mo_to_unknown()
.imsi = IMSI,
};
+ struct gsm_mncc_rtp mncc_rtp = {};
+
comment_start();
fake_time_start();
- standard_lu();
+ lu_utran_tmsi();
BTW("after a while, a new conn sends a CM Service Request. VLR responds with Auth Req, 2nd auth vector");
auth_request_sent = false;
@@ -453,13 +618,14 @@ static void test_call_mo_to_unknown()
VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d");
btw("MS sends SecurityModeControl acceptance, VLR accepts; above Ciphering is an implicit CM Service Accept");
- ms_sends_security_mode_complete();
+ ms_sends_security_mode_complete(1);
VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d");
BTW("a call is initiated");
- btw("SETUP gets forwarded to MNCC");
- cc_to_mncc_expect_tx(IMSI, MNCC_SETUP_IND);
+ btw("CC SETUP causes CRCX towards CN and RAN");
+ expect_crcx(RTP_TO_CN);
+ expect_crcx(RTP_TO_RAN);
ms_sends_msg("0385" /* CC, seq = 2 -> 0x80 | CC Setup = 0x5 */
"0406600402000581" /* Bearer Capability */
"5e038121f3" /* Called Number BCD */
@@ -468,8 +634,27 @@ static void test_call_mo_to_unknown()
"04026000" /* UMTS: AMR 2 | AMR */
"00021f00" /* GSM: HR AMR | FR AMR | GSM EFR | GSM HR | GSM FR */
);
+ OSMO_ASSERT(crcx_scheduled(RTP_TO_CN));
+ OSMO_ASSERT(crcx_scheduled(RTP_TO_RAN));
+
+ btw("As soon as the MGW port towards CN is created, MNCC_SETUP_IND is triggered");
+ cc_to_mncc_expect_tx(IMSI, MNCC_SETUP_IND);
+ crcx_ok(RTP_TO_CN);
+ OSMO_ASSERT(cc_to_mncc_tx_confirmed);
+ mncc.callref = mncc_rtp.callref = cc_to_mncc_tx_got_callref;
+
+ btw("MNCC replies with MNCC_RTP_CREATE");
+ mncc_sends_to_cc(MNCC_RTP_CREATE, &mncc_rtp);
+
+ btw("MGW acknowledges the CRCX, triggering Assignment");
+ expect_iu_rab_assignment();
+ crcx_ok(RTP_TO_RAN);
+ OSMO_ASSERT(iu_rab_assignment_sent);
+
+ btw("Assignment succeeds, triggering MNCC_RTP_CREATE ack to MNCC");
+ cc_to_mncc_expect_tx("", MNCC_RTP_CREATE);
+ ms_sends_assignment_complete("AMR");
OSMO_ASSERT(cc_to_mncc_tx_confirmed);
- mncc.callref = cc_to_mncc_tx_got_callref;
btw("MNCC says that's fine");
dtap_expect_tx("8302" /* CC: Call Proceeding */);
@@ -486,7 +671,6 @@ static void test_call_mo_to_unknown()
expect_iu_release();
cc_to_mncc_expect_tx("", MNCC_REL_CNF);
ms_sends_msg("036a" /* CC: Release Complete */);
- OSMO_ASSERT(cc_to_mncc_tx_confirmed);
OSMO_ASSERT(iu_release_sent);
OSMO_ASSERT(cc_to_mncc_tx_confirmed);
@@ -501,12 +685,13 @@ static void test_call_mo_to_unknown_timeout()
struct gsm_mncc mncc = {
.imsi = IMSI,
};
+ struct gsm_mncc_rtp mncc_rtp = {};
comment_start();
fake_time_start();
- standard_lu();
+ lu_utran_tmsi();
BTW("after a while, a new conn sends a CM Service Request. VLR responds with Auth Req, 2nd auth vector");
auth_request_sent = false;
@@ -530,13 +715,14 @@ static void test_call_mo_to_unknown_timeout()
VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d");
btw("MS sends SecurityModeControl acceptance, VLR accepts; above Ciphering is an implicit CM Service Accept");
- ms_sends_security_mode_complete();
+ ms_sends_security_mode_complete(1);
VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d");
BTW("a call is initiated");
- btw("SETUP gets forwarded to MNCC");
- cc_to_mncc_expect_tx(IMSI, MNCC_SETUP_IND);
+ btw("CC SETUP causes CRCX towards CN and RAN");
+ expect_crcx(RTP_TO_CN);
+ expect_crcx(RTP_TO_RAN);
ms_sends_msg("0385" /* CC, seq = 2 -> 0x80 | CC Setup = 0x5 */
"0406600402000581" /* Bearer Capability */
"5e038121f3" /* Called Number BCD */
@@ -545,8 +731,27 @@ static void test_call_mo_to_unknown_timeout()
"04026000" /* UMTS: AMR 2 | AMR */
"00021f00" /* GSM: HR AMR | FR AMR | GSM EFR | GSM HR | GSM FR */
);
+ OSMO_ASSERT(crcx_scheduled(RTP_TO_CN));
+ OSMO_ASSERT(crcx_scheduled(RTP_TO_RAN));
+
+ btw("As soon as the MGW port towards CN is created, MNCC_SETUP_IND is triggered");
+ cc_to_mncc_expect_tx(IMSI, MNCC_SETUP_IND);
+ crcx_ok(RTP_TO_CN);
+ OSMO_ASSERT(cc_to_mncc_tx_confirmed);
+ mncc.callref = mncc_rtp.callref = cc_to_mncc_tx_got_callref;
+
+ btw("MNCC replies with MNCC_RTP_CREATE");
+ mncc_sends_to_cc(MNCC_RTP_CREATE, &mncc_rtp);
+
+ btw("MGW acknowledges the CRCX, triggering Assignment");
+ expect_iu_rab_assignment();
+ crcx_ok(RTP_TO_RAN);
+ OSMO_ASSERT(iu_rab_assignment_sent);
+
+ btw("Assignment succeeds, triggering MNCC_RTP_CREATE ack to MNCC");
+ cc_to_mncc_expect_tx("", MNCC_RTP_CREATE);
+ ms_sends_assignment_complete("AMR");
OSMO_ASSERT(cc_to_mncc_tx_confirmed);
- mncc.callref = cc_to_mncc_tx_got_callref;
btw("MNCC says that's fine");
dtap_expect_tx("8302" /* CC: Call Proceeding */);
@@ -574,6 +779,862 @@ static void test_call_mo_to_unknown_timeout()
comment_end();
}
+#define LIST_END 0xffff
+
+struct codec_test {
+ const char *desc;
+
+ /* What to send during Complete Layer 3 as Codec List (BSS Supported). List ends with a LIST_END entry */
+ enum gsm0808_speech_codec_type mo_rx_compl_l3_codec_list_bss_supported[8];
+
+ /* What to send during CC Setup as MS Bearer Capability. List ends with a LIST_END entry */
+ enum gsm48_bcap_speech_ver mo_rx_ms_bcap[8];
+
+ /* What codecs should osmo-msc send in the MNCC_SETUP_IND message.
+ * Just the SDP subtype names like "GSM", "GSM-EFR", "AMR", ..., list ends with NULL entry */
+ const char *mo_tx_sdp_mncc_setup_ind[8];
+
+ /* What codecs the remote call leg should send as SDP via MNCC during MNCC_RTP_CREATE (if any). */
+ const char *mo_rx_sdp_mncc_rtp_create[8];
+
+ /* What the MSC should send as Channel Type IE in the Assignment Command to the BSS. List ends with a
+ * LIST_END entry */
+ enum gsm0808_permitted_speech mo_tx_assignment_perm_speech[8];
+
+ /* What codec to assign in the Assignment Complete's Codec (Chosen) IE. Just a subtype name. */
+ const char *mo_rx_assigned_codec;
+
+ /* MO acks the MNCC_RTP_CREATE with these codecs (if any). */
+ const char *mo_tx_sdp_mncc_rtp_create[8];
+
+ /* mt_rx_sdp_mncc_setup_req == mo_tx_sdp_mncc_rtp_create */
+#define mt_rx_sdp_mncc_setup_req mo_tx_sdp_mncc_rtp_create
+
+ enum gsm0808_speech_codec_type mt_rx_compl_l3_codec_list_bss_supported[8];
+ bool expect_codec_mismatch_on_paging_response;
+ enum gsm48_bcap_speech_ver mt_tx_cc_setup_bcap[8];
+ enum gsm48_bcap_speech_ver mt_rx_ms_bcap[8];
+ bool expect_codec_mismatch_on_cc_call_conf;
+ const char *mt_tx_sdp_mncc_call_conf_ind[8];
+
+ enum gsm0808_permitted_speech mt_tx_assignment_perm_speech[8];
+ const char *mt_rx_assigned_codec;
+
+ const char *mt_rx_sdp_mncc_rtp_create[8];
+ const char *mt_tx_sdp_mncc_rtp_create[8];
+
+ const char *mt_tx_sdp_mncc_alert_ind[8];
+
+ bool mo_expect_reassignment;
+ enum gsm0808_permitted_speech mo_tx_reassignment_perm_speech[8];
+ const char *mo_rx_reassigned_codec;
+
+ const char *mt_tx_sdp_mncc_setup_cnf[8];
+ const char *mt_rx_sdp_mncc_setup_compl_req[8];
+
+ /* mo_rx_sdp_mncc_alert_req == mt_tx_sdp_mncc_alert_ind */
+#define mo_rx_sdp_mncc_alert_req mt_tx_sdp_mncc_alert_ind
+#define mo_rx_sdp_mncc_setup_rsp mt_tx_sdp_mncc_alert_ind
+
+ const char *mo_tx_sdp_mncc_setup_compl_ind[8];
+};
+
+#define CODEC_LIST_ALL_GSM { \
+ GSM0808_SCT_FR1, \
+ GSM0808_SCT_FR2, \
+ GSM0808_SCT_FR3, \
+ GSM0808_SCT_HR1, \
+ GSM0808_SCT_HR3, \
+ LIST_END \
+ }
+
+#define BCAP_ALL_GSM { \
+ GSM48_BCAP_SV_AMR_F, \
+ GSM48_BCAP_SV_AMR_H, \
+ GSM48_BCAP_SV_AMR_OH, \
+ GSM48_BCAP_SV_EFR, \
+ GSM48_BCAP_SV_FR, \
+ GSM48_BCAP_SV_HR, \
+ LIST_END \
+ }
+
+#define PERM_SPEECH_ALL_GSM { \
+ GSM0808_PERM_FR3, \
+ GSM0808_PERM_HR3, \
+ GSM0808_PERM_FR2, \
+ GSM0808_PERM_FR1, \
+ GSM0808_PERM_HR1, \
+ LIST_END \
+ }
+
+#define SDP_CODECS_ALL_GSM { \
+ "AMR", \
+ "GSM-EFR", \
+ "GSM", \
+ "GSM-HR-08", \
+ }
+
+static const struct codec_test codec_tests[] = {
+ {
+ .desc = "AMR picked by both MO and MT",
+ .mo_rx_compl_l3_codec_list_bss_supported = CODEC_LIST_ALL_GSM,
+ .mo_rx_ms_bcap = BCAP_ALL_GSM,
+ .mo_tx_sdp_mncc_setup_ind = SDP_CODECS_ALL_GSM,
+ .mo_rx_sdp_mncc_rtp_create = {},
+ .mo_tx_assignment_perm_speech = PERM_SPEECH_ALL_GSM,
+ .mo_rx_assigned_codec = "AMR",
+ .mo_tx_sdp_mncc_rtp_create = { "AMR", "GSM-EFR", "GSM", "GSM-HR-08" },
+ /* mt_rx_sdp_mncc_setup_req == mo_tx_sdp_mncc_rtp_create */
+ .mt_rx_compl_l3_codec_list_bss_supported = CODEC_LIST_ALL_GSM,
+ .mt_tx_cc_setup_bcap = {
+ GSM48_BCAP_SV_AMR_F,
+ GSM48_BCAP_SV_AMR_H,
+ GSM48_BCAP_SV_AMR_OH,
+ GSM48_BCAP_SV_EFR,
+ GSM48_BCAP_SV_FR,
+ GSM48_BCAP_SV_HR,
+ LIST_END
+ },
+ .mt_rx_ms_bcap = BCAP_ALL_GSM,
+ .mt_tx_sdp_mncc_call_conf_ind = {},
+ .mt_rx_sdp_mncc_rtp_create = {},
+ .mt_tx_assignment_perm_speech = {
+ GSM0808_PERM_FR3,
+ GSM0808_PERM_HR3,
+ GSM0808_PERM_FR2,
+ GSM0808_PERM_FR1,
+ GSM0808_PERM_HR1,
+ LIST_END
+ },
+ .mt_rx_assigned_codec = "AMR",
+ .mt_tx_sdp_mncc_rtp_create = { "AMR", "GSM-EFR", "GSM", "GSM-HR-08" },
+ .mt_tx_sdp_mncc_alert_ind = { "AMR", "GSM-EFR", "GSM", "GSM-HR-08" },
+ .mt_tx_sdp_mncc_setup_cnf = { "AMR", "GSM-EFR", "GSM", "GSM-HR-08" },
+ .mo_tx_sdp_mncc_setup_compl_ind = {},
+ },
+
+ {
+ .desc = "FR1 picked by MO from Codec List (BSS Supported), MT hence also picks FR1",
+ .mo_rx_compl_l3_codec_list_bss_supported = { GSM0808_SCT_FR1, LIST_END },
+ .mo_rx_ms_bcap = BCAP_ALL_GSM,
+ .mo_tx_sdp_mncc_setup_ind = { "GSM" },
+ .mo_rx_sdp_mncc_rtp_create = {},
+ .mo_tx_assignment_perm_speech = { GSM0808_PERM_FR1, LIST_END },
+ .mo_rx_assigned_codec = "GSM",
+ .mo_tx_sdp_mncc_rtp_create = { "GSM" },
+ /* mt_rx_sdp_mncc_setup_req == mo_tx_sdp_mncc_rtp_create */
+ .mt_rx_compl_l3_codec_list_bss_supported = CODEC_LIST_ALL_GSM,
+ .mt_tx_cc_setup_bcap = { GSM48_BCAP_SV_FR, LIST_END },
+ .mt_rx_ms_bcap = BCAP_ALL_GSM,
+ .mt_tx_sdp_mncc_call_conf_ind = {},
+ .mt_rx_sdp_mncc_rtp_create = {},
+ .mt_tx_assignment_perm_speech = { GSM0808_PERM_FR1, LIST_END },
+ .mt_rx_assigned_codec = "GSM",
+ .mt_tx_sdp_mncc_rtp_create = { "GSM" },
+ .mt_tx_sdp_mncc_alert_ind = { "GSM" },
+ .mt_tx_sdp_mncc_setup_cnf = { "GSM" },
+ .mo_tx_sdp_mncc_setup_compl_ind = {},
+ },
+
+ {
+ .desc = "FR1 picked by MO from Bearer Cap, MT hence also picks FR1",
+ .mo_rx_compl_l3_codec_list_bss_supported = CODEC_LIST_ALL_GSM,
+ .mo_rx_ms_bcap = { GSM48_BCAP_SV_FR, LIST_END },
+ .mo_tx_sdp_mncc_setup_ind = { "GSM" },
+ .mo_rx_sdp_mncc_rtp_create = {},
+ .mo_tx_assignment_perm_speech = { GSM0808_PERM_FR1, LIST_END },
+ .mo_rx_assigned_codec = "GSM",
+ .mo_tx_sdp_mncc_rtp_create = { "GSM" },
+ /* mt_rx_sdp_mncc_setup_req == mo_tx_sdp_mncc_rtp_create */
+ .mt_rx_compl_l3_codec_list_bss_supported = CODEC_LIST_ALL_GSM,
+ .mt_tx_cc_setup_bcap = { GSM48_BCAP_SV_FR, LIST_END },
+ .mt_rx_ms_bcap = BCAP_ALL_GSM,
+ .mt_tx_sdp_mncc_call_conf_ind = {},
+ .mt_rx_sdp_mncc_rtp_create = {},
+ .mt_tx_assignment_perm_speech = { GSM0808_PERM_FR1, LIST_END },
+ .mt_rx_assigned_codec = "GSM",
+ .mt_tx_sdp_mncc_rtp_create = { "GSM" },
+ .mt_tx_sdp_mncc_alert_ind = { "GSM" },
+ .mt_tx_sdp_mncc_setup_cnf = { "GSM" },
+ .mo_tx_sdp_mncc_setup_compl_ind = {},
+ },
+
+ {
+ .desc = "FR1 picked by MT's Codec List (BSS Supported), hence MO re-assigns to FR1",
+ .mo_rx_compl_l3_codec_list_bss_supported = CODEC_LIST_ALL_GSM,
+ .mo_rx_ms_bcap = BCAP_ALL_GSM,
+ .mo_tx_sdp_mncc_setup_ind = SDP_CODECS_ALL_GSM,
+ .mo_rx_sdp_mncc_rtp_create = {},
+ .mo_tx_assignment_perm_speech = PERM_SPEECH_ALL_GSM,
+ .mo_rx_assigned_codec = "AMR", /* <- Early Assignment first picks a mismatching codec */
+ .mo_tx_sdp_mncc_rtp_create = { "AMR", "GSM-EFR", "GSM", "GSM-HR-08" },
+
+ /* This is the codec limitation this test verifies, Codec List (BSS Supported): */
+ .mt_rx_compl_l3_codec_list_bss_supported = { GSM0808_SCT_FR1, LIST_END },
+
+ /* from above codec list, MSC derives the limited bcap sent in CC Setup to MS */
+ .mt_tx_cc_setup_bcap = {
+ GSM48_BCAP_SV_FR,
+ LIST_END
+ },
+ /* MS could do more, but it doesn't affect the choice of FR1 */
+ .mt_rx_ms_bcap = BCAP_ALL_GSM,
+ .mt_tx_sdp_mncc_call_conf_ind = {},
+ .mt_rx_sdp_mncc_rtp_create = {},
+ .mt_tx_assignment_perm_speech = {
+ GSM0808_PERM_FR1,
+ LIST_END
+ },
+ .mt_rx_assigned_codec = "GSM",
+ .mt_tx_sdp_mncc_rtp_create = { "GSM" },
+ .mt_tx_sdp_mncc_alert_ind = { "GSM" },
+
+ .mo_expect_reassignment = true,
+ .mo_tx_reassignment_perm_speech = {
+ GSM0808_PERM_FR1,
+ LIST_END
+ },
+ .mo_rx_reassigned_codec = "GSM",
+
+ .mt_tx_sdp_mncc_setup_cnf = { "GSM" },
+ .mo_tx_sdp_mncc_setup_compl_ind = {},
+ },
+
+ {
+ .desc = "FR1 picked by MT's MS Bearer Capability, hence MO re-assigns to FR1",
+ .mo_rx_compl_l3_codec_list_bss_supported = CODEC_LIST_ALL_GSM,
+ .mo_rx_ms_bcap = BCAP_ALL_GSM,
+ .mo_tx_sdp_mncc_setup_ind = SDP_CODECS_ALL_GSM,
+ .mo_rx_sdp_mncc_rtp_create = {},
+ .mo_tx_assignment_perm_speech = PERM_SPEECH_ALL_GSM,
+ .mo_rx_assigned_codec = "AMR", /* <- Early Assignment first picks a mismatching codec */
+ .mo_tx_sdp_mncc_rtp_create = { "AMR", "GSM-EFR", "GSM", "GSM-HR-08" },
+
+ .mt_rx_compl_l3_codec_list_bss_supported = CODEC_LIST_ALL_GSM,
+ .mt_tx_cc_setup_bcap = BCAP_ALL_GSM,
+
+ /* This is the codec limitation this test verifies: */
+ .mt_rx_ms_bcap = {
+ GSM48_BCAP_SV_FR,
+ LIST_END
+ },
+ .mt_tx_sdp_mncc_call_conf_ind = {},
+ .mt_rx_sdp_mncc_rtp_create = {},
+ .mt_tx_assignment_perm_speech = {
+ GSM0808_PERM_FR1,
+ LIST_END
+ },
+ .mt_rx_assigned_codec = "GSM",
+ .mt_tx_sdp_mncc_rtp_create = { "GSM" },
+ .mt_tx_sdp_mncc_alert_ind = { "GSM" },
+
+ .mo_expect_reassignment = true,
+ .mo_tx_reassignment_perm_speech = {
+ GSM0808_PERM_FR1,
+ LIST_END
+ },
+ .mo_rx_reassigned_codec = "GSM",
+
+ .mt_tx_sdp_mncc_setup_cnf = { "GSM" },
+ .mo_tx_sdp_mncc_setup_compl_ind = {},
+ },
+
+ {
+ .desc = "AMR picked by both MO and MT, but MT assigns a different payload type number",
+ .mo_rx_compl_l3_codec_list_bss_supported = CODEC_LIST_ALL_GSM,
+ .mo_rx_ms_bcap = BCAP_ALL_GSM,
+ .mo_tx_sdp_mncc_setup_ind = SDP_CODECS_ALL_GSM,
+ .mo_rx_sdp_mncc_rtp_create = {},
+ .mo_tx_assignment_perm_speech = PERM_SPEECH_ALL_GSM,
+ .mo_rx_assigned_codec = "AMR",
+ .mo_tx_sdp_mncc_rtp_create = { "AMR", "GSM-EFR", "GSM", "GSM-HR-08" },
+ /* mt_rx_sdp_mncc_setup_req == mo_tx_sdp_mncc_rtp_create */
+ .mt_rx_compl_l3_codec_list_bss_supported = CODEC_LIST_ALL_GSM,
+ .mt_tx_cc_setup_bcap = {
+ GSM48_BCAP_SV_AMR_F,
+ GSM48_BCAP_SV_AMR_H,
+ GSM48_BCAP_SV_AMR_OH,
+ GSM48_BCAP_SV_EFR,
+ GSM48_BCAP_SV_FR,
+ GSM48_BCAP_SV_HR,
+ LIST_END
+ },
+ .mt_rx_ms_bcap = BCAP_ALL_GSM,
+ .mt_tx_sdp_mncc_call_conf_ind = {},
+ .mt_rx_sdp_mncc_rtp_create = {},
+ .mt_tx_assignment_perm_speech = {
+ GSM0808_PERM_FR3,
+ GSM0808_PERM_HR3,
+ GSM0808_PERM_FR2,
+ GSM0808_PERM_FR1,
+ GSM0808_PERM_HR1,
+ LIST_END
+ },
+ .mt_rx_assigned_codec = "AMR",
+ .mt_tx_sdp_mncc_rtp_create = { "AMR#96", "GSM-EFR", "GSM", "GSM-HR-08" },
+ .mt_tx_sdp_mncc_alert_ind = { "AMR#96", "GSM-EFR", "GSM", "GSM-HR-08" },
+ .mt_tx_sdp_mncc_setup_cnf = { "AMR#96", "GSM-EFR", "GSM", "GSM-HR-08" },
+ .mo_tx_sdp_mncc_setup_compl_ind = {},
+ },
+
+ {
+ .desc = "AMR picked by both MO and MT, but MO assigns a different payload type number",
+ .mo_rx_compl_l3_codec_list_bss_supported = CODEC_LIST_ALL_GSM,
+ .mo_rx_ms_bcap = BCAP_ALL_GSM,
+ .mo_tx_sdp_mncc_setup_ind = SDP_CODECS_ALL_GSM,
+ .mo_rx_sdp_mncc_rtp_create = {},
+ .mo_tx_assignment_perm_speech = PERM_SPEECH_ALL_GSM,
+ .mo_rx_assigned_codec = "AMR",
+ .mo_tx_sdp_mncc_rtp_create = { "AMR#98", "GSM-EFR", "GSM", "GSM-HR-08" },
+ /* mt_rx_sdp_mncc_setup_req == mo_tx_sdp_mncc_rtp_create */
+ .mt_rx_compl_l3_codec_list_bss_supported = CODEC_LIST_ALL_GSM,
+ .mt_tx_cc_setup_bcap = {
+ GSM48_BCAP_SV_AMR_F,
+ GSM48_BCAP_SV_AMR_H,
+ GSM48_BCAP_SV_AMR_OH,
+ GSM48_BCAP_SV_EFR,
+ GSM48_BCAP_SV_FR,
+ GSM48_BCAP_SV_HR,
+ LIST_END
+ },
+ .mt_rx_ms_bcap = BCAP_ALL_GSM,
+ .mt_tx_sdp_mncc_call_conf_ind = {},
+ .mt_rx_sdp_mncc_rtp_create = {},
+ .mt_tx_assignment_perm_speech = {
+ GSM0808_PERM_FR3,
+ GSM0808_PERM_HR3,
+ GSM0808_PERM_FR2,
+ GSM0808_PERM_FR1,
+ GSM0808_PERM_HR1,
+ LIST_END
+ },
+ .mt_rx_assigned_codec = "AMR",
+ .mt_tx_sdp_mncc_rtp_create = { "AMR#98", "GSM-EFR", "GSM", "GSM-HR-08" },
+ .mt_tx_sdp_mncc_alert_ind = { "AMR#98", "GSM-EFR", "GSM", "GSM-HR-08" },
+ .mt_tx_sdp_mncc_setup_cnf = { "AMR#98", "GSM-EFR", "GSM", "GSM-HR-08" },
+ .mo_tx_sdp_mncc_setup_compl_ind = {},
+ },
+};
+
+static char namebuf[4][1024];
+static int use_namebuf = 0;
+
+static const char *codec_list_name(const enum gsm0808_speech_codec_type compl_l3_codec_list_bss_supported[])
+{
+ struct osmo_strbuf sb = { .buf = namebuf[use_namebuf], .len = sizeof(namebuf[0]) };
+ use_namebuf = (use_namebuf + 1) % ARRAY_SIZE(namebuf);
+
+ const enum gsm0808_speech_codec_type *pos;
+ sb.buf[0] = '\0';
+ for (pos = compl_l3_codec_list_bss_supported; *pos != LIST_END; pos++)
+ OSMO_STRBUF_PRINTF(sb, " %s", gsm0808_speech_codec_type_name(*pos));
+ return sb.buf;
+}
+
+static const struct gsm0808_speech_codec_list *codec_list(const enum gsm0808_speech_codec_type compl_l3_codec_list_bss_supported[])
+{
+ static struct gsm0808_speech_codec_list scl;
+ scl = (struct gsm0808_speech_codec_list){};
+ const enum gsm0808_speech_codec_type *pos;
+ for (pos = compl_l3_codec_list_bss_supported; *pos != LIST_END; pos++) {
+ scl.codec[scl.len] = (struct gsm0808_speech_codec){
+ .fi = true,
+ .type = *pos,
+ };
+ scl.len++;
+ }
+ return &scl;
+}
+
+static const char *bcap_name(const enum gsm48_bcap_speech_ver ms_bcap[])
+{
+ struct osmo_strbuf sb = { .buf = namebuf[use_namebuf], .len = sizeof(namebuf[0]) };
+ use_namebuf = (use_namebuf + 1) % ARRAY_SIZE(namebuf);
+
+ const enum gsm48_bcap_speech_ver *pos;
+ sb.buf[0] = '\0';
+ for (pos = ms_bcap; *pos != LIST_END; pos++) {
+ const struct codec_mapping *m = codec_mapping_by_speech_ver(*pos);
+ OSMO_STRBUF_PRINTF(sb, " %s", m ? m->sdp.subtype_name : "NULL");
+ }
+ return sb.buf;
+}
+
+static const char *perm_speech_name(const enum gsm0808_permitted_speech perm_speech[])
+{
+ struct osmo_strbuf sb = { .buf = namebuf[use_namebuf], .len = sizeof(namebuf[0]) };
+ use_namebuf = (use_namebuf + 1) % ARRAY_SIZE(namebuf);
+
+ const enum gsm0808_permitted_speech *pos;
+ sb.buf[0] = '\0';
+ for (pos = perm_speech; *pos != LIST_END; pos++)
+ OSMO_STRBUF_PRINTF(sb, " %s", gsm0808_permitted_speech_name(*pos));
+ return sb.buf;
+}
+
+static const char *strlist_name(const char *const*strs)
+{
+ struct osmo_strbuf sb = { .buf = namebuf[use_namebuf], .len = sizeof(namebuf[0]) };
+ use_namebuf = (use_namebuf + 1) % ARRAY_SIZE(namebuf);
+
+ const char * const *pos;
+ sb.buf[0] = '\0';
+ for (pos = strs; *pos != NULL; pos++)
+ OSMO_STRBUF_PRINTF(sb, " %s", *pos);
+ return sb.buf;
+}
+
+/* Split an input string of "AMR#96" into "AMR" and 96: copy the subtype name without the "#96" part to
+ * split_subtype_name_and_pt_nr which must be a char[16]. If pt_nr is non-NULL, write the 96 to *pt_nr.
+ */
+static void split_subtype_name_and_pt_nr(char subtype_name_wo_pt[], int *pt_nr, const char *input)
+{
+ char *hash;
+ osmo_strlcpy(subtype_name_wo_pt, input, 16);
+ hash = strchr(subtype_name_wo_pt, '#');
+ if (hash) {
+ *hash = '\0';
+ if (pt_nr)
+ *pt_nr = atoi(hash + 1);
+ }
+}
+
+/* Validate that the codecs in sdp_str appear in the order as expected by the list of subtype names in expected_codecs.
+ * Ignore any payload type numbers ("#96") in expected_codecs.
+ */
+static bool validate_sdp(const char *func, const char *desc,
+ const char *sdp_str, const char * const expected_codecs[])
+{
+ const char * const *expect_pos;
+ struct sdp_audio_codec *codec;
+ struct sdp_msg sdp;
+ if (sdp_msg_from_sdp_str(&sdp, sdp_str)) {
+ BTW("%s: %s: ERROR: failed to parse SDP\n%s", func, desc, sdp_str);
+ return false;
+ }
+
+ expect_pos = expected_codecs;
+ sdp_audio_codecs_foreach(codec, &sdp.audio_codecs) {
+ char subtype_name_wo_pt[16];
+ if (!*expect_pos) {
+ BTW("%s: %s: ERROR: did not expect %s", func, desc, codec->subtype_name);
+ return false;
+ }
+ split_subtype_name_and_pt_nr(subtype_name_wo_pt, NULL, *expect_pos);
+ if (strcmp(subtype_name_wo_pt, codec->subtype_name)) {
+ BTW("%s: %s: ERROR: mismatch: in idx %d, expect %s, got %s", func, desc,
+ (int)(expect_pos - expected_codecs), *expect_pos, codec->subtype_name);
+ return false;
+ }
+ expect_pos++;
+
+ /* only match first codec */
+ return true;
+ }
+ if (*expect_pos) {
+ BTW("%s: %s: ERROR: mismatch: expected %s to be listed, but not found", func, desc, *expect_pos);
+ return false;
+ }
+ return true;
+}
+
+#define VALIDATE_SDP(GOT_SDP_STR, EXPECT_SDP_STR) do { \
+ if (validate_sdp(__func__, t->desc, GOT_SDP_STR, EXPECT_SDP_STR)) { \
+ btw("VALIDATE_SDP OK: " #GOT_SDP_STR " == " #EXPECT_SDP_STR " ==%s", strlist_name(EXPECT_SDP_STR)); \
+ } else { \
+ btw("Failed to validate SDP:\nexpected%s\ngot\n%s", \
+ strlist_name(EXPECT_SDP_STR), GOT_SDP_STR); \
+ OSMO_ASSERT(false); \
+ } \
+ } while (0)
+
+static bool validate_perm_speech(const char *func, const char *desc,
+ const struct gsm0808_channel_type *ct,
+ const enum gsm0808_permitted_speech perm_speech[])
+{
+ const enum gsm0808_permitted_speech *pos;
+ const uint8_t *pos2 = ct->perm_spch;
+ for (pos = perm_speech; *pos != LIST_END; pos++, pos2++) {
+ if (pos2 - ct->perm_spch >= ct->perm_spch_len) {
+ BTW("%s: %s: ERROR: mismatch: expected %s to be listed, but not found", func, desc,
+ gsm0808_permitted_speech_name(*pos));
+ return false;
+ }
+ if (*pos2 != *pos) {
+ BTW("%s: %s: ERROR: mismatch: in idx %d, expect %s", func, desc,
+ (int)(pos - perm_speech), gsm0808_permitted_speech_name(*pos));
+ btw("in idx %d, got %s", (int)(pos - perm_speech), gsm0808_permitted_speech_name(*pos2));
+ return false;
+ }
+ }
+ if (pos2 - ct->perm_spch < ct->perm_spch_len) {
+ BTW("%s: %s: ERROR: did not expect %s", func, desc, gsm0808_permitted_speech_name(*pos2));
+ return false;
+ }
+ return true;
+}
+
+#define VALIDATE_PERM_SPEECH(GOT_PERM_SPEECH, EXPECT_PERM_SPEECH) do { \
+ if (validate_perm_speech(__func__, t->desc, GOT_PERM_SPEECH, EXPECT_PERM_SPEECH)) { \
+ btw("VALIDATE_PERM_SPEECH OK: " #GOT_PERM_SPEECH " == " #EXPECT_PERM_SPEECH " ==%s", \
+ perm_speech_name(EXPECT_PERM_SPEECH)); \
+ } else { \
+ btw("Failed to validate Permitted Speech:\nexpected%s", \
+ perm_speech_name(EXPECT_PERM_SPEECH)); \
+ btw("got:"); \
+ int i; \
+ for (i = 0; i < (GOT_PERM_SPEECH)->perm_spch_len; i++) { \
+ btw("%s", gsm0808_permitted_speech_name((GOT_PERM_SPEECH)->perm_spch[i])); \
+ } \
+ OSMO_ASSERT(false); \
+ } \
+ } while (0)
+
+/* Compose a valid SDP string from the list of codec subtype names given. If a subtype name includes a payload type
+ * number ("AMR#96") then use that PT number in the SDP instead of the default from codec_mapping.c. */
+static struct sdp_msg *sdp_from_subtype_names(const char *const *subtype_names)
+{
+ static struct sdp_msg sdp;
+ sdp = (struct sdp_msg){};
+ const char *const *subtype_name;
+ osmo_sockaddr_str_from_str(&sdp.rtp, "1.2.3.4", 56);
+ for (subtype_name = subtype_names; *subtype_name; subtype_name++) {
+ char subtype_name_wo_pt[16];
+ const struct codec_mapping *m;
+ struct sdp_audio_codec *ac;
+ int set_pt = -1;
+ split_subtype_name_and_pt_nr(subtype_name_wo_pt, &set_pt, *subtype_name);
+ m = codec_mapping_by_subtype_name(subtype_name_wo_pt);
+ if (!m) {
+ BTW("ERROR: unknown subtype_name: %s", *subtype_name);
+ abort();
+ }
+ ac = sdp_audio_codecs_add_copy(&sdp.audio_codecs, &m->sdp);
+ if (set_pt >= 0)
+ ac->payload_type = set_pt;
+ }
+ return &sdp;
+}
+
+static int sdp_str_from_subtype_names(char *buf, size_t buflen, const char *const *subtype_names)
+{
+ if (!subtype_names[0]) {
+ buf[0] = '\0';
+ return 0;
+ }
+ return sdp_msg_to_sdp_str_buf(buf, buflen, sdp_from_subtype_names(subtype_names));
+}
+
+static const char *bcap_hexstr(const enum gsm48_bcap_speech_ver ms_bcap[])
+{
+ struct gsm_mncc_bearer_cap bcap = {
+ .transfer = GSM_MNCC_BCAP_SPEECH,
+ .speech_ver = { -1 },
+ };
+ const enum gsm48_bcap_speech_ver *pos;
+ for (pos = ms_bcap; *pos != LIST_END; pos++)
+ bearer_cap_add_speech_ver(&bcap, *pos);
+ bearer_cap_set_radio(&bcap);
+ struct msgb *msg = msgb_alloc(128, "bcap");
+ gsm48_encode_bearer_cap(msg, 0, &bcap);
+ char *ret = osmo_hexdump_nospc(msg->data, msg->len);
+ msgb_free(msg);
+ return ret;
+}
+
+static void test_codecs_mo(const struct codec_test *t)
+{
+ struct gsm_mncc mncc = {
+ .imsi = IMSI,
+ };
+
+ struct gsm_mncc_rtp mncc_rtp = {};
+
+ BTW("======================== MO call: %s", t->desc);
+ btw("CM Service Request with Codec List (BSS Supported) =%s",
+ codec_list_name(t->mo_rx_compl_l3_codec_list_bss_supported));
+
+ cm_service_result_sent = RES_NONE;
+ ms_sends_compl_l3("052471"
+ "03575886" /* classmark 2 */
+ "089910070000106005" /* IMSI */,
+ codec_list(t->mo_rx_compl_l3_codec_list_bss_supported));
+ VERBOSE_ASSERT(cm_service_result_sent, == RES_ACCEPT, "%d");
+ EXPECT_ACCEPTED(true);
+
+ btw("MS sends CC SETUP with Bearer Capability = %s",
+ bcap_name(t->mo_rx_ms_bcap));
+ expect_crcx(RTP_TO_CN);
+ expect_crcx(RTP_TO_RAN);
+ ms_sends_msgf("0385" /* CC, seq = 2 -> 0x80 | CC Setup = 0x5 */
+ "%s" /* Bearer Capability */
+ "5e038121f3" /* Called Number BCD */
+ "15020100" /* CC Capabilities */
+ "4008" /* Supported Codec List */
+ "04026000" /* UMTS: AMR 2 | AMR */
+ "00021f00" /* GSM: HR AMR | FR AMR | GSM EFR | GSM HR | GSM FR */,
+ bcap_hexstr(t->mo_rx_ms_bcap)
+ );
+ OSMO_ASSERT(crcx_scheduled(RTP_TO_CN));
+ OSMO_ASSERT(crcx_scheduled(RTP_TO_RAN));
+
+ btw("As soon as the MGW port towards CN is created, MNCC_SETUP_IND is triggered");
+ cc_to_mncc_expect_tx(IMSI, MNCC_SETUP_IND);
+ crcx_ok(RTP_TO_CN);
+ OSMO_ASSERT(cc_to_mncc_tx_confirmed);
+ mncc.callref = mncc_rtp.callref = cc_to_mncc_tx_got_callref;
+ VALIDATE_SDP(cc_to_mncc_tx_last_sdp, t->mo_tx_sdp_mncc_setup_ind);
+
+ btw("MNCC replies with MNCC_RTP_CREATE");
+ sdp_str_from_subtype_names(mncc_rtp.sdp, sizeof(mncc_rtp.sdp), t->mo_rx_sdp_mncc_rtp_create);
+ mncc_sends_to_cc(MNCC_RTP_CREATE, &mncc_rtp);
+
+ btw("MGW acknowledges the CRCX, triggering Assignment with%s", perm_speech_name(t->mo_tx_assignment_perm_speech));
+ expect_bssap_assignment();
+ crcx_ok(RTP_TO_RAN);
+ OSMO_ASSERT(bssap_assignment_sent);
+ VALIDATE_PERM_SPEECH(&bssap_assignment_command_last_channel_type, t->mo_tx_assignment_perm_speech);
+
+ btw("Assignment succeeds, triggering MNCC_RTP_CREATE ack to MNCC");
+ cc_to_mncc_expect_tx("", MNCC_RTP_CREATE);
+ ms_sends_assignment_complete(t->mo_rx_assigned_codec);
+ OSMO_ASSERT(cc_to_mncc_tx_confirmed);
+ VALIDATE_SDP(cc_to_mncc_tx_last_sdp, t->mo_tx_sdp_mncc_rtp_create);
+
+ btw("MNCC says that's fine");
+ dtap_expect_tx("8302" /* CC: Call Proceeding */);
+ mncc_sends_to_cc(MNCC_CALL_PROC_REQ, &mncc);
+ OSMO_ASSERT(dtap_tx_confirmed);
+
+ fake_time_passes(1, 23);
+
+ btw("The other call leg got established (not shown here), MNCC tells us so, with codecs {%s }",
+ strlist_name(t->mo_rx_sdp_mncc_alert_req));
+ dtap_expect_tx("8301" /* CC: Call Alerting */);
+
+ if (t->mo_expect_reassignment) {
+ btw("Expecting re-assignment");
+ expect_bssap_assignment();
+ }
+
+ sdp_str_from_subtype_names(mncc.sdp, sizeof(mncc.sdp), t->mo_rx_sdp_mncc_alert_req);
+ mncc_sends_to_cc(MNCC_ALERT_REQ, &mncc);
+ OSMO_ASSERT(dtap_tx_confirmed);
+
+ if (t->mo_expect_reassignment) {
+ btw("Validating re-assignment");
+ OSMO_ASSERT(bssap_assignment_sent);
+ VALIDATE_PERM_SPEECH(&bssap_assignment_command_last_channel_type, t->mo_tx_reassignment_perm_speech);
+ ms_sends_assignment_complete(t->mo_rx_reassigned_codec);
+ }
+
+ dtap_expect_tx("8307" /* CC: Connect */);
+ sdp_str_from_subtype_names(mncc.sdp, sizeof(mncc.sdp), t->mo_rx_sdp_mncc_setup_rsp);
+ mncc_sends_to_cc(MNCC_SETUP_RSP, &mncc);
+ OSMO_ASSERT(dtap_tx_confirmed);
+
+ fake_time_passes(1, 23);
+
+ cc_to_mncc_expect_tx("", MNCC_SETUP_COMPL_IND);
+ ms_sends_msg("03cf" /* CC: Connect Acknowledge */);
+ OSMO_ASSERT(cc_to_mncc_tx_confirmed);
+ VALIDATE_SDP(cc_to_mncc_tx_last_sdp, t->mo_tx_sdp_mncc_setup_compl_ind);
+
+ BTW("RTP stream goes ahead, not shown here.");
+ fake_time_passes(123, 45);
+
+ BTW("Call ends");
+ cc_to_mncc_expect_tx("", MNCC_DISC_IND);
+ ms_sends_msg("032502e090" /* CC: Disconnect, cause: Normal Call Clearing */);
+ OSMO_ASSERT(cc_to_mncc_tx_confirmed);
+
+ dtap_expect_tx("832d" /* CC: Release */);
+ mncc_sends_to_cc(MNCC_REL_REQ, &mncc);
+ OSMO_ASSERT(dtap_tx_confirmed);
+
+ cc_to_mncc_expect_tx("", MNCC_REL_CNF);
+ expect_bssap_clear();
+ ms_sends_msg("036a" /* CC: Release Complete */);
+ OSMO_ASSERT(cc_to_mncc_tx_confirmed);
+ OSMO_ASSERT(bssap_clear_sent);
+
+ ran_sends_clear_complete();
+ EXPECT_CONN_COUNT(0);
+ BTW("======================== SUCCESS: MO call: %s", t->desc);
+}
+
+static void test_codecs_mt(const struct codec_test *t)
+{
+ struct gsm_mncc mncc = {
+ .imsi = IMSI,
+ .callref = 0x423,
+ .fields = MNCC_F_BEARER_CAP,
+ .bearer_cap = {
+ .speech_ver = { GSM48_BCAP_SV_FR, -1, },
+ },
+ };
+ struct gsm_mncc_rtp mncc_rtp = {
+ .callref = 0x423,
+ };
+
+ BTW("======================== MT call: %s", t->desc);
+
+ BTW("MNCC asks us to setup a call, causing Paging");
+
+ paging_expect_imsi(IMSI);
+ paging_sent = false;
+ sdp_str_from_subtype_names(mncc.sdp, sizeof(mncc.sdp), t->mt_rx_sdp_mncc_setup_req);
+ mncc_sends_to_cc(MNCC_SETUP_REQ, &mncc);
+ mncc.sdp[0] = '\0';
+
+ VERBOSE_ASSERT(paging_sent, == true, "%d");
+
+ btw("MS replies with Paging Response, with Codec List (BSS Supported) =%s",
+ codec_list_name(t->mt_rx_compl_l3_codec_list_bss_supported));
+
+ if (t->expect_codec_mismatch_on_paging_response) {
+ btw("VLR accepts, but MSC notices a codec mismatch and aborts");
+ cc_to_mncc_expect_tx("", MNCC_REL_IND);
+ expect_bssap_clear();
+ ms_sends_compl_l3("062707"
+ "03575886" /* classmark 2 */
+ "089910070000106005" /* IMSI */,
+ codec_list(t->mt_rx_compl_l3_codec_list_bss_supported));
+ OSMO_ASSERT(cc_to_mncc_tx_confirmed);
+ OSMO_ASSERT(bssap_clear_sent);
+
+ ran_sends_clear_complete();
+ EXPECT_CONN_COUNT(0);
+
+ BTW("======================== SUCCESS: MT call: %s", t->desc);
+ return;
+ }
+
+ btw("VLR accepts, MSC sends CC Setup with Bearer Capability = %s",
+ bcap_name(t->mt_tx_cc_setup_bcap));
+ char *cc_setup_bcap = talloc_asprintf(msc_vlr_tests_ctx, "0305%s",
+ bcap_hexstr(t->mt_tx_cc_setup_bcap));
+ dtap_expect_tx(cc_setup_bcap);
+ ms_sends_compl_l3("062707"
+ "03575886" /* classmark 2 */
+ "089910070000106005" /* IMSI */,
+ codec_list(t->mt_rx_compl_l3_codec_list_bss_supported));
+ OSMO_ASSERT(dtap_tx_confirmed);
+ talloc_free(cc_setup_bcap);
+
+ btw("MS confirms call, we create a RAN-side RTP and forward MNCC_CALL_CONF_IND");
+ expect_crcx(RTP_TO_CN);
+ expect_crcx(RTP_TO_RAN);
+ cc_to_mncc_expect_tx(IMSI, MNCC_CALL_CONF_IND);
+ ms_sends_msgf("8348" /* CC: Call Confirmed */
+ "%s" /* Bearer Capability */
+ "15020100" /* Call Control Capabilities */
+ "40080402600400021f00" /* Supported Codec List */,
+ bcap_hexstr(t->mt_rx_ms_bcap)
+ );
+ OSMO_ASSERT(crcx_scheduled(RTP_TO_CN));
+ OSMO_ASSERT(crcx_scheduled(RTP_TO_RAN));
+ OSMO_ASSERT(cc_to_mncc_tx_confirmed);
+ VALIDATE_SDP(cc_to_mncc_tx_last_sdp, t->mt_tx_sdp_mncc_call_conf_ind);
+
+ btw("MGW acknowledges the CRCX to RAN, triggering Assignment with%s", perm_speech_name(t->mt_tx_assignment_perm_speech));
+
+ if (t->expect_codec_mismatch_on_cc_call_conf) {
+ btw("MS Bearer Capability leads to a codec mismatch, Assignment aborts");
+
+ dtap_expect_tx("032d0802e1af" /* CC Release */);
+ cc_to_mncc_expect_tx("", MNCC_REL_IND);
+ expect_bssap_clear();
+ crcx_ok(RTP_TO_RAN);
+
+ OSMO_ASSERT(cc_to_mncc_tx_confirmed);
+ OSMO_ASSERT(bssap_clear_sent);
+
+ ran_sends_clear_complete();
+ EXPECT_CONN_COUNT(0);
+ BTW("======================== SUCCESS: MT call: %s", t->desc);
+ return;
+ }
+
+ expect_bssap_assignment();
+ crcx_ok(RTP_TO_RAN);
+ OSMO_ASSERT(bssap_assignment_sent);
+ VALIDATE_PERM_SPEECH(&bssap_assignment_command_last_channel_type, t->mt_tx_assignment_perm_speech);
+
+ btw("Assignment completes, triggering CRCX to CN");
+ ms_sends_assignment_complete(t->mt_rx_assigned_codec);
+
+ btw("MNCC sends MNCC_RTP_CREATE, which first waits for the CN side RTP");
+ sdp_str_from_subtype_names(mncc_rtp.sdp, sizeof(mncc_rtp.sdp), t->mt_rx_sdp_mncc_rtp_create);
+ mncc_sends_to_cc(MNCC_RTP_CREATE, &mncc_rtp);
+
+ btw("When the CN side RTP address is known, ack MNCC_RTP_CREATE");
+ cc_to_mncc_expect_tx("", MNCC_RTP_CREATE);
+ crcx_ok(RTP_TO_CN);
+ OSMO_ASSERT(cc_to_mncc_tx_confirmed);
+ VALIDATE_SDP(cc_to_mncc_tx_last_sdp, t->mt_tx_sdp_mncc_rtp_create);
+
+ fake_time_passes(1, 23);
+
+ cc_to_mncc_expect_tx("", MNCC_ALERT_IND);
+ ms_sends_msg("8381" /* CC: Alerting */);
+ OSMO_ASSERT(cc_to_mncc_tx_confirmed);
+ VALIDATE_SDP(cc_to_mncc_tx_last_sdp, t->mt_tx_sdp_mncc_alert_ind);
+
+ fake_time_passes(1, 23);
+
+ cc_to_mncc_expect_tx(IMSI, MNCC_SETUP_CNF);
+ ms_sends_msg("83c7" /* CC: Connect */);
+ OSMO_ASSERT(cc_to_mncc_tx_confirmed);
+ VALIDATE_SDP(cc_to_mncc_tx_last_sdp, t->mt_tx_sdp_mncc_setup_cnf);
+
+ dtap_expect_tx("030f" /* CC: Connect Acknowledge */);
+ sdp_str_from_subtype_names(mncc.sdp, sizeof(mncc.sdp), t->mt_rx_sdp_mncc_setup_compl_req);
+ mncc_sends_to_cc(MNCC_SETUP_COMPL_REQ, &mncc);
+
+ BTW("RTP stream goes ahead, not shown here.");
+ fake_time_passes(123, 45);
+
+ BTW("Call ends");
+ cc_to_mncc_expect_tx("", MNCC_DISC_IND);
+ ms_sends_msg("832502e090" /* CC: Disconnect, cause: Normal Call Clearing */);
+ OSMO_ASSERT(cc_to_mncc_tx_confirmed);
+
+ dtap_expect_tx("032d" /* CC: Release */);
+ mncc_sends_to_cc(MNCC_REL_REQ, &mncc);
+ OSMO_ASSERT(dtap_tx_confirmed);
+
+ cc_to_mncc_expect_tx("", MNCC_REL_CNF);
+ expect_bssap_clear();
+ ms_sends_msg("836a" /* CC: Release Complete */);
+ OSMO_ASSERT(cc_to_mncc_tx_confirmed);
+ OSMO_ASSERT(bssap_clear_sent);
+
+ ran_sends_clear_complete();
+ EXPECT_CONN_COUNT(0);
+ BTW("======================== SUCCESS: MT call: %s", t->desc);
+}
+
+static void test_codecs(void)
+{
+ const struct codec_test *t;
+ clear_vlr();
+
+ comment_start();
+
+ fake_time_start();
+
+ lu_geran_noauth();
+
+ for (t = codec_tests; t - codec_tests < ARRAY_SIZE(codec_tests); t++) {
+ test_codecs_mo(t);
+ test_codecs_mt(t);
+ }
+
+ EXPECT_CONN_COUNT(0);
+ clear_vlr();
+ comment_end();
+}
msc_vlr_test_func_t msc_vlr_tests[] = {
test_call_mo,
@@ -581,5 +1642,6 @@ msc_vlr_test_func_t msc_vlr_tests[] = {
test_call_mt2,
test_call_mo_to_unknown,
test_call_mo_to_unknown_timeout,
+ test_codecs,
NULL
};
diff --git a/tests/msc_vlr/msc_vlr_test_call.err b/tests/msc_vlr/msc_vlr_test_call.err
index 0eaa2f304..6fae30e73 100644
--- a/tests/msc_vlr/msc_vlr_test_call.err
+++ b/tests/msc_vlr/msc_vlr_test_call.err
@@ -1,7 +1,3 @@
-DLMGCP MGCP client: using endpoint domain '@mgw'
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 17
-
===== test_call_mo
- Total time passed: 0.000000 s
- Location Update request causes a GSUP Send Auth Info request to HLR
@@ -31,13 +27,14 @@ DREF VLR subscr IMSI-901700000010650 + active-conn: now used by 2 (_lu_fsm_assoc
DMSC msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK
DMSC msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH
DREF VLR subscr IMSI-901700000010650 - _lu_fsm_associate_vsub: now used by 1 (active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre()
DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH
DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: Allocated
DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU)
DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
-GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f00a0101
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f02801020a0101
DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
DREF msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: - mm_rx_loc_upd_req: now used by 2 (rx_from_ms,lu)
DREF msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu)
@@ -70,7 +67,7 @@ DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_WAIT_RESP}: A
DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU)
-DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES
+DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_SUCCESS
DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth()
DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: Set Ciphering Mode
DMSC msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: CIPHER_MODE_COMMAND on UTRAN-Iu
@@ -189,11 +186,11 @@ DMSC msub_fsm{terminating}: Deferring: will deallocate with msc_a(IMSI-901700000
DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){MSC_A_ST_RELEASED}: Deallocated, including all deferred deallocations
- msub gone
llist_count(&msub_list) == 0
-DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + standard_lu: now used by 2 (attached,standard_lu)
+DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + lu_utran_tmsi: now used by 2 (attached,lu_utran_tmsi)
vsub != NULL == 1
strcmp(vsub->imsi, IMSI) == 0
LAC == 23
-DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - standard_lu: now used by 1 (attached)
+DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - lu_utran_tmsi: now used by 1 (attached)
- after a while, a new conn sends a CM Service Request. VLR responds with Auth Req, 2nd auth vector
@@ -278,55 +275,119 @@ DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE
- a call is initiated
-- SETUP gets forwarded to MNCC
+- CC SETUP causes CRCX towards CN and RAN
MSC <--UTRAN-Iu-- MS: GSM48_MT_CC_SETUP
DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: + rx_from_ms: now used by 2 (cm_service_cc,rx_from_ms)
DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: RAN decode: DTAP
DRLL msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: Dispatching 04.08 message: CC GSM48_MT_CC_SETUP
DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + CC: now used by 3 (attached,active-conn,CC)
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 callref-0x80000001 tid-8) New transaction
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 callref-0x80000001 tid-8) New transaction
DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: Received Event MSC_A_EV_TRANSACTION_ACCEPTED
DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: state_chg to MSC_A_ST_COMMUNICATING
DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: + cc: now used by 3 (cm_service_cc,rx_from_ms,cc)
DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - cm_service_cc: now used by 2 (rx_from_ms,cc)
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) rx SETUP in state NULL
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) starting guard timer with 180 seconds
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) new state NULL -> INITIATED
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) SETUP to 123
-DMNCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) tx MNCC_SETUP_IND
- MSC --> MNCC: callref 0x80000001: MNCC_SETUP_IND
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) rx SETUP in state NULL
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) starting guard timer with 180 seconds
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) codecs: :0{AMR:octet-align=1#112} (from: MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} RAN={AMR:octet-align=1#112,AMR-WB/16000:octet-align=1#113})
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) SETUP to 123
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) new state NULL -> INITIATED
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Starting call assignment
+DCC call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){ESTABLISHING}: Allocated
+DCC call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){ESTABLISHING}: is child of msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ)
+DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) codecs: :0{AMR:octet-align=1#112} (from: MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} RAN={AMR:octet-align=1#112,AMR-WB/16000:octet-align=1#113})
+ MGW <--CRCX to RTP_TO_CN-- MSC: call_id=0x1 codecs=AMR:octet-align=1#112
+DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){UNINITIALIZED}: Allocated
+DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){UNINITIALIZED}: is child of call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ:trans-8:call-1:RTP_TO_CN:no-CI){UNINITIALIZED}: setting codecs to AMR:octet-align=1#112
+ MGW <--CRCX to RTP_TO_RAN-- MSC: call_id=0x1 codecs=VND.3GPP.IUFP/16000#96
+DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){UNINITIALIZED}: Allocated
+DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){UNINITIALIZED}: is child of call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ:trans-8:call-1:RTP_TO_RAN:no-CI){UNINITIALIZED}: setting codecs to VND.3GPP.IUFP/16000#96
DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc)
+- As soon as the MGW port towards CN is created, MNCC_SETUP_IND is triggered
+ MGW --CRCX OK to RTP_TO_CN--> MSC
+DCC call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){ESTABLISHING}: Received Event CALL_LEG_EV_RTP_STREAM_ADDR_AVAILABLE
+DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Received Event MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: MGW endpoint's RTP address available for the CI RTP_TO_CN: 10.23.23.1:23 (osmux=no:-2)
+DMNCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) tx MNCC_SETUP_IND (RTP=10.23.23.1:23{AMR:octet-align=1#112})
+ MSC --> MNCC: callref 0x80000001: MNCC_SETUP_IND
+v=0
+o=OsmoMSC 0 0 IN IP4 10.23.23.1
+s=GSM Call
+c=IN IP4 10.23.23.1
+t=0 0
+m=audio 23 RTP/AVP 112
+a=rtpmap:112 AMR/8000
+a=fmtp:112 octet-align=1
+a=ptime:20
+
+- MNCC replies with MNCC_RTP_CREATE
+ MSC <-- MNCC: callref 0x80000001: MNCC_RTP_CREATE
+
+DMNCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) rx MNCC_RTP_CREATE
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Assignment for this trans already started earlier
+- MGW acknowledges the CRCX, triggering Assignment
+ MGW --CRCX OK to RTP_TO_RAN--> MSC
+DCC call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){ESTABLISHING}: Received Event CALL_LEG_EV_RTP_STREAM_ADDR_AVAILABLE
+DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Received Event MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: MGW endpoint's RTP address available for the CI RTP_TO_RAN: 10.23.23.1:23 (osmux=no:-2)
+DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) codecs: 10.23.23.1:23{AMR:octet-align=1#112} (from: MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} RAN={AMR:octet-align=1#112,AMR-WB/16000:octet-align=1#113})
+DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) Sending Assignment Command
+DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN encode: ASSIGNMENT_COMMAND on UTRAN-Iu
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+- Assignment succeeds, triggering MNCC_RTP_CREATE ack to MNCC
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN decode: ASSIGNMENT_COMPLETE
+DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ:trans-8:call-1:RTP_TO_RAN:no-CI){UNINITIALIZED}: setting remote addr to 1.2.3.4:1234
+DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ:trans-8:call-1:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Not committing: no MGW endpoint CI set up
+DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) codecs: 10.23.23.1:23{AMR:octet-align=1#112} (from: assigned=AMR:octet-align=1#112 MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} RAN={AMR:octet-align=1#112,AMR-WB/16000:octet-align=1#113})
+DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) Assignment Complete: RAN: VND.3GPP.IUFP/16000#96, CN: AMR:octet-align=1#112
+DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) codecs: 10.23.23.1:23{AMR:octet-align=1#112} (from: assigned=AMR:octet-align=1#112 MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} RAN={AMR:octet-align=1#112,AMR-WB/16000:octet-align=1#113})
+DMNCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) tx MNCC_RTP_CREATE (RTP=10.23.23.1:23{AMR:octet-align=1#112})
+ MSC --> MNCC: callref 0x80000001: MNCC_RTP_CREATE
+v=0
+o=OsmoMSC 0 0 IN IP4 10.23.23.1
+s=GSM Call
+c=IN IP4 10.23.23.1
+t=0 0
+m=audio 23 RTP/AVP 112
+a=rtpmap:112 AMR/8000
+a=fmtp:112 octet-align=1
+a=ptime:20
+
- MNCC says that's fine
-DMNCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) rx MNCC_CALL_PROC_REQ
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) stopping pending guard timer
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) starting guard timer with 180 seconds
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) rx MNCC_CALL_PROC_REQ in state INITIATED
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) new state INITIATED -> MO_CALL_PROC
+ MSC <-- MNCC: callref 0x80000001: MNCC_CALL_PROC_REQ
+
+DMNCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) rx MNCC_CALL_PROC_REQ
+DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) stopping pending guard timer
+DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) starting guard timer with 180 seconds
+DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) new state INITIATED -> MO_CALL_PROC
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_CALL_PROC
DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on UTRAN-Iu
- DTAP --UTRAN-Iu--> MS: GSM48_MT_CC_CALL_PROC: 8302
- DTAP matches expected message
DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
-DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Starting call assignment
-DCC call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){ESTABLISHING}: Allocated
-DCC call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){ESTABLISHING}: is child of msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ)
- MS <--Call Assignment-- MSC: callref=0x80000001
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Assignment for this trans already started earlier
- Total time passed: 1.000023 s
- The other call leg got established (not shown here), MNCC tells us so
-DMNCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) rx MNCC_ALERT_REQ
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) stopping pending guard timer
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) starting guard timer with 180 seconds
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) rx MNCC_ALERT_REQ in state MO_CALL_PROC
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) new state MO_CALL_PROC -> CALL_DELIVERED
+ MSC <-- MNCC: callref 0x80000001: MNCC_ALERT_REQ
+
+DMNCC trans(CC:MO_CALL_PROC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) rx MNCC_ALERT_REQ
+DCC trans(CC:MO_CALL_PROC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) stopping pending guard timer
+DCC trans(CC:MO_CALL_PROC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) starting guard timer with 180 seconds
+DCC trans(CC:MO_CALL_PROC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) new state MO_CALL_PROC -> CALL_DELIVERED
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_ALERTING
DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on UTRAN-Iu
- DTAP --UTRAN-Iu--> MS: GSM48_MT_CC_ALERTING: 8301
- DTAP matches expected message
DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
-DMNCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) rx MNCC_SETUP_RSP
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) stopping pending guard timer
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) starting guard timer with 180 seconds
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) rx MNCC_SETUP_RSP in state CALL_DELIVERED
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) starting timer T313 with 30 seconds
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) new state CALL_DELIVERED -> CONNECT_IND
+ MSC <-- MNCC: callref 0x80000001: MNCC_SETUP_RSP
+
+DMNCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) rx MNCC_SETUP_RSP
+DCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) stopping pending guard timer
+DCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) starting guard timer with 180 seconds
+DCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) starting timer T313 with 30 seconds
+DCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) new state CALL_DELIVERED -> CONNECT_IND
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_CONNECT
DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on UTRAN-Iu
- DTAP --UTRAN-Iu--> MS: GSM48_MT_CC_CONNECT: 8307
- DTAP matches expected message
@@ -336,12 +397,13 @@ DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_S
DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms)
DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP
DRLL msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_CONNECT_ACK
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) rx CONNECT_ACK in state CONNECT_IND
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) stopping pending timer T313
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) new state CONNECT_IND -> ACTIVE
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) stopping pending guard timer
-DMNCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) tx MNCC_SETUP_COMPL_IND
+DCC trans(CC:CONNECT_IND IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) rx CONNECT_ACK in state CONNECT_IND
+DCC trans(CC:CONNECT_IND IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) stopping pending timer T313
+DCC trans(CC:CONNECT_IND IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) new state CONNECT_IND -> ACTIVE
+DCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) stopping pending guard timer
+DMNCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) tx MNCC_SETUP_COMPL_IND
MSC --> MNCC: callref 0x80000001: MNCC_SETUP_COMPL_IND
+
DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc)
@@ -354,16 +416,19 @@ DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE
DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms)
DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP
DRLL msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_DISCONNECT
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) rx DISCONNECT in state ACTIVE
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) new state ACTIVE -> DISCONNECT_IND
-DMNCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) tx MNCC_DISC_IND
+DCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) rx DISCONNECT in state ACTIVE
+DCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) new state ACTIVE -> DISCONNECT_IND
+DMNCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) tx MNCC_DISC_IND
MSC --> MNCC: callref 0x80000001: MNCC_DISC_IND
+
DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc)
-DMNCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) rx MNCC_REL_REQ
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) starting guard timer with 180 seconds
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) rx MNCC_REL_REQ in state DISCONNECT_IND
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) starting timer T308 with 10 seconds
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) new state DISCONNECT_IND -> RELEASE_REQ
+ MSC <-- MNCC: callref 0x80000001: MNCC_REL_REQ
+
+DMNCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) rx MNCC_REL_REQ
+DCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) starting guard timer with 180 seconds
+DCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) starting timer T308 with 10 seconds
+DCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) new state DISCONNECT_IND -> RELEASE_REQ
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_RELEASE
DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on UTRAN-Iu
- DTAP --UTRAN-Iu--> MS: GSM48_MT_CC_RELEASE: 832d
- DTAP matches expected message
@@ -372,13 +437,14 @@ DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_S
DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms)
DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP
DRLL msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_RELEASE_COMPL
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) rx RELEASE_COMPL in state RELEASE_REQ
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) stopping pending timer T308
-DMNCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) tx MNCC_REL_CNF
+DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) rx RELEASE_COMPL in state RELEASE_REQ
+DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) stopping pending timer T308
+DMNCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000001 tid-8) tx MNCC_REL_CNF
MSC --> MNCC: callref 0x80000001: MNCC_REL_CNF
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x0 tid-8) Freeing transaction
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x0 tid-8) new state RELEASE_REQ -> NULL
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x0 tid-8) stopping pending guard timer
+
+DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x0 tid-8) Freeing transaction
+DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x0 tid-8) new state RELEASE_REQ -> NULL
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x0 tid-8) stopping pending guard timer
DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - CC: now used by 2 (attached,active-conn)
DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - cc: now used by 1 (rx_from_ms)
DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 0 (-)
@@ -389,6 +455,12 @@ DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + msc_a_fsm_re
DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,active-conn,msc_a_fsm_releasing_onenter,vlr_subscr_cancel_attach_fsm)
DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,active-conn,msc_a_fsm_releasing_onenter)
DCC call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){ESTABLISHING}: state_chg to RELEASING
+DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ:trans-8:call-1:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ:trans-8:call-1:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Removing from parent call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ:trans-8:call-1:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Deallocated
+DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ:trans-8:call-1:RTP_TO_CN:no-CI){UNINITIALIZED}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ:trans-8:call-1:RTP_TO_CN:no-CI){UNINITIALIZED}: Removing from parent call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ:trans-8:call-1:RTP_TO_CN:no-CI){UNINITIALIZED}: Deallocated
DCC call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){RELEASING}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
DCC call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){RELEASING}: Removing from parent msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ)
DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: Received Event MSC_EV_CALL_LEG_TERM
@@ -425,9 +497,6 @@ DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE
DVLR freeing VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 (max total use count was 4)
===== test_call_mo: SUCCESS
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 17
-
===== test_call_mt
- Total time passed: 0.000000 s
- Location Update request causes a GSUP Send Auth Info request to HLR
@@ -457,13 +526,14 @@ DREF VLR subscr IMSI-901700000010650 + active-conn: now used by 2 (_lu_fsm_assoc
DMSC msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK
DMSC msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH
DREF VLR subscr IMSI-901700000010650 - _lu_fsm_associate_vsub: now used by 1 (active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre()
DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH
DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: Allocated
DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU)
DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
-GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f00a0101
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f02801020a0101
DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
DREF msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: - mm_rx_loc_upd_req: now used by 2 (rx_from_ms,lu)
DREF msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu)
@@ -496,7 +566,7 @@ DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_WAIT_RESP}: A
DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU)
-DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES
+DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_SUCCESS
DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth()
DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: Set Ciphering Mode
DMSC msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: CIPHER_MODE_COMMAND on UTRAN-Iu
@@ -615,17 +685,30 @@ DMSC msub_fsm{terminating}: Deferring: will deallocate with msc_a(IMSI-901700000
DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){MSC_A_ST_RELEASED}: Deallocated, including all deferred deallocations
- msub gone
llist_count(&msub_list) == 0
-DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + standard_lu: now used by 2 (attached,standard_lu)
+DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + lu_utran_tmsi: now used by 2 (attached,lu_utran_tmsi)
vsub != NULL == 1
strcmp(vsub->imsi, IMSI) == 0
LAC == 23
-DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - standard_lu: now used by 1 (attached)
+DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - lu_utran_tmsi: now used by 1 (attached)
- after a while, MNCC asks us to setup a call, causing Paging
+ MSC <-- MNCC: callref 0x423: MNCC_SETUP_REQ
+v=0
+o=OsmoMSC 0 0 IN IP4 10.23.23.1
+s=GSM Call
+c=IN IP4 10.23.23.1
+t=0 0
+m=audio 23 RTP/AVP 112
+a=rtpmap:112 AMR/8000
+a=fmtp:112 octet-align=1
+a=ptime:20
+
DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + mncc_tx_to_gsm_cc: now used by 2 (attached,mncc_tx_to_gsm_cc)
DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + CC: now used by 3 (attached,mncc_tx_to_gsm_cc,CC)
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 callref-0x423 tid-255) New transaction
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 callref-0x423 tid-255) New transaction
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 callref-0x423 tid-255) codecs: :0{(no-codecs)} (from: remote=10.23.23.1:23{AMR:octet-align=1#112} RAN={(no-codecs)})
+DMNCC trans(CC:NULL IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 callref-0x423 tid-255) rx MNCC_SETUP_REQ (RTP=10.23.23.1:23{AMR:octet-align=1#112})
DPAG Paging: IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 for MNCC: establish call: Starting paging
paging request (CALL_CONVERSATIONAL) to IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 on UTRAN-Iu
strcmp(paging_expecting_imsi, vsub->imsi) == 0
@@ -644,7 +727,7 @@ DMSC dummy_msc_i{0}: is child of msub_fsm
DREF msc_a(unknown:UTRAN-Iu:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms)
DIUCS msc_a(unknown:UTRAN-Iu:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3
DRLL msc_a(unknown:UTRAN-Iu:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: RR GSM48_MT_RR_PAG_RESP
-DRR msc_a(IMSI-901700000010650:UTRAN-Iu:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: Rx PAGING RESPONSE
+DRR msc_a(IMSI-901700000010650:UTRAN-Iu:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: Rx PAGING RESPONSE IMSI-901700000010650
DREF msc_a(IMSI-901700000010650:UTRAN-Iu:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: + paging-response: now used by 2 (rx_from_ms,paging-response)
DVLR Process_Access_Request_VLR(IMSI-901700000010650:UTRAN-Iu:PAGING_RESP){PR_ARQ_S_INIT}: Allocated
DVLR Process_Access_Request_VLR(IMSI-901700000010650:UTRAN-Iu:PAGING_RESP){PR_ARQ_S_INIT}: is child of msc_a(IMSI-901700000010650:UTRAN-Iu:PAGING_RESP)
@@ -708,61 +791,136 @@ DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RES
DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: state_chg to MSC_A_ST_AUTHENTICATED
DPAG Paging: IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 for MNCC: establish call: Paging Response action (success)
DPAG Paging: IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 for MNCC: establish call: Removing Paging Request
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 callref-0x423 tid-255) Paging succeeded
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 callref-0x423 tid-255) Paging succeeded
DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: + cc: now used by 2 (paging-response,cc)
DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: Received Event MSC_A_EV_TRANSACTION_ACCEPTED
DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: state_chg to MSC_A_ST_COMMUNICATING
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) starting timer T303 with 30 seconds
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) new state NULL -> CALL_PRESENT
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) starting timer T303 with 30 seconds
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) codecs: :0{AMR:octet-align=1#112} (from: remote=10.23.23.1:23{AMR:octet-align=1#112} RAN={AMR:octet-align=1#112,AMR-WB/16000:octet-align=1#113})
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) new state NULL -> CALL_PRESENT
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_SETUP
DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on UTRAN-Iu
-- DTAP --UTRAN-Iu--> MS: GSM48_MT_CC_SETUP: 0305
+- DTAP --UTRAN-Iu--> MS: GSM48_MT_CC_SETUP: 030504046004058b
- DTAP matches expected message
DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - Paging: now used by 3 (attached,CC,active-conn)
DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - paging-response: now used by 1 (cc)
+- MS confirms call, we create a RAN-side RTP and forward MNCC_CALL_CONF_IND
MSC <--UTRAN-Iu-- MS: GSM48_MT_CC_CALL_CONF
DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms)
DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP
DRLL msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_CALL_CONF
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) rx CALL_CONF in state CALL_PRESENT
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) stopping pending timer T303
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) starting timer T310 with 30 seconds
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) new state CALL_PRESENT -> MO_TERM_CALL_CONF
+DCC trans(CC:CALL_PRESENT IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) rx CALL_CONF in state CALL_PRESENT
+DCC trans(CC:CALL_PRESENT IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) stopping pending timer T303
+DCC trans(CC:CALL_PRESENT IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) starting timer T310 with 30 seconds
DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Starting call assignment
DCC call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){ESTABLISHING}: Allocated
DCC call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){ESTABLISHING}: is child of msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP)
- MS <--Call Assignment-- MSC: callref=0x423
-DMNCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) tx MNCC_CALL_CONF_IND
+DCC trans(CC:CALL_PRESENT IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) codecs: :0{AMR:octet-align=1#112} (from: remote=10.23.23.1:23{AMR:octet-align=1#112} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} RAN={AMR:octet-align=1#112,AMR-WB/16000:octet-align=1#113})
+ MGW <--CRCX to RTP_TO_CN-- MSC: call_id=0x2 codecs=AMR:octet-align=1#112
+DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){UNINITIALIZED}: Allocated
+DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){UNINITIALIZED}: is child of call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP:trans-0:call-2:RTP_TO_CN:no-CI){UNINITIALIZED}: setting codecs to AMR:octet-align=1#112
+ MGW <--CRCX to RTP_TO_RAN-- MSC: call_id=0x2 codecs=VND.3GPP.IUFP/16000#96
+DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){UNINITIALIZED}: Allocated
+DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){UNINITIALIZED}: is child of call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP:trans-0:call-2:RTP_TO_RAN:no-CI){UNINITIALIZED}: setting codecs to VND.3GPP.IUFP/16000#96
+DCC trans(CC:CALL_PRESENT IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) new state CALL_PRESENT -> MO_TERM_CALL_CONF
+DMNCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) tx MNCC_CALL_CONF_IND
MSC --> MNCC: callref 0x423: MNCC_CALL_CONF_IND
+
DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc)
+- MGW acknowledges the CRCX to RAN, triggering Assignment
+ MGW --CRCX OK to RTP_TO_RAN--> MSC
+DCC call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){ESTABLISHING}: Received Event CALL_LEG_EV_RTP_STREAM_ADDR_AVAILABLE
+DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Received Event MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: MGW endpoint's RTP address available for the CI RTP_TO_RAN: 10.23.23.1:23 (osmux=no:-2)
+DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) codecs: :0{AMR:octet-align=1#112} (from: remote=10.23.23.1:23{AMR:octet-align=1#112} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} RAN={AMR:octet-align=1#112,AMR-WB/16000:octet-align=1#113})
+DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) Sending Assignment Command
+DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN encode: ASSIGNMENT_COMMAND on UTRAN-Iu
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+- Assignment completes, triggering CRCX to CN
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN decode: ASSIGNMENT_COMPLETE
+DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP:trans-0:call-2:RTP_TO_RAN:no-CI){UNINITIALIZED}: setting remote addr to 1.2.3.4:1234
+DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP:trans-0:call-2:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Not committing: no MGW endpoint CI set up
+DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) codecs: :0{AMR:octet-align=1#112} (from: assigned=AMR:octet-align=1#112 remote=10.23.23.1:23{AMR:octet-align=1#112} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} RAN={AMR:octet-align=1#112,AMR-WB/16000:octet-align=1#113})
+DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) Assignment Complete: RAN: VND.3GPP.IUFP/16000#96, CN: AMR:octet-align=1#112
+DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) Assignment complete, but still waiting for the CRCX OK on the CN side RTP
+- MNCC sends MNCC_RTP_CREATE, which first waits for the CN side RTP
+ MSC <-- MNCC: callref 0x423: MNCC_RTP_CREATE
+
+DMNCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) rx MNCC_RTP_CREATE
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Assignment for this trans already started earlier
+- When the CN side RTP address is known, ack MNCC_RTP_CREATE with full SDP
+ MGW --CRCX OK to RTP_TO_CN--> MSC
+DCC call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){ESTABLISHING}: Received Event CALL_LEG_EV_RTP_STREAM_ADDR_AVAILABLE
+DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Received Event MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: MGW endpoint's RTP address available for the CI RTP_TO_CN: 10.23.23.1:23 (osmux=no:-2)
+DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) codecs: 10.23.23.1:23{AMR:octet-align=1#112} (from: assigned=AMR:octet-align=1#112 remote=10.23.23.1:23{AMR:octet-align=1#112} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} RAN={AMR:octet-align=1#112,AMR-WB/16000:octet-align=1#113})
+DMNCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) tx MNCC_RTP_CREATE (RTP=10.23.23.1:23{AMR:octet-align=1#112})
+ MSC --> MNCC: callref 0x423: MNCC_RTP_CREATE
+v=0
+o=OsmoMSC 0 0 IN IP4 10.23.23.1
+s=GSM Call
+c=IN IP4 10.23.23.1
+t=0 0
+m=audio 23 RTP/AVP 112
+a=rtpmap:112 AMR/8000
+a=fmtp:112 octet-align=1
+a=ptime:20
+
- Total time passed: 1.000023 s
MSC <--UTRAN-Iu-- MS: GSM48_MT_CC_ALERTING
DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms)
DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP
DRLL msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_ALERTING
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) rx ALERTING in state MO_TERM_CALL_CONF
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) stopping pending timer T310
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) starting timer T301 with 180 seconds
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) new state MO_TERM_CALL_CONF -> CALL_RECEIVED
-DMNCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) tx MNCC_ALERT_IND
+DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) rx ALERTING in state MO_TERM_CALL_CONF
+DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) stopping pending timer T310
+DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) starting timer T301 with 180 seconds
+DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) new state MO_TERM_CALL_CONF -> CALL_RECEIVED
+DCC trans(CC:CALL_RECEIVED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) codecs: 10.23.23.1:23{AMR:octet-align=1#112} (from: assigned=AMR:octet-align=1#112 remote=10.23.23.1:23{AMR:octet-align=1#112} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} RAN={AMR:octet-align=1#112,AMR-WB/16000:octet-align=1#113})
+DMNCC trans(CC:CALL_RECEIVED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) tx MNCC_ALERT_IND (RTP=10.23.23.1:23{AMR:octet-align=1#112})
MSC --> MNCC: callref 0x423: MNCC_ALERT_IND
+v=0
+o=OsmoMSC 0 0 IN IP4 10.23.23.1
+s=GSM Call
+c=IN IP4 10.23.23.1
+t=0 0
+m=audio 23 RTP/AVP 112
+a=rtpmap:112 AMR/8000
+a=fmtp:112 octet-align=1
+a=ptime:20
+
DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc)
- Total time passed: 2.000046 s
MSC <--UTRAN-Iu-- MS: GSM48_MT_CC_CONNECT
DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms)
DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP
DRLL msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_CONNECT
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) rx CONNECT in state CALL_RECEIVED
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) stopping pending timer T301
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) new state CALL_RECEIVED -> CONNECT_REQUEST
-DMNCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) tx MNCC_SETUP_CNF
+DCC trans(CC:CALL_RECEIVED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) rx CONNECT in state CALL_RECEIVED
+DCC trans(CC:CALL_RECEIVED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) stopping pending timer T301
+DCC trans(CC:CALL_RECEIVED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) new state CALL_RECEIVED -> CONNECT_REQUEST
+DCC trans(CC:CONNECT_REQUEST IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) codecs: 10.23.23.1:23{AMR:octet-align=1#112} (from: assigned=AMR:octet-align=1#112 remote=10.23.23.1:23{AMR:octet-align=1#112} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} RAN={AMR:octet-align=1#112,AMR-WB/16000:octet-align=1#113})
+DMNCC trans(CC:CONNECT_REQUEST IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) tx MNCC_SETUP_CNF (RTP=10.23.23.1:23{AMR:octet-align=1#112})
MSC --> MNCC: callref 0x423: MNCC_SETUP_CNF
+v=0
+o=OsmoMSC 0 0 IN IP4 10.23.23.1
+s=GSM Call
+c=IN IP4 10.23.23.1
+t=0 0
+m=audio 23 RTP/AVP 112
+a=rtpmap:112 AMR/8000
+a=fmtp:112 octet-align=1
+a=ptime:20
+
DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc)
-DMNCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) rx MNCC_SETUP_COMPL_REQ
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) starting guard timer with 180 seconds
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) rx MNCC_SETUP_COMPL_REQ in state CONNECT_REQUEST
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) new state CONNECT_REQUEST -> ACTIVE
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) stopping pending guard timer
+ MSC <-- MNCC: callref 0x423: MNCC_SETUP_COMPL_REQ
+
+DMNCC trans(CC:CONNECT_REQUEST IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) rx MNCC_SETUP_COMPL_REQ
+DCC trans(CC:CONNECT_REQUEST IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) starting guard timer with 180 seconds
+DCC trans(CC:CONNECT_REQUEST IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) new state CONNECT_REQUEST -> ACTIVE
+DCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) stopping pending guard timer
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_CONNECT_ACK
DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on UTRAN-Iu
- DTAP --UTRAN-Iu--> MS: GSM48_MT_CC_CONNECT_ACK: 030f
- DTAP matches expected message
@@ -778,16 +936,19 @@ DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGI
DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms)
DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP
DRLL msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_DISCONNECT
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) rx DISCONNECT in state ACTIVE
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) new state ACTIVE -> DISCONNECT_IND
-DMNCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) tx MNCC_DISC_IND
+DCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) rx DISCONNECT in state ACTIVE
+DCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) new state ACTIVE -> DISCONNECT_IND
+DMNCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) tx MNCC_DISC_IND
MSC --> MNCC: callref 0x423: MNCC_DISC_IND
+
DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc)
-DMNCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) rx MNCC_REL_REQ
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) starting guard timer with 180 seconds
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) rx MNCC_REL_REQ in state DISCONNECT_IND
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) starting timer T308 with 10 seconds
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) new state DISCONNECT_IND -> RELEASE_REQ
+ MSC <-- MNCC: callref 0x423: MNCC_REL_REQ
+
+DMNCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) rx MNCC_REL_REQ
+DCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) starting guard timer with 180 seconds
+DCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) starting timer T308 with 10 seconds
+DCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) new state DISCONNECT_IND -> RELEASE_REQ
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_RELEASE
DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on UTRAN-Iu
- DTAP --UTRAN-Iu--> MS: GSM48_MT_CC_RELEASE: 032d
- DTAP matches expected message
@@ -796,13 +957,14 @@ DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGI
DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms)
DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP
DRLL msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_RELEASE_COMPL
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) rx RELEASE_COMPL in state RELEASE_REQ
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) stopping pending timer T308
-DMNCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) tx MNCC_REL_CNF
+DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) rx RELEASE_COMPL in state RELEASE_REQ
+DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) stopping pending timer T308
+DMNCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) tx MNCC_REL_CNF
MSC --> MNCC: callref 0x423: MNCC_REL_CNF
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x0 tid-0) Freeing transaction
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x0 tid-0) new state RELEASE_REQ -> NULL
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x0 tid-0) stopping pending guard timer
+
+DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x0 tid-0) Freeing transaction
+DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x0 tid-0) new state RELEASE_REQ -> NULL
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x0 tid-0) stopping pending guard timer
DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - CC: now used by 2 (attached,active-conn)
DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - cc: now used by 1 (rx_from_ms)
DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 0 (-)
@@ -813,6 +975,12 @@ DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + msc_a_fsm_re
DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,active-conn,msc_a_fsm_releasing_onenter,vlr_subscr_cancel_attach_fsm)
DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,active-conn,msc_a_fsm_releasing_onenter)
DCC call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){ESTABLISHING}: state_chg to RELEASING
+DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP:trans-0:call-2:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP:trans-0:call-2:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Removing from parent call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP:trans-0:call-2:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Deallocated
+DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP:trans-0:call-2:RTP_TO_CN:no-CI){UNINITIALIZED}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP:trans-0:call-2:RTP_TO_CN:no-CI){UNINITIALIZED}: Removing from parent call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP:trans-0:call-2:RTP_TO_CN:no-CI){UNINITIALIZED}: Deallocated
DCC call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){RELEASING}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
DCC call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){RELEASING}: Removing from parent msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP)
DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_RELEASING}: Received Event MSC_EV_CALL_LEG_TERM
@@ -849,9 +1017,6 @@ DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RES
DVLR freeing VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 (max total use count was 5)
===== test_call_mt: SUCCESS
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 17
-
===== test_call_mt2
- Total time passed: 0.000000 s
- Location Update request causes a GSUP Send Auth Info request to HLR
@@ -881,13 +1046,14 @@ DREF VLR subscr IMSI-901700000010650 + active-conn: now used by 2 (_lu_fsm_assoc
DMSC msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK
DMSC msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH
DREF VLR subscr IMSI-901700000010650 - _lu_fsm_associate_vsub: now used by 1 (active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre()
DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH
DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: Allocated
DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU)
DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
-GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f00a0101
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f02801020a0101
DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
DREF msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: - mm_rx_loc_upd_req: now used by 2 (rx_from_ms,lu)
DREF msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu)
@@ -920,7 +1086,7 @@ DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_WAIT_RESP}: A
DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU)
-DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES
+DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_SUCCESS
DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth()
DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: Set Ciphering Mode
DMSC msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: CIPHER_MODE_COMMAND on UTRAN-Iu
@@ -1039,17 +1205,30 @@ DMSC msub_fsm{terminating}: Deferring: will deallocate with msc_a(IMSI-901700000
DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){MSC_A_ST_RELEASED}: Deallocated, including all deferred deallocations
- msub gone
llist_count(&msub_list) == 0
-DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + standard_lu: now used by 2 (attached,standard_lu)
+DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + lu_utran_tmsi: now used by 2 (attached,lu_utran_tmsi)
vsub != NULL == 1
strcmp(vsub->imsi, IMSI) == 0
LAC == 23
-DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - standard_lu: now used by 1 (attached)
+DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - lu_utran_tmsi: now used by 1 (attached)
- after a while, MNCC asks us to setup a call, causing Paging
+ MSC <-- MNCC: callref 0x423: MNCC_SETUP_REQ
+v=0
+o=OsmoMSC 0 0 IN IP4 10.23.23.1
+s=GSM Call
+c=IN IP4 10.23.23.1
+t=0 0
+m=audio 23 RTP/AVP 112
+a=rtpmap:112 AMR/8000
+a=fmtp:112 octet-align=1
+a=ptime:20
+
DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + mncc_tx_to_gsm_cc: now used by 2 (attached,mncc_tx_to_gsm_cc)
DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + CC: now used by 3 (attached,mncc_tx_to_gsm_cc,CC)
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 callref-0x423 tid-255) New transaction
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 callref-0x423 tid-255) New transaction
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 callref-0x423 tid-255) codecs: :0{(no-codecs)} (from: remote=10.23.23.1:23{AMR:octet-align=1#112} RAN={(no-codecs)})
+DMNCC trans(CC:NULL IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 callref-0x423 tid-255) rx MNCC_SETUP_REQ (RTP=10.23.23.1:23{AMR:octet-align=1#112})
DPAG Paging: IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 for MNCC: establish call: Starting paging
paging request (CALL_CONVERSATIONAL) to IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 on UTRAN-Iu
strcmp(paging_expecting_imsi, vsub->imsi) == 0
@@ -1068,7 +1247,7 @@ DMSC dummy_msc_i{0}: is child of msub_fsm
DREF msc_a(unknown:UTRAN-Iu:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms)
DIUCS msc_a(unknown:UTRAN-Iu:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3
DRLL msc_a(unknown:UTRAN-Iu:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: RR GSM48_MT_RR_PAG_RESP
-DRR msc_a(IMSI-901700000010650:UTRAN-Iu:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: Rx PAGING RESPONSE
+DRR msc_a(IMSI-901700000010650:UTRAN-Iu:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: Rx PAGING RESPONSE IMSI-901700000010650
DREF msc_a(IMSI-901700000010650:UTRAN-Iu:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: + paging-response: now used by 2 (rx_from_ms,paging-response)
DVLR Process_Access_Request_VLR(IMSI-901700000010650:UTRAN-Iu:PAGING_RESP){PR_ARQ_S_INIT}: Allocated
DVLR Process_Access_Request_VLR(IMSI-901700000010650:UTRAN-Iu:PAGING_RESP){PR_ARQ_S_INIT}: is child of msc_a(IMSI-901700000010650:UTRAN-Iu:PAGING_RESP)
@@ -1132,44 +1311,115 @@ DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RES
DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: state_chg to MSC_A_ST_AUTHENTICATED
DPAG Paging: IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 for MNCC: establish call: Paging Response action (success)
DPAG Paging: IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 for MNCC: establish call: Removing Paging Request
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 callref-0x423 tid-255) Paging succeeded
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 callref-0x423 tid-255) Paging succeeded
DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: + cc: now used by 2 (paging-response,cc)
DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: Received Event MSC_A_EV_TRANSACTION_ACCEPTED
DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: state_chg to MSC_A_ST_COMMUNICATING
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) starting timer T303 with 30 seconds
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) new state NULL -> CALL_PRESENT
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) starting timer T303 with 30 seconds
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) codecs: :0{AMR:octet-align=1#112} (from: remote=10.23.23.1:23{AMR:octet-align=1#112} RAN={AMR:octet-align=1#112,AMR-WB/16000:octet-align=1#113})
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) new state NULL -> CALL_PRESENT
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_SETUP
DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on UTRAN-Iu
-- DTAP --UTRAN-Iu--> MS: GSM48_MT_CC_SETUP: 0305
+- DTAP --UTRAN-Iu--> MS: GSM48_MT_CC_SETUP: 030504046004058b
- DTAP matches expected message
DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - Paging: now used by 3 (attached,CC,active-conn)
DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - paging-response: now used by 1 (cc)
+- MS confirms call, we create a RAN-side RTP and forward MNCC_CALL_CONF_IND
MSC <--UTRAN-Iu-- MS: GSM48_MT_CC_CALL_CONF
DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms)
DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP
DRLL msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_CALL_CONF
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) rx CALL_CONF in state CALL_PRESENT
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) stopping pending timer T303
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) starting timer T310 with 30 seconds
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) new state CALL_PRESENT -> MO_TERM_CALL_CONF
+DCC trans(CC:CALL_PRESENT IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) rx CALL_CONF in state CALL_PRESENT
+DCC trans(CC:CALL_PRESENT IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) stopping pending timer T303
+DCC trans(CC:CALL_PRESENT IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) starting timer T310 with 30 seconds
DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Starting call assignment
DCC call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){ESTABLISHING}: Allocated
DCC call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){ESTABLISHING}: is child of msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP)
- MS <--Call Assignment-- MSC: callref=0x423
-DMNCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) tx MNCC_CALL_CONF_IND
+DCC trans(CC:CALL_PRESENT IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) codecs: :0{AMR:octet-align=1#112} (from: remote=10.23.23.1:23{AMR:octet-align=1#112} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} RAN={AMR:octet-align=1#112,AMR-WB/16000:octet-align=1#113})
+ MGW <--CRCX to RTP_TO_CN-- MSC: call_id=0x3 codecs=AMR:octet-align=1#112
+DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){UNINITIALIZED}: Allocated
+DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){UNINITIALIZED}: is child of call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP:trans-0:call-3:RTP_TO_CN:no-CI){UNINITIALIZED}: setting codecs to AMR:octet-align=1#112
+ MGW <--CRCX to RTP_TO_RAN-- MSC: call_id=0x3 codecs=VND.3GPP.IUFP/16000#96
+DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){UNINITIALIZED}: Allocated
+DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){UNINITIALIZED}: is child of call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP:trans-0:call-3:RTP_TO_RAN:no-CI){UNINITIALIZED}: setting codecs to VND.3GPP.IUFP/16000#96
+DCC trans(CC:CALL_PRESENT IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) new state CALL_PRESENT -> MO_TERM_CALL_CONF
+DMNCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) tx MNCC_CALL_CONF_IND
MSC --> MNCC: callref 0x423: MNCC_CALL_CONF_IND
+
DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc)
+- MNCC sends MNCC_RTP_CREATE, which first waits for the CN side RTP
+ MSC <-- MNCC: callref 0x423: MNCC_RTP_CREATE
+v=0
+o=OsmoMSC 0 0 IN IP4 10.23.23.1
+s=GSM Call
+c=IN IP4 10.23.23.1
+t=0 0
+m=audio 23 RTP/AVP 112
+a=rtpmap:112 AMR/8000
+a=fmtp:112 octet-align=1
+a=ptime:20
+
+DMNCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) rx MNCC_RTP_CREATE (RTP=10.23.23.1:23{AMR:octet-align=1#112})
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Assignment for this trans already started earlier
+- MGW acknowledges the CRCX to RAN, triggering Assignment
+ MGW --CRCX OK to RTP_TO_RAN--> MSC
+DCC call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){ESTABLISHING}: Received Event CALL_LEG_EV_RTP_STREAM_ADDR_AVAILABLE
+DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Received Event MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: MGW endpoint's RTP address available for the CI RTP_TO_RAN: 10.23.23.1:23 (osmux=no:-2)
+DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) codecs: :0{AMR:octet-align=1#112} (from: remote=10.23.23.1:23{AMR:octet-align=1#112} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} RAN={AMR:octet-align=1#112,AMR-WB/16000:octet-align=1#113})
+DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) Sending Assignment Command
+DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN encode: ASSIGNMENT_COMMAND on UTRAN-Iu
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+- Assignment completes, triggering CRCX to CN
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN decode: ASSIGNMENT_COMPLETE
+DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP:trans-0:call-3:RTP_TO_RAN:no-CI){UNINITIALIZED}: setting remote addr to 1.2.3.4:1234
+DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP:trans-0:call-3:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Not committing: no MGW endpoint CI set up
+DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) codecs: :0{AMR:octet-align=1#112} (from: assigned=AMR:octet-align=1#112 remote=10.23.23.1:23{AMR:octet-align=1#112} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} RAN={AMR:octet-align=1#112,AMR-WB/16000:octet-align=1#113})
+DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) Assignment Complete: RAN: VND.3GPP.IUFP/16000#96, CN: AMR:octet-align=1#112
+DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) Assignment complete, but still waiting for the CRCX OK on the CN side RTP
+- When the CN side RTP address is known, ack MNCC_RTP_CREATE with full SDP
+ MGW --CRCX OK to RTP_TO_CN--> MSC
+DCC call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){ESTABLISHING}: Received Event CALL_LEG_EV_RTP_STREAM_ADDR_AVAILABLE
+DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Received Event MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: MGW endpoint's RTP address available for the CI RTP_TO_CN: 10.23.23.1:23 (osmux=no:-2)
+DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) codecs: 10.23.23.1:23{AMR:octet-align=1#112} (from: assigned=AMR:octet-align=1#112 remote=10.23.23.1:23{AMR:octet-align=1#112} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} RAN={AMR:octet-align=1#112,AMR-WB/16000:octet-align=1#113})
+DMNCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) tx MNCC_RTP_CREATE (RTP=10.23.23.1:23{AMR:octet-align=1#112})
+ MSC --> MNCC: callref 0x423: MNCC_RTP_CREATE
+v=0
+o=OsmoMSC 0 0 IN IP4 10.23.23.1
+s=GSM Call
+c=IN IP4 10.23.23.1
+t=0 0
+m=audio 23 RTP/AVP 112
+a=rtpmap:112 AMR/8000
+a=fmtp:112 octet-align=1
+a=ptime:20
+
- Total time passed: 1.000023 s
MSC <--UTRAN-Iu-- MS: GSM48_MT_CC_ALERTING
DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms)
DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP
DRLL msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_ALERTING
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) rx ALERTING in state MO_TERM_CALL_CONF
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) stopping pending timer T310
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) starting timer T301 with 180 seconds
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) new state MO_TERM_CALL_CONF -> CALL_RECEIVED
-DMNCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) tx MNCC_ALERT_IND
+DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) rx ALERTING in state MO_TERM_CALL_CONF
+DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) stopping pending timer T310
+DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) starting timer T301 with 180 seconds
+DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) new state MO_TERM_CALL_CONF -> CALL_RECEIVED
+DCC trans(CC:CALL_RECEIVED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) codecs: 10.23.23.1:23{AMR:octet-align=1#112} (from: assigned=AMR:octet-align=1#112 remote=10.23.23.1:23{AMR:octet-align=1#112} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} RAN={AMR:octet-align=1#112,AMR-WB/16000:octet-align=1#113})
+DMNCC trans(CC:CALL_RECEIVED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) tx MNCC_ALERT_IND (RTP=10.23.23.1:23{AMR:octet-align=1#112})
MSC --> MNCC: callref 0x423: MNCC_ALERT_IND
+v=0
+o=OsmoMSC 0 0 IN IP4 10.23.23.1
+s=GSM Call
+c=IN IP4 10.23.23.1
+t=0 0
+m=audio 23 RTP/AVP 112
+a=rtpmap:112 AMR/8000
+a=fmtp:112 octet-align=1
+a=ptime:20
+
DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc)
- Total time passed: 16.000046 s
- The call failed, the BSC sends a BSSMAP Clear Request
@@ -1179,22 +1429,30 @@ DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RE
DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + msc_a_fsm_releasing_onenter: now used by 4 (attached,CC,active-conn,msc_a_fsm_releasing_onenter)
DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + vlr_subscr_cancel_attach_fsm: now used by 5 (attached,CC,active-conn,msc_a_fsm_releasing_onenter,vlr_subscr_cancel_attach_fsm)
DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - vlr_subscr_cancel_attach_fsm: now used by 4 (attached,CC,active-conn,msc_a_fsm_releasing_onenter)
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) Freeing transaction
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) stopping pending timer T301
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) starting timer T308 with 10 seconds
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) new state CALL_RECEIVED -> RELEASE_REQ
+DCC trans(CC:CALL_RECEIVED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) Freeing transaction
+DCC trans(CC:CALL_RECEIVED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) stopping pending timer T301
+DMNCC trans(CC:CALL_RECEIVED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) tx MNCC_REL_IND
+ MSC --> MNCC: callref 0x423: MNCC_REL_IND
+
+DCC trans(CC:CALL_RECEIVED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) starting timer T308 with 10 seconds
+DCC trans(CC:CALL_RECEIVED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) new state CALL_RECEIVED -> RELEASE_REQ
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_RELEASING}: Sending DTAP: CC GSM48_MT_CC_RELEASE
DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_RELEASING}: RAN encode: DTAP on UTRAN-Iu
-- DTAP --UTRAN-Iu--> MS: GSM48_MT_CC_RELEASE: 032d080281af
+- DTAP --UTRAN-Iu--> MS: GSM48_MT_CC_RELEASE: 032d0802e1af
- DTAP matches expected message
DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
-DMNCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) tx MNCC_REL_CNF
- MSC --> MNCC: callref 0x423: MNCC_REL_CNF
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) stopping pending timer T308
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) new state RELEASE_REQ -> NULL
+DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) stopping pending timer T308
+DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x423 tid-0) new state RELEASE_REQ -> NULL
DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - CC: now used by 3 (attached,active-conn,msc_a_fsm_releasing_onenter)
DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_RELEASING}: - cc: now used by 0 (-)
DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_RELEASING}: Received Event MSC_A_EV_UNUSED
DCC call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){ESTABLISHING}: state_chg to RELEASING
+DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP:trans-0:call-3:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP:trans-0:call-3:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Removing from parent call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP:trans-0:call-3:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Deallocated
+DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP:trans-0:call-3:RTP_TO_CN:no-CI){UNINITIALIZED}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP:trans-0:call-3:RTP_TO_CN:no-CI){UNINITIALIZED}: Removing from parent call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP:trans-0:call-3:RTP_TO_CN:no-CI){UNINITIALIZED}: Deallocated
DCC call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){RELEASING}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
DCC call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){RELEASING}: Removing from parent msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP)
DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_RELEASING}: Received Event MSC_EV_CALL_LEG_TERM
@@ -1232,9 +1490,6 @@ DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RES
DVLR freeing VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 (max total use count was 5)
===== test_call_mt2: SUCCESS
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 17
-
===== test_call_mo_to_unknown
- Total time passed: 0.000000 s
- Location Update request causes a GSUP Send Auth Info request to HLR
@@ -1264,13 +1519,14 @@ DREF VLR subscr IMSI-901700000010650 + active-conn: now used by 2 (_lu_fsm_assoc
DMSC msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK
DMSC msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH
DREF VLR subscr IMSI-901700000010650 - _lu_fsm_associate_vsub: now used by 1 (active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre()
DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH
DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: Allocated
DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU)
DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
-GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f00a0101
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f02801020a0101
DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
DREF msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: - mm_rx_loc_upd_req: now used by 2 (rx_from_ms,lu)
DREF msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu)
@@ -1303,7 +1559,7 @@ DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_WAIT_RESP}: A
DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU)
-DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES
+DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_SUCCESS
DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth()
DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: Set Ciphering Mode
DMSC msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: CIPHER_MODE_COMMAND on UTRAN-Iu
@@ -1422,11 +1678,11 @@ DMSC msub_fsm{terminating}: Deferring: will deallocate with msc_a(IMSI-901700000
DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){MSC_A_ST_RELEASED}: Deallocated, including all deferred deallocations
- msub gone
llist_count(&msub_list) == 0
-DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + standard_lu: now used by 2 (attached,standard_lu)
+DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + lu_utran_tmsi: now used by 2 (attached,lu_utran_tmsi)
vsub != NULL == 1
strcmp(vsub->imsi, IMSI) == 0
LAC == 23
-DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - standard_lu: now used by 1 (attached)
+DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - lu_utran_tmsi: now used by 1 (attached)
- after a while, a new conn sends a CM Service Request. VLR responds with Auth Req, 2nd auth vector
@@ -1511,51 +1767,115 @@ DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE
- a call is initiated
-- SETUP gets forwarded to MNCC
+- CC SETUP causes CRCX towards CN and RAN
MSC <--UTRAN-Iu-- MS: GSM48_MT_CC_SETUP
DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: + rx_from_ms: now used by 2 (cm_service_cc,rx_from_ms)
DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: RAN decode: DTAP
DRLL msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: Dispatching 04.08 message: CC GSM48_MT_CC_SETUP
DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + CC: now used by 3 (attached,active-conn,CC)
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 callref-0x80000002 tid-8) New transaction
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 callref-0x80000002 tid-8) New transaction
DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: Received Event MSC_A_EV_TRANSACTION_ACCEPTED
DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: state_chg to MSC_A_ST_COMMUNICATING
DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: + cc: now used by 3 (cm_service_cc,rx_from_ms,cc)
DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - cm_service_cc: now used by 2 (rx_from_ms,cc)
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000002 tid-8) rx SETUP in state NULL
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000002 tid-8) starting guard timer with 180 seconds
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000002 tid-8) new state NULL -> INITIATED
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000002 tid-8) SETUP to 123
-DMNCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000002 tid-8) tx MNCC_SETUP_IND
- MSC --> MNCC: callref 0x80000002: MNCC_SETUP_IND
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000002 tid-8) rx SETUP in state NULL
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000002 tid-8) starting guard timer with 180 seconds
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000002 tid-8) codecs: :0{AMR:octet-align=1#112} (from: MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} RAN={AMR:octet-align=1#112,AMR-WB/16000:octet-align=1#113})
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000002 tid-8) SETUP to 123
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000002 tid-8) new state NULL -> INITIATED
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Starting call assignment
+DCC call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){ESTABLISHING}: Allocated
+DCC call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){ESTABLISHING}: is child of msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ)
+DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000002 tid-8) codecs: :0{AMR:octet-align=1#112} (from: MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} RAN={AMR:octet-align=1#112,AMR-WB/16000:octet-align=1#113})
+ MGW <--CRCX to RTP_TO_CN-- MSC: call_id=0x4 codecs=AMR:octet-align=1#112
+DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){UNINITIALIZED}: Allocated
+DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){UNINITIALIZED}: is child of call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ:trans-8:call-4:RTP_TO_CN:no-CI){UNINITIALIZED}: setting codecs to AMR:octet-align=1#112
+ MGW <--CRCX to RTP_TO_RAN-- MSC: call_id=0x4 codecs=VND.3GPP.IUFP/16000#96
+DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){UNINITIALIZED}: Allocated
+DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){UNINITIALIZED}: is child of call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ:trans-8:call-4:RTP_TO_RAN:no-CI){UNINITIALIZED}: setting codecs to VND.3GPP.IUFP/16000#96
DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc)
+- As soon as the MGW port towards CN is created, MNCC_SETUP_IND is triggered
+ MGW --CRCX OK to RTP_TO_CN--> MSC
+DCC call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){ESTABLISHING}: Received Event CALL_LEG_EV_RTP_STREAM_ADDR_AVAILABLE
+DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Received Event MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: MGW endpoint's RTP address available for the CI RTP_TO_CN: 10.23.23.1:23 (osmux=no:-2)
+DMNCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000002 tid-8) tx MNCC_SETUP_IND (RTP=10.23.23.1:23{AMR:octet-align=1#112})
+ MSC --> MNCC: callref 0x80000002: MNCC_SETUP_IND
+v=0
+o=OsmoMSC 0 0 IN IP4 10.23.23.1
+s=GSM Call
+c=IN IP4 10.23.23.1
+t=0 0
+m=audio 23 RTP/AVP 112
+a=rtpmap:112 AMR/8000
+a=fmtp:112 octet-align=1
+a=ptime:20
+
+- MNCC replies with MNCC_RTP_CREATE
+ MSC <-- MNCC: callref 0x80000002: MNCC_RTP_CREATE
+
+DMNCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000002 tid-8) rx MNCC_RTP_CREATE
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Assignment for this trans already started earlier
+- MGW acknowledges the CRCX, triggering Assignment
+ MGW --CRCX OK to RTP_TO_RAN--> MSC
+DCC call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){ESTABLISHING}: Received Event CALL_LEG_EV_RTP_STREAM_ADDR_AVAILABLE
+DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Received Event MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: MGW endpoint's RTP address available for the CI RTP_TO_RAN: 10.23.23.1:23 (osmux=no:-2)
+DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000002 tid-8) codecs: 10.23.23.1:23{AMR:octet-align=1#112} (from: MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} RAN={AMR:octet-align=1#112,AMR-WB/16000:octet-align=1#113})
+DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000002 tid-8) Sending Assignment Command
+DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN encode: ASSIGNMENT_COMMAND on UTRAN-Iu
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+- Assignment succeeds, triggering MNCC_RTP_CREATE ack to MNCC
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN decode: ASSIGNMENT_COMPLETE
+DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ:trans-8:call-4:RTP_TO_RAN:no-CI){UNINITIALIZED}: setting remote addr to 1.2.3.4:1234
+DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ:trans-8:call-4:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Not committing: no MGW endpoint CI set up
+DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000002 tid-8) codecs: 10.23.23.1:23{AMR:octet-align=1#112} (from: assigned=AMR:octet-align=1#112 MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} RAN={AMR:octet-align=1#112,AMR-WB/16000:octet-align=1#113})
+DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000002 tid-8) Assignment Complete: RAN: VND.3GPP.IUFP/16000#96, CN: AMR:octet-align=1#112
+DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000002 tid-8) codecs: 10.23.23.1:23{AMR:octet-align=1#112} (from: assigned=AMR:octet-align=1#112 MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} RAN={AMR:octet-align=1#112,AMR-WB/16000:octet-align=1#113})
+DMNCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000002 tid-8) tx MNCC_RTP_CREATE (RTP=10.23.23.1:23{AMR:octet-align=1#112})
+ MSC --> MNCC: callref 0x80000002: MNCC_RTP_CREATE
+v=0
+o=OsmoMSC 0 0 IN IP4 10.23.23.1
+s=GSM Call
+c=IN IP4 10.23.23.1
+t=0 0
+m=audio 23 RTP/AVP 112
+a=rtpmap:112 AMR/8000
+a=fmtp:112 octet-align=1
+a=ptime:20
+
- MNCC says that's fine
-DMNCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000002 tid-8) rx MNCC_CALL_PROC_REQ
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000002 tid-8) stopping pending guard timer
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000002 tid-8) starting guard timer with 180 seconds
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000002 tid-8) rx MNCC_CALL_PROC_REQ in state INITIATED
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000002 tid-8) new state INITIATED -> MO_CALL_PROC
+ MSC <-- MNCC: callref 0x80000002: MNCC_CALL_PROC_REQ
+
+DMNCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000002 tid-8) rx MNCC_CALL_PROC_REQ
+DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000002 tid-8) stopping pending guard timer
+DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000002 tid-8) starting guard timer with 180 seconds
+DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000002 tid-8) new state INITIATED -> MO_CALL_PROC
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_CALL_PROC
DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on UTRAN-Iu
- DTAP --UTRAN-Iu--> MS: GSM48_MT_CC_CALL_PROC: 8302
- DTAP matches expected message
DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
-DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Starting call assignment
-DCC call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){ESTABLISHING}: Allocated
-DCC call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){ESTABLISHING}: is child of msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ)
- MS <--Call Assignment-- MSC: callref=0x80000002
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Assignment for this trans already started earlier
- But the other side's MSISDN could not be resolved, MNCC tells us to cancel
-DMNCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000002 tid-8) rx MNCC_REL_REQ
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000002 tid-8) stopping pending guard timer
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000002 tid-8) starting guard timer with 180 seconds
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000002 tid-8) rx MNCC_REL_REQ in state MO_CALL_PROC
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000002 tid-8) starting timer T308 with 10 seconds
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000002 tid-8) new state MO_CALL_PROC -> RELEASE_REQ
+ MSC <-- MNCC: callref 0x80000002: MNCC_REL_REQ
+
+DMNCC trans(CC:MO_CALL_PROC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000002 tid-8) rx MNCC_REL_REQ
+DCC trans(CC:MO_CALL_PROC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000002 tid-8) stopping pending guard timer
+DCC trans(CC:MO_CALL_PROC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000002 tid-8) starting guard timer with 180 seconds
+DCC trans(CC:MO_CALL_PROC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000002 tid-8) starting timer T308 with 10 seconds
+DCC trans(CC:MO_CALL_PROC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000002 tid-8) new state MO_CALL_PROC -> RELEASE_REQ
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_RELEASE
DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on UTRAN-Iu
- DTAP --UTRAN-Iu--> MS: GSM48_MT_CC_RELEASE: 832d
- DTAP matches expected message
DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
- Total time passed: 10.000023 s
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000002 tid-8) starting timer T308 with 10 seconds
+DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000002 tid-8) Timeout of T308
+DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000002 tid-8) starting timer T308 with 10 seconds
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_RELEASE
DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on UTRAN-Iu
- DTAP --UTRAN-Iu--> MS: GSM48_MT_CC_RELEASE: 832d
- DTAP matches expected message
@@ -1564,13 +1884,14 @@ DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_S
DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms)
DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP
DRLL msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_RELEASE_COMPL
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000002 tid-8) rx RELEASE_COMPL in state RELEASE_REQ
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000002 tid-8) stopping pending timer T308
-DMNCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000002 tid-8) tx MNCC_REL_CNF
+DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000002 tid-8) rx RELEASE_COMPL in state RELEASE_REQ
+DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000002 tid-8) stopping pending timer T308
+DMNCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000002 tid-8) tx MNCC_REL_CNF
MSC --> MNCC: callref 0x80000002: MNCC_REL_CNF
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x0 tid-8) Freeing transaction
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x0 tid-8) new state RELEASE_REQ -> NULL
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x0 tid-8) stopping pending guard timer
+
+DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x0 tid-8) Freeing transaction
+DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x0 tid-8) new state RELEASE_REQ -> NULL
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x0 tid-8) stopping pending guard timer
DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - CC: now used by 2 (attached,active-conn)
DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - cc: now used by 1 (rx_from_ms)
DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 0 (-)
@@ -1581,6 +1902,12 @@ DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + msc_a_fsm_re
DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,active-conn,msc_a_fsm_releasing_onenter,vlr_subscr_cancel_attach_fsm)
DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,active-conn,msc_a_fsm_releasing_onenter)
DCC call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){ESTABLISHING}: state_chg to RELEASING
+DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ:trans-8:call-4:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ:trans-8:call-4:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Removing from parent call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ:trans-8:call-4:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Deallocated
+DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ:trans-8:call-4:RTP_TO_CN:no-CI){UNINITIALIZED}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ:trans-8:call-4:RTP_TO_CN:no-CI){UNINITIALIZED}: Removing from parent call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ:trans-8:call-4:RTP_TO_CN:no-CI){UNINITIALIZED}: Deallocated
DCC call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){RELEASING}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
DCC call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){RELEASING}: Removing from parent msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ)
DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: Received Event MSC_EV_CALL_LEG_TERM
@@ -1617,9 +1944,6 @@ DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE
DVLR freeing VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 (max total use count was 4)
===== test_call_mo_to_unknown: SUCCESS
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 17
-
===== test_call_mo_to_unknown_timeout
- Total time passed: 0.000000 s
- Location Update request causes a GSUP Send Auth Info request to HLR
@@ -1649,13 +1973,14 @@ DREF VLR subscr IMSI-901700000010650 + active-conn: now used by 2 (_lu_fsm_assoc
DMSC msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK
DMSC msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH
DREF VLR subscr IMSI-901700000010650 - _lu_fsm_associate_vsub: now used by 1 (active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre()
DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH
DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: Allocated
DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU)
DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
-GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f00a0101
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f02801020a0101
DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
DREF msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: - mm_rx_loc_upd_req: now used by 2 (rx_from_ms,lu)
DREF msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu)
@@ -1688,7 +2013,7 @@ DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_WAIT_RESP}: A
DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU)
-DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES
+DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_SUCCESS
DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth()
DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: Set Ciphering Mode
DMSC msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: CIPHER_MODE_COMMAND on UTRAN-Iu
@@ -1807,11 +2132,11 @@ DMSC msub_fsm{terminating}: Deferring: will deallocate with msc_a(IMSI-901700000
DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){MSC_A_ST_RELEASED}: Deallocated, including all deferred deallocations
- msub gone
llist_count(&msub_list) == 0
-DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + standard_lu: now used by 2 (attached,standard_lu)
+DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + lu_utran_tmsi: now used by 2 (attached,lu_utran_tmsi)
vsub != NULL == 1
strcmp(vsub->imsi, IMSI) == 0
LAC == 23
-DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - standard_lu: now used by 1 (attached)
+DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - lu_utran_tmsi: now used by 1 (attached)
- after a while, a new conn sends a CM Service Request. VLR responds with Auth Req, 2nd auth vector
@@ -1896,63 +2221,129 @@ DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE
- a call is initiated
-- SETUP gets forwarded to MNCC
+- CC SETUP causes CRCX towards CN and RAN
MSC <--UTRAN-Iu-- MS: GSM48_MT_CC_SETUP
DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: + rx_from_ms: now used by 2 (cm_service_cc,rx_from_ms)
DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: RAN decode: DTAP
DRLL msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: Dispatching 04.08 message: CC GSM48_MT_CC_SETUP
DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + CC: now used by 3 (attached,active-conn,CC)
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 callref-0x80000003 tid-8) New transaction
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 callref-0x80000003 tid-8) New transaction
DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: Received Event MSC_A_EV_TRANSACTION_ACCEPTED
DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: state_chg to MSC_A_ST_COMMUNICATING
DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: + cc: now used by 3 (cm_service_cc,rx_from_ms,cc)
DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - cm_service_cc: now used by 2 (rx_from_ms,cc)
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000003 tid-8) rx SETUP in state NULL
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000003 tid-8) starting guard timer with 180 seconds
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000003 tid-8) new state NULL -> INITIATED
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000003 tid-8) SETUP to 123
-DMNCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000003 tid-8) tx MNCC_SETUP_IND
- MSC --> MNCC: callref 0x80000003: MNCC_SETUP_IND
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000003 tid-8) rx SETUP in state NULL
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000003 tid-8) starting guard timer with 180 seconds
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000003 tid-8) codecs: :0{AMR:octet-align=1#112} (from: MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} RAN={AMR:octet-align=1#112,AMR-WB/16000:octet-align=1#113})
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000003 tid-8) SETUP to 123
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000003 tid-8) new state NULL -> INITIATED
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Starting call assignment
+DCC call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){ESTABLISHING}: Allocated
+DCC call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){ESTABLISHING}: is child of msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ)
+DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000003 tid-8) codecs: :0{AMR:octet-align=1#112} (from: MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} RAN={AMR:octet-align=1#112,AMR-WB/16000:octet-align=1#113})
+ MGW <--CRCX to RTP_TO_CN-- MSC: call_id=0x5 codecs=AMR:octet-align=1#112
+DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){UNINITIALIZED}: Allocated
+DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){UNINITIALIZED}: is child of call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ:trans-8:call-5:RTP_TO_CN:no-CI){UNINITIALIZED}: setting codecs to AMR:octet-align=1#112
+ MGW <--CRCX to RTP_TO_RAN-- MSC: call_id=0x5 codecs=VND.3GPP.IUFP/16000#96
+DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){UNINITIALIZED}: Allocated
+DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){UNINITIALIZED}: is child of call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ:trans-8:call-5:RTP_TO_RAN:no-CI){UNINITIALIZED}: setting codecs to VND.3GPP.IUFP/16000#96
DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc)
+- As soon as the MGW port towards CN is created, MNCC_SETUP_IND is triggered
+ MGW --CRCX OK to RTP_TO_CN--> MSC
+DCC call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){ESTABLISHING}: Received Event CALL_LEG_EV_RTP_STREAM_ADDR_AVAILABLE
+DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Received Event MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: MGW endpoint's RTP address available for the CI RTP_TO_CN: 10.23.23.1:23 (osmux=no:-2)
+DMNCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000003 tid-8) tx MNCC_SETUP_IND (RTP=10.23.23.1:23{AMR:octet-align=1#112})
+ MSC --> MNCC: callref 0x80000003: MNCC_SETUP_IND
+v=0
+o=OsmoMSC 0 0 IN IP4 10.23.23.1
+s=GSM Call
+c=IN IP4 10.23.23.1
+t=0 0
+m=audio 23 RTP/AVP 112
+a=rtpmap:112 AMR/8000
+a=fmtp:112 octet-align=1
+a=ptime:20
+
+- MNCC replies with MNCC_RTP_CREATE
+ MSC <-- MNCC: callref 0x80000003: MNCC_RTP_CREATE
+
+DMNCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000003 tid-8) rx MNCC_RTP_CREATE
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Assignment for this trans already started earlier
+- MGW acknowledges the CRCX, triggering Assignment
+ MGW --CRCX OK to RTP_TO_RAN--> MSC
+DCC call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){ESTABLISHING}: Received Event CALL_LEG_EV_RTP_STREAM_ADDR_AVAILABLE
+DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Received Event MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: MGW endpoint's RTP address available for the CI RTP_TO_RAN: 10.23.23.1:23 (osmux=no:-2)
+DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000003 tid-8) codecs: 10.23.23.1:23{AMR:octet-align=1#112} (from: MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} RAN={AMR:octet-align=1#112,AMR-WB/16000:octet-align=1#113})
+DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000003 tid-8) Sending Assignment Command
+DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN encode: ASSIGNMENT_COMMAND on UTRAN-Iu
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+- Assignment succeeds, triggering MNCC_RTP_CREATE ack to MNCC
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN decode: ASSIGNMENT_COMPLETE
+DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ:trans-8:call-5:RTP_TO_RAN:no-CI){UNINITIALIZED}: setting remote addr to 1.2.3.4:1234
+DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ:trans-8:call-5:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Not committing: no MGW endpoint CI set up
+DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000003 tid-8) codecs: 10.23.23.1:23{AMR:octet-align=1#112} (from: assigned=AMR:octet-align=1#112 MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} RAN={AMR:octet-align=1#112,AMR-WB/16000:octet-align=1#113})
+DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000003 tid-8) Assignment Complete: RAN: VND.3GPP.IUFP/16000#96, CN: AMR:octet-align=1#112
+DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000003 tid-8) codecs: 10.23.23.1:23{AMR:octet-align=1#112} (from: assigned=AMR:octet-align=1#112 MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} RAN={AMR:octet-align=1#112,AMR-WB/16000:octet-align=1#113})
+DMNCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000003 tid-8) tx MNCC_RTP_CREATE (RTP=10.23.23.1:23{AMR:octet-align=1#112})
+ MSC --> MNCC: callref 0x80000003: MNCC_RTP_CREATE
+v=0
+o=OsmoMSC 0 0 IN IP4 10.23.23.1
+s=GSM Call
+c=IN IP4 10.23.23.1
+t=0 0
+m=audio 23 RTP/AVP 112
+a=rtpmap:112 AMR/8000
+a=fmtp:112 octet-align=1
+a=ptime:20
+
- MNCC says that's fine
-DMNCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000003 tid-8) rx MNCC_CALL_PROC_REQ
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000003 tid-8) stopping pending guard timer
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000003 tid-8) starting guard timer with 180 seconds
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000003 tid-8) rx MNCC_CALL_PROC_REQ in state INITIATED
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000003 tid-8) new state INITIATED -> MO_CALL_PROC
+ MSC <-- MNCC: callref 0x80000003: MNCC_CALL_PROC_REQ
+
+DMNCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000003 tid-8) rx MNCC_CALL_PROC_REQ
+DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000003 tid-8) stopping pending guard timer
+DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000003 tid-8) starting guard timer with 180 seconds
+DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000003 tid-8) new state INITIATED -> MO_CALL_PROC
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_CALL_PROC
DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on UTRAN-Iu
- DTAP --UTRAN-Iu--> MS: GSM48_MT_CC_CALL_PROC: 8302
- DTAP matches expected message
DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
-DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Starting call assignment
-DCC call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){ESTABLISHING}: Allocated
-DCC call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){ESTABLISHING}: is child of msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ)
- MS <--Call Assignment-- MSC: callref=0x80000003
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Assignment for this trans already started earlier
- But the other side's MSISDN could not be resolved, MNCC tells us to cancel
-DMNCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000003 tid-8) rx MNCC_REL_REQ
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000003 tid-8) stopping pending guard timer
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000003 tid-8) starting guard timer with 180 seconds
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000003 tid-8) rx MNCC_REL_REQ in state MO_CALL_PROC
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000003 tid-8) starting timer T308 with 10 seconds
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000003 tid-8) new state MO_CALL_PROC -> RELEASE_REQ
+ MSC <-- MNCC: callref 0x80000003: MNCC_REL_REQ
+
+DMNCC trans(CC:MO_CALL_PROC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000003 tid-8) rx MNCC_REL_REQ
+DCC trans(CC:MO_CALL_PROC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000003 tid-8) stopping pending guard timer
+DCC trans(CC:MO_CALL_PROC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000003 tid-8) starting guard timer with 180 seconds
+DCC trans(CC:MO_CALL_PROC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000003 tid-8) starting timer T308 with 10 seconds
+DCC trans(CC:MO_CALL_PROC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000003 tid-8) new state MO_CALL_PROC -> RELEASE_REQ
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_RELEASE
DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on UTRAN-Iu
- DTAP --UTRAN-Iu--> MS: GSM48_MT_CC_RELEASE: 832d
- DTAP matches expected message
DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
- Despite our repeated CC Release Requests, the MS does not respond anymore
- Total time passed: 10.000023 s
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000003 tid-8) starting timer T308 with 10 seconds
+DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000003 tid-8) Timeout of T308
+DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000003 tid-8) starting timer T308 with 10 seconds
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_RELEASE
DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on UTRAN-Iu
- DTAP --UTRAN-Iu--> MS: GSM48_MT_CC_RELEASE: 832d
- DTAP matches expected message
DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
- The CC Release times out and we still properly clear the conn
- Total time passed: 20.000046 s
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000003 tid-8) Freeing transaction
-DMNCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000003 tid-8) tx MNCC_REL_CNF
+DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000003 tid-8) Timeout of T308
+DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000003 tid-8) Freeing transaction
+DMNCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000003 tid-8) tx MNCC_REL_CNF
MSC --> MNCC: callref 0x80000003: MNCC_REL_CNF
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000003 tid-8) new state RELEASE_REQ -> NULL
-DCC trans(CC IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000003 tid-8) stopping pending guard timer
+
+DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000003 tid-8) new state RELEASE_REQ -> NULL
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ callref-0x80000003 tid-8) stopping pending guard timer
DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - CC: now used by 2 (attached,active-conn)
DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - cc: now used by 0 (-)
DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Received Event MSC_A_EV_UNUSED
@@ -1962,6 +2353,12 @@ DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + msc_a_fsm_re
DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,active-conn,msc_a_fsm_releasing_onenter,vlr_subscr_cancel_attach_fsm)
DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,active-conn,msc_a_fsm_releasing_onenter)
DCC call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){ESTABLISHING}: state_chg to RELEASING
+DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ:trans-8:call-5:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ:trans-8:call-5:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Removing from parent call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ:trans-8:call-5:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Deallocated
+DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ:trans-8:call-5:RTP_TO_CN:no-CI){UNINITIALIZED}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ:trans-8:call-5:RTP_TO_CN:no-CI){UNINITIALIZED}: Removing from parent call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ:trans-8:call-5:RTP_TO_CN:no-CI){UNINITIALIZED}: Deallocated
DCC call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){RELEASING}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
DCC call_leg(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){RELEASING}: Removing from parent msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ)
DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: Received Event MSC_EV_CALL_LEG_TERM
@@ -1998,9 +2395,4513 @@ DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE
DVLR freeing VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 (max total use count was 4)
===== test_call_mo_to_unknown_timeout: SUCCESS
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 17
+===== test_codecs
+- Total time passed: 0.000000 s
+- Location Update request causes a GSUP LU request to HLR
+ MSC <--GERAN-A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
+ new conn
+DMSC msub_fsm{active}: Allocated
+DMSC msc_a{MSC_A_ST_VALIDATE_L3}: Allocated
+DMSC msc_a{MSC_A_ST_VALIDATE_L3}: is child of msub_fsm
+DMSC msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_VALIDATE_L3
+DMSC dummy_msc_i{0}: Allocated
+DMSC dummy_msc_i{0}: is child of msub_fsm
+DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms)
+DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3
+DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: MM GSM48_MT_MM_LOC_UPD_REQUEST
+DMM msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: LOCATION UPDATING REQUEST: MI=IMSI-901700000010650 LU-type=NORMAL
+DMM msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: USIM: old LAI: 901-70-23
+DREF msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: + mm_rx_loc_upd_req: now used by 2 (rx_from_ms,mm_rx_loc_upd_req)
+DREF msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: + lu: now used by 3 (rx_from_ms,mm_rx_loc_upd_req,lu)
+DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_IDLE}: Allocated
+DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_IDLE}: is child of msc_a(IMSI-901700000010650:GERAN-A:LU)
+DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_IDLE}: rev=R99 net=GERAN (no Auth)
+DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA
+DREF VLR subscr unknown + _lu_fsm_associate_vsub: now used by 1 (_lu_fsm_associate_vsub)
+DVLR set IMSI on subscriber; IMSI=901700000010650 id=901700000010650
+DVLR New subscr, IMSI: 901700000010650
+DREF VLR subscr IMSI-901700000010650 + active-conn: now used by 2 (_lu_fsm_associate_vsub,active-conn)
+DMSC msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK
+DMSC msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH
+DREF VLR subscr IMSI-901700000010650 - _lu_fsm_associate_vsub: now used by 1 (active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
+DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre()
+DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
+DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_post_auth()
+DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_post_ciph()
+DMSC msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000010650:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node_4()
+DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
+DVLR upd_hlr_vlr_fsm(IMSI-901700000010650:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated
+DVLR upd_hlr_vlr_fsm(IMSI-901700000010650:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU)
+DVLR upd_hlr_vlr_fsm(IMSI-901700000010650:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START
+GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000000156f02801020a0101
+DVLR upd_hlr_vlr_fsm(IMSI-901700000010650:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA
+DREF msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - mm_rx_loc_upd_req: now used by 2 (rx_from_ms,lu)
+DREF msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu)
+ lu_result_sent == 0
+- HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT
+<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: 10010809710000000156f00804036470f10a0101
+DREF VLR subscr IMSI-901700000010650 + vlr_gsup_rx: now used by 2 (active-conn,vlr_gsup_rx)
+DVLR IMSI:901700000010650 has MSISDN:46071
+DVLR SUBSCR(IMSI-901700000010650:MSISDN-46071) VLR: update for IMSI=901700000010650 (MSISDN=46071)
+GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000000156f00a0101
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - vlr_gsup_rx: now used by 1 (active-conn)
+<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: vlr_gsupc_read_cb() returns 0
+ lu_result_sent == 0
+- HLR also sends GSUP _UPDATE_LOCATION_RESULT
+<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: 06010809710000000156f00a0101
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + vlr_gsup_rx: now used by 2 (active-conn,vlr_gsup_rx)
+DVLR vlr_lu_fsm(IMSI-901700000010650:MSISDN-46071:GERAN-A:LU){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES
+DVLR upd_hlr_vlr_fsm(IMSI-901700000010650:GERAN-A:LU){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK
+DVLR upd_hlr_vlr_fsm(IMSI-901700000010650:GERAN-A:LU){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE
+DVLR upd_hlr_vlr_fsm(IMSI-901700000010650:GERAN-A:LU){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR upd_hlr_vlr_fsm(IMSI-901700000010650:GERAN-A:LU){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(IMSI-901700000010650:MSISDN-46071:GERAN-A:LU)
+DVLR vlr_lu_fsm(IMSI-901700000010650:MSISDN-46071:GERAN-A:LU){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL
+DVLR vlr_lu_fsm(IMSI-901700000010650:MSISDN-46071:GERAN-A:LU){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL
+DVLR lu_compl_vlr_fsm(IMSI-901700000010650:MSISDN-46071:GERAN-A:LU){LU_COMPL_VLR_S_INIT}: Allocated
+DVLR lu_compl_vlr_fsm(IMSI-901700000010650:MSISDN-46071:GERAN-A:LU){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(IMSI-901700000010650:MSISDN-46071:GERAN-A:LU)
+DVLR lu_compl_vlr_fsm(IMSI-901700000010650:MSISDN-46071:GERAN-A:LU){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START
+DVLR lu_compl_vlr_fsm(IMSI-901700000010650:MSISDN-46071:GERAN-A:LU){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES
+DVLR lu_compl_vlr_fsm(IMSI-901700000010650:MSISDN-46071:GERAN-A:LU){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL
+- sending LU Accept for IMSI-901700000010650:MSISDN-46071:GERAN-A:LU
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + attached: now used by 3 (active-conn,vlr_gsup_rx,attached)
+DVLR lu_compl_vlr_fsm(IMSI-901700000010650:MSISDN-46071:GERAN-A:LU){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_DONE
+DVLR vlr_lu_fsm(IMSI-901700000010650:MSISDN-46071:GERAN-A:LU){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS
+DVLR lu_compl_vlr_fsm(IMSI-901700000010650:MSISDN-46071:GERAN-A:LU){LU_COMPL_VLR_S_DONE}: Terminating in cascade, depth 2 (cause = OSMO_FSM_TERM_PARENT, caused by: upd_hlr_vlr_fsm(IMSI-901700000010650:GERAN-A:LU))
+DVLR lu_compl_vlr_fsm(IMSI-901700000010650:MSISDN-46071:GERAN-A:LU){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(IMSI-901700000010650:MSISDN-46071:GERAN-A:LU)
+DVLR lu_compl_vlr_fsm(IMSI-901700000010650:MSISDN-46071:GERAN-A:LU){LU_COMPL_VLR_S_DONE}: Deferring: will deallocate with upd_hlr_vlr_fsm(IMSI-901700000010650:GERAN-A:LU)
+DVLR vlr_lu_fsm(IMSI-901700000010650:MSISDN-46071:GERAN-A:LU){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: Received Event MSC_A_EV_AUTHENTICATED
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: state_chg to MSC_A_ST_AUTHENTICATED
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTHENTICATED}: - lu: now used by 0 (-)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTHENTICATED}: Received Event MSC_A_EV_UNUSED
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTHENTICATED}: state_chg to MSC_A_ST_RELEASING
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:LU){MSC_A_ST_RELEASING}: Releasing: msc_a use is 0 (-)
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + msc_a_fsm_releasing_onenter: now used by 4 (active-conn,vlr_gsup_rx,attached,msc_a_fsm_releasing_onenter)
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + vlr_subscr_cancel_attach_fsm: now used by 5 (active-conn,vlr_gsup_rx,attached,msc_a_fsm_releasing_onenter,vlr_subscr_cancel_attach_fsm)
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - vlr_subscr_cancel_attach_fsm: now used by 4 (active-conn,vlr_gsup_rx,attached,msc_a_fsm_releasing_onenter)
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:LU){MSC_A_ST_RELEASING}: + wait-Clear-Complete: now used by 1 (wait-Clear-Complete)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:LU){MSC_A_ST_RELEASING}: RAN encode: CLEAR_COMMAND on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - msc_a_fsm_releasing_onenter: now used by 3 (active-conn,vlr_gsup_rx,attached)
+DVLR upd_hlr_vlr_fsm(IMSI-901700000010650:GERAN-A:LU){UPD_HLR_VLR_S_DONE}: Deallocated, including all deferred deallocations
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - vlr_gsup_rx: now used by 2 (active-conn,attached)
+<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: vlr_gsupc_read_cb() returns 0
+- LU was successful, and the conn has already been closed
+ lu_result_sent == 1
+ bssap_clear_sent == 1
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:LU){MSC_A_ST_RELEASING}: RAN decode: CLEAR_COMPLETE
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:LU){MSC_A_ST_RELEASING}: - wait-Clear-Complete: now used by 0 (-)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:LU){MSC_A_ST_RELEASING}: Received Event MSC_A_EV_UNUSED
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:LU){MSC_A_ST_RELEASING}: state_chg to MSC_A_ST_RELEASED
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:LU){MSC_A_ST_RELEASED}: Released: msc_a use is 0 (-)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:LU){MSC_A_ST_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR vlr_lu_fsm(IMSI-901700000010650:MSISDN-46071:GERAN-A:LU){VLR_ULA_S_DONE}: Terminating in cascade, depth 2 (cause = OSMO_FSM_TERM_PARENT, caused by: msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:LU))
+DVLR vlr_lu_fsm(IMSI-901700000010650:MSISDN-46071:GERAN-A:LU){VLR_ULA_S_DONE}: Removing from parent msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:LU)
+DVLR vlr_lu_fsm(IMSI-901700000010650:MSISDN-46071:GERAN-A:LU){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT
+DVLR vlr_lu_fsm(IMSI-901700000010650:MSISDN-46071:GERAN-A:LU){VLR_ULA_S_DONE}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:LU)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:LU){MSC_A_ST_RELEASED}: Removing from parent msub_fsm
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:LU){MSC_A_ST_RELEASED}: max total use count was 3
+DMSC msub_fsm{active}: Received Event MSUB_EV_ROLE_TERMINATED
+DMSC msub(IMSI-901700000010650:MSISDN-46071) MSC-A terminated
+DMSC msub(IMSI-901700000010650:MSISDN-46071) 1 MSC-I still active
+DMSC msub_fsm{active}: state_chg to terminating
+DMSC msub_fsm{terminating}: Terminating in cascade, depth 2 (cause = OSMO_FSM_TERM_REGULAR, caused by: msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:LU))
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:LU){0}: Terminating in cascade, depth 3 (cause = OSMO_FSM_TERM_PARENT, caused by: msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:LU))
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:LU){0}: Removing from parent msub_fsm
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:LU){0}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:LU)
+DMSC msub(IMSI-901700000010650:MSISDN-46071) Free
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - active-conn: now used by 1 (attached)
+DMSC msub_fsm{terminating}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:LU)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:LU){MSC_A_ST_RELEASED}: Deallocated, including all deferred deallocations
+- msub gone
+ llist_count(&msub_list) == 0
+
+
+- ======================== MO call: AMR picked by both MO and MT
+- CM Service Request with Codec List (BSS Supported) = FR1 FR2 FR3 HR1 HR3
+ MSC <--GERAN-A-- MS: GSM48_MT_MM_CM_SERV_REQ
+ new conn
+DMSC msub_fsm{active}: Allocated
+DMSC msc_a{MSC_A_ST_VALIDATE_L3}: Allocated
+DMSC msc_a{MSC_A_ST_VALIDATE_L3}: is child of msub_fsm
+DMSC msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_VALIDATE_L3
+DMSC dummy_msc_i{0}: Allocated
+DMSC dummy_msc_i{0}: is child of msub_fsm
+DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms)
+DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3
+DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Complete Layer 3: Codec List (BSS Supported): GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111
+DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: MM GSM48_MT_MM_CM_SERV_REQ
+DMM msc_a(IMSI-901700000010650:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_VALIDATE_L3}: Rx CM SERVICE REQUEST cm_service_type=MO-Call
+DREF msc_a(IMSI-901700000010650:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_VALIDATE_L3}: + cm_service_cc: now used by 2 (rx_from_ms,cm_service_cc)
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: Allocated
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: is child of msc_a(IMSI-901700000010650:GERAN-A:CM_SERVICE_REQ)
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: rev=R99 net=GERAN (no Auth)
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + proc_arq_vlr_fn_init: now used by 2 (attached,proc_arq_vlr_fn_init)
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + active-conn: now used by 3 (attached,proc_arq_vlr_fn_init,active-conn)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi()
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_node2()
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_ciph()
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_vlr()
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_post_pres()
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_post_trace()
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_post_imei()
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: proc_arq_fsm_done(PASSED)
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_DONE
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_DONE}: Process Access Request result: PASSED
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: Sending DTAP: MM GSM48_MT_MM_CM_SERV_ACC
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN encode: DTAP on GERAN-A
+- DTAP --GERAN-A--> MS: GSM48_MT_MM_CM_SERV_ACC: 0521
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: Received Event MSC_A_EV_AUTHENTICATED
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: state_chg to MSC_A_ST_AUTHENTICATED
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - proc_arq_vlr_fn_init: now used by 2 (attached,active-conn)
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: - rx_from_ms: now used by 1 (cm_service_cc)
+ cm_service_result_sent == 1
+msc_a_is_accepted() == true
+- MS sends CC SETUP with Bearer Capability = AMR AMR AMR GSM-EFR GSM GSM-HR-08
+ MSC <--GERAN-A-- MS: GSM48_MT_CC_SETUP
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: + rx_from_ms: now used by 2 (cm_service_cc,rx_from_ms)
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: RAN decode: DTAP
+DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: Dispatching 04.08 message: CC GSM48_MT_CC_SETUP
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + CC: now used by 3 (attached,active-conn,CC)
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071 callref-0x80000004 tid-8) New transaction
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: Received Event MSC_A_EV_TRANSACTION_ACCEPTED
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: state_chg to MSC_A_ST_COMMUNICATING
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: + cc: now used by 3 (cm_service_cc,rx_from_ms,cc)
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - cm_service_cc: now used by 2 (rx_from_ms,cc)
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000004 tid-8) rx SETUP in state NULL
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000004 tid-8) starting guard timer with 180 seconds
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000004 tid-8) codecs: :0{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} (from: MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000004 tid-8) SETUP to 123
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000004 tid-8) new state NULL -> INITIATED
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Starting call assignment
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){ESTABLISHING}: Allocated
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){ESTABLISHING}: is child of msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ)
+DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000004 tid-8) codecs: :0{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} (from: MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+ MGW <--CRCX to RTP_TO_CN-- MSC: call_id=0x6 codecs=AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){UNINITIALIZED}: Allocated
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){UNINITIALIZED}: is child of call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-6:RTP_TO_CN:no-CI){UNINITIALIZED}: setting codecs to AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111
+ MGW <--CRCX to RTP_TO_RAN-- MSC: call_id=0x6 codecs=AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){UNINITIALIZED}: Allocated
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){UNINITIALIZED}: is child of call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-6:RTP_TO_RAN:no-CI){UNINITIALIZED}: setting codecs to AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc)
+- As soon as the MGW port towards CN is created, MNCC_SETUP_IND is triggered
+ MGW --CRCX OK to RTP_TO_CN--> MSC
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){ESTABLISHING}: Received Event CALL_LEG_EV_RTP_STREAM_ADDR_AVAILABLE
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Received Event MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: MGW endpoint's RTP address available for the CI RTP_TO_CN: 10.23.23.1:23 (osmux=no:-2)
+DMNCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000004 tid-8) tx MNCC_SETUP_IND (RTP=10.23.23.1:23{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+ MSC --> MNCC: callref 0x80000004: MNCC_SETUP_IND
+v=0
+o=OsmoMSC 0 0 IN IP4 10.23.23.1
+s=GSM Call
+c=IN IP4 10.23.23.1
+t=0 0
+m=audio 23 RTP/AVP 112 110 3 111
+a=rtpmap:112 AMR/8000
+a=fmtp:112 octet-align=1
+a=rtpmap:110 GSM-EFR/8000
+a=rtpmap:3 GSM/8000
+a=rtpmap:111 GSM-HR-08/8000
+a=ptime:20
+
+- VALIDATE_SDP OK: cc_to_mncc_tx_last_sdp == t->mo_tx_sdp_mncc_setup_ind == AMR GSM-EFR GSM GSM-HR-08
+- MNCC replies with MNCC_RTP_CREATE
+ MSC <-- MNCC: callref 0x80000004: MNCC_RTP_CREATE
+
+DMNCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000004 tid-8) rx MNCC_RTP_CREATE
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Assignment for this trans already started earlier
+- MGW acknowledges the CRCX, triggering Assignment with FR3 HR3 FR2 FR1 HR1
+ MGW --CRCX OK to RTP_TO_RAN--> MSC
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){ESTABLISHING}: Received Event CALL_LEG_EV_RTP_STREAM_ADDR_AVAILABLE
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Received Event MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: MGW endpoint's RTP address available for the CI RTP_TO_RAN: 10.23.23.1:23 (osmux=no:-2)
+DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000004 tid-8) codecs: 10.23.23.1:23{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} (from: MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000004 tid-8) Sending Assignment Command
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN encode: ASSIGNMENT_COMMAND on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+- VALIDATE_PERM_SPEECH OK: &bssap_assignment_command_last_channel_type == t->mo_tx_assignment_perm_speech == FR3 HR3 FR2 FR1 HR1
+- Assignment succeeds, triggering MNCC_RTP_CREATE ack to MNCC
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN decode: ASSIGNMENT_COMPLETE
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-6:RTP_TO_RAN:no-CI){UNINITIALIZED}: setting codecs to AMR:octet-align=1#112
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-6:RTP_TO_RAN:no-CI:local-10-23-23-1-23){UNINITIALIZED}: setting remote addr to 1.2.3.4:1234
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-6:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Not committing: no MGW endpoint CI set up
+DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000004 tid-8) codecs: 10.23.23.1:23{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} (from: assigned=AMR:octet-align=1#112 MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000004 tid-8) Assignment Complete: RAN: AMR:octet-align=1#112, CN: AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111
+DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000004 tid-8) codecs: 10.23.23.1:23{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} (from: assigned=AMR:octet-align=1#112 MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+DMNCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000004 tid-8) tx MNCC_RTP_CREATE (RTP=10.23.23.1:23{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+ MSC --> MNCC: callref 0x80000004: MNCC_RTP_CREATE
+v=0
+o=OsmoMSC 0 0 IN IP4 10.23.23.1
+s=GSM Call
+c=IN IP4 10.23.23.1
+t=0 0
+m=audio 23 RTP/AVP 112 110 3 111
+a=rtpmap:112 AMR/8000
+a=fmtp:112 octet-align=1
+a=rtpmap:110 GSM-EFR/8000
+a=rtpmap:3 GSM/8000
+a=rtpmap:111 GSM-HR-08/8000
+a=ptime:20
+
+- VALIDATE_SDP OK: cc_to_mncc_tx_last_sdp == t->mo_tx_sdp_mncc_rtp_create == AMR GSM-EFR GSM GSM-HR-08
+- MNCC says that's fine
+ MSC <-- MNCC: callref 0x80000004: MNCC_CALL_PROC_REQ
+
+DMNCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000004 tid-8) rx MNCC_CALL_PROC_REQ
+DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000004 tid-8) stopping pending guard timer
+DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000004 tid-8) starting guard timer with 180 seconds
+DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000004 tid-8) new state INITIATED -> MO_CALL_PROC
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_CALL_PROC
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on GERAN-A
+- DTAP --GERAN-A--> MS: GSM48_MT_CC_CALL_PROC: 8302
+- DTAP matches expected message
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Assignment for this trans already started earlier
+- Total time passed: 1.000023 s
+- The other call leg got established (not shown here), MNCC tells us so, with codecs { AMR GSM-EFR GSM GSM-HR-08 }
+ MSC <-- MNCC: callref 0x80000004: MNCC_ALERT_REQ
+v=0
+o=OsmoMSC 0 0 IN IP4 1.2.3.4
+s=GSM Call
+c=IN IP4 1.2.3.4
+t=0 0
+m=audio 56 RTP/AVP 112 110 3 111
+a=rtpmap:112 AMR/8000
+a=fmtp:112 octet-align=1
+a=rtpmap:110 GSM-EFR/8000
+a=rtpmap:3 GSM/8000
+a=rtpmap:111 GSM-HR-08/8000
+a=ptime:20
+
+DMNCC trans(CC:MO_CALL_PROC IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000004 tid-8) rx MNCC_ALERT_REQ (RTP=1.2.3.4:56{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+DCC trans(CC:MO_CALL_PROC IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000004 tid-8) stopping pending guard timer
+DCC trans(CC:MO_CALL_PROC IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000004 tid-8) starting guard timer with 180 seconds
+DCC trans(CC:MO_CALL_PROC IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000004 tid-8) new state MO_CALL_PROC -> CALL_DELIVERED
+DCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000004 tid-8) codecs: 10.23.23.1:23{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} (from: assigned=AMR:octet-align=1#112 remote=1.2.3.4:56{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-6:RTP_TO_CN:no-CI){UNINITIALIZED}: no change: codecs already set to AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-6:RTP_TO_CN:no-CI){UNINITIALIZED}: setting remote addr to 1.2.3.4:56
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-6:RTP_TO_CN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-56){UNINITIALIZED}: Not committing: no MGW endpoint CI set up
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_ALERTING
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on GERAN-A
+- DTAP --GERAN-A--> MS: GSM48_MT_CC_ALERTING: 8301
+- DTAP matches expected message
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+ MSC <-- MNCC: callref 0x80000004: MNCC_SETUP_RSP
+v=0
+o=OsmoMSC 0 0 IN IP4 1.2.3.4
+s=GSM Call
+c=IN IP4 1.2.3.4
+t=0 0
+m=audio 56 RTP/AVP 112 110 3 111
+a=rtpmap:112 AMR/8000
+a=fmtp:112 octet-align=1
+a=rtpmap:110 GSM-EFR/8000
+a=rtpmap:3 GSM/8000
+a=rtpmap:111 GSM-HR-08/8000
+a=ptime:20
+
+DMNCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000004 tid-8) rx MNCC_SETUP_RSP (RTP=1.2.3.4:56{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+DCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000004 tid-8) stopping pending guard timer
+DCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000004 tid-8) starting guard timer with 180 seconds
+DCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000004 tid-8) starting timer T313 with 30 seconds
+DCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000004 tid-8) new state CALL_DELIVERED -> CONNECT_IND
+DCC trans(CC:CONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000004 tid-8) codecs: 10.23.23.1:23{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} (from: assigned=AMR:octet-align=1#112 remote=1.2.3.4:56{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-6:RTP_TO_CN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-56){UNINITIALIZED}: no change: codecs already set to AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-6:RTP_TO_CN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-56){UNINITIALIZED}: remote addr already 1.2.3.4:56, no change
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-6:RTP_TO_CN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-56){UNINITIALIZED}: Not committing: no MGW endpoint CI set up
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_CONNECT
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on GERAN-A
+- DTAP --GERAN-A--> MS: GSM48_MT_CC_CONNECT: 8307
+- DTAP matches expected message
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+- Total time passed: 2.000046 s
+ MSC <--GERAN-A-- MS: GSM48_MT_CC_CONNECT_ACK
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms)
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP
+DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_CONNECT_ACK
+DCC trans(CC:CONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000004 tid-8) rx CONNECT_ACK in state CONNECT_IND
+DCC trans(CC:CONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000004 tid-8) stopping pending timer T313
+DCC trans(CC:CONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000004 tid-8) new state CONNECT_IND -> ACTIVE
+DCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000004 tid-8) stopping pending guard timer
+DMNCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000004 tid-8) tx MNCC_SETUP_COMPL_IND
+ MSC --> MNCC: callref 0x80000004: MNCC_SETUP_COMPL_IND
+
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc)
+- VALIDATE_SDP OK: cc_to_mncc_tx_last_sdp == t->mo_tx_sdp_mncc_setup_compl_ind ==
+
+
+- RTP stream goes ahead, not shown here.
+- Total time passed: 125.000091 s
+
+
+- Call ends
+ MSC <--GERAN-A-- MS: GSM48_MT_CC_DISCONNECT
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms)
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP
+DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_DISCONNECT
+DCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000004 tid-8) rx DISCONNECT in state ACTIVE
+DCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000004 tid-8) new state ACTIVE -> DISCONNECT_IND
+DMNCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000004 tid-8) tx MNCC_DISC_IND
+ MSC --> MNCC: callref 0x80000004: MNCC_DISC_IND
+
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc)
+ MSC <-- MNCC: callref 0x80000004: MNCC_REL_REQ
+v=0
+o=OsmoMSC 0 0 IN IP4 1.2.3.4
+s=GSM Call
+c=IN IP4 1.2.3.4
+t=0 0
+m=audio 56 RTP/AVP 112 110 3 111
+a=rtpmap:112 AMR/8000
+a=fmtp:112 octet-align=1
+a=rtpmap:110 GSM-EFR/8000
+a=rtpmap:3 GSM/8000
+a=rtpmap:111 GSM-HR-08/8000
+a=ptime:20
+
+DMNCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000004 tid-8) rx MNCC_REL_REQ
+DCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000004 tid-8) starting guard timer with 180 seconds
+DCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000004 tid-8) starting timer T308 with 10 seconds
+DCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000004 tid-8) new state DISCONNECT_IND -> RELEASE_REQ
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_RELEASE
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on GERAN-A
+- DTAP --GERAN-A--> MS: GSM48_MT_CC_RELEASE: 832d
+- DTAP matches expected message
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+ MSC <--GERAN-A-- MS: GSM48_MT_CC_RELEASE_COMPL
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms)
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP
+DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_RELEASE_COMPL
+DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000004 tid-8) rx RELEASE_COMPL in state RELEASE_REQ
+DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000004 tid-8) stopping pending timer T308
+DMNCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000004 tid-8) tx MNCC_REL_CNF
+ MSC --> MNCC: callref 0x80000004: MNCC_REL_CNF
+
+DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x0 tid-8) Freeing transaction
+DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x0 tid-8) new state RELEASE_REQ -> NULL
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x0 tid-8) stopping pending guard timer
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - CC: now used by 2 (attached,active-conn)
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - cc: now used by 1 (rx_from_ms)
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 0 (-)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Received Event MSC_A_EV_UNUSED
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: state_chg to MSC_A_ST_RELEASING
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: Releasing: msc_a use is 0 (-)
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + msc_a_fsm_releasing_onenter: now used by 3 (attached,active-conn,msc_a_fsm_releasing_onenter)
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,active-conn,msc_a_fsm_releasing_onenter,vlr_subscr_cancel_attach_fsm)
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,active-conn,msc_a_fsm_releasing_onenter)
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){ESTABLISHING}: state_chg to RELEASING
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-6:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-6:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Removing from parent call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-6:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Deallocated
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-6:RTP_TO_CN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-56){UNINITIALIZED}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-6:RTP_TO_CN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-56){UNINITIALIZED}: Removing from parent call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-6:RTP_TO_CN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-56){UNINITIALIZED}: Deallocated
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){RELEASING}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){RELEASING}: Removing from parent msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: Received Event MSC_EV_CALL_LEG_TERM
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){RELEASING}: Deallocated
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: + wait-Clear-Complete: now used by 1 (wait-Clear-Complete)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: RAN encode: CLEAR_COMMAND on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - msc_a_fsm_releasing_onenter: now used by 2 (attached,active-conn)
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: RAN decode: CLEAR_COMPLETE
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: - wait-Clear-Complete: now used by 0 (-)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: Received Event MSC_A_EV_UNUSED
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: state_chg to MSC_A_ST_RELEASED
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASED}: Released: msc_a use is 0 (-)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_DONE}: Terminating in cascade, depth 2 (cause = OSMO_FSM_TERM_PARENT, caused by: msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ))
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_DONE}: Removing from parent msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ)
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_DONE}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASED}: Removing from parent msub_fsm
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASED}: max total use count was 3
+DMSC msub_fsm{active}: Received Event MSUB_EV_ROLE_TERMINATED
+DMSC msub(IMSI-901700000010650:MSISDN-46071) MSC-A terminated
+DMSC msub(IMSI-901700000010650:MSISDN-46071) 1 MSC-I still active
+DMSC msub_fsm{active}: state_chg to terminating
+DMSC msub_fsm{terminating}: Terminating in cascade, depth 2 (cause = OSMO_FSM_TERM_REGULAR, caused by: msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ))
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Terminating in cascade, depth 3 (cause = OSMO_FSM_TERM_PARENT, caused by: msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ))
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Removing from parent msub_fsm
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ)
+DMSC msub(IMSI-901700000010650:MSISDN-46071) Free
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - active-conn: now used by 1 (attached)
+DMSC msub_fsm{terminating}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASED}: Deallocated, including all deferred deallocations
+- msub gone
+ llist_count(&msub_list) == 0
+
+
+- ======================== SUCCESS: MO call: AMR picked by both MO and MT
+
+
+- ======================== MT call: AMR picked by both MO and MT
+
+
+- MNCC asks us to setup a call, causing Paging
+ MSC <-- MNCC: callref 0x423: MNCC_SETUP_REQ
+v=0
+o=OsmoMSC 0 0 IN IP4 1.2.3.4
+s=GSM Call
+c=IN IP4 1.2.3.4
+t=0 0
+m=audio 56 RTP/AVP 112 110 3 111
+a=rtpmap:112 AMR/8000
+a=fmtp:112 octet-align=1
+a=rtpmap:110 GSM-EFR/8000
+a=rtpmap:3 GSM/8000
+a=rtpmap:111 GSM-HR-08/8000
+a=ptime:20
+
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + mncc_tx_to_gsm_cc: now used by 2 (attached,mncc_tx_to_gsm_cc)
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + CC: now used by 3 (attached,mncc_tx_to_gsm_cc,CC)
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071 callref-0x423 tid-255) New transaction
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071 callref-0x423 tid-255) codecs: :0{(no-codecs)} (from: remote=1.2.3.4:56{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} RAN={(no-codecs)})
+DMNCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071 callref-0x423 tid-255) rx MNCC_SETUP_REQ (RTP=1.2.3.4:56{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+DPAG Paging: IMSI-901700000010650:MSISDN-46071 for MNCC: establish call: Starting paging
+ paging request (CALL_CONVERSATIONAL) to IMSI-901700000010650:MSISDN-46071 on GERAN-A
+ strcmp(paging_expecting_imsi, vsub->imsi) == 0
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + Paging: now used by 4 (attached,mncc_tx_to_gsm_cc,CC,Paging)
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - mncc_tx_to_gsm_cc: now used by 3 (attached,CC,Paging)
+ paging_sent == 1
+- MS replies with Paging Response, with Codec List (BSS Supported) = FR1 FR2 FR3 HR1 HR3
+- VLR accepts, MSC sends CC Setup with Bearer Capability = AMR AMR AMR GSM-EFR GSM GSM-HR-08
+ MSC <--GERAN-A-- MS: GSM48_MT_RR_PAG_RESP
+ new conn
+DMSC msub_fsm{active}: Allocated
+DMSC msc_a{MSC_A_ST_VALIDATE_L3}: Allocated
+DMSC msc_a{MSC_A_ST_VALIDATE_L3}: is child of msub_fsm
+DMSC msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_VALIDATE_L3
+DMSC dummy_msc_i{0}: Allocated
+DMSC dummy_msc_i{0}: is child of msub_fsm
+DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms)
+DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3
+DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Complete Layer 3: Codec List (BSS Supported): GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111
+DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: RR GSM48_MT_RR_PAG_RESP
+DRR msc_a(IMSI-901700000010650:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: Rx PAGING RESPONSE IMSI-901700000010650
+DREF msc_a(IMSI-901700000010650:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: + paging-response: now used by 2 (rx_from_ms,paging-response)
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: Allocated
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: is child of msc_a(IMSI-901700000010650:GERAN-A:PAGING_RESP)
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: rev=R99 net=GERAN (no Auth)
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + proc_arq_vlr_fn_init: now used by 4 (attached,CC,Paging,proc_arq_vlr_fn_init)
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + active-conn: now used by 5 (attached,CC,Paging,proc_arq_vlr_fn_init,active-conn)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi()
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_node2()
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_ciph()
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_vlr()
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_post_pres()
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_post_trace()
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_post_imei()
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: proc_arq_fsm_done(PASSED)
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_DONE
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_DONE}: Process Access Request result: PASSED
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: Received Event MSC_A_EV_AUTHENTICATED
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: state_chg to MSC_A_ST_AUTHENTICATED
+DPAG Paging: IMSI-901700000010650:MSISDN-46071 for MNCC: establish call: Paging Response action (success)
+DPAG Paging: IMSI-901700000010650:MSISDN-46071 for MNCC: establish call: Removing Paging Request
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071 callref-0x423 tid-255) Paging succeeded
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: + cc: now used by 3 (rx_from_ms,paging-response,cc)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: Received Event MSC_A_EV_TRANSACTION_ACCEPTED
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: state_chg to MSC_A_ST_COMMUNICATING
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) starting timer T303 with 30 seconds
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) codecs: :0{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} (from: remote=1.2.3.4:56{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) new state NULL -> CALL_PRESENT
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_SETUP
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on GERAN-A
+- DTAP --GERAN-A--> MS: GSM48_MT_CC_SETUP: 030504076004050b020081
+- DTAP matches expected message
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - Paging: now used by 4 (attached,CC,proc_arq_vlr_fn_init,active-conn)
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - paging-response: now used by 2 (rx_from_ms,cc)
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - proc_arq_vlr_fn_init: now used by 3 (attached,CC,active-conn)
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc)
+- MS confirms call, we create a RAN-side RTP and forward MNCC_CALL_CONF_IND
+ MSC <--GERAN-A-- MS: GSM48_MT_CC_CALL_CONF
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms)
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP
+DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_CALL_CONF
+DCC trans(CC:CALL_PRESENT IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx CALL_CONF in state CALL_PRESENT
+DCC trans(CC:CALL_PRESENT IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) stopping pending timer T303
+DCC trans(CC:CALL_PRESENT IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) starting timer T310 with 30 seconds
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Starting call assignment
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){ESTABLISHING}: Allocated
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){ESTABLISHING}: is child of msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP)
+DCC trans(CC:CALL_PRESENT IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) codecs: :0{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} (from: remote=1.2.3.4:56{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+ MGW <--CRCX to RTP_TO_CN-- MSC: call_id=0x7 codecs=AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){UNINITIALIZED}: Allocated
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){UNINITIALIZED}: is child of call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-7:RTP_TO_CN:no-CI){UNINITIALIZED}: setting codecs to AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111
+ MGW <--CRCX to RTP_TO_RAN-- MSC: call_id=0x7 codecs=AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){UNINITIALIZED}: Allocated
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){UNINITIALIZED}: is child of call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-7:RTP_TO_RAN:no-CI){UNINITIALIZED}: setting codecs to AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111
+DCC trans(CC:CALL_PRESENT IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) new state CALL_PRESENT -> MO_TERM_CALL_CONF
+DMNCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) tx MNCC_CALL_CONF_IND
+ MSC --> MNCC: callref 0x423: MNCC_CALL_CONF_IND
+
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc)
+- VALIDATE_SDP OK: cc_to_mncc_tx_last_sdp == t->mt_tx_sdp_mncc_call_conf_ind ==
+- MGW acknowledges the CRCX to RAN, triggering Assignment with FR3 HR3 FR2 FR1 HR1
+ MGW --CRCX OK to RTP_TO_RAN--> MSC
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){ESTABLISHING}: Received Event CALL_LEG_EV_RTP_STREAM_ADDR_AVAILABLE
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Received Event MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: MGW endpoint's RTP address available for the CI RTP_TO_RAN: 10.23.23.1:23 (osmux=no:-2)
+DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) codecs: :0{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} (from: remote=1.2.3.4:56{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) Sending Assignment Command
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN encode: ASSIGNMENT_COMMAND on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+- VALIDATE_PERM_SPEECH OK: &bssap_assignment_command_last_channel_type == t->mt_tx_assignment_perm_speech == FR3 HR3 FR2 FR1 HR1
+- Assignment completes, triggering CRCX to CN
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN decode: ASSIGNMENT_COMPLETE
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-7:RTP_TO_RAN:no-CI){UNINITIALIZED}: setting codecs to AMR:octet-align=1#112
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-7:RTP_TO_RAN:no-CI:local-10-23-23-1-23){UNINITIALIZED}: setting remote addr to 1.2.3.4:1234
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-7:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Not committing: no MGW endpoint CI set up
+DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) codecs: :0{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} (from: assigned=AMR:octet-align=1#112 remote=1.2.3.4:56{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) Assignment Complete: RAN: AMR:octet-align=1#112, CN: AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111
+DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) Assignment complete, but still waiting for the CRCX OK on the CN side RTP
+- MNCC sends MNCC_RTP_CREATE, which first waits for the CN side RTP
+ MSC <-- MNCC: callref 0x423: MNCC_RTP_CREATE
+
+DMNCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx MNCC_RTP_CREATE
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Assignment for this trans already started earlier
+- When the CN side RTP address is known, ack MNCC_RTP_CREATE
+ MGW --CRCX OK to RTP_TO_CN--> MSC
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){ESTABLISHING}: Received Event CALL_LEG_EV_RTP_STREAM_ADDR_AVAILABLE
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Received Event MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: MGW endpoint's RTP address available for the CI RTP_TO_CN: 10.23.23.1:23 (osmux=no:-2)
+DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) codecs: 10.23.23.1:23{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} (from: assigned=AMR:octet-align=1#112 remote=1.2.3.4:56{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+DMNCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) tx MNCC_RTP_CREATE (RTP=10.23.23.1:23{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+ MSC --> MNCC: callref 0x423: MNCC_RTP_CREATE
+v=0
+o=OsmoMSC 0 0 IN IP4 10.23.23.1
+s=GSM Call
+c=IN IP4 10.23.23.1
+t=0 0
+m=audio 23 RTP/AVP 112 110 3 111
+a=rtpmap:112 AMR/8000
+a=fmtp:112 octet-align=1
+a=rtpmap:110 GSM-EFR/8000
+a=rtpmap:3 GSM/8000
+a=rtpmap:111 GSM-HR-08/8000
+a=ptime:20
+
+- VALIDATE_SDP OK: cc_to_mncc_tx_last_sdp == t->mt_tx_sdp_mncc_rtp_create == AMR GSM-EFR GSM GSM-HR-08
+- Total time passed: 126.000114 s
+ MSC <--GERAN-A-- MS: GSM48_MT_CC_ALERTING
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms)
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP
+DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_ALERTING
+DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx ALERTING in state MO_TERM_CALL_CONF
+DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) stopping pending timer T310
+DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) starting timer T301 with 180 seconds
+DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) new state MO_TERM_CALL_CONF -> CALL_RECEIVED
+DCC trans(CC:CALL_RECEIVED IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) codecs: 10.23.23.1:23{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} (from: assigned=AMR:octet-align=1#112 remote=1.2.3.4:56{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+DMNCC trans(CC:CALL_RECEIVED IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) tx MNCC_ALERT_IND (RTP=10.23.23.1:23{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+ MSC --> MNCC: callref 0x423: MNCC_ALERT_IND
+v=0
+o=OsmoMSC 0 0 IN IP4 10.23.23.1
+s=GSM Call
+c=IN IP4 10.23.23.1
+t=0 0
+m=audio 23 RTP/AVP 112 110 3 111
+a=rtpmap:112 AMR/8000
+a=fmtp:112 octet-align=1
+a=rtpmap:110 GSM-EFR/8000
+a=rtpmap:3 GSM/8000
+a=rtpmap:111 GSM-HR-08/8000
+a=ptime:20
+
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc)
+- VALIDATE_SDP OK: cc_to_mncc_tx_last_sdp == t->mt_tx_sdp_mncc_alert_ind == AMR GSM-EFR GSM GSM-HR-08
+- Total time passed: 127.000137 s
+ MSC <--GERAN-A-- MS: GSM48_MT_CC_CONNECT
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms)
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP
+DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_CONNECT
+DCC trans(CC:CALL_RECEIVED IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx CONNECT in state CALL_RECEIVED
+DCC trans(CC:CALL_RECEIVED IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) stopping pending timer T301
+DCC trans(CC:CALL_RECEIVED IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) new state CALL_RECEIVED -> CONNECT_REQUEST
+DCC trans(CC:CONNECT_REQUEST IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) codecs: 10.23.23.1:23{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} (from: assigned=AMR:octet-align=1#112 remote=1.2.3.4:56{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+DMNCC trans(CC:CONNECT_REQUEST IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) tx MNCC_SETUP_CNF (RTP=10.23.23.1:23{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+ MSC --> MNCC: callref 0x423: MNCC_SETUP_CNF
+v=0
+o=OsmoMSC 0 0 IN IP4 10.23.23.1
+s=GSM Call
+c=IN IP4 10.23.23.1
+t=0 0
+m=audio 23 RTP/AVP 112 110 3 111
+a=rtpmap:112 AMR/8000
+a=fmtp:112 octet-align=1
+a=rtpmap:110 GSM-EFR/8000
+a=rtpmap:3 GSM/8000
+a=rtpmap:111 GSM-HR-08/8000
+a=ptime:20
+
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc)
+- VALIDATE_SDP OK: cc_to_mncc_tx_last_sdp == t->mt_tx_sdp_mncc_setup_cnf == AMR GSM-EFR GSM GSM-HR-08
+ MSC <-- MNCC: callref 0x423: MNCC_SETUP_COMPL_REQ
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 17
+DMNCC trans(CC:CONNECT_REQUEST IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx MNCC_SETUP_COMPL_REQ
+DCC trans(CC:CONNECT_REQUEST IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) starting guard timer with 180 seconds
+DCC trans(CC:CONNECT_REQUEST IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) new state CONNECT_REQUEST -> ACTIVE
+DCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) stopping pending guard timer
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_CONNECT_ACK
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on GERAN-A
+- DTAP --GERAN-A--> MS: GSM48_MT_CC_CONNECT_ACK: 030f
+- DTAP matches expected message
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+
+
+- RTP stream goes ahead, not shown here.
+- Total time passed: 250.000182 s
+
+
+- Call ends
+ MSC <--GERAN-A-- MS: GSM48_MT_CC_DISCONNECT
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms)
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP
+DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_DISCONNECT
+DCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx DISCONNECT in state ACTIVE
+DCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) new state ACTIVE -> DISCONNECT_IND
+DMNCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) tx MNCC_DISC_IND
+ MSC --> MNCC: callref 0x423: MNCC_DISC_IND
+
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc)
+ MSC <-- MNCC: callref 0x423: MNCC_REL_REQ
+
+DMNCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx MNCC_REL_REQ
+DCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) starting guard timer with 180 seconds
+DCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) starting timer T308 with 10 seconds
+DCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) new state DISCONNECT_IND -> RELEASE_REQ
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_RELEASE
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on GERAN-A
+- DTAP --GERAN-A--> MS: GSM48_MT_CC_RELEASE: 032d
+- DTAP matches expected message
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+ MSC <--GERAN-A-- MS: GSM48_MT_CC_RELEASE_COMPL
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms)
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP
+DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_RELEASE_COMPL
+DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx RELEASE_COMPL in state RELEASE_REQ
+DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) stopping pending timer T308
+DMNCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) tx MNCC_REL_CNF
+ MSC --> MNCC: callref 0x423: MNCC_REL_CNF
+
+DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x0 tid-0) Freeing transaction
+DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x0 tid-0) new state RELEASE_REQ -> NULL
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x0 tid-0) stopping pending guard timer
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - CC: now used by 2 (attached,active-conn)
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - cc: now used by 1 (rx_from_ms)
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 0 (-)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Received Event MSC_A_EV_UNUSED
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: state_chg to MSC_A_ST_RELEASING
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: Releasing: msc_a use is 0 (-)
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + msc_a_fsm_releasing_onenter: now used by 3 (attached,active-conn,msc_a_fsm_releasing_onenter)
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,active-conn,msc_a_fsm_releasing_onenter,vlr_subscr_cancel_attach_fsm)
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,active-conn,msc_a_fsm_releasing_onenter)
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){ESTABLISHING}: state_chg to RELEASING
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-7:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-7:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Removing from parent call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-7:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Deallocated
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-7:RTP_TO_CN:no-CI){UNINITIALIZED}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-7:RTP_TO_CN:no-CI){UNINITIALIZED}: Removing from parent call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-7:RTP_TO_CN:no-CI){UNINITIALIZED}: Deallocated
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){RELEASING}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){RELEASING}: Removing from parent msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: Received Event MSC_EV_CALL_LEG_TERM
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){RELEASING}: Deallocated
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: + wait-Clear-Complete: now used by 1 (wait-Clear-Complete)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: RAN encode: CLEAR_COMMAND on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - msc_a_fsm_releasing_onenter: now used by 2 (attached,active-conn)
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: RAN decode: CLEAR_COMPLETE
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: - wait-Clear-Complete: now used by 0 (-)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: Received Event MSC_A_EV_UNUSED
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: state_chg to MSC_A_ST_RELEASED
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASED}: Released: msc_a use is 0 (-)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_DONE}: Terminating in cascade, depth 2 (cause = OSMO_FSM_TERM_PARENT, caused by: msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP))
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_DONE}: Removing from parent msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP)
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_DONE}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASED}: Removing from parent msub_fsm
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASED}: max total use count was 3
+DMSC msub_fsm{active}: Received Event MSUB_EV_ROLE_TERMINATED
+DMSC msub(IMSI-901700000010650:MSISDN-46071) MSC-A terminated
+DMSC msub(IMSI-901700000010650:MSISDN-46071) 1 MSC-I still active
+DMSC msub_fsm{active}: state_chg to terminating
+DMSC msub_fsm{terminating}: Terminating in cascade, depth 2 (cause = OSMO_FSM_TERM_REGULAR, caused by: msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP))
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Terminating in cascade, depth 3 (cause = OSMO_FSM_TERM_PARENT, caused by: msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP))
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Removing from parent msub_fsm
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP)
+DMSC msub(IMSI-901700000010650:MSISDN-46071) Free
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - active-conn: now used by 1 (attached)
+DMSC msub_fsm{terminating}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASED}: Deallocated, including all deferred deallocations
+- msub gone
+ llist_count(&msub_list) == 0
+
+
+- ======================== SUCCESS: MT call: AMR picked by both MO and MT
+
+
+- ======================== MO call: FR1 picked by MO from Codec List (BSS Supported), MT hence also picks FR1
+- CM Service Request with Codec List (BSS Supported) = FR1
+ MSC <--GERAN-A-- MS: GSM48_MT_MM_CM_SERV_REQ
+ new conn
+DMSC msub_fsm{active}: Allocated
+DMSC msc_a{MSC_A_ST_VALIDATE_L3}: Allocated
+DMSC msc_a{MSC_A_ST_VALIDATE_L3}: is child of msub_fsm
+DMSC msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_VALIDATE_L3
+DMSC dummy_msc_i{0}: Allocated
+DMSC dummy_msc_i{0}: is child of msub_fsm
+DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms)
+DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3
+DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Complete Layer 3: Codec List (BSS Supported): GSM#3
+DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: MM GSM48_MT_MM_CM_SERV_REQ
+DMM msc_a(IMSI-901700000010650:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_VALIDATE_L3}: Rx CM SERVICE REQUEST cm_service_type=MO-Call
+DREF msc_a(IMSI-901700000010650:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_VALIDATE_L3}: + cm_service_cc: now used by 2 (rx_from_ms,cm_service_cc)
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: Allocated
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: is child of msc_a(IMSI-901700000010650:GERAN-A:CM_SERVICE_REQ)
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: rev=R99 net=GERAN (no Auth)
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + proc_arq_vlr_fn_init: now used by 2 (attached,proc_arq_vlr_fn_init)
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + active-conn: now used by 3 (attached,proc_arq_vlr_fn_init,active-conn)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi()
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_node2()
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_ciph()
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_vlr()
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_post_pres()
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_post_trace()
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_post_imei()
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: proc_arq_fsm_done(PASSED)
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_DONE
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_DONE}: Process Access Request result: PASSED
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: Sending DTAP: MM GSM48_MT_MM_CM_SERV_ACC
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN encode: DTAP on GERAN-A
+- DTAP --GERAN-A--> MS: GSM48_MT_MM_CM_SERV_ACC: 0521
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: Received Event MSC_A_EV_AUTHENTICATED
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: state_chg to MSC_A_ST_AUTHENTICATED
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - proc_arq_vlr_fn_init: now used by 2 (attached,active-conn)
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: - rx_from_ms: now used by 1 (cm_service_cc)
+ cm_service_result_sent == 1
+msc_a_is_accepted() == true
+- MS sends CC SETUP with Bearer Capability = AMR AMR AMR GSM-EFR GSM GSM-HR-08
+ MSC <--GERAN-A-- MS: GSM48_MT_CC_SETUP
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: + rx_from_ms: now used by 2 (cm_service_cc,rx_from_ms)
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: RAN decode: DTAP
+DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: Dispatching 04.08 message: CC GSM48_MT_CC_SETUP
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + CC: now used by 3 (attached,active-conn,CC)
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071 callref-0x80000005 tid-8) New transaction
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: Received Event MSC_A_EV_TRANSACTION_ACCEPTED
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: state_chg to MSC_A_ST_COMMUNICATING
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: + cc: now used by 3 (cm_service_cc,rx_from_ms,cc)
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - cm_service_cc: now used by 2 (rx_from_ms,cc)
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000005 tid-8) rx SETUP in state NULL
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000005 tid-8) starting guard timer with 180 seconds
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000005 tid-8) codecs: :0{GSM#3} (from: MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000005 tid-8) SETUP to 123
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000005 tid-8) new state NULL -> INITIATED
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Starting call assignment
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){ESTABLISHING}: Allocated
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){ESTABLISHING}: is child of msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ)
+DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000005 tid-8) codecs: :0{GSM#3} (from: MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+ MGW <--CRCX to RTP_TO_CN-- MSC: call_id=0x8 codecs=GSM#3
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){UNINITIALIZED}: Allocated
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){UNINITIALIZED}: is child of call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-8:RTP_TO_CN:no-CI){UNINITIALIZED}: setting codecs to GSM#3
+ MGW <--CRCX to RTP_TO_RAN-- MSC: call_id=0x8 codecs=GSM#3
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){UNINITIALIZED}: Allocated
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){UNINITIALIZED}: is child of call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-8:RTP_TO_RAN:no-CI){UNINITIALIZED}: setting codecs to GSM#3
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc)
+- As soon as the MGW port towards CN is created, MNCC_SETUP_IND is triggered
+ MGW --CRCX OK to RTP_TO_CN--> MSC
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){ESTABLISHING}: Received Event CALL_LEG_EV_RTP_STREAM_ADDR_AVAILABLE
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Received Event MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: MGW endpoint's RTP address available for the CI RTP_TO_CN: 10.23.23.1:23 (osmux=no:-2)
+DMNCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000005 tid-8) tx MNCC_SETUP_IND (RTP=10.23.23.1:23{GSM#3})
+ MSC --> MNCC: callref 0x80000005: MNCC_SETUP_IND
+v=0
+o=OsmoMSC 0 0 IN IP4 10.23.23.1
+s=GSM Call
+c=IN IP4 10.23.23.1
+t=0 0
+m=audio 23 RTP/AVP 3
+a=rtpmap:3 GSM/8000
+a=ptime:20
+
+- VALIDATE_SDP OK: cc_to_mncc_tx_last_sdp == t->mo_tx_sdp_mncc_setup_ind == GSM
+- MNCC replies with MNCC_RTP_CREATE
+ MSC <-- MNCC: callref 0x80000005: MNCC_RTP_CREATE
+
+DMNCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000005 tid-8) rx MNCC_RTP_CREATE
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Assignment for this trans already started earlier
+- MGW acknowledges the CRCX, triggering Assignment with FR1
+ MGW --CRCX OK to RTP_TO_RAN--> MSC
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){ESTABLISHING}: Received Event CALL_LEG_EV_RTP_STREAM_ADDR_AVAILABLE
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Received Event MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: MGW endpoint's RTP address available for the CI RTP_TO_RAN: 10.23.23.1:23 (osmux=no:-2)
+DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000005 tid-8) codecs: 10.23.23.1:23{GSM#3} (from: MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000005 tid-8) Sending Assignment Command
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN encode: ASSIGNMENT_COMMAND on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+- VALIDATE_PERM_SPEECH OK: &bssap_assignment_command_last_channel_type == t->mo_tx_assignment_perm_speech == FR1
+- Assignment succeeds, triggering MNCC_RTP_CREATE ack to MNCC
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN decode: ASSIGNMENT_COMPLETE
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-8:RTP_TO_RAN:no-CI){UNINITIALIZED}: no change: codecs already set to GSM#3
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-8:RTP_TO_RAN:no-CI){UNINITIALIZED}: setting remote addr to 1.2.3.4:1234
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-8:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Not committing: no MGW endpoint CI set up
+DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000005 tid-8) codecs: 10.23.23.1:23{GSM#3} (from: assigned=GSM#3 MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000005 tid-8) Assignment Complete: RAN: GSM#3, CN: GSM#3
+DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000005 tid-8) codecs: 10.23.23.1:23{GSM#3} (from: assigned=GSM#3 MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+DMNCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000005 tid-8) tx MNCC_RTP_CREATE (RTP=10.23.23.1:23{GSM#3})
+ MSC --> MNCC: callref 0x80000005: MNCC_RTP_CREATE
+v=0
+o=OsmoMSC 0 0 IN IP4 10.23.23.1
+s=GSM Call
+c=IN IP4 10.23.23.1
+t=0 0
+m=audio 23 RTP/AVP 3
+a=rtpmap:3 GSM/8000
+a=ptime:20
+
+- VALIDATE_SDP OK: cc_to_mncc_tx_last_sdp == t->mo_tx_sdp_mncc_rtp_create == GSM
+- MNCC says that's fine
+ MSC <-- MNCC: callref 0x80000005: MNCC_CALL_PROC_REQ
+
+DMNCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000005 tid-8) rx MNCC_CALL_PROC_REQ
+DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000005 tid-8) stopping pending guard timer
+DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000005 tid-8) starting guard timer with 180 seconds
+DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000005 tid-8) new state INITIATED -> MO_CALL_PROC
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_CALL_PROC
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on GERAN-A
+- DTAP --GERAN-A--> MS: GSM48_MT_CC_CALL_PROC: 8302
+- DTAP matches expected message
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Assignment for this trans already started earlier
+- Total time passed: 251.000205 s
+- The other call leg got established (not shown here), MNCC tells us so, with codecs { GSM }
+ MSC <-- MNCC: callref 0x80000005: MNCC_ALERT_REQ
+v=0
+o=OsmoMSC 0 0 IN IP4 1.2.3.4
+s=GSM Call
+c=IN IP4 1.2.3.4
+t=0 0
+m=audio 56 RTP/AVP 3
+a=rtpmap:3 GSM/8000
+a=ptime:20
+
+DMNCC trans(CC:MO_CALL_PROC IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000005 tid-8) rx MNCC_ALERT_REQ (RTP=1.2.3.4:56{GSM#3})
+DCC trans(CC:MO_CALL_PROC IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000005 tid-8) stopping pending guard timer
+DCC trans(CC:MO_CALL_PROC IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000005 tid-8) starting guard timer with 180 seconds
+DCC trans(CC:MO_CALL_PROC IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000005 tid-8) new state MO_CALL_PROC -> CALL_DELIVERED
+DCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000005 tid-8) codecs: 10.23.23.1:23{GSM#3} (from: assigned=GSM#3 remote=1.2.3.4:56{GSM#3} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-8:RTP_TO_CN:no-CI){UNINITIALIZED}: no change: codecs already set to GSM#3
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-8:RTP_TO_CN:no-CI){UNINITIALIZED}: setting remote addr to 1.2.3.4:56
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-8:RTP_TO_CN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-56){UNINITIALIZED}: Not committing: no MGW endpoint CI set up
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_ALERTING
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on GERAN-A
+- DTAP --GERAN-A--> MS: GSM48_MT_CC_ALERTING: 8301
+- DTAP matches expected message
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+ MSC <-- MNCC: callref 0x80000005: MNCC_SETUP_RSP
+v=0
+o=OsmoMSC 0 0 IN IP4 1.2.3.4
+s=GSM Call
+c=IN IP4 1.2.3.4
+t=0 0
+m=audio 56 RTP/AVP 3
+a=rtpmap:3 GSM/8000
+a=ptime:20
+
+DMNCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000005 tid-8) rx MNCC_SETUP_RSP (RTP=1.2.3.4:56{GSM#3})
+DCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000005 tid-8) stopping pending guard timer
+DCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000005 tid-8) starting guard timer with 180 seconds
+DCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000005 tid-8) starting timer T313 with 30 seconds
+DCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000005 tid-8) new state CALL_DELIVERED -> CONNECT_IND
+DCC trans(CC:CONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000005 tid-8) codecs: 10.23.23.1:23{GSM#3} (from: assigned=GSM#3 remote=1.2.3.4:56{GSM#3} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-8:RTP_TO_CN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-56){UNINITIALIZED}: no change: codecs already set to GSM#3
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-8:RTP_TO_CN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-56){UNINITIALIZED}: remote addr already 1.2.3.4:56, no change
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-8:RTP_TO_CN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-56){UNINITIALIZED}: Not committing: no MGW endpoint CI set up
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_CONNECT
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on GERAN-A
+- DTAP --GERAN-A--> MS: GSM48_MT_CC_CONNECT: 8307
+- DTAP matches expected message
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+- Total time passed: 252.000228 s
+ MSC <--GERAN-A-- MS: GSM48_MT_CC_CONNECT_ACK
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms)
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP
+DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_CONNECT_ACK
+DCC trans(CC:CONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000005 tid-8) rx CONNECT_ACK in state CONNECT_IND
+DCC trans(CC:CONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000005 tid-8) stopping pending timer T313
+DCC trans(CC:CONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000005 tid-8) new state CONNECT_IND -> ACTIVE
+DCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000005 tid-8) stopping pending guard timer
+DMNCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000005 tid-8) tx MNCC_SETUP_COMPL_IND
+ MSC --> MNCC: callref 0x80000005: MNCC_SETUP_COMPL_IND
+
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc)
+- VALIDATE_SDP OK: cc_to_mncc_tx_last_sdp == t->mo_tx_sdp_mncc_setup_compl_ind ==
+
+
+- RTP stream goes ahead, not shown here.
+- Total time passed: 375.000273 s
+
+
+- Call ends
+ MSC <--GERAN-A-- MS: GSM48_MT_CC_DISCONNECT
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms)
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP
+DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_DISCONNECT
+DCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000005 tid-8) rx DISCONNECT in state ACTIVE
+DCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000005 tid-8) new state ACTIVE -> DISCONNECT_IND
+DMNCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000005 tid-8) tx MNCC_DISC_IND
+ MSC --> MNCC: callref 0x80000005: MNCC_DISC_IND
+
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc)
+ MSC <-- MNCC: callref 0x80000005: MNCC_REL_REQ
+v=0
+o=OsmoMSC 0 0 IN IP4 1.2.3.4
+s=GSM Call
+c=IN IP4 1.2.3.4
+t=0 0
+m=audio 56 RTP/AVP 3
+a=rtpmap:3 GSM/8000
+a=ptime:20
+
+DMNCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000005 tid-8) rx MNCC_REL_REQ
+DCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000005 tid-8) starting guard timer with 180 seconds
+DCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000005 tid-8) starting timer T308 with 10 seconds
+DCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000005 tid-8) new state DISCONNECT_IND -> RELEASE_REQ
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_RELEASE
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on GERAN-A
+- DTAP --GERAN-A--> MS: GSM48_MT_CC_RELEASE: 832d
+- DTAP matches expected message
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+ MSC <--GERAN-A-- MS: GSM48_MT_CC_RELEASE_COMPL
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms)
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP
+DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_RELEASE_COMPL
+DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000005 tid-8) rx RELEASE_COMPL in state RELEASE_REQ
+DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000005 tid-8) stopping pending timer T308
+DMNCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000005 tid-8) tx MNCC_REL_CNF
+ MSC --> MNCC: callref 0x80000005: MNCC_REL_CNF
+
+DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x0 tid-8) Freeing transaction
+DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x0 tid-8) new state RELEASE_REQ -> NULL
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x0 tid-8) stopping pending guard timer
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - CC: now used by 2 (attached,active-conn)
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - cc: now used by 1 (rx_from_ms)
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 0 (-)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Received Event MSC_A_EV_UNUSED
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: state_chg to MSC_A_ST_RELEASING
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: Releasing: msc_a use is 0 (-)
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + msc_a_fsm_releasing_onenter: now used by 3 (attached,active-conn,msc_a_fsm_releasing_onenter)
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,active-conn,msc_a_fsm_releasing_onenter,vlr_subscr_cancel_attach_fsm)
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,active-conn,msc_a_fsm_releasing_onenter)
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){ESTABLISHING}: state_chg to RELEASING
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-8:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-8:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Removing from parent call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-8:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Deallocated
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-8:RTP_TO_CN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-56){UNINITIALIZED}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-8:RTP_TO_CN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-56){UNINITIALIZED}: Removing from parent call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-8:RTP_TO_CN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-56){UNINITIALIZED}: Deallocated
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){RELEASING}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){RELEASING}: Removing from parent msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: Received Event MSC_EV_CALL_LEG_TERM
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){RELEASING}: Deallocated
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: + wait-Clear-Complete: now used by 1 (wait-Clear-Complete)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: RAN encode: CLEAR_COMMAND on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - msc_a_fsm_releasing_onenter: now used by 2 (attached,active-conn)
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: RAN decode: CLEAR_COMPLETE
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: - wait-Clear-Complete: now used by 0 (-)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: Received Event MSC_A_EV_UNUSED
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: state_chg to MSC_A_ST_RELEASED
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASED}: Released: msc_a use is 0 (-)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_DONE}: Terminating in cascade, depth 2 (cause = OSMO_FSM_TERM_PARENT, caused by: msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ))
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_DONE}: Removing from parent msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ)
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_DONE}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASED}: Removing from parent msub_fsm
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASED}: max total use count was 3
+DMSC msub_fsm{active}: Received Event MSUB_EV_ROLE_TERMINATED
+DMSC msub(IMSI-901700000010650:MSISDN-46071) MSC-A terminated
+DMSC msub(IMSI-901700000010650:MSISDN-46071) 1 MSC-I still active
+DMSC msub_fsm{active}: state_chg to terminating
+DMSC msub_fsm{terminating}: Terminating in cascade, depth 2 (cause = OSMO_FSM_TERM_REGULAR, caused by: msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ))
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Terminating in cascade, depth 3 (cause = OSMO_FSM_TERM_PARENT, caused by: msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ))
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Removing from parent msub_fsm
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ)
+DMSC msub(IMSI-901700000010650:MSISDN-46071) Free
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - active-conn: now used by 1 (attached)
+DMSC msub_fsm{terminating}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASED}: Deallocated, including all deferred deallocations
+- msub gone
+ llist_count(&msub_list) == 0
+
+
+- ======================== SUCCESS: MO call: FR1 picked by MO from Codec List (BSS Supported), MT hence also picks FR1
+
+
+- ======================== MT call: FR1 picked by MO from Codec List (BSS Supported), MT hence also picks FR1
+
+
+- MNCC asks us to setup a call, causing Paging
+ MSC <-- MNCC: callref 0x423: MNCC_SETUP_REQ
+v=0
+o=OsmoMSC 0 0 IN IP4 1.2.3.4
+s=GSM Call
+c=IN IP4 1.2.3.4
+t=0 0
+m=audio 56 RTP/AVP 3
+a=rtpmap:3 GSM/8000
+a=ptime:20
+
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + mncc_tx_to_gsm_cc: now used by 2 (attached,mncc_tx_to_gsm_cc)
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + CC: now used by 3 (attached,mncc_tx_to_gsm_cc,CC)
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071 callref-0x423 tid-255) New transaction
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071 callref-0x423 tid-255) codecs: :0{(no-codecs)} (from: remote=1.2.3.4:56{GSM#3} RAN={(no-codecs)})
+DMNCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071 callref-0x423 tid-255) rx MNCC_SETUP_REQ (RTP=1.2.3.4:56{GSM#3})
+DPAG Paging: IMSI-901700000010650:MSISDN-46071 for MNCC: establish call: Starting paging
+ paging request (CALL_CONVERSATIONAL) to IMSI-901700000010650:MSISDN-46071 on GERAN-A
+ strcmp(paging_expecting_imsi, vsub->imsi) == 0
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + Paging: now used by 4 (attached,mncc_tx_to_gsm_cc,CC,Paging)
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - mncc_tx_to_gsm_cc: now used by 3 (attached,CC,Paging)
+ paging_sent == 1
+- MS replies with Paging Response, with Codec List (BSS Supported) = FR1 FR2 FR3 HR1 HR3
+- VLR accepts, MSC sends CC Setup with Bearer Capability = GSM
+ MSC <--GERAN-A-- MS: GSM48_MT_RR_PAG_RESP
+ new conn
+DMSC msub_fsm{active}: Allocated
+DMSC msc_a{MSC_A_ST_VALIDATE_L3}: Allocated
+DMSC msc_a{MSC_A_ST_VALIDATE_L3}: is child of msub_fsm
+DMSC msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_VALIDATE_L3
+DMSC dummy_msc_i{0}: Allocated
+DMSC dummy_msc_i{0}: is child of msub_fsm
+DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms)
+DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3
+DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Complete Layer 3: Codec List (BSS Supported): GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111
+DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: RR GSM48_MT_RR_PAG_RESP
+DRR msc_a(IMSI-901700000010650:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: Rx PAGING RESPONSE IMSI-901700000010650
+DREF msc_a(IMSI-901700000010650:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: + paging-response: now used by 2 (rx_from_ms,paging-response)
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: Allocated
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: is child of msc_a(IMSI-901700000010650:GERAN-A:PAGING_RESP)
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: rev=R99 net=GERAN (no Auth)
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + proc_arq_vlr_fn_init: now used by 4 (attached,CC,Paging,proc_arq_vlr_fn_init)
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + active-conn: now used by 5 (attached,CC,Paging,proc_arq_vlr_fn_init,active-conn)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi()
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_node2()
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_ciph()
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_vlr()
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_post_pres()
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_post_trace()
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_post_imei()
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: proc_arq_fsm_done(PASSED)
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_DONE
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_DONE}: Process Access Request result: PASSED
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: Received Event MSC_A_EV_AUTHENTICATED
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: state_chg to MSC_A_ST_AUTHENTICATED
+DPAG Paging: IMSI-901700000010650:MSISDN-46071 for MNCC: establish call: Paging Response action (success)
+DPAG Paging: IMSI-901700000010650:MSISDN-46071 for MNCC: establish call: Removing Paging Request
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071 callref-0x423 tid-255) Paging succeeded
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: + cc: now used by 3 (rx_from_ms,paging-response,cc)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: Received Event MSC_A_EV_TRANSACTION_ACCEPTED
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: state_chg to MSC_A_ST_COMMUNICATING
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) starting timer T303 with 30 seconds
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) codecs: :0{GSM#3} (from: remote=1.2.3.4:56{GSM#3} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) new state NULL -> CALL_PRESENT
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_SETUP
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on GERAN-A
+- DTAP --GERAN-A--> MS: GSM48_MT_CC_SETUP: 030504022080
+- DTAP matches expected message
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - Paging: now used by 4 (attached,CC,proc_arq_vlr_fn_init,active-conn)
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - paging-response: now used by 2 (rx_from_ms,cc)
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - proc_arq_vlr_fn_init: now used by 3 (attached,CC,active-conn)
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc)
+- MS confirms call, we create a RAN-side RTP and forward MNCC_CALL_CONF_IND
+ MSC <--GERAN-A-- MS: GSM48_MT_CC_CALL_CONF
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms)
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP
+DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_CALL_CONF
+DCC trans(CC:CALL_PRESENT IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx CALL_CONF in state CALL_PRESENT
+DCC trans(CC:CALL_PRESENT IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) stopping pending timer T303
+DCC trans(CC:CALL_PRESENT IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) starting timer T310 with 30 seconds
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Starting call assignment
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){ESTABLISHING}: Allocated
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){ESTABLISHING}: is child of msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP)
+DCC trans(CC:CALL_PRESENT IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) codecs: :0{GSM#3} (from: remote=1.2.3.4:56{GSM#3} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+ MGW <--CRCX to RTP_TO_CN-- MSC: call_id=0x9 codecs=GSM#3
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){UNINITIALIZED}: Allocated
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){UNINITIALIZED}: is child of call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-9:RTP_TO_CN:no-CI){UNINITIALIZED}: setting codecs to GSM#3
+ MGW <--CRCX to RTP_TO_RAN-- MSC: call_id=0x9 codecs=GSM#3
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){UNINITIALIZED}: Allocated
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){UNINITIALIZED}: is child of call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-9:RTP_TO_RAN:no-CI){UNINITIALIZED}: setting codecs to GSM#3
+DCC trans(CC:CALL_PRESENT IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) new state CALL_PRESENT -> MO_TERM_CALL_CONF
+DMNCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) tx MNCC_CALL_CONF_IND
+ MSC --> MNCC: callref 0x423: MNCC_CALL_CONF_IND
+
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc)
+- VALIDATE_SDP OK: cc_to_mncc_tx_last_sdp == t->mt_tx_sdp_mncc_call_conf_ind ==
+- MGW acknowledges the CRCX to RAN, triggering Assignment with FR1
+ MGW --CRCX OK to RTP_TO_RAN--> MSC
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){ESTABLISHING}: Received Event CALL_LEG_EV_RTP_STREAM_ADDR_AVAILABLE
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Received Event MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: MGW endpoint's RTP address available for the CI RTP_TO_RAN: 10.23.23.1:23 (osmux=no:-2)
+DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) codecs: :0{GSM#3} (from: remote=1.2.3.4:56{GSM#3} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) Sending Assignment Command
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN encode: ASSIGNMENT_COMMAND on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+- VALIDATE_PERM_SPEECH OK: &bssap_assignment_command_last_channel_type == t->mt_tx_assignment_perm_speech == FR1
+- Assignment completes, triggering CRCX to CN
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN decode: ASSIGNMENT_COMPLETE
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-9:RTP_TO_RAN:no-CI){UNINITIALIZED}: no change: codecs already set to GSM#3
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-9:RTP_TO_RAN:no-CI){UNINITIALIZED}: setting remote addr to 1.2.3.4:1234
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-9:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Not committing: no MGW endpoint CI set up
+DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) codecs: :0{GSM#3} (from: assigned=GSM#3 remote=1.2.3.4:56{GSM#3} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) Assignment Complete: RAN: GSM#3, CN: GSM#3
+DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) Assignment complete, but still waiting for the CRCX OK on the CN side RTP
+- MNCC sends MNCC_RTP_CREATE, which first waits for the CN side RTP
+ MSC <-- MNCC: callref 0x423: MNCC_RTP_CREATE
+
+DMNCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx MNCC_RTP_CREATE
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Assignment for this trans already started earlier
+- When the CN side RTP address is known, ack MNCC_RTP_CREATE
+ MGW --CRCX OK to RTP_TO_CN--> MSC
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){ESTABLISHING}: Received Event CALL_LEG_EV_RTP_STREAM_ADDR_AVAILABLE
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Received Event MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: MGW endpoint's RTP address available for the CI RTP_TO_CN: 10.23.23.1:23 (osmux=no:-2)
+DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) codecs: 10.23.23.1:23{GSM#3} (from: assigned=GSM#3 remote=1.2.3.4:56{GSM#3} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+DMNCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) tx MNCC_RTP_CREATE (RTP=10.23.23.1:23{GSM#3})
+ MSC --> MNCC: callref 0x423: MNCC_RTP_CREATE
+v=0
+o=OsmoMSC 0 0 IN IP4 10.23.23.1
+s=GSM Call
+c=IN IP4 10.23.23.1
+t=0 0
+m=audio 23 RTP/AVP 3
+a=rtpmap:3 GSM/8000
+a=ptime:20
+
+- VALIDATE_SDP OK: cc_to_mncc_tx_last_sdp == t->mt_tx_sdp_mncc_rtp_create == GSM
+- Total time passed: 376.000296 s
+ MSC <--GERAN-A-- MS: GSM48_MT_CC_ALERTING
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms)
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP
+DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_ALERTING
+DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx ALERTING in state MO_TERM_CALL_CONF
+DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) stopping pending timer T310
+DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) starting timer T301 with 180 seconds
+DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) new state MO_TERM_CALL_CONF -> CALL_RECEIVED
+DCC trans(CC:CALL_RECEIVED IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) codecs: 10.23.23.1:23{GSM#3} (from: assigned=GSM#3 remote=1.2.3.4:56{GSM#3} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+DMNCC trans(CC:CALL_RECEIVED IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) tx MNCC_ALERT_IND (RTP=10.23.23.1:23{GSM#3})
+ MSC --> MNCC: callref 0x423: MNCC_ALERT_IND
+v=0
+o=OsmoMSC 0 0 IN IP4 10.23.23.1
+s=GSM Call
+c=IN IP4 10.23.23.1
+t=0 0
+m=audio 23 RTP/AVP 3
+a=rtpmap:3 GSM/8000
+a=ptime:20
+
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc)
+- VALIDATE_SDP OK: cc_to_mncc_tx_last_sdp == t->mt_tx_sdp_mncc_alert_ind == GSM
+- Total time passed: 377.000319 s
+ MSC <--GERAN-A-- MS: GSM48_MT_CC_CONNECT
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms)
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP
+DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_CONNECT
+DCC trans(CC:CALL_RECEIVED IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx CONNECT in state CALL_RECEIVED
+DCC trans(CC:CALL_RECEIVED IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) stopping pending timer T301
+DCC trans(CC:CALL_RECEIVED IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) new state CALL_RECEIVED -> CONNECT_REQUEST
+DCC trans(CC:CONNECT_REQUEST IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) codecs: 10.23.23.1:23{GSM#3} (from: assigned=GSM#3 remote=1.2.3.4:56{GSM#3} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+DMNCC trans(CC:CONNECT_REQUEST IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) tx MNCC_SETUP_CNF (RTP=10.23.23.1:23{GSM#3})
+ MSC --> MNCC: callref 0x423: MNCC_SETUP_CNF
+v=0
+o=OsmoMSC 0 0 IN IP4 10.23.23.1
+s=GSM Call
+c=IN IP4 10.23.23.1
+t=0 0
+m=audio 23 RTP/AVP 3
+a=rtpmap:3 GSM/8000
+a=ptime:20
+
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc)
+- VALIDATE_SDP OK: cc_to_mncc_tx_last_sdp == t->mt_tx_sdp_mncc_setup_cnf == GSM
+ MSC <-- MNCC: callref 0x423: MNCC_SETUP_COMPL_REQ
+
+DMNCC trans(CC:CONNECT_REQUEST IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx MNCC_SETUP_COMPL_REQ
+DCC trans(CC:CONNECT_REQUEST IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) starting guard timer with 180 seconds
+DCC trans(CC:CONNECT_REQUEST IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) new state CONNECT_REQUEST -> ACTIVE
+DCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) stopping pending guard timer
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_CONNECT_ACK
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on GERAN-A
+- DTAP --GERAN-A--> MS: GSM48_MT_CC_CONNECT_ACK: 030f
+- DTAP matches expected message
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+
+
+- RTP stream goes ahead, not shown here.
+- Total time passed: 500.000364 s
+
+
+- Call ends
+ MSC <--GERAN-A-- MS: GSM48_MT_CC_DISCONNECT
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms)
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP
+DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_DISCONNECT
+DCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx DISCONNECT in state ACTIVE
+DCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) new state ACTIVE -> DISCONNECT_IND
+DMNCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) tx MNCC_DISC_IND
+ MSC --> MNCC: callref 0x423: MNCC_DISC_IND
+
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc)
+ MSC <-- MNCC: callref 0x423: MNCC_REL_REQ
+
+DMNCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx MNCC_REL_REQ
+DCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) starting guard timer with 180 seconds
+DCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) starting timer T308 with 10 seconds
+DCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) new state DISCONNECT_IND -> RELEASE_REQ
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_RELEASE
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on GERAN-A
+- DTAP --GERAN-A--> MS: GSM48_MT_CC_RELEASE: 032d
+- DTAP matches expected message
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+ MSC <--GERAN-A-- MS: GSM48_MT_CC_RELEASE_COMPL
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms)
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP
+DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_RELEASE_COMPL
+DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx RELEASE_COMPL in state RELEASE_REQ
+DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) stopping pending timer T308
+DMNCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) tx MNCC_REL_CNF
+ MSC --> MNCC: callref 0x423: MNCC_REL_CNF
+
+DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x0 tid-0) Freeing transaction
+DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x0 tid-0) new state RELEASE_REQ -> NULL
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x0 tid-0) stopping pending guard timer
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - CC: now used by 2 (attached,active-conn)
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - cc: now used by 1 (rx_from_ms)
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 0 (-)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Received Event MSC_A_EV_UNUSED
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: state_chg to MSC_A_ST_RELEASING
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: Releasing: msc_a use is 0 (-)
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + msc_a_fsm_releasing_onenter: now used by 3 (attached,active-conn,msc_a_fsm_releasing_onenter)
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,active-conn,msc_a_fsm_releasing_onenter,vlr_subscr_cancel_attach_fsm)
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,active-conn,msc_a_fsm_releasing_onenter)
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){ESTABLISHING}: state_chg to RELEASING
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-9:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-9:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Removing from parent call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-9:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Deallocated
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-9:RTP_TO_CN:no-CI){UNINITIALIZED}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-9:RTP_TO_CN:no-CI){UNINITIALIZED}: Removing from parent call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-9:RTP_TO_CN:no-CI){UNINITIALIZED}: Deallocated
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){RELEASING}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){RELEASING}: Removing from parent msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: Received Event MSC_EV_CALL_LEG_TERM
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){RELEASING}: Deallocated
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: + wait-Clear-Complete: now used by 1 (wait-Clear-Complete)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: RAN encode: CLEAR_COMMAND on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - msc_a_fsm_releasing_onenter: now used by 2 (attached,active-conn)
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: RAN decode: CLEAR_COMPLETE
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: - wait-Clear-Complete: now used by 0 (-)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: Received Event MSC_A_EV_UNUSED
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: state_chg to MSC_A_ST_RELEASED
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASED}: Released: msc_a use is 0 (-)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_DONE}: Terminating in cascade, depth 2 (cause = OSMO_FSM_TERM_PARENT, caused by: msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP))
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_DONE}: Removing from parent msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP)
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_DONE}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASED}: Removing from parent msub_fsm
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASED}: max total use count was 3
+DMSC msub_fsm{active}: Received Event MSUB_EV_ROLE_TERMINATED
+DMSC msub(IMSI-901700000010650:MSISDN-46071) MSC-A terminated
+DMSC msub(IMSI-901700000010650:MSISDN-46071) 1 MSC-I still active
+DMSC msub_fsm{active}: state_chg to terminating
+DMSC msub_fsm{terminating}: Terminating in cascade, depth 2 (cause = OSMO_FSM_TERM_REGULAR, caused by: msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP))
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Terminating in cascade, depth 3 (cause = OSMO_FSM_TERM_PARENT, caused by: msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP))
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Removing from parent msub_fsm
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP)
+DMSC msub(IMSI-901700000010650:MSISDN-46071) Free
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - active-conn: now used by 1 (attached)
+DMSC msub_fsm{terminating}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASED}: Deallocated, including all deferred deallocations
+- msub gone
+ llist_count(&msub_list) == 0
+
+
+- ======================== SUCCESS: MT call: FR1 picked by MO from Codec List (BSS Supported), MT hence also picks FR1
+
+
+- ======================== MO call: FR1 picked by MO from Bearer Cap, MT hence also picks FR1
+- CM Service Request with Codec List (BSS Supported) = FR1 FR2 FR3 HR1 HR3
+ MSC <--GERAN-A-- MS: GSM48_MT_MM_CM_SERV_REQ
+ new conn
+DMSC msub_fsm{active}: Allocated
+DMSC msc_a{MSC_A_ST_VALIDATE_L3}: Allocated
+DMSC msc_a{MSC_A_ST_VALIDATE_L3}: is child of msub_fsm
+DMSC msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_VALIDATE_L3
+DMSC dummy_msc_i{0}: Allocated
+DMSC dummy_msc_i{0}: is child of msub_fsm
+DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms)
+DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3
+DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Complete Layer 3: Codec List (BSS Supported): GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111
+DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: MM GSM48_MT_MM_CM_SERV_REQ
+DMM msc_a(IMSI-901700000010650:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_VALIDATE_L3}: Rx CM SERVICE REQUEST cm_service_type=MO-Call
+DREF msc_a(IMSI-901700000010650:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_VALIDATE_L3}: + cm_service_cc: now used by 2 (rx_from_ms,cm_service_cc)
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: Allocated
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: is child of msc_a(IMSI-901700000010650:GERAN-A:CM_SERVICE_REQ)
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: rev=R99 net=GERAN (no Auth)
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + proc_arq_vlr_fn_init: now used by 2 (attached,proc_arq_vlr_fn_init)
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + active-conn: now used by 3 (attached,proc_arq_vlr_fn_init,active-conn)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi()
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_node2()
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_ciph()
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_vlr()
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_post_pres()
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_post_trace()
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_post_imei()
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: proc_arq_fsm_done(PASSED)
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_DONE
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_DONE}: Process Access Request result: PASSED
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: Sending DTAP: MM GSM48_MT_MM_CM_SERV_ACC
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN encode: DTAP on GERAN-A
+- DTAP --GERAN-A--> MS: GSM48_MT_MM_CM_SERV_ACC: 0521
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: Received Event MSC_A_EV_AUTHENTICATED
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: state_chg to MSC_A_ST_AUTHENTICATED
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - proc_arq_vlr_fn_init: now used by 2 (attached,active-conn)
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: - rx_from_ms: now used by 1 (cm_service_cc)
+ cm_service_result_sent == 1
+msc_a_is_accepted() == true
+- MS sends CC SETUP with Bearer Capability = GSM
+ MSC <--GERAN-A-- MS: GSM48_MT_CC_SETUP
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: + rx_from_ms: now used by 2 (cm_service_cc,rx_from_ms)
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: RAN decode: DTAP
+DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: Dispatching 04.08 message: CC GSM48_MT_CC_SETUP
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + CC: now used by 3 (attached,active-conn,CC)
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071 callref-0x80000006 tid-8) New transaction
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: Received Event MSC_A_EV_TRANSACTION_ACCEPTED
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: state_chg to MSC_A_ST_COMMUNICATING
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: + cc: now used by 3 (cm_service_cc,rx_from_ms,cc)
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - cm_service_cc: now used by 2 (rx_from_ms,cc)
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000006 tid-8) rx SETUP in state NULL
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000006 tid-8) starting guard timer with 180 seconds
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000006 tid-8) codecs: :0{GSM#3} (from: MS={GSM#3} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000006 tid-8) SETUP to 123
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000006 tid-8) new state NULL -> INITIATED
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Starting call assignment
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){ESTABLISHING}: Allocated
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){ESTABLISHING}: is child of msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ)
+DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000006 tid-8) codecs: :0{GSM#3} (from: MS={GSM#3} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+ MGW <--CRCX to RTP_TO_CN-- MSC: call_id=0xa codecs=GSM#3
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){UNINITIALIZED}: Allocated
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){UNINITIALIZED}: is child of call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-10:RTP_TO_CN:no-CI){UNINITIALIZED}: setting codecs to GSM#3
+ MGW <--CRCX to RTP_TO_RAN-- MSC: call_id=0xa codecs=GSM#3
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){UNINITIALIZED}: Allocated
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){UNINITIALIZED}: is child of call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-10:RTP_TO_RAN:no-CI){UNINITIALIZED}: setting codecs to GSM#3
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc)
+- As soon as the MGW port towards CN is created, MNCC_SETUP_IND is triggered
+ MGW --CRCX OK to RTP_TO_CN--> MSC
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){ESTABLISHING}: Received Event CALL_LEG_EV_RTP_STREAM_ADDR_AVAILABLE
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Received Event MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: MGW endpoint's RTP address available for the CI RTP_TO_CN: 10.23.23.1:23 (osmux=no:-2)
+DMNCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000006 tid-8) tx MNCC_SETUP_IND (RTP=10.23.23.1:23{GSM#3})
+ MSC --> MNCC: callref 0x80000006: MNCC_SETUP_IND
+v=0
+o=OsmoMSC 0 0 IN IP4 10.23.23.1
+s=GSM Call
+c=IN IP4 10.23.23.1
+t=0 0
+m=audio 23 RTP/AVP 3
+a=rtpmap:3 GSM/8000
+a=ptime:20
+
+- VALIDATE_SDP OK: cc_to_mncc_tx_last_sdp == t->mo_tx_sdp_mncc_setup_ind == GSM
+- MNCC replies with MNCC_RTP_CREATE
+ MSC <-- MNCC: callref 0x80000006: MNCC_RTP_CREATE
+
+DMNCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000006 tid-8) rx MNCC_RTP_CREATE
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Assignment for this trans already started earlier
+- MGW acknowledges the CRCX, triggering Assignment with FR1
+ MGW --CRCX OK to RTP_TO_RAN--> MSC
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){ESTABLISHING}: Received Event CALL_LEG_EV_RTP_STREAM_ADDR_AVAILABLE
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Received Event MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: MGW endpoint's RTP address available for the CI RTP_TO_RAN: 10.23.23.1:23 (osmux=no:-2)
+DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000006 tid-8) codecs: 10.23.23.1:23{GSM#3} (from: MS={GSM#3} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000006 tid-8) Sending Assignment Command
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN encode: ASSIGNMENT_COMMAND on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+- VALIDATE_PERM_SPEECH OK: &bssap_assignment_command_last_channel_type == t->mo_tx_assignment_perm_speech == FR1
+- Assignment succeeds, triggering MNCC_RTP_CREATE ack to MNCC
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN decode: ASSIGNMENT_COMPLETE
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-10:RTP_TO_RAN:no-CI){UNINITIALIZED}: no change: codecs already set to GSM#3
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-10:RTP_TO_RAN:no-CI){UNINITIALIZED}: setting remote addr to 1.2.3.4:1234
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-10:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Not committing: no MGW endpoint CI set up
+DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000006 tid-8) codecs: 10.23.23.1:23{GSM#3} (from: assigned=GSM#3 MS={GSM#3} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000006 tid-8) Assignment Complete: RAN: GSM#3, CN: GSM#3
+DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000006 tid-8) codecs: 10.23.23.1:23{GSM#3} (from: assigned=GSM#3 MS={GSM#3} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+DMNCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000006 tid-8) tx MNCC_RTP_CREATE (RTP=10.23.23.1:23{GSM#3})
+ MSC --> MNCC: callref 0x80000006: MNCC_RTP_CREATE
+v=0
+o=OsmoMSC 0 0 IN IP4 10.23.23.1
+s=GSM Call
+c=IN IP4 10.23.23.1
+t=0 0
+m=audio 23 RTP/AVP 3
+a=rtpmap:3 GSM/8000
+a=ptime:20
+
+- VALIDATE_SDP OK: cc_to_mncc_tx_last_sdp == t->mo_tx_sdp_mncc_rtp_create == GSM
+- MNCC says that's fine
+ MSC <-- MNCC: callref 0x80000006: MNCC_CALL_PROC_REQ
+
+DMNCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000006 tid-8) rx MNCC_CALL_PROC_REQ
+DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000006 tid-8) stopping pending guard timer
+DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000006 tid-8) starting guard timer with 180 seconds
+DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000006 tid-8) new state INITIATED -> MO_CALL_PROC
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_CALL_PROC
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on GERAN-A
+- DTAP --GERAN-A--> MS: GSM48_MT_CC_CALL_PROC: 8302
+- DTAP matches expected message
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Assignment for this trans already started earlier
+- Total time passed: 501.000387 s
+- The other call leg got established (not shown here), MNCC tells us so, with codecs { GSM }
+ MSC <-- MNCC: callref 0x80000006: MNCC_ALERT_REQ
+v=0
+o=OsmoMSC 0 0 IN IP4 1.2.3.4
+s=GSM Call
+c=IN IP4 1.2.3.4
+t=0 0
+m=audio 56 RTP/AVP 3
+a=rtpmap:3 GSM/8000
+a=ptime:20
+
+DMNCC trans(CC:MO_CALL_PROC IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000006 tid-8) rx MNCC_ALERT_REQ (RTP=1.2.3.4:56{GSM#3})
+DCC trans(CC:MO_CALL_PROC IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000006 tid-8) stopping pending guard timer
+DCC trans(CC:MO_CALL_PROC IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000006 tid-8) starting guard timer with 180 seconds
+DCC trans(CC:MO_CALL_PROC IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000006 tid-8) new state MO_CALL_PROC -> CALL_DELIVERED
+DCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000006 tid-8) codecs: 10.23.23.1:23{GSM#3} (from: assigned=GSM#3 remote=1.2.3.4:56{GSM#3} MS={GSM#3} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-10:RTP_TO_CN:no-CI){UNINITIALIZED}: no change: codecs already set to GSM#3
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-10:RTP_TO_CN:no-CI){UNINITIALIZED}: setting remote addr to 1.2.3.4:56
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-10:RTP_TO_CN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-56){UNINITIALIZED}: Not committing: no MGW endpoint CI set up
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_ALERTING
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on GERAN-A
+- DTAP --GERAN-A--> MS: GSM48_MT_CC_ALERTING: 8301
+- DTAP matches expected message
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+ MSC <-- MNCC: callref 0x80000006: MNCC_SETUP_RSP
+v=0
+o=OsmoMSC 0 0 IN IP4 1.2.3.4
+s=GSM Call
+c=IN IP4 1.2.3.4
+t=0 0
+m=audio 56 RTP/AVP 3
+a=rtpmap:3 GSM/8000
+a=ptime:20
+
+DMNCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000006 tid-8) rx MNCC_SETUP_RSP (RTP=1.2.3.4:56{GSM#3})
+DCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000006 tid-8) stopping pending guard timer
+DCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000006 tid-8) starting guard timer with 180 seconds
+DCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000006 tid-8) starting timer T313 with 30 seconds
+DCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000006 tid-8) new state CALL_DELIVERED -> CONNECT_IND
+DCC trans(CC:CONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000006 tid-8) codecs: 10.23.23.1:23{GSM#3} (from: assigned=GSM#3 remote=1.2.3.4:56{GSM#3} MS={GSM#3} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-10:RTP_TO_CN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-56){UNINITIALIZED}: no change: codecs already set to GSM#3
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-10:RTP_TO_CN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-56){UNINITIALIZED}: remote addr already 1.2.3.4:56, no change
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-10:RTP_TO_CN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-56){UNINITIALIZED}: Not committing: no MGW endpoint CI set up
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_CONNECT
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on GERAN-A
+- DTAP --GERAN-A--> MS: GSM48_MT_CC_CONNECT: 8307
+- DTAP matches expected message
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+- Total time passed: 502.000410 s
+ MSC <--GERAN-A-- MS: GSM48_MT_CC_CONNECT_ACK
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms)
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP
+DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_CONNECT_ACK
+DCC trans(CC:CONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000006 tid-8) rx CONNECT_ACK in state CONNECT_IND
+DCC trans(CC:CONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000006 tid-8) stopping pending timer T313
+DCC trans(CC:CONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000006 tid-8) new state CONNECT_IND -> ACTIVE
+DCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000006 tid-8) stopping pending guard timer
+DMNCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000006 tid-8) tx MNCC_SETUP_COMPL_IND
+ MSC --> MNCC: callref 0x80000006: MNCC_SETUP_COMPL_IND
+
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc)
+- VALIDATE_SDP OK: cc_to_mncc_tx_last_sdp == t->mo_tx_sdp_mncc_setup_compl_ind ==
+
+
+- RTP stream goes ahead, not shown here.
+- Total time passed: 625.000455 s
+
+
+- Call ends
+ MSC <--GERAN-A-- MS: GSM48_MT_CC_DISCONNECT
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms)
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP
+DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_DISCONNECT
+DCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000006 tid-8) rx DISCONNECT in state ACTIVE
+DCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000006 tid-8) new state ACTIVE -> DISCONNECT_IND
+DMNCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000006 tid-8) tx MNCC_DISC_IND
+ MSC --> MNCC: callref 0x80000006: MNCC_DISC_IND
+
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc)
+ MSC <-- MNCC: callref 0x80000006: MNCC_REL_REQ
+v=0
+o=OsmoMSC 0 0 IN IP4 1.2.3.4
+s=GSM Call
+c=IN IP4 1.2.3.4
+t=0 0
+m=audio 56 RTP/AVP 3
+a=rtpmap:3 GSM/8000
+a=ptime:20
+
+DMNCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000006 tid-8) rx MNCC_REL_REQ
+DCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000006 tid-8) starting guard timer with 180 seconds
+DCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000006 tid-8) starting timer T308 with 10 seconds
+DCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000006 tid-8) new state DISCONNECT_IND -> RELEASE_REQ
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_RELEASE
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on GERAN-A
+- DTAP --GERAN-A--> MS: GSM48_MT_CC_RELEASE: 832d
+- DTAP matches expected message
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+ MSC <--GERAN-A-- MS: GSM48_MT_CC_RELEASE_COMPL
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms)
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP
+DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_RELEASE_COMPL
+DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000006 tid-8) rx RELEASE_COMPL in state RELEASE_REQ
+DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000006 tid-8) stopping pending timer T308
+DMNCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000006 tid-8) tx MNCC_REL_CNF
+ MSC --> MNCC: callref 0x80000006: MNCC_REL_CNF
+
+DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x0 tid-8) Freeing transaction
+DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x0 tid-8) new state RELEASE_REQ -> NULL
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x0 tid-8) stopping pending guard timer
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - CC: now used by 2 (attached,active-conn)
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - cc: now used by 1 (rx_from_ms)
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 0 (-)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Received Event MSC_A_EV_UNUSED
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: state_chg to MSC_A_ST_RELEASING
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: Releasing: msc_a use is 0 (-)
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + msc_a_fsm_releasing_onenter: now used by 3 (attached,active-conn,msc_a_fsm_releasing_onenter)
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,active-conn,msc_a_fsm_releasing_onenter,vlr_subscr_cancel_attach_fsm)
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,active-conn,msc_a_fsm_releasing_onenter)
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){ESTABLISHING}: state_chg to RELEASING
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-10:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-10:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Removing from parent call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-10:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Deallocated
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-10:RTP_TO_CN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-56){UNINITIALIZED}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-10:RTP_TO_CN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-56){UNINITIALIZED}: Removing from parent call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-10:RTP_TO_CN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-56){UNINITIALIZED}: Deallocated
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){RELEASING}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){RELEASING}: Removing from parent msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: Received Event MSC_EV_CALL_LEG_TERM
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){RELEASING}: Deallocated
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: + wait-Clear-Complete: now used by 1 (wait-Clear-Complete)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: RAN encode: CLEAR_COMMAND on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - msc_a_fsm_releasing_onenter: now used by 2 (attached,active-conn)
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: RAN decode: CLEAR_COMPLETE
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: - wait-Clear-Complete: now used by 0 (-)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: Received Event MSC_A_EV_UNUSED
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: state_chg to MSC_A_ST_RELEASED
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASED}: Released: msc_a use is 0 (-)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_DONE}: Terminating in cascade, depth 2 (cause = OSMO_FSM_TERM_PARENT, caused by: msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ))
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_DONE}: Removing from parent msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ)
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_DONE}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASED}: Removing from parent msub_fsm
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASED}: max total use count was 3
+DMSC msub_fsm{active}: Received Event MSUB_EV_ROLE_TERMINATED
+DMSC msub(IMSI-901700000010650:MSISDN-46071) MSC-A terminated
+DMSC msub(IMSI-901700000010650:MSISDN-46071) 1 MSC-I still active
+DMSC msub_fsm{active}: state_chg to terminating
+DMSC msub_fsm{terminating}: Terminating in cascade, depth 2 (cause = OSMO_FSM_TERM_REGULAR, caused by: msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ))
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Terminating in cascade, depth 3 (cause = OSMO_FSM_TERM_PARENT, caused by: msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ))
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Removing from parent msub_fsm
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ)
+DMSC msub(IMSI-901700000010650:MSISDN-46071) Free
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - active-conn: now used by 1 (attached)
+DMSC msub_fsm{terminating}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASED}: Deallocated, including all deferred deallocations
+- msub gone
+ llist_count(&msub_list) == 0
+
+
+- ======================== SUCCESS: MO call: FR1 picked by MO from Bearer Cap, MT hence also picks FR1
+
+
+- ======================== MT call: FR1 picked by MO from Bearer Cap, MT hence also picks FR1
+
+
+- MNCC asks us to setup a call, causing Paging
+ MSC <-- MNCC: callref 0x423: MNCC_SETUP_REQ
+v=0
+o=OsmoMSC 0 0 IN IP4 1.2.3.4
+s=GSM Call
+c=IN IP4 1.2.3.4
+t=0 0
+m=audio 56 RTP/AVP 3
+a=rtpmap:3 GSM/8000
+a=ptime:20
+
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + mncc_tx_to_gsm_cc: now used by 2 (attached,mncc_tx_to_gsm_cc)
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + CC: now used by 3 (attached,mncc_tx_to_gsm_cc,CC)
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071 callref-0x423 tid-255) New transaction
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071 callref-0x423 tid-255) codecs: :0{(no-codecs)} (from: remote=1.2.3.4:56{GSM#3} RAN={(no-codecs)})
+DMNCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071 callref-0x423 tid-255) rx MNCC_SETUP_REQ (RTP=1.2.3.4:56{GSM#3})
+DPAG Paging: IMSI-901700000010650:MSISDN-46071 for MNCC: establish call: Starting paging
+ paging request (CALL_CONVERSATIONAL) to IMSI-901700000010650:MSISDN-46071 on GERAN-A
+ strcmp(paging_expecting_imsi, vsub->imsi) == 0
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + Paging: now used by 4 (attached,mncc_tx_to_gsm_cc,CC,Paging)
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - mncc_tx_to_gsm_cc: now used by 3 (attached,CC,Paging)
+ paging_sent == 1
+- MS replies with Paging Response, with Codec List (BSS Supported) = FR1 FR2 FR3 HR1 HR3
+- VLR accepts, MSC sends CC Setup with Bearer Capability = GSM
+ MSC <--GERAN-A-- MS: GSM48_MT_RR_PAG_RESP
+ new conn
+DMSC msub_fsm{active}: Allocated
+DMSC msc_a{MSC_A_ST_VALIDATE_L3}: Allocated
+DMSC msc_a{MSC_A_ST_VALIDATE_L3}: is child of msub_fsm
+DMSC msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_VALIDATE_L3
+DMSC dummy_msc_i{0}: Allocated
+DMSC dummy_msc_i{0}: is child of msub_fsm
+DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms)
+DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3
+DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Complete Layer 3: Codec List (BSS Supported): GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111
+DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: RR GSM48_MT_RR_PAG_RESP
+DRR msc_a(IMSI-901700000010650:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: Rx PAGING RESPONSE IMSI-901700000010650
+DREF msc_a(IMSI-901700000010650:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: + paging-response: now used by 2 (rx_from_ms,paging-response)
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: Allocated
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: is child of msc_a(IMSI-901700000010650:GERAN-A:PAGING_RESP)
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: rev=R99 net=GERAN (no Auth)
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + proc_arq_vlr_fn_init: now used by 4 (attached,CC,Paging,proc_arq_vlr_fn_init)
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + active-conn: now used by 5 (attached,CC,Paging,proc_arq_vlr_fn_init,active-conn)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi()
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_node2()
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_ciph()
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_vlr()
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_post_pres()
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_post_trace()
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_post_imei()
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: proc_arq_fsm_done(PASSED)
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_DONE
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_DONE}: Process Access Request result: PASSED
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: Received Event MSC_A_EV_AUTHENTICATED
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: state_chg to MSC_A_ST_AUTHENTICATED
+DPAG Paging: IMSI-901700000010650:MSISDN-46071 for MNCC: establish call: Paging Response action (success)
+DPAG Paging: IMSI-901700000010650:MSISDN-46071 for MNCC: establish call: Removing Paging Request
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071 callref-0x423 tid-255) Paging succeeded
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: + cc: now used by 3 (rx_from_ms,paging-response,cc)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: Received Event MSC_A_EV_TRANSACTION_ACCEPTED
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: state_chg to MSC_A_ST_COMMUNICATING
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) starting timer T303 with 30 seconds
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) codecs: :0{GSM#3} (from: remote=1.2.3.4:56{GSM#3} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) new state NULL -> CALL_PRESENT
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_SETUP
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on GERAN-A
+- DTAP --GERAN-A--> MS: GSM48_MT_CC_SETUP: 030504022080
+- DTAP matches expected message
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - Paging: now used by 4 (attached,CC,proc_arq_vlr_fn_init,active-conn)
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - paging-response: now used by 2 (rx_from_ms,cc)
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - proc_arq_vlr_fn_init: now used by 3 (attached,CC,active-conn)
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc)
+- MS confirms call, we create a RAN-side RTP and forward MNCC_CALL_CONF_IND
+ MSC <--GERAN-A-- MS: GSM48_MT_CC_CALL_CONF
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms)
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP
+DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_CALL_CONF
+DCC trans(CC:CALL_PRESENT IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx CALL_CONF in state CALL_PRESENT
+DCC trans(CC:CALL_PRESENT IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) stopping pending timer T303
+DCC trans(CC:CALL_PRESENT IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) starting timer T310 with 30 seconds
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Starting call assignment
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){ESTABLISHING}: Allocated
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){ESTABLISHING}: is child of msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP)
+DCC trans(CC:CALL_PRESENT IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) codecs: :0{GSM#3} (from: remote=1.2.3.4:56{GSM#3} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+ MGW <--CRCX to RTP_TO_CN-- MSC: call_id=0xb codecs=GSM#3
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){UNINITIALIZED}: Allocated
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){UNINITIALIZED}: is child of call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-11:RTP_TO_CN:no-CI){UNINITIALIZED}: setting codecs to GSM#3
+ MGW <--CRCX to RTP_TO_RAN-- MSC: call_id=0xb codecs=GSM#3
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){UNINITIALIZED}: Allocated
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){UNINITIALIZED}: is child of call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-11:RTP_TO_RAN:no-CI){UNINITIALIZED}: setting codecs to GSM#3
+DCC trans(CC:CALL_PRESENT IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) new state CALL_PRESENT -> MO_TERM_CALL_CONF
+DMNCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) tx MNCC_CALL_CONF_IND
+ MSC --> MNCC: callref 0x423: MNCC_CALL_CONF_IND
+
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc)
+- VALIDATE_SDP OK: cc_to_mncc_tx_last_sdp == t->mt_tx_sdp_mncc_call_conf_ind ==
+- MGW acknowledges the CRCX to RAN, triggering Assignment with FR1
+ MGW --CRCX OK to RTP_TO_RAN--> MSC
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){ESTABLISHING}: Received Event CALL_LEG_EV_RTP_STREAM_ADDR_AVAILABLE
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Received Event MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: MGW endpoint's RTP address available for the CI RTP_TO_RAN: 10.23.23.1:23 (osmux=no:-2)
+DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) codecs: :0{GSM#3} (from: remote=1.2.3.4:56{GSM#3} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) Sending Assignment Command
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN encode: ASSIGNMENT_COMMAND on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+- VALIDATE_PERM_SPEECH OK: &bssap_assignment_command_last_channel_type == t->mt_tx_assignment_perm_speech == FR1
+- Assignment completes, triggering CRCX to CN
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN decode: ASSIGNMENT_COMPLETE
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-11:RTP_TO_RAN:no-CI){UNINITIALIZED}: no change: codecs already set to GSM#3
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-11:RTP_TO_RAN:no-CI){UNINITIALIZED}: setting remote addr to 1.2.3.4:1234
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-11:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Not committing: no MGW endpoint CI set up
+DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) codecs: :0{GSM#3} (from: assigned=GSM#3 remote=1.2.3.4:56{GSM#3} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) Assignment Complete: RAN: GSM#3, CN: GSM#3
+DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) Assignment complete, but still waiting for the CRCX OK on the CN side RTP
+- MNCC sends MNCC_RTP_CREATE, which first waits for the CN side RTP
+ MSC <-- MNCC: callref 0x423: MNCC_RTP_CREATE
+
+DMNCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx MNCC_RTP_CREATE
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Assignment for this trans already started earlier
+- When the CN side RTP address is known, ack MNCC_RTP_CREATE
+ MGW --CRCX OK to RTP_TO_CN--> MSC
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){ESTABLISHING}: Received Event CALL_LEG_EV_RTP_STREAM_ADDR_AVAILABLE
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Received Event MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: MGW endpoint's RTP address available for the CI RTP_TO_CN: 10.23.23.1:23 (osmux=no:-2)
+DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) codecs: 10.23.23.1:23{GSM#3} (from: assigned=GSM#3 remote=1.2.3.4:56{GSM#3} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+DMNCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) tx MNCC_RTP_CREATE (RTP=10.23.23.1:23{GSM#3})
+ MSC --> MNCC: callref 0x423: MNCC_RTP_CREATE
+v=0
+o=OsmoMSC 0 0 IN IP4 10.23.23.1
+s=GSM Call
+c=IN IP4 10.23.23.1
+t=0 0
+m=audio 23 RTP/AVP 3
+a=rtpmap:3 GSM/8000
+a=ptime:20
+
+- VALIDATE_SDP OK: cc_to_mncc_tx_last_sdp == t->mt_tx_sdp_mncc_rtp_create == GSM
+- Total time passed: 626.000478 s
+ MSC <--GERAN-A-- MS: GSM48_MT_CC_ALERTING
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms)
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP
+DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_ALERTING
+DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx ALERTING in state MO_TERM_CALL_CONF
+DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) stopping pending timer T310
+DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) starting timer T301 with 180 seconds
+DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) new state MO_TERM_CALL_CONF -> CALL_RECEIVED
+DCC trans(CC:CALL_RECEIVED IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) codecs: 10.23.23.1:23{GSM#3} (from: assigned=GSM#3 remote=1.2.3.4:56{GSM#3} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+DMNCC trans(CC:CALL_RECEIVED IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) tx MNCC_ALERT_IND (RTP=10.23.23.1:23{GSM#3})
+ MSC --> MNCC: callref 0x423: MNCC_ALERT_IND
+v=0
+o=OsmoMSC 0 0 IN IP4 10.23.23.1
+s=GSM Call
+c=IN IP4 10.23.23.1
+t=0 0
+m=audio 23 RTP/AVP 3
+a=rtpmap:3 GSM/8000
+a=ptime:20
+
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc)
+- VALIDATE_SDP OK: cc_to_mncc_tx_last_sdp == t->mt_tx_sdp_mncc_alert_ind == GSM
+- Total time passed: 627.000501 s
+ MSC <--GERAN-A-- MS: GSM48_MT_CC_CONNECT
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms)
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP
+DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_CONNECT
+DCC trans(CC:CALL_RECEIVED IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx CONNECT in state CALL_RECEIVED
+DCC trans(CC:CALL_RECEIVED IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) stopping pending timer T301
+DCC trans(CC:CALL_RECEIVED IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) new state CALL_RECEIVED -> CONNECT_REQUEST
+DCC trans(CC:CONNECT_REQUEST IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) codecs: 10.23.23.1:23{GSM#3} (from: assigned=GSM#3 remote=1.2.3.4:56{GSM#3} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+DMNCC trans(CC:CONNECT_REQUEST IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) tx MNCC_SETUP_CNF (RTP=10.23.23.1:23{GSM#3})
+ MSC --> MNCC: callref 0x423: MNCC_SETUP_CNF
+v=0
+o=OsmoMSC 0 0 IN IP4 10.23.23.1
+s=GSM Call
+c=IN IP4 10.23.23.1
+t=0 0
+m=audio 23 RTP/AVP 3
+a=rtpmap:3 GSM/8000
+a=ptime:20
+
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc)
+- VALIDATE_SDP OK: cc_to_mncc_tx_last_sdp == t->mt_tx_sdp_mncc_setup_cnf == GSM
+ MSC <-- MNCC: callref 0x423: MNCC_SETUP_COMPL_REQ
+
+DMNCC trans(CC:CONNECT_REQUEST IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx MNCC_SETUP_COMPL_REQ
+DCC trans(CC:CONNECT_REQUEST IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) starting guard timer with 180 seconds
+DCC trans(CC:CONNECT_REQUEST IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) new state CONNECT_REQUEST -> ACTIVE
+DCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) stopping pending guard timer
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_CONNECT_ACK
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on GERAN-A
+- DTAP --GERAN-A--> MS: GSM48_MT_CC_CONNECT_ACK: 030f
+- DTAP matches expected message
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+
+
+- RTP stream goes ahead, not shown here.
+- Total time passed: 750.000546 s
+
+
+- Call ends
+ MSC <--GERAN-A-- MS: GSM48_MT_CC_DISCONNECT
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms)
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP
+DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_DISCONNECT
+DCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx DISCONNECT in state ACTIVE
+DCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) new state ACTIVE -> DISCONNECT_IND
+DMNCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) tx MNCC_DISC_IND
+ MSC --> MNCC: callref 0x423: MNCC_DISC_IND
+
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc)
+ MSC <-- MNCC: callref 0x423: MNCC_REL_REQ
+
+DMNCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx MNCC_REL_REQ
+DCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) starting guard timer with 180 seconds
+DCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) starting timer T308 with 10 seconds
+DCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) new state DISCONNECT_IND -> RELEASE_REQ
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_RELEASE
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on GERAN-A
+- DTAP --GERAN-A--> MS: GSM48_MT_CC_RELEASE: 032d
+- DTAP matches expected message
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+ MSC <--GERAN-A-- MS: GSM48_MT_CC_RELEASE_COMPL
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms)
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP
+DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_RELEASE_COMPL
+DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx RELEASE_COMPL in state RELEASE_REQ
+DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) stopping pending timer T308
+DMNCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) tx MNCC_REL_CNF
+ MSC --> MNCC: callref 0x423: MNCC_REL_CNF
+
+DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x0 tid-0) Freeing transaction
+DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x0 tid-0) new state RELEASE_REQ -> NULL
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x0 tid-0) stopping pending guard timer
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - CC: now used by 2 (attached,active-conn)
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - cc: now used by 1 (rx_from_ms)
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 0 (-)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Received Event MSC_A_EV_UNUSED
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: state_chg to MSC_A_ST_RELEASING
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: Releasing: msc_a use is 0 (-)
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + msc_a_fsm_releasing_onenter: now used by 3 (attached,active-conn,msc_a_fsm_releasing_onenter)
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,active-conn,msc_a_fsm_releasing_onenter,vlr_subscr_cancel_attach_fsm)
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,active-conn,msc_a_fsm_releasing_onenter)
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){ESTABLISHING}: state_chg to RELEASING
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-11:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-11:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Removing from parent call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-11:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Deallocated
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-11:RTP_TO_CN:no-CI){UNINITIALIZED}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-11:RTP_TO_CN:no-CI){UNINITIALIZED}: Removing from parent call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-11:RTP_TO_CN:no-CI){UNINITIALIZED}: Deallocated
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){RELEASING}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){RELEASING}: Removing from parent msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: Received Event MSC_EV_CALL_LEG_TERM
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){RELEASING}: Deallocated
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: + wait-Clear-Complete: now used by 1 (wait-Clear-Complete)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: RAN encode: CLEAR_COMMAND on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - msc_a_fsm_releasing_onenter: now used by 2 (attached,active-conn)
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: RAN decode: CLEAR_COMPLETE
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: - wait-Clear-Complete: now used by 0 (-)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: Received Event MSC_A_EV_UNUSED
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: state_chg to MSC_A_ST_RELEASED
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASED}: Released: msc_a use is 0 (-)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_DONE}: Terminating in cascade, depth 2 (cause = OSMO_FSM_TERM_PARENT, caused by: msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP))
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_DONE}: Removing from parent msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP)
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_DONE}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASED}: Removing from parent msub_fsm
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASED}: max total use count was 3
+DMSC msub_fsm{active}: Received Event MSUB_EV_ROLE_TERMINATED
+DMSC msub(IMSI-901700000010650:MSISDN-46071) MSC-A terminated
+DMSC msub(IMSI-901700000010650:MSISDN-46071) 1 MSC-I still active
+DMSC msub_fsm{active}: state_chg to terminating
+DMSC msub_fsm{terminating}: Terminating in cascade, depth 2 (cause = OSMO_FSM_TERM_REGULAR, caused by: msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP))
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Terminating in cascade, depth 3 (cause = OSMO_FSM_TERM_PARENT, caused by: msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP))
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Removing from parent msub_fsm
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP)
+DMSC msub(IMSI-901700000010650:MSISDN-46071) Free
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - active-conn: now used by 1 (attached)
+DMSC msub_fsm{terminating}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASED}: Deallocated, including all deferred deallocations
+- msub gone
+ llist_count(&msub_list) == 0
+
+
+- ======================== SUCCESS: MT call: FR1 picked by MO from Bearer Cap, MT hence also picks FR1
+
+
+- ======================== MO call: FR1 picked by MT's Codec List (BSS Supported), hence MO re-assigns to FR1
+- CM Service Request with Codec List (BSS Supported) = FR1 FR2 FR3 HR1 HR3
+ MSC <--GERAN-A-- MS: GSM48_MT_MM_CM_SERV_REQ
+ new conn
+DMSC msub_fsm{active}: Allocated
+DMSC msc_a{MSC_A_ST_VALIDATE_L3}: Allocated
+DMSC msc_a{MSC_A_ST_VALIDATE_L3}: is child of msub_fsm
+DMSC msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_VALIDATE_L3
+DMSC dummy_msc_i{0}: Allocated
+DMSC dummy_msc_i{0}: is child of msub_fsm
+DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms)
+DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3
+DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Complete Layer 3: Codec List (BSS Supported): GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111
+DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: MM GSM48_MT_MM_CM_SERV_REQ
+DMM msc_a(IMSI-901700000010650:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_VALIDATE_L3}: Rx CM SERVICE REQUEST cm_service_type=MO-Call
+DREF msc_a(IMSI-901700000010650:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_VALIDATE_L3}: + cm_service_cc: now used by 2 (rx_from_ms,cm_service_cc)
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: Allocated
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: is child of msc_a(IMSI-901700000010650:GERAN-A:CM_SERVICE_REQ)
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: rev=R99 net=GERAN (no Auth)
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + proc_arq_vlr_fn_init: now used by 2 (attached,proc_arq_vlr_fn_init)
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + active-conn: now used by 3 (attached,proc_arq_vlr_fn_init,active-conn)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi()
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_node2()
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_ciph()
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_vlr()
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_post_pres()
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_post_trace()
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_post_imei()
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: proc_arq_fsm_done(PASSED)
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_DONE
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_DONE}: Process Access Request result: PASSED
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: Sending DTAP: MM GSM48_MT_MM_CM_SERV_ACC
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN encode: DTAP on GERAN-A
+- DTAP --GERAN-A--> MS: GSM48_MT_MM_CM_SERV_ACC: 0521
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: Received Event MSC_A_EV_AUTHENTICATED
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: state_chg to MSC_A_ST_AUTHENTICATED
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - proc_arq_vlr_fn_init: now used by 2 (attached,active-conn)
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: - rx_from_ms: now used by 1 (cm_service_cc)
+ cm_service_result_sent == 1
+msc_a_is_accepted() == true
+- MS sends CC SETUP with Bearer Capability = AMR AMR AMR GSM-EFR GSM GSM-HR-08
+ MSC <--GERAN-A-- MS: GSM48_MT_CC_SETUP
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: + rx_from_ms: now used by 2 (cm_service_cc,rx_from_ms)
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: RAN decode: DTAP
+DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: Dispatching 04.08 message: CC GSM48_MT_CC_SETUP
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + CC: now used by 3 (attached,active-conn,CC)
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071 callref-0x80000007 tid-8) New transaction
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: Received Event MSC_A_EV_TRANSACTION_ACCEPTED
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: state_chg to MSC_A_ST_COMMUNICATING
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: + cc: now used by 3 (cm_service_cc,rx_from_ms,cc)
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - cm_service_cc: now used by 2 (rx_from_ms,cc)
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000007 tid-8) rx SETUP in state NULL
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000007 tid-8) starting guard timer with 180 seconds
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000007 tid-8) codecs: :0{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} (from: MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000007 tid-8) SETUP to 123
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000007 tid-8) new state NULL -> INITIATED
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Starting call assignment
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){ESTABLISHING}: Allocated
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){ESTABLISHING}: is child of msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ)
+DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000007 tid-8) codecs: :0{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} (from: MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+ MGW <--CRCX to RTP_TO_CN-- MSC: call_id=0xc codecs=AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){UNINITIALIZED}: Allocated
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){UNINITIALIZED}: is child of call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-12:RTP_TO_CN:no-CI){UNINITIALIZED}: setting codecs to AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111
+ MGW <--CRCX to RTP_TO_RAN-- MSC: call_id=0xc codecs=AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){UNINITIALIZED}: Allocated
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){UNINITIALIZED}: is child of call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-12:RTP_TO_RAN:no-CI){UNINITIALIZED}: setting codecs to AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc)
+- As soon as the MGW port towards CN is created, MNCC_SETUP_IND is triggered
+ MGW --CRCX OK to RTP_TO_CN--> MSC
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){ESTABLISHING}: Received Event CALL_LEG_EV_RTP_STREAM_ADDR_AVAILABLE
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Received Event MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: MGW endpoint's RTP address available for the CI RTP_TO_CN: 10.23.23.1:23 (osmux=no:-2)
+DMNCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000007 tid-8) tx MNCC_SETUP_IND (RTP=10.23.23.1:23{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+ MSC --> MNCC: callref 0x80000007: MNCC_SETUP_IND
+v=0
+o=OsmoMSC 0 0 IN IP4 10.23.23.1
+s=GSM Call
+c=IN IP4 10.23.23.1
+t=0 0
+m=audio 23 RTP/AVP 112 110 3 111
+a=rtpmap:112 AMR/8000
+a=fmtp:112 octet-align=1
+a=rtpmap:110 GSM-EFR/8000
+a=rtpmap:3 GSM/8000
+a=rtpmap:111 GSM-HR-08/8000
+a=ptime:20
+
+- VALIDATE_SDP OK: cc_to_mncc_tx_last_sdp == t->mo_tx_sdp_mncc_setup_ind == AMR GSM-EFR GSM GSM-HR-08
+- MNCC replies with MNCC_RTP_CREATE
+ MSC <-- MNCC: callref 0x80000007: MNCC_RTP_CREATE
+
+DMNCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000007 tid-8) rx MNCC_RTP_CREATE
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Assignment for this trans already started earlier
+- MGW acknowledges the CRCX, triggering Assignment with FR3 HR3 FR2 FR1 HR1
+ MGW --CRCX OK to RTP_TO_RAN--> MSC
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){ESTABLISHING}: Received Event CALL_LEG_EV_RTP_STREAM_ADDR_AVAILABLE
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Received Event MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: MGW endpoint's RTP address available for the CI RTP_TO_RAN: 10.23.23.1:23 (osmux=no:-2)
+DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000007 tid-8) codecs: 10.23.23.1:23{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} (from: MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000007 tid-8) Sending Assignment Command
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN encode: ASSIGNMENT_COMMAND on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+- VALIDATE_PERM_SPEECH OK: &bssap_assignment_command_last_channel_type == t->mo_tx_assignment_perm_speech == FR3 HR3 FR2 FR1 HR1
+- Assignment succeeds, triggering MNCC_RTP_CREATE ack to MNCC
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN decode: ASSIGNMENT_COMPLETE
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-12:RTP_TO_RAN:no-CI){UNINITIALIZED}: setting codecs to AMR:octet-align=1#112
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-12:RTP_TO_RAN:no-CI:local-10-23-23-1-23){UNINITIALIZED}: setting remote addr to 1.2.3.4:1234
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-12:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Not committing: no MGW endpoint CI set up
+DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000007 tid-8) codecs: 10.23.23.1:23{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} (from: assigned=AMR:octet-align=1#112 MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000007 tid-8) Assignment Complete: RAN: AMR:octet-align=1#112, CN: AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111
+DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000007 tid-8) codecs: 10.23.23.1:23{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} (from: assigned=AMR:octet-align=1#112 MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+DMNCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000007 tid-8) tx MNCC_RTP_CREATE (RTP=10.23.23.1:23{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+ MSC --> MNCC: callref 0x80000007: MNCC_RTP_CREATE
+v=0
+o=OsmoMSC 0 0 IN IP4 10.23.23.1
+s=GSM Call
+c=IN IP4 10.23.23.1
+t=0 0
+m=audio 23 RTP/AVP 112 110 3 111
+a=rtpmap:112 AMR/8000
+a=fmtp:112 octet-align=1
+a=rtpmap:110 GSM-EFR/8000
+a=rtpmap:3 GSM/8000
+a=rtpmap:111 GSM-HR-08/8000
+a=ptime:20
+
+- VALIDATE_SDP OK: cc_to_mncc_tx_last_sdp == t->mo_tx_sdp_mncc_rtp_create == AMR GSM-EFR GSM GSM-HR-08
+- MNCC says that's fine
+ MSC <-- MNCC: callref 0x80000007: MNCC_CALL_PROC_REQ
+
+DMNCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000007 tid-8) rx MNCC_CALL_PROC_REQ
+DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000007 tid-8) stopping pending guard timer
+DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000007 tid-8) starting guard timer with 180 seconds
+DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000007 tid-8) new state INITIATED -> MO_CALL_PROC
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_CALL_PROC
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on GERAN-A
+- DTAP --GERAN-A--> MS: GSM48_MT_CC_CALL_PROC: 8302
+- DTAP matches expected message
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Assignment for this trans already started earlier
+- Total time passed: 751.000569 s
+- The other call leg got established (not shown here), MNCC tells us so, with codecs { GSM }
+- Expecting re-assignment
+ MSC <-- MNCC: callref 0x80000007: MNCC_ALERT_REQ
+v=0
+o=OsmoMSC 0 0 IN IP4 1.2.3.4
+s=GSM Call
+c=IN IP4 1.2.3.4
+t=0 0
+m=audio 56 RTP/AVP 3
+a=rtpmap:3 GSM/8000
+a=ptime:20
+
+DMNCC trans(CC:MO_CALL_PROC IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000007 tid-8) rx MNCC_ALERT_REQ (RTP=1.2.3.4:56{GSM#3})
+DCC trans(CC:MO_CALL_PROC IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000007 tid-8) stopping pending guard timer
+DCC trans(CC:MO_CALL_PROC IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000007 tid-8) starting guard timer with 180 seconds
+DCC trans(CC:MO_CALL_PROC IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000007 tid-8) new state MO_CALL_PROC -> CALL_DELIVERED
+DCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000007 tid-8) codecs: 10.23.23.1:23{GSM#3} (from: assigned=AMR:octet-align=1#112 remote=1.2.3.4:56{GSM#3} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-12:RTP_TO_CN:no-CI){UNINITIALIZED}: setting codecs to GSM#3
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-12:RTP_TO_CN:no-CI:local-10-23-23-1-23){UNINITIALIZED}: setting remote addr to 1.2.3.4:56
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-12:RTP_TO_CN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-56){UNINITIALIZED}: Not committing: no MGW endpoint CI set up
+DCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000007 tid-8) Remote call leg mismatches assigned codec: 10.23.23.1:23{GSM#3} (from: assigned=AMR:octet-align=1#112 remote=1.2.3.4:56{GSM#3} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+DCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000007 tid-8) codecs: 10.23.23.1:23{GSM#3} (from: assigned=AMR:octet-align=1#112 remote=1.2.3.4:56{GSM#3} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+DCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000007 tid-8) Sending Assignment Command
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN encode: ASSIGNMENT_COMMAND on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_ALERTING
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on GERAN-A
+- DTAP --GERAN-A--> MS: GSM48_MT_CC_ALERTING: 8301
+- DTAP matches expected message
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+- Validating re-assignment
+- VALIDATE_PERM_SPEECH OK: &bssap_assignment_command_last_channel_type == t->mo_tx_reassignment_perm_speech == FR1
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN decode: ASSIGNMENT_COMPLETE
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-12:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: setting codecs to GSM#3
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-12:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: remote addr already 1.2.3.4:1234, no change
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-12:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Not committing: no MGW endpoint CI set up
+DCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000007 tid-8) codecs: 10.23.23.1:23{GSM#3} (from: assigned=GSM#3 remote=1.2.3.4:56{GSM#3} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+DCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000007 tid-8) Assignment Complete: RAN: GSM#3, CN: GSM#3
+DCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000007 tid-8) Re-Assignment complete
+ MSC <-- MNCC: callref 0x80000007: MNCC_SETUP_RSP
+v=0
+o=OsmoMSC 0 0 IN IP4 1.2.3.4
+s=GSM Call
+c=IN IP4 1.2.3.4
+t=0 0
+m=audio 56 RTP/AVP 3
+a=rtpmap:3 GSM/8000
+a=ptime:20
+
+DMNCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000007 tid-8) rx MNCC_SETUP_RSP (RTP=1.2.3.4:56{GSM#3})
+DCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000007 tid-8) stopping pending guard timer
+DCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000007 tid-8) starting guard timer with 180 seconds
+DCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000007 tid-8) starting timer T313 with 30 seconds
+DCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000007 tid-8) new state CALL_DELIVERED -> CONNECT_IND
+DCC trans(CC:CONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000007 tid-8) codecs: 10.23.23.1:23{GSM#3} (from: assigned=GSM#3 remote=1.2.3.4:56{GSM#3} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-12:RTP_TO_CN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-56){UNINITIALIZED}: no change: codecs already set to GSM#3
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-12:RTP_TO_CN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-56){UNINITIALIZED}: remote addr already 1.2.3.4:56, no change
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-12:RTP_TO_CN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-56){UNINITIALIZED}: Not committing: no MGW endpoint CI set up
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_CONNECT
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on GERAN-A
+- DTAP --GERAN-A--> MS: GSM48_MT_CC_CONNECT: 8307
+- DTAP matches expected message
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+- Total time passed: 752.000592 s
+ MSC <--GERAN-A-- MS: GSM48_MT_CC_CONNECT_ACK
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms)
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP
+DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_CONNECT_ACK
+DCC trans(CC:CONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000007 tid-8) rx CONNECT_ACK in state CONNECT_IND
+DCC trans(CC:CONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000007 tid-8) stopping pending timer T313
+DCC trans(CC:CONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000007 tid-8) new state CONNECT_IND -> ACTIVE
+DCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000007 tid-8) stopping pending guard timer
+DMNCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000007 tid-8) tx MNCC_SETUP_COMPL_IND
+ MSC --> MNCC: callref 0x80000007: MNCC_SETUP_COMPL_IND
+
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc)
+- VALIDATE_SDP OK: cc_to_mncc_tx_last_sdp == t->mo_tx_sdp_mncc_setup_compl_ind ==
+
+
+- RTP stream goes ahead, not shown here.
+- Total time passed: 875.000637 s
+
+
+- Call ends
+ MSC <--GERAN-A-- MS: GSM48_MT_CC_DISCONNECT
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms)
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP
+DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_DISCONNECT
+DCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000007 tid-8) rx DISCONNECT in state ACTIVE
+DCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000007 tid-8) new state ACTIVE -> DISCONNECT_IND
+DMNCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000007 tid-8) tx MNCC_DISC_IND
+ MSC --> MNCC: callref 0x80000007: MNCC_DISC_IND
+
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc)
+ MSC <-- MNCC: callref 0x80000007: MNCC_REL_REQ
+v=0
+o=OsmoMSC 0 0 IN IP4 1.2.3.4
+s=GSM Call
+c=IN IP4 1.2.3.4
+t=0 0
+m=audio 56 RTP/AVP 3
+a=rtpmap:3 GSM/8000
+a=ptime:20
+
+DMNCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000007 tid-8) rx MNCC_REL_REQ
+DCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000007 tid-8) starting guard timer with 180 seconds
+DCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000007 tid-8) starting timer T308 with 10 seconds
+DCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000007 tid-8) new state DISCONNECT_IND -> RELEASE_REQ
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_RELEASE
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on GERAN-A
+- DTAP --GERAN-A--> MS: GSM48_MT_CC_RELEASE: 832d
+- DTAP matches expected message
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+ MSC <--GERAN-A-- MS: GSM48_MT_CC_RELEASE_COMPL
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms)
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP
+DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_RELEASE_COMPL
+DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000007 tid-8) rx RELEASE_COMPL in state RELEASE_REQ
+DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000007 tid-8) stopping pending timer T308
+DMNCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000007 tid-8) tx MNCC_REL_CNF
+ MSC --> MNCC: callref 0x80000007: MNCC_REL_CNF
+
+DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x0 tid-8) Freeing transaction
+DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x0 tid-8) new state RELEASE_REQ -> NULL
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x0 tid-8) stopping pending guard timer
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - CC: now used by 2 (attached,active-conn)
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - cc: now used by 1 (rx_from_ms)
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 0 (-)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Received Event MSC_A_EV_UNUSED
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: state_chg to MSC_A_ST_RELEASING
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: Releasing: msc_a use is 0 (-)
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + msc_a_fsm_releasing_onenter: now used by 3 (attached,active-conn,msc_a_fsm_releasing_onenter)
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,active-conn,msc_a_fsm_releasing_onenter,vlr_subscr_cancel_attach_fsm)
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,active-conn,msc_a_fsm_releasing_onenter)
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){ESTABLISHING}: state_chg to RELEASING
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-12:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-12:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Removing from parent call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-12:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Deallocated
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-12:RTP_TO_CN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-56){UNINITIALIZED}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-12:RTP_TO_CN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-56){UNINITIALIZED}: Removing from parent call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-12:RTP_TO_CN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-56){UNINITIALIZED}: Deallocated
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){RELEASING}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){RELEASING}: Removing from parent msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: Received Event MSC_EV_CALL_LEG_TERM
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){RELEASING}: Deallocated
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: + wait-Clear-Complete: now used by 1 (wait-Clear-Complete)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: RAN encode: CLEAR_COMMAND on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - msc_a_fsm_releasing_onenter: now used by 2 (attached,active-conn)
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: RAN decode: CLEAR_COMPLETE
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: - wait-Clear-Complete: now used by 0 (-)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: Received Event MSC_A_EV_UNUSED
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: state_chg to MSC_A_ST_RELEASED
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASED}: Released: msc_a use is 0 (-)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_DONE}: Terminating in cascade, depth 2 (cause = OSMO_FSM_TERM_PARENT, caused by: msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ))
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_DONE}: Removing from parent msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ)
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_DONE}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASED}: Removing from parent msub_fsm
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASED}: max total use count was 3
+DMSC msub_fsm{active}: Received Event MSUB_EV_ROLE_TERMINATED
+DMSC msub(IMSI-901700000010650:MSISDN-46071) MSC-A terminated
+DMSC msub(IMSI-901700000010650:MSISDN-46071) 1 MSC-I still active
+DMSC msub_fsm{active}: state_chg to terminating
+DMSC msub_fsm{terminating}: Terminating in cascade, depth 2 (cause = OSMO_FSM_TERM_REGULAR, caused by: msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ))
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Terminating in cascade, depth 3 (cause = OSMO_FSM_TERM_PARENT, caused by: msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ))
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Removing from parent msub_fsm
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ)
+DMSC msub(IMSI-901700000010650:MSISDN-46071) Free
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - active-conn: now used by 1 (attached)
+DMSC msub_fsm{terminating}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASED}: Deallocated, including all deferred deallocations
+- msub gone
+ llist_count(&msub_list) == 0
+
+
+- ======================== SUCCESS: MO call: FR1 picked by MT's Codec List (BSS Supported), hence MO re-assigns to FR1
+
+
+- ======================== MT call: FR1 picked by MT's Codec List (BSS Supported), hence MO re-assigns to FR1
+
+
+- MNCC asks us to setup a call, causing Paging
+ MSC <-- MNCC: callref 0x423: MNCC_SETUP_REQ
+v=0
+o=OsmoMSC 0 0 IN IP4 1.2.3.4
+s=GSM Call
+c=IN IP4 1.2.3.4
+t=0 0
+m=audio 56 RTP/AVP 112 110 3 111
+a=rtpmap:112 AMR/8000
+a=fmtp:112 octet-align=1
+a=rtpmap:110 GSM-EFR/8000
+a=rtpmap:3 GSM/8000
+a=rtpmap:111 GSM-HR-08/8000
+a=ptime:20
+
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + mncc_tx_to_gsm_cc: now used by 2 (attached,mncc_tx_to_gsm_cc)
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + CC: now used by 3 (attached,mncc_tx_to_gsm_cc,CC)
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071 callref-0x423 tid-255) New transaction
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071 callref-0x423 tid-255) codecs: :0{(no-codecs)} (from: remote=1.2.3.4:56{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} RAN={(no-codecs)})
+DMNCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071 callref-0x423 tid-255) rx MNCC_SETUP_REQ (RTP=1.2.3.4:56{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+DPAG Paging: IMSI-901700000010650:MSISDN-46071 for MNCC: establish call: Starting paging
+ paging request (CALL_CONVERSATIONAL) to IMSI-901700000010650:MSISDN-46071 on GERAN-A
+ strcmp(paging_expecting_imsi, vsub->imsi) == 0
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + Paging: now used by 4 (attached,mncc_tx_to_gsm_cc,CC,Paging)
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - mncc_tx_to_gsm_cc: now used by 3 (attached,CC,Paging)
+ paging_sent == 1
+- MS replies with Paging Response, with Codec List (BSS Supported) = FR1
+- VLR accepts, MSC sends CC Setup with Bearer Capability = GSM
+ MSC <--GERAN-A-- MS: GSM48_MT_RR_PAG_RESP
+ new conn
+DMSC msub_fsm{active}: Allocated
+DMSC msc_a{MSC_A_ST_VALIDATE_L3}: Allocated
+DMSC msc_a{MSC_A_ST_VALIDATE_L3}: is child of msub_fsm
+DMSC msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_VALIDATE_L3
+DMSC dummy_msc_i{0}: Allocated
+DMSC dummy_msc_i{0}: is child of msub_fsm
+DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms)
+DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3
+DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Complete Layer 3: Codec List (BSS Supported): GSM#3
+DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: RR GSM48_MT_RR_PAG_RESP
+DRR msc_a(IMSI-901700000010650:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: Rx PAGING RESPONSE IMSI-901700000010650
+DREF msc_a(IMSI-901700000010650:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: + paging-response: now used by 2 (rx_from_ms,paging-response)
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: Allocated
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: is child of msc_a(IMSI-901700000010650:GERAN-A:PAGING_RESP)
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: rev=R99 net=GERAN (no Auth)
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + proc_arq_vlr_fn_init: now used by 4 (attached,CC,Paging,proc_arq_vlr_fn_init)
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + active-conn: now used by 5 (attached,CC,Paging,proc_arq_vlr_fn_init,active-conn)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi()
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_node2()
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_ciph()
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_vlr()
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_post_pres()
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_post_trace()
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_post_imei()
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: proc_arq_fsm_done(PASSED)
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_DONE
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_DONE}: Process Access Request result: PASSED
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: Received Event MSC_A_EV_AUTHENTICATED
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: state_chg to MSC_A_ST_AUTHENTICATED
+DPAG Paging: IMSI-901700000010650:MSISDN-46071 for MNCC: establish call: Paging Response action (success)
+DPAG Paging: IMSI-901700000010650:MSISDN-46071 for MNCC: establish call: Removing Paging Request
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071 callref-0x423 tid-255) Paging succeeded
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: + cc: now used by 3 (rx_from_ms,paging-response,cc)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: Received Event MSC_A_EV_TRANSACTION_ACCEPTED
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: state_chg to MSC_A_ST_COMMUNICATING
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) starting timer T303 with 30 seconds
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) codecs: :0{GSM#3} (from: remote=1.2.3.4:56{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) new state NULL -> CALL_PRESENT
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_SETUP
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on GERAN-A
+- DTAP --GERAN-A--> MS: GSM48_MT_CC_SETUP: 030504022080
+- DTAP matches expected message
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - Paging: now used by 4 (attached,CC,proc_arq_vlr_fn_init,active-conn)
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - paging-response: now used by 2 (rx_from_ms,cc)
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - proc_arq_vlr_fn_init: now used by 3 (attached,CC,active-conn)
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc)
+- MS confirms call, we create a RAN-side RTP and forward MNCC_CALL_CONF_IND
+ MSC <--GERAN-A-- MS: GSM48_MT_CC_CALL_CONF
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms)
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP
+DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_CALL_CONF
+DCC trans(CC:CALL_PRESENT IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx CALL_CONF in state CALL_PRESENT
+DCC trans(CC:CALL_PRESENT IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) stopping pending timer T303
+DCC trans(CC:CALL_PRESENT IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) starting timer T310 with 30 seconds
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Starting call assignment
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){ESTABLISHING}: Allocated
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){ESTABLISHING}: is child of msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP)
+DCC trans(CC:CALL_PRESENT IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) codecs: :0{GSM#3} (from: remote=1.2.3.4:56{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+ MGW <--CRCX to RTP_TO_CN-- MSC: call_id=0xd codecs=GSM#3
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){UNINITIALIZED}: Allocated
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){UNINITIALIZED}: is child of call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-13:RTP_TO_CN:no-CI){UNINITIALIZED}: setting codecs to GSM#3
+ MGW <--CRCX to RTP_TO_RAN-- MSC: call_id=0xd codecs=GSM#3
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){UNINITIALIZED}: Allocated
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){UNINITIALIZED}: is child of call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-13:RTP_TO_RAN:no-CI){UNINITIALIZED}: setting codecs to GSM#3
+DCC trans(CC:CALL_PRESENT IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) new state CALL_PRESENT -> MO_TERM_CALL_CONF
+DMNCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) tx MNCC_CALL_CONF_IND
+ MSC --> MNCC: callref 0x423: MNCC_CALL_CONF_IND
+
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc)
+- VALIDATE_SDP OK: cc_to_mncc_tx_last_sdp == t->mt_tx_sdp_mncc_call_conf_ind ==
+- MGW acknowledges the CRCX to RAN, triggering Assignment with FR1
+ MGW --CRCX OK to RTP_TO_RAN--> MSC
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){ESTABLISHING}: Received Event CALL_LEG_EV_RTP_STREAM_ADDR_AVAILABLE
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Received Event MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: MGW endpoint's RTP address available for the CI RTP_TO_RAN: 10.23.23.1:23 (osmux=no:-2)
+DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) codecs: :0{GSM#3} (from: remote=1.2.3.4:56{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) Sending Assignment Command
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN encode: ASSIGNMENT_COMMAND on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+- VALIDATE_PERM_SPEECH OK: &bssap_assignment_command_last_channel_type == t->mt_tx_assignment_perm_speech == FR1
+- Assignment completes, triggering CRCX to CN
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN decode: ASSIGNMENT_COMPLETE
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-13:RTP_TO_RAN:no-CI){UNINITIALIZED}: no change: codecs already set to GSM#3
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-13:RTP_TO_RAN:no-CI){UNINITIALIZED}: setting remote addr to 1.2.3.4:1234
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-13:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Not committing: no MGW endpoint CI set up
+DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) codecs: :0{GSM#3} (from: assigned=GSM#3 remote=1.2.3.4:56{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) Assignment Complete: RAN: GSM#3, CN: GSM#3
+DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) Assignment complete, but still waiting for the CRCX OK on the CN side RTP
+- MNCC sends MNCC_RTP_CREATE, which first waits for the CN side RTP
+ MSC <-- MNCC: callref 0x423: MNCC_RTP_CREATE
+
+DMNCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx MNCC_RTP_CREATE
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Assignment for this trans already started earlier
+- When the CN side RTP address is known, ack MNCC_RTP_CREATE
+ MGW --CRCX OK to RTP_TO_CN--> MSC
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){ESTABLISHING}: Received Event CALL_LEG_EV_RTP_STREAM_ADDR_AVAILABLE
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Received Event MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: MGW endpoint's RTP address available for the CI RTP_TO_CN: 10.23.23.1:23 (osmux=no:-2)
+DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) codecs: 10.23.23.1:23{GSM#3} (from: assigned=GSM#3 remote=1.2.3.4:56{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+DMNCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) tx MNCC_RTP_CREATE (RTP=10.23.23.1:23{GSM#3})
+ MSC --> MNCC: callref 0x423: MNCC_RTP_CREATE
+v=0
+o=OsmoMSC 0 0 IN IP4 10.23.23.1
+s=GSM Call
+c=IN IP4 10.23.23.1
+t=0 0
+m=audio 23 RTP/AVP 3
+a=rtpmap:3 GSM/8000
+a=ptime:20
+
+- VALIDATE_SDP OK: cc_to_mncc_tx_last_sdp == t->mt_tx_sdp_mncc_rtp_create == GSM
+- Total time passed: 876.000660 s
+ MSC <--GERAN-A-- MS: GSM48_MT_CC_ALERTING
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms)
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP
+DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_ALERTING
+DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx ALERTING in state MO_TERM_CALL_CONF
+DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) stopping pending timer T310
+DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) starting timer T301 with 180 seconds
+DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) new state MO_TERM_CALL_CONF -> CALL_RECEIVED
+DCC trans(CC:CALL_RECEIVED IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) codecs: 10.23.23.1:23{GSM#3} (from: assigned=GSM#3 remote=1.2.3.4:56{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+DMNCC trans(CC:CALL_RECEIVED IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) tx MNCC_ALERT_IND (RTP=10.23.23.1:23{GSM#3})
+ MSC --> MNCC: callref 0x423: MNCC_ALERT_IND
+v=0
+o=OsmoMSC 0 0 IN IP4 10.23.23.1
+s=GSM Call
+c=IN IP4 10.23.23.1
+t=0 0
+m=audio 23 RTP/AVP 3
+a=rtpmap:3 GSM/8000
+a=ptime:20
+
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc)
+- VALIDATE_SDP OK: cc_to_mncc_tx_last_sdp == t->mt_tx_sdp_mncc_alert_ind == GSM
+- Total time passed: 877.000683 s
+ MSC <--GERAN-A-- MS: GSM48_MT_CC_CONNECT
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms)
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP
+DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_CONNECT
+DCC trans(CC:CALL_RECEIVED IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx CONNECT in state CALL_RECEIVED
+DCC trans(CC:CALL_RECEIVED IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) stopping pending timer T301
+DCC trans(CC:CALL_RECEIVED IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) new state CALL_RECEIVED -> CONNECT_REQUEST
+DCC trans(CC:CONNECT_REQUEST IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) codecs: 10.23.23.1:23{GSM#3} (from: assigned=GSM#3 remote=1.2.3.4:56{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+DMNCC trans(CC:CONNECT_REQUEST IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) tx MNCC_SETUP_CNF (RTP=10.23.23.1:23{GSM#3})
+ MSC --> MNCC: callref 0x423: MNCC_SETUP_CNF
+v=0
+o=OsmoMSC 0 0 IN IP4 10.23.23.1
+s=GSM Call
+c=IN IP4 10.23.23.1
+t=0 0
+m=audio 23 RTP/AVP 3
+a=rtpmap:3 GSM/8000
+a=ptime:20
+
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc)
+- VALIDATE_SDP OK: cc_to_mncc_tx_last_sdp == t->mt_tx_sdp_mncc_setup_cnf == GSM
+ MSC <-- MNCC: callref 0x423: MNCC_SETUP_COMPL_REQ
+
+DMNCC trans(CC:CONNECT_REQUEST IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx MNCC_SETUP_COMPL_REQ
+DCC trans(CC:CONNECT_REQUEST IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) starting guard timer with 180 seconds
+DCC trans(CC:CONNECT_REQUEST IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) new state CONNECT_REQUEST -> ACTIVE
+DCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) stopping pending guard timer
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_CONNECT_ACK
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on GERAN-A
+- DTAP --GERAN-A--> MS: GSM48_MT_CC_CONNECT_ACK: 030f
+- DTAP matches expected message
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+
+
+- RTP stream goes ahead, not shown here.
+- Total time passed: 1000.000728 s
+
+
+- Call ends
+ MSC <--GERAN-A-- MS: GSM48_MT_CC_DISCONNECT
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms)
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP
+DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_DISCONNECT
+DCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx DISCONNECT in state ACTIVE
+DCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) new state ACTIVE -> DISCONNECT_IND
+DMNCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) tx MNCC_DISC_IND
+ MSC --> MNCC: callref 0x423: MNCC_DISC_IND
+
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc)
+ MSC <-- MNCC: callref 0x423: MNCC_REL_REQ
+
+DMNCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx MNCC_REL_REQ
+DCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) starting guard timer with 180 seconds
+DCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) starting timer T308 with 10 seconds
+DCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) new state DISCONNECT_IND -> RELEASE_REQ
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_RELEASE
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on GERAN-A
+- DTAP --GERAN-A--> MS: GSM48_MT_CC_RELEASE: 032d
+- DTAP matches expected message
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+ MSC <--GERAN-A-- MS: GSM48_MT_CC_RELEASE_COMPL
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms)
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP
+DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_RELEASE_COMPL
+DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx RELEASE_COMPL in state RELEASE_REQ
+DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) stopping pending timer T308
+DMNCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) tx MNCC_REL_CNF
+ MSC --> MNCC: callref 0x423: MNCC_REL_CNF
+
+DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x0 tid-0) Freeing transaction
+DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x0 tid-0) new state RELEASE_REQ -> NULL
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x0 tid-0) stopping pending guard timer
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - CC: now used by 2 (attached,active-conn)
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - cc: now used by 1 (rx_from_ms)
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 0 (-)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Received Event MSC_A_EV_UNUSED
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: state_chg to MSC_A_ST_RELEASING
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: Releasing: msc_a use is 0 (-)
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + msc_a_fsm_releasing_onenter: now used by 3 (attached,active-conn,msc_a_fsm_releasing_onenter)
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,active-conn,msc_a_fsm_releasing_onenter,vlr_subscr_cancel_attach_fsm)
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,active-conn,msc_a_fsm_releasing_onenter)
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){ESTABLISHING}: state_chg to RELEASING
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-13:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-13:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Removing from parent call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-13:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Deallocated
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-13:RTP_TO_CN:no-CI){UNINITIALIZED}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-13:RTP_TO_CN:no-CI){UNINITIALIZED}: Removing from parent call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-13:RTP_TO_CN:no-CI){UNINITIALIZED}: Deallocated
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){RELEASING}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){RELEASING}: Removing from parent msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: Received Event MSC_EV_CALL_LEG_TERM
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){RELEASING}: Deallocated
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: + wait-Clear-Complete: now used by 1 (wait-Clear-Complete)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: RAN encode: CLEAR_COMMAND on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - msc_a_fsm_releasing_onenter: now used by 2 (attached,active-conn)
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: RAN decode: CLEAR_COMPLETE
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: - wait-Clear-Complete: now used by 0 (-)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: Received Event MSC_A_EV_UNUSED
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: state_chg to MSC_A_ST_RELEASED
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASED}: Released: msc_a use is 0 (-)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_DONE}: Terminating in cascade, depth 2 (cause = OSMO_FSM_TERM_PARENT, caused by: msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP))
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_DONE}: Removing from parent msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP)
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_DONE}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASED}: Removing from parent msub_fsm
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASED}: max total use count was 3
+DMSC msub_fsm{active}: Received Event MSUB_EV_ROLE_TERMINATED
+DMSC msub(IMSI-901700000010650:MSISDN-46071) MSC-A terminated
+DMSC msub(IMSI-901700000010650:MSISDN-46071) 1 MSC-I still active
+DMSC msub_fsm{active}: state_chg to terminating
+DMSC msub_fsm{terminating}: Terminating in cascade, depth 2 (cause = OSMO_FSM_TERM_REGULAR, caused by: msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP))
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Terminating in cascade, depth 3 (cause = OSMO_FSM_TERM_PARENT, caused by: msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP))
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Removing from parent msub_fsm
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP)
+DMSC msub(IMSI-901700000010650:MSISDN-46071) Free
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - active-conn: now used by 1 (attached)
+DMSC msub_fsm{terminating}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASED}: Deallocated, including all deferred deallocations
+- msub gone
+ llist_count(&msub_list) == 0
+
+
+- ======================== SUCCESS: MT call: FR1 picked by MT's Codec List (BSS Supported), hence MO re-assigns to FR1
+
+
+- ======================== MO call: FR1 picked by MT's MS Bearer Capability, hence MO re-assigns to FR1
+- CM Service Request with Codec List (BSS Supported) = FR1 FR2 FR3 HR1 HR3
+ MSC <--GERAN-A-- MS: GSM48_MT_MM_CM_SERV_REQ
+ new conn
+DMSC msub_fsm{active}: Allocated
+DMSC msc_a{MSC_A_ST_VALIDATE_L3}: Allocated
+DMSC msc_a{MSC_A_ST_VALIDATE_L3}: is child of msub_fsm
+DMSC msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_VALIDATE_L3
+DMSC dummy_msc_i{0}: Allocated
+DMSC dummy_msc_i{0}: is child of msub_fsm
+DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms)
+DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3
+DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Complete Layer 3: Codec List (BSS Supported): GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111
+DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: MM GSM48_MT_MM_CM_SERV_REQ
+DMM msc_a(IMSI-901700000010650:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_VALIDATE_L3}: Rx CM SERVICE REQUEST cm_service_type=MO-Call
+DREF msc_a(IMSI-901700000010650:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_VALIDATE_L3}: + cm_service_cc: now used by 2 (rx_from_ms,cm_service_cc)
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: Allocated
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: is child of msc_a(IMSI-901700000010650:GERAN-A:CM_SERVICE_REQ)
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: rev=R99 net=GERAN (no Auth)
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + proc_arq_vlr_fn_init: now used by 2 (attached,proc_arq_vlr_fn_init)
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + active-conn: now used by 3 (attached,proc_arq_vlr_fn_init,active-conn)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi()
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_node2()
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_ciph()
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_vlr()
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_post_pres()
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_post_trace()
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_post_imei()
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: proc_arq_fsm_done(PASSED)
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_DONE
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_DONE}: Process Access Request result: PASSED
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: Sending DTAP: MM GSM48_MT_MM_CM_SERV_ACC
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN encode: DTAP on GERAN-A
+- DTAP --GERAN-A--> MS: GSM48_MT_MM_CM_SERV_ACC: 0521
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: Received Event MSC_A_EV_AUTHENTICATED
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: state_chg to MSC_A_ST_AUTHENTICATED
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - proc_arq_vlr_fn_init: now used by 2 (attached,active-conn)
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: - rx_from_ms: now used by 1 (cm_service_cc)
+ cm_service_result_sent == 1
+msc_a_is_accepted() == true
+- MS sends CC SETUP with Bearer Capability = AMR AMR AMR GSM-EFR GSM GSM-HR-08
+ MSC <--GERAN-A-- MS: GSM48_MT_CC_SETUP
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: + rx_from_ms: now used by 2 (cm_service_cc,rx_from_ms)
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: RAN decode: DTAP
+DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: Dispatching 04.08 message: CC GSM48_MT_CC_SETUP
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + CC: now used by 3 (attached,active-conn,CC)
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071 callref-0x80000008 tid-8) New transaction
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: Received Event MSC_A_EV_TRANSACTION_ACCEPTED
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: state_chg to MSC_A_ST_COMMUNICATING
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: + cc: now used by 3 (cm_service_cc,rx_from_ms,cc)
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - cm_service_cc: now used by 2 (rx_from_ms,cc)
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000008 tid-8) rx SETUP in state NULL
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000008 tid-8) starting guard timer with 180 seconds
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000008 tid-8) codecs: :0{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} (from: MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000008 tid-8) SETUP to 123
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000008 tid-8) new state NULL -> INITIATED
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Starting call assignment
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){ESTABLISHING}: Allocated
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){ESTABLISHING}: is child of msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ)
+DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000008 tid-8) codecs: :0{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} (from: MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+ MGW <--CRCX to RTP_TO_CN-- MSC: call_id=0xe codecs=AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){UNINITIALIZED}: Allocated
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){UNINITIALIZED}: is child of call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-14:RTP_TO_CN:no-CI){UNINITIALIZED}: setting codecs to AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111
+ MGW <--CRCX to RTP_TO_RAN-- MSC: call_id=0xe codecs=AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){UNINITIALIZED}: Allocated
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){UNINITIALIZED}: is child of call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-14:RTP_TO_RAN:no-CI){UNINITIALIZED}: setting codecs to AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc)
+- As soon as the MGW port towards CN is created, MNCC_SETUP_IND is triggered
+ MGW --CRCX OK to RTP_TO_CN--> MSC
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){ESTABLISHING}: Received Event CALL_LEG_EV_RTP_STREAM_ADDR_AVAILABLE
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Received Event MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: MGW endpoint's RTP address available for the CI RTP_TO_CN: 10.23.23.1:23 (osmux=no:-2)
+DMNCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000008 tid-8) tx MNCC_SETUP_IND (RTP=10.23.23.1:23{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+ MSC --> MNCC: callref 0x80000008: MNCC_SETUP_IND
+v=0
+o=OsmoMSC 0 0 IN IP4 10.23.23.1
+s=GSM Call
+c=IN IP4 10.23.23.1
+t=0 0
+m=audio 23 RTP/AVP 112 110 3 111
+a=rtpmap:112 AMR/8000
+a=fmtp:112 octet-align=1
+a=rtpmap:110 GSM-EFR/8000
+a=rtpmap:3 GSM/8000
+a=rtpmap:111 GSM-HR-08/8000
+a=ptime:20
+
+- VALIDATE_SDP OK: cc_to_mncc_tx_last_sdp == t->mo_tx_sdp_mncc_setup_ind == AMR GSM-EFR GSM GSM-HR-08
+- MNCC replies with MNCC_RTP_CREATE
+ MSC <-- MNCC: callref 0x80000008: MNCC_RTP_CREATE
+
+DMNCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000008 tid-8) rx MNCC_RTP_CREATE
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Assignment for this trans already started earlier
+- MGW acknowledges the CRCX, triggering Assignment with FR3 HR3 FR2 FR1 HR1
+ MGW --CRCX OK to RTP_TO_RAN--> MSC
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){ESTABLISHING}: Received Event CALL_LEG_EV_RTP_STREAM_ADDR_AVAILABLE
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Received Event MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: MGW endpoint's RTP address available for the CI RTP_TO_RAN: 10.23.23.1:23 (osmux=no:-2)
+DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000008 tid-8) codecs: 10.23.23.1:23{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} (from: MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000008 tid-8) Sending Assignment Command
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN encode: ASSIGNMENT_COMMAND on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+- VALIDATE_PERM_SPEECH OK: &bssap_assignment_command_last_channel_type == t->mo_tx_assignment_perm_speech == FR3 HR3 FR2 FR1 HR1
+- Assignment succeeds, triggering MNCC_RTP_CREATE ack to MNCC
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN decode: ASSIGNMENT_COMPLETE
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-14:RTP_TO_RAN:no-CI){UNINITIALIZED}: setting codecs to AMR:octet-align=1#112
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-14:RTP_TO_RAN:no-CI:local-10-23-23-1-23){UNINITIALIZED}: setting remote addr to 1.2.3.4:1234
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-14:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Not committing: no MGW endpoint CI set up
+DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000008 tid-8) codecs: 10.23.23.1:23{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} (from: assigned=AMR:octet-align=1#112 MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000008 tid-8) Assignment Complete: RAN: AMR:octet-align=1#112, CN: AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111
+DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000008 tid-8) codecs: 10.23.23.1:23{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} (from: assigned=AMR:octet-align=1#112 MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+DMNCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000008 tid-8) tx MNCC_RTP_CREATE (RTP=10.23.23.1:23{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+ MSC --> MNCC: callref 0x80000008: MNCC_RTP_CREATE
+v=0
+o=OsmoMSC 0 0 IN IP4 10.23.23.1
+s=GSM Call
+c=IN IP4 10.23.23.1
+t=0 0
+m=audio 23 RTP/AVP 112 110 3 111
+a=rtpmap:112 AMR/8000
+a=fmtp:112 octet-align=1
+a=rtpmap:110 GSM-EFR/8000
+a=rtpmap:3 GSM/8000
+a=rtpmap:111 GSM-HR-08/8000
+a=ptime:20
+
+- VALIDATE_SDP OK: cc_to_mncc_tx_last_sdp == t->mo_tx_sdp_mncc_rtp_create == AMR GSM-EFR GSM GSM-HR-08
+- MNCC says that's fine
+ MSC <-- MNCC: callref 0x80000008: MNCC_CALL_PROC_REQ
+
+DMNCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000008 tid-8) rx MNCC_CALL_PROC_REQ
+DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000008 tid-8) stopping pending guard timer
+DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000008 tid-8) starting guard timer with 180 seconds
+DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000008 tid-8) new state INITIATED -> MO_CALL_PROC
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_CALL_PROC
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on GERAN-A
+- DTAP --GERAN-A--> MS: GSM48_MT_CC_CALL_PROC: 8302
+- DTAP matches expected message
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Assignment for this trans already started earlier
+- Total time passed: 1001.000751 s
+- The other call leg got established (not shown here), MNCC tells us so, with codecs { GSM }
+- Expecting re-assignment
+ MSC <-- MNCC: callref 0x80000008: MNCC_ALERT_REQ
+v=0
+o=OsmoMSC 0 0 IN IP4 1.2.3.4
+s=GSM Call
+c=IN IP4 1.2.3.4
+t=0 0
+m=audio 56 RTP/AVP 3
+a=rtpmap:3 GSM/8000
+a=ptime:20
+
+DMNCC trans(CC:MO_CALL_PROC IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000008 tid-8) rx MNCC_ALERT_REQ (RTP=1.2.3.4:56{GSM#3})
+DCC trans(CC:MO_CALL_PROC IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000008 tid-8) stopping pending guard timer
+DCC trans(CC:MO_CALL_PROC IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000008 tid-8) starting guard timer with 180 seconds
+DCC trans(CC:MO_CALL_PROC IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000008 tid-8) new state MO_CALL_PROC -> CALL_DELIVERED
+DCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000008 tid-8) codecs: 10.23.23.1:23{GSM#3} (from: assigned=AMR:octet-align=1#112 remote=1.2.3.4:56{GSM#3} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-14:RTP_TO_CN:no-CI){UNINITIALIZED}: setting codecs to GSM#3
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-14:RTP_TO_CN:no-CI:local-10-23-23-1-23){UNINITIALIZED}: setting remote addr to 1.2.3.4:56
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-14:RTP_TO_CN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-56){UNINITIALIZED}: Not committing: no MGW endpoint CI set up
+DCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000008 tid-8) Remote call leg mismatches assigned codec: 10.23.23.1:23{GSM#3} (from: assigned=AMR:octet-align=1#112 remote=1.2.3.4:56{GSM#3} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+DCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000008 tid-8) codecs: 10.23.23.1:23{GSM#3} (from: assigned=AMR:octet-align=1#112 remote=1.2.3.4:56{GSM#3} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+DCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000008 tid-8) Sending Assignment Command
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN encode: ASSIGNMENT_COMMAND on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_ALERTING
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on GERAN-A
+- DTAP --GERAN-A--> MS: GSM48_MT_CC_ALERTING: 8301
+- DTAP matches expected message
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+- Validating re-assignment
+- VALIDATE_PERM_SPEECH OK: &bssap_assignment_command_last_channel_type == t->mo_tx_reassignment_perm_speech == FR1
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN decode: ASSIGNMENT_COMPLETE
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-14:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: setting codecs to GSM#3
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-14:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: remote addr already 1.2.3.4:1234, no change
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-14:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Not committing: no MGW endpoint CI set up
+DCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000008 tid-8) codecs: 10.23.23.1:23{GSM#3} (from: assigned=GSM#3 remote=1.2.3.4:56{GSM#3} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+DCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000008 tid-8) Assignment Complete: RAN: GSM#3, CN: GSM#3
+DCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000008 tid-8) Re-Assignment complete
+ MSC <-- MNCC: callref 0x80000008: MNCC_SETUP_RSP
+v=0
+o=OsmoMSC 0 0 IN IP4 1.2.3.4
+s=GSM Call
+c=IN IP4 1.2.3.4
+t=0 0
+m=audio 56 RTP/AVP 3
+a=rtpmap:3 GSM/8000
+a=ptime:20
+
+DMNCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000008 tid-8) rx MNCC_SETUP_RSP (RTP=1.2.3.4:56{GSM#3})
+DCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000008 tid-8) stopping pending guard timer
+DCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000008 tid-8) starting guard timer with 180 seconds
+DCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000008 tid-8) starting timer T313 with 30 seconds
+DCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000008 tid-8) new state CALL_DELIVERED -> CONNECT_IND
+DCC trans(CC:CONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000008 tid-8) codecs: 10.23.23.1:23{GSM#3} (from: assigned=GSM#3 remote=1.2.3.4:56{GSM#3} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-14:RTP_TO_CN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-56){UNINITIALIZED}: no change: codecs already set to GSM#3
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-14:RTP_TO_CN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-56){UNINITIALIZED}: remote addr already 1.2.3.4:56, no change
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-14:RTP_TO_CN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-56){UNINITIALIZED}: Not committing: no MGW endpoint CI set up
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_CONNECT
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on GERAN-A
+- DTAP --GERAN-A--> MS: GSM48_MT_CC_CONNECT: 8307
+- DTAP matches expected message
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+- Total time passed: 1002.000774 s
+ MSC <--GERAN-A-- MS: GSM48_MT_CC_CONNECT_ACK
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms)
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP
+DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_CONNECT_ACK
+DCC trans(CC:CONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000008 tid-8) rx CONNECT_ACK in state CONNECT_IND
+DCC trans(CC:CONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000008 tid-8) stopping pending timer T313
+DCC trans(CC:CONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000008 tid-8) new state CONNECT_IND -> ACTIVE
+DCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000008 tid-8) stopping pending guard timer
+DMNCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000008 tid-8) tx MNCC_SETUP_COMPL_IND
+ MSC --> MNCC: callref 0x80000008: MNCC_SETUP_COMPL_IND
+
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc)
+- VALIDATE_SDP OK: cc_to_mncc_tx_last_sdp == t->mo_tx_sdp_mncc_setup_compl_ind ==
+
+
+- RTP stream goes ahead, not shown here.
+- Total time passed: 1125.000819 s
+
+
+- Call ends
+ MSC <--GERAN-A-- MS: GSM48_MT_CC_DISCONNECT
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms)
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP
+DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_DISCONNECT
+DCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000008 tid-8) rx DISCONNECT in state ACTIVE
+DCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000008 tid-8) new state ACTIVE -> DISCONNECT_IND
+DMNCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000008 tid-8) tx MNCC_DISC_IND
+ MSC --> MNCC: callref 0x80000008: MNCC_DISC_IND
+
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc)
+ MSC <-- MNCC: callref 0x80000008: MNCC_REL_REQ
+v=0
+o=OsmoMSC 0 0 IN IP4 1.2.3.4
+s=GSM Call
+c=IN IP4 1.2.3.4
+t=0 0
+m=audio 56 RTP/AVP 3
+a=rtpmap:3 GSM/8000
+a=ptime:20
+
+DMNCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000008 tid-8) rx MNCC_REL_REQ
+DCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000008 tid-8) starting guard timer with 180 seconds
+DCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000008 tid-8) starting timer T308 with 10 seconds
+DCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000008 tid-8) new state DISCONNECT_IND -> RELEASE_REQ
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_RELEASE
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on GERAN-A
+- DTAP --GERAN-A--> MS: GSM48_MT_CC_RELEASE: 832d
+- DTAP matches expected message
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+ MSC <--GERAN-A-- MS: GSM48_MT_CC_RELEASE_COMPL
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms)
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP
+DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_RELEASE_COMPL
+DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000008 tid-8) rx RELEASE_COMPL in state RELEASE_REQ
+DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000008 tid-8) stopping pending timer T308
+DMNCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000008 tid-8) tx MNCC_REL_CNF
+ MSC --> MNCC: callref 0x80000008: MNCC_REL_CNF
+
+DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x0 tid-8) Freeing transaction
+DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x0 tid-8) new state RELEASE_REQ -> NULL
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x0 tid-8) stopping pending guard timer
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - CC: now used by 2 (attached,active-conn)
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - cc: now used by 1 (rx_from_ms)
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 0 (-)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Received Event MSC_A_EV_UNUSED
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: state_chg to MSC_A_ST_RELEASING
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: Releasing: msc_a use is 0 (-)
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + msc_a_fsm_releasing_onenter: now used by 3 (attached,active-conn,msc_a_fsm_releasing_onenter)
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,active-conn,msc_a_fsm_releasing_onenter,vlr_subscr_cancel_attach_fsm)
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,active-conn,msc_a_fsm_releasing_onenter)
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){ESTABLISHING}: state_chg to RELEASING
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-14:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-14:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Removing from parent call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-14:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Deallocated
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-14:RTP_TO_CN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-56){UNINITIALIZED}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-14:RTP_TO_CN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-56){UNINITIALIZED}: Removing from parent call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-14:RTP_TO_CN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-56){UNINITIALIZED}: Deallocated
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){RELEASING}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){RELEASING}: Removing from parent msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: Received Event MSC_EV_CALL_LEG_TERM
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){RELEASING}: Deallocated
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: + wait-Clear-Complete: now used by 1 (wait-Clear-Complete)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: RAN encode: CLEAR_COMMAND on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - msc_a_fsm_releasing_onenter: now used by 2 (attached,active-conn)
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: RAN decode: CLEAR_COMPLETE
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: - wait-Clear-Complete: now used by 0 (-)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: Received Event MSC_A_EV_UNUSED
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: state_chg to MSC_A_ST_RELEASED
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASED}: Released: msc_a use is 0 (-)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_DONE}: Terminating in cascade, depth 2 (cause = OSMO_FSM_TERM_PARENT, caused by: msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ))
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_DONE}: Removing from parent msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ)
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_DONE}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASED}: Removing from parent msub_fsm
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASED}: max total use count was 3
+DMSC msub_fsm{active}: Received Event MSUB_EV_ROLE_TERMINATED
+DMSC msub(IMSI-901700000010650:MSISDN-46071) MSC-A terminated
+DMSC msub(IMSI-901700000010650:MSISDN-46071) 1 MSC-I still active
+DMSC msub_fsm{active}: state_chg to terminating
+DMSC msub_fsm{terminating}: Terminating in cascade, depth 2 (cause = OSMO_FSM_TERM_REGULAR, caused by: msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ))
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Terminating in cascade, depth 3 (cause = OSMO_FSM_TERM_PARENT, caused by: msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ))
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Removing from parent msub_fsm
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ)
+DMSC msub(IMSI-901700000010650:MSISDN-46071) Free
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - active-conn: now used by 1 (attached)
+DMSC msub_fsm{terminating}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASED}: Deallocated, including all deferred deallocations
+- msub gone
+ llist_count(&msub_list) == 0
+
+
+- ======================== SUCCESS: MO call: FR1 picked by MT's MS Bearer Capability, hence MO re-assigns to FR1
+
+
+- ======================== MT call: FR1 picked by MT's MS Bearer Capability, hence MO re-assigns to FR1
+
+
+- MNCC asks us to setup a call, causing Paging
+ MSC <-- MNCC: callref 0x423: MNCC_SETUP_REQ
+v=0
+o=OsmoMSC 0 0 IN IP4 1.2.3.4
+s=GSM Call
+c=IN IP4 1.2.3.4
+t=0 0
+m=audio 56 RTP/AVP 112 110 3 111
+a=rtpmap:112 AMR/8000
+a=fmtp:112 octet-align=1
+a=rtpmap:110 GSM-EFR/8000
+a=rtpmap:3 GSM/8000
+a=rtpmap:111 GSM-HR-08/8000
+a=ptime:20
+
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + mncc_tx_to_gsm_cc: now used by 2 (attached,mncc_tx_to_gsm_cc)
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + CC: now used by 3 (attached,mncc_tx_to_gsm_cc,CC)
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071 callref-0x423 tid-255) New transaction
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071 callref-0x423 tid-255) codecs: :0{(no-codecs)} (from: remote=1.2.3.4:56{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} RAN={(no-codecs)})
+DMNCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071 callref-0x423 tid-255) rx MNCC_SETUP_REQ (RTP=1.2.3.4:56{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+DPAG Paging: IMSI-901700000010650:MSISDN-46071 for MNCC: establish call: Starting paging
+ paging request (CALL_CONVERSATIONAL) to IMSI-901700000010650:MSISDN-46071 on GERAN-A
+ strcmp(paging_expecting_imsi, vsub->imsi) == 0
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + Paging: now used by 4 (attached,mncc_tx_to_gsm_cc,CC,Paging)
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - mncc_tx_to_gsm_cc: now used by 3 (attached,CC,Paging)
+ paging_sent == 1
+- MS replies with Paging Response, with Codec List (BSS Supported) = FR1 FR2 FR3 HR1 HR3
+- VLR accepts, MSC sends CC Setup with Bearer Capability = AMR AMR AMR GSM-EFR GSM GSM-HR-08
+ MSC <--GERAN-A-- MS: GSM48_MT_RR_PAG_RESP
+ new conn
+DMSC msub_fsm{active}: Allocated
+DMSC msc_a{MSC_A_ST_VALIDATE_L3}: Allocated
+DMSC msc_a{MSC_A_ST_VALIDATE_L3}: is child of msub_fsm
+DMSC msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_VALIDATE_L3
+DMSC dummy_msc_i{0}: Allocated
+DMSC dummy_msc_i{0}: is child of msub_fsm
+DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms)
+DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3
+DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Complete Layer 3: Codec List (BSS Supported): GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111
+DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: RR GSM48_MT_RR_PAG_RESP
+DRR msc_a(IMSI-901700000010650:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: Rx PAGING RESPONSE IMSI-901700000010650
+DREF msc_a(IMSI-901700000010650:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: + paging-response: now used by 2 (rx_from_ms,paging-response)
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: Allocated
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: is child of msc_a(IMSI-901700000010650:GERAN-A:PAGING_RESP)
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: rev=R99 net=GERAN (no Auth)
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + proc_arq_vlr_fn_init: now used by 4 (attached,CC,Paging,proc_arq_vlr_fn_init)
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + active-conn: now used by 5 (attached,CC,Paging,proc_arq_vlr_fn_init,active-conn)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi()
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_node2()
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_ciph()
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_vlr()
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_post_pres()
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_post_trace()
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_post_imei()
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: proc_arq_fsm_done(PASSED)
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_DONE
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_DONE}: Process Access Request result: PASSED
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: Received Event MSC_A_EV_AUTHENTICATED
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: state_chg to MSC_A_ST_AUTHENTICATED
+DPAG Paging: IMSI-901700000010650:MSISDN-46071 for MNCC: establish call: Paging Response action (success)
+DPAG Paging: IMSI-901700000010650:MSISDN-46071 for MNCC: establish call: Removing Paging Request
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071 callref-0x423 tid-255) Paging succeeded
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: + cc: now used by 3 (rx_from_ms,paging-response,cc)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: Received Event MSC_A_EV_TRANSACTION_ACCEPTED
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: state_chg to MSC_A_ST_COMMUNICATING
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) starting timer T303 with 30 seconds
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) codecs: :0{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} (from: remote=1.2.3.4:56{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) new state NULL -> CALL_PRESENT
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_SETUP
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on GERAN-A
+- DTAP --GERAN-A--> MS: GSM48_MT_CC_SETUP: 030504076004050b020081
+- DTAP matches expected message
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - Paging: now used by 4 (attached,CC,proc_arq_vlr_fn_init,active-conn)
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - paging-response: now used by 2 (rx_from_ms,cc)
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - proc_arq_vlr_fn_init: now used by 3 (attached,CC,active-conn)
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc)
+- MS confirms call, we create a RAN-side RTP and forward MNCC_CALL_CONF_IND
+ MSC <--GERAN-A-- MS: GSM48_MT_CC_CALL_CONF
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms)
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP
+DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_CALL_CONF
+DCC trans(CC:CALL_PRESENT IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx CALL_CONF in state CALL_PRESENT
+DCC trans(CC:CALL_PRESENT IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) stopping pending timer T303
+DCC trans(CC:CALL_PRESENT IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) starting timer T310 with 30 seconds
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Starting call assignment
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){ESTABLISHING}: Allocated
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){ESTABLISHING}: is child of msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP)
+DCC trans(CC:CALL_PRESENT IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) codecs: :0{GSM#3} (from: remote=1.2.3.4:56{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} MS={GSM#3} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+ MGW <--CRCX to RTP_TO_CN-- MSC: call_id=0xf codecs=GSM#3
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){UNINITIALIZED}: Allocated
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){UNINITIALIZED}: is child of call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-15:RTP_TO_CN:no-CI){UNINITIALIZED}: setting codecs to GSM#3
+ MGW <--CRCX to RTP_TO_RAN-- MSC: call_id=0xf codecs=GSM#3
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){UNINITIALIZED}: Allocated
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){UNINITIALIZED}: is child of call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-15:RTP_TO_RAN:no-CI){UNINITIALIZED}: setting codecs to GSM#3
+DCC trans(CC:CALL_PRESENT IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) new state CALL_PRESENT -> MO_TERM_CALL_CONF
+DMNCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) tx MNCC_CALL_CONF_IND
+ MSC --> MNCC: callref 0x423: MNCC_CALL_CONF_IND
+
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc)
+- VALIDATE_SDP OK: cc_to_mncc_tx_last_sdp == t->mt_tx_sdp_mncc_call_conf_ind ==
+- MGW acknowledges the CRCX to RAN, triggering Assignment with FR1
+ MGW --CRCX OK to RTP_TO_RAN--> MSC
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){ESTABLISHING}: Received Event CALL_LEG_EV_RTP_STREAM_ADDR_AVAILABLE
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Received Event MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: MGW endpoint's RTP address available for the CI RTP_TO_RAN: 10.23.23.1:23 (osmux=no:-2)
+DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) codecs: :0{GSM#3} (from: remote=1.2.3.4:56{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} MS={GSM#3} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) Sending Assignment Command
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN encode: ASSIGNMENT_COMMAND on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+- VALIDATE_PERM_SPEECH OK: &bssap_assignment_command_last_channel_type == t->mt_tx_assignment_perm_speech == FR1
+- Assignment completes, triggering CRCX to CN
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN decode: ASSIGNMENT_COMPLETE
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-15:RTP_TO_RAN:no-CI){UNINITIALIZED}: no change: codecs already set to GSM#3
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-15:RTP_TO_RAN:no-CI){UNINITIALIZED}: setting remote addr to 1.2.3.4:1234
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-15:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Not committing: no MGW endpoint CI set up
+DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) codecs: :0{GSM#3} (from: assigned=GSM#3 remote=1.2.3.4:56{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} MS={GSM#3} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) Assignment Complete: RAN: GSM#3, CN: GSM#3
+DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) Assignment complete, but still waiting for the CRCX OK on the CN side RTP
+- MNCC sends MNCC_RTP_CREATE, which first waits for the CN side RTP
+ MSC <-- MNCC: callref 0x423: MNCC_RTP_CREATE
+
+DMNCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx MNCC_RTP_CREATE
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Assignment for this trans already started earlier
+- When the CN side RTP address is known, ack MNCC_RTP_CREATE
+ MGW --CRCX OK to RTP_TO_CN--> MSC
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){ESTABLISHING}: Received Event CALL_LEG_EV_RTP_STREAM_ADDR_AVAILABLE
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Received Event MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: MGW endpoint's RTP address available for the CI RTP_TO_CN: 10.23.23.1:23 (osmux=no:-2)
+DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) codecs: 10.23.23.1:23{GSM#3} (from: assigned=GSM#3 remote=1.2.3.4:56{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} MS={GSM#3} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+DMNCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) tx MNCC_RTP_CREATE (RTP=10.23.23.1:23{GSM#3})
+ MSC --> MNCC: callref 0x423: MNCC_RTP_CREATE
+v=0
+o=OsmoMSC 0 0 IN IP4 10.23.23.1
+s=GSM Call
+c=IN IP4 10.23.23.1
+t=0 0
+m=audio 23 RTP/AVP 3
+a=rtpmap:3 GSM/8000
+a=ptime:20
+
+- VALIDATE_SDP OK: cc_to_mncc_tx_last_sdp == t->mt_tx_sdp_mncc_rtp_create == GSM
+- Total time passed: 1126.000842 s
+ MSC <--GERAN-A-- MS: GSM48_MT_CC_ALERTING
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms)
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP
+DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_ALERTING
+DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx ALERTING in state MO_TERM_CALL_CONF
+DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) stopping pending timer T310
+DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) starting timer T301 with 180 seconds
+DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) new state MO_TERM_CALL_CONF -> CALL_RECEIVED
+DCC trans(CC:CALL_RECEIVED IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) codecs: 10.23.23.1:23{GSM#3} (from: assigned=GSM#3 remote=1.2.3.4:56{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} MS={GSM#3} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+DMNCC trans(CC:CALL_RECEIVED IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) tx MNCC_ALERT_IND (RTP=10.23.23.1:23{GSM#3})
+ MSC --> MNCC: callref 0x423: MNCC_ALERT_IND
+v=0
+o=OsmoMSC 0 0 IN IP4 10.23.23.1
+s=GSM Call
+c=IN IP4 10.23.23.1
+t=0 0
+m=audio 23 RTP/AVP 3
+a=rtpmap:3 GSM/8000
+a=ptime:20
+
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc)
+- VALIDATE_SDP OK: cc_to_mncc_tx_last_sdp == t->mt_tx_sdp_mncc_alert_ind == GSM
+- Total time passed: 1127.000865 s
+ MSC <--GERAN-A-- MS: GSM48_MT_CC_CONNECT
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms)
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP
+DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_CONNECT
+DCC trans(CC:CALL_RECEIVED IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx CONNECT in state CALL_RECEIVED
+DCC trans(CC:CALL_RECEIVED IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) stopping pending timer T301
+DCC trans(CC:CALL_RECEIVED IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) new state CALL_RECEIVED -> CONNECT_REQUEST
+DCC trans(CC:CONNECT_REQUEST IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) codecs: 10.23.23.1:23{GSM#3} (from: assigned=GSM#3 remote=1.2.3.4:56{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} MS={GSM#3} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+DMNCC trans(CC:CONNECT_REQUEST IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) tx MNCC_SETUP_CNF (RTP=10.23.23.1:23{GSM#3})
+ MSC --> MNCC: callref 0x423: MNCC_SETUP_CNF
+v=0
+o=OsmoMSC 0 0 IN IP4 10.23.23.1
+s=GSM Call
+c=IN IP4 10.23.23.1
+t=0 0
+m=audio 23 RTP/AVP 3
+a=rtpmap:3 GSM/8000
+a=ptime:20
+
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc)
+- VALIDATE_SDP OK: cc_to_mncc_tx_last_sdp == t->mt_tx_sdp_mncc_setup_cnf == GSM
+ MSC <-- MNCC: callref 0x423: MNCC_SETUP_COMPL_REQ
+
+DMNCC trans(CC:CONNECT_REQUEST IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx MNCC_SETUP_COMPL_REQ
+DCC trans(CC:CONNECT_REQUEST IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) starting guard timer with 180 seconds
+DCC trans(CC:CONNECT_REQUEST IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) new state CONNECT_REQUEST -> ACTIVE
+DCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) stopping pending guard timer
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_CONNECT_ACK
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on GERAN-A
+- DTAP --GERAN-A--> MS: GSM48_MT_CC_CONNECT_ACK: 030f
+- DTAP matches expected message
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+
+
+- RTP stream goes ahead, not shown here.
+- Total time passed: 1250.000910 s
+
+
+- Call ends
+ MSC <--GERAN-A-- MS: GSM48_MT_CC_DISCONNECT
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms)
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP
+DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_DISCONNECT
+DCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx DISCONNECT in state ACTIVE
+DCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) new state ACTIVE -> DISCONNECT_IND
+DMNCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) tx MNCC_DISC_IND
+ MSC --> MNCC: callref 0x423: MNCC_DISC_IND
+
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc)
+ MSC <-- MNCC: callref 0x423: MNCC_REL_REQ
+
+DMNCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx MNCC_REL_REQ
+DCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) starting guard timer with 180 seconds
+DCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) starting timer T308 with 10 seconds
+DCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) new state DISCONNECT_IND -> RELEASE_REQ
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_RELEASE
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on GERAN-A
+- DTAP --GERAN-A--> MS: GSM48_MT_CC_RELEASE: 032d
+- DTAP matches expected message
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+ MSC <--GERAN-A-- MS: GSM48_MT_CC_RELEASE_COMPL
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms)
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP
+DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_RELEASE_COMPL
+DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx RELEASE_COMPL in state RELEASE_REQ
+DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) stopping pending timer T308
+DMNCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) tx MNCC_REL_CNF
+ MSC --> MNCC: callref 0x423: MNCC_REL_CNF
+
+DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x0 tid-0) Freeing transaction
+DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x0 tid-0) new state RELEASE_REQ -> NULL
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x0 tid-0) stopping pending guard timer
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - CC: now used by 2 (attached,active-conn)
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - cc: now used by 1 (rx_from_ms)
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 0 (-)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Received Event MSC_A_EV_UNUSED
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: state_chg to MSC_A_ST_RELEASING
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: Releasing: msc_a use is 0 (-)
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + msc_a_fsm_releasing_onenter: now used by 3 (attached,active-conn,msc_a_fsm_releasing_onenter)
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,active-conn,msc_a_fsm_releasing_onenter,vlr_subscr_cancel_attach_fsm)
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,active-conn,msc_a_fsm_releasing_onenter)
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){ESTABLISHING}: state_chg to RELEASING
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-15:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-15:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Removing from parent call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-15:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Deallocated
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-15:RTP_TO_CN:no-CI){UNINITIALIZED}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-15:RTP_TO_CN:no-CI){UNINITIALIZED}: Removing from parent call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-15:RTP_TO_CN:no-CI){UNINITIALIZED}: Deallocated
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){RELEASING}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){RELEASING}: Removing from parent msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: Received Event MSC_EV_CALL_LEG_TERM
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){RELEASING}: Deallocated
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: + wait-Clear-Complete: now used by 1 (wait-Clear-Complete)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: RAN encode: CLEAR_COMMAND on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - msc_a_fsm_releasing_onenter: now used by 2 (attached,active-conn)
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: RAN decode: CLEAR_COMPLETE
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: - wait-Clear-Complete: now used by 0 (-)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: Received Event MSC_A_EV_UNUSED
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: state_chg to MSC_A_ST_RELEASED
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASED}: Released: msc_a use is 0 (-)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_DONE}: Terminating in cascade, depth 2 (cause = OSMO_FSM_TERM_PARENT, caused by: msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP))
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_DONE}: Removing from parent msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP)
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_DONE}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASED}: Removing from parent msub_fsm
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASED}: max total use count was 3
+DMSC msub_fsm{active}: Received Event MSUB_EV_ROLE_TERMINATED
+DMSC msub(IMSI-901700000010650:MSISDN-46071) MSC-A terminated
+DMSC msub(IMSI-901700000010650:MSISDN-46071) 1 MSC-I still active
+DMSC msub_fsm{active}: state_chg to terminating
+DMSC msub_fsm{terminating}: Terminating in cascade, depth 2 (cause = OSMO_FSM_TERM_REGULAR, caused by: msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP))
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Terminating in cascade, depth 3 (cause = OSMO_FSM_TERM_PARENT, caused by: msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP))
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Removing from parent msub_fsm
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP)
+DMSC msub(IMSI-901700000010650:MSISDN-46071) Free
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - active-conn: now used by 1 (attached)
+DMSC msub_fsm{terminating}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASED}: Deallocated, including all deferred deallocations
+- msub gone
+ llist_count(&msub_list) == 0
+
+
+- ======================== SUCCESS: MT call: FR1 picked by MT's MS Bearer Capability, hence MO re-assigns to FR1
+
+
+- ======================== MO call: AMR picked by both MO and MT, but MT assigns a different payload type number
+- CM Service Request with Codec List (BSS Supported) = FR1 FR2 FR3 HR1 HR3
+ MSC <--GERAN-A-- MS: GSM48_MT_MM_CM_SERV_REQ
+ new conn
+DMSC msub_fsm{active}: Allocated
+DMSC msc_a{MSC_A_ST_VALIDATE_L3}: Allocated
+DMSC msc_a{MSC_A_ST_VALIDATE_L3}: is child of msub_fsm
+DMSC msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_VALIDATE_L3
+DMSC dummy_msc_i{0}: Allocated
+DMSC dummy_msc_i{0}: is child of msub_fsm
+DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms)
+DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3
+DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Complete Layer 3: Codec List (BSS Supported): GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111
+DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: MM GSM48_MT_MM_CM_SERV_REQ
+DMM msc_a(IMSI-901700000010650:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_VALIDATE_L3}: Rx CM SERVICE REQUEST cm_service_type=MO-Call
+DREF msc_a(IMSI-901700000010650:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_VALIDATE_L3}: + cm_service_cc: now used by 2 (rx_from_ms,cm_service_cc)
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: Allocated
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: is child of msc_a(IMSI-901700000010650:GERAN-A:CM_SERVICE_REQ)
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: rev=R99 net=GERAN (no Auth)
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + proc_arq_vlr_fn_init: now used by 2 (attached,proc_arq_vlr_fn_init)
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + active-conn: now used by 3 (attached,proc_arq_vlr_fn_init,active-conn)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi()
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_node2()
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_ciph()
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_vlr()
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_post_pres()
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_post_trace()
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_post_imei()
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: proc_arq_fsm_done(PASSED)
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_DONE
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_DONE}: Process Access Request result: PASSED
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: Sending DTAP: MM GSM48_MT_MM_CM_SERV_ACC
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN encode: DTAP on GERAN-A
+- DTAP --GERAN-A--> MS: GSM48_MT_MM_CM_SERV_ACC: 0521
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: Received Event MSC_A_EV_AUTHENTICATED
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: state_chg to MSC_A_ST_AUTHENTICATED
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - proc_arq_vlr_fn_init: now used by 2 (attached,active-conn)
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: - rx_from_ms: now used by 1 (cm_service_cc)
+ cm_service_result_sent == 1
+msc_a_is_accepted() == true
+- MS sends CC SETUP with Bearer Capability = AMR AMR AMR GSM-EFR GSM GSM-HR-08
+ MSC <--GERAN-A-- MS: GSM48_MT_CC_SETUP
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: + rx_from_ms: now used by 2 (cm_service_cc,rx_from_ms)
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: RAN decode: DTAP
+DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: Dispatching 04.08 message: CC GSM48_MT_CC_SETUP
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + CC: now used by 3 (attached,active-conn,CC)
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071 callref-0x80000009 tid-8) New transaction
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: Received Event MSC_A_EV_TRANSACTION_ACCEPTED
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: state_chg to MSC_A_ST_COMMUNICATING
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: + cc: now used by 3 (cm_service_cc,rx_from_ms,cc)
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - cm_service_cc: now used by 2 (rx_from_ms,cc)
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000009 tid-8) rx SETUP in state NULL
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000009 tid-8) starting guard timer with 180 seconds
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000009 tid-8) codecs: :0{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} (from: MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000009 tid-8) SETUP to 123
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000009 tid-8) new state NULL -> INITIATED
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Starting call assignment
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){ESTABLISHING}: Allocated
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){ESTABLISHING}: is child of msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ)
+DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000009 tid-8) codecs: :0{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} (from: MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+ MGW <--CRCX to RTP_TO_CN-- MSC: call_id=0x10 codecs=AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){UNINITIALIZED}: Allocated
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){UNINITIALIZED}: is child of call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-16:RTP_TO_CN:no-CI){UNINITIALIZED}: setting codecs to AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111
+ MGW <--CRCX to RTP_TO_RAN-- MSC: call_id=0x10 codecs=AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){UNINITIALIZED}: Allocated
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){UNINITIALIZED}: is child of call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-16:RTP_TO_RAN:no-CI){UNINITIALIZED}: setting codecs to AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc)
+- As soon as the MGW port towards CN is created, MNCC_SETUP_IND is triggered
+ MGW --CRCX OK to RTP_TO_CN--> MSC
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){ESTABLISHING}: Received Event CALL_LEG_EV_RTP_STREAM_ADDR_AVAILABLE
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Received Event MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: MGW endpoint's RTP address available for the CI RTP_TO_CN: 10.23.23.1:23 (osmux=no:-2)
+DMNCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000009 tid-8) tx MNCC_SETUP_IND (RTP=10.23.23.1:23{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+ MSC --> MNCC: callref 0x80000009: MNCC_SETUP_IND
+v=0
+o=OsmoMSC 0 0 IN IP4 10.23.23.1
+s=GSM Call
+c=IN IP4 10.23.23.1
+t=0 0
+m=audio 23 RTP/AVP 112 110 3 111
+a=rtpmap:112 AMR/8000
+a=fmtp:112 octet-align=1
+a=rtpmap:110 GSM-EFR/8000
+a=rtpmap:3 GSM/8000
+a=rtpmap:111 GSM-HR-08/8000
+a=ptime:20
+
+- VALIDATE_SDP OK: cc_to_mncc_tx_last_sdp == t->mo_tx_sdp_mncc_setup_ind == AMR GSM-EFR GSM GSM-HR-08
+- MNCC replies with MNCC_RTP_CREATE
+ MSC <-- MNCC: callref 0x80000009: MNCC_RTP_CREATE
+
+DMNCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000009 tid-8) rx MNCC_RTP_CREATE
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Assignment for this trans already started earlier
+- MGW acknowledges the CRCX, triggering Assignment with FR3 HR3 FR2 FR1 HR1
+ MGW --CRCX OK to RTP_TO_RAN--> MSC
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){ESTABLISHING}: Received Event CALL_LEG_EV_RTP_STREAM_ADDR_AVAILABLE
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Received Event MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: MGW endpoint's RTP address available for the CI RTP_TO_RAN: 10.23.23.1:23 (osmux=no:-2)
+DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000009 tid-8) codecs: 10.23.23.1:23{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} (from: MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000009 tid-8) Sending Assignment Command
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN encode: ASSIGNMENT_COMMAND on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+- VALIDATE_PERM_SPEECH OK: &bssap_assignment_command_last_channel_type == t->mo_tx_assignment_perm_speech == FR3 HR3 FR2 FR1 HR1
+- Assignment succeeds, triggering MNCC_RTP_CREATE ack to MNCC
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN decode: ASSIGNMENT_COMPLETE
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-16:RTP_TO_RAN:no-CI){UNINITIALIZED}: setting codecs to AMR:octet-align=1#112
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-16:RTP_TO_RAN:no-CI:local-10-23-23-1-23){UNINITIALIZED}: setting remote addr to 1.2.3.4:1234
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-16:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Not committing: no MGW endpoint CI set up
+DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000009 tid-8) codecs: 10.23.23.1:23{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} (from: assigned=AMR:octet-align=1#112 MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000009 tid-8) Assignment Complete: RAN: AMR:octet-align=1#112, CN: AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111
+DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000009 tid-8) codecs: 10.23.23.1:23{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} (from: assigned=AMR:octet-align=1#112 MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+DMNCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000009 tid-8) tx MNCC_RTP_CREATE (RTP=10.23.23.1:23{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+ MSC --> MNCC: callref 0x80000009: MNCC_RTP_CREATE
+v=0
+o=OsmoMSC 0 0 IN IP4 10.23.23.1
+s=GSM Call
+c=IN IP4 10.23.23.1
+t=0 0
+m=audio 23 RTP/AVP 112 110 3 111
+a=rtpmap:112 AMR/8000
+a=fmtp:112 octet-align=1
+a=rtpmap:110 GSM-EFR/8000
+a=rtpmap:3 GSM/8000
+a=rtpmap:111 GSM-HR-08/8000
+a=ptime:20
+
+- VALIDATE_SDP OK: cc_to_mncc_tx_last_sdp == t->mo_tx_sdp_mncc_rtp_create == AMR GSM-EFR GSM GSM-HR-08
+- MNCC says that's fine
+ MSC <-- MNCC: callref 0x80000009: MNCC_CALL_PROC_REQ
+
+DMNCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000009 tid-8) rx MNCC_CALL_PROC_REQ
+DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000009 tid-8) stopping pending guard timer
+DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000009 tid-8) starting guard timer with 180 seconds
+DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000009 tid-8) new state INITIATED -> MO_CALL_PROC
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_CALL_PROC
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on GERAN-A
+- DTAP --GERAN-A--> MS: GSM48_MT_CC_CALL_PROC: 8302
+- DTAP matches expected message
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Assignment for this trans already started earlier
+- Total time passed: 1251.000933 s
+- The other call leg got established (not shown here), MNCC tells us so, with codecs { AMR#96 GSM-EFR GSM GSM-HR-08 }
+ MSC <-- MNCC: callref 0x80000009: MNCC_ALERT_REQ
+v=0
+o=OsmoMSC 0 0 IN IP4 1.2.3.4
+s=GSM Call
+c=IN IP4 1.2.3.4
+t=0 0
+m=audio 56 RTP/AVP 96 110 3 111
+a=rtpmap:96 AMR/8000
+a=fmtp:96 octet-align=1
+a=rtpmap:110 GSM-EFR/8000
+a=rtpmap:3 GSM/8000
+a=rtpmap:111 GSM-HR-08/8000
+a=ptime:20
+
+DMNCC trans(CC:MO_CALL_PROC IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000009 tid-8) rx MNCC_ALERT_REQ (RTP=1.2.3.4:56{AMR:octet-align=1#96,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+DCC trans(CC:MO_CALL_PROC IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000009 tid-8) stopping pending guard timer
+DCC trans(CC:MO_CALL_PROC IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000009 tid-8) starting guard timer with 180 seconds
+DCC trans(CC:MO_CALL_PROC IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000009 tid-8) new state MO_CALL_PROC -> CALL_DELIVERED
+DCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000009 tid-8) codecs: 10.23.23.1:23{AMR:octet-align=1#96,GSM-EFR#110,GSM#3,GSM-HR-08#111} (from: assigned=AMR:octet-align=1#112 remote=1.2.3.4:56{AMR:octet-align=1#96,GSM-EFR#110,GSM#3,GSM-HR-08#111} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-16:RTP_TO_CN:no-CI){UNINITIALIZED}: setting codecs to AMR:octet-align=1#96,GSM-EFR#110,GSM#3,GSM-HR-08#111
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-16:RTP_TO_CN:no-CI:local-10-23-23-1-23){UNINITIALIZED}: setting remote addr to 1.2.3.4:56
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-16:RTP_TO_CN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-56){UNINITIALIZED}: Not committing: no MGW endpoint CI set up
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_ALERTING
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on GERAN-A
+- DTAP --GERAN-A--> MS: GSM48_MT_CC_ALERTING: 8301
+- DTAP matches expected message
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+ MSC <-- MNCC: callref 0x80000009: MNCC_SETUP_RSP
+v=0
+o=OsmoMSC 0 0 IN IP4 1.2.3.4
+s=GSM Call
+c=IN IP4 1.2.3.4
+t=0 0
+m=audio 56 RTP/AVP 96 110 3 111
+a=rtpmap:96 AMR/8000
+a=fmtp:96 octet-align=1
+a=rtpmap:110 GSM-EFR/8000
+a=rtpmap:3 GSM/8000
+a=rtpmap:111 GSM-HR-08/8000
+a=ptime:20
+
+DMNCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000009 tid-8) rx MNCC_SETUP_RSP (RTP=1.2.3.4:56{AMR:octet-align=1#96,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+DCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000009 tid-8) stopping pending guard timer
+DCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000009 tid-8) starting guard timer with 180 seconds
+DCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000009 tid-8) starting timer T313 with 30 seconds
+DCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000009 tid-8) new state CALL_DELIVERED -> CONNECT_IND
+DCC trans(CC:CONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000009 tid-8) codecs: 10.23.23.1:23{AMR:octet-align=1#96,GSM-EFR#110,GSM#3,GSM-HR-08#111} (from: assigned=AMR:octet-align=1#112 remote=1.2.3.4:56{AMR:octet-align=1#96,GSM-EFR#110,GSM#3,GSM-HR-08#111} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-16:RTP_TO_CN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-56){UNINITIALIZED}: no change: codecs already set to AMR:octet-align=1#96,GSM-EFR#110,GSM#3,GSM-HR-08#111
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-16:RTP_TO_CN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-56){UNINITIALIZED}: remote addr already 1.2.3.4:56, no change
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-16:RTP_TO_CN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-56){UNINITIALIZED}: Not committing: no MGW endpoint CI set up
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_CONNECT
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on GERAN-A
+- DTAP --GERAN-A--> MS: GSM48_MT_CC_CONNECT: 8307
+- DTAP matches expected message
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+- Total time passed: 1252.000956 s
+ MSC <--GERAN-A-- MS: GSM48_MT_CC_CONNECT_ACK
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms)
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP
+DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_CONNECT_ACK
+DCC trans(CC:CONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000009 tid-8) rx CONNECT_ACK in state CONNECT_IND
+DCC trans(CC:CONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000009 tid-8) stopping pending timer T313
+DCC trans(CC:CONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000009 tid-8) new state CONNECT_IND -> ACTIVE
+DCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000009 tid-8) stopping pending guard timer
+DMNCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000009 tid-8) tx MNCC_SETUP_COMPL_IND
+ MSC --> MNCC: callref 0x80000009: MNCC_SETUP_COMPL_IND
+
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc)
+- VALIDATE_SDP OK: cc_to_mncc_tx_last_sdp == t->mo_tx_sdp_mncc_setup_compl_ind ==
+
+
+- RTP stream goes ahead, not shown here.
+- Total time passed: 1375.001001 s
+
+
+- Call ends
+ MSC <--GERAN-A-- MS: GSM48_MT_CC_DISCONNECT
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms)
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP
+DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_DISCONNECT
+DCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000009 tid-8) rx DISCONNECT in state ACTIVE
+DCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000009 tid-8) new state ACTIVE -> DISCONNECT_IND
+DMNCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000009 tid-8) tx MNCC_DISC_IND
+ MSC --> MNCC: callref 0x80000009: MNCC_DISC_IND
+
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc)
+ MSC <-- MNCC: callref 0x80000009: MNCC_REL_REQ
+v=0
+o=OsmoMSC 0 0 IN IP4 1.2.3.4
+s=GSM Call
+c=IN IP4 1.2.3.4
+t=0 0
+m=audio 56 RTP/AVP 96 110 3 111
+a=rtpmap:96 AMR/8000
+a=fmtp:96 octet-align=1
+a=rtpmap:110 GSM-EFR/8000
+a=rtpmap:3 GSM/8000
+a=rtpmap:111 GSM-HR-08/8000
+a=ptime:20
+
+DMNCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000009 tid-8) rx MNCC_REL_REQ
+DCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000009 tid-8) starting guard timer with 180 seconds
+DCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000009 tid-8) starting timer T308 with 10 seconds
+DCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000009 tid-8) new state DISCONNECT_IND -> RELEASE_REQ
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_RELEASE
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on GERAN-A
+- DTAP --GERAN-A--> MS: GSM48_MT_CC_RELEASE: 832d
+- DTAP matches expected message
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+ MSC <--GERAN-A-- MS: GSM48_MT_CC_RELEASE_COMPL
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms)
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP
+DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_RELEASE_COMPL
+DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000009 tid-8) rx RELEASE_COMPL in state RELEASE_REQ
+DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000009 tid-8) stopping pending timer T308
+DMNCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x80000009 tid-8) tx MNCC_REL_CNF
+ MSC --> MNCC: callref 0x80000009: MNCC_REL_CNF
+
+DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x0 tid-8) Freeing transaction
+DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x0 tid-8) new state RELEASE_REQ -> NULL
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x0 tid-8) stopping pending guard timer
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - CC: now used by 2 (attached,active-conn)
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - cc: now used by 1 (rx_from_ms)
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 0 (-)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Received Event MSC_A_EV_UNUSED
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: state_chg to MSC_A_ST_RELEASING
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: Releasing: msc_a use is 0 (-)
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + msc_a_fsm_releasing_onenter: now used by 3 (attached,active-conn,msc_a_fsm_releasing_onenter)
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,active-conn,msc_a_fsm_releasing_onenter,vlr_subscr_cancel_attach_fsm)
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,active-conn,msc_a_fsm_releasing_onenter)
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){ESTABLISHING}: state_chg to RELEASING
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-16:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-16:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Removing from parent call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-16:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Deallocated
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-16:RTP_TO_CN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-56){UNINITIALIZED}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-16:RTP_TO_CN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-56){UNINITIALIZED}: Removing from parent call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-16:RTP_TO_CN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-56){UNINITIALIZED}: Deallocated
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){RELEASING}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){RELEASING}: Removing from parent msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: Received Event MSC_EV_CALL_LEG_TERM
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){RELEASING}: Deallocated
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: + wait-Clear-Complete: now used by 1 (wait-Clear-Complete)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: RAN encode: CLEAR_COMMAND on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - msc_a_fsm_releasing_onenter: now used by 2 (attached,active-conn)
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: RAN decode: CLEAR_COMPLETE
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: - wait-Clear-Complete: now used by 0 (-)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: Received Event MSC_A_EV_UNUSED
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: state_chg to MSC_A_ST_RELEASED
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASED}: Released: msc_a use is 0 (-)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_DONE}: Terminating in cascade, depth 2 (cause = OSMO_FSM_TERM_PARENT, caused by: msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ))
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_DONE}: Removing from parent msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ)
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_DONE}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASED}: Removing from parent msub_fsm
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASED}: max total use count was 3
+DMSC msub_fsm{active}: Received Event MSUB_EV_ROLE_TERMINATED
+DMSC msub(IMSI-901700000010650:MSISDN-46071) MSC-A terminated
+DMSC msub(IMSI-901700000010650:MSISDN-46071) 1 MSC-I still active
+DMSC msub_fsm{active}: state_chg to terminating
+DMSC msub_fsm{terminating}: Terminating in cascade, depth 2 (cause = OSMO_FSM_TERM_REGULAR, caused by: msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ))
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Terminating in cascade, depth 3 (cause = OSMO_FSM_TERM_PARENT, caused by: msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ))
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Removing from parent msub_fsm
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ)
+DMSC msub(IMSI-901700000010650:MSISDN-46071) Free
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - active-conn: now used by 1 (attached)
+DMSC msub_fsm{terminating}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASED}: Deallocated, including all deferred deallocations
+- msub gone
+ llist_count(&msub_list) == 0
+
+
+- ======================== SUCCESS: MO call: AMR picked by both MO and MT, but MT assigns a different payload type number
+
+
+- ======================== MT call: AMR picked by both MO and MT, but MT assigns a different payload type number
+
+
+- MNCC asks us to setup a call, causing Paging
+ MSC <-- MNCC: callref 0x423: MNCC_SETUP_REQ
+v=0
+o=OsmoMSC 0 0 IN IP4 1.2.3.4
+s=GSM Call
+c=IN IP4 1.2.3.4
+t=0 0
+m=audio 56 RTP/AVP 112 110 3 111
+a=rtpmap:112 AMR/8000
+a=fmtp:112 octet-align=1
+a=rtpmap:110 GSM-EFR/8000
+a=rtpmap:3 GSM/8000
+a=rtpmap:111 GSM-HR-08/8000
+a=ptime:20
+
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + mncc_tx_to_gsm_cc: now used by 2 (attached,mncc_tx_to_gsm_cc)
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + CC: now used by 3 (attached,mncc_tx_to_gsm_cc,CC)
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071 callref-0x423 tid-255) New transaction
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071 callref-0x423 tid-255) codecs: :0{(no-codecs)} (from: remote=1.2.3.4:56{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} RAN={(no-codecs)})
+DMNCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071 callref-0x423 tid-255) rx MNCC_SETUP_REQ (RTP=1.2.3.4:56{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+DPAG Paging: IMSI-901700000010650:MSISDN-46071 for MNCC: establish call: Starting paging
+ paging request (CALL_CONVERSATIONAL) to IMSI-901700000010650:MSISDN-46071 on GERAN-A
+ strcmp(paging_expecting_imsi, vsub->imsi) == 0
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + Paging: now used by 4 (attached,mncc_tx_to_gsm_cc,CC,Paging)
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - mncc_tx_to_gsm_cc: now used by 3 (attached,CC,Paging)
+ paging_sent == 1
+- MS replies with Paging Response, with Codec List (BSS Supported) = FR1 FR2 FR3 HR1 HR3
+- VLR accepts, MSC sends CC Setup with Bearer Capability = AMR AMR AMR GSM-EFR GSM GSM-HR-08
+ MSC <--GERAN-A-- MS: GSM48_MT_RR_PAG_RESP
+ new conn
+DMSC msub_fsm{active}: Allocated
+DMSC msc_a{MSC_A_ST_VALIDATE_L3}: Allocated
+DMSC msc_a{MSC_A_ST_VALIDATE_L3}: is child of msub_fsm
+DMSC msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_VALIDATE_L3
+DMSC dummy_msc_i{0}: Allocated
+DMSC dummy_msc_i{0}: is child of msub_fsm
+DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms)
+DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3
+DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Complete Layer 3: Codec List (BSS Supported): GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111
+DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: RR GSM48_MT_RR_PAG_RESP
+DRR msc_a(IMSI-901700000010650:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: Rx PAGING RESPONSE IMSI-901700000010650
+DREF msc_a(IMSI-901700000010650:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: + paging-response: now used by 2 (rx_from_ms,paging-response)
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: Allocated
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: is child of msc_a(IMSI-901700000010650:GERAN-A:PAGING_RESP)
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: rev=R99 net=GERAN (no Auth)
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + proc_arq_vlr_fn_init: now used by 4 (attached,CC,Paging,proc_arq_vlr_fn_init)
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + active-conn: now used by 5 (attached,CC,Paging,proc_arq_vlr_fn_init,active-conn)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi()
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_node2()
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_ciph()
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_vlr()
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_post_pres()
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_post_trace()
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_post_imei()
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: proc_arq_fsm_done(PASSED)
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_DONE
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_DONE}: Process Access Request result: PASSED
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: Received Event MSC_A_EV_AUTHENTICATED
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: state_chg to MSC_A_ST_AUTHENTICATED
+DPAG Paging: IMSI-901700000010650:MSISDN-46071 for MNCC: establish call: Paging Response action (success)
+DPAG Paging: IMSI-901700000010650:MSISDN-46071 for MNCC: establish call: Removing Paging Request
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071 callref-0x423 tid-255) Paging succeeded
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: + cc: now used by 3 (rx_from_ms,paging-response,cc)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: Received Event MSC_A_EV_TRANSACTION_ACCEPTED
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: state_chg to MSC_A_ST_COMMUNICATING
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) starting timer T303 with 30 seconds
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) codecs: :0{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} (from: remote=1.2.3.4:56{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) new state NULL -> CALL_PRESENT
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_SETUP
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on GERAN-A
+- DTAP --GERAN-A--> MS: GSM48_MT_CC_SETUP: 030504076004050b020081
+- DTAP matches expected message
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - Paging: now used by 4 (attached,CC,proc_arq_vlr_fn_init,active-conn)
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - paging-response: now used by 2 (rx_from_ms,cc)
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - proc_arq_vlr_fn_init: now used by 3 (attached,CC,active-conn)
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc)
+- MS confirms call, we create a RAN-side RTP and forward MNCC_CALL_CONF_IND
+ MSC <--GERAN-A-- MS: GSM48_MT_CC_CALL_CONF
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms)
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP
+DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_CALL_CONF
+DCC trans(CC:CALL_PRESENT IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx CALL_CONF in state CALL_PRESENT
+DCC trans(CC:CALL_PRESENT IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) stopping pending timer T303
+DCC trans(CC:CALL_PRESENT IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) starting timer T310 with 30 seconds
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Starting call assignment
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){ESTABLISHING}: Allocated
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){ESTABLISHING}: is child of msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP)
+DCC trans(CC:CALL_PRESENT IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) codecs: :0{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} (from: remote=1.2.3.4:56{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+ MGW <--CRCX to RTP_TO_CN-- MSC: call_id=0x11 codecs=AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){UNINITIALIZED}: Allocated
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){UNINITIALIZED}: is child of call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-17:RTP_TO_CN:no-CI){UNINITIALIZED}: setting codecs to AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111
+ MGW <--CRCX to RTP_TO_RAN-- MSC: call_id=0x11 codecs=AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){UNINITIALIZED}: Allocated
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){UNINITIALIZED}: is child of call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-17:RTP_TO_RAN:no-CI){UNINITIALIZED}: setting codecs to AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111
+DCC trans(CC:CALL_PRESENT IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) new state CALL_PRESENT -> MO_TERM_CALL_CONF
+DMNCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) tx MNCC_CALL_CONF_IND
+ MSC --> MNCC: callref 0x423: MNCC_CALL_CONF_IND
+
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc)
+- VALIDATE_SDP OK: cc_to_mncc_tx_last_sdp == t->mt_tx_sdp_mncc_call_conf_ind ==
+- MGW acknowledges the CRCX to RAN, triggering Assignment with FR3 HR3 FR2 FR1 HR1
+ MGW --CRCX OK to RTP_TO_RAN--> MSC
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){ESTABLISHING}: Received Event CALL_LEG_EV_RTP_STREAM_ADDR_AVAILABLE
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Received Event MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: MGW endpoint's RTP address available for the CI RTP_TO_RAN: 10.23.23.1:23 (osmux=no:-2)
+DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) codecs: :0{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} (from: remote=1.2.3.4:56{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) Sending Assignment Command
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN encode: ASSIGNMENT_COMMAND on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+- VALIDATE_PERM_SPEECH OK: &bssap_assignment_command_last_channel_type == t->mt_tx_assignment_perm_speech == FR3 HR3 FR2 FR1 HR1
+- Assignment completes, triggering CRCX to CN
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN decode: ASSIGNMENT_COMPLETE
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-17:RTP_TO_RAN:no-CI){UNINITIALIZED}: setting codecs to AMR:octet-align=1#112
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-17:RTP_TO_RAN:no-CI:local-10-23-23-1-23){UNINITIALIZED}: setting remote addr to 1.2.3.4:1234
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-17:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Not committing: no MGW endpoint CI set up
+DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) codecs: :0{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} (from: assigned=AMR:octet-align=1#112 remote=1.2.3.4:56{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) Assignment Complete: RAN: AMR:octet-align=1#112, CN: AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111
+DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) Assignment complete, but still waiting for the CRCX OK on the CN side RTP
+- MNCC sends MNCC_RTP_CREATE, which first waits for the CN side RTP
+ MSC <-- MNCC: callref 0x423: MNCC_RTP_CREATE
+
+DMNCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx MNCC_RTP_CREATE
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Assignment for this trans already started earlier
+- When the CN side RTP address is known, ack MNCC_RTP_CREATE
+ MGW --CRCX OK to RTP_TO_CN--> MSC
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){ESTABLISHING}: Received Event CALL_LEG_EV_RTP_STREAM_ADDR_AVAILABLE
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Received Event MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: MGW endpoint's RTP address available for the CI RTP_TO_CN: 10.23.23.1:23 (osmux=no:-2)
+DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) codecs: 10.23.23.1:23{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} (from: assigned=AMR:octet-align=1#112 remote=1.2.3.4:56{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+DMNCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) tx MNCC_RTP_CREATE (RTP=10.23.23.1:23{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+ MSC --> MNCC: callref 0x423: MNCC_RTP_CREATE
+v=0
+o=OsmoMSC 0 0 IN IP4 10.23.23.1
+s=GSM Call
+c=IN IP4 10.23.23.1
+t=0 0
+m=audio 23 RTP/AVP 112 110 3 111
+a=rtpmap:112 AMR/8000
+a=fmtp:112 octet-align=1
+a=rtpmap:110 GSM-EFR/8000
+a=rtpmap:3 GSM/8000
+a=rtpmap:111 GSM-HR-08/8000
+a=ptime:20
+
+- VALIDATE_SDP OK: cc_to_mncc_tx_last_sdp == t->mt_tx_sdp_mncc_rtp_create == AMR#96 GSM-EFR GSM GSM-HR-08
+- Total time passed: 1376.001024 s
+ MSC <--GERAN-A-- MS: GSM48_MT_CC_ALERTING
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms)
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP
+DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_ALERTING
+DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx ALERTING in state MO_TERM_CALL_CONF
+DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) stopping pending timer T310
+DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) starting timer T301 with 180 seconds
+DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) new state MO_TERM_CALL_CONF -> CALL_RECEIVED
+DCC trans(CC:CALL_RECEIVED IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) codecs: 10.23.23.1:23{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} (from: assigned=AMR:octet-align=1#112 remote=1.2.3.4:56{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+DMNCC trans(CC:CALL_RECEIVED IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) tx MNCC_ALERT_IND (RTP=10.23.23.1:23{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+ MSC --> MNCC: callref 0x423: MNCC_ALERT_IND
+v=0
+o=OsmoMSC 0 0 IN IP4 10.23.23.1
+s=GSM Call
+c=IN IP4 10.23.23.1
+t=0 0
+m=audio 23 RTP/AVP 112 110 3 111
+a=rtpmap:112 AMR/8000
+a=fmtp:112 octet-align=1
+a=rtpmap:110 GSM-EFR/8000
+a=rtpmap:3 GSM/8000
+a=rtpmap:111 GSM-HR-08/8000
+a=ptime:20
+
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc)
+- VALIDATE_SDP OK: cc_to_mncc_tx_last_sdp == t->mt_tx_sdp_mncc_alert_ind == AMR#96 GSM-EFR GSM GSM-HR-08
+- Total time passed: 1377.001047 s
+ MSC <--GERAN-A-- MS: GSM48_MT_CC_CONNECT
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms)
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP
+DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_CONNECT
+DCC trans(CC:CALL_RECEIVED IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx CONNECT in state CALL_RECEIVED
+DCC trans(CC:CALL_RECEIVED IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) stopping pending timer T301
+DCC trans(CC:CALL_RECEIVED IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) new state CALL_RECEIVED -> CONNECT_REQUEST
+DCC trans(CC:CONNECT_REQUEST IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) codecs: 10.23.23.1:23{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} (from: assigned=AMR:octet-align=1#112 remote=1.2.3.4:56{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+DMNCC trans(CC:CONNECT_REQUEST IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) tx MNCC_SETUP_CNF (RTP=10.23.23.1:23{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+ MSC --> MNCC: callref 0x423: MNCC_SETUP_CNF
+v=0
+o=OsmoMSC 0 0 IN IP4 10.23.23.1
+s=GSM Call
+c=IN IP4 10.23.23.1
+t=0 0
+m=audio 23 RTP/AVP 112 110 3 111
+a=rtpmap:112 AMR/8000
+a=fmtp:112 octet-align=1
+a=rtpmap:110 GSM-EFR/8000
+a=rtpmap:3 GSM/8000
+a=rtpmap:111 GSM-HR-08/8000
+a=ptime:20
+
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc)
+- VALIDATE_SDP OK: cc_to_mncc_tx_last_sdp == t->mt_tx_sdp_mncc_setup_cnf == AMR#96 GSM-EFR GSM GSM-HR-08
+ MSC <-- MNCC: callref 0x423: MNCC_SETUP_COMPL_REQ
+
+DMNCC trans(CC:CONNECT_REQUEST IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx MNCC_SETUP_COMPL_REQ
+DCC trans(CC:CONNECT_REQUEST IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) starting guard timer with 180 seconds
+DCC trans(CC:CONNECT_REQUEST IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) new state CONNECT_REQUEST -> ACTIVE
+DCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) stopping pending guard timer
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_CONNECT_ACK
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on GERAN-A
+- DTAP --GERAN-A--> MS: GSM48_MT_CC_CONNECT_ACK: 030f
+- DTAP matches expected message
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+
+
+- RTP stream goes ahead, not shown here.
+- Total time passed: 1500.001092 s
+
+
+- Call ends
+ MSC <--GERAN-A-- MS: GSM48_MT_CC_DISCONNECT
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms)
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP
+DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_DISCONNECT
+DCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx DISCONNECT in state ACTIVE
+DCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) new state ACTIVE -> DISCONNECT_IND
+DMNCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) tx MNCC_DISC_IND
+ MSC --> MNCC: callref 0x423: MNCC_DISC_IND
+
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc)
+ MSC <-- MNCC: callref 0x423: MNCC_REL_REQ
+
+DMNCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx MNCC_REL_REQ
+DCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) starting guard timer with 180 seconds
+DCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) starting timer T308 with 10 seconds
+DCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) new state DISCONNECT_IND -> RELEASE_REQ
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_RELEASE
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on GERAN-A
+- DTAP --GERAN-A--> MS: GSM48_MT_CC_RELEASE: 032d
+- DTAP matches expected message
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+ MSC <--GERAN-A-- MS: GSM48_MT_CC_RELEASE_COMPL
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms)
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP
+DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_RELEASE_COMPL
+DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx RELEASE_COMPL in state RELEASE_REQ
+DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) stopping pending timer T308
+DMNCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) tx MNCC_REL_CNF
+ MSC --> MNCC: callref 0x423: MNCC_REL_CNF
+
+DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x0 tid-0) Freeing transaction
+DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x0 tid-0) new state RELEASE_REQ -> NULL
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x0 tid-0) stopping pending guard timer
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - CC: now used by 2 (attached,active-conn)
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - cc: now used by 1 (rx_from_ms)
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 0 (-)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Received Event MSC_A_EV_UNUSED
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: state_chg to MSC_A_ST_RELEASING
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: Releasing: msc_a use is 0 (-)
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + msc_a_fsm_releasing_onenter: now used by 3 (attached,active-conn,msc_a_fsm_releasing_onenter)
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,active-conn,msc_a_fsm_releasing_onenter,vlr_subscr_cancel_attach_fsm)
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,active-conn,msc_a_fsm_releasing_onenter)
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){ESTABLISHING}: state_chg to RELEASING
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-17:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-17:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Removing from parent call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-17:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Deallocated
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-17:RTP_TO_CN:no-CI){UNINITIALIZED}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-17:RTP_TO_CN:no-CI){UNINITIALIZED}: Removing from parent call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-17:RTP_TO_CN:no-CI){UNINITIALIZED}: Deallocated
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){RELEASING}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){RELEASING}: Removing from parent msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: Received Event MSC_EV_CALL_LEG_TERM
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){RELEASING}: Deallocated
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: + wait-Clear-Complete: now used by 1 (wait-Clear-Complete)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: RAN encode: CLEAR_COMMAND on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - msc_a_fsm_releasing_onenter: now used by 2 (attached,active-conn)
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: RAN decode: CLEAR_COMPLETE
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: - wait-Clear-Complete: now used by 0 (-)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: Received Event MSC_A_EV_UNUSED
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: state_chg to MSC_A_ST_RELEASED
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASED}: Released: msc_a use is 0 (-)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_DONE}: Terminating in cascade, depth 2 (cause = OSMO_FSM_TERM_PARENT, caused by: msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP))
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_DONE}: Removing from parent msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP)
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_DONE}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASED}: Removing from parent msub_fsm
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASED}: max total use count was 3
+DMSC msub_fsm{active}: Received Event MSUB_EV_ROLE_TERMINATED
+DMSC msub(IMSI-901700000010650:MSISDN-46071) MSC-A terminated
+DMSC msub(IMSI-901700000010650:MSISDN-46071) 1 MSC-I still active
+DMSC msub_fsm{active}: state_chg to terminating
+DMSC msub_fsm{terminating}: Terminating in cascade, depth 2 (cause = OSMO_FSM_TERM_REGULAR, caused by: msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP))
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Terminating in cascade, depth 3 (cause = OSMO_FSM_TERM_PARENT, caused by: msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP))
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Removing from parent msub_fsm
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP)
+DMSC msub(IMSI-901700000010650:MSISDN-46071) Free
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - active-conn: now used by 1 (attached)
+DMSC msub_fsm{terminating}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASED}: Deallocated, including all deferred deallocations
+- msub gone
+ llist_count(&msub_list) == 0
+
+
+- ======================== SUCCESS: MT call: AMR picked by both MO and MT, but MT assigns a different payload type number
+
+
+- ======================== MO call: AMR picked by both MO and MT, but MO assigns a different payload type number
+- CM Service Request with Codec List (BSS Supported) = FR1 FR2 FR3 HR1 HR3
+ MSC <--GERAN-A-- MS: GSM48_MT_MM_CM_SERV_REQ
+ new conn
+DMSC msub_fsm{active}: Allocated
+DMSC msc_a{MSC_A_ST_VALIDATE_L3}: Allocated
+DMSC msc_a{MSC_A_ST_VALIDATE_L3}: is child of msub_fsm
+DMSC msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_VALIDATE_L3
+DMSC dummy_msc_i{0}: Allocated
+DMSC dummy_msc_i{0}: is child of msub_fsm
+DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms)
+DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3
+DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Complete Layer 3: Codec List (BSS Supported): GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111
+DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: MM GSM48_MT_MM_CM_SERV_REQ
+DMM msc_a(IMSI-901700000010650:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_VALIDATE_L3}: Rx CM SERVICE REQUEST cm_service_type=MO-Call
+DREF msc_a(IMSI-901700000010650:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_VALIDATE_L3}: + cm_service_cc: now used by 2 (rx_from_ms,cm_service_cc)
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: Allocated
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: is child of msc_a(IMSI-901700000010650:GERAN-A:CM_SERVICE_REQ)
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: rev=R99 net=GERAN (no Auth)
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + proc_arq_vlr_fn_init: now used by 2 (attached,proc_arq_vlr_fn_init)
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + active-conn: now used by 3 (attached,proc_arq_vlr_fn_init,active-conn)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi()
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_node2()
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_ciph()
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_vlr()
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_post_pres()
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_post_trace()
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_post_imei()
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: proc_arq_fsm_done(PASSED)
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_DONE
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_DONE}: Process Access Request result: PASSED
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: Sending DTAP: MM GSM48_MT_MM_CM_SERV_ACC
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN encode: DTAP on GERAN-A
+- DTAP --GERAN-A--> MS: GSM48_MT_MM_CM_SERV_ACC: 0521
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: Received Event MSC_A_EV_AUTHENTICATED
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: state_chg to MSC_A_ST_AUTHENTICATED
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - proc_arq_vlr_fn_init: now used by 2 (attached,active-conn)
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: - rx_from_ms: now used by 1 (cm_service_cc)
+ cm_service_result_sent == 1
+msc_a_is_accepted() == true
+- MS sends CC SETUP with Bearer Capability = AMR AMR AMR GSM-EFR GSM GSM-HR-08
+ MSC <--GERAN-A-- MS: GSM48_MT_CC_SETUP
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: + rx_from_ms: now used by 2 (cm_service_cc,rx_from_ms)
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: RAN decode: DTAP
+DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: Dispatching 04.08 message: CC GSM48_MT_CC_SETUP
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + CC: now used by 3 (attached,active-conn,CC)
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071 callref-0x8000000a tid-8) New transaction
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: Received Event MSC_A_EV_TRANSACTION_ACCEPTED
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: state_chg to MSC_A_ST_COMMUNICATING
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: + cc: now used by 3 (cm_service_cc,rx_from_ms,cc)
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - cm_service_cc: now used by 2 (rx_from_ms,cc)
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x8000000a tid-8) rx SETUP in state NULL
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x8000000a tid-8) starting guard timer with 180 seconds
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x8000000a tid-8) codecs: :0{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} (from: MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x8000000a tid-8) SETUP to 123
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x8000000a tid-8) new state NULL -> INITIATED
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Starting call assignment
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){ESTABLISHING}: Allocated
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){ESTABLISHING}: is child of msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ)
+DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x8000000a tid-8) codecs: :0{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} (from: MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+ MGW <--CRCX to RTP_TO_CN-- MSC: call_id=0x12 codecs=AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){UNINITIALIZED}: Allocated
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){UNINITIALIZED}: is child of call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-18:RTP_TO_CN:no-CI){UNINITIALIZED}: setting codecs to AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111
+ MGW <--CRCX to RTP_TO_RAN-- MSC: call_id=0x12 codecs=AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){UNINITIALIZED}: Allocated
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){UNINITIALIZED}: is child of call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-18:RTP_TO_RAN:no-CI){UNINITIALIZED}: setting codecs to AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc)
+- As soon as the MGW port towards CN is created, MNCC_SETUP_IND is triggered
+ MGW --CRCX OK to RTP_TO_CN--> MSC
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){ESTABLISHING}: Received Event CALL_LEG_EV_RTP_STREAM_ADDR_AVAILABLE
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Received Event MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: MGW endpoint's RTP address available for the CI RTP_TO_CN: 10.23.23.1:23 (osmux=no:-2)
+DMNCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x8000000a tid-8) tx MNCC_SETUP_IND (RTP=10.23.23.1:23{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+ MSC --> MNCC: callref 0x8000000a: MNCC_SETUP_IND
+v=0
+o=OsmoMSC 0 0 IN IP4 10.23.23.1
+s=GSM Call
+c=IN IP4 10.23.23.1
+t=0 0
+m=audio 23 RTP/AVP 112 110 3 111
+a=rtpmap:112 AMR/8000
+a=fmtp:112 octet-align=1
+a=rtpmap:110 GSM-EFR/8000
+a=rtpmap:3 GSM/8000
+a=rtpmap:111 GSM-HR-08/8000
+a=ptime:20
+
+- VALIDATE_SDP OK: cc_to_mncc_tx_last_sdp == t->mo_tx_sdp_mncc_setup_ind == AMR GSM-EFR GSM GSM-HR-08
+- MNCC replies with MNCC_RTP_CREATE
+ MSC <-- MNCC: callref 0x8000000a: MNCC_RTP_CREATE
+
+DMNCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x8000000a tid-8) rx MNCC_RTP_CREATE
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Assignment for this trans already started earlier
+- MGW acknowledges the CRCX, triggering Assignment with FR3 HR3 FR2 FR1 HR1
+ MGW --CRCX OK to RTP_TO_RAN--> MSC
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){ESTABLISHING}: Received Event CALL_LEG_EV_RTP_STREAM_ADDR_AVAILABLE
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Received Event MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: MGW endpoint's RTP address available for the CI RTP_TO_RAN: 10.23.23.1:23 (osmux=no:-2)
+DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x8000000a tid-8) codecs: 10.23.23.1:23{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} (from: MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x8000000a tid-8) Sending Assignment Command
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN encode: ASSIGNMENT_COMMAND on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+- VALIDATE_PERM_SPEECH OK: &bssap_assignment_command_last_channel_type == t->mo_tx_assignment_perm_speech == FR3 HR3 FR2 FR1 HR1
+- Assignment succeeds, triggering MNCC_RTP_CREATE ack to MNCC
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN decode: ASSIGNMENT_COMPLETE
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-18:RTP_TO_RAN:no-CI){UNINITIALIZED}: setting codecs to AMR:octet-align=1#112
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-18:RTP_TO_RAN:no-CI:local-10-23-23-1-23){UNINITIALIZED}: setting remote addr to 1.2.3.4:1234
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-18:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Not committing: no MGW endpoint CI set up
+DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x8000000a tid-8) codecs: 10.23.23.1:23{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} (from: assigned=AMR:octet-align=1#112 MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x8000000a tid-8) Assignment Complete: RAN: AMR:octet-align=1#112, CN: AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111
+DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x8000000a tid-8) codecs: 10.23.23.1:23{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} (from: assigned=AMR:octet-align=1#112 MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+DMNCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x8000000a tid-8) tx MNCC_RTP_CREATE (RTP=10.23.23.1:23{AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+ MSC --> MNCC: callref 0x8000000a: MNCC_RTP_CREATE
+v=0
+o=OsmoMSC 0 0 IN IP4 10.23.23.1
+s=GSM Call
+c=IN IP4 10.23.23.1
+t=0 0
+m=audio 23 RTP/AVP 112 110 3 111
+a=rtpmap:112 AMR/8000
+a=fmtp:112 octet-align=1
+a=rtpmap:110 GSM-EFR/8000
+a=rtpmap:3 GSM/8000
+a=rtpmap:111 GSM-HR-08/8000
+a=ptime:20
+
+- VALIDATE_SDP OK: cc_to_mncc_tx_last_sdp == t->mo_tx_sdp_mncc_rtp_create == AMR#98 GSM-EFR GSM GSM-HR-08
+- MNCC says that's fine
+ MSC <-- MNCC: callref 0x8000000a: MNCC_CALL_PROC_REQ
+
+DMNCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x8000000a tid-8) rx MNCC_CALL_PROC_REQ
+DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x8000000a tid-8) stopping pending guard timer
+DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x8000000a tid-8) starting guard timer with 180 seconds
+DCC trans(CC:INITIATED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x8000000a tid-8) new state INITIATED -> MO_CALL_PROC
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_CALL_PROC
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on GERAN-A
+- DTAP --GERAN-A--> MS: GSM48_MT_CC_CALL_PROC: 8302
+- DTAP matches expected message
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Assignment for this trans already started earlier
+- Total time passed: 1501.001115 s
+- The other call leg got established (not shown here), MNCC tells us so, with codecs { AMR#98 GSM-EFR GSM GSM-HR-08 }
+ MSC <-- MNCC: callref 0x8000000a: MNCC_ALERT_REQ
+v=0
+o=OsmoMSC 0 0 IN IP4 1.2.3.4
+s=GSM Call
+c=IN IP4 1.2.3.4
+t=0 0
+m=audio 56 RTP/AVP 98 110 3 111
+a=rtpmap:98 AMR/8000
+a=fmtp:98 octet-align=1
+a=rtpmap:110 GSM-EFR/8000
+a=rtpmap:3 GSM/8000
+a=rtpmap:111 GSM-HR-08/8000
+a=ptime:20
+
+DMNCC trans(CC:MO_CALL_PROC IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x8000000a tid-8) rx MNCC_ALERT_REQ (RTP=1.2.3.4:56{AMR:octet-align=1#98,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+DCC trans(CC:MO_CALL_PROC IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x8000000a tid-8) stopping pending guard timer
+DCC trans(CC:MO_CALL_PROC IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x8000000a tid-8) starting guard timer with 180 seconds
+DCC trans(CC:MO_CALL_PROC IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x8000000a tid-8) new state MO_CALL_PROC -> CALL_DELIVERED
+DCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x8000000a tid-8) codecs: 10.23.23.1:23{AMR:octet-align=1#98,GSM-EFR#110,GSM#3,GSM-HR-08#111} (from: assigned=AMR:octet-align=1#112 remote=1.2.3.4:56{AMR:octet-align=1#98,GSM-EFR#110,GSM#3,GSM-HR-08#111} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-18:RTP_TO_CN:no-CI){UNINITIALIZED}: setting codecs to AMR:octet-align=1#98,GSM-EFR#110,GSM#3,GSM-HR-08#111
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-18:RTP_TO_CN:no-CI:local-10-23-23-1-23){UNINITIALIZED}: setting remote addr to 1.2.3.4:56
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-18:RTP_TO_CN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-56){UNINITIALIZED}: Not committing: no MGW endpoint CI set up
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_ALERTING
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on GERAN-A
+- DTAP --GERAN-A--> MS: GSM48_MT_CC_ALERTING: 8301
+- DTAP matches expected message
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+ MSC <-- MNCC: callref 0x8000000a: MNCC_SETUP_RSP
+v=0
+o=OsmoMSC 0 0 IN IP4 1.2.3.4
+s=GSM Call
+c=IN IP4 1.2.3.4
+t=0 0
+m=audio 56 RTP/AVP 98 110 3 111
+a=rtpmap:98 AMR/8000
+a=fmtp:98 octet-align=1
+a=rtpmap:110 GSM-EFR/8000
+a=rtpmap:3 GSM/8000
+a=rtpmap:111 GSM-HR-08/8000
+a=ptime:20
+
+DMNCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x8000000a tid-8) rx MNCC_SETUP_RSP (RTP=1.2.3.4:56{AMR:octet-align=1#98,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+DCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x8000000a tid-8) stopping pending guard timer
+DCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x8000000a tid-8) starting guard timer with 180 seconds
+DCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x8000000a tid-8) starting timer T313 with 30 seconds
+DCC trans(CC:CALL_DELIVERED IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x8000000a tid-8) new state CALL_DELIVERED -> CONNECT_IND
+DCC trans(CC:CONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x8000000a tid-8) codecs: 10.23.23.1:23{AMR:octet-align=1#98,GSM-EFR#110,GSM#3,GSM-HR-08#111} (from: assigned=AMR:octet-align=1#112 remote=1.2.3.4:56{AMR:octet-align=1#98,GSM-EFR#110,GSM#3,GSM-HR-08#111} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-18:RTP_TO_CN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-56){UNINITIALIZED}: no change: codecs already set to AMR:octet-align=1#98,GSM-EFR#110,GSM#3,GSM-HR-08#111
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-18:RTP_TO_CN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-56){UNINITIALIZED}: remote addr already 1.2.3.4:56, no change
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-18:RTP_TO_CN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-56){UNINITIALIZED}: Not committing: no MGW endpoint CI set up
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_CONNECT
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on GERAN-A
+- DTAP --GERAN-A--> MS: GSM48_MT_CC_CONNECT: 8307
+- DTAP matches expected message
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+- Total time passed: 1502.001138 s
+ MSC <--GERAN-A-- MS: GSM48_MT_CC_CONNECT_ACK
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms)
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP
+DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_CONNECT_ACK
+DCC trans(CC:CONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x8000000a tid-8) rx CONNECT_ACK in state CONNECT_IND
+DCC trans(CC:CONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x8000000a tid-8) stopping pending timer T313
+DCC trans(CC:CONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x8000000a tid-8) new state CONNECT_IND -> ACTIVE
+DCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x8000000a tid-8) stopping pending guard timer
+DMNCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x8000000a tid-8) tx MNCC_SETUP_COMPL_IND
+ MSC --> MNCC: callref 0x8000000a: MNCC_SETUP_COMPL_IND
+
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc)
+- VALIDATE_SDP OK: cc_to_mncc_tx_last_sdp == t->mo_tx_sdp_mncc_setup_compl_ind ==
+
+
+- RTP stream goes ahead, not shown here.
+- Total time passed: 1625.001183 s
+
+
+- Call ends
+ MSC <--GERAN-A-- MS: GSM48_MT_CC_DISCONNECT
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms)
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP
+DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_DISCONNECT
+DCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x8000000a tid-8) rx DISCONNECT in state ACTIVE
+DCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x8000000a tid-8) new state ACTIVE -> DISCONNECT_IND
+DMNCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x8000000a tid-8) tx MNCC_DISC_IND
+ MSC --> MNCC: callref 0x8000000a: MNCC_DISC_IND
+
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc)
+ MSC <-- MNCC: callref 0x8000000a: MNCC_REL_REQ
+v=0
+o=OsmoMSC 0 0 IN IP4 1.2.3.4
+s=GSM Call
+c=IN IP4 1.2.3.4
+t=0 0
+m=audio 56 RTP/AVP 98 110 3 111
+a=rtpmap:98 AMR/8000
+a=fmtp:98 octet-align=1
+a=rtpmap:110 GSM-EFR/8000
+a=rtpmap:3 GSM/8000
+a=rtpmap:111 GSM-HR-08/8000
+a=ptime:20
+
+DMNCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x8000000a tid-8) rx MNCC_REL_REQ
+DCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x8000000a tid-8) starting guard timer with 180 seconds
+DCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x8000000a tid-8) starting timer T308 with 10 seconds
+DCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x8000000a tid-8) new state DISCONNECT_IND -> RELEASE_REQ
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_RELEASE
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on GERAN-A
+- DTAP --GERAN-A--> MS: GSM48_MT_CC_RELEASE: 832d
+- DTAP matches expected message
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+ MSC <--GERAN-A-- MS: GSM48_MT_CC_RELEASE_COMPL
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms)
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP
+DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_RELEASE_COMPL
+DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x8000000a tid-8) rx RELEASE_COMPL in state RELEASE_REQ
+DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x8000000a tid-8) stopping pending timer T308
+DMNCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x8000000a tid-8) tx MNCC_REL_CNF
+ MSC --> MNCC: callref 0x8000000a: MNCC_REL_CNF
+
+DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x0 tid-8) Freeing transaction
+DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x0 tid-8) new state RELEASE_REQ -> NULL
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x0 tid-8) stopping pending guard timer
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - CC: now used by 2 (attached,active-conn)
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - cc: now used by 1 (rx_from_ms)
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 0 (-)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Received Event MSC_A_EV_UNUSED
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: state_chg to MSC_A_ST_RELEASING
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: Releasing: msc_a use is 0 (-)
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + msc_a_fsm_releasing_onenter: now used by 3 (attached,active-conn,msc_a_fsm_releasing_onenter)
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,active-conn,msc_a_fsm_releasing_onenter,vlr_subscr_cancel_attach_fsm)
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,active-conn,msc_a_fsm_releasing_onenter)
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){ESTABLISHING}: state_chg to RELEASING
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-18:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-18:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Removing from parent call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-18:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Deallocated
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-18:RTP_TO_CN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-56){UNINITIALIZED}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-18:RTP_TO_CN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-56){UNINITIALIZED}: Removing from parent call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ:trans-8:call-18:RTP_TO_CN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-56){UNINITIALIZED}: Deallocated
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){RELEASING}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){RELEASING}: Removing from parent msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: Received Event MSC_EV_CALL_LEG_TERM
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){RELEASING}: Deallocated
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: + wait-Clear-Complete: now used by 1 (wait-Clear-Complete)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: RAN encode: CLEAR_COMMAND on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - msc_a_fsm_releasing_onenter: now used by 2 (attached,active-conn)
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: RAN decode: CLEAR_COMPLETE
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: - wait-Clear-Complete: now used by 0 (-)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: Received Event MSC_A_EV_UNUSED
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: state_chg to MSC_A_ST_RELEASED
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASED}: Released: msc_a use is 0 (-)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_DONE}: Terminating in cascade, depth 2 (cause = OSMO_FSM_TERM_PARENT, caused by: msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ))
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_DONE}: Removing from parent msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ)
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_DONE}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASED}: Removing from parent msub_fsm
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASED}: max total use count was 3
+DMSC msub_fsm{active}: Received Event MSUB_EV_ROLE_TERMINATED
+DMSC msub(IMSI-901700000010650:MSISDN-46071) MSC-A terminated
+DMSC msub(IMSI-901700000010650:MSISDN-46071) 1 MSC-I still active
+DMSC msub_fsm{active}: state_chg to terminating
+DMSC msub_fsm{terminating}: Terminating in cascade, depth 2 (cause = OSMO_FSM_TERM_REGULAR, caused by: msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ))
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Terminating in cascade, depth 3 (cause = OSMO_FSM_TERM_PARENT, caused by: msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ))
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Removing from parent msub_fsm
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ)
+DMSC msub(IMSI-901700000010650:MSISDN-46071) Free
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - active-conn: now used by 1 (attached)
+DMSC msub_fsm{terminating}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASED}: Deallocated, including all deferred deallocations
+- msub gone
+ llist_count(&msub_list) == 0
+
+
+- ======================== SUCCESS: MO call: AMR picked by both MO and MT, but MO assigns a different payload type number
+
+
+- ======================== MT call: AMR picked by both MO and MT, but MO assigns a different payload type number
+
+
+- MNCC asks us to setup a call, causing Paging
+ MSC <-- MNCC: callref 0x423: MNCC_SETUP_REQ
+v=0
+o=OsmoMSC 0 0 IN IP4 1.2.3.4
+s=GSM Call
+c=IN IP4 1.2.3.4
+t=0 0
+m=audio 56 RTP/AVP 98 110 3 111
+a=rtpmap:98 AMR/8000
+a=fmtp:98 octet-align=1
+a=rtpmap:110 GSM-EFR/8000
+a=rtpmap:3 GSM/8000
+a=rtpmap:111 GSM-HR-08/8000
+a=ptime:20
+
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + mncc_tx_to_gsm_cc: now used by 2 (attached,mncc_tx_to_gsm_cc)
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + CC: now used by 3 (attached,mncc_tx_to_gsm_cc,CC)
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071 callref-0x423 tid-255) New transaction
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071 callref-0x423 tid-255) codecs: :0{(no-codecs)} (from: remote=1.2.3.4:56{AMR:octet-align=1#98,GSM-EFR#110,GSM#3,GSM-HR-08#111} RAN={(no-codecs)})
+DMNCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071 callref-0x423 tid-255) rx MNCC_SETUP_REQ (RTP=1.2.3.4:56{AMR:octet-align=1#98,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+DPAG Paging: IMSI-901700000010650:MSISDN-46071 for MNCC: establish call: Starting paging
+ paging request (CALL_CONVERSATIONAL) to IMSI-901700000010650:MSISDN-46071 on GERAN-A
+ strcmp(paging_expecting_imsi, vsub->imsi) == 0
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + Paging: now used by 4 (attached,mncc_tx_to_gsm_cc,CC,Paging)
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - mncc_tx_to_gsm_cc: now used by 3 (attached,CC,Paging)
+ paging_sent == 1
+- MS replies with Paging Response, with Codec List (BSS Supported) = FR1 FR2 FR3 HR1 HR3
+- VLR accepts, MSC sends CC Setup with Bearer Capability = AMR AMR AMR GSM-EFR GSM GSM-HR-08
+ MSC <--GERAN-A-- MS: GSM48_MT_RR_PAG_RESP
+ new conn
+DMSC msub_fsm{active}: Allocated
+DMSC msc_a{MSC_A_ST_VALIDATE_L3}: Allocated
+DMSC msc_a{MSC_A_ST_VALIDATE_L3}: is child of msub_fsm
+DMSC msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_VALIDATE_L3
+DMSC dummy_msc_i{0}: Allocated
+DMSC dummy_msc_i{0}: is child of msub_fsm
+DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms)
+DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3
+DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Complete Layer 3: Codec List (BSS Supported): GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111
+DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: RR GSM48_MT_RR_PAG_RESP
+DRR msc_a(IMSI-901700000010650:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: Rx PAGING RESPONSE IMSI-901700000010650
+DREF msc_a(IMSI-901700000010650:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: + paging-response: now used by 2 (rx_from_ms,paging-response)
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: Allocated
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: is child of msc_a(IMSI-901700000010650:GERAN-A:PAGING_RESP)
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: rev=R99 net=GERAN (no Auth)
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + proc_arq_vlr_fn_init: now used by 4 (attached,CC,Paging,proc_arq_vlr_fn_init)
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + active-conn: now used by 5 (attached,CC,Paging,proc_arq_vlr_fn_init,active-conn)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi()
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_node2()
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_ciph()
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_vlr()
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_post_pres()
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_post_trace()
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_post_imei()
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: proc_arq_fsm_done(PASSED)
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_DONE
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_DONE}: Process Access Request result: PASSED
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: Received Event MSC_A_EV_AUTHENTICATED
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: state_chg to MSC_A_ST_AUTHENTICATED
+DPAG Paging: IMSI-901700000010650:MSISDN-46071 for MNCC: establish call: Paging Response action (success)
+DPAG Paging: IMSI-901700000010650:MSISDN-46071 for MNCC: establish call: Removing Paging Request
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071 callref-0x423 tid-255) Paging succeeded
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: + cc: now used by 3 (rx_from_ms,paging-response,cc)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: Received Event MSC_A_EV_TRANSACTION_ACCEPTED
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: state_chg to MSC_A_ST_COMMUNICATING
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) starting timer T303 with 30 seconds
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) codecs: :0{AMR:octet-align=1#98,GSM-EFR#110,GSM#3,GSM-HR-08#111} (from: remote=1.2.3.4:56{AMR:octet-align=1#98,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) new state NULL -> CALL_PRESENT
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_SETUP
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on GERAN-A
+- DTAP --GERAN-A--> MS: GSM48_MT_CC_SETUP: 030504076004050b020081
+- DTAP matches expected message
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - Paging: now used by 4 (attached,CC,proc_arq_vlr_fn_init,active-conn)
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - paging-response: now used by 2 (rx_from_ms,cc)
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - proc_arq_vlr_fn_init: now used by 3 (attached,CC,active-conn)
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc)
+- MS confirms call, we create a RAN-side RTP and forward MNCC_CALL_CONF_IND
+ MSC <--GERAN-A-- MS: GSM48_MT_CC_CALL_CONF
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms)
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP
+DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_CALL_CONF
+DCC trans(CC:CALL_PRESENT IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx CALL_CONF in state CALL_PRESENT
+DCC trans(CC:CALL_PRESENT IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) stopping pending timer T303
+DCC trans(CC:CALL_PRESENT IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) starting timer T310 with 30 seconds
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Starting call assignment
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){ESTABLISHING}: Allocated
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){ESTABLISHING}: is child of msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP)
+DCC trans(CC:CALL_PRESENT IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) codecs: :0{AMR:octet-align=1#98,GSM-EFR#110,GSM#3,GSM-HR-08#111} (from: remote=1.2.3.4:56{AMR:octet-align=1#98,GSM-EFR#110,GSM#3,GSM-HR-08#111} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+ MGW <--CRCX to RTP_TO_CN-- MSC: call_id=0x13 codecs=AMR:octet-align=1#98,GSM-EFR#110,GSM#3,GSM-HR-08#111
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){UNINITIALIZED}: Allocated
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){UNINITIALIZED}: is child of call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-19:RTP_TO_CN:no-CI){UNINITIALIZED}: setting codecs to AMR:octet-align=1#98,GSM-EFR#110,GSM#3,GSM-HR-08#111
+ MGW <--CRCX to RTP_TO_RAN-- MSC: call_id=0x13 codecs=AMR:octet-align=1#98,GSM-EFR#110,GSM#3,GSM-HR-08#111
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){UNINITIALIZED}: Allocated
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){UNINITIALIZED}: is child of call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-19:RTP_TO_RAN:no-CI){UNINITIALIZED}: setting codecs to AMR:octet-align=1#98,GSM-EFR#110,GSM#3,GSM-HR-08#111
+DCC trans(CC:CALL_PRESENT IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) new state CALL_PRESENT -> MO_TERM_CALL_CONF
+DMNCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) tx MNCC_CALL_CONF_IND
+ MSC --> MNCC: callref 0x423: MNCC_CALL_CONF_IND
+
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc)
+- VALIDATE_SDP OK: cc_to_mncc_tx_last_sdp == t->mt_tx_sdp_mncc_call_conf_ind ==
+- MGW acknowledges the CRCX to RAN, triggering Assignment with FR3 HR3 FR2 FR1 HR1
+ MGW --CRCX OK to RTP_TO_RAN--> MSC
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){ESTABLISHING}: Received Event CALL_LEG_EV_RTP_STREAM_ADDR_AVAILABLE
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Received Event MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: MGW endpoint's RTP address available for the CI RTP_TO_RAN: 10.23.23.1:23 (osmux=no:-2)
+DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) codecs: :0{AMR:octet-align=1#98,GSM-EFR#110,GSM#3,GSM-HR-08#111} (from: remote=1.2.3.4:56{AMR:octet-align=1#98,GSM-EFR#110,GSM#3,GSM-HR-08#111} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) Sending Assignment Command
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN encode: ASSIGNMENT_COMMAND on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+- VALIDATE_PERM_SPEECH OK: &bssap_assignment_command_last_channel_type == t->mt_tx_assignment_perm_speech == FR3 HR3 FR2 FR1 HR1
+- Assignment completes, triggering CRCX to CN
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN decode: ASSIGNMENT_COMPLETE
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-19:RTP_TO_RAN:no-CI){UNINITIALIZED}: setting codecs to AMR:octet-align=1#112
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-19:RTP_TO_RAN:no-CI:local-10-23-23-1-23){UNINITIALIZED}: setting remote addr to 1.2.3.4:1234
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-19:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Not committing: no MGW endpoint CI set up
+DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) codecs: :0{AMR:octet-align=1#98,GSM-EFR#110,GSM#3,GSM-HR-08#111} (from: assigned=AMR:octet-align=1#112 remote=1.2.3.4:56{AMR:octet-align=1#98,GSM-EFR#110,GSM#3,GSM-HR-08#111} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) Assignment Complete: RAN: AMR:octet-align=1#112, CN: AMR:octet-align=1#98,GSM-EFR#110,GSM#3,GSM-HR-08#111
+DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) Assignment complete, but still waiting for the CRCX OK on the CN side RTP
+- MNCC sends MNCC_RTP_CREATE, which first waits for the CN side RTP
+ MSC <-- MNCC: callref 0x423: MNCC_RTP_CREATE
+
+DMNCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx MNCC_RTP_CREATE
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Assignment for this trans already started earlier
+- When the CN side RTP address is known, ack MNCC_RTP_CREATE
+ MGW --CRCX OK to RTP_TO_CN--> MSC
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){ESTABLISHING}: Received Event CALL_LEG_EV_RTP_STREAM_ADDR_AVAILABLE
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Received Event MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: MGW endpoint's RTP address available for the CI RTP_TO_CN: 10.23.23.1:23 (osmux=no:-2)
+DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) codecs: 10.23.23.1:23{AMR:octet-align=1#98,GSM-EFR#110,GSM#3,GSM-HR-08#111} (from: assigned=AMR:octet-align=1#112 remote=1.2.3.4:56{AMR:octet-align=1#98,GSM-EFR#110,GSM#3,GSM-HR-08#111} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+DMNCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) tx MNCC_RTP_CREATE (RTP=10.23.23.1:23{AMR:octet-align=1#98,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+ MSC --> MNCC: callref 0x423: MNCC_RTP_CREATE
+v=0
+o=OsmoMSC 0 0 IN IP4 10.23.23.1
+s=GSM Call
+c=IN IP4 10.23.23.1
+t=0 0
+m=audio 23 RTP/AVP 98 110 3 111
+a=rtpmap:98 AMR/8000
+a=fmtp:98 octet-align=1
+a=rtpmap:110 GSM-EFR/8000
+a=rtpmap:3 GSM/8000
+a=rtpmap:111 GSM-HR-08/8000
+a=ptime:20
+
+- VALIDATE_SDP OK: cc_to_mncc_tx_last_sdp == t->mt_tx_sdp_mncc_rtp_create == AMR#98 GSM-EFR GSM GSM-HR-08
+- Total time passed: 1626.001206 s
+ MSC <--GERAN-A-- MS: GSM48_MT_CC_ALERTING
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms)
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP
+DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_ALERTING
+DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx ALERTING in state MO_TERM_CALL_CONF
+DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) stopping pending timer T310
+DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) starting timer T301 with 180 seconds
+DCC trans(CC:MO_TERM_CALL_CONF IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) new state MO_TERM_CALL_CONF -> CALL_RECEIVED
+DCC trans(CC:CALL_RECEIVED IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) codecs: 10.23.23.1:23{AMR:octet-align=1#98,GSM-EFR#110,GSM#3,GSM-HR-08#111} (from: assigned=AMR:octet-align=1#112 remote=1.2.3.4:56{AMR:octet-align=1#98,GSM-EFR#110,GSM#3,GSM-HR-08#111} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+DMNCC trans(CC:CALL_RECEIVED IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) tx MNCC_ALERT_IND (RTP=10.23.23.1:23{AMR:octet-align=1#98,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+ MSC --> MNCC: callref 0x423: MNCC_ALERT_IND
+v=0
+o=OsmoMSC 0 0 IN IP4 10.23.23.1
+s=GSM Call
+c=IN IP4 10.23.23.1
+t=0 0
+m=audio 23 RTP/AVP 98 110 3 111
+a=rtpmap:98 AMR/8000
+a=fmtp:98 octet-align=1
+a=rtpmap:110 GSM-EFR/8000
+a=rtpmap:3 GSM/8000
+a=rtpmap:111 GSM-HR-08/8000
+a=ptime:20
+
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc)
+- VALIDATE_SDP OK: cc_to_mncc_tx_last_sdp == t->mt_tx_sdp_mncc_alert_ind == AMR#98 GSM-EFR GSM GSM-HR-08
+- Total time passed: 1627.001229 s
+ MSC <--GERAN-A-- MS: GSM48_MT_CC_CONNECT
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms)
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP
+DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_CONNECT
+DCC trans(CC:CALL_RECEIVED IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx CONNECT in state CALL_RECEIVED
+DCC trans(CC:CALL_RECEIVED IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) stopping pending timer T301
+DCC trans(CC:CALL_RECEIVED IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) new state CALL_RECEIVED -> CONNECT_REQUEST
+DCC trans(CC:CONNECT_REQUEST IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) codecs: 10.23.23.1:23{AMR:octet-align=1#98,GSM-EFR#110,GSM#3,GSM-HR-08#111} (from: assigned=AMR:octet-align=1#112 remote=1.2.3.4:56{AMR:octet-align=1#98,GSM-EFR#110,GSM#3,GSM-HR-08#111} MS={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111} bss={GSM#3,GSM-EFR#110,AMR:octet-align=1#112,GSM-HR-08#111} RAN={AMR:octet-align=1#112,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+DMNCC trans(CC:CONNECT_REQUEST IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) tx MNCC_SETUP_CNF (RTP=10.23.23.1:23{AMR:octet-align=1#98,GSM-EFR#110,GSM#3,GSM-HR-08#111})
+ MSC --> MNCC: callref 0x423: MNCC_SETUP_CNF
+v=0
+o=OsmoMSC 0 0 IN IP4 10.23.23.1
+s=GSM Call
+c=IN IP4 10.23.23.1
+t=0 0
+m=audio 23 RTP/AVP 98 110 3 111
+a=rtpmap:98 AMR/8000
+a=fmtp:98 octet-align=1
+a=rtpmap:110 GSM-EFR/8000
+a=rtpmap:3 GSM/8000
+a=rtpmap:111 GSM-HR-08/8000
+a=ptime:20
+
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc)
+- VALIDATE_SDP OK: cc_to_mncc_tx_last_sdp == t->mt_tx_sdp_mncc_setup_cnf == AMR#98 GSM-EFR GSM GSM-HR-08
+ MSC <-- MNCC: callref 0x423: MNCC_SETUP_COMPL_REQ
+
+DMNCC trans(CC:CONNECT_REQUEST IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx MNCC_SETUP_COMPL_REQ
+DCC trans(CC:CONNECT_REQUEST IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) starting guard timer with 180 seconds
+DCC trans(CC:CONNECT_REQUEST IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) new state CONNECT_REQUEST -> ACTIVE
+DCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) stopping pending guard timer
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_CONNECT_ACK
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on GERAN-A
+- DTAP --GERAN-A--> MS: GSM48_MT_CC_CONNECT_ACK: 030f
+- DTAP matches expected message
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+
+
+- RTP stream goes ahead, not shown here.
+- Total time passed: 1750.001274 s
+
+
+- Call ends
+ MSC <--GERAN-A-- MS: GSM48_MT_CC_DISCONNECT
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms)
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP
+DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_DISCONNECT
+DCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx DISCONNECT in state ACTIVE
+DCC trans(CC:ACTIVE IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) new state ACTIVE -> DISCONNECT_IND
+DMNCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) tx MNCC_DISC_IND
+ MSC --> MNCC: callref 0x423: MNCC_DISC_IND
+
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (cc)
+ MSC <-- MNCC: callref 0x423: MNCC_REL_REQ
+
+DMNCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx MNCC_REL_REQ
+DCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) starting guard timer with 180 seconds
+DCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) starting timer T308 with 10 seconds
+DCC trans(CC:DISCONNECT_IND IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) new state DISCONNECT_IND -> RELEASE_REQ
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Sending DTAP: CC GSM48_MT_CC_RELEASE
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on GERAN-A
+- DTAP --GERAN-A--> MS: GSM48_MT_CC_RELEASE: 032d
+- DTAP matches expected message
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+ MSC <--GERAN-A-- MS: GSM48_MT_CC_RELEASE_COMPL
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: + rx_from_ms: now used by 2 (cc,rx_from_ms)
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: RAN decode: DTAP
+DRLL msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Dispatching 04.08 message: CC GSM48_MT_CC_RELEASE_COMPL
+DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) rx RELEASE_COMPL in state RELEASE_REQ
+DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) stopping pending timer T308
+DMNCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x423 tid-0) tx MNCC_REL_CNF
+ MSC --> MNCC: callref 0x423: MNCC_REL_CNF
+
+DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x0 tid-0) Freeing transaction
+DCC trans(CC:RELEASE_REQ IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x0 tid-0) new state RELEASE_REQ -> NULL
+DCC trans(CC:NULL IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x0 tid-0) stopping pending guard timer
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - CC: now used by 2 (attached,active-conn)
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - cc: now used by 1 (rx_from_ms)
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 0 (-)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: Received Event MSC_A_EV_UNUSED
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_COMMUNICATING}: state_chg to MSC_A_ST_RELEASING
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: Releasing: msc_a use is 0 (-)
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + msc_a_fsm_releasing_onenter: now used by 3 (attached,active-conn,msc_a_fsm_releasing_onenter)
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,active-conn,msc_a_fsm_releasing_onenter,vlr_subscr_cancel_attach_fsm)
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,active-conn,msc_a_fsm_releasing_onenter)
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){ESTABLISHING}: state_chg to RELEASING
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-19:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-19:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Removing from parent call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-19:RTP_TO_RAN:no-CI:local-10-23-23-1-23:remote-1-2-3-4-1234){UNINITIALIZED}: Deallocated
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-19:RTP_TO_CN:no-CI){UNINITIALIZED}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-19:RTP_TO_CN:no-CI){UNINITIALIZED}: Removing from parent call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP)
+DCC rtp_stream(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP:trans-0:call-19:RTP_TO_CN:no-CI){UNINITIALIZED}: Deallocated
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){RELEASING}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){RELEASING}: Removing from parent msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: Received Event MSC_EV_CALL_LEG_TERM
+DCC call_leg(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){RELEASING}: Deallocated
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: + wait-Clear-Complete: now used by 1 (wait-Clear-Complete)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: RAN encode: CLEAR_COMMAND on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - msc_a_fsm_releasing_onenter: now used by 2 (attached,active-conn)
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: RAN decode: CLEAR_COMPLETE
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: - wait-Clear-Complete: now used by 0 (-)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: Received Event MSC_A_EV_UNUSED
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: state_chg to MSC_A_ST_RELEASED
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASED}: Released: msc_a use is 0 (-)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_DONE}: Terminating in cascade, depth 2 (cause = OSMO_FSM_TERM_PARENT, caused by: msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP))
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_DONE}: Removing from parent msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP)
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_DONE}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASED}: Removing from parent msub_fsm
+DREF msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASED}: max total use count was 3
+DMSC msub_fsm{active}: Received Event MSUB_EV_ROLE_TERMINATED
+DMSC msub(IMSI-901700000010650:MSISDN-46071) MSC-A terminated
+DMSC msub(IMSI-901700000010650:MSISDN-46071) 1 MSC-I still active
+DMSC msub_fsm{active}: state_chg to terminating
+DMSC msub_fsm{terminating}: Terminating in cascade, depth 2 (cause = OSMO_FSM_TERM_REGULAR, caused by: msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP))
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Terminating in cascade, depth 3 (cause = OSMO_FSM_TERM_PARENT, caused by: msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP))
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Removing from parent msub_fsm
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP)
+DMSC msub(IMSI-901700000010650:MSISDN-46071) Free
+DREF VLR subscr IMSI-901700000010650:MSISDN-46071 - active-conn: now used by 1 (attached)
+DMSC msub_fsm{terminating}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP)
+DMSC msc_a(IMSI-901700000010650:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASED}: Deallocated, including all deferred deallocations
+- msub gone
+ llist_count(&msub_list) == 0
+
+
+- ======================== SUCCESS: MT call: AMR picked by both MO and MT, but MO assigns a different payload type number
+ llist_count(&msub_list) == 0
+DVLR freeing VLR subscr IMSI-901700000010650:MSISDN-46071 (max total use count was 5)
+===== test_codecs: SUCCESS
diff --git a/tests/msc_vlr/msc_vlr_test_gsm_authen.c b/tests/msc_vlr/msc_vlr_test_gsm_authen.c
index 805ae6425..6d7e88a0d 100644
--- a/tests/msc_vlr/msc_vlr_test_gsm_authen.c
+++ b/tests/msc_vlr/msc_vlr_test_gsm_authen.c
@@ -22,7 +22,6 @@
*/
#include "msc_vlr_tests.h"
-#include "stubs.h"
static void test_gsm_authen()
{
@@ -35,7 +34,7 @@ static void test_gsm_authen()
btw("Location Update request causes a GSUP Send Auth Info request to HLR");
lu_result_sent = RES_NONE;
- gsup_expect_tx("08010809710000004026f0" VLR_TO_HLR);
+ gsup_expect_tx("08010809710000004026f0" CN_DOMAIN VLR_TO_HLR);
ms_sends_msg("0508020081680001"
"30" /* <-- Revision Level == 1, i.e. is_r99 == false */
"089910070000006402");
@@ -77,7 +76,7 @@ static void test_gsm_authen()
VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
btw("MS sends Authen Response, VLR accepts and sends GSUP LU Req to HLR");
- gsup_expect_tx("04010809710000004026f0280102" VLR_TO_HLR);
+ gsup_expect_tx("04010809710000004026f0" CN_DOMAIN VLR_TO_HLR);
ms_sends_msg("05542d8b2c3e");
VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
@@ -114,7 +113,7 @@ static void test_gsm_authen()
VERBOSE_ASSERT(cm_service_result_sent, == RES_ACCEPT, "%d");
/* Release connection */
- expect_bssap_clear(OSMO_RAT_GERAN_A);
+ expect_bssap_clear();
conn_conclude_cm_service_req(g_msub, MSC_A_USE_CM_SERVICE_SMS);
btw("all requests serviced, conn has been released");
@@ -225,7 +224,7 @@ static void test_gsm_authen_tmsi()
btw("Location Update request causes a GSUP Send Auth Info request to HLR");
lu_result_sent = RES_NONE;
- gsup_expect_tx("08010809710000004026f0" VLR_TO_HLR);
+ gsup_expect_tx("08010809710000004026f0" CN_DOMAIN VLR_TO_HLR);
ms_sends_msg("0508020081680001"
"30" /* <-- Revision Level == 1, i.e. is_r99 == false */
"089910070000006402");
@@ -267,7 +266,7 @@ static void test_gsm_authen_tmsi()
VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
btw("MS sends Authen Response, VLR accepts and sends GSUP LU Req to HLR");
- gsup_expect_tx("04010809710000004026f0280102" VLR_TO_HLR);
+ gsup_expect_tx("04010809710000004026f0" CN_DOMAIN VLR_TO_HLR);
ms_sends_msg("05542d8b2c3e");
VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
@@ -328,7 +327,7 @@ static void test_gsm_authen_tmsi()
VERBOSE_ASSERT(cm_service_result_sent, == RES_ACCEPT, "%d");
/* Release connection */
- expect_bssap_clear(OSMO_RAT_GERAN_A);
+ expect_bssap_clear();
conn_conclude_cm_service_req(g_msub, MSC_A_USE_CM_SERVICE_SMS);
btw("all requests serviced, conn has been released");
@@ -439,7 +438,7 @@ static void test_gsm_authen_tmsi()
VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
btw("MS sends Authen Response, VLR accepts and sends GSUP LU Req to HLR");
- gsup_expect_tx("04010809710000004026f0280102" VLR_TO_HLR);
+ gsup_expect_tx("04010809710000004026f0" CN_DOMAIN VLR_TO_HLR);
ms_sends_msg("05545afc8d72");
VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
@@ -505,7 +504,7 @@ static void test_gsm_authen_imei()
btw("Location Update request causes a GSUP Send Auth Info request to HLR");
lu_result_sent = RES_NONE;
- gsup_expect_tx("08010809710000004026f0" VLR_TO_HLR);
+ gsup_expect_tx("08010809710000004026f0" CN_DOMAIN VLR_TO_HLR);
ms_sends_msg("0508020081680001"
"30" /* <-- Revision Level == 1, i.e. is_r99 == false */
"089910070000006402");
@@ -545,7 +544,7 @@ static void test_gsm_authen_imei()
VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
btw("MS sends Authen Response, VLR accepts and sends GSUP LU Req to HLR");
- gsup_expect_tx("04010809710000004026f0280102" VLR_TO_HLR);
+ gsup_expect_tx("04010809710000004026f0" CN_DOMAIN VLR_TO_HLR);
ms_sends_msg("05542d8b2c3e");
VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
@@ -612,7 +611,7 @@ static void test_gsm_authen_imei_nack()
btw("Location Update request causes a GSUP Send Auth Info request to HLR");
lu_result_sent = RES_NONE;
- gsup_expect_tx("08010809710000004026f0" VLR_TO_HLR);
+ gsup_expect_tx("08010809710000004026f0" CN_DOMAIN VLR_TO_HLR);
ms_sends_msg("0508020081680001"
"30" /* <-- Revision Level == 1, i.e. is_r99 == false */
"089910070000006402");
@@ -654,7 +653,7 @@ static void test_gsm_authen_imei_nack()
VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
btw("MS sends Authen Response, VLR accepts and sends GSUP LU Req to HLR");
- gsup_expect_tx("04010809710000004026f0280102" VLR_TO_HLR);
+ gsup_expect_tx("04010809710000004026f0" CN_DOMAIN VLR_TO_HLR);
ms_sends_msg("05542d8b2c3e");
VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
@@ -706,7 +705,7 @@ static void test_gsm_authen_imei_err()
btw("Location Update request causes a GSUP Send Auth Info request to HLR");
lu_result_sent = RES_NONE;
- gsup_expect_tx("08010809710000004026f0" VLR_TO_HLR);
+ gsup_expect_tx("08010809710000004026f0" CN_DOMAIN VLR_TO_HLR);
ms_sends_msg("0508020081680001"
"30" /* <-- Revision Level == 1, i.e. is_r99 == false */
"089910070000006402");
@@ -747,7 +746,7 @@ static void test_gsm_authen_imei_err()
VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
btw("MS sends Authen Response, VLR accepts and sends GSUP LU Req to HLR");
- gsup_expect_tx("04010809710000004026f0280102" VLR_TO_HLR);
+ gsup_expect_tx("04010809710000004026f0" CN_DOMAIN VLR_TO_HLR);
ms_sends_msg("05542d8b2c3e");
VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
@@ -800,7 +799,7 @@ static void test_gsm_authen_tmsi_imei()
btw("Location Update request causes a GSUP Send Auth Info request to HLR");
lu_result_sent = RES_NONE;
- gsup_expect_tx("08010809710000004026f0" VLR_TO_HLR);
+ gsup_expect_tx("08010809710000004026f0" CN_DOMAIN VLR_TO_HLR);
ms_sends_msg("0508020081680001"
"30" /* <-- Revision Level == 1, i.e. is_r99 == false */
"089910070000006402");
@@ -841,7 +840,7 @@ static void test_gsm_authen_tmsi_imei()
VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
btw("MS sends Authen Response, VLR accepts and sends GSUP LU Req to HLR");
- gsup_expect_tx("04010809710000004026f0280102" VLR_TO_HLR);
+ gsup_expect_tx("04010809710000004026f0" CN_DOMAIN VLR_TO_HLR);
ms_sends_msg("05542d8b2c3e");
VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
@@ -925,7 +924,7 @@ static void test_gsm_milenage_authen()
btw("Location Update request causes a GSUP Send Auth Info request to HLR");
lu_result_sent = RES_NONE;
- gsup_expect_tx("080108" "09710000000156f0" VLR_TO_HLR);
+ gsup_expect_tx("080108" "09710000000156f0" CN_DOMAIN VLR_TO_HLR);
ms_sends_msg("0508" /* MM LU */
"7" /* ciph key seq: no key available */
"0" /* LU type: normal */
@@ -978,7 +977,7 @@ static void test_gsm_milenage_authen()
VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
btw("MS sends Authen Response, VLR accepts and sends GSUP LU Req to HLR");
- gsup_expect_tx("04010809710000000156f0280102" VLR_TO_HLR);
+ gsup_expect_tx("04010809710000000156f0" CN_DOMAIN VLR_TO_HLR);
ms_sends_msg("0554" "9b36efdf");
VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
@@ -1018,7 +1017,7 @@ static void test_gsm_milenage_authen()
VERBOSE_ASSERT(cm_service_result_sent, == RES_ACCEPT, "%d");
/* Release connection */
- expect_bssap_clear(OSMO_RAT_GERAN_A);
+ expect_bssap_clear();
conn_conclude_cm_service_req(g_msub, MSC_A_USE_CM_SERVICE_SMS);
btw("all requests serviced, conn has been released");
@@ -1130,7 +1129,7 @@ static void test_wrong_sres_length()
btw("Location Update request causes a GSUP Send Auth Info request to HLR");
lu_result_sent = RES_NONE;
- gsup_expect_tx("08010809710000004026f0" VLR_TO_HLR);
+ gsup_expect_tx("08010809710000004026f0" CN_DOMAIN VLR_TO_HLR);
ms_sends_msg("0508020081680001"
"30" /* <-- Revision Level == 1, i.e. is_r99 == false */
"089910070000006402");
diff --git a/tests/msc_vlr/msc_vlr_test_gsm_authen.err b/tests/msc_vlr/msc_vlr_test_gsm_authen.err
index 45b047d86..94c169488 100644
--- a/tests/msc_vlr/msc_vlr_test_gsm_authen.err
+++ b/tests/msc_vlr/msc_vlr_test_gsm_authen.err
@@ -1,7 +1,3 @@
-DLMGCP MGCP client: using endpoint domain '@mgw'
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 17
-
===== test_gsm_authen
- Location Update request causes a GSUP Send Auth Info request to HLR
MSC <--GERAN-A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
@@ -30,13 +26,14 @@ DREF VLR subscr IMSI-901700000004620 + active-conn: now used by 2 (_lu_fsm_assoc
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH
DREF VLR subscr IMSI-901700000004620 - _lu_fsm_associate_vsub: now used by 1 (active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Allocated
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU)
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
-GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f00a0101
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f02801020a0101
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - mm_rx_loc_upd_req: now used by 2 (rx_from_ms,lu)
DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu)
@@ -94,9 +91,11 @@ DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: Au
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU)
-DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES
+DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_SUCCESS
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_ciph()
+DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000004620:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_node_4()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
DVLR upd_hlr_vlr_fsm(IMSI-901700000004620:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated
@@ -257,6 +256,8 @@ DVLR VLR_Authenticate(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: Received Event PR_ARQ_E_AUTH_RES
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2()
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2_post_ciph()
+DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2_post_vlr()
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_pres()
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_trace()
@@ -264,6 +265,7 @@ DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SER
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: proc_arq_fsm_done(PASSED)
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: state_chg to PR_ARQ_S_DONE
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_DONE}: Process Access Request result: PASSED
+DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: Sending DTAP: MM GSM48_MT_MM_CM_SERV_ACC
DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN encode: DTAP on GERAN-A
- DTAP --GERAN-A--> MS: GSM48_MT_MM_CM_SERV_ACC: 0521
DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
@@ -351,7 +353,7 @@ DMSC dummy_msc_i{0}: is child of msub_fsm
DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms)
DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3
DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: RR GSM48_MT_RR_PAG_RESP
-DRR msc_a(IMSI-901700000004620:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: Rx PAGING RESPONSE
+DRR msc_a(IMSI-901700000004620:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: Rx PAGING RESPONSE IMSI-901700000004620
DREF msc_a(IMSI-901700000004620:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: + paging-response: now used by 2 (rx_from_ms,paging-response)
DVLR Process_Access_Request_VLR(IMSI-901700000004620:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: Allocated
DVLR Process_Access_Request_VLR(IMSI-901700000004620:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: is child of msc_a(IMSI-901700000004620:GERAN-A:PAGING_RESP)
@@ -409,6 +411,8 @@ DVLR VLR_Authenticate(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){VLR
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_WAIT_AUTH}: Received Event PR_ARQ_E_AUTH_RES
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2()
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2_post_ciph()
+DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2_post_vlr()
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_pres()
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_trace()
@@ -427,6 +431,7 @@ DLSMS SMC(0) send CP data
DLSMS SMC(0) new CP state MM_CONN_PENDING -> WAIT_CP_ACK
DLSMS trans(SMS IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x40000001 tid-0) sending CP message (trans=0)
DLSMS trans(SMS IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x40000001 tid-0) GSM4.11 TX 09 01 58 01 00 07 91 44 77 58 10 06 50 00 4c 00 05 80 64 70 f1 00 00 07 10 10 00 00 00 00 44 50 79 da 1e 1e e7 41 69 37 48 5e 9e a7 c9 65 37 3d 1d 66 83 c2 70 38 3b 3d 0e d3 d3 6f f7 1c 94 9e 83 c2 20 72 79 9e 96 87 c5 ec 32 a8 1d 96 af cb f4 b4 fb 0c 7a c3 e9 e9 b7 db 05
+DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: Sending DTAP: SMS SMS:0x01
DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: RAN encode: DTAP on GERAN-A
- DTAP --GERAN-A--> MS: SMS:0x01: 09015801000791447758100650004c0005806470f1000007101000000000445079da1e1ee7416937485e9ea7c965373d1d6683c270383b3d0ed3d36ff71c949e83c22072799e9687c5ec32a81d96afcbf4b4fb0c7ac3e9e9b7db05
- DTAP matches expected message
@@ -463,6 +468,7 @@ DLSMS SMC(0) message MMSMS-DATA-IND (CP DATA) received in state MM_ESTABLISHED
DLSMS SMC(0) received CP-DATA
DLSMS trans(SMS IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x40000001 tid-0) sending CP message (trans=0)
DLSMS trans(SMS IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x40000001 tid-0) GSM4.11 TX 09 04
+DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: Sending DTAP: SMS SMS:0x04
DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: RAN encode: DTAP on GERAN-A
- DTAP --GERAN-A--> MS: SMS:0x04: 0904
- DTAP matches expected message
@@ -535,12 +541,13 @@ DMSC dummy_msc_i{0}: is child of msub_fsm
DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms)
DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3
DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: MM GSM48_MT_MM_IMSI_DETACH_IND
-DMM IMSI DETACH INDICATION: MI(IMSI)=901700000004620
+DMM IMSI DETACH INDICATION: IMSI-901700000004620
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + gsm48_rx_mm_imsi_detach_ind: now used by 2 (attached,gsm48_rx_mm_imsi_detach_ind)
DMM IMSI DETACH for IMSI-901700000004620:MSISDN-46071
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + active-conn: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn)
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn,vlr_subscr_cancel_attach_fsm)
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - attached: now used by 2 (gsm48_rx_mm_imsi_detach_ind,active-conn)
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - gsm48_rx_mm_imsi_detach_ind: now used by 1 (active-conn)
DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_CN_CLOSE
@@ -580,9 +587,6 @@ DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:NONE){MSC_A_ST_RELEASED}: D
llist_count(&msub_list) == 0
===== test_gsm_authen: SUCCESS
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 17
-
===== test_gsm_authen_tmsi
- Location Update request causes a GSUP Send Auth Info request to HLR
MSC <--GERAN-A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
@@ -611,13 +615,14 @@ DREF VLR subscr IMSI-901700000004620 + active-conn: now used by 2 (_lu_fsm_assoc
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH
DREF VLR subscr IMSI-901700000004620 - _lu_fsm_associate_vsub: now used by 1 (active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Allocated
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU)
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
-GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f00a0101
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f02801020a0101
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - mm_rx_loc_upd_req: now used by 2 (rx_from_ms,lu)
DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu)
@@ -675,9 +680,11 @@ DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: Au
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU)
-DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES
+DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_SUCCESS
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_ciph()
+DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000004620:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_node_4()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
DVLR upd_hlr_vlr_fsm(IMSI-901700000004620:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated
@@ -885,6 +892,8 @@ DVLR VLR_Authenticate(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: Received Event PR_ARQ_E_AUTH_RES
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2()
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2_post_ciph()
+DMSC msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2_post_vlr()
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_pres()
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_trace()
@@ -892,6 +901,7 @@ DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:TMSI-0x0302010
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: proc_arq_fsm_done(PASSED)
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: state_chg to PR_ARQ_S_DONE
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_DONE}: Process Access Request result: PASSED
+DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: Sending DTAP: MM GSM48_MT_MM_CM_SERV_ACC
DMSC msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN encode: DTAP on GERAN-A
- DTAP --GERAN-A--> MS: GSM48_MT_MM_CM_SERV_ACC: 0521
DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
@@ -979,7 +989,7 @@ DMSC dummy_msc_i{0}: is child of msub_fsm
DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms)
DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3
DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: RR GSM48_MT_RR_PAG_RESP
-DRR msc_a(TMSI-0x03020100:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: Rx PAGING RESPONSE
+DRR msc_a(TMSI-0x03020100:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: Rx PAGING RESPONSE TMSI-0x03020100
DREF msc_a(TMSI-0x03020100:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: + paging-response: now used by 2 (rx_from_ms,paging-response)
DVLR Process_Access_Request_VLR(TMSI-0x03020100:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: Allocated
DVLR Process_Access_Request_VLR(TMSI-0x03020100:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: is child of msc_a(TMSI-0x03020100:GERAN-A:PAGING_RESP)
@@ -1037,6 +1047,8 @@ DVLR VLR_Authenticate(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:PAGING_RESP){PR_ARQ_S_WAIT_AUTH}: Received Event PR_ARQ_E_AUTH_RES
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:PAGING_RESP){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2()
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:PAGING_RESP){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2_post_ciph()
+DMSC msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:PAGING_RESP){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2_post_vlr()
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:PAGING_RESP){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_pres()
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:PAGING_RESP){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_trace()
@@ -1055,6 +1067,7 @@ DLSMS SMC(0) send CP data
DLSMS SMC(0) new CP state MM_CONN_PENDING -> WAIT_CP_ACK
DLSMS trans(SMS IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:PAGING_RESP callref-0x40000002 tid-0) sending CP message (trans=0)
DLSMS trans(SMS IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:PAGING_RESP callref-0x40000002 tid-0) GSM4.11 TX 09 01 58 01 00 07 91 44 77 58 10 06 50 00 4c 00 05 80 64 70 f1 00 00 07 10 10 00 00 00 00 44 50 79 da 1e 1e e7 41 69 37 48 5e 9e a7 c9 65 37 3d 1d 66 83 c2 70 38 3b 3d 0e d3 d3 6f f7 1c 94 9e 83 c2 20 72 79 9e 96 87 c5 ec 32 a8 1d 96 af cb f4 b4 fb 0c 7a c3 e9 e9 b7 db 05
+DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: Sending DTAP: SMS SMS:0x01
DMSC msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: RAN encode: DTAP on GERAN-A
- DTAP --GERAN-A--> MS: SMS:0x01: 09015801000791447758100650004c0005806470f1000007101000000000445079da1e1ee7416937485e9ea7c965373d1d6683c270383b3d0ed3d36ff71c949e83c22072799e9687c5ec32a81d96afcbf4b4fb0c7ac3e9e9b7db05
- DTAP matches expected message
@@ -1091,6 +1104,7 @@ DLSMS SMC(0) message MMSMS-DATA-IND (CP DATA) received in state MM_ESTABLISHED
DLSMS SMC(0) received CP-DATA
DLSMS trans(SMS IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:PAGING_RESP callref-0x40000002 tid-0) sending CP message (trans=0)
DLSMS trans(SMS IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:PAGING_RESP callref-0x40000002 tid-0) GSM4.11 TX 09 04
+DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: Sending DTAP: SMS SMS:0x04
DMSC msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: RAN encode: DTAP on GERAN-A
- DTAP --GERAN-A--> MS: SMS:0x04: 0904
- DTAP matches expected message
@@ -1177,6 +1191,7 @@ DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100 + active-conn:
DMSC msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK
DMSC msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH
DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100 - _lu_fsm_associate_vsub: now used by 2 (attached,active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre()
DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH
@@ -1205,9 +1220,11 @@ DVLR VLR_Authenticate(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:
DVLR VLR_Authenticate(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
DVLR VLR_Authenticate(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
DVLR VLR_Authenticate(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:LU)
-DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES
+DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_SUCCESS
DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth()
DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_ciph()
+DMSC msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_node_4()
DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
DVLR upd_hlr_vlr_fsm(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated
@@ -1355,12 +1372,13 @@ DMSC dummy_msc_i{0}: is child of msub_fsm
DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms)
DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3
DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: MM GSM48_MT_MM_IMSI_DETACH_IND
-DMM IMSI DETACH INDICATION: MI(TMSI)=117835012
+DMM IMSI DETACH INDICATION: TMSI-0x07060504
DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x07060504 + gsm48_rx_mm_imsi_detach_ind: now used by 2 (attached,gsm48_rx_mm_imsi_detach_ind)
DMM IMSI DETACH for IMSI-901700000004620:MSISDN-46071:TMSI-0x07060504
DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x07060504 + active-conn: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn)
DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x07060504 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn,vlr_subscr_cancel_attach_fsm)
DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x07060504 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x07060504 - attached: now used by 2 (gsm48_rx_mm_imsi_detach_ind,active-conn)
DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x07060504 - gsm48_rx_mm_imsi_detach_ind: now used by 1 (active-conn)
DMSC msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x07060504:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_CN_CLOSE
@@ -1400,9 +1418,6 @@ DMSC msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x07060504:GERAN-A:NONE){MSC_A
llist_count(&msub_list) == 0
===== test_gsm_authen_tmsi: SUCCESS
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 17
-
===== test_gsm_authen_imei
- Location Update request causes a GSUP Send Auth Info request to HLR
MSC <--GERAN-A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
@@ -1431,13 +1446,14 @@ DREF VLR subscr IMSI-901700000004620 + active-conn: now used by 2 (_lu_fsm_assoc
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH
DREF VLR subscr IMSI-901700000004620 - _lu_fsm_associate_vsub: now used by 1 (active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Allocated
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU)
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
-GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f00a0101
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f02801020a0101
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - mm_rx_loc_upd_req: now used by 2 (rx_from_ms,lu)
DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu)
@@ -1495,9 +1511,11 @@ DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: Au
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU)
-DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES
+DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_SUCCESS
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_ciph()
+DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000004620:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_node_4()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
DVLR upd_hlr_vlr_fsm(IMSI-901700000004620:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated
@@ -1533,6 +1551,7 @@ DVLR lu_compl_vlr_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){LU_COMPL_VLR
DVLR lu_compl_vlr_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES
DVLR lu_compl_vlr_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL
DVLR lu_compl_vlr_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_WAIT_IMEI
+DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: Sending DTAP: MM GSM48_MT_MM_ID_REQ
DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: DTAP on GERAN-A
- DTAP --GERAN-A--> MS: GSM48_MT_MM_ID_REQ: 051802
- DTAP matches expected message
@@ -1568,7 +1587,7 @@ DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}:
DREF msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: + rx_from_ms: now used by 2 (lu,rx_from_ms)
DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN decode: DTAP
DRLL msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: Dispatching 04.08 message: MM GSM48_MT_MM_ID_RESP
-DMM IDENTITY RESPONSE: MI=IMEI-423423423423420
+DMM IDENTITY RESPONSE: IMEI-423423423423420
DVLR set IMEI on subscriber; IMSI=901700000004620 IMEI=42342342342342
DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_ID_IMEI
GSUP --> HLR: OSMO_GSUP_MSGT_CHECK_IMEI_REQUEST: 30010809710000004026f0500807244332244332240a0101
@@ -1666,12 +1685,13 @@ DMSC dummy_msc_i{0}: is child of msub_fsm
DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms)
DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3
DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: MM GSM48_MT_MM_IMSI_DETACH_IND
-DMM IMSI DETACH INDICATION: MI(IMSI)=901700000004620
+DMM IMSI DETACH INDICATION: IMSI-901700000004620
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + gsm48_rx_mm_imsi_detach_ind: now used by 2 (attached,gsm48_rx_mm_imsi_detach_ind)
DMM IMSI DETACH for IMSI-901700000004620:MSISDN-46071
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + active-conn: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn)
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn,vlr_subscr_cancel_attach_fsm)
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - attached: now used by 2 (gsm48_rx_mm_imsi_detach_ind,active-conn)
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - gsm48_rx_mm_imsi_detach_ind: now used by 1 (active-conn)
DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_CN_CLOSE
@@ -1711,9 +1731,6 @@ DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:NONE){MSC_A_ST_RELEASED}: D
llist_count(&msub_list) == 0
===== test_gsm_authen_imei: SUCCESS
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 17
-
===== test_gsm_authen_imei_nack
- Location Update request causes a GSUP Send Auth Info request to HLR
MSC <--GERAN-A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
@@ -1742,13 +1759,14 @@ DREF VLR subscr IMSI-901700000004620 + active-conn: now used by 2 (_lu_fsm_assoc
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH
DREF VLR subscr IMSI-901700000004620 - _lu_fsm_associate_vsub: now used by 1 (active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Allocated
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU)
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
-GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f00a0101
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f02801020a0101
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - mm_rx_loc_upd_req: now used by 2 (rx_from_ms,lu)
DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu)
@@ -1806,9 +1824,11 @@ DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: Au
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU)
-DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES
+DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_SUCCESS
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_ciph()
+DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000004620:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_node_4()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
DVLR upd_hlr_vlr_fsm(IMSI-901700000004620:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated
@@ -1844,6 +1864,7 @@ DVLR lu_compl_vlr_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){LU_COMPL_VLR
DVLR lu_compl_vlr_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES
DVLR lu_compl_vlr_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL
DVLR lu_compl_vlr_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_WAIT_IMEI
+DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: Sending DTAP: MM GSM48_MT_MM_ID_REQ
DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: DTAP on GERAN-A
- DTAP --GERAN-A--> MS: GSM48_MT_MM_ID_REQ: 051802
- DTAP matches expected message
@@ -1879,7 +1900,7 @@ DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}:
DREF msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: + rx_from_ms: now used by 2 (lu,rx_from_ms)
DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN decode: DTAP
DRLL msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: Dispatching 04.08 message: MM GSM48_MT_MM_ID_RESP
-DMM IDENTITY RESPONSE: MI=IMEI-423423423423420
+DMM IDENTITY RESPONSE: IMEI-423423423423420
DVLR set IMEI on subscriber; IMSI=901700000004620 IMEI=42342342342342
DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_ID_IMEI
GSUP --> HLR: OSMO_GSUP_MSGT_CHECK_IMEI_REQUEST: 30010809710000004026f0500807244332244332240a0101
@@ -1907,7 +1928,6 @@ DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}:
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + vlr_gsup_rx: now used by 2 (active-conn,vlr_gsup_rx)
DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_HLR_IMEI_NACK
DVLR lu_compl_vlr_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){LU_COMPL_VLR_S_WAIT_IMEI}: Received Event LU_COMPL_VLR_E_IMEI_CHECK_NACK
-- sending LU Reject for IMSI-901700000004620:MSISDN-46071:GERAN-A:LU, cause 6
DVLR lu_compl_vlr_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){LU_COMPL_VLR_S_WAIT_IMEI}: state_chg to LU_COMPL_VLR_S_DONE
DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_FAILURE
DVLR lu_compl_vlr_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
@@ -1927,7 +1947,6 @@ DREF msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_RELEASING}: +
DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_RELEASING}: RAN encode: CLEAR_COMMAND on GERAN-A
DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - msc_a_fsm_releasing_onenter: now used by 2 (active-conn,vlr_gsup_rx)
-DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_RELEASING}: transition to state MSC_A_ST_RELEASING not permitted!
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - vlr_gsup_rx: now used by 1 (active-conn)
<-- GSUP rx OSMO_GSUP_MSGT_CHECK_IMEI_RESULT: vlr_gsupc_read_cb() returns 0
msc_a_is_accepted() == false
@@ -1977,9 +1996,6 @@ DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_RELEASED}: Dea
llist_count(&msub_list) == 0
===== test_gsm_authen_imei_nack: SUCCESS
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 17
-
===== test_gsm_authen_imei_err
- Location Update request causes a GSUP Send Auth Info request to HLR
MSC <--GERAN-A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
@@ -2008,13 +2024,14 @@ DREF VLR subscr IMSI-901700000004620 + active-conn: now used by 2 (_lu_fsm_assoc
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH
DREF VLR subscr IMSI-901700000004620 - _lu_fsm_associate_vsub: now used by 1 (active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Allocated
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU)
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
-GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f00a0101
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f02801020a0101
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - mm_rx_loc_upd_req: now used by 2 (rx_from_ms,lu)
DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu)
@@ -2072,9 +2089,11 @@ DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: Au
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU)
-DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES
+DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_SUCCESS
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_ciph()
+DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000004620:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_node_4()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
DVLR upd_hlr_vlr_fsm(IMSI-901700000004620:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated
@@ -2110,6 +2129,7 @@ DVLR lu_compl_vlr_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){LU_COMPL_VLR
DVLR lu_compl_vlr_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES
DVLR lu_compl_vlr_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL
DVLR lu_compl_vlr_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_WAIT_IMEI
+DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: Sending DTAP: MM GSM48_MT_MM_ID_REQ
DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: DTAP on GERAN-A
- DTAP --GERAN-A--> MS: GSM48_MT_MM_ID_REQ: 051802
- DTAP matches expected message
@@ -2145,7 +2165,7 @@ DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}:
DREF msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: + rx_from_ms: now used by 2 (lu,rx_from_ms)
DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN decode: DTAP
DRLL msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: Dispatching 04.08 message: MM GSM48_MT_MM_ID_RESP
-DMM IDENTITY RESPONSE: MI=IMEI-423423423423420
+DMM IDENTITY RESPONSE: IMEI-423423423423420
DVLR set IMEI on subscriber; IMSI=901700000004620 IMEI=42342342342342
DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_ID_IMEI
GSUP --> HLR: OSMO_GSUP_MSGT_CHECK_IMEI_REQUEST: 30010809710000004026f0500807244332244332240a0101
@@ -2174,7 +2194,6 @@ DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + vlr_gsup_rx: now used by 2 (
DVLR SUBSCR(IMSI-901700000004620:MSISDN-46071) Check_IMEI_VLR failed; gmm_cause: Invalid mandatory information
DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_HLR_IMEI_NACK
DVLR lu_compl_vlr_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){LU_COMPL_VLR_S_WAIT_IMEI}: Received Event LU_COMPL_VLR_E_IMEI_CHECK_NACK
-- sending LU Reject for IMSI-901700000004620:MSISDN-46071:GERAN-A:LU, cause 6
DVLR lu_compl_vlr_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){LU_COMPL_VLR_S_WAIT_IMEI}: state_chg to LU_COMPL_VLR_S_DONE
DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_FAILURE
DVLR lu_compl_vlr_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
@@ -2194,7 +2213,6 @@ DREF msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_RELEASING}: +
DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_RELEASING}: RAN encode: CLEAR_COMMAND on GERAN-A
DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - msc_a_fsm_releasing_onenter: now used by 2 (active-conn,vlr_gsup_rx)
-DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_RELEASING}: transition to state MSC_A_ST_RELEASING not permitted!
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - vlr_gsup_rx: now used by 1 (active-conn)
<-- GSUP rx OSMO_GSUP_MSGT_CHECK_IMEI_ERROR: vlr_gsupc_read_cb() returns 0
msc_a_is_accepted() == false
@@ -2244,9 +2262,6 @@ DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_RELEASED}: Dea
llist_count(&msub_list) == 0
===== test_gsm_authen_imei_err: SUCCESS
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 17
-
===== test_gsm_authen_tmsi_imei
- Location Update request causes a GSUP Send Auth Info request to HLR
MSC <--GERAN-A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
@@ -2275,13 +2290,14 @@ DREF VLR subscr IMSI-901700000004620 + active-conn: now used by 2 (_lu_fsm_assoc
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH
DREF VLR subscr IMSI-901700000004620 - _lu_fsm_associate_vsub: now used by 1 (active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Allocated
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU)
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
-GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f00a0101
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f02801020a0101
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - mm_rx_loc_upd_req: now used by 2 (rx_from_ms,lu)
DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu)
@@ -2339,9 +2355,11 @@ DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: Au
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU)
-DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES
+DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_SUCCESS
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_ciph()
+DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000004620:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_node_4()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
DVLR upd_hlr_vlr_fsm(IMSI-901700000004620:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated
@@ -2377,6 +2395,7 @@ DVLR lu_compl_vlr_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){LU_COMPL_VLR
DVLR lu_compl_vlr_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES
DVLR lu_compl_vlr_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL
DVLR lu_compl_vlr_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_WAIT_IMEI_TMSI
+DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: Sending DTAP: MM GSM48_MT_MM_ID_REQ
DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: DTAP on GERAN-A
- DTAP --GERAN-A--> MS: GSM48_MT_MM_ID_REQ: 051802
- DTAP matches expected message
@@ -2412,7 +2431,7 @@ DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}:
DREF msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: + rx_from_ms: now used by 2 (lu,rx_from_ms)
DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN decode: DTAP
DRLL msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: Dispatching 04.08 message: MM GSM48_MT_MM_ID_RESP
-DMM IDENTITY RESPONSE: MI=IMEI-423423423423420
+DMM IDENTITY RESPONSE: IMEI-423423423423420
DVLR set IMEI on subscriber; IMSI=901700000004620 IMEI=42342342342342
DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_ID_IMEI
GSUP --> HLR: OSMO_GSUP_MSGT_CHECK_IMEI_REQUEST: 30010809710000004026f0500807244332244332240a0101
@@ -2551,12 +2570,13 @@ DMSC dummy_msc_i{0}: is child of msub_fsm
DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms)
DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3
DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: MM GSM48_MT_MM_IMSI_DETACH_IND
-DMM IMSI DETACH INDICATION: MI(TMSI)=50462976
+DMM IMSI DETACH INDICATION: TMSI-0x03020100
DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100 + gsm48_rx_mm_imsi_detach_ind: now used by 2 (attached,gsm48_rx_mm_imsi_detach_ind)
DMM IMSI DETACH for IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100
DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100 + active-conn: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn)
DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn,vlr_subscr_cancel_attach_fsm)
DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100 - attached: now used by 2 (gsm48_rx_mm_imsi_detach_ind,active-conn)
DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100 - gsm48_rx_mm_imsi_detach_ind: now used by 1 (active-conn)
DMSC msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_CN_CLOSE
@@ -2596,9 +2616,6 @@ DMSC msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:NONE){MSC_A
llist_count(&msub_list) == 0
===== test_gsm_authen_tmsi_imei: SUCCESS
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 17
-
===== test_gsm_milenage_authen
- Location Update request causes a GSUP Send Auth Info request to HLR
MSC <--GERAN-A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
@@ -2627,13 +2644,14 @@ DREF VLR subscr IMSI-901700000010650 + active-conn: now used by 2 (_lu_fsm_assoc
DMSC msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK
DMSC msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH
DREF VLR subscr IMSI-901700000010650 - _lu_fsm_associate_vsub: now used by 1 (active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre()
DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH
DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Allocated
DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU)
DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
-GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f00a0101
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f02801020a0101
DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
DREF msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - mm_rx_loc_upd_req: now used by 2 (rx_from_ms,lu)
DREF msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu)
@@ -2665,9 +2683,11 @@ DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: Au
DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU)
-DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES
+DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_SUCCESS
DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth()
DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_ciph()
+DMSC msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000010650:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_node_4()
DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
DVLR upd_hlr_vlr_fsm(IMSI-901700000010650:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated
@@ -2828,6 +2848,8 @@ DVLR VLR_Authenticate(IMSI-901700000010650:MSISDN-42342:GERAN-A:CM_SERVICE_REQ){
DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: Received Event PR_ARQ_E_AUTH_RES
DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2()
DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2_post_ciph()
+DMSC msc_a(IMSI-901700000010650:MSISDN-42342:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2_post_vlr()
DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_pres()
DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_trace()
@@ -2835,6 +2857,7 @@ DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:GERAN-A:CM_SER
DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: proc_arq_fsm_done(PASSED)
DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: state_chg to PR_ARQ_S_DONE
DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_DONE}: Process Access Request result: PASSED
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-42342:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: Sending DTAP: MM GSM48_MT_MM_CM_SERV_ACC
DMSC msc_a(IMSI-901700000010650:MSISDN-42342:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN encode: DTAP on GERAN-A
- DTAP --GERAN-A--> MS: GSM48_MT_MM_CM_SERV_ACC: 0521
DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
@@ -2922,7 +2945,7 @@ DMSC dummy_msc_i{0}: is child of msub_fsm
DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms)
DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3
DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: RR GSM48_MT_RR_PAG_RESP
-DRR msc_a(IMSI-901700000010650:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: Rx PAGING RESPONSE
+DRR msc_a(IMSI-901700000010650:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: Rx PAGING RESPONSE IMSI-901700000010650
DREF msc_a(IMSI-901700000010650:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: + paging-response: now used by 2 (rx_from_ms,paging-response)
DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: Allocated
DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: is child of msc_a(IMSI-901700000010650:GERAN-A:PAGING_RESP)
@@ -2980,6 +3003,8 @@ DVLR VLR_Authenticate(IMSI-901700000010650:MSISDN-42342:GERAN-A:PAGING_RESP){VLR
DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:GERAN-A:PAGING_RESP){PR_ARQ_S_WAIT_AUTH}: Received Event PR_ARQ_E_AUTH_RES
DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:GERAN-A:PAGING_RESP){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2()
DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:GERAN-A:PAGING_RESP){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2_post_ciph()
+DMSC msc_a(IMSI-901700000010650:MSISDN-42342:GERAN-A:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:GERAN-A:PAGING_RESP){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2_post_vlr()
DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:GERAN-A:PAGING_RESP){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_pres()
DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:GERAN-A:PAGING_RESP){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_trace()
@@ -2998,6 +3023,7 @@ DLSMS SMC(0) send CP data
DLSMS SMC(0) new CP state MM_CONN_PENDING -> WAIT_CP_ACK
DLSMS trans(SMS IMSI-901700000010650:MSISDN-42342:GERAN-A:PAGING_RESP callref-0x40000003 tid-0) sending CP message (trans=0)
DLSMS trans(SMS IMSI-901700000010650:MSISDN-42342:GERAN-A:PAGING_RESP callref-0x40000003 tid-0) GSM4.11 TX 09 01 58 01 00 07 91 44 77 58 10 06 50 00 4c 00 05 80 24 43 f2 00 00 07 10 10 00 00 00 00 44 50 79 da 1e 1e e7 41 69 37 48 5e 9e a7 c9 65 37 3d 1d 66 83 c2 70 38 3b 3d 0e d3 d3 6f f7 1c 94 9e 83 c2 20 72 79 9e 96 87 c5 ec 32 a8 1d 96 af cb f4 b4 fb 0c 7a c3 e9 e9 b7 db 05
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-42342:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: Sending DTAP: SMS SMS:0x01
DMSC msc_a(IMSI-901700000010650:MSISDN-42342:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: RAN encode: DTAP on GERAN-A
- DTAP --GERAN-A--> MS: SMS:0x01: 09015801000791447758100650004c0005802443f2000007101000000000445079da1e1ee7416937485e9ea7c965373d1d6683c270383b3d0ed3d36ff71c949e83c22072799e9687c5ec32a81d96afcbf4b4fb0c7ac3e9e9b7db05
- DTAP matches expected message
@@ -3034,6 +3060,7 @@ DLSMS SMC(0) message MMSMS-DATA-IND (CP DATA) received in state MM_ESTABLISHED
DLSMS SMC(0) received CP-DATA
DLSMS trans(SMS IMSI-901700000010650:MSISDN-42342:GERAN-A:PAGING_RESP callref-0x40000003 tid-0) sending CP message (trans=0)
DLSMS trans(SMS IMSI-901700000010650:MSISDN-42342:GERAN-A:PAGING_RESP callref-0x40000003 tid-0) GSM4.11 TX 09 04
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-42342:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: Sending DTAP: SMS SMS:0x04
DMSC msc_a(IMSI-901700000010650:MSISDN-42342:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: RAN encode: DTAP on GERAN-A
- DTAP --GERAN-A--> MS: SMS:0x04: 0904
- DTAP matches expected message
@@ -3106,12 +3133,13 @@ DMSC dummy_msc_i{0}: is child of msub_fsm
DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms)
DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3
DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: MM GSM48_MT_MM_IMSI_DETACH_IND
-DMM IMSI DETACH INDICATION: MI(IMSI)=901700000010650
+DMM IMSI DETACH INDICATION: IMSI-901700000010650
DREF VLR subscr IMSI-901700000010650:MSISDN-42342 + gsm48_rx_mm_imsi_detach_ind: now used by 2 (attached,gsm48_rx_mm_imsi_detach_ind)
DMM IMSI DETACH for IMSI-901700000010650:MSISDN-42342
DREF VLR subscr IMSI-901700000010650:MSISDN-42342 + active-conn: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn)
DREF VLR subscr IMSI-901700000010650:MSISDN-42342 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn,vlr_subscr_cancel_attach_fsm)
DREF VLR subscr IMSI-901700000010650:MSISDN-42342 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DREF VLR subscr IMSI-901700000010650:MSISDN-42342 - attached: now used by 2 (gsm48_rx_mm_imsi_detach_ind,active-conn)
DREF VLR subscr IMSI-901700000010650:MSISDN-42342 - gsm48_rx_mm_imsi_detach_ind: now used by 1 (active-conn)
DMSC msc_a(IMSI-901700000010650:MSISDN-42342:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_CN_CLOSE
@@ -3151,9 +3179,6 @@ DMSC msc_a(IMSI-901700000010650:MSISDN-42342:GERAN-A:NONE){MSC_A_ST_RELEASED}: D
llist_count(&msub_list) == 0
===== test_gsm_milenage_authen: SUCCESS
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 17
-
===== test_wrong_sres_length
- Total time passed: 0.000000 s
- Location Update request causes a GSUP Send Auth Info request to HLR
@@ -3183,13 +3208,14 @@ DREF VLR subscr IMSI-901700000004620 + active-conn: now used by 2 (_lu_fsm_assoc
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH
DREF VLR subscr IMSI-901700000004620 - _lu_fsm_associate_vsub: now used by 1 (active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Allocated
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU)
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
-GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f00a0101
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f02801020a0101
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - mm_rx_loc_upd_req: now used by 2 (rx_from_ms,lu)
DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu)
@@ -3245,12 +3271,12 @@ DMM msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: MM GSM AUTHENTIC
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP
DVLR SUBSCR(IMSI-901700000004620) AUTH on GERAN received SRES/RES: (0 bytes)
DVLR SUBSCR(IMSI-901700000004620) AUTH SRES/RES missing
-DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result Illegal MS
+DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result FAILURE, cause ILLEGAL_MS
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTH_FAILED
GSUP --> HLR: OSMO_GSUP_MSGT_AUTH_FAIL_REPORT: 0b010809710000004026f00a0101
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_AUTH_FAILED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_AUTH_FAILED}: Removing from parent vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU)
-DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES
+DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_FAILURE
- sending LU Reject for IMSI-901700000004620:GERAN-A:LU, cause 3
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_DONE
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: Received Event MSC_A_EV_CN_CLOSE
@@ -3296,9 +3322,3 @@ DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_RELEASED}: Deallocated, inc
llist_count(&msub_list) == 0
===== test_wrong_sres_length: SUCCESS
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 17
-
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 17
-
diff --git a/tests/msc_vlr/msc_vlr_test_gsm_ciph.c b/tests/msc_vlr/msc_vlr_test_gsm_ciph.c
index ceb17a5fe..38a5caff0 100644
--- a/tests/msc_vlr/msc_vlr_test_gsm_ciph.c
+++ b/tests/msc_vlr/msc_vlr_test_gsm_ciph.c
@@ -22,7 +22,6 @@
*/
#include "msc_vlr_tests.h"
-#include "stubs.h"
static const struct osmo_gsm48_classmark classmark = {
// TODO
@@ -41,7 +40,7 @@ static void test_ciph()
btw("Location Update request causes a GSUP Send Auth Info request to HLR");
lu_result_sent = RES_NONE;
- gsup_expect_tx("08010809710000004026f0" VLR_TO_HLR);
+ gsup_expect_tx("08010809710000004026f0" CN_DOMAIN VLR_TO_HLR);
ms_sends_msg("050802008168000130089910070000006402");
OSMO_ASSERT(gsup_tx_confirmed);
VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
@@ -83,7 +82,7 @@ static void test_ciph()
VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
btw("MS sends Ciphering Mode Complete, VLR accepts and sends GSUP LU Req to HLR");
- gsup_expect_tx("04010809710000004026f0280102" VLR_TO_HLR);
+ gsup_expect_tx("04010809710000004026f0" CN_DOMAIN VLR_TO_HLR);
ms_sends_ciphering_mode_complete(NULL);
VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
@@ -129,7 +128,7 @@ static void test_ciph()
VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d");
/* Release connection */
- expect_bssap_clear(OSMO_RAT_GERAN_A);
+ expect_bssap_clear();
conn_conclude_cm_service_req(g_msub, MSC_A_USE_CM_SERVICE_SMS);
btw("all requests serviced, conn has been released");
@@ -250,7 +249,7 @@ static void test_ciph_tmsi()
btw("Location Update request causes a GSUP Send Auth Info request to HLR");
lu_result_sent = RES_NONE;
- gsup_expect_tx("08010809710000004026f0" VLR_TO_HLR);
+ gsup_expect_tx("08010809710000004026f0" CN_DOMAIN VLR_TO_HLR);
ms_sends_msg("050802008168000130089910070000006402");
OSMO_ASSERT(gsup_tx_confirmed);
VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
@@ -293,7 +292,7 @@ static void test_ciph_tmsi()
VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
btw("MS sends Ciphering Mode Complete, VLR accepts and sends GSUP LU Req to HLR");
- gsup_expect_tx("04010809710000004026f0280102" VLR_TO_HLR);
+ gsup_expect_tx("04010809710000004026f0" CN_DOMAIN VLR_TO_HLR);
ms_sends_ciphering_mode_complete(NULL);
VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
@@ -364,7 +363,7 @@ static void test_ciph_tmsi()
VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d");
/* Release connection */
- expect_bssap_clear(OSMO_RAT_GERAN_A);
+ expect_bssap_clear();
conn_conclude_cm_service_req(g_msub, MSC_A_USE_CM_SERVICE_SMS);
btw("all requests serviced, conn has been released");
@@ -485,7 +484,7 @@ static void test_ciph_imei()
btw("Location Update request causes a GSUP Send Auth Info request to HLR");
lu_result_sent = RES_NONE;
- gsup_expect_tx("08010809710000004026f0" VLR_TO_HLR);
+ gsup_expect_tx("08010809710000004026f0" CN_DOMAIN VLR_TO_HLR);
ms_sends_msg("050802008168000130089910070000006402");
OSMO_ASSERT(gsup_tx_confirmed);
VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
@@ -527,7 +526,7 @@ static void test_ciph_imei()
VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
btw("MS sends Ciphering Mode Complete, VLR accepts and sends GSUP LU Req to HLR");
- gsup_expect_tx("04010809710000004026f0280102" VLR_TO_HLR);
+ gsup_expect_tx("04010809710000004026f0" CN_DOMAIN VLR_TO_HLR);
ms_sends_ciphering_mode_complete(NULL);
VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
@@ -595,7 +594,7 @@ static void test_ciph_imeisv()
btw("Location Update request causes a GSUP Send Auth Info request to HLR");
lu_result_sent = RES_NONE;
- gsup_expect_tx("08010809710000004026f0" VLR_TO_HLR);
+ gsup_expect_tx("08010809710000004026f0" CN_DOMAIN VLR_TO_HLR);
ms_sends_msg("050802008168000130089910070000006402");
OSMO_ASSERT(gsup_tx_confirmed);
VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
@@ -643,8 +642,8 @@ static void test_ciph_imeisv()
vlr_subscr_put(vsub, __func__);
btw("MS sends Ciphering Mode Complete with IMEISV, VLR accepts and sends GSUP LU Req to HLR");
- gsup_expect_tx("04010809710000004026f0280102" VLR_TO_HLR);
- ms_sends_ciphering_mode_complete("063217094b32244332244372f5");
+ gsup_expect_tx("04010809710000004026f0" CN_DOMAIN VLR_TO_HLR);
+ ms_sends_ciphering_mode_complete("063217094332244332244372f5");
VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
btw("Subscriber has the IMEISV");
@@ -696,7 +695,7 @@ static void test_ciph_tmsi_imei()
btw("Location Update request causes a GSUP Send Auth Info request to HLR");
lu_result_sent = RES_NONE;
- gsup_expect_tx("08010809710000004026f0" VLR_TO_HLR);
+ gsup_expect_tx("08010809710000004026f0" CN_DOMAIN VLR_TO_HLR);
ms_sends_msg("050802008168000130089910070000006402");
OSMO_ASSERT(gsup_tx_confirmed);
VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
@@ -738,7 +737,7 @@ static void test_ciph_tmsi_imei()
VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
btw("MS sends Ciphering Mode Complete, VLR accepts and sends GSUP LU Req to HLR");
- gsup_expect_tx("04010809710000004026f0280102" VLR_TO_HLR);
+ gsup_expect_tx("04010809710000004026f0" CN_DOMAIN VLR_TO_HLR);
ms_sends_ciphering_mode_complete(NULL);
VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
@@ -845,7 +844,7 @@ static void test_gsm_ciph_in_umts_env()
btw("Location Update request causes a GSUP Send Auth Info request to HLR");
lu_result_sent = RES_NONE;
- gsup_expect_tx("080108" "09710000000156f0" VLR_TO_HLR);
+ gsup_expect_tx("080108" "09710000000156f0" CN_DOMAIN VLR_TO_HLR);
ms_sends_msg("0508" /* MM LU */
"7" /* ciph key seq: no key available */
"0" /* LU type: normal */
@@ -923,7 +922,7 @@ static void test_gsm_ciph_in_umts_env()
VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
btw("MS sends Ciphering Mode Complete, VLR accepts and sends GSUP LU Req to HLR");
- gsup_expect_tx("04010809710000000156f0280102" VLR_TO_HLR);
+ gsup_expect_tx("04010809710000000156f0" CN_DOMAIN VLR_TO_HLR);
ms_sends_ciphering_mode_complete(NULL);
VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
@@ -968,7 +967,7 @@ static void test_gsm_ciph_in_umts_env()
VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d");
/* Release connection */
- expect_bssap_clear(OSMO_RAT_GERAN_A);
+ expect_bssap_clear();
conn_conclude_cm_service_req(g_msub, MSC_A_USE_CM_SERVICE_SMS);
btw("all requests serviced, conn has been released");
@@ -1068,7 +1067,7 @@ static void test_a5_3_supported()
btw("Location Update request causes a GSUP Send Auth Info request to HLR");
lu_result_sent = RES_NONE;
- gsup_expect_tx("08010809710000004026f0" VLR_TO_HLR);
+ gsup_expect_tx("08010809710000004026f0" CN_DOMAIN VLR_TO_HLR);
ms_sends_msg("050802008168000130089910070000006402");
OSMO_ASSERT(gsup_tx_confirmed);
VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
@@ -1112,7 +1111,7 @@ static void test_a5_3_supported()
VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
btw("MS sends Ciphering Mode Complete, VLR accepts and sends GSUP LU Req to HLR");
- gsup_expect_tx("04010809710000004026f0280102" VLR_TO_HLR);
+ gsup_expect_tx("04010809710000004026f0" CN_DOMAIN VLR_TO_HLR);
ms_sends_ciphering_mode_complete(NULL);
VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
@@ -1159,7 +1158,7 @@ static void test_a5_3_supported()
VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d");
/* Release connection */
- expect_bssap_clear(OSMO_RAT_GERAN_A);
+ expect_bssap_clear();
conn_conclude_cm_service_req(g_msub, MSC_A_USE_CM_SERVICE_SMS);
btw("all requests serviced, conn has been released");
@@ -1268,7 +1267,7 @@ static void test_a5_3_supported()
}
/* During CM Service Request or Paging Response we already have Classmark 2 that indicates A5/3
- * availablity. Here, in a hacky way remove the knowledge of Classmark 2 to tickle a code path where
+ * availability. Here, in a hacky way remove the knowledge of Classmark 2 to tickle a code path where
* proc_arq_fsm needs a Classmark Update during Ciphering. Shouldn't happen in reality though. */
static void test_cm_service_needs_classmark_update()
{
@@ -1284,7 +1283,7 @@ static void test_cm_service_needs_classmark_update()
btw("Location Update request causes a GSUP Send Auth Info request to HLR");
lu_result_sent = RES_NONE;
- gsup_expect_tx("08010809710000004026f0" VLR_TO_HLR);
+ gsup_expect_tx("08010809710000004026f0" CN_DOMAIN VLR_TO_HLR);
ms_sends_msg("050802008168000130089910070000006402");
OSMO_ASSERT(gsup_tx_confirmed);
VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
@@ -1328,7 +1327,7 @@ static void test_cm_service_needs_classmark_update()
VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
btw("MS sends Ciphering Mode Complete, VLR accepts and sends GSUP LU Req to HLR");
- gsup_expect_tx("04010809710000004026f0280102" VLR_TO_HLR);
+ gsup_expect_tx("04010809710000004026f0" CN_DOMAIN VLR_TO_HLR);
ms_sends_ciphering_mode_complete(NULL);
VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
@@ -1376,7 +1375,7 @@ static void test_cm_service_needs_classmark_update()
VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d");
/* Release connection */
- expect_bssap_clear(OSMO_RAT_GERAN_A);
+ expect_bssap_clear();
conn_conclude_cm_service_req(g_msub, MSC_A_USE_CM_SERVICE_SMS);
btw("all requests serviced, conn has been released");
diff --git a/tests/msc_vlr/msc_vlr_test_gsm_ciph.err b/tests/msc_vlr/msc_vlr_test_gsm_ciph.err
index b527f05af..afea400c8 100644
--- a/tests/msc_vlr/msc_vlr_test_gsm_ciph.err
+++ b/tests/msc_vlr/msc_vlr_test_gsm_ciph.err
@@ -1,7 +1,3 @@
-DLMGCP MGCP client: using endpoint domain '@mgw'
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 17
-
===== test_ciph
- Location Update request causes a GSUP Send Auth Info request to HLR
MSC <--GERAN-A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
@@ -30,13 +26,14 @@ DREF VLR subscr IMSI-901700000004620 + active-conn: now used by 2 (_lu_fsm_assoc
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH
DREF VLR subscr IMSI-901700000004620 - _lu_fsm_associate_vsub: now used by 1 (active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Allocated
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU)
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
-GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f00a0101
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f02801020a0101
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - mm_rx_loc_upd_req: now used by 2 (rx_from_ms,lu)
DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu)
@@ -68,7 +65,7 @@ DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: Au
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU)
-DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES
+DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_SUCCESS
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Set Ciphering Mode
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: CIPHER_MODE_COMMAND on GERAN-A
@@ -105,6 +102,8 @@ DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: + ms_sends_ciph
DBSSAP msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN decode: CIPHER_MODE_COMPLETE
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_CIPH}: Received Event VLR_ULA_E_CIPH_RES
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_CIPH}: vlr_loc_upd_post_ciph()
+DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000004620:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_CIPH}: vlr_loc_upd_node_4()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_CIPH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
DVLR upd_hlr_vlr_fsm(IMSI-901700000004620:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated
@@ -298,6 +297,8 @@ DREF msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AU
DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN decode: CIPHER_MODE_COMPLETE
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_CIPH}: Received Event PR_ARQ_E_CIPH_RES
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_node2_post_ciph()
+DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_node2_post_vlr()
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_pres()
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_trace()
@@ -388,7 +389,7 @@ DMSC dummy_msc_i{0}: is child of msub_fsm
DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms)
DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3
DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: RR GSM48_MT_RR_PAG_RESP
-DRR msc_a(IMSI-901700000004620:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: Rx PAGING RESPONSE
+DRR msc_a(IMSI-901700000004620:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: Rx PAGING RESPONSE IMSI-901700000004620
DREF msc_a(IMSI-901700000004620:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: + paging-response: now used by 2 (rx_from_ms,paging-response)
DVLR Process_Access_Request_VLR(IMSI-901700000004620:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: Allocated
DVLR Process_Access_Request_VLR(IMSI-901700000004620:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: is child of msc_a(IMSI-901700000004620:GERAN-A:PAGING_RESP)
@@ -479,6 +480,8 @@ DREF msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTH_
DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: RAN decode: CIPHER_MODE_COMPLETE
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_WAIT_CIPH}: Received Event PR_ARQ_E_CIPH_RES
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_node2_post_ciph()
+DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_node2_post_vlr()
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_pres()
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_trace()
@@ -497,6 +500,7 @@ DLSMS SMC(0) send CP data
DLSMS SMC(0) new CP state MM_CONN_PENDING -> WAIT_CP_ACK
DLSMS trans(SMS IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x40000001 tid-0) sending CP message (trans=0)
DLSMS trans(SMS IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x40000001 tid-0) GSM4.11 TX 09 01 58 01 00 07 91 44 77 58 10 06 50 00 4c 00 05 80 64 70 f1 00 00 07 10 10 00 00 00 00 44 50 79 da 1e 1e e7 41 69 37 48 5e 9e a7 c9 65 37 3d 1d 66 83 c2 70 38 3b 3d 0e d3 d3 6f f7 1c 94 9e 83 c2 20 72 79 9e 96 87 c5 ec 32 a8 1d 96 af cb f4 b4 fb 0c 7a c3 e9 e9 b7 db 05
+DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: Sending DTAP: SMS SMS:0x01
DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: RAN encode: DTAP on GERAN-A
- DTAP --GERAN-A--> MS: SMS:0x01: 09015801000791447758100650004c0005806470f1000007101000000000445079da1e1ee7416937485e9ea7c965373d1d6683c270383b3d0ed3d36ff71c949e83c22072799e9687c5ec32a81d96afcbf4b4fb0c7ac3e9e9b7db05
- DTAP matches expected message
@@ -532,6 +536,7 @@ DLSMS SMC(0) message MMSMS-DATA-IND (CP DATA) received in state MM_ESTABLISHED
DLSMS SMC(0) received CP-DATA
DLSMS trans(SMS IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x40000001 tid-0) sending CP message (trans=0)
DLSMS trans(SMS IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x40000001 tid-0) GSM4.11 TX 09 04
+DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: Sending DTAP: SMS SMS:0x04
DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: RAN encode: DTAP on GERAN-A
- DTAP --GERAN-A--> MS: SMS:0x04: 0904
- DTAP matches expected message
@@ -604,12 +609,13 @@ DMSC dummy_msc_i{0}: is child of msub_fsm
DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms)
DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3
DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: MM GSM48_MT_MM_IMSI_DETACH_IND
-DMM IMSI DETACH INDICATION: MI(IMSI)=901700000004620
+DMM IMSI DETACH INDICATION: IMSI-901700000004620
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + gsm48_rx_mm_imsi_detach_ind: now used by 2 (attached,gsm48_rx_mm_imsi_detach_ind)
DMM IMSI DETACH for IMSI-901700000004620:MSISDN-46071
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + active-conn: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn)
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn,vlr_subscr_cancel_attach_fsm)
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - attached: now used by 2 (gsm48_rx_mm_imsi_detach_ind,active-conn)
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - gsm48_rx_mm_imsi_detach_ind: now used by 1 (active-conn)
DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_CN_CLOSE
@@ -649,9 +655,6 @@ DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:NONE){MSC_A_ST_RELEASED}: D
llist_count(&msub_list) == 0
===== test_ciph: SUCCESS
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 17
-
===== test_ciph_tmsi
- Location Update request causes a GSUP Send Auth Info request to HLR
MSC <--GERAN-A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
@@ -680,13 +683,14 @@ DREF VLR subscr IMSI-901700000004620 + active-conn: now used by 2 (_lu_fsm_assoc
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH
DREF VLR subscr IMSI-901700000004620 - _lu_fsm_associate_vsub: now used by 1 (active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Allocated
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU)
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
-GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f00a0101
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f02801020a0101
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - mm_rx_loc_upd_req: now used by 2 (rx_from_ms,lu)
DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu)
@@ -718,7 +722,7 @@ DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: Au
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU)
-DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES
+DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_SUCCESS
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Set Ciphering Mode
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: CIPHER_MODE_COMMAND on GERAN-A
@@ -756,6 +760,8 @@ DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: + ms_sends_ciph
DBSSAP msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN decode: CIPHER_MODE_COMPLETE
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_CIPH}: Received Event VLR_ULA_E_CIPH_RES
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_CIPH}: vlr_loc_upd_post_ciph()
+DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000004620:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_CIPH}: vlr_loc_upd_node_4()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_CIPH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
DVLR upd_hlr_vlr_fsm(IMSI-901700000004620:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated
@@ -996,6 +1002,8 @@ DREF msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:CM_SERVICE_
DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN decode: CIPHER_MODE_COMPLETE
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_CIPH}: Received Event PR_ARQ_E_CIPH_RES
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_node2_post_ciph()
+DMSC msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_node2_post_vlr()
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_pres()
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_trace()
@@ -1086,7 +1094,7 @@ DMSC dummy_msc_i{0}: is child of msub_fsm
DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms)
DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3
DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: RR GSM48_MT_RR_PAG_RESP
-DRR msc_a(TMSI-0x03020100:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: Rx PAGING RESPONSE
+DRR msc_a(TMSI-0x03020100:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: Rx PAGING RESPONSE TMSI-0x03020100
DREF msc_a(TMSI-0x03020100:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: + paging-response: now used by 2 (rx_from_ms,paging-response)
DVLR Process_Access_Request_VLR(TMSI-0x03020100:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: Allocated
DVLR Process_Access_Request_VLR(TMSI-0x03020100:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: is child of msc_a(TMSI-0x03020100:GERAN-A:PAGING_RESP)
@@ -1177,6 +1185,8 @@ DREF msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:PAGING_RESP
DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: RAN decode: CIPHER_MODE_COMPLETE
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:PAGING_RESP){PR_ARQ_S_WAIT_CIPH}: Received Event PR_ARQ_E_CIPH_RES
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:PAGING_RESP){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_node2_post_ciph()
+DMSC msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:PAGING_RESP){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_node2_post_vlr()
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:PAGING_RESP){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_pres()
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:PAGING_RESP){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_trace()
@@ -1195,6 +1205,7 @@ DLSMS SMC(0) send CP data
DLSMS SMC(0) new CP state MM_CONN_PENDING -> WAIT_CP_ACK
DLSMS trans(SMS IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:PAGING_RESP callref-0x40000002 tid-0) sending CP message (trans=0)
DLSMS trans(SMS IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:PAGING_RESP callref-0x40000002 tid-0) GSM4.11 TX 09 01 58 01 00 07 91 44 77 58 10 06 50 00 4c 00 05 80 64 70 f1 00 00 07 10 10 00 00 00 00 44 50 79 da 1e 1e e7 41 69 37 48 5e 9e a7 c9 65 37 3d 1d 66 83 c2 70 38 3b 3d 0e d3 d3 6f f7 1c 94 9e 83 c2 20 72 79 9e 96 87 c5 ec 32 a8 1d 96 af cb f4 b4 fb 0c 7a c3 e9 e9 b7 db 05
+DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: Sending DTAP: SMS SMS:0x01
DMSC msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: RAN encode: DTAP on GERAN-A
- DTAP --GERAN-A--> MS: SMS:0x01: 09015801000791447758100650004c0005806470f1000007101000000000445079da1e1ee7416937485e9ea7c965373d1d6683c270383b3d0ed3d36ff71c949e83c22072799e9687c5ec32a81d96afcbf4b4fb0c7ac3e9e9b7db05
- DTAP matches expected message
@@ -1230,6 +1241,7 @@ DLSMS SMC(0) message MMSMS-DATA-IND (CP DATA) received in state MM_ESTABLISHED
DLSMS SMC(0) received CP-DATA
DLSMS trans(SMS IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:PAGING_RESP callref-0x40000002 tid-0) sending CP message (trans=0)
DLSMS trans(SMS IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:PAGING_RESP callref-0x40000002 tid-0) GSM4.11 TX 09 04
+DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: Sending DTAP: SMS SMS:0x04
DMSC msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: RAN encode: DTAP on GERAN-A
- DTAP --GERAN-A--> MS: SMS:0x04: 0904
- DTAP matches expected message
@@ -1302,12 +1314,13 @@ DMSC dummy_msc_i{0}: is child of msub_fsm
DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms)
DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3
DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: MM GSM48_MT_MM_IMSI_DETACH_IND
-DMM IMSI DETACH INDICATION: MI(TMSI)=50462976
+DMM IMSI DETACH INDICATION: TMSI-0x03020100
DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100 + gsm48_rx_mm_imsi_detach_ind: now used by 2 (attached,gsm48_rx_mm_imsi_detach_ind)
DMM IMSI DETACH for IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100
DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100 + active-conn: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn)
DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn,vlr_subscr_cancel_attach_fsm)
DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100 - attached: now used by 2 (gsm48_rx_mm_imsi_detach_ind,active-conn)
DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100 - gsm48_rx_mm_imsi_detach_ind: now used by 1 (active-conn)
DMSC msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_CN_CLOSE
@@ -1347,9 +1360,6 @@ DMSC msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:NONE){MSC_A
llist_count(&msub_list) == 0
===== test_ciph_tmsi: SUCCESS
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 17
-
===== test_ciph_imei
- Location Update request causes a GSUP Send Auth Info request to HLR
MSC <--GERAN-A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
@@ -1378,13 +1388,14 @@ DREF VLR subscr IMSI-901700000004620 + active-conn: now used by 2 (_lu_fsm_assoc
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH
DREF VLR subscr IMSI-901700000004620 - _lu_fsm_associate_vsub: now used by 1 (active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Allocated
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU)
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
-GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f00a0101
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f02801020a0101
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - mm_rx_loc_upd_req: now used by 2 (rx_from_ms,lu)
DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu)
@@ -1416,7 +1427,7 @@ DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: Au
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU)
-DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES
+DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_SUCCESS
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Set Ciphering Mode
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: CIPHER_MODE_COMMAND on GERAN-A
@@ -1453,6 +1464,8 @@ DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: + ms_sends_ciph
DBSSAP msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN decode: CIPHER_MODE_COMPLETE
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_CIPH}: Received Event VLR_ULA_E_CIPH_RES
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_CIPH}: vlr_loc_upd_post_ciph()
+DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000004620:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_CIPH}: vlr_loc_upd_node_4()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_CIPH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
DVLR upd_hlr_vlr_fsm(IMSI-901700000004620:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated
@@ -1487,6 +1500,7 @@ DVLR lu_compl_vlr_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){LU_COMPL_VLR
DVLR lu_compl_vlr_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES
DVLR lu_compl_vlr_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL
DVLR lu_compl_vlr_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_WAIT_IMEI
+DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: Sending DTAP: MM GSM48_MT_MM_ID_REQ
DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: DTAP on GERAN-A
- DTAP --GERAN-A--> MS: GSM48_MT_MM_ID_REQ: 051802
- DTAP matches expected message
@@ -1522,7 +1536,7 @@ DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}:
DREF msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: + rx_from_ms: now used by 2 (lu,rx_from_ms)
DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN decode: DTAP
DRLL msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: Dispatching 04.08 message: MM GSM48_MT_MM_ID_RESP
-DMM IDENTITY RESPONSE: MI=IMEI-423423423423420
+DMM IDENTITY RESPONSE: IMEI-423423423423420
DVLR set IMEI on subscriber; IMSI=901700000004620 IMEI=42342342342342
DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_ID_IMEI
GSUP --> HLR: OSMO_GSUP_MSGT_CHECK_IMEI_REQUEST: 30010809710000004026f0500807244332244332240a0101
@@ -1620,12 +1634,13 @@ DMSC dummy_msc_i{0}: is child of msub_fsm
DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms)
DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3
DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: MM GSM48_MT_MM_IMSI_DETACH_IND
-DMM IMSI DETACH INDICATION: MI(IMSI)=901700000004620
+DMM IMSI DETACH INDICATION: IMSI-901700000004620
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + gsm48_rx_mm_imsi_detach_ind: now used by 2 (attached,gsm48_rx_mm_imsi_detach_ind)
DMM IMSI DETACH for IMSI-901700000004620:MSISDN-46071
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + active-conn: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn)
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn,vlr_subscr_cancel_attach_fsm)
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - attached: now used by 2 (gsm48_rx_mm_imsi_detach_ind,active-conn)
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - gsm48_rx_mm_imsi_detach_ind: now used by 1 (active-conn)
DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_CN_CLOSE
@@ -1665,9 +1680,6 @@ DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:NONE){MSC_A_ST_RELEASED}: D
llist_count(&msub_list) == 0
===== test_ciph_imei: SUCCESS
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 17
-
===== test_ciph_imeisv
- Location Update request causes a GSUP Send Auth Info request to HLR
MSC <--GERAN-A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
@@ -1696,13 +1708,14 @@ DREF VLR subscr IMSI-901700000004620 + active-conn: now used by 2 (_lu_fsm_assoc
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH
DREF VLR subscr IMSI-901700000004620 - _lu_fsm_associate_vsub: now used by 1 (active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Allocated
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU)
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
-GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f00a0101
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f02801020a0101
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - mm_rx_loc_upd_req: now used by 2 (rx_from_ms,lu)
DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu)
@@ -1734,7 +1747,7 @@ DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: Au
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU)
-DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES
+DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_SUCCESS
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Set Ciphering Mode
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: CIPHER_MODE_COMMAND on GERAN-A
@@ -1776,6 +1789,8 @@ DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: + ms_sends_ciph
DBSSAP msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN decode: CIPHER_MODE_COMPLETE
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_CIPH}: Received Event VLR_ULA_E_CIPH_RES
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_CIPH}: vlr_loc_upd_post_ciph()
+DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000004620:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_CIPH}: vlr_loc_upd_node_4()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_CIPH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
DVLR upd_hlr_vlr_fsm(IMSI-901700000004620:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated
@@ -1785,11 +1800,10 @@ GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000004026f02801
DVLR upd_hlr_vlr_fsm(IMSI-901700000004620:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA
DBSSAP msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN decode: DTAP
DRLL msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: Dispatching 04.08 message: RR GSM48_MT_RR_CIPH_M_COMPL
-DBSSAP msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: Ciphering Mode Complete contains Mobile Identity: IMEI-SV-4234234234234275F
+DBSSAP msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RR Ciphering Mode Complete contains Mobile Identity: IMEI-SV-4234234234234275
DVLR set IMEISV on subscriber; IMSI=901700000004620 IMEISV=4234234234234275
DVLR set IMEI on subscriber; IMSI=901700000004620 IMEI=42342342342342
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_ID_IMEISV
-DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_HLR_UPD}: Event VLR_ULA_E_ID_IMEISV not permitted
DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - ms_sends_ciphering_mode_complete: now used by 1 (lu)
lu_result_sent == 0
- Subscriber has the IMEISV
@@ -1905,12 +1919,13 @@ DMSC dummy_msc_i{0}: is child of msub_fsm
DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms)
DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3
DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: MM GSM48_MT_MM_IMSI_DETACH_IND
-DMM IMSI DETACH INDICATION: MI(IMSI)=901700000004620
+DMM IMSI DETACH INDICATION: IMSI-901700000004620
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + gsm48_rx_mm_imsi_detach_ind: now used by 2 (attached,gsm48_rx_mm_imsi_detach_ind)
DMM IMSI DETACH for IMSI-901700000004620:MSISDN-46071
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + active-conn: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn)
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn,vlr_subscr_cancel_attach_fsm)
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - attached: now used by 2 (gsm48_rx_mm_imsi_detach_ind,active-conn)
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - gsm48_rx_mm_imsi_detach_ind: now used by 1 (active-conn)
DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_CN_CLOSE
@@ -1950,9 +1965,6 @@ DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:NONE){MSC_A_ST_RELEASED}: D
llist_count(&msub_list) == 0
===== test_ciph_imeisv: SUCCESS
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 17
-
===== test_ciph_tmsi_imei
- Location Update request causes a GSUP Send Auth Info request to HLR
MSC <--GERAN-A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
@@ -1981,13 +1993,14 @@ DREF VLR subscr IMSI-901700000004620 + active-conn: now used by 2 (_lu_fsm_assoc
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH
DREF VLR subscr IMSI-901700000004620 - _lu_fsm_associate_vsub: now used by 1 (active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Allocated
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU)
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
-GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f00a0101
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f02801020a0101
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - mm_rx_loc_upd_req: now used by 2 (rx_from_ms,lu)
DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu)
@@ -2019,7 +2032,7 @@ DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: Au
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU)
-DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES
+DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_SUCCESS
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Set Ciphering Mode
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: CIPHER_MODE_COMMAND on GERAN-A
@@ -2056,6 +2069,8 @@ DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: + ms_sends_ciph
DBSSAP msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN decode: CIPHER_MODE_COMPLETE
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_CIPH}: Received Event VLR_ULA_E_CIPH_RES
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_CIPH}: vlr_loc_upd_post_ciph()
+DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000004620:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_CIPH}: vlr_loc_upd_node_4()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_CIPH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
DVLR upd_hlr_vlr_fsm(IMSI-901700000004620:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated
@@ -2090,6 +2105,7 @@ DVLR lu_compl_vlr_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){LU_COMPL_VLR
DVLR lu_compl_vlr_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES
DVLR lu_compl_vlr_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL
DVLR lu_compl_vlr_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_WAIT_IMEI_TMSI
+DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: Sending DTAP: MM GSM48_MT_MM_ID_REQ
DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: DTAP on GERAN-A
- DTAP --GERAN-A--> MS: GSM48_MT_MM_ID_REQ: 051802
- DTAP matches expected message
@@ -2125,7 +2141,7 @@ DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}:
DREF msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: + rx_from_ms: now used by 2 (lu,rx_from_ms)
DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN decode: DTAP
DRLL msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: Dispatching 04.08 message: MM GSM48_MT_MM_ID_RESP
-DMM IDENTITY RESPONSE: MI=IMEI-423423423423420
+DMM IDENTITY RESPONSE: IMEI-423423423423420
DVLR set IMEI on subscriber; IMSI=901700000004620 IMEI=42342342342342
DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_ID_IMEI
GSUP --> HLR: OSMO_GSUP_MSGT_CHECK_IMEI_REQUEST: 30010809710000004026f0500807244332244332240a0101
@@ -2264,12 +2280,13 @@ DMSC dummy_msc_i{0}: is child of msub_fsm
DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms)
DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3
DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: MM GSM48_MT_MM_IMSI_DETACH_IND
-DMM IMSI DETACH INDICATION: MI(TMSI)=50462976
+DMM IMSI DETACH INDICATION: TMSI-0x03020100
DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100 + gsm48_rx_mm_imsi_detach_ind: now used by 2 (attached,gsm48_rx_mm_imsi_detach_ind)
DMM IMSI DETACH for IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100
DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100 + active-conn: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn)
DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn,vlr_subscr_cancel_attach_fsm)
DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100 - attached: now used by 2 (gsm48_rx_mm_imsi_detach_ind,active-conn)
DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100 - gsm48_rx_mm_imsi_detach_ind: now used by 1 (active-conn)
DMSC msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_CN_CLOSE
@@ -2309,9 +2326,6 @@ DMSC msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:NONE){MSC_A
llist_count(&msub_list) == 0
===== test_ciph_tmsi_imei: SUCCESS
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 17
-
===== test_gsm_ciph_in_umts_env
- Location Update request causes a GSUP Send Auth Info request to HLR
MSC <--GERAN-A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
@@ -2340,13 +2354,14 @@ DREF VLR subscr IMSI-901700000010650 + active-conn: now used by 2 (_lu_fsm_assoc
DMSC msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK
DMSC msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH
DREF VLR subscr IMSI-901700000010650 - _lu_fsm_associate_vsub: now used by 1 (active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre()
DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH
DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Allocated
DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU)
DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
-GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f00a0101
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f02801020a0101
DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
DREF msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - mm_rx_loc_upd_req: now used by 2 (rx_from_ms,lu)
DREF msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu)
@@ -2379,7 +2394,7 @@ DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: Au
DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU)
-DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES
+DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_SUCCESS
DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth()
DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Set Ciphering Mode
DMSC msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: CIPHER_MODE_COMMAND on GERAN-A
@@ -2396,6 +2411,8 @@ DREF msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: + ms_sends_ciph
DBSSAP msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN decode: CIPHER_MODE_COMPLETE
DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_WAIT_CIPH}: Received Event VLR_ULA_E_CIPH_RES
DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_WAIT_CIPH}: vlr_loc_upd_post_ciph()
+DMSC msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000010650:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_WAIT_CIPH}: vlr_loc_upd_node_4()
DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_WAIT_CIPH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
DVLR upd_hlr_vlr_fsm(IMSI-901700000010650:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated
@@ -2571,6 +2588,8 @@ DREF msc_a(IMSI-901700000010650:MSISDN-42342:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AU
DBSSAP msc_a(IMSI-901700000010650:MSISDN-42342:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN decode: CIPHER_MODE_COMPLETE
DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_CIPH}: Received Event PR_ARQ_E_CIPH_RES
DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_node2_post_ciph()
+DMSC msc_a(IMSI-901700000010650:MSISDN-42342:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_node2_post_vlr()
DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_pres()
DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_trace()
@@ -2661,7 +2680,7 @@ DMSC dummy_msc_i{0}: is child of msub_fsm
DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms)
DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3
DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: RR GSM48_MT_RR_PAG_RESP
-DRR msc_a(IMSI-901700000010650:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: Rx PAGING RESPONSE
+DRR msc_a(IMSI-901700000010650:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: Rx PAGING RESPONSE IMSI-901700000010650
DREF msc_a(IMSI-901700000010650:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: + paging-response: now used by 2 (rx_from_ms,paging-response)
DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: Allocated
DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: is child of msc_a(IMSI-901700000010650:GERAN-A:PAGING_RESP)
@@ -2734,6 +2753,8 @@ DREF msc_a(IMSI-901700000010650:MSISDN-42342:GERAN-A:PAGING_RESP){MSC_A_ST_AUTH_
DBSSAP msc_a(IMSI-901700000010650:MSISDN-42342:GERAN-A:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: RAN decode: CIPHER_MODE_COMPLETE
DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:GERAN-A:PAGING_RESP){PR_ARQ_S_WAIT_CIPH}: Received Event PR_ARQ_E_CIPH_RES
DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:GERAN-A:PAGING_RESP){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_node2_post_ciph()
+DMSC msc_a(IMSI-901700000010650:MSISDN-42342:GERAN-A:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:GERAN-A:PAGING_RESP){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_node2_post_vlr()
DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:GERAN-A:PAGING_RESP){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_pres()
DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:GERAN-A:PAGING_RESP){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_trace()
@@ -2752,6 +2773,7 @@ DLSMS SMC(0) send CP data
DLSMS SMC(0) new CP state MM_CONN_PENDING -> WAIT_CP_ACK
DLSMS trans(SMS IMSI-901700000010650:MSISDN-42342:GERAN-A:PAGING_RESP callref-0x40000003 tid-0) sending CP message (trans=0)
DLSMS trans(SMS IMSI-901700000010650:MSISDN-42342:GERAN-A:PAGING_RESP callref-0x40000003 tid-0) GSM4.11 TX 09 01 58 01 00 07 91 44 77 58 10 06 50 00 4c 00 05 80 24 43 f2 00 00 07 10 10 00 00 00 00 44 50 79 da 1e 1e e7 41 69 37 48 5e 9e a7 c9 65 37 3d 1d 66 83 c2 70 38 3b 3d 0e d3 d3 6f f7 1c 94 9e 83 c2 20 72 79 9e 96 87 c5 ec 32 a8 1d 96 af cb f4 b4 fb 0c 7a c3 e9 e9 b7 db 05
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-42342:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: Sending DTAP: SMS SMS:0x01
DMSC msc_a(IMSI-901700000010650:MSISDN-42342:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: RAN encode: DTAP on GERAN-A
- DTAP --GERAN-A--> MS: SMS:0x01: 09015801000791447758100650004c0005802443f2000007101000000000445079da1e1ee7416937485e9ea7c965373d1d6683c270383b3d0ed3d36ff71c949e83c22072799e9687c5ec32a81d96afcbf4b4fb0c7ac3e9e9b7db05
- DTAP matches expected message
@@ -2787,6 +2809,7 @@ DLSMS SMC(0) message MMSMS-DATA-IND (CP DATA) received in state MM_ESTABLISHED
DLSMS SMC(0) received CP-DATA
DLSMS trans(SMS IMSI-901700000010650:MSISDN-42342:GERAN-A:PAGING_RESP callref-0x40000003 tid-0) sending CP message (trans=0)
DLSMS trans(SMS IMSI-901700000010650:MSISDN-42342:GERAN-A:PAGING_RESP callref-0x40000003 tid-0) GSM4.11 TX 09 04
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-42342:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: Sending DTAP: SMS SMS:0x04
DMSC msc_a(IMSI-901700000010650:MSISDN-42342:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: RAN encode: DTAP on GERAN-A
- DTAP --GERAN-A--> MS: SMS:0x04: 0904
- DTAP matches expected message
@@ -2859,12 +2882,13 @@ DMSC dummy_msc_i{0}: is child of msub_fsm
DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms)
DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3
DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: MM GSM48_MT_MM_IMSI_DETACH_IND
-DMM IMSI DETACH INDICATION: MI(IMSI)=901700000010650
+DMM IMSI DETACH INDICATION: IMSI-901700000010650
DREF VLR subscr IMSI-901700000010650:MSISDN-42342 + gsm48_rx_mm_imsi_detach_ind: now used by 2 (attached,gsm48_rx_mm_imsi_detach_ind)
DMM IMSI DETACH for IMSI-901700000010650:MSISDN-42342
DREF VLR subscr IMSI-901700000010650:MSISDN-42342 + active-conn: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn)
DREF VLR subscr IMSI-901700000010650:MSISDN-42342 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn,vlr_subscr_cancel_attach_fsm)
DREF VLR subscr IMSI-901700000010650:MSISDN-42342 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DREF VLR subscr IMSI-901700000010650:MSISDN-42342 - attached: now used by 2 (gsm48_rx_mm_imsi_detach_ind,active-conn)
DREF VLR subscr IMSI-901700000010650:MSISDN-42342 - gsm48_rx_mm_imsi_detach_ind: now used by 1 (active-conn)
DMSC msc_a(IMSI-901700000010650:MSISDN-42342:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_CN_CLOSE
@@ -2904,9 +2928,6 @@ DMSC msc_a(IMSI-901700000010650:MSISDN-42342:GERAN-A:NONE){MSC_A_ST_RELEASED}: D
llist_count(&msub_list) == 0
===== test_gsm_ciph_in_umts_env: SUCCESS
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 17
-
===== test_a5_3_supported
- Location Update request causes a GSUP Send Auth Info request to HLR
MSC <--GERAN-A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
@@ -2935,13 +2956,14 @@ DREF VLR subscr IMSI-901700000004620 + active-conn: now used by 2 (_lu_fsm_assoc
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH
DREF VLR subscr IMSI-901700000004620 - _lu_fsm_associate_vsub: now used by 1 (active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Allocated
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU)
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
-GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f00a0101
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f02801020a0101
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - mm_rx_loc_upd_req: now used by 2 (rx_from_ms,lu)
DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu)
@@ -2975,7 +2997,7 @@ DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: Au
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU)
-DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES
+DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_SUCCESS
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Set Ciphering Mode
DBSSAP msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: For A5/3, we still need Classmark 2
@@ -2988,7 +3010,7 @@ DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_WAIT_CLASSMARK_UPDATE}: - r
lu_result_sent == 0
- BSC sends back a BSSMAP Classmark Update, that triggers the Ciphering Mode Command in A5/3
DBSSAP msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_WAIT_CLASSMARK_UPDATE}: RAN decode: CLASSMARK_UPDATE
-DBSSAP msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_WAIT_CLASSMARK_UPDATE}: A5 capabilities recived from Classmark Update: no-cm1 no-cm2 no-cm3
+DBSSAP msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_WAIT_CLASSMARK_UPDATE}: A5 capabilities received from Classmark Update: no-cm1 no-cm2 no-cm3
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_WAIT_CLASSMARK_UPDATE}: Received Event MSC_A_EV_CLASSMARK_UPDATE
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_WAIT_CLASSMARK_UPDATE}: state_chg to MSC_A_ST_AUTH_CIPH
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: CIPHER_MODE_COMMAND on GERAN-A
@@ -3002,6 +3024,8 @@ DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: + ms_sends_ciph
DBSSAP msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN decode: CIPHER_MODE_COMPLETE
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_CIPH}: Received Event VLR_ULA_E_CIPH_RES
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_CIPH}: vlr_loc_upd_post_ciph()
+DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000004620:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_CIPH}: vlr_loc_upd_node_4()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_CIPH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
DVLR upd_hlr_vlr_fsm(IMSI-901700000004620:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated
@@ -3195,6 +3219,8 @@ DREF msc_a(IMSI-901700000004620:MSISDN-42342:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AU
DBSSAP msc_a(IMSI-901700000004620:MSISDN-42342:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN decode: CIPHER_MODE_COMPLETE
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-42342:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_CIPH}: Received Event PR_ARQ_E_CIPH_RES
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-42342:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_node2_post_ciph()
+DMSC msc_a(IMSI-901700000004620:MSISDN-42342:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-42342:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-42342:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_node2_post_vlr()
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-42342:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_pres()
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-42342:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_trace()
@@ -3285,7 +3311,7 @@ DMSC dummy_msc_i{0}: is child of msub_fsm
DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms)
DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3
DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: RR GSM48_MT_RR_PAG_RESP
-DRR msc_a(IMSI-901700000004620:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: Rx PAGING RESPONSE
+DRR msc_a(IMSI-901700000004620:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: Rx PAGING RESPONSE IMSI-901700000004620
DREF msc_a(IMSI-901700000004620:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: + paging-response: now used by 2 (rx_from_ms,paging-response)
DVLR Process_Access_Request_VLR(IMSI-901700000004620:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: Allocated
DVLR Process_Access_Request_VLR(IMSI-901700000004620:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: is child of msc_a(IMSI-901700000004620:GERAN-A:PAGING_RESP)
@@ -3376,6 +3402,8 @@ DREF msc_a(IMSI-901700000004620:MSISDN-42342:GERAN-A:PAGING_RESP){MSC_A_ST_AUTH_
DBSSAP msc_a(IMSI-901700000004620:MSISDN-42342:GERAN-A:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: RAN decode: CIPHER_MODE_COMPLETE
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-42342:GERAN-A:PAGING_RESP){PR_ARQ_S_WAIT_CIPH}: Received Event PR_ARQ_E_CIPH_RES
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-42342:GERAN-A:PAGING_RESP){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_node2_post_ciph()
+DMSC msc_a(IMSI-901700000004620:MSISDN-42342:GERAN-A:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-42342:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-42342:GERAN-A:PAGING_RESP){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_node2_post_vlr()
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-42342:GERAN-A:PAGING_RESP){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_pres()
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-42342:GERAN-A:PAGING_RESP){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_trace()
@@ -3394,6 +3422,7 @@ DLSMS SMC(0) send CP data
DLSMS SMC(0) new CP state MM_CONN_PENDING -> WAIT_CP_ACK
DLSMS trans(SMS IMSI-901700000004620:MSISDN-42342:GERAN-A:PAGING_RESP callref-0x40000004 tid-0) sending CP message (trans=0)
DLSMS trans(SMS IMSI-901700000004620:MSISDN-42342:GERAN-A:PAGING_RESP callref-0x40000004 tid-0) GSM4.11 TX 09 01 58 01 00 07 91 44 77 58 10 06 50 00 4c 00 05 80 24 43 f2 00 00 07 10 10 00 00 00 00 44 50 79 da 1e 1e e7 41 69 37 48 5e 9e a7 c9 65 37 3d 1d 66 83 c2 70 38 3b 3d 0e d3 d3 6f f7 1c 94 9e 83 c2 20 72 79 9e 96 87 c5 ec 32 a8 1d 96 af cb f4 b4 fb 0c 7a c3 e9 e9 b7 db 05
+DBSSAP msc_a(IMSI-901700000004620:MSISDN-42342:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: Sending DTAP: SMS SMS:0x01
DMSC msc_a(IMSI-901700000004620:MSISDN-42342:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: RAN encode: DTAP on GERAN-A
- DTAP --GERAN-A--> MS: SMS:0x01: 09015801000791447758100650004c0005802443f2000007101000000000445079da1e1ee7416937485e9ea7c965373d1d6683c270383b3d0ed3d36ff71c949e83c22072799e9687c5ec32a81d96afcbf4b4fb0c7ac3e9e9b7db05
- DTAP matches expected message
@@ -3429,6 +3458,7 @@ DLSMS SMC(0) message MMSMS-DATA-IND (CP DATA) received in state MM_ESTABLISHED
DLSMS SMC(0) received CP-DATA
DLSMS trans(SMS IMSI-901700000004620:MSISDN-42342:GERAN-A:PAGING_RESP callref-0x40000004 tid-0) sending CP message (trans=0)
DLSMS trans(SMS IMSI-901700000004620:MSISDN-42342:GERAN-A:PAGING_RESP callref-0x40000004 tid-0) GSM4.11 TX 09 04
+DBSSAP msc_a(IMSI-901700000004620:MSISDN-42342:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: Sending DTAP: SMS SMS:0x04
DMSC msc_a(IMSI-901700000004620:MSISDN-42342:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: RAN encode: DTAP on GERAN-A
- DTAP --GERAN-A--> MS: SMS:0x04: 0904
- DTAP matches expected message
@@ -3501,12 +3531,13 @@ DMSC dummy_msc_i{0}: is child of msub_fsm
DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms)
DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3
DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: MM GSM48_MT_MM_IMSI_DETACH_IND
-DMM IMSI DETACH INDICATION: MI(IMSI)=901700000004620
+DMM IMSI DETACH INDICATION: IMSI-901700000004620
DREF VLR subscr IMSI-901700000004620:MSISDN-42342 + gsm48_rx_mm_imsi_detach_ind: now used by 2 (attached,gsm48_rx_mm_imsi_detach_ind)
DMM IMSI DETACH for IMSI-901700000004620:MSISDN-42342
DREF VLR subscr IMSI-901700000004620:MSISDN-42342 + active-conn: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn)
DREF VLR subscr IMSI-901700000004620:MSISDN-42342 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn,vlr_subscr_cancel_attach_fsm)
DREF VLR subscr IMSI-901700000004620:MSISDN-42342 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DREF VLR subscr IMSI-901700000004620:MSISDN-42342 - attached: now used by 2 (gsm48_rx_mm_imsi_detach_ind,active-conn)
DREF VLR subscr IMSI-901700000004620:MSISDN-42342 - gsm48_rx_mm_imsi_detach_ind: now used by 1 (active-conn)
DMSC msc_a(IMSI-901700000004620:MSISDN-42342:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_CN_CLOSE
@@ -3546,9 +3577,6 @@ DMSC msc_a(IMSI-901700000004620:MSISDN-42342:GERAN-A:NONE){MSC_A_ST_RELEASED}: D
llist_count(&msub_list) == 0
===== test_a5_3_supported: SUCCESS
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 17
-
===== test_cm_service_needs_classmark_update
- Location Update request causes a GSUP Send Auth Info request to HLR
MSC <--GERAN-A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
@@ -3577,13 +3605,14 @@ DREF VLR subscr IMSI-901700000004620 + active-conn: now used by 2 (_lu_fsm_assoc
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH
DREF VLR subscr IMSI-901700000004620 - _lu_fsm_associate_vsub: now used by 1 (active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Allocated
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU)
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
-GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f00a0101
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f02801020a0101
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - mm_rx_loc_upd_req: now used by 2 (rx_from_ms,lu)
DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu)
@@ -3617,7 +3646,7 @@ DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: Au
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU)
-DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES
+DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_SUCCESS
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Set Ciphering Mode
DBSSAP msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: For A5/3, we still need Classmark 2
@@ -3630,7 +3659,7 @@ DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_WAIT_CLASSMARK_UPDATE}: - r
lu_result_sent == 0
- BSC sends back a BSSMAP Classmark Update, that triggers the Ciphering Mode Command in A5/3
DBSSAP msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_WAIT_CLASSMARK_UPDATE}: RAN decode: CLASSMARK_UPDATE
-DBSSAP msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_WAIT_CLASSMARK_UPDATE}: A5 capabilities recived from Classmark Update: no-cm1 no-cm2 no-cm3
+DBSSAP msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_WAIT_CLASSMARK_UPDATE}: A5 capabilities received from Classmark Update: no-cm1 no-cm2 no-cm3
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_WAIT_CLASSMARK_UPDATE}: Received Event MSC_A_EV_CLASSMARK_UPDATE
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_WAIT_CLASSMARK_UPDATE}: state_chg to MSC_A_ST_AUTH_CIPH
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: CIPHER_MODE_COMMAND on GERAN-A
@@ -3644,6 +3673,8 @@ DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: + ms_sends_ciph
DBSSAP msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN decode: CIPHER_MODE_COMPLETE
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_CIPH}: Received Event VLR_ULA_E_CIPH_RES
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_CIPH}: vlr_loc_upd_post_ciph()
+DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000004620:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_CIPH}: vlr_loc_upd_node_4()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_CIPH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
DVLR upd_hlr_vlr_fsm(IMSI-901700000004620:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated
@@ -3837,6 +3868,8 @@ DREF msc_a(IMSI-901700000004620:MSISDN-42342:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AU
DBSSAP msc_a(IMSI-901700000004620:MSISDN-42342:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN decode: CIPHER_MODE_COMPLETE
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-42342:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_CIPH}: Received Event PR_ARQ_E_CIPH_RES
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-42342:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_node2_post_ciph()
+DMSC msc_a(IMSI-901700000004620:MSISDN-42342:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-42342:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-42342:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_node2_post_vlr()
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-42342:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_pres()
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-42342:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_trace()
@@ -3927,7 +3960,7 @@ DMSC dummy_msc_i{0}: is child of msub_fsm
DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms)
DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3
DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: RR GSM48_MT_RR_PAG_RESP
-DRR msc_a(IMSI-901700000004620:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: Rx PAGING RESPONSE
+DRR msc_a(IMSI-901700000004620:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: Rx PAGING RESPONSE IMSI-901700000004620
DREF msc_a(IMSI-901700000004620:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: + paging-response: now used by 2 (rx_from_ms,paging-response)
DVLR Process_Access_Request_VLR(IMSI-901700000004620:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: Allocated
DVLR Process_Access_Request_VLR(IMSI-901700000004620:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: is child of msc_a(IMSI-901700000004620:GERAN-A:PAGING_RESP)
@@ -3981,7 +4014,7 @@ DVLR VLR_Authenticate(IMSI-901700000004620:MSISDN-42342:GERAN-A:PAGING_RESP){VLR
DREF msc_a(IMSI-901700000004620:MSISDN-42342:GERAN-A:PAGING_RESP){MSC_A_ST_WAIT_CLASSMARK_UPDATE}: - rx_from_ms: now used by 1 (paging-response)
- BSC sends back a BSSMAP Classmark Update, that triggers the Ciphering Mode Command in A5/3
DBSSAP msc_a(IMSI-901700000004620:MSISDN-42342:GERAN-A:PAGING_RESP){MSC_A_ST_WAIT_CLASSMARK_UPDATE}: RAN decode: CLASSMARK_UPDATE
-DBSSAP msc_a(IMSI-901700000004620:MSISDN-42342:GERAN-A:PAGING_RESP){MSC_A_ST_WAIT_CLASSMARK_UPDATE}: A5 capabilities recived from Classmark Update: no-cm1 no-cm2 no-cm3
+DBSSAP msc_a(IMSI-901700000004620:MSISDN-42342:GERAN-A:PAGING_RESP){MSC_A_ST_WAIT_CLASSMARK_UPDATE}: A5 capabilities received from Classmark Update: no-cm1 no-cm2 no-cm3
DMSC msc_a(IMSI-901700000004620:MSISDN-42342:GERAN-A:PAGING_RESP){MSC_A_ST_WAIT_CLASSMARK_UPDATE}: Received Event MSC_A_EV_CLASSMARK_UPDATE
DMSC msc_a(IMSI-901700000004620:MSISDN-42342:GERAN-A:PAGING_RESP){MSC_A_ST_WAIT_CLASSMARK_UPDATE}: state_chg to MSC_A_ST_AUTH_CIPH
DMSC msc_a(IMSI-901700000004620:MSISDN-42342:GERAN-A:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: RAN encode: CIPHER_MODE_COMMAND on GERAN-A
@@ -3996,6 +4029,8 @@ DREF msc_a(IMSI-901700000004620:MSISDN-42342:GERAN-A:PAGING_RESP){MSC_A_ST_AUTH_
DBSSAP msc_a(IMSI-901700000004620:MSISDN-42342:GERAN-A:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: RAN decode: CIPHER_MODE_COMPLETE
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-42342:GERAN-A:PAGING_RESP){PR_ARQ_S_WAIT_CIPH}: Received Event PR_ARQ_E_CIPH_RES
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-42342:GERAN-A:PAGING_RESP){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_node2_post_ciph()
+DMSC msc_a(IMSI-901700000004620:MSISDN-42342:GERAN-A:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-42342:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-42342:GERAN-A:PAGING_RESP){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_node2_post_vlr()
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-42342:GERAN-A:PAGING_RESP){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_pres()
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-42342:GERAN-A:PAGING_RESP){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_trace()
@@ -4014,6 +4049,7 @@ DLSMS SMC(0) send CP data
DLSMS SMC(0) new CP state MM_CONN_PENDING -> WAIT_CP_ACK
DLSMS trans(SMS IMSI-901700000004620:MSISDN-42342:GERAN-A:PAGING_RESP callref-0x40000005 tid-0) sending CP message (trans=0)
DLSMS trans(SMS IMSI-901700000004620:MSISDN-42342:GERAN-A:PAGING_RESP callref-0x40000005 tid-0) GSM4.11 TX 09 01 58 01 00 07 91 44 77 58 10 06 50 00 4c 00 05 80 24 43 f2 00 00 07 10 10 00 00 00 00 44 50 79 da 1e 1e e7 41 69 37 48 5e 9e a7 c9 65 37 3d 1d 66 83 c2 70 38 3b 3d 0e d3 d3 6f f7 1c 94 9e 83 c2 20 72 79 9e 96 87 c5 ec 32 a8 1d 96 af cb f4 b4 fb 0c 7a c3 e9 e9 b7 db 05
+DBSSAP msc_a(IMSI-901700000004620:MSISDN-42342:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: Sending DTAP: SMS SMS:0x01
DMSC msc_a(IMSI-901700000004620:MSISDN-42342:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: RAN encode: DTAP on GERAN-A
- DTAP --GERAN-A--> MS: SMS:0x01: 09015801000791447758100650004c0005802443f2000007101000000000445079da1e1ee7416937485e9ea7c965373d1d6683c270383b3d0ed3d36ff71c949e83c22072799e9687c5ec32a81d96afcbf4b4fb0c7ac3e9e9b7db05
- DTAP matches expected message
@@ -4049,6 +4085,7 @@ DLSMS SMC(0) message MMSMS-DATA-IND (CP DATA) received in state MM_ESTABLISHED
DLSMS SMC(0) received CP-DATA
DLSMS trans(SMS IMSI-901700000004620:MSISDN-42342:GERAN-A:PAGING_RESP callref-0x40000005 tid-0) sending CP message (trans=0)
DLSMS trans(SMS IMSI-901700000004620:MSISDN-42342:GERAN-A:PAGING_RESP callref-0x40000005 tid-0) GSM4.11 TX 09 04
+DBSSAP msc_a(IMSI-901700000004620:MSISDN-42342:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: Sending DTAP: SMS SMS:0x04
DMSC msc_a(IMSI-901700000004620:MSISDN-42342:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: RAN encode: DTAP on GERAN-A
- DTAP --GERAN-A--> MS: SMS:0x04: 0904
- DTAP matches expected message
@@ -4121,12 +4158,13 @@ DMSC dummy_msc_i{0}: is child of msub_fsm
DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms)
DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3
DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: MM GSM48_MT_MM_IMSI_DETACH_IND
-DMM IMSI DETACH INDICATION: MI(IMSI)=901700000004620
+DMM IMSI DETACH INDICATION: IMSI-901700000004620
DREF VLR subscr IMSI-901700000004620:MSISDN-42342 + gsm48_rx_mm_imsi_detach_ind: now used by 2 (attached,gsm48_rx_mm_imsi_detach_ind)
DMM IMSI DETACH for IMSI-901700000004620:MSISDN-42342
DREF VLR subscr IMSI-901700000004620:MSISDN-42342 + active-conn: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn)
DREF VLR subscr IMSI-901700000004620:MSISDN-42342 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn,vlr_subscr_cancel_attach_fsm)
DREF VLR subscr IMSI-901700000004620:MSISDN-42342 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DREF VLR subscr IMSI-901700000004620:MSISDN-42342 - attached: now used by 2 (gsm48_rx_mm_imsi_detach_ind,active-conn)
DREF VLR subscr IMSI-901700000004620:MSISDN-42342 - gsm48_rx_mm_imsi_detach_ind: now used by 1 (active-conn)
DMSC msc_a(IMSI-901700000004620:MSISDN-42342:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_CN_CLOSE
@@ -4166,9 +4204,3 @@ DMSC msc_a(IMSI-901700000004620:MSISDN-42342:GERAN-A:NONE){MSC_A_ST_RELEASED}: D
llist_count(&msub_list) == 0
===== test_cm_service_needs_classmark_update: SUCCESS
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 17
-
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 17
-
diff --git a/tests/msc_vlr/msc_vlr_test_hlr_reject.c b/tests/msc_vlr/msc_vlr_test_hlr_reject.c
index 1134d8971..6cdadcb8f 100644
--- a/tests/msc_vlr/msc_vlr_test_hlr_reject.c
+++ b/tests/msc_vlr/msc_vlr_test_hlr_reject.c
@@ -22,7 +22,6 @@
*/
#include "msc_vlr_tests.h"
-#include "stubs.h"
static void test_hlr_rej_auth_info_unknown_imsi()
{
@@ -32,7 +31,7 @@ static void test_hlr_rej_auth_info_unknown_imsi()
btw("Location Update request causes a GSUP Send Auth Info request to HLR");
lu_result_sent = RES_NONE;
- gsup_expect_tx("08010809710000004026f0" VLR_TO_HLR);
+ gsup_expect_tx("08010809710000004026f0" CN_DOMAIN VLR_TO_HLR);
ms_sends_msg("050802008168000130089910070000006402");
OSMO_ASSERT(gsup_tx_confirmed);
VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
@@ -59,7 +58,7 @@ static void test_hlr_rej_auth_info_net_fail()
btw("Location Update request causes a GSUP Send Auth Info request to HLR");
lu_result_sent = RES_NONE;
- gsup_expect_tx("08010809710000004026f0" VLR_TO_HLR);
+ gsup_expect_tx("08010809710000004026f0" CN_DOMAIN VLR_TO_HLR);
ms_sends_msg("050802008168000130089910070000006402");
OSMO_ASSERT(gsup_tx_confirmed);
VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
@@ -92,7 +91,7 @@ static void test_hlr_rej_auth_info_net_fail_no_reuse_tuples()
BTW("Submit a used auth tuple in the VLR");
btw("Location Update request causes a GSUP Send Auth Info request to HLR");
lu_result_sent = RES_NONE;
- gsup_expect_tx("08010809710000004026f0" VLR_TO_HLR);
+ gsup_expect_tx("08010809710000004026f0" CN_DOMAIN VLR_TO_HLR);
ms_sends_msg("050802008168000130089910070000006402");
OSMO_ASSERT(gsup_tx_confirmed);
VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
@@ -115,7 +114,7 @@ static void test_hlr_rej_auth_info_net_fail_no_reuse_tuples()
VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
btw("MS sends Authen Response, VLR accepts and sends GSUP LU Req to HLR");
- gsup_expect_tx("04010809710000004026f0280102" VLR_TO_HLR);
+ gsup_expect_tx("04010809710000004026f0" CN_DOMAIN VLR_TO_HLR);
ms_sends_msg("05542d8b2c3e");
VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
@@ -148,7 +147,7 @@ static void test_hlr_rej_auth_info_net_fail_no_reuse_tuples()
btw("Location Update request causes a GSUP Send Auth Info request to HLR");
lu_result_sent = RES_NONE;
- gsup_expect_tx("08010809710000004026f0" VLR_TO_HLR);
+ gsup_expect_tx("08010809710000004026f0" CN_DOMAIN VLR_TO_HLR);
ms_sends_msg("050802008168000130089910070000006402");
OSMO_ASSERT(gsup_tx_confirmed);
VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
@@ -181,7 +180,7 @@ static void test_hlr_rej_auth_info_unkown_imsi_no_reuse_tuples()
BTW("Submit a used auth tuple in the VLR");
btw("Location Update request causes a GSUP Send Auth Info request to HLR");
lu_result_sent = RES_NONE;
- gsup_expect_tx("08010809710000004026f0" VLR_TO_HLR);
+ gsup_expect_tx("08010809710000004026f0" CN_DOMAIN VLR_TO_HLR);
ms_sends_msg("050802008168000130089910070000006402");
OSMO_ASSERT(gsup_tx_confirmed);
VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
@@ -204,7 +203,7 @@ static void test_hlr_rej_auth_info_unkown_imsi_no_reuse_tuples()
VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
btw("MS sends Authen Response, VLR accepts and sends GSUP LU Req to HLR");
- gsup_expect_tx("04010809710000004026f0280102" VLR_TO_HLR);
+ gsup_expect_tx("04010809710000004026f0" CN_DOMAIN VLR_TO_HLR);
ms_sends_msg("05542d8b2c3e");
VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
@@ -238,7 +237,7 @@ static void test_hlr_rej_auth_info_unkown_imsi_no_reuse_tuples()
btw("Location Update request causes a GSUP Send Auth Info request to HLR");
lu_result_sent = RES_NONE;
- gsup_expect_tx("08010809710000004026f0" VLR_TO_HLR);
+ gsup_expect_tx("08010809710000004026f0" CN_DOMAIN VLR_TO_HLR);
ms_sends_msg("050802008168000130089910070000006402");
OSMO_ASSERT(gsup_tx_confirmed);
VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
@@ -267,7 +266,7 @@ static void test_hlr_acc_but_no_auth_tuples()
btw("Location Update request causes a GSUP Send Auth Info request to HLR");
lu_result_sent = RES_NONE;
- gsup_expect_tx("08010809710000004026f0" VLR_TO_HLR);
+ gsup_expect_tx("08010809710000004026f0" CN_DOMAIN VLR_TO_HLR);
ms_sends_msg("050802008168000130089910070000006402");
OSMO_ASSERT(gsup_tx_confirmed);
VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
@@ -305,7 +304,7 @@ static void test_hlr_rej_auth_info_net_fail_reuse_tuples()
BTW("Submit a used auth tuple in the VLR");
btw("Location Update request causes a GSUP Send Auth Info request to HLR");
lu_result_sent = RES_NONE;
- gsup_expect_tx("08010809710000004026f0" VLR_TO_HLR);
+ gsup_expect_tx("08010809710000004026f0" CN_DOMAIN VLR_TO_HLR);
ms_sends_msg("050802008168000130089910070000006402");
OSMO_ASSERT(gsup_tx_confirmed);
VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
@@ -329,7 +328,7 @@ static void test_hlr_rej_auth_info_net_fail_reuse_tuples()
VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
btw("MS sends Authen Response, VLR accepts and sends GSUP LU Req to HLR");
- gsup_expect_tx("04010809710000004026f0280102" VLR_TO_HLR);
+ gsup_expect_tx("04010809710000004026f0" CN_DOMAIN VLR_TO_HLR);
ms_sends_msg("05542d8b2c3e");
VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
@@ -362,7 +361,7 @@ static void test_hlr_rej_auth_info_net_fail_reuse_tuples()
btw("Location Update request causes a GSUP Send Auth Info request to HLR");
lu_result_sent = RES_NONE;
- gsup_expect_tx("08010809710000004026f0" VLR_TO_HLR);
+ gsup_expect_tx("08010809710000004026f0" CN_DOMAIN VLR_TO_HLR);
ms_sends_msg("050802008168000130089910070000006402");
OSMO_ASSERT(gsup_tx_confirmed);
VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
@@ -374,7 +373,7 @@ static void test_hlr_rej_auth_info_net_fail_reuse_tuples()
VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
btw("MS sends Authen Response, VLR accepts and sends GSUP LU Req to HLR");
- gsup_expect_tx("04010809710000004026f0280102" VLR_TO_HLR);
+ gsup_expect_tx("04010809710000004026f0" CN_DOMAIN VLR_TO_HLR);
ms_sends_msg("05542d8b2c3e");
VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
@@ -403,7 +402,7 @@ static void test_hlr_rej_lu()
btw("Location Update request causes a GSUP LU request to HLR");
lu_result_sent = RES_NONE;
- gsup_expect_tx("04010809710000004026f0280102" VLR_TO_HLR);
+ gsup_expect_tx("04010809710000004026f0" CN_DOMAIN VLR_TO_HLR);
ms_sends_msg("050802008168000130089910070000006402");
OSMO_ASSERT(gsup_tx_confirmed);
VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
@@ -427,7 +426,7 @@ static void test_hlr_no_insert_data()
btw("Location Update request causes a GSUP LU request to HLR");
lu_result_sent = RES_NONE;
- gsup_expect_tx("04010809710000004026f0280102" VLR_TO_HLR);
+ gsup_expect_tx("04010809710000004026f0" CN_DOMAIN VLR_TO_HLR);
ms_sends_msg("050802008168000130089910070000006402");
OSMO_ASSERT(gsup_tx_confirmed);
VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
diff --git a/tests/msc_vlr/msc_vlr_test_hlr_reject.err b/tests/msc_vlr/msc_vlr_test_hlr_reject.err
index 2dd6a52e6..305e1b814 100644
--- a/tests/msc_vlr/msc_vlr_test_hlr_reject.err
+++ b/tests/msc_vlr/msc_vlr_test_hlr_reject.err
@@ -1,7 +1,3 @@
-DLMGCP MGCP client: using endpoint domain '@mgw'
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 17
-
===== test_hlr_rej_auth_info_unknown_imsi
- Location Update request causes a GSUP Send Auth Info request to HLR
MSC <--GERAN-A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
@@ -30,13 +26,14 @@ DREF VLR subscr IMSI-901700000004620 + active-conn: now used by 2 (_lu_fsm_assoc
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH
DREF VLR subscr IMSI-901700000004620 - _lu_fsm_associate_vsub: now used by 1 (active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Allocated
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU)
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
-GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f00a0101
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f02801020a0101
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - mm_rx_loc_upd_req: now used by 2 (rx_from_ms,lu)
DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu)
@@ -46,11 +43,11 @@ DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: n
DREF VLR subscr IMSI-901700000004620 + vlr_gsup_rx: now used by 2 (active-conn,vlr_gsup_rx)
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: Received Event VLR_AUTH_E_HLR_SAI_NACK
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: GSUP: rx Auth Info Error cause: 2: IMSI unknown in HLR
-DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: Authentication terminating with result IMSI unknown in HLR
+DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: Authentication terminating with result NO_AUTH_INFO, cause IMSI_UNKNOWN_IN_HLR
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: state_chg to VLR_SUB_AS_AUTH_FAILED
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_AUTH_FAILED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_AUTH_FAILED}: Removing from parent vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU)
-DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES
+DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_NO_INFO
- sending LU Reject for IMSI-901700000004620:GERAN-A:LU, cause 2
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_DONE
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: Received Event MSC_A_EV_CN_CLOSE
@@ -65,7 +62,6 @@ DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_RELEASING}: + wait-Clear-Co
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_RELEASING}: RAN encode: CLEAR_COMMAND on GERAN-A
DMSC dummy_msc_i(IMSI-901700000004620:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DREF VLR subscr IMSI-901700000004620 - msc_a_fsm_releasing_onenter: now used by 2 (active-conn,vlr_gsup_rx)
-DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_RELEASING}: transition to state MSC_A_ST_RELEASING not permitted!
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_AUTH_FAILED}: Deallocated
DREF VLR subscr IMSI-901700000004620 - vlr_gsup_rx: now used by 1 (active-conn)
<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_ERROR: vlr_gsupc_read_cb() returns 0
@@ -101,9 +97,6 @@ DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_RELEASED}: Deallocated, inc
llist_count(&msub_list) == 0
===== test_hlr_rej_auth_info_unknown_imsi: SUCCESS
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 17
-
===== test_hlr_rej_auth_info_net_fail
- Location Update request causes a GSUP Send Auth Info request to HLR
MSC <--GERAN-A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
@@ -132,13 +125,14 @@ DREF VLR subscr IMSI-901700000004620 + active-conn: now used by 2 (_lu_fsm_assoc
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH
DREF VLR subscr IMSI-901700000004620 - _lu_fsm_associate_vsub: now used by 1 (active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Allocated
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU)
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
-GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f00a0101
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f02801020a0101
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - mm_rx_loc_upd_req: now used by 2 (rx_from_ms,lu)
DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu)
@@ -148,11 +142,11 @@ DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: n
DREF VLR subscr IMSI-901700000004620 + vlr_gsup_rx: now used by 2 (active-conn,vlr_gsup_rx)
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: Received Event VLR_AUTH_E_HLR_SAI_NACK
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: GSUP: rx Auth Info Error cause: 17: Network failure
-DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: Authentication terminating with result Network failure
+DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: Authentication terminating with result NO_AUTH_INFO, cause NETWORK_FAILURE
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: state_chg to VLR_SUB_AS_AUTH_FAILED
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_AUTH_FAILED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_AUTH_FAILED}: Removing from parent vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU)
-DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES
+DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_NO_INFO
- sending LU Reject for IMSI-901700000004620:GERAN-A:LU, cause 17
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_DONE
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: Received Event MSC_A_EV_CN_CLOSE
@@ -167,7 +161,6 @@ DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_RELEASING}: + wait-Clear-Co
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_RELEASING}: RAN encode: CLEAR_COMMAND on GERAN-A
DMSC dummy_msc_i(IMSI-901700000004620:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DREF VLR subscr IMSI-901700000004620 - msc_a_fsm_releasing_onenter: now used by 2 (active-conn,vlr_gsup_rx)
-DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_RELEASING}: transition to state MSC_A_ST_RELEASING not permitted!
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_AUTH_FAILED}: Deallocated
DREF VLR subscr IMSI-901700000004620 - vlr_gsup_rx: now used by 1 (active-conn)
<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_ERROR: vlr_gsupc_read_cb() returns 0
@@ -203,9 +196,6 @@ DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_RELEASED}: Deallocated, inc
llist_count(&msub_list) == 0
===== test_hlr_rej_auth_info_net_fail: SUCCESS
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 17
-
===== test_hlr_rej_auth_info_net_fail_reuse_tuples
@@ -237,13 +227,14 @@ DREF VLR subscr IMSI-901700000004620 + active-conn: now used by 2 (_lu_fsm_assoc
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH
DREF VLR subscr IMSI-901700000004620 - _lu_fsm_associate_vsub: now used by 1 (active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Allocated
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU)
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
-GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f00a0101
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f02801020a0101
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - mm_rx_loc_upd_req: now used by 2 (rx_from_ms,lu)
DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu)
@@ -275,9 +266,11 @@ DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: Au
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU)
-DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES
+DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_SUCCESS
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_ciph()
+DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000004620:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_node_4()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
DVLR upd_hlr_vlr_fsm(IMSI-901700000004620:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated
@@ -399,13 +392,14 @@ DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + active-conn: now used by 3 (
DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK
DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - _lu_fsm_associate_vsub: now used by 2 (attached,active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre()
DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH
DVLR VLR_Authenticate(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Allocated
DVLR VLR_Authenticate(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU)
DVLR VLR_Authenticate(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
-GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f00a0101
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f02801020a0101
DVLR VLR_Authenticate(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
DREF msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - mm_rx_loc_upd_req: now used by 2 (rx_from_ms,lu)
DREF msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu)
@@ -437,9 +431,11 @@ DVLR VLR_Authenticate(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_SUB_AS_W
DVLR VLR_Authenticate(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
DVLR VLR_Authenticate(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
DVLR VLR_Authenticate(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU)
-DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES
+DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_SUCCESS
DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth()
DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_ciph()
+DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_node_4()
DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
DVLR upd_hlr_vlr_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated
@@ -529,9 +525,6 @@ DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_RELEASED}: Dea
DVLR freeing VLR subscr IMSI-901700000004620:MSISDN-46071 (max total use count was 5)
===== test_hlr_rej_auth_info_net_fail_reuse_tuples: SUCCESS
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 17
-
===== test_hlr_rej_auth_info_net_fail_no_reuse_tuples
@@ -563,13 +556,14 @@ DREF VLR subscr IMSI-901700000004620 + active-conn: now used by 2 (_lu_fsm_assoc
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH
DREF VLR subscr IMSI-901700000004620 - _lu_fsm_associate_vsub: now used by 1 (active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Allocated
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU)
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
-GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f00a0101
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f02801020a0101
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - mm_rx_loc_upd_req: now used by 2 (rx_from_ms,lu)
DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu)
@@ -601,9 +595,11 @@ DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: Au
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU)
-DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES
+DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_SUCCESS
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_ciph()
+DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000004620:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_node_4()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
DVLR upd_hlr_vlr_fsm(IMSI-901700000004620:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated
@@ -725,13 +721,14 @@ DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + active-conn: now used by 3 (
DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK
DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - _lu_fsm_associate_vsub: now used by 2 (attached,active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre()
DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH
DVLR VLR_Authenticate(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Allocated
DVLR VLR_Authenticate(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU)
DVLR VLR_Authenticate(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
-GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f00a0101
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f02801020a0101
DVLR VLR_Authenticate(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
DREF msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - mm_rx_loc_upd_req: now used by 2 (rx_from_ms,lu)
DREF msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu)
@@ -741,11 +738,11 @@ DREF msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: -
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + vlr_gsup_rx: now used by 3 (attached,active-conn,vlr_gsup_rx)
DVLR VLR_Authenticate(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: Received Event VLR_AUTH_E_HLR_SAI_NACK
DVLR VLR_Authenticate(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: GSUP: rx Auth Info Error cause: 17: Network failure
-DVLR VLR_Authenticate(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: Authentication terminating with result Network failure
+DVLR VLR_Authenticate(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: Authentication terminating with result NO_AUTH_INFO, cause NETWORK_FAILURE
DVLR VLR_Authenticate(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: state_chg to VLR_SUB_AS_AUTH_FAILED
DVLR VLR_Authenticate(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_SUB_AS_AUTH_FAILED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
DVLR VLR_Authenticate(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_SUB_AS_AUTH_FAILED}: Removing from parent vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU)
-DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES
+DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_NO_INFO
- sending LU Reject for IMSI-901700000004620:MSISDN-46071:GERAN-A:LU, cause 17
DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_DONE
DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: Received Event MSC_A_EV_CN_CLOSE
@@ -760,7 +757,6 @@ DREF msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_RELEASING}: +
DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_RELEASING}: RAN encode: CLEAR_COMMAND on GERAN-A
DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - msc_a_fsm_releasing_onenter: now used by 3 (attached,active-conn,vlr_gsup_rx)
-DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_RELEASING}: transition to state MSC_A_ST_RELEASING not permitted!
DVLR VLR_Authenticate(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_SUB_AS_AUTH_FAILED}: Deallocated
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - vlr_gsup_rx: now used by 2 (attached,active-conn)
<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_ERROR: vlr_gsupc_read_cb() returns 0
@@ -796,9 +792,6 @@ DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_RELEASED}: Dea
DVLR freeing VLR subscr IMSI-901700000004620:MSISDN-46071 (max total use count was 5)
===== test_hlr_rej_auth_info_net_fail_no_reuse_tuples: SUCCESS
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 17
-
===== test_hlr_rej_auth_info_unkown_imsi_no_reuse_tuples
@@ -830,13 +823,14 @@ DREF VLR subscr IMSI-901700000004620 + active-conn: now used by 2 (_lu_fsm_assoc
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH
DREF VLR subscr IMSI-901700000004620 - _lu_fsm_associate_vsub: now used by 1 (active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Allocated
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU)
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
-GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f00a0101
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f02801020a0101
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - mm_rx_loc_upd_req: now used by 2 (rx_from_ms,lu)
DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu)
@@ -868,9 +862,11 @@ DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: Au
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU)
-DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES
+DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_SUCCESS
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_ciph()
+DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000004620:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_node_4()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
DVLR upd_hlr_vlr_fsm(IMSI-901700000004620:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated
@@ -993,13 +989,14 @@ DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + active-conn: now used by 3 (
DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK
DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - _lu_fsm_associate_vsub: now used by 2 (attached,active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre()
DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH
DVLR VLR_Authenticate(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Allocated
DVLR VLR_Authenticate(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU)
DVLR VLR_Authenticate(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
-GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f00a0101
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f02801020a0101
DVLR VLR_Authenticate(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
DREF msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - mm_rx_loc_upd_req: now used by 2 (rx_from_ms,lu)
DREF msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu)
@@ -1009,11 +1006,11 @@ DREF msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: -
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + vlr_gsup_rx: now used by 3 (attached,active-conn,vlr_gsup_rx)
DVLR VLR_Authenticate(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: Received Event VLR_AUTH_E_HLR_SAI_NACK
DVLR VLR_Authenticate(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: GSUP: rx Auth Info Error cause: 2: IMSI unknown in HLR
-DVLR VLR_Authenticate(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: Authentication terminating with result IMSI unknown in HLR
+DVLR VLR_Authenticate(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: Authentication terminating with result NO_AUTH_INFO, cause IMSI_UNKNOWN_IN_HLR
DVLR VLR_Authenticate(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: state_chg to VLR_SUB_AS_AUTH_FAILED
DVLR VLR_Authenticate(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_SUB_AS_AUTH_FAILED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
DVLR VLR_Authenticate(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_SUB_AS_AUTH_FAILED}: Removing from parent vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU)
-DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES
+DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_NO_INFO
- sending LU Reject for IMSI-901700000004620:MSISDN-46071:GERAN-A:LU, cause 2
DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_DONE
DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: Received Event MSC_A_EV_CN_CLOSE
@@ -1028,7 +1025,6 @@ DREF msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_RELEASING}: +
DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_RELEASING}: RAN encode: CLEAR_COMMAND on GERAN-A
DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - msc_a_fsm_releasing_onenter: now used by 3 (attached,active-conn,vlr_gsup_rx)
-DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_RELEASING}: transition to state MSC_A_ST_RELEASING not permitted!
DVLR VLR_Authenticate(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_SUB_AS_AUTH_FAILED}: Deallocated
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - vlr_gsup_rx: now used by 2 (attached,active-conn)
<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_ERROR: vlr_gsupc_read_cb() returns 0
@@ -1064,9 +1060,6 @@ DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_RELEASED}: Dea
DVLR freeing VLR subscr IMSI-901700000004620:MSISDN-46071 (max total use count was 5)
===== test_hlr_rej_auth_info_unkown_imsi_no_reuse_tuples: SUCCESS
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 17
-
===== test_hlr_acc_but_no_auth_tuples
- Location Update request causes a GSUP Send Auth Info request to HLR
MSC <--GERAN-A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
@@ -1095,13 +1088,14 @@ DREF VLR subscr IMSI-901700000004620 + active-conn: now used by 2 (_lu_fsm_assoc
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH
DREF VLR subscr IMSI-901700000004620 - _lu_fsm_associate_vsub: now used by 1 (active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Allocated
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU)
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
-GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f00a0101
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f02801020a0101
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - mm_rx_loc_upd_req: now used by 2 (rx_from_ms,lu)
DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu)
@@ -1110,11 +1104,11 @@ DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: n
<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT: 0a010809710000004026f00a0101
DREF VLR subscr IMSI-901700000004620 + vlr_gsup_rx: now used by 2 (active-conn,vlr_gsup_rx)
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: Received Event VLR_AUTH_E_HLR_SAI_ACK
-DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: Authentication terminating with result Network failure
+DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: Authentication terminating with result FAILURE, cause NETWORK_FAILURE
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: state_chg to VLR_SUB_AS_AUTH_FAILED
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_AUTH_FAILED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_AUTH_FAILED}: Removing from parent vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU)
-DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES
+DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_FAILURE
- sending LU Reject for IMSI-901700000004620:GERAN-A:LU, cause 17
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_DONE
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: Received Event MSC_A_EV_CN_CLOSE
@@ -1129,7 +1123,6 @@ DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_RELEASING}: + wait-Clear-Co
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_RELEASING}: RAN encode: CLEAR_COMMAND on GERAN-A
DMSC dummy_msc_i(IMSI-901700000004620:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DREF VLR subscr IMSI-901700000004620 - msc_a_fsm_releasing_onenter: now used by 2 (active-conn,vlr_gsup_rx)
-DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_RELEASING}: transition to state MSC_A_ST_RELEASING not permitted!
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_AUTH_FAILED}: Deallocated
DREF VLR subscr IMSI-901700000004620 - vlr_gsup_rx: now used by 1 (active-conn)
<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT: vlr_gsupc_read_cb() returns 0
@@ -1165,9 +1158,6 @@ DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_RELEASED}: Deallocated, inc
llist_count(&msub_list) == 0
===== test_hlr_acc_but_no_auth_tuples: SUCCESS
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 17
-
===== test_hlr_rej_lu
- Location Update request causes a GSUP LU request to HLR
MSC <--GERAN-A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
@@ -1196,10 +1186,13 @@ DREF VLR subscr IMSI-901700000004620 + active-conn: now used by 2 (_lu_fsm_assoc
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH
DREF VLR subscr IMSI-901700000004620 - _lu_fsm_associate_vsub: now used by 1 (active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_post_auth()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_post_ciph()
+DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000004620:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node_4()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
DVLR upd_hlr_vlr_fsm(IMSI-901700000004620:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated
@@ -1234,7 +1227,6 @@ DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_RELEASING}: + wait-Clear-Co
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_RELEASING}: RAN encode: CLEAR_COMMAND on GERAN-A
DMSC dummy_msc_i(IMSI-901700000004620:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DREF VLR subscr IMSI-901700000004620 - msc_a_fsm_releasing_onenter: now used by 2 (active-conn,vlr_gsup_rx)
-DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_RELEASING}: transition to state MSC_A_ST_RELEASING not permitted!
DVLR upd_hlr_vlr_fsm(IMSI-901700000004620:GERAN-A:LU){UPD_HLR_VLR_S_DONE}: Deallocated
DREF VLR subscr IMSI-901700000004620 - vlr_gsup_rx: now used by 1 (active-conn)
<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_ERROR: vlr_gsupc_read_cb() returns 0
@@ -1269,9 +1261,6 @@ DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_RELEASED}: Deallocated, inc
llist_count(&msub_list) == 0
===== test_hlr_rej_lu: SUCCESS
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 17
-
===== test_hlr_no_insert_data
- Location Update request causes a GSUP LU request to HLR
MSC <--GERAN-A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
@@ -1300,10 +1289,13 @@ DREF VLR subscr IMSI-901700000004620 + active-conn: now used by 2 (_lu_fsm_assoc
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH
DREF VLR subscr IMSI-901700000004620 - _lu_fsm_associate_vsub: now used by 1 (active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_post_auth()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_post_ciph()
+DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000004620:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node_4()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
DVLR upd_hlr_vlr_fsm(IMSI-901700000004620:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated
@@ -1385,9 +1377,3 @@ DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_RELEASED}: Deallocated, inc
DVLR freeing VLR subscr IMSI-901700000004620 (max total use count was 5)
===== test_hlr_no_insert_data: SUCCESS
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 17
-
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 17
-
diff --git a/tests/msc_vlr/msc_vlr_test_hlr_timeout.c b/tests/msc_vlr/msc_vlr_test_hlr_timeout.c
index af5441b7c..4523a7c7b 100644
--- a/tests/msc_vlr/msc_vlr_test_hlr_timeout.c
+++ b/tests/msc_vlr/msc_vlr_test_hlr_timeout.c
@@ -22,7 +22,6 @@
*/
#include "msc_vlr_tests.h"
-#include "stubs.h"
#include <osmocom/core/logging.h>
@@ -36,7 +35,7 @@ static void test_hlr_timeout_lu_auth_info()
btw("Location Update request causes a GSUP Send Auth Info request to HLR");
lu_result_sent = RES_NONE;
- gsup_expect_tx("08010809710000004026f0" VLR_TO_HLR);
+ gsup_expect_tx("08010809710000004026f0" CN_DOMAIN VLR_TO_HLR);
ms_sends_msg("050802008168000130089910070000006402");
OSMO_ASSERT(gsup_tx_confirmed);
VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
@@ -74,7 +73,7 @@ static void test_hlr_timeout_lu_upd_loc_result()
btw("Location Update request causes a GSUP LU request to HLR");
lu_result_sent = RES_NONE;
- gsup_expect_tx("04010809710000004026f0280102" VLR_TO_HLR);
+ gsup_expect_tx("04010809710000004026f0" CN_DOMAIN VLR_TO_HLR);
ms_sends_msg("050802008168000130089910070000006402");
OSMO_ASSERT(gsup_tx_confirmed);
VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
diff --git a/tests/msc_vlr/msc_vlr_test_hlr_timeout.err b/tests/msc_vlr/msc_vlr_test_hlr_timeout.err
index 60b240da6..6a4daa5bd 100644
--- a/tests/msc_vlr/msc_vlr_test_hlr_timeout.err
+++ b/tests/msc_vlr/msc_vlr_test_hlr_timeout.err
@@ -1,7 +1,3 @@
-DLMGCP MGCP client: using endpoint domain '@mgw'
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 17
-
===== test_hlr_timeout_lu_auth_info
- Total time passed: 0.000000 s
- Location Update request causes a GSUP Send Auth Info request to HLR
@@ -31,13 +27,14 @@ DREF VLR subscr IMSI-901700000004620 + active-conn: now used by 2 (_lu_fsm_assoc
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH
DREF VLR subscr IMSI-901700000004620 - _lu_fsm_associate_vsub: now used by 1 (active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Allocated
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU)
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
-GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f00a0101
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f02801020a0101
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - mm_rx_loc_upd_req: now used by 2 (rx_from_ms,lu)
DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu)
@@ -68,13 +65,11 @@ DREF VLR subscr IMSI-901700000004620 + vlr_subscr_cancel_attach_fsm: now used by
- sending LU Reject for IMSI-901700000004620:GERAN-A:LU, cause 22
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_DONE
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_RELEASING}: Received Event MSC_A_EV_CN_CLOSE
-DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_RELEASING}: Event MSC_A_EV_CN_CLOSE not permitted
DREF VLR subscr IMSI-901700000004620 - vlr_subscr_cancel_attach_fsm: now used by 2 (active-conn,msc_a_fsm_releasing_onenter)
DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_RELEASING}: + wait-Clear-Complete: now used by 1 (wait-Clear-Complete)
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_RELEASING}: RAN encode: CLEAR_COMMAND on GERAN-A
DMSC dummy_msc_i(IMSI-901700000004620:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DREF VLR subscr IMSI-901700000004620 - msc_a_fsm_releasing_onenter: now used by 1 (active-conn)
-DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_RELEASING}: transition to state MSC_A_ST_RELEASING not permitted!
- RAN_CONN_TIMEOUT has passed, conn is gone.
bssap_clear_sent == 1
DBSSAP msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_RELEASING}: RAN decode: CLEAR_COMPLETE
@@ -110,9 +105,6 @@ DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_RELEASED}: Deallocated, inc
lu_result_sent == 2
===== test_hlr_timeout_lu_auth_info: SUCCESS
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 17
-
===== test_hlr_timeout_lu_upd_loc_result
- Total time passed: 0.000000 s
- Location Update request causes a GSUP LU request to HLR
@@ -142,10 +134,13 @@ DREF VLR subscr IMSI-901700000004620 + active-conn: now used by 2 (_lu_fsm_assoc
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH
DREF VLR subscr IMSI-901700000004620 - _lu_fsm_associate_vsub: now used by 1 (active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_post_auth()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_post_ciph()
+DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000004620:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node_4()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
DVLR upd_hlr_vlr_fsm(IMSI-901700000004620:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated
@@ -196,13 +191,11 @@ DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + vlr_subscr_cancel_attach_fsm
- sending LU Reject for IMSI-901700000004620:MSISDN-46071:GERAN-A:LU, cause 22
DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_DONE
DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_RELEASING}: Received Event MSC_A_EV_CN_CLOSE
-DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_RELEASING}: Event MSC_A_EV_CN_CLOSE not permitted
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - vlr_subscr_cancel_attach_fsm: now used by 2 (active-conn,msc_a_fsm_releasing_onenter)
DREF msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_RELEASING}: + wait-Clear-Complete: now used by 1 (wait-Clear-Complete)
DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_RELEASING}: RAN encode: CLEAR_COMMAND on GERAN-A
DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - msc_a_fsm_releasing_onenter: now used by 1 (active-conn)
-DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_RELEASING}: transition to state MSC_A_ST_RELEASING not permitted!
- RAN_CONN_TIMEOUT has passed, conn is gone.
bssap_clear_sent == 1
DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_RELEASING}: RAN decode: CLEAR_COMPLETE
@@ -238,9 +231,3 @@ DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_RELEASED}: Dea
lu_result_sent == 2
===== test_hlr_timeout_lu_upd_loc_result: SUCCESS
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 17
-
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 17
-
diff --git a/tests/msc_vlr/msc_vlr_test_ms_timeout.c b/tests/msc_vlr/msc_vlr_test_ms_timeout.c
index 450909fe9..11afc5196 100644
--- a/tests/msc_vlr/msc_vlr_test_ms_timeout.c
+++ b/tests/msc_vlr/msc_vlr_test_ms_timeout.c
@@ -22,7 +22,6 @@
*/
#include "msc_vlr_tests.h"
-#include "stubs.h"
static void test_ms_timeout_lu_auth_resp()
{
@@ -34,7 +33,7 @@ static void test_ms_timeout_lu_auth_resp()
btw("Location Update request causes a GSUP Send Auth Info request to HLR");
lu_result_sent = RES_NONE;
- gsup_expect_tx("08010809710000004026f0" VLR_TO_HLR);
+ gsup_expect_tx("08010809710000004026f0" CN_DOMAIN VLR_TO_HLR);
ms_sends_msg("050802008168000130089910070000006402");
OSMO_ASSERT(gsup_tx_confirmed);
VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
@@ -95,7 +94,7 @@ static void test_ms_timeout_cm_auth_resp()
btw("Location Update request causes a GSUP Send Auth Info request to HLR");
lu_result_sent = RES_NONE;
- gsup_expect_tx("08010809710000004026f0" VLR_TO_HLR);
+ gsup_expect_tx("08010809710000004026f0" CN_DOMAIN VLR_TO_HLR);
ms_sends_msg("050802008168000130089910070000006402");
OSMO_ASSERT(gsup_tx_confirmed);
VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
@@ -126,7 +125,7 @@ static void test_ms_timeout_cm_auth_resp()
VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
btw("MS sends Authen Response, VLR accepts and sends GSUP LU Req to HLR");
- gsup_expect_tx("04010809710000004026f0280102" VLR_TO_HLR);
+ gsup_expect_tx("04010809710000004026f0" CN_DOMAIN VLR_TO_HLR);
ms_sends_msg("05542d8b2c3e");
VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
@@ -196,7 +195,7 @@ static void test_ms_timeout_paging()
btw("Location Update request causes a GSUP LU request to HLR");
lu_result_sent = RES_NONE;
- gsup_expect_tx("04010809710000004026f0280102" VLR_TO_HLR);
+ gsup_expect_tx("04010809710000004026f0" CN_DOMAIN VLR_TO_HLR);
ms_sends_msg("050802008168000130089910070000006402");
OSMO_ASSERT(gsup_tx_confirmed);
VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
@@ -297,7 +296,7 @@ static void test_classmark_update_timeout()
btw("Location Update request causes a GSUP Send Auth Info request to HLR");
lu_result_sent = RES_NONE;
- gsup_expect_tx("08010809710000004026f0" VLR_TO_HLR);
+ gsup_expect_tx("08010809710000004026f0" CN_DOMAIN VLR_TO_HLR);
ms_sends_msg("050802008168000130089910070000006402");
OSMO_ASSERT(gsup_tx_confirmed);
VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
diff --git a/tests/msc_vlr/msc_vlr_test_ms_timeout.err b/tests/msc_vlr/msc_vlr_test_ms_timeout.err
index 07f2b5b40..c4a73e35b 100644
--- a/tests/msc_vlr/msc_vlr_test_ms_timeout.err
+++ b/tests/msc_vlr/msc_vlr_test_ms_timeout.err
@@ -1,7 +1,3 @@
-DLMGCP MGCP client: using endpoint domain '@mgw'
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 17
-
===== test_ms_timeout_lu_auth_resp
- Total time passed: 0.000000 s
- Location Update request causes a GSUP Send Auth Info request to HLR
@@ -31,13 +27,14 @@ DREF VLR subscr IMSI-901700000004620 + active-conn: now used by 2 (_lu_fsm_assoc
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH
DREF VLR subscr IMSI-901700000004620 - _lu_fsm_associate_vsub: now used by 1 (active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Allocated
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU)
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
-GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f00a0101
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f02801020a0101
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - mm_rx_loc_upd_req: now used by 2 (rx_from_ms,lu)
DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu)
@@ -87,13 +84,11 @@ DREF VLR subscr IMSI-901700000004620 + vlr_subscr_cancel_attach_fsm: now used by
- sending LU Reject for IMSI-901700000004620:GERAN-A:LU, cause 22
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_DONE
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_RELEASING}: Received Event MSC_A_EV_CN_CLOSE
-DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_RELEASING}: Event MSC_A_EV_CN_CLOSE not permitted
DREF VLR subscr IMSI-901700000004620 - vlr_subscr_cancel_attach_fsm: now used by 2 (active-conn,msc_a_fsm_releasing_onenter)
DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_RELEASING}: + wait-Clear-Complete: now used by 1 (wait-Clear-Complete)
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_RELEASING}: RAN encode: CLEAR_COMMAND on GERAN-A
DMSC dummy_msc_i(IMSI-901700000004620:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DREF VLR subscr IMSI-901700000004620 - msc_a_fsm_releasing_onenter: now used by 1 (active-conn)
-DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_RELEASING}: transition to state MSC_A_ST_RELEASING not permitted!
- RAN_CONN_TIMEOUT has passed, conn is gone.
bssap_clear_sent == 1
DBSSAP msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_RELEASING}: RAN decode: CLEAR_COMPLETE
@@ -129,9 +124,6 @@ DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_RELEASED}: Deallocated, inc
lu_result_sent == 2
===== test_ms_timeout_lu_auth_resp: SUCCESS
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 17
-
===== test_ms_timeout_cm_auth_resp
- Total time passed: 0.000000 s
- Location Update request causes a GSUP Send Auth Info request to HLR
@@ -161,13 +153,14 @@ DREF VLR subscr IMSI-901700000004620 + active-conn: now used by 2 (_lu_fsm_assoc
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH
DREF VLR subscr IMSI-901700000004620 - _lu_fsm_associate_vsub: now used by 1 (active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Allocated
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU)
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
-GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f00a0101
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f02801020a0101
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - mm_rx_loc_upd_req: now used by 2 (rx_from_ms,lu)
DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu)
@@ -199,9 +192,11 @@ DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: Au
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU)
-DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES
+DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_SUCCESS
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_ciph()
+DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000004620:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_node_4()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
DVLR upd_hlr_vlr_fsm(IMSI-901700000004620:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated
@@ -359,7 +354,6 @@ DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SER
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_DONE}: Process Access Request result: CONGESTION
- sending CM Service Reject (Short-Messaging-Service) for IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ, cause: CONGESTION
DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: Received Event MSC_A_EV_CN_CLOSE
-DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: Event MSC_A_EV_CN_CLOSE not permitted
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,active-conn,msc_a_fsm_releasing_onenter)
DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: Releasing: canceling still pending use: cm_service_sms (1)
DREF msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: - cm_service_sms: now used by 0 (-)
@@ -402,9 +396,6 @@ DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RE
DVLR freeing VLR subscr IMSI-901700000004620:MSISDN-46071 (max total use count was 5)
===== test_ms_timeout_cm_auth_resp: SUCCESS
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 17
-
===== test_ms_timeout_paging
- Total time passed: 0.000000 s
- Location Update request causes a GSUP LU request to HLR
@@ -434,10 +425,13 @@ DREF VLR subscr IMSI-901700000004620 + active-conn: now used by 2 (_lu_fsm_assoc
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH
DREF VLR subscr IMSI-901700000004620 - _lu_fsm_associate_vsub: now used by 1 (active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_post_auth()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_post_ciph()
+DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000004620:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node_4()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
DVLR upd_hlr_vlr_fsm(IMSI-901700000004620:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated
@@ -647,7 +641,7 @@ DMSC dummy_msc_i{0}: is child of msub_fsm
DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms)
DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3
DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: MM GSM48_MT_MM_IMSI_DETACH_IND
-DMM IMSI DETACH INDICATION: MI(IMSI)=901700000004620
+DMM IMSI DETACH INDICATION: IMSI-901700000004620
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + gsm48_rx_mm_imsi_detach_ind: now used by 5 (attached,SMS-receiver,SMS,Paging,gsm48_rx_mm_imsi_detach_ind)
DMM IMSI DETACH for IMSI-901700000004620:MSISDN-46071
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + active-conn: now used by 6 (attached,SMS-receiver,SMS,Paging,gsm48_rx_mm_imsi_detach_ind,active-conn)
@@ -671,6 +665,7 @@ DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - SMS: now used by 4 (attached
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - Paging: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn)
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn,vlr_subscr_cancel_attach_fsm)
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - attached: now used by 2 (gsm48_rx_mm_imsi_detach_ind,active-conn)
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - gsm48_rx_mm_imsi_detach_ind: now used by 1 (active-conn)
DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_CN_CLOSE
@@ -710,9 +705,6 @@ DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:NONE){MSC_A_ST_RELEASED}: D
llist_count(&msub_list) == 0
===== test_ms_timeout_paging: SUCCESS
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 17
-
===== test_classmark_update_timeout
- Total time passed: 0.000000 s
- Location Update request causes a GSUP Send Auth Info request to HLR
@@ -742,13 +734,14 @@ DREF VLR subscr IMSI-901700000004620 + active-conn: now used by 2 (_lu_fsm_assoc
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH
DREF VLR subscr IMSI-901700000004620 - _lu_fsm_associate_vsub: now used by 1 (active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Allocated
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU)
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
-GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f00a0101
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f02801020a0101
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - mm_rx_loc_upd_req: now used by 2 (rx_from_ms,lu)
DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu)
@@ -782,7 +775,7 @@ DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: Au
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
DVLR VLR_Authenticate(IMSI-901700000004620:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU)
-DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES
+DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_SUCCESS
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Set Ciphering Mode
DBSSAP msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: For A5/3, we still need Classmark 2
@@ -825,7 +818,6 @@ DREF VLR subscr IMSI-901700000004620 + vlr_subscr_cancel_attach_fsm: now used by
- sending LU Reject for IMSI-901700000004620:GERAN-A:LU, cause 22
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_CIPH}: state_chg to VLR_ULA_S_DONE
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_RELEASING}: Received Event MSC_A_EV_CN_CLOSE
-DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_RELEASING}: Event MSC_A_EV_CN_CLOSE not permitted
DREF VLR subscr IMSI-901700000004620 - vlr_subscr_cancel_attach_fsm: now used by 2 (active-conn,msc_a_fsm_releasing_onenter)
DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_RELEASING}: + wait-Clear-Complete: now used by 1 (wait-Clear-Complete)
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_RELEASING}: RAN encode: CLEAR_COMMAND on GERAN-A
@@ -863,9 +855,3 @@ DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_RELEASED}: Deallocated, inc
lu_result_sent == 2
===== test_classmark_update_timeout: SUCCESS
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 17
-
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 17
-
diff --git a/tests/msc_vlr/msc_vlr_test_no_authen.c b/tests/msc_vlr/msc_vlr_test_no_authen.c
index b3289f3eb..5d3db69ae 100644
--- a/tests/msc_vlr/msc_vlr_test_no_authen.c
+++ b/tests/msc_vlr/msc_vlr_test_no_authen.c
@@ -22,7 +22,6 @@
*/
#include "msc_vlr_tests.h"
-#include "stubs.h"
static void test_no_authen()
{
@@ -35,7 +34,7 @@ static void test_no_authen()
btw("Location Update request causes a GSUP LU request to HLR");
lu_result_sent = RES_NONE;
- gsup_expect_tx("04010809710000004026f0280102" VLR_TO_HLR);
+ gsup_expect_tx("04010809710000004026f0" CN_DOMAIN VLR_TO_HLR);
ms_sends_msg("050802008168000130089910070000006402");
OSMO_ASSERT(gsup_tx_confirmed);
VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
@@ -70,7 +69,7 @@ static void test_no_authen()
EXPECT_ACCEPTED(true);
/* Release connection */
- expect_bssap_clear(OSMO_RAT_GERAN_A);
+ expect_bssap_clear();
conn_conclude_cm_service_req(g_msub, MSC_A_USE_CM_SERVICE_SMS);
btw("all requests serviced, conn has been released");
@@ -172,7 +171,7 @@ static void test_no_authen_tmsi()
btw("Location Update request causes a GSUP LU request to HLR");
lu_result_sent = RES_NONE;
- gsup_expect_tx("04010809710000004026f0280102" VLR_TO_HLR);
+ gsup_expect_tx("04010809710000004026f0" CN_DOMAIN VLR_TO_HLR);
ms_sends_msg("050802008168000130089910070000006402");
OSMO_ASSERT(gsup_tx_confirmed);
VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
@@ -228,7 +227,7 @@ static void test_no_authen_tmsi()
EXPECT_ACCEPTED(true);
/* Release connection */
- expect_bssap_clear(OSMO_RAT_GERAN_A);
+ expect_bssap_clear();
conn_conclude_cm_service_req(g_msub, MSC_A_USE_CM_SERVICE_SMS);
btw("all requests serviced, conn has been released");
@@ -317,7 +316,7 @@ static void test_no_authen_tmsi()
BTW("subscriber sends LU Request, this time with the TMSI");
btw("Location Update request causes a GSUP LU request to HLR");
lu_result_sent = RES_NONE;
- gsup_expect_tx("04010809710000004026f0280102" VLR_TO_HLR);
+ gsup_expect_tx("04010809710000004026f0" CN_DOMAIN VLR_TO_HLR);
ms_sends_msg("050802008168000130" "05f4" "03020100");
OSMO_ASSERT(gsup_tx_confirmed);
VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
@@ -390,7 +389,7 @@ static void test_no_authen_imei()
btw("Location Update request causes a GSUP LU request to HLR");
lu_result_sent = RES_NONE;
- gsup_expect_tx("04010809710000004026f0280102" VLR_TO_HLR);
+ gsup_expect_tx("04010809710000004026f0" CN_DOMAIN VLR_TO_HLR);
ms_sends_msg("050802008168000130089910070000006402");
OSMO_ASSERT(gsup_tx_confirmed);
VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
@@ -465,7 +464,7 @@ static void test_no_authen_tmsi_imei()
btw("Location Update request causes a GSUP LU request to HLR");
lu_result_sent = RES_NONE;
- gsup_expect_tx("04010809710000004026f0280102" VLR_TO_HLR);
+ gsup_expect_tx("04010809710000004026f0" CN_DOMAIN VLR_TO_HLR);
ms_sends_msg("050802008168000130089910070000006402");
OSMO_ASSERT(gsup_tx_confirmed);
VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
@@ -553,7 +552,7 @@ static void test_no_authen_imeisv()
OSMO_ASSERT(dtap_tx_confirmed);
btw("MS replies with an Identity Response, causes LU to commence with a GSUP LU request to HLR");
- gsup_expect_tx("04010809710000004026f0280102" VLR_TO_HLR);
+ gsup_expect_tx("04010809710000004026f0" CN_DOMAIN VLR_TO_HLR);
ms_sends_msg("0559094332244332244372f5");
OSMO_ASSERT(gsup_tx_confirmed);
VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
@@ -629,7 +628,7 @@ static void test_no_authen_imeisv_imei()
btw("HLR accepts the IMEI, VLR responds with LU Request");
expect_bssap_clear();
gsup_rx("32010809710000004026f0510100" HLR_TO_VLR,
- "04010809710000004026f0280102" VLR_TO_HLR);
+ "04010809710000004026f0" CN_DOMAIN VLR_TO_HLR);
OSMO_ASSERT(gsup_tx_confirmed);
VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
@@ -687,7 +686,7 @@ static void test_no_authen_imeisv_tmsi()
OSMO_ASSERT(dtap_tx_confirmed);
btw("MS replies with an Identity Response, causes LU to commence with a GSUP LU request to HLR");
- gsup_expect_tx("04010809710000004026f0280102" VLR_TO_HLR);
+ gsup_expect_tx("04010809710000004026f0" CN_DOMAIN VLR_TO_HLR);
ms_sends_msg("0559094332244332244372f5");
OSMO_ASSERT(gsup_tx_confirmed);
VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
@@ -743,7 +742,7 @@ static void test_no_authen_imeisv_tmsi()
OSMO_ASSERT(dtap_tx_confirmed);
btw("MS replies with an Identity Response, causes LU to commence with a GSUP LU request to HLR");
- gsup_expect_tx("04010809710000004026f0280102" VLR_TO_HLR);
+ gsup_expect_tx("04010809710000004026f0" CN_DOMAIN VLR_TO_HLR);
ms_sends_msg("0559095332244332244372f6");
OSMO_ASSERT(gsup_tx_confirmed);
VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
@@ -842,7 +841,7 @@ static void test_no_authen_imeisv_tmsi_imei()
btw("HLR accepts the IMEI, VLR responds with LU Request");
expect_bssap_clear();
gsup_rx("32010809710000004026f0510100" HLR_TO_VLR,
- "04010809710000004026f0280102" VLR_TO_HLR);
+ "04010809710000004026f0" CN_DOMAIN VLR_TO_HLR);
OSMO_ASSERT(gsup_tx_confirmed);
VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
@@ -916,7 +915,7 @@ static void test_no_authen_subscr_expire()
btw("Location Update request causes a GSUP LU request to HLR");
lu_result_sent = RES_NONE;
- gsup_expect_tx("04010809710000004026f0280102" VLR_TO_HLR);
+ gsup_expect_tx("04010809710000004026f0" CN_DOMAIN VLR_TO_HLR);
ms_sends_msg("050802008168000130089910070000006402");
OSMO_ASSERT(gsup_tx_confirmed);
VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
@@ -942,7 +941,7 @@ static void test_no_authen_subscr_expire()
vlr_subscr_put(vsub, __func__);
/* Let T3212 (periodic Location update timer) expire */
- fake_time_passes((net->t3212 * 60 * 6 * 2) + 60*4, 0);
+ fake_time_passes(vlr_timer(net->vlr, 3212) + 60 * 4, 0);
/* The subscriber should now be gone. */
vsub = vlr_subscr_find_by_imsi(net->vlr, imsi, __func__);
diff --git a/tests/msc_vlr/msc_vlr_test_no_authen.err b/tests/msc_vlr/msc_vlr_test_no_authen.err
index b6c069854..1cc55de80 100644
--- a/tests/msc_vlr/msc_vlr_test_no_authen.err
+++ b/tests/msc_vlr/msc_vlr_test_no_authen.err
@@ -1,7 +1,3 @@
-DLMGCP MGCP client: using endpoint domain '@mgw'
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 17
-
===== test_no_authen
- Location Update request causes a GSUP LU request to HLR
MSC <--GERAN-A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
@@ -30,10 +26,13 @@ DREF VLR subscr IMSI-901700000004620 + active-conn: now used by 2 (_lu_fsm_assoc
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH
DREF VLR subscr IMSI-901700000004620 - _lu_fsm_associate_vsub: now used by 1 (active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_post_auth()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_post_ciph()
+DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000004620:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node_4()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
DVLR upd_hlr_vlr_fsm(IMSI-901700000004620:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated
@@ -168,6 +167,8 @@ DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_VA
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi()
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_node2()
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_ciph()
+DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_vlr()
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_post_pres()
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_post_trace()
@@ -175,6 +176,7 @@ DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SER
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: proc_arq_fsm_done(PASSED)
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_DONE
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_DONE}: Process Access Request result: PASSED
+DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: Sending DTAP: MM GSM48_MT_MM_CM_SERV_ACC
DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN encode: DTAP on GERAN-A
- DTAP --GERAN-A--> MS: GSM48_MT_MM_CM_SERV_ACC: 0521
DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
@@ -263,7 +265,7 @@ DMSC dummy_msc_i{0}: is child of msub_fsm
DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms)
DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3
DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: RR GSM48_MT_RR_PAG_RESP
-DRR msc_a(IMSI-901700000004620:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: Rx PAGING RESPONSE
+DRR msc_a(IMSI-901700000004620:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: Rx PAGING RESPONSE IMSI-901700000004620
DREF msc_a(IMSI-901700000004620:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: + paging-response: now used by 2 (rx_from_ms,paging-response)
DVLR Process_Access_Request_VLR(IMSI-901700000004620:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: Allocated
DVLR Process_Access_Request_VLR(IMSI-901700000004620:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: is child of msc_a(IMSI-901700000004620:GERAN-A:PAGING_RESP)
@@ -276,6 +278,8 @@ DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_VALID
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi()
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_node2()
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_ciph()
+DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_vlr()
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_post_pres()
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_post_trace()
@@ -294,6 +298,7 @@ DLSMS SMC(0) send CP data
DLSMS SMC(0) new CP state MM_CONN_PENDING -> WAIT_CP_ACK
DLSMS trans(SMS IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x40000001 tid-0) sending CP message (trans=0)
DLSMS trans(SMS IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x40000001 tid-0) GSM4.11 TX 09 01 58 01 00 07 91 44 77 58 10 06 50 00 4c 00 05 80 64 70 f1 00 00 07 10 10 00 00 00 00 44 50 79 da 1e 1e e7 41 69 37 48 5e 9e a7 c9 65 37 3d 1d 66 83 c2 70 38 3b 3d 0e d3 d3 6f f7 1c 94 9e 83 c2 20 72 79 9e 96 87 c5 ec 32 a8 1d 96 af cb f4 b4 fb 0c 7a c3 e9 e9 b7 db 05
+DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: Sending DTAP: SMS SMS:0x01
DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: RAN encode: DTAP on GERAN-A
- DTAP --GERAN-A--> MS: SMS:0x01: 09015801000791447758100650004c0005806470f1000007101000000000445079da1e1ee7416937485e9ea7c965373d1d6683c270383b3d0ed3d36ff71c949e83c22072799e9687c5ec32a81d96afcbf4b4fb0c7ac3e9e9b7db05
- DTAP matches expected message
@@ -330,6 +335,7 @@ DLSMS SMC(0) message MMSMS-DATA-IND (CP DATA) received in state MM_ESTABLISHED
DLSMS SMC(0) received CP-DATA
DLSMS trans(SMS IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x40000001 tid-0) sending CP message (trans=0)
DLSMS trans(SMS IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x40000001 tid-0) GSM4.11 TX 09 04
+DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: Sending DTAP: SMS SMS:0x04
DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: RAN encode: DTAP on GERAN-A
- DTAP --GERAN-A--> MS: SMS:0x04: 0904
- DTAP matches expected message
@@ -402,12 +408,13 @@ DMSC dummy_msc_i{0}: is child of msub_fsm
DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms)
DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3
DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: MM GSM48_MT_MM_IMSI_DETACH_IND
-DMM IMSI DETACH INDICATION: MI(IMSI)=901700000004620
+DMM IMSI DETACH INDICATION: IMSI-901700000004620
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + gsm48_rx_mm_imsi_detach_ind: now used by 2 (attached,gsm48_rx_mm_imsi_detach_ind)
DMM IMSI DETACH for IMSI-901700000004620:MSISDN-46071
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + active-conn: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn)
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn,vlr_subscr_cancel_attach_fsm)
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - attached: now used by 2 (gsm48_rx_mm_imsi_detach_ind,active-conn)
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - gsm48_rx_mm_imsi_detach_ind: now used by 1 (active-conn)
DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_CN_CLOSE
@@ -447,9 +454,6 @@ DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:NONE){MSC_A_ST_RELEASED}: D
llist_count(&msub_list) == 0
===== test_no_authen: SUCCESS
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 17
-
===== test_no_authen_tmsi
- Location Update request causes a GSUP LU request to HLR
MSC <--GERAN-A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
@@ -478,10 +482,13 @@ DREF VLR subscr IMSI-901700000004620 + active-conn: now used by 2 (_lu_fsm_assoc
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH
DREF VLR subscr IMSI-901700000004620 - _lu_fsm_associate_vsub: now used by 1 (active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_post_auth()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_post_ciph()
+DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000004620:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node_4()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
DVLR upd_hlr_vlr_fsm(IMSI-901700000004620:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated
@@ -663,6 +670,8 @@ DMSC msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:CM_SERVICE_
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi()
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_node2()
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_ciph()
+DMSC msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_vlr()
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_post_pres()
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_post_trace()
@@ -670,6 +679,7 @@ DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:TMSI-0x0302010
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: proc_arq_fsm_done(PASSED)
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_DONE
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_DONE}: Process Access Request result: PASSED
+DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: Sending DTAP: MM GSM48_MT_MM_CM_SERV_ACC
DMSC msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN encode: DTAP on GERAN-A
- DTAP --GERAN-A--> MS: GSM48_MT_MM_CM_SERV_ACC: 0521
DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
@@ -758,7 +768,7 @@ DMSC dummy_msc_i{0}: is child of msub_fsm
DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms)
DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3
DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: RR GSM48_MT_RR_PAG_RESP
-DRR msc_a(TMSI-0x03020100:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: Rx PAGING RESPONSE
+DRR msc_a(TMSI-0x03020100:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: Rx PAGING RESPONSE TMSI-0x03020100
DREF msc_a(TMSI-0x03020100:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: + paging-response: now used by 2 (rx_from_ms,paging-response)
DVLR Process_Access_Request_VLR(TMSI-0x03020100:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: Allocated
DVLR Process_Access_Request_VLR(TMSI-0x03020100:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: is child of msc_a(TMSI-0x03020100:GERAN-A:PAGING_RESP)
@@ -771,6 +781,8 @@ DMSC msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:PAGING_RESP
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi()
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_node2()
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_ciph()
+DMSC msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_vlr()
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_post_pres()
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_post_trace()
@@ -789,6 +801,7 @@ DLSMS SMC(0) send CP data
DLSMS SMC(0) new CP state MM_CONN_PENDING -> WAIT_CP_ACK
DLSMS trans(SMS IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:PAGING_RESP callref-0x40000002 tid-0) sending CP message (trans=0)
DLSMS trans(SMS IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:PAGING_RESP callref-0x40000002 tid-0) GSM4.11 TX 09 01 58 01 00 07 91 44 77 58 10 06 50 00 4c 00 05 80 64 70 f1 00 00 07 10 10 00 00 00 00 44 50 79 da 1e 1e e7 41 69 37 48 5e 9e a7 c9 65 37 3d 1d 66 83 c2 70 38 3b 3d 0e d3 d3 6f f7 1c 94 9e 83 c2 20 72 79 9e 96 87 c5 ec 32 a8 1d 96 af cb f4 b4 fb 0c 7a c3 e9 e9 b7 db 05
+DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: Sending DTAP: SMS SMS:0x01
DMSC msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: RAN encode: DTAP on GERAN-A
- DTAP --GERAN-A--> MS: SMS:0x01: 09015801000791447758100650004c0005806470f1000007101000000000445079da1e1ee7416937485e9ea7c965373d1d6683c270383b3d0ed3d36ff71c949e83c22072799e9687c5ec32a81d96afcbf4b4fb0c7ac3e9e9b7db05
- DTAP matches expected message
@@ -825,6 +838,7 @@ DLSMS SMC(0) message MMSMS-DATA-IND (CP DATA) received in state MM_ESTABLISHED
DLSMS SMC(0) received CP-DATA
DLSMS trans(SMS IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:PAGING_RESP callref-0x40000002 tid-0) sending CP message (trans=0)
DLSMS trans(SMS IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:PAGING_RESP callref-0x40000002 tid-0) GSM4.11 TX 09 04
+DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: Sending DTAP: SMS SMS:0x04
DMSC msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: RAN encode: DTAP on GERAN-A
- DTAP --GERAN-A--> MS: SMS:0x04: 0904
- DTAP matches expected message
@@ -911,10 +925,13 @@ DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100 + active-conn:
DMSC msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK
DMSC msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH
DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100 - _lu_fsm_associate_vsub: now used by 2 (attached,active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre()
DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_post_auth()
DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_post_ciph()
+DMSC msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node_4()
DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
DVLR upd_hlr_vlr_fsm(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated
@@ -1082,12 +1099,13 @@ DMSC dummy_msc_i{0}: is child of msub_fsm
DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms)
DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3
DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: MM GSM48_MT_MM_IMSI_DETACH_IND
-DMM IMSI DETACH INDICATION: MI(TMSI)=117835012
+DMM IMSI DETACH INDICATION: TMSI-0x07060504
DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x07060504 + gsm48_rx_mm_imsi_detach_ind: now used by 2 (attached,gsm48_rx_mm_imsi_detach_ind)
DMM IMSI DETACH for IMSI-901700000004620:MSISDN-46071:TMSI-0x07060504
DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x07060504 + active-conn: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn)
DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x07060504 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn,vlr_subscr_cancel_attach_fsm)
DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x07060504 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x07060504 - attached: now used by 2 (gsm48_rx_mm_imsi_detach_ind,active-conn)
DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x07060504 - gsm48_rx_mm_imsi_detach_ind: now used by 1 (active-conn)
DMSC msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x07060504:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_CN_CLOSE
@@ -1127,9 +1145,6 @@ DMSC msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x07060504:GERAN-A:NONE){MSC_A
llist_count(&msub_list) == 0
===== test_no_authen_tmsi: SUCCESS
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 17
-
===== test_no_authen_imei
- Location Update request causes a GSUP LU request to HLR
MSC <--GERAN-A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
@@ -1158,10 +1173,13 @@ DREF VLR subscr IMSI-901700000004620 + active-conn: now used by 2 (_lu_fsm_assoc
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH
DREF VLR subscr IMSI-901700000004620 - _lu_fsm_associate_vsub: now used by 1 (active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_post_auth()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_post_ciph()
+DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000004620:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node_4()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
DVLR upd_hlr_vlr_fsm(IMSI-901700000004620:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated
@@ -1217,6 +1235,7 @@ DVLR lu_compl_vlr_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){LU_COMPL_VLR
DVLR lu_compl_vlr_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES
DVLR lu_compl_vlr_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL
DVLR lu_compl_vlr_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_WAIT_IMEI
+DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: Sending DTAP: MM GSM48_MT_MM_ID_REQ
DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: DTAP on GERAN-A
- DTAP --GERAN-A--> MS: GSM48_MT_MM_ID_REQ: 051802
- DTAP matches expected message
@@ -1252,7 +1271,7 @@ DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}:
DREF msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: + rx_from_ms: now used by 2 (lu,rx_from_ms)
DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN decode: DTAP
DRLL msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: Dispatching 04.08 message: MM GSM48_MT_MM_ID_RESP
-DMM IDENTITY RESPONSE: MI=IMEI-423423423423420
+DMM IDENTITY RESPONSE: IMEI-423423423423420
DVLR set IMEI on subscriber; IMSI=901700000004620 IMEI=42342342342342
DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_ID_IMEI
GSUP --> HLR: OSMO_GSUP_MSGT_CHECK_IMEI_REQUEST: 30010809710000004026f0500807244332244332240a0101
@@ -1332,12 +1351,13 @@ DMSC dummy_msc_i{0}: is child of msub_fsm
DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms)
DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3
DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: MM GSM48_MT_MM_IMSI_DETACH_IND
-DMM IMSI DETACH INDICATION: MI(IMSI)=901700000004620
+DMM IMSI DETACH INDICATION: IMSI-901700000004620
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + gsm48_rx_mm_imsi_detach_ind: now used by 2 (attached,gsm48_rx_mm_imsi_detach_ind)
DMM IMSI DETACH for IMSI-901700000004620:MSISDN-46071
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + active-conn: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn)
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn,vlr_subscr_cancel_attach_fsm)
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - attached: now used by 2 (gsm48_rx_mm_imsi_detach_ind,active-conn)
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - gsm48_rx_mm_imsi_detach_ind: now used by 1 (active-conn)
DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_CN_CLOSE
@@ -1377,9 +1397,6 @@ DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:NONE){MSC_A_ST_RELEASED}: D
llist_count(&msub_list) == 0
===== test_no_authen_imei: SUCCESS
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 17
-
===== test_no_authen_tmsi_imei
- Location Update request causes a GSUP LU request to HLR
MSC <--GERAN-A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
@@ -1408,10 +1425,13 @@ DREF VLR subscr IMSI-901700000004620 + active-conn: now used by 2 (_lu_fsm_assoc
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH
DREF VLR subscr IMSI-901700000004620 - _lu_fsm_associate_vsub: now used by 1 (active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_post_auth()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_post_ciph()
+DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000004620:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node_4()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
DVLR upd_hlr_vlr_fsm(IMSI-901700000004620:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated
@@ -1467,6 +1487,7 @@ DVLR lu_compl_vlr_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){LU_COMPL_VLR
DVLR lu_compl_vlr_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES
DVLR lu_compl_vlr_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL
DVLR lu_compl_vlr_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_WAIT_IMEI_TMSI
+DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: Sending DTAP: MM GSM48_MT_MM_ID_REQ
DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: DTAP on GERAN-A
- DTAP --GERAN-A--> MS: GSM48_MT_MM_ID_REQ: 051802
- DTAP matches expected message
@@ -1502,7 +1523,7 @@ DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}:
DREF msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: + rx_from_ms: now used by 2 (lu,rx_from_ms)
DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN decode: DTAP
DRLL msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: Dispatching 04.08 message: MM GSM48_MT_MM_ID_RESP
-DMM IDENTITY RESPONSE: MI=IMEI-423423423423420
+DMM IDENTITY RESPONSE: IMEI-423423423423420
DVLR set IMEI on subscriber; IMSI=901700000004620 IMEI=42342342342342
DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_ID_IMEI
GSUP --> HLR: OSMO_GSUP_MSGT_CHECK_IMEI_REQUEST: 30010809710000004026f0500807244332244332240a0101
@@ -1617,12 +1638,13 @@ DMSC dummy_msc_i{0}: is child of msub_fsm
DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms)
DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3
DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: MM GSM48_MT_MM_IMSI_DETACH_IND
-DMM IMSI DETACH INDICATION: MI(IMSI)=901700000004620
+DMM IMSI DETACH INDICATION: IMSI-901700000004620
DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100 + gsm48_rx_mm_imsi_detach_ind: now used by 2 (attached,gsm48_rx_mm_imsi_detach_ind)
DMM IMSI DETACH for IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100
DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100 + active-conn: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn)
DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn,vlr_subscr_cancel_attach_fsm)
DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100 - attached: now used by 2 (gsm48_rx_mm_imsi_detach_ind,active-conn)
DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100 - gsm48_rx_mm_imsi_detach_ind: now used by 1 (active-conn)
DMSC msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_CN_CLOSE
@@ -1662,9 +1684,6 @@ DMSC msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:NONE){MSC_A
llist_count(&msub_list) == 0
===== test_no_authen_tmsi_imei: SUCCESS
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 17
-
===== test_no_authen_imeisv
- Location Update request causes an IMEISV ID request back to the MS
MSC <--GERAN-A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
@@ -1693,6 +1712,8 @@ DREF VLR subscr IMSI-901700000004620 + active-conn: now used by 2 (_lu_fsm_assoc
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH
DREF VLR subscr IMSI-901700000004620 - _lu_fsm_associate_vsub: now used by 1 (active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
+DBSSAP msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: Sending DTAP: MM GSM48_MT_MM_ID_REQ
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: DTAP on GERAN-A
- DTAP --GERAN-A--> MS: GSM48_MT_MM_ID_REQ: 051803
- DTAP matches expected message
@@ -1705,7 +1726,7 @@ DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: n
DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: + rx_from_ms: now used by 2 (lu,rx_from_ms)
DBSSAP msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN decode: DTAP
DRLL msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: Dispatching 04.08 message: MM GSM48_MT_MM_ID_RESP
-DMM IDENTITY RESPONSE: MI=IMEI-SV-4234234234234275
+DMM IDENTITY RESPONSE: IMEI-SV-4234234234234275
DVLR set IMEISV on subscriber; IMSI=901700000004620 IMEISV=4234234234234275
DVLR set IMEI on subscriber; IMSI=901700000004620 IMEI=42342342342342
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_IMEISV}: Received Event VLR_ULA_E_ID_IMEISV
@@ -1713,6 +1734,8 @@ DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_IMEISV}: vlr_loc
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_IMEISV}: vlr_loc_upd_node1()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_IMEISV}: vlr_loc_upd_post_auth()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_IMEISV}: vlr_loc_upd_post_ciph()
+DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000004620:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_IMEISV}: vlr_loc_upd_node_4()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_IMEISV}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
DVLR upd_hlr_vlr_fsm(IMSI-901700000004620:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated
@@ -1837,12 +1860,13 @@ DMSC dummy_msc_i{0}: is child of msub_fsm
DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms)
DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3
DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: MM GSM48_MT_MM_IMSI_DETACH_IND
-DMM IMSI DETACH INDICATION: MI(IMSI)=901700000004620
+DMM IMSI DETACH INDICATION: IMSI-901700000004620
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + gsm48_rx_mm_imsi_detach_ind: now used by 2 (attached,gsm48_rx_mm_imsi_detach_ind)
DMM IMSI DETACH for IMSI-901700000004620:MSISDN-46071
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + active-conn: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn)
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn,vlr_subscr_cancel_attach_fsm)
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - attached: now used by 2 (gsm48_rx_mm_imsi_detach_ind,active-conn)
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - gsm48_rx_mm_imsi_detach_ind: now used by 1 (active-conn)
DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_CN_CLOSE
@@ -1882,9 +1906,6 @@ DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:NONE){MSC_A_ST_RELEASED}: D
llist_count(&msub_list) == 0
===== test_no_authen_imeisv: SUCCESS
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 17
-
===== test_no_authen_imeisv_imei
- Location Update request causes an IMEISV ID request back to the MS
MSC <--GERAN-A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
@@ -1913,6 +1934,8 @@ DREF VLR subscr IMSI-901700000004620 + active-conn: now used by 2 (_lu_fsm_assoc
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH
DREF VLR subscr IMSI-901700000004620 - _lu_fsm_associate_vsub: now used by 1 (active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
+DBSSAP msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: Sending DTAP: MM GSM48_MT_MM_ID_REQ
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: DTAP on GERAN-A
- DTAP --GERAN-A--> MS: GSM48_MT_MM_ID_REQ: 051803
- DTAP matches expected message
@@ -1925,7 +1948,7 @@ DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: n
DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: + rx_from_ms: now used by 2 (lu,rx_from_ms)
DBSSAP msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN decode: DTAP
DRLL msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: Dispatching 04.08 message: MM GSM48_MT_MM_ID_RESP
-DMM IDENTITY RESPONSE: MI=IMEI-SV-4234234234234275
+DMM IDENTITY RESPONSE: IMEI-SV-4234234234234275
DVLR set IMEISV on subscriber; IMSI=901700000004620 IMEISV=4234234234234275
DVLR set IMEI on subscriber; IMSI=901700000004620 IMEI=42342342342342
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_IMEISV}: Received Event VLR_ULA_E_ID_IMEISV
@@ -1944,6 +1967,8 @@ DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_HLR_CHECK_IMEI_E
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_HLR_CHECK_IMEI_EARLY}: vlr_loc_upd_node1()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_HLR_CHECK_IMEI_EARLY}: vlr_loc_upd_post_auth()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_HLR_CHECK_IMEI_EARLY}: vlr_loc_upd_post_ciph()
+DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000004620:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_HLR_CHECK_IMEI_EARLY}: vlr_loc_upd_node_4()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_HLR_CHECK_IMEI_EARLY}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
DVLR upd_hlr_vlr_fsm(IMSI-901700000004620:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated
@@ -2068,12 +2093,13 @@ DMSC dummy_msc_i{0}: is child of msub_fsm
DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms)
DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3
DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: MM GSM48_MT_MM_IMSI_DETACH_IND
-DMM IMSI DETACH INDICATION: MI(IMSI)=901700000004620
+DMM IMSI DETACH INDICATION: IMSI-901700000004620
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + gsm48_rx_mm_imsi_detach_ind: now used by 2 (attached,gsm48_rx_mm_imsi_detach_ind)
DMM IMSI DETACH for IMSI-901700000004620:MSISDN-46071
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + active-conn: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn)
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn,vlr_subscr_cancel_attach_fsm)
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - attached: now used by 2 (gsm48_rx_mm_imsi_detach_ind,active-conn)
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - gsm48_rx_mm_imsi_detach_ind: now used by 1 (active-conn)
DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_CN_CLOSE
@@ -2113,9 +2139,6 @@ DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:NONE){MSC_A_ST_RELEASED}: D
llist_count(&msub_list) == 0
===== test_no_authen_imeisv_imei: SUCCESS
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 17
-
===== test_no_authen_imeisv_tmsi
- Location Update request causes an IMEISV ID request back to the MS
MSC <--GERAN-A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
@@ -2144,6 +2167,8 @@ DREF VLR subscr IMSI-901700000004620 + active-conn: now used by 2 (_lu_fsm_assoc
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH
DREF VLR subscr IMSI-901700000004620 - _lu_fsm_associate_vsub: now used by 1 (active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
+DBSSAP msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: Sending DTAP: MM GSM48_MT_MM_ID_REQ
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: DTAP on GERAN-A
- DTAP --GERAN-A--> MS: GSM48_MT_MM_ID_REQ: 051803
- DTAP matches expected message
@@ -2156,7 +2181,7 @@ DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: n
DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: + rx_from_ms: now used by 2 (lu,rx_from_ms)
DBSSAP msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN decode: DTAP
DRLL msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: Dispatching 04.08 message: MM GSM48_MT_MM_ID_RESP
-DMM IDENTITY RESPONSE: MI=IMEI-SV-4234234234234275
+DMM IDENTITY RESPONSE: IMEI-SV-4234234234234275
DVLR set IMEISV on subscriber; IMSI=901700000004620 IMEISV=4234234234234275
DVLR set IMEI on subscriber; IMSI=901700000004620 IMEI=42342342342342
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_IMEISV}: Received Event VLR_ULA_E_ID_IMEISV
@@ -2164,6 +2189,8 @@ DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_IMEISV}: vlr_loc
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_IMEISV}: vlr_loc_upd_node1()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_IMEISV}: vlr_loc_upd_post_auth()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_IMEISV}: vlr_loc_upd_post_ciph()
+DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000004620:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_IMEISV}: vlr_loc_upd_node_4()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_IMEISV}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
DVLR upd_hlr_vlr_fsm(IMSI-901700000004620:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated
@@ -2342,6 +2369,8 @@ DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100 + active-conn:
DMSC msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK
DMSC msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH
DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100 - _lu_fsm_associate_vsub: now used by 2 (attached,active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
+DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: Sending DTAP: MM GSM48_MT_MM_ID_REQ
DMSC msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: DTAP on GERAN-A
- DTAP --GERAN-A--> MS: GSM48_MT_MM_ID_REQ: 051803
- DTAP matches expected message
@@ -2354,7 +2383,7 @@ DREF msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:LU){MSC_A_S
DREF msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: + rx_from_ms: now used by 2 (lu,rx_from_ms)
DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN decode: DTAP
DRLL msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: Dispatching 04.08 message: MM GSM48_MT_MM_ID_RESP
-DMM IDENTITY RESPONSE: MI=IMEI-SV-5234234234234276
+DMM IDENTITY RESPONSE: IMEI-SV-5234234234234276
DVLR set IMEISV on subscriber; IMSI=901700000004620 IMEISV=5234234234234276
DVLR set IMEI on subscriber; IMSI=901700000004620 IMEI=52342342342342
DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:LU){VLR_ULA_S_WAIT_IMEISV}: Received Event VLR_ULA_E_ID_IMEISV
@@ -2362,6 +2391,8 @@ DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:LU){VL
DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:LU){VLR_ULA_S_WAIT_IMEISV}: vlr_loc_upd_node1()
DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:LU){VLR_ULA_S_WAIT_IMEISV}: vlr_loc_upd_post_auth()
DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:LU){VLR_ULA_S_WAIT_IMEISV}: vlr_loc_upd_post_ciph()
+DMSC msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:LU){VLR_ULA_S_WAIT_IMEISV}: vlr_loc_upd_node_4()
DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:LU){VLR_ULA_S_WAIT_IMEISV}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
DVLR upd_hlr_vlr_fsm(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated
@@ -2532,12 +2563,13 @@ DMSC dummy_msc_i{0}: is child of msub_fsm
DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms)
DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3
DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: MM GSM48_MT_MM_IMSI_DETACH_IND
-DMM IMSI DETACH INDICATION: MI(TMSI)=117835012
+DMM IMSI DETACH INDICATION: TMSI-0x07060504
DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x07060504 + gsm48_rx_mm_imsi_detach_ind: now used by 2 (attached,gsm48_rx_mm_imsi_detach_ind)
DMM IMSI DETACH for IMSI-901700000004620:MSISDN-46071:TMSI-0x07060504
DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x07060504 + active-conn: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn)
DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x07060504 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn,vlr_subscr_cancel_attach_fsm)
DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x07060504 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x07060504 - attached: now used by 2 (gsm48_rx_mm_imsi_detach_ind,active-conn)
DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x07060504 - gsm48_rx_mm_imsi_detach_ind: now used by 1 (active-conn)
DMSC msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x07060504:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_CN_CLOSE
@@ -2577,9 +2609,6 @@ DMSC msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x07060504:GERAN-A:NONE){MSC_A
llist_count(&msub_list) == 0
===== test_no_authen_imeisv_tmsi: SUCCESS
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 17
-
===== test_no_authen_imeisv_tmsi_imei
- Location Update request causes an IMEISV ID request back to the MS
MSC <--GERAN-A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
@@ -2608,6 +2637,8 @@ DREF VLR subscr IMSI-901700000004620 + active-conn: now used by 2 (_lu_fsm_assoc
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH
DREF VLR subscr IMSI-901700000004620 - _lu_fsm_associate_vsub: now used by 1 (active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
+DBSSAP msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: Sending DTAP: MM GSM48_MT_MM_ID_REQ
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: DTAP on GERAN-A
- DTAP --GERAN-A--> MS: GSM48_MT_MM_ID_REQ: 051803
- DTAP matches expected message
@@ -2620,7 +2651,7 @@ DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: n
DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: + rx_from_ms: now used by 2 (lu,rx_from_ms)
DBSSAP msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN decode: DTAP
DRLL msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: Dispatching 04.08 message: MM GSM48_MT_MM_ID_RESP
-DMM IDENTITY RESPONSE: MI=IMEI-SV-4234234234234275
+DMM IDENTITY RESPONSE: IMEI-SV-4234234234234275
DVLR set IMEISV on subscriber; IMSI=901700000004620 IMEISV=4234234234234275
DVLR set IMEI on subscriber; IMSI=901700000004620 IMEI=42342342342342
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_IMEISV}: Received Event VLR_ULA_E_ID_IMEISV
@@ -2639,6 +2670,8 @@ DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_HLR_CHECK_IMEI_E
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_HLR_CHECK_IMEI_EARLY}: vlr_loc_upd_node1()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_HLR_CHECK_IMEI_EARLY}: vlr_loc_upd_post_auth()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_HLR_CHECK_IMEI_EARLY}: vlr_loc_upd_post_ciph()
+DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000004620:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_HLR_CHECK_IMEI_EARLY}: vlr_loc_upd_node_4()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_WAIT_HLR_CHECK_IMEI_EARLY}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
DVLR upd_hlr_vlr_fsm(IMSI-901700000004620:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated
@@ -2800,12 +2833,13 @@ DMSC dummy_msc_i{0}: is child of msub_fsm
DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms)
DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3
DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: MM GSM48_MT_MM_IMSI_DETACH_IND
-DMM IMSI DETACH INDICATION: MI(IMSI)=901700000004620
+DMM IMSI DETACH INDICATION: IMSI-901700000004620
DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100 + gsm48_rx_mm_imsi_detach_ind: now used by 2 (attached,gsm48_rx_mm_imsi_detach_ind)
DMM IMSI DETACH for IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100
DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100 + active-conn: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn)
DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn,vlr_subscr_cancel_attach_fsm)
DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100 - attached: now used by 2 (gsm48_rx_mm_imsi_detach_ind,active-conn)
DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100 - gsm48_rx_mm_imsi_detach_ind: now used by 1 (active-conn)
DMSC msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_CN_CLOSE
@@ -2845,9 +2879,6 @@ DMSC msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x03020100:GERAN-A:NONE){MSC_A
llist_count(&msub_list) == 0
===== test_no_authen_imeisv_tmsi_imei: SUCCESS
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 17
-
===== test_no_authen_subscr_expire
- Total time passed: 0.000000 s
- Total time passed: 61.000000 s
@@ -2878,10 +2909,13 @@ DREF VLR subscr IMSI-901700000004620 + active-conn: now used by 2 (_lu_fsm_assoc
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH
DREF VLR subscr IMSI-901700000004620 - _lu_fsm_associate_vsub: now used by 1 (active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_post_auth()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_post_ciph()
+DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000004620:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node_4()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
DVLR upd_hlr_vlr_fsm(IMSI-901700000004620:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated
@@ -2975,14 +3009,9 @@ DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - test_no_authen_subscr_expire
DVLR IMSI-901700000004620:MSISDN-46071: Location Update expired
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + vlr_subscr_cancel_attach_fsm: now used by 2 (attached,vlr_subscr_cancel_attach_fsm)
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - vlr_subscr_cancel_attach_fsm: now used by 1 (attached)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - attached: now used by 0 (-)
DVLR freeing VLR subscr IMSI-901700000004620:MSISDN-46071 (max total use count was 5)
llist_count(&msub_list) == 0
===== test_no_authen_subscr_expire: SUCCESS
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 17
-
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 17
-
diff --git a/tests/msc_vlr/msc_vlr_test_reject_concurrency.c b/tests/msc_vlr/msc_vlr_test_reject_concurrency.c
index 7eaedb27c..dea0c291b 100644
--- a/tests/msc_vlr/msc_vlr_test_reject_concurrency.c
+++ b/tests/msc_vlr/msc_vlr_test_reject_concurrency.c
@@ -22,7 +22,6 @@
*/
#include "msc_vlr_tests.h"
-#include "stubs.h"
static void test_reject_2nd_conn()
{
@@ -31,7 +30,7 @@ static void test_reject_2nd_conn()
btw("Location Update Request on one connection");
lu_result_sent = RES_NONE;
- gsup_expect_tx("04010809710000004026f0280102" VLR_TO_HLR);
+ gsup_expect_tx("04010809710000004026f0" CN_DOMAIN VLR_TO_HLR);
ms_sends_msg("050802008168000130089910070000006402");
OSMO_ASSERT(gsup_tx_confirmed);
VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
@@ -74,7 +73,7 @@ static void _normal_lu_part1()
{
btw("Location Update Request");
lu_result_sent = RES_NONE;
- gsup_expect_tx("04010809710000004026f0280102" VLR_TO_HLR);
+ gsup_expect_tx("04010809710000004026f0" CN_DOMAIN VLR_TO_HLR);
ms_sends_msg("050802008168000130089910070000006402");
OSMO_ASSERT(gsup_tx_confirmed);
VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
@@ -309,7 +308,7 @@ static void test_reject_paging_resp_during_cm()
BTW("The original CM Service Request can conclude");
/* Release connection */
- expect_bssap_clear(OSMO_RAT_GERAN_A);
+ expect_bssap_clear();
conn_conclude_cm_service_req(g_msub, MSC_A_USE_CM_SERVICE_SMS);
btw("all requests serviced, conn has been released");
diff --git a/tests/msc_vlr/msc_vlr_test_reject_concurrency.err b/tests/msc_vlr/msc_vlr_test_reject_concurrency.err
index e1df2db14..25ccdfb64 100644
--- a/tests/msc_vlr/msc_vlr_test_reject_concurrency.err
+++ b/tests/msc_vlr/msc_vlr_test_reject_concurrency.err
@@ -1,7 +1,3 @@
-DLMGCP MGCP client: using endpoint domain '@mgw'
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 17
-
===== test_reject_2nd_conn
- Location Update Request on one connection
MSC <--GERAN-A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
@@ -30,10 +26,13 @@ DREF VLR subscr IMSI-901700000004620 + active-conn: now used by 2 (_lu_fsm_assoc
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH
DREF VLR subscr IMSI-901700000004620 - _lu_fsm_associate_vsub: now used by 1 (active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_post_auth()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_post_ciph()
+DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000004620:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node_4()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
DVLR upd_hlr_vlr_fsm(IMSI-901700000004620:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated
@@ -189,9 +188,6 @@ DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_RELEASED}: Dea
DVLR freeing VLR subscr IMSI-901700000004620:MSISDN-46071 (max total use count was 5)
===== test_reject_2nd_conn: SUCCESS
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 17
-
===== test_reject_lu_during_lu
- Location Update Request
MSC <--GERAN-A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
@@ -220,10 +216,13 @@ DREF VLR subscr IMSI-901700000004620 + active-conn: now used by 2 (_lu_fsm_assoc
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH
DREF VLR subscr IMSI-901700000004620 - _lu_fsm_associate_vsub: now used by 1 (active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_post_auth()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_post_ciph()
+DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000004620:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node_4()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
DVLR upd_hlr_vlr_fsm(IMSI-901700000004620:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated
@@ -330,9 +329,6 @@ DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_RELEASED}: Dea
DVLR freeing VLR subscr IMSI-901700000004620:MSISDN-46071 (max total use count was 5)
===== test_reject_lu_during_lu: SUCCESS
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 17
-
===== test_reject_cm_during_lu
- Location Update Request
MSC <--GERAN-A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
@@ -361,10 +357,13 @@ DREF VLR subscr IMSI-901700000004620 + active-conn: now used by 2 (_lu_fsm_assoc
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH
DREF VLR subscr IMSI-901700000004620 - _lu_fsm_associate_vsub: now used by 1 (active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_post_auth()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_post_ciph()
+DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000004620:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node_4()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
DVLR upd_hlr_vlr_fsm(IMSI-901700000004620:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated
@@ -385,6 +384,7 @@ DBSSAP msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN decode: D
DRLL msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: Dispatching 04.08 message: MM GSM48_MT_MM_CM_SERV_REQ
DBSSAP msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: Cannot accept CM Service Request, conn already busy establishing authenticity
DMM msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: -> CM SERVICE Reject cause: 22
+DBSSAP msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: Sending DTAP: MM GSM48_MT_MM_CM_SERV_REJ
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: DTAP on GERAN-A
- DTAP --GERAN-A--> MS: GSM48_MT_MM_CM_SERV_REJ: 052216
DMSC dummy_msc_i(IMSI-901700000004620:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
@@ -475,9 +475,6 @@ DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_RELEASED}: Dea
DVLR freeing VLR subscr IMSI-901700000004620:MSISDN-46071 (max total use count was 5)
===== test_reject_cm_during_lu: SUCCESS
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 17
-
===== test_reject_paging_resp_during_lu
- Location Update Request
MSC <--GERAN-A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
@@ -506,10 +503,13 @@ DREF VLR subscr IMSI-901700000004620 + active-conn: now used by 2 (_lu_fsm_assoc
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH
DREF VLR subscr IMSI-901700000004620 - _lu_fsm_associate_vsub: now used by 1 (active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_post_auth()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_post_ciph()
+DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000004620:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node_4()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
DVLR upd_hlr_vlr_fsm(IMSI-901700000004620:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated
@@ -528,7 +528,7 @@ DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: n
DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: + rx_from_ms: now used by 2 (lu,rx_from_ms)
DBSSAP msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN decode: DTAP
DRLL msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: Dispatching 04.08 message: RR GSM48_MT_RR_PAG_RESP
-DMM msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: Ignoring Paging Response, conn already busy establishing authenticity
+DRR msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: Ignoring Paging Response, conn already busy establishing authenticity
DREF msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu)
lu_result_sent == 0
llist_count(&msub_list) == 1
@@ -615,9 +615,6 @@ DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_RELEASED}: Dea
DVLR freeing VLR subscr IMSI-901700000004620:MSISDN-46071 (max total use count was 5)
===== test_reject_paging_resp_during_lu: SUCCESS
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 17
-
===== test_reject_lu_during_cm
@@ -649,10 +646,13 @@ DREF VLR subscr IMSI-901700000004620 + active-conn: now used by 2 (_lu_fsm_assoc
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH
DREF VLR subscr IMSI-901700000004620 - _lu_fsm_associate_vsub: now used by 1 (active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_post_auth()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_post_ciph()
+DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000004620:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node_4()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
DVLR upd_hlr_vlr_fsm(IMSI-901700000004620:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated
@@ -768,6 +768,8 @@ DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_VA
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi()
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_node2()
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_ciph()
+DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_vlr()
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_post_pres()
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_post_trace()
@@ -775,6 +777,7 @@ DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SER
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: proc_arq_fsm_done(PASSED)
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_DONE
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_DONE}: Process Access Request result: PASSED
+DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: Sending DTAP: MM GSM48_MT_MM_CM_SERV_ACC
DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN encode: DTAP on GERAN-A
- DTAP --GERAN-A--> MS: GSM48_MT_MM_CM_SERV_ACC: 0521
DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
@@ -801,11 +804,12 @@ DREF msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AU
DREF msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: + rx_from_ms: now used by 2 (cm_service_sms,rx_from_ms)
DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: RAN decode: DTAP
DRLL msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: Dispatching 04.08 message: MM GSM48_MT_MM_IMSI_DETACH_IND
-DMM IMSI DETACH INDICATION: MI(IMSI)=901700000004620
+DMM IMSI DETACH INDICATION: IMSI-901700000004620
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + gsm48_rx_mm_imsi_detach_ind: now used by 3 (attached,active-conn,gsm48_rx_mm_imsi_detach_ind)
DMM IMSI DETACH for IMSI-901700000004620:MSISDN-46071
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,active-conn,gsm48_rx_mm_imsi_detach_ind,vlr_subscr_cancel_attach_fsm)
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,active-conn,gsm48_rx_mm_imsi_detach_ind)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - attached: now used by 2 (active-conn,gsm48_rx_mm_imsi_detach_ind)
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - gsm48_rx_mm_imsi_detach_ind: now used by 1 (active-conn)
DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: Received Event MSC_A_EV_CN_CLOSE
@@ -850,9 +854,6 @@ DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RE
llist_count(&msub_list) == 0
===== test_reject_lu_during_cm: SUCCESS
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 17
-
===== test_reject_cm_during_cm
@@ -884,10 +885,13 @@ DREF VLR subscr IMSI-901700000004620 + active-conn: now used by 2 (_lu_fsm_assoc
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH
DREF VLR subscr IMSI-901700000004620 - _lu_fsm_associate_vsub: now used by 1 (active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_post_auth()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_post_ciph()
+DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000004620:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node_4()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
DVLR upd_hlr_vlr_fsm(IMSI-901700000004620:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated
@@ -1003,6 +1007,8 @@ DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_VA
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi()
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_node2()
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_ciph()
+DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_vlr()
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_post_pres()
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_post_trace()
@@ -1010,6 +1016,7 @@ DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SER
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: proc_arq_fsm_done(PASSED)
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_DONE
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_DONE}: Process Access Request result: PASSED
+DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: Sending DTAP: MM GSM48_MT_MM_CM_SERV_ACC
DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN encode: DTAP on GERAN-A
- DTAP --GERAN-A--> MS: GSM48_MT_MM_CM_SERV_ACC: 0521
DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
@@ -1025,8 +1032,9 @@ DREF msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AU
DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: RAN decode: DTAP
DRLL msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: Dispatching 04.08 message: MM GSM48_MT_MM_CM_SERV_REQ
DMM msc_a(IMSI-901700000004620:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: Rx CM SERVICE REQUEST cm_service_type=Short-Messaging-Service
-DMM msc_a(IMSI-901700000004620:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: re-using already accepted connection
DREF msc_a(IMSI-901700000004620:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: + cm_service_sms: now used by 3 (2*cm_service_sms,rx_from_ms)
+DMM msc_a(IMSI-901700000004620:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: re-using already accepted connection
+DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: Sending DTAP: MM GSM48_MT_MM_CM_SERV_ACC
DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: RAN encode: DTAP on GERAN-A
- DTAP --GERAN-A--> MS: GSM48_MT_MM_CM_SERV_ACC: 0521
DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
@@ -1040,11 +1048,12 @@ DREF msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AU
DREF msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: + rx_from_ms: now used by 3 (2*cm_service_sms,rx_from_ms)
DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: RAN decode: DTAP
DRLL msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: Dispatching 04.08 message: MM GSM48_MT_MM_IMSI_DETACH_IND
-DMM IMSI DETACH INDICATION: MI(IMSI)=901700000004620
+DMM IMSI DETACH INDICATION: IMSI-901700000004620
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + gsm48_rx_mm_imsi_detach_ind: now used by 3 (attached,active-conn,gsm48_rx_mm_imsi_detach_ind)
DMM IMSI DETACH for IMSI-901700000004620:MSISDN-46071
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,active-conn,gsm48_rx_mm_imsi_detach_ind,vlr_subscr_cancel_attach_fsm)
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,active-conn,gsm48_rx_mm_imsi_detach_ind)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - attached: now used by 2 (active-conn,gsm48_rx_mm_imsi_detach_ind)
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - gsm48_rx_mm_imsi_detach_ind: now used by 1 (active-conn)
DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: Received Event MSC_A_EV_CN_CLOSE
@@ -1089,9 +1098,6 @@ DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RE
llist_count(&msub_list) == 0
===== test_reject_cm_during_cm: SUCCESS
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 17
-
===== test_reject_paging_resp_during_cm
@@ -1123,10 +1129,13 @@ DREF VLR subscr IMSI-901700000004620 + active-conn: now used by 2 (_lu_fsm_assoc
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH
DREF VLR subscr IMSI-901700000004620 - _lu_fsm_associate_vsub: now used by 1 (active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_post_auth()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_post_ciph()
+DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000004620:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node_4()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
DVLR upd_hlr_vlr_fsm(IMSI-901700000004620:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated
@@ -1242,6 +1251,8 @@ DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_VA
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi()
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_node2()
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_ciph()
+DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_vlr()
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_post_pres()
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_post_trace()
@@ -1249,6 +1260,7 @@ DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SER
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: proc_arq_fsm_done(PASSED)
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_DONE
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_DONE}: Process Access Request result: PASSED
+DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: Sending DTAP: MM GSM48_MT_MM_CM_SERV_ACC
DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN encode: DTAP on GERAN-A
- DTAP --GERAN-A--> MS: GSM48_MT_MM_CM_SERV_ACC: 0521
DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
@@ -1265,7 +1277,7 @@ msc_a_is_accepted() == true
DREF msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: + rx_from_ms: now used by 2 (cm_service_sms,rx_from_ms)
DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: RAN decode: DTAP
DRLL msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: Dispatching 04.08 message: RR GSM48_MT_RR_PAG_RESP
-DMM msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: Ignoring Paging Response, conn already established
+DRR msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: Ignoring Paging Response, conn already established
DREF msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: - rx_from_ms: now used by 1 (cm_service_sms)
llist_count(&msub_list) == 1
@@ -1313,9 +1325,6 @@ DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RE
DVLR freeing VLR subscr IMSI-901700000004620:MSISDN-46071 (max total use count was 5)
===== test_reject_paging_resp_during_cm: SUCCESS
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 17
-
===== test_reject_lu_during_paging_resp
@@ -1347,10 +1356,13 @@ DREF VLR subscr IMSI-901700000004620 + active-conn: now used by 2 (_lu_fsm_assoc
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH
DREF VLR subscr IMSI-901700000004620 - _lu_fsm_associate_vsub: now used by 1 (active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_post_auth()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_post_ciph()
+DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000004620:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node_4()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
DVLR upd_hlr_vlr_fsm(IMSI-901700000004620:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated
@@ -1475,7 +1487,7 @@ DMSC dummy_msc_i{0}: is child of msub_fsm
DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms)
DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3
DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: RR GSM48_MT_RR_PAG_RESP
-DRR msc_a(IMSI-901700000004620:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: Rx PAGING RESPONSE
+DRR msc_a(IMSI-901700000004620:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: Rx PAGING RESPONSE IMSI-901700000004620
DREF msc_a(IMSI-901700000004620:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: + paging-response: now used by 2 (rx_from_ms,paging-response)
DVLR Process_Access_Request_VLR(IMSI-901700000004620:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: Allocated
DVLR Process_Access_Request_VLR(IMSI-901700000004620:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: is child of msc_a(IMSI-901700000004620:GERAN-A:PAGING_RESP)
@@ -1488,6 +1500,8 @@ DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_VALID
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi()
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_node2()
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_ciph()
+DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_vlr()
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_post_pres()
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_post_trace()
@@ -1506,6 +1520,7 @@ DLSMS SMC(0) send CP data
DLSMS SMC(0) new CP state MM_CONN_PENDING -> WAIT_CP_ACK
DLSMS trans(SMS IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x40000001 tid-0) sending CP message (trans=0)
DLSMS trans(SMS IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x40000001 tid-0) GSM4.11 TX 09 01 58 01 00 07 91 44 77 58 10 06 50 00 4c 00 05 80 64 70 f1 00 00 07 10 10 00 00 00 00 44 50 79 da 1e 1e e7 41 69 37 48 5e 9e a7 c9 65 37 3d 1d 66 83 c2 70 38 3b 3d 0e d3 d3 6f f7 1c 94 9e 83 c2 20 72 79 9e 96 87 c5 ec 32 a8 1d 96 af cb f4 b4 fb 0c 7a c3 e9 e9 b7 db 05
+DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: Sending DTAP: SMS SMS:0x01
DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: RAN encode: DTAP on GERAN-A
- DTAP --GERAN-A--> MS: SMS:0x01: 09015801000791447758100650004c0005806470f1000007101000000000445079da1e1ee7416937485e9ea7c965373d1d6683c270383b3d0ed3d36ff71c949e83c22072799e9687c5ec32a81d96afcbf4b4fb0c7ac3e9e9b7db05
- DTAP matches expected message
@@ -1550,6 +1565,7 @@ DLSMS SMC(0) message MMSMS-DATA-IND (CP DATA) received in state MM_ESTABLISHED
DLSMS SMC(0) received CP-DATA
DLSMS trans(SMS IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x40000001 tid-0) sending CP message (trans=0)
DLSMS trans(SMS IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x40000001 tid-0) GSM4.11 TX 09 04
+DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: Sending DTAP: SMS SMS:0x04
DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: RAN encode: DTAP on GERAN-A
- DTAP --GERAN-A--> MS: SMS:0x04: 0904
- DTAP matches expected message
@@ -1611,9 +1627,6 @@ DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEA
DVLR freeing VLR subscr IMSI-901700000004620:MSISDN-46071 (max total use count was 6)
===== test_reject_lu_during_paging_resp: SUCCESS
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 17
-
===== test_accept_cm_during_paging_resp
@@ -1645,10 +1658,13 @@ DREF VLR subscr IMSI-901700000004620 + active-conn: now used by 2 (_lu_fsm_assoc
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH
DREF VLR subscr IMSI-901700000004620 - _lu_fsm_associate_vsub: now used by 1 (active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_post_auth()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_post_ciph()
+DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000004620:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node_4()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
DVLR upd_hlr_vlr_fsm(IMSI-901700000004620:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated
@@ -1773,7 +1789,7 @@ DMSC dummy_msc_i{0}: is child of msub_fsm
DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms)
DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3
DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: RR GSM48_MT_RR_PAG_RESP
-DRR msc_a(IMSI-901700000004620:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: Rx PAGING RESPONSE
+DRR msc_a(IMSI-901700000004620:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: Rx PAGING RESPONSE IMSI-901700000004620
DREF msc_a(IMSI-901700000004620:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: + paging-response: now used by 2 (rx_from_ms,paging-response)
DVLR Process_Access_Request_VLR(IMSI-901700000004620:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: Allocated
DVLR Process_Access_Request_VLR(IMSI-901700000004620:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: is child of msc_a(IMSI-901700000004620:GERAN-A:PAGING_RESP)
@@ -1786,6 +1802,8 @@ DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_VALID
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi()
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_node2()
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_ciph()
+DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_vlr()
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_post_pres()
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_post_trace()
@@ -1804,6 +1822,7 @@ DLSMS SMC(0) send CP data
DLSMS SMC(0) new CP state MM_CONN_PENDING -> WAIT_CP_ACK
DLSMS trans(SMS IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x40000002 tid-0) sending CP message (trans=0)
DLSMS trans(SMS IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x40000002 tid-0) GSM4.11 TX 09 01 58 01 00 07 91 44 77 58 10 06 50 00 4c 00 05 80 64 70 f1 00 00 07 10 10 00 00 00 00 44 50 79 da 1e 1e e7 41 69 37 48 5e 9e a7 c9 65 37 3d 1d 66 83 c2 70 38 3b 3d 0e d3 d3 6f f7 1c 94 9e 83 c2 20 72 79 9e 96 87 c5 ec 32 a8 1d 96 af cb f4 b4 fb 0c 7a c3 e9 e9 b7 db 05
+DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: Sending DTAP: SMS SMS:0x01
DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: RAN encode: DTAP on GERAN-A
- DTAP --GERAN-A--> MS: SMS:0x01: 09015801000791447758100650004c0005806470f1000007101000000000445079da1e1ee7416937485e9ea7c965373d1d6683c270383b3d0ed3d36ff71c949e83c22072799e9687c5ec32a81d96afcbf4b4fb0c7ac3e9e9b7db05
- DTAP matches expected message
@@ -1823,8 +1842,9 @@ DREF msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHE
DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: RAN decode: DTAP
DRLL msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: Dispatching 04.08 message: MM GSM48_MT_MM_CM_SERV_REQ
DMM msc_a(IMSI-901700000004620:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: Rx CM SERVICE REQUEST cm_service_type=Short-Messaging-Service
-DMM msc_a(IMSI-901700000004620:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: re-using already accepted connection
DREF msc_a(IMSI-901700000004620:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: + cm_service_sms: now used by 3 (sms,rx_from_ms,cm_service_sms)
+DMM msc_a(IMSI-901700000004620:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: re-using already accepted connection
+DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: Sending DTAP: MM GSM48_MT_MM_CM_SERV_ACC
DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: RAN encode: DTAP on GERAN-A
- DTAP --GERAN-A--> MS: GSM48_MT_MM_CM_SERV_ACC: 0521
DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
@@ -1853,6 +1873,7 @@ DLSMS SMC(0) message MMSMS-DATA-IND (CP DATA) received in state MM_ESTABLISHED
DLSMS SMC(0) received CP-DATA
DLSMS trans(SMS IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x40000002 tid-0) sending CP message (trans=0)
DLSMS trans(SMS IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x40000002 tid-0) GSM4.11 TX 09 04
+DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: Sending DTAP: SMS SMS:0x04
DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: RAN encode: DTAP on GERAN-A
- DTAP --GERAN-A--> MS: SMS:0x04: 0904
- DTAP matches expected message
@@ -1883,11 +1904,12 @@ DREF msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AU
DREF msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: + rx_from_ms: now used by 2 (cm_service_sms,rx_from_ms)
DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: RAN decode: DTAP
DRLL msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: Dispatching 04.08 message: MM GSM48_MT_MM_IMSI_DETACH_IND
-DMM IMSI DETACH INDICATION: MI(IMSI)=901700000004620
+DMM IMSI DETACH INDICATION: IMSI-901700000004620
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + gsm48_rx_mm_imsi_detach_ind: now used by 3 (attached,active-conn,gsm48_rx_mm_imsi_detach_ind)
DMM IMSI DETACH for IMSI-901700000004620:MSISDN-46071
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,active-conn,gsm48_rx_mm_imsi_detach_ind,vlr_subscr_cancel_attach_fsm)
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,active-conn,gsm48_rx_mm_imsi_detach_ind)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - attached: now used by 2 (active-conn,gsm48_rx_mm_imsi_detach_ind)
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - gsm48_rx_mm_imsi_detach_ind: now used by 1 (active-conn)
DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: Received Event MSC_A_EV_CN_CLOSE
@@ -1932,9 +1954,6 @@ DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RE
llist_count(&msub_list) == 0
===== test_accept_cm_during_paging_resp: SUCCESS
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 17
-
===== test_reject_paging_resp_during_paging_resp
@@ -1966,10 +1985,13 @@ DREF VLR subscr IMSI-901700000004620 + active-conn: now used by 2 (_lu_fsm_assoc
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH
DREF VLR subscr IMSI-901700000004620 - _lu_fsm_associate_vsub: now used by 1 (active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_post_auth()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_post_ciph()
+DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000004620:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node_4()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
DVLR upd_hlr_vlr_fsm(IMSI-901700000004620:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated
@@ -2094,7 +2116,7 @@ DMSC dummy_msc_i{0}: is child of msub_fsm
DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms)
DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3
DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: RR GSM48_MT_RR_PAG_RESP
-DRR msc_a(IMSI-901700000004620:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: Rx PAGING RESPONSE
+DRR msc_a(IMSI-901700000004620:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: Rx PAGING RESPONSE IMSI-901700000004620
DREF msc_a(IMSI-901700000004620:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: + paging-response: now used by 2 (rx_from_ms,paging-response)
DVLR Process_Access_Request_VLR(IMSI-901700000004620:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: Allocated
DVLR Process_Access_Request_VLR(IMSI-901700000004620:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: is child of msc_a(IMSI-901700000004620:GERAN-A:PAGING_RESP)
@@ -2107,6 +2129,8 @@ DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_VALID
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi()
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_node2()
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_ciph()
+DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_vlr()
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_post_pres()
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_post_trace()
@@ -2125,6 +2149,7 @@ DLSMS SMC(0) send CP data
DLSMS SMC(0) new CP state MM_CONN_PENDING -> WAIT_CP_ACK
DLSMS trans(SMS IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x40000003 tid-0) sending CP message (trans=0)
DLSMS trans(SMS IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x40000003 tid-0) GSM4.11 TX 09 01 58 01 00 07 91 44 77 58 10 06 50 00 4c 00 05 80 64 70 f1 00 00 07 10 10 00 00 00 00 44 50 79 da 1e 1e e7 41 69 37 48 5e 9e a7 c9 65 37 3d 1d 66 83 c2 70 38 3b 3d 0e d3 d3 6f f7 1c 94 9e 83 c2 20 72 79 9e 96 87 c5 ec 32 a8 1d 96 af cb f4 b4 fb 0c 7a c3 e9 e9 b7 db 05
+DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: Sending DTAP: SMS SMS:0x01
DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: RAN encode: DTAP on GERAN-A
- DTAP --GERAN-A--> MS: SMS:0x01: 09015801000791447758100650004c0005806470f1000007101000000000445079da1e1ee7416937485e9ea7c965373d1d6683c270383b3d0ed3d36ff71c949e83c22072799e9687c5ec32a81d96afcbf4b4fb0c7ac3e9e9b7db05
- DTAP matches expected message
@@ -2143,7 +2168,7 @@ DREF msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHE
DREF msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: + rx_from_ms: now used by 2 (sms,rx_from_ms)
DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: RAN decode: DTAP
DRLL msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: Dispatching 04.08 message: RR GSM48_MT_RR_PAG_RESP
-DMM msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: Ignoring Paging Response, conn already established
+DRR msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: Ignoring Paging Response, conn already established
DREF msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: - rx_from_ms: now used by 1 (sms)
- MS replies with CP-ACK for received SMS
MSC <--GERAN-A-- MS: SMS:0x04
@@ -2166,6 +2191,7 @@ DLSMS SMC(0) message MMSMS-DATA-IND (CP DATA) received in state MM_ESTABLISHED
DLSMS SMC(0) received CP-DATA
DLSMS trans(SMS IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x40000003 tid-0) sending CP message (trans=0)
DLSMS trans(SMS IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x40000003 tid-0) GSM4.11 TX 09 04
+DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: Sending DTAP: SMS SMS:0x04
DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: RAN encode: DTAP on GERAN-A
- DTAP --GERAN-A--> MS: SMS:0x04: 0904
- DTAP matches expected message
@@ -2227,9 +2253,3 @@ DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEA
DVLR freeing VLR subscr IMSI-901700000004620:MSISDN-46071 (max total use count was 6)
===== test_reject_paging_resp_during_paging_resp: SUCCESS
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 17
-
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 17
-
diff --git a/tests/msc_vlr/msc_vlr_test_rest.c b/tests/msc_vlr/msc_vlr_test_rest.c
index 620652c95..029e8b5b7 100644
--- a/tests/msc_vlr/msc_vlr_test_rest.c
+++ b/tests/msc_vlr/msc_vlr_test_rest.c
@@ -22,7 +22,7 @@
*/
#include "msc_vlr_tests.h"
-#include "stubs.h"
+
#include <osmocom/msc/vlr.h>
#if 0
@@ -89,7 +89,7 @@ static void test_two_lu()
btw("Location Update request causes a GSUP LU request to HLR");
lu_result_sent = RES_NONE;
- gsup_expect_tx("04010809710000004026f0280102" VLR_TO_HLR);
+ gsup_expect_tx("04010809710000004026f0" CN_DOMAIN VLR_TO_HLR);
ms_sends_msg("050802008168000130089910070000006402");
OSMO_ASSERT(gsup_tx_confirmed);
VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
@@ -120,7 +120,7 @@ static void test_two_lu()
BTW("verify that the MS can send another LU request");
btw("Location Update request causes a GSUP LU request to HLR");
lu_result_sent = RES_NONE;
- gsup_expect_tx("04010809710000004026f0280102" VLR_TO_HLR);
+ gsup_expect_tx("04010809710000004026f0" CN_DOMAIN VLR_TO_HLR);
ms_sends_msg("050802008168000130089910070000006402");
OSMO_ASSERT(gsup_tx_confirmed);
VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
@@ -172,7 +172,7 @@ static void test_lu_unknown_tmsi()
thwart_rx_non_initial_requests();
btw("MS tells us the IMSI, causes a GSUP LU request to HLR");
- gsup_expect_tx("04010809710000004026f0280102" VLR_TO_HLR);
+ gsup_expect_tx("04010809710000004026f0" CN_DOMAIN VLR_TO_HLR);
ms_sends_msg("0559089910070000006402");
OSMO_ASSERT(gsup_tx_confirmed);
VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
diff --git a/tests/msc_vlr/msc_vlr_test_rest.err b/tests/msc_vlr/msc_vlr_test_rest.err
index 3990d109a..3a6442e21 100644
--- a/tests/msc_vlr/msc_vlr_test_rest.err
+++ b/tests/msc_vlr/msc_vlr_test_rest.err
@@ -1,7 +1,3 @@
-DLMGCP MGCP client: using endpoint domain '@mgw'
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 17
-
===== test_cm_service_without_lu
- CM Service Request without a prior Location Updating
MSC <--GERAN-A-- MS: GSM48_MT_MM_CM_SERV_REQ
@@ -64,9 +60,6 @@ DMSC msc_a(IMSI-901700000004620:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASED}: Deal
llist_count(&msub_list) == 0
===== test_cm_service_without_lu: SUCCESS
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 17
-
===== test_two_lu
- Location Update request causes a GSUP LU request to HLR
MSC <--GERAN-A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
@@ -95,10 +88,13 @@ DREF VLR subscr IMSI-901700000004620 + active-conn: now used by 2 (_lu_fsm_assoc
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH
DREF VLR subscr IMSI-901700000004620 - _lu_fsm_associate_vsub: now used by 1 (active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_post_auth()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_post_ciph()
+DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000004620:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node_4()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
DVLR upd_hlr_vlr_fsm(IMSI-901700000004620:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated
@@ -234,10 +230,13 @@ DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + active-conn: now used by 3 (
DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK
DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - _lu_fsm_associate_vsub: now used by 2 (attached,active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre()
DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_post_auth()
DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_post_ciph()
+DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node_4()
DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
DVLR upd_hlr_vlr_fsm(IMSI-901700000004620:MSISDN-46071:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated
@@ -358,12 +357,13 @@ DMSC dummy_msc_i{0}: is child of msub_fsm
DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms)
DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3
DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: MM GSM48_MT_MM_IMSI_DETACH_IND
-DMM IMSI DETACH INDICATION: MI(IMSI)=901700000004620
+DMM IMSI DETACH INDICATION: IMSI-901700000004620
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + gsm48_rx_mm_imsi_detach_ind: now used by 2 (attached,gsm48_rx_mm_imsi_detach_ind)
DMM IMSI DETACH for IMSI-901700000004620:MSISDN-46071
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + active-conn: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn)
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn,vlr_subscr_cancel_attach_fsm)
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - attached: now used by 2 (gsm48_rx_mm_imsi_detach_ind,active-conn)
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - gsm48_rx_mm_imsi_detach_ind: now used by 1 (active-conn)
DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_CN_CLOSE
@@ -403,9 +403,6 @@ DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:NONE){MSC_A_ST_RELEASED}: D
llist_count(&msub_list) == 0
===== test_two_lu: SUCCESS
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 17
-
===== test_lu_unknown_tmsi
- Location Update request with unknown TMSI sends ID Request for IMSI
MSC <--GERAN-A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
@@ -433,8 +430,10 @@ DREF VLR subscr TMSI-0x23422342 + active-conn: now used by 2 (_lu_fsm_associate_
DMSC msc_a(TMSI-0x23422342:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK
DMSC msc_a(TMSI-0x23422342:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH
DREF VLR subscr TMSI-0x23422342 - _lu_fsm_associate_vsub: now used by 1 (active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DVLR vlr_lu_fsm(TMSI-0x23422342:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_want_imsi()
DVLR vlr_lu_fsm(TMSI-0x23422342:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_IMSI
+DBSSAP msc_a(TMSI-0x23422342:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: Sending DTAP: MM GSM48_MT_MM_ID_REQ
DMSC msc_a(TMSI-0x23422342:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: DTAP on GERAN-A
- DTAP --GERAN-A--> MS: GSM48_MT_MM_ID_REQ: 051801
- DTAP matches expected message
@@ -465,14 +464,15 @@ DBSSAP msc_a(TMSI-0x23422342:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN decode error (
DREF msc_a(TMSI-0x23422342:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: + rx_from_ms: now used by 2 (lu,rx_from_ms)
DBSSAP msc_a(TMSI-0x23422342:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN decode: DTAP
DRLL msc_a(TMSI-0x23422342:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: Dispatching 04.08 message: MM GSM48_MT_MM_ID_RESP
-DMM IDENTITY RESPONSE: MI=IMSI-901700000004620
+DMM IDENTITY RESPONSE: IMSI-901700000004620
DVLR set IMSI on subscriber; IMSI=901700000004620 id=901700000004620
DVLR vlr_lu_fsm(TMSI-0x23422342:GERAN-A:LU){VLR_ULA_S_WAIT_IMSI}: Received Event VLR_ULA_E_ID_IMSI
-DVLR set IMSI on subscriber; IMSI=901700000004620 id=901700000004620
DVLR vlr_lu_fsm(TMSI-0x23422342:GERAN-A:LU){VLR_ULA_S_WAIT_IMSI}: vlr_loc_upd_node1_pre()
DVLR vlr_lu_fsm(TMSI-0x23422342:GERAN-A:LU){VLR_ULA_S_WAIT_IMSI}: vlr_loc_upd_node1()
DVLR vlr_lu_fsm(TMSI-0x23422342:GERAN-A:LU){VLR_ULA_S_WAIT_IMSI}: vlr_loc_upd_post_auth()
DVLR vlr_lu_fsm(TMSI-0x23422342:GERAN-A:LU){VLR_ULA_S_WAIT_IMSI}: vlr_loc_upd_post_ciph()
+DMSC msc_a(TMSI-0x23422342:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(TMSI-0x23422342:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DVLR vlr_lu_fsm(TMSI-0x23422342:GERAN-A:LU){VLR_ULA_S_WAIT_IMSI}: vlr_loc_upd_node_4()
DVLR vlr_lu_fsm(TMSI-0x23422342:GERAN-A:LU){VLR_ULA_S_WAIT_IMSI}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
DVLR upd_hlr_vlr_fsm(TMSI-0x23422342:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated
@@ -527,7 +527,7 @@ DVLR lu_compl_vlr_fsm(IMSI-901700000004620:MSISDN-46071:TMSI-0x23422342:GERAN-A:
DVLR lu_compl_vlr_fsm(IMSI-901700000004620:MSISDN-46071:TMSI-0x23422342:GERAN-A:LU){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES
DVLR lu_compl_vlr_fsm(IMSI-901700000004620:MSISDN-46071:TMSI-0x23422342:GERAN-A:LU){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL
- sending LU Accept for IMSI-901700000004620:MSISDN-46071:TMSI-0x23422342:GERAN-A:LU
-DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x23422342 + attached: now used by 3 (active-conn,vlr_gsup_rx,attached)
+DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + attached: now used by 3 (active-conn,vlr_gsup_rx,attached)
DVLR lu_compl_vlr_fsm(IMSI-901700000004620:MSISDN-46071:TMSI-0x23422342:GERAN-A:LU){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_DONE
DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:TMSI-0x23422342:GERAN-A:LU){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS
DVLR lu_compl_vlr_fsm(IMSI-901700000004620:MSISDN-46071:TMSI-0x23422342:GERAN-A:LU){LU_COMPL_VLR_S_DONE}: Terminating in cascade, depth 2 (cause = OSMO_FSM_TERM_PARENT, caused by: upd_hlr_vlr_fsm(TMSI-0x23422342:GERAN-A:LU))
@@ -540,15 +540,15 @@ DREF msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x23422342:GERAN-A:LU){MSC_A_S
DMSC msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x23422342:GERAN-A:LU){MSC_A_ST_AUTHENTICATED}: Received Event MSC_A_EV_UNUSED
DMSC msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x23422342:GERAN-A:LU){MSC_A_ST_AUTHENTICATED}: state_chg to MSC_A_ST_RELEASING
DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x23422342:GERAN-A:LU){MSC_A_ST_RELEASING}: Releasing: msc_a use is 0 (-)
-DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x23422342 + msc_a_fsm_releasing_onenter: now used by 4 (active-conn,vlr_gsup_rx,attached,msc_a_fsm_releasing_onenter)
-DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x23422342 + vlr_subscr_cancel_attach_fsm: now used by 5 (active-conn,vlr_gsup_rx,attached,msc_a_fsm_releasing_onenter,vlr_subscr_cancel_attach_fsm)
-DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x23422342 - vlr_subscr_cancel_attach_fsm: now used by 4 (active-conn,vlr_gsup_rx,attached,msc_a_fsm_releasing_onenter)
+DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + msc_a_fsm_releasing_onenter: now used by 4 (active-conn,vlr_gsup_rx,attached,msc_a_fsm_releasing_onenter)
+DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + vlr_subscr_cancel_attach_fsm: now used by 5 (active-conn,vlr_gsup_rx,attached,msc_a_fsm_releasing_onenter,vlr_subscr_cancel_attach_fsm)
+DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - vlr_subscr_cancel_attach_fsm: now used by 4 (active-conn,vlr_gsup_rx,attached,msc_a_fsm_releasing_onenter)
DREF msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x23422342:GERAN-A:LU){MSC_A_ST_RELEASING}: + wait-Clear-Complete: now used by 1 (wait-Clear-Complete)
DMSC msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x23422342:GERAN-A:LU){MSC_A_ST_RELEASING}: RAN encode: CLEAR_COMMAND on GERAN-A
DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:TMSI-0x23422342:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
-DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x23422342 - msc_a_fsm_releasing_onenter: now used by 3 (active-conn,vlr_gsup_rx,attached)
+DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - msc_a_fsm_releasing_onenter: now used by 3 (active-conn,vlr_gsup_rx,attached)
DVLR upd_hlr_vlr_fsm(TMSI-0x23422342:GERAN-A:LU){UPD_HLR_VLR_S_DONE}: Deallocated, including all deferred deallocations
-DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x23422342 - vlr_gsup_rx: now used by 2 (active-conn,attached)
+DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - vlr_gsup_rx: now used by 2 (active-conn,attached)
<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: vlr_gsupc_read_cb() returns 0
bssap_clear_sent == 1
- LU was successful, and the conn has already been closed
@@ -566,25 +566,19 @@ DVLR vlr_lu_fsm(IMSI-901700000004620:MSISDN-46071:TMSI-0x23422342:GERAN-A:LU){VL
DMSC msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x23422342:GERAN-A:LU){MSC_A_ST_RELEASED}: Removing from parent msub_fsm
DREF msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x23422342:GERAN-A:LU){MSC_A_ST_RELEASED}: max total use count was 3
DMSC msub_fsm{active}: Received Event MSUB_EV_ROLE_TERMINATED
-DMSC msub(IMSI-901700000004620:MSISDN-46071:TMSI-0x23422342) MSC-A terminated
-DMSC msub(IMSI-901700000004620:MSISDN-46071:TMSI-0x23422342) 1 MSC-I still active
+DMSC msub(IMSI-901700000004620:MSISDN-46071) MSC-A terminated
+DMSC msub(IMSI-901700000004620:MSISDN-46071) 1 MSC-I still active
DMSC msub_fsm{active}: state_chg to terminating
DMSC msub_fsm{terminating}: Terminating in cascade, depth 2 (cause = OSMO_FSM_TERM_REGULAR, caused by: msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x23422342:GERAN-A:LU))
DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:TMSI-0x23422342:GERAN-A:LU){0}: Terminating in cascade, depth 3 (cause = OSMO_FSM_TERM_PARENT, caused by: msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x23422342:GERAN-A:LU))
DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:TMSI-0x23422342:GERAN-A:LU){0}: Removing from parent msub_fsm
DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:TMSI-0x23422342:GERAN-A:LU){0}: Deferring: will deallocate with msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x23422342:GERAN-A:LU)
-DMSC msub(IMSI-901700000004620:MSISDN-46071:TMSI-0x23422342) Free
-DREF VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x23422342 - active-conn: now used by 1 (attached)
+DMSC msub(IMSI-901700000004620:MSISDN-46071) Free
+DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - active-conn: now used by 1 (attached)
DMSC msub_fsm{terminating}: Deferring: will deallocate with msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x23422342:GERAN-A:LU)
DMSC msc_a(IMSI-901700000004620:MSISDN-46071:TMSI-0x23422342:GERAN-A:LU){MSC_A_ST_RELEASED}: Deallocated, including all deferred deallocations
- msub gone
llist_count(&msub_list) == 0
-DVLR freeing VLR subscr IMSI-901700000004620:MSISDN-46071:TMSI-0x23422342 (max total use count was 5)
+DVLR freeing VLR subscr IMSI-901700000004620:MSISDN-46071 (max total use count was 5)
===== test_lu_unknown_tmsi: SUCCESS
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 17
-
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 17
-
diff --git a/tests/msc_vlr/msc_vlr_test_ss.c b/tests/msc_vlr/msc_vlr_test_ss.c
index e4b3a4e4d..772429e72 100644
--- a/tests/msc_vlr/msc_vlr_test_ss.c
+++ b/tests/msc_vlr/msc_vlr_test_ss.c
@@ -21,7 +21,6 @@
*/
#include "msc_vlr_tests.h"
-#include "stubs.h"
#define IMSI "901700000004620"
@@ -48,7 +47,7 @@ static void perform_lu(void)
btw("Location Update request causes a GSUP LU request to HLR");
lu_result_sent = RES_NONE;
- gsup_expect_tx("04010809710000004026f0280102" VLR_TO_HLR);
+ gsup_expect_tx("04010809710000004026f0" CN_DOMAIN VLR_TO_HLR);
ms_sends_msg("050802008168000130089910070000006402");
OSMO_ASSERT(gsup_tx_confirmed);
VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
diff --git a/tests/msc_vlr/msc_vlr_test_ss.err b/tests/msc_vlr/msc_vlr_test_ss.err
index 976b26395..8a1bd8272 100644
--- a/tests/msc_vlr/msc_vlr_test_ss.err
+++ b/tests/msc_vlr/msc_vlr_test_ss.err
@@ -1,7 +1,3 @@
-DLMGCP MGCP client: using endpoint domain '@mgw'
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 17
-
===== test_ss_ussd_mo_geran
- Location Update request causes a GSUP LU request to HLR
MSC <--GERAN-A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
@@ -30,10 +26,13 @@ DREF VLR subscr IMSI-901700000004620 + active-conn: now used by 2 (_lu_fsm_assoc
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH
DREF VLR subscr IMSI-901700000004620 - _lu_fsm_associate_vsub: now used by 1 (active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_post_auth()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_post_ciph()
+DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000004620:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node_4()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
DVLR upd_hlr_vlr_fsm(IMSI-901700000004620:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated
@@ -153,6 +152,8 @@ DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_VA
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi()
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_node2()
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_ciph()
+DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_vlr()
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_post_pres()
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: _proc_arq_vlr_post_trace()
@@ -160,6 +161,7 @@ DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SER
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: proc_arq_fsm_done(PASSED)
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_DONE
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_DONE}: Process Access Request result: PASSED
+DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: Sending DTAP: MM GSM48_MT_MM_CM_SERV_ACC
DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN encode: DTAP on GERAN-A
- DTAP --GERAN-A--> MS: GSM48_MT_MM_CM_SERV_ACC: 0521
DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
@@ -184,23 +186,25 @@ GSUP --> HLR: OSMO_GSUP_MSGT_PROC_SS_REQUEST: 20010809710000004026f0300420000001
DREF msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - rx_from_ms: now used by 1 (nc_ss)
<-- GSUP rx OSMO_GSUP_MSGT_PROC_SS_REQUEST: 20010809710000004026f03004200000013101033527a225020101302002013b301b04010f0416d9775d0e2ae3e965f73cfd7683d27310cd06bbc51a0d0a0103
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + gsm0911_gsup_rx: now used by 4 (attached,active-conn,NCSS,gsm0911_gsup_rx)
+DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - gsm0911_gsup_rx: now used by 3 (attached,active-conn,NCSS)
+DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Sending DTAP: NCSS GSM0480_MTYPE_RELEASE_COMPLETE
DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: RAN encode: DTAP on GERAN-A
- DTAP --GERAN-A--> MS: GSM0480_MTYPE_RELEASE_COMPLETE: 8b2a1c27a225020101302002013b301b04010f0416d9775d0e2ae3e965f73cfd7683d27310cd06bbc51a0d
- DTAP matches expected message
DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DSS trans(NCSS IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ callref-0x20000001 tid-8) Freeing transaction
-DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - NCSS: now used by 3 (attached,active-conn,gsm0911_gsup_rx)
+DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - NCSS: now used by 2 (attached,active-conn)
DREF msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: - nc_ss: now used by 0 (-)
DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: Received Event MSC_A_EV_UNUSED
DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_COMMUNICATING}: state_chg to MSC_A_ST_RELEASING
DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: Releasing: msc_a use is 0 (-)
-DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + msc_a_fsm_releasing_onenter: now used by 4 (attached,active-conn,gsm0911_gsup_rx,msc_a_fsm_releasing_onenter)
-DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + vlr_subscr_cancel_attach_fsm: now used by 5 (attached,active-conn,gsm0911_gsup_rx,msc_a_fsm_releasing_onenter,vlr_subscr_cancel_attach_fsm)
-DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - vlr_subscr_cancel_attach_fsm: now used by 4 (attached,active-conn,gsm0911_gsup_rx,msc_a_fsm_releasing_onenter)
+DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + msc_a_fsm_releasing_onenter: now used by 3 (attached,active-conn,msc_a_fsm_releasing_onenter)
+DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,active-conn,msc_a_fsm_releasing_onenter,vlr_subscr_cancel_attach_fsm)
+DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,active-conn,msc_a_fsm_releasing_onenter)
DREF msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: + wait-Clear-Complete: now used by 1 (wait-Clear-Complete)
DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: RAN encode: CLEAR_COMMAND on GERAN-A
DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
-DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - msc_a_fsm_releasing_onenter: now used by 3 (attached,active-conn,gsm0911_gsup_rx)
+DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - msc_a_fsm_releasing_onenter: now used by 2 (attached,active-conn)
<-- GSUP rx OSMO_GSUP_MSGT_PROC_SS_REQUEST: vlr_gsupc_read_cb() returns 0
dtap_tx_confirmed == 1
bssap_clear_sent == 1
@@ -225,7 +229,7 @@ DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: T
DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Removing from parent msub_fsm
DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){0}: Deferring: will deallocate with msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ)
DMSC msub(IMSI-901700000004620:MSISDN-46071) Free
-DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - active-conn: now used by 2 (attached,gsm0911_gsup_rx)
+DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - active-conn: now used by 1 (attached)
DMSC msub_fsm{terminating}: Deferring: will deallocate with msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ)
DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RELEASED}: Deallocated, including all deferred deallocations
- msub gone
@@ -233,9 +237,6 @@ DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_RE
DVLR freeing VLR subscr IMSI-901700000004620:MSISDN-46071 (max total use count was 5)
===== test_ss_ussd_mo_geran: SUCCESS
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 17
-
===== test_ss_ussd_no_geran
- Location Update request causes a GSUP LU request to HLR
MSC <--GERAN-A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
@@ -264,10 +265,13 @@ DREF VLR subscr IMSI-901700000004620 + active-conn: now used by 2 (_lu_fsm_assoc
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK
DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH
DREF VLR subscr IMSI-901700000004620 - _lu_fsm_associate_vsub: now used by 1 (active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_post_auth()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_post_ciph()
+DMSC msc_a(IMSI-901700000004620:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000004620:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node_4()
DVLR vlr_lu_fsm(IMSI-901700000004620:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
DVLR upd_hlr_vlr_fsm(IMSI-901700000004620:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated
@@ -367,22 +371,23 @@ DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + _test_ss_ussd_no: now used b
llist_count(&vsub->cs.requests) == 0
<-- GSUP rx OSMO_GSUP_MSGT_PROC_SS_REQUEST: 20010809710000004026f03004200001013101013515a11302010102013b300b04010f0406aa510c061b010a0103
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + gsm0911_gsup_rx: now used by 3 (attached,_test_ss_ussd_no,gsm0911_gsup_rx)
+DSS (IMSI-901700000004620:MSISDN-46071) Establishing a network-originated session (id=0x20000101)
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + NCSS: now used by 4 (attached,_test_ss_ussd_no,gsm0911_gsup_rx,NCSS)
-DSS trans(NCSS IMSI-901700000004620:MSISDN-46071 callref-0x20000101 tid-255) New transaction
-DSS trans(NCSS IMSI-901700000004620:MSISDN-46071 callref-0x20000101 tid-255) Establishing network-originated session
+DSS trans(NCSS IMSI-901700000004620:MSISDN-46071 callref-0x20000101 tid-0) New transaction
DSS trans(NCSS IMSI-901700000004620:MSISDN-46071 callref-0x20000101 tid-0) Triggering Paging Request
DPAG Paging: IMSI-901700000004620:MSISDN-46071 for GSM 09.11 SS/USSD: Starting paging
paging request (SIGNALLING_HIGH_PRIO) to IMSI-901700000004620:MSISDN-46071 on GERAN-A
strcmp(paging_expecting_imsi, vsub->imsi) == 0
DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + Paging: now used by 5 (attached,_test_ss_ussd_no,gsm0911_gsup_rx,NCSS,Paging)
-<-- GSUP rx OSMO_GSUP_MSGT_PROC_SS_REQUEST: vlr_gsupc_read_cb() returns -22
+DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - gsm0911_gsup_rx: now used by 4 (attached,_test_ss_ussd_no,NCSS,Paging)
+<-- GSUP rx OSMO_GSUP_MSGT_PROC_SS_REQUEST: vlr_gsupc_read_cb() returns 0
llist_count(&vsub->cs.requests) == 1
-DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - _test_ss_ussd_no: now used by 4 (attached,gsm0911_gsup_rx,NCSS,Paging)
+DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - _test_ss_ussd_no: now used by 3 (attached,NCSS,Paging)
paging_sent == 1
- the subscriber and its pending request should remain
-DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + _test_ss_ussd_no: now used by 5 (attached,gsm0911_gsup_rx,NCSS,Paging,_test_ss_ussd_no)
+DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + _test_ss_ussd_no: now used by 4 (attached,NCSS,Paging,_test_ss_ussd_no)
llist_count(&vsub->cs.requests) == 1
-DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - _test_ss_ussd_no: now used by 4 (attached,gsm0911_gsup_rx,NCSS,Paging)
+DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - _test_ss_ussd_no: now used by 3 (attached,NCSS,Paging)
- MS replies with Paging Response, we deliver the NC/USSD
MSC <--GERAN-A-- MS: GSM48_MT_RR_PAG_RESP
new conn
@@ -395,19 +400,21 @@ DMSC dummy_msc_i{0}: is child of msub_fsm
DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms)
DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3
DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: RR GSM48_MT_RR_PAG_RESP
-DRR msc_a(IMSI-901700000004620:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: Rx PAGING RESPONSE
+DRR msc_a(IMSI-901700000004620:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: Rx PAGING RESPONSE IMSI-901700000004620
DREF msc_a(IMSI-901700000004620:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: + paging-response: now used by 2 (rx_from_ms,paging-response)
DVLR Process_Access_Request_VLR(IMSI-901700000004620:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: Allocated
DVLR Process_Access_Request_VLR(IMSI-901700000004620:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: is child of msc_a(IMSI-901700000004620:GERAN-A:PAGING_RESP)
DVLR Process_Access_Request_VLR(IMSI-901700000004620:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: rev=GSM net=GERAN (no Auth)
DVLR Process_Access_Request_VLR(IMSI-901700000004620:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START
-DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + proc_arq_vlr_fn_init: now used by 5 (attached,gsm0911_gsup_rx,NCSS,Paging,proc_arq_vlr_fn_init)
-DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + active-conn: now used by 6 (attached,gsm0911_gsup_rx,NCSS,Paging,proc_arq_vlr_fn_init,active-conn)
+DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + proc_arq_vlr_fn_init: now used by 4 (attached,NCSS,Paging,proc_arq_vlr_fn_init)
+DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + active-conn: now used by 5 (attached,NCSS,Paging,proc_arq_vlr_fn_init,active-conn)
DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK
DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi()
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_node2()
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_ciph()
+DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_vlr()
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_post_pres()
DVLR Process_Access_Request_VLR(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: _proc_arq_vlr_post_trace()
@@ -421,13 +428,14 @@ DPAG Paging: IMSI-901700000004620:MSISDN-46071 for GSM 09.11 SS/USSD: Paging Res
DPAG Paging: IMSI-901700000004620:MSISDN-46071 for GSM 09.11 SS/USSD: Removing Paging Request
DSS msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: Paging succeeded
DREF msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: + nc_ss: now used by 3 (rx_from_ms,paging-response,nc_ss)
+DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: Sending DTAP: NCSS GSM0480_MTYPE_REGISTER
DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: RAN encode: DTAP on GERAN-A
- DTAP --GERAN-A--> MS: GSM0480_MTYPE_REGISTER: 0b3b1c15a11302010102013b300b04010f0406aa510c061b01
- DTAP matches expected message
DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
-DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - Paging: now used by 5 (attached,gsm0911_gsup_rx,NCSS,proc_arq_vlr_fn_init,active-conn)
+DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - Paging: now used by 4 (attached,NCSS,proc_arq_vlr_fn_init,active-conn)
DREF msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: - paging-response: now used by 2 (rx_from_ms,nc_ss)
-DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - proc_arq_vlr_fn_init: now used by 4 (attached,gsm0911_gsup_rx,NCSS,active-conn)
+DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - proc_arq_vlr_fn_init: now used by 3 (attached,NCSS,active-conn)
DREF msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: - rx_from_ms: now used by 1 (nc_ss)
dtap_tx_confirmed == 1
- MS responds to SS/USSD request
@@ -441,24 +449,26 @@ DREF msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHE
dtap_tx_confirmed == 1
- HLR terminates the session
<-- GSUP rx OSMO_GSUP_MSGT_PROC_SS_REQUEST: 20010809710000004026f03004200001013101030a0103
-DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + gsm0911_gsup_rx: now used by 5 (attached,2*gsm0911_gsup_rx,NCSS,active-conn)
+DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + gsm0911_gsup_rx: now used by 4 (attached,NCSS,active-conn,gsm0911_gsup_rx)
+DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - gsm0911_gsup_rx: now used by 3 (attached,NCSS,active-conn)
+DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: Sending DTAP: NCSS GSM0480_MTYPE_RELEASE_COMPLETE
DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: RAN encode: DTAP on GERAN-A
- DTAP --GERAN-A--> MS: GSM0480_MTYPE_RELEASE_COMPLETE: 0b2a
- DTAP matches expected message
DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DSS trans(NCSS IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP callref-0x20000101 tid-0) Freeing transaction
-DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - NCSS: now used by 4 (attached,2*gsm0911_gsup_rx,active-conn)
+DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - NCSS: now used by 2 (attached,active-conn)
DREF msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: - nc_ss: now used by 0 (-)
DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: Received Event MSC_A_EV_UNUSED
DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: state_chg to MSC_A_ST_RELEASING
DBSSAP msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: Releasing: msc_a use is 0 (-)
-DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + msc_a_fsm_releasing_onenter: now used by 5 (attached,2*gsm0911_gsup_rx,active-conn,msc_a_fsm_releasing_onenter)
-DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + vlr_subscr_cancel_attach_fsm: now used by 6 (attached,2*gsm0911_gsup_rx,active-conn,msc_a_fsm_releasing_onenter,vlr_subscr_cancel_attach_fsm)
-DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - vlr_subscr_cancel_attach_fsm: now used by 5 (attached,2*gsm0911_gsup_rx,active-conn,msc_a_fsm_releasing_onenter)
+DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + msc_a_fsm_releasing_onenter: now used by 3 (attached,active-conn,msc_a_fsm_releasing_onenter)
+DREF VLR subscr IMSI-901700000004620:MSISDN-46071 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,active-conn,msc_a_fsm_releasing_onenter,vlr_subscr_cancel_attach_fsm)
+DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,active-conn,msc_a_fsm_releasing_onenter)
DREF msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: + wait-Clear-Complete: now used by 1 (wait-Clear-Complete)
DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASING}: RAN encode: CLEAR_COMMAND on GERAN-A
DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
-DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - msc_a_fsm_releasing_onenter: now used by 4 (attached,2*gsm0911_gsup_rx,active-conn)
+DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - msc_a_fsm_releasing_onenter: now used by 2 (attached,active-conn)
<-- GSUP rx OSMO_GSUP_MSGT_PROC_SS_REQUEST: vlr_gsupc_read_cb() returns 0
dtap_tx_confirmed == 1
bssap_clear_sent == 1
@@ -483,17 +493,11 @@ DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Term
DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Removing from parent msub_fsm
DMSC dummy_msc_i(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){0}: Deferring: will deallocate with msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP)
DMSC msub(IMSI-901700000004620:MSISDN-46071) Free
-DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - active-conn: now used by 3 (attached,2*gsm0911_gsup_rx)
+DREF VLR subscr IMSI-901700000004620:MSISDN-46071 - active-conn: now used by 1 (attached)
DMSC msub_fsm{terminating}: Deferring: will deallocate with msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP)
DMSC msc_a(IMSI-901700000004620:MSISDN-46071:GERAN-A:PAGING_RESP){MSC_A_ST_RELEASED}: Deallocated, including all deferred deallocations
- msub gone
llist_count(&msub_list) == 0
-DVLR freeing VLR subscr IMSI-901700000004620:MSISDN-46071 (max total use count was 6)
+DVLR freeing VLR subscr IMSI-901700000004620:MSISDN-46071 (max total use count was 5)
===== test_ss_ussd_no_geran: SUCCESS
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 17
-
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 17
-
diff --git a/tests/msc_vlr/msc_vlr_test_umts_authen.c b/tests/msc_vlr/msc_vlr_test_umts_authen.c
index cb8a03291..0a2a4464b 100644
--- a/tests/msc_vlr/msc_vlr_test_umts_authen.c
+++ b/tests/msc_vlr/msc_vlr_test_umts_authen.c
@@ -22,7 +22,6 @@
*/
#include "msc_vlr_tests.h"
-#include "stubs.h"
static void _test_umts_authen(enum osmo_rat_type via_ran)
{
@@ -50,6 +49,8 @@ static void _test_umts_authen(enum osmo_rat_type via_ran)
"5079da1e1ee7416937485e9ea7c965373d1d6683c270383b3d0e"
"d3d36ff71c949e83c22072799e9687c5ec32a81d96afcbf4b4fb"
"0c7ac3e9e9b7db05";
+ bool encryption = (via_ran == OSMO_RAT_GERAN_A && net->a5_encryption_mask > 0x1)
+ || (via_ran == OSMO_RAT_UTRAN_IU && net->uea_encryption_mask > (1 << OSMO_UTRAN_UEA0));
net->authentication_required = true;
net->vlr->cfg.assign_tmsi = true;
@@ -57,7 +58,7 @@ static void _test_umts_authen(enum osmo_rat_type via_ran)
btw("Location Update request causes a GSUP Send Auth Info request to HLR");
lu_result_sent = RES_NONE;
- gsup_expect_tx("080108" "09710000000156f0" VLR_TO_HLR);
+ gsup_expect_tx("080108" "09710000000156f0" CN_DOMAIN VLR_TO_HLR);
ms_sends_msg("0508" /* MM LU */
"7" /* ciph key seq: no key available */
"0" /* LU type: normal */
@@ -123,25 +124,38 @@ static void _test_umts_authen(enum osmo_rat_type via_ran)
VERBOSE_ASSERT(auth_request_sent, == true, "%d");
VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
- if (via_ran == OSMO_RAT_GERAN_A) {
- btw("MS sends Authen Response, VLR accepts and sends GSUP LU Req to HLR");
- gsup_expect_tx("04010809710000000156f0280102" VLR_TO_HLR);
+ switch (via_ran) {
+ case OSMO_RAT_GERAN_A:
+ if (encryption) {
+ btw("Test code not implemented");
+ OSMO_ASSERT(false);
+ }
+
+ btw("Encryption disabled. MS sends Authen Response, VLR accepts and sends GSUP LU Req to HLR");
+ gsup_expect_tx("04010809710000000156f0" CN_DOMAIN VLR_TO_HLR);
ms_sends_msg("0554" "e229c19e" "2104" "791f2e41");
VERBOSE_ASSERT(gsup_tx_confirmed, == true, "%d");
VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
- } else {
- /* On UTRAN */
- btw("MS sends Authen Response, VLR accepts and sends SecurityModeControl");
+ break;
+ case OSMO_RAT_UTRAN_IU:
+ /* Even if encryption is disabled (UEA0), we still expect a SecurityModeControl
+ * message indicating UIA, because integrity protection is mandatory in UTRAN. */
+ btw("Encryption %sabled. MS sends Authen Response, VLR accepts and sends SecurityModeControl",
+ encryption ? "en" : "dis");
expect_security_mode_ctrl(NULL, "27497388b6cb044648f396aa155b95ef");
ms_sends_msg("0554" "e229c19e" "2104" "791f2e41");
VERBOSE_ASSERT(security_mode_ctrl_sent, == true, "%d");
VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
btw("MS sends SecurityModeControl acceptance, VLR accepts and sends GSUP LU Req to HLR");
- gsup_expect_tx("04010809710000000156f0280102" VLR_TO_HLR);
- ms_sends_security_mode_complete();
+ gsup_expect_tx("04010809710000000156f0" CN_DOMAIN VLR_TO_HLR);
+ ms_sends_security_mode_complete(encryption ? 0x01 : 0x00);
VERBOSE_ASSERT(gsup_tx_confirmed, == true, "%d");
VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+ break;
+ default:
+ btw("Unhandled RAT %s", osmo_rat_type_name(via_ran));
+ OSMO_ASSERT(false);
}
btw("HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT");
@@ -191,22 +205,35 @@ static void _test_umts_authen(enum osmo_rat_type via_ran)
EXPECT_ACCEPTED(false);
thwart_rx_non_initial_requests();
- if (via_ran == OSMO_RAT_GERAN_A) {
- btw("MS sends Authen Response, VLR accepts with a CM Service Accept");
+ switch (via_ran) {
+ case OSMO_RAT_GERAN_A:
+ if (encryption) {
+ btw("Test code not implemented");
+ OSMO_ASSERT(false);
+ }
+
+ btw("Encryption disabled. MS sends Authen Response, VLR accepts with a CM Service Accept");
gsup_expect_tx(NULL);
ms_sends_msg("0554" "7db47cf7" "2104" "f81e4dc7"); /* 2nd vector's res, s.a. */
VERBOSE_ASSERT(cm_service_result_sent, == RES_ACCEPT, "%d");
- } else {
- /* On UTRAN */
- btw("MS sends Authen Response, VLR accepts and sends SecurityModeControl");
+ break;
+ case OSMO_RAT_UTRAN_IU:
+ /* Even if encryption is disabled (UEA0), we still expect a SecurityModeControl
+ * message indicating UIA, because integrity protection is mandatory in UTRAN. */
+ btw("Encryption %sabled. MS sends Authen Response, VLR accepts and sends SecurityModeControl",
+ encryption ? "en" : "dis");
expect_security_mode_ctrl(NULL, "1159ec926a50e98c034a6b7d7c9f418d");
ms_sends_msg("0554" "7db47cf7" "2104" "f81e4dc7"); /* 2nd vector's res, s.a. */
VERBOSE_ASSERT(security_mode_ctrl_sent, == true, "%d");
VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d");
btw("MS sends SecurityModeControl acceptance, VLR accepts; above Ciphering is an implicit CM Service Accept");
- ms_sends_security_mode_complete();
+ ms_sends_security_mode_complete(encryption ? 0x01 : 0x00);
VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d");
+ break;
+ default:
+ btw("Unhandled RAT %s", osmo_rat_type_name(via_ran));
+ OSMO_ASSERT(false);
}
/* Release connection */
@@ -252,21 +279,34 @@ static void _test_umts_authen(enum osmo_rat_type via_ran)
EXPECT_ACCEPTED(false);
thwart_rx_non_initial_requests();
- if (via_ran == OSMO_RAT_GERAN_A) {
- btw("MS sends Authen Response, VLR accepts and sends pending SMS");
+ switch (via_ran) {
+ case OSMO_RAT_GERAN_A:
+ if (encryption) {
+ btw("Test code not implemented");
+ OSMO_ASSERT(false);
+ }
+
+ btw("Encryption disabled. MS sends Authen Response, VLR accepts and sends pending SMS");
dtap_expect_tx(sms);
ms_sends_msg("0554" "706f9967" "2104" "19ba609c"); /* 3nd vector's res, s.a. */
VERBOSE_ASSERT(dtap_tx_confirmed, == true, "%d");
- } else {
- /* On UTRAN */
- btw("MS sends Authen Response, VLR accepts and sends SecurityModeControl");
+ break;
+ case OSMO_RAT_UTRAN_IU:
+ /* Even if encryption is disabled (UEA0), we still expect a SecurityModeControl
+ * message indicating UIA, because integrity protection is mandatory in UTRAN. */
+ btw("Encryption %sabled. MS sends Authen Response, VLR accepts and sends SecurityModeControl",
+ encryption ? "en" : "dis");
expect_security_mode_ctrl(NULL, "eb50e770ddcc3060101d2f43b6c2b884");
ms_sends_msg("0554" "706f9967" "2104" "19ba609c"); /* 3nd vector's res, s.a. */
VERBOSE_ASSERT(security_mode_ctrl_sent, == true, "%d");
btw("MS sends SecurityModeControl acceptance, VLR accepts and sends SMS");
dtap_expect_tx(sms);
- ms_sends_security_mode_complete();
+ ms_sends_security_mode_complete(encryption ? 0x01 : 0x00);
+ break;
+ default:
+ btw("Unhandled RAT %s", osmo_rat_type_name(via_ran));
+ OSMO_ASSERT(false);
}
btw("SMS was delivered, no requests pending for subscr");
@@ -314,6 +354,15 @@ static void test_umts_authen_geran()
static void test_umts_authen_utran()
{
comment_start();
+ net->uea_encryption_mask = (1 << OSMO_UTRAN_UEA0);
+ _test_umts_authen(OSMO_RAT_UTRAN_IU);
+ comment_end();
+}
+
+static void test_umts_auth_ciph_utran()
+{
+ comment_start();
+ net->uea_encryption_mask = (1 << OSMO_UTRAN_UEA1) | (1 << OSMO_UTRAN_UEA2);
_test_umts_authen(OSMO_RAT_UTRAN_IU);
comment_end();
}
@@ -332,6 +381,8 @@ static void _test_umts_authen_resync(enum osmo_rat_type via_ran)
{
struct vlr_subscr *vsub;
const char *imsi = "901700000010650";
+ bool encryption = (via_ran == OSMO_RAT_GERAN_A && net->a5_encryption_mask > 0x1)
+ || (via_ran == OSMO_RAT_UTRAN_IU && net->uea_encryption_mask > (1 << OSMO_UTRAN_UEA0));
net->authentication_required = true;
net->vlr->cfg.assign_tmsi = true;
@@ -339,7 +390,7 @@ static void _test_umts_authen_resync(enum osmo_rat_type via_ran)
btw("Location Update request causes a GSUP Send Auth Info request to HLR");
lu_result_sent = RES_NONE;
- gsup_expect_tx("080108" "09710000000156f0" VLR_TO_HLR);
+ gsup_expect_tx("080108" "09710000000156f0" CN_DOMAIN VLR_TO_HLR);
ms_sends_msg("0508" /* MM LU */
"7" /* ciph key seq: no key available */
"0" /* LU type: normal */
@@ -441,7 +492,7 @@ static void _test_umts_authen_resync(enum osmo_rat_type via_ran)
"0108" "09710000000156f0" /* IMSI */
"260e" "979498b1f72d3e28c59fa2e72f9c" /* AUTS */
"2010" "39fa2f4e3d523d8619a73b4f65c3e14d" /* RAND */
- VLR_TO_HLR);
+ CN_DOMAIN VLR_TO_HLR);
ms_sends_msg("051c" /* 05 = MM; 1c = Auth Failure */
"15" /* cause = Synch Failure */
"220e" "979498b1f72d3e28c59fa2e72f9c" /* AUTS */);
@@ -486,25 +537,38 @@ static void _test_umts_authen_resync(enum osmo_rat_type via_ran)
VERBOSE_ASSERT(auth_request_sent, == true, "%d");
VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
- if (via_ran == OSMO_RAT_GERAN_A) {
- btw("MS sends Authen Response, VLR accepts and sends GSUP LU Req to HLR");
- gsup_expect_tx("04010809710000000156f0280102" VLR_TO_HLR);
+ switch (via_ran) {
+ case OSMO_RAT_GERAN_A:
+ if (encryption) {
+ btw("Test code not implemented");
+ OSMO_ASSERT(false);
+ }
+
+ btw("Encryption disabled. MS sends Authen Response, VLR accepts and sends GSUP LU Req to HLR");
+ gsup_expect_tx("04010809710000000156f0" CN_DOMAIN VLR_TO_HLR);
ms_sends_msg("0554" "1df5f0b4" "2104" "f22b696e");
VERBOSE_ASSERT(gsup_tx_confirmed, == true, "%d");
VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
- } else {
- /* On UTRAN */
- btw("MS sends Authen Response, VLR accepts and sends SecurityModeControl");
+ break;
+ case OSMO_RAT_UTRAN_IU:
+ /* Even if encryption is disabled (UEA0), we still expect a SecurityModeControl
+ * message indicating UIA, because integrity protection is mandatory in UTRAN. */
+ btw("Encryption %sabled. MS sends Authen Response, VLR accepts and sends SecurityModeControl",
+ encryption ? "en" : "dis");
expect_security_mode_ctrl(NULL, "8a90c769b7272f3bb7a1c1fbb1ea9349");
ms_sends_msg("0554" "1df5f0b4" "2104" "f22b696e");
VERBOSE_ASSERT(security_mode_ctrl_sent, == true, "%d");
VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
btw("MS sends SecurityModeControl acceptance, VLR accepts and sends GSUP LU Req to HLR");
- gsup_expect_tx("04010809710000000156f0280102" VLR_TO_HLR);
- ms_sends_security_mode_complete();
+ gsup_expect_tx("04010809710000000156f0" CN_DOMAIN VLR_TO_HLR);
+ ms_sends_security_mode_complete(encryption ? 0x01 : 0x00);
VERBOSE_ASSERT(gsup_tx_confirmed, == true, "%d");
VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+ break;
+ default:
+ btw("Unhandled RAT %s", osmo_rat_type_name(via_ran));
+ OSMO_ASSERT(false);
}
btw("HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT");
@@ -552,6 +616,15 @@ static void test_umts_authen_resync_geran()
static void test_umts_authen_resync_utran()
{
comment_start();
+ net->uea_encryption_mask = (1 << OSMO_UTRAN_UEA0);
+ _test_umts_authen_resync(OSMO_RAT_UTRAN_IU);
+ comment_end();
+}
+
+static void test_umts_auth_ciph_resync_utran()
+{
+ comment_start();
+ net->uea_encryption_mask = (1 << OSMO_UTRAN_UEA1) | (1 << OSMO_UTRAN_UEA2);
_test_umts_authen_resync(OSMO_RAT_UTRAN_IU);
comment_end();
}
@@ -564,7 +637,7 @@ static void _test_umts_authen_too_short_res(enum osmo_rat_type via_ran)
btw("Location Update request causes a GSUP Send Auth Info request to HLR");
lu_result_sent = RES_NONE;
- gsup_expect_tx("080108" "09710000000156f0" VLR_TO_HLR);
+ gsup_expect_tx("080108" "09710000000156f0" CN_DOMAIN VLR_TO_HLR);
ms_sends_msg("0508" /* MM LU */
"7" /* ciph key seq: no key available */
"0" /* LU type: normal */
@@ -664,7 +737,7 @@ static void _test_umts_authen_too_long_res(enum osmo_rat_type via_ran)
btw("Location Update request causes a GSUP Send Auth Info request to HLR");
lu_result_sent = RES_NONE;
- gsup_expect_tx("080108" "09710000000156f0" VLR_TO_HLR);
+ gsup_expect_tx("080108" "09710000000156f0" CN_DOMAIN VLR_TO_HLR);
ms_sends_msg("0508" /* MM LU */
"7" /* ciph key seq: no key available */
"0" /* LU type: normal */
@@ -764,7 +837,7 @@ static void _test_umts_authen_only_sres(enum osmo_rat_type via_ran)
btw("Location Update request causes a GSUP Send Auth Info request to HLR");
lu_result_sent = RES_NONE;
- gsup_expect_tx("080108" "09710000000156f0" VLR_TO_HLR);
+ gsup_expect_tx("080108" "09710000000156f0" CN_DOMAIN VLR_TO_HLR);
ms_sends_msg("0508" /* MM LU */
"7" /* ciph key seq: no key available */
"0" /* LU type: normal */
@@ -865,8 +938,10 @@ static void test_umts_authen_only_sres_utran()
msc_vlr_test_func_t msc_vlr_tests[] = {
test_umts_authen_geran,
test_umts_authen_utran,
+ test_umts_auth_ciph_utran,
test_umts_authen_resync_geran,
test_umts_authen_resync_utran,
+ test_umts_auth_ciph_resync_utran,
test_umts_authen_too_short_res_geran,
test_umts_authen_too_short_res_utran,
test_umts_authen_too_long_res_geran,
diff --git a/tests/msc_vlr/msc_vlr_test_umts_authen.err b/tests/msc_vlr/msc_vlr_test_umts_authen.err
index b11f077d4..aacff394d 100644
--- a/tests/msc_vlr/msc_vlr_test_umts_authen.err
+++ b/tests/msc_vlr/msc_vlr_test_umts_authen.err
@@ -1,7 +1,3 @@
-DLMGCP MGCP client: using endpoint domain '@mgw'
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 17
-
===== test_umts_authen_geran
- Location Update request causes a GSUP Send Auth Info request to HLR
MSC <--GERAN-A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
@@ -30,13 +26,14 @@ DREF VLR subscr IMSI-901700000010650 + active-conn: now used by 2 (_lu_fsm_assoc
DMSC msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK
DMSC msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH
DREF VLR subscr IMSI-901700000010650 - _lu_fsm_associate_vsub: now used by 1 (active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre()
DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH
DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Allocated
DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU)
DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
-GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f00a0101
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f02801020a0101
DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
DREF msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - mm_rx_loc_upd_req: now used by 2 (rx_from_ms,lu)
DREF msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu)
@@ -56,7 +53,7 @@ DREF VLR subscr IMSI-901700000010650 - vlr_gsup_rx: now used by 1 (active-conn)
<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT: vlr_gsupc_read_cb() returns 0
auth_request_sent == 1
lu_result_sent == 0
-- MS sends Authen Response, VLR accepts and sends GSUP LU Req to HLR
+- Encryption disabled. MS sends Authen Response, VLR accepts and sends GSUP LU Req to HLR
MSC <--GERAN-A-- MS: GSM48_MT_MM_AUTH_RESP
DREF msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: + rx_from_ms: now used by 2 (lu,rx_from_ms)
DBSSAP msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN decode: DTAP
@@ -69,9 +66,11 @@ DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: Au
DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU)
-DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES
+DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_SUCCESS
DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth()
DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_ciph()
+DMSC msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000010650:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_node_4()
DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
DVLR upd_hlr_vlr_fsm(IMSI-901700000010650:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated
@@ -258,7 +257,7 @@ DBSSAP msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVIC
DRLL msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: Dispatching 04.08 message: SMS SMS:0x01
DBSSAP msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: Message not permitted for initial conn: SMS:0x01
DBSSAP msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN decode error (rc=-13) for DTAP from MSC-I
-- MS sends Authen Response, VLR accepts with a CM Service Accept
+- Encryption disabled. MS sends Authen Response, VLR accepts with a CM Service Accept
MSC <--GERAN-A-- MS: GSM48_MT_MM_AUTH_RESP
DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: + rx_from_ms: now used by 2 (cm_service_sms,rx_from_ms)
DBSSAP msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN decode: DTAP
@@ -274,6 +273,8 @@ DVLR VLR_Authenticate(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:
DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: Received Event PR_ARQ_E_AUTH_RES
DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2()
DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2_post_ciph()
+DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2_post_vlr()
DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_pres()
DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_trace()
@@ -281,6 +282,7 @@ DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x0302010
DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: proc_arq_fsm_done(PASSED)
DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: state_chg to PR_ARQ_S_DONE
DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){PR_ARQ_S_DONE}: Process Access Request result: PASSED
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: Sending DTAP: MM GSM48_MT_MM_CM_SERV_ACC
DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN encode: DTAP on GERAN-A
- DTAP --GERAN-A--> MS: GSM48_MT_MM_CM_SERV_ACC: 0521
DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
@@ -368,7 +370,7 @@ DMSC dummy_msc_i{0}: is child of msub_fsm
DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms)
DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3
DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: RR GSM48_MT_RR_PAG_RESP
-DRR msc_a(IMSI-901700000010650:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: Rx PAGING RESPONSE
+DRR msc_a(IMSI-901700000010650:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: Rx PAGING RESPONSE IMSI-901700000010650
DREF msc_a(IMSI-901700000010650:GERAN-A:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: + paging-response: now used by 2 (rx_from_ms,paging-response)
DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: Allocated
DVLR Process_Access_Request_VLR(IMSI-901700000010650:GERAN-A:PAGING_RESP){PR_ARQ_S_INIT}: is child of msc_a(IMSI-901700000010650:GERAN-A:PAGING_RESP)
@@ -411,7 +413,7 @@ DBSSAP msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:PAGING_RE
DRLL msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: Dispatching 04.08 message: SMS SMS:0x01
DBSSAP msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: Message not permitted for initial conn: SMS:0x01
DBSSAP msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: RAN decode error (rc=-13) for DTAP from MSC-I
-- MS sends Authen Response, VLR accepts and sends pending SMS
+- Encryption disabled. MS sends Authen Response, VLR accepts and sends pending SMS
MSC <--GERAN-A-- MS: GSM48_MT_MM_AUTH_RESP
DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: + rx_from_ms: now used by 2 (paging-response,rx_from_ms)
DBSSAP msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: RAN decode: DTAP
@@ -427,6 +429,8 @@ DVLR VLR_Authenticate(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:
DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:PAGING_RESP){PR_ARQ_S_WAIT_AUTH}: Received Event PR_ARQ_E_AUTH_RES
DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:PAGING_RESP){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2()
DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:PAGING_RESP){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2_post_ciph()
+DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:PAGING_RESP){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2_post_vlr()
DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:PAGING_RESP){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_pres()
DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:PAGING_RESP){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_trace()
@@ -445,6 +449,7 @@ DLSMS SMC(0) send CP data
DLSMS SMC(0) new CP state MM_CONN_PENDING -> WAIT_CP_ACK
DLSMS trans(SMS IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:PAGING_RESP callref-0x40000001 tid-0) sending CP message (trans=0)
DLSMS trans(SMS IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:PAGING_RESP callref-0x40000001 tid-0) GSM4.11 TX 09 01 58 01 00 07 91 44 77 58 10 06 50 00 4c 00 05 80 24 43 f2 00 00 07 10 10 00 00 00 00 44 50 79 da 1e 1e e7 41 69 37 48 5e 9e a7 c9 65 37 3d 1d 66 83 c2 70 38 3b 3d 0e d3 d3 6f f7 1c 94 9e 83 c2 20 72 79 9e 96 87 c5 ec 32 a8 1d 96 af cb f4 b4 fb 0c 7a c3 e9 e9 b7 db 05
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: Sending DTAP: SMS SMS:0x01
DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: RAN encode: DTAP on GERAN-A
- DTAP --GERAN-A--> MS: SMS:0x01: 09015801000791447758100650004c0005802443f2000007101000000000445079da1e1ee7416937485e9ea7c965373d1d6683c270383b3d0ed3d36ff71c949e83c22072799e9687c5ec32a81d96afcbf4b4fb0c7ac3e9e9b7db05
- DTAP matches expected message
@@ -481,6 +486,7 @@ DLSMS SMC(0) message MMSMS-DATA-IND (CP DATA) received in state MM_ESTABLISHED
DLSMS SMC(0) received CP-DATA
DLSMS trans(SMS IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:PAGING_RESP callref-0x40000001 tid-0) sending CP message (trans=0)
DLSMS trans(SMS IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:PAGING_RESP callref-0x40000001 tid-0) GSM4.11 TX 09 04
+DBSSAP msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: Sending DTAP: SMS SMS:0x04
DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: RAN encode: DTAP on GERAN-A
- DTAP --GERAN-A--> MS: SMS:0x04: 0904
- DTAP matches expected message
@@ -553,12 +559,13 @@ DMSC dummy_msc_i{0}: is child of msub_fsm
DREF msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms)
DBSSAP msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3
DRLL msc_a(unknown:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: MM GSM48_MT_MM_IMSI_DETACH_IND
-DMM IMSI DETACH INDICATION: MI(IMSI)=901700000010650
+DMM IMSI DETACH INDICATION: IMSI-901700000010650
DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + gsm48_rx_mm_imsi_detach_ind: now used by 2 (attached,gsm48_rx_mm_imsi_detach_ind)
DMM IMSI DETACH for IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100
DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + active-conn: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn)
DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn,vlr_subscr_cancel_attach_fsm)
DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - attached: now used by 2 (gsm48_rx_mm_imsi_detach_ind,active-conn)
DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - gsm48_rx_mm_imsi_detach_ind: now used by 1 (active-conn)
DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:NONE){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_CN_CLOSE
@@ -598,9 +605,6 @@ DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:NONE){MSC_A
llist_count(&msub_list) == 0
===== test_umts_authen_geran: SUCCESS
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 17
-
===== test_umts_authen_utran
- Location Update request causes a GSUP Send Auth Info request to HLR
MSC <--UTRAN-Iu-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
@@ -620,7 +624,7 @@ DREF msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_VALIDATE_L3}: + mm_rx_loc_
DREF msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_VALIDATE_L3}: + lu: now used by 3 (rx_from_ms,mm_rx_loc_upd_req,lu)
DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: Allocated
DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: is child of msc_a(IMSI-901700000010650:UTRAN-Iu:LU)
-DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: rev=R99 net=UTRAN Auth+Ciph
+DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: rev=R99 net=UTRAN Auth (no Ciph)
DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA
DREF VLR subscr unknown + _lu_fsm_associate_vsub: now used by 1 (_lu_fsm_associate_vsub)
DVLR set IMSI on subscriber; IMSI=901700000010650 id=901700000010650
@@ -629,13 +633,14 @@ DREF VLR subscr IMSI-901700000010650 + active-conn: now used by 2 (_lu_fsm_assoc
DMSC msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK
DMSC msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH
DREF VLR subscr IMSI-901700000010650 - _lu_fsm_associate_vsub: now used by 1 (active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre()
DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH
DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: Allocated
DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU)
DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
-GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f00a0101
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f02801020a0101
DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
DREF msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: - mm_rx_loc_upd_req: now used by 2 (rx_from_ms,lu)
DREF msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu)
@@ -655,7 +660,7 @@ DREF VLR subscr IMSI-901700000010650 - vlr_gsup_rx: now used by 1 (active-conn)
<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT: vlr_gsupc_read_cb() returns 0
auth_request_sent == 1
lu_result_sent == 0
-- MS sends Authen Response, VLR accepts and sends SecurityModeControl
+- Encryption disabled. MS sends Authen Response, VLR accepts and sends SecurityModeControl
MSC <--UTRAN-Iu-- MS: GSM48_MT_MM_AUTH_RESP
DREF msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: + rx_from_ms: now used by 2 (lu,rx_from_ms)
DIUCS msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: RAN decode: DTAP
@@ -668,7 +673,7 @@ DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_WAIT_RESP}: A
DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU)
-DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES
+DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_SUCCESS
DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth()
DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: Set Ciphering Mode
DMSC msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: CIPHER_MODE_COMMAND on UTRAN-Iu
@@ -829,7 +834,7 @@ DMM msc_a(IMSI-901700000010650:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_VALIDATE_L3}: R
DREF msc_a(IMSI-901700000010650:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_VALIDATE_L3}: + cm_service_sms: now used by 2 (rx_from_ms,cm_service_sms)
DVLR Process_Access_Request_VLR(IMSI-901700000010650:UTRAN-Iu:CM_SERVICE_REQ){PR_ARQ_S_INIT}: Allocated
DVLR Process_Access_Request_VLR(IMSI-901700000010650:UTRAN-Iu:CM_SERVICE_REQ){PR_ARQ_S_INIT}: is child of msc_a(IMSI-901700000010650:UTRAN-Iu:CM_SERVICE_REQ)
-DVLR Process_Access_Request_VLR(IMSI-901700000010650:UTRAN-Iu:CM_SERVICE_REQ){PR_ARQ_S_INIT}: rev=R99 net=UTRAN Auth+Ciph
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:UTRAN-Iu:CM_SERVICE_REQ){PR_ARQ_S_INIT}: rev=R99 net=UTRAN Auth (no Ciph)
DVLR Process_Access_Request_VLR(IMSI-901700000010650:UTRAN-Iu:CM_SERVICE_REQ){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START
DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + proc_arq_vlr_fn_init: now used by 2 (attached,proc_arq_vlr_fn_init)
DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + active-conn: now used by 3 (attached,proc_arq_vlr_fn_init,active-conn)
@@ -869,7 +874,7 @@ DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVIC
DRLL msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: Dispatching 04.08 message: SMS SMS:0x01
DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: Message not permitted for initial conn: SMS:0x01
DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN decode error (rc=-13) for DTAP from MSC-I
-- MS sends Authen Response, VLR accepts and sends SecurityModeControl
+- Encryption disabled. MS sends Authen Response, VLR accepts and sends SecurityModeControl
MSC <--UTRAN-Iu-- MS: GSM48_MT_MM_AUTH_RESP
DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: + rx_from_ms: now used by 2 (cm_service_sms,rx_from_ms)
DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN decode: DTAP
@@ -988,11 +993,11 @@ DMSC dummy_msc_i{0}: is child of msub_fsm
DREF msc_a(unknown:UTRAN-Iu:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms)
DIUCS msc_a(unknown:UTRAN-Iu:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3
DRLL msc_a(unknown:UTRAN-Iu:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: RR GSM48_MT_RR_PAG_RESP
-DRR msc_a(IMSI-901700000010650:UTRAN-Iu:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: Rx PAGING RESPONSE
+DRR msc_a(IMSI-901700000010650:UTRAN-Iu:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: Rx PAGING RESPONSE IMSI-901700000010650
DREF msc_a(IMSI-901700000010650:UTRAN-Iu:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: + paging-response: now used by 2 (rx_from_ms,paging-response)
DVLR Process_Access_Request_VLR(IMSI-901700000010650:UTRAN-Iu:PAGING_RESP){PR_ARQ_S_INIT}: Allocated
DVLR Process_Access_Request_VLR(IMSI-901700000010650:UTRAN-Iu:PAGING_RESP){PR_ARQ_S_INIT}: is child of msc_a(IMSI-901700000010650:UTRAN-Iu:PAGING_RESP)
-DVLR Process_Access_Request_VLR(IMSI-901700000010650:UTRAN-Iu:PAGING_RESP){PR_ARQ_S_INIT}: rev=R99 net=UTRAN Auth+Ciph
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:UTRAN-Iu:PAGING_RESP){PR_ARQ_S_INIT}: rev=R99 net=UTRAN Auth (no Ciph)
DVLR Process_Access_Request_VLR(IMSI-901700000010650:UTRAN-Iu:PAGING_RESP){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START
DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + proc_arq_vlr_fn_init: now used by 5 (attached,SMS-receiver,SMS,Paging,proc_arq_vlr_fn_init)
DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + active-conn: now used by 6 (attached,SMS-receiver,SMS,Paging,proc_arq_vlr_fn_init,active-conn)
@@ -1031,7 +1036,7 @@ DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RE
DRLL msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: Dispatching 04.08 message: SMS SMS:0x01
DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: Message not permitted for initial conn: SMS:0x01
DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: RAN decode error (rc=-13) for DTAP from MSC-I
-- MS sends Authen Response, VLR accepts and sends SecurityModeControl
+- Encryption disabled. MS sends Authen Response, VLR accepts and sends SecurityModeControl
MSC <--UTRAN-Iu-- MS: GSM48_MT_MM_AUTH_RESP
DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: + rx_from_ms: now used by 2 (paging-response,rx_from_ms)
DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: RAN decode: DTAP
@@ -1078,6 +1083,7 @@ DLSMS SMC(0) send CP data
DLSMS SMC(0) new CP state MM_CONN_PENDING -> WAIT_CP_ACK
DLSMS trans(SMS IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x40000002 tid-0) sending CP message (trans=0)
DLSMS trans(SMS IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x40000002 tid-0) GSM4.11 TX 09 01 58 01 00 07 91 44 77 58 10 06 50 00 4c 00 05 80 24 43 f2 00 00 07 10 10 00 00 00 00 44 50 79 da 1e 1e e7 41 69 37 48 5e 9e a7 c9 65 37 3d 1d 66 83 c2 70 38 3b 3d 0e d3 d3 6f f7 1c 94 9e 83 c2 20 72 79 9e 96 87 c5 ec 32 a8 1d 96 af cb f4 b4 fb 0c 7a c3 e9 e9 b7 db 05
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: Sending DTAP: SMS SMS:0x01
DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: RAN encode: DTAP on UTRAN-Iu
- DTAP --UTRAN-Iu--> MS: SMS:0x01: 09015801000791447758100650004c0005802443f2000007101000000000445079da1e1ee7416937485e9ea7c965373d1d6683c270383b3d0ed3d36ff71c949e83c22072799e9687c5ec32a81d96afcbf4b4fb0c7ac3e9e9b7db05
- DTAP matches expected message
@@ -1111,6 +1117,7 @@ DLSMS SMC(0) message MMSMS-DATA-IND (CP DATA) received in state MM_ESTABLISHED
DLSMS SMC(0) received CP-DATA
DLSMS trans(SMS IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x40000002 tid-0) sending CP message (trans=0)
DLSMS trans(SMS IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x40000002 tid-0) GSM4.11 TX 09 04
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: Sending DTAP: SMS SMS:0x04
DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: RAN encode: DTAP on UTRAN-Iu
- DTAP --UTRAN-Iu--> MS: SMS:0x04: 0904
- DTAP matches expected message
@@ -1183,12 +1190,13 @@ DMSC dummy_msc_i{0}: is child of msub_fsm
DREF msc_a(unknown:UTRAN-Iu:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms)
DIUCS msc_a(unknown:UTRAN-Iu:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3
DRLL msc_a(unknown:UTRAN-Iu:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: MM GSM48_MT_MM_IMSI_DETACH_IND
-DMM IMSI DETACH INDICATION: MI(IMSI)=901700000010650
+DMM IMSI DETACH INDICATION: IMSI-901700000010650
DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + gsm48_rx_mm_imsi_detach_ind: now used by 2 (attached,gsm48_rx_mm_imsi_detach_ind)
DMM IMSI DETACH for IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100
DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + active-conn: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn)
DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn,vlr_subscr_cancel_attach_fsm)
DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - attached: now used by 2 (gsm48_rx_mm_imsi_detach_ind,active-conn)
DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - gsm48_rx_mm_imsi_detach_ind: now used by 1 (active-conn)
DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:NONE){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_CN_CLOSE
@@ -1228,8 +1236,636 @@ DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:NONE){MSC_
llist_count(&msub_list) == 0
===== test_umts_authen_utran: SUCCESS
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 17
+===== test_umts_auth_ciph_utran
+- Location Update request causes a GSUP Send Auth Info request to HLR
+ MSC <--UTRAN-Iu-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
+ new conn
+DMSC msub_fsm{active}: Allocated
+DMSC msc_a{MSC_A_ST_VALIDATE_L3}: Allocated
+DMSC msc_a{MSC_A_ST_VALIDATE_L3}: is child of msub_fsm
+DMSC msc_a(unknown:UTRAN-Iu:NONE){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_VALIDATE_L3
+DMSC dummy_msc_i{0}: Allocated
+DMSC dummy_msc_i{0}: is child of msub_fsm
+DREF msc_a(unknown:UTRAN-Iu:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms)
+DIUCS msc_a(unknown:UTRAN-Iu:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3
+DRLL msc_a(unknown:UTRAN-Iu:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: MM GSM48_MT_MM_LOC_UPD_REQUEST
+DMM msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_VALIDATE_L3}: LOCATION UPDATING REQUEST: MI=IMSI-901700000010650 LU-type=NORMAL
+DMM msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_VALIDATE_L3}: USIM: old LAI: 1665-165-0
+DREF msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_VALIDATE_L3}: + mm_rx_loc_upd_req: now used by 2 (rx_from_ms,mm_rx_loc_upd_req)
+DREF msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_VALIDATE_L3}: + lu: now used by 3 (rx_from_ms,mm_rx_loc_upd_req,lu)
+DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: Allocated
+DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: is child of msc_a(IMSI-901700000010650:UTRAN-Iu:LU)
+DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: rev=R99 net=UTRAN Auth+Ciph
+DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA
+DREF VLR subscr unknown + _lu_fsm_associate_vsub: now used by 1 (_lu_fsm_associate_vsub)
+DVLR set IMSI on subscriber; IMSI=901700000010650 id=901700000010650
+DVLR New subscr, IMSI: 901700000010650
+DREF VLR subscr IMSI-901700000010650 + active-conn: now used by 2 (_lu_fsm_associate_vsub,active-conn)
+DMSC msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK
+DMSC msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH
+DREF VLR subscr IMSI-901700000010650 - _lu_fsm_associate_vsub: now used by 1 (active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
+DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre()
+DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
+DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH
+DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: Allocated
+DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU)
+DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f02801020a0101
+DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
+DREF msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: - mm_rx_loc_upd_req: now used by 2 (rx_from_ms,lu)
+DREF msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu)
+ lu_result_sent == 0
+- from HLR, rx _SEND_AUTH_INFO_RESULT; VLR sends Auth Req to MS
+<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT: 0a010809710000000156f00362201039fa2f4e3d523d8619a73b4f65c3e14d21049b36efdf2208059a4f668f6fbe39231027497388b6cb044648f396aa155b95ef2410f64735036e5871319c679f4742a75ea125108704f5ba55f30000d2ee44b22c8ea9192708e229c19e791f2e4103622010c187a53a5e6b9d573cac7c74451fd46d210485aa31302208d3d50a000bf04f6e23101159ec926a50e98c034a6b7d7c9f418d2410df3a03d9ca5335641efc8e36d76cd20b25101843a645b98d00005b2d666af46c45d927087db47cf7f81e4dc703622010efa9c29a9742148d5c9070348716e1bb210469d5f9fb22083df176f0c29f1a3d2310eb50e770ddcc3060101d2f43b6c2b884241076542abce5ff9345b0e8947f4c6e019c2510f9375e6d41e1000096e7fe4ff1c27e392708706f996719ba609c03622010f023d5a3b24726e0631b64b3840f82532104d570c03f2208ec011be8919883d62310c4e58af4ba43f3bcd904e16984f086d724100593f65e752e5cb7f473862bda05aa0a2510541ff1f077270000c5ea00d658bc7e9a27083fd26072eaa2a04d036220102f8f90c780d6a9c0c53da7ac57b6707e2104b072446f220823f39f9f425ad6e6231065af0527fda95b0dc5ae4aa515cdf32f2410537c3b35a3b13b08d08eeb28098f45cc25104bf4e564f75300009bc796706bc6574427080edb0eadbea94ac20a0101
+DREF VLR subscr IMSI-901700000010650 + vlr_gsup_rx: now used by 2 (active-conn,vlr_gsup_rx)
+DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: Received Event VLR_AUTH_E_HLR_SAI_ACK
+DVLR SUBSCR(IMSI-901700000010650) Received 5 auth tuples
+DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: state_chg to VLR_SUB_AS_WAIT_RESP
+DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_WAIT_RESP}: got auth tuple: use_count=1 key_seq=0 -- will use UMTS AKA (is_r99=yes, at->vec.auth_types=0x3)
+- sending UMTS Auth Request for IMSI-901700000010650:UTRAN-Iu:LU: tuple use_count=1 key_seq=0 auth_types=0x3 and...
+- ...rand=39fa2f4e3d523d8619a73b4f65c3e14d
+- ...autn=8704f5ba55f30000d2ee44b22c8ea919
+- ...expecting res=e229c19e791f2e41
+DREF VLR subscr IMSI-901700000010650 - vlr_gsup_rx: now used by 1 (active-conn)
+<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT: vlr_gsupc_read_cb() returns 0
+ auth_request_sent == 1
+ lu_result_sent == 0
+- Encryption enabled. MS sends Authen Response, VLR accepts and sends SecurityModeControl
+ MSC <--UTRAN-Iu-- MS: GSM48_MT_MM_AUTH_RESP
+DREF msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: + rx_from_ms: now used by 2 (lu,rx_from_ms)
+DIUCS msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: RAN decode: DTAP
+DRLL msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: Dispatching 04.08 message: MM GSM48_MT_MM_AUTH_RESP
+DMM msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: MM UMTS AUTHENTICATION RESPONSE (res = e229c19e791f2e41)
+DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP
+DVLR SUBSCR(IMSI-901700000010650) AUTH on UTRAN received RES: e229c19e791f2e41 (8 bytes)
+DVLR SUBSCR(IMSI-901700000010650) AUTH established UMTS security context
+DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result PASSED
+DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
+DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU)
+DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_SUCCESS
+DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth()
+DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: Set Ciphering Mode
+DMSC msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: CIPHER_MODE_COMMAND on UTRAN-Iu
+- sending SecurityModeControl: ik=27497388b6cb044648f396aa155b95ef
+DMSC dummy_msc_i(IMSI-901700000010650:UTRAN-Iu:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_WAIT_CIPH
+DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_AUTHENTICATED}: Deallocated
+DREF msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu)
+ security_mode_ctrl_sent == 1
+ lu_result_sent == 0
+- MS sends SecurityModeControl acceptance, VLR accepts and sends GSUP LU Req to HLR
+DIUCS msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: RAN decode: CIPHER_MODE_COMPLETE
+DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_CIPH}: Received Event VLR_ULA_E_CIPH_RES
+DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_CIPH}: vlr_loc_upd_post_ciph()
+DMSC msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on UTRAN-Iu
+DMSC dummy_msc_i(IMSI-901700000010650:UTRAN-Iu:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_CIPH}: vlr_loc_upd_node_4()
+DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_CIPH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
+DVLR upd_hlr_vlr_fsm(IMSI-901700000010650:UTRAN-Iu:LU){UPD_HLR_VLR_S_INIT}: Allocated
+DVLR upd_hlr_vlr_fsm(IMSI-901700000010650:UTRAN-Iu:LU){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU)
+DVLR upd_hlr_vlr_fsm(IMSI-901700000010650:UTRAN-Iu:LU){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START
+GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000000156f02801020a0101
+DVLR upd_hlr_vlr_fsm(IMSI-901700000010650:UTRAN-Iu:LU){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA
+ gsup_tx_confirmed == 1
+ lu_result_sent == 0
+- HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT
+<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: 10010809710000000156f00804032443f20a0101
+DREF VLR subscr IMSI-901700000010650 + vlr_gsup_rx: now used by 2 (active-conn,vlr_gsup_rx)
+DVLR IMSI:901700000010650 has MSISDN:42342
+DVLR SUBSCR(IMSI-901700000010650:MSISDN-42342) VLR: update for IMSI=901700000010650 (MSISDN=42342)
+GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000000156f00a0101
+DREF VLR subscr IMSI-901700000010650:MSISDN-42342 - vlr_gsup_rx: now used by 1 (active-conn)
+<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: vlr_gsupc_read_cb() returns 0
+ lu_result_sent == 0
+- HLR also sends GSUP _UPDATE_LOCATION_RESULT
+<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: 06010809710000000156f00a0101
+DREF VLR subscr IMSI-901700000010650:MSISDN-42342 + vlr_gsup_rx: now used by 2 (active-conn,vlr_gsup_rx)
+DVLR vlr_lu_fsm(IMSI-901700000010650:MSISDN-42342:UTRAN-Iu:LU){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES
+DVLR upd_hlr_vlr_fsm(IMSI-901700000010650:UTRAN-Iu:LU){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK
+DVLR upd_hlr_vlr_fsm(IMSI-901700000010650:UTRAN-Iu:LU){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE
+DVLR upd_hlr_vlr_fsm(IMSI-901700000010650:UTRAN-Iu:LU){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR upd_hlr_vlr_fsm(IMSI-901700000010650:UTRAN-Iu:LU){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(IMSI-901700000010650:MSISDN-42342:UTRAN-Iu:LU)
+DVLR vlr_lu_fsm(IMSI-901700000010650:MSISDN-42342:UTRAN-Iu:LU){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL
+DVLR vlr_lu_fsm(IMSI-901700000010650:MSISDN-42342:UTRAN-Iu:LU){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL
+DVLR lu_compl_vlr_fsm(IMSI-901700000010650:MSISDN-42342:UTRAN-Iu:LU){LU_COMPL_VLR_S_INIT}: Allocated
+DVLR lu_compl_vlr_fsm(IMSI-901700000010650:MSISDN-42342:UTRAN-Iu:LU){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(IMSI-901700000010650:MSISDN-42342:UTRAN-Iu:LU)
+DVLR lu_compl_vlr_fsm(IMSI-901700000010650:MSISDN-42342:UTRAN-Iu:LU){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START
+DVLR lu_compl_vlr_fsm(IMSI-901700000010650:MSISDN-42342:UTRAN-Iu:LU){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES
+DVLR lu_compl_vlr_fsm(IMSI-901700000010650:MSISDN-42342:UTRAN-Iu:LU){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL
+DVLR lu_compl_vlr_fsm(IMSI-901700000010650:MSISDN-42342:UTRAN-Iu:LU){LU_COMPL_VLR_S_WAIT_SUB_PRES}: lu_compl_vlr_new_tmsi()
+DVLR SUBSCR(IMSI-901700000010650:MSISDN-42342:TMSInew-0x03020100) VLR: update for IMSI=901700000010650 (MSISDN=42342)
+DVLR lu_compl_vlr_fsm(IMSI-901700000010650:MSISDN-42342:UTRAN-Iu:LU){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_WAIT_TMSI_CNF
+- sending LU Accept for IMSI-901700000010650:MSISDN-42342:TMSInew-0x03020100:UTRAN-Iu:LU, with TMSI 0x03020100
+DVLR upd_hlr_vlr_fsm(IMSI-901700000010650:UTRAN-Iu:LU){UPD_HLR_VLR_S_DONE}: Deallocated
+DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSInew-0x03020100 - vlr_gsup_rx: now used by 1 (active-conn)
+<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: vlr_gsupc_read_cb() returns 0
+ lu_result_sent == 1
+- a LU Accept with a new TMSI was sent, waiting for TMSI Realloc Compl
+ llist_count(&msub_list) == 1
+msc_a_is_accepted() == false
+ requests shall be thwarted
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSInew-0x03020100:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: RAN decode: DTAP
+DRLL msc_a(IMSI-901700000010650:MSISDN-42342:TMSInew-0x03020100:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: Dispatching 04.08 message: CC GSM48_MT_CC_SETUP
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSInew-0x03020100:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: Message not permitted for initial conn: GSM48_MT_CC_SETUP
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSInew-0x03020100:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: RAN decode error (rc=-13) for DTAP from MSC-I
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSInew-0x03020100:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: RAN decode: DTAP
+DRLL msc_a(IMSI-901700000010650:MSISDN-42342:TMSInew-0x03020100:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: Dispatching 04.08 message: MM unknown 0x33
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSInew-0x03020100:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: Message not permitted for initial conn: unknown 0x33
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSInew-0x03020100:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: RAN decode error (rc=-13) for DTAP from MSC-I
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSInew-0x03020100:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: RAN decode: DTAP
+DRLL msc_a(IMSI-901700000010650:MSISDN-42342:TMSInew-0x03020100:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: Dispatching 04.08 message: RR GSM48_MT_RR_SYSINFO_1
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSInew-0x03020100:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSInew-0x03020100:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: RAN decode error (rc=-13) for DTAP from MSC-I
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSInew-0x03020100:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: RAN decode: DTAP
+DRLL msc_a(IMSI-901700000010650:MSISDN-42342:TMSInew-0x03020100:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: Dispatching 04.08 message: SMS SMS:0x01
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSInew-0x03020100:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: Message not permitted for initial conn: SMS:0x01
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSInew-0x03020100:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: RAN decode error (rc=-13) for DTAP from MSC-I
+- even though the TMSI is not acked, we can already find the subscr with it
+DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSInew-0x03020100 + _test_umts_authen: now used by 2 (active-conn,_test_umts_authen)
+ vsub != NULL == 1
+ strcmp(vsub->imsi, imsi) == 0
+ vsub->tmsi_new == 0x03020100
+ vsub->tmsi == 0xffffffff
+DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSInew-0x03020100 - _test_umts_authen: now used by 1 (active-conn)
+- MS sends TMSI Realloc Complete
+ MSC <--UTRAN-Iu-- MS: GSM48_MT_MM_TMSI_REALL_COMPL
+DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSInew-0x03020100:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: + rx_from_ms: now used by 2 (lu,rx_from_ms)
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSInew-0x03020100:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: RAN decode: DTAP
+DRLL msc_a(IMSI-901700000010650:MSISDN-42342:TMSInew-0x03020100:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: Dispatching 04.08 message: MM GSM48_MT_MM_TMSI_REALL_COMPL
+DMM msc_a(IMSI-901700000010650:MSISDN-42342:TMSInew-0x03020100:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: TMSI Reallocation Completed
+DVLR vlr_lu_fsm(IMSI-901700000010650:MSISDN-42342:TMSInew-0x03020100:UTRAN-Iu:LU){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_NEW_TMSI_ACK
+DVLR lu_compl_vlr_fsm(IMSI-901700000010650:MSISDN-42342:UTRAN-Iu:LU){LU_COMPL_VLR_S_WAIT_TMSI_CNF}: Received Event LU_COMPL_VLR_E_NEW_TMSI_ACK
+DVLR SUBSCR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100) VLR: update for IMSI=901700000010650 (MSISDN=42342)
+DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + attached: now used by 2 (active-conn,attached)
+DVLR lu_compl_vlr_fsm(IMSI-901700000010650:MSISDN-42342:UTRAN-Iu:LU){LU_COMPL_VLR_S_WAIT_TMSI_CNF}: state_chg to LU_COMPL_VLR_S_DONE
+DVLR vlr_lu_fsm(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS
+DVLR lu_compl_vlr_fsm(IMSI-901700000010650:MSISDN-42342:UTRAN-Iu:LU){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR lu_compl_vlr_fsm(IMSI-901700000010650:MSISDN-42342:UTRAN-Iu:LU){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU)
+DVLR lu_compl_vlr_fsm(IMSI-901700000010650:MSISDN-42342:UTRAN-Iu:LU){LU_COMPL_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE
+DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: Received Event MSC_A_EV_AUTHENTICATED
+DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: state_chg to MSC_A_ST_AUTHENTICATED
+DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){MSC_A_ST_AUTHENTICATED}: - lu: now used by 1 (rx_from_ms)
+DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){MSC_A_ST_AUTHENTICATED}: - rx_from_ms: now used by 0 (-)
+DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){MSC_A_ST_AUTHENTICATED}: Received Event MSC_A_EV_UNUSED
+DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){MSC_A_ST_AUTHENTICATED}: state_chg to MSC_A_ST_RELEASING
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){MSC_A_ST_RELEASING}: Releasing: msc_a use is 0 (-)
+DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + msc_a_fsm_releasing_onenter: now used by 3 (active-conn,attached,msc_a_fsm_releasing_onenter)
+DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + vlr_subscr_cancel_attach_fsm: now used by 4 (active-conn,attached,msc_a_fsm_releasing_onenter,vlr_subscr_cancel_attach_fsm)
+DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - vlr_subscr_cancel_attach_fsm: now used by 3 (active-conn,attached,msc_a_fsm_releasing_onenter)
+DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){MSC_A_ST_RELEASING}: + wait-Clear-Complete: now used by 1 (wait-Clear-Complete)
+DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){MSC_A_ST_RELEASING}: RAN encode: CLEAR_COMMAND on UTRAN-Iu
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - msc_a_fsm_releasing_onenter: now used by 2 (active-conn,attached)
+ iu_release_sent == 1
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){MSC_A_ST_RELEASING}: RAN decode: CLEAR_COMPLETE
+DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){MSC_A_ST_RELEASING}: - wait-Clear-Complete: now used by 0 (-)
+DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){MSC_A_ST_RELEASING}: Received Event MSC_A_EV_UNUSED
+DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){MSC_A_ST_RELEASING}: state_chg to MSC_A_ST_RELEASED
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){MSC_A_ST_RELEASED}: Released: msc_a use is 0 (-)
+DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){MSC_A_ST_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR vlr_lu_fsm(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){VLR_ULA_S_DONE}: Terminating in cascade, depth 2 (cause = OSMO_FSM_TERM_PARENT, caused by: msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU))
+DVLR vlr_lu_fsm(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){VLR_ULA_S_DONE}: Removing from parent msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU)
+DVLR vlr_lu_fsm(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT
+DVLR vlr_lu_fsm(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){VLR_ULA_S_DONE}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU)
+DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){MSC_A_ST_RELEASED}: Removing from parent msub_fsm
+DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){MSC_A_ST_RELEASED}: max total use count was 3
+DMSC msub_fsm{active}: Received Event MSUB_EV_ROLE_TERMINATED
+DMSC msub(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100) MSC-A terminated
+DMSC msub(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100) 1 MSC-I still active
+DMSC msub_fsm{active}: state_chg to terminating
+DMSC msub_fsm{terminating}: Terminating in cascade, depth 2 (cause = OSMO_FSM_TERM_REGULAR, caused by: msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU))
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){0}: Terminating in cascade, depth 3 (cause = OSMO_FSM_TERM_PARENT, caused by: msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU))
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){0}: Removing from parent msub_fsm
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){0}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU)
+DMSC msub(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100) Free
+DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - active-conn: now used by 1 (attached)
+DMSC msub_fsm{terminating}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU)
+DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){MSC_A_ST_RELEASED}: Deallocated, including all deferred deallocations
+- msub gone
+- LU was successful, and the conn has already been closed
+ llist_count(&msub_list) == 0
+
+
+- after a while, a new conn sends a CM Service Request. VLR responds with Auth Req, 2nd auth vector
+ MSC <--UTRAN-Iu-- MS: GSM48_MT_MM_CM_SERV_REQ
+ new conn
+DMSC msub_fsm{active}: Allocated
+DMSC msc_a{MSC_A_ST_VALIDATE_L3}: Allocated
+DMSC msc_a{MSC_A_ST_VALIDATE_L3}: is child of msub_fsm
+DMSC msc_a(unknown:UTRAN-Iu:NONE){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_VALIDATE_L3
+DMSC dummy_msc_i{0}: Allocated
+DMSC dummy_msc_i{0}: is child of msub_fsm
+DREF msc_a(unknown:UTRAN-Iu:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms)
+DIUCS msc_a(unknown:UTRAN-Iu:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3
+DRLL msc_a(unknown:UTRAN-Iu:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: MM GSM48_MT_MM_CM_SERV_REQ
+DMM msc_a(IMSI-901700000010650:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_VALIDATE_L3}: Rx CM SERVICE REQUEST cm_service_type=Short-Messaging-Service
+DREF msc_a(IMSI-901700000010650:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_VALIDATE_L3}: + cm_service_sms: now used by 2 (rx_from_ms,cm_service_sms)
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:UTRAN-Iu:CM_SERVICE_REQ){PR_ARQ_S_INIT}: Allocated
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:UTRAN-Iu:CM_SERVICE_REQ){PR_ARQ_S_INIT}: is child of msc_a(IMSI-901700000010650:UTRAN-Iu:CM_SERVICE_REQ)
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:UTRAN-Iu:CM_SERVICE_REQ){PR_ARQ_S_INIT}: rev=R99 net=UTRAN Auth+Ciph
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:UTRAN-Iu:CM_SERVICE_REQ){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START
+DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + proc_arq_vlr_fn_init: now used by 2 (attached,proc_arq_vlr_fn_init)
+DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + active-conn: now used by 3 (attached,proc_arq_vlr_fn_init,active-conn)
+DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK
+DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi()
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_WAIT_AUTH
+DVLR VLR_Authenticate(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){VLR_SUB_AS_NEEDS_AUTH}: Allocated
+DVLR VLR_Authenticate(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){VLR_SUB_AS_NEEDS_AUTH}: is child of Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ)
+DVLR VLR_Authenticate(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
+DVLR VLR_Authenticate(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_WAIT_RESP
+DVLR VLR_Authenticate(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){VLR_SUB_AS_WAIT_RESP}: got auth tuple: use_count=1 key_seq=1 -- will use UMTS AKA (is_r99=yes, at->vec.auth_types=0x3)
+- sending UMTS Auth Request for IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ: tuple use_count=1 key_seq=1 auth_types=0x3 and...
+- ...rand=c187a53a5e6b9d573cac7c74451fd46d
+- ...autn=1843a645b98d00005b2d666af46c45d9
+- ...expecting res=7db47cf7f81e4dc7
+DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - proc_arq_vlr_fn_init: now used by 2 (attached,active-conn)
+DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (cm_service_sms)
+ cm_service_result_sent == 0
+ auth_request_sent == 1
+- needs auth, not yet accepted
+msc_a_is_accepted() == false
+ requests shall be thwarted
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN decode: DTAP
+DRLL msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: Dispatching 04.08 message: CC GSM48_MT_CC_SETUP
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: Message not permitted for initial conn: GSM48_MT_CC_SETUP
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN decode error (rc=-13) for DTAP from MSC-I
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN decode: DTAP
+DRLL msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: Dispatching 04.08 message: MM unknown 0x33
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: Message not permitted for initial conn: unknown 0x33
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN decode error (rc=-13) for DTAP from MSC-I
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN decode: DTAP
+DRLL msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: Dispatching 04.08 message: RR GSM48_MT_RR_SYSINFO_1
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN decode error (rc=-13) for DTAP from MSC-I
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN decode: DTAP
+DRLL msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: Dispatching 04.08 message: SMS SMS:0x01
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: Message not permitted for initial conn: SMS:0x01
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN decode error (rc=-13) for DTAP from MSC-I
+- Encryption enabled. MS sends Authen Response, VLR accepts and sends SecurityModeControl
+ MSC <--UTRAN-Iu-- MS: GSM48_MT_MM_AUTH_RESP
+DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: + rx_from_ms: now used by 2 (cm_service_sms,rx_from_ms)
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN decode: DTAP
+DRLL msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: Dispatching 04.08 message: MM GSM48_MT_MM_AUTH_RESP
+DMM msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: MM UMTS AUTHENTICATION RESPONSE (res = 7db47cf7f81e4dc7)
+DVLR VLR_Authenticate(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP
+DVLR SUBSCR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100) AUTH on UTRAN received RES: 7db47cf7f81e4dc7 (8 bytes)
+DVLR SUBSCR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100) AUTH established UMTS security context
+DVLR VLR_Authenticate(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result PASSED
+DVLR VLR_Authenticate(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
+DVLR VLR_Authenticate(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR VLR_Authenticate(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){VLR_SUB_AS_AUTHENTICATED}: Removing from parent Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ)
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: Received Event PR_ARQ_E_AUTH_RES
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2()
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: Set Ciphering Mode
+DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN encode: CIPHER_MODE_COMMAND on UTRAN-Iu
+- sending SecurityModeControl: ik=1159ec926a50e98c034a6b7d7c9f418d
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){PR_ARQ_S_WAIT_AUTH}: state_chg to PR_ARQ_S_WAIT_CIPH
+DVLR VLR_Authenticate(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){VLR_SUB_AS_AUTHENTICATED}: Deallocated
+DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (cm_service_sms)
+ security_mode_ctrl_sent == 1
+ cm_service_result_sent == 0
+- MS sends SecurityModeControl acceptance, VLR accepts; above Ciphering is an implicit CM Service Accept
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN decode: CIPHER_MODE_COMPLETE
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){PR_ARQ_S_WAIT_CIPH}: Received Event PR_ARQ_E_CIPH_RES
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_node2_post_ciph()
+DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on UTRAN-Iu
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_node2_post_vlr()
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_pres()
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_trace()
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_imei()
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){PR_ARQ_S_WAIT_CIPH}: proc_arq_fsm_done(PASSED)
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){PR_ARQ_S_WAIT_CIPH}: state_chg to PR_ARQ_S_DONE
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){PR_ARQ_S_DONE}: Process Access Request result: PASSED
+DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: Received Event MSC_A_EV_AUTHENTICATED
+DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_AUTH_CIPH}: state_chg to MSC_A_ST_AUTHENTICATED
+ cm_service_result_sent == 0
+- Concluding CM Service Request
+DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: - cm_service_sms: now used by 0 (-)
+DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: Received Event MSC_A_EV_UNUSED
+DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_AUTHENTICATED}: state_chg to MSC_A_ST_RELEASING
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: Releasing: msc_a use is 0 (-)
+DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + msc_a_fsm_releasing_onenter: now used by 3 (attached,active-conn,msc_a_fsm_releasing_onenter)
+DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,active-conn,msc_a_fsm_releasing_onenter,vlr_subscr_cancel_attach_fsm)
+DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,active-conn,msc_a_fsm_releasing_onenter)
+DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: + wait-Clear-Complete: now used by 1 (wait-Clear-Complete)
+DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: RAN encode: CLEAR_COMMAND on UTRAN-Iu
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - msc_a_fsm_releasing_onenter: now used by 2 (attached,active-conn)
+ iu_release_sent == 1
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: RAN decode: CLEAR_COMPLETE
+DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: - wait-Clear-Complete: now used by 0 (-)
+DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: Received Event MSC_A_EV_UNUSED
+DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_RELEASING}: state_chg to MSC_A_ST_RELEASED
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_RELEASED}: Released: msc_a use is 0 (-)
+DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){PR_ARQ_S_DONE}: Terminating in cascade, depth 2 (cause = OSMO_FSM_TERM_PARENT, caused by: msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ))
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){PR_ARQ_S_DONE}: Removing from parent msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ)
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){PR_ARQ_S_DONE}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ)
+DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_RELEASED}: Removing from parent msub_fsm
+DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_RELEASED}: max total use count was 2
+DMSC msub_fsm{active}: Received Event MSUB_EV_ROLE_TERMINATED
+DMSC msub(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100) MSC-A terminated
+DMSC msub(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100) 1 MSC-I still active
+DMSC msub_fsm{active}: state_chg to terminating
+DMSC msub_fsm{terminating}: Terminating in cascade, depth 2 (cause = OSMO_FSM_TERM_REGULAR, caused by: msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ))
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){0}: Terminating in cascade, depth 3 (cause = OSMO_FSM_TERM_PARENT, caused by: msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ))
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){0}: Removing from parent msub_fsm
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){0}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ)
+DMSC msub(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100) Free
+DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - active-conn: now used by 1 (attached)
+DMSC msub_fsm{terminating}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ)
+DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:CM_SERVICE_REQ){MSC_A_ST_RELEASED}: Deallocated, including all deferred deallocations
+- msub gone
+- all requests serviced, conn has been released
+ llist_count(&msub_list) == 0
+
+
+- an SMS is sent, MS is paged
+DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + _test_umts_authen: now used by 2 (attached,_test_umts_authen)
+ llist_count(&vsub->cs.requests) == 0
+DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + SMS-receiver: now used by 3 (attached,_test_umts_authen,SMS-receiver)
+DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + SMS: now used by 4 (attached,_test_umts_authen,SMS-receiver,SMS)
+DLSMS trans(SMS IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 callref-0x40000003 tid-0) New transaction
+DLSMS SMC(0) instance created for network
+DLSMS SMR(0) instance created for network.
+DLSMS trans(SMS IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 callref-0x40000003 tid-0) Going to send a MT SMS
+DLSMS SMR(0) message SM-RL-DATA_REQ received in state IDLE
+DLSMS SMR(0) TX SMS RP-DATA
+DLSMS SMR(0) new RP state IDLE -> WAIT_FOR_RP_ACK
+DLSMS SMC(0) message MNSMS-EST-REQ received in state IDLE
+DLSMS SMC(0) new CP state IDLE -> MM_CONN_PENDING
+DLSMS trans(SMS IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 callref-0x40000003 tid-0) Initiating Paging due to MMSMS_EST_REQ
+DPAG Paging: IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 for MT-SMS: Starting paging
+ paging request (SIGNALLING_LOW_PRIO) to IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 on UTRAN-Iu
+ strcmp(paging_expecting_imsi, vsub->imsi) == 0
+DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + Paging: now used by 5 (attached,_test_umts_authen,SMS-receiver,SMS,Paging)
+ llist_count(&vsub->cs.requests) == 1
+DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - _test_umts_authen: now used by 4 (attached,SMS-receiver,SMS,Paging)
+ paging_sent == 1
+- the subscriber and its pending request should remain
+DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + _test_umts_authen: now used by 5 (attached,SMS-receiver,SMS,Paging,_test_umts_authen)
+ llist_count(&vsub->cs.requests) == 1
+DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - _test_umts_authen: now used by 4 (attached,SMS-receiver,SMS,Paging)
+- MS replies with Paging Response, and VLR sends Auth Request with third key
+ MSC <--UTRAN-Iu-- MS: GSM48_MT_RR_PAG_RESP
+ new conn
+DMSC msub_fsm{active}: Allocated
+DMSC msc_a{MSC_A_ST_VALIDATE_L3}: Allocated
+DMSC msc_a{MSC_A_ST_VALIDATE_L3}: is child of msub_fsm
+DMSC msc_a(unknown:UTRAN-Iu:NONE){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_VALIDATE_L3
+DMSC dummy_msc_i{0}: Allocated
+DMSC dummy_msc_i{0}: is child of msub_fsm
+DREF msc_a(unknown:UTRAN-Iu:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms)
+DIUCS msc_a(unknown:UTRAN-Iu:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3
+DRLL msc_a(unknown:UTRAN-Iu:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: RR GSM48_MT_RR_PAG_RESP
+DRR msc_a(IMSI-901700000010650:UTRAN-Iu:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: Rx PAGING RESPONSE IMSI-901700000010650
+DREF msc_a(IMSI-901700000010650:UTRAN-Iu:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: + paging-response: now used by 2 (rx_from_ms,paging-response)
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:UTRAN-Iu:PAGING_RESP){PR_ARQ_S_INIT}: Allocated
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:UTRAN-Iu:PAGING_RESP){PR_ARQ_S_INIT}: is child of msc_a(IMSI-901700000010650:UTRAN-Iu:PAGING_RESP)
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:UTRAN-Iu:PAGING_RESP){PR_ARQ_S_INIT}: rev=R99 net=UTRAN Auth+Ciph
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:UTRAN-Iu:PAGING_RESP){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START
+DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + proc_arq_vlr_fn_init: now used by 5 (attached,SMS-receiver,SMS,Paging,proc_arq_vlr_fn_init)
+DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + active-conn: now used by 6 (attached,SMS-receiver,SMS,Paging,proc_arq_vlr_fn_init,active-conn)
+DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK
+DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi()
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_WAIT_AUTH
+DVLR VLR_Authenticate(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){VLR_SUB_AS_NEEDS_AUTH}: Allocated
+DVLR VLR_Authenticate(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){VLR_SUB_AS_NEEDS_AUTH}: is child of Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP)
+DVLR VLR_Authenticate(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
+DVLR VLR_Authenticate(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_WAIT_RESP
+DVLR VLR_Authenticate(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){VLR_SUB_AS_WAIT_RESP}: got auth tuple: use_count=1 key_seq=2 -- will use UMTS AKA (is_r99=yes, at->vec.auth_types=0x3)
+- sending UMTS Auth Request for IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP: tuple use_count=1 key_seq=2 auth_types=0x3 and...
+- ...rand=efa9c29a9742148d5c9070348716e1bb
+- ...autn=f9375e6d41e1000096e7fe4ff1c27e39
+- ...expecting res=706f996719ba609c
+DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - proc_arq_vlr_fn_init: now used by 5 (attached,SMS-receiver,SMS,Paging,active-conn)
+DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (paging-response)
+ auth_request_sent == 1
+- needs auth, not yet accepted
+msc_a_is_accepted() == false
+ requests shall be thwarted
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: RAN decode: DTAP
+DRLL msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: Dispatching 04.08 message: CC GSM48_MT_CC_SETUP
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: Message not permitted for initial conn: GSM48_MT_CC_SETUP
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: RAN decode error (rc=-13) for DTAP from MSC-I
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: RAN decode: DTAP
+DRLL msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: Dispatching 04.08 message: MM unknown 0x33
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: Message not permitted for initial conn: unknown 0x33
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: RAN decode error (rc=-13) for DTAP from MSC-I
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: RAN decode: DTAP
+DRLL msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: Dispatching 04.08 message: RR GSM48_MT_RR_SYSINFO_1
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: RAN decode error (rc=-13) for DTAP from MSC-I
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: RAN decode: DTAP
+DRLL msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: Dispatching 04.08 message: SMS SMS:0x01
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: Message not permitted for initial conn: SMS:0x01
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: RAN decode error (rc=-13) for DTAP from MSC-I
+- Encryption enabled. MS sends Authen Response, VLR accepts and sends SecurityModeControl
+ MSC <--UTRAN-Iu-- MS: GSM48_MT_MM_AUTH_RESP
+DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: + rx_from_ms: now used by 2 (paging-response,rx_from_ms)
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: RAN decode: DTAP
+DRLL msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: Dispatching 04.08 message: MM GSM48_MT_MM_AUTH_RESP
+DMM msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: MM UMTS AUTHENTICATION RESPONSE (res = 706f996719ba609c)
+DVLR VLR_Authenticate(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP
+DVLR SUBSCR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100) AUTH on UTRAN received RES: 706f996719ba609c (8 bytes)
+DVLR SUBSCR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100) AUTH established UMTS security context
+DVLR VLR_Authenticate(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result PASSED
+DVLR VLR_Authenticate(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
+DVLR VLR_Authenticate(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR VLR_Authenticate(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){VLR_SUB_AS_AUTHENTICATED}: Removing from parent Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP)
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){PR_ARQ_S_WAIT_AUTH}: Received Event PR_ARQ_E_AUTH_RES
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2()
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){PR_ARQ_S_WAIT_AUTH}: Set Ciphering Mode
+DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: RAN encode: CIPHER_MODE_COMMAND on UTRAN-Iu
+- sending SecurityModeControl: ik=eb50e770ddcc3060101d2f43b6c2b884
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){PR_ARQ_S_WAIT_AUTH}: state_chg to PR_ARQ_S_WAIT_CIPH
+DVLR VLR_Authenticate(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){VLR_SUB_AS_AUTHENTICATED}: Deallocated
+DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (paging-response)
+ security_mode_ctrl_sent == 1
+- MS sends SecurityModeControl acceptance, VLR accepts and sends SMS
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: RAN decode: CIPHER_MODE_COMPLETE
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){PR_ARQ_S_WAIT_CIPH}: Received Event PR_ARQ_E_CIPH_RES
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_node2_post_ciph()
+DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on UTRAN-Iu
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_node2_post_vlr()
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_pres()
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_trace()
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_imei()
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){PR_ARQ_S_WAIT_CIPH}: proc_arq_fsm_done(PASSED)
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){PR_ARQ_S_WAIT_CIPH}: state_chg to PR_ARQ_S_DONE
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){PR_ARQ_S_DONE}: Process Access Request result: PASSED
+DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: Received Event MSC_A_EV_AUTHENTICATED
+DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTH_CIPH}: state_chg to MSC_A_ST_AUTHENTICATED
+DPAG Paging: IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 for MT-SMS: Paging Response action (success)
+DPAG Paging: IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 for MT-SMS: Removing Paging Request
+DLSMS trans(SMS IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 callref-0x40000003 tid-0) mmsms_paging_cb(success)
+DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: + sms: now used by 2 (paging-response,sms)
+DLSMS SMC(0) message MMSMS-EST-CNF received in state MM_CONN_PENDING
+DLSMS SMC(0) send CP data
+DLSMS SMC(0) new CP state MM_CONN_PENDING -> WAIT_CP_ACK
+DLSMS trans(SMS IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x40000003 tid-0) sending CP message (trans=0)
+DLSMS trans(SMS IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x40000003 tid-0) GSM4.11 TX 09 01 58 01 00 07 91 44 77 58 10 06 50 00 4c 00 05 80 24 43 f2 00 00 07 10 10 00 00 00 00 44 50 79 da 1e 1e e7 41 69 37 48 5e 9e a7 c9 65 37 3d 1d 66 83 c2 70 38 3b 3d 0e d3 d3 6f f7 1c 94 9e 83 c2 20 72 79 9e 96 87 c5 ec 32 a8 1d 96 af cb f4 b4 fb 0c 7a c3 e9 e9 b7 db 05
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: Sending DTAP: SMS SMS:0x01
+DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: RAN encode: DTAP on UTRAN-Iu
+- DTAP --UTRAN-Iu--> MS: SMS:0x01: 09015801000791447758100650004c0005802443f2000007101000000000445079da1e1ee7416937485e9ea7c965373d1d6683c270383b3d0ed3d36ff71c949e83c22072799e9687c5ec32a81d96afcbf4b4fb0c7ac3e9e9b7db05
+- DTAP matches expected message
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - Paging: now used by 4 (attached,SMS-receiver,SMS,active-conn)
+DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: - paging-response: now used by 1 (sms)
+- SMS was delivered, no requests pending for subscr
+DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + _test_umts_authen: now used by 5 (attached,SMS-receiver,SMS,active-conn,_test_umts_authen)
+ llist_count(&vsub->cs.requests) == 0
+DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - _test_umts_authen: now used by 4 (attached,SMS-receiver,SMS,active-conn)
+- conn is still open to wait for SMS ack dance
+ llist_count(&msub_list) == 1
+- MS replies with CP-ACK for received SMS
+ MSC <--UTRAN-Iu-- MS: SMS:0x04
+DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: + rx_from_ms: now used by 2 (sms,rx_from_ms)
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: RAN decode: DTAP
+DRLL msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: Dispatching 04.08 message: SMS SMS:0x04
+DLSMS trans(SMS IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x40000003 tid-0) receiving SMS message SMS:0x04
+DLSMS SMC(0) message MMSMS-DATA-IND (CP ACK) received in state WAIT_CP_ACK
+DLSMS SMC(0) received CP-ACK
+DLSMS SMC(0) new CP state WAIT_CP_ACK -> MM_ESTABLISHED
+DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: - rx_from_ms: now used by 1 (sms)
+ llist_count(&msub_list) == 1
+- MS also sends RP-ACK, MSC in turn sends CP-ACK for that
+ MSC <--UTRAN-Iu-- MS: SMS:0x01
+DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: + rx_from_ms: now used by 2 (sms,rx_from_ms)
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: RAN decode: DTAP
+DRLL msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: Dispatching 04.08 message: SMS SMS:0x01
+DLSMS trans(SMS IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x40000003 tid-0) receiving SMS message SMS:0x01
+DLSMS SMC(0) message MMSMS-DATA-IND (CP DATA) received in state MM_ESTABLISHED
+DLSMS SMC(0) received CP-DATA
+DLSMS trans(SMS IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x40000003 tid-0) sending CP message (trans=0)
+DLSMS trans(SMS IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x40000003 tid-0) GSM4.11 TX 09 04
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: Sending DTAP: SMS SMS:0x04
+DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: RAN encode: DTAP on UTRAN-Iu
+- DTAP --UTRAN-Iu--> MS: SMS:0x04: 0904
+- DTAP matches expected message
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+DLSMS trans(SMS IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x40000003 tid-0) MNSMS-DATA/EST-IND
+DLSMS SMR(0) message MNSMS-DATA-IND received in state WAIT_FOR_RP_ACK
+DLSMS SMR(0) RX SMS RP-ACK
+DLSMS SMR(0) new RP state WAIT_FOR_RP_ACK -> IDLE
+DLSMS trans(SMS IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x40000003 tid-0) RX SMS RP-ACK (MO)
+DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - SMS-receiver: now used by 3 (attached,SMS,active-conn)
+DLSMS SMR(0) TX: MNSMS-REL-REQ
+DLSMS SMC(0) message MNSMS-REL-REQ received in state MM_ESTABLISHED
+DLSMS SMC(0) new CP state MM_ESTABLISHED -> IDLE
+DLSMS trans(SMS IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x40000003 tid-0) Got MMSMS_REL_REQ, destroying transaction.
+DLSMS trans(SMS IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP callref-0x40000003 tid-0) Freeing transaction
+DLSMS SMR(0) clearing SMR instance
+DLSMS SMC(0) clearing instance
+DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - SMS: now used by 2 (attached,active-conn)
+DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: - sms: now used by 1 (rx_from_ms)
+DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: - rx_from_ms: now used by 0 (-)
+DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: Received Event MSC_A_EV_UNUSED
+DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_AUTHENTICATED}: state_chg to MSC_A_ST_RELEASING
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_RELEASING}: Releasing: msc_a use is 0 (-)
+DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + msc_a_fsm_releasing_onenter: now used by 3 (attached,active-conn,msc_a_fsm_releasing_onenter)
+DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,active-conn,msc_a_fsm_releasing_onenter,vlr_subscr_cancel_attach_fsm)
+DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,active-conn,msc_a_fsm_releasing_onenter)
+DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_RELEASING}: + wait-Clear-Complete: now used by 1 (wait-Clear-Complete)
+DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_RELEASING}: RAN encode: CLEAR_COMMAND on UTRAN-Iu
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - msc_a_fsm_releasing_onenter: now used by 2 (attached,active-conn)
+ dtap_tx_confirmed == 1
+ iu_release_sent == 1
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_RELEASING}: RAN decode: CLEAR_COMPLETE
+DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_RELEASING}: - wait-Clear-Complete: now used by 0 (-)
+DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_RELEASING}: Received Event MSC_A_EV_UNUSED
+DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_RELEASING}: state_chg to MSC_A_ST_RELEASED
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_RELEASED}: Released: msc_a use is 0 (-)
+DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){PR_ARQ_S_DONE}: Terminating in cascade, depth 2 (cause = OSMO_FSM_TERM_PARENT, caused by: msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP))
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){PR_ARQ_S_DONE}: Removing from parent msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP)
+DVLR Process_Access_Request_VLR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){PR_ARQ_S_DONE}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP)
+DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_RELEASED}: Removing from parent msub_fsm
+DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_RELEASED}: max total use count was 2
+DMSC msub_fsm{active}: Received Event MSUB_EV_ROLE_TERMINATED
+DMSC msub(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100) MSC-A terminated
+DMSC msub(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100) 1 MSC-I still active
+DMSC msub_fsm{active}: state_chg to terminating
+DMSC msub_fsm{terminating}: Terminating in cascade, depth 2 (cause = OSMO_FSM_TERM_REGULAR, caused by: msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP))
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){0}: Terminating in cascade, depth 3 (cause = OSMO_FSM_TERM_PARENT, caused by: msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP))
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){0}: Removing from parent msub_fsm
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){0}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP)
+DMSC msub(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100) Free
+DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - active-conn: now used by 1 (attached)
+DMSC msub_fsm{terminating}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP)
+DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:PAGING_RESP){MSC_A_ST_RELEASED}: Deallocated, including all deferred deallocations
+- msub gone
+- SMS is done, conn is gone
+ llist_count(&msub_list) == 0
+
+
+- subscriber detaches
+ MSC <--UTRAN-Iu-- MS: GSM48_MT_MM_IMSI_DETACH_IND
+ new conn
+DMSC msub_fsm{active}: Allocated
+DMSC msc_a{MSC_A_ST_VALIDATE_L3}: Allocated
+DMSC msc_a{MSC_A_ST_VALIDATE_L3}: is child of msub_fsm
+DMSC msc_a(unknown:UTRAN-Iu:NONE){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_VALIDATE_L3
+DMSC dummy_msc_i{0}: Allocated
+DMSC dummy_msc_i{0}: is child of msub_fsm
+DREF msc_a(unknown:UTRAN-Iu:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms)
+DIUCS msc_a(unknown:UTRAN-Iu:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3
+DRLL msc_a(unknown:UTRAN-Iu:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: MM GSM48_MT_MM_IMSI_DETACH_IND
+DMM IMSI DETACH INDICATION: IMSI-901700000010650
+DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + gsm48_rx_mm_imsi_detach_ind: now used by 2 (attached,gsm48_rx_mm_imsi_detach_ind)
+DMM IMSI DETACH for IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100
+DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + active-conn: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn)
+DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + vlr_subscr_cancel_attach_fsm: now used by 4 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn,vlr_subscr_cancel_attach_fsm)
+DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - vlr_subscr_cancel_attach_fsm: now used by 3 (attached,gsm48_rx_mm_imsi_detach_ind,active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
+DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - attached: now used by 2 (gsm48_rx_mm_imsi_detach_ind,active-conn)
+DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - gsm48_rx_mm_imsi_detach_ind: now used by 1 (active-conn)
+DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:NONE){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_CN_CLOSE
+DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:NONE){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_RELEASING
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:NONE){MSC_A_ST_RELEASING}: Releasing: msc_a use is 1 (rx_from_ms)
+DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + msc_a_fsm_releasing_onenter: now used by 2 (active-conn,msc_a_fsm_releasing_onenter)
+DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + vlr_subscr_cancel_attach_fsm: now used by 3 (active-conn,msc_a_fsm_releasing_onenter,vlr_subscr_cancel_attach_fsm)
+DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - vlr_subscr_cancel_attach_fsm: now used by 2 (active-conn,msc_a_fsm_releasing_onenter)
+DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:NONE){MSC_A_ST_RELEASING}: + wait-Clear-Complete: now used by 2 (rx_from_ms,wait-Clear-Complete)
+DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:NONE){MSC_A_ST_RELEASING}: RAN encode: CLEAR_COMMAND on UTRAN-Iu
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:NONE){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - msc_a_fsm_releasing_onenter: now used by 1 (active-conn)
+DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:NONE){MSC_A_ST_RELEASING}: - rx_from_ms: now used by 1 (wait-Clear-Complete)
+ iu_release_sent == 1
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:NONE){MSC_A_ST_RELEASING}: RAN decode: CLEAR_COMPLETE
+DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:NONE){MSC_A_ST_RELEASING}: - wait-Clear-Complete: now used by 0 (-)
+DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:NONE){MSC_A_ST_RELEASING}: Received Event MSC_A_EV_UNUSED
+DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:NONE){MSC_A_ST_RELEASING}: state_chg to MSC_A_ST_RELEASED
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:NONE){MSC_A_ST_RELEASED}: Released: msc_a use is 0 (-)
+DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:NONE){MSC_A_ST_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:NONE){MSC_A_ST_RELEASED}: Removing from parent msub_fsm
+DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:NONE){MSC_A_ST_RELEASED}: max total use count was 2
+DMSC msub_fsm{active}: Received Event MSUB_EV_ROLE_TERMINATED
+DMSC msub(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100) MSC-A terminated
+DMSC msub(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100) 1 MSC-I still active
+DMSC msub_fsm{active}: state_chg to terminating
+DMSC msub_fsm{terminating}: Terminating in cascade, depth 2 (cause = OSMO_FSM_TERM_REGULAR, caused by: msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:NONE))
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:NONE){0}: Terminating in cascade, depth 3 (cause = OSMO_FSM_TERM_PARENT, caused by: msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:NONE))
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:NONE){0}: Removing from parent msub_fsm
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:NONE){0}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:NONE)
+DMSC msub(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100) Free
+DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - active-conn: now used by 0 (-)
+DVLR freeing VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 (max total use count was 6)
+DMSC msub_fsm{terminating}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:NONE)
+DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:NONE){MSC_A_ST_RELEASED}: Deallocated, including all deferred deallocations
+- msub gone
+ llist_count(&msub_list) == 0
+===== test_umts_auth_ciph_utran: SUCCESS
===== test_umts_authen_resync_geran
- Location Update request causes a GSUP Send Auth Info request to HLR
@@ -1259,13 +1895,14 @@ DREF VLR subscr IMSI-901700000010650 + active-conn: now used by 2 (_lu_fsm_assoc
DMSC msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK
DMSC msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH
DREF VLR subscr IMSI-901700000010650 - _lu_fsm_associate_vsub: now used by 1 (active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre()
DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH
DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Allocated
DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU)
DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
-GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f00a0101
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f02801020a0101
DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
DREF msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - mm_rx_loc_upd_req: now used by 2 (rx_from_ms,lu)
DREF msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu)
@@ -1292,7 +1929,7 @@ DBSSAP msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN decode: D
DRLL msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: Dispatching 04.08 message: MM GSM48_MT_MM_AUTH_FAIL
DMM msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: MM R99 AUTHENTICATION SYNCH (AUTS = 979498b1f72d3e28c59fa2e72f9c)
DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_FAIL
-GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f0260e979498b1f72d3e28c59fa2e72f9c201039fa2f4e3d523d8619a73b4f65c3e14d0a0101
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f0260e979498b1f72d3e28c59fa2e72f9c201039fa2f4e3d523d8619a73b4f65c3e14d2801020a0101
DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_SAI_RESYNC
DREF msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu)
gsup_tx_confirmed == 1
@@ -1313,7 +1950,7 @@ DREF VLR subscr IMSI-901700000010650 - vlr_gsup_rx: now used by 1 (active-conn)
<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT: vlr_gsupc_read_cb() returns 0
auth_request_sent == 1
lu_result_sent == 0
-- MS sends Authen Response, VLR accepts and sends GSUP LU Req to HLR
+- Encryption disabled. MS sends Authen Response, VLR accepts and sends GSUP LU Req to HLR
MSC <--GERAN-A-- MS: GSM48_MT_MM_AUTH_RESP
DREF msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: + rx_from_ms: now used by 2 (lu,rx_from_ms)
DBSSAP msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN decode: DTAP
@@ -1326,9 +1963,11 @@ DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP_RESY
DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP_RESYNC}: state_chg to VLR_SUB_AS_AUTHENTICATED
DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU)
-DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES
+DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_SUCCESS
DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth()
DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_ciph()
+DMSC msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on GERAN-A
+DMSC dummy_msc_i(IMSI-901700000010650:GERAN-A:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_node_4()
DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
DVLR upd_hlr_vlr_fsm(IMSI-901700000010650:GERAN-A:LU){UPD_HLR_VLR_S_INIT}: Allocated
@@ -1460,9 +2099,6 @@ DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:GERAN-A:LU){MSC_A_S
DVLR freeing VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 (max total use count was 4)
===== test_umts_authen_resync_geran: SUCCESS
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 17
-
===== test_umts_authen_resync_utran
- Location Update request causes a GSUP Send Auth Info request to HLR
MSC <--UTRAN-Iu-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
@@ -1482,7 +2118,7 @@ DREF msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_VALIDATE_L3}: + mm_rx_loc_
DREF msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_VALIDATE_L3}: + lu: now used by 3 (rx_from_ms,mm_rx_loc_upd_req,lu)
DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: Allocated
DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: is child of msc_a(IMSI-901700000010650:UTRAN-Iu:LU)
-DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: rev=R99 net=UTRAN Auth+Ciph
+DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: rev=R99 net=UTRAN Auth (no Ciph)
DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA
DREF VLR subscr unknown + _lu_fsm_associate_vsub: now used by 1 (_lu_fsm_associate_vsub)
DVLR set IMSI on subscriber; IMSI=901700000010650 id=901700000010650
@@ -1491,13 +2127,14 @@ DREF VLR subscr IMSI-901700000010650 + active-conn: now used by 2 (_lu_fsm_assoc
DMSC msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK
DMSC msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH
DREF VLR subscr IMSI-901700000010650 - _lu_fsm_associate_vsub: now used by 1 (active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre()
DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH
DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: Allocated
DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU)
DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
-GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f00a0101
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f02801020a0101
DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
DREF msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: - mm_rx_loc_upd_req: now used by 2 (rx_from_ms,lu)
DREF msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu)
@@ -1524,7 +2161,7 @@ DIUCS msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: RAN decode: D
DRLL msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: Dispatching 04.08 message: MM GSM48_MT_MM_AUTH_FAIL
DMM msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: MM R99 AUTHENTICATION SYNCH (AUTS = 979498b1f72d3e28c59fa2e72f9c)
DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_FAIL
-GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f0260e979498b1f72d3e28c59fa2e72f9c201039fa2f4e3d523d8619a73b4f65c3e14d0a0101
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f0260e979498b1f72d3e28c59fa2e72f9c201039fa2f4e3d523d8619a73b4f65c3e14d2801020a0101
DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_SAI_RESYNC
DREF msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu)
gsup_tx_confirmed == 1
@@ -1545,7 +2182,7 @@ DREF VLR subscr IMSI-901700000010650 - vlr_gsup_rx: now used by 1 (active-conn)
<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT: vlr_gsupc_read_cb() returns 0
auth_request_sent == 1
lu_result_sent == 0
-- MS sends Authen Response, VLR accepts and sends SecurityModeControl
+- Encryption disabled. MS sends Authen Response, VLR accepts and sends SecurityModeControl
MSC <--UTRAN-Iu-- MS: GSM48_MT_MM_AUTH_RESP
DREF msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: + rx_from_ms: now used by 2 (lu,rx_from_ms)
DIUCS msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: RAN decode: DTAP
@@ -1558,7 +2195,7 @@ DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_WAIT_RESP_RES
DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_WAIT_RESP_RESYNC}: state_chg to VLR_SUB_AS_AUTHENTICATED
DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU)
-DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES
+DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_SUCCESS
DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth()
DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: Set Ciphering Mode
DMSC msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: CIPHER_MODE_COMMAND on UTRAN-Iu
@@ -1704,8 +2341,247 @@ DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){MSC_A_
DVLR freeing VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 (max total use count was 4)
===== test_umts_authen_resync_utran: SUCCESS
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 17
+===== test_umts_auth_ciph_resync_utran
+- Location Update request causes a GSUP Send Auth Info request to HLR
+ MSC <--UTRAN-Iu-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
+ new conn
+DMSC msub_fsm{active}: Allocated
+DMSC msc_a{MSC_A_ST_VALIDATE_L3}: Allocated
+DMSC msc_a{MSC_A_ST_VALIDATE_L3}: is child of msub_fsm
+DMSC msc_a(unknown:UTRAN-Iu:NONE){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_VALIDATE_L3
+DMSC dummy_msc_i{0}: Allocated
+DMSC dummy_msc_i{0}: is child of msub_fsm
+DREF msc_a(unknown:UTRAN-Iu:NONE){MSC_A_ST_VALIDATE_L3}: + rx_from_ms: now used by 1 (rx_from_ms)
+DIUCS msc_a(unknown:UTRAN-Iu:NONE){MSC_A_ST_VALIDATE_L3}: RAN decode: COMPL_L3
+DRLL msc_a(unknown:UTRAN-Iu:NONE){MSC_A_ST_VALIDATE_L3}: Dispatching 04.08 message: MM GSM48_MT_MM_LOC_UPD_REQUEST
+DMM msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_VALIDATE_L3}: LOCATION UPDATING REQUEST: MI=IMSI-901700000010650 LU-type=NORMAL
+DMM msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_VALIDATE_L3}: USIM: old LAI: 1665-165-0
+DREF msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_VALIDATE_L3}: + mm_rx_loc_upd_req: now used by 2 (rx_from_ms,mm_rx_loc_upd_req)
+DREF msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_VALIDATE_L3}: + lu: now used by 3 (rx_from_ms,mm_rx_loc_upd_req,lu)
+DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: Allocated
+DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: is child of msc_a(IMSI-901700000010650:UTRAN-Iu:LU)
+DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: rev=R99 net=UTRAN Auth+Ciph
+DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA
+DREF VLR subscr unknown + _lu_fsm_associate_vsub: now used by 1 (_lu_fsm_associate_vsub)
+DVLR set IMSI on subscriber; IMSI=901700000010650 id=901700000010650
+DVLR New subscr, IMSI: 901700000010650
+DREF VLR subscr IMSI-901700000010650 + active-conn: now used by 2 (_lu_fsm_associate_vsub,active-conn)
+DMSC msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK
+DMSC msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH
+DREF VLR subscr IMSI-901700000010650 - _lu_fsm_associate_vsub: now used by 1 (active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
+DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre()
+DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
+DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH
+DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: Allocated
+DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU)
+DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f02801020a0101
+DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
+DREF msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: - mm_rx_loc_upd_req: now used by 2 (rx_from_ms,lu)
+DREF msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu)
+ lu_result_sent == 0
+- from HLR, rx _SEND_AUTH_INFO_RESULT; VLR sends Auth Req to MS
+<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT: 0a010809710000000156f00362201039fa2f4e3d523d8619a73b4f65c3e14d21049b36efdf2208059a4f668f6fbe39231027497388b6cb044648f396aa155b95ef2410f64735036e5871319c679f4742a75ea125108704f5ba55f30000d2ee44b22c8ea9192708e229c19e791f2e410a0101
+DREF VLR subscr IMSI-901700000010650 + vlr_gsup_rx: now used by 2 (active-conn,vlr_gsup_rx)
+DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: Received Event VLR_AUTH_E_HLR_SAI_ACK
+DVLR SUBSCR(IMSI-901700000010650) Received 1 auth tuples
+DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: state_chg to VLR_SUB_AS_WAIT_RESP
+DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_WAIT_RESP}: got auth tuple: use_count=1 key_seq=0 -- will use UMTS AKA (is_r99=yes, at->vec.auth_types=0x3)
+- sending UMTS Auth Request for IMSI-901700000010650:UTRAN-Iu:LU: tuple use_count=1 key_seq=0 auth_types=0x3 and...
+- ...rand=39fa2f4e3d523d8619a73b4f65c3e14d
+- ...autn=8704f5ba55f30000d2ee44b22c8ea919
+- ...expecting res=e229c19e791f2e41
+DREF VLR subscr IMSI-901700000010650 - vlr_gsup_rx: now used by 1 (active-conn)
+<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT: vlr_gsupc_read_cb() returns 0
+ auth_request_sent == 1
+ lu_result_sent == 0
+- MS sends Authen Failure with Resync cause, VLR sends GSUP to HLR to resync
+ MSC <--UTRAN-Iu-- MS: GSM48_MT_MM_AUTH_FAIL
+DREF msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: + rx_from_ms: now used by 2 (lu,rx_from_ms)
+DIUCS msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: RAN decode: DTAP
+DRLL msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: Dispatching 04.08 message: MM GSM48_MT_MM_AUTH_FAIL
+DMM msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: MM R99 AUTHENTICATION SYNCH (AUTS = 979498b1f72d3e28c59fa2e72f9c)
+DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_FAIL
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f0260e979498b1f72d3e28c59fa2e72f9c201039fa2f4e3d523d8619a73b4f65c3e14d2801020a0101
+DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_SAI_RESYNC
+DREF msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu)
+ gsup_tx_confirmed == 1
+ auth_request_sent == 0
+ lu_result_sent == 0
+- HLR replies with new tuples
+<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT: 0a010809710000000156f0036220100f1feb1623e1bf626334e37ec448ac182104efde99da220814778c855c52373023108a90c769b7272f3bb7a1c1fbb1ea9349241043ffc1cf8c89a7fd6ab94bd8d6162cbf251002a83f62e9470000660d51afc75f169d27081df5f0b4f22b696e03622010ac21d34937b4e1142a2c757af294931921047818bfdc2208d175571f41f314a42310ff8edbceb6dd24799c77c3b9a6790c102410157c39022ca9d885a7f0766a7dfee44825108a43b91898e500002cf354c6f5d1f8c32708f748a7078f5018db0a0101
+DREF VLR subscr IMSI-901700000010650 + vlr_gsup_rx: now used by 2 (active-conn,vlr_gsup_rx)
+DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH_WAIT_SAI_RESYNC}: Received Event VLR_AUTH_E_HLR_SAI_ACK
+DVLR SUBSCR(IMSI-901700000010650) Received 2 auth tuples
+DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH_WAIT_SAI_RESYNC}: state_chg to VLR_SUB_AS_WAIT_RESP_RESYNC
+DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_WAIT_RESP_RESYNC}: got auth tuple: use_count=1 key_seq=0 -- will use UMTS AKA (is_r99=yes, at->vec.auth_types=0x3)
+- sending UMTS Auth Request for IMSI-901700000010650:UTRAN-Iu:LU: tuple use_count=1 key_seq=0 auth_types=0x3 and...
+- ...rand=0f1feb1623e1bf626334e37ec448ac18
+- ...autn=02a83f62e9470000660d51afc75f169d
+- ...expecting res=1df5f0b4f22b696e
+DREF VLR subscr IMSI-901700000010650 - vlr_gsup_rx: now used by 1 (active-conn)
+<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT: vlr_gsupc_read_cb() returns 0
+ auth_request_sent == 1
+ lu_result_sent == 0
+- Encryption enabled. MS sends Authen Response, VLR accepts and sends SecurityModeControl
+ MSC <--UTRAN-Iu-- MS: GSM48_MT_MM_AUTH_RESP
+DREF msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: + rx_from_ms: now used by 2 (lu,rx_from_ms)
+DIUCS msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: RAN decode: DTAP
+DRLL msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: Dispatching 04.08 message: MM GSM48_MT_MM_AUTH_RESP
+DMM msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: MM UMTS AUTHENTICATION RESPONSE (res = 1df5f0b4f22b696e)
+DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_WAIT_RESP_RESYNC}: Received Event VLR_AUTH_E_MS_AUTH_RESP
+DVLR SUBSCR(IMSI-901700000010650) AUTH on UTRAN received RES: 1df5f0b4f22b696e (8 bytes)
+DVLR SUBSCR(IMSI-901700000010650) AUTH established UMTS security context
+DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_WAIT_RESP_RESYNC}: Authentication terminating with result PASSED
+DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_WAIT_RESP_RESYNC}: state_chg to VLR_SUB_AS_AUTHENTICATED
+DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU)
+DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_SUCCESS
+DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth()
+DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: Set Ciphering Mode
+DMSC msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: CIPHER_MODE_COMMAND on UTRAN-Iu
+- sending SecurityModeControl: ik=8a90c769b7272f3bb7a1c1fbb1ea9349
+DMSC dummy_msc_i(IMSI-901700000010650:UTRAN-Iu:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_WAIT_CIPH
+DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_AUTHENTICATED}: Deallocated
+DREF msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu)
+ security_mode_ctrl_sent == 1
+ lu_result_sent == 0
+- MS sends SecurityModeControl acceptance, VLR accepts and sends GSUP LU Req to HLR
+DIUCS msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: RAN decode: CIPHER_MODE_COMPLETE
+DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_CIPH}: Received Event VLR_ULA_E_CIPH_RES
+DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_CIPH}: vlr_loc_upd_post_ciph()
+DMSC msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: RAN encode: COMMON_ID on UTRAN-Iu
+DMSC dummy_msc_i(IMSI-901700000010650:UTRAN-Iu:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_CIPH}: vlr_loc_upd_node_4()
+DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_CIPH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
+DVLR upd_hlr_vlr_fsm(IMSI-901700000010650:UTRAN-Iu:LU){UPD_HLR_VLR_S_INIT}: Allocated
+DVLR upd_hlr_vlr_fsm(IMSI-901700000010650:UTRAN-Iu:LU){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU)
+DVLR upd_hlr_vlr_fsm(IMSI-901700000010650:UTRAN-Iu:LU){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START
+GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000000156f02801020a0101
+DVLR upd_hlr_vlr_fsm(IMSI-901700000010650:UTRAN-Iu:LU){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA
+ gsup_tx_confirmed == 1
+ lu_result_sent == 0
+- HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT
+<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: 10010809710000000156f00804032443f20a0101
+DREF VLR subscr IMSI-901700000010650 + vlr_gsup_rx: now used by 2 (active-conn,vlr_gsup_rx)
+DVLR IMSI:901700000010650 has MSISDN:42342
+DVLR SUBSCR(IMSI-901700000010650:MSISDN-42342) VLR: update for IMSI=901700000010650 (MSISDN=42342)
+GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000000156f00a0101
+DREF VLR subscr IMSI-901700000010650:MSISDN-42342 - vlr_gsup_rx: now used by 1 (active-conn)
+<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: vlr_gsupc_read_cb() returns 0
+ lu_result_sent == 0
+- HLR also sends GSUP _UPDATE_LOCATION_RESULT
+<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: 06010809710000000156f00a0101
+DREF VLR subscr IMSI-901700000010650:MSISDN-42342 + vlr_gsup_rx: now used by 2 (active-conn,vlr_gsup_rx)
+DVLR vlr_lu_fsm(IMSI-901700000010650:MSISDN-42342:UTRAN-Iu:LU){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES
+DVLR upd_hlr_vlr_fsm(IMSI-901700000010650:UTRAN-Iu:LU){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK
+DVLR upd_hlr_vlr_fsm(IMSI-901700000010650:UTRAN-Iu:LU){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE
+DVLR upd_hlr_vlr_fsm(IMSI-901700000010650:UTRAN-Iu:LU){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR upd_hlr_vlr_fsm(IMSI-901700000010650:UTRAN-Iu:LU){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(IMSI-901700000010650:MSISDN-42342:UTRAN-Iu:LU)
+DVLR vlr_lu_fsm(IMSI-901700000010650:MSISDN-42342:UTRAN-Iu:LU){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL
+DVLR vlr_lu_fsm(IMSI-901700000010650:MSISDN-42342:UTRAN-Iu:LU){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL
+DVLR lu_compl_vlr_fsm(IMSI-901700000010650:MSISDN-42342:UTRAN-Iu:LU){LU_COMPL_VLR_S_INIT}: Allocated
+DVLR lu_compl_vlr_fsm(IMSI-901700000010650:MSISDN-42342:UTRAN-Iu:LU){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(IMSI-901700000010650:MSISDN-42342:UTRAN-Iu:LU)
+DVLR lu_compl_vlr_fsm(IMSI-901700000010650:MSISDN-42342:UTRAN-Iu:LU){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START
+DVLR lu_compl_vlr_fsm(IMSI-901700000010650:MSISDN-42342:UTRAN-Iu:LU){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES
+DVLR lu_compl_vlr_fsm(IMSI-901700000010650:MSISDN-42342:UTRAN-Iu:LU){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL
+DVLR lu_compl_vlr_fsm(IMSI-901700000010650:MSISDN-42342:UTRAN-Iu:LU){LU_COMPL_VLR_S_WAIT_SUB_PRES}: lu_compl_vlr_new_tmsi()
+DVLR SUBSCR(IMSI-901700000010650:MSISDN-42342:TMSInew-0x03020100) VLR: update for IMSI=901700000010650 (MSISDN=42342)
+DVLR lu_compl_vlr_fsm(IMSI-901700000010650:MSISDN-42342:UTRAN-Iu:LU){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_WAIT_TMSI_CNF
+- sending LU Accept for IMSI-901700000010650:MSISDN-42342:TMSInew-0x03020100:UTRAN-Iu:LU, with TMSI 0x03020100
+DVLR upd_hlr_vlr_fsm(IMSI-901700000010650:UTRAN-Iu:LU){UPD_HLR_VLR_S_DONE}: Deallocated
+DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSInew-0x03020100 - vlr_gsup_rx: now used by 1 (active-conn)
+<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: vlr_gsupc_read_cb() returns 0
+ lu_result_sent == 1
+- a LU Accept with a new TMSI was sent, waiting for TMSI Realloc Compl
+ llist_count(&msub_list) == 1
+msc_a_is_accepted() == false
+ requests shall be thwarted
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSInew-0x03020100:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: RAN decode: DTAP
+DRLL msc_a(IMSI-901700000010650:MSISDN-42342:TMSInew-0x03020100:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: Dispatching 04.08 message: CC GSM48_MT_CC_SETUP
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSInew-0x03020100:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: Message not permitted for initial conn: GSM48_MT_CC_SETUP
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSInew-0x03020100:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: RAN decode error (rc=-13) for DTAP from MSC-I
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSInew-0x03020100:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: RAN decode: DTAP
+DRLL msc_a(IMSI-901700000010650:MSISDN-42342:TMSInew-0x03020100:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: Dispatching 04.08 message: MM unknown 0x33
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSInew-0x03020100:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: Message not permitted for initial conn: unknown 0x33
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSInew-0x03020100:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: RAN decode error (rc=-13) for DTAP from MSC-I
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSInew-0x03020100:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: RAN decode: DTAP
+DRLL msc_a(IMSI-901700000010650:MSISDN-42342:TMSInew-0x03020100:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: Dispatching 04.08 message: RR GSM48_MT_RR_SYSINFO_1
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSInew-0x03020100:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSInew-0x03020100:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: RAN decode error (rc=-13) for DTAP from MSC-I
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSInew-0x03020100:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: RAN decode: DTAP
+DRLL msc_a(IMSI-901700000010650:MSISDN-42342:TMSInew-0x03020100:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: Dispatching 04.08 message: SMS SMS:0x01
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSInew-0x03020100:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: Message not permitted for initial conn: SMS:0x01
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSInew-0x03020100:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: RAN decode error (rc=-13) for DTAP from MSC-I
+- even though the TMSI is not acked, we can already find the subscr with it
+DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSInew-0x03020100 + _test_umts_authen_resync: now used by 2 (active-conn,_test_umts_authen_resync)
+ vsub != NULL == 1
+ strcmp(vsub->imsi, imsi) == 0
+ vsub->tmsi_new == 0x03020100
+ vsub->tmsi == 0xffffffff
+DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSInew-0x03020100 - _test_umts_authen_resync: now used by 1 (active-conn)
+- MS sends TMSI Realloc Complete
+ MSC <--UTRAN-Iu-- MS: GSM48_MT_MM_TMSI_REALL_COMPL
+DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSInew-0x03020100:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: + rx_from_ms: now used by 2 (lu,rx_from_ms)
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSInew-0x03020100:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: RAN decode: DTAP
+DRLL msc_a(IMSI-901700000010650:MSISDN-42342:TMSInew-0x03020100:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: Dispatching 04.08 message: MM GSM48_MT_MM_TMSI_REALL_COMPL
+DMM msc_a(IMSI-901700000010650:MSISDN-42342:TMSInew-0x03020100:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: TMSI Reallocation Completed
+DVLR vlr_lu_fsm(IMSI-901700000010650:MSISDN-42342:TMSInew-0x03020100:UTRAN-Iu:LU){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_NEW_TMSI_ACK
+DVLR lu_compl_vlr_fsm(IMSI-901700000010650:MSISDN-42342:UTRAN-Iu:LU){LU_COMPL_VLR_S_WAIT_TMSI_CNF}: Received Event LU_COMPL_VLR_E_NEW_TMSI_ACK
+DVLR SUBSCR(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100) VLR: update for IMSI=901700000010650 (MSISDN=42342)
+DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + attached: now used by 2 (active-conn,attached)
+DVLR lu_compl_vlr_fsm(IMSI-901700000010650:MSISDN-42342:UTRAN-Iu:LU){LU_COMPL_VLR_S_WAIT_TMSI_CNF}: state_chg to LU_COMPL_VLR_S_DONE
+DVLR vlr_lu_fsm(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS
+DVLR lu_compl_vlr_fsm(IMSI-901700000010650:MSISDN-42342:UTRAN-Iu:LU){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR lu_compl_vlr_fsm(IMSI-901700000010650:MSISDN-42342:UTRAN-Iu:LU){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU)
+DVLR lu_compl_vlr_fsm(IMSI-901700000010650:MSISDN-42342:UTRAN-Iu:LU){LU_COMPL_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE
+DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: Received Event MSC_A_EV_AUTHENTICATED
+DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: state_chg to MSC_A_ST_AUTHENTICATED
+DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){MSC_A_ST_AUTHENTICATED}: - lu: now used by 1 (rx_from_ms)
+DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){MSC_A_ST_AUTHENTICATED}: - rx_from_ms: now used by 0 (-)
+DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){MSC_A_ST_AUTHENTICATED}: Received Event MSC_A_EV_UNUSED
+DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){MSC_A_ST_AUTHENTICATED}: state_chg to MSC_A_ST_RELEASING
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){MSC_A_ST_RELEASING}: Releasing: msc_a use is 0 (-)
+DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + msc_a_fsm_releasing_onenter: now used by 3 (active-conn,attached,msc_a_fsm_releasing_onenter)
+DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 + vlr_subscr_cancel_attach_fsm: now used by 4 (active-conn,attached,msc_a_fsm_releasing_onenter,vlr_subscr_cancel_attach_fsm)
+DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - vlr_subscr_cancel_attach_fsm: now used by 3 (active-conn,attached,msc_a_fsm_releasing_onenter)
+DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){MSC_A_ST_RELEASING}: + wait-Clear-Complete: now used by 1 (wait-Clear-Complete)
+DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){MSC_A_ST_RELEASING}: RAN encode: CLEAR_COMMAND on UTRAN-Iu
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){0}: Received Event MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST
+DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - msc_a_fsm_releasing_onenter: now used by 2 (active-conn,attached)
+ iu_release_sent == 1
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){MSC_A_ST_RELEASING}: RAN decode: CLEAR_COMPLETE
+DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){MSC_A_ST_RELEASING}: - wait-Clear-Complete: now used by 0 (-)
+DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){MSC_A_ST_RELEASING}: Received Event MSC_A_EV_UNUSED
+DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){MSC_A_ST_RELEASING}: state_chg to MSC_A_ST_RELEASED
+DIUCS msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){MSC_A_ST_RELEASED}: Released: msc_a use is 0 (-)
+DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){MSC_A_ST_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR vlr_lu_fsm(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){VLR_ULA_S_DONE}: Terminating in cascade, depth 2 (cause = OSMO_FSM_TERM_PARENT, caused by: msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU))
+DVLR vlr_lu_fsm(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){VLR_ULA_S_DONE}: Removing from parent msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU)
+DVLR vlr_lu_fsm(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT
+DVLR vlr_lu_fsm(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){VLR_ULA_S_DONE}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU)
+DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){MSC_A_ST_RELEASED}: Removing from parent msub_fsm
+DREF msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){MSC_A_ST_RELEASED}: max total use count was 3
+DMSC msub_fsm{active}: Received Event MSUB_EV_ROLE_TERMINATED
+DMSC msub(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100) MSC-A terminated
+DMSC msub(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100) 1 MSC-I still active
+DMSC msub_fsm{active}: state_chg to terminating
+DMSC msub_fsm{terminating}: Terminating in cascade, depth 2 (cause = OSMO_FSM_TERM_REGULAR, caused by: msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU))
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){0}: Terminating in cascade, depth 3 (cause = OSMO_FSM_TERM_PARENT, caused by: msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU))
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){0}: Removing from parent msub_fsm
+DMSC dummy_msc_i(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){0}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU)
+DMSC msub(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100) Free
+DREF VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 - active-conn: now used by 1 (attached)
+DMSC msub_fsm{terminating}: Deferring: will deallocate with msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU)
+DMSC msc_a(IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100:UTRAN-Iu:LU){MSC_A_ST_RELEASED}: Deallocated, including all deferred deallocations
+- msub gone
+- LU was successful, and the conn has already been closed
+ llist_count(&msub_list) == 0
+DVLR freeing VLR subscr IMSI-901700000010650:MSISDN-42342:TMSI-0x03020100 (max total use count was 4)
+===== test_umts_auth_ciph_resync_utran: SUCCESS
===== test_umts_authen_too_short_res_geran
- Location Update request causes a GSUP Send Auth Info request to HLR
@@ -1735,13 +2611,14 @@ DREF VLR subscr IMSI-901700000010650 + active-conn: now used by 2 (_lu_fsm_assoc
DMSC msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK
DMSC msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH
DREF VLR subscr IMSI-901700000010650 - _lu_fsm_associate_vsub: now used by 1 (active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre()
DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH
DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Allocated
DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU)
DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
-GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f00a0101
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f02801020a0101
DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
DREF msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - mm_rx_loc_upd_req: now used by 2 (rx_from_ms,lu)
DREF msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu)
@@ -1770,12 +2647,12 @@ DMM msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: MM UMTS AUTHENTI
DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP
DVLR SUBSCR(IMSI-901700000010650) AUTH on GERAN received SRES/RES: e229c19e791f2e (7 bytes)
DVLR SUBSCR(IMSI-901700000010650) AUTH SRES/RES has invalid length: 7. Expected either 4 (GSM AKA) or 8 (UMTS AKA)
-DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result Illegal MS
+DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result FAILURE, cause ILLEGAL_MS
DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTH_FAILED
GSUP --> HLR: OSMO_GSUP_MSGT_AUTH_FAIL_REPORT: 0b010809710000000156f00a0101
DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_AUTH_FAILED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_AUTH_FAILED}: Removing from parent vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU)
-DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES
+DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_FAILURE
- sending LU Reject for IMSI-901700000010650:GERAN-A:LU, cause 3
DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_DONE
DMSC msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: Received Event MSC_A_EV_CN_CLOSE
@@ -1822,9 +2699,6 @@ DMSC msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_RELEASED}: Deallocated, inc
llist_count(&msub_list) == 0
===== test_umts_authen_too_short_res_geran: SUCCESS
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 17
-
===== test_umts_authen_too_short_res_utran
- Location Update request causes a GSUP Send Auth Info request to HLR
MSC <--UTRAN-Iu-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
@@ -1853,13 +2727,14 @@ DREF VLR subscr IMSI-901700000010650 + active-conn: now used by 2 (_lu_fsm_assoc
DMSC msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK
DMSC msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH
DREF VLR subscr IMSI-901700000010650 - _lu_fsm_associate_vsub: now used by 1 (active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre()
DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH
DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: Allocated
DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU)
DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
-GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f00a0101
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f02801020a0101
DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
DREF msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: - mm_rx_loc_upd_req: now used by 2 (rx_from_ms,lu)
DREF msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu)
@@ -1888,12 +2763,12 @@ DMM msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: MM UMTS AUTHENT
DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP
DVLR SUBSCR(IMSI-901700000010650) AUTH on UTRAN received RES: e229c19e791f2e (7 bytes)
DVLR SUBSCR(IMSI-901700000010650) AUTH RES has invalid length: 7. Expected 8 (UMTS AKA)
-DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result Illegal MS
+DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result FAILURE, cause ILLEGAL_MS
DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTH_FAILED
GSUP --> HLR: OSMO_GSUP_MSGT_AUTH_FAIL_REPORT: 0b010809710000000156f00a0101
DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_AUTH_FAILED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_AUTH_FAILED}: Removing from parent vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU)
-DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES
+DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_FAILURE
- sending LU Reject for IMSI-901700000010650:UTRAN-Iu:LU, cause 3
DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_DONE
DMSC msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: Received Event MSC_A_EV_CN_CLOSE
@@ -1940,9 +2815,6 @@ DMSC msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_RELEASED}: Deallocated, in
llist_count(&msub_list) == 0
===== test_umts_authen_too_short_res_utran: SUCCESS
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 17
-
===== test_umts_authen_too_long_res_geran
- Location Update request causes a GSUP Send Auth Info request to HLR
MSC <--GERAN-A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
@@ -1971,13 +2843,14 @@ DREF VLR subscr IMSI-901700000010650 + active-conn: now used by 2 (_lu_fsm_assoc
DMSC msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK
DMSC msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH
DREF VLR subscr IMSI-901700000010650 - _lu_fsm_associate_vsub: now used by 1 (active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre()
DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH
DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Allocated
DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU)
DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
-GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f00a0101
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f02801020a0101
DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
DREF msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - mm_rx_loc_upd_req: now used by 2 (rx_from_ms,lu)
DREF msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu)
@@ -2006,12 +2879,12 @@ DMM msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: MM UMTS AUTHENTI
DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP
DVLR SUBSCR(IMSI-901700000010650) AUTH on GERAN received SRES/RES: e229c19e791f2e4123 (9 bytes)
DVLR SUBSCR(IMSI-901700000010650) AUTH SRES/RES has invalid length: 9. Expected either 4 (GSM AKA) or 8 (UMTS AKA)
-DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result Illegal MS
+DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result FAILURE, cause ILLEGAL_MS
DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTH_FAILED
GSUP --> HLR: OSMO_GSUP_MSGT_AUTH_FAIL_REPORT: 0b010809710000000156f00a0101
DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_AUTH_FAILED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_AUTH_FAILED}: Removing from parent vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU)
-DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES
+DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_FAILURE
- sending LU Reject for IMSI-901700000010650:GERAN-A:LU, cause 3
DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_DONE
DMSC msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: Received Event MSC_A_EV_CN_CLOSE
@@ -2058,9 +2931,6 @@ DMSC msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_RELEASED}: Deallocated, inc
llist_count(&msub_list) == 0
===== test_umts_authen_too_long_res_geran: SUCCESS
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 17
-
===== test_umts_authen_too_long_res_utran
- Location Update request causes a GSUP Send Auth Info request to HLR
MSC <--UTRAN-Iu-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
@@ -2089,13 +2959,14 @@ DREF VLR subscr IMSI-901700000010650 + active-conn: now used by 2 (_lu_fsm_assoc
DMSC msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK
DMSC msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH
DREF VLR subscr IMSI-901700000010650 - _lu_fsm_associate_vsub: now used by 1 (active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre()
DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH
DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: Allocated
DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU)
DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
-GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f00a0101
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f02801020a0101
DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
DREF msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: - mm_rx_loc_upd_req: now used by 2 (rx_from_ms,lu)
DREF msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu)
@@ -2124,12 +2995,12 @@ DMM msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: MM UMTS AUTHENT
DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP
DVLR SUBSCR(IMSI-901700000010650) AUTH on UTRAN received RES: e229c19e791f2e4123 (9 bytes)
DVLR SUBSCR(IMSI-901700000010650) AUTH RES has invalid length: 9. Expected 8 (UMTS AKA)
-DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result Illegal MS
+DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result FAILURE, cause ILLEGAL_MS
DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTH_FAILED
GSUP --> HLR: OSMO_GSUP_MSGT_AUTH_FAIL_REPORT: 0b010809710000000156f00a0101
DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_AUTH_FAILED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_AUTH_FAILED}: Removing from parent vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU)
-DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES
+DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_FAILURE
- sending LU Reject for IMSI-901700000010650:UTRAN-Iu:LU, cause 3
DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_DONE
DMSC msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: Received Event MSC_A_EV_CN_CLOSE
@@ -2176,9 +3047,6 @@ DMSC msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_RELEASED}: Deallocated, in
llist_count(&msub_list) == 0
===== test_umts_authen_too_long_res_utran: SUCCESS
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 17
-
===== test_umts_authen_only_sres_geran
- Location Update request causes a GSUP Send Auth Info request to HLR
MSC <--GERAN-A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
@@ -2207,13 +3075,14 @@ DREF VLR subscr IMSI-901700000010650 + active-conn: now used by 2 (_lu_fsm_assoc
DMSC msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK
DMSC msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH
DREF VLR subscr IMSI-901700000010650 - _lu_fsm_associate_vsub: now used by 1 (active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre()
DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH
DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Allocated
DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU)
DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
-GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f00a0101
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f02801020a0101
DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
DREF msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - mm_rx_loc_upd_req: now used by 2 (rx_from_ms,lu)
DREF msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu)
@@ -2242,12 +3111,12 @@ DMM msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: MM GSM AUTHENTIC
DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP
DVLR SUBSCR(IMSI-901700000010650) AUTH on GERAN received SRES/RES: e229c19e (4 bytes)
DVLR SUBSCR(IMSI-901700000010650) GSM AUTH failure: mismatching sres (expected sres=9b 36 ef df )
-DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result Illegal MS
+DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result FAILURE, cause ILLEGAL_MS
DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTH_FAILED
GSUP --> HLR: OSMO_GSUP_MSGT_AUTH_FAIL_REPORT: 0b010809710000000156f00a0101
DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_AUTH_FAILED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
DVLR VLR_Authenticate(IMSI-901700000010650:GERAN-A:LU){VLR_SUB_AS_AUTH_FAILED}: Removing from parent vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU)
-DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES
+DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_FAILURE
- sending LU Reject for IMSI-901700000010650:GERAN-A:LU, cause 3
DVLR vlr_lu_fsm(IMSI-901700000010650:GERAN-A:LU){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_DONE
DMSC msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_AUTH_CIPH}: Received Event MSC_A_EV_CN_CLOSE
@@ -2294,9 +3163,6 @@ DMSC msc_a(IMSI-901700000010650:GERAN-A:LU){MSC_A_ST_RELEASED}: Deallocated, inc
llist_count(&msub_list) == 0
===== test_umts_authen_only_sres_geran: SUCCESS
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 17
-
===== test_umts_authen_only_sres_utran
- Location Update request causes a GSUP Send Auth Info request to HLR
MSC <--UTRAN-Iu-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
@@ -2325,13 +3191,14 @@ DREF VLR subscr IMSI-901700000010650 + active-conn: now used by 2 (_lu_fsm_assoc
DMSC msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_VALIDATE_L3}: Received Event MSC_A_EV_COMPLETE_LAYER_3_OK
DMSC msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_VALIDATE_L3}: state_chg to MSC_A_ST_AUTH_CIPH
DREF VLR subscr IMSI-901700000010650 - _lu_fsm_associate_vsub: now used by 1 (active-conn)
+DVLR set Last E-UTRAN PLMN ID on subscriber: (none)
DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1_pre()
DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH
DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: Allocated
DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU)
DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
-GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f00a0101
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f02801020a0101
DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
DREF msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: - mm_rx_loc_upd_req: now used by 2 (rx_from_ms,lu)
DREF msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: - rx_from_ms: now used by 1 (lu)
@@ -2360,12 +3227,12 @@ DMM msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: MM GSM AUTHENTI
DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP
DVLR SUBSCR(IMSI-901700000010650) AUTH on UTRAN received RES: e229c19e (4 bytes)
DVLR SUBSCR(IMSI-901700000010650) AUTH via UTRAN, cannot allow GSM AKA (MS is R99 capable, vec has UMTS AKA tokens, res_len=4 is INVALID on UTRAN)
-DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result Illegal MS
+DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result FAILURE, cause ILLEGAL_MS
DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTH_FAILED
GSUP --> HLR: OSMO_GSUP_MSGT_AUTH_FAIL_REPORT: 0b010809710000000156f00a0101
DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_AUTH_FAILED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
DVLR VLR_Authenticate(IMSI-901700000010650:UTRAN-Iu:LU){VLR_SUB_AS_AUTH_FAILED}: Removing from parent vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU)
-DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES
+DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_FAILURE
- sending LU Reject for IMSI-901700000010650:UTRAN-Iu:LU, cause 3
DVLR vlr_lu_fsm(IMSI-901700000010650:UTRAN-Iu:LU){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_DONE
DMSC msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_AUTH_CIPH}: Received Event MSC_A_EV_CN_CLOSE
@@ -2412,9 +3279,3 @@ DMSC msc_a(IMSI-901700000010650:UTRAN-Iu:LU){MSC_A_ST_RELEASED}: Deallocated, in
llist_count(&msub_list) == 0
===== test_umts_authen_only_sres_utran: SUCCESS
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 17
-
-full talloc report on 'msgb' (total 0 bytes in 1 blocks)
-talloc_total_blocks(tall_bsc_ctx) == 17
-
diff --git a/tests/msc_vlr/msc_vlr_tests.c b/tests/msc_vlr/msc_vlr_tests.c
index 488cd198c..062d8a35b 100644
--- a/tests/msc_vlr/msc_vlr_tests.c
+++ b/tests/msc_vlr/msc_vlr_tests.c
@@ -41,10 +41,12 @@
#include <osmocom/msc/msc_t.h>
#include <osmocom/msc/call_leg.h>
#include <osmocom/msc/rtp_stream.h>
+#include <osmocom/msc/codec_mapping.h>
#include "msc_vlr_tests.h"
void *msc_vlr_tests_ctx = NULL;
+void *msgb_ctx = NULL;
bool _log_lines = false;
@@ -73,10 +75,20 @@ bool iu_release_sent = false;
bool bssap_clear_expected = false;
bool bssap_clear_sent = false;
+bool bssap_assignment_expected = false;
+bool bssap_assignment_sent = false;
+struct gsm0808_channel_type bssap_assignment_command_last_channel_type;
+bool iu_rab_assignment_expected = false;
+bool iu_rab_assignment_sent = false;
+
uint32_t cc_to_mncc_tx_expected_msg_type = 0;
const char *cc_to_mncc_tx_expected_imsi = NULL;
bool cc_to_mncc_tx_confirmed = false;
uint32_t cc_to_mncc_tx_got_callref = 0;
+char cc_to_mncc_tx_last_sdp[1024] = {};
+
+bool expecting_crcx[2] = {};
+bool got_crcx[2] = {};
extern int ran_dec_dtap_undup_pdisc_ctr_bin(uint8_t pdisc);
@@ -171,7 +183,7 @@ void conn_conclude_cm_service_req(struct msub *msub, const char *cm_service_use)
count = osmo_use_count_by(&msc_a->use_count, cm_service_use);
OSMO_ASSERT(count > 0);
- OSMO_ASSERT(osmo_use_count_get_put(&msc_a->use_count, cm_service_use, -count) == 0)
+ OSMO_ASSERT(osmo_use_count_get_put(&msc_a->use_count, cm_service_use, -count) == 0);
ASSERT_RELEASE_CLEAR(msc_a->c.ran->type);
}
@@ -246,8 +258,10 @@ static int _validate_dtap(struct msgb *msg, enum osmo_rat_type to_ran)
/* Mask the sequence number out before comparing */
msg->data[1] &= 0x3f;
- if (!msgb_eq_data_print(msg, dtap_tx_expected->data, dtap_tx_expected->len))
+ if (!msgb_eq_data_print(msg, dtap_tx_expected->data, dtap_tx_expected->len)) {
+ btw("Expected %s", osmo_hexdump(dtap_tx_expected->data, dtap_tx_expected->len));
abort();
+ }
btw("DTAP matches expected message");
@@ -296,6 +310,24 @@ static int bssap_validate_cipher_mode_cmd(const struct ran_cipher_mode_command *
return 0;
}
+static void bssap_validate_assignment_cmd(const struct ran_assignment_command *assignment_command)
+{
+ OSMO_ASSERT(bssap_assignment_expected);
+ bssap_assignment_expected = false;
+ bssap_assignment_sent = true;
+ if (assignment_command->channel_type)
+ bssap_assignment_command_last_channel_type = *assignment_command->channel_type;
+ else
+ bssap_assignment_command_last_channel_type = (struct gsm0808_channel_type){};
+}
+
+static void iucs_validate_assignment_cmd(const struct ran_assignment_command *assignment_command)
+{
+ OSMO_ASSERT(iu_rab_assignment_expected);
+ iu_rab_assignment_expected = false;
+ iu_rab_assignment_sent = true;
+}
+
static int iucs_validate_security_mode_ctrl(const struct ran_cipher_mode_command *cmd)
{
const char *got_ik;
@@ -346,6 +378,18 @@ struct msgb *dont_ran_encode(struct osmo_fsm_inst *caller_fi, const struct ran_m
OSMO_ASSERT(false);
}
break;
+ case RAN_MSG_ASSIGNMENT_COMMAND:
+ switch (ran_type) {
+ case OSMO_RAT_GERAN_A:
+ bssap_validate_assignment_cmd(&ran_enc_msg->assignment_command);
+ break;
+ case OSMO_RAT_UTRAN_IU:
+ iucs_validate_assignment_cmd(&ran_enc_msg->assignment_command);
+ break;
+ default:
+ OSMO_ASSERT(false);
+ }
+ break;
default:
break;
}
@@ -371,6 +415,16 @@ struct ran_infra test_ran_infra[] = {
.log_subsys = DIUCS,
.tdefs = msc_tdefs_utran,
.ran_encode = dont_ran_encode,
+ .force_mgw_codecs_to_ran = {
+ .count = 1,
+ .codec = {
+ {
+ .payload_type = 96,
+ .subtype_name = "VND.3GPP.IUFP",
+ .rate = 16000,
+ },
+ },
+ },
},
};
@@ -382,7 +436,7 @@ static int fake_msc_a_ran_dec(const struct ran_msg *ran_dec_msg)
return msc_a_ran_decode_cb(g_msub->role[MSC_ROLE_A], &d, ran_dec_msg);
}
-void rx_from_ms(struct msgb *msg)
+void rx_from_ms(struct msgb *msg, const struct gsm0808_speech_codec_list *codec_list_bss_supported)
{
struct gsm48_hdr *gh = msgb_l3(msg);
struct ran_msg ran_dec_msg;
@@ -415,6 +469,7 @@ void rx_from_ms(struct msgb *msg)
.compl_l3 = {
.cell_id = &cell_id,
.msg = msg,
+ .codec_list_bss_supported = codec_list_bss_supported,
},
};
} else {
@@ -442,7 +497,30 @@ void ms_sends_msg(const char *hex)
msg = msgb_from_hex("ms_sends_msg", 1024, hex);
msg->l1h = msg->l2h = msg->l3h = msg->data;
- rx_from_ms(msg);
+ rx_from_ms(msg, NULL);
+ msgb_free(msg);
+}
+
+void ms_sends_msgf(const char *fmt, ...)
+{
+ va_list ap;
+ char *hex;
+
+ va_start(ap, fmt);
+ hex = talloc_vasprintf(msc_vlr_tests_ctx, fmt, ap);
+ va_end(ap);
+
+ ms_sends_msg(hex);
+ talloc_free(hex);
+}
+
+void ms_sends_compl_l3(const char *hex, const struct gsm0808_speech_codec_list *codec_list_bss_supported)
+{
+ struct msgb *msg;
+
+ msg = msgb_from_hex("ms_sends_msg", 1024, hex);
+ msg->l1h = msg->l2h = msg->l3h = msg->data;
+ rx_from_ms(msg, codec_list_bss_supported);
msgb_free(msg);
}
@@ -602,6 +680,14 @@ void clear_vlr()
bssap_clear_sent = false;
osmo_gettimeofday_override = false;
+
+ memset(expecting_crcx, 0, sizeof(expecting_crcx));
+ memset(got_crcx, 0, sizeof(got_crcx));
+
+ bssap_assignment_expected = false;
+ bssap_assignment_sent = false;
+ iu_rab_assignment_expected = false;
+ iu_rab_assignment_sent = false;
}
static struct log_info_cat test_categories[] = {
@@ -677,8 +763,18 @@ struct gsm_mncc *on_call_release_mncc_sends_to_cc_data = NULL;
int mncc_recv(struct gsm_network *net, struct msgb *msg)
{
struct gsm_mncc *mncc = (void*)msg->data;
- log("MSC --> MNCC: callref 0x%x: %s", mncc->callref,
- get_mncc_name(mncc->msg_type));
+ if (mncc->msg_type == MNCC_RTP_CREATE) {
+ struct gsm_mncc_rtp *rtp = (void *)msg->data;
+ log("MSC --> MNCC: callref 0x%x: %s\n%s", rtp->callref,
+ get_mncc_name(rtp->msg_type),
+ rtp->sdp);
+ OSMO_STRLCPY_ARRAY(cc_to_mncc_tx_last_sdp, rtp->sdp);
+ } else {
+ log("MSC --> MNCC: callref 0x%x: %s\n%s", mncc->callref,
+ get_mncc_name(mncc->msg_type),
+ mncc->sdp);
+ OSMO_STRLCPY_ARRAY(cc_to_mncc_tx_last_sdp, mncc->sdp);
+ }
if (mncc->msg_type == MNCC_REL_IND && on_call_release_mncc_sends_to_cc_data) {
@@ -746,8 +842,16 @@ int __wrap_osmo_gsup_client_send(struct osmo_gsup_client *gsupc, struct msgb *ms
if (len < 1)
abort();
- if (!msgb_eq_data_print(msg, buf, len))
+ /* Compare only the length expected. Extra data is fine, to not care about new GSUP IEs invented later. */
+ if (msg->len < len) {
+ fprintf(stderr, "ERROR: GSUP message too short, expected '%s'\n", gsup_tx_expected);
abort();
+ }
+
+ if (memcmp(msg->data, buf, len)) {
+ fprintf(stderr, "ERROR: GSUP message mismatch, expected it to start with '%s'\n", gsup_tx_expected);
+ abort();
+ }
talloc_free(msg);
gsup_tx_confirmed = true;
@@ -755,14 +859,81 @@ int __wrap_osmo_gsup_client_send(struct osmo_gsup_client *gsupc, struct msgb *ms
return 0;
}
+struct rtp_stream fake_rtp[2] = {
+ {
+ .dir = RTP_TO_RAN,
+ .local = {
+ .ip = "10.23.42.1",
+ .port = 99,
+ },
+ .remote = {
+ .ip = "10.23.42.2",
+ .port = 100,
+ },
+ },
+ {
+ .dir = RTP_TO_CN,
+ .local = {
+ .ip = "10.23.42.1",
+ .port = 23,
+ },
+ .remote = {
+ .ip = "10.23.42.2",
+ .port = 42,
+ },
+ },
+};
+
+void expect_crcx(enum rtp_direction towards)
+{
+ OSMO_ASSERT(!expecting_crcx[towards]);
+ expecting_crcx[towards] = true;
+ got_crcx[towards] = false;
+}
+
+bool crcx_scheduled(enum rtp_direction towards)
+{
+ return got_crcx[towards];
+}
+
/* override, requires '-Wl,--wrap=call_leg_ensure_ci' */
-int __real_call_leg_ensure_ci(struct call_leg *cl, enum rtp_direction dir, uint32_t call_id, struct gsm_trans *for_trans);
-int __wrap_call_leg_ensure_ci(struct call_leg *cl, enum rtp_direction dir, uint32_t call_id, struct gsm_trans *for_trans)
+int __real_call_leg_ensure_ci(struct call_leg *cl, enum rtp_direction dir, uint32_t call_id, struct gsm_trans *for_trans,
+ const struct sdp_audio_codecs *codecs_if_known,
+ const struct osmo_sockaddr_str *remote_addr_if_known);
+int __wrap_call_leg_ensure_ci(struct call_leg *cl, enum rtp_direction dir, uint32_t call_id, struct gsm_trans *for_trans,
+ const struct sdp_audio_codecs *codecs_if_known,
+ const struct osmo_sockaddr_str *remote_addr_if_known)
{
- log("MS <--Call Assignment-- MSC: callref=0x%x", call_id);
+ if (!cl->rtp[dir]) {
+ log("MGW <--CRCX to %s-- MSC: call_id=0x%x codecs=%s", rtp_direction_name(dir), call_id,
+ codecs_if_known ? sdp_audio_codecs_to_str(codecs_if_known) : "unset");
+
+ OSMO_ASSERT(expecting_crcx[dir]);
+ expecting_crcx[dir] = false;
+ got_crcx[dir] = true;
+
+ call_leg_ensure_rtp_alloc(cl, dir, call_id, for_trans);
+ if (codecs_if_known)
+ rtp_stream_set_codecs(cl->rtp[dir], codecs_if_known);
+ if (remote_addr_if_known && osmo_sockaddr_str_is_nonzero(remote_addr_if_known))
+ rtp_stream_set_remote_addr(cl->rtp[dir], remote_addr_if_known);
+ }
+
return 0;
}
+void crcx_ok(enum rtp_direction dir)
+{
+ struct msc_a *msc_a = msub_msc_a(g_msub);
+ struct call_leg *cl = msc_a->cc.call_leg;
+ OSMO_ASSERT(cl);
+ OSMO_ASSERT(cl->rtp[dir]);
+ osmo_sockaddr_str_from_str(&cl->rtp[dir]->local, "10.23.23.1", 23);
+ //osmo_sockaddr_str_from_str(&cl->rtp[dir].remote, "10.42.42.1", 42);
+ log("MGW --CRCX OK to %s--> MSC", rtp_direction_name(dir));
+ osmo_fsm_inst_dispatch(cl->fi, CALL_LEG_EV_RTP_STREAM_ADDR_AVAILABLE, cl->rtp[dir]);
+}
+
static int fake_vlr_tx_lu_acc(void *msc_conn_ref, uint32_t send_tmsi)
{
struct msc_a *msc_a = msc_conn_ref;
@@ -874,13 +1045,36 @@ void ms_sends_ciphering_mode_complete(const char *inner_ran_msg)
g_msub = NULL;
}
-void ms_sends_security_mode_complete()
+void ms_sends_security_mode_complete(uint8_t utran_encryption)
{
struct ran_msg ran_dec;
ran_dec = (struct ran_msg){
.msg_type = RAN_MSG_CIPHER_MODE_COMPLETE,
+ .cipher_mode_complete.utran_encryption = utran_encryption,
+ };
+ fake_msc_a_ran_dec(&ran_dec);
+
+ if (!conn_exists(g_msub))
+ g_msub = NULL;
+}
+
+void ms_sends_assignment_complete(const char *sdp_codec_name)
+{
+ struct ran_msg ran_dec;
+ const struct codec_mapping *m = codec_mapping_by_subtype_name(sdp_codec_name);
+ OSMO_ASSERT(m);
+ OSMO_ASSERT(m->has_gsm0808_speech_codec);
+
+ ran_dec = (struct ran_msg){
+ .msg_type = RAN_MSG_ASSIGNMENT_COMPLETE,
+ .assignment_complete = {
+ .codec_present = true,
+ .codec = m->gsm0808_speech_codec,
+ .codec_with_iuup = (rx_from_ran == OSMO_RAT_UTRAN_IU),
+ },
};
+ osmo_sockaddr_str_from_str(&ran_dec.assignment_complete.remote_rtp, "1.2.3.4", 1234);
fake_msc_a_ran_dec(&ran_dec);
if (!conn_exists(g_msub))
@@ -916,38 +1110,6 @@ void fake_time_start()
fake_time_passes(0, 0);
}
-static void check_talloc(void *msgb_ctx, void *msc_vlr_tests_ctx)
-{
- /* Verifying that the msgb context is empty */
- talloc_report_full(msgb_ctx, stderr);
- /* Expecting these to stick around in msc_vlr_tests_ctx:
- * full talloc report on 'msgb' (total 0 bytes in 1 blocks)
- * talloc_total_blocks(tall_bsc_ctx) == 17
- * full talloc report on 'msc_vlr_tests_ctx' (total 6336 bytes in 17 blocks)
- * struct osmo_gsup_client contains 256 bytes in 1 blocks (ref 0) 0x613000000260
- * struct gsm_network contains 4647 bytes in 9 blocks (ref 0) 0x6190000000e0
- * struct mgcp_client contains 688 bytes in 1 blocks (ref 0) 0x6180000000e0
- * struct sccp_ran_inst contains 152 bytes in 1 blocks (ref 0) 0x611000000460
- * struct sccp_ran_inst contains 152 bytes in 1 blocks (ref 0) 0x611000000320
- * struct gsup_client_mux contains 200 bytes in 2 blocks (ref 0) 0x6110000001e0
- * struct ipaccess_unit contains 64 bytes in 1 blocks (ref 0) 0x60e000023180
- * struct vlr_instance contains 248 bytes in 1 blocks (ref 0) 0x6130000000a0
- * no_gsup_server contains 15 bytes in 1 blocks (ref 0) 0x60b000000150
- * ../../../src/libosmocore/src/rate_ctr.c:234 contains 2352 bytes in 1 blocks (ref 0) 0x61e0000000e0
- * logging contains 1433 bytes in 5 blocks (ref 0) 0x60b0000000a0
- * struct log_target contains 240 bytes in 2 blocks (ref 0) 0x6120000000a0
- * struct log_category contains 72 bytes in 1 blocks (ref 0) 0x60f0000000a0
- * struct log_info contains 1192 bytes in 2 blocks (ref 0) 0x60d0000000a0
- * struct log_info_cat contains 1152 bytes in 1 blocks (ref 0) 0x61a0000000e0
- * msgb contains 0 bytes in 1 blocks (ref 0) 0x608000000100
- */
- fprintf(stderr, "talloc_total_blocks(tall_bsc_ctx) == %zu\n",
- talloc_total_blocks(msc_vlr_tests_ctx));
- if (talloc_total_blocks(msc_vlr_tests_ctx) != 17)
- talloc_report_full(msc_vlr_tests_ctx, stderr);
- fprintf(stderr, "\n");
-}
-
static struct {
bool verbose;
int run_test_nr;
@@ -999,34 +1161,46 @@ static void handle_options(int argc, char **argv)
}
}
-void *msgb_ctx = NULL;
-
static void run_tests(int nr)
{
int test_nr;
- check_talloc(msgb_ctx, msc_vlr_tests_ctx);
-
nr--; /* arg's first test is 1, in here it's 0 */
for (test_nr = 0; msc_vlr_tests[test_nr]; test_nr++) {
+ size_t talloc_blocks_before_test;
+
if (nr >= 0 && test_nr != nr)
continue;
if (cmdline_opts.verbose)
fprintf(stderr, "(test nr %d)\n", test_nr + 1);
+ talloc_blocks_before_test = talloc_total_blocks(msc_vlr_tests_ctx);
+
msc_vlr_tests[test_nr]();
+ if (talloc_total_blocks(msc_vlr_tests_ctx) != talloc_blocks_before_test) {
+ fprintf(stderr, "ERROR: talloc leak: %zu blocks\n",
+ talloc_total_blocks(msc_vlr_tests_ctx) - talloc_blocks_before_test);
+ talloc_report_full(msc_vlr_tests_ctx, stderr);
+ fprintf(stderr, "\n");
+ }
+
+ if (talloc_total_blocks(msgb_ctx) > 1) {
+ fprintf(stderr, "ERROR: msgb leak:\n");
+ talloc_report_full(msgb_ctx, stderr);
+ fprintf(stderr, "\n");
+ }
+
if (cmdline_opts.verbose)
fprintf(stderr, "(test nr %d)\n", test_nr + 1);
-
- check_talloc(msgb_ctx, msc_vlr_tests_ctx);
}
}
struct gsm_network *test_net(void *ctx)
{
struct gsm_network *net = gsm_network_init(ctx, mncc_recv);
+ struct mgcp_client *client;
net->gsup_server_addr_str = talloc_strdup(net, "no_gsup_server");
net->gsup_server_port = 0;
@@ -1061,10 +1235,11 @@ struct gsm_network *test_net(void *ctx)
INIT_LLIST_HEAD(&net->iu.sri->ran_conns);
net->mgw.tdefs = g_mgw_tdefs;
- mgcp_client_conf_init(&net->mgw.conf);
net->mgw.tdefs = g_mgw_tdefs;
- net->mgw.client = mgcp_client_init(net, &net->mgw.conf);
-
+ net->mgw.conf = mgcp_client_conf_alloc(net);
+ net->mgw.mgw_pool = mgcp_client_pool_alloc(net);
+ client = mgcp_client_init(net, net->mgw.conf);
+ mgcp_client_pool_register_single(net->mgw.mgw_pool, client);
return net;
}
@@ -1083,9 +1258,11 @@ int main(int argc, char **argv)
OSMO_ASSERT(osmo_stderr_target);
log_set_use_color(osmo_stderr_target, 0);
log_set_print_timestamp(osmo_stderr_target, 0);
- log_set_print_filename(osmo_stderr_target, 0);
+ log_set_print_filename2(osmo_stderr_target, LOG_FILENAME_NONE);
log_set_print_category(osmo_stderr_target, 1);
+ log_set_print_category_hex(osmo_stderr_target, 0);
log_set_category_filter(osmo_stderr_target, DLSMS, 1, LOGL_DEBUG);
+ log_set_category_filter(osmo_stderr_target, DLMGCP, 0, LOGL_NOTICE);
if (cmdline_opts.verbose) {
log_set_print_filename2(osmo_stderr_target, LOG_FILENAME_BASENAME);
@@ -1125,6 +1302,5 @@ int main(int argc, char **argv)
printf("Done\n");
- check_talloc(msgb_ctx, msc_vlr_tests_ctx);
return 0;
}
diff --git a/tests/msc_vlr/msc_vlr_tests.h b/tests/msc_vlr/msc_vlr_tests.h
index 9df9cf049..b0605f104 100644
--- a/tests/msc_vlr/msc_vlr_tests.h
+++ b/tests/msc_vlr/msc_vlr_tests.h
@@ -26,16 +26,22 @@
#include <stdbool.h>
#include <stdio.h>
+#include <osmocom/crypt/utran_cipher.h>
#include <osmocom/msc/gsm_data.h>
#include <osmocom/msc/vlr.h>
#include <osmocom/msc/msub.h>
#include <osmocom/msc/msc_a.h>
#include <osmocom/msc/mncc.h>
+#include <osmocom/msc/call_leg.h>
+#include <osmocom/msc/rtp_stream.h>
extern bool _log_lines;
+#define LOG_COLOR "\033[1;33m"
+#define LOG_COLOR_OFF "\033[0;m"
+
#define _log(fmt, args...) do { \
if (_log_lines) \
- fprintf(stderr, " %4d:%s: " fmt "\n", \
+ fprintf(stderr, LOG_COLOR " %4d:%s: " fmt LOG_COLOR_OFF "\n", \
__LINE__, __FILE__, ## args ); \
else \
fprintf(stderr, fmt "\n", ## args ); \
@@ -50,6 +56,8 @@ extern bool _log_lines;
#define comment_start() fprintf(stderr, "===== %s\n", __func__);
#define comment_end() fprintf(stderr, "===== %s: SUCCESS\n\n", __func__);
+extern void *msc_vlr_tests_ctx;
+
extern struct msub *g_msub;
extern struct gsm_network *net;
extern void *msgb_ctx;
@@ -110,6 +118,7 @@ extern uint32_t cc_to_mncc_tx_expected_msg_type;
extern const char *cc_to_mncc_tx_expected_imsi;
extern bool cc_to_mncc_tx_confirmed;
extern uint32_t cc_to_mncc_tx_got_callref;
+extern char cc_to_mncc_tx_last_sdp[1024];
extern struct gsm_mncc *on_call_release_mncc_sends_to_cc_data;
@@ -140,6 +149,24 @@ static inline void expect_release_clear(enum osmo_rat_type via_ran)
}
}
+extern bool bssap_assignment_expected;
+extern bool bssap_assignment_sent;
+extern struct gsm0808_channel_type bssap_assignment_command_last_channel_type;
+extern bool iu_rab_assignment_expected;
+extern bool iu_rab_assignment_sent;
+
+static inline void expect_bssap_assignment()
+{
+ bssap_assignment_expected = true;
+ bssap_assignment_sent = false;
+}
+
+static inline void expect_iu_rab_assignment()
+{
+ iu_rab_assignment_expected = true;
+ iu_rab_assignment_sent = false;
+}
+
struct msc_vlr_test_cmdline_opts {
bool verbose;
int run_test_nr;
@@ -160,13 +187,17 @@ void paging_expect_imsi(const char *imsi);
void paging_expect_tmsi(uint32_t tmsi);
void ms_sends_msg(const char *hex);
+void ms_sends_msgf(const char *fmt, ...);
+void ms_sends_compl_l3(const char *hex, const struct gsm0808_speech_codec_list *codec_list_bss_supported);
void ms_sends_classmark_update(const struct osmo_gsm48_classmark *classmark);
void ms_sends_ciphering_mode_complete(const char *inner_nas_msg);
-void ms_sends_security_mode_complete();
+void ms_sends_security_mode_complete(uint8_t utran_encryption);
+void ms_sends_assignment_complete(const char *sdp_codec_name);
void gsup_rx(const char *rx_hex, const char *expect_tx_hex);
void send_sms(struct vlr_subscr *receiver,
struct vlr_subscr *sender,
char *str);
+void crcx_ok(enum rtp_direction dir);
void ran_sends_clear_complete();
@@ -246,5 +277,9 @@ extern const struct timeval fake_time_start_time;
#define HLR_TO_VLR "0a0101"
#define VLR_TO_HLR "0a0101"
+#define CN_DOMAIN "280102"
#define EUSE_TO_MSC_USSD "0a0103"
#define MSC_USSD_TO_EUSE "0a0103"
+
+void expect_crcx(enum rtp_direction towards);
+bool crcx_scheduled(enum rtp_direction towards);
diff --git a/tests/sdp_msg/Makefile.am b/tests/sdp_msg/Makefile.am
new file mode 100644
index 000000000..f86e5f7a3
--- /dev/null
+++ b/tests/sdp_msg/Makefile.am
@@ -0,0 +1,37 @@
+AM_CPPFLAGS = \
+ $(all_includes) \
+ -I$(top_srcdir)/include \
+ $(NULL)
+
+AM_CFLAGS = \
+ -Wall \
+ -ggdb3 \
+ $(LIBOSMOCORE_CFLAGS) \
+ $(NULL)
+
+AM_LDFLAGS = \
+ $(COVERAGE_LDFLAGS) \
+ -no-install \
+ $(NULL)
+
+LDADD = \
+ $(top_builddir)/src/libmsc/libmsc.a \
+ $(LIBOSMOCORE_LIBS) \
+ $(NULL)
+
+EXTRA_DIST = \
+ sdp_msg_test.ok \
+ sdp_msg_test.err \
+ $(NULL)
+
+check_PROGRAMS = \
+ sdp_msg_test \
+ $(NULL)
+
+sdp_msg_test_SOURCES = \
+ sdp_msg_test.c \
+ $(NULL)
+
+.PHONY: update_exp
+update_exp:
+ $(builddir)/sdp_msg_test >$(srcdir)/sdp_msg_test.ok 2>$(srcdir)/sdp_msg_test.err
diff --git a/tests/sdp_msg/sdp_msg_test.c b/tests/sdp_msg/sdp_msg_test.c
new file mode 100644
index 000000000..4798ae007
--- /dev/null
+++ b/tests/sdp_msg/sdp_msg_test.c
@@ -0,0 +1,574 @@
+#include <stdio.h>
+#include <string.h>
+#include <osmocom/core/utils.h>
+#include <osmocom/msc/sdp_msg.h>
+
+struct sdp_test_data {
+ const char *sdp_input;
+ const char *expect_sdp_str;
+};
+
+static void dump_sdp(const char *str, const char *prefix)
+{
+ while (str && *str) {
+ const char *line_end = sdp_msg_line_end(str);
+ while (*line_end == '\r' || *line_end == '\n')
+ line_end++;
+ printf("%s%s\n", prefix, osmo_escape_str(str, line_end - str));
+ str = line_end;
+ }
+}
+
+struct sdp_test_data sdp_tests[] = {
+ {
+ "v=0\r\n"
+ "o=- 5628250 5628250 IN IP4 192.168.11.121\r\n"
+ "s=-\r\n"
+ "c=IN IP4 192.168.11.121\r\n"
+ "t=0 0\r\n"
+ "m=audio 10020 RTP/AVP 18 0 2 4 8 96 97 98 100 101\r\n"
+ "a=rtpmap:18 G729/8000\r\n"
+ "a=rtpmap:0 PCMU/8000\r\n"
+ "a=rtpmap:2 G726-32/8000\r\n"
+ "a=rtpmap:4 G723/8000\r\n"
+ "a=rtpmap:8 PCMA/8000\r\n"
+ "a=rtpmap:96 G726-40/8000\r\n"
+ "a=rtpmap:97 G726-24/8000\r\n"
+ "a=rtpmap:98 G726-16/8000\r\n"
+ "a=rtpmap:100 NSE/8000\r\n"
+ "a=fmtp:100 192-193\r\n"
+ "a=rtpmap:101 telephone-event/8000\r\n"
+ "a=fmtp:101 0-15\r\n"
+ "a=ptime:20\r\n"
+ "a=sendrecv\r\n"
+ ,
+ "v=0\r\n"
+ "o=OsmoMSC 0 0 IN IP4 192.168.11.121\r\n"
+ "s=GSM Call\r\n"
+ "c=IN IP4 192.168.11.121\r\n"
+ "t=0 0\r\n"
+ "m=audio 10020 RTP/AVP 18 0 2 4 8 96 97 98 100 101\r\n"
+ "a=rtpmap:18 G729/8000\r\n"
+ "a=rtpmap:0 PCMU/8000\r\n"
+ "a=rtpmap:2 G726-32/8000\r\n"
+ "a=rtpmap:4 G723/8000\r\n"
+ "a=rtpmap:8 PCMA/8000\r\n"
+ "a=rtpmap:96 G726-40/8000\r\n"
+ "a=rtpmap:97 G726-24/8000\r\n"
+ "a=rtpmap:98 G726-16/8000\r\n"
+ "a=rtpmap:100 NSE/8000\r\n"
+ "a=fmtp:100 192-193\r\n"
+ "a=rtpmap:101 telephone-event/8000\r\n"
+ "a=fmtp:101 0-15\r\n"
+ "a=ptime:20\r\n"
+ "a=sendrecv\r\n"
+ ,
+ },
+ {
+ "v=0\r\n"
+ "o=FooBar 1565090289 1565090290 IN IP4 192.168.11.151\r\n"
+ "s=FooBar\r\n"
+ "c=IN IP4 192.168.11.151\r\n"
+ "t=0 0\r\n"
+ "m=audio 16398 RTP/AVP 98\r\n"
+ "a=rtpmap:98 AMR/8000\r\n"
+ "a=fmtp:98 octet-align=1; mode-set=4\r\n"
+ "a=ptime:20\r\n"
+ "a=rtcp:16399 IN IP4 192.168.11.151\r\n"
+ ,
+ "v=0\r\n"
+ "o=OsmoMSC 0 0 IN IP4 192.168.11.151\r\n"
+ "s=GSM Call\r\n"
+ "c=IN IP4 192.168.11.151\r\n"
+ "t=0 0\r\n"
+ "m=audio 16398 RTP/AVP 98\r\n"
+ "a=rtpmap:98 AMR/8000\r\n"
+ "a=fmtp:98 octet-align=1; mode-set=4\r\n"
+ "a=ptime:20\r\n"
+ ,
+ },
+ {
+ "v=0\r\n"
+ "o=FooBar 1565090289 1565090290 IN IP4 192.168.11.151\r\n"
+ "s=FooBar\r\n"
+ "c=IN IP4 192.168.11.140\r\n"
+ "t=0 0\r\n"
+ "m=audio 30436 RTP/AVP 18 0 4 8 101\r\n"
+ "a=rtpmap:18 G729/8000\r\n"
+ "a=rtpmap:0 PCMU/8000\r\n"
+ "a=rtpmap:4 G723/8000\r\n"
+ "a=rtpmap:8 PCMA/8000\r\n"
+ "a=rtpmap:101 telephone-event/8000\r\n"
+ "a=fmtp:101 0-15\r\n"
+ "a=sendrecv\r\n"
+ "a=rtcp:30437\r\n"
+ "a=ptime:20\r\n"
+ ,
+ "v=0\r\n"
+ "o=OsmoMSC 0 0 IN IP4 192.168.11.140\r\n" /* <- NOTE: loses the 'o=' address, uses only 'c=' */
+ "s=GSM Call\r\n"
+ "c=IN IP4 192.168.11.140\r\n"
+ "t=0 0\r\n"
+ "m=audio 30436 RTP/AVP 18 0 4 8 101\r\n"
+ "a=rtpmap:18 G729/8000\r\n"
+ "a=rtpmap:0 PCMU/8000\r\n"
+ "a=rtpmap:4 G723/8000\r\n"
+ "a=rtpmap:8 PCMA/8000\r\n"
+ "a=rtpmap:101 telephone-event/8000\r\n"
+ "a=fmtp:101 0-15\r\n"
+ "a=ptime:20\r\n"
+ "a=sendrecv\r\n"
+ ,
+ },
+};
+
+void test_parse_and_compose()
+{
+ int i;
+ bool ok = true;
+
+ printf("\n\n%s\n", __func__);
+
+ for (i = 0; i < ARRAY_SIZE(sdp_tests); i++) {
+ struct sdp_test_data *t = &sdp_tests[i];
+ struct sdp_msg sdp = {};
+ char str[1024];
+ printf("\n[%d]\n", i);
+ dump_sdp(t->sdp_input, "sdp input: ");
+
+ OSMO_ASSERT(sdp_msg_from_sdp_str(&sdp, t->sdp_input) == 0);
+ sdp_msg_to_sdp_str_buf(str, sizeof(str), &sdp);
+
+ dump_sdp(str, "sdp_msg_to_sdp_str_buf: ");
+ if (strcmp(str, t->expect_sdp_str)) {
+ int j;
+ ok = false;
+ printf("ERROR:\n");
+ dump_sdp(t->expect_sdp_str, "expect_sdp_str: ");
+ for (j = 0; t->expect_sdp_str[j]; j++) {
+ if (t->expect_sdp_str[j] != str[j]) {
+ printf("ERROR at position %d, at:\n", j);
+ dump_sdp(str + j, " mismatch: ");
+ break;
+ }
+ }
+ } else
+ printf("[%d] ok\n", i);
+ }
+
+ OSMO_ASSERT(ok);
+}
+
+struct sdp_intersect_test_data {
+ const char *descr;
+ const char *sdp_a;
+ const char *sdp_b;
+ const char *expect_intersection;
+};
+
+#define SDP_1 \
+ "v=0\r\n" \
+ "o=OsmoMSC 0 0 IN IP4 23.42.23.42\r\n" \
+ "s=GSM Call\r\n" \
+ "c=IN IP4 23.42.23.42\r\n" \
+ "t=0 0\r\n" \
+ "m=audio 30436 RTP/AVP 112 3 111 110\r\n" \
+ "a=rtpmap:112 AMR/8000\r\n" \
+ "a=fmtp:112 octet-align=1\r\n" \
+ "a=rtpmap:3 GSM/8000\r\n" \
+ "a=rtpmap:111 GSM-HR-08/8000\r\n" \
+ "a=rtpmap:110 GSM-EFR/8000\r\n" \
+ "a=ptime:20\r\n"
+
+#define SDP_2 \
+ "v=0\r\n" \
+ "o=OsmoMSC 0 0 IN IP4 23.42.23.42\r\n" \
+ "s=GSM Call\r\n" \
+ "c=IN IP4 23.42.23.42\r\n" \
+ "t=0 0\r\n" \
+ "m=audio 30436 RTP/AVP 112 110\r\n" \
+ "a=rtpmap:112 AMR/8000\r\n" \
+ "a=fmtp:112 octet-align=1\r\n" \
+ "a=rtpmap:110 GSM-EFR/8000\r\n" \
+ "a=ptime:20\r\n"
+
+#define SDP_3 \
+ "v=0\r\n" \
+ "o=OsmoMSC 0 0 IN IP4 23.42.23.42\r\n" \
+ "s=GSM Call\r\n" \
+ "c=IN IP4 23.42.23.42\r\n" \
+ "t=0 0\r\n" \
+ "m=audio 30436 RTP/AVP 3 111\r\n" \
+ "a=rtpmap:3 GSM/8000\r\n" \
+ "a=rtpmap:111 GSM-HR-08/8000\r\n" \
+ "a=ptime:20\r\n"
+
+
+struct sdp_intersect_test_data sdp_intersect_tests[] = {
+ {
+ "identical codecs lead to no change"
+ ,
+ SDP_1
+ ,
+ "c=IN IP4 5.6.7.8\r\n" \
+ "m=audio 12345 RTP/AVP 112 3 111 110\r\n"
+ "a=rtpmap:112 AMR/8000\r\n"
+ "a=fmtp:112 octet-align=1\r\n"
+ "a=rtpmap:3 GSM/8000\r\n"
+ "a=rtpmap:111 GSM-HR-08/8000\r\n"
+ "a=rtpmap:110 GSM-EFR/8000\r\n"
+ ,
+ SDP_1
+ },
+ {
+ "identical codecs in different order also lead to no change"
+ ,
+ SDP_1
+ ,
+ "c=IN IP4 5.6.7.8\r\n" \
+ "m=audio 12345 RTP/AVP 3 110 111 112\r\n"
+ "a=rtpmap:3 GSM/8000\r\n"
+ "a=rtpmap:110 GSM-EFR/8000\r\n"
+ "a=rtpmap:111 GSM-HR-08/8000\r\n"
+ "a=rtpmap:112 AMR/8000\r\n"
+ "a=fmtp:112 octet-align=1\r\n"
+ ,
+ SDP_1
+ },
+ {
+ "identical codecs with mismatching payload type numbers also lead to no change"
+ ,
+ SDP_1
+ ,
+ "c=IN IP4 5.6.7.8\r\n" \
+ "m=audio 12345 RTP/AVP 96 97 98 99\r\n"
+ "a=rtpmap:96 GSM/8000\r\n"
+ "a=rtpmap:97 GSM-EFR/8000\r\n"
+ "a=rtpmap:98 GSM-HR-08/8000\r\n"
+ "a=rtpmap:99 AMR/8000\r\n"
+ "a=fmtp:99 octet-align=1\r\n"
+ ,
+ SDP_1
+ },
+ {
+ "identical codecs plus some extra codecs also lead to no change"
+ ,
+ SDP_1
+ ,
+ "c=IN IP4 5.6.7.8\r\n" \
+ "m=audio 12345 RTP/AVP 8 0 96 97 98 99\r\n"
+ "a=rtpmap:8 PCMA/8000\r\n"
+ "a=rtpmap:0 PCMU/8000\r\n"
+ "a=rtpmap:96 GSM/8000\r\n"
+ "a=rtpmap:97 GSM-EFR/8000\r\n"
+ "a=rtpmap:98 GSM-HR-08/8000\r\n"
+ "a=rtpmap:99 AMR/8000\r\n"
+ "a=fmtp:99 octet-align=1\r\n"
+ ,
+ SDP_1
+ },
+ {
+ "some codecs removed",
+ SDP_1,
+ SDP_2,
+ SDP_2,
+ },
+ {
+ "other codecs removed",
+ SDP_1,
+ SDP_3,
+ SDP_3,
+ },
+ {
+ "all codecs removed",
+ SDP_1
+ ,
+ "s=empty"
+ ,
+ "v=0\r\n" \
+ "o=OsmoMSC 0 0 IN IP4 23.42.23.42\r\n" \
+ "s=GSM Call\r\n" \
+ "c=IN IP4 23.42.23.42\r\n" \
+ "t=0 0\r\n" \
+ "m=audio 30436 RTP/AVP\r\n" \
+ "a=ptime:20\r\n"
+ },
+ {
+ "some real world test case"
+ ,
+ "v=0\r\n"
+ "o=OsmoMSC 0 0 IN IP4 0.0.0.0\r\n"
+ "s=GSM Call\r\n"
+ "c=IN IP4 0.0.0.0\r\n"
+ "t=0 0\r\n"
+ "m=audio 0 RTP/AVP 112 113 110 3 111\r\n"
+ "a=rtpmap:112 AMR/8000\r\n"
+ "a=fmtp:112 octet-align=1;mode-set=0,1,2,3\r\n"
+ "a=rtpmap:113 AMR-WB/8000\r\n"
+ "a=fmtp:113 octet-align=1\r\n"
+ "a=rtpmap:110 GSM-EFR/8000\r\n"
+ "a=rtpmap:3 GSM/8000\r\n"
+ "a=rtpmap:111 GSM-HR-08/8000\r\n"
+ "a=ptime:20\r\n"
+ ,
+ "v=0\r\n"
+ "o=OsmoMSC 0 0 IN IP4 0.0.0.0\r\n"
+ "s=GSM Call\r\n"
+ "c=IN IP4 0.0.0.0\r\n"
+ "t=0 0\r\n"
+ "m=audio 0 RTP/AVP 112 113 110 3 111\r\n"
+ "a=rtpmap:112 AMR/8000\r\n"
+ "a=fmtp:112 octet-align=1;mode-set=0,1,2,3\r\n"
+ "a=rtpmap:113 AMR-WB/8000\r\n"
+ "a=fmtp:113 octet-align=1\r\n"
+ "a=rtpmap:110 GSM-EFR/8000\r\n"
+ "a=rtpmap:3 GSM/8000\r\n"
+ "a=rtpmap:111 GSM-HR-08/8000\r\n"
+ "a=ptime:20\r\n"
+ ,
+ "v=0\r\n"
+ "o=OsmoMSC 0 0 IN IP4 0.0.0.0\r\n"
+ "s=GSM Call\r\n"
+ "c=IN IP4 0.0.0.0\r\n"
+ "t=0 0\r\n"
+ "m=audio 0 RTP/AVP 112 113 110 3 111\r\n"
+ "a=rtpmap:112 AMR/8000\r\n"
+ "a=fmtp:112 octet-align=1;mode-set=0,1,2,3\r\n"
+ "a=rtpmap:113 AMR-WB/8000\r\n"
+ "a=fmtp:113 octet-align=1\r\n"
+ "a=rtpmap:110 GSM-EFR/8000\r\n"
+ "a=rtpmap:3 GSM/8000\r\n"
+ "a=rtpmap:111 GSM-HR-08/8000\r\n"
+ "a=ptime:20\r\n"
+ }
+};
+
+const char *sdp_msg_logstr(const struct sdp_msg *sdp)
+{
+ static char buf[1024];
+ sdp_msg_to_sdp_str_buf(buf, sizeof(buf), sdp);
+ return buf;
+}
+
+static void test_intersect()
+{
+ int i;
+ bool ok = true;
+ int rc;
+
+ printf("\n\n%s\n", __func__);
+
+ for (i = 0; i < ARRAY_SIZE(sdp_intersect_tests); i++) {
+ struct sdp_intersect_test_data *t = &sdp_intersect_tests[i];
+ struct sdp_msg sdp_a = {};
+ struct sdp_msg sdp_b = {};
+ char str[1024];
+ printf("\n[%d] %s\n", i, t->descr);
+ dump_sdp(t->sdp_a, "SDP A: ");
+ dump_sdp(t->sdp_b, " SDP B: ");
+
+ rc = sdp_msg_from_sdp_str(&sdp_a, t->sdp_a);
+ if (rc) {
+ printf("ERROR parsing SDP A: %d\n", rc);
+ break;
+ }
+ dump_sdp(sdp_msg_logstr(&sdp_a), "parsed SDP A: ");
+ rc = sdp_msg_from_sdp_str(&sdp_b, t->sdp_b);
+ if (rc) {
+ printf("ERROR parsing SDP A: %d\n", rc);
+ break;
+ }
+ dump_sdp(sdp_msg_logstr(&sdp_b), "parsed SDP B: ");
+ sdp_audio_codecs_intersection(&sdp_a.audio_codecs, &sdp_b.audio_codecs, false);
+ sdp_msg_to_sdp_str_buf(str, sizeof(str), &sdp_a);
+
+ dump_sdp(str, "sdp_msg_intersection(a,b): ");
+ if (strcmp(str, t->expect_intersection)) {
+ int j;
+ ok = false;
+ printf("ERROR:\n");
+ dump_sdp(t->expect_intersection, "expect_intersection: ");
+ for (j = 0; t->expect_intersection[j]; j++) {
+ if (t->expect_intersection[j] != str[j]) {
+ printf("ERROR at position %d, at:\n", j);
+ dump_sdp(str + j, " mismatch: ");
+ break;
+ }
+ }
+ } else
+ printf("[%d] ok\n", i);
+ }
+
+ OSMO_ASSERT(ok);
+}
+
+struct sdp_select_test_data {
+ const char *sdp;
+ unsigned int select_payload_type;
+ const char *expect_sdp;
+};
+
+struct sdp_select_test_data sdp_select_tests[] = {
+ {
+ "v=0\r\n"
+ "o=OsmoMSC 0 0 IN IP4 23.42.23.42\r\n"
+ "s=GSM Call\r\n"
+ "c=IN IP4 23.42.23.42\r\n"
+ "t=0 0\r\n"
+ "m=audio 30436 RTP/AVP 112 3 111 110\r\n"
+ "a=rtpmap:112 AMR/8000\r\n"
+ "a=fmtp:112 octet-align=1\r\n"
+ "a=rtpmap:3 GSM/8000\r\n"
+ "a=rtpmap:111 GSM-HR-08/8000\r\n"
+ "a=rtpmap:110 GSM-EFR/8000\r\n"
+ "a=ptime:20\r\n"
+ ,
+ 112,
+ NULL
+ },
+ {
+ "v=0\r\n"
+ "o=OsmoMSC 0 0 IN IP4 23.42.23.42\r\n"
+ "s=GSM Call\r\n"
+ "c=IN IP4 23.42.23.42\r\n"
+ "t=0 0\r\n"
+ "m=audio 30436 RTP/AVP 112 3 111 110\r\n"
+ "a=rtpmap:112 AMR/8000\r\n"
+ "a=fmtp:112 octet-align=1\r\n"
+ "a=rtpmap:3 GSM/8000\r\n"
+ "a=rtpmap:111 GSM-HR-08/8000\r\n"
+ "a=rtpmap:110 GSM-EFR/8000\r\n"
+ "a=ptime:20\r\n"
+ ,
+ 3,
+ "v=0\r\n"
+ "o=OsmoMSC 0 0 IN IP4 23.42.23.42\r\n"
+ "s=GSM Call\r\n"
+ "c=IN IP4 23.42.23.42\r\n"
+ "t=0 0\r\n"
+ "m=audio 30436 RTP/AVP 3 112 111 110\r\n"
+ "a=rtpmap:3 GSM/8000\r\n"
+ "a=rtpmap:112 AMR/8000\r\n"
+ "a=fmtp:112 octet-align=1\r\n"
+ "a=rtpmap:111 GSM-HR-08/8000\r\n"
+ "a=rtpmap:110 GSM-EFR/8000\r\n"
+ "a=ptime:20\r\n"
+ },
+ {
+ "v=0\r\n"
+ "o=OsmoMSC 0 0 IN IP4 23.42.23.42\r\n"
+ "s=GSM Call\r\n"
+ "c=IN IP4 23.42.23.42\r\n"
+ "t=0 0\r\n"
+ "m=audio 30436 RTP/AVP 112 3 111 110\r\n"
+ "a=rtpmap:112 AMR/8000\r\n"
+ "a=fmtp:112 octet-align=1\r\n"
+ "a=rtpmap:3 GSM/8000\r\n"
+ "a=rtpmap:111 GSM-HR-08/8000\r\n"
+ "a=rtpmap:110 GSM-EFR/8000\r\n"
+ "a=ptime:20\r\n"
+ ,
+ 111,
+ "v=0\r\n"
+ "o=OsmoMSC 0 0 IN IP4 23.42.23.42\r\n"
+ "s=GSM Call\r\n"
+ "c=IN IP4 23.42.23.42\r\n"
+ "t=0 0\r\n"
+ "m=audio 30436 RTP/AVP 111 112 3 110\r\n"
+ "a=rtpmap:111 GSM-HR-08/8000\r\n"
+ "a=rtpmap:112 AMR/8000\r\n"
+ "a=fmtp:112 octet-align=1\r\n"
+ "a=rtpmap:3 GSM/8000\r\n"
+ "a=rtpmap:110 GSM-EFR/8000\r\n"
+ "a=ptime:20\r\n"
+ },
+ {
+ "v=0\r\n"
+ "o=OsmoMSC 0 0 IN IP4 23.42.23.42\r\n"
+ "s=GSM Call\r\n"
+ "c=IN IP4 23.42.23.42\r\n"
+ "t=0 0\r\n"
+ "m=audio 30436 RTP/AVP 112 3 111 110\r\n"
+ "a=rtpmap:112 AMR/8000\r\n"
+ "a=fmtp:112 octet-align=1\r\n"
+ "a=rtpmap:3 GSM/8000\r\n"
+ "a=rtpmap:111 GSM-HR-08/8000\r\n"
+ "a=rtpmap:110 GSM-EFR/8000\r\n"
+ "a=ptime:20\r\n"
+ ,
+ 110,
+ "v=0\r\n"
+ "o=OsmoMSC 0 0 IN IP4 23.42.23.42\r\n"
+ "s=GSM Call\r\n"
+ "c=IN IP4 23.42.23.42\r\n"
+ "t=0 0\r\n"
+ "m=audio 30436 RTP/AVP 110 112 3 111\r\n"
+ "a=rtpmap:110 GSM-EFR/8000\r\n"
+ "a=rtpmap:112 AMR/8000\r\n"
+ "a=fmtp:112 octet-align=1\r\n"
+ "a=rtpmap:3 GSM/8000\r\n"
+ "a=rtpmap:111 GSM-HR-08/8000\r\n"
+ "a=ptime:20\r\n"
+ },
+
+};
+
+static void test_select()
+{
+ int i;
+ bool ok = true;
+ int rc;
+
+ printf("\n\n%s\n", __func__);
+
+ for (i = 0; i < ARRAY_SIZE(sdp_select_tests); i++) {
+ struct sdp_select_test_data *t = &sdp_select_tests[i];
+ struct sdp_msg sdp = {};
+ struct sdp_audio_codec *codec;
+ char buf[1024];
+ const char *expect_sdp;
+
+ printf("\n[%d]\n", i);
+ rc = sdp_msg_from_sdp_str(&sdp, t->sdp);
+ if (rc) {
+ printf("ERROR parsing SDP: %d\n", rc);
+ break;
+ }
+ printf("SDP: %s\n", sdp_audio_codecs_to_str(&sdp.audio_codecs));
+ codec = sdp_audio_codecs_by_payload_type(&sdp.audio_codecs, t->select_payload_type, false);
+ OSMO_ASSERT(codec);
+ printf("Select: %s\n", sdp_audio_codec_to_str(codec));
+
+ sdp_audio_codecs_select(&sdp.audio_codecs, codec);
+
+ printf("SDP: %s\n", sdp_audio_codecs_to_str(&sdp.audio_codecs));
+ sdp_msg_to_sdp_str_buf(buf, sizeof(buf), &sdp);
+
+ expect_sdp = t->expect_sdp ? : t->sdp;
+ if (strcmp(buf, expect_sdp)) {
+ int j;
+ ok = false;
+ printf("ERROR:\n");
+ dump_sdp(buf, "selection result: ");
+ dump_sdp(expect_sdp, "expect result: ");
+ for (j = 0; expect_sdp[j]; j++) {
+ if (expect_sdp[j] != buf[j]) {
+ printf("ERROR at position %d, at:\n", j);
+ dump_sdp(buf + j, " mismatch: ");
+ break;
+ }
+ }
+ } else
+ printf("[%d] ok\n", i);
+ }
+
+ OSMO_ASSERT(ok);
+}
+
+int main(void)
+{
+ test_parse_and_compose();
+ test_intersect();
+ test_select();
+ return 0;
+}
diff --git a/tests/sdp_msg/sdp_msg_test.err b/tests/sdp_msg/sdp_msg_test.err
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/tests/sdp_msg/sdp_msg_test.err
diff --git a/tests/sdp_msg/sdp_msg_test.ok b/tests/sdp_msg/sdp_msg_test.ok
new file mode 100644
index 000000000..51a236b51
--- /dev/null
+++ b/tests/sdp_msg/sdp_msg_test.ok
@@ -0,0 +1,592 @@
+
+
+test_parse_and_compose
+
+[0]
+sdp input: v=0\r\n
+sdp input: o=- 5628250 5628250 IN IP4 192.168.11.121\r\n
+sdp input: s=-\r\n
+sdp input: c=IN IP4 192.168.11.121\r\n
+sdp input: t=0 0\r\n
+sdp input: m=audio 10020 RTP/AVP 18 0 2 4 8 96 97 98 100 101\r\n
+sdp input: a=rtpmap:18 G729/8000\r\n
+sdp input: a=rtpmap:0 PCMU/8000\r\n
+sdp input: a=rtpmap:2 G726-32/8000\r\n
+sdp input: a=rtpmap:4 G723/8000\r\n
+sdp input: a=rtpmap:8 PCMA/8000\r\n
+sdp input: a=rtpmap:96 G726-40/8000\r\n
+sdp input: a=rtpmap:97 G726-24/8000\r\n
+sdp input: a=rtpmap:98 G726-16/8000\r\n
+sdp input: a=rtpmap:100 NSE/8000\r\n
+sdp input: a=fmtp:100 192-193\r\n
+sdp input: a=rtpmap:101 telephone-event/8000\r\n
+sdp input: a=fmtp:101 0-15\r\n
+sdp input: a=ptime:20\r\n
+sdp input: a=sendrecv\r\n
+sdp_msg_to_sdp_str_buf: v=0\r\n
+sdp_msg_to_sdp_str_buf: o=OsmoMSC 0 0 IN IP4 192.168.11.121\r\n
+sdp_msg_to_sdp_str_buf: s=GSM Call\r\n
+sdp_msg_to_sdp_str_buf: c=IN IP4 192.168.11.121\r\n
+sdp_msg_to_sdp_str_buf: t=0 0\r\n
+sdp_msg_to_sdp_str_buf: m=audio 10020 RTP/AVP 18 0 2 4 8 96 97 98 100 101\r\n
+sdp_msg_to_sdp_str_buf: a=rtpmap:18 G729/8000\r\n
+sdp_msg_to_sdp_str_buf: a=rtpmap:0 PCMU/8000\r\n
+sdp_msg_to_sdp_str_buf: a=rtpmap:2 G726-32/8000\r\n
+sdp_msg_to_sdp_str_buf: a=rtpmap:4 G723/8000\r\n
+sdp_msg_to_sdp_str_buf: a=rtpmap:8 PCMA/8000\r\n
+sdp_msg_to_sdp_str_buf: a=rtpmap:96 G726-40/8000\r\n
+sdp_msg_to_sdp_str_buf: a=rtpmap:97 G726-24/8000\r\n
+sdp_msg_to_sdp_str_buf: a=rtpmap:98 G726-16/8000\r\n
+sdp_msg_to_sdp_str_buf: a=rtpmap:100 NSE/8000\r\n
+sdp_msg_to_sdp_str_buf: a=fmtp:100 192-193\r\n
+sdp_msg_to_sdp_str_buf: a=rtpmap:101 telephone-event/8000\r\n
+sdp_msg_to_sdp_str_buf: a=fmtp:101 0-15\r\n
+sdp_msg_to_sdp_str_buf: a=ptime:20\r\n
+sdp_msg_to_sdp_str_buf: a=sendrecv\r\n
+[0] ok
+
+[1]
+sdp input: v=0\r\n
+sdp input: o=FooBar 1565090289 1565090290 IN IP4 192.168.11.151\r\n
+sdp input: s=FooBar\r\n
+sdp input: c=IN IP4 192.168.11.151\r\n
+sdp input: t=0 0\r\n
+sdp input: m=audio 16398 RTP/AVP 98\r\n
+sdp input: a=rtpmap:98 AMR/8000\r\n
+sdp input: a=fmtp:98 octet-align=1; mode-set=4\r\n
+sdp input: a=ptime:20\r\n
+sdp input: a=rtcp:16399 IN IP4 192.168.11.151\r\n
+sdp_msg_to_sdp_str_buf: v=0\r\n
+sdp_msg_to_sdp_str_buf: o=OsmoMSC 0 0 IN IP4 192.168.11.151\r\n
+sdp_msg_to_sdp_str_buf: s=GSM Call\r\n
+sdp_msg_to_sdp_str_buf: c=IN IP4 192.168.11.151\r\n
+sdp_msg_to_sdp_str_buf: t=0 0\r\n
+sdp_msg_to_sdp_str_buf: m=audio 16398 RTP/AVP 98\r\n
+sdp_msg_to_sdp_str_buf: a=rtpmap:98 AMR/8000\r\n
+sdp_msg_to_sdp_str_buf: a=fmtp:98 octet-align=1; mode-set=4\r\n
+sdp_msg_to_sdp_str_buf: a=ptime:20\r\n
+[1] ok
+
+[2]
+sdp input: v=0\r\n
+sdp input: o=FooBar 1565090289 1565090290 IN IP4 192.168.11.151\r\n
+sdp input: s=FooBar\r\n
+sdp input: c=IN IP4 192.168.11.140\r\n
+sdp input: t=0 0\r\n
+sdp input: m=audio 30436 RTP/AVP 18 0 4 8 101\r\n
+sdp input: a=rtpmap:18 G729/8000\r\n
+sdp input: a=rtpmap:0 PCMU/8000\r\n
+sdp input: a=rtpmap:4 G723/8000\r\n
+sdp input: a=rtpmap:8 PCMA/8000\r\n
+sdp input: a=rtpmap:101 telephone-event/8000\r\n
+sdp input: a=fmtp:101 0-15\r\n
+sdp input: a=sendrecv\r\n
+sdp input: a=rtcp:30437\r\n
+sdp input: a=ptime:20\r\n
+sdp_msg_to_sdp_str_buf: v=0\r\n
+sdp_msg_to_sdp_str_buf: o=OsmoMSC 0 0 IN IP4 192.168.11.140\r\n
+sdp_msg_to_sdp_str_buf: s=GSM Call\r\n
+sdp_msg_to_sdp_str_buf: c=IN IP4 192.168.11.140\r\n
+sdp_msg_to_sdp_str_buf: t=0 0\r\n
+sdp_msg_to_sdp_str_buf: m=audio 30436 RTP/AVP 18 0 4 8 101\r\n
+sdp_msg_to_sdp_str_buf: a=rtpmap:18 G729/8000\r\n
+sdp_msg_to_sdp_str_buf: a=rtpmap:0 PCMU/8000\r\n
+sdp_msg_to_sdp_str_buf: a=rtpmap:4 G723/8000\r\n
+sdp_msg_to_sdp_str_buf: a=rtpmap:8 PCMA/8000\r\n
+sdp_msg_to_sdp_str_buf: a=rtpmap:101 telephone-event/8000\r\n
+sdp_msg_to_sdp_str_buf: a=fmtp:101 0-15\r\n
+sdp_msg_to_sdp_str_buf: a=ptime:20\r\n
+sdp_msg_to_sdp_str_buf: a=sendrecv\r\n
+[2] ok
+
+
+test_intersect
+
+[0] identical codecs lead to no change
+SDP A: v=0\r\n
+SDP A: o=OsmoMSC 0 0 IN IP4 23.42.23.42\r\n
+SDP A: s=GSM Call\r\n
+SDP A: c=IN IP4 23.42.23.42\r\n
+SDP A: t=0 0\r\n
+SDP A: m=audio 30436 RTP/AVP 112 3 111 110\r\n
+SDP A: a=rtpmap:112 AMR/8000\r\n
+SDP A: a=fmtp:112 octet-align=1\r\n
+SDP A: a=rtpmap:3 GSM/8000\r\n
+SDP A: a=rtpmap:111 GSM-HR-08/8000\r\n
+SDP A: a=rtpmap:110 GSM-EFR/8000\r\n
+SDP A: a=ptime:20\r\n
+ SDP B: c=IN IP4 5.6.7.8\r\n
+ SDP B: m=audio 12345 RTP/AVP 112 3 111 110\r\n
+ SDP B: a=rtpmap:112 AMR/8000\r\n
+ SDP B: a=fmtp:112 octet-align=1\r\n
+ SDP B: a=rtpmap:3 GSM/8000\r\n
+ SDP B: a=rtpmap:111 GSM-HR-08/8000\r\n
+ SDP B: a=rtpmap:110 GSM-EFR/8000\r\n
+parsed SDP A: v=0\r\n
+parsed SDP A: o=OsmoMSC 0 0 IN IP4 23.42.23.42\r\n
+parsed SDP A: s=GSM Call\r\n
+parsed SDP A: c=IN IP4 23.42.23.42\r\n
+parsed SDP A: t=0 0\r\n
+parsed SDP A: m=audio 30436 RTP/AVP 112 3 111 110\r\n
+parsed SDP A: a=rtpmap:112 AMR/8000\r\n
+parsed SDP A: a=fmtp:112 octet-align=1\r\n
+parsed SDP A: a=rtpmap:3 GSM/8000\r\n
+parsed SDP A: a=rtpmap:111 GSM-HR-08/8000\r\n
+parsed SDP A: a=rtpmap:110 GSM-EFR/8000\r\n
+parsed SDP A: a=ptime:20\r\n
+parsed SDP B: v=0\r\n
+parsed SDP B: o=OsmoMSC 0 0 IN IP4 5.6.7.8\r\n
+parsed SDP B: s=GSM Call\r\n
+parsed SDP B: c=IN IP4 5.6.7.8\r\n
+parsed SDP B: t=0 0\r\n
+parsed SDP B: m=audio 12345 RTP/AVP 112 3 111 110\r\n
+parsed SDP B: a=rtpmap:112 AMR/8000\r\n
+parsed SDP B: a=fmtp:112 octet-align=1\r\n
+parsed SDP B: a=rtpmap:3 GSM/8000\r\n
+parsed SDP B: a=rtpmap:111 GSM-HR-08/8000\r\n
+parsed SDP B: a=rtpmap:110 GSM-EFR/8000\r\n
+parsed SDP B: a=ptime:20\r\n
+sdp_msg_intersection(a,b): v=0\r\n
+sdp_msg_intersection(a,b): o=OsmoMSC 0 0 IN IP4 23.42.23.42\r\n
+sdp_msg_intersection(a,b): s=GSM Call\r\n
+sdp_msg_intersection(a,b): c=IN IP4 23.42.23.42\r\n
+sdp_msg_intersection(a,b): t=0 0\r\n
+sdp_msg_intersection(a,b): m=audio 30436 RTP/AVP 112 3 111 110\r\n
+sdp_msg_intersection(a,b): a=rtpmap:112 AMR/8000\r\n
+sdp_msg_intersection(a,b): a=fmtp:112 octet-align=1\r\n
+sdp_msg_intersection(a,b): a=rtpmap:3 GSM/8000\r\n
+sdp_msg_intersection(a,b): a=rtpmap:111 GSM-HR-08/8000\r\n
+sdp_msg_intersection(a,b): a=rtpmap:110 GSM-EFR/8000\r\n
+sdp_msg_intersection(a,b): a=ptime:20\r\n
+[0] ok
+
+[1] identical codecs in different order also lead to no change
+SDP A: v=0\r\n
+SDP A: o=OsmoMSC 0 0 IN IP4 23.42.23.42\r\n
+SDP A: s=GSM Call\r\n
+SDP A: c=IN IP4 23.42.23.42\r\n
+SDP A: t=0 0\r\n
+SDP A: m=audio 30436 RTP/AVP 112 3 111 110\r\n
+SDP A: a=rtpmap:112 AMR/8000\r\n
+SDP A: a=fmtp:112 octet-align=1\r\n
+SDP A: a=rtpmap:3 GSM/8000\r\n
+SDP A: a=rtpmap:111 GSM-HR-08/8000\r\n
+SDP A: a=rtpmap:110 GSM-EFR/8000\r\n
+SDP A: a=ptime:20\r\n
+ SDP B: c=IN IP4 5.6.7.8\r\n
+ SDP B: m=audio 12345 RTP/AVP 3 110 111 112\r\n
+ SDP B: a=rtpmap:3 GSM/8000\r\n
+ SDP B: a=rtpmap:110 GSM-EFR/8000\r\n
+ SDP B: a=rtpmap:111 GSM-HR-08/8000\r\n
+ SDP B: a=rtpmap:112 AMR/8000\r\n
+ SDP B: a=fmtp:112 octet-align=1\r\n
+parsed SDP A: v=0\r\n
+parsed SDP A: o=OsmoMSC 0 0 IN IP4 23.42.23.42\r\n
+parsed SDP A: s=GSM Call\r\n
+parsed SDP A: c=IN IP4 23.42.23.42\r\n
+parsed SDP A: t=0 0\r\n
+parsed SDP A: m=audio 30436 RTP/AVP 112 3 111 110\r\n
+parsed SDP A: a=rtpmap:112 AMR/8000\r\n
+parsed SDP A: a=fmtp:112 octet-align=1\r\n
+parsed SDP A: a=rtpmap:3 GSM/8000\r\n
+parsed SDP A: a=rtpmap:111 GSM-HR-08/8000\r\n
+parsed SDP A: a=rtpmap:110 GSM-EFR/8000\r\n
+parsed SDP A: a=ptime:20\r\n
+parsed SDP B: v=0\r\n
+parsed SDP B: o=OsmoMSC 0 0 IN IP4 5.6.7.8\r\n
+parsed SDP B: s=GSM Call\r\n
+parsed SDP B: c=IN IP4 5.6.7.8\r\n
+parsed SDP B: t=0 0\r\n
+parsed SDP B: m=audio 12345 RTP/AVP 3 110 111 112\r\n
+parsed SDP B: a=rtpmap:3 GSM/8000\r\n
+parsed SDP B: a=rtpmap:110 GSM-EFR/8000\r\n
+parsed SDP B: a=rtpmap:111 GSM-HR-08/8000\r\n
+parsed SDP B: a=rtpmap:112 AMR/8000\r\n
+parsed SDP B: a=fmtp:112 octet-align=1\r\n
+parsed SDP B: a=ptime:20\r\n
+sdp_msg_intersection(a,b): v=0\r\n
+sdp_msg_intersection(a,b): o=OsmoMSC 0 0 IN IP4 23.42.23.42\r\n
+sdp_msg_intersection(a,b): s=GSM Call\r\n
+sdp_msg_intersection(a,b): c=IN IP4 23.42.23.42\r\n
+sdp_msg_intersection(a,b): t=0 0\r\n
+sdp_msg_intersection(a,b): m=audio 30436 RTP/AVP 112 3 111 110\r\n
+sdp_msg_intersection(a,b): a=rtpmap:112 AMR/8000\r\n
+sdp_msg_intersection(a,b): a=fmtp:112 octet-align=1\r\n
+sdp_msg_intersection(a,b): a=rtpmap:3 GSM/8000\r\n
+sdp_msg_intersection(a,b): a=rtpmap:111 GSM-HR-08/8000\r\n
+sdp_msg_intersection(a,b): a=rtpmap:110 GSM-EFR/8000\r\n
+sdp_msg_intersection(a,b): a=ptime:20\r\n
+[1] ok
+
+[2] identical codecs with mismatching payload type numbers also lead to no change
+SDP A: v=0\r\n
+SDP A: o=OsmoMSC 0 0 IN IP4 23.42.23.42\r\n
+SDP A: s=GSM Call\r\n
+SDP A: c=IN IP4 23.42.23.42\r\n
+SDP A: t=0 0\r\n
+SDP A: m=audio 30436 RTP/AVP 112 3 111 110\r\n
+SDP A: a=rtpmap:112 AMR/8000\r\n
+SDP A: a=fmtp:112 octet-align=1\r\n
+SDP A: a=rtpmap:3 GSM/8000\r\n
+SDP A: a=rtpmap:111 GSM-HR-08/8000\r\n
+SDP A: a=rtpmap:110 GSM-EFR/8000\r\n
+SDP A: a=ptime:20\r\n
+ SDP B: c=IN IP4 5.6.7.8\r\n
+ SDP B: m=audio 12345 RTP/AVP 96 97 98 99\r\n
+ SDP B: a=rtpmap:96 GSM/8000\r\n
+ SDP B: a=rtpmap:97 GSM-EFR/8000\r\n
+ SDP B: a=rtpmap:98 GSM-HR-08/8000\r\n
+ SDP B: a=rtpmap:99 AMR/8000\r\n
+ SDP B: a=fmtp:99 octet-align=1\r\n
+parsed SDP A: v=0\r\n
+parsed SDP A: o=OsmoMSC 0 0 IN IP4 23.42.23.42\r\n
+parsed SDP A: s=GSM Call\r\n
+parsed SDP A: c=IN IP4 23.42.23.42\r\n
+parsed SDP A: t=0 0\r\n
+parsed SDP A: m=audio 30436 RTP/AVP 112 3 111 110\r\n
+parsed SDP A: a=rtpmap:112 AMR/8000\r\n
+parsed SDP A: a=fmtp:112 octet-align=1\r\n
+parsed SDP A: a=rtpmap:3 GSM/8000\r\n
+parsed SDP A: a=rtpmap:111 GSM-HR-08/8000\r\n
+parsed SDP A: a=rtpmap:110 GSM-EFR/8000\r\n
+parsed SDP A: a=ptime:20\r\n
+parsed SDP B: v=0\r\n
+parsed SDP B: o=OsmoMSC 0 0 IN IP4 5.6.7.8\r\n
+parsed SDP B: s=GSM Call\r\n
+parsed SDP B: c=IN IP4 5.6.7.8\r\n
+parsed SDP B: t=0 0\r\n
+parsed SDP B: m=audio 12345 RTP/AVP 96 97 98 99\r\n
+parsed SDP B: a=rtpmap:96 GSM/8000\r\n
+parsed SDP B: a=rtpmap:97 GSM-EFR/8000\r\n
+parsed SDP B: a=rtpmap:98 GSM-HR-08/8000\r\n
+parsed SDP B: a=rtpmap:99 AMR/8000\r\n
+parsed SDP B: a=fmtp:99 octet-align=1\r\n
+parsed SDP B: a=ptime:20\r\n
+sdp_msg_intersection(a,b): v=0\r\n
+sdp_msg_intersection(a,b): o=OsmoMSC 0 0 IN IP4 23.42.23.42\r\n
+sdp_msg_intersection(a,b): s=GSM Call\r\n
+sdp_msg_intersection(a,b): c=IN IP4 23.42.23.42\r\n
+sdp_msg_intersection(a,b): t=0 0\r\n
+sdp_msg_intersection(a,b): m=audio 30436 RTP/AVP 112 3 111 110\r\n
+sdp_msg_intersection(a,b): a=rtpmap:112 AMR/8000\r\n
+sdp_msg_intersection(a,b): a=fmtp:112 octet-align=1\r\n
+sdp_msg_intersection(a,b): a=rtpmap:3 GSM/8000\r\n
+sdp_msg_intersection(a,b): a=rtpmap:111 GSM-HR-08/8000\r\n
+sdp_msg_intersection(a,b): a=rtpmap:110 GSM-EFR/8000\r\n
+sdp_msg_intersection(a,b): a=ptime:20\r\n
+[2] ok
+
+[3] identical codecs plus some extra codecs also lead to no change
+SDP A: v=0\r\n
+SDP A: o=OsmoMSC 0 0 IN IP4 23.42.23.42\r\n
+SDP A: s=GSM Call\r\n
+SDP A: c=IN IP4 23.42.23.42\r\n
+SDP A: t=0 0\r\n
+SDP A: m=audio 30436 RTP/AVP 112 3 111 110\r\n
+SDP A: a=rtpmap:112 AMR/8000\r\n
+SDP A: a=fmtp:112 octet-align=1\r\n
+SDP A: a=rtpmap:3 GSM/8000\r\n
+SDP A: a=rtpmap:111 GSM-HR-08/8000\r\n
+SDP A: a=rtpmap:110 GSM-EFR/8000\r\n
+SDP A: a=ptime:20\r\n
+ SDP B: c=IN IP4 5.6.7.8\r\n
+ SDP B: m=audio 12345 RTP/AVP 8 0 96 97 98 99\r\n
+ SDP B: a=rtpmap:8 PCMA/8000\r\n
+ SDP B: a=rtpmap:0 PCMU/8000\r\n
+ SDP B: a=rtpmap:96 GSM/8000\r\n
+ SDP B: a=rtpmap:97 GSM-EFR/8000\r\n
+ SDP B: a=rtpmap:98 GSM-HR-08/8000\r\n
+ SDP B: a=rtpmap:99 AMR/8000\r\n
+ SDP B: a=fmtp:99 octet-align=1\r\n
+parsed SDP A: v=0\r\n
+parsed SDP A: o=OsmoMSC 0 0 IN IP4 23.42.23.42\r\n
+parsed SDP A: s=GSM Call\r\n
+parsed SDP A: c=IN IP4 23.42.23.42\r\n
+parsed SDP A: t=0 0\r\n
+parsed SDP A: m=audio 30436 RTP/AVP 112 3 111 110\r\n
+parsed SDP A: a=rtpmap:112 AMR/8000\r\n
+parsed SDP A: a=fmtp:112 octet-align=1\r\n
+parsed SDP A: a=rtpmap:3 GSM/8000\r\n
+parsed SDP A: a=rtpmap:111 GSM-HR-08/8000\r\n
+parsed SDP A: a=rtpmap:110 GSM-EFR/8000\r\n
+parsed SDP A: a=ptime:20\r\n
+parsed SDP B: v=0\r\n
+parsed SDP B: o=OsmoMSC 0 0 IN IP4 5.6.7.8\r\n
+parsed SDP B: s=GSM Call\r\n
+parsed SDP B: c=IN IP4 5.6.7.8\r\n
+parsed SDP B: t=0 0\r\n
+parsed SDP B: m=audio 12345 RTP/AVP 8 0 96 97 98 99\r\n
+parsed SDP B: a=rtpmap:8 PCMA/8000\r\n
+parsed SDP B: a=rtpmap:0 PCMU/8000\r\n
+parsed SDP B: a=rtpmap:96 GSM/8000\r\n
+parsed SDP B: a=rtpmap:97 GSM-EFR/8000\r\n
+parsed SDP B: a=rtpmap:98 GSM-HR-08/8000\r\n
+parsed SDP B: a=rtpmap:99 AMR/8000\r\n
+parsed SDP B: a=fmtp:99 octet-align=1\r\n
+parsed SDP B: a=ptime:20\r\n
+sdp_msg_intersection(a,b): v=0\r\n
+sdp_msg_intersection(a,b): o=OsmoMSC 0 0 IN IP4 23.42.23.42\r\n
+sdp_msg_intersection(a,b): s=GSM Call\r\n
+sdp_msg_intersection(a,b): c=IN IP4 23.42.23.42\r\n
+sdp_msg_intersection(a,b): t=0 0\r\n
+sdp_msg_intersection(a,b): m=audio 30436 RTP/AVP 112 3 111 110\r\n
+sdp_msg_intersection(a,b): a=rtpmap:112 AMR/8000\r\n
+sdp_msg_intersection(a,b): a=fmtp:112 octet-align=1\r\n
+sdp_msg_intersection(a,b): a=rtpmap:3 GSM/8000\r\n
+sdp_msg_intersection(a,b): a=rtpmap:111 GSM-HR-08/8000\r\n
+sdp_msg_intersection(a,b): a=rtpmap:110 GSM-EFR/8000\r\n
+sdp_msg_intersection(a,b): a=ptime:20\r\n
+[3] ok
+
+[4] some codecs removed
+SDP A: v=0\r\n
+SDP A: o=OsmoMSC 0 0 IN IP4 23.42.23.42\r\n
+SDP A: s=GSM Call\r\n
+SDP A: c=IN IP4 23.42.23.42\r\n
+SDP A: t=0 0\r\n
+SDP A: m=audio 30436 RTP/AVP 112 3 111 110\r\n
+SDP A: a=rtpmap:112 AMR/8000\r\n
+SDP A: a=fmtp:112 octet-align=1\r\n
+SDP A: a=rtpmap:3 GSM/8000\r\n
+SDP A: a=rtpmap:111 GSM-HR-08/8000\r\n
+SDP A: a=rtpmap:110 GSM-EFR/8000\r\n
+SDP A: a=ptime:20\r\n
+ SDP B: v=0\r\n
+ SDP B: o=OsmoMSC 0 0 IN IP4 23.42.23.42\r\n
+ SDP B: s=GSM Call\r\n
+ SDP B: c=IN IP4 23.42.23.42\r\n
+ SDP B: t=0 0\r\n
+ SDP B: m=audio 30436 RTP/AVP 112 110\r\n
+ SDP B: a=rtpmap:112 AMR/8000\r\n
+ SDP B: a=fmtp:112 octet-align=1\r\n
+ SDP B: a=rtpmap:110 GSM-EFR/8000\r\n
+ SDP B: a=ptime:20\r\n
+parsed SDP A: v=0\r\n
+parsed SDP A: o=OsmoMSC 0 0 IN IP4 23.42.23.42\r\n
+parsed SDP A: s=GSM Call\r\n
+parsed SDP A: c=IN IP4 23.42.23.42\r\n
+parsed SDP A: t=0 0\r\n
+parsed SDP A: m=audio 30436 RTP/AVP 112 3 111 110\r\n
+parsed SDP A: a=rtpmap:112 AMR/8000\r\n
+parsed SDP A: a=fmtp:112 octet-align=1\r\n
+parsed SDP A: a=rtpmap:3 GSM/8000\r\n
+parsed SDP A: a=rtpmap:111 GSM-HR-08/8000\r\n
+parsed SDP A: a=rtpmap:110 GSM-EFR/8000\r\n
+parsed SDP A: a=ptime:20\r\n
+parsed SDP B: v=0\r\n
+parsed SDP B: o=OsmoMSC 0 0 IN IP4 23.42.23.42\r\n
+parsed SDP B: s=GSM Call\r\n
+parsed SDP B: c=IN IP4 23.42.23.42\r\n
+parsed SDP B: t=0 0\r\n
+parsed SDP B: m=audio 30436 RTP/AVP 112 110\r\n
+parsed SDP B: a=rtpmap:112 AMR/8000\r\n
+parsed SDP B: a=fmtp:112 octet-align=1\r\n
+parsed SDP B: a=rtpmap:110 GSM-EFR/8000\r\n
+parsed SDP B: a=ptime:20\r\n
+sdp_msg_intersection(a,b): v=0\r\n
+sdp_msg_intersection(a,b): o=OsmoMSC 0 0 IN IP4 23.42.23.42\r\n
+sdp_msg_intersection(a,b): s=GSM Call\r\n
+sdp_msg_intersection(a,b): c=IN IP4 23.42.23.42\r\n
+sdp_msg_intersection(a,b): t=0 0\r\n
+sdp_msg_intersection(a,b): m=audio 30436 RTP/AVP 112 110\r\n
+sdp_msg_intersection(a,b): a=rtpmap:112 AMR/8000\r\n
+sdp_msg_intersection(a,b): a=fmtp:112 octet-align=1\r\n
+sdp_msg_intersection(a,b): a=rtpmap:110 GSM-EFR/8000\r\n
+sdp_msg_intersection(a,b): a=ptime:20\r\n
+[4] ok
+
+[5] other codecs removed
+SDP A: v=0\r\n
+SDP A: o=OsmoMSC 0 0 IN IP4 23.42.23.42\r\n
+SDP A: s=GSM Call\r\n
+SDP A: c=IN IP4 23.42.23.42\r\n
+SDP A: t=0 0\r\n
+SDP A: m=audio 30436 RTP/AVP 112 3 111 110\r\n
+SDP A: a=rtpmap:112 AMR/8000\r\n
+SDP A: a=fmtp:112 octet-align=1\r\n
+SDP A: a=rtpmap:3 GSM/8000\r\n
+SDP A: a=rtpmap:111 GSM-HR-08/8000\r\n
+SDP A: a=rtpmap:110 GSM-EFR/8000\r\n
+SDP A: a=ptime:20\r\n
+ SDP B: v=0\r\n
+ SDP B: o=OsmoMSC 0 0 IN IP4 23.42.23.42\r\n
+ SDP B: s=GSM Call\r\n
+ SDP B: c=IN IP4 23.42.23.42\r\n
+ SDP B: t=0 0\r\n
+ SDP B: m=audio 30436 RTP/AVP 3 111\r\n
+ SDP B: a=rtpmap:3 GSM/8000\r\n
+ SDP B: a=rtpmap:111 GSM-HR-08/8000\r\n
+ SDP B: a=ptime:20\r\n
+parsed SDP A: v=0\r\n
+parsed SDP A: o=OsmoMSC 0 0 IN IP4 23.42.23.42\r\n
+parsed SDP A: s=GSM Call\r\n
+parsed SDP A: c=IN IP4 23.42.23.42\r\n
+parsed SDP A: t=0 0\r\n
+parsed SDP A: m=audio 30436 RTP/AVP 112 3 111 110\r\n
+parsed SDP A: a=rtpmap:112 AMR/8000\r\n
+parsed SDP A: a=fmtp:112 octet-align=1\r\n
+parsed SDP A: a=rtpmap:3 GSM/8000\r\n
+parsed SDP A: a=rtpmap:111 GSM-HR-08/8000\r\n
+parsed SDP A: a=rtpmap:110 GSM-EFR/8000\r\n
+parsed SDP A: a=ptime:20\r\n
+parsed SDP B: v=0\r\n
+parsed SDP B: o=OsmoMSC 0 0 IN IP4 23.42.23.42\r\n
+parsed SDP B: s=GSM Call\r\n
+parsed SDP B: c=IN IP4 23.42.23.42\r\n
+parsed SDP B: t=0 0\r\n
+parsed SDP B: m=audio 30436 RTP/AVP 3 111\r\n
+parsed SDP B: a=rtpmap:3 GSM/8000\r\n
+parsed SDP B: a=rtpmap:111 GSM-HR-08/8000\r\n
+parsed SDP B: a=ptime:20\r\n
+sdp_msg_intersection(a,b): v=0\r\n
+sdp_msg_intersection(a,b): o=OsmoMSC 0 0 IN IP4 23.42.23.42\r\n
+sdp_msg_intersection(a,b): s=GSM Call\r\n
+sdp_msg_intersection(a,b): c=IN IP4 23.42.23.42\r\n
+sdp_msg_intersection(a,b): t=0 0\r\n
+sdp_msg_intersection(a,b): m=audio 30436 RTP/AVP 3 111\r\n
+sdp_msg_intersection(a,b): a=rtpmap:3 GSM/8000\r\n
+sdp_msg_intersection(a,b): a=rtpmap:111 GSM-HR-08/8000\r\n
+sdp_msg_intersection(a,b): a=ptime:20\r\n
+[5] ok
+
+[6] all codecs removed
+SDP A: v=0\r\n
+SDP A: o=OsmoMSC 0 0 IN IP4 23.42.23.42\r\n
+SDP A: s=GSM Call\r\n
+SDP A: c=IN IP4 23.42.23.42\r\n
+SDP A: t=0 0\r\n
+SDP A: m=audio 30436 RTP/AVP 112 3 111 110\r\n
+SDP A: a=rtpmap:112 AMR/8000\r\n
+SDP A: a=fmtp:112 octet-align=1\r\n
+SDP A: a=rtpmap:3 GSM/8000\r\n
+SDP A: a=rtpmap:111 GSM-HR-08/8000\r\n
+SDP A: a=rtpmap:110 GSM-EFR/8000\r\n
+SDP A: a=ptime:20\r\n
+ SDP B: s=empty
+parsed SDP A: v=0\r\n
+parsed SDP A: o=OsmoMSC 0 0 IN IP4 23.42.23.42\r\n
+parsed SDP A: s=GSM Call\r\n
+parsed SDP A: c=IN IP4 23.42.23.42\r\n
+parsed SDP A: t=0 0\r\n
+parsed SDP A: m=audio 30436 RTP/AVP 112 3 111 110\r\n
+parsed SDP A: a=rtpmap:112 AMR/8000\r\n
+parsed SDP A: a=fmtp:112 octet-align=1\r\n
+parsed SDP A: a=rtpmap:3 GSM/8000\r\n
+parsed SDP A: a=rtpmap:111 GSM-HR-08/8000\r\n
+parsed SDP A: a=rtpmap:110 GSM-EFR/8000\r\n
+parsed SDP A: a=ptime:20\r\n
+parsed SDP B: v=0\r\n
+parsed SDP B: o=OsmoMSC 0 0 IN IP4 0.0.0.0\r\n
+parsed SDP B: s=GSM Call\r\n
+parsed SDP B: c=IN IP4 0.0.0.0\r\n
+parsed SDP B: t=0 0\r\n
+parsed SDP B: m=audio 0 RTP/AVP\r\n
+parsed SDP B: a=ptime:20\r\n
+sdp_msg_intersection(a,b): v=0\r\n
+sdp_msg_intersection(a,b): o=OsmoMSC 0 0 IN IP4 23.42.23.42\r\n
+sdp_msg_intersection(a,b): s=GSM Call\r\n
+sdp_msg_intersection(a,b): c=IN IP4 23.42.23.42\r\n
+sdp_msg_intersection(a,b): t=0 0\r\n
+sdp_msg_intersection(a,b): m=audio 30436 RTP/AVP\r\n
+sdp_msg_intersection(a,b): a=ptime:20\r\n
+[6] ok
+
+[7] some real world test case
+SDP A: v=0\r\n
+SDP A: o=OsmoMSC 0 0 IN IP4 0.0.0.0\r\n
+SDP A: s=GSM Call\r\n
+SDP A: c=IN IP4 0.0.0.0\r\n
+SDP A: t=0 0\r\n
+SDP A: m=audio 0 RTP/AVP 112 113 110 3 111\r\n
+SDP A: a=rtpmap:112 AMR/8000\r\n
+SDP A: a=fmtp:112 octet-align=1;mode-set=0,1,2,3\r\n
+SDP A: a=rtpmap:113 AMR-WB/8000\r\n
+SDP A: a=fmtp:113 octet-align=1\r\n
+SDP A: a=rtpmap:110 GSM-EFR/8000\r\n
+SDP A: a=rtpmap:3 GSM/8000\r\n
+SDP A: a=rtpmap:111 GSM-HR-08/8000\r\n
+SDP A: a=ptime:20\r\n
+ SDP B: v=0\r\n
+ SDP B: o=OsmoMSC 0 0 IN IP4 0.0.0.0\r\n
+ SDP B: s=GSM Call\r\n
+ SDP B: c=IN IP4 0.0.0.0\r\n
+ SDP B: t=0 0\r\n
+ SDP B: m=audio 0 RTP/AVP 112 113 110 3 111\r\n
+ SDP B: a=rtpmap:112 AMR/8000\r\n
+ SDP B: a=fmtp:112 octet-align=1;mode-set=0,1,2,3\r\n
+ SDP B: a=rtpmap:113 AMR-WB/8000\r\n
+ SDP B: a=fmtp:113 octet-align=1\r\n
+ SDP B: a=rtpmap:110 GSM-EFR/8000\r\n
+ SDP B: a=rtpmap:3 GSM/8000\r\n
+ SDP B: a=rtpmap:111 GSM-HR-08/8000\r\n
+ SDP B: a=ptime:20\r\n
+parsed SDP A: v=0\r\n
+parsed SDP A: o=OsmoMSC 0 0 IN IP4 0.0.0.0\r\n
+parsed SDP A: s=GSM Call\r\n
+parsed SDP A: c=IN IP4 0.0.0.0\r\n
+parsed SDP A: t=0 0\r\n
+parsed SDP A: m=audio 0 RTP/AVP 112 113 110 3 111\r\n
+parsed SDP A: a=rtpmap:112 AMR/8000\r\n
+parsed SDP A: a=fmtp:112 octet-align=1;mode-set=0,1,2,3\r\n
+parsed SDP A: a=rtpmap:113 AMR-WB/8000\r\n
+parsed SDP A: a=fmtp:113 octet-align=1\r\n
+parsed SDP A: a=rtpmap:110 GSM-EFR/8000\r\n
+parsed SDP A: a=rtpmap:3 GSM/8000\r\n
+parsed SDP A: a=rtpmap:111 GSM-HR-08/8000\r\n
+parsed SDP A: a=ptime:20\r\n
+parsed SDP B: v=0\r\n
+parsed SDP B: o=OsmoMSC 0 0 IN IP4 0.0.0.0\r\n
+parsed SDP B: s=GSM Call\r\n
+parsed SDP B: c=IN IP4 0.0.0.0\r\n
+parsed SDP B: t=0 0\r\n
+parsed SDP B: m=audio 0 RTP/AVP 112 113 110 3 111\r\n
+parsed SDP B: a=rtpmap:112 AMR/8000\r\n
+parsed SDP B: a=fmtp:112 octet-align=1;mode-set=0,1,2,3\r\n
+parsed SDP B: a=rtpmap:113 AMR-WB/8000\r\n
+parsed SDP B: a=fmtp:113 octet-align=1\r\n
+parsed SDP B: a=rtpmap:110 GSM-EFR/8000\r\n
+parsed SDP B: a=rtpmap:3 GSM/8000\r\n
+parsed SDP B: a=rtpmap:111 GSM-HR-08/8000\r\n
+parsed SDP B: a=ptime:20\r\n
+sdp_msg_intersection(a,b): v=0\r\n
+sdp_msg_intersection(a,b): o=OsmoMSC 0 0 IN IP4 0.0.0.0\r\n
+sdp_msg_intersection(a,b): s=GSM Call\r\n
+sdp_msg_intersection(a,b): c=IN IP4 0.0.0.0\r\n
+sdp_msg_intersection(a,b): t=0 0\r\n
+sdp_msg_intersection(a,b): m=audio 0 RTP/AVP 112 113 110 3 111\r\n
+sdp_msg_intersection(a,b): a=rtpmap:112 AMR/8000\r\n
+sdp_msg_intersection(a,b): a=fmtp:112 octet-align=1;mode-set=0,1,2,3\r\n
+sdp_msg_intersection(a,b): a=rtpmap:113 AMR-WB/8000\r\n
+sdp_msg_intersection(a,b): a=fmtp:113 octet-align=1\r\n
+sdp_msg_intersection(a,b): a=rtpmap:110 GSM-EFR/8000\r\n
+sdp_msg_intersection(a,b): a=rtpmap:3 GSM/8000\r\n
+sdp_msg_intersection(a,b): a=rtpmap:111 GSM-HR-08/8000\r\n
+sdp_msg_intersection(a,b): a=ptime:20\r\n
+[7] ok
+
+
+test_select
+
+[0]
+SDP: AMR:octet-align=1#112,GSM#3,GSM-HR-08#111,GSM-EFR#110
+Select: AMR:octet-align=1#112
+SDP: AMR:octet-align=1#112,GSM#3,GSM-HR-08#111,GSM-EFR#110
+[0] ok
+
+[1]
+SDP: AMR:octet-align=1#112,GSM#3,GSM-HR-08#111,GSM-EFR#110
+Select: GSM#3
+SDP: GSM#3,AMR:octet-align=1#112,GSM-HR-08#111,GSM-EFR#110
+[1] ok
+
+[2]
+SDP: AMR:octet-align=1#112,GSM#3,GSM-HR-08#111,GSM-EFR#110
+Select: GSM-HR-08#111
+SDP: GSM-HR-08#111,AMR:octet-align=1#112,GSM#3,GSM-EFR#110
+[2] ok
+
+[3]
+SDP: AMR:octet-align=1#112,GSM#3,GSM-HR-08#111,GSM-EFR#110
+Select: GSM-EFR#110
+SDP: GSM-EFR#110,AMR:octet-align=1#112,GSM#3,GSM-HR-08#111
+[3] ok
diff --git a/tests/smpp/Makefile.am b/tests/smpp/Makefile.am
index 8d631198c..ff19d3d7c 100644
--- a/tests/smpp/Makefile.am
+++ b/tests/smpp/Makefile.am
@@ -11,12 +11,15 @@ AM_CFLAGS = \
$(LIBOSMOGSM_CFLAGS) \
$(LIBOSMOSCCP_CFLAGS) \
$(LIBOSMOABIS_CFLAGS) \
+ $(LIBOSMOSCCP_CFLAGS) \
+ $(LIBOSMOMGCPCLIENT_CFLAGS) \
$(COVERAGE_CFLAGS) \
$(LIBSMPP34_CFLAGS) \
$(NULL)
AM_LDFLAGS = \
$(COVERAGE_LDFLAGS) \
+ -no-install \
$(NULL)
EXTRA_DIST = \
@@ -24,16 +27,16 @@ EXTRA_DIST = \
smpp_test.err \
$(NULL)
-noinst_PROGRAMS = \
+check_PROGRAMS = \
smpp_test \
$(NULL)
smpp_test_SOURCES = \
smpp_test.c \
- $(top_builddir)/src/libmsc/smpp_utils.c \
$(NULL)
smpp_test_LDADD = \
+ $(top_builddir)/src/libsmpputil/libsmpputil.a \
$(LIBOSMOCORE_LIBS) \
$(LIBOSMOGSM_LIBS) \
$(NULL)
diff --git a/tests/smpp/smpp_test.c b/tests/smpp/smpp_test.c
index 1abb63b01..9b94c63f4 100644
--- a/tests/smpp/smpp_test.c
+++ b/tests/smpp/smpp_test.c
@@ -1,5 +1,6 @@
/*
* (C) 2013 by Holger Hans Peter Freyther
+ * (C) 2022 by Harald Welte <laforge@osmocom.org>
* All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify
@@ -21,12 +22,10 @@
#include <stdio.h>
#include <osmocom/msc/debug.h>
-
+#include <osmocom/smpp/smpp_smsc.h>
#include <osmocom/core/application.h>
#include <osmocom/core/backtrace.h>
-#include "smpp_smsc.h"
-
struct coding_test {
uint8_t dcs;
uint8_t coding;
@@ -62,6 +61,41 @@ static void test_coding_scheme(void)
}
}
+static const char *smpp_time_tests[] = {
+ "\0",
+ "220517175524000+",
+ "220517175524000-",
+ "220517175524004+", /* 1 hour advanced compared to GMT */
+ "220517175524004-", /* 1 hour retarded compared to GMT */
+ "000000010000000R", /* 1 hour */
+ "000001000000000R", /* 1 day */
+};
+
+static void test_smpp_parse_time_format(void)
+{
+ time_t t_now = 1652745600; /* 2022-05-17 00:00:00 UTC */
+ char *orig_tz;
+
+ printf("Testing SMPP time format parser\n");
+
+ /* relative time format conversion depends on the local time */
+ orig_tz = getenv("TZ");
+ setenv("TZ", "UTC", 1);
+
+ for (unsigned int i = 0; i < ARRAY_SIZE(smpp_time_tests); i++) {
+ time_t t = smpp_parse_time_format(smpp_time_tests[i], &t_now);
+ char buf[32];
+ strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", gmtime(&t));
+ printf("'%s': %ld == %s\n", smpp_time_tests[i], t, buf);
+ }
+
+ if (orig_tz)
+ setenv("TZ", orig_tz, 1);
+ else
+ unsetenv("TZ");
+
+}
+
static const struct log_info_cat smpp_mirror_default_categories[] = {
[DSMPP] = {
.name = "DSMPP",
@@ -80,8 +114,12 @@ int main(int argc, char **argv)
void *ctx = talloc_named_const(NULL, 0, "smpp_test");
osmo_init_logging2(ctx, &log_info);
log_set_use_color(osmo_stderr_target, 0);
- log_set_print_filename(osmo_stderr_target, 0);
+ log_set_print_filename2(osmo_stderr_target, LOG_FILENAME_NONE);
+ log_set_print_category(osmo_stderr_target, 0);
+ log_set_print_category_hex(osmo_stderr_target, 0);
test_coding_scheme();
+ test_smpp_parse_time_format();
+
return EXIT_SUCCESS;
}
diff --git a/tests/smpp/smpp_test.ok b/tests/smpp/smpp_test.ok
index fd44804d1..feb75a6ed 100644
--- a/tests/smpp/smpp_test.ok
+++ b/tests/smpp/smpp_test.ok
@@ -1 +1,9 @@
Testing coding scheme support
+Testing SMPP time format parser
+'': 0 == 1970-01-01 00:00:00
+'220517175524000+': 1652810124 == 2022-05-17 17:55:24
+'220517175524000-': 1652810124 == 2022-05-17 17:55:24
+'220517175524004+': 1652806524 == 2022-05-17 16:55:24
+'220517175524004-': 1652813724 == 2022-05-17 18:55:24
+'000000010000000R': 1652749200 == 2022-05-17 01:00:00
+'000001000000000R': 1652832000 == 2022-05-18 00:00:00
diff --git a/tests/smpp_test_runner.py b/tests/smpp_test_runner.py
index f6567d9b4..b8c6e1c9b 100755
--- a/tests/smpp_test_runner.py
+++ b/tests/smpp_test_runner.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2
+#!/usr/bin/env python3
# (C) 2014 by Holger Hans Peter Freyther
# based on vty_test_runner.py:
@@ -46,8 +46,8 @@ class TestVTYBase(unittest.TestCase):
try:
self.proc = osmoutil.popen_devnull(osmo_vty_cmd)
except OSError:
- print >> sys.stderr, "Current directory: %s" % os.getcwd()
- print >> sys.stderr, "Consider setting -b"
+ print("Current directory: %s" % os.getcwd(), file=sys.stderr)
+ print("Consider setting -b", file=sys.stderr)
appstring = self.vty_app()[2]
appport = self.vty_app()[0]
@@ -73,14 +73,14 @@ class TestSMPPMSC(TestVTYBase):
# Enable the configuration
self.vty.enable()
self.assertTrue(self.vty.verify("configure terminal", ['']))
- self.assertEquals(self.vty.node(), 'config')
+ self.assertEqual(self.vty.node(), 'config')
self.assertTrue(self.vty.verify('smpp', ['']))
- self.assertEquals(self.vty.node(), 'config-smpp')
+ self.assertEqual(self.vty.node(), 'config-smpp')
self.assertTrue(self.vty.verify('system-id test', ['']))
self.assertTrue(self.vty.verify('local-tcp-port 2775', ['']))
self.assertTrue(self.vty.verify('esme test', ['']))
- self.assertEquals(self.vty.node(), 'config-smpp-esme')
+ self.assertEqual(self.vty.node(), 'config-smpp-esme')
self.assertTrue(self.vty.verify('default-route', ['']))
self.assertTrue(self.vty.verify('end', ['']))
@@ -88,7 +88,7 @@ class TestSMPPMSC(TestVTYBase):
sck = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sck.setblocking(1)
sck.connect(('0.0.0.0', 2775))
- sck.sendall('\x00\x00\x00\x02\x00')
+ sck.sendall(b'\x00\x00\x00\x02\x00')
sck.close()
# Check if the VTY is still there
@@ -98,7 +98,7 @@ class TestSMPPMSC(TestVTYBase):
sck = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sck.setblocking(1)
sck.connect(('0.0.0.0', 2775))
- sck.sendall('\x00\x01\x00\x01\x01')
+ sck.sendall(b'\x00\x01\x00\x01\x01')
sck.close()
self.vty.verify('enable',[''])
@@ -128,9 +128,9 @@ if __name__ == '__main__':
if args.p:
confpath = args.p
- print "confpath %s, workdir %s" % (confpath, workdir)
+ print("confpath %s, workdir %s" % (confpath, workdir))
os.chdir(workdir)
- print "Running tests for specific SMPP"
+ print("Running tests for specific SMPP")
suite = unittest.TestSuite()
suite.addTest(unittest.TestLoader().loadTestsFromTestCase(TestSMPPMSC))
res = unittest.TextTestRunner(verbosity=verbose_level).run(suite)
diff --git a/tests/sms_queue/Makefile.am b/tests/sms_queue/Makefile.am
index 80189c793..055a22902 100644
--- a/tests/sms_queue/Makefile.am
+++ b/tests/sms_queue/Makefile.am
@@ -12,9 +12,16 @@ AM_CFLAGS = \
$(LIBOSMOABIS_CFLAGS) \
$(LIBOSMOSIGTRAN_CFLAGS) \
$(LIBOSMORANAP_CFLAGS) \
+ $(LIBOSMONETIF_CFLAGS) \
$(LIBASN1C_CFLAGS) \
$(LIBOSMOMGCPCLIENT_CFLAGS) \
$(LIBOSMOGSUPCLIENT_CFLAGS) \
+ $(LIBSQLITE3_CFLAGS) \
+ $(NULL)
+
+AM_LDFLAGS = \
+ $(COVERAGE_LDFLAGS) \
+ -no-install \
$(NULL)
EXTRA_DIST = \
@@ -22,18 +29,18 @@ EXTRA_DIST = \
sms_queue_test.err \
$(NULL)
-noinst_PROGRAMS = \
+check_PROGRAMS = \
sms_queue_test \
$(NULL)
sms_queue_test_SOURCES = \
sms_queue_test.c \
+ $(srcdir)/../stubs.c \
$(NULL)
sms_queue_test_LDADD = \
$(top_builddir)/src/libmsc/libmsc.a \
$(top_builddir)/src/libvlr/libvlr.a \
- $(LIBSMPP34_LIBS) \
$(LIBOSMOCORE_LIBS) \
$(LIBOSMOGSM_LIBS) \
$(LIBOSMOVTY_LIBS) \
@@ -43,10 +50,11 @@ sms_queue_test_LDADD = \
$(LIBASN1C_LIBS) \
$(LIBOSMOMGCPCLIENT_LIBS) \
$(LIBOSMOGSUPCLIENT_LIBS) \
+ $(LIBSQLITE3_LIBS) \
$(LIBRARY_GSM) \
- -ldbi \
$(NULL)
sms_queue_test_LDFLAGS = \
-Wl,--wrap=db_sms_get_next_unsent_rr_msisdn \
+ $(AM_LDFLAGS) \
$(NULL)
diff --git a/tests/sms_queue/sms_queue_test.c b/tests/sms_queue/sms_queue_test.c
index 25fc3122a..cc78e1491 100644
--- a/tests/sms_queue/sms_queue_test.c
+++ b/tests/sms_queue/sms_queue_test.c
@@ -158,7 +158,7 @@ void show_fake_sms_db()
static void test_next_sms()
{
int i;
- char last_msisdn[VLR_MSISDN_LENGTH+1] = "";
+ char last_msisdn[GSM23003_MSISDN_MAX_DIGITS+1] = "";
printf("Testing smsq_take_next_sms()\n");
@@ -246,7 +246,7 @@ int main(int argc, char **argv)
OSMO_ASSERT(osmo_stderr_target);
log_set_use_color(osmo_stderr_target, 0);
log_set_print_timestamp(osmo_stderr_target, 0);
- log_set_print_filename(osmo_stderr_target, 0);
+ log_set_print_filename2(osmo_stderr_target, LOG_FILENAME_NONE);
log_set_print_category(osmo_stderr_target, 1);
log_parse_category_mask(osmo_stderr_target, "DLOAP,1");
@@ -277,24 +277,3 @@ int main(int argc, char **argv)
return 0;
}
-
-void osmo_stream_srv_link_set_data(struct osmo_stream_srv_link *link, void *data) {}
-struct osmo_fd *osmo_stream_srv_get_ofd(struct osmo_stream_srv *srv) { return NULL; }
-void osmo_stream_srv_destroy(struct osmo_stream_srv *conn) {}
-struct osmo_stream_srv *osmo_stream_srv_create(void *ctx, struct osmo_stream_srv_link *link,
- int fd, int (*cb)(struct osmo_stream_srv *conn),
- int (*closed_cb)(struct osmo_stream_srv *conn),
- void *data) { return NULL; }
-void osmo_stream_srv_send(struct osmo_stream_srv *conn, struct msgb *msg) {}
-void osmo_stream_srv_link_set_proto(struct osmo_stream_srv_link *link, uint16_t proto) {}
-struct osmo_fd *osmo_stream_srv_link_get_ofd(struct osmo_stream_srv_link *link) { return NULL; }
-struct osmo_stream_srv_link *osmo_stream_srv_link_create(void *ctx) { return NULL; }
-void *osmo_stream_srv_get_data(struct osmo_stream_srv *conn) { return NULL; }
-void osmo_stream_srv_link_set_nodelay(struct osmo_stream_srv_link *link, bool nodelay) {}
-void osmo_stream_srv_link_set_accept_cb(struct osmo_stream_srv_link *link, int (*accept_cb)
- (struct osmo_stream_srv_link *link, int fd)) {}
-int osmo_stream_srv_link_open(struct osmo_stream_srv_link *link) { return 0; }
-void *osmo_stream_srv_link_get_data(struct osmo_stream_srv_link *link) { return NULL; }
-void osmo_stream_srv_link_set_port(struct osmo_stream_srv_link *link, uint16_t port) {}
-void osmo_stream_srv_link_set_addr(struct osmo_stream_srv_link *link, const char *addr) {}
-int sctp_recvmsg(int sd, void *msg, size_t len, void *from, void *fromlen, void *info, int *msg_flags) { return 0; }
diff --git a/tests/msc_vlr/stubs.h b/tests/stubs.c
index bf55baafb..f4ccb48c7 100644
--- a/tests/msc_vlr/stubs.h
+++ b/tests/stubs.c
@@ -18,6 +18,9 @@
*
*/
+#include <osmocom/core/linuxlist.h>
+#include <osmocom/netif/stream.h>
+
void osmo_stream_srv_link_set_data(struct osmo_stream_srv_link *link, void *data) {}
struct osmo_fd *osmo_stream_srv_get_ofd(struct osmo_stream_srv *srv) { return NULL; }
void osmo_stream_srv_destroy(struct osmo_stream_srv *conn) {}
@@ -34,7 +37,17 @@ void osmo_stream_srv_link_set_nodelay(struct osmo_stream_srv_link *link, bool no
void osmo_stream_srv_link_set_accept_cb(struct osmo_stream_srv_link *link, int (*accept_cb)
(struct osmo_stream_srv_link *link, int fd)) {}
int osmo_stream_srv_link_open(struct osmo_stream_srv_link *link) { return 0; }
+void osmo_stream_srv_link_close(struct osmo_stream_srv_link *link) {}
void *osmo_stream_srv_link_get_data(struct osmo_stream_srv_link *link) { return NULL; }
+char *osmo_stream_srv_link_get_sockname(const struct osmo_stream_srv_link *link) { return NULL; }
void osmo_stream_srv_link_set_port(struct osmo_stream_srv_link *link, uint16_t port) {}
void osmo_stream_srv_link_set_addr(struct osmo_stream_srv_link *link, const char *addr) {}
int sctp_recvmsg(int sd, void *msg, size_t len, void *from, void *fromlen, void *info, int *msg_flags) { return 0; }
+struct gsm_sms;
+struct msc_a;
+struct gsm_trans;
+struct smpp_esme;
+bool smpp_route_smpp_first() { return false; }
+void smpp_esme_put(struct smpp_esme *esme) { return; }
+int smpp_try_deliver(struct gsm_sms *sms, struct msc_a *msc_a) { return 0; }
+int sms_route_mt_sms(struct gsm_trans *trans, struct gsm_sms *gsms) { return 0; }
diff --git a/tests/test_nodes.vty b/tests/test_nodes.vty
index fb7b1c529..5e4b793b1 100644
--- a/tests/test_nodes.vty
+++ b/tests/test_nodes.vty
@@ -5,6 +5,8 @@ OsmoMSC(config)# list
network
msc
sgs
+ smsc
+ asci
mncc-int
hlr
...
@@ -14,23 +16,43 @@ OsmoMSC(config-net)# list
...
network country code <1-999>
mobile network code <0-999>
- short name NAME
- long name NAME
- encryption a5 <0-3> [<0-3>] [<0-3>] [<0-3>]
+ short name .NAME
+ long name .NAME
+ encryption a5 <0-4> [<0-4>] [<0-4>] [<0-4>] [<0-4>]
+ encryption uea <0-2> [<0-2>] [<0-2>]
authentication (optional|required)
rrlp mode (none|ms-based|ms-preferred|ass-preferred)
mm info (0|1)
timezone <-19-19> (0|15|30|45)
timezone <-19-19> (0|15|30|45) <0-2>
no timezone
- periodic location update <6-1530>
- no periodic location update
+ call-waiting
+ no call-waiting
+ mgw <0-255>
+ no mgw <0-255>
+
+OsmoMSC(config-net)# encryption?
+ encryption Encryption options
+OsmoMSC(config-net)# encryption ?
+ a5 GSM A5 Air Interface Encryption.
+ uea UTRAN (3G) encryption algorithms to allow: 0 = UEA0 (no encryption), 1 = UEA1, 2 = UEA2.
+
+OsmoMSC(config-net)# encryption uea ?
+ <0-2> UEAn Algorithm Number
+OsmoMSC(config-net)# encryption uea 0 ?
+ [<0-2>] UEAn Algorithm Number
+OsmoMSC(config-net)# encryption uea 0 1 ?
+ [<0-2>] UEAn Algorithm Number
+OsmoMSC(config-net)# encryption uea 0 1 2 ?
+ <cr>
OsmoMSC(config-net)# exit
OsmoMSC(config)# msc
OsmoMSC(config-msc)# list
...
assign-tmsi
+ lcls-permitted
+ no lcls-permitted
mncc internal
mncc external MNCC_SOCKET_PATH
mncc guard-timeout <0-255>
@@ -41,20 +63,19 @@ OsmoMSC(config-msc)# list
check-imei-rqd (0|1|early)
cs7-instance-a <0-15>
cs7-instance-iu <0-15>
- paging response-timer (default|<1-65535>)
emergency-call route-to-msisdn MSISDN
sms-over-gsup
no sms-over-gsup
osmux (on|off|only)
handover-number range MSISDN_FIRST MSISDN_LAST
+ nri bitlen <0-15>
+ nri add <0-32767> [<0-32767>]
+ nri del <0-32767> [<0-32767>]
neighbor (a|iu) lac <0-65535> (ran-pc|msc-ipa-name) RAN_PC_OR_MSC_IPA_NAME
neighbor (a|iu) lac-ci <0-65535> <0-65535> (ran-pc|msc-ipa-name) RAN_PC_OR_MSC_IPA_NAME
neighbor (a|iu) cgi <0-999> <0-999> <0-65535> <0-65535> (ran-pc|msc-ipa-name) RAN_PC_OR_MSC_IPA_NAME
no neighbor (a|iu) (ran-pc|msc-ipa-name) RAN_PC_OR_MSC_IPA_NAME
- mgw local-ip A.B.C.D
- mgw local-port <0-65535>
- mgw remote-ip A.B.C.D
- mgw remote-port <0-65535>
+ timer [(vlr|mgw|mncc|sccp|geran|utran|sgs)] [TNNNN] [(<0-2147483647>|default)]
...
OsmoMSC(config-msc)# ncss?
@@ -78,12 +99,16 @@ OsmoMSC(config-msc)# mncc external /path/not/used
OsmoMSC(config-msc)# show running-config
...
msc
-...
+... ! mncc internal
mncc external /path/not/used
-...
+... ! mncc internal
OsmoMSC(config-msc)# mncc internal
OsmoMSC(config-msc)# show running-config
+...
+msc
+... ! mncc external
+ mncc internal
... ! mncc external
OsmoMSC(config-msc)# exit
@@ -130,11 +155,13 @@ network
short name OsmoMSC
long name OsmoMSC
encryption a5 0
+ encryption uea 1 2
authentication optional
rrlp mode none
mm info 1
- periodic location update 30
+...
msc
+ mncc internal
mncc guard-timeout 180
ncss guard-timeout 30
assign-tmsi
@@ -142,9 +169,6 @@ msc
...
auth-tuple-max-reuse-count 3
auth-tuple-reuse-on-error 1
- mgw local-port 2728
- mgw remote-ip 10.23.24.1
- mgw remote-port 2427
mncc-int
default-codec tch-f fr
default-codec tch-h hr
@@ -152,8 +176,57 @@ mncc-int
hlr
remote-ip 127.0.0.1
remote-port 4222
+ ipa-name unnamed-MSC
sgs
local-port 29118
local-ip 0.0.0.0
vlr-name vlr.example.net
+smsc
+ queue max-pending 20
+ queue max-failure 1
+ database delete-delivered 1
+ database delete-expired 1
+ validity-period minimum 1
+ validity-period default 10080
+asci
+ disable
+ gcr
end
+
+OsmoMSC# configure terminal
+OsmoMSC(config)# network
+OsmoMSC(config-net)# encryption uea 0
+OsmoMSC(config-net)# show running-config
+...
+ encryption uea 0
+...
+
+OsmoMSC(config-net)# encryption uea 1
+OsmoMSC(config-net)# show running-config
+...
+ encryption uea 1
+...
+
+OsmoMSC(config-net)# encryption uea 2
+OsmoMSC(config-net)# show running-config
+...
+ encryption uea 2
+...
+
+OsmoMSC(config-net)# encryption uea 0 1
+OsmoMSC(config-net)# show running-config
+...
+ encryption uea 0 1
+...
+
+OsmoMSC(config-net)# encryption uea 0 2
+OsmoMSC(config-net)# show running-config
+...
+ encryption uea 0 2
+...
+
+OsmoMSC(config-net)# encryption uea 1 2
+OsmoMSC(config-net)# show running-config
+...
+ encryption uea 1 2
+...
diff --git a/tests/testsuite.at b/tests/testsuite.at
index f27b60c48..fbf594b48 100644
--- a/tests/testsuite.at
+++ b/tests/testsuite.at
@@ -16,6 +16,14 @@ cat $abs_srcdir/sms_queue/sms_queue_test.err > experr
AT_CHECK([$abs_top_builddir/tests/sms_queue/sms_queue_test], [], [expout], [experr])
AT_CLEANUP
+AT_SETUP([db_sms_test])
+AT_KEYWORDS([db_sms_test])
+cat $abs_srcdir/db_sms/db_sms_test.ok > expout
+cat $abs_srcdir/db_sms/db_sms_test.err > experr
+# swap the output from stderr and stdout so we can drop libdbi prints to stderr when trying to load wrong drivers
+AT_CHECK([$abs_top_builddir/tests/db_sms/db_sms_test 3>&1 1>&2 2>&3 | grep -v "Failed to load driver" | grep -v "cannot open shared object file"], [], [expout], [experr])
+AT_CLEANUP
+
AT_SETUP([msc_vlr_test_no_authen])
AT_KEYWORDS([msc_vlr_test_no_authen])
cat $abs_srcdir/msc_vlr/msc_vlr_test_no_authen.ok > expout
@@ -99,3 +107,24 @@ cat $abs_srcdir/msc_vlr/msc_vlr_test_ss.ok > expout
cat $abs_srcdir/msc_vlr/msc_vlr_test_ss.err > experr
AT_CHECK([$abs_top_builddir/tests/msc_vlr/msc_vlr_test_ss], [], [expout], [experr])
AT_CLEANUP
+
+AT_SETUP([sdp_msg_test])
+AT_KEYWORDS([sdp_msg_test])
+cat $abs_srcdir/sdp_msg/sdp_msg_test.ok > expout
+cat $abs_srcdir/sdp_msg/sdp_msg_test.err > experr
+AT_CHECK([$abs_top_builddir/tests/sdp_msg/sdp_msg_test], [], [expout], [experr])
+AT_CLEANUP
+
+AT_SETUP([mncc_test])
+AT_KEYWORDS([mncc_test])
+cat $abs_srcdir/mncc/mncc_test.ok > expout
+cat $abs_srcdir/mncc/mncc_test.err > experr
+AT_CHECK([$abs_top_builddir/tests/mncc/mncc_test], [], [expout], [experr])
+AT_CLEANUP
+
+AT_SETUP([csd_test])
+AT_KEYWORDS([csd_test])
+cat $abs_srcdir/csd/csd_test.ok > expout
+cat $abs_srcdir/csd/csd_test.err > experr
+AT_CHECK([$abs_top_builddir/tests/csd/csd_test], [], [expout], [experr])
+AT_CLEANUP
diff --git a/tests/vty_test_runner.py b/tests/vty_test_runner.py
index 471ecf6c6..2dfa15534 100755
--- a/tests/vty_test_runner.py
+++ b/tests/vty_test_runner.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2
+#!/usr/bin/env python3
# (C) 2013 by Katerina Barone-Adesi <kat.obsc@gmail.com>
# (C) 2013 by Holger Hans Peter Freyther
@@ -33,9 +33,9 @@ class TestVTYBase(unittest.TestCase):
def checkForEndAndExit(self):
res = self.vty.command("list")
#print ('looking for "exit"\n')
- self.assert_(res.find(' exit\r') > 0)
+ self.assertTrue(res.find(' exit\r') > 0)
#print 'found "exit"\nlooking for "end"\n'
- self.assert_(res.find(' end\r') > 0)
+ self.assertTrue(res.find(' end\r') > 0)
#print 'found "end"\n'
def vty_command(self):
@@ -54,8 +54,8 @@ class TestVTYBase(unittest.TestCase):
try:
self.proc = osmoutil.popen_devnull(osmo_vty_cmd)
except OSError:
- print >> sys.stderr, "Current directory: %s" % os.getcwd()
- print >> sys.stderr, "Consider setting -b"
+ print("Current directory: %s" % os.getcwd(), file=sys.stderr)
+ print("Consider setting -b", file=sys.stderr)
appstring = self.vty_app()[2]
appport = self.vty_app()[0]
@@ -65,7 +65,9 @@ class TestVTYBase(unittest.TestCase):
if self.vty:
self.vty._close_socket()
self.vty = None
- osmoutil.end_proc(self.proc)
+ rc = osmoutil.end_proc(self.proc)
+ if rc is not None and rc != 0:
+ raise Exception("Process returned %d" % rc)
class TestVTYMSC(TestVTYBase):
@@ -79,14 +81,14 @@ class TestVTYMSC(TestVTYBase):
def testConfigNetworkTree(self, include_bsc_items=True):
self.vty.enable()
self.assertTrue(self.vty.verify("configure terminal",['']))
- self.assertEquals(self.vty.node(), 'config')
+ self.assertEqual(self.vty.node(), 'config')
self.checkForEndAndExit()
self.assertTrue(self.vty.verify("network",['']))
- self.assertEquals(self.vty.node(), 'config-net')
+ self.assertEqual(self.vty.node(), 'config-net')
self.checkForEndAndExit()
self.vty.command("write terminal")
self.assertTrue(self.vty.verify("exit",['']))
- self.assertEquals(self.vty.node(), 'config')
+ self.assertEqual(self.vty.node(), 'config')
self.assertTrue(self.vty.verify("exit",['']))
self.assertTrue(self.vty.node() is None)
@@ -107,35 +109,35 @@ class TestVTYMSC(TestVTYBase):
# check the default
res = self.vty.command("write terminal")
- self.assert_(res.find(' no smpp-first') > 0)
+ self.assertTrue(res.find(' no smpp-first') > 0)
self.vty.verify("smpp-first", [''])
res = self.vty.command("write terminal")
- self.assert_(res.find(' smpp-first') > 0)
- self.assertEquals(res.find('no smpp-first'), -1)
+ self.assertTrue(res.find(' smpp-first') > 0)
+ self.assertEqual(res.find('no smpp-first'), -1)
self.vty.verify("no smpp-first", [''])
res = self.vty.command("write terminal")
- self.assert_(res.find('no smpp-first') > 0)
+ self.assertTrue(res.find('no smpp-first') > 0)
def testVtyTree(self):
self.vty.enable()
self.assertTrue(self.vty.verify("configure terminal", ['']))
- self.assertEquals(self.vty.node(), 'config')
+ self.assertEqual(self.vty.node(), 'config')
self.checkForEndAndExit()
self.assertTrue(self.vty.verify('mncc-int', ['']))
- self.assertEquals(self.vty.node(), 'config-mncc-int')
+ self.assertEqual(self.vty.node(), 'config-mncc-int')
self.checkForEndAndExit()
self.assertTrue(self.vty.verify('exit', ['']))
if self.checkForSmpp():
- self.assertEquals(self.vty.node(), 'config')
+ self.assertEqual(self.vty.node(), 'config')
self.assertTrue(self.vty.verify('smpp', ['']))
- self.assertEquals(self.vty.node(), 'config-smpp')
+ self.assertEqual(self.vty.node(), 'config-smpp')
self.checkForEndAndExit()
self.assertTrue(self.vty.verify("exit", ['']))
- self.assertEquals(self.vty.node(), 'config')
+ self.assertEqual(self.vty.node(), 'config')
self.assertTrue(self.vty.verify("exit", ['']))
self.assertTrue(self.vty.node() is None)
@@ -145,10 +147,10 @@ class TestVTYMSC(TestVTYBase):
if self.checkForSmpp():
self.vty.command('smpp')
- self.assertEquals(self.vty.node(), 'config-smpp')
+ self.assertEqual(self.vty.node(), 'config-smpp')
self.vty.command('mncc-int')
- self.assertEquals(self.vty.node(), 'config-mncc-int')
+ self.assertEqual(self.vty.node(), 'config-mncc-int')
def testSi2Q(self):
self.vty.enable()
@@ -162,7 +164,7 @@ class TestVTYMSC(TestVTYBase):
self.vty.command("si2quater neighbor-list del earfcn 1911")
self.vty.command("si2quater neighbor-list del earfcn 1924")
self.vty.command("si2quater neighbor-list del earfcn 2111")
- self.assertEquals(before, self.vty.command("show running-config"))
+ self.assertEqual(before, self.vty.command("show running-config"))
self.vty.command("si2quater neighbor-list add uarfcn 1976 13 1")
self.vty.command("si2quater neighbor-list add uarfcn 1976 38 1")
self.vty.command("si2quater neighbor-list add uarfcn 1976 44 1")
@@ -185,7 +187,7 @@ class TestVTYMSC(TestVTYBase):
self.vty.command("si2quater neighbor-list del uarfcn 1976 224")
self.vty.command("si2quater neighbor-list del uarfcn 1976 225")
self.vty.command("si2quater neighbor-list del uarfcn 1976 226")
- self.assertEquals(before, self.vty.command("show running-config"))
+ self.assertEqual(before, self.vty.command("show running-config"))
def testEnableDisablePeriodicLU(self):
self.vty.enable()
@@ -198,21 +200,26 @@ class TestVTYMSC(TestVTYBase):
self.vty.verify("periodic location update 5", ['% Unknown command.'])
self.vty.verify("periodic location update 1531", ['% Unknown command.'])
- # Enable periodic lu..
- self.vty.verify("periodic location update 60", [''])
+ depr_str = "% 'periodic location update' is now deprecated: " \
+ "use 'timer T3212' to change subscriber expiration timeout."
+ set_str = "% Setting T3212 to 121 minutes (emulating the old behaviour)."
+
+ # Enable periodic LU (deprecated command)
+ self.vty.verify("periodic location update 60", [depr_str, set_str])
res = self.vty.command("write terminal")
- self.assert_(res.find('periodic location update 60') > 0)
- self.assertEquals(res.find('no periodic location update'), -1)
+ self.assertTrue(res.find('timer vlr T3212 121') > 0)
+ self.assertEqual(res.find('periodic location update 60'), -1)
+ self.assertEqual(res.find('no periodic location update'), -1)
- # Now disable it..
- self.vty.verify("no periodic location update", [''])
+ # Now disable it (deprecated command)
+ self.vty.verify("no periodic location update", [depr_str])
res = self.vty.command("write terminal")
- self.assertEquals(res.find('periodic location update 60'), -1)
- self.assert_(res.find('no periodic location update') > 0)
+ self.assertEqual(res.find('no periodic location update'), -1)
+ self.assertEqual(res.find('timer vlr T3212 121'), -1)
def testShowNetwork(self):
res = self.vty.command("show network")
- self.assert_(res.startswith('BSC is on Country Code') >= 0)
+ self.assertTrue(res.startswith('BSC is on Country Code') >= 0)
def ipa_handle_small(x, verbose = False):
s = data2str(x.recv(4))
@@ -220,42 +227,42 @@ def ipa_handle_small(x, verbose = False):
raise Exception("expected to receive 4 bytes, but got %d (%r)" % (len(s)/2, s))
if "0001fe00" == s:
if (verbose):
- print "\tBSC <- NAT: PING?"
+ print("\tBSC <- NAT: PING?")
x.send(IPA().pong())
elif "0001fe06" == s:
if (verbose):
- print "\tBSC <- NAT: IPA ID ACK"
+ print("\tBSC <- NAT: IPA ID ACK")
x.send(IPA().id_ack())
elif "0001fe00" == s:
if (verbose):
- print "\tBSC <- NAT: PONG!"
+ print("\tBSC <- NAT: PONG!")
else:
if (verbose):
- print "\tBSC <- NAT: ", s
+ print("\tBSC <- NAT: ", s)
def ipa_handle_resp(x, tk, verbose = False, proc=None):
s = data2str(x.recv(38))
if "0023fe040108010701020103010401050101010011" in s:
retries = 3
while True:
- print "\tsending IPA identity(%s) at %s" % (tk, time.strftime("%T"))
+ print("\tsending IPA identity(%s) at %s" % (tk, time.strftime("%T")))
try:
x.send(IPA().id_resp(IPA().identity(name = tk.encode('utf-8'))))
- print "\tdone sending IPA identity(%s) at %s" % (tk,
- time.strftime("%T"))
+ print("\tdone sending IPA identity(%s) at %s" % (tk,
+ time.strftime("%T")))
break
except:
- print "\tfailed sending IPA identity at", time.strftime("%T")
+ print("\tfailed sending IPA identity at", time.strftime("%T"))
if proc:
- print "\tproc.poll() = %r" % proc.poll()
+ print("\tproc.poll() = %r" % proc.poll())
if retries < 1:
- print "\tgiving up"
+ print("\tgiving up")
raise
- print "\tretrying (%d attempts left)" % retries
+ print("\tretrying (%d attempts left)" % retries)
retries -= 1
else:
if (verbose):
- print "\tBSC <- NAT: ", s
+ print("\tBSC <- NAT: ", s)
if __name__ == '__main__':
import argparse
@@ -283,9 +290,9 @@ if __name__ == '__main__':
if args.p:
confpath = args.p
- print "confpath %s, workdir %s" % (confpath, workdir)
+ print("confpath %s, workdir %s" % (confpath, workdir))
os.chdir(workdir)
- print "Running tests for specific VTY commands"
+ print("Running tests for specific VTY commands")
suite = unittest.TestSuite()
suite.addTest(unittest.TestLoader().loadTestsFromTestCase(TestVTYMSC))