Merge history from osmo-gsm-manuals.git

Change-Id: I30ec6b3bc18fa36e7bad74ca445bc9949dcefe80
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..2424c1f
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,63 @@
+debian/*.log
+*.o
+*.lo
+*.a
+.deps
+Makefile
+Makefile.in
+bscconfig.h
+bscconfig.h.in
+*.pc
+
+*.*~
+*.sw?
+.libs
+*.pyc
+*.gcda
+*.gcno
+
+#configure
+aclocal.m4
+autom4te.cache/
+config.log
+config.status
+config.guess
+config.sub
+configure
+compile
+depcomp
+install-sh
+missing
+stamp-h1
+libtool
+ltmain.sh
+m4/*.m4
+
+# git-version-gen magic
+.tarball-version
+.version
+
+# apps and app data
+src/osmo-msc/osmo-msc
+src/utils/smpp_mirror
+sms.db
+src/osmo-msc/*.cfg*
+
+#tests
+tests/testsuite.dir
+tests/*/*_test
+# ignore compiled binaries like msc_vlr_test_foo; do not ignore
+# msc_vlr_test_foo.{c,ok,err}, but do still ignore the corresponding .o object
+# files:
+tests/msc_vlr/msc_vlr_test_*
+!tests/msc_vlr/msc_vlr_test_*.*
+tests/msc_vlr/msc_vlr_test_*.o
+
+
+tests/atconfig
+tests/atlocal
+tests/package.m4
+tests/testsuite
+tests/testsuite.log
+
+writtenconfig/
diff --git a/.gitreview b/.gitreview
new file mode 100644
index 0000000..6f1bb85
--- /dev/null
+++ b/.gitreview
@@ -0,0 +1,3 @@
+[gerrit]
+host=gerrit.osmocom.org
+project=osmo-msc
diff --git a/.mailmap b/.mailmap
new file mode 100644
index 0000000..cda4057
--- /dev/null
+++ b/.mailmap
@@ -0,0 +1,12 @@
+Harald Welte <laforge@gnumonks.org>
+Harald Welte <laforge@gnumonks.org> <laflocal@hanuman.gnumonks.org>
+Harald Welte <laforge@gnumonks.org> <laflocal@goeller.de.gnumonks.org>
+Holger Hans Peter Freyther <holger@moiji-mobile.com> <zecke@selfish.org>
+Holger Hans Peter Freyther <holger@moiji-mobile.com> <ich@tamarin.(none)>
+Holger Hans Peter Freyther <holgre@moiji-mobile.com> <holger@freyther.de>
+Andreas Eversberg <jolly@eversberg.eu>
+Andreas Eversberg <jolly@eversberg.eu> <Andreas.Eversberg@versatel.de>
+Andreas Eversberg <jolly@eversberg.eu> <root@nuedel.(none)>
+Pablo Neira Ayuso <pablo@soleta.eu> <pablo@gnumonks.org>
+Max Suraev <msuraev@sysmocom.de>
+Tom Tsou <tom.tsou@ettus.com> <tom@tsou.cc>
diff --git a/AUTHORS b/AUTHORS
new file mode 100644
index 0000000..91af515
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1,9 @@
+Harald Welte <laforge@gnumonks.org>
+Holger Freyther <zecke@selfish.org>
+Jan Luebbe <jluebbe@debian.org>
+Stefan Schmidt <stefan@datenfreihafen.org>
+Daniel Willmann <daniel@totalueberwachung.de>
+Andreas Eversberg <Andreas.Eversberg@versatel.de>
+Sylvain Munaut <246tnt@gmail.com>
+Jacob Erlbeck <jerlbeck@sysmocom.de>
+Neels Hofmeyr <nhofmeyr@sysmocom.de>
diff --git a/COPYING b/COPYING
new file mode 100644
index 0000000..dba13ed
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,661 @@
+                    GNU AFFERO GENERAL PUBLIC LICENSE
+                       Version 3, 19 November 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The GNU Affero General Public License is a free, copyleft license for
+software and other kinds of works, specifically designed to ensure
+cooperation with the community in the case of network server software.
+
+  The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works.  By contrast,
+our General Public Licenses are intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+  Developers that use our General Public Licenses protect your rights
+with two steps: (1) assert copyright on the software, and (2) offer
+you this License which gives you legal permission to copy, distribute
+and/or modify the software.
+
+  A secondary benefit of defending all users' freedom is that
+improvements made in alternate versions of the program, if they
+receive widespread use, become available for other developers to
+incorporate.  Many developers of free software are heartened and
+encouraged by the resulting cooperation.  However, in the case of
+software used on network servers, this result may fail to come about.
+The GNU General Public License permits making a modified version and
+letting the public access it on a server without ever releasing its
+source code to the public.
+
+  The GNU Affero General Public License is designed specifically to
+ensure that, in such cases, the modified source code becomes available
+to the community.  It requires the operator of a network server to
+provide the source code of the modified version running there to the
+users of that server.  Therefore, public use of a modified version, on
+a publicly accessible server, gives the public access to the source
+code of the modified version.
+
+  An older license, called the Affero General Public License and
+published by Affero, was designed to accomplish similar goals.  This is
+a different license, not a version of the Affero GPL, but Affero has
+released a new version of the Affero GPL which permits relicensing under
+this license.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                       TERMS AND CONDITIONS
+
+  0. Definitions.
+
+  "This License" refers to version 3 of the GNU Affero General Public License.
+
+  "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+  "The Program" refers to any copyrightable work licensed under this
+License.  Each licensee is addressed as "you".  "Licensees" and
+"recipients" may be individuals or organizations.
+
+  To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy.  The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+  A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+  To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy.  Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+  To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies.  Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+  An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License.  If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+  1. Source Code.
+
+  The "source code" for a work means the preferred form of the work
+for making modifications to it.  "Object code" means any non-source
+form of a work.
+
+  A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+  The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form.  A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+  The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities.  However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work.  For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+  The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+  The Corresponding Source for a work in source code form is that
+same work.
+
+  2. Basic Permissions.
+
+  All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met.  This License explicitly affirms your unlimited
+permission to run the unmodified Program.  The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work.  This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+  You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force.  You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright.  Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+  Conveying under any other circumstances is permitted solely under
+the conditions stated below.  Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+  No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+  When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+  4. Conveying Verbatim Copies.
+
+  You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+  You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+  5. Conveying Modified Source Versions.
+
+  You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+    a) The work must carry prominent notices stating that you modified
+    it, and giving a relevant date.
+
+    b) The work must carry prominent notices stating that it is
+    released under this License and any conditions added under section
+    7.  This requirement modifies the requirement in section 4 to
+    "keep intact all notices".
+
+    c) You must license the entire work, as a whole, under this
+    License to anyone who comes into possession of a copy.  This
+    License will therefore apply, along with any applicable section 7
+    additional terms, to the whole of the work, and all its parts,
+    regardless of how they are packaged.  This License gives no
+    permission to license the work in any other way, but it does not
+    invalidate such permission if you have separately received it.
+
+    d) If the work has interactive user interfaces, each must display
+    Appropriate Legal Notices; however, if the Program has interactive
+    interfaces that do not display Appropriate Legal Notices, your
+    work need not make them do so.
+
+  A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit.  Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+  6. Conveying Non-Source Forms.
+
+  You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+    a) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by the
+    Corresponding Source fixed on a durable physical medium
+    customarily used for software interchange.
+
+    b) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by a
+    written offer, valid for at least three years and valid for as
+    long as you offer spare parts or customer support for that product
+    model, to give anyone who possesses the object code either (1) a
+    copy of the Corresponding Source for all the software in the
+    product that is covered by this License, on a durable physical
+    medium customarily used for software interchange, for a price no
+    more than your reasonable cost of physically performing this
+    conveying of source, or (2) access to copy the
+    Corresponding Source from a network server at no charge.
+
+    c) Convey individual copies of the object code with a copy of the
+    written offer to provide the Corresponding Source.  This
+    alternative is allowed only occasionally and noncommercially, and
+    only if you received the object code with such an offer, in accord
+    with subsection 6b.
+
+    d) Convey the object code by offering access from a designated
+    place (gratis or for a charge), and offer equivalent access to the
+    Corresponding Source in the same way through the same place at no
+    further charge.  You need not require recipients to copy the
+    Corresponding Source along with the object code.  If the place to
+    copy the object code is a network server, the Corresponding Source
+    may be on a different server (operated by you or a third party)
+    that supports equivalent copying facilities, provided you maintain
+    clear directions next to the object code saying where to find the
+    Corresponding Source.  Regardless of what server hosts the
+    Corresponding Source, you remain obligated to ensure that it is
+    available for as long as needed to satisfy these requirements.
+
+    e) Convey the object code using peer-to-peer transmission, provided
+    you inform other peers where the object code and Corresponding
+    Source of the work are being offered to the general public at no
+    charge under subsection 6d.
+
+  A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+  A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling.  In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage.  For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product.  A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+  "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source.  The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+  If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information.  But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+  The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed.  Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+  Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+  7. Additional Terms.
+
+  "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law.  If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+  When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it.  (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.)  You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+  Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+    a) Disclaiming warranty or limiting liability differently from the
+    terms of sections 15 and 16 of this License; or
+
+    b) Requiring preservation of specified reasonable legal notices or
+    author attributions in that material or in the Appropriate Legal
+    Notices displayed by works containing it; or
+
+    c) Prohibiting misrepresentation of the origin of that material, or
+    requiring that modified versions of such material be marked in
+    reasonable ways as different from the original version; or
+
+    d) Limiting the use for publicity purposes of names of licensors or
+    authors of the material; or
+
+    e) Declining to grant rights under trademark law for use of some
+    trade names, trademarks, or service marks; or
+
+    f) Requiring indemnification of licensors and authors of that
+    material by anyone who conveys the material (or modified versions of
+    it) with contractual assumptions of liability to the recipient, for
+    any liability that these contractual assumptions directly impose on
+    those licensors and authors.
+
+  All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10.  If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term.  If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+  If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+  Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+  8. Termination.
+
+  You may not propagate or modify a covered work except as expressly
+provided under this License.  Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+  However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+  Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+  Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License.  If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+  9. Acceptance Not Required for Having Copies.
+
+  You are not required to accept this License in order to receive or
+run a copy of the Program.  Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance.  However,
+nothing other than this License grants you permission to propagate or
+modify any covered work.  These actions infringe copyright if you do
+not accept this License.  Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+  10. Automatic Licensing of Downstream Recipients.
+
+  Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License.  You are not responsible
+for enforcing compliance by third parties with this License.
+
+  An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations.  If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+  You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License.  For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+  11. Patents.
+
+  A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based.  The
+work thus licensed is called the contributor's "contributor version".
+
+  A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version.  For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+  Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+  In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement).  To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+  If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients.  "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+  If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+  A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License.  You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+  Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+  12. No Surrender of Others' Freedom.
+
+  If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all.  For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+  13. Remote Network Interaction; Use with the GNU General Public License.
+
+  Notwithstanding any other provision of this License, if you modify the
+Program, your modified version must prominently offer all users
+interacting with it remotely through a computer network (if your version
+supports such interaction) an opportunity to receive the Corresponding
+Source of your version by providing access to the Corresponding Source
+from a network server at no charge, through some standard or customary
+means of facilitating copying of software.  This Corresponding Source
+shall include the Corresponding Source for any work covered by version 3
+of the GNU General Public License that is incorporated pursuant to the
+following paragraph.
+
+  Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU General Public License into a single
+combined work, and to convey the resulting work.  The terms of this
+License will continue to apply to the part which is the covered work,
+but the work with which it is combined will remain governed by version
+3 of the GNU General Public License.
+
+  14. Revised Versions of this License.
+
+  The Free Software Foundation may publish revised and/or new versions of
+the GNU Affero General Public License from time to time.  Such new versions
+will be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+  Each version is given a distinguishing version number.  If the
+Program specifies that a certain numbered version of the GNU Affero General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation.  If the Program does not specify a version number of the
+GNU Affero General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+  If the Program specifies that a proxy can decide which future
+versions of the GNU Affero General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+  Later license versions may give you additional or different
+permissions.  However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+  15. Disclaimer of Warranty.
+
+  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. Limitation of Liability.
+
+  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+  17. Interpretation of Sections 15 and 16.
+
+  If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    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/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+  If your software can interact with users remotely through a computer
+network, you should also make sure that it provides a way for users to
+get its source.  For example, if your program is a web application, its
+interface could display a "Source" link that leads users to an archive
+of the code.  There are many ways you could offer source, and different
+solutions will be better for different programs; see section 13 for the
+specific requirements.
+
+  You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU AGPL, see
+<http://www.gnu.org/licenses/>.
diff --git a/Makefile.am b/Makefile.am
new file mode 100644
index 0000000..9f3644f
--- /dev/null
+++ b/Makefile.am
@@ -0,0 +1,30 @@
+AUTOMAKE_OPTIONS = foreign dist-bzip2 1.6
+
+## FIXME: automake >= 1.13 or autoconf >= 2.70 provide better suited AC_CONFIG_MACRO_DIRS for configure.ac
+## remove line below when OE toolchain is updated to version which include those
+ACLOCAL_AMFLAGS = -I m4
+AM_CPPFLAGS = \
+	$(all_includes) \
+	-I$(top_srcdir)/include \
+	$(NULL)
+
+SUBDIRS = \
+	doc \
+	include \
+	src \
+	contrib \
+	tests \
+	$(NULL)
+
+BUILT_SOURCES = $(top_srcdir)/.version
+EXTRA_DIST = git-version-gen osmoappdesc.py .version
+
+DISTCHECK_CONFIGURE_FLAGS = \
+	--with-systemdsystemunitdir=$$dc_install_base/$(systemdsystemunitdir)
+
+@RELMAKE@
+
+$(top_srcdir)/.version:
+	echo $(VERSION) > $@-t && mv $@-t $@
+dist-hook:
+	echo $(VERSION) > $(distdir)/.tarball-version
diff --git a/README b/README
new file mode 100644
index 0000000..a45ef95
--- /dev/null
+++ b/README
@@ -0,0 +1,24 @@
+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.vty-tests b/README.vty-tests
new file mode 100644
index 0000000..0669ea8
--- /dev/null
+++ b/README.vty-tests
@@ -0,0 +1,11 @@
+To run the configuration parsing and output (VTY) test suite, first install
+
+  git://git.osmocom.org/python/osmo-python-tests
+
+and pass the following configure options here:
+
+  ./configure --enable-external-tests
+
+The VTY tests are then included in the standard check target:
+
+  make check
diff --git a/configure.ac b/configure.ac
new file mode 100644
index 0000000..2d8dc42
--- /dev/null
+++ b/configure.ac
@@ -0,0 +1,224 @@
+dnl Process this file with autoconf to produce a configure script
+AC_INIT([osmo-msc],
+	m4_esyscmd([./git-version-gen .tarball-version]),
+	[openbsc@lists.osmocom.org])
+
+dnl *This* is the root dir, even if an install-sh exists in ../ or ../../
+AC_CONFIG_AUX_DIR([.])
+
+AM_INIT_AUTOMAKE([dist-bzip2])
+AC_CONFIG_TESTDIR(tests)
+
+dnl kernel style compile messages
+m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
+
+dnl include release helper
+RELMAKE='-include osmo-release.mk'
+AC_SUBST([RELMAKE])
+
+dnl checks for programs
+AC_PROG_MAKE_SET
+AC_PROG_CC
+AC_PROG_INSTALL
+LT_INIT
+
+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
+        AC_MSG_WARN([You need to install pkg-config])
+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(LIBOSMOCORE, libosmocore >= 0.11.0)
+PKG_CHECK_MODULES(LIBOSMOVTY, libosmovty >= 0.11.0)
+PKG_CHECK_MODULES(LIBOSMOCTRL, libosmoctrl >= 0.11.0)
+PKG_CHECK_MODULES(LIBOSMOGSM, libosmogsm >= 0.11.0)
+PKG_CHECK_MODULES(LIBOSMOABIS, libosmoabis >= 0.5.0)
+PKG_CHECK_MODULES(LIBOSMONETIF, libosmo-netif >= 0.2.0)
+PKG_CHECK_MODULES(LIBOSMOSIGTRAN, libosmo-sigtran >= 0.9.0)
+PKG_CHECK_MODULES(LIBOSMOSCCP, libosmo-sccp >= 0.9.0)
+PKG_CHECK_MODULES(LIBOSMOMGCPCLIENT, libosmo-mgcp-client >= 1.3.0)
+PKG_CHECK_MODULES(LIBOSMOGSUPCLIENT, libosmo-gsup-client >= 0.2.1)
+
+AC_ARG_ENABLE(sanitize,
+	[AS_HELP_STRING(
+		[--enable-sanitize],
+		[Compile with address sanitizer enabled],
+	)],
+	[sanitize=$enableval], [sanitize="no"])
+if test x"$sanitize" = x"yes"
+then
+	CFLAGS="$CFLAGS -fsanitize=address -fsanitize=undefined"
+	CPPFLAGS="$CPPFLAGS -fsanitize=address -fsanitize=undefined"
+fi
+
+AC_ARG_ENABLE(werror,
+	[AS_HELP_STRING(
+		[--enable-werror],
+		[Turn all compiler warnings into errors, with exceptions:
+		 a) deprecation (allow upstream to mark deprecation without breaking builds);
+		 b) "#warning" pragmas (allow to remind ourselves of errors without breaking builds)
+		]
+	)],
+	[werror=$enableval], [werror="no"])
+if test x"$werror" = x"yes"
+then
+	WERROR_FLAGS="-Werror"
+	WERROR_FLAGS+=" -Wno-error=deprecated -Wno-error=deprecated-declarations"
+	WERROR_FLAGS+=" -Wno-error=cpp" # "#warning"
+	CFLAGS="$CFLAGS $WERROR_FLAGS"
+	CPPFLAGS="$CPPFLAGS $WERROR_FLAGS"
+fi
+
+# Enable/disable smpp support in the msc?
+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)
+    AC_DEFINE(BUILD_SMPP, 1, [Define if we want to build SMPP])
+fi
+AM_CONDITIONAL(BUILD_SMPP, test "x$osmo_ac_build_smpp" = "xyes")
+AC_SUBST(osmo_ac_build_smpp)
+
+# Enable/disable 3G aka IuPS + IuCS support?
+AC_ARG_ENABLE([iu], [AS_HELP_STRING([--enable-iu], [Build 3G support, aka IuPS and IuCS interfaces])],
+    [osmo_ac_iu="$enableval"],[osmo_ac_iu="no"])
+if test "x$osmo_ac_iu" = "xyes" ; then
+    PKG_CHECK_MODULES(LIBASN1C, libasn1c >= 0.9.30)
+    PKG_CHECK_MODULES(LIBOSMORANAP, libosmo-ranap >= 0.3.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))
+
+found_sqlite3=yes
+PKG_CHECK_MODULES(SQLITE3, sqlite3, ,found_sqlite3=no)
+AM_CONDITIONAL(HAVE_SQLITE3, test "$found_sqlite3" = yes)
+AC_SUBST(found_sqlite3)
+
+
+dnl Checks for typedefs, structures and compiler characteristics
+
+# The following test is taken from WebKit's webkit.m4
+saved_CFLAGS="$CFLAGS"
+CFLAGS="$CFLAGS -fvisibility=hidden "
+AC_MSG_CHECKING([if ${CC} supports -fvisibility=hidden])
+AC_COMPILE_IFELSE([AC_LANG_SOURCE([char foo;])],
+      [ AC_MSG_RESULT([yes])
+        SYMBOL_VISIBILITY="-fvisibility=hidden"],
+        AC_MSG_RESULT([no]))
+CFLAGS="$saved_CFLAGS"
+AC_SUBST(SYMBOL_VISIBILITY)
+
+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,
+              AC_HELP_STRING([--enable-coverage],
+                             [enable code coverage support [default=no]]),
+              [],[enable_coverage="no"])
+AC_MSG_RESULT([$enable_coverage])
+if test "$enable_coverage" = "yes"; then
+   COVERAGE_CFLAGS="-ftest-coverage -fprofile-arcs"
+   COVERAGE_LDFLAGS="-ftest-coverage -fprofile-arcs"
+   AC_SUBST([COVERAGE_CFLAGS])
+   AC_SUBST([COVERAGE_LDFLAGS])
+fi
+
+AC_DEFUN([CHECK_TM_INCLUDES_TM_GMTOFF], [
+  AC_CACHE_CHECK(
+    [whether struct tm has tm_gmtoff member],
+    osmo_cv_tm_includes_tm_gmtoff,
+    [AC_LINK_IFELSE([
+      AC_LANG_PROGRAM([
+        #include <time.h>
+      ], [
+        time_t t = time(NULL);
+        struct tm* lt = localtime(&t);
+        int off = lt->tm_gmtoff;
+      ])
+    ],
+    osmo_cv_tm_includes_tm_gmtoff=yes,
+    osmo_cv_tm_includes_tm_gmtoff=no
+    )]
+  )
+  if test "x$osmo_cv_tm_includes_tm_gmtoff" = xyes; then
+    AC_DEFINE(HAVE_TM_GMTOFF_IN_TM, 1,
+              [Define if struct tm has tm_gmtoff member.])
+  fi
+])
+
+CHECK_TM_INCLUDES_TM_GMTOFF
+
+AC_ARG_ENABLE([external_tests],
+		AC_HELP_STRING([--enable-external-tests],
+				[Include the VTY/CTRL tests in make check [default=no]]),
+		[enable_ext_tests="$enableval"],[enable_ext_tests="no"])
+if test "x$enable_ext_tests" = "xyes" ; then
+	AM_PATH_PYTHON
+	AC_CHECK_PROG(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.])
+	fi
+fi
+AC_MSG_CHECKING([whether to enable VTY/CTRL tests])
+AC_MSG_RESULT([$enable_ext_tests])
+AM_CONDITIONAL(ENABLE_EXT_TESTS, test "x$enable_ext_tests" = "xyes")
+
+# https://www.freedesktop.org/software/systemd/man/daemon.html
+AC_ARG_WITH([systemdsystemunitdir],
+     [AS_HELP_STRING([--with-systemdsystemunitdir=DIR], [Directory for systemd service files])],,
+     [with_systemdsystemunitdir=auto])
+AS_IF([test "x$with_systemdsystemunitdir" = "xyes" -o "x$with_systemdsystemunitdir" = "xauto"], [
+     def_systemdsystemunitdir=$($PKG_CONFIG --variable=systemdsystemunitdir systemd)
+
+     AS_IF([test "x$def_systemdsystemunitdir" = "x"],
+   [AS_IF([test "x$with_systemdsystemunitdir" = "xyes"],
+    [AC_MSG_ERROR([systemd support requested but pkg-config unable to query systemd package])])
+    with_systemdsystemunitdir=no],
+   [with_systemdsystemunitdir="$def_systemdsystemunitdir"])])
+AS_IF([test "x$with_systemdsystemunitdir" != "xno"],
+      [AC_SUBST([systemdsystemunitdir], [$with_systemdsystemunitdir])])
+AM_CONDITIONAL([HAVE_SYSTEMD], [test "x$with_systemdsystemunitdir" != "xno"])
+
+AC_MSG_RESULT([CFLAGS="$CFLAGS"])
+AC_MSG_RESULT([CPPFLAGS="$CPPFLAGS"])
+
+dnl Generate the output
+AM_CONFIG_HEADER(bscconfig.h)
+
+AC_OUTPUT(
+    include/Makefile
+    include/osmocom/Makefile
+    include/osmocom/msc/Makefile
+    src/Makefile
+    src/libmsc/Makefile
+    src/libvlr/Makefile
+    src/osmo-msc/Makefile
+    src/utils/Makefile
+    tests/Makefile
+    tests/atlocal
+    tests/smpp/Makefile
+    tests/sms_queue/Makefile
+    tests/msc_vlr/Makefile
+    doc/Makefile
+    doc/examples/Makefile
+    contrib/Makefile
+    contrib/systemd/Makefile
+    Makefile)
diff --git a/contrib/Makefile.am b/contrib/Makefile.am
new file mode 100644
index 0000000..3439c97
--- /dev/null
+++ b/contrib/Makefile.am
@@ -0,0 +1 @@
+SUBDIRS = systemd
diff --git a/contrib/jenkins.sh b/contrib/jenkins.sh
new file mode 100755
index 0000000..8b8b6e7
--- /dev/null
+++ b/contrib/jenkins.sh
@@ -0,0 +1,63 @@
+#!/usr/bin/env bash
+# jenkins build helper script for openbsc.  This is how we build on jenkins.osmocom.org
+
+if ! [ -x "$(command -v osmo-build-dep.sh)" ]; then
+	echo "Error: We need to have scripts/osmo-deps.sh from http://git.osmocom.org/osmo-ci/ in PATH !"
+	exit 2
+fi
+
+
+set -ex
+
+base="$PWD"
+deps="$base/deps"
+inst="$deps/install"
+export deps inst
+
+osmo-clean-workspace.sh
+
+mkdir "$deps" || true
+
+osmo-build-dep.sh libosmocore "" ac_cv_path_DOXYGEN=false
+
+verify_value_string_arrays_are_terminated.py $(find . -name "*.[hc]")
+
+export PKG_CONFIG_PATH="$inst/lib/pkgconfig:$PKG_CONFIG_PATH"
+export LD_LIBRARY_PATH="$inst/lib"
+
+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 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
+
+set +x
+echo
+echo
+echo
+echo " =============================== osmo-msc ==============================="
+echo
+set -x
+
+cd "$base"
+autoreconf --install --force
+./configure --enable-sanitize $enable_werror --enable-smpp $IU --enable-external-tests
+$MAKE $PARALLEL_MAKE
+LD_LIBRARY_PATH="$inst/lib" $MAKE check \
+  || cat-testlogs.sh
+LD_LIBRARY_PATH="$inst/lib" \
+  DISTCHECK_CONFIGURE_FLAGS="$enable_werror --enable-smpp $IU --enable-external-tests" \
+  $MAKE distcheck \
+  || cat-testlogs.sh
+
+osmo-clean-workspace.sh
diff --git a/contrib/systemd/Makefile.am b/contrib/systemd/Makefile.am
new file mode 100644
index 0000000..8648172
--- /dev/null
+++ b/contrib/systemd/Makefile.am
@@ -0,0 +1,5 @@
+if HAVE_SYSTEMD
+EXTRA_DIST = osmo-msc.service
+systemdsystemunit_DATA = \
+  osmo-msc.service
+endif
diff --git a/contrib/systemd/osmo-msc.service b/contrib/systemd/osmo-msc.service
new file mode 100644
index 0000000..343639c
--- /dev/null
+++ b/contrib/systemd/osmo-msc.service
@@ -0,0 +1,15 @@
+[Unit]
+Description=Osmocom Mobile Switching Center (MSC)
+Wants=osmo-hlr.service
+Wants=osmo-mgw.service
+After=osmo-hlr.service
+After=osmo-hnbgw.service
+
+[Service]
+Type=simple
+Restart=always
+ExecStart=/usr/bin/osmo-msc -c /etc/osmocom/osmo-msc.cfg
+RestartSec=2
+
+[Install]
+WantedBy=multi-user.target
diff --git a/debian/changelog b/debian/changelog
new file mode 100644
index 0000000..f14c792
--- /dev/null
+++ b/debian/changelog
@@ -0,0 +1,369 @@
+osmo-msc (1.2.0) unstable; urgency=medium
+
+  [ Neels Hofmeyr ]
+  * msc_vlr_tests: fix rebuild: rebuild when src/ libs were rebuilt
+  * cosmetic: vlr: rename auth_tuple_max_use_count to _reuse_
+  * tests: add msc_vlr_test_authen_reuse
+  * vty: make auth tuple reuse configurable
+  * vty: drop deprecated 'logging level sms...'
+  * defaults: assign TMSI by default
+  * vty: skip installing cmds now always installed by default
+  * examples: apply mgcp_client vty rename from 'mgcpgw' to 'mgw'
+  * vlr: auth_fsm_start: check return value of fsm alloc
+  * add --enable-sanitize config option
+  * rate_ctr: don't use . as separator
+  * sub_pres_vlr_fsm_start: fix heap use after free
+  * vlr_gsupc_read_cb: fix use after free of GSUP msgb
+  * subscr_conn: don't close after conn timeout
+  * vlr_subscr_conn_timeout(): don't fire events to discarded fi
+  * cosmetic: msc_vlr_tests: add comment to show expected tallocs
+  * sms_queue_test: sanitize: clean up talloc contexts when done
+  * cosmetic: log: CC state transition: log trans id and subscr
+  * cosmetic: log: CC trans_alloc: log trans_id and subscr, not memory addrs
+  * cosmetic: debug log: mncc: detached subscr: show subscriber
+  * msc_vlr_tests: fix test nr arg: clear errno before strtol()
+  * msc_vlr_tests: set a valid lac for fake conns
+  * use only 0.23.1 as point code for both A and Iu
+  * subscr_conn: introduce usage tokens for ref error tracking
+  * cosmetic: log error when using a conn that's in release
+  * add msc_vlr_test_call to reproduce a sanitizer error
+  * fix use after free: missing conn_get on CC paging response
+  * sms db: don't attempt to query pending SMS for unset MSISDN
+  * sms db: properly quote MSISDN in various SQL queries
+  * sms.db: silence libdbi warnings on out-of-range index
+  * fix vty write: add missing 'authentication optional/required' output
+  * compiler warning: drop double 'const' in a_iface_tx_cipher_mode()
+  * debug log: a_iface_tx_cipher_mode(): log cipher and key
+  * cosmetic: msc_vlr_tests: log SMS details when invoked with -v
+  * vlr: debug log: log Ciphering Mode details
+  * fix BSSMAP Cipher Mode Cmd: properly set permitted algorithms
+  * cosmetic: move translation of vlr_ciph into msc_vlr_set_ciph_mode()
+  * cosmetic prep: publish vlr_use_umts_aka() decision
+  * cosmetic prep: tell vlr_ops.set_ciph_mode() whether UMTS AKA is used
+  * drop unused T* timers (BSC land, not MSC)
+  * cosmetic: msc_paging_request: drop obsolete comment
+  * fix GSM-Milenage in presence of 2G keys
+  * compiler warning: extend #if 0 to include unused array
+  * a_iface_bssap: compiler warning: cast const away from TLV val for l2h
+  * smpp_smsc: fix truncated string copy into bind_r.system_id
+  * log: a_iface.c: revisit logging, use LOGPCONN
+  * cosmetic: rename sccp_rx_udt and sccp_rx_dt to a_*
+  * fix paging: add timeout to discard unsuccessful paging
+  * fix: properly cancel all Paging on IMSI Detach
+  * a_iface_tx_assignment: fix log lvl for "Sending Assignment..."
+  * fix build: missing LIBOSMORANAP flags in libmsc
+  * drop unused libmsc/meas_feed.h
+  * cosmetic: gsm_network_init(): imply default 001-01 PLMN
+  * implement support for 3-digit MNC with leading zeros
+  * vlr: fix post-auth LU failure handling
+  * vlr_lu_fsm: guard against using the wrong fi
+  * msc_vlr_tests: revert IMSI parameter and test nr output
+  * msc_vlr_test_gsm_ciph: drop unused function
+  * msc_vlr_tests: make all test functions static
+  * msc_vlr_tests: improve cipher mode coverage
+  * fix: clear vlr_subscr->msc_conn_ref when the conn is discarded
+  * vty: drop unused commands
+  * vty: add 'msisdn' as alias for 'extension'
+  * vty: add 'subscriber ... paging' cmd
+  * msc_main: do not say 'osmo-nitb' in the usage
+  * silent call: clarify rc and error messages logged on vty
+  * msc_vlr_tests: clearly separate Ciph Mode from Security Mode checking
+  * msc_vlr_test_gsm_ciph: add test for GSM AKA in UMTS environment
+  * vlr: fix GSM AKA in a UMTS AKA capable environment
+  * vlr auth: gracefully reject malformed auth response
+  * gsm48_rx_mm_auth_resp(): pass is_r99 from classmark, not response size
+  * cosmetic: gsm48_rx_mm_auth_resp(): log 'UMTS AUTH', not 'R99 AUTH'
+  * msc_vlr_test_umts_authen: test response with too short RES
+  * msc_vlr_test_umts_authen: test response with too long RES
+  * msc_vlr_test_umts_authen: test response with only SRES half of RES
+  * cosmetic: vlr_auth_fsm: clarify decision on UMTS AKA or GSM AKA
+  * cosmetic: vlr_auth_fsm: log RAN and size along with SRES/RES
+  * msc_vlr_tests: add test_a5_3_not_supported
+  * configure: add --enable-werror
+  * vlr_ciph_result: fix use after free of imeisv
+  * trans_free: safeguard against a still running CC timer on free
+  * cosmetic: vlr_auth: log decision to send UMTS or GSM AKA challenge
+  * cosmetic: msc_vlr_tests: enable CC logging in debug
+  * cosmetic: rename conn_fsm "bump" event to "release_when_unused"
+  * msc_vlr_tests: add CC Release test and test to catch OS#2779
+  * cosmetic: gsm_04_08.c: drop unused struct gsm_lai
+  * trans_free: tear down conn when last transaction is done
+  * dissolve libcommon,libcommon-cs: clean up vty definitions
+  * cosmetic: msc_vty.c: use static gsmnet instead of gsmnet_from_vty()
+  * dissolve libcommon: drop unused bsc_version.c
+  * dissolve libcommon: drop debug.c
+  * dissolve libcommon: move talloc ctx into msc_main.c, drop talloc_ctx.c
+  * dissolve libcommon: drop gsm_subscriber_base.c, move vlr_subscr_* to vlr.c
+  * dissolve libcommon: drop gsm_data.c, move code to libmsc
+  * rename libcommon to libgsupclient
+  * dissolve libcommon-cs: mv a_reset.c to libmsc
+  * dissolve libcommon-cs: move gsm_network_init() to libmsc
+  * dissolve libcommon-cs: move gsm48_* code to libmsc, drop sms_next_rp_msg_ref()
+  * remove empty libcommon-cs
+  * gsup_test_client: gsupc_read_cb: fix uninitialized value 'io'
+  * use osmo_init_logging2() with proper talloc ctx
+  * drop some dead definitions (gsm_data.h, gsup_client.c)
+  * test_reject_concurrency: missing assert
+  * cosmetic: rx_bssmap: read message type once into local var
+  * cosmetic: rename gsm_subscriber_connection->conn_fsm to ->fi
+  * cosmetic: rename subscr_conn_from to complete_layer3_type
+  * subscr_conn: store complete_layer3_type in conn, not FSM event arg
+  * unify allocation of gsm_subscriber_connection
+  * trans_free: drop bad assertion
+  * msc_vlr_test_call: reproduce OS#3062
+  * CC: intentionally release T308 on BSSMAP Clear Request from BSC
+  * refactor subscr_conn and subscr_conn_fsm de-/alloc
+  * properly receive BSSMAP Clear Complete and Iu Release Complete
+  * fix BSC Clear Request
+  * cosmetic: embed compl_l3_type in FSM id
+  * refactor VLR FSM result handling
+  * msc conn ref counts: log human readable list of conn owners
+  * cosmetic: use enum ranap_nsap_addr_enc instead of int
+
+  [ Harald Welte ]
+  * sms_route_mt_sms: Don't return uninitialized variable
+  * MNCC: Add input validation
+  * Log difference between SETUP and EMERGENCY_SETUP
+  * Emergency Call: Set MNCC_F_EMERGENCY flag
+  * Refuse Emergency Calls by IMEI with proper CM SERVICE REJECT Cause
+    (Closes: #2866)
+  * Reject any CM SERVICE we don't support
+  * Remove traces of meas_feed
+  * Fix msc_vlr test results (.err) for new libosmocore GSM48_PDISC names
+  * Properly reject CM Re-Establishment Request
+  * msc_cipher_mode_compl: Handle CIPH MOD COMPL without L3 message
+  * remove unused paging.h and osmo_bsc_grace.h
+  * debug: Remove code for filters that don't exist in OsmoMSC
+  * remove traces of bsc_subscriber
+  * jenkins.sh: Don't depend on osmo-ggsn
+  * Massive removal of unused code/structs/headers
+  * remove unused ipaccess.h
+  * remove dead code in auth.h / auth.c
+  * remove dead header files bsc_msc.h, bsc_msc_data.h and bsc_rll.h
+  * signal.h: Remove unused/dead signal definitions
+  * remove dead ctrl.h header file
+  * debug: Remove dead log categories
+  * Shift ciphering algorithm selection from VLR to MSC
+  * Permit a set of multiple different A5 ciphers
+  * MSC: Intersect configured A5 algorithms with MS-supported ones
+  * Change GSUP re-connect interval to 1s
+  * Implement checks for duplicate uplink UL L3 message (Closes: #2908)
+  * VTY: Add 'show connections' and 'show transactions' commands
+  * a_reset: Add additional "a_reset_alloc" argument
+  * Don't answer to BSC-originated RESET with another RESET
+  * cosmetic: Use msgb_hexdump*() rather than manual osmo_hexdump() on msg
+  * a_iface: Reduce log levels
+  * a_iface_bssap.c: Use LOGPCONN() whenever possible
+  * a_sccp_rx_dt(): Don't print hexdump of message multiple times
+  * cosmetic: a_iface: Harmonize log statements
+  * cosmetic: No need for 'break' after 'return'
+  * a_iface: centralize lookup of subscriber_conn
+  * cosmetic: a_iface: More logging harmonization
+  * a_iface: Add copyright statement (after recent contributions)
+  * Introduce new BSSAP logging category/subsystem
+  * a_iface: Fix heap-use-after-free by cleaning up msgb ownership
+  * Add VTY command to configure destination MSISDN for emergency calls
+  * a_iface: Fix heap-use-after-free in a_clear_all()
+  * MGCP: Response code 250 is *not* an error for DLCX
+  * a_iface: s/Abis/L3/ for speech version/preference fields
+  * a_iface: Consistent and understandable function names
+  * MT Calls: Copy bearer capabilities from NNCC primitive to trans
+  * MNCC: Copy bearer_cap from MNCC to gsm_trans
+  * gsm_data: remove unused gsm_subscriber_connection members
+  * remove bsc_api.h and all users - they're all dead code
+  * dead code removal
+  * remove unused dyn_ts_allow_tch_f VTY option
+  * osmo-msc: Add talloc context introspection via VTY
+  * remove unused VTY command "location updating reject cause"
+  * remove unused "authorized-regexp" VTY command
+  * remove unused "auth policy" VTY command
+  * remove dead code (gsm_parse_reg)
+  * BSSAP: Return error code if COMPL L3 with no or too short L3 payload
+  * a_iface_bssap: Treat inbound RESET as implicit RESET ACK
+  * a_iface: If L3/DTAP returns error in COMPL L3, close SCCP connection
+  * DTAP: Ensure proper DLCI is used in MSC-originated DTAP
+  * Permit any Sender MSISDN when sending SMS from VTY
+  * smpp: Unset esme->acl on socket close
+  * sms_queue: fix use-after-free on 'pending'
+
+  [ Alexander Couzens ]
+  * debian/rules: remove doublicated project name in example files
+  * libmsc/vty: don't access old bsc rate counters
+
+  [ Philipp Maier ]
+  * reset: remove name variable from reset context
+  * cosmetic: move log message to else branch
+  * cosmetic: add missing spaces
+  * cosmetic: remove duplicate logging
+  * mncc: re-add lchan members to structs
+  * mncc: remove deprecated commandline option.
+  * a_iface: correct data type for a.conn_id in gsm_subscriber_connection
+  * mgcp: use osmo-mgw to switch rtp streams
+  * increase RAN timeout in MGCP FSM
+  * a_reset: Add FSM event names
+  * msc_mgcp: Add FSM event names
+  * a_iface: fix BSSMAP reset handling
+  * msc_mgcp: fix mgw timeout handling
+  * mgcp: be sure that pending mgcp transactions are canceled before free
+  * msc_mgcp: use more conceise error msg on truncation
+  * mcgp: let the MGW allocate the MGCP endpoint
+  * cosmetic: remove disabled (debug) code gsm_04_08.c
+  * msc_mgcp: to not access higher layers after release
+  * cosmetic: remove unused variable
+  * msc_mgcp.c: log endpoint name instead of pointer
+  * msc_mgcp: do not send wildcarded DLCX messages
+
+  [ Max ]
+  * Use osmo-ggsn instead of openggsn in jenkins tests
+  * Add basic CTRL test
+  * Remove obsolete ./configure option
+  * Remove unneeded .py scripts
+  * Enable sanitize for CI tests
+  * Migrate from OpenSSL to osmo_get_rand_id()
+  * VLR: remove unused parameter
+  * VLR: log subscriber update
+  * Add control command to expire subscriber
+  * VLR: constify GSUP-related function parameters
+  * cosmetic: log prim operation as text
+  * Remove unused code
+  * Wrap osmo_strlcpy() calls
+  * Fix whitespace issues
+  * Constify msc_subscr_conn_is_accepted() parameter
+  * Move IMSI into test parameters
+  * VLR tests: mark static test functions as such
+  * Expand VLR tests
+  * VLR tests: don't fail via assert
+  * VLR tests: remove weird code
+  * VLR tests: always print test parameters
+  * VLR tests: move network init into function
+  * GSUP: check osmo_gsup_encode() result
+  * VLR: fix potential NULL dereference
+
+  [ Alexander Huemer ]
+  * Add missing CFLAGS
+  * Remove utils imported from openbsc, fix building remaining util smpp_mirror
+
+  [ Pau Espin Pedrol ]
+  * libmsc: db.c: Replace dbi APIs marked as deprecated
+  * libmsc: msc_vty: Fix compilation warning
+  * libmsc: bssap: Fix typo in log message
+  * libmsc: bssap: Refactor rx paths to to avoid parse_tlv code duplication
+  * libmsc: bssap: Catch TLV parse failures
+  * libmsc: bssap: Remove fixme and properly update msgb tail
+  * msc_mgcp.c: Fix several wrong ptr printf fmt
+  * contrib: osmo-msc.service: Depend on osmo-mgw.service
+  * smpp_smsc_conf: Fix heap-use-after-free
+  * Remove unused GSM_PAGING_OOM
+  * setup_trig_pag_evt: Remove uneeded default case in switch statement
+  * setup_trig_pag_evt: Always log correct paging failure case
+  * setup_trig_pag_evt: Fix heap-use-after-free
+
+  [ the 34c3 gsm team ]
+  * smpp_smsc.c: don't talloc_strdup NULL pointers
+
+  [ Vadim Yanitskiy ]
+  * msc/gsm_04_80.h: clean up useless declarations
+  * msc/gsm_04_80.h: cosmetic: whitespace fix
+  * msc/gsm_04_80.h: use '#pragma once' instead of includes
+  * src/libmsc/ussd.c: drop useless forward declaration
+  * ussd.h: cosmetic: remove useless comment
+  * ussd.h: cosmetic: use '#pragma once' include guard
+  * libmsc/gsm_04_80.c: drop unused 'in_msg' argument
+  * libmsc/ussd.c: cosmetic: correct log level and message
+  * libmsc/ussd: don't overwrite rc if decoding failed
+  * tests/msc_vlr: fix expected SS message names
+
+  [ Stefan Sperling ]
+  * Improve an error message in db_init().
+  * Delete SMS from the database once they were sent successfully
+  * Store/retrieve SMS validity time in the SMS datebase
+  * Fix value of stored SMS validity time.
+  * Add a VTY command which deletes all expired SMS.
+  * Accept SMS for any receiver
+  * Delete expired SMS automatically.
+  * Make sending an SMS to an unknown subscriber B work over SMPP.
+  * enable osmo_fsm vty commands in osmo-msc vty
+  * Track libosmocore API change in osmo-msc.
+  * restore sending of optional MM info messages
+  * use libosmocom to parse cell identifier in bssmap_rx_l3_compl()
+
+  [ Daniel Willmann ]
+  * iucs: Add a function to return the connection ID for the IU SCCP conn
+  * libmsc: Add a function to return a unique ID of the subscriber conn
+  * libmsc: Pretend MNCC requested release in handle_error()
+
+ -- Pau Espin Pedrol <pespin@sysmocom.de>  Thu, 03 May 2018 18:52:03 +0200
+
+osmo-msc (1.1.2) unstable; urgency=medium
+
+  * Depend on both libosmo-sigtran-dev and libosmo-sccp-dev
+  * Debian: require minimum versions of packages we depend on
+
+ -- Harald Welte <laforge@gnumonks.org>  Sun, 29 Oct 2017 09:01:30 +0100
+
+osmo-msc (1.1.1) unstable; urgency=medium
+
+  * Debian: Depend on libosmo-sigtran-dev, not libsomo-sccp-dev!
+
+ -- Harald Welte <laforge@gnumonks.org>  Sat, 28 Oct 2017 21:57:22 +0200
+
+osmo-msc (1.1.0) unstable; urgency=medium
+
+  [ Alexander Couzens ]
+  * Initial release.
+  * debian/rules: show testsuite.log when tests are failing
+
+  [ Neels Hofmeyr ]
+  * build: check for -lgsm
+  * am: msc_vlr_tests: use AM_LDFLAGS instead of COMMON vars
+  * jenkins: fix build: osmo-mgw from master, not pre_release
+  * jenkins: drop unused build matrix vars, always --enable-smpp
+  * configure.ac: fix to "AC_INIT[osmo-msc]"
+  * rewrite README
+  * rename openbsc.pc to osmo-msc.pc
+  * debian: fix web and VCS links, tweak osmo-msc.install
+  * drop files unrelated to osmo-msc
+  * rename include/openbsc to include/osmocom/msc
+  * doc/examples: add detailed cs7 config examples
+  * use separated libosmo-mgcp-client, apply rename to mgcp_client_*
+  * ctrl: subscriber-list-active: list only attached subscribers
+  * debian: fix dependency to mgcp library
+  * main: remove cmdline args no longer available for osmo-msc
+  * vty: fix: missing default cmds at hlr node
+  * ctrl: remove unimplemented cmds subscriber-{modify,delete}
+  * fix build: remove obsolete header legacy_mgcp/mgcp.h
+  * fix debian: fix erratic doc/examples install path
+  * fix memory leak: vlr: vlr_gsupc_read_cb() must msgb_free()
+  * fix vty tests: long timeout due to unreachable STP address
+  * cosmetic: vlr: declare a struct in .h; drop unused header
+  * add ';' after OSMO_ASSERT()
+
+  [ Philipp Maier ]
+  * a_iface: fix memory leaks
+  * a_iface: fix typo
+
+  [ Max ]
+  * Remove rest_octets.h
+  * Remove SI-related code
+  * Remove BTS-specific attributes
+  * Remove unused osmo_bsc_rf.h header
+  * Remove pkg-config file
+
+  [ Harald Welte ]
+  * Update .gitignore for post-nitb-split
+  * remove further files and autotest/autoconf bits irrelevant to osmo-msc
+  * Rename osmo_fsm to avoid illegal space in name + more meaningful name
+  * Debian: remove obsolete Dependencies
+  * configure.ac: Depend on latest tagged/released libosmo-* versions
+  * Debian: Build with enabled SMPP support
+  * osmo-msc: Don't link against libasn1c
+  * Debian: Include systemd.service in package
+  * Debian: include all (not just one) example config files
+
+ -- Harald Welte <laforge@gnumonks.org>  Sat, 28 Oct 2017 14:45:58 +0200
+
+osmo-msc (0.1.0) UNRELEASED; urgency=low
+
+  * Initial release.
+
+ -- Alexander Couzens <lynxis@fe80.eu>  Tue, 08 Aug 2017 01:13:01 +0000
diff --git a/debian/compat b/debian/compat
new file mode 100644
index 0000000..ec63514
--- /dev/null
+++ b/debian/compat
@@ -0,0 +1 @@
+9
diff --git a/debian/control b/debian/control
new file mode 100644
index 0000000..e607d10
--- /dev/null
+++ b/debian/control
@@ -0,0 +1,63 @@
+Source: osmo-msc
+Section: net
+Priority: extra
+Maintainer: Alexander Couzens <lynxis@fe80.eu>
+Build-Depends: debhelper (>=9),
+               dh-autoreconf,
+               autotools-dev,
+               autoconf,
+               automake,
+               libtool,
+               pkg-config,
+               libdbi-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)
+Standards-Version: 3.9.8
+Vcs-Git: git://git.osmocom.org/osmo-msc.git
+Vcs-Browser: https://git.osmocom.org/osmo-msc/
+Homepage: https://osmocom.org/projects/osmomsc
+
+Package: osmo-msc
+Architecture: any
+Multi-Arch: foreign
+Depends: ${misc:Depends}, ${shlibs:Depends}
+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
+  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.
+
+Package: osmo-msc-dbg
+Section: debug
+Architecture: any
+Multi-Arch: same
+Depends: osmo-msc (= ${binary:Version}), ${misc:Depends}
+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
+  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.
+  .
+  This package contains the debug symbols for osmo-mgw in order to
+  generate meaningful backtraces in bug-reports.
diff --git a/debian/copyright b/debian/copyright
new file mode 100644
index 0000000..e3cd9b3
--- /dev/null
+++ b/debian/copyright
@@ -0,0 +1,173 @@
+Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
+Upstream-Name: osmo-msc
+Source: git://git.osmocom.org/osmo-msc
+
+Files:     *
+Copyright: 2008 Daniel Willmann <daniel@totalueberwachung.de>
+           2008 Jan Luebbe <jluebbe@debian.org>
+           2008-2015 Holger Hans Peter Freyther <zecke@selfish.org>
+           2008-2016 Harald Welte <laforge@gnumonks.org>
+           2009 Andreas Eversberg <Andreas.Eversberg@versatel.de>
+           2009 Mike Haben <michael.haben@btinternet.com>
+           2010 Sylvain Munaut <tnt@246tNt.com>
+           2010-2013 On-Waves
+           2013 Jacob Erlbeck <jerlbeck@sysmocom.de>
+           2011 Andreas Eversberg <jolly@eversberg.eu>
+           2011-2017 sysmocom s.f.m.c. GmbH <info@sysmocom.de>
+           2014-2015 Alexander Chemeris <Alexander.Chemeris@fairwaves.co>
+License:   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/>.
+
+Files:     src/libmsc/mncc_builtin.c
+           src/libmsc/mncc_sock.c
+Copyright: 2008-2010 Harald Welte <laforge@gnumonks.org>
+           2009 Andreas Eversberg <Andreas.Eversberg@versatel.de>
+           2012 Holger Hans Peter Freyther
+License:   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.
+ .
+ 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.
+ .
+ On Debian systems, the complete text of the GNU General Public License
+ Version 2 can be found in `/usr/share/common-licenses/GPL-2'.
+
+Files:     osmoappdesc.py
+Copyright: 2013 Katerina Barone-Adesi <kat.obsc@gmail.com>
+License:   GPL-3.0+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+ .
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ GNU General Public License for more details.
+ .
+ You should have received a copy of the GNU General Public License
+ along with this program.  If not, see <http://www.gnu.org/licenses/>
+ .
+ Most systems won't be able to use these, so they're separated out
+ .
+ On Debian systems, the complete text of the GNU General Public License
+ Version 3 can be found in `/usr/share/common-licenses/GPL-3'.
+
+Files:     git-version-gen
+Copyright: 2007-2010 Free Software Foundation, Inc.
+License:   GPL-3.0+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+ .
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ GNU General Public License for more details.
+ .
+ You should have received a copy of the GNU General Public License
+ along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ .
+ This script is derived from GIT-VERSION-GEN from GIT: http://git.or.cz/.
+ It may be run two ways:
+ - from a git repository in which the "git describe" command below
+ produces useful output (thus requiring at least one signed tag)
+ - from a non-git-repo directory containing a .tarball-version file, which
+ presumes this script is invoked like "./git-version-gen .tarball-version".
+ .
+ In order to use intra-version strings in your project, you will need two
+ separate generated version string files:
+ .
+ .tarball-version - present only in a distribution tarball, and not in
+ a checked-out repository.  Created with contents that were learned at
+ the last time autoconf was run, and used by git-version-gen.  Must not
+ be present in either $(srcdir) or $(builddir) for git-version-gen to
+ give accurate answers during normal development with a checked out tree,
+ but must be present in a tarball when there is no version control system.
+ Therefore, it cannot be used in any dependencies.  GNUmakefile has
+ hooks to force a reconfigure at distribution time to get the value
+ correct, without penalizing normal development with extra reconfigures.
+ .
+ .version - present in a checked-out repository and in a distribution
+ tarball.  Usable in dependencies, particularly for files that don't
+ want to depend on config.h but do want to track version changes.
+ Delete this file prior to any autoconf run where you want to rebuild
+ files to pick up a version string change; and leave it stale to
+ minimize rebuild time after unrelated changes to configure sources.
+ .
+ It is probably wise to add these two files to .gitignore, so that you
+ don't accidentally commit either generated file.
+ .
+ Use the following line in your configure.ac, so that $(VERSION) will
+ automatically be up-to-date each time configure is run (and note that
+ since configure.ac no longer includes a version string, Makefile rules
+ should not depend on configure.ac for version updates).
+ .
+ On Debian systems, the complete text of the GNU General Public License
+ Version 3 can be found in `/usr/share/common-licenses/GPL-3'.
+
+Files:     tests/vty_test_runner.py
+Copyright: 2013 Holger Hans Peter Freyther
+           2013 Katerina Barone-Adesi <kat.obsc@gmail.com>
+License:   GPL-3.0+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+ .
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ GNU General Public License for more details.
+ .
+ You should have received a copy of the GNU General Public License
+ along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ .
+ On Debian systems, the complete text of the GNU General Public License
+ Version 3 can be found in `/usr/share/common-licenses/GPL-3'.
+
+Files:     include/openbsc/slhc.h
+Copyright: 1989 Regents of the University of California.
+License:   __UNKNOWN__
+ Redistribution and use in source and binary forms are permitted
+ provided that the above copyright notice and this paragraph are
+ duplicated in all such forms and that any documentation,
+ advertising materials, and other materials related to such
+ distribution and use acknowledge that the software was developed
+ by the University of California, Berkeley.  The name of the
+ University may not be used to endorse or promote products derived
+ from this software without specific prior written permission.
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ .
+ Van Jacobson (van@helios.ee.lbl.gov), Dec 31, 1989:
+ - Initial distribution.
+ .
+ modified for KA9Q Internet Software Package by
+ Katie Stevens (dkstevens@ucdavis.edu)
+ University of California, Davis
+ Computing Services
+ - 01-31-90	initial adaptation
+
diff --git a/debian/osmo-msc.install b/debian/osmo-msc.install
new file mode 100644
index 0000000..e4b9646
--- /dev/null
+++ b/debian/osmo-msc.install
@@ -0,0 +1,6 @@
+etc/osmocom/osmo-msc.cfg
+lib/systemd/system/osmo-msc.service
+usr/bin/osmo-msc
+usr/share/doc/osmo-msc/examples/osmo-msc/osmo-msc.cfg usr/share/doc/osmo-msc/examples
+usr/share/doc/osmo-msc/examples/osmo-msc/osmo-msc_custom-sccp.cfg usr/share/doc/osmo-msc/examples
+usr/share/doc/osmo-msc/examples/osmo-msc/osmo-msc_multi-cs7.cfg usr/share/doc/osmo-msc/examples
diff --git a/debian/rules b/debian/rules
new file mode 100755
index 0000000..1cf3a35
--- /dev/null
+++ b/debian/rules
@@ -0,0 +1,63 @@
+#!/usr/bin/make -f
+# You must remove unused comment lines for the released package.
+# See debhelper(7) (uncomment to enable)
+# This is an autogenerated template for debian/rules.
+#
+# Output every command that modifies files on the build system.
+#export DH_VERBOSE = 1
+#
+# Copy some variable definitions from pkg-info.mk and vendor.mk
+# under /usr/share/dpkg/ to here if they are useful.
+#
+# See FEATURE AREAS/ENVIRONMENT in dpkg-buildflags(1)
+# Apply all hardening options
+#export DEB_BUILD_MAINT_OPTIONS = hardening=+all
+# Package maintainers to append CFLAGS
+#export DEB_CFLAGS_MAINT_APPEND  = -Wall -pedantic
+# Package maintainers to append LDFLAGS
+#export DEB_LDFLAGS_MAINT_APPEND = -Wl,--as-needed
+#
+# With debhelper version 9 or newer, the dh command exports
+# all buildflags.  So there is no need to include the
+# /usr/share/dpkg/buildflags.mk file here if compat is 9 or newer.
+#
+# These are rarely used code. (START)
+#
+# The following include for *.mk magically sets miscellaneous
+# variables while honoring existing values of pertinent
+# environment variables:
+#
+# Architecture-related variables such as DEB_TARGET_MULTIARCH:
+#include /usr/share/dpkg/architecture.mk
+# Vendor-related variables such as DEB_VENDOR:
+#include /usr/share/dpkg/vendor.mk
+# Package-related variables such as DEB_DISTRIBUTION
+#include /usr/share/dpkg/pkg-info.mk
+#
+# You may alternatively set them susing a simple script such as:
+# DEB_VENDOR ?= $(shell dpkg-vendor --query  Vendor)
+#
+# These are rarely used code. (END)
+#
+
+# main packaging script based on dh7 syntax
+%:
+	dh $@ --with autoreconf
+
+# debmake generated override targets
+# Set options for ./configure
+CONFIGURE_FLAGS += --enable-iu --enable-smpp --with-systemdsystemunitdir=/lib/systemd/system
+override_dh_auto_configure:
+	dh_auto_configure -- $(CONFIGURE_FLAGS)
+#
+# Do not install libtool archive, python .pyc .pyo
+#override_dh_install:
+#	dh_install --list-missing -X.la -X.pyc -X.pyo
+
+# See https://www.debian.org/doc/manuals/developers-reference/best-pkging-practices.html#bpp-dbg
+override_dh_strip:
+	dh_strip --dbg-package=osmo-msc-dbg
+
+# Print test results in case of a failure
+override_dh_auto_test:
+	dh_auto_test || (find . -name testsuite.log -exec cat {} \; ; false)
diff --git a/debian/source/format b/debian/source/format
new file mode 100644
index 0000000..89ae9db
--- /dev/null
+++ b/debian/source/format
@@ -0,0 +1 @@
+3.0 (native)
diff --git a/doc/Makefile.am b/doc/Makefile.am
new file mode 100644
index 0000000..5a23107
--- /dev/null
+++ b/doc/Makefile.am
@@ -0,0 +1,3 @@
+SUBDIRS = \
+	examples \
+	$(NULL)
diff --git a/doc/examples/Makefile.am b/doc/examples/Makefile.am
new file mode 100644
index 0000000..af36318
--- /dev/null
+++ b/doc/examples/Makefile.am
@@ -0,0 +1,30 @@
+OSMOCONF_FILES = \
+	osmo-msc/osmo-msc.cfg
+
+osmoconfdir = $(sysconfdir)/osmocom
+osmoconf_DATA = $(OSMOCONF_FILES)
+
+EXTRA_DIST = $(OSMOCONF_FILES)
+
+CFG_FILES = find $(srcdir) -name '*.cfg*' | sed -e 's,^$(srcdir),,'
+
+dist-hook:
+	for f in $$($(CFG_FILES)); do \
+		j="$(distdir)/$$f" && \
+		mkdir -p "$$(dirname $$j)" && \
+		$(INSTALL_DATA) $(srcdir)/$$f $$j; \
+	done
+
+install-data-hook:
+	for f in $$($(CFG_FILES)); do \
+		j="$(DESTDIR)$(docdir)/examples/$$f" && \
+		mkdir -p "$$(dirname $$j)" && \
+		$(INSTALL_DATA) $(srcdir)/$$f $$j; \
+	done
+
+uninstall-hook:
+	@$(PRE_UNINSTALL)
+	for f in $$($(CFG_FILES)); do \
+		j="$(DESTDIR)$(docdir)/examples/$$f" && \
+		$(RM) $$j; \
+	done
diff --git a/doc/examples/osmo-msc/osmo-msc.cfg b/doc/examples/osmo-msc/osmo-msc.cfg
new file mode 100644
index 0000000..f80143d
--- /dev/null
+++ b/doc/examples/osmo-msc/osmo-msc.cfg
@@ -0,0 +1,21 @@
+!
+! OsmoMSC configuration saved from vty
+!
+line vty
+ no login
+!
+network
+ network country code 1
+ mobile network code 1
+ short name OsmoMSC
+ long name OsmoMSC
+ encryption a5 0
+ rrlp mode none
+ mm info 1
+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
new file mode 100644
index 0000000..39ca9d4
--- /dev/null
+++ b/doc/examples/osmo-msc/osmo-msc_custom-sccp.cfg
@@ -0,0 +1,27 @@
+!
+! OsmoMSC configuration saved from vty
+!
+line vty
+ no login
+!
+network
+ network country code 1
+ mobile network code 1
+ short name OsmoMSC
+ long name OsmoMSC
+ encryption a5 0
+ rrlp mode none
+ mm info 1
+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
+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
new file mode 100644
index 0000000..2af1726
--- /dev/null
+++ b/doc/examples/osmo-msc/osmo-msc_multi-cs7.cfg
@@ -0,0 +1,29 @@
+!
+! OsmoMSC configuration saved from vty
+!
+line vty
+ no login
+!
+network
+ network country code 1
+ mobile network code 1
+ short name OsmoMSC
+ long name OsmoMSC
+ encryption a5 0
+ rrlp mode none
+ mm info 1
+cs7 instance 0
+ point-code 0.23.1
+ asp asp-clnt-OsmoMSC-A 2905 0 m3ua
+  remote-ip 127.0.0.5
+cs7 instance 1
+ point-code 0.23.2
+ asp asp-clnt-OsmoMSC-Iu 2905 0 m3ua
+  remote-ip 127.0.0.6
+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/git-version-gen b/git-version-gen
new file mode 100755
index 0000000..42cf3d2
--- /dev/null
+++ b/git-version-gen
@@ -0,0 +1,151 @@
+#!/bin/sh
+# Print a version string.
+scriptversion=2010-01-28.01
+
+# Copyright (C) 2007-2010 Free Software Foundation, Inc.
+#
+# 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/>.
+
+# This script is derived from GIT-VERSION-GEN from GIT: http://git.or.cz/.
+# It may be run two ways:
+# - from a git repository in which the "git describe" command below
+#   produces useful output (thus requiring at least one signed tag)
+# - from a non-git-repo directory containing a .tarball-version file, which
+#   presumes this script is invoked like "./git-version-gen .tarball-version".
+
+# In order to use intra-version strings in your project, you will need two
+# separate generated version string files:
+#
+# .tarball-version - present only in a distribution tarball, and not in
+#   a checked-out repository.  Created with contents that were learned at
+#   the last time autoconf was run, and used by git-version-gen.  Must not
+#   be present in either $(srcdir) or $(builddir) for git-version-gen to
+#   give accurate answers during normal development with a checked out tree,
+#   but must be present in a tarball when there is no version control system.
+#   Therefore, it cannot be used in any dependencies.  GNUmakefile has
+#   hooks to force a reconfigure at distribution time to get the value
+#   correct, without penalizing normal development with extra reconfigures.
+#
+# .version - present in a checked-out repository and in a distribution
+#   tarball.  Usable in dependencies, particularly for files that don't
+#   want to depend on config.h but do want to track version changes.
+#   Delete this file prior to any autoconf run where you want to rebuild
+#   files to pick up a version string change; and leave it stale to
+#   minimize rebuild time after unrelated changes to configure sources.
+#
+# It is probably wise to add these two files to .gitignore, so that you
+# don't accidentally commit either generated file.
+#
+# Use the following line in your configure.ac, so that $(VERSION) will
+# automatically be up-to-date each time configure is run (and note that
+# since configure.ac no longer includes a version string, Makefile rules
+# should not depend on configure.ac for version updates).
+#
+# AC_INIT([GNU project],
+#         m4_esyscmd([build-aux/git-version-gen .tarball-version]),
+#         [bug-project@example])
+#
+# Then use the following lines in your Makefile.am, so that .version
+# will be present for dependencies, and so that .tarball-version will
+# exist in distribution tarballs.
+#
+# BUILT_SOURCES = $(top_srcdir)/.version
+# $(top_srcdir)/.version:
+#	echo $(VERSION) > $@-t && mv $@-t $@
+# dist-hook:
+#	echo $(VERSION) > $(distdir)/.tarball-version
+
+case $# in
+    1) ;;
+    *) echo 1>&2 "Usage: $0 \$srcdir/.tarball-version"; exit 1;;
+esac
+
+tarball_version_file=$1
+nl='
+'
+
+# First see if there is a tarball-only version file.
+# then try "git describe", then default.
+if test -f $tarball_version_file
+then
+    v=`cat $tarball_version_file` || exit 1
+    case $v in
+	*$nl*) v= ;; # reject multi-line output
+	[0-9]*) ;;
+	*) v= ;;
+    esac
+    test -z "$v" \
+	&& echo "$0: WARNING: $tarball_version_file seems to be damaged" 1>&2
+fi
+
+if test -n "$v"
+then
+    : # use $v
+elif
+       v=`git describe --abbrev=4 --match='v*' HEAD 2>/dev/null \
+	  || git describe --abbrev=4 HEAD 2>/dev/null` \
+    && case $v in
+	 [0-9]*) ;;
+	 v[0-9]*) ;;
+	 *) (exit 1) ;;
+       esac
+then
+    # Is this a new git that lists number of commits since the last
+    # tag or the previous older version that did not?
+    #   Newer: v6.10-77-g0f8faeb
+    #   Older: v6.10-g0f8faeb
+    case $v in
+	*-*-*) : git describe is okay three part flavor ;;
+	*-*)
+	    : git describe is older two part flavor
+	    # Recreate the number of commits and rewrite such that the
+	    # result is the same as if we were using the newer version
+	    # of git describe.
+	    vtag=`echo "$v" | sed 's/-.*//'`
+	    numcommits=`git rev-list "$vtag"..HEAD | wc -l`
+	    v=`echo "$v" | sed "s/\(.*\)-\(.*\)/\1-$numcommits-\2/"`;
+	    ;;
+    esac
+
+    # Change the first '-' to a '.', so version-comparing tools work properly.
+    # Remove the "g" in git describe's output string, to save a byte.
+    v=`echo "$v" | sed 's/-/./;s/\(.*\)-g/\1-/'`;
+else
+    v=UNKNOWN
+fi
+
+v=`echo "$v" |sed 's/^v//'`
+
+# Don't declare a version "dirty" merely because a time stamp has changed.
+git status > /dev/null 2>&1
+
+dirty=`sh -c 'git diff-index --name-only HEAD' 2>/dev/null` || dirty=
+case "$dirty" in
+    '') ;;
+    *) # Append the suffix only if there isn't one already.
+	case $v in
+	  *-dirty) ;;
+	  *) v="$v-dirty" ;;
+	esac ;;
+esac
+
+# Omit the trailing newline, so that m4_esyscmd can use the result directly.
+echo "$v" | tr -d '\012'
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-end: "$"
+# End:
diff --git a/include/Makefile.am b/include/Makefile.am
new file mode 100644
index 0000000..9d963a0
--- /dev/null
+++ b/include/Makefile.am
@@ -0,0 +1,3 @@
+SUBDIRS = \
+	osmocom \
+	$(NULL)
diff --git a/include/osmocom/Makefile.am b/include/osmocom/Makefile.am
new file mode 100644
index 0000000..4d80637
--- /dev/null
+++ b/include/osmocom/Makefile.am
@@ -0,0 +1,3 @@
+SUBDIRS = \
+	msc \
+	$(NULL)
diff --git a/include/osmocom/msc/Makefile.am b/include/osmocom/msc/Makefile.am
new file mode 100644
index 0000000..ebc946a
--- /dev/null
+++ b/include/osmocom/msc/Makefile.am
@@ -0,0 +1,34 @@
+noinst_HEADERS = \
+	a_iface.h \
+	a_iface_bssap.h \
+	common.h \
+	common_cs.h \
+	db.h \
+	debug.h \
+	gsm_04_08.h \
+	gsm_04_11.h \
+	gsm_04_14.h \
+	gsm_04_80.h \
+	gsm_09_11.h \
+	gsm_data.h \
+	gsm_data_shared.h \
+	gsm_subscriber.h \
+	iucs.h \
+	iucs_ranap.h \
+	iu_dummy.h \
+	mncc.h \
+	mncc_int.h \
+	msc_ifaces.h \
+	msc_mgcp.h \
+	openbscdefines.h \
+	a_reset.h \
+	osmo_msc.h \
+	rrlp.h \
+	signal.h \
+	silent_call.h \
+	smpp.h \
+	sms_queue.h \
+	transaction.h \
+	vlr.h \
+	vty.h \
+	$(NULL)
diff --git a/include/osmocom/msc/a_iface.h b/include/osmocom/msc/a_iface.h
new file mode 100644
index 0000000..9a758d3
--- /dev/null
+++ b/include/osmocom/msc/a_iface.h
@@ -0,0 +1,91 @@
+/* (C) 2017 by Sysmocom s.f.m.c. GmbH
+ * All Rights Reserved
+ *
+ * Author: Philipp Maier
+ *
+ * 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/a_reset.h>
+#include <osmocom/msc/transaction.h>
+#include <osmocom/msc/vlr.h>
+#include <osmocom/gsm/protocol/gsm_08_08.h>
+
+#define LOGPCONN(conn, level, fmt, args...) \
+	LOGP(DBSSAP, level, "(subscr %s, conn_id %d) " fmt, \
+	     vlr_subscr_name(conn ? conn->vsub : NULL), conn ? conn->a.conn_id : -1, \
+	     ## args)
+
+#define LOGPBSCCONN(conn, level, fmt, args...) \
+	LOGP(DBSSAP, level, "(conn_id %u) " fmt, conn ? conn->conn_id : (uint32_t)(-1), ## args)
+
+/* A struct to keep a context information about the BSCs we are associated with */
+struct bsc_context {
+	struct llist_head list;
+
+	/* Holds a copy of the sccp address of the BSC,
+	 * this address will become known as soon as
+	 * a remote BSC tries to make a connection or
+	 * sends a RESET request via UNIDATA */
+	struct osmo_sccp_addr bsc_addr;
+
+	/* Holds a copy of the our local MSC address,
+	 * this will be the sccp-address that is associated
+	 * with the A interface */
+	struct osmo_sccp_addr msc_addr;
+
+	/* A pointer to the reset handler FSM, the
+	 * state machine is allocated when the BSC
+	 * is registerd. */
+	struct osmo_fsm_inst *reset_fsm;
+
+	/* A pointer to the sccp_user that is associated
+	 * with the A interface. We need this information
+	 * to send the resets and to send paging requests */
+	struct osmo_sccp_user *sccp_user;
+};
+
+/* Initalize A interface connection between to MSC and BSC */
+int a_init(struct osmo_sccp_instance *sccp, struct gsm_network *network);
+
+/* Send DTAP message via A-interface, take ownership of msg */
+int a_iface_tx_dtap(struct msgb *msg);
+
+/* Send Cipher mode command via A-interface */
+int a_iface_tx_cipher_mode(const struct gsm_subscriber_connection *conn,
+			   struct gsm0808_encrypt_info *ei, int include_imeisv);
+
+/* Page a subscriber via A-interface */
+int a_iface_tx_paging(const char *imsi, uint32_t tmsi, uint16_t lac);
+
+/* Send assignment request via A-interface */
+int a_iface_tx_assignment(const struct gsm_trans *trans);
+
+/* Send clear command via A-interface */
+int a_iface_tx_clear_cmd(struct gsm_subscriber_connection *conn);
+
+int a_iface_tx_classmark_request(const struct gsm_subscriber_connection *conn);
+
+/* Clear all subscriber connections on a specified BSC
+ * (Helper function for a_iface_bssap.c) */
+void a_clear_all(struct osmo_sccp_user *scu, const struct osmo_sccp_addr *bsc_addr);
+
+void a_start_reset(struct bsc_context *bsc_ctx, bool already_connected);
+
+/* Delete info of a closed connection from the active connection list
+ * (Helper function for a_iface_bssap.c) */
+void a_delete_bsc_con(uint32_t conn_id);
diff --git a/include/osmocom/msc/a_iface_bssap.h b/include/osmocom/msc/a_iface_bssap.h
new file mode 100644
index 0000000..d4b67e3
--- /dev/null
+++ b/include/osmocom/msc/a_iface_bssap.h
@@ -0,0 +1,41 @@
+/* (C) 2017 by sysmocom s.f.m.c. GmbH
+ * All Rights Reserved
+ *
+ * Author: Philipp Maier
+ *
+ * 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/a_iface.h>
+
+/* Note: The structs and functions presented in this header file are intended
+ * to be used only by a_iface.c. */
+
+/* A structure to hold tha most basic information about a sigtran connection
+ * we use this struct internally here to pass connection data around */
+struct a_conn_info {
+	struct bsc_context *bsc;
+	uint32_t conn_id;
+	struct gsm_network *network;
+};
+
+/* Receive incoming connection less data messages via sccp */
+void a_sccp_rx_udt(struct osmo_sccp_user *scu, const struct a_conn_info *a_conn_info, struct msgb *msg);
+
+/* Receive incoming connection oriented data messages via sccp */
+int a_sccp_rx_dt(struct osmo_sccp_user *scu, const struct a_conn_info *a_conn_info, struct msgb *msg);
+
diff --git a/include/osmocom/msc/a_reset.h b/include/osmocom/msc/a_reset.h
new file mode 100644
index 0000000..8eb3bbf
--- /dev/null
+++ b/include/osmocom/msc/a_reset.h
@@ -0,0 +1,31 @@
+/* (C) 2017 by sysmocom s.f.m.c. GmbH
+ * All Rights Reserved
+ *
+ * Author: Philipp Maier
+ *
+ * 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
+
+/* Create and start state machine which handles the reset/reset-ack procedure */
+struct osmo_fsm_inst *a_reset_alloc(void *ctx, const char *name, void *cb,
+				    void *priv, bool already_connected);
+
+/* Confirm that we sucessfully received a reset acknowlege message */
+void a_reset_ack_confirm(struct osmo_fsm_inst *reset_fsm);
+
+/* Check if we have a connection to a specified msc */
+bool a_reset_conn_ready(struct osmo_fsm_inst *reset_fsm);
diff --git a/include/osmocom/msc/common.h b/include/osmocom/msc/common.h
new file mode 100644
index 0000000..d91b3d3
--- /dev/null
+++ b/include/osmocom/msc/common.h
@@ -0,0 +1,6 @@
+#pragma once
+
+enum nsap_addr_enc {
+	NSAP_ADDR_ENC_X213,
+	NSAP_ADDR_ENC_V4RAW,
+};
diff --git a/include/osmocom/msc/common_cs.h b/include/osmocom/msc/common_cs.h
new file mode 100644
index 0000000..fddc6ec
--- /dev/null
+++ b/include/osmocom/msc/common_cs.h
@@ -0,0 +1,18 @@
+#pragma once
+
+#include <stdint.h>
+
+struct msgb;
+struct gsm_network;
+
+typedef int (*mncc_recv_cb_t)(struct gsm_network *, struct msgb *);
+
+#define MAX_A5_KEY_LEN	(128/8)
+
+struct gsm_encr {
+	uint8_t alg_id;
+	uint8_t key_len;
+	uint8_t key[MAX_A5_KEY_LEN];
+};
+
+struct gsm_network *gsm_network_init(void *ctx, mncc_recv_cb_t mncc_recv);
diff --git a/include/osmocom/msc/db.h b/include/osmocom/msc/db.h
new file mode 100644
index 0000000..a1de7d6
--- /dev/null
+++ b/include/osmocom/msc/db.h
@@ -0,0 +1,62 @@
+/* (C) 2008 by Jan Luebbe <jluebbe@debian.org>
+ * (C) 2009 by Holger Hans Peter Freyther <zecke@selfish.org>
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef _DB_H
+#define _DB_H
+
+#include <stdbool.h>
+
+#include "gsm_subscriber.h"
+
+struct gsm_equipment;
+struct gsm_network;
+struct gsm_auth_info;
+struct gsm_auth_tuple;
+struct gsm_sms;
+
+/* one time initialisation */
+int db_init(const char *name);
+int db_prepare(void);
+int db_fini(void);
+
+/* SMS store-and-forward */
+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);
+struct gsm_sms *db_sms_get_next_unsent_rr_msisdn(struct gsm_network *net,
+						 const char *last_msisdn,
+						 unsigned int max_failed);
+struct gsm_sms *db_sms_get_unsent_for_subscr(struct vlr_subscr *vsub,
+					     unsigned 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);
+int db_sms_delete_sent_message_by_id(unsigned long long sms_id);
+int db_sms_delete_expired_message_by_id(unsigned long long sms_id);
+void db_sms_delete_oldest_expired_message(void);
+
+/* Statistics counter storage */
+struct osmo_counter;
+int db_store_counter(struct osmo_counter *ctr);
+struct rate_ctr_group;
+int db_store_rate_ctr_group(struct rate_ctr_group *ctrg);
+
+#endif /* _DB_H */
diff --git a/include/osmocom/msc/debug.h b/include/osmocom/msc/debug.h
new file mode 100644
index 0000000..717cf74
--- /dev/null
+++ b/include/osmocom/msc/debug.h
@@ -0,0 +1,25 @@
+#pragma once
+
+#include <osmocom/core/logging.h>
+
+/* Debug Areas of the code */
+enum {
+	DRLL,
+	DCC,
+	DMM,
+	DRR,
+	DMNCC,
+	DPAG,
+	DMSC,
+	DMGCP,
+	DHO,
+	DDB,
+	DREF,
+	DCTRL,
+	DSMPP,
+	DRANAP,
+	DVLR,
+	DIUCS,
+	DBSSAP,
+	Debug_LastEntry,
+};
diff --git a/include/osmocom/msc/gsm_04_08.h b/include/osmocom/msc/gsm_04_08.h
new file mode 100644
index 0000000..8767070
--- /dev/null
+++ b/include/osmocom/msc/gsm_04_08.h
@@ -0,0 +1,82 @@
+#ifndef _GSM_04_08_H
+#define _GSM_04_08_H
+
+#include <osmocom/gsm/gsm48.h>
+#include <osmocom/gsm/gsm_utils.h>
+#include <osmocom/gsm/protocol/gsm_04_08.h>
+
+struct msgb;
+struct gsm_bts;
+struct gsm_network;
+struct gsm_trans;
+struct gsm_subscriber_connection;
+struct amr_multirate_conf;
+struct amr_mode;
+
+#define GSM48_ALLOC_SIZE	2048
+#define GSM48_ALLOC_HEADROOM	256
+
+static inline struct msgb *gsm48_msgb_alloc_name(const char *name)
+{
+	return msgb_alloc_headroom(GSM48_ALLOC_SIZE, GSM48_ALLOC_HEADROOM,
+				   name);
+}
+
+void cm_service_request_concludes(struct gsm_subscriber_connection *conn,
+				  struct msgb *msg);
+
+/* config options controlling the behaviour of the lower leves */
+void gsm0408_allow_everyone(int allow);
+void gsm0408_clear_all_trans(struct gsm_network *net, int protocol);
+int gsm0408_dispatch(struct gsm_subscriber_connection *conn, struct msgb *msg);
+
+int gsm0408_rcvmsg(struct msgb *msg, uint8_t link_id);
+/* don't use "enum gsm_chreq_reason_t" to avoid circular dependency */
+void gsm_net_update_ctype(struct gsm_network *net);
+
+int gsm48_tx_simple(struct gsm_subscriber_connection *conn,
+		    uint8_t pdisc, uint8_t msg_type);
+int gsm48_tx_mm_info(struct gsm_subscriber_connection *conn);
+int gsm48_tx_mm_auth_req(struct gsm_subscriber_connection *conn, uint8_t *rand,
+			 uint8_t *autn, int key_seq);
+int gsm48_tx_mm_auth_rej(struct gsm_subscriber_connection *conn);
+int gsm48_tx_mm_serv_ack(struct gsm_subscriber_connection *conn);
+int gsm48_tx_mm_serv_rej(struct gsm_subscriber_connection *conn,
+				enum gsm48_reject_value value);
+int gsm48_send_rr_release(struct gsm_lchan *lchan);
+int gsm48_send_rr_ciph_mode(struct gsm_lchan *lchan, int want_imeisv);
+int gsm48_send_rr_app_info(struct gsm_subscriber_connection *conn, uint8_t apdu_id,
+			   uint8_t apdu_len, const uint8_t *apdu);
+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);
+
+int mncc_tx_to_cc(struct gsm_network *net, int msg_type, void *arg);
+
+/* convert a ASCII phone number to call-control BCD */
+int encode_bcd_number(uint8_t *bcd_lv, uint8_t max_len,
+		      int h_len, const char *input);
+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);
+
+struct msgb *gsm48_create_mm_serv_rej(enum gsm48_reject_value value);
+struct msgb *gsm48_create_loc_upd_rej(uint8_t cause);
+void gsm48_lchan2chan_desc(struct gsm48_chan_desc *cd,
+			   const struct gsm_lchan *lchan);
+
+void release_security_operation(struct gsm_subscriber_connection *conn);
+void allocate_security_operation(struct gsm_subscriber_connection *conn);
+
+int gsm48_multirate_config(uint8_t *lv, const struct amr_multirate_conf *mr, const struct amr_mode *modes);
+
+int gsm48_tch_rtp_create(struct gsm_trans *trans);
+int gsm48_conn_sendmsg(struct msgb *msg, struct gsm_subscriber_connection *conn, struct gsm_trans *trans);
+
+#endif
diff --git a/include/osmocom/msc/gsm_04_11.h b/include/osmocom/msc/gsm_04_11.h
new file mode 100644
index 0000000..0b9639f
--- /dev/null
+++ b/include/osmocom/msc/gsm_04_11.h
@@ -0,0 +1,50 @@
+#ifndef _GSM_04_11_H
+#define _GSM_04_11_H
+
+#include <osmocom/gsm/protocol/gsm_04_11.h>
+
+struct vlr_subscr;
+struct gsm_subscriber_connection;
+struct gsm_trans;
+
+#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 msgb;
+
+int gsm0411_rcv_sms(struct gsm_subscriber_connection *conn, struct msgb *msg);
+
+struct gsm_sms *sms_alloc(void);
+void sms_free(struct gsm_sms *sms);
+struct gsm_sms *sms_from_text(struct vlr_subscr *receiver,
+			      const char *sender_msisdn,
+			      int dcs, const char *text);
+
+int gsm411_send_sms_subscr(struct vlr_subscr *vsub,
+			   struct gsm_sms *sms);
+int gsm411_send_sms(struct gsm_subscriber_connection *conn,
+		    struct gsm_sms *sms);
+void gsm411_sapi_n_reject(struct gsm_subscriber_connection *conn);
+
+int gsm411_send_rp_ack(struct gsm_trans *trans, uint8_t msg_ref);
+int gsm411_send_rp_error(struct gsm_trans *trans, uint8_t msg_ref,
+			 uint8_t cause);
+
+#endif
diff --git a/include/osmocom/msc/gsm_04_14.h b/include/osmocom/msc/gsm_04_14.h
new file mode 100644
index 0000000..3cdbe04
--- /dev/null
+++ b/include/osmocom/msc/gsm_04_14.h
@@ -0,0 +1,15 @@
+#pragma once
+
+#include <osmocom/gsm/protocol/gsm_04_14.h>
+
+int gsm0414_tx_close_tch_loop_cmd(struct gsm_subscriber_connection *conn,
+				  enum gsm414_tch_loop_mode loop_mode);
+int gsm0414_tx_open_loop_cmd(struct gsm_subscriber_connection *conn);
+int gsm0414_tx_act_emmi_cmd(struct gsm_subscriber_connection *conn);
+int gsm0414_tx_test_interface(struct gsm_subscriber_connection *conn,
+			      uint8_t tested_devs);
+int gsm0414_tx_reset_ms_pos_store(struct gsm_subscriber_connection *conn,
+				  uint8_t technology);
+
+int gsm0414_rcv_test(struct gsm_subscriber_connection *conn,
+		     struct msgb *msg);
diff --git a/include/osmocom/msc/gsm_04_80.h b/include/osmocom/msc/gsm_04_80.h
new file mode 100644
index 0000000..c448c91
--- /dev/null
+++ b/include/osmocom/msc/gsm_04_80.h
@@ -0,0 +1,13 @@
+#pragma once
+
+#include <stdint.h>
+
+struct gsm_subscriber_connection;
+
+int msc_send_ussd_reject(struct gsm_subscriber_connection *conn,
+			     uint8_t transaction_id, int invoke_id,
+			     uint8_t problem_tag, uint8_t problem_code);
+
+int msc_send_ussd_notify(struct gsm_subscriber_connection *conn, int level,
+			 const char *text);
+int msc_send_ussd_release_complete(struct gsm_subscriber_connection *conn);
diff --git a/include/osmocom/msc/gsm_09_11.h b/include/osmocom/msc/gsm_09_11.h
new file mode 100644
index 0000000..5e689fb
--- /dev/null
+++ b/include/osmocom/msc/gsm_09_11.h
@@ -0,0 +1,7 @@
+#pragma once
+
+#include <osmocom/core/msgb.h>
+#include <osmocom/gsm/gsup.h>
+
+int gsm0911_rcv_nc_ss(struct gsm_subscriber_connection *conn, struct msgb *msg);
+int gsm0911_gsup_handler(struct vlr_subscr *vsub, struct osmo_gsup_message *gsup);
diff --git a/include/osmocom/msc/gsm_data.h b/include/osmocom/msc/gsm_data.h
new file mode 100644
index 0000000..085248c
--- /dev/null
+++ b/include/osmocom/msc/gsm_data.h
@@ -0,0 +1,426 @@
+#ifndef _GSM_DATA_H
+#define _GSM_DATA_H
+
+#include <stdint.h>
+#include <regex.h>
+#include <sys/types.h>
+#include <stdbool.h>
+
+#include <osmocom/core/timer.h>
+#include <osmocom/core/rate_ctr.h>
+#include <osmocom/core/select.h>
+#include <osmocom/core/stats.h>
+#include <osmocom/gsm/gsm48.h>
+#include <osmocom/crypt/auth.h>
+#include <osmocom/sigtran/sccp_sap.h>
+
+#include <osmocom/msc/common.h>
+#include <osmocom/msc/common_cs.h>
+#include <osmocom/mgcp_client/mgcp_client.h>
+
+#include "gsm_data_shared.h"
+
+/* TS 48.008 DLCI containing DCCH/ACCH + SAPI */
+#define OMSC_LINKID_CB(__msgb)   (__msgb)->cb[3]
+
+#include "../../bscconfig.h"
+#if BUILD_IU
+#include <osmocom/ranap/iu_client.h>
+#endif
+
+/** annotations for msgb ownership */
+#define __uses
+
+struct mncc_sock_state;
+struct vlr_instance;
+struct vlr_subscr;
+struct ranap_ue_conn_ctx;
+
+#define tmsi_from_string(str) strtoul(str, NULL, 10)
+
+struct msgb;
+typedef int gsm_cbfn(unsigned int hooknum,
+		     unsigned int event,
+		     struct msgb *msg,
+		     void *data, void *param);
+
+struct gsm_auth_tuple {
+	int use_count;
+	int key_seq;
+	struct osmo_auth_vector vec;
+};
+#define GSM_KEY_SEQ_INVAL	7	/* GSM 04.08 - 10.5.1.2 */
+
+enum ran_type {
+       RAN_UNKNOWN,
+       RAN_GERAN_A,	/* 2G / A-interface */
+       RAN_UTRAN_IU,	/* 3G / Iu-interface (IuCS or IuPS) */
+};
+
+extern const struct value_string ran_type_names[];
+static inline const char *ran_type_name(enum ran_type val)
+{	return get_value_string(ran_type_names, val);	}
+
+struct gsm_classmark {
+	bool classmark1_set;
+	struct gsm48_classmark1 classmark1;
+	uint8_t classmark2_len;
+	uint8_t classmark2[3];
+	uint8_t classmark3_len;
+	uint8_t classmark3[14]; /* if cm3 gets extended by spec, it will be truncated */
+};
+
+enum integrity_protection_state {
+	INTEGRITY_PROTECTION_NONE	= 0,
+	INTEGRITY_PROTECTION_IK		= 1,
+	INTEGRITY_PROTECTION_IK_CK	= 2,
+};
+
+enum complete_layer3_type {
+	COMPLETE_LAYER3_NONE,
+	COMPLETE_LAYER3_LU,
+	COMPLETE_LAYER3_CM_SERVICE_REQ,
+	COMPLETE_LAYER3_PAGING_RESP,
+};
+
+extern const struct value_string complete_layer3_type_names[];
+static inline const char *complete_layer3_type_name(enum complete_layer3_type val)
+{
+	return get_value_string(complete_layer3_type_names, val);
+}
+
+/* active radio connection of a mobile subscriber */
+struct gsm_subscriber_connection {
+	/* global linked list of subscriber_connections */
+	struct llist_head entry;
+
+	/* FSM instance to control the subscriber connection's permissions and lifetime. */
+	struct osmo_fsm_inst *fi;
+	enum complete_layer3_type complete_layer3_type;
+
+	/* usage count. If this drops to zero, we start the release
+	 * towards A/Iu */
+	uint32_t use_count;
+	uint32_t use_tokens;
+
+	/* The MS has opened the conn with a CM Service Request, and we shall
+	 * keep it open for an actual request (or until timeout). */
+	bool received_cm_service_request;
+
+	/* libmsc/libvlr subscriber information (if available) */
+	struct vlr_subscr *vsub;
+
+	/* LU expiration handling */
+	uint8_t expire_timer_stopped;
+	/* SMS helpers for libmsc */
+	uint8_t next_rp_ref;
+
+	/* Are we part of a special "silent" call */
+	int silent_call;
+
+	/* MNCC rtp bridge markers */
+	int mncc_rtp_bridge;
+
+	/* back pointers */
+	struct gsm_network *network;
+
+	/* connected via 2G or 3G? */
+	enum ran_type via_ran;
+
+	uint16_t lac;
+	struct gsm_encr encr;
+
+	/* "Temporary" storage for the case the VLR asked for Cipher Mode Command, but the MSC still
+	 * wants to request a Classmark Update first. */
+	struct {
+		bool umts_aka;
+		bool retrieve_imeisv;
+	} geran_set_cipher_mode;
+
+	/* 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];
+
+	struct {
+		struct mgcp_ctx *mgcp_ctx;
+		unsigned int mgcp_rtp_endpoint;
+
+		uint16_t local_port_ran;
+		char local_addr_ran[INET_ADDRSTRLEN];
+		uint16_t remote_port_ran;
+		char remote_addr_ran[INET_ADDRSTRLEN];
+		enum mgcp_codecs codec_ran;
+
+		uint16_t local_port_cn;
+		char local_addr_cn[INET_ADDRSTRLEN];
+		uint16_t remote_port_cn;
+		char remote_addr_cn[INET_ADDRSTRLEN];
+		enum mgcp_codecs codec_cn;
+	} rtp;
+
+	/* which Iu-CS connection, if any. */
+	struct {
+		struct ranap_ue_conn_ctx *ue_ctx;
+		uint8_t rab_id;
+		bool waiting_for_release_complete;
+	} iu;
+
+	struct {
+		/* A pointer to the SCCP user that handles
+		 * the SCCP connections for this subscriber
+		 * connection */
+		struct osmo_sccp_user *scu;
+
+		/* The address of the BSC that is associated
+		 * with this subscriber connection */
+		struct osmo_sccp_addr bsc_addr;
+
+		/* The connection identifier that is used
+		 * to reference the SCCP connection that is
+		 * associated with this subscriber connection */
+		uint32_t conn_id;
+
+		bool waiting_for_clear_complete;
+	} a;
+
+	/* Temporary storage for Classmark Information for times when a connection has no VLR subscriber
+	 * associated yet. It will get copied to the VLR subscriber upon msc_vlr_subscr_assoc(). */
+	struct gsm_classmark temporary_classmark;
+};
+
+
+enum {
+	MSC_CTR_LOC_UPDATE_TYPE_ATTACH,
+	MSC_CTR_LOC_UPDATE_TYPE_NORMAL,
+	MSC_CTR_LOC_UPDATE_TYPE_PERIODIC,
+	MSC_CTR_LOC_UPDATE_TYPE_DETACH,
+	MSC_CTR_LOC_UPDATE_FAILED,
+	MSC_CTR_LOC_UPDATE_COMPLETED,
+	MSC_CTR_CM_SERVICE_REQUEST_REJECTED,
+	MSC_CTR_CM_SERVICE_REQUEST_ACCEPTED,
+	MSC_CTR_PAGING_RESP_REJECTED,
+	MSC_CTR_PAGING_RESP_ACCEPTED,
+	MSC_CTR_SMS_SUBMITTED,
+	MSC_CTR_SMS_NO_RECEIVER,
+	MSC_CTR_SMS_DELIVERED,
+	MSC_CTR_SMS_RP_ERR_MEM,
+	MSC_CTR_SMS_RP_ERR_OTHER,
+	MSC_CTR_SMS_DELIVER_UNKNOWN_ERROR,
+	MSC_CTR_CALL_MO_SETUP,
+	MSC_CTR_CALL_MO_CONNECT_ACK,
+	MSC_CTR_CALL_MT_SETUP,
+	MSC_CTR_CALL_MT_CONNECT,
+	MSC_CTR_CALL_ACTIVE,
+	MSC_CTR_CALL_COMPLETE,
+	MSC_CTR_CALL_INCOMPLETE,
+	MSC_CTR_NC_SS_MO_REQUESTS,
+	MSC_CTR_NC_SS_MO_ESTABLISHED,
+	MSC_CTR_NC_SS_MT_REQUESTS,
+	MSC_CTR_NC_SS_MT_ESTABLISHED,
+	MSC_CTR_BSSMAP_CIPHER_MODE_REJECT,
+	MSC_CTR_BSSMAP_CIPHER_MODE_COMPLETE,
+};
+
+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_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."},
+	[MSC_CTR_NC_SS_MT_ESTABLISHED] = 	{"nc_ss:mt_established", "Established network-initiated call independent SS/USSD sessions."},
+	[MSC_CTR_BSSMAP_CIPHER_MODE_REJECT] =	{"bssmap:cipher_mode_reject", "Number of CIPHER MODE REJECT messages processed by BSSMAP layer"},
+	[MSC_CTR_BSSMAP_CIPHER_MODE_COMPLETE] =	{"bssmap:cipher_mode_complete", "Number of CIPHER MODE COMPLETE messages processed by BSSMAP layer"},
+};
+
+static const struct rate_ctr_group_desc msc_ctrg_desc = {
+	"msc",
+	"mobile switching center",
+	OSMO_STATS_CLASS_GLOBAL,
+	ARRAY_SIZE(msc_ctr_description),
+	msc_ctr_description,
+};
+
+#define MSC_PAGING_RESPONSE_TIMER_DEFAULT 10
+
+struct gsm_tz {
+	int override; /* if 0, use system's time zone instead. */
+	int hr; /* hour */
+	int mn; /* minute */
+	int dst; /* daylight savings */
+};
+
+struct gsm_network {
+	/* TODO MSCSPLIT the gsm_network struct is basically a kitchen sink for
+	 * global settings and variables, "madly" mixing BSC and MSC stuff. Split
+	 * this in e.g. struct osmo_bsc and struct osmo_msc, with the things
+	 * these have in common, like country and network code, put in yet
+	 * separate structs and placed as members in osmo_bsc and osmo_msc. */
+
+	struct osmo_plmn_id plmn;
+
+	char *name_long;
+	char *name_short;
+
+	/* bit-mask of permitted encryption algorithms. LSB=A5/0, MSB=A5/7 */
+	uint8_t a5_encryption_mask;
+	bool authentication_required;
+	int send_mm_info;
+	struct {
+		int active;
+	} handover;
+
+	struct rate_ctr_group *msc_ctrs;
+	struct osmo_counter *active_calls;
+	struct osmo_counter *active_nc_ss;
+
+	/* layer 4 */
+	struct mncc_sock_state *mncc_state;
+	mncc_recv_cb_t mncc_recv;
+	struct llist_head upqueue;
+	/*
+	 * TODO: Move the trans_list into the subscriber connection and
+	 * create a pending list for MT transactions. These exist before
+	 * we have a subscriber connection.
+	 */
+	struct llist_head trans_list;
+
+	unsigned int paging_response_timer;
+
+	/* Radio Resource Location Protocol (TS 04.31) */
+	struct {
+		enum rrlp_mode mode;
+	} rrlp;
+
+	struct gsm_sms_queue *sms_queue;
+
+	/* control interface */
+	struct ctrl_handle *ctrl;
+
+	/* all active subscriber connections. */
+	struct llist_head subscr_conns;
+
+	/* if override is nonzero, this timezone data is used for all MM
+	 * contexts. */
+	/* TODO: in OsmoNITB, tz-override used to be BTS-specific. To enable
+	 * BTS|RNC specific timezone overrides for multi-tz networks in
+	 * OsmoMSC, this should be tied to the location area code (LAC). */
+	struct gsm_tz tz;
+
+	/* MSC: GSUP server address of the HLR */
+	const char *gsup_server_addr_str;
+	uint16_t gsup_server_port;
+
+	struct vlr_instance *vlr;
+
+	/* Periodic location update default value */
+	uint8_t t3212;
+
+	/* Global MNCC guard timer value */
+	int mncc_guard_timeout;
+
+	struct {
+		struct mgcp_client_conf conf;
+		struct mgcp_client *client;
+	} mgw;
+
+#if BUILD_IU
+	struct {
+		/* CS7 instance id number (set via VTY) */
+		uint32_t cs7_instance;
+		enum ranap_nsap_addr_enc rab_assign_addr_enc;
+		struct osmo_sccp_instance *sccp;
+	} iu;
+#endif
+
+	struct {
+		/* CS7 instance id number (set via VTY) */
+		uint32_t cs7_instance;
+		/* A list with the context information about
+		 * all BSCs we have connections with */
+		struct llist_head bscs;
+		struct osmo_sccp_instance *sccp;
+	} a;
+
+	struct {
+		/* MSISDN to which to route MO emergency calls */
+		char *route_to_msisdn;
+	} emergency;
+};
+
+struct osmo_esme;
+
+enum gsm_sms_source_id {
+	SMS_SOURCE_UNKNOWN = 0,
+	SMS_SOURCE_MS,		/* received from MS */
+	SMS_SOURCE_VTY,		/* received from VTY */
+	SMS_SOURCE_SMPP,	/* received via SMPP */
+};
+
+#define SMS_HDR_SIZE	128
+#define SMS_TEXT_SIZE	256
+
+struct gsm_sms_addr {
+	uint8_t ton;
+	uint8_t npi;
+	char addr[21+1];
+};
+
+struct gsm_sms {
+	unsigned long long id;
+	struct vlr_subscr *receiver;
+	struct gsm_sms_addr src, dst;
+	enum gsm_sms_source_id source;
+
+	struct {
+		uint8_t transaction_id;
+		uint32_t msg_ref;
+	} gsm411;
+
+	struct {
+		struct osmo_esme *esme;
+		uint32_t sequence_nr;
+		int transaction_mode;
+		char msg_id[16];
+	} smpp;
+
+	unsigned long validity_minutes;
+	time_t created;
+	bool is_report;
+	uint8_t reply_path_req;
+	uint8_t status_rep_req;
+	uint8_t ud_hdr_ind;
+	uint8_t protocol_id;
+	uint8_t data_coding_scheme;
+	uint8_t msg_ref;
+	uint8_t user_data_len;
+	uint8_t user_data[SMS_TEXT_SIZE];
+
+	char text[SMS_TEXT_SIZE];
+};
+
+/* control interface handling */
+int bsc_base_ctrl_cmds_install(void);
+int msc_ctrl_cmds_install(struct gsm_network *net);
+
+#endif /* _GSM_DATA_H */
diff --git a/include/osmocom/msc/gsm_data_shared.h b/include/osmocom/msc/gsm_data_shared.h
new file mode 100644
index 0000000..f71e92b
--- /dev/null
+++ b/include/osmocom/msc/gsm_data_shared.h
@@ -0,0 +1,42 @@
+#ifndef _GSM_DATA_SHAREDH
+#define _GSM_DATA_SHAREDH
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#include <osmocom/core/timer.h>
+#include <osmocom/core/bitvec.h>
+#include <osmocom/core/statistics.h>
+#include <osmocom/core/utils.h>
+#include <osmocom/gsm/gsm_utils.h>
+#include <osmocom/gsm/tlv.h>
+#include <osmocom/gsm/protocol/gsm_04_08.h>
+
+#include <osmocom/msc/common_cs.h>
+
+struct osmo_bsc_data;
+
+struct osmo_bsc_sccp_con;
+struct gsm_sms_queue;
+
+/* RRLP mode of operation */
+enum rrlp_mode {
+	RRLP_MODE_NONE,
+	RRLP_MODE_MS_BASED,
+	RRLP_MODE_MS_PREF,
+	RRLP_MODE_ASS_PREF,
+};
+
+enum gsm_hooks {
+	GSM_HOOK_NM_SWLOAD,
+	GSM_HOOK_RR_PAGING,
+	GSM_HOOK_RR_SECURITY,
+};
+
+enum gsm_paging_event {
+	GSM_PAGING_SUCCEEDED,
+	GSM_PAGING_EXPIRED,
+	GSM_PAGING_BUSY,
+};
+
+#endif
diff --git a/include/osmocom/msc/gsm_subscriber.h b/include/osmocom/msc/gsm_subscriber.h
new file mode 100644
index 0000000..01d9c58
--- /dev/null
+++ b/include/osmocom/msc/gsm_subscriber.h
@@ -0,0 +1,70 @@
+#ifndef _GSM_SUBSCR_H
+#define _GSM_SUBSCR_H
+
+#include <stdbool.h>
+
+#include <osmocom/core/linuxlist.h>
+#include <osmocom/gsm/protocol/gsm_23_003.h>
+
+#include <osmocom/msc/gsm_data.h>
+
+#define GSM_NAME_LENGTH 160
+
+#define GSM_EXTENSION_LENGTH 15 /* MSISDN can only be 15 digits length */
+#define GSM_MIN_EXTEN 20000
+#define GSM_MAX_EXTEN 49999
+
+#define GSM_SUBSCRIBER_FIRST_CONTACT	0x00000001
+/* gprs_sgsn.h defines additional flags including and above bit 16 (0x10000) */
+
+enum gsm_subscriber_field {
+	GSM_SUBSCRIBER_IMSI,
+	GSM_SUBSCRIBER_TMSI,
+	GSM_SUBSCRIBER_EXTENSION,
+	GSM_SUBSCRIBER_ID,
+};
+
+enum gsm_subscriber_update_reason {
+	GSM_SUBSCRIBER_UPDATE_ATTACHED,
+	GSM_SUBSCRIBER_UPDATE_DETACHED,
+	GSM_SUBSCRIBER_UPDATE_EQUIPMENT,
+};
+
+/*
+ * Struct for pending channel requests. This is managed in the
+ * llist_head requests of each subscriber. The reference counting
+ * should work in such a way that a subscriber with a pending request
+ * remains in memory.
+ */
+struct subscr_request {
+       struct llist_head entry;
+
+       /* human readable label to be able to log pending request kinds */
+       const char *label;
+
+       /* the callback data */
+       gsm_cbfn *cbfn;
+       void *param;
+};
+
+int subscr_update(struct vlr_subscr *vsub, int reason);
+
+/*
+ * Paging handling with authentication
+ */
+struct subscr_request *subscr_request_conn(struct vlr_subscr *vsub,
+					   gsm_cbfn *cbfn, void *param,
+					   const char *label);
+
+void subscr_remove_request(struct subscr_request *req);
+int subscr_rx_paging_response(struct msgb *msg,
+			      struct gsm_subscriber_connection *conn);
+
+void subscr_paging_cancel(struct vlr_subscr *vsub, enum gsm_paging_event event);
+int subscr_paging_dispatch(unsigned int hooknum, unsigned int event,
+			   struct msgb *msg, void *data, void *param);
+
+/* Find an allocated channel for a specified subscriber */
+struct gsm_subscriber_connection *connection_for_subscr(struct vlr_subscr *vsub);
+
+#endif /* _GSM_SUBSCR_H */
diff --git a/include/osmocom/msc/iu_dummy.h b/include/osmocom/msc/iu_dummy.h
new file mode 100644
index 0000000..d5e1428
--- /dev/null
+++ b/include/osmocom/msc/iu_dummy.h
@@ -0,0 +1,51 @@
+/* Trivial switch-off of external Iu dependencies,
+ * allowing to run full unit tests even when built without Iu support. */
+
+/*
+ * (C) 2016,2017 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>
+ *
+ * Author: Neels Hofmeyr <nhofmeyr@sysmocom.de>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#include <osmocom/core/linuxlist.h>
+
+struct msgb;
+struct gsm_auth_tuple;
+struct RANAP_Cause;
+struct osmo_auth_vector;
+
+struct ranap_ue_conn_ctx {
+	struct llist_head list;
+	uint32_t conn_id;
+};
+
+int ranap_iu_tx(struct msgb *msg, uint8_t sapi);
+int ranap_iu_tx_sec_mode_cmd(struct ranap_ue_conn_ctx *uectx, struct osmo_auth_vector *vec,
+			     int send_ck);
+int ranap_iu_page_cs(const char *imsi, const uint32_t *tmsi, uint16_t lac);
+int ranap_iu_page_ps(const char *imsi, const uint32_t *ptmsi, uint16_t lac, uint8_t rac);
+struct msgb *ranap_new_msg_rab_assign_voice(uint8_t rab_id, uint32_t rtp_ip,
+					    uint16_t rtp_port,
+					    bool use_x213_nsap);
+int ranap_iu_rab_act(struct ranap_ue_conn_ctx *ue_ctx, struct msgb *msg);
+int ranap_iu_tx_common_id(struct ranap_ue_conn_ctx *uectx, const char *imsi);
+int ranap_iu_tx_release(struct ranap_ue_conn_ctx *ctx, const struct RANAP_Cause *cause);
diff --git a/include/osmocom/msc/iucs.h b/include/osmocom/msc/iucs.h
new file mode 100644
index 0000000..8b22104
--- /dev/null
+++ b/include/osmocom/msc/iucs.h
@@ -0,0 +1,12 @@
+#pragma once
+
+#include <osmocom/msc/transaction.h>
+
+int gsm0408_rcvmsg_iucs(struct gsm_network *network, struct msgb *msg,
+			uint16_t *lac);
+
+struct gsm_subscriber_connection *subscr_conn_lookup_iu(struct gsm_network *network,
+							struct ranap_ue_conn_ctx *ue);
+int iu_rab_act_cs(struct gsm_trans *trans);
+
+uint32_t iu_get_conn_id(const struct ranap_ue_conn_ctx *ue);
diff --git a/include/osmocom/msc/iucs_ranap.h b/include/osmocom/msc/iucs_ranap.h
new file mode 100644
index 0000000..c2ff5f9
--- /dev/null
+++ b/include/osmocom/msc/iucs_ranap.h
@@ -0,0 +1,7 @@
+#pragma once
+
+struct gsm_network;
+struct ranap_ue_conn_ctx;
+
+int iucs_rx_ranap_event(struct gsm_network *network,
+			struct ranap_ue_conn_ctx *ue_ctx, int type, void *data);
diff --git a/include/osmocom/msc/mncc.h b/include/osmocom/msc/mncc.h
new file mode 100644
index 0000000..d2f0541
--- /dev/null
+++ b/include/osmocom/msc/mncc.h
@@ -0,0 +1,220 @@
+/* GSM Mobile Radio Interface Layer 3 messages on the A-bis interface 
+ * 3GPP TS 04.08 version 7.21.0 Release 1998 / ETSI TS 100 940 V7.21.0 */
+
+/* (C) 2008-2009 by Harald Welte <laforge@gnumonks.org>
+ * (C) 2008, 2009 by Holger Hans Peter Freyther <zecke@selfish.org>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef _MNCC_H
+#define _MNCC_H
+
+#include <osmocom/core/linuxlist.h>
+#include <osmocom/gsm/mncc.h>
+
+#include <stdint.h>
+
+struct gsm_network;
+struct msgb;
+
+
+/* One end of a call */
+struct gsm_call {
+	struct llist_head entry;
+
+	/* network handle */
+	void *net;
+
+	/* the 'local' transaction */
+	uint32_t callref;
+	/* the 'remote' transaction */
+	uint32_t remote_ref;
+};
+
+#define MNCC_SETUP_REQ		0x0101
+#define MNCC_SETUP_IND		0x0102
+#define MNCC_SETUP_RSP		0x0103
+#define MNCC_SETUP_CNF		0x0104
+#define MNCC_SETUP_COMPL_REQ	0x0105
+#define MNCC_SETUP_COMPL_IND	0x0106
+/* MNCC_REJ_* is perfomed via MNCC_REL_* */
+#define MNCC_CALL_CONF_IND	0x0107
+#define MNCC_CALL_PROC_REQ	0x0108
+#define MNCC_PROGRESS_REQ	0x0109
+#define MNCC_ALERT_REQ		0x010a
+#define MNCC_ALERT_IND		0x010b
+#define MNCC_NOTIFY_REQ		0x010c
+#define MNCC_NOTIFY_IND		0x010d
+#define MNCC_DISC_REQ		0x010e
+#define MNCC_DISC_IND		0x010f
+#define MNCC_REL_REQ		0x0110
+#define MNCC_REL_IND		0x0111
+#define MNCC_REL_CNF		0x0112
+#define MNCC_FACILITY_REQ	0x0113
+#define MNCC_FACILITY_IND	0x0114
+#define MNCC_START_DTMF_IND	0x0115
+#define MNCC_START_DTMF_RSP	0x0116
+#define MNCC_START_DTMF_REJ	0x0117
+#define MNCC_STOP_DTMF_IND	0x0118
+#define MNCC_STOP_DTMF_RSP	0x0119
+#define MNCC_MODIFY_REQ		0x011a
+#define MNCC_MODIFY_IND		0x011b
+#define MNCC_MODIFY_RSP		0x011c
+#define MNCC_MODIFY_CNF		0x011d
+#define MNCC_MODIFY_REJ		0x011e
+#define MNCC_HOLD_IND		0x011f
+#define MNCC_HOLD_CNF		0x0120
+#define MNCC_HOLD_REJ		0x0121
+#define MNCC_RETRIEVE_IND	0x0122
+#define MNCC_RETRIEVE_CNF	0x0123
+#define MNCC_RETRIEVE_REJ	0x0124
+#define MNCC_USERINFO_REQ	0x0125
+#define MNCC_USERINFO_IND	0x0126
+#define MNCC_REJ_REQ		0x0127
+#define MNCC_REJ_IND		0x0128
+
+#define MNCC_BRIDGE		0x0200
+#define MNCC_FRAME_RECV		0x0201
+#define MNCC_FRAME_DROP		0x0202
+#define MNCC_LCHAN_MODIFY	0x0203
+#define MNCC_RTP_CREATE		0x0204
+#define MNCC_RTP_CONNECT	0x0205
+#define MNCC_RTP_FREE		0x0206
+
+#define GSM_TCHF_FRAME		0x0300
+#define GSM_TCHF_FRAME_EFR	0x0301
+#define GSM_TCHH_FRAME		0x0302
+#define GSM_TCH_FRAME_AMR	0x0303
+#define GSM_BAD_FRAME		0x03ff
+
+#define MNCC_SOCKET_HELLO	0x0400
+
+#define GSM_MAX_FACILITY	128
+#define GSM_MAX_SSVERSION	128
+#define GSM_MAX_USERUSER	128
+
+#define	MNCC_F_BEARER_CAP	0x0001
+#define MNCC_F_CALLED		0x0002
+#define MNCC_F_CALLING		0x0004
+#define MNCC_F_REDIRECTING	0x0008
+#define MNCC_F_CONNECTED	0x0010
+#define MNCC_F_CAUSE		0x0020
+#define MNCC_F_USERUSER		0x0040
+#define MNCC_F_PROGRESS		0x0080
+#define MNCC_F_EMERGENCY	0x0100
+#define MNCC_F_FACILITY		0x0200
+#define MNCC_F_SSVERSION	0x0400
+#define MNCC_F_CCCAP		0x0800
+#define MNCC_F_KEYPAD		0x1000
+#define MNCC_F_SIGNAL		0x2000
+
+struct gsm_mncc {
+	/* context based information */
+	uint32_t	msg_type;
+	uint32_t	callref;
+
+	/* which fields are present */
+	uint32_t	fields;
+
+	/* data derived informations (MNCC_F_ based) */
+	struct gsm_mncc_bearer_cap	bearer_cap;
+	struct gsm_mncc_number		called;
+	struct gsm_mncc_number		calling;
+	struct gsm_mncc_number		redirecting;
+	struct gsm_mncc_number		connected;
+	struct gsm_mncc_cause		cause;
+	struct gsm_mncc_progress	progress;
+	struct gsm_mncc_useruser	useruser;
+	struct gsm_mncc_facility	facility;
+	struct gsm_mncc_cccap		cccap;
+	struct gsm_mncc_ssversion	ssversion;
+	struct	{
+		int		sup;
+		int		inv;
+	} clir;
+	int		signal;
+
+	/* data derived information, not MNCC_F based */
+	int		keypad;
+	int		more;
+	int		notify; /* 0..127 */
+	int		emergency;
+	char		imsi[16];
+
+	unsigned char	lchan_type;
+	unsigned char	lchan_mode;
+};
+
+struct gsm_data_frame {
+	uint32_t	msg_type;
+	uint32_t	callref;
+	unsigned char	data[0];
+};
+
+#define MNCC_SOCK_VERSION	5
+struct gsm_mncc_hello {
+	uint32_t	msg_type;
+	uint32_t	version;
+
+	/* send the sizes of the structs */
+	uint32_t	mncc_size;
+	uint32_t	data_frame_size;
+
+	/* send some offsets */
+	uint32_t	called_offset;
+	uint32_t	signal_offset;
+	uint32_t	emergency_offset;
+	uint32_t	lchan_type_offset;
+};
+
+struct gsm_mncc_rtp {
+	uint32_t	msg_type;
+	uint32_t	callref;
+	uint32_t	ip;
+	uint16_t	port;
+	uint32_t	payload_type;
+	uint32_t	payload_msg_type;
+};
+
+struct gsm_mncc_bridge {
+	uint32_t	msg_type;
+	uint32_t	callref[2];
+};
+
+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);
+
+/* input from CC code into mncc_sock */
+int mncc_sock_from_cc(struct gsm_network *net, struct msgb *msg);
+
+int mncc_sock_init(struct gsm_network *net, const char *sock_path);
+
+#define mncc_is_data_frame(msg_type) \
+	(msg_type == GSM_TCHF_FRAME \
+		|| msg_type == GSM_TCHF_FRAME_EFR \
+		|| msg_type == GSM_TCHH_FRAME \
+		|| msg_type == GSM_TCH_FRAME_AMR \
+		|| msg_type == GSM_BAD_FRAME)
+
+int mncc_prim_check(const struct gsm_mncc *mncc_prim, unsigned int len);
+
+#endif
diff --git a/include/osmocom/msc/mncc_int.h b/include/osmocom/msc/mncc_int.h
new file mode 100644
index 0000000..213ce14
--- /dev/null
+++ b/include/osmocom/msc/mncc_int.h
@@ -0,0 +1,14 @@
+#ifndef _MNCC_INT_H
+#define _MNCC_INT_H
+
+#include <stdint.h>
+
+struct mncc_int {
+	uint8_t def_codec[2];
+};
+
+extern struct mncc_int mncc_int;
+
+uint8_t mncc_codec_for_mode(int lchan_type);
+
+#endif
diff --git a/include/osmocom/msc/msc_ifaces.h b/include/osmocom/msc/msc_ifaces.h
new file mode 100644
index 0000000..ca25e9d
--- /dev/null
+++ b/include/osmocom/msc/msc_ifaces.h
@@ -0,0 +1,39 @@
+#pragma once
+
+#include <osmocom/core/msgb.h>
+#include <osmocom/msc/gsm_data.h>
+#include <osmocom/msc/transaction.h>
+
+/* These are the interfaces of the MSC layer towards (from?) the BSC and RNC,
+ * i.e. in the direction towards the mobile device (MS aka UE).
+ *
+ * 2G will use the A-interface,
+ * 3G aka UMTS will use the Iu-interface (for the MSC, it's IuCS).
+ *
+ * To allow linking parts of the MSC code without having to include entire
+ * infrastructures of external libraries, the core transmitting and receiving
+ * functions are left unimplemented. For example, a unit test does not need to
+ * link against external ASN1 libraries if it is never going to encode actual
+ * outgoing messages. It is up to each building scope to implement real world
+ * functions or to plug mere dummy implementations.
+ *
+ * For example, msc_tx_dtap(conn, msg), depending on conn->via_iface, will call
+ * either iu_tx() or a_tx() [note: at time of writing, the A-interface is not
+ * yet implemented]. When you try to link against libmsc, you will find that
+ * the compiler complains about an undefined reference to iu_tx(). If you,
+ * however, link against libiu as well as the osmo-iuh libs (etc.), iu_tx() is
+ * available. A unit test may instead simply implement a dummy iu_tx() function
+ * and not link against osmo-iuh, see tests/libiudummy/.
+ */
+
+/* Each main linkage must implement this function (see comment above). */
+extern int iu_tx(struct msgb *msg, uint8_t sapi);
+
+int msc_tx_dtap(struct gsm_subscriber_connection *conn,
+		struct msgb *msg);
+
+int msc_gsm48_tx_mm_serv_ack(struct gsm_subscriber_connection *conn);
+int msc_gsm48_tx_mm_serv_rej(struct gsm_subscriber_connection *conn,
+			     enum gsm48_reject_value value);
+
+int msc_tx_common_id(struct gsm_subscriber_connection *conn);
diff --git a/include/osmocom/msc/msc_mgcp.h b/include/osmocom/msc/msc_mgcp.h
new file mode 100644
index 0000000..3c4bc62
--- /dev/null
+++ b/include/osmocom/msc/msc_mgcp.h
@@ -0,0 +1,61 @@
+/* (C) 2017 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
+ * All Rights Reserved
+ *
+ * Author: Philipp Maier
+ *
+ * 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/mgcp_client/mgcp_client.h>
+#include <osmocom/msc/gsm_data.h>
+
+/* MGCP state handler context. This context information stores all information
+ * to handle the direction of the RTP streams via MGCP. There is one instance
+ * of this context struct per subscriber connection.
+ * (see also struct gsm_subscriber_connection) */
+struct mgcp_ctx {
+	/* FSM instance, which handles the connection switching procedure */
+	struct osmo_fsm_inst *fsm;
+
+	/* RTP endpoint string. This string identifies the endpoint
+	 * on the MGW on which the RAN and CN connection is created. This
+	 * endpoint number is assigned by the MGW. */
+	char rtp_endpoint[MGCP_ENDPOINT_MAXLEN];
+
+	/* Call id of the current call. Will be derived from the callref
+	 * of the transaction that is valid during the first CRCX. (The
+	 * callref may change throughout the call) */
+	unsigned int call_id;
+
+	/* Set to true, when the context information is no longer needed */
+	bool free_ctx;
+
+	/* RTP connection identifiers */
+	char conn_id_ran[MGCP_CONN_ID_LENGTH];
+	char conn_id_cn[MGCP_CONN_ID_LENGTH];
+
+	/* Copy of the pointer and the data with context information
+	 * needed to process the AoIP and MGCP requests (system data) */
+	struct mgcp_client *mgcp;
+	struct gsm_trans *trans;
+	mgcp_trans_id_t mgw_pending_trans;
+};
+
+int msc_mgcp_call_assignment(struct gsm_trans *trans);
+int msc_mgcp_ass_complete(struct gsm_subscriber_connection *conn, uint16_t port, char *addr);
+int msc_mgcp_call_complete(struct gsm_trans *trans, uint16_t port, char *addr);
+int msc_mgcp_call_release(struct gsm_trans *trans);
diff --git a/include/osmocom/msc/openbscdefines.h b/include/osmocom/msc/openbscdefines.h
new file mode 100644
index 0000000..c6ac153
--- /dev/null
+++ b/include/osmocom/msc/openbscdefines.h
@@ -0,0 +1,34 @@
+/* 
+ * (C) 2009 by Holger Hans Peter Freyther <zecke@selfish.org>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef OPENBSCDEFINES_H
+#define OPENBSCDEFINES_H
+
+#ifdef BUILDING_ON_WINDOWS
+    #ifdef BUILDING_OPENBSC
+        #define BSC_API __declspec(dllexport)
+    #else
+        #define BSC_API __declspec(dllimport)
+    #endif
+#else
+    #define BSC_API __attribute__((visibility("default")))
+#endif
+
+#endif
diff --git a/include/osmocom/msc/osmo_msc.h b/include/osmocom/msc/osmo_msc.h
new file mode 100644
index 0000000..a757a99
--- /dev/null
+++ b/include/osmocom/msc/osmo_msc.h
@@ -0,0 +1,124 @@
+/* Routines for the MSC handling */
+
+#ifndef OSMO_MSC_H
+#define OSMO_MSC_H
+
+#include <osmocom/core/fsm.h>
+#include <osmocom/gsm/gsup.h>
+
+#include <osmocom/msc/gsm_data.h>
+
+#define MSC_HLR_REMOTE_IP_DEFAULT "127.0.0.1"
+#define MSC_HLR_REMOTE_PORT_DEFAULT OSMO_GSUP_PORT
+
+enum subscr_conn_fsm_event {
+	/* Mark 0 as invalid to catch uninitialized vars */
+	SUBSCR_CONN_E_INVALID = 0,
+	/* Accepted the initial Complete Layer 3 (starting to evaluate Authentication and Ciphering) */
+	SUBSCR_CONN_E_COMPLETE_LAYER_3,
+	/* Received Classmark Update, typically neede for Ciphering Mode Command */
+	SUBSCR_CONN_E_CLASSMARK_UPDATE,
+	/* LU or Process Access FSM has determined that this conn is good */
+	SUBSCR_CONN_E_ACCEPTED,
+	/* received first reply from MS in "real" CC, SMS, USSD communication */
+	SUBSCR_CONN_E_COMMUNICATING,
+	/* Some async action has completed, check again whether all is done */
+	SUBSCR_CONN_E_RELEASE_WHEN_UNUSED,
+	/* MS/BTS/BSC originated close request */
+	SUBSCR_CONN_E_MO_CLOSE,
+	/* MSC originated close request, e.g. failed authentication */
+	SUBSCR_CONN_E_CN_CLOSE,
+	/* The usage count for the conn has reached zero */
+	SUBSCR_CONN_E_UNUSED,
+};
+
+enum subscr_conn_fsm_state {
+	SUBSCR_CONN_S_NEW,
+	SUBSCR_CONN_S_AUTH_CIPH,
+	SUBSCR_CONN_S_WAIT_CLASSMARK_UPDATE,
+	SUBSCR_CONN_S_ACCEPTED,
+	SUBSCR_CONN_S_COMMUNICATING,
+	SUBSCR_CONN_S_RELEASING,
+	SUBSCR_CONN_S_RELEASED,
+};
+
+enum msc_compl_l3_rc {
+	MSC_CONN_ACCEPT = 0,
+	MSC_CONN_REJECT = 1,
+};
+
+struct gsm_subscriber_connection *msc_subscr_conn_alloc(struct gsm_network *network,
+							enum ran_type via_ran, uint16_t lac);
+
+void msc_subscr_conn_update_id(struct gsm_subscriber_connection *conn,
+			       enum complete_layer3_type from, const char *id);
+char *msc_subscr_conn_get_conn_id(struct gsm_subscriber_connection *conn);
+
+void msc_subscr_conn_complete_layer_3(struct gsm_subscriber_connection *conn);
+
+int msc_vlr_alloc(struct gsm_network *net);
+int msc_vlr_start(struct gsm_network *net);
+
+void msc_sapi_n_reject(struct gsm_subscriber_connection *conn, int dlci);
+int msc_clear_request(struct gsm_subscriber_connection *conn, uint32_t cause);
+int msc_compl_l3(struct gsm_subscriber_connection *conn,
+		 struct msgb *msg, uint16_t chosen_channel);
+void msc_dtap(struct gsm_subscriber_connection *conn, struct msgb *msg);
+int msc_classmark_request_then_cipher_mode_cmd(struct gsm_subscriber_connection *conn, bool umts_aka,
+					       bool retrieve_imeisv);
+int msc_geran_set_cipher_mode(struct gsm_subscriber_connection *conn, bool umts_aka, bool retrieve_imeisv);
+void msc_cipher_mode_compl(struct gsm_subscriber_connection *conn,
+			   struct msgb *msg, uint8_t alg_id);
+void msc_rx_sec_mode_compl(struct gsm_subscriber_connection *conn);
+void msc_classmark_chg(struct gsm_subscriber_connection *conn,
+		       const uint8_t *cm2, uint8_t cm2_len,
+		       const uint8_t *cm3, uint8_t cm3_len);
+void msc_assign_fail(struct gsm_subscriber_connection *conn,
+		     uint8_t cause, uint8_t *rr_cause);
+
+void msc_subscr_conn_init(void);
+bool msc_subscr_conn_is_accepted(const struct gsm_subscriber_connection *conn);
+bool msc_subscr_conn_is_establishing_auth_ciph(const struct gsm_subscriber_connection *conn);
+void msc_subscr_conn_communicating(struct gsm_subscriber_connection *conn);
+void msc_subscr_conn_close(struct gsm_subscriber_connection *conn,
+			   uint32_t cause);
+void msc_subscr_conn_mo_close(struct gsm_subscriber_connection *conn, uint32_t cause);
+bool msc_subscr_conn_in_release(struct gsm_subscriber_connection *conn);
+
+void msc_subscr_conn_rx_bssmap_clear_complete(struct gsm_subscriber_connection *conn);
+void msc_subscr_conn_rx_iu_release_complete(struct gsm_subscriber_connection *conn);
+
+enum msc_subscr_conn_use {
+	MSC_CONN_USE_UNTRACKED = -1,
+	MSC_CONN_USE_COMPL_L3,
+	MSC_CONN_USE_DTAP,
+	MSC_CONN_USE_AUTH_CIPH,
+	MSC_CONN_USE_CM_SERVICE,
+	MSC_CONN_USE_TRANS_CC,
+	MSC_CONN_USE_TRANS_SMS,
+	MSC_CONN_USE_TRANS_NC_SS,
+	MSC_CONN_USE_SILENT_CALL,
+	MSC_CONN_USE_RELEASE,
+};
+
+extern const struct value_string msc_subscr_conn_use_names[];
+static inline const char *msc_subscr_conn_use_name(enum msc_subscr_conn_use val)
+{ return get_value_string(msc_subscr_conn_use_names, val); }
+
+#define msc_subscr_conn_get(conn, balance_token) \
+	_msc_subscr_conn_get(conn, balance_token, __FILE__, __LINE__)
+#define msc_subscr_conn_put(conn, balance_token) \
+	_msc_subscr_conn_put(conn, balance_token, __FILE__, __LINE__)
+struct gsm_subscriber_connection *
+_msc_subscr_conn_get(struct gsm_subscriber_connection *conn,
+		     enum msc_subscr_conn_use balance_token,
+		     const char *file, int line);
+void _msc_subscr_conn_put(struct gsm_subscriber_connection *conn,
+			  enum msc_subscr_conn_use balance_token,
+			  const char *file, int line);
+bool msc_subscr_conn_used_by(struct gsm_subscriber_connection *conn,
+			     enum msc_subscr_conn_use token);
+
+void msc_stop_paging(struct vlr_subscr *vsub);
+
+#endif
diff --git a/include/osmocom/msc/rrlp.h b/include/osmocom/msc/rrlp.h
new file mode 100644
index 0000000..7d1369d
--- /dev/null
+++ b/include/osmocom/msc/rrlp.h
@@ -0,0 +1,8 @@
+#pragma once
+
+#include <osmocom/msc/gsm_data_shared.h>
+
+enum rrlp_mode msc_rrlp_mode_parse(const char *arg);
+const char *msc_rrlp_mode_name(enum rrlp_mode mode);
+
+void msc_rrlp_init(void);
diff --git a/include/osmocom/msc/signal.h b/include/osmocom/msc/signal.h
new file mode 100644
index 0000000..f630b27
--- /dev/null
+++ b/include/osmocom/msc/signal.h
@@ -0,0 +1,100 @@
+/* Generic signalling/notification infrastructure */
+/* (C) 2009-2010, 2015 by Holger Hans Peter Freyther <zecke@selfish.org>
+ * (C) 2009 by Harald Welte <laforge@gnumonks.org>
+ * (C) 2010 by On-Waves
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#pragma once
+
+#include <stdlib.h>
+#include <errno.h>
+
+#include <osmocom/msc/gsm_data.h>
+
+#include <osmocom/core/signal.h>
+
+/*
+ * Signalling subsystems
+ */
+enum signal_subsystems {
+	SS_PAGING,
+	SS_SMS,
+	SS_SUBSCR,
+	SS_SCALL,
+};
+
+/* SS_PAGING signals */
+enum signal_paging {
+	S_PAGING_SUCCEEDED,
+	S_PAGING_EXPIRED,
+};
+
+/* SS_SMS signals */
+enum signal_sms {
+	S_SMS_SUBMITTED,	/* A SMS has been successfully submitted to us */
+	S_SMS_DELIVERED,	/* A SMS has been successfully delivered to a MS */
+	S_SMS_SMMA,		/* A MS tells us it has more space available */
+	S_SMS_MEM_EXCEEDED,	/* A MS tells us it has no more space available */
+	S_SMS_UNKNOWN_ERROR,	/* A MS tells us it has an error */
+};
+
+/* SS_SUBSCR signals */
+enum signal_subscr {
+	S_SUBSCR_ATTACHED,
+	S_SUBSCR_DETACHED,
+	S_SUBSCR_IDENTITY,		/* we've received some identity information */
+};
+
+/* SS_SCALL signals */
+enum signal_scall {
+	S_SCALL_SUCCESS,
+	S_SCALL_EXPIRED,
+	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 gsm_bts *bts;
+
+	int paging_result;
+
+	/* NULL in case the paging didn't work */
+	struct gsm_subscriber_connection *conn;
+};
+
+struct scall_signal_data {
+	struct gsm_subscriber_connection *conn;
+	void *data;
+};
+struct sms_signal_data {
+	/* The transaction where this occured */
+	struct gsm_trans *trans;
+	/* Can be NULL for SMMA */
+	struct gsm_sms *sms;
+	/* int paging result. Only the ones with > 0 */
+	int paging_result;
+};
diff --git a/include/osmocom/msc/silent_call.h b/include/osmocom/msc/silent_call.h
new file mode 100644
index 0000000..5fec77b
--- /dev/null
+++ b/include/osmocom/msc/silent_call.h
@@ -0,0 +1,15 @@
+#ifndef _SILENT_CALL_H
+#define _SILENT_CALL_H
+
+struct gsm_subscriber_connection;
+
+extern int gsm_silent_call_start(struct vlr_subscr *vsub,
+                                 void *data, int type);
+extern int gsm_silent_call_stop(struct vlr_subscr *vsub);
+
+#if 0
+extern int silent_call_rx(struct gsm_subscriber_connection *conn, struct msgb *msg);
+extern int silent_call_reroute(struct gsm_subscriber_connection *conn, struct msgb *msg);
+#endif
+
+#endif /* _SILENT_CALL_H */
diff --git a/include/osmocom/msc/smpp.h b/include/osmocom/msc/smpp.h
new file mode 100644
index 0000000..bcdac8f
--- /dev/null
+++ b/include/osmocom/msc/smpp.h
@@ -0,0 +1,4 @@
+#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
new file mode 100644
index 0000000..b5488fe
--- /dev/null
+++ b/include/osmocom/msc/sms_queue.h
@@ -0,0 +1,18 @@
+#ifndef SMS_QUEUE_H
+#define SMS_QUEUE_H
+
+struct gsm_network;
+struct gsm_sms_queue;
+struct vty;
+
+int sms_queue_start(struct gsm_network *, int in_flight);
+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);
+
+#endif
diff --git a/include/osmocom/msc/transaction.h b/include/osmocom/msc/transaction.h
new file mode 100644
index 0000000..b7d7971
--- /dev/null
+++ b/include/osmocom/msc/transaction.h
@@ -0,0 +1,114 @@
+#ifndef _TRANSACT_H
+#define _TRANSACT_H
+
+#include <osmocom/msc/gsm_data.h>
+#include <osmocom/msc/gsm_subscriber.h>
+#include <osmocom/core/linuxlist.h>
+#include <osmocom/msc/gsm_04_11.h>
+#include <osmocom/msc/mncc.h>
+#include <osmocom/gsm/gsm0411_smc.h>
+#include <osmocom/gsm/gsm0411_smr.h>
+
+enum bridge_state {
+	BRIDGE_STATE_NONE,
+	BRIDGE_STATE_LOOPBACK_PENDING,
+	BRIDGE_STATE_LOOPBACK_ESTABLISHED,
+	BRIDGE_STATE_BRIDGE_PENDING,
+	BRIDGE_STATE_BRIDGE_ESTABLISHED,
+};
+
+/* One transaction */
+struct gsm_trans {
+	/* Entry in list of all transactions */
+	struct llist_head entry;
+
+	/* Back pointer to the network struct */
+	struct gsm_network *net;
+
+	/* The protocol within which we live */
+	uint8_t protocol;
+
+	/* The current transaction ID */
+	uint8_t transaction_id;
+
+	/* The DLCI (DCCH/ACCH + SAPI) of this transaction */
+	uint8_t dlci;
+
+	/* To whom we belong, unique identifier of remote MM entity */
+	struct vlr_subscr *vsub;
+
+	/* The associated connection we are using to transmit messages */
+	struct gsm_subscriber_connection *conn;
+
+	/* reference from MNCC or other application */
+	uint32_t callref;
+
+	/* if traffic channel receive was requested */
+	int tch_recv;
+
+	/* is thats one paging? */
+	struct subscr_request *paging_request;
+
+	/* bearer capabilities (rate and codec) */
+	struct gsm_mncc_bearer_cap bearer_cap;
+
+	/* status of the assignment, true when done */
+	bool assignment_done;
+
+	/* if true, TCH_RTP_CREATE is sent after the
+	 * assignment is done */
+	bool tch_rtp_create;
+
+	union {
+		struct {
+
+			/* current call state */
+			int state;
+
+			/* current timer and message queue */
+			int Tcurrent;		/* current CC timer */
+			int T308_second;	/* used to send release again */
+			struct osmo_timer_list timer;
+			struct osmo_timer_list timer_guard;
+			struct gsm_mncc msg;	/* stores setup/disconnect/release message */
+		} cc;
+		struct {
+			struct gsm411_smc_inst smc_inst;
+			struct gsm411_smr_inst smr_inst;
+
+			struct gsm_sms *sms;
+		} sms;
+		struct {
+			/**
+			 * Stores a GSM 04.80 message to be sent to
+			 * a subscriber after successful Paging Response
+			 */
+			struct msgb *msg;
+		} ss;
+	};
+
+	struct {
+		struct gsm_trans *peer;
+		enum bridge_state state;
+	} bridge;
+};
+
+
+
+struct gsm_trans *trans_find_by_id(struct gsm_subscriber_connection *conn,
+				   uint8_t proto, uint8_t trans_id);
+struct gsm_trans *trans_find_by_callref(struct gsm_network *net,
+					uint32_t callref);
+
+struct gsm_trans *trans_alloc(struct gsm_network *net,
+			      struct vlr_subscr *vsub,
+			      uint8_t protocol, uint8_t trans_id,
+			      uint32_t callref);
+void trans_free(struct gsm_trans *trans);
+
+int trans_assign_trans_id(struct gsm_network *net, struct vlr_subscr *vsub,
+			  uint8_t protocol, uint8_t ti_flag);
+struct gsm_trans *trans_has_conn(const struct gsm_subscriber_connection *conn);
+void trans_conn_closed(struct gsm_subscriber_connection *conn);
+
+#endif
diff --git a/include/osmocom/msc/vlr.h b/include/osmocom/msc/vlr.h
new file mode 100644
index 0000000..d52713c
--- /dev/null
+++ b/include/osmocom/msc/vlr.h
@@ -0,0 +1,446 @@
+#pragma once
+
+#include <stdint.h>
+#include <osmocom/core/linuxlist.h>
+#include <osmocom/core/fsm.h>
+#include <osmocom/core/logging.h>
+#include <osmocom/gsm/protocol/gsm_23_003.h>
+#include <osmocom/gsm/protocol/gsm_04_08_gprs.h>
+#include <osmocom/gsm/gsm23003.h>
+#include <osmocom/gsm/gsm0808.h>
+#include <osmocom/gsm/gsup.h>
+#include <osmocom/msc/gsm_data.h>
+// for GSM_NAME_LENGTH
+#include <osmocom/msc/gsm_subscriber.h>
+#include <osmocom/gsupclient/gsup_client.h>
+
+#define LOGGSUPP(level, gsup, fmt, args...)				\
+	LOGP(DVLR, level, "GSUP(%s) " fmt, (gsup)->imsi, ## args)
+
+#define LOGVSUBP(level, vsub, fmt, args...)				\
+	LOGP(DVLR, level, "SUBSCR(%s) " fmt, vlr_subscr_name(vsub), ## args)
+
+struct log_target;
+
+#define VLR_SUBSCRIBER_NO_EXPIRATION	0
+#define VLR_SUBSCRIBER_LU_EXPIRATION_INTERVAL	60	/* in seconds */
+
+/* from 3s to 10s */
+#define GSM_29002_TIMER_S	10
+/* from 15s to 30s */
+#define GSM_29002_TIMER_M	30
+/* from 1min to 10min */
+#define GSM_29002_TIMER_ML	(10*60)
+/* from 28h to 38h */
+#define GSM_29002_TIMER_L	(32*60*60)
+
+/* VLR subscriber authentication state */
+enum vlr_subscr_auth_state {
+	/* subscriber needs to be autenticated */
+	VLR_SUB_AS_NEEDS_AUTH,
+	/* waiting for AuthInfo from HLR/AUC */
+	VLR_SUB_AS_NEEDS_AUTH_WAIT_AI,
+	/* waiting for response from subscriber */
+	VLR_SUB_AS_WAIT_RESP,
+	/* successfully authenticated */
+	VLR_SUB_AS_AUTHENTICATED,
+	/* subscriber needs re-sync */
+	VLR_SUB_AS_NEEDS_RESYNC,
+	/* waiting for AuthInfo with ReSync */
+	VLR_SUB_AS_NEEDS_AUTH_WAIT_SAI_RESYNC,
+	/* waiting for response from subscr, resync case */
+	VLR_SUB_AS_WAIT_RESP_RESYNC,
+	/* waiting for IMSI from subscriber */
+	VLR_SUB_AS_WAIT_ID_IMSI,
+	/* authentication has failed */
+	VLR_SUB_AS_AUTH_FAILED,
+};
+
+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_CIPH_RES,	/* Result of Ciphering Mode Command */
+	VLR_ULA_E_ID_IMSI,	/* IMSI recieved from MS */
+	VLR_ULA_E_ID_IMEI,	/* IMEI received from MS */
+	VLR_ULA_E_ID_IMEISV,	/* IMEISV received from MS */
+	VLR_ULA_E_HLR_LU_RES,	/* HLR UpdateLocation result */
+	VLR_ULA_E_UPD_HLR_COMPL,/* UpdatE_HLR_VLR result */
+	VLR_ULA_E_LU_COMPL_SUCCESS,/* Location_Update_Completion_VLR result */
+	VLR_ULA_E_LU_COMPL_FAILURE,/* Location_Update_Completion_VLR result */
+	VLR_ULA_E_NEW_TMSI_ACK,	/* TMSI Reallocation Complete */
+};
+
+enum vlr_ciph_result_cause {
+	VLR_CIPH_REJECT, /* ? */
+	VLR_CIPH_COMPL,
+};
+
+struct vlr_ciph_result {
+	enum vlr_ciph_result_cause cause;
+	char imeisv[GSM48_MI_SIZE];
+};
+
+enum vlr_subscr_security_context {
+	VLR_SEC_CTX_NONE,
+	VLR_SEC_CTX_GSM,
+	VLR_SEC_CTX_UMTS,
+};
+
+enum vlr_lu_type {
+	VLR_LU_TYPE_PERIODIC,
+	VLR_LU_TYPE_IMSI_ATTACH,
+	VLR_LU_TYPE_REGULAR,
+};
+
+#define OSMO_LBUF_DECL(name, xlen)		\
+	struct {				\
+		uint8_t buf[xlen];		\
+		size_t len;			\
+	} name
+
+struct sgsn_mm_ctx;
+struct vlr_instance;
+
+/* 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 */
+struct vlr_subscr {
+	struct llist_head list;
+	struct vlr_instance *vlr;
+
+	/* TODO either populate from HLR or drop this completely? */
+	long long unsigned int id;
+
+	/* 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[GSM_EXTENSION_LENGTH+1];		/* 2.1.2 */
+	char name[GSM_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 */
+	struct gsm_auth_tuple auth_tuples[5];		/* 2.3.1-2.3.4 */
+	struct gsm_auth_tuple *last_tuple;
+	enum vlr_subscr_security_context sec_ctx;
+
+	/* Data local to VLR is below */
+	uint32_t tmsi;					/* 2.1.4 */
+	/* Newly allocated TMSI that was not yet acked by MS */
+	uint32_t tmsi_new;
+
+	/* some redundancy in information below? */
+	struct osmo_cell_global_id cgi;			/* 2.4.16 */
+	uint16_t lac;					/* 2.4.2 */
+
+	char imeisv[GSM23003_IMEISV_NUM_DIGITS+1];	/* 2.2.3 */
+	char imei[GSM23003_IMEISV_NUM_DIGITS+1];	/* 2.1.9 */
+	bool imsi_detached_flag;			/* 2.7.1 */
+	bool conf_by_radio_contact_ind;			/* 2.7.4.1 */
+	bool sub_dataconf_by_hlr_ind;			/* 2.7.4.2 */
+	bool loc_conf_in_hlr_ind;			/* 2.7.4.3 */
+	bool dormant_ind;				/* 2.7.8 */
+	bool cancel_loc_rx;				/* 2.7.8A */
+	bool ms_not_reachable_flag;			/* 2.10.2 (MNRF) */
+	bool la_allowed;
+
+	int use_count;
+
+	struct osmo_fsm_inst *lu_fsm;
+	struct osmo_fsm_inst *auth_fsm;
+	struct osmo_fsm_inst *proc_arq_fsm;
+
+	bool lu_complete;
+	time_t expire_lu;
+
+	void *msc_conn_ref;
+
+	/* PS (SGSN) specific parts */
+	struct {
+		struct llist_head pdp_list;
+		uint8_t rac;
+		uint8_t sac;
+		struct gprs_mm_ctx *mmctx;
+	} ps;
+	/* CS (NITB/CSCN) specific parts */
+	struct {
+		/* pending requests */
+		bool is_paging;
+		struct osmo_timer_list paging_response_timer;
+		/* list of struct subscr_request */
+		struct llist_head requests;
+		uint8_t lac;
+		enum ran_type attached_via_ran;
+	} cs;
+
+	struct gsm_classmark classmark;
+};
+
+enum vlr_ciph {
+	VLR_CIPH_NONE, /*< A5/0, no encryption */
+	VLR_CIPH_A5_1, /*< A5/1, encryption */
+	VLR_CIPH_A5_2, /*< A5/2, deprecated export-grade encryption */
+	VLR_CIPH_A5_3, /*< A5/3, 'new secure' encryption */
+};
+
+static inline uint8_t vlr_ciph_to_gsm0808_alg_id(enum vlr_ciph ciph)
+{
+	switch (ciph) {
+	default:
+	case VLR_CIPH_NONE:
+		return GSM0808_ALG_ID_A5_0;
+	case VLR_CIPH_A5_1:
+		return GSM0808_ALG_ID_A5_1;
+	case VLR_CIPH_A5_2:
+		return GSM0808_ALG_ID_A5_2;
+	case VLR_CIPH_A5_3:
+		return GSM0808_ALG_ID_A5_3;
+	}
+}
+
+struct vlr_ops {
+	/* encode + transmit an AUTH REQ towards the MS.
+	 * \param[in] at  auth tuple providing rand, key_seq and autn.
+	 * \param[in] send_autn  True to send AUTN, for r99 UMTS auth.
+	 */
+	int (*tx_auth_req)(void *msc_conn_ref, struct gsm_auth_tuple *at,
+			   bool send_autn);
+	/* encode + transmit an AUTH REJECT towards the MS */
+	int (*tx_auth_rej)(void *msc_conn_ref);
+
+	/* encode + transmit an IDENTITY REQUEST towards the MS */
+	int (*tx_id_req)(void *msc_conn_ref, uint8_t mi_type);
+
+	int (*tx_lu_acc)(void *msc_conn_ref, uint32_t send_tmsi);
+	int (*tx_lu_rej)(void *msc_conn_ref, enum gsm48_reject_value cause);
+	int (*tx_cm_serv_acc)(void *msc_conn_ref);
+	int (*tx_cm_serv_rej)(void *msc_conn_ref, enum gsm48_reject_value cause);
+
+	int (*set_ciph_mode)(void *msc_conn_ref, bool umts_aka, bool retrieve_imeisv);
+
+	/* UTRAN: send Common Id (when auth+ciph are complete) */
+	int (*tx_common_id)(void *msc_conn_ref);
+
+	int (*tx_mm_info)(void *msc_conn_ref);
+
+	/* notify MSC/SGSN that the subscriber data in VLR has been updated */
+	void (*subscr_update)(struct vlr_subscr *vsub);
+	/* notify MSC/SGSN that the given subscriber has been associated
+	 * with this msc_conn_ref */
+	void (*subscr_assoc)(void *msc_conn_ref, struct vlr_subscr *vsub);
+
+	/* Forward a parsed GSUP message towards MSC message router */
+	int (*forward_gsup_msg)(struct vlr_subscr *vsub, struct osmo_gsup_message *gsup_msg);
+};
+
+enum vlr_timer {
+	VLR_T_3250,
+	VLR_T_3260,
+	VLR_T_3270,
+	_NUM_VLR_TIMERS
+};
+
+/* An instance of the VLR codebase */
+struct vlr_instance {
+	struct llist_head subscribers;
+	struct llist_head operations;
+	struct osmo_gsup_client *gsup_client;
+	struct vlr_ops ops;
+	struct osmo_timer_list lu_expire_timer;
+	struct {
+		bool retrieve_imeisv_early;
+		bool retrieve_imeisv_ciphered;
+		bool assign_tmsi;
+		bool check_imei_rqd;
+		int auth_tuple_max_reuse_count;
+		bool auth_reuse_old_sets_on_error;
+		bool parq_retrieve_imsi;
+		bool is_ps;
+		uint32_t timer[_NUM_VLR_TIMERS];
+	} cfg;
+	/* A free-form pointer for use by the caller */
+	void *user_ctx;
+};
+
+extern const struct value_string vlr_ciph_names[];
+static inline const char *vlr_ciph_name(enum vlr_ciph val)
+{
+	return get_value_string(vlr_ciph_names, val);
+}
+
+/* Location Updating request */
+struct osmo_fsm_inst *
+vlr_loc_update(struct osmo_fsm_inst *parent,
+	       uint32_t parent_event_success,
+	       uint32_t parent_event_failure,
+	       void *parent_event_data,
+	       struct vlr_instance *vlr, void *msc_conn_ref,
+	       enum vlr_lu_type type, uint32_t tmsi, const char *imsi,
+	       const struct osmo_location_area_id *old_lai,
+	       const struct osmo_location_area_id *new_lai,
+	       bool authentication_required,
+	       bool ciphering_required,
+	       bool is_r99, bool is_utran,
+	       bool assign_tmsi);
+
+void vlr_loc_update_cancel(struct osmo_fsm_inst *fi,
+			   enum osmo_fsm_term_cause fsm_cause,
+			   uint8_t gsm48_cause);
+
+/* tell the VLR that the subscriber 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_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);
+int vlr_subscr_tx_auth_fail_rep(const struct vlr_subscr *vsub) __attribute__((warn_unused_result));
+void vlr_subscr_rx_ciph_res(struct vlr_subscr *vsub, struct vlr_ciph_result *res);
+int vlr_subscr_rx_tmsi_reall_compl(struct vlr_subscr *vsub);
+int vlr_subscr_rx_imsi_detach(struct vlr_subscr *vsub);
+
+struct vlr_instance *vlr_alloc(void *ctx, const struct vlr_ops *ops);
+int vlr_start(const char *gsup_unit_name, struct vlr_instance *vlr,
+	      const char *gsup_server_addr_str, uint16_t gsup_server_port);
+
+/* internal use only */
+
+void sub_pres_vlr_fsm_start(struct osmo_fsm_inst **fsm,
+			    struct osmo_fsm_inst *parent,
+			    struct vlr_subscr *vsub,
+			    uint32_t term_event);
+struct osmo_fsm_inst *
+upd_hlr_vlr_proc_start(struct osmo_fsm_inst *parent,
+		       struct vlr_subscr *vsub,
+		       uint32_t parent_event);
+
+struct osmo_fsm_inst *
+lu_compl_vlr_proc_start(struct osmo_fsm_inst *parent,
+			struct vlr_subscr *vsub,
+			void *msc_conn_ref,
+			uint32_t parent_event_success,
+			uint32_t parent_event_failure);
+
+
+const char *vlr_subscr_name(struct vlr_subscr *vsub);
+const char *vlr_subscr_msisdn_or_name(struct vlr_subscr *vsub);
+
+#define vlr_subscr_find_by_imsi(vlr, imsi) \
+	_vlr_subscr_find_by_imsi(vlr, imsi, __FILE__, __LINE__)
+#define vlr_subscr_find_or_create_by_imsi(vlr, imsi, created) \
+	_vlr_subscr_find_or_create_by_imsi(vlr, imsi, created, \
+					   __FILE__, __LINE__)
+
+#define vlr_subscr_find_by_tmsi(vlr, tmsi) \
+	_vlr_subscr_find_by_tmsi(vlr, tmsi, __FILE__, __LINE__)
+#define vlr_subscr_find_or_create_by_tmsi(vlr, tmsi, created) \
+	_vlr_subscr_find_or_create_by_tmsi(vlr, tmsi, created, \
+					   __FILE__, __LINE__)
+
+#define vlr_subscr_find_by_msisdn(vlr, msisdn) \
+	_vlr_subscr_find_by_msisdn(vlr, msisdn, __FILE__, __LINE__)
+
+struct vlr_subscr *_vlr_subscr_find_by_imsi(struct vlr_instance *vlr,
+					    const char *imsi,
+					    const char *file, int line);
+struct vlr_subscr *_vlr_subscr_find_or_create_by_imsi(struct vlr_instance *vlr,
+						      const char *imsi,
+						      bool *created,
+						      const char *file,
+						      int line);
+
+struct vlr_subscr *_vlr_subscr_find_by_tmsi(struct vlr_instance *vlr,
+					    uint32_t tmsi,
+					    const char *file, int line);
+struct vlr_subscr *_vlr_subscr_find_or_create_by_tmsi(struct vlr_instance *vlr,
+						      uint32_t tmsi,
+						      bool *created,
+						      const char *file,
+						      int line);
+
+struct vlr_subscr *_vlr_subscr_find_by_msisdn(struct vlr_instance *vlr,
+					      const char *msisdn,
+					      const char *file, int line);
+
+#define vlr_subscr_get(sub) _vlr_subscr_get(sub, __FILE__, __LINE__)
+#define vlr_subscr_put(sub) _vlr_subscr_put(sub, __FILE__, __LINE__)
+struct vlr_subscr *_vlr_subscr_get(struct vlr_subscr *sub, const char *file, int line);
+struct vlr_subscr *_vlr_subscr_put(struct vlr_subscr *sub, const char *file, int line);
+
+struct vlr_subscr *vlr_subscr_alloc(struct vlr_instance *vlr);
+void vlr_subscr_free(struct vlr_subscr *vsub);
+int vlr_subscr_alloc_tmsi(struct vlr_subscr *vsub);
+
+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);
+
+bool vlr_subscr_matches_imsi(struct vlr_subscr *vsub, const char *imsi);
+bool vlr_subscr_matches_tmsi(struct vlr_subscr *vsub, uint32_t tmsi);
+bool vlr_subscr_matches_msisdn(struct vlr_subscr *vsub, const char *msisdn);
+bool vlr_subscr_matches_imei(struct vlr_subscr *vsub, const char *imei);
+
+uint32_t vlr_timer(struct vlr_instance *vlr, uint32_t timer);
+
+int vlr_subscr_changed(struct vlr_subscr *vsub);
+int vlr_subscr_purge(struct vlr_subscr *vsub) __attribute__((warn_unused_result));
+void vlr_subscr_cancel_attach_fsm(struct vlr_subscr *vsub,
+				  enum osmo_fsm_term_cause fsm_cause,
+				  uint8_t gsm48_cause);
+
+void vlr_subscr_enable_expire_lu(struct vlr_subscr *vsub);
+
+/* Process Acccess Request FSM */
+
+enum proc_arq_vlr_event {
+	PR_ARQ_E_START,
+	PR_ARQ_E_ID_IMSI,
+	PR_ARQ_E_AUTH_RES,
+	PR_ARQ_E_CIPH_RES,
+	PR_ARQ_E_UPD_LOC_RES,
+	PR_ARQ_E_TRACE_RES,
+	PR_ARQ_E_IMEI_RES,
+	PR_ARQ_E_PRES_RES,
+	PR_ARQ_E_TMSI_ACK,
+};
+
+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,
+	/* FIXME: differentiate between services of 24.008 10.5.3.3 */
+};
+
+/* Process Access Request (CM SERV REQ / PAGING RESP) */
+void
+vlr_proc_acc_req(struct osmo_fsm_inst *parent,
+		 uint32_t parent_event_success,
+		 uint32_t parent_event_failure,
+		 void *parent_event_data,
+		 struct vlr_instance *vlr, void *msc_conn_ref,
+		 enum vlr_parq_type type, const uint8_t *mi_lv,
+		 const struct osmo_location_area_id *lai,
+		 bool authentication_required,
+		 bool ciphering_required,
+		 bool is_r99, bool is_utran);
+
+void vlr_parq_cancel(struct osmo_fsm_inst *fi,
+		     enum osmo_fsm_term_cause fsm_cause,
+		     enum gsm48_reject_value gsm48_cause);
+
+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);
+
+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);
diff --git a/include/osmocom/msc/vty.h b/include/osmocom/msc/vty.h
new file mode 100644
index 0000000..6a55df7
--- /dev/null
+++ b/include/osmocom/msc/vty.h
@@ -0,0 +1,34 @@
+#ifndef OPENBSC_VTY_H
+#define OPENBSC_VTY_H
+
+#include <osmocom/vty/vty.h>
+#include <osmocom/vty/buffer.h>
+#include <osmocom/vty/command.h>
+
+struct gsm_network;
+struct vty;
+
+void openbsc_vty_print_statistics(struct vty *vty, struct gsm_network *);
+
+struct buffer *vty_argv_to_buffer(int argc, const char *argv[], int base);
+
+extern struct cmd_element cfg_description_cmd;
+extern struct cmd_element cfg_no_description_cmd;
+
+enum bsc_vty_node {
+	GSMNET_NODE = _LAST_OSMOVTY_NODE + 1,
+	SUBSCR_NODE,
+	MSC_NODE,
+	MNCC_INT_NODE,
+	SMPP_NODE,
+	SMPP_ESME_NODE,
+	HLR_NODE,
+};
+
+int bsc_vty_init_extra(void);
+
+void msc_vty_init(struct gsm_network *msc_network);
+
+struct gsm_network *gsmnet_from_vty(struct vty *vty);
+
+#endif
diff --git a/m4/README b/m4/README
new file mode 100644
index 0000000..92eb30b
--- /dev/null
+++ b/m4/README
@@ -0,0 +1,3 @@
+We want to avoid creating too many external build-time dependencies
+like this one to autoconf-archive.  This directory provides a local
+copy of required m4 rules.
diff --git a/m4/ax_check_compile_flag.m4 b/m4/ax_check_compile_flag.m4
new file mode 100644
index 0000000..ca36397
--- /dev/null
+++ b/m4/ax_check_compile_flag.m4
@@ -0,0 +1,74 @@
+# ===========================================================================
+#   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
new file mode 100644
index 0000000..886c682
--- /dev/null
+++ b/osmoappdesc.py
@@ -0,0 +1,30 @@
+#!/usr/bin/env python
+
+# (C) 2013 by Katerina Barone-Adesi <kat.obsc@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/>
+
+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",
+	   ],
+}
+
+apps = [(4254, "src/osmo-msc/osmo-msc", "OsmoMSC", "msc"),
+        ]
+
+vty_command = ["./src/osmo-msc/osmo-msc", "-c",
+               "doc/examples/osmo-msc/osmo-msc.cfg"]
+
+vty_app = apps[0] # reference apps[] entry for osmo-msc
diff --git a/src/Makefile.am b/src/Makefile.am
new file mode 100644
index 0000000..4e7cea1
--- /dev/null
+++ b/src/Makefile.am
@@ -0,0 +1,32 @@
+AM_CPPFLAGS = \
+	$(all_includes) \
+	-I$(top_srcdir)/include \
+	-I$(top_builddir) \
+	$(NULL)
+
+AM_CFLAGS = \
+	-Wall \
+	$(LIBOSMOCORE_CFLAGS) \
+	$(LIBOSMOGSM_CFLAGS) \
+	$(LIBOSMOGSM_CFLAGS) \
+	$(LIBOSMOVTY_CFLAGS) \
+	$(COVERAGE_CFLAGS) \
+	$(NULL)
+
+AM_LDFLAGS = \
+	$(LIBOSMOCORE_LIBS) \
+	$(LIBOSMOGSM_LIBS) \
+	$(COVERAGE_LDFLAGS) \
+	$(NULL)
+
+# Libraries
+SUBDIRS = \
+	libvlr \
+	libmsc \
+	$(NULL)
+
+# Programs
+SUBDIRS += \
+	osmo-msc \
+	utils \
+	$(NULL)
diff --git a/src/libmsc/Makefile.am b/src/libmsc/Makefile.am
new file mode 100644
index 0000000..90bbbf8
--- /dev/null
+++ b/src/libmsc/Makefile.am
@@ -0,0 +1,77 @@
+AM_CPPFLAGS = \
+	$(all_includes) \
+	-I$(top_srcdir)/include \
+	-I$(top_builddir) \
+	$(NULL)
+
+AM_CFLAGS = \
+	-Wall \
+	$(LIBOSMOCORE_CFLAGS) \
+	$(LIBOSMOVTY_CFLAGS) \
+	$(LIBOSMOABIS_CFLAGS) \
+	$(COVERAGE_CFLAGS) \
+	$(LIBSMPP34_CFLAGS) \
+	$(LIBASN1C_CFLAGS) \
+	$(LIBOSMOSIGTRAN_CFLAGS) \
+	$(LIBOSMOSCCP_CFLAGS) \
+	$(LIBOSMOMGCPCLIENT_CFLAGS) \
+	$(LIBOSMOGSUPCLIENT_CFLAGS) \
+	$(LIBOSMORANAP_CFLAGS) \
+	$(NULL)
+
+noinst_HEADERS = \
+	$(NULL)
+
+noinst_LIBRARIES = \
+	libmsc.a \
+	$(NULL)
+
+libmsc_a_SOURCES = \
+	a_iface.c \
+	a_iface_bssap.c \
+	a_reset.c \
+	msc_vty.c \
+	db.c \
+	gsm_04_08.c \
+	gsm_04_08_cc.c \
+	gsm_04_11.c \
+	gsm_04_14.c \
+	gsm_04_80.c \
+	gsm_09_11.c \
+	gsm_subscriber.c \
+	mncc.c \
+	mncc_builtin.c \
+	mncc_sock.c \
+	msc_ifaces.c \
+	msc_mgcp.c \
+	rrlp.c \
+	silent_call.c \
+	sms_queue.c \
+	transaction.c \
+	osmo_msc.c \
+	ctrl_commands.c \
+	subscr_conn.c \
+	$(NULL)
+if BUILD_IU
+libmsc_a_SOURCES += \
+	iucs.c \
+	iucs_ranap.c \
+	$(NULL)
+else
+libmsc_a_SOURCES += \
+	iu_dummy.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/a_iface.c b/src/libmsc/a_iface.c
new file mode 100644
index 0000000..bd9b890
--- /dev/null
+++ b/src/libmsc/a_iface.c
@@ -0,0 +1,664 @@
+/* (C) 2017 by sysmocom s.f.m.c. GmbH
+ * (C) 2018 by Harald Welte <laforge@gnumonks.org>
+ * All Rights Reserved
+ *
+ * Author: Philipp Maier
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <osmocom/core/utils.h>
+#include <osmocom/core/msgb.h>
+#include <osmocom/core/logging.h>
+#include <osmocom/sigtran/sccp_helpers.h>
+#include <osmocom/sigtran/sccp_sap.h>
+#include <osmocom/sigtran/osmo_ss7.h>
+#include <osmocom/sigtran/protocol/m3ua.h>
+#include <osmocom/gsm/gsm0808.h>
+#include <osmocom/gsm/protocol/gsm_08_08.h>
+#include <osmocom/gsm/protocol/gsm_04_08.h>
+#include <osmocom/gsm/gsm0808_utils.h>
+#include <osmocom/msc/debug.h>
+#include <osmocom/msc/msc_ifaces.h>
+#include <osmocom/msc/a_iface.h>
+#include <osmocom/msc/a_iface_bssap.h>
+#include <osmocom/msc/transaction.h>
+#include <osmocom/mgcp_client/mgcp_client.h>
+#include <osmocom/core/byteswap.h>
+#include <osmocom/sccp/sccp_types.h>
+#include <osmocom/msc/a_reset.h>
+#include <osmocom/msc/osmo_msc.h>
+#include <osmocom/msc/vlr.h>
+
+#include <errno.h>
+
+/* A pointer to the GSM network we work with. By the current paradigm,
+ * there can only be one gsm_network per MSC. The pointer is set once
+ * when calling a_init() */
+static struct gsm_network *gsm_network = NULL;
+
+/* A struct to track currently active connections. We need that information
+ * to handle failure sitautions. In case of a problem, we must know which
+ * connections are currently open and which BSC is responsible. We also need
+ * the data to perform our connection checks (a_reset). All other logic will
+ * look at the connection ids and addresses that are supplied by the
+ * primitives */
+struct bsc_conn {
+	struct llist_head list;
+	uint32_t conn_id;			/* Connection identifier */
+	struct bsc_context *bsc;
+};
+
+/* Internal list with connections we currently maintain. This
+ * list is of type struct bsc_conn (see above) */
+static LLIST_HEAD(active_connections);
+
+/* Record info of a new active connection in the active connection list */
+static void record_bsc_con(const void *ctx, struct bsc_context *bsc, uint32_t conn_id)
+{
+	struct bsc_conn *conn;
+
+	conn = talloc_zero(ctx, struct bsc_conn);
+	OSMO_ASSERT(conn);
+
+	conn->conn_id = conn_id;
+	conn->bsc = bsc;
+
+	llist_add_tail(&conn->list, &active_connections);
+}
+
+/* Delete info of a closed connection from the active connection list */
+void a_delete_bsc_con(uint32_t conn_id)
+{
+	struct bsc_conn *conn;
+	struct bsc_conn *conn_temp;
+
+	llist_for_each_entry_safe(conn, conn_temp, &active_connections, list) {
+		if (conn->conn_id == conn_id) {
+			LOGPBSCCONN(conn, LOGL_DEBUG, "Removing A-interface conn\n");
+			llist_del(&conn->list);
+			talloc_free(conn);
+		}
+	}
+}
+
+/* Find a specified connection id */
+static struct bsc_conn *find_bsc_con(uint32_t conn_id)
+{
+	struct bsc_conn *conn;
+
+	/* Find the address for the current connection id */
+	llist_for_each_entry(conn, &active_connections, list) {
+		if (conn->conn_id == conn_id) {
+			return conn;
+		}
+	}
+
+	return NULL;
+}
+
+/* Check if a specified connection id has an active SCCP connection */
+static bool check_connection_active(uint32_t conn_id)
+{
+	if (find_bsc_con(conn_id))
+		return true;
+	else
+		return false;
+}
+
+/* Get the context for a specific calling (BSC) address */
+static struct bsc_context *get_bsc_context_by_sccp_addr(const struct osmo_sccp_addr *addr)
+{
+	struct bsc_context *bsc_ctx;
+	struct osmo_ss7_instance *ss7;
+
+	if (!addr)
+		return NULL;
+
+	llist_for_each_entry(bsc_ctx, &gsm_network->a.bscs, list) {
+		if (memcmp(&bsc_ctx->bsc_addr, addr, sizeof(*addr)) == 0)
+			return bsc_ctx;
+	}
+
+	ss7 = osmo_ss7_instance_find(gsm_network->a.cs7_instance);
+	OSMO_ASSERT(ss7);
+	LOGP(DBSSAP, LOGL_NOTICE, "The calling BSC (%s) is unknown to this MSC ...\n",
+	     osmo_sccp_addr_name(ss7, addr));
+	return NULL;
+}
+
+/* Send DTAP message via A-interface, take ownership of msg */
+int a_iface_tx_dtap(struct msgb *msg)
+{
+	struct gsm_subscriber_connection *conn;
+	struct msgb *msg_resp;
+
+	uint8_t link_id = OMSC_LINKID_CB(msg);
+	OSMO_ASSERT(msg);
+	conn = (struct gsm_subscriber_connection *)msg->dst;
+	OSMO_ASSERT(conn);
+	OSMO_ASSERT(conn->a.scu);
+
+	LOGPCONN(conn, LOGL_DEBUG, "Passing DTAP message (DLCI=0x%02x) from MSC to BSC\n", link_id);
+
+	msg->l3h = msg->data;
+	msg_resp = gsm0808_create_dtap(msg, link_id);
+
+	/* gsm0808_create_dtap() has copied the data to msg_resp,
+	 * so msg has served its purpose now */
+	msgb_free(msg);
+
+	if (!msg_resp) {
+		LOGPCONN(conn, LOGL_ERROR, "Unable to generate BSSMAP DTAP message!\n");
+		return -EINVAL;
+	}
+
+	LOGPCONN(conn, LOGL_DEBUG, "N-DATA.req(%s)\n", msgb_hexdump_l2(msg_resp));
+	/* osmo_sccp_tx_data_msg() takes ownership of msg_resp */
+	return osmo_sccp_tx_data_msg(conn->a.scu, conn->a.conn_id, msg_resp);
+}
+
+/* Send Cipher mode command via A-interface */
+int a_iface_tx_cipher_mode(const struct gsm_subscriber_connection *conn,
+			   struct gsm0808_encrypt_info *ei, int include_imeisv)
+{
+	/* TODO generalize for A- and Iu interfaces, don't name after 08.08 */
+	struct msgb *msg_resp;
+	uint8_t crm = 0x01;
+
+	OSMO_ASSERT(conn);
+	LOGPCONN(conn, LOGL_DEBUG, "Tx BSSMAP CIPHER MODE COMMAND to BSC, %u ciphers (%s)",
+		 ei->perm_algo_len, osmo_hexdump_nospc(ei->perm_algo, ei->perm_algo_len));
+	LOGPC(DBSSAP, LOGL_DEBUG, " key %s\n", osmo_hexdump_nospc(ei->key, ei->key_len));
+
+	msg_resp = gsm0808_create_cipher(ei, include_imeisv ? &crm : NULL);
+	LOGPCONN(conn, LOGL_DEBUG, "N-DATA.req(%s)\n", msgb_hexdump_l2(msg_resp));
+
+	return osmo_sccp_tx_data_msg(conn->a.scu, conn->a.conn_id, msg_resp);
+}
+
+/* Page a subscriber via A-interface */
+int a_iface_tx_paging(const char *imsi, uint32_t tmsi, uint16_t lac)
+{
+	struct bsc_context *bsc_ctx;
+	struct gsm0808_cell_id_list2 cil;
+	struct msgb *msg;
+	int page_count = 0;
+	struct osmo_ss7_instance *ss7;
+
+	OSMO_ASSERT(imsi);
+
+	cil.id_discr = CELL_IDENT_LAC;
+	cil.id_list[0].lac = lac;
+	cil.id_list_len = 1;
+
+	ss7 = osmo_ss7_instance_find(gsm_network->a.cs7_instance);
+	OSMO_ASSERT(ss7);
+
+	/* Deliver paging request to all known BSCs */
+	llist_for_each_entry(bsc_ctx, &gsm_network->a.bscs, list) {
+		if (a_reset_conn_ready(bsc_ctx->reset_fsm)) {
+			LOGP(DBSSAP, LOGL_DEBUG,
+			     "Tx BSSMAP paging message from MSC %s to BSC %s (imsi=%s, tmsi=0x%08x, lac=%u)\n",
+			     osmo_sccp_addr_name(ss7, &bsc_ctx->msc_addr),
+			     osmo_sccp_addr_name(ss7, &bsc_ctx->bsc_addr), imsi, tmsi, lac);
+			msg = gsm0808_create_paging2(imsi, &tmsi, &cil, NULL);
+			osmo_sccp_tx_unitdata_msg(bsc_ctx->sccp_user,
+						  &bsc_ctx->msc_addr, &bsc_ctx->bsc_addr, msg);
+			page_count++;
+		} else {
+			LOGP(DBSSAP, LOGL_DEBUG,
+			     "Connection down, dropping paging from MSC %s to BSC %s (imsi=%s, tmsi=0x%08x, lac=%u)\n",
+			     osmo_sccp_addr_name(ss7, &bsc_ctx->msc_addr),
+			     osmo_sccp_addr_name(ss7, &bsc_ctx->bsc_addr), imsi, tmsi, lac);
+		}
+	}
+
+	if (page_count <= 0)
+		LOGP(DBSSAP, LOGL_ERROR, "Could not deliver paging because none of the associated BSCs is available!\n");
+
+	return page_count;
+}
+
+/* Convert speech version field */
+static uint8_t convert_speech_version_l3_to_A(int speech_ver)
+{
+	/* The speech versions that are transmitted in the Bearer capability
+	 * information element, that is transmitted on the Layer 3 (CC)
+	 * use a different encoding than the permitted speech version
+	 * identifier, that is signalled in the channel type element on the A
+	 * interface. (See also 3GPP TS 48.008, 3.2.2.1 and 3GPP TS 24.008,
+	 * 10.5.103 */
+
+	switch (speech_ver) {
+	case GSM48_BCAP_SV_FR:
+		return GSM0808_PERM_FR1;
+	case GSM48_BCAP_SV_HR:
+		return GSM0808_PERM_HR1;
+	case GSM48_BCAP_SV_EFR:
+		return GSM0808_PERM_FR2;
+	case GSM48_BCAP_SV_AMR_F:
+		return GSM0808_PERM_FR3;
+	case GSM48_BCAP_SV_AMR_H:
+		return GSM0808_PERM_HR3;
+	case GSM48_BCAP_SV_AMR_OFW:
+		return GSM0808_PERM_FR4;
+	case GSM48_BCAP_SV_AMR_OHW:
+		return GSM0808_PERM_HR4;
+	case GSM48_BCAP_SV_AMR_FW:
+		return GSM0808_PERM_FR5;
+	case GSM48_BCAP_SV_AMR_OH:
+		return GSM0808_PERM_HR6;
+	}
+
+	/* If nothing matches, tag the result as invalid */
+	LOGP(DBSSAP, LOGL_ERROR, "Invalid permitted speech version: %d\n", speech_ver);
+	return 0xFF;
+}
+
+/* Convert speech preference field */
+static uint8_t convert_speech_pref_l3_to_A(int radio)
+{
+	/* The Radio channel requirement field that is transmitted in the
+	 * Bearer capability information element, that is transmitted on the
+	 * Layer 3 (CC) uses a different encoding than the Channel rate and
+	 * type field that is signalled in the channel type element on the A
+	 * interface. (See also 3GPP TS 48.008, 3.2.2.1 and 3GPP TS 24.008,
+	 * 10.5.102 */
+
+	switch (radio) {
+	case GSM48_BCAP_RRQ_FR_ONLY:
+		return GSM0808_SPEECH_FULL_BM;
+	case GSM48_BCAP_RRQ_DUAL_FR:
+		return GSM0808_SPEECH_FULL_PREF;
+	case GSM48_BCAP_RRQ_DUAL_HR:
+		return GSM0808_SPEECH_HALF_PREF;
+	}
+
+	LOGP(DBSSAP, LOGL_ERROR, "Invalid radio channel preference: %d; defaulting to full rate.\n",
+	     radio);
+	return GSM0808_SPEECH_FULL_BM;
+}
+
+/* Assemble the channel type field */
+static int enc_channel_type(struct gsm0808_channel_type *ct, const struct gsm_mncc_bearer_cap *bc)
+{
+	unsigned int i;
+	uint8_t sv;
+	unsigned int count = 0;
+	bool only_gsm_hr = true;
+
+	OSMO_ASSERT(ct);
+	OSMO_ASSERT(bc);
+
+	ct->ch_indctr = GSM0808_CHAN_SPEECH;
+
+	for (i = 0; i < ARRAY_SIZE(bc->speech_ver); i++) {
+		if (bc->speech_ver[i] == -1)
+			break;
+		sv = convert_speech_version_l3_to_A(bc->speech_ver[i]);
+		if (sv != 0xFF) {
+			/* Detect if something else than
+			 * GSM HR V1 is supported */
+			if (sv == GSM0808_PERM_HR2 ||
+			    sv == GSM0808_PERM_HR3 || sv == GSM0808_PERM_HR4 || sv == GSM0808_PERM_HR6)
+				only_gsm_hr = false;
+
+			ct->perm_spch[count] = sv;
+			count++;
+		}
+	}
+	ct->perm_spch_len = count;
+
+	if (only_gsm_hr)
+		/* Note: We must avoid the usage of GSM HR1 as this
+		 * codec only offers very poor audio quality. If the
+		 * MS only supports GSM HR1 (and full rate), and has
+		 * a preference for half rate. Then we will ignore the
+		 * preference and assume a preference for full rate. */
+		ct->ch_rate_type = GSM0808_SPEECH_FULL_BM;
+	else
+		ct->ch_rate_type = convert_speech_pref_l3_to_A(bc->radio);
+
+	if (count)
+		return 0;
+	else
+		return -EINVAL;
+}
+
+/* Assemble the speech codec field */
+static int enc_speech_codec_list(struct gsm0808_speech_codec_list *scl, const struct gsm0808_channel_type *ct)
+{
+	unsigned int i;
+	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;
+	}
+	scl->len = i;
+
+	return 0;
+}
+
+/* Send assignment request via A-interface */
+int a_iface_tx_assignment(const struct gsm_trans *trans)
+{
+	struct gsm_subscriber_connection *conn;
+	struct gsm0808_channel_type ct;
+	struct gsm0808_speech_codec_list scl;
+	uint32_t *ci_ptr = NULL;
+	struct msgb *msg;
+	struct sockaddr_storage rtp_addr;
+	struct sockaddr_in rtp_addr_in;
+	int rc;
+
+	OSMO_ASSERT(trans);
+	conn = trans->conn;
+	OSMO_ASSERT(conn);
+
+	LOGPCONN(conn, LOGL_DEBUG, "Tx BSSMAP ASSIGNMENT COMMAND to BSC\n");
+
+	/* Channel type */
+	rc = enc_channel_type(&ct, &trans->bearer_cap);
+	if (rc < 0) {
+		LOGPCONN(conn, LOGL_ERROR, "Not sending Assignment to BSC: failed to generate channel type\n");
+		return -EINVAL;
+	}
+
+	/* Speech codec list */
+	rc = enc_speech_codec_list(&scl, &ct);
+	if (rc < 0) {
+		LOGPCONN(conn, LOGL_ERROR, "Not sending Assignment to BSC: failed to generate speech codec list\n");
+		return -EINVAL;
+	}
+
+	/* Package RTP-Address data */
+	memset(&rtp_addr_in, 0, sizeof(rtp_addr_in));
+	rtp_addr_in.sin_family = AF_INET;
+	rtp_addr_in.sin_port = osmo_htons(conn->rtp.local_port_ran);
+	rtp_addr_in.sin_addr.s_addr = inet_addr(conn->rtp.local_addr_ran);
+
+	if (rtp_addr_in.sin_addr.s_addr == INADDR_NONE) {
+		LOGPCONN(conn, LOGL_ERROR, "Invalid RTP-Address -- assignment not sent!\n");
+		return -EINVAL;
+	}
+	if (rtp_addr_in.sin_port == 0) {
+		LOGPCONN(conn, LOGL_ERROR, "Invalid RTP-Port -- assignment not sent!\n");
+		return -EINVAL;
+	}
+
+	memset(&rtp_addr, 0, sizeof(rtp_addr));
+	memcpy(&rtp_addr, &rtp_addr_in, sizeof(rtp_addr_in));
+
+	msg = gsm0808_create_ass(&ct, NULL, &rtp_addr, &scl, ci_ptr);
+
+	LOGPCONN(conn, LOGL_DEBUG, "N-DATA.req(%s)\n", msgb_hexdump_l2(msg));
+	return osmo_sccp_tx_data_msg(conn->a.scu, conn->a.conn_id, msg);
+}
+
+/* Send clear command via A-interface */
+int a_iface_tx_clear_cmd(struct gsm_subscriber_connection *conn)
+{
+	struct msgb *msg;
+
+	LOGPCONN(conn, LOGL_INFO, "Tx BSSMAP CLEAR COMMAND to BSC\n");
+
+	msg = gsm0808_create_clear_command(GSM0808_CAUSE_CALL_CONTROL);
+	return osmo_sccp_tx_data_msg(conn->a.scu, conn->a.conn_id, msg);
+}
+
+int a_iface_tx_classmark_request(const struct gsm_subscriber_connection *conn)
+{
+	struct msgb *msg;
+
+	LOGPCONN(conn, LOGL_INFO, "Tx BSSMAP CLASSMARK REQUEST to BSC\n");
+
+	msg = gsm0808_create_classmark_request();
+	return osmo_sccp_tx_data_msg(conn->a.scu, conn->a.conn_id, msg);
+}
+
+/* Callback function: Close all open connections */
+static void a_reset_cb(const void *priv)
+{
+	struct msgb *msg;
+	struct bsc_context *bsc_ctx = (struct bsc_context*) priv;
+	struct osmo_ss7_instance *ss7;
+
+	/* Skip if the A interface is not properly initalized yet */
+	if (!gsm_network)
+		return;
+
+	/* Clear all now orphaned subscriber connections */
+	a_clear_all(bsc_ctx->sccp_user, &bsc_ctx->bsc_addr);
+
+	/* Send reset to the remote BSC */
+	ss7 = osmo_ss7_instance_find(gsm_network->a.cs7_instance);
+	OSMO_ASSERT(ss7);
+	LOGP(DBSSAP, LOGL_NOTICE, "Tx BSSMAP RESET to BSC %s\n", osmo_sccp_addr_name(ss7, &bsc_ctx->bsc_addr));
+	msg = gsm0808_create_reset();
+	osmo_sccp_tx_unitdata_msg(bsc_ctx->sccp_user, &bsc_ctx->msc_addr,
+				  &bsc_ctx->bsc_addr, msg);
+}
+
+/* Add a new BSC connection to our internal list with known BSCs */
+static struct bsc_context *add_bsc(const struct osmo_sccp_addr *msc_addr,
+				   const struct osmo_sccp_addr *bsc_addr, struct osmo_sccp_user *scu)
+{
+	struct bsc_context *bsc_ctx;
+	struct osmo_ss7_instance *ss7;
+
+	ss7 = osmo_ss7_instance_find(gsm_network->a.cs7_instance);
+	OSMO_ASSERT(ss7);
+	LOGP(DBSSAP, LOGL_NOTICE, "Adding new BSC connection for BSC %s...\n", osmo_sccp_addr_name(ss7, bsc_addr));
+
+	/* Generate and fill up a new bsc context */
+	bsc_ctx = talloc_zero(gsm_network, struct bsc_context);
+	OSMO_ASSERT(bsc_ctx);
+	memcpy(&bsc_ctx->bsc_addr, bsc_addr, sizeof(*bsc_addr));
+	memcpy(&bsc_ctx->msc_addr, msc_addr, sizeof(*msc_addr));
+	bsc_ctx->sccp_user = scu;
+	llist_add_tail(&bsc_ctx->list, &gsm_network->a.bscs);
+
+	return bsc_ctx;
+}
+
+/* start the BSSMAP RESET fsm */
+void a_start_reset(struct bsc_context *bsc_ctx, bool already_connected)
+{
+	char bsc_name[32];
+	OSMO_ASSERT(bsc_ctx->reset_fsm == NULL);
+	/* Start reset procedure to make the new connection active */
+	snprintf(bsc_name, sizeof(bsc_name), "bsc-%i", bsc_ctx->bsc_addr.pc);
+	bsc_ctx->reset_fsm = a_reset_alloc(bsc_ctx, bsc_name, a_reset_cb, bsc_ctx, already_connected);
+}
+
+/* determine if given msg is BSSMAP RESET related (true) or not (false) */
+static bool bssmap_is_reset(struct msgb *msg)
+{
+	struct bssmap_header *bs = (struct bssmap_header *)msgb_l2(msg);
+
+	if (msgb_l2len(msg) < sizeof(*bs))
+		return false;
+
+	if (bs->type != BSSAP_MSG_BSS_MANAGEMENT)
+		return false;
+
+	if (msg->l2h[sizeof(*bs)] == BSS_MAP_MSG_RESET)
+		return true;
+
+	if (msg->l2h[sizeof(*bs)] == BSS_MAP_MSG_RESET_ACKNOWLEDGE)
+		return true;
+
+	return false;
+}
+
+/* Callback function, called by the SSCP stack when data arrives */
+static int sccp_sap_up(struct osmo_prim_hdr *oph, void *_scu)
+{
+	struct osmo_sccp_user *scu = _scu;
+	struct osmo_scu_prim *scu_prim = (struct osmo_scu_prim *)oph;
+	int rc = 0;
+	struct a_conn_info a_conn_info;
+	struct bsc_conn *bsc_con;
+
+	memset(&a_conn_info, 0, sizeof(a_conn_info));
+	a_conn_info.network = gsm_network;
+
+	switch (OSMO_PRIM_HDR(&scu_prim->oph)) {
+	case OSMO_PRIM(OSMO_SCU_PRIM_N_CONNECT, PRIM_OP_INDICATION):
+		/* Handle inbound connection indication */
+		a_conn_info.conn_id = scu_prim->u.connect.conn_id;
+		a_conn_info.bsc = get_bsc_context_by_sccp_addr(&scu_prim->u.unitdata.calling_addr);
+		if (!a_conn_info.bsc) {
+			/* We haven't heard from this BSC before, allocate it */
+			a_conn_info.bsc = add_bsc(&scu_prim->u.connect.called_addr,
+						  &scu_prim->u.connect.calling_addr, scu);
+			a_start_reset(a_conn_info.bsc, false);
+		} else {
+			/* This BSC is already known to us, check if we have been through reset yet */
+			if (a_reset_conn_ready(a_conn_info.bsc->reset_fsm) == false) {
+				LOGP(DBSSAP, LOGL_NOTICE, "Refusing N-CONNECT.ind(%u, %s), BSC not reset yet\n",
+				     scu_prim->u.connect.conn_id, msgb_hexdump_l2(oph->msg));
+				rc = osmo_sccp_tx_disconn(scu, a_conn_info.conn_id, &a_conn_info.bsc->msc_addr,
+							  SCCP_RETURN_CAUSE_UNQUALIFIED);
+				break;
+			}
+
+			osmo_sccp_tx_conn_resp(scu, scu_prim->u.connect.conn_id, &scu_prim->u.connect.called_addr, NULL, 0);
+			if (msgb_l2len(oph->msg) > 0) {
+				LOGP(DBSSAP, LOGL_DEBUG, "N-CONNECT.ind(%u, %s)\n",
+				     scu_prim->u.connect.conn_id, msgb_hexdump_l2(oph->msg));
+				rc = a_sccp_rx_dt(scu, &a_conn_info, oph->msg);
+			} else {
+				LOGP(DBSSAP, LOGL_DEBUG, "N-CONNECT.ind(%u)\n", scu_prim->u.connect.conn_id);
+				rc = -ENODATA;
+			}
+
+			if (rc < 0) {
+				/* initial message (COMPL L3) caused some error, we didn't allocate
+				 * a subscriber_conn and must close the connection again */
+				rc = osmo_sccp_tx_disconn(scu, a_conn_info.conn_id,
+							  &a_conn_info.bsc->msc_addr,
+							  SCCP_RETURN_CAUSE_UNQUALIFIED);
+			} else
+				record_bsc_con(scu, a_conn_info.bsc, scu_prim->u.connect.conn_id);
+		}
+		break;
+
+	case OSMO_PRIM(OSMO_SCU_PRIM_N_DATA, PRIM_OP_INDICATION):
+		/* Handle incoming connection oriented data */
+		bsc_con = find_bsc_con(scu_prim->u.data.conn_id);
+		if (!bsc_con) {
+			LOGP(DBSSAP, LOGL_ERROR, "N-DATA.ind(%u, %s) for unknown conn_id\n",
+				scu_prim->u.data.conn_id, msgb_hexdump_l2(oph->msg));
+			break;
+		}
+		a_conn_info.conn_id = scu_prim->u.data.conn_id;
+		a_conn_info.bsc = bsc_con->bsc;
+		LOGP(DBSSAP, LOGL_DEBUG, "N-DATA.ind(%u, %s)\n",
+		     scu_prim->u.data.conn_id, msgb_hexdump_l2(oph->msg));
+		a_sccp_rx_dt(scu, &a_conn_info, oph->msg);
+		break;
+
+	case OSMO_PRIM(OSMO_SCU_PRIM_N_UNITDATA, PRIM_OP_INDICATION):
+		/* Handle inbound UNITDATA */
+
+		/* Get BSC context, create a new one if necessary */
+		a_conn_info.bsc = get_bsc_context_by_sccp_addr(&scu_prim->u.unitdata.calling_addr);
+		if (!a_conn_info.bsc) {
+			/* We haven't heard from this BSC before, allocate it */
+			a_conn_info.bsc = add_bsc(&scu_prim->u.unitdata.called_addr,
+						&scu_prim->u.unitdata.calling_addr, scu);
+			/* Make sure that reset procedure is started */
+			a_start_reset(a_conn_info.bsc, false);
+		}
+
+		/* As long as we are in the reset phase, only reset related BSSMAP messages may pass
+		 * beond here. */
+		if (!bssmap_is_reset(oph->msg) && a_reset_conn_ready(a_conn_info.bsc->reset_fsm) == false) {
+			LOGP(DBSSAP, LOGL_NOTICE, "Ignoring N-UNITDATA.ind(%s), BSC not reset yet\n",
+			     msgb_hexdump_l2(oph->msg));
+			break;
+		}
+
+		DEBUGP(DBSSAP, "N-UNITDATA.ind(%s)\n", msgb_hexdump_l2(oph->msg));
+		a_sccp_rx_udt(scu, &a_conn_info, oph->msg);
+		break;
+
+	default:
+		LOGP(DBSSAP, LOGL_ERROR, "Unhandled SIGTRAN operation %s on primitive %u\n",
+		     get_value_string(osmo_prim_op_names, oph->operation), oph->primitive);
+		break;
+	}
+
+	/* We didn't transfer msgb ownership to any downstream functions so we rely on
+	 * this single/central location to free() the msgb wrapping the primitive */
+	msgb_free(oph->msg);
+	return rc;
+}
+
+/* Clear all subscriber connections on a specified BSC */
+void a_clear_all(struct osmo_sccp_user *scu, const struct osmo_sccp_addr *bsc_addr)
+{
+	struct gsm_subscriber_connection *conn;
+	struct gsm_subscriber_connection *conn_temp;
+	struct gsm_network *network = gsm_network;
+
+	OSMO_ASSERT(scu);
+	OSMO_ASSERT(bsc_addr);
+
+	llist_for_each_entry_safe(conn, conn_temp, &network->subscr_conns, entry) {
+		/* Clear only A connections and connections that actually
+		 * belong to the specified BSC */
+		if (conn->via_ran == RAN_GERAN_A && memcmp(bsc_addr, &conn->a.bsc_addr, sizeof(conn->a.bsc_addr)) == 0) {
+			uint32_t conn_id = conn->a.conn_id;
+			LOGPCONN(conn, LOGL_NOTICE, "Dropping orphaned subscriber connection\n");
+			/* This call will/may talloc_free(conn), so we must save conn_id above */
+			msc_clear_request(conn, GSM48_CC_CAUSE_SWITCH_CONG);
+
+			/* If there is still an SCCP connection active, remove it now */
+			if (check_connection_active(conn_id)) {
+				osmo_sccp_tx_disconn(scu, conn_id, bsc_addr,
+						     SCCP_RELEASE_CAUSE_END_USER_ORIGINATED);
+				a_delete_bsc_con(conn_id);
+			}
+		}
+	}
+}
+
+/* Initalize A interface connection between to MSC and BSC */
+int a_init(struct osmo_sccp_instance *sccp, struct gsm_network *network)
+{
+	OSMO_ASSERT(sccp);
+	OSMO_ASSERT(network);
+
+	/* FIXME: Remove hardcoded parameters, use parameters in parameter list */
+	LOGP(DBSSAP, LOGL_NOTICE, "Initalizing SCCP connection to stp...\n");
+
+	/* Set GSM network variable, there can only be
+	 * one network by design */
+	if (gsm_network != NULL) {
+		OSMO_ASSERT(gsm_network == network);
+	} else
+		gsm_network = network;
+
+	/* SCCP Protocol stack */
+	osmo_sccp_user_bind(sccp, "OsmoMSC-A", sccp_sap_up, SCCP_SSN_BSSAP);
+
+	return 0;
+}
diff --git a/src/libmsc/a_iface_bssap.c b/src/libmsc/a_iface_bssap.c
new file mode 100644
index 0000000..9a2333d
--- /dev/null
+++ b/src/libmsc/a_iface_bssap.c
@@ -0,0 +1,718 @@
+/* (C) 2017 by Sysmocom s.f.m.c. GmbH
+ * (C) 2018 by Harald Welte <laforge@gnumonks.org>
+ * All Rights Reserved
+ *
+ * Author: Philipp Maier
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <osmocom/core/utils.h>
+#include <osmocom/core/msgb.h>
+#include <osmocom/core/logging.h>
+#include <osmocom/sigtran/sccp_helpers.h>
+#include <osmocom/sccp/sccp_types.h>
+#include <osmocom/gsm/gsm0808.h>
+#include <osmocom/gsm/gsm48.h>
+#include <osmocom/gsm/gsm0808_utils.h>
+#include <osmocom/msc/debug.h>
+#include <osmocom/msc/gsm_data.h>
+#include <osmocom/msc/a_iface_bssap.h>
+#include <osmocom/msc/a_iface.h>
+#include <osmocom/msc/osmo_msc.h>
+#include <osmocom/core/byteswap.h>
+#include <osmocom/msc/a_reset.h>
+#include <osmocom/msc/transaction.h>
+#include <osmocom/msc/msc_mgcp.h>
+
+#include <errno.h>
+
+#define IP_V4_ADDR_LEN 4
+
+/*
+ * Helper functions to lookup and allocate subscribers
+ */
+
+/* Allocate a new subscriber connection */
+static struct gsm_subscriber_connection *subscr_conn_allocate_a(const struct a_conn_info *a_conn_info,
+								struct gsm_network *network,
+								uint16_t lac, struct osmo_sccp_user *scu, int conn_id)
+{
+	struct gsm_subscriber_connection *conn;
+
+	LOGP(DMSC, LOGL_DEBUG, "Allocating A-Interface subscriber conn: lac %i, conn_id %i\n", lac, conn_id);
+
+	conn = msc_subscr_conn_alloc(network, RAN_GERAN_A, lac);
+	if (!conn)
+		return NULL;
+
+	conn->a.conn_id = conn_id;
+	conn->a.scu = scu;
+
+	/* Also backup the calling address of the BSC, this allows us to
+	 * identify later which BSC is responsible for this subscriber connection */
+	memcpy(&conn->a.bsc_addr, &a_conn_info->bsc->bsc_addr, sizeof(conn->a.bsc_addr));
+
+	LOGPCONN(conn, LOGL_DEBUG, "A-Interface subscriber connection successfully allocated!\n");
+	return conn;
+}
+
+/* Return an existing A subscriber connection record for the given
+ * connection IDs, or return NULL if not found. */
+static struct gsm_subscriber_connection *subscr_conn_lookup_a(const struct gsm_network *network, int conn_id)
+{
+	struct gsm_subscriber_connection *conn;
+
+	OSMO_ASSERT(network);
+
+	DEBUGP(DMSC, "Looking for A subscriber: conn_id %i\n", conn_id);
+
+	/* FIXME: log_subscribers() is defined in iucs.c as static inline, if
+	 * maybe this function should be public to reach it from here? */
+	/* log_subscribers(network); */
+
+	llist_for_each_entry(conn, &network->subscr_conns, entry) {
+		if (conn->via_ran == RAN_GERAN_A && conn->a.conn_id == conn_id) {
+			LOGPCONN(conn, LOGL_DEBUG, "Found A subscriber for conn_id %i\n", conn_id);
+			return conn;
+		}
+	}
+	DEBUGP(DMSC, "No A subscriber found for conn_id %i\n", conn_id);
+	return NULL;
+}
+
+/*
+ * BSSMAP handling for UNITDATA
+ */
+
+/* Endpoint to handle BSSMAP reset */
+static void bssmap_rx_reset(struct osmo_sccp_user *scu, const struct a_conn_info *a_conn_info, struct msgb *msg)
+{
+	struct gsm_network *network = a_conn_info->network;
+	struct osmo_ss7_instance *ss7;
+
+	ss7 = osmo_ss7_instance_find(network->a.cs7_instance);
+	OSMO_ASSERT(ss7);
+
+	LOGP(DBSSAP, LOGL_NOTICE, "Rx BSSMAP RESET from BSC %s, sending RESET ACK\n",
+	     osmo_sccp_addr_name(ss7, &a_conn_info->bsc->bsc_addr));
+	osmo_sccp_tx_unitdata_msg(scu, &a_conn_info->bsc->msc_addr, &a_conn_info->bsc->bsc_addr,
+				  gsm0808_create_reset_ack());
+
+	/* Make sure all orphand subscriber connections will be cleard */
+	a_clear_all(scu, &a_conn_info->bsc->bsc_addr);
+
+	if (!a_conn_info->bsc->reset_fsm)
+		a_start_reset(a_conn_info->bsc, true);
+
+	/* Treat an incoming RESET like an ACK to any RESET request we may have just sent.
+	 * After all, what we wanted is the A interface to be reset, which we now know has happened. */
+	a_reset_ack_confirm(a_conn_info->bsc->reset_fsm);
+}
+
+/* Endpoint to handle BSSMAP reset acknowlegement */
+static void bssmap_rx_reset_ack(const struct osmo_sccp_user *scu, const struct a_conn_info *a_conn_info,
+				struct msgb *msg)
+{
+
+	struct gsm_network *network = a_conn_info->network;
+	struct osmo_ss7_instance *ss7;
+
+	ss7 = osmo_ss7_instance_find(network->a.cs7_instance);
+	OSMO_ASSERT(ss7);
+
+	if (a_conn_info->bsc->reset_fsm == NULL) {
+		LOGP(DBSSAP, LOGL_ERROR, "Received RESET ACK from an unknown BSC %s, ignoring...\n",
+		     osmo_sccp_addr_name(ss7, &a_conn_info->bsc->bsc_addr));
+		return;
+	}
+
+	LOGP(DBSSAP, LOGL_NOTICE, "Received RESET ACK from BSC %s\n",
+		osmo_sccp_addr_name(ss7, &a_conn_info->bsc->bsc_addr));
+
+	/* Confirm that we managed to get the reset ack message
+	 * towards the connection reset logic */
+	a_reset_ack_confirm(a_conn_info->bsc->reset_fsm);
+}
+
+/* Handle UNITDATA BSSMAP messages */
+static void bssmap_rcvmsg_udt(struct osmo_sccp_user *scu, const struct a_conn_info *a_conn_info, struct msgb *msg)
+{
+	/* Note: When in the MSC role, RESET ACK is the only valid message that
+	 * can be received via UNITDATA */
+
+	if (msgb_l3len(msg) < 1) {
+		LOGP(DBSSAP, LOGL_NOTICE, "Error: No data received -- discarding message!\n");
+		return;
+	}
+
+	LOGP(DBSSAP, LOGL_DEBUG, "Rx BSSMAP UDT %s\n", gsm0808_bssmap_name(msg->l3h[0]));
+
+	switch (msg->l3h[0]) {
+	case BSS_MAP_MSG_RESET:
+		bssmap_rx_reset(scu, a_conn_info, msg);
+		break;
+	case BSS_MAP_MSG_RESET_ACKNOWLEDGE:
+		bssmap_rx_reset_ack(scu, a_conn_info, msg);
+		break;
+	default:
+		LOGP(DBSSAP, LOGL_NOTICE, "Unimplemented message format: %s -- message discarded!\n",
+		     gsm0808_bssmap_name(msg->l3h[0]));
+	}
+}
+
+/* Receive incoming connection less data messages via sccp */
+void a_sccp_rx_udt(struct osmo_sccp_user *scu, const struct a_conn_info *a_conn_info, struct msgb *msg)
+{
+	/* Note: The only valid message type that can be received
+	 * via UNITDATA are BSS Management messages */
+	struct bssmap_header *bs;
+
+	OSMO_ASSERT(scu);
+	OSMO_ASSERT(a_conn_info);
+	OSMO_ASSERT(msg);
+
+	LOGP(DBSSAP, LOGL_DEBUG, "Rx BSSMAP UDT: %s\n", msgb_hexdump_l2(msg));
+
+	if (msgb_l2len(msg) < sizeof(*bs)) {
+		LOGP(DBSSAP, LOGL_ERROR, "Error: Header is too short -- discarding message!\n");
+		return;
+	}
+
+	bs = (struct bssmap_header *)msgb_l2(msg);
+	if (bs->length < msgb_l2len(msg) - sizeof(*bs)) {
+		LOGP(DBSSAP, LOGL_ERROR, "Error: Message is too short -- discarding message!\n");
+		return;
+	}
+
+	switch (bs->type) {
+	case BSSAP_MSG_BSS_MANAGEMENT:
+		msg->l3h = &msg->l2h[sizeof(struct bssmap_header)];
+		bssmap_rcvmsg_udt(scu, a_conn_info, msg);
+		break;
+	default:
+		LOGP(DBSSAP, LOGL_ERROR,
+		     "Error: Unimplemented message type: %s -- message discarded!\n", gsm0808_bssmap_name(bs->type));
+	}
+}
+
+/*
+ * BSSMAP handling for connection oriented data
+ */
+
+/* Endpoint to handle BSSMAP clear request */
+static int bssmap_rx_clear_rqst(struct gsm_subscriber_connection *conn,
+				struct msgb *msg, struct tlv_parsed *tp)
+{
+	uint8_t cause;
+
+	LOGPCONN(conn, LOGL_INFO, "Rx BSSMAP CLEAR REQUEST\n");
+
+	if (!TLVP_PRESENT(tp, GSM0808_IE_CAUSE)) {
+		LOGP(DBSSAP, LOGL_ERROR, "Cause code is missing -- discarding message!\n");
+		return -EINVAL;
+	}
+	cause = TLVP_VAL(tp, GSM0808_IE_CAUSE)[0];
+
+	msc_subscr_conn_mo_close(conn, cause);
+
+	return 0;
+}
+
+/* Endpoint to handle BSSMAP clear complete */
+static int bssmap_rx_clear_complete(struct osmo_sccp_user *scu,
+				    const struct a_conn_info *a_conn_info,
+				    struct gsm_subscriber_connection *conn)
+{
+	int rc;
+
+	LOGPCONN(conn, LOGL_INFO, "Rx BSSMAP CLEAR COMPLETE, releasing SCCP connection\n");
+
+	if (conn)
+		msc_subscr_conn_rx_bssmap_clear_complete(conn);
+
+	rc = osmo_sccp_tx_disconn(scu, a_conn_info->conn_id,
+				  NULL, SCCP_RELEASE_CAUSE_END_USER_ORIGINATED);
+
+	/* Remove the record from the list with active connections. */
+	a_delete_bsc_con(a_conn_info->conn_id);
+
+	return rc;
+}
+
+/* Endpoint to handle layer 3 complete messages */
+static int bssmap_rx_l3_compl(struct osmo_sccp_user *scu, const struct a_conn_info *a_conn_info,
+			      struct msgb *msg, struct tlv_parsed *tp)
+{
+	struct gsm0808_cell_id_list2 cil;
+	uint16_t lac = 0;
+	uint8_t data_length;
+	const uint8_t *data;
+	int rc;
+
+	struct gsm_network *network = a_conn_info->network;
+	struct gsm_subscriber_connection *conn;
+
+	LOGP(DBSSAP, LOGL_INFO, "Rx BSSMAP COMPLETE L3 INFO (conn_id=%i)\n", a_conn_info->conn_id);
+
+	if (!TLVP_PRESENT(tp, GSM0808_IE_CELL_IDENTIFIER)) {
+		LOGP(DBSSAP, LOGL_ERROR, "Mandatory CELL IDENTIFIER not present -- discarding message!\n");
+		return -EINVAL;
+	}
+	if (!TLVP_PRESENT(tp, GSM0808_IE_LAYER_3_INFORMATION)) {
+		LOGP(DBSSAP, LOGL_ERROR, "Mandatory LAYER 3 INFORMATION not present -- discarding message!\n");
+		return -EINVAL;
+	}
+
+	/* Parse Cell ID element -- this should yield a cell identifier "list" with 1 element. */
+
+	data_length = TLVP_LEN(tp, GSM0808_IE_CELL_IDENTIFIER);
+	data = TLVP_VAL(tp, GSM0808_IE_CELL_IDENTIFIER);
+	if (gsm0808_dec_cell_id_list2(&cil, data, data_length) < 0 || cil.id_list_len != 1) {
+		LOGP(DBSSAP, LOGL_ERROR,
+		     "Unable to parse element CELL IDENTIFIER -- discarding message!\n");
+		return -EINVAL;
+	}
+
+	/* Determine the LAC which we will use for this subscriber. */
+	switch (cil.id_discr) {
+	case CELL_IDENT_WHOLE_GLOBAL: {
+		const struct osmo_cell_global_id *id = &cil.id_list[0].global;
+		if (osmo_plmn_cmp(&id->lai.plmn, &network->plmn) != 0) {
+			LOGP(DBSSAP, LOGL_ERROR,
+			     "WHOLE GLOBAL CELL IDENTIFIER does not match network MCC/MNC -- discarding message!\n");
+			return -EINVAL;
+		}
+		lac = id->lai.lac;
+		break;
+	}
+	case CELL_IDENT_LAC_AND_CI: {
+		const struct osmo_lac_and_ci_id *id = &cil.id_list[0].lac_and_ci;
+		lac = id->lac;
+		break;
+	}
+	case CELL_IDENT_LAI_AND_LAC: {
+		const struct osmo_location_area_id *id = &cil.id_list[0].lai_and_lac;
+		if (osmo_plmn_cmp(&id->plmn, &network->plmn) != 0) {
+			LOGP(DBSSAP, LOGL_ERROR,
+			     "LAI AND LAC CELL IDENTIFIER does not match network MCC/MNC -- discarding message!\n");
+			return -EINVAL;
+		}
+		lac = id->lac;
+		break;
+	}
+	case CELL_IDENT_LAC:
+		lac = cil.id_list[0].lac;
+		break;
+
+	case CELL_IDENT_CI:
+	case CELL_IDENT_NO_CELL:
+	case CELL_IDENT_BSS:
+		LOGP(DBSSAP, LOGL_ERROR,
+		     "CELL IDENTIFIER does not specify a LAC -- discarding message!\n");
+		return -EINVAL;
+
+	default:
+		LOGP(DBSSAP, LOGL_ERROR,
+		     "Unable to parse element CELL IDENTIFIER (unknown cell identification discriminator 0x%x) "
+		     "-- discarding message!\n", cil.id_discr);
+		return -EINVAL;
+	}
+
+	/* Parse Layer 3 Information element */
+	msg->l3h = (uint8_t*)TLVP_VAL(tp, GSM0808_IE_LAYER_3_INFORMATION);
+	msgb_l3trim(msg, TLVP_LEN(tp, GSM0808_IE_LAYER_3_INFORMATION));
+
+	if (msgb_l3len(msg) < sizeof(struct gsm48_hdr)) {
+		LOGP(DBSSAP, LOGL_ERROR, "COMPL_L3 with too short L3 (%d) -- discarding\n",
+		     msgb_l3len(msg));
+		return -ENODATA;
+	}
+
+	/* Create new subscriber context */
+	conn = subscr_conn_allocate_a(a_conn_info, network, lac, scu, a_conn_info->conn_id);
+
+	/* Handover location update to the MSC code */
+	rc = msc_compl_l3(conn, msg, 0);
+
+	if (rc == MSC_CONN_ACCEPT) {
+		LOGP(DMSC, LOGL_INFO, "User has been accepted by MSC.\n");
+		return 0;
+	} else if (rc == MSC_CONN_REJECT)
+		LOGP(DMSC, LOGL_INFO, "User has been rejected by MSC.\n");
+	else
+		LOGP(DMSC, LOGL_INFO, "User has been rejected by MSC (unknown error)\n");
+
+	return -EINVAL;
+}
+
+/* Endpoint to handle BSSMAP classmark update */
+static int bssmap_rx_classmark_upd(struct gsm_subscriber_connection *conn, struct msgb *msg,
+				   struct tlv_parsed *tp)
+{
+	const uint8_t *cm2 = NULL;
+	const uint8_t *cm3 = NULL;
+	uint8_t cm2_len = 0;
+	uint8_t cm3_len = 0;
+
+	LOGPCONN(conn, LOGL_DEBUG, "Rx BSSMAP CLASSMARK UPDATE\n");
+
+	if (!TLVP_PRESENT(tp, GSM0808_IE_CLASSMARK_INFORMATION_T2)) {
+		LOGPCONN(conn, LOGL_ERROR, "Mandatory Classmark Information Type 2 not present -- discarding message!\n");
+		return -EINVAL;
+	}
+
+	cm2 = TLVP_VAL(tp, GSM0808_IE_CLASSMARK_INFORMATION_T2);
+	cm2_len = TLVP_LEN(tp, GSM0808_IE_CLASSMARK_INFORMATION_T2);
+
+	if (TLVP_PRESENT(tp, GSM0808_IE_CLASSMARK_INFORMATION_T3)) {
+		cm3 = TLVP_VAL(tp, GSM0808_IE_CLASSMARK_INFORMATION_T3);
+		cm3_len = TLVP_LEN(tp, GSM0808_IE_CLASSMARK_INFORMATION_T3);
+	}
+
+	/* Inform MSC about the classmark change */
+	msc_classmark_chg(conn, cm2, cm2_len, cm3, cm3_len);
+
+	return 0;
+}
+
+/* Endpoint to handle BSSMAP cipher mode complete */
+static int bssmap_rx_ciph_compl(struct gsm_subscriber_connection *conn, struct msgb *msg,
+				struct tlv_parsed *tp)
+{
+	/* FIXME: The field GSM0808_IE_LAYER_3_MESSAGE_CONTENTS is optional by
+	 * means of the specification. So there can be messages without L3 info.
+	 * In this case, the code will crash becrause msc_cipher_mode_compl()
+	 * is not able to deal with msg = NULL and apperently
+	 * msc_cipher_mode_compl() was never meant to be used without L3 data.
+	 * This needs to be discussed further! */
+
+	uint8_t alg_id = 1;
+	struct rate_ctr_group *msc = conn->network->msc_ctrs;
+
+	LOGPCONN(conn, LOGL_DEBUG, "Rx BSSMAP CIPHER MODE COMPLETE\n");
+
+	if (TLVP_PRESENT(tp, GSM0808_IE_CHOSEN_ENCR_ALG)) {
+		alg_id = TLVP_VAL(tp, GSM0808_IE_CHOSEN_ENCR_ALG)[0] - 1;
+	}
+
+	if (TLVP_PRESENT(tp, GSM0808_IE_LAYER_3_MESSAGE_CONTENTS)) {
+		msg->l3h = (uint8_t*)TLVP_VAL(tp, GSM0808_IE_LAYER_3_MESSAGE_CONTENTS);
+		msgb_l3trim(msg, TLVP_LEN(tp, GSM0808_IE_LAYER_3_MESSAGE_CONTENTS));
+	} else {
+		msg = NULL;
+	}
+
+	rate_ctr_inc(&msc->ctr[MSC_CTR_BSSMAP_CIPHER_MODE_COMPLETE]);
+
+	/* Hand over cipher mode complete message to the MSC */
+	msc_cipher_mode_compl(conn, msg, alg_id);
+
+	return 0;
+}
+
+/* Endpoint to handle BSSMAP cipher mode reject, 3GPP TS 08.08 §3.2.1.48 */
+static int bssmap_rx_ciph_rej(struct gsm_subscriber_connection *conn,
+			      struct msgb *msg, struct tlv_parsed *tp)
+{
+	int rc;
+	enum gsm0808_cause cause;
+	struct rate_ctr_group *msc = conn->network->msc_ctrs;
+
+	LOGPCONN(conn, LOGL_NOTICE, "RX BSSMAP CIPHER MODE REJECT\n");
+
+	rc = gsm0808_get_cipher_reject_cause(tp);
+	if (rc < 0) {
+		LOGPCONN(conn, LOGL_ERROR, "failed (%s) to extract Cause from Cipher mode reject: %s\n",
+			 strerror(-rc), msgb_hexdump(msg));
+		return rc;
+	}
+
+	rate_ctr_inc(&msc->ctr[MSC_CTR_BSSMAP_CIPHER_MODE_REJECT]);
+	cause = (enum gsm0808_cause)rc;
+	LOGPCONN(conn, LOGL_NOTICE, "Cipher mode rejection cause: %s\n", gsm0808_cause_name(cause));
+
+	/* FIXME: Can we do something meaningful here? e.g. report to the
+	 * msc code somehow that the cipher mode command has failed. */
+
+	return 0;
+}
+
+/* Endpoint to handle BSSMAP assignment failure */
+static int bssmap_rx_ass_fail(struct gsm_subscriber_connection *conn, struct msgb *msg,
+			      struct tlv_parsed *tp)
+{
+	uint8_t cause;
+	uint8_t *rr_cause_ptr = NULL;
+	uint8_t rr_cause;
+
+	LOGPCONN(conn, LOGL_NOTICE, "Rx BSSMAP ASSIGNMENT FAILURE message\n");
+
+	if (!TLVP_PRESENT(tp, GSM0808_IE_CAUSE)) {
+		LOGPCONN(conn, LOGL_ERROR, "Cause code is missing -- discarding message!\n");
+		return -EINVAL;
+	}
+	cause = TLVP_VAL(tp, GSM0808_IE_CAUSE)[0];
+
+	if (TLVP_PRESENT(tp, GSM0808_IE_RR_CAUSE)) {
+		rr_cause = TLVP_VAL(tp, GSM0808_IE_RR_CAUSE)[0];
+		rr_cause_ptr = &rr_cause;
+	}
+
+	/* FIXME: In AoIP, the Assignment failure will carry also an optional
+	 * Codec List (BSS Supported) element. It has to be discussed if we
+	 * can ignore this element. If not, The msc_assign_fail() function
+	 * call has to change. However msc_assign_fail() does nothing in the
+	 * end. So probably we can just leave it as it is. Even for AoIP */
+
+	/* Inform the MSC about the assignment failure event */
+	msc_assign_fail(conn, cause, rr_cause_ptr);
+
+	return 0;
+}
+
+/* Endpoint to handle sapi "n" reject */
+static int bssmap_rx_sapi_n_rej(struct gsm_subscriber_connection *conn, struct msgb *msg,
+				struct tlv_parsed *tp)
+{
+	uint8_t dlci;
+
+	LOGPCONN(conn, LOGL_NOTICE, "Rx BSSMAP SAPI-N-REJECT message\n");
+
+	/* Note: The MSC code seems not to care about the cause code, but by
+	 * the specification it is mandatory, so we check its presence. See
+	 * also 3GPP TS 48.008 3.2.1.34 SAPI "n" REJECT */
+	if (!TLVP_PRESENT(tp, GSM0808_IE_CAUSE)) {
+		LOGPCONN(conn, LOGL_ERROR, "Cause code is missing -- discarding message!\n");
+		return -EINVAL;
+	}
+	if (!TLVP_PRESENT(tp, GSM0808_IE_DLCI)) {
+		LOGPCONN(conn, LOGL_ERROR, "DLCI is missing -- discarding message!\n");
+		return -EINVAL;
+	}
+	dlci = TLVP_VAL(tp, GSM0808_IE_DLCI)[0];
+
+	/* Inform the MSC about the sapi "n" reject event */
+	msc_sapi_n_reject(conn, dlci);
+
+	return 0;
+}
+
+/* Use the speech codec info we go with the assignment complete to dtermine
+ * which codec we will signal to the MGW */
+static enum mgcp_codecs mgcp_codec_from_sc(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;
+	default:
+		return CODEC_PCMU_8000_1;
+		break;
+	}
+}
+
+/* Endpoint to handle assignment complete */
+static int bssmap_rx_ass_compl(struct gsm_subscriber_connection *conn, struct msgb *msg,
+			       struct tlv_parsed *tp)
+{
+	struct sockaddr_storage rtp_addr;
+	struct gsm0808_speech_codec sc;
+	struct sockaddr_in *rtp_addr_in;
+	int rc;
+
+	LOGPCONN(conn, LOGL_INFO, "Rx BSSMAP ASSIGNMENT COMPLETE message\n");
+
+	if (!TLVP_PRESENT(tp, GSM0808_IE_AOIP_TRASP_ADDR)) {
+		LOGPCONN(conn, LOGL_ERROR, "AoIP transport identifier missing -- discarding message!\n");
+		return -EINVAL;
+	}
+
+	/* Decode AoIP transport address element */
+	rc = gsm0808_dec_aoip_trasp_addr(&rtp_addr, TLVP_VAL(tp, GSM0808_IE_AOIP_TRASP_ADDR),
+					 TLVP_LEN(tp, GSM0808_IE_AOIP_TRASP_ADDR));
+	if (rc < 0) {
+		LOGPCONN(conn, LOGL_ERROR, "Unable to decode aoip transport address.\n");
+		return -EINVAL;
+	}
+
+	/* Decode speech codec (choosen) element */
+	rc = gsm0808_dec_speech_codec(&sc, TLVP_VAL(tp, GSM0808_IE_SPEECH_CODEC),
+					 TLVP_LEN(tp, GSM0808_IE_SPEECH_CODEC));
+	if (rc < 0) {
+		LOGPCONN(conn, LOGL_ERROR, "Unable to decode speech codec (choosen).\n");
+		return -EINVAL;
+	}
+	conn->rtp.codec_ran = mgcp_codec_from_sc(&sc);
+
+	/* use address / port supplied with the AoIP
+	 * transport address element */
+	if (rtp_addr.ss_family == AF_INET) {
+		rtp_addr_in = (struct sockaddr_in *)&rtp_addr;
+		msc_mgcp_ass_complete(conn, osmo_ntohs(rtp_addr_in->sin_port), inet_ntoa(rtp_addr_in->sin_addr));
+	} else {
+		LOGPCONN(conn, LOGL_ERROR, "Unsopported addressing scheme. (supports only IPV4)\n");
+		return -EINVAL;
+	}
+
+	/* FIXME: Seems to be related to authentication or,
+	   encryption. Is this really in the right place? */
+	msc_rx_sec_mode_compl(conn);
+
+	return 0;
+}
+
+/* Handle incoming connection oriented BSSMAP messages */
+static int rx_bssmap(struct osmo_sccp_user *scu, const struct a_conn_info *a_conn_info, struct msgb *msg)
+{
+	struct gsm_subscriber_connection *conn;
+	struct tlv_parsed tp;
+	int rc;
+	uint8_t msg_type;
+
+	if (msgb_l3len(msg) < 1) {
+		LOGP(DBSSAP, LOGL_NOTICE, "Error: No data received -- discarding message!\n");
+		return -1;
+	}
+	msg_type = msg->l3h[0];
+
+	rc = osmo_bssap_tlv_parse(&tp, msg->l3h + 1, msgb_l3len(msg) - 1);
+	if (rc < 0) {
+		LOGP(DBSSAP, LOGL_ERROR, "Failed parsing TLV -- discarding message! %s\n",
+			osmo_hexdump(msg->l3h, msgb_l3len(msg)));
+		return -EINVAL;
+	}
+
+	/* Only message types allowed without a 'conn' */
+	switch (msg_type) {
+	case BSS_MAP_MSG_COMPLETE_LAYER_3:
+		return bssmap_rx_l3_compl(scu, a_conn_info, msg, &tp);
+	default:
+		break;
+	}
+
+	conn = subscr_conn_lookup_a(a_conn_info->network, a_conn_info->conn_id);
+	if (!conn) {
+		LOGP(DBSSAP, LOGL_ERROR, "Couldn't find subscr_conn for conn_id=%d\n", a_conn_info->conn_id);
+		/* We expect a Clear Complete to come in on a valid conn. But if for some reason we still
+		 * have the SCCP connection while the subscriber connection data is already gone, at
+		 * least close the SCCP conn. */
+
+		if (msg_type == BSS_MAP_MSG_CLEAR_COMPLETE)
+			return bssmap_rx_clear_complete(scu, a_conn_info, NULL);
+
+		return -EINVAL;
+	}
+
+	LOGPCONN(conn, LOGL_DEBUG, "Rx BSSMAP DT1 %s\n", gsm0808_bssmap_name(msg_type));
+
+	switch (msg_type) {
+	case BSS_MAP_MSG_CLEAR_RQST:
+		return bssmap_rx_clear_rqst(conn, msg, &tp);
+	case BSS_MAP_MSG_CLEAR_COMPLETE:
+		return bssmap_rx_clear_complete(scu, a_conn_info, conn);
+	case BSS_MAP_MSG_CLASSMARK_UPDATE:
+		return bssmap_rx_classmark_upd(conn, msg, &tp);
+	case BSS_MAP_MSG_CIPHER_MODE_COMPLETE:
+		return bssmap_rx_ciph_compl(conn, msg, &tp);
+	case BSS_MAP_MSG_CIPHER_MODE_REJECT:
+		return bssmap_rx_ciph_rej(conn, msg, &tp);
+	case BSS_MAP_MSG_ASSIGMENT_FAILURE:
+		return bssmap_rx_ass_fail(conn, msg, &tp);
+	case BSS_MAP_MSG_SAPI_N_REJECT:
+		return bssmap_rx_sapi_n_rej(conn, msg, &tp);
+	case BSS_MAP_MSG_ASSIGMENT_COMPLETE:
+		return bssmap_rx_ass_compl(conn, msg, &tp);
+	default:
+		LOGPCONN(conn, LOGL_ERROR, "Unimplemented msg type: %s\n", gsm0808_bssmap_name(msg_type));
+		return -EINVAL;
+	}
+
+	return -EINVAL;
+}
+
+/* Endpoint to handle regular BSSAP DTAP messages. No ownership of 'msg' is passed on! */
+static int rx_dtap(const struct osmo_sccp_user *scu, const struct a_conn_info *a_conn_info, struct msgb *msg)
+{
+	struct gsm_network *network = a_conn_info->network;
+	struct gsm_subscriber_connection *conn;
+	struct dtap_header *dtap = (struct dtap_header *) msg->l2h;
+
+	conn = subscr_conn_lookup_a(network, a_conn_info->conn_id);
+	if (!conn) {
+		return -EINVAL;
+	}
+
+	LOGPCONN(conn, LOGL_DEBUG, "Rx DTAP %s\n", msgb_hexdump_l2(msg));
+
+	/* msc_dtap expects the dtap payload in l3h */
+	msg->l3h = msg->l2h + 3;
+	OMSC_LINKID_CB(msg) = dtap->link_id;
+
+	/* Forward dtap payload into the msc */
+	msc_dtap(conn, msg);
+
+	return 0;
+}
+
+/* Handle incoming connection oriented messages. No ownership of 'msg' is passed on! */
+int a_sccp_rx_dt(struct osmo_sccp_user *scu, const struct a_conn_info *a_conn_info, struct msgb *msg)
+{
+	OSMO_ASSERT(scu);
+	OSMO_ASSERT(a_conn_info);
+	OSMO_ASSERT(msg);
+
+	if (msgb_l2len(msg) < sizeof(struct bssmap_header)) {
+		LOGP(DBSSAP, LOGL_NOTICE, "The header is too short -- discarding message!\n");
+		return -EINVAL;
+	}
+
+	switch (msg->l2h[0]) {
+	case BSSAP_MSG_BSS_MANAGEMENT:
+		msg->l3h = &msg->l2h[sizeof(struct bssmap_header)];
+		return rx_bssmap(scu, a_conn_info, msg);
+	case BSSAP_MSG_DTAP:
+		return rx_dtap(scu, a_conn_info, msg);
+	default:
+		LOGP(DBSSAP, LOGL_ERROR, "Unimplemented BSSAP msg type: %s\n", gsm0808_bssap_name(msg->l2h[0]));
+		return -EINVAL;
+	}
+
+	return -EINVAL;
+}
diff --git a/src/libmsc/a_reset.c b/src/libmsc/a_reset.c
new file mode 100644
index 0000000..1e35a10
--- /dev/null
+++ b/src/libmsc/a_reset.c
@@ -0,0 +1,149 @@
+/* (C) 2017 by sysmocom s.f.m.c. GmbH
+ * All Rights Reserved
+ *
+ * Author: Philipp Maier
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <osmocom/core/logging.h>
+#include <osmocom/core/utils.h>
+#include <osmocom/core/timer.h>
+#include <osmocom/core/fsm.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+#include <osmocom/msc/debug.h>
+#include <osmocom/msc/a_reset.h>
+
+#define RESET_RESEND_INTERVAL 2		/* sec */
+#define RESET_RESEND_TIMER_NO 16	/* See also 3GPP TS 48.008 Chapter 3.1.4.1.3.2 */
+
+enum reset_fsm_states {
+	ST_DISC,		/* Disconnected from remote end */
+	ST_CONN,		/* We have a confirmed connection */
+};
+
+enum reset_fsm_evt {
+	EV_CONN_ACK,		/* Received either BSSMAP RESET or BSSMAP RESET
+				 * ACK from the remote end */
+};
+
+/* Reset context data (callbacks, state machine etc...) */
+struct reset_ctx {
+	/* Callback function to be called when a connection
+	 * failure is detected and a rest must occur */
+	void (*cb)(void *priv);
+
+	/* Privated data for the callback function */
+	void *priv;
+};
+
+static const struct value_string fsm_event_names[] = {
+	OSMO_VALUE_STRING(EV_CONN_ACK),
+	{0, NULL}
+};
+
+/* Disconnected state */
+static void fsm_disc_cb(struct osmo_fsm_inst *fi, uint32_t event, void *data)
+{
+	osmo_fsm_inst_state_chg(fi, ST_CONN, 0, 0);
+}
+
+/* Timer callback to retransmit the reset signal */
+static int fsm_reset_ack_timeout_cb(struct osmo_fsm_inst *fi)
+{
+	struct reset_ctx *reset_ctx = (struct reset_ctx *)fi->priv;
+	LOGPFSML(fi, LOGL_NOTICE, "(re)sending BSSMAP RESET message...\n");
+	reset_ctx->cb(reset_ctx->priv);
+	osmo_fsm_inst_state_chg(fi, ST_DISC, RESET_RESEND_INTERVAL, RESET_RESEND_TIMER_NO);
+	return 0;
+}
+
+static struct osmo_fsm_state reset_fsm_states[] = {
+	[ST_DISC] = {
+		     .in_event_mask = (1 << EV_CONN_ACK),
+		     .out_state_mask = (1 << ST_CONN) | (1 << ST_DISC),
+		     .name = "DISC",
+		     .action = fsm_disc_cb,
+		     },
+	[ST_CONN] = {
+		     .in_event_mask = (1 << EV_CONN_ACK),
+		     .name = "CONN",
+		     },
+};
+
+/* State machine definition */
+static struct osmo_fsm fsm = {
+	.name = "A-RESET",
+	.states = reset_fsm_states,
+	.num_states = ARRAY_SIZE(reset_fsm_states),
+	.log_subsys = DMSC,
+	.timer_cb = fsm_reset_ack_timeout_cb,
+	.event_names = fsm_event_names,
+};
+
+/* Create and start state machine which handles the reset/reset-ack procedure */
+struct osmo_fsm_inst *a_reset_alloc(void *ctx, const char *name, void *cb,
+				    void *priv, bool already_connected)
+{
+	OSMO_ASSERT(name);
+
+	struct reset_ctx *reset_ctx;
+	struct osmo_fsm_inst *reset_fsm;
+
+	/* Register the fsm description (if not already done) */
+	if (osmo_fsm_find_by_name(fsm.name) != &fsm)
+		osmo_fsm_register(&fsm);
+
+	/* Allocate and configure a new fsm instance */
+	reset_ctx = talloc_zero(ctx, struct reset_ctx);
+	OSMO_ASSERT(reset_ctx);
+	reset_ctx->priv = priv;
+	reset_ctx->cb = cb;
+        reset_fsm = osmo_fsm_inst_alloc(&fsm, ctx, reset_ctx, LOGL_DEBUG, name);
+	OSMO_ASSERT(reset_fsm);
+
+	if (already_connected)
+		osmo_fsm_inst_state_chg(reset_fsm, ST_CONN, 0, 0);
+	else {
+		/* kick off reset-ack sending mechanism */
+		osmo_fsm_inst_state_chg(reset_fsm, ST_DISC, RESET_RESEND_INTERVAL,
+					RESET_RESEND_TIMER_NO);
+	}
+
+	return reset_fsm;
+}
+
+/* Confirm that we sucessfully received a reset acknowlege message */
+void a_reset_ack_confirm(struct osmo_fsm_inst *reset_fsm)
+{
+	OSMO_ASSERT(reset_fsm);
+	osmo_fsm_inst_dispatch(reset_fsm, EV_CONN_ACK, NULL);
+}
+
+/* Check if we have a connection to a specified msc */
+bool a_reset_conn_ready(struct osmo_fsm_inst *reset_fsm)
+{
+	/* If no reset context is supplied, we assume that
+	 * the connection can't be ready! */
+	if (!reset_fsm)
+		return false;
+
+	if (reset_fsm->state == ST_CONN)
+		return true;
+
+	return false;
+}
diff --git a/src/libmsc/ctrl_commands.c b/src/libmsc/ctrl_commands.c
new file mode 100644
index 0000000..e37cc94
--- /dev/null
+++ b/src/libmsc/ctrl_commands.c
@@ -0,0 +1,106 @@
+/*
+ * (C) 2014 by Holger Hans Peter Freyther
+ * (C) 2014 by sysmocom s.f.m.c. GmbH
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <osmocom/ctrl/control_cmd.h>
+#include <osmocom/core/utils.h>
+#include <osmocom/msc/gsm_data.h>
+#include <osmocom/msc/gsm_subscriber.h>
+#include <osmocom/msc/db.h>
+#include <osmocom/msc/debug.h>
+#include <osmocom/msc/vlr.h>
+
+#include <stdbool.h>
+
+static struct gsm_network *msc_ctrl_net = NULL;
+
+static int get_subscriber_list(struct ctrl_cmd *cmd, void *d)
+{
+	struct vlr_subscr *vsub;
+
+	if (!msc_ctrl_net) {
+		cmd->reply = "MSC CTRL commands not initialized";
+		return CTRL_CMD_ERROR;
+	}
+
+	if (!msc_ctrl_net->vlr) {
+		cmd->reply = "VLR not initialized";
+		return CTRL_CMD_ERROR;
+	}
+
+	cmd->reply = talloc_strdup(cmd, "");
+
+	llist_for_each_entry(vsub, &msc_ctrl_net->vlr->subscribers, list) {
+		/* Do not list subscribers that aren't successfully attached. */
+		if (!vsub->lu_complete)
+			continue;
+		cmd->reply = talloc_asprintf_append(cmd->reply, "%s,%s\n",
+						    vsub->imsi, vsub->msisdn);
+	}
+	return CTRL_CMD_REPLY;
+}
+CTRL_CMD_DEFINE_RO(subscriber_list, "subscriber-list-active-v1");
+
+CTRL_CMD_DEFINE_WO_NOVRF(sub_expire, "subscriber-expire");
+static int set_sub_expire(struct ctrl_cmd *cmd, void *data)
+{
+	struct vlr_subscr *vsub;
+
+	if (!msc_ctrl_net) {
+		cmd->reply = "MSC CTRL commands not initialized";
+		return CTRL_CMD_ERROR;
+	}
+
+	if (!msc_ctrl_net->vlr) {
+		cmd->reply = "VLR not initialized";
+		return CTRL_CMD_ERROR;
+	}
+
+	vsub = vlr_subscr_find_by_imsi(msc_ctrl_net->vlr, cmd->value);
+	if (!vsub) {
+		LOGP(DCTRL, LOGL_ERROR, "Attempt to expire unknown subscriber IMSI=%s\n", cmd->value);
+		cmd->reply = "IMSI unknown";
+		return CTRL_CMD_ERROR;
+	}
+
+	LOGP(DCTRL, LOGL_NOTICE, "Expiring subscriber IMSI=%s\n", cmd->value);
+
+	if (vlr_subscr_expire(vsub))
+		LOGP(DCTRL, LOGL_NOTICE, "VLR released subscriber %s\n", vlr_subscr_name(vsub));
+
+	if (vsub->use_count > 1)
+		LOGP(DCTRL, LOGL_NOTICE, "Subscriber %s is still in use, should be released soon\n",
+		     vlr_subscr_name(vsub));
+
+	vlr_subscr_put(vsub);
+
+	return CTRL_CMD_REPLY;
+}
+
+int msc_ctrl_cmds_install(struct gsm_network *net)
+{
+	int rc = 0;
+	msc_ctrl_net = net;
+
+	rc |= ctrl_cmd_install(CTRL_NODE_ROOT, &cmd_subscriber_list);
+	rc |= ctrl_cmd_install(CTRL_NODE_ROOT, &cmd_sub_expire);
+
+	return rc;
+}
diff --git a/src/libmsc/db.c b/src/libmsc/db.c
new file mode 100644
index 0000000..b5e7ad8
--- /dev/null
+++ b/src/libmsc/db.c
@@ -0,0 +1,1119 @@
+/* Simple HLR/VLR database backend using dbi */
+/* (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>
+ * 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 <stdint.h>
+#include <inttypes.h>
+#include <libgen.h>
+#include <stdio.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <time.h>
+#include <dbi/dbi.h>
+
+#include <osmocom/msc/gsm_data.h>
+#include <osmocom/msc/gsm_subscriber.h>
+#include <osmocom/msc/gsm_04_11.h>
+#include <osmocom/msc/db.h>
+#include <osmocom/msc/debug.h>
+#include <osmocom/msc/vlr.h>
+
+#include <osmocom/gsm/protocol/gsm_23_003.h>
+#include <osmocom/core/talloc.h>
+#include <osmocom/core/statistics.h>
+#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;
+
+#define SCHEMA_REVISION "5"
+
+enum {
+	SCHEMA_META,
+	INSERT_META,
+	SCHEMA_SUBSCRIBER,
+	SCHEMA_AUTH,
+	SCHEMA_EQUIPMENT,
+	SCHEMA_EQUIPMENT_WATCH,
+	SCHEMA_SMS,
+	SCHEMA_VLR,
+	SCHEMA_APDU,
+	SCHEMA_COUNTERS,
+	SCHEMA_RATE,
+	SCHEMA_AUTHKEY,
+	SCHEMA_AUTHLAST,
+};
+
+static const char *create_stmts[] = {
+	[SCHEMA_META] = "CREATE TABLE IF NOT EXISTS Meta ("
+		"id INTEGER PRIMARY KEY AUTOINCREMENT, "
+		"key TEXT UNIQUE NOT NULL, "
+		"value TEXT NOT NULL"
+		")",
+	[INSERT_META] = "INSERT OR IGNORE INTO Meta "
+		"(key, value) "
+		"VALUES "
+		"('revision', " SCHEMA_REVISION ")",
+	[SCHEMA_SUBSCRIBER] = "CREATE TABLE IF NOT EXISTS Subscriber ("
+		"id INTEGER PRIMARY KEY AUTOINCREMENT, "
+		"created TIMESTAMP NOT NULL, "
+		"updated TIMESTAMP NOT NULL, "
+		"imsi NUMERIC UNIQUE NOT NULL, "
+		"name TEXT, "
+		"extension TEXT UNIQUE, "
+		"authorized INTEGER NOT NULL DEFAULT 0, "
+		"tmsi TEXT UNIQUE, "
+		"lac INTEGER NOT NULL DEFAULT 0, "
+		"expire_lu TIMESTAMP DEFAULT NULL"
+		")",
+	[SCHEMA_AUTH] = "CREATE TABLE IF NOT EXISTS AuthToken ("
+		"id INTEGER PRIMARY KEY AUTOINCREMENT, "
+		"subscriber_id INTEGER UNIQUE NOT NULL, "
+		"created TIMESTAMP NOT NULL, "
+		"token TEXT UNIQUE NOT NULL"
+		")",
+	[SCHEMA_EQUIPMENT] = "CREATE TABLE IF NOT EXISTS Equipment ("
+		"id INTEGER PRIMARY KEY AUTOINCREMENT, "
+		"created TIMESTAMP NOT NULL, "
+		"updated TIMESTAMP NOT NULL, "
+		"name TEXT, "
+		"classmark1 NUMERIC, "
+		"classmark2 BLOB, "
+		"classmark3 BLOB, "
+		"imei NUMERIC UNIQUE NOT NULL"
+		")",
+	[SCHEMA_EQUIPMENT_WATCH] = "CREATE TABLE IF NOT EXISTS EquipmentWatch ("
+		"id INTEGER PRIMARY KEY AUTOINCREMENT, "
+		"created TIMESTAMP NOT NULL, "
+		"updated TIMESTAMP NOT NULL, "
+		"subscriber_id NUMERIC NOT NULL, "
+		"equipment_id NUMERIC NOT NULL, "
+		"UNIQUE (subscriber_id, equipment_id) "
+		")",
+	[SCHEMA_SMS] = "CREATE TABLE IF NOT EXISTS SMS ("
+		/* metadata, not part of sms */
+		"id INTEGER PRIMARY KEY AUTOINCREMENT, "
+		"created TIMESTAMP NOT NULL, "
+		"sent TIMESTAMP, "
+		"deliver_attempts INTEGER NOT NULL DEFAULT 0, "
+		/* data directly copied/derived from SMS */
+		"valid_until TIMESTAMP, "
+		"reply_path_req INTEGER NOT NULL, "
+		"status_rep_req INTEGER NOT NULL, "
+		"is_report INTEGER NOT NULL, "
+		"msg_ref INTEGER NOT NULL, "
+		"protocol_id INTEGER NOT NULL, "
+		"data_coding_scheme INTEGER NOT NULL, "
+		"ud_hdr_ind INTEGER NOT NULL, "
+		"src_addr TEXT NOT NULL, "
+		"src_ton INTEGER NOT NULL, "
+		"src_npi INTEGER NOT NULL, "
+		"dest_addr TEXT NOT NULL, "
+		"dest_ton INTEGER NOT NULL, "
+		"dest_npi INTEGER NOT NULL, "
+		"user_data BLOB, "	/* TP-UD */
+		/* additional data, interpreted from SMS */
+		"header BLOB, "		/* UD Header */
+		"text TEXT "		/* decoded UD after UDH */
+		")",
+	[SCHEMA_VLR] = "CREATE TABLE IF NOT EXISTS VLR ("
+		"id INTEGER PRIMARY KEY AUTOINCREMENT, "
+		"created TIMESTAMP NOT NULL, "
+		"updated TIMESTAMP NOT NULL, "
+		"subscriber_id NUMERIC UNIQUE NOT NULL, "
+		"last_bts NUMERIC NOT NULL "
+		")",
+	[SCHEMA_APDU] = "CREATE TABLE IF NOT EXISTS ApduBlobs ("
+		"id INTEGER PRIMARY KEY AUTOINCREMENT, "
+		"created TIMESTAMP NOT NULL, "
+		"apdu_id_flags INTEGER NOT NULL, "
+		"subscriber_id INTEGER NOT NULL, "
+		"apdu BLOB "
+		")",
+	[SCHEMA_COUNTERS] = "CREATE TABLE IF NOT EXISTS Counters ("
+		"id INTEGER PRIMARY KEY AUTOINCREMENT, "
+		"timestamp TIMESTAMP NOT NULL, "
+		"value INTEGER NOT NULL, "
+		"name TEXT NOT NULL "
+		")",
+	[SCHEMA_RATE] = "CREATE TABLE IF NOT EXISTS RateCounters ("
+		"id INTEGER PRIMARY KEY AUTOINCREMENT, "
+		"timestamp TIMESTAMP NOT NULL, "
+		"value INTEGER NOT NULL, "
+		"name TEXT NOT NULL, "
+		"idx INTEGER NOT NULL "
+		")",
+	[SCHEMA_AUTHKEY] = "CREATE TABLE IF NOT EXISTS AuthKeys ("
+		"subscriber_id INTEGER PRIMARY KEY, "
+		"algorithm_id INTEGER NOT NULL, "
+		"a3a8_ki BLOB "
+		")",
+	[SCHEMA_AUTHLAST] = "CREATE TABLE IF NOT EXISTS AuthLastTuples ("
+		"subscriber_id INTEGER PRIMARY KEY, "
+		"issued TIMESTAMP NOT NULL, "
+		"use_count INTEGER NOT NULL DEFAULT 0, "
+		"key_seq INTEGER NOT NULL, "
+		"rand BLOB NOT NULL, "
+		"sres BLOB NOT NULL, "
+		"kc BLOB NOT NULL "
+		")",
+};
+
+static inline int next_row(dbi_result result)
+{
+	if (!dbi_result_has_next_row(result))
+		return 0;
+	return dbi_result_next_row(result);
+}
+
+void db_error_func(dbi_conn conn, void *data)
+{
+	const char *msg;
+	dbi_conn_error(conn, &msg);
+	LOGP(DDB, LOGL_ERROR, "DBI: %s\n", msg);
+	osmo_log_backtrace(DDB, LOGL_ERROR);
+}
+
+static int update_db_revision_2(void)
+{
+	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;
+	}
+	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)
+{
+	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;
+}
+
+static int update_db_revision_3(void)
+{
+	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;
+	}
+	dbi_result_free(result);
+
+	/* Rename old SMS table to be able create a new one */
+	result = dbi_conn_query(conn, "ALTER TABLE SMS RENAME TO SMS_3");
+	if (!result) {
+		LOGP(DDB, LOGL_ERROR,
+		     "Failed to rename the old SMS table (upgrade from rev 3).\n");
+		goto rollback;
+	}
+	dbi_result_free(result);
+
+	/* Create new SMS table with all the bells and whistles! */
+	result = dbi_conn_query(conn, create_stmts[SCHEMA_SMS]);
+	if (!result) {
+		LOGP(DDB, LOGL_ERROR,
+		     "Failed to create a new SMS table (upgrade from rev 3).\n");
+		goto rollback;
+	}
+	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;
+}
+
+/* Just like v3, but there is a new message reference field for status reports,
+ * that is set to zero for existing entries since there is no way we can infer
+ * this.
+ */
+static struct gsm_sms *sms_from_result_v4(dbi_result result)
+{
+	struct gsm_sms *sms = sms_alloc();
+	const 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;
+	}
+	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;
+	}
+	dbi_result_free(result);
+
+	/* Cycle through old messages and convert them to the new format */
+	result = dbi_conn_query(conn, "SELECT * FROM SMS_4");
+	if (!result) {
+		LOGP(DDB, LOGL_ERROR,
+		     "Failed fetch messages from the old SMS table (upgrade from rev 4).\n");
+		goto rollback;
+	}
+	while (next_row(result)) {
+		sms = sms_from_result_v4(result);
+		if (db_sms_store(sms) != 0) {
+			LOGP(DDB, LOGL_ERROR, "Failed to store message to the new SMS table(upgrade from rev 4).\n");
+			sms_free(sms);
+			dbi_result_free(result);
+			goto rollback;
+		}
+		sms_free(sms);
+	}
+	dbi_result_free(result);
+
+	/* Remove the temporary table */
+	result = dbi_conn_query(conn, "DROP TABLE SMS_4");
+	if (!result) {
+		LOGP(DDB, LOGL_ERROR,
+		     "Failed to drop the old SMS table (upgrade from rev 4).\n");
+		goto rollback;
+	}
+	dbi_result_free(result);
+
+	/* We're done. Bump DB Meta revision to 4 */
+	result = dbi_conn_query(conn,
+				"UPDATE Meta "
+				"SET value = '5' "
+				"WHERE key = 'revision'");
+	if (!result) {
+		LOGP(DDB, LOGL_ERROR,
+		     "Failed to update DB schema revision (upgrade from rev 4).\n");
+		goto rollback;
+	}
+	dbi_result_free(result);
+
+	result = dbi_conn_query(conn, "COMMIT TRANSACTION");
+	if (!result) {
+		LOGP(DDB, LOGL_ERROR,
+			"Failed to commit the transaction (upgrade from rev 4)\n");
+		return -EINVAL;
+	} else {
+		dbi_result_free(result);
+	}
+
+	/* 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);
+
+	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)
+{
+	dbi_result result;
+	const char *rev_s;
+	int db_rev = 0;
+
+	/* Make a query */
+	result = dbi_conn_query(conn,
+		"SELECT value FROM Meta "
+		"WHERE key = 'revision'");
+
+	if (!result)
+		return -EINVAL;
+
+	if (!next_row(result)) {
+		dbi_result_free(result);
+		return -EINVAL;
+	}
+
+	/* Fetch the DB schema revision */
+	rev_s = dbi_result_get_string(result, "value");
+	if (!rev_s) {
+		dbi_result_free(result);
+		return -EINVAL;
+	}
+
+	if (!strcmp(rev_s, SCHEMA_REVISION)) {
+		/* Everything is fine */
+		dbi_result_free(result);
+		return 0;
+	}
+
+	db_rev = atoi(rev_s);
+	dbi_result_free(result);
+
+	/* Incremental migration waterfall */
+	switch (db_rev) {
+	case 2:
+		if (update_db_revision_2())
+			goto error;
+	/* fall through */
+	case 3:
+		if (update_db_revision_3())
+			goto error;
+	/* fall through */
+	case 4:
+		if (update_db_revision_4())
+			goto error;
+
+	/* The end of waterfall */
+	break;
+	default:
+		LOGP(DDB, LOGL_FATAL,
+			"Invalid database schema revision '%d'.\n", db_rev);
+		return -EINVAL;
+	}
+
+	return 0;
+
+error:
+	LOGP(DDB, LOGL_FATAL, "Failed to update database "
+		"from schema revision '%d'.\n", db_rev);
+	return -EINVAL;
+}
+
+static int db_configure(void)
+{
+	dbi_result result;
+
+	result = dbi_conn_query(conn,
+				"PRAGMA synchronous = FULL");
+	if (!result)
+		return -EINVAL;
+
+	dbi_result_free(result);
+	return 0;
+}
+
+int db_init(const char *name)
+{
+	dbi_initialize_r(NULL, &inst);
+
+	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;
+	}
+
+	dbi_conn_error_handler( conn, db_error_func, NULL );
+
+	/* MySQL
+	dbi_conn_set_option(conn, "host", "localhost");
+	dbi_conn_set_option(conn, "username", "your_name");
+	dbi_conn_set_option(conn, "password", "your_password");
+	dbi_conn_set_option(conn, "dbname", "your_dbname");
+	dbi_conn_set_option(conn, "encoding", "UTF-8");
+	*/
+
+	/* SqLite 3 */
+	db_basename = strdup(name);
+	db_dirname = strdup(name);
+	dbi_conn_set_option(conn, "sqlite3_dbdir", dirname(db_dirname));
+	dbi_conn_set_option(conn, "dbname", basename(db_basename));
+
+	if (dbi_conn_connect(conn) < 0)
+		goto out_err;
+
+	return 0;
+
+out_err:
+	free(db_dirname);
+	free(db_basename);
+	db_dirname = db_basename = NULL;
+	return -1;
+}
+
+
+int db_prepare(void)
+{
+	dbi_result result;
+	int i;
+
+	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);
+	}
+
+	if (check_db_revision() < 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);
+
+	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;
+	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);
+
+	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)
+		return -EIO;
+
+	dbi_result_free(result);
+	return 0;
+}
+
+static struct gsm_sms *sms_from_result(struct gsm_network *net, dbi_result result)
+{
+	struct gsm_sms *sms = sms_alloc();
+	const char *text, *daddr, *saddr;
+	const unsigned char *user_data;
+	time_t validity_timestamp;
+
+	if (!sms)
+		return NULL;
+
+	sms->id = dbi_result_get_ulonglong(result, "id");
+
+	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");
+	if (daddr)
+		OSMO_STRLCPY_ARRAY(sms->dst.addr, daddr);
+	sms->receiver = vlr_subscr_find_by_msisdn(net->vlr, sms->dst.addr);
+
+	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 (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);
+
+	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;
+	struct gsm_sms *sms;
+
+	result = dbi_conn_queryf(conn,
+		"SELECT * FROM SMS WHERE SMS.id = %llu", id);
+	if (!result)
+		return NULL;
+
+	if (!next_row(result)) {
+		dbi_result_free(result);
+		return NULL;
+	}
+
+	sms = sms_from_result(net, result);
+
+	dbi_result_free(result);
+
+	return sms;
+}
+
+struct gsm_sms *db_sms_get_next_unsent(struct gsm_network *net,
+				       unsigned long long min_sms_id,
+				       unsigned int max_failed)
+{
+	dbi_result result;
+	struct gsm_sms *sms;
+
+	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);
+
+	if (!result)
+		return NULL;
+
+	if (!next_row(result)) {
+		dbi_result_free(result);
+		return NULL;
+	}
+
+	sms = sms_from_result(net, result);
+
+	dbi_result_free(result);
+
+	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)
+{
+	struct gsm_network *net = vsub->vlr->user_ctx;
+	dbi_result result;
+	struct gsm_sms *sms;
+	char *q_msisdn;
+
+	if (!vsub->lu_complete)
+		return NULL;
+
+	/* A subscriber having no phone number cannot possibly receive SMS. */
+	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;
+
+	if (!next_row(result)) {
+		dbi_result_free(result);
+		return NULL;
+	}
+
+	sms = sms_from_result(net, result);
+
+	dbi_result_free(result);
+
+	return sms;
+}
+
+struct gsm_sms *db_sms_get_next_unsent_rr_msisdn(struct gsm_network *net,
+						 const char *last_msisdn,
+						 unsigned int max_failed)
+{
+	dbi_result result;
+	struct gsm_sms *sms;
+	char *q_last_msisdn;
+
+	dbi_conn_quote_string_copy(conn, last_msisdn, &q_last_msisdn);
+	result = dbi_conn_queryf(conn,
+		"SELECT * FROM SMS"
+		" WHERE sent IS NULL"
+		" AND dest_addr > %s"
+		" AND deliver_attempts <= %u"
+		" ORDER BY dest_addr, id LIMIT 1",
+		q_last_msisdn, max_failed);
+	free(q_last_msisdn);
+
+	if (!result)
+		return NULL;
+
+	if (!next_row(result)) {
+		dbi_result_free(result);
+		return NULL;
+	}
+
+	sms = sms_from_result(net, result);
+
+	dbi_result_free(result);
+
+	return sms;
+}
+
+/* mark a given SMS as delivered */
+int db_sms_mark_delivered(struct gsm_sms *sms)
+{
+	dbi_result result;
+
+	result = dbi_conn_queryf(conn,
+		"UPDATE SMS "
+		"SET sent = datetime('now') "
+		"WHERE id = %llu", sms->id);
+	if (!result) {
+		LOGP(DDB, LOGL_ERROR, "Failed to mark SMS %llu as sent.\n", sms->id);
+		return 1;
+	}
+
+	dbi_result_free(result);
+	return 0;
+}
+
+/* increase the number of attempted deliveries */
+int db_sms_inc_deliver_attempts(struct gsm_sms *sms)
+{
+	dbi_result result;
+
+	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);
+		return 1;
+	}
+
+	dbi_result_free(result);
+	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;
+	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);
+
+	if (!result) {
+		LOGP(DDB, LOGL_ERROR,
+		     "Failed to delete SMS for %s\n", msisdn);
+		return -1;
+	}
+	dbi_result_free(result);
+	return 0;
+}
+
+int db_sms_delete_sent_message_by_id(unsigned long long sms_id)
+{
+	dbi_result result;
+
+	result = dbi_conn_queryf(conn,
+			"DELETE FROM SMS WHERE id = %llu AND sent is NOT NULL",
+			 sms_id);
+	if (!result) {
+		LOGP(DDB, LOGL_ERROR, "Failed to delete SMS %llu.\n", sms_id);
+		return 1;
+	}
+
+	dbi_result_free(result);
+	return 0;
+}
+
+
+static int delete_expired_sms(unsigned long long sms_id, time_t created, time_t validity_timestamp)
+{
+	dbi_result result;
+	time_t now, min_created;
+
+	now = time(NULL);
+	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;
+
+	result = dbi_conn_queryf(conn, "DELETE FROM SMS WHERE id = %llu", sms_id);
+	if (!result) {
+		LOGP(DDB, LOGL_ERROR, "Failed to delete SMS %llu.\n", sms_id);
+		return -1;
+	}
+	dbi_result_free(result);
+	return 0;
+}
+
+int db_sms_delete_expired_message_by_id(unsigned long long sms_id)
+{
+	dbi_result result;
+	time_t created, validity_timestamp;
+
+	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);
+		return -1;
+	}
+
+	created = dbi_result_get_datetime(result, "created");
+	validity_timestamp = dbi_result_get_datetime(result, "valid_until");
+
+	dbi_result_free(result);
+	return delete_expired_sms(sms_id, created, 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;
+
+	if (next_row(result)) {
+		unsigned long long sms_id;
+		time_t created, 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);
+	}
+
+	dbi_result_free(result);
+}
+
+int db_store_counter(struct osmo_counter *ctr)
+{
+	dbi_result result;
+	char *q_name;
+
+	dbi_conn_quote_string_copy(conn, ctr->name, &q_name);
+
+	result = dbi_conn_queryf(conn,
+		"INSERT INTO Counters "
+		"(timestamp,name,value) VALUES "
+		"(datetime('now'),%s,%lu)", q_name, ctr->value);
+
+	free(q_name);
+
+	if (!result)
+		return -EIO;
+
+	dbi_result_free(result);
+	return 0;
+}
+
+static int db_store_rate_ctr(struct rate_ctr_group *ctrg, unsigned int num,
+			     char *q_prefix)
+{
+	dbi_result result;
+	char *q_name;
+
+	dbi_conn_quote_string_copy(conn, ctrg->desc->ctr_desc[num].name,
+				   &q_name);
+
+	result = dbi_conn_queryf(conn,
+		"Insert INTO RateCounters "
+		"(timestamp,name,idx,value) VALUES "
+		"(datetime('now'),%s.%s,%u,%"PRIu64")",
+		q_prefix, q_name, ctrg->idx, ctrg->ctr[num].current);
+
+	free(q_name);
+
+	if (!result)
+		return -EIO;
+
+	dbi_result_free(result);
+	return 0;
+}
+
+int db_store_rate_ctr_group(struct rate_ctr_group *ctrg)
+{
+	unsigned int i;
+	char *q_prefix;
+
+	dbi_conn_quote_string_copy(conn, ctrg->desc->group_name_prefix, &q_prefix);
+
+	for (i = 0; i < ctrg->desc->num_ctr; i++)
+		db_store_rate_ctr(ctrg, i, q_prefix);
+
+	free(q_prefix);
+
+	return 0;
+}
diff --git a/src/libmsc/gsm_04_08.c b/src/libmsc/gsm_04_08.c
new file mode 100644
index 0000000..d5cc212
--- /dev/null
+++ b/src/libmsc/gsm_04_08.c
@@ -0,0 +1,1884 @@
+/* GSM Mobile Radio Interface Layer 3 messages on the A-bis interface
+ * 3GPP TS 04.08 version 7.21.0 Release 1998 / ETSI TS 100 940 V7.21.0 */
+
+/* (C) 2008-2016 by Harald Welte <laforge@gnumonks.org>
+ * (C) 2008-2012 by Holger Hans Peter Freyther <zecke@selfish.org>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdbool.h>
+#include <errno.h>
+#include <time.h>
+#include <netinet/in.h>
+#include <regex.h>
+#include <sys/types.h>
+
+#include "bscconfig.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/signal.h>
+#include <osmocom/msc/transaction.h>
+#include <osmocom/msc/silent_call.h>
+#include <osmocom/msc/osmo_msc.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_ifaces.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/gsm/tlv.h>
+#include <osmocom/crypt/auth.h>
+#ifdef BUILD_IU
+#include <osmocom/ranap/iu_client.h>
+#endif
+
+#include <osmocom/msc/msc_ifaces.h>
+#include <osmocom/msc/a_iface.h>
+#include <osmocom/msc/msc_mgcp.h>
+
+#include <assert.h>
+
+
+void *tall_locop_ctx;
+void *tall_authciphop_ctx;
+
+static int gsm0408_loc_upd_acc(struct gsm_subscriber_connection *conn,
+			       uint32_t send_tmsi);
+
+/*! Send a simple GSM 04.08 message without any payload
+ * \param      conn      Active subscriber connection
+ * \param[in]  pdisc     Protocol discriminator
+ * \param[in]  msg_type  Message type
+ * \return     result of \ref gsm48_conn_sendmsg
+ */
+int gsm48_tx_simple(struct gsm_subscriber_connection *conn,
+		    uint8_t pdisc, uint8_t msg_type)
+{
+	struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 TX SIMPLE");
+	struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
+
+	gh->proto_discr = pdisc;
+	gh->msg_type = msg_type;
+
+	return gsm48_conn_sendmsg(msg, conn, NULL);
+}
+
+static bool classmark1_is_r99(const struct gsm48_classmark1 *cm1)
+{
+	return cm1->rev_lev >= 2;
+}
+
+static bool classmark2_is_r99(const uint8_t *cm2, uint8_t cm2_len)
+{
+	uint8_t rev_lev;
+	if (!cm2_len)
+		return false;
+	rev_lev = (cm2[0] >> 5) & 0x3;
+	return rev_lev >= 2;
+}
+
+static bool classmark_is_r99(struct gsm_classmark *cm)
+{
+	if (cm->classmark1_set)
+		return classmark1_is_r99(&cm->classmark1);
+	return classmark2_is_r99(cm->classmark2, cm->classmark2_len);
+}
+
+/* Determine if the given CLASSMARK (1/2/3) value permits a given A5/n cipher.
+ * Return 1 when the given A5/n is permitted, 0 when not, and negative if the respective MS CLASSMARK is
+ * not known, where the negative number indicates the classmark type: -2 means Classmark 2 is not
+ * available. */
+static int classmark_supports_a5(const struct gsm_classmark *cm, uint8_t a5)
+{
+	switch (a5) {
+	case 0:
+		/* all phones must implement A5/0, see 3GPP TS 43.020 4.9 */
+		return 1;
+	case 1:
+		/* 3GPP TS 43.020 4.9 requires A5/1 to be suppored by all phones and actually states:
+		 * "The network shall not provide service to an MS which indicates that it does not
+		 *  support the ciphering algorithm A5/1.".  However, let's be more tolerant based
+		 * on policy here */
+		/* See 3GPP TS 24.008 10.5.1.7 */
+		if (!cm->classmark1_set) {
+			DEBUGP(DMSC, "CLASSMARK 1 unknown, assuming MS supports A5/1\n");
+			return -1;
+		} else {
+			if (cm->classmark1.a5_1)
+				return 0;	/* Inverted logic for this bit! */
+			else
+				return 1;
+		}
+		break;
+	case 2:
+	case 3:
+		/* See 3GPP TS 24.008 10.5.1.6 */
+		if (cm->classmark2_len < 3) {
+			return -2;
+		} else {
+			if (cm->classmark2[2] & (1 << (a5-2)))
+				return 1;
+			else
+				return 0;
+		}
+		break;
+	case 4:
+	case 5:
+	case 6:
+	case 7:
+		/* See 3GPP TS 24.008 10.5.1.7 */
+		if (cm->classmark3_len < 1) {
+			return -3;
+		} else {
+			if (cm->classmark3[0] & (1 << (a5-4)))
+				return 1;
+			else
+				return 0;
+		}
+		break;
+	default:
+		return false;
+	}
+}
+
+int gsm48_conn_sendmsg(struct msgb *msg, struct gsm_subscriber_connection *conn, struct gsm_trans *trans)
+{
+	struct gsm48_hdr *gh = (struct gsm48_hdr *) msg->data;
+
+	/* if we get passed a transaction reference, do some common
+	 * work that the caller no longer has to do */
+	if (trans) {
+		gh->proto_discr = trans->protocol | (trans->transaction_id << 4);
+		OMSC_LINKID_CB(msg) = trans->dlci;
+	}
+
+	return msc_tx_dtap(conn, msg);
+}
+
+/* clear all transactions globally; used in case of MNCC socket disconnect */
+void gsm0408_clear_all_trans(struct gsm_network *net, int protocol)
+{
+	struct gsm_trans *trans, *temp;
+
+	LOGP(DCC, LOGL_NOTICE, "Clearing all currently active transactions!!!\n");
+
+	llist_for_each_entry_safe(trans, temp, &net->trans_list, entry) {
+		if (trans->protocol == protocol) {
+			trans->callref = 0;
+			trans_free(trans);
+		}
+	}
+}
+
+/* Chapter 9.2.14 : Send LOCATION UPDATING REJECT */
+static int gsm0408_loc_upd_rej(struct gsm_subscriber_connection *conn, uint8_t cause)
+{
+	struct msgb *msg;
+
+	msg = gsm48_create_loc_upd_rej(cause);
+	if (!msg) {
+		LOGP(DMM, LOGL_ERROR, "Failed to create msg for LOCATION UPDATING REJECT.\n");
+		return -1;
+	}
+
+	LOGP(DMM, LOGL_INFO, "Subscriber %s: LOCATION UPDATING REJECT\n",
+	     vlr_subscr_name(conn->vsub));
+
+	return gsm48_conn_sendmsg(msg, conn, NULL);
+}
+
+/* Chapter 9.2.13 : Send LOCATION UPDATE ACCEPT */
+static int gsm0408_loc_upd_acc(struct gsm_subscriber_connection *conn,
+			       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 osmo_location_area_id laid = {
+		.plmn = conn->network->plmn,
+		.lac = conn->lac,
+	};
+
+	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);
+
+	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, conn->vsub->imsi);
+		mid = msgb_put(msg, len);
+		memcpy(mid, mi, len);
+		DEBUGP(DMM, "-> %s LOCATION UPDATE ACCEPT\n",
+		       vlr_subscr_name(conn->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);
+		DEBUGP(DMM, "-> %s LOCATION UPDATE ACCEPT (TMSI = 0x%08x)\n",
+		       vlr_subscr_name(conn->vsub),
+		       send_tmsi);
+	}
+	/* TODO: Follow-on proceed */
+	/* TODO: CTS permission */
+	/* TODO: Equivalent PLMNs */
+	/* TODO: Emergency Number List */
+	/* TODO: Per-MS T3312 */
+
+
+	return gsm48_conn_sendmsg(msg, conn, NULL);
+}
+
+/* Transmit Chapter 9.2.10 Identity Request */
+static int mm_tx_identity_req(struct gsm_subscriber_connection *conn, uint8_t id_type)
+{
+	struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 ID REQ");
+	struct gsm48_hdr *gh;
+
+	gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh) + 1);
+	gh->proto_discr = GSM48_PDISC_MM;
+	gh->msg_type = GSM48_MT_MM_ID_REQ;
+	gh->data[0] = id_type;
+
+	return gsm48_conn_sendmsg(msg, conn, NULL);
+}
+
+/* Parse Chapter 9.2.11 Identity Response */
+static int mm_rx_id_resp(struct gsm_subscriber_connection *conn, struct msgb *msg)
+{
+	struct gsm48_hdr *gh = msgb_l3(msg);
+	uint8_t mi_type = gh->data[1] & GSM_MI_TYPE_MASK;
+	char mi_string[GSM48_MI_SIZE];
+
+	if (!conn->vsub) {
+		LOGP(DMM, LOGL_ERROR,
+		     "Rx MM Identity Response: invalid: no subscriber\n");
+		return -EINVAL;
+	}
+
+	gsm48_mi_to_string(mi_string, sizeof(mi_string), &gh->data[1], gh->data[0]);
+	DEBUGP(DMM, "IDENTITY RESPONSE: MI(%s)=%s\n",
+		gsm48_mi_type_name(mi_type), mi_string);
+
+	osmo_signal_dispatch(SS_SUBSCR, S_SUBSCR_IDENTITY, gh->data);
+
+	return vlr_subscr_rx_id_resp(conn->vsub, gh->data+1, gh->data[0]);
+}
+
+/* FIXME: to libosmogsm */
+static const struct value_string lupd_names[] = {
+	{ GSM48_LUPD_NORMAL, "NORMAL" },
+	{ GSM48_LUPD_PERIODIC, "PERIODIC" },
+	{ GSM48_LUPD_IMSI_ATT, "IMSI ATTACH" },
+	{ 0, NULL }
+};
+
+/* Chapter 9.2.15: Receive Location Updating Request.
+ * Keep this function non-static for direct invocation by unit tests. */
+int mm_rx_loc_upd_req(struct gsm_subscriber_connection *conn, struct msgb *msg)
+{
+	struct gsm_network *net = conn->network;
+	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;
+	struct osmo_location_area_id old_lai, new_lai;
+	struct osmo_fsm_inst *lu_fsm;
+	bool is_utran;
+
+ 	lu = (struct gsm48_loc_upd_req *) gh->data;
+
+	mi_type = lu->mi[0] & GSM_MI_TYPE_MASK;
+
+	gsm48_mi_to_string(mi_string, sizeof(mi_string), lu->mi, lu->mi_len);
+
+	if (msc_subscr_conn_is_establishing_auth_ciph(conn)) {
+		LOGP(DMM, LOGL_ERROR,
+		     "Cannot accept another LU, conn already busy establishing authenticity;"
+		     " extraneous LOCATION UPDATING REQUEST: MI(%s)=%s type=%s\n",
+		     gsm48_mi_type_name(mi_type), mi_string, get_value_string(lupd_names, lu->type));
+		return -EINVAL;
+	}
+
+	if (msc_subscr_conn_is_accepted(conn)) {
+		LOGP(DMM, LOGL_ERROR,
+		     "Cannot accept another LU, conn already established;"
+		     " extraneous LOCATION UPDATING REQUEST: MI(%s)=%s type=%s\n",
+		     gsm48_mi_type_name(mi_type), mi_string, get_value_string(lupd_names, lu->type));
+		return -EINVAL;
+	}
+
+	msc_subscr_conn_update_id(conn, COMPLETE_LAYER3_LU, mi_string);
+
+	DEBUGP(DMM, "LOCATION UPDATING REQUEST: MI(%s)=%s type=%s\n",
+	       gsm48_mi_type_name(mi_type), mi_string,
+	       get_value_string(lupd_names, lu->type));
+
+	osmo_signal_dispatch(SS_SUBSCR, S_SUBSCR_IDENTITY, &lu->mi_len);
+
+	switch (lu->type) {
+	case GSM48_LUPD_NORMAL:
+		rate_ctr_inc(&conn->network->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_NORMAL]);
+		vlr_lu_type = VLR_LU_TYPE_REGULAR;
+		break;
+	case GSM48_LUPD_IMSI_ATT:
+		rate_ctr_inc(&conn->network->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_ATTACH]);
+		vlr_lu_type = VLR_LU_TYPE_IMSI_ATTACH;
+		break;
+	case GSM48_LUPD_PERIODIC:
+		rate_ctr_inc(&conn->network->msc_ctrs->ctr[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.7.8 Device properties */
+	/* TODO: 10.5.1.15 MS network feature support */
+
+	switch (mi_type) {
+	case GSM_MI_TYPE_IMSI:
+		tmsi = GSM_RESERVED_TMSI;
+		imsi = mi_string;
+		break;
+	case GSM_MI_TYPE_TMSI:
+		tmsi = tmsi_from_string(mi_string);
+		imsi = NULL;
+		break;
+	default:
+		DEBUGPC(DMM, "unknown mobile identity type\n");
+		tmsi = GSM_RESERVED_TMSI;
+		imsi = NULL;
+		break;
+	}
+
+	gsm48_decode_lai2(&lu->lai, &old_lai);
+	new_lai.plmn = conn->network->plmn;
+	new_lai.lac = conn->lac;
+	DEBUGP(DMM, "LU/new-LAC: %u/%u\n", old_lai.lac, new_lai.lac);
+
+	is_utran = (conn->via_ran == RAN_UTRAN_IU);
+	lu_fsm = vlr_loc_update(conn->fi,
+				SUBSCR_CONN_E_ACCEPTED, SUBSCR_CONN_E_CN_CLOSE, NULL,
+				net->vlr, conn, vlr_lu_type, tmsi, imsi,
+				&old_lai, &new_lai,
+				is_utran || conn->network->authentication_required,
+				is_utran || conn->network->a5_encryption_mask > 0x01,
+				classmark1_is_r99(&lu->classmark1),
+				is_utran,
+				net->vlr->cfg.assign_tmsi);
+	if (!lu_fsm) {
+		DEBUGP(DRR, "%s: Can't start LU FSM\n", mi_string);
+		return 0;
+	}
+
+	/* 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? */
+
+	if (!conn->vsub || conn->vsub->lu_fsm != lu_fsm) {
+		LOGP(DRR, LOGL_ERROR,
+		     "%s: internal error during Location Updating attempt\n",
+		     mi_string);
+		return -EIO;
+	}
+
+	conn->vsub->classmark.classmark1 = lu->classmark1;
+	conn->vsub->classmark.classmark1_set = true;
+
+	msc_subscr_conn_complete_layer_3(conn);
+	return 0;
+}
+
+/* Turn int into semi-octet representation: 98 => 0x89 */
+/* FIXME: libosmocore/libosmogsm */
+static uint8_t bcdify(uint8_t value)
+{
+        uint8_t ret;
+
+        ret = value / 10;
+        ret |= (value % 10) << 4;
+
+        return ret;
+}
+
+
+/* Section 9.2.15a */
+int gsm48_tx_mm_info(struct gsm_subscriber_connection *conn)
+{
+	struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 MM INF");
+	struct gsm48_hdr *gh;
+	struct gsm_network *net = conn->network;
+	uint8_t *ptr8;
+	int name_len, name_pad;
+
+	time_t cur_t;
+	struct tm* gmt_time;
+	struct tm* local_time;
+	int tzunits;
+	int dst = 0;
+
+	gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
+	gh->proto_discr = GSM48_PDISC_MM;
+	gh->msg_type = GSM48_MT_MM_INFO;
+
+	if (net->name_long) {
+#if 0
+		name_len = strlen(net->name_long);
+		/* 10.5.3.5a */
+		ptr8 = msgb_put(msg, 3);
+		ptr8[0] = GSM48_IE_NAME_LONG;
+		ptr8[1] = name_len*2 +1;
+		ptr8[2] = 0x90; /* UCS2, no spare bits, no CI */
+
+		ptr16 = (uint16_t *) msgb_put(msg, name_len*2);
+		for (i = 0; i < name_len; i++)
+			ptr16[i] = htons(net->name_long[i]);
+
+		/* FIXME: Use Cell Broadcast, not UCS-2, since
+		 * UCS-2 is only supported by later revisions of the spec */
+#endif
+		name_len = (strlen(net->name_long)*7)/8;
+		name_pad = (8 - strlen(net->name_long)*7)%8;
+		if (name_pad > 0)
+			name_len++;
+		/* 10.5.3.5a */
+		ptr8 = msgb_put(msg, 3);
+		ptr8[0] = GSM48_IE_NAME_LONG;
+		ptr8[1] = name_len +1;
+		ptr8[2] = 0x80 | name_pad; /* Cell Broadcast DCS, no CI */
+
+		ptr8 = msgb_put(msg, name_len);
+		gsm_7bit_encode_n(ptr8, name_len, net->name_long, NULL);
+
+	}
+
+	if (net->name_short) {
+#if 0
+		name_len = strlen(net->name_short);
+		/* 10.5.3.5a */
+		ptr8 = (uint8_t *) msgb_put(msg, 3);
+		ptr8[0] = GSM48_IE_NAME_SHORT;
+		ptr8[1] = name_len*2 + 1;
+		ptr8[2] = 0x90; /* UCS2, no spare bits, no CI */
+
+		ptr16 = (uint16_t *) msgb_put(msg, name_len*2);
+		for (i = 0; i < name_len; i++)
+			ptr16[i] = htons(net->name_short[i]);
+#endif
+		name_len = (strlen(net->name_short)*7)/8;
+		name_pad = (8 - strlen(net->name_short)*7)%8;
+		if (name_pad > 0)
+			name_len++;
+		/* 10.5.3.5a */
+		ptr8 = (uint8_t *) msgb_put(msg, 3);
+		ptr8[0] = GSM48_IE_NAME_SHORT;
+		ptr8[1] = name_len +1;
+		ptr8[2] = 0x80 | name_pad; /* Cell Broadcast DCS, no CI */
+
+		ptr8 = msgb_put(msg, name_len);
+		gsm_7bit_encode_n(ptr8, name_len, net->name_short, NULL);
+
+	}
+
+	/* Section 10.5.3.9 */
+	cur_t = time(NULL);
+	gmt_time = gmtime(&cur_t);
+
+	ptr8 = msgb_put(msg, 8);
+	ptr8[0] = GSM48_IE_NET_TIME_TZ;
+	ptr8[1] = bcdify(gmt_time->tm_year % 100);
+	ptr8[2] = bcdify(gmt_time->tm_mon + 1);
+	ptr8[3] = bcdify(gmt_time->tm_mday);
+	ptr8[4] = bcdify(gmt_time->tm_hour);
+	ptr8[5] = bcdify(gmt_time->tm_min);
+	ptr8[6] = bcdify(gmt_time->tm_sec);
+
+	if (net->tz.override) {
+		/* Convert tz.hr and tz.mn to units */
+		if (net->tz.hr < 0) {
+			tzunits = ((net->tz.hr/-1)*4);
+			tzunits = tzunits + (net->tz.mn/15);
+			ptr8[7] = bcdify(tzunits);
+			/* Set negative time */
+			ptr8[7] |= 0x08;
+		}
+		else {
+			tzunits = net->tz.hr*4;
+			tzunits = tzunits + (net->tz.mn/15);
+			ptr8[7] = bcdify(tzunits);
+		}
+		/* Convert DST value */
+		if (net->tz.dst >= 0 && net->tz.dst <= 2)
+			dst = net->tz.dst;
+	}
+	else {
+		/* Need to get GSM offset and convert into 15 min units */
+		/* This probably breaks if gmtoff returns a value not evenly divisible by 15? */
+#ifdef HAVE_TM_GMTOFF_IN_TM
+		local_time = localtime(&cur_t);
+		tzunits = (local_time->tm_gmtoff/60)/15;
+#else
+		/* find timezone offset */
+		time_t utc;
+		double offsetFromUTC;
+		utc = mktime(gmt_time);
+		local_time = localtime(&cur_t);
+		offsetFromUTC = difftime(cur_t, utc);
+		if (local_time->tm_isdst)
+			offsetFromUTC += 3600.0;
+		tzunits = ((int)offsetFromUTC) / 60 / 15;
+#endif
+		if (tzunits < 0) {
+			tzunits = tzunits/-1;
+			ptr8[7] = bcdify(tzunits);
+			/* Flip it to negative */
+			ptr8[7] |= 0x08;
+		}
+		else
+			ptr8[7] = bcdify(tzunits);
+
+		/* Does not support DST +2 */
+		if (local_time->tm_isdst)
+			dst = 1;
+	}
+
+	if (dst) {
+		ptr8 = msgb_put(msg, 3);
+		ptr8[0] = GSM48_IE_NET_DST;
+		ptr8[1] = 1;
+		ptr8[2] = dst;
+	}
+
+	DEBUGP(DMM, "-> MM INFO\n");
+
+	return gsm48_conn_sendmsg(msg, conn, NULL);
+}
+
+/*! Send an Authentication Request to MS on the given subscriber connection
+ * according to 3GPP/ETSI TS 24.008, Section 9.2.2.
+ * \param[in] conn  Subscriber connection to send on.
+ * \param[in] rand  Random challenge token to send, must be 16 bytes long.
+ * \param[in] autn  r99: In case of UMTS mutual authentication, AUTN token to
+ * 	send; must be 16 bytes long, or pass NULL for plain GSM auth.
+ * \param[in] key_seq  auth tuple's sequence number.
+ */
+int gsm48_tx_mm_auth_req(struct gsm_subscriber_connection *conn, uint8_t *rand,
+			 uint8_t *autn, int key_seq)
+{
+	struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 AUTH REQ");
+	struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
+	struct gsm48_auth_req *ar = (struct gsm48_auth_req *) msgb_put(msg, sizeof(*ar));
+
+	DEBUGP(DMM, "-> AUTH REQ (rand = %s)\n", osmo_hexdump_nospc(rand, 16));
+	if (autn)
+		DEBUGP(DMM, "   AUTH REQ (autn = %s)\n", osmo_hexdump_nospc(autn, 16));
+
+	gh->proto_discr = GSM48_PDISC_MM;
+	gh->msg_type = GSM48_MT_MM_AUTH_REQ;
+
+	ar->key_seq = key_seq;
+
+	/* 16 bytes RAND parameters */
+	osmo_static_assert(sizeof(ar->rand) == 16, sizeof_auth_req_r99_rand);
+	if (rand)
+		memcpy(ar->rand, rand, 16);
+
+
+	/* 16 bytes AUTN */
+	if (autn)
+		msgb_tlv_put(msg, GSM48_IE_AUTN, 16, autn);
+
+	return gsm48_conn_sendmsg(msg, conn, NULL);
+}
+
+/* Section 9.2.1 */
+int gsm48_tx_mm_auth_rej(struct gsm_subscriber_connection *conn)
+{
+	DEBUGP(DMM, "-> AUTH REJECT\n");
+	return gsm48_tx_simple(conn, GSM48_PDISC_MM, GSM48_MT_MM_AUTH_REJ);
+}
+
+static int msc_vlr_tx_cm_serv_acc(void *msc_conn_ref);
+static int msc_vlr_tx_cm_serv_rej(void *msc_conn_ref, enum gsm48_reject_value result);
+
+static int cm_serv_reuse_conn(struct gsm_subscriber_connection *conn, const uint8_t *mi_lv)
+{
+	uint8_t mi_type;
+	char mi_string[GSM48_MI_SIZE];
+	uint32_t tmsi;
+
+	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) {
+	case GSM_MI_TYPE_IMSI:
+		if (vlr_subscr_matches_imsi(conn->vsub, mi_string))
+			goto accept_reuse;
+		break;
+	case GSM_MI_TYPE_TMSI:
+		tmsi = osmo_load32be(mi_lv+2);
+		if (vlr_subscr_matches_tmsi(conn->vsub, tmsi))
+			goto accept_reuse;
+		break;
+	case GSM_MI_TYPE_IMEI:
+		if (vlr_subscr_matches_imei(conn->vsub, mi_string))
+			goto accept_reuse;
+		break;
+	default:
+		break;
+	}
+
+	LOGP(DMM, LOGL_ERROR, "%s: CM Service Request with mismatching mobile identity: %s %s\n",
+	     vlr_subscr_name(conn->vsub), gsm48_mi_type_name(mi_type), mi_string);
+	msc_vlr_tx_cm_serv_rej(conn, GSM48_REJECT_ILLEGAL_MS);
+	return -EINVAL;
+
+accept_reuse:
+	DEBUGP(DMM, "%s: re-using already accepted connection\n",
+	       vlr_subscr_name(conn->vsub));
+
+	if (!conn->received_cm_service_request) {
+		conn->received_cm_service_request = true;
+		msc_subscr_conn_get(conn, MSC_CONN_USE_CM_SERVICE);
+	}
+	msc_subscr_conn_update_id(conn, conn->complete_layer3_type, mi_string);
+	return conn->network->vlr->ops.tx_cm_serv_acc(conn);
+}
+
+/*
+ * Handle CM Service Requests
+ * a) Verify that the packet is long enough to contain the information
+ *    we require otherwsie 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
+ * d) Set the subscriber on the conn and accept
+ *
+ * Keep this function non-static for direct invocation by unit tests.
+ */
+int gsm48_rx_mm_serv_req(struct gsm_subscriber_connection *conn, struct msgb *msg)
+{
+	struct gsm_network *net = conn->network;
+	uint8_t mi_type;
+	char mi_string[GSM48_MI_SIZE];
+
+	struct gsm48_hdr *gh = msgb_l3(msg);
+	struct gsm48_service_request *req =
+			(struct gsm48_service_request *)gh->data;
+	/* unfortunately in Phase1 the classmark2 length is variable */
+	uint8_t classmark2_len = gh->data[1];
+	uint8_t *classmark2 = gh->data+2;
+	uint8_t *mi_p = classmark2 + classmark2_len;
+	uint8_t mi_len = *mi_p;
+	uint8_t *mi = mi_p + 1;
+	struct osmo_location_area_id lai;
+	bool is_utran;
+
+	lai.plmn = conn->network->plmn;
+	lai.lac = conn->lac;
+
+	if (msg->data_len < sizeof(struct gsm48_service_request*)) {
+		LOGP(DMM, LOGL_ERROR, "<- CM SERVICE REQUEST wrong sized message\n");
+		return msc_gsm48_tx_mm_serv_rej(conn,
+						GSM48_REJECT_INCORRECT_MESSAGE);
+	}
+
+	if (msg->data_len < req->mi_len + 6) {
+		LOGP(DMM, LOGL_ERROR, "<- CM SERVICE REQUEST does not fit in packet\n");
+		return msc_gsm48_tx_mm_serv_rej(conn,
+						GSM48_REJECT_INCORRECT_MESSAGE);
+	}
+
+	gsm48_mi_to_string(mi_string, sizeof(mi_string), mi, mi_len);
+	mi_type = mi[0] & GSM_MI_TYPE_MASK;
+	DEBUGP(DMM, "<- CM SERVICE REQUEST serv_type=0x%02x MI(%s)=%s\n",
+	       req->cm_service_type, gsm48_mi_type_name(mi_type), mi_string);
+
+	switch (mi_type) {
+	case GSM_MI_TYPE_IMSI:
+	case GSM_MI_TYPE_TMSI:
+		/* continue below */
+		break;
+	case GSM_MI_TYPE_IMEI:
+		if (req->cm_service_type == GSM48_CMSERV_EMERGENCY) {
+			/* We don't do emergency calls by IMEI */
+			LOGP(DMM, LOGL_NOTICE, "<- CM SERVICE REQUEST(IMEI=%s) rejected\n", mi_string);
+			return msc_gsm48_tx_mm_serv_rej(conn, GSM48_REJECT_IMEI_NOT_ACCEPTED);
+		}
+		/* fall-through for non-emergency setup */
+	default:
+		DEBUGPC(DMM, "mi_type is not expected: %d\n", mi_type);
+		return msc_gsm48_tx_mm_serv_rej(conn,
+						GSM48_REJECT_INCORRECT_MESSAGE);
+	}
+
+	switch (req->cm_service_type) {
+	case GSM48_CMSERV_MO_CALL_PACKET:
+	case GSM48_CMSERV_EMERGENCY:
+	case GSM48_CMSERV_SMS:
+	case GSM48_CMSERV_SUP_SERV:
+		/* continue below */
+		break;
+	default:
+		return msc_gsm48_tx_mm_serv_rej(conn, GSM48_REJECT_SRV_OPT_NOT_SUPPORTED);
+	}
+
+	if (msc_subscr_conn_is_accepted(conn))
+		return cm_serv_reuse_conn(conn, mi_p);
+
+	if (msc_subscr_conn_is_establishing_auth_ciph(conn)) {
+		LOGP(DMM, LOGL_ERROR,
+		     "Cannot accept CM Service Request, conn already busy establishing authenticity\n");
+		msc_vlr_tx_cm_serv_rej(conn, GSM48_REJECT_CONGESTION);
+		return -EINVAL;
+		/* or should we accept and note down the service request anyway? */
+	}
+
+	msc_subscr_conn_update_id(conn, COMPLETE_LAYER3_CM_SERVICE_REQ, mi_string);
+
+	osmo_signal_dispatch(SS_SUBSCR, S_SUBSCR_IDENTITY, mi_p);
+
+	is_utran = (conn->via_ran == RAN_UTRAN_IU);
+	vlr_proc_acc_req(conn->fi,
+			 SUBSCR_CONN_E_ACCEPTED, SUBSCR_CONN_E_CN_CLOSE, NULL,
+			 net->vlr, conn,
+			 VLR_PR_ARQ_T_CM_SERV_REQ, mi-1, &lai,
+			 is_utran || conn->network->authentication_required,
+			 is_utran || conn->network->a5_encryption_mask > 0x01,
+			 classmark2_is_r99(classmark2, 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? */
+	if (!conn->vsub) {
+		LOGP(DRR, LOGL_ERROR, "%s: subscriber not allowed to do a CM Service Request\n",
+		     mi_string);
+		return -EIO;
+	}
+
+	memcpy(conn->vsub->classmark.classmark2, classmark2, classmark2_len);
+	conn->vsub->classmark.classmark2_len = classmark2_len;
+
+	msc_subscr_conn_complete_layer_3(conn);
+	return 0;
+}
+
+/* Receive a CM Re-establish Request */
+static int gsm48_rx_cm_reest_req(struct gsm_subscriber_connection *conn, struct msgb *msg)
+{
+	uint8_t mi_type;
+	char mi_string[GSM48_MI_SIZE];
+	struct gsm48_hdr *gh = msgb_l3(msg);
+
+	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);
+
+	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);
+
+	/* we don't support CM call re-establishment */
+	return msc_gsm48_tx_mm_serv_rej(conn, GSM48_REJECT_SRV_OPT_NOT_SUPPORTED);
+}
+
+static int gsm48_rx_mm_imsi_detach_ind(struct gsm_subscriber_connection *conn, struct msgb *msg)
+{
+	struct gsm_network *network = conn->network;
+	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 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);
+
+	rate_ctr_inc(&network->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_DETACH]);
+
+	switch (mi_type) {
+	case GSM_MI_TYPE_TMSI:
+		vsub = vlr_subscr_find_by_tmsi(network->vlr,
+					       tmsi_from_string(mi_string));
+		break;
+	case GSM_MI_TYPE_IMSI:
+		vsub = vlr_subscr_find_by_imsi(network->vlr, mi_string);
+		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);
+		break;
+	default:
+		LOGP(DMM, LOGL_ERROR, "MI(%s)=%s: unknown mobile identity type\n",
+		     gsm48_mi_type_name(mi_type), mi_string);
+		break;
+	}
+
+	if (!vsub) {
+		LOGP(DMM, LOGL_ERROR, "IMSI DETACH for unknown subscriber MI(%s)=%s\n",
+		     gsm48_mi_type_name(mi_type), mi_string);
+	} else {
+		LOGP(DMM, LOGL_INFO, "IMSI DETACH for %s\n", vlr_subscr_name(vsub));
+
+		if (vsub->cs.is_paging)
+			subscr_paging_cancel(vsub, GSM_PAGING_EXPIRED);
+
+		/* We already got Classmark 1 during Location Updating ... but well, ok */
+		vsub->classmark.classmark1 = idi->classmark1;
+
+		vlr_subscr_rx_imsi_detach(vsub);
+		osmo_signal_dispatch(SS_SUBSCR, S_SUBSCR_DETACHED, vsub);
+		vlr_subscr_put(vsub);
+	}
+
+	msc_subscr_conn_close(conn, 0);
+	return 0;
+}
+
+static int gsm48_rx_mm_status(struct msgb *msg)
+{
+	struct gsm48_hdr *gh = msgb_l3(msg);
+
+	DEBUGP(DMM, "MM STATUS (reject cause 0x%02x)\n", gh->data[0]);
+
+	return 0;
+}
+
+static int parse_gsm_auth_resp(uint8_t *res, uint8_t *res_len,
+			       struct gsm_subscriber_connection *conn,
+			       struct msgb *msg)
+{
+	struct gsm48_hdr *gh = msgb_l3(msg);
+	struct gsm48_auth_resp *ar = (struct gsm48_auth_resp*) gh->data;
+
+	if (msgb_l3len(msg) < sizeof(*gh) + sizeof(*ar)) {
+		LOGP(DMM, LOGL_ERROR,
+		     "%s: MM AUTHENTICATION RESPONSE:"
+		     " l3 length invalid: %u\n",
+		     vlr_subscr_name(conn->vsub), msgb_l3len(msg));
+		return -EINVAL;
+	}
+
+	*res_len = sizeof(ar->sres);
+	memcpy(res, ar->sres, sizeof(ar->sres));
+	return 0;
+}
+
+static int parse_umts_auth_resp(uint8_t *res, uint8_t *res_len,
+				struct gsm_subscriber_connection *conn,
+				struct msgb *msg)
+{
+	struct gsm48_hdr *gh;
+	uint8_t *data;
+	uint8_t iei;
+	uint8_t ie_len;
+	unsigned int data_len;
+
+	/* First parse the GSM part */
+	if (parse_gsm_auth_resp(res, res_len, conn, msg))
+		return -EINVAL;
+	OSMO_ASSERT(*res_len == 4);
+
+	/* Then add the extended res part */
+	gh = msgb_l3(msg);
+	data = gh->data + sizeof(struct gsm48_auth_resp);
+	data_len = msgb_l3len(msg) - (data - (uint8_t*)msgb_l3(msg));
+
+	if (data_len < 3) {
+		LOGP(DMM, LOGL_ERROR,
+		     "%s: MM AUTHENTICATION RESPONSE:"
+		     " l3 length invalid: %u\n",
+		     vlr_subscr_name(conn->vsub), msgb_l3len(msg));
+		return -EINVAL;
+	}
+
+	iei = data[0];
+	ie_len = data[1];
+	if (iei != GSM48_IE_AUTH_RES_EXT) {
+		LOGP(DMM, LOGL_ERROR,
+		     "%s: MM R99 AUTHENTICATION RESPONSE:"
+		     " expected IEI 0x%02x, got 0x%02x\n",
+		     vlr_subscr_name(conn->vsub),
+		     GSM48_IE_AUTH_RES_EXT, iei);
+		return -EINVAL;
+	}
+
+	if (ie_len > 12) {
+		LOGP(DMM, LOGL_ERROR,
+		     "%s: MM R99 AUTHENTICATION RESPONSE:"
+		     " extended Auth Resp IE 0x%02x is too large: %u bytes\n",
+		     vlr_subscr_name(conn->vsub), GSM48_IE_AUTH_RES_EXT, ie_len);
+		return -EINVAL;
+	}
+
+	*res_len += ie_len;
+	memcpy(res + 4, &data[2], ie_len);
+	return 0;
+}
+
+/* Chapter 9.2.3: Authentication Response */
+static int gsm48_rx_mm_auth_resp(struct gsm_subscriber_connection *conn, struct msgb *msg)
+{
+	uint8_t res[16];
+	uint8_t res_len;
+	int rc;
+	bool is_umts;
+
+	if (!conn->vsub) {
+		LOGP(DMM, LOGL_ERROR,
+		     "MM AUTHENTICATION RESPONSE: invalid: no subscriber\n");
+		msc_subscr_conn_close(conn, GSM_CAUSE_AUTH_FAILED);
+		return -EINVAL;
+	}
+
+	is_umts = (msgb_l3len(msg) > sizeof(struct gsm48_hdr) + sizeof(struct gsm48_auth_resp));
+
+	if (is_umts)
+		rc = parse_umts_auth_resp(res, &res_len, conn, msg);
+	else
+		rc = parse_gsm_auth_resp(res, &res_len, conn, msg);
+
+	if (rc) {
+		LOGP(DMM, LOGL_ERROR,
+		     "%s: MM AUTHENTICATION RESPONSE: invalid: parsing %s AKA Auth Response"
+		     " failed with rc=%d; dispatching zero length SRES/RES to trigger failure\n",
+		     vlr_subscr_name(conn->vsub), is_umts ? "UMTS" : "GSM", rc);
+		memset(res, 0, sizeof(res));
+		res_len = 0;
+	}
+
+	DEBUGP(DMM, "%s: MM %s AUTHENTICATION RESPONSE (%s = %s)\n",
+	       vlr_subscr_name(conn->vsub),
+	       is_umts ? "UMTS" : "GSM", is_umts ? "res" : "sres",
+	       osmo_hexdump_nospc(res, res_len));
+
+	return vlr_subscr_rx_auth_resp(conn->vsub, classmark_is_r99(&conn->vsub->classmark),
+				       conn->via_ran == RAN_UTRAN_IU,
+				       res, res_len);
+}
+
+static int gsm48_rx_mm_auth_fail(struct gsm_subscriber_connection *conn, struct msgb *msg)
+{
+	struct gsm48_hdr *gh = msgb_l3(msg);
+	uint8_t cause;
+	uint8_t auts_tag;
+	uint8_t auts_len;
+	uint8_t *auts;
+
+	if (!conn->vsub) {
+		LOGP(DMM, LOGL_ERROR,
+		     "MM R99 AUTHENTICATION FAILURE: invalid: no subscriber\n");
+		msc_subscr_conn_close(conn, GSM_CAUSE_AUTH_FAILED);
+		return -EINVAL;
+	}
+
+	if (msgb_l3len(msg) < sizeof(*gh) + 1) {
+		LOGP(DMM, LOGL_ERROR,
+		     "%s: MM R99 AUTHENTICATION FAILURE:"
+		     " l3 length invalid: %u\n",
+		     vlr_subscr_name(conn->vsub), msgb_l3len(msg));
+		msc_subscr_conn_close(conn, GSM_CAUSE_AUTH_FAILED);
+		return -EINVAL;
+	}
+
+	cause = gh->data[0];
+
+	if (cause != GSM48_REJECT_SYNCH_FAILURE) {
+		LOGP(DMM, LOGL_INFO,
+		     "%s: MM R99 AUTHENTICATION FAILURE: cause 0x%0x\n",
+		     vlr_subscr_name(conn->vsub), cause);
+		vlr_subscr_rx_auth_fail(conn->vsub, NULL);
+		return 0;
+	}
+
+	/* This is a Synch Failure procedure, which should pass an AUTS to
+	 * resynchronize the sequence nr with the HLR. Expecting exactly one
+	 * TLV with 14 bytes of AUTS. */
+
+	if (msgb_l3len(msg) < sizeof(*gh) + 1 + 2) {
+		LOGP(DMM, LOGL_INFO,
+		     "%s: MM R99 AUTHENTICATION FAILURE:"
+		     " invalid Synch Failure: missing AUTS IE\n",
+		     vlr_subscr_name(conn->vsub));
+		msc_subscr_conn_close(conn, GSM_CAUSE_AUTH_FAILED);
+		return -EINVAL;
+	}
+
+	auts_tag = gh->data[1];
+	auts_len = gh->data[2];
+	auts = &gh->data[3];
+
+	if (auts_tag != GSM48_IE_AUTS
+	    || auts_len != 14) {
+		LOGP(DMM, LOGL_INFO,
+		     "%s: MM R99 AUTHENTICATION FAILURE:"
+		     " invalid Synch Failure:"
+		     " expected AUTS IE 0x%02x of 14 bytes,"
+		     " got IE 0x%02x of %u bytes\n",
+		     vlr_subscr_name(conn->vsub),
+		     GSM48_IE_AUTS, auts_tag, auts_len);
+		msc_subscr_conn_close(conn, GSM_CAUSE_AUTH_FAILED);
+		return -EINVAL;
+	}
+
+	if (msgb_l3len(msg) < sizeof(*gh) + 1 + 2 + auts_len) {
+		LOGP(DMM, LOGL_INFO,
+		     "%s: MM R99 AUTHENTICATION FAILURE:"
+		     " invalid Synch Failure msg: message truncated (%u)\n",
+		     vlr_subscr_name(conn->vsub), msgb_l3len(msg));
+		msc_subscr_conn_close(conn, GSM_CAUSE_AUTH_FAILED);
+		return -EINVAL;
+	}
+
+	/* We have an AUTS IE with exactly 14 bytes of AUTS and the msgb is
+	 * large enough. */
+
+	DEBUGP(DMM, "%s: MM R99 AUTHENTICATION SYNCH (AUTS = %s)\n",
+	       vlr_subscr_name(conn->vsub), osmo_hexdump_nospc(auts, 14));
+
+	return vlr_subscr_rx_auth_fail(conn->vsub, auts);
+}
+
+static int gsm48_rx_mm_tmsi_reall_compl(struct gsm_subscriber_connection *conn)
+{
+	DEBUGP(DMM, "TMSI Reallocation Completed. Subscriber: %s\n",
+	       vlr_subscr_name(conn->vsub));
+	if (!conn->vsub) {
+		LOGP(DMM, LOGL_ERROR,
+		     "Rx MM TMSI Reallocation Complete: invalid: no subscriber\n");
+		return -EINVAL;
+	}
+	return vlr_subscr_rx_tmsi_reall_compl(conn->vsub);
+}
+
+/* Receive a GSM 04.08 Mobility Management (MM) message */
+static int gsm0408_rcv_mm(struct gsm_subscriber_connection *conn, struct msgb *msg)
+{
+	struct gsm48_hdr *gh = msgb_l3(msg);
+	int rc = 0;
+
+	switch (gsm48_hdr_msg_type(gh)) {
+	case GSM48_MT_MM_LOC_UPD_REQUEST:
+		rc = mm_rx_loc_upd_req(conn, msg);
+		break;
+	case GSM48_MT_MM_ID_RESP:
+		rc = mm_rx_id_resp(conn, msg);
+		break;
+	case GSM48_MT_MM_CM_SERV_REQ:
+		rc = gsm48_rx_mm_serv_req(conn, msg);
+		break;
+	case GSM48_MT_MM_STATUS:
+		rc = gsm48_rx_mm_status(msg);
+		break;
+	case GSM48_MT_MM_TMSI_REALL_COMPL:
+		rc = gsm48_rx_mm_tmsi_reall_compl(conn);
+		break;
+	case GSM48_MT_MM_IMSI_DETACH_IND:
+		rc = gsm48_rx_mm_imsi_detach_ind(conn, msg);
+		break;
+	case GSM48_MT_MM_CM_REEST_REQ:
+		rc = gsm48_rx_cm_reest_req(conn, msg);
+		break;
+	case GSM48_MT_MM_AUTH_RESP:
+		rc = gsm48_rx_mm_auth_resp(conn, msg);
+		break;
+	case GSM48_MT_MM_AUTH_FAIL:
+		rc = gsm48_rx_mm_auth_fail(conn, msg);
+		break;
+	default:
+		LOGP(DMM, LOGL_NOTICE, "Unknown GSM 04.08 MM msg type 0x%02x\n",
+			gh->msg_type);
+		break;
+	}
+
+	return rc;
+}
+
+/* Receive a PAGING RESPONSE message from the MS */
+static int gsm48_rx_rr_pag_resp(struct gsm_subscriber_connection *conn, struct msgb *msg)
+{
+	struct gsm_network *net = conn->network;
+	struct gsm48_hdr *gh = msgb_l3(msg);
+	struct gsm48_pag_resp *resp;
+	uint8_t classmark2_len = gh->data[1];
+	uint8_t *classmark2 = gh->data+2;
+	uint8_t *mi_lv = classmark2 + classmark2_len;
+	uint8_t mi_type;
+	char mi_string[GSM48_MI_SIZE];
+	struct osmo_location_area_id lai;
+	bool is_utran;
+
+	lai.plmn = conn->network->plmn;
+	lai.lac = conn->lac;
+
+	resp = (struct gsm48_pag_resp *) &gh->data[0];
+
+	if (gsm48_paging_extract_mi(resp, msgb_l3len(msg) - sizeof(*gh), mi_string, &mi_type) <= 0) {
+		LOGP(DRR, LOGL_ERROR, "PAGING RESPONSE: invalid Mobile Identity\n");
+		return -EINVAL;
+	}
+
+	if (msc_subscr_conn_is_establishing_auth_ciph(conn)) {
+		LOGP(DMM, LOGL_ERROR,
+		     "Ignoring Paging Response, conn already busy establishing authenticity\n");
+		return 0;
+	}
+
+	if (msc_subscr_conn_is_accepted(conn)) {
+		LOGP(DMM, LOGL_ERROR, "Ignoring Paging Response, conn already established\n");
+		return 0;
+	}
+
+	DEBUGP(DRR, "PAGING RESPONSE: MI(%s)=%s\n", gsm48_mi_type_name(mi_type), mi_string);
+
+	msc_subscr_conn_update_id(conn, COMPLETE_LAYER3_PAGING_RESP, mi_string);
+
+	is_utran = (conn->via_ran == RAN_UTRAN_IU);
+	vlr_proc_acc_req(conn->fi,
+			 SUBSCR_CONN_E_ACCEPTED, SUBSCR_CONN_E_CN_CLOSE, NULL,
+			 net->vlr, conn,
+			 VLR_PR_ARQ_T_PAGING_RESP, mi_lv, &lai,
+			 is_utran || conn->network->authentication_required,
+			 is_utran || conn->network->a5_encryption_mask > 0x01,
+			 classmark2_is_r99(classmark2, 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? */
+	if (!conn->vsub) {
+		LOGP(DRR, LOGL_ERROR, "%s: subscriber not allowed to do a Paging Response\n",
+		     mi_string);
+		return -EIO;
+	}
+
+	memcpy(conn->vsub->classmark.classmark2, classmark2, classmark2_len);
+	conn->vsub->classmark.classmark2_len = classmark2_len;
+
+	msc_subscr_conn_complete_layer_3(conn);
+	return 0;
+}
+
+static int gsm48_rx_rr_app_info(struct gsm_subscriber_connection *conn, struct msgb *msg)
+{
+	struct gsm48_hdr *gh = msgb_l3(msg);
+	uint8_t apdu_id_flags;
+	uint8_t apdu_len;
+	uint8_t *apdu_data;
+
+	apdu_id_flags = gh->data[0];
+	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));
+
+	/* we're not using the app info blob anywhere, so ignore. */
+#if 0
+	return db_apdu_blob_store(conn->subscr, apdu_id_flags, apdu_len, apdu_data);
+#else
+	return 0;
+#endif
+}
+
+/* Receive a GSM 04.08 Radio Resource (RR) message */
+static int gsm0408_rcv_rr(struct gsm_subscriber_connection *conn, struct msgb *msg)
+{
+	struct gsm48_hdr *gh = msgb_l3(msg);
+	int rc = 0;
+
+	switch (gh->msg_type) {
+	case GSM48_MT_RR_PAG_RESP:
+		rc = gsm48_rx_rr_pag_resp(conn, msg);
+		break;
+	case GSM48_MT_RR_APP_INFO:
+		rc = gsm48_rx_rr_app_info(conn, msg);
+		break;
+	default:
+		LOGP(DRR, LOGL_NOTICE, "MSC: Unimplemented %s GSM 04.08 RR "
+		     "message\n", gsm48_rr_msg_name(gh->msg_type));
+		break;
+	}
+
+	return rc;
+}
+
+int gsm48_send_rr_app_info(struct gsm_subscriber_connection *conn, uint8_t apdu_id,
+			   uint8_t apdu_len, const uint8_t *apdu)
+{
+	struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 APP INF");
+	struct gsm48_hdr *gh;
+
+	DEBUGP(DRR, "TX APPLICATION INFO id=0x%02x, len=%u\n",
+		apdu_id, apdu_len);
+
+	gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh) + 2 + apdu_len);
+	gh->proto_discr = GSM48_PDISC_RR;
+	gh->msg_type = GSM48_MT_RR_APP_INFO;
+	gh->data[0] = apdu_id;
+	gh->data[1] = apdu_len;
+	memcpy(gh->data+2, apdu, apdu_len);
+
+	return gsm48_conn_sendmsg(msg, conn, NULL);
+}
+
+static bool msg_is_initially_permitted(const struct gsm48_hdr *hdr)
+{
+	uint8_t pdisc = gsm48_hdr_pdisc(hdr);
+	uint8_t msg_type = gsm48_hdr_msg_type(hdr);
+
+	switch (pdisc) {
+	case GSM48_PDISC_MM:
+		switch (msg_type) {
+		case GSM48_MT_MM_LOC_UPD_REQUEST:
+		case GSM48_MT_MM_CM_SERV_REQ:
+		case GSM48_MT_MM_CM_REEST_REQ:
+		case GSM48_MT_MM_AUTH_RESP:
+		case GSM48_MT_MM_AUTH_FAIL:
+		case GSM48_MT_MM_ID_RESP:
+		case GSM48_MT_MM_TMSI_REALL_COMPL:
+		case GSM48_MT_MM_IMSI_DETACH_IND:
+			return true;
+		default:
+			break;
+		}
+		break;
+	case GSM48_PDISC_RR:
+		switch (msg_type) {
+		case GSM48_MT_RR_CIPH_M_COMPL:
+		case GSM48_MT_RR_PAG_RESP:
+			return true;
+		default:
+			break;
+		}
+		break;
+	default:
+		break;
+	}
+
+	return false;
+}
+
+void cm_service_request_concludes(struct gsm_subscriber_connection *conn,
+				  struct msgb *msg)
+{
+
+	/* If a CM Service Request was received before, this is the request the
+	 * conn was opened for. No need to wait for further messages. */
+
+	if (!conn->received_cm_service_request)
+		return;
+
+	if (log_check_level(DMM, LOGL_DEBUG)) {
+		struct gsm48_hdr *gh = msgb_l3(msg);
+		uint8_t pdisc = gsm48_hdr_pdisc(gh);
+		uint8_t msg_type = gsm48_hdr_msg_type(gh);
+
+		DEBUGP(DMM, "%s: rx msg %s:"
+		       " received_cm_service_request changes to false\n",
+		       vlr_subscr_name(conn->vsub),
+		       gsm48_pdisc_msgtype_name(pdisc, msg_type));
+	}
+	conn->received_cm_service_request = false;
+	msc_subscr_conn_put(conn, MSC_CONN_USE_CM_SERVICE);
+}
+
+/* TS 24.007 11.2.3.2.3 Message Type Octet / Duplicate Detection */
+int gsm0407_pdisc_ctr_bin(uint8_t pdisc)
+{
+	switch (pdisc) {
+	case GSM48_PDISC_MM:
+	case GSM48_PDISC_CC:
+	case GSM48_PDISC_NC_SS:
+		return 0;
+	case GSM48_PDISC_GROUP_CC:
+		return 1;
+	case GSM48_PDISC_BCAST_CC:
+		return 2;
+	case GSM48_PDISC_LOC:
+		return 3;
+	default:
+		return -1;
+	}
+}
+
+/* extract the N(SD) and return the modulo value for a R98 message */
+static uint8_t gsm0407_determine_nsd_ret_modulo_r99(uint8_t pdisc, uint8_t msg_type, uint8_t *n_sd)
+{
+	switch (pdisc) {
+	case GSM48_PDISC_MM:
+	case GSM48_PDISC_CC:
+	case GSM48_PDISC_NC_SS:
+		*n_sd = (msg_type >> 6) & 0x3;
+		return 4;
+	case GSM48_PDISC_GROUP_CC:
+	case GSM48_PDISC_BCAST_CC:
+	case GSM48_PDISC_LOC:
+		*n_sd = (msg_type >> 6) & 0x1;
+		return 2;
+	default:
+		/* no sequence number, we cannot detect dups */
+		return 0;
+	}
+}
+
+/* extract the N(SD) and return the modulo value for a R99 message */
+static uint8_t gsm0407_determine_nsd_ret_modulo_r98(uint8_t pdisc, uint8_t msg_type, uint8_t *n_sd)
+{
+	switch (pdisc) {
+	case GSM48_PDISC_MM:
+	case GSM48_PDISC_CC:
+	case GSM48_PDISC_NC_SS:
+	case GSM48_PDISC_GROUP_CC:
+	case GSM48_PDISC_BCAST_CC:
+	case GSM48_PDISC_LOC:
+		*n_sd = (msg_type >> 6) & 0x1;
+		return 2;
+	default:
+		/* no sequence number, we cannot detect dups */
+		return 0;
+	}
+}
+
+/* TS 24.007 11.2.3.2 Message Type Octet / Duplicate Detection */
+static bool gsm0407_is_duplicate(struct gsm_subscriber_connection *conn, struct msgb *msg)
+{
+	struct gsm48_hdr *gh;
+	uint8_t pdisc;
+	uint8_t n_sd, modulo;
+	int bin;
+
+	gh = msgb_l3(msg);
+	pdisc = gsm48_hdr_pdisc(gh);
+
+	if (conn->vsub && classmark_is_r99(&conn->vsub->classmark)) {
+		modulo = gsm0407_determine_nsd_ret_modulo_r99(pdisc, gh->msg_type, &n_sd);
+	} else { /* pre R99 */
+		modulo = gsm0407_determine_nsd_ret_modulo_r98(pdisc, gh->msg_type, &n_sd);
+	}
+	if (modulo == 0)
+		return false;
+	bin = gsm0407_pdisc_ctr_bin(pdisc);
+	if (bin < 0)
+		return false;
+
+	OSMO_ASSERT(bin < ARRAY_SIZE(conn->n_sd_next));
+	if (n_sd != conn->n_sd_next[bin]) {
+		/* not what we expected: duplicate */
+		return true;
+	} else {
+		/* as expected: no dup; update expected counter for next message */
+		conn->n_sd_next[bin] = (n_sd + 1) % modulo;
+		return false;
+	}
+}
+
+extern int gsm0408_rcv_cc(struct gsm_subscriber_connection *conn, struct msgb *msg);
+
+/* Main entry point for GSM 04.08/44.008 Layer 3 data (e.g. from the BSC). */
+int gsm0408_dispatch(struct gsm_subscriber_connection *conn, struct msgb *msg)
+{
+	struct gsm48_hdr *gh;
+	uint8_t pdisc;
+	int rc = 0;
+
+	OSMO_ASSERT(msg->l3h);
+	OSMO_ASSERT(conn);
+	OSMO_ASSERT(msg);
+
+	gh = msgb_l3(msg);
+	pdisc = gsm48_hdr_pdisc(gh);
+
+	if (gsm0407_is_duplicate(conn, msg)) {
+		LOGP(DRLL, LOGL_NOTICE, "%s: Discarding duplicate L3 message\n",
+			(conn && conn->vsub) ? vlr_subscr_name(conn->vsub) : "UNKNOWN");
+		return 0;
+	}
+
+	LOGP(DRLL, LOGL_DEBUG, "Dispatching 04.08 message %s (0x%x:0x%x)\n",
+	     gsm48_pdisc_msgtype_name(pdisc, gsm48_hdr_msg_type(gh)),
+	     pdisc, gsm48_hdr_msg_type(gh));
+
+	if (!msc_subscr_conn_is_accepted(conn)
+	    && !msg_is_initially_permitted(gh)) {
+		LOGP(DRLL, LOGL_ERROR,
+		     "subscr %s: Message not permitted for initial conn: %s\n",
+		     vlr_subscr_name(conn->vsub),
+		     gsm48_pdisc_msgtype_name(pdisc, gsm48_hdr_msg_type(gh)));
+		return -EACCES;
+	}
+
+	if (conn->vsub && conn->vsub->cs.attached_via_ran != conn->via_ran) {
+		LOGP(DMM, LOGL_ERROR,
+		     "%s: Illegal situation: RAN type mismatch:"
+		     " attached via %s, received message via %s\n",
+		     vlr_subscr_name(conn->vsub),
+		     ran_type_name(conn->vsub->cs.attached_via_ran),
+		     ran_type_name(conn->via_ran));
+		return -EACCES;
+	}
+
+#if 0
+	if (silent_call_reroute(conn, msg))
+		return silent_call_rx(conn, msg);
+#endif
+
+	switch (pdisc) {
+	case GSM48_PDISC_CC:
+		rc = gsm0408_rcv_cc(conn, msg);
+		break;
+	case GSM48_PDISC_MM:
+		rc = gsm0408_rcv_mm(conn, msg);
+		break;
+	case GSM48_PDISC_RR:
+		rc = gsm0408_rcv_rr(conn, msg);
+		break;
+	case GSM48_PDISC_SMS:
+		rc = gsm0411_rcv_sms(conn, msg);
+		break;
+	case GSM48_PDISC_MM_GPRS:
+	case GSM48_PDISC_SM_GPRS:
+		LOGP(DRLL, LOGL_NOTICE, "Unimplemented "
+			"GSM 04.08 discriminator 0x%02x\n", pdisc);
+		rc = -ENOTSUP;
+		break;
+	case GSM48_PDISC_NC_SS:
+		rc = gsm0911_rcv_nc_ss(conn, msg);
+		break;
+	case GSM48_PDISC_TEST:
+		rc = gsm0414_rcv_test(conn, msg);
+		break;
+	default:
+		LOGP(DRLL, LOGL_NOTICE, "Unknown "
+			"GSM 04.08 discriminator 0x%02x\n", pdisc);
+		rc = -EINVAL;
+		break;
+	}
+
+	return rc;
+}
+
+/***********************************************************************
+ * VLR integration
+ ***********************************************************************/
+
+/* VLR asks us to send an authentication request */
+static int msc_vlr_tx_auth_req(void *msc_conn_ref, struct gsm_auth_tuple *at,
+			       bool send_autn)
+{
+	struct gsm_subscriber_connection *conn = msc_conn_ref;
+	return gsm48_tx_mm_auth_req(conn, at->vec.rand,
+				    send_autn? at->vec.autn : NULL,
+				    at->key_seq);
+}
+
+/* VLR asks us to send an authentication reject */
+static int msc_vlr_tx_auth_rej(void *msc_conn_ref)
+{
+	struct gsm_subscriber_connection *conn = msc_conn_ref;
+	return gsm48_tx_mm_auth_rej(conn);
+}
+
+/* VLR asks us to transmit an Identity Request of given type */
+static int msc_vlr_tx_id_req(void *msc_conn_ref, uint8_t mi_type)
+{
+	struct gsm_subscriber_connection *conn = msc_conn_ref;
+	return mm_tx_identity_req(conn, mi_type);
+}
+
+/* VLR asks us to transmit a Location Update Accept */
+static int msc_vlr_tx_lu_acc(void *msc_conn_ref, uint32_t send_tmsi)
+{
+	struct gsm_subscriber_connection *conn = msc_conn_ref;
+	return gsm0408_loc_upd_acc(conn, send_tmsi);
+}
+
+/* VLR asks us to transmit a Location Update Reject */
+static int msc_vlr_tx_lu_rej(void *msc_conn_ref, enum gsm48_reject_value cause)
+{
+	struct gsm_subscriber_connection *conn = msc_conn_ref;
+	return gsm0408_loc_upd_rej(conn, cause);
+}
+
+/* VLR asks us to transmit a CM Service Accept */
+static int msc_vlr_tx_cm_serv_acc(void *msc_conn_ref)
+{
+	struct gsm_subscriber_connection *conn = msc_conn_ref;
+	return msc_gsm48_tx_mm_serv_ack(conn);
+}
+
+static int msc_vlr_tx_common_id(void *msc_conn_ref)
+{
+	struct gsm_subscriber_connection *conn = msc_conn_ref;
+	return msc_tx_common_id(conn);
+}
+
+/* VLR asks us to transmit MM info. */
+static int msc_vlr_tx_mm_info(void *msc_conn_ref)
+{
+	struct gsm_subscriber_connection *conn = msc_conn_ref;
+	if (!conn->network->send_mm_info)
+		return 0;
+	return gsm48_tx_mm_info(conn);
+}
+
+/* VLR asks us to transmit a CM Service Reject */
+static int msc_vlr_tx_cm_serv_rej(void *msc_conn_ref, enum gsm48_reject_value cause)
+{
+	struct gsm_subscriber_connection *conn = msc_conn_ref;
+	int rc;
+
+	rc = msc_gsm48_tx_mm_serv_rej(conn, cause);
+
+	if (conn->received_cm_service_request) {
+		conn->received_cm_service_request = false;
+		msc_subscr_conn_put(conn, MSC_CONN_USE_CM_SERVICE);
+	}
+
+	return rc;
+}
+
+/* For msc_vlr_set_ciph_mode() */
+osmo_static_assert(sizeof(((struct gsm0808_encrypt_info*)0)->key) >= sizeof(((struct osmo_auth_vector*)0)->kc),
+		   gsm0808_encrypt_info_key_fits_osmo_auth_vec_kc);
+
+int msc_geran_set_cipher_mode(struct gsm_subscriber_connection *conn, bool umts_aka, bool retrieve_imeisv)
+{
+	struct gsm_network *net = conn->network;
+	struct gsm0808_encrypt_info ei;
+	int i, j = 0;
+	int request_classmark = 0;
+	int request_classmark_for_a5_n = 0;
+	struct gsm_auth_tuple *tuple = conn->vsub->last_tuple;
+
+	if (!conn || !conn->vsub || !conn->vsub->last_tuple) {
+		/* This should really never happen, because we checked this in msc_vlr_set_ciph_mode()
+		 * already. */
+		LOGP(DMM, LOGL_ERROR, "Internal error: missing state during Ciphering Mode Command\n");
+		return -EINVAL;
+	}
+
+	for (i = 0; i < 8; i++) {
+		int supported;
+
+		/* A5/n permitted by osmo-msc.cfg? */
+		if (!(net->a5_encryption_mask & (1 << i)))
+			continue;
+
+		/* A5/n supported by MS? */
+		supported = classmark_supports_a5(&conn->vsub->classmark, i);
+		if (supported == 1) {
+			ei.perm_algo[j++] = vlr_ciph_to_gsm0808_alg_id(i);
+			/* A higher A5/n is supported, so no need to request a Classmark
+			 * for support of a lesser A5/n. */
+			request_classmark = 0;
+		} else if (supported < 0) {
+			request_classmark = -supported;
+			request_classmark_for_a5_n = i;
+		}
+	}
+	ei.perm_algo_len = j;
+
+	if (request_classmark) {
+		/* The highest A5/n as from osmo-msc.cfg might be available, but we are
+		 * still missing the Classmark information for that from the MS. First
+		 * ask for that. */
+		LOGP(DMM, LOGL_DEBUG, "%s: to determine whether A5/%d is supported,"
+		     " first ask for a Classmark Update to obtain Classmark %d\n",
+		     vlr_subscr_name(conn->vsub), request_classmark_for_a5_n,
+		     request_classmark);
+
+		return msc_classmark_request_then_cipher_mode_cmd(conn, umts_aka, retrieve_imeisv);
+	}
+
+	if (ei.perm_algo_len == 0) {
+		LOGP(DMM, LOGL_ERROR, "%s: cannot start ciphering, no intersection "
+		     "between MSC-configured and MS-supported A5 algorithms\n",
+		     vlr_subscr_name(conn->vsub));
+		return -ENOTSUP;
+	}
+
+	DEBUGP(DMM, "-> CIPHER MODE COMMAND %s\n", vlr_subscr_name(conn->vsub));
+
+	tuple = conn->vsub->last_tuple;
+
+	/* In case of UMTS AKA, the Kc for ciphering must be derived from the 3G auth
+	 * tokens.  tuple->vec.kc was calculated from the GSM algorithm and is not
+	 * necessarily a match for the UMTS AKA tokens. */
+	if (umts_aka)
+		osmo_auth_c3(ei.key, tuple->vec.ck, tuple->vec.ik);
+	else
+		memcpy(ei.key, tuple->vec.kc, sizeof(tuple->vec.kc));
+	ei.key_len = sizeof(tuple->vec.kc);
+
+	return a_iface_tx_cipher_mode(conn, &ei, retrieve_imeisv);
+}
+
+/* VLR asks us to start using ciphering.
+ * (Keep non-static to allow regression testing on this function.) */
+int msc_vlr_set_ciph_mode(void *msc_conn_ref,
+			  bool umts_aka,
+			  bool retrieve_imeisv)
+{
+	struct gsm_subscriber_connection *conn = msc_conn_ref;
+	struct vlr_subscr *vsub;
+	struct gsm_auth_tuple *tuple;
+
+	if (!conn || !conn->vsub) {
+		LOGP(DMM, LOGL_ERROR, "Cannot send Ciphering Mode Command to"
+		     " NULL conn/subscriber");
+		return -EINVAL;
+	}
+
+	vsub = conn->vsub;
+	tuple = vsub->last_tuple;
+
+	if (!tuple) {
+		LOGP(DMM, LOGL_ERROR, "subscr %s: Cannot send Ciphering Mode"
+		     " Command: no auth tuple available\n",
+		     vlr_subscr_name(vsub));
+		return -EINVAL;
+	}
+
+	switch (conn->via_ran) {
+	case RAN_GERAN_A:
+		return msc_geran_set_cipher_mode(conn, umts_aka, retrieve_imeisv);
+
+	case RAN_UTRAN_IU:
+#ifdef BUILD_IU
+		DEBUGP(DMM, "-> SECURITY MODE CONTROL %s\n",
+		       vlr_subscr_name(conn->vsub));
+		return ranap_iu_tx_sec_mode_cmd(conn->iu.ue_ctx, &tuple->vec, 0, 1);
+#else
+		LOGP(DMM, LOGL_ERROR, "Cannot send Security Mode Control over RAN_UTRAN_IU,"
+		     " built without Iu support\n");
+		return -ENOTSUP;
+#endif
+
+	default:
+		break;
+	}
+	LOGP(DMM, LOGL_ERROR,
+	     "%s: cannot start ciphering, unknown RAN type %d\n",
+	     vlr_subscr_name(conn->vsub), conn->via_ran);
+	return -ENOTSUP;
+}
+
+void msc_rx_sec_mode_compl(struct gsm_subscriber_connection *conn)
+{
+	struct vlr_ciph_result vlr_res = {};
+
+	if (!conn || !conn->vsub) {
+		LOGP(DMM, LOGL_ERROR,
+		     "Rx Security Mode Complete for invalid conn\n");
+		return;
+	}
+
+	DEBUGP(DMM, "<- SECURITY MODE COMPLETE %s\n",
+	       vlr_subscr_name(conn->vsub));
+
+	vlr_res.cause = VLR_CIPH_COMPL;
+	vlr_subscr_rx_ciph_res(conn->vsub, &vlr_res);
+}
+
+/* VLR informs us that the subscriber data has somehow been modified */
+static void msc_vlr_subscr_update(struct vlr_subscr *subscr)
+{
+	LOGVSUBP(LOGL_NOTICE, subscr, "VLR: update for IMSI=%s (MSISDN=%s, used=%d)\n",
+		 subscr->imsi, subscr->msisdn, subscr->use_count);
+}
+
+static void update_classmark(const struct gsm_classmark *src, struct gsm_classmark *dst)
+{
+	if (src->classmark1_set) {
+		dst->classmark1 = src->classmark1;
+		dst->classmark1_set = true;
+	}
+	if (src->classmark2_len) {
+		dst->classmark2_len = src->classmark2_len;
+		memcpy(dst->classmark2, src->classmark2, sizeof(dst->classmark2));
+	}
+	if (src->classmark3_len) {
+		dst->classmark3_len = src->classmark3_len;
+		memcpy(dst->classmark3, src->classmark3, sizeof(dst->classmark3));
+	}
+}
+
+/* VLR informs us that the subscriber has been associated with a conn */
+static void msc_vlr_subscr_assoc(void *msc_conn_ref,
+				 struct vlr_subscr *vsub)
+{
+	struct gsm_subscriber_connection *conn = msc_conn_ref;
+	OSMO_ASSERT(vsub);
+	OSMO_ASSERT(!conn->vsub);
+	conn->vsub = vlr_subscr_get(vsub);
+	OSMO_ASSERT(conn->vsub);
+	conn->vsub->cs.attached_via_ran = conn->via_ran;
+
+	/* In case we have already received Classmark Information before the VLR Subscriber was
+	 * associated with the conn: merge the new Classmark into vsub->classmark. Don't overwrite valid
+	 * vsub->classmark with unset classmark, though. */
+	update_classmark(&conn->temporary_classmark, &conn->vsub->classmark);
+}
+
+static int msc_vlr_route_gsup_msg(struct vlr_subscr *vsub,
+				  struct osmo_gsup_message *gsup_msg)
+{
+	switch (gsup_msg->message_type) {
+	/* GSM 09.11 code implementing SS/USSD */
+	case OSMO_GSUP_MSGT_PROC_SS_REQUEST:
+	case OSMO_GSUP_MSGT_PROC_SS_RESULT:
+	case OSMO_GSUP_MSGT_PROC_SS_ERROR:
+		DEBUGP(DMSC, "Routed to GSM 09.11 SS/USSD handler\n");
+		return gsm0911_gsup_handler(vsub, gsup_msg);
+
+	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;
+	}
+}
+
+/* operations that we need to implement for libvlr */
+static const struct vlr_ops msc_vlr_ops = {
+	.tx_auth_req = msc_vlr_tx_auth_req,
+	.tx_auth_rej = msc_vlr_tx_auth_rej,
+	.tx_id_req = msc_vlr_tx_id_req,
+	.tx_lu_acc = msc_vlr_tx_lu_acc,
+	.tx_lu_rej = msc_vlr_tx_lu_rej,
+	.tx_cm_serv_acc = msc_vlr_tx_cm_serv_acc,
+	.tx_cm_serv_rej = msc_vlr_tx_cm_serv_rej,
+	.set_ciph_mode = msc_vlr_set_ciph_mode,
+	.tx_common_id = msc_vlr_tx_common_id,
+	.tx_mm_info = msc_vlr_tx_mm_info,
+	.subscr_update = msc_vlr_subscr_update,
+	.subscr_assoc = msc_vlr_subscr_assoc,
+	.forward_gsup_msg = msc_vlr_route_gsup_msg,
+};
+
+/* Allocate net->vlr so that the VTY may configure the VLR's data structures */
+int msc_vlr_alloc(struct gsm_network *net)
+{
+	net->vlr = vlr_alloc(net, &msc_vlr_ops);
+	if (!net->vlr)
+		return -ENOMEM;
+	net->vlr->user_ctx = net;
+	return 0;
+}
+
+/* Launch the VLR, i.e. its GSUP connection */
+int msc_vlr_start(struct gsm_network *net)
+{
+	OSMO_ASSERT(net->vlr);
+	return vlr_start("MSC", net->vlr, net->gsup_server_addr_str,
+			 net->gsup_server_port);
+}
+
+struct msgb *gsm48_create_mm_serv_rej(enum gsm48_reject_value value)
+{
+	struct msgb *msg;
+	struct gsm48_hdr *gh;
+
+	msg = gsm48_msgb_alloc_name("GSM 04.08 SERV REJ");
+	if (!msg)
+		return NULL;
+
+	gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh) + 1);
+	gh->proto_discr = GSM48_PDISC_MM;
+	gh->msg_type = GSM48_MT_MM_CM_SERV_REJ;
+	gh->data[0] = value;
+
+	return msg;
+}
+
+struct msgb *gsm48_create_loc_upd_rej(uint8_t cause)
+{
+	struct gsm48_hdr *gh;
+	struct msgb *msg;
+
+	msg = gsm48_msgb_alloc_name("GSM 04.08 LOC UPD REJ");
+	if (!msg)
+		return NULL;
+
+	gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh) + 1);
+	gh->proto_discr = GSM48_PDISC_MM;
+	gh->msg_type = GSM48_MT_MM_LOC_UPD_REJECT;
+	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
new file mode 100644
index 0000000..f9888d7
--- /dev/null
+++ b/src/libmsc/gsm_04_08_cc.c
@@ -0,0 +1,2186 @@
+/* GSM Mobile Radio Interface Layer 3 Call Control */
+
+/* (C) 2008-2016 by Harald Welte <laforge@gnumonks.org>
+ * (C) 2008-2012 by Holger Hans Peter Freyther <zecke@selfish.org>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdbool.h>
+#include <errno.h>
+#include <time.h>
+#include <netinet/in.h>
+#include <regex.h>
+#include <sys/types.h>
+
+#include "bscconfig.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/signal.h>
+#include <osmocom/msc/transaction.h>
+#include <osmocom/msc/silent_call.h>
+#include <osmocom/msc/osmo_msc.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_ifaces.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/gsm/tlv.h>
+#include <osmocom/crypt/auth.h>
+#ifdef BUILD_IU
+#include <osmocom/ranap/iu_client.h>
+#endif
+
+#include <osmocom/msc/msc_ifaces.h>
+#include <osmocom/msc/a_iface.h>
+#include <osmocom/msc/msc_mgcp.h>
+
+#include <assert.h>
+
+static uint32_t new_callref = 0x80000001;
+
+static void gsm48_cc_guard_timeout(void *arg)
+{
+	struct gsm_trans *trans = arg;
+	DEBUGP(DCC, "(sub %s) guard timeout expired\n",
+	       vlr_subscr_msisdn_or_name(trans->vsub));
+	trans_free(trans);
+	return;
+}
+
+static void gsm48_stop_guard_timer(struct gsm_trans *trans)
+{
+	if (osmo_timer_pending(&trans->cc.timer_guard)) {
+		DEBUGP(DCC, "(sub %s) stopping pending guard timer\n",
+		       vlr_subscr_msisdn_or_name(trans->vsub));
+		osmo_timer_del(&trans->cc.timer_guard);
+	}
+}
+
+static void gsm48_start_guard_timer(struct gsm_trans *trans)
+{
+	/* NOTE: The purpose of this timer is to prevent the cc state machine
+	 * from hanging in cases where mncc, gsm48 or both become unresponsive
+	 * for some reason. The timer is started initially with the setup from
+	 * the gsm48 side and then re-started with every incoming mncc message.
+	 * Once the mncc state reaches its active state the timer is stopped.
+	 * So if the cc state machine does not show any activity for an
+	 * extended amount of time during call setup or teardown the guard
+	 * timer will time out and hard-clear the connection. */
+	if (osmo_timer_pending(&trans->cc.timer_guard))
+		gsm48_stop_guard_timer(trans);
+	DEBUGP(DCC, "(sub %s) starting guard timer with %d seconds\n",
+	       vlr_subscr_msisdn_or_name(trans->vsub),
+	       trans->net->mncc_guard_timeout);
+	osmo_timer_setup(&trans->cc.timer_guard, gsm48_cc_guard_timeout, trans);
+	osmo_timer_schedule(&trans->cc.timer_guard,
+			    trans->net->mncc_guard_timeout, 0);
+}
+
+/* Call Control */
+
+void cc_tx_to_mncc(struct gsm_network *net, struct msgb *msg)
+{
+	net->mncc_recv(net, msg);
+}
+
+int gsm48_cc_tx_notify_ss(struct gsm_trans *trans, const char *message)
+{
+	struct gsm48_hdr *gh;
+	struct msgb *ss_notify;
+
+	ss_notify = gsm0480_create_notifySS(message);
+	if (!ss_notify)
+		return -1;
+
+	gsm0480_wrap_invoke(ss_notify, GSM0480_OP_CODE_NOTIFY_SS, 0);
+	uint8_t *data = msgb_push(ss_notify, 1);
+	data[0] = ss_notify->len - 1;
+	gh = (struct gsm48_hdr *) msgb_push(ss_notify, sizeof(*gh));
+	gh->msg_type = GSM48_MT_CC_FACILITY;
+	return gsm48_conn_sendmsg(ss_notify, trans->conn, trans);
+}
+
+/* FIXME: this count_statistics is a state machine behaviour. we should convert
+ * the complete call control into a state machine. Afterwards we can move this
+ * code into state transitions.
+ */
+static void count_statistics(struct gsm_trans *trans, int new_state)
+{
+	int old_state = trans->cc.state;
+	struct rate_ctr_group *msc = trans->net->msc_ctrs;
+
+	if (old_state == new_state)
+		return;
+
+	/* 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]);
+		break;
+	}
+
+	/* state outgoing */
+	switch (old_state) {
+	case GSM_CSTATE_ACTIVE:
+		osmo_counter_dec(trans->net->active_calls);
+		if (new_state == GSM_CSTATE_DISCONNECT_REQ ||
+				new_state == GSM_CSTATE_DISCONNECT_IND)
+			rate_ctr_inc(&msc->ctr[MSC_CTR_CALL_COMPLETE]);
+		else
+			rate_ctr_inc(&msc->ctr[MSC_CTR_CALL_INCOMPLETE]);
+		break;
+	}
+}
+
+/* The entire call control code is written in accordance with Figure 7.10c
+ * for 'very early assignment', i.e. we allocate a TCH/F during IMMEDIATE
+ * ASSIGN, then first use that TCH/F for signalling and later MODE MODIFY
+ * it for voice */
+
+static void new_cc_state(struct gsm_trans *trans, int state)
+{
+	if (state > 31 || state < 0)
+		return;
+
+	DEBUGP(DCC, "(ti %02x sub %s) new state %s -> %s\n",
+	       trans->transaction_id,
+	       vlr_subscr_name(trans->vsub),
+	       gsm48_cc_state_name(trans->cc.state),
+	       gsm48_cc_state_name(state));
+
+	count_statistics(trans, state);
+	trans->cc.state = state;
+
+	/* Stop the guard timer when a call reaches the active state */
+	if (state == GSM_CSTATE_ACTIVE)
+		gsm48_stop_guard_timer(trans);
+}
+
+static int gsm48_cc_tx_status(struct gsm_trans *trans, void *arg)
+{
+	struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 CC STATUS");
+	struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
+	uint8_t *cause, *call_state;
+
+	gh->msg_type = GSM48_MT_CC_STATUS;
+
+	cause = msgb_put(msg, 3);
+	cause[0] = 2;
+	cause[1] = GSM48_CAUSE_CS_GSM | GSM48_CAUSE_LOC_USER;
+	cause[2] = 0x80 | 30;	/* response to status inquiry */
+
+	call_state = msgb_put(msg, 1);
+	call_state[0] = 0xc0 | 0x00;
+
+	return gsm48_conn_sendmsg(msg, trans->conn, trans);
+}
+
+static void gsm48_stop_cc_timer(struct gsm_trans *trans)
+{
+	if (osmo_timer_pending(&trans->cc.timer)) {
+		DEBUGP(DCC, "stopping pending timer T%x\n", trans->cc.Tcurrent);
+		osmo_timer_del(&trans->cc.timer);
+		trans->cc.Tcurrent = 0;
+	}
+}
+
+static int mncc_recvmsg(struct gsm_network *net, struct gsm_trans *trans,
+			int msg_type, struct gsm_mncc *mncc)
+{
+	struct msgb *msg;
+	unsigned char *data;
+
+	DEBUGP(DMNCC, "transmit message %s\n", get_mncc_name(msg_type));
+
+#if BEFORE_MSCSPLIT
+	/* Re-enable this log output once we can obtain this information via
+	 * A-interface, see OS#2391. */
+	if (trans)
+		if (trans->conn && trans->conn->lchan)
+			DEBUGP(DCC, "(bts %d trx %d ts %d ti %x sub %s) "
+				"Sending '%s' to MNCC.\n",
+				trans->conn->lchan->ts->trx->bts->nr,
+				trans->conn->lchan->ts->trx->nr,
+				trans->conn->lchan->ts->nr, trans->transaction_id,
+				vlr_subscr_msisdn_or_name(trans->vsub),
+				get_mncc_name(msg_type));
+		else
+			DEBUGP(DCC, "(bts - trx - ts - ti -- sub %s) "
+				"Sending '%s' to MNCC.\n",
+				vlr_subscr_msisdn_or_name(trans->vsub),
+				get_mncc_name(msg_type));
+	else
+		DEBUGP(DCC, "(bts - trx - ts - ti -- sub -) "
+			"Sending '%s' to MNCC.\n", get_mncc_name(msg_type));
+#else
+	DEBUGP(DCC, "Sending '%s' to MNCC.\n", get_mncc_name(msg_type));
+#endif
+
+	mncc->msg_type = msg_type;
+
+	msg = msgb_alloc(sizeof(struct gsm_mncc), "MNCC");
+	if (!msg)
+		return -ENOMEM;
+
+	data = msgb_put(msg, sizeof(struct gsm_mncc));
+	memcpy(data, mncc, sizeof(struct gsm_mncc));
+
+	cc_tx_to_mncc(net, msg);
+
+	return 0;
+}
+
+int mncc_release_ind(struct gsm_network *net, struct gsm_trans *trans,
+		     uint32_t callref, int location, int value)
+{
+	struct gsm_mncc rel;
+
+	memset(&rel, 0, sizeof(rel));
+	rel.callref = callref;
+	mncc_set_cause(&rel, location, value);
+	if (trans && trans->cc.state == GSM_CSTATE_RELEASE_REQ)
+		return mncc_recvmsg(net, trans, MNCC_REL_CNF, &rel);
+	return mncc_recvmsg(net, trans, MNCC_REL_IND, &rel);
+}
+
+/* Call Control Specific transaction release.
+ * gets called by trans_free, DO NOT CALL YOURSELF! */
+void _gsm48_cc_trans_free(struct gsm_trans *trans)
+{
+	gsm48_stop_cc_timer(trans);
+
+	/* Initiate the teardown of the related connections on the MGW */
+	msc_mgcp_call_release(trans);
+
+	/* send release to L4, if callref still exists */
+	if (trans->callref) {
+		/* 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);
+	}
+	if (trans->cc.state != GSM_CSTATE_NULL)
+		new_cc_state(trans, GSM_CSTATE_NULL);
+
+	gsm48_stop_guard_timer(trans);
+}
+
+static int gsm48_cc_tx_setup(struct gsm_trans *trans, void *arg);
+
+/* call-back from paging the B-end of the connection */
+static int setup_trig_pag_evt(unsigned int hooknum, unsigned int event,
+			      struct msgb *msg, void *_conn, void *_transt)
+{
+	struct gsm_subscriber_connection *conn = _conn;
+	struct gsm_trans *transt = _transt;
+	enum gsm_paging_event paging_event = event;
+
+	OSMO_ASSERT(!transt->conn);
+
+	switch (paging_event) {
+	case GSM_PAGING_SUCCEEDED:
+		DEBUGP(DCC, "Paging subscr %s succeeded!\n",
+		       vlr_subscr_msisdn_or_name(transt->vsub));
+		OSMO_ASSERT(conn);
+		/* Assign conn */
+		transt->conn = msc_subscr_conn_get(conn, MSC_CONN_USE_TRANS_CC);
+		transt->paging_request = NULL;
+		/* send SETUP request to called party */
+		gsm48_cc_tx_setup(transt, &transt->cc.msg);
+		break;
+	case GSM_PAGING_EXPIRED:
+	case GSM_PAGING_BUSY:
+		DEBUGP(DCC, "Paging subscr %s %s!\n",
+		       vlr_subscr_msisdn_or_name(transt->vsub),
+		       paging_event == GSM_PAGING_EXPIRED ? "expired" : "busy");
+		/* Temporarily out of order */
+		mncc_release_ind(transt->net, transt,
+				 transt->callref,
+				 GSM48_CAUSE_LOC_PRN_S_LU,
+				 GSM48_CC_CAUSE_DEST_OOO);
+		transt->callref = 0;
+		transt->paging_request = NULL;
+		trans_free(transt);
+		break;
+	}
+
+	return 0;
+}
+
+/* bridge channels of two transactions */
+static int tch_bridge(struct gsm_network *net, 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]);
+	int rc;
+
+	if (!trans1 || !trans2)
+		return -EIO;
+
+	if (!trans1->conn || !trans2->conn)
+		return -EIO;
+
+	/* Which subscriber do we want to track trans1 or trans2? */
+	log_set_context(LOG_CTX_VLR_SUBSCR, trans1->vsub);
+
+	/* This call briding mechanism is only used with the internal MNCC.
+	 * functionality (with external MNCC briding would be done by the PBX)
+	 * This means 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. */
+	trans1->conn->rtp.codec_cn = trans1->conn->rtp.codec_ran;
+	trans2->conn->rtp.codec_cn = trans1->conn->rtp.codec_ran;
+
+	/* Bridge RTP streams */
+	rc = msc_mgcp_call_complete(trans1, trans2->conn->rtp.local_port_cn,
+				    trans2->conn->rtp.local_addr_cn);
+	if (rc)
+		return -EINVAL;
+
+	rc = msc_mgcp_call_complete(trans2, trans1->conn->rtp.local_port_cn,
+				    trans1->conn->rtp.local_addr_cn);
+	if (rc)
+		return -EINVAL;
+
+	return 0;
+}
+
+static int gsm48_cc_rx_status_enq(struct gsm_trans *trans, struct msgb *msg)
+{
+	DEBUGP(DCC, "-> STATUS ENQ\n");
+	return gsm48_cc_tx_status(trans, msg);
+}
+
+static int gsm48_cc_tx_release(struct gsm_trans *trans, void *arg);
+static int gsm48_cc_tx_disconnect(struct gsm_trans *trans, void *arg);
+
+static void gsm48_cc_timeout(void *arg)
+{
+	struct gsm_trans *trans = arg;
+	int disconnect = 0, release = 0;
+	int mo_cause = GSM48_CC_CAUSE_RECOVERY_TIMER;
+	int mo_location = GSM48_CAUSE_LOC_USER;
+	int l4_cause = GSM48_CC_CAUSE_NORMAL_UNSPEC;
+	int l4_location = GSM48_CAUSE_LOC_PRN_S_LU;
+	struct gsm_mncc mo_rel, l4_rel;
+
+	memset(&mo_rel, 0, sizeof(struct gsm_mncc));
+	mo_rel.callref = trans->callref;
+	memset(&l4_rel, 0, sizeof(struct gsm_mncc));
+	l4_rel.callref = trans->callref;
+
+	switch(trans->cc.Tcurrent) {
+	case 0x303:
+		release = 1;
+		l4_cause = GSM48_CC_CAUSE_USER_NOTRESPOND;
+		break;
+	case 0x310:
+		disconnect = 1;
+		l4_cause = GSM48_CC_CAUSE_USER_NOTRESPOND;
+		break;
+	case 0x313:
+		disconnect = 1;
+		/* unknown, did not find it in the specs */
+		break;
+	case 0x301:
+		disconnect = 1;
+		l4_cause = GSM48_CC_CAUSE_USER_NOTRESPOND;
+		break;
+	case 0x308:
+		if (!trans->cc.T308_second) {
+			/* restart T308 a second time */
+			gsm48_cc_tx_release(trans, &trans->cc.msg);
+			trans->cc.T308_second = 1;
+			break; /* stay in release state */
+		}
+		trans_free(trans);
+		return;
+	case 0x306:
+		release = 1;
+		mo_cause = trans->cc.msg.cause.value;
+		mo_location = trans->cc.msg.cause.location;
+		break;
+	case 0x323:
+		disconnect = 1;
+		break;
+	default:
+		release = 1;
+	}
+
+	if (release && trans->callref) {
+		/* process release towards layer 4 */
+		mncc_release_ind(trans->net, trans, trans->callref,
+				 l4_location, l4_cause);
+		trans->callref = 0;
+	}
+
+	if (disconnect && trans->callref) {
+		/* process disconnect towards layer 4 */
+		mncc_set_cause(&l4_rel, l4_location, l4_cause);
+		mncc_recvmsg(trans->net, trans, MNCC_DISC_IND, &l4_rel);
+	}
+
+	/* process disconnect towards mobile station */
+	if (disconnect || release) {
+		mncc_set_cause(&mo_rel, mo_location, mo_cause);
+		mo_rel.cause.diag[0] = ((trans->cc.Tcurrent & 0xf00) >> 8) + '0';
+		mo_rel.cause.diag[1] = ((trans->cc.Tcurrent & 0x0f0) >> 4) + '0';
+		mo_rel.cause.diag[2] = (trans->cc.Tcurrent & 0x00f) + '0';
+		mo_rel.cause.diag_len = 3;
+
+		if (disconnect)
+			gsm48_cc_tx_disconnect(trans, &mo_rel);
+		if (release)
+			gsm48_cc_tx_release(trans, &mo_rel);
+	}
+
+}
+
+/* disconnect both calls from the bridge */
+static inline void disconnect_bridge(struct gsm_network *net,
+				     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_mncc mx_rel;
+	if (!trans0 || !trans1)
+		return;
+
+	DEBUGP(DCC, "Failed to bridge TCH for calls %x <-> %x :: %s \n",
+	       trans0->callref, trans1->callref, strerror(err));
+
+	memset(&mx_rel, 0, sizeof(struct gsm_mncc));
+	mncc_set_cause(&mx_rel, GSM48_CAUSE_LOC_INN_NET,
+		       GSM48_CC_CAUSE_CHAN_UNACCEPT);
+
+	mx_rel.callref = trans0->callref;
+	gsm48_cc_tx_disconnect(trans0, &mx_rel);
+
+	mx_rel.callref = trans1->callref;
+	gsm48_cc_tx_disconnect(trans1, &mx_rel);
+}
+
+static void gsm48_start_cc_timer(struct gsm_trans *trans, int current,
+				 int sec, int micro)
+{
+	DEBUGP(DCC, "starting timer T%x with %d seconds\n", current, sec);
+	osmo_timer_setup(&trans->cc.timer, gsm48_cc_timeout, trans);
+	osmo_timer_schedule(&trans->cc.timer, sec, micro);
+	trans->cc.Tcurrent = current;
+}
+
+static int gsm48_cc_rx_setup(struct gsm_trans *trans, struct msgb *msg)
+{
+	struct gsm48_hdr *gh = msgb_l3(msg);
+	uint8_t msg_type = gsm48_hdr_msg_type(gh);
+	unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
+	struct tlv_parsed tp;
+	struct gsm_mncc setup;
+
+	gsm48_start_guard_timer(trans);
+
+	memset(&setup, 0, sizeof(struct gsm_mncc));
+	setup.callref = trans->callref;
+
+	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) {
+		setup.fields |= MNCC_F_EMERGENCY;
+		setup.emergency = 1;
+		/* use destination number as configured by user (if any) */
+		if (trans->net->emergency.route_to_msisdn) {
+			setup.fields |= MNCC_F_CALLED;
+			setup.called.type = 0; /* unknown */
+			setup.called.plan = 0; /* unknown */
+			OSMO_STRLCPY_ARRAY(setup.called.number,
+					   trans->net->emergency.route_to_msisdn);
+		}
+	}
+
+	/* use subscriber as calling party number */
+	setup.fields |= MNCC_F_CALLING;
+	OSMO_STRLCPY_ARRAY(setup.calling.number, trans->vsub->msisdn);
+	OSMO_STRLCPY_ARRAY(setup.imsi, trans->vsub->imsi);
+
+	/* bearer capability */
+	if (TLVP_PRESENT(&tp, GSM48_IE_BEARER_CAP)) {
+		setup.fields |= MNCC_F_BEARER_CAP;
+		gsm48_decode_bearer_cap(&setup.bearer_cap,
+				  TLVP_VAL(&tp, GSM48_IE_BEARER_CAP)-1);
+
+		/* 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));
+	}
+	/* facility */
+	if (TLVP_PRESENT(&tp, GSM48_IE_FACILITY)) {
+		setup.fields |= MNCC_F_FACILITY;
+		gsm48_decode_facility(&setup.facility,
+				TLVP_VAL(&tp, GSM48_IE_FACILITY)-1);
+	}
+	/* called party bcd number */
+	if (TLVP_PRESENT(&tp, GSM48_IE_CALLED_BCD)) {
+		setup.fields |= MNCC_F_CALLED;
+		gsm48_decode_called(&setup.called,
+			      TLVP_VAL(&tp, GSM48_IE_CALLED_BCD)-1);
+	}
+	/* user-user */
+	if (TLVP_PRESENT(&tp, GSM48_IE_USER_USER)) {
+		setup.fields |= MNCC_F_USERUSER;
+		gsm48_decode_useruser(&setup.useruser,
+				TLVP_VAL(&tp, GSM48_IE_USER_USER)-1);
+	}
+	/* ss-version */
+	if (TLVP_PRESENT(&tp, GSM48_IE_SS_VERS)) {
+		setup.fields |= MNCC_F_SSVERSION;
+		gsm48_decode_ssversion(&setup.ssversion,
+				 TLVP_VAL(&tp, GSM48_IE_SS_VERS)-1);
+	}
+	/* CLIR suppression */
+	if (TLVP_PRESENT(&tp, GSM48_IE_CLIR_SUPP))
+		setup.clir.sup = 1;
+	/* CLIR invocation */
+	if (TLVP_PRESENT(&tp, GSM48_IE_CLIR_INVOC))
+		setup.clir.inv = 1;
+	/* cc cap */
+	if (TLVP_PRESENT(&tp, GSM48_IE_CC_CAP)) {
+		setup.fields |= MNCC_F_CCCAP;
+		gsm48_decode_cccap(&setup.cccap,
+			     TLVP_VAL(&tp, GSM48_IE_CC_CAP)-1);
+	}
+
+	new_cc_state(trans, GSM_CSTATE_INITIATED);
+
+	LOGP(DCC, setup.emergency ? LOGL_NOTICE : LOGL_INFO, "Subscriber %s (%s) sends %sSETUP to %s\n",
+	     vlr_subscr_name(trans->vsub), trans->vsub->msisdn, setup.emergency ? "EMERGENCY_" : "",
+	     setup.called.number);
+
+	rate_ctr_inc(&trans->net->msc_ctrs->ctr[MSC_CTR_CALL_MO_SETUP]);
+
+	/* 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 int gsm48_cc_tx_setup(struct gsm_trans *trans, void *arg)
+{
+	struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 CC STUP");
+	struct gsm48_hdr *gh;
+	struct gsm_mncc *setup = arg;
+	int rc, trans_id;
+
+	gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
+
+	/* transaction id must not be assigned */
+	if (trans->transaction_id != 0xff) { /* unasssigned */
+		DEBUGP(DCC, "TX Setup with assigned transaction. "
+			"This is not allowed!\n");
+		/* Temporarily out of order */
+		rc = mncc_release_ind(trans->net, trans, trans->callref,
+				      GSM48_CAUSE_LOC_PRN_S_LU,
+				      GSM48_CC_CAUSE_RESOURCE_UNAVAIL);
+		trans->callref = 0;
+		trans_free(trans);
+		return rc;
+	}
+
+	/* Get free transaction_id */
+	trans_id = trans_assign_trans_id(trans->net, trans->vsub,
+					 GSM48_PDISC_CC, 0);
+	if (trans_id < 0) {
+		/* no free transaction ID */
+		rc = mncc_release_ind(trans->net, trans, trans->callref,
+				      GSM48_CAUSE_LOC_PRN_S_LU,
+				      GSM48_CC_CAUSE_RESOURCE_UNAVAIL);
+		trans->callref = 0;
+		trans_free(trans);
+		return rc;
+	}
+	trans->transaction_id = trans_id;
+
+	gh->msg_type = GSM48_MT_CC_SETUP;
+
+	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);
+	}
+	/* facility */
+	if (setup->fields & MNCC_F_FACILITY)
+		gsm48_encode_facility(msg, 0, &setup->facility);
+	/* progress */
+	if (setup->fields & MNCC_F_PROGRESS)
+		gsm48_encode_progress(msg, 0, &setup->progress);
+	/* calling party BCD number */
+	if (setup->fields & MNCC_F_CALLING)
+		gsm48_encode_calling(msg, &setup->calling);
+	/* called party BCD number */
+	if (setup->fields & MNCC_F_CALLED)
+		gsm48_encode_called(msg, &setup->called);
+	/* user-user */
+	if (setup->fields & MNCC_F_USERUSER)
+		gsm48_encode_useruser(msg, 0, &setup->useruser);
+	/* redirecting party BCD number */
+	if (setup->fields & MNCC_F_REDIRECTING)
+		gsm48_encode_redirecting(msg, &setup->redirecting);
+	/* signal */
+	if (setup->fields & MNCC_F_SIGNAL)
+		gsm48_encode_signal(msg, setup->signal);
+
+	new_cc_state(trans, GSM_CSTATE_CALL_PRESENT);
+
+	rate_ctr_inc(&trans->net->msc_ctrs->ctr[MSC_CTR_CALL_MT_SETUP]);
+
+	return gsm48_conn_sendmsg(msg, trans->conn, trans);
+}
+
+static int gsm48_cc_rx_call_conf(struct gsm_trans *trans, struct msgb *msg)
+{
+	struct gsm48_hdr *gh = msgb_l3(msg);
+	unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
+	struct tlv_parsed tp;
+	struct gsm_mncc call_conf;
+	int rc;
+
+	gsm48_stop_cc_timer(trans);
+	gsm48_start_cc_timer(trans, 0x310, GSM48_T310);
+
+	memset(&call_conf, 0, sizeof(struct gsm_mncc));
+	call_conf.callref = trans->callref;
+
+	tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len, 0, 0);
+#if 0
+	/* repeat */
+	if (TLVP_PRESENT(&tp, GSM48_IE_REPEAT_CIR))
+		call_conf.repeat = 1;
+	if (TLVP_PRESENT(&tp, GSM48_IE_REPEAT_SEQ))
+		call_conf.repeat = 2;
+#endif
+	/* bearer capability */
+	if (TLVP_PRESENT(&tp, GSM48_IE_BEARER_CAP)) {
+		call_conf.fields |= MNCC_F_BEARER_CAP;
+		gsm48_decode_bearer_cap(&call_conf.bearer_cap,
+				  TLVP_VAL(&tp, GSM48_IE_BEARER_CAP)-1);
+
+		/* 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,
+		       sizeof(trans->bearer_cap));
+	}
+	/* cause */
+	if (TLVP_PRESENT(&tp, GSM48_IE_CAUSE)) {
+		call_conf.fields |= MNCC_F_CAUSE;
+		gsm48_decode_cause(&call_conf.cause,
+			     TLVP_VAL(&tp, GSM48_IE_CAUSE)-1);
+	}
+	/* cc cap */
+	if (TLVP_PRESENT(&tp, GSM48_IE_CC_CAP)) {
+		call_conf.fields |= MNCC_F_CCCAP;
+		gsm48_decode_cccap(&call_conf.cccap,
+			     TLVP_VAL(&tp, GSM48_IE_CC_CAP)-1);
+	}
+
+	/* 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) */
+	if (trans->assignment_done == false) {
+		rc = msc_mgcp_call_assignment(trans);
+		trans->assignment_done = true;
+	}
+	else
+		rc = 0;
+
+	/* don't continue, if there were problems with
+	 * the call assignment. */
+	if (rc)
+		return rc;
+
+	return mncc_recvmsg(trans->net, trans, MNCC_CALL_CONF_IND,
+			    &call_conf);
+}
+
+static int gsm48_cc_tx_call_proc_and_assign(struct gsm_trans *trans, void *arg)
+{
+	struct gsm_mncc *proceeding = arg;
+	struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 CC PROC");
+	struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
+	int rc;
+
+	gh->msg_type = GSM48_MT_CC_CALL_PROC;
+
+	new_cc_state(trans, GSM_CSTATE_MO_CALL_PROC);
+
+	/* bearer capability */
+	if (proceeding->fields & MNCC_F_BEARER_CAP) {
+		gsm48_encode_bearer_cap(msg, 0, &proceeding->bearer_cap);
+		memcpy(&trans->bearer_cap, &proceeding->bearer_cap, sizeof(trans->bearer_cap));
+	}
+	/* facility */
+	if (proceeding->fields & MNCC_F_FACILITY)
+		gsm48_encode_facility(msg, 0, &proceeding->facility);
+	/* progress */
+	if (proceeding->fields & MNCC_F_PROGRESS)
+		gsm48_encode_progress(msg, 0, &proceeding->progress);
+
+	rc = gsm48_conn_sendmsg(msg, trans->conn, trans);
+	if (rc)
+		return rc;
+
+	/* Assign call (if not done yet) */
+	if (trans->assignment_done == false) {
+		rc = msc_mgcp_call_assignment(trans);
+		trans->assignment_done = true;
+	}
+	else
+		rc = 0;
+
+	return rc;
+}
+
+static int gsm48_cc_rx_alerting(struct gsm_trans *trans, struct msgb *msg)
+{
+	struct gsm48_hdr *gh = msgb_l3(msg);
+	unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
+	struct tlv_parsed tp;
+	struct gsm_mncc alerting;
+
+	gsm48_stop_cc_timer(trans);
+	gsm48_start_cc_timer(trans, 0x301, GSM48_T301);
+
+	memset(&alerting, 0, sizeof(struct gsm_mncc));
+	alerting.callref = trans->callref;
+	tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len, 0, 0);
+	/* facility */
+	if (TLVP_PRESENT(&tp, GSM48_IE_FACILITY)) {
+		alerting.fields |= MNCC_F_FACILITY;
+		gsm48_decode_facility(&alerting.facility,
+				TLVP_VAL(&tp, GSM48_IE_FACILITY)-1);
+	}
+
+	/* progress */
+	if (TLVP_PRESENT(&tp, GSM48_IE_PROGR_IND)) {
+		alerting.fields |= MNCC_F_PROGRESS;
+		gsm48_decode_progress(&alerting.progress,
+				TLVP_VAL(&tp, GSM48_IE_PROGR_IND)-1);
+	}
+	/* ss-version */
+	if (TLVP_PRESENT(&tp, GSM48_IE_SS_VERS)) {
+		alerting.fields |= MNCC_F_SSVERSION;
+		gsm48_decode_ssversion(&alerting.ssversion,
+				 TLVP_VAL(&tp, GSM48_IE_SS_VERS)-1);
+	}
+
+	new_cc_state(trans, GSM_CSTATE_CALL_RECEIVED);
+
+	return mncc_recvmsg(trans->net, trans, MNCC_ALERT_IND,
+			    &alerting);
+}
+
+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));
+
+	gh->msg_type = GSM48_MT_CC_ALERTING;
+
+	/* facility */
+	if (alerting->fields & MNCC_F_FACILITY)
+		gsm48_encode_facility(msg, 0, &alerting->facility);
+	/* progress */
+	if (alerting->fields & MNCC_F_PROGRESS)
+		gsm48_encode_progress(msg, 0, &alerting->progress);
+	/* user-user */
+	if (alerting->fields & MNCC_F_USERUSER)
+		gsm48_encode_useruser(msg, 0, &alerting->useruser);
+
+	new_cc_state(trans, GSM_CSTATE_CALL_DELIVERED);
+
+	return gsm48_conn_sendmsg(msg, trans->conn, trans);
+}
+
+static int gsm48_cc_tx_progress(struct gsm_trans *trans, void *arg)
+{
+	struct gsm_mncc *progress = arg;
+	struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 CC PROGRESS");
+	struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
+
+	gh->msg_type = GSM48_MT_CC_PROGRESS;
+
+	/* progress */
+	gsm48_encode_progress(msg, 1, &progress->progress);
+	/* user-user */
+	if (progress->fields & MNCC_F_USERUSER)
+		gsm48_encode_useruser(msg, 0, &progress->useruser);
+
+	return gsm48_conn_sendmsg(msg, trans->conn, trans);
+}
+
+static int gsm48_cc_tx_connect(struct gsm_trans *trans, void *arg)
+{
+	struct gsm_mncc *connect = arg;
+	struct msgb *msg = gsm48_msgb_alloc_name("GSN 04.08 CC CON");
+	struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
+
+	gh->msg_type = GSM48_MT_CC_CONNECT;
+
+	gsm48_stop_cc_timer(trans);
+	gsm48_start_cc_timer(trans, 0x313, GSM48_T313);
+
+	/* facility */
+	if (connect->fields & MNCC_F_FACILITY)
+		gsm48_encode_facility(msg, 0, &connect->facility);
+	/* progress */
+	if (connect->fields & MNCC_F_PROGRESS)
+		gsm48_encode_progress(msg, 0, &connect->progress);
+	/* connected number */
+	if (connect->fields & MNCC_F_CONNECTED)
+		gsm48_encode_connected(msg, &connect->connected);
+	/* user-user */
+	if (connect->fields & MNCC_F_USERUSER)
+		gsm48_encode_useruser(msg, 0, &connect->useruser);
+
+	new_cc_state(trans, GSM_CSTATE_CONNECT_IND);
+
+	return gsm48_conn_sendmsg(msg, trans->conn, trans);
+}
+
+static int gsm48_cc_rx_connect(struct gsm_trans *trans, struct msgb *msg)
+{
+	struct gsm48_hdr *gh = msgb_l3(msg);
+	unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
+	struct tlv_parsed tp;
+	struct gsm_mncc connect;
+
+	gsm48_stop_cc_timer(trans);
+
+	memset(&connect, 0, sizeof(struct gsm_mncc));
+	connect.callref = trans->callref;
+	tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len, 0, 0);
+	/* use subscriber as connected party number */
+	connect.fields |= MNCC_F_CONNECTED;
+	OSMO_STRLCPY_ARRAY(connect.connected.number, trans->vsub->msisdn);
+	OSMO_STRLCPY_ARRAY(connect.imsi, trans->vsub->imsi);
+
+	/* facility */
+	if (TLVP_PRESENT(&tp, GSM48_IE_FACILITY)) {
+		connect.fields |= MNCC_F_FACILITY;
+		gsm48_decode_facility(&connect.facility,
+				TLVP_VAL(&tp, GSM48_IE_FACILITY)-1);
+	}
+	/* user-user */
+	if (TLVP_PRESENT(&tp, GSM48_IE_USER_USER)) {
+		connect.fields |= MNCC_F_USERUSER;
+		gsm48_decode_useruser(&connect.useruser,
+				TLVP_VAL(&tp, GSM48_IE_USER_USER)-1);
+	}
+	/* ss-version */
+	if (TLVP_PRESENT(&tp, GSM48_IE_SS_VERS)) {
+		connect.fields |= MNCC_F_SSVERSION;
+		gsm48_decode_ssversion(&connect.ssversion,
+				 TLVP_VAL(&tp, GSM48_IE_SS_VERS)-1);
+	}
+
+	new_cc_state(trans, GSM_CSTATE_CONNECT_REQUEST);
+	rate_ctr_inc(&trans->net->msc_ctrs->ctr[MSC_CTR_CALL_MT_CONNECT]);
+
+	return mncc_recvmsg(trans->net, trans, MNCC_SETUP_CNF, &connect);
+}
+
+
+static int gsm48_cc_rx_connect_ack(struct gsm_trans *trans, struct msgb *msg)
+{
+	struct gsm_mncc connect_ack;
+
+	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]);
+
+	memset(&connect_ack, 0, sizeof(struct gsm_mncc));
+	connect_ack.callref = trans->callref;
+
+	return mncc_recvmsg(trans->net, trans, MNCC_SETUP_COMPL_IND,
+			    &connect_ack);
+}
+
+static int gsm48_cc_tx_connect_ack(struct gsm_trans *trans, void *arg)
+{
+	struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 CC CON ACK");
+	struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
+
+	gh->msg_type = GSM48_MT_CC_CONNECT_ACK;
+
+	new_cc_state(trans, GSM_CSTATE_ACTIVE);
+
+	return gsm48_conn_sendmsg(msg, trans->conn, trans);
+}
+
+static int gsm48_cc_rx_disconnect(struct gsm_trans *trans, struct msgb *msg)
+{
+	struct gsm48_hdr *gh = msgb_l3(msg);
+	unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
+	struct tlv_parsed tp;
+	struct gsm_mncc disc;
+
+	gsm48_stop_cc_timer(trans);
+
+	new_cc_state(trans, GSM_CSTATE_DISCONNECT_REQ);
+
+	memset(&disc, 0, sizeof(struct gsm_mncc));
+	disc.callref = trans->callref;
+	tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len, GSM48_IE_CAUSE, 0);
+	/* cause */
+	if (TLVP_PRESENT(&tp, GSM48_IE_CAUSE)) {
+		disc.fields |= MNCC_F_CAUSE;
+		gsm48_decode_cause(&disc.cause,
+			     TLVP_VAL(&tp, GSM48_IE_CAUSE)-1);
+	}
+	/* facility */
+	if (TLVP_PRESENT(&tp, GSM48_IE_FACILITY)) {
+		disc.fields |= MNCC_F_FACILITY;
+		gsm48_decode_facility(&disc.facility,
+				TLVP_VAL(&tp, GSM48_IE_FACILITY)-1);
+	}
+	/* user-user */
+	if (TLVP_PRESENT(&tp, GSM48_IE_USER_USER)) {
+		disc.fields |= MNCC_F_USERUSER;
+		gsm48_decode_useruser(&disc.useruser,
+				TLVP_VAL(&tp, GSM48_IE_USER_USER)-1);
+	}
+	/* ss-version */
+	if (TLVP_PRESENT(&tp, GSM48_IE_SS_VERS)) {
+		disc.fields |= MNCC_F_SSVERSION;
+		gsm48_decode_ssversion(&disc.ssversion,
+				 TLVP_VAL(&tp, GSM48_IE_SS_VERS)-1);
+	}
+
+	return mncc_recvmsg(trans->net, trans, MNCC_DISC_IND, &disc);
+
+}
+
+static struct gsm_mncc_cause default_cause = {
+	.location	= GSM48_CAUSE_LOC_PRN_S_LU,
+	.coding		= 0,
+	.rec		= 0,
+	.rec_val	= 0,
+	.value		= GSM48_CC_CAUSE_NORMAL_UNSPEC,
+	.diag_len	= 0,
+	.diag		= { 0 },
+};
+
+static int gsm48_cc_tx_disconnect(struct gsm_trans *trans, void *arg)
+{
+	struct gsm_mncc *disc = arg;
+	struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 CC DISC");
+	struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
+
+	gh->msg_type = GSM48_MT_CC_DISCONNECT;
+
+	gsm48_stop_cc_timer(trans);
+	gsm48_start_cc_timer(trans, 0x306, GSM48_T306);
+
+	/* cause */
+	if (disc->fields & MNCC_F_CAUSE)
+		gsm48_encode_cause(msg, 1, &disc->cause);
+	else
+		gsm48_encode_cause(msg, 1, &default_cause);
+
+	/* facility */
+	if (disc->fields & MNCC_F_FACILITY)
+		gsm48_encode_facility(msg, 0, &disc->facility);
+	/* progress */
+	if (disc->fields & MNCC_F_PROGRESS)
+		gsm48_encode_progress(msg, 0, &disc->progress);
+	/* user-user */
+	if (disc->fields & MNCC_F_USERUSER)
+		gsm48_encode_useruser(msg, 0, &disc->useruser);
+
+	/* store disconnect cause for T306 expiry */
+	memcpy(&trans->cc.msg, disc, sizeof(struct gsm_mncc));
+
+	new_cc_state(trans, GSM_CSTATE_DISCONNECT_IND);
+
+	return gsm48_conn_sendmsg(msg, trans->conn, trans);
+}
+
+static int gsm48_cc_rx_release(struct gsm_trans *trans, struct msgb *msg)
+{
+	struct gsm48_hdr *gh = msgb_l3(msg);
+	unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
+	struct tlv_parsed tp;
+	struct gsm_mncc rel;
+	int rc;
+
+	gsm48_stop_cc_timer(trans);
+
+	memset(&rel, 0, sizeof(struct gsm_mncc));
+	rel.callref = trans->callref;
+	tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len, 0, 0);
+	/* cause */
+	if (TLVP_PRESENT(&tp, GSM48_IE_CAUSE)) {
+		rel.fields |= MNCC_F_CAUSE;
+		gsm48_decode_cause(&rel.cause,
+			     TLVP_VAL(&tp, GSM48_IE_CAUSE)-1);
+	}
+	/* facility */
+	if (TLVP_PRESENT(&tp, GSM48_IE_FACILITY)) {
+		rel.fields |= MNCC_F_FACILITY;
+		gsm48_decode_facility(&rel.facility,
+				TLVP_VAL(&tp, GSM48_IE_FACILITY)-1);
+	}
+	/* user-user */
+	if (TLVP_PRESENT(&tp, GSM48_IE_USER_USER)) {
+		rel.fields |= MNCC_F_USERUSER;
+		gsm48_decode_useruser(&rel.useruser,
+				TLVP_VAL(&tp, GSM48_IE_USER_USER)-1);
+	}
+	/* ss-version */
+	if (TLVP_PRESENT(&tp, GSM48_IE_SS_VERS)) {
+		rel.fields |= MNCC_F_SSVERSION;
+		gsm48_decode_ssversion(&rel.ssversion,
+				 TLVP_VAL(&tp, GSM48_IE_SS_VERS)-1);
+	}
+
+	if (trans->cc.state == GSM_CSTATE_RELEASE_REQ) {
+		/* release collision 5.4.5 */
+		rc = mncc_recvmsg(trans->net, trans, MNCC_REL_CNF, &rel);
+	} else {
+		rc = gsm48_tx_simple(trans->conn,
+				     GSM48_PDISC_CC | (trans->transaction_id << 4),
+				     GSM48_MT_CC_RELEASE_COMPL);
+		rc = mncc_recvmsg(trans->net, trans, MNCC_REL_IND, &rel);
+	}
+
+	new_cc_state(trans, GSM_CSTATE_NULL);
+
+	trans->callref = 0;
+	trans_free(trans);
+
+	return rc;
+}
+
+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));
+
+	gh->msg_type = GSM48_MT_CC_RELEASE;
+
+	gsm48_stop_cc_timer(trans);
+	gsm48_start_cc_timer(trans, 0x308, GSM48_T308);
+
+	/* cause */
+	if (rel->fields & MNCC_F_CAUSE)
+		gsm48_encode_cause(msg, 0, &rel->cause);
+	/* facility */
+	if (rel->fields & MNCC_F_FACILITY)
+		gsm48_encode_facility(msg, 0, &rel->facility);
+	/* user-user */
+	if (rel->fields & MNCC_F_USERUSER)
+		gsm48_encode_useruser(msg, 0, &rel->useruser);
+
+	trans->cc.T308_second = 0;
+	memcpy(&trans->cc.msg, rel, sizeof(struct gsm_mncc));
+
+	if (trans->cc.state != GSM_CSTATE_RELEASE_REQ)
+		new_cc_state(trans, GSM_CSTATE_RELEASE_REQ);
+
+	return gsm48_conn_sendmsg(msg, trans->conn, trans);
+}
+
+static int gsm48_cc_rx_release_compl(struct gsm_trans *trans, struct msgb *msg)
+{
+	struct gsm48_hdr *gh = msgb_l3(msg);
+	unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
+	struct tlv_parsed tp;
+	struct gsm_mncc rel;
+	int rc = 0;
+
+	gsm48_stop_cc_timer(trans);
+
+	memset(&rel, 0, sizeof(struct gsm_mncc));
+	rel.callref = trans->callref;
+	tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len, 0, 0);
+	/* cause */
+	if (TLVP_PRESENT(&tp, GSM48_IE_CAUSE)) {
+		rel.fields |= MNCC_F_CAUSE;
+		gsm48_decode_cause(&rel.cause,
+			     TLVP_VAL(&tp, GSM48_IE_CAUSE)-1);
+	}
+	/* facility */
+	if (TLVP_PRESENT(&tp, GSM48_IE_FACILITY)) {
+		rel.fields |= MNCC_F_FACILITY;
+		gsm48_decode_facility(&rel.facility,
+				TLVP_VAL(&tp, GSM48_IE_FACILITY)-1);
+	}
+	/* user-user */
+	if (TLVP_PRESENT(&tp, GSM48_IE_USER_USER)) {
+		rel.fields |= MNCC_F_USERUSER;
+		gsm48_decode_useruser(&rel.useruser,
+				TLVP_VAL(&tp, GSM48_IE_USER_USER)-1);
+	}
+	/* ss-version */
+	if (TLVP_PRESENT(&tp, GSM48_IE_SS_VERS)) {
+		rel.fields |= MNCC_F_SSVERSION;
+		gsm48_decode_ssversion(&rel.ssversion,
+				 TLVP_VAL(&tp, GSM48_IE_SS_VERS)-1);
+	}
+
+	if (trans->callref) {
+		switch (trans->cc.state) {
+		case GSM_CSTATE_CALL_PRESENT:
+			rc = mncc_recvmsg(trans->net, trans,
+					  MNCC_REJ_IND, &rel);
+			break;
+		case GSM_CSTATE_RELEASE_REQ:
+			rc = mncc_recvmsg(trans->net, trans,
+					  MNCC_REL_CNF, &rel);
+			break;
+		default:
+			rc = mncc_recvmsg(trans->net, trans,
+					  MNCC_REL_IND, &rel);
+		}
+	}
+
+	trans->callref = 0;
+	trans_free(trans);
+
+	return rc;
+}
+
+static int gsm48_cc_tx_release_compl(struct gsm_trans *trans, void *arg)
+{
+	struct gsm_mncc *rel = arg;
+	struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 CC REL COMPL");
+	struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
+	int ret;
+
+	gh->msg_type = GSM48_MT_CC_RELEASE_COMPL;
+
+	trans->callref = 0;
+
+	gsm48_stop_cc_timer(trans);
+
+	/* cause */
+	if (rel->fields & MNCC_F_CAUSE)
+		gsm48_encode_cause(msg, 0, &rel->cause);
+	/* facility */
+	if (rel->fields & MNCC_F_FACILITY)
+		gsm48_encode_facility(msg, 0, &rel->facility);
+	/* user-user */
+	if (rel->fields & MNCC_F_USERUSER)
+		gsm48_encode_useruser(msg, 0, &rel->useruser);
+
+	ret =  gsm48_conn_sendmsg(msg, trans->conn, trans);
+
+	trans_free(trans);
+
+	return ret;
+}
+
+static int gsm48_cc_rx_facility(struct gsm_trans *trans, struct msgb *msg)
+{
+	struct gsm48_hdr *gh = msgb_l3(msg);
+	unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
+	struct tlv_parsed tp;
+	struct gsm_mncc fac;
+
+	memset(&fac, 0, sizeof(struct gsm_mncc));
+	fac.callref = trans->callref;
+	tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len, GSM48_IE_FACILITY, 0);
+	/* facility */
+	if (TLVP_PRESENT(&tp, GSM48_IE_FACILITY)) {
+		fac.fields |= MNCC_F_FACILITY;
+		gsm48_decode_facility(&fac.facility,
+				TLVP_VAL(&tp, GSM48_IE_FACILITY)-1);
+	}
+	/* ss-version */
+	if (TLVP_PRESENT(&tp, GSM48_IE_SS_VERS)) {
+		fac.fields |= MNCC_F_SSVERSION;
+		gsm48_decode_ssversion(&fac.ssversion,
+				 TLVP_VAL(&tp, GSM48_IE_SS_VERS)-1);
+	}
+
+	return mncc_recvmsg(trans->net, trans, MNCC_FACILITY_IND, &fac);
+}
+
+static int gsm48_cc_tx_facility(struct gsm_trans *trans, void *arg)
+{
+	struct gsm_mncc *fac = arg;
+	struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 CC FAC");
+	struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
+
+	gh->msg_type = GSM48_MT_CC_FACILITY;
+
+	/* facility */
+	gsm48_encode_facility(msg, 1, &fac->facility);
+
+	return gsm48_conn_sendmsg(msg, trans->conn, trans);
+}
+
+static int gsm48_cc_rx_hold(struct gsm_trans *trans, struct msgb *msg)
+{
+	struct gsm_mncc hold;
+
+	memset(&hold, 0, sizeof(struct gsm_mncc));
+	hold.callref = trans->callref;
+	return mncc_recvmsg(trans->net, trans, MNCC_HOLD_IND, &hold);
+}
+
+static int gsm48_cc_tx_hold_ack(struct gsm_trans *trans, void *arg)
+{
+	struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 CC HLD ACK");
+	struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
+
+	gh->msg_type = GSM48_MT_CC_HOLD_ACK;
+
+	return gsm48_conn_sendmsg(msg, trans->conn, trans);
+}
+
+static int gsm48_cc_tx_hold_rej(struct gsm_trans *trans, void *arg)
+{
+	struct gsm_mncc *hold_rej = arg;
+	struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 CC HLD REJ");
+	struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
+
+	gh->msg_type = GSM48_MT_CC_HOLD_REJ;
+
+	/* cause */
+	if (hold_rej->fields & MNCC_F_CAUSE)
+		gsm48_encode_cause(msg, 1, &hold_rej->cause);
+	else
+		gsm48_encode_cause(msg, 1, &default_cause);
+
+	return gsm48_conn_sendmsg(msg, trans->conn, trans);
+}
+
+static int gsm48_cc_rx_retrieve(struct gsm_trans *trans, struct msgb *msg)
+{
+	struct gsm_mncc retrieve;
+
+	memset(&retrieve, 0, sizeof(struct gsm_mncc));
+	retrieve.callref = trans->callref;
+	return mncc_recvmsg(trans->net, trans, MNCC_RETRIEVE_IND,
+			    &retrieve);
+}
+
+static int gsm48_cc_tx_retrieve_ack(struct gsm_trans *trans, void *arg)
+{
+	struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 CC RETR ACK");
+	struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
+
+	gh->msg_type = GSM48_MT_CC_RETR_ACK;
+
+	return gsm48_conn_sendmsg(msg, trans->conn, trans);
+}
+
+static int gsm48_cc_tx_retrieve_rej(struct gsm_trans *trans, void *arg)
+{
+	struct gsm_mncc *retrieve_rej = arg;
+	struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 CC RETR REJ");
+	struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
+
+	gh->msg_type = GSM48_MT_CC_RETR_REJ;
+
+	/* cause */
+	if (retrieve_rej->fields & MNCC_F_CAUSE)
+		gsm48_encode_cause(msg, 1, &retrieve_rej->cause);
+	else
+		gsm48_encode_cause(msg, 1, &default_cause);
+
+	return gsm48_conn_sendmsg(msg, trans->conn, trans);
+}
+
+static int gsm48_cc_rx_start_dtmf(struct gsm_trans *trans, struct msgb *msg)
+{
+	struct gsm48_hdr *gh = msgb_l3(msg);
+	unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
+	struct tlv_parsed tp;
+	struct gsm_mncc dtmf;
+
+	memset(&dtmf, 0, sizeof(struct gsm_mncc));
+	dtmf.callref = trans->callref;
+	tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len, 0, 0);
+	/* keypad facility */
+	if (TLVP_PRESENT(&tp, GSM48_IE_KPD_FACILITY)) {
+		dtmf.fields |= MNCC_F_KEYPAD;
+		gsm48_decode_keypad(&dtmf.keypad,
+			      TLVP_VAL(&tp, GSM48_IE_KPD_FACILITY)-1);
+	}
+
+	return mncc_recvmsg(trans->net, trans, MNCC_START_DTMF_IND, &dtmf);
+}
+
+static int gsm48_cc_tx_start_dtmf_ack(struct gsm_trans *trans, void *arg)
+{
+	struct gsm_mncc *dtmf = arg;
+	struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 DTMF ACK");
+	struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
+
+	gh->msg_type = GSM48_MT_CC_START_DTMF_ACK;
+
+	/* keypad */
+	if (dtmf->fields & MNCC_F_KEYPAD)
+		gsm48_encode_keypad(msg, dtmf->keypad);
+
+	return gsm48_conn_sendmsg(msg, trans->conn, trans);
+}
+
+static int gsm48_cc_tx_start_dtmf_rej(struct gsm_trans *trans, void *arg)
+{
+	struct gsm_mncc *dtmf = arg;
+	struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 DTMF REJ");
+	struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
+
+	gh->msg_type = GSM48_MT_CC_START_DTMF_REJ;
+
+	/* cause */
+	if (dtmf->fields & MNCC_F_CAUSE)
+		gsm48_encode_cause(msg, 1, &dtmf->cause);
+	else
+		gsm48_encode_cause(msg, 1, &default_cause);
+
+	return gsm48_conn_sendmsg(msg, trans->conn, trans);
+}
+
+static int gsm48_cc_tx_stop_dtmf_ack(struct gsm_trans *trans, void *arg)
+{
+	struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 DTMF STP ACK");
+	struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
+
+	gh->msg_type = GSM48_MT_CC_STOP_DTMF_ACK;
+
+	return gsm48_conn_sendmsg(msg, trans->conn, trans);
+}
+
+static int gsm48_cc_rx_stop_dtmf(struct gsm_trans *trans, struct msgb *msg)
+{
+	struct gsm_mncc dtmf;
+
+	memset(&dtmf, 0, sizeof(struct gsm_mncc));
+	dtmf.callref = trans->callref;
+
+	return mncc_recvmsg(trans->net, trans, MNCC_STOP_DTMF_IND, &dtmf);
+}
+
+static int gsm48_cc_rx_modify(struct gsm_trans *trans, struct msgb *msg)
+{
+	struct gsm48_hdr *gh = msgb_l3(msg);
+	unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
+	struct tlv_parsed tp;
+	struct gsm_mncc modify;
+
+	memset(&modify, 0, sizeof(struct gsm_mncc));
+	modify.callref = trans->callref;
+	tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len, GSM48_IE_BEARER_CAP, 0);
+	/* bearer capability */
+	if (TLVP_PRESENT(&tp, GSM48_IE_BEARER_CAP)) {
+		modify.fields |= MNCC_F_BEARER_CAP;
+		gsm48_decode_bearer_cap(&modify.bearer_cap,
+				  TLVP_VAL(&tp, GSM48_IE_BEARER_CAP)-1);
+
+		/* Create a copy of the bearer capability
+		 * in the transaction struct, so we can use
+		 * this information later */
+		memcpy(&trans->bearer_cap,&modify.bearer_cap,
+		       sizeof(trans->bearer_cap));
+	}
+
+	new_cc_state(trans, GSM_CSTATE_MO_ORIG_MODIFY);
+
+	return mncc_recvmsg(trans->net, trans, MNCC_MODIFY_IND, &modify);
+}
+
+static int gsm48_cc_tx_modify(struct gsm_trans *trans, void *arg)
+{
+	struct gsm_mncc *modify = arg;
+	struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 CC MOD");
+	struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
+
+	gh->msg_type = GSM48_MT_CC_MODIFY;
+
+	gsm48_start_cc_timer(trans, 0x323, GSM48_T323);
+
+	/* bearer capability */
+	gsm48_encode_bearer_cap(msg, 1, &modify->bearer_cap);
+	memcpy(&trans->bearer_cap, &modify->bearer_cap, sizeof(trans->bearer_cap));
+
+	new_cc_state(trans, GSM_CSTATE_MO_TERM_MODIFY);
+
+	return gsm48_conn_sendmsg(msg, trans->conn, trans);
+}
+
+static int gsm48_cc_rx_modify_complete(struct gsm_trans *trans, struct msgb *msg)
+{
+	struct gsm48_hdr *gh = msgb_l3(msg);
+	unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
+	struct tlv_parsed tp;
+	struct gsm_mncc modify;
+
+	gsm48_stop_cc_timer(trans);
+
+	memset(&modify, 0, sizeof(struct gsm_mncc));
+	modify.callref = trans->callref;
+	tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len, GSM48_IE_BEARER_CAP, 0);
+	/* bearer capability */
+	if (TLVP_PRESENT(&tp, GSM48_IE_BEARER_CAP)) {
+		modify.fields |= MNCC_F_BEARER_CAP;
+		gsm48_decode_bearer_cap(&modify.bearer_cap,
+				  TLVP_VAL(&tp, GSM48_IE_BEARER_CAP)-1);
+
+		/* Create a copy of the bearer capability
+		 * in the transaction struct, so we can use
+		 * this information later */
+		memcpy(&trans->bearer_cap,&modify.bearer_cap,
+		       sizeof(trans->bearer_cap));
+	}
+
+	new_cc_state(trans, GSM_CSTATE_ACTIVE);
+
+	return mncc_recvmsg(trans->net, trans, MNCC_MODIFY_CNF, &modify);
+}
+
+static int gsm48_cc_tx_modify_complete(struct gsm_trans *trans, void *arg)
+{
+	struct gsm_mncc *modify = arg;
+	struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 CC MOD COMPL");
+	struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
+
+	gh->msg_type = GSM48_MT_CC_MODIFY_COMPL;
+
+	/* bearer capability */
+	gsm48_encode_bearer_cap(msg, 1, &modify->bearer_cap);
+	memcpy(&trans->bearer_cap, &modify->bearer_cap, sizeof(trans->bearer_cap));
+
+	new_cc_state(trans, GSM_CSTATE_ACTIVE);
+
+	return gsm48_conn_sendmsg(msg, trans->conn, trans);
+}
+
+static int gsm48_cc_rx_modify_reject(struct gsm_trans *trans, struct msgb *msg)
+{
+	struct gsm48_hdr *gh = msgb_l3(msg);
+	unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
+	struct tlv_parsed tp;
+	struct gsm_mncc modify;
+
+	gsm48_stop_cc_timer(trans);
+
+	memset(&modify, 0, sizeof(struct gsm_mncc));
+	modify.callref = trans->callref;
+	tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len, GSM48_IE_BEARER_CAP, GSM48_IE_CAUSE);
+	/* bearer capability */
+	if (TLVP_PRESENT(&tp, GSM48_IE_BEARER_CAP)) {
+		modify.fields |= GSM48_IE_BEARER_CAP;
+		gsm48_decode_bearer_cap(&modify.bearer_cap,
+				  TLVP_VAL(&tp, GSM48_IE_BEARER_CAP)-1);
+
+		/* Create a copy of the bearer capability
+		 * in the transaction struct, so we can use
+		 * this information later */
+		memcpy(&trans->bearer_cap,&modify.bearer_cap,
+		       sizeof(trans->bearer_cap));
+	}
+	/* cause */
+	if (TLVP_PRESENT(&tp, GSM48_IE_CAUSE)) {
+		modify.fields |= MNCC_F_CAUSE;
+		gsm48_decode_cause(&modify.cause,
+			     TLVP_VAL(&tp, GSM48_IE_CAUSE)-1);
+	}
+
+	new_cc_state(trans, GSM_CSTATE_ACTIVE);
+
+	return mncc_recvmsg(trans->net, trans, MNCC_MODIFY_REJ, &modify);
+}
+
+static int gsm48_cc_tx_modify_reject(struct gsm_trans *trans, void *arg)
+{
+	struct gsm_mncc *modify = arg;
+	struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 CC MOD REJ");
+	struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
+
+	gh->msg_type = GSM48_MT_CC_MODIFY_REJECT;
+
+	/* bearer capability */
+	gsm48_encode_bearer_cap(msg, 1, &modify->bearer_cap);
+	memcpy(&trans->bearer_cap, &modify->bearer_cap, sizeof(trans->bearer_cap));
+	/* cause */
+	gsm48_encode_cause(msg, 1, &modify->cause);
+
+	new_cc_state(trans, GSM_CSTATE_ACTIVE);
+
+	return gsm48_conn_sendmsg(msg, trans->conn, trans);
+}
+
+static int gsm48_cc_tx_notify(struct gsm_trans *trans, void *arg)
+{
+	struct gsm_mncc *notify = arg;
+	struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 CC NOT");
+	struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
+
+	gh->msg_type = GSM48_MT_CC_NOTIFY;
+
+	/* notify */
+	gsm48_encode_notify(msg, notify->notify);
+
+	return gsm48_conn_sendmsg(msg, trans->conn, trans);
+}
+
+static int gsm48_cc_rx_notify(struct gsm_trans *trans, struct msgb *msg)
+{
+	struct gsm48_hdr *gh = msgb_l3(msg);
+	unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
+//	struct tlv_parsed tp;
+	struct gsm_mncc notify;
+
+	memset(&notify, 0, sizeof(struct gsm_mncc));
+	notify.callref = trans->callref;
+//	tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len);
+	if (payload_len >= 1)
+		gsm48_decode_notify(&notify.notify, gh->data);
+
+	return mncc_recvmsg(trans->net, trans, MNCC_NOTIFY_IND, &notify);
+}
+
+static int gsm48_cc_tx_userinfo(struct gsm_trans *trans, void *arg)
+{
+	struct gsm_mncc *user = arg;
+	struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 USR INFO");
+	struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
+
+	gh->msg_type = GSM48_MT_CC_USER_INFO;
+
+	/* user-user */
+	if (user->fields & MNCC_F_USERUSER)
+		gsm48_encode_useruser(msg, 1, &user->useruser);
+	/* more data */
+	if (user->more)
+		gsm48_encode_more(msg);
+
+	return gsm48_conn_sendmsg(msg, trans->conn, trans);
+}
+
+static int gsm48_cc_rx_userinfo(struct gsm_trans *trans, struct msgb *msg)
+{
+	struct gsm48_hdr *gh = msgb_l3(msg);
+	unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
+	struct tlv_parsed tp;
+	struct gsm_mncc user;
+
+	memset(&user, 0, sizeof(struct gsm_mncc));
+	user.callref = trans->callref;
+	tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len, GSM48_IE_USER_USER, 0);
+	/* user-user */
+	if (TLVP_PRESENT(&tp, GSM48_IE_USER_USER)) {
+		user.fields |= MNCC_F_USERUSER;
+		gsm48_decode_useruser(&user.useruser,
+				TLVP_VAL(&tp, GSM48_IE_USER_USER)-1);
+	}
+	/* more data */
+	if (TLVP_PRESENT(&tp, GSM48_IE_MORE_DATA))
+		user.more = 1;
+
+	return mncc_recvmsg(trans->net, trans, MNCC_USERINFO_IND, &user);
+}
+
+static void mncc_recv_rtp(struct gsm_network *net, uint32_t callref,
+		int cmd, uint32_t addr, uint16_t port, uint32_t payload_type,
+		uint32_t payload_msg_type)
+{
+	uint8_t data[sizeof(struct gsm_mncc)];
+	struct gsm_mncc_rtp *rtp;
+
+	memset(&data, 0, sizeof(data));
+	rtp = (struct gsm_mncc_rtp *) &data[0];
+
+	rtp->callref = callref;
+	rtp->msg_type = cmd;
+	rtp->ip = osmo_htonl(addr);
+	rtp->port = port;
+	rtp->payload_type = payload_type;
+	rtp->payload_msg_type = payload_msg_type;
+	mncc_recvmsg(net, NULL, cmd, (struct gsm_mncc *)data);
+}
+
+static void mncc_recv_rtp_sock(struct gsm_network *net, struct gsm_trans *trans, int cmd)
+{
+	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;
+
+	uint32_t addr = inet_addr(trans->conn->rtp.local_addr_cn);
+	uint16_t port = trans->conn->rtp.local_port_cn;
+
+	LOGP(DMNCC, LOGL_ERROR, "RTP create for non-existing trans\n");
+
+	if (addr == INADDR_NONE) {
+		LOGP(DMNCC, LOGL_ERROR,
+		     "(subscriber:%s) external MNCC is signalling invalid IP-Address\n",
+		     vlr_subscr_name(trans->vsub));
+		return;
+	}
+	if (port == 0) {
+		LOGP(DMNCC, LOGL_ERROR,
+		     "(subscriber:%s) external MNCC is signalling invalid Port\n",
+		     vlr_subscr_name(trans->vsub));
+		return;
+	}
+
+	/* 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;
+
+	return mncc_recv_rtp(net, trans->callref, cmd,
+			addr,
+			port,
+		        payload_type,
+			msg_type);
+}
+
+static void mncc_recv_rtp_err(struct gsm_network *net, uint32_t callref, int cmd)
+{
+	return mncc_recv_rtp(net, callref, cmd, 0, 0, 0, 0);
+}
+
+static int tch_rtp_create(struct gsm_network *net, uint32_t callref)
+{
+	struct gsm_trans *trans;
+	int rc;
+
+	/* Find callref */
+	trans = trans_find_by_callref(net, callref);
+	if (!trans) {
+		LOGP(DMNCC, LOGL_ERROR, "RTP create for non-existing trans\n");
+		mncc_recv_rtp_err(net, callref, MNCC_RTP_CREATE);
+		return -EIO;
+	}
+	log_set_context(LOG_CTX_VLR_SUBSCR, trans->vsub);
+	if (!trans->conn) {
+		LOGP(DMNCC, LOGL_NOTICE, "RTP create for trans without conn\n");
+		mncc_recv_rtp_err(net, callref, MNCC_RTP_CREATE);
+		return 0;
+	}
+
+	trans->conn->mncc_rtp_bridge = 1;
+
+	/* 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;
+
+	/* Assign call (if not done yet) */
+	if (trans->assignment_done == false) {
+		rc = msc_mgcp_call_assignment(trans);
+		trans->assignment_done = true;
+	}
+	else
+		rc = 0;
+
+	return rc;
+}
+
+/* Trigger TCH_RTP_CREATE acknowledgement */
+int gsm48_tch_rtp_create(struct gsm_trans *trans)
+{
+	/* This function is called as soon as the port, on which the
+	 * mgcp-gw expects the incoming RTP stream from the remote
+	 * end (e.g. Asterisk) is known. */
+
+	struct gsm_subscriber_connection *conn = trans->conn;
+	struct gsm_network *network = conn->network;
+
+	mncc_recv_rtp_sock(network, trans, MNCC_RTP_CREATE);
+	return 0;
+}
+
+static int tch_rtp_connect(struct gsm_network *net, void *arg)
+{
+	struct gsm_trans *trans;
+	struct gsm_mncc_rtp *rtp = arg;
+	struct in_addr 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);
+	if (!trans) {
+		LOGP(DMNCC, LOGL_ERROR, "RTP connect for non-existing trans\n");
+		mncc_recv_rtp_err(net, rtp->callref, MNCC_RTP_CONNECT);
+		return -EIO;
+	}
+	log_set_context(LOG_CTX_VLR_SUBSCR, trans->vsub);
+	if (!trans->conn) {
+		LOGP(DMNCC, LOGL_ERROR, "RTP connect for trans without conn\n");
+		mncc_recv_rtp_err(net, rtp->callref, MNCC_RTP_CONNECT);
+		return 0;
+	}
+
+	addr.s_addr = osmo_htonl(rtp->ip);
+	return msc_mgcp_call_complete(trans, rtp->port, inet_ntoa(addr));
+}
+
+static struct downstate {
+	uint32_t	states;
+	int		type;
+	int		(*rout) (struct gsm_trans *trans, void *arg);
+} downstatelist[] = {
+	/* mobile originating call establishment */
+	{SBIT(GSM_CSTATE_INITIATED), /* 5.2.1.2 */
+	 MNCC_CALL_PROC_REQ, gsm48_cc_tx_call_proc_and_assign},
+	{SBIT(GSM_CSTATE_INITIATED) | SBIT(GSM_CSTATE_MO_CALL_PROC), /* 5.2.1.2 | 5.2.1.5 */
+	 MNCC_ALERT_REQ, gsm48_cc_tx_alerting},
+	{SBIT(GSM_CSTATE_INITIATED) | SBIT(GSM_CSTATE_MO_CALL_PROC) | SBIT(GSM_CSTATE_CALL_DELIVERED), /* 5.2.1.2 | 5.2.1.6 | 5.2.1.6 */
+	 MNCC_SETUP_RSP, gsm48_cc_tx_connect},
+	{SBIT(GSM_CSTATE_MO_CALL_PROC), /* 5.2.1.4.2 */
+	 MNCC_PROGRESS_REQ, gsm48_cc_tx_progress},
+	/* mobile terminating call establishment */
+	{SBIT(GSM_CSTATE_NULL), /* 5.2.2.1 */
+	 MNCC_SETUP_REQ, gsm48_cc_tx_setup},
+	{SBIT(GSM_CSTATE_CONNECT_REQUEST),
+	 MNCC_SETUP_COMPL_REQ, gsm48_cc_tx_connect_ack},
+	 /* signalling during call */
+	{SBIT(GSM_CSTATE_ACTIVE),
+	 MNCC_NOTIFY_REQ, gsm48_cc_tx_notify},
+	{ALL_STATES - SBIT(GSM_CSTATE_NULL) - SBIT(GSM_CSTATE_RELEASE_REQ),
+	 MNCC_FACILITY_REQ, gsm48_cc_tx_facility},
+	{ALL_STATES,
+	 MNCC_START_DTMF_RSP, gsm48_cc_tx_start_dtmf_ack},
+	{ALL_STATES,
+	 MNCC_START_DTMF_REJ, gsm48_cc_tx_start_dtmf_rej},
+	{ALL_STATES,
+	 MNCC_STOP_DTMF_RSP, gsm48_cc_tx_stop_dtmf_ack},
+	{SBIT(GSM_CSTATE_ACTIVE),
+	 MNCC_HOLD_CNF, gsm48_cc_tx_hold_ack},
+	{SBIT(GSM_CSTATE_ACTIVE),
+	 MNCC_HOLD_REJ, gsm48_cc_tx_hold_rej},
+	{SBIT(GSM_CSTATE_ACTIVE),
+	 MNCC_RETRIEVE_CNF, gsm48_cc_tx_retrieve_ack},
+	{SBIT(GSM_CSTATE_ACTIVE),
+	 MNCC_RETRIEVE_REJ, gsm48_cc_tx_retrieve_rej},
+	{SBIT(GSM_CSTATE_ACTIVE),
+	 MNCC_MODIFY_REQ, gsm48_cc_tx_modify},
+	{SBIT(GSM_CSTATE_MO_ORIG_MODIFY),
+	 MNCC_MODIFY_RSP, gsm48_cc_tx_modify_complete},
+	{SBIT(GSM_CSTATE_MO_ORIG_MODIFY),
+	 MNCC_MODIFY_REJ, gsm48_cc_tx_modify_reject},
+	{SBIT(GSM_CSTATE_ACTIVE),
+	 MNCC_USERINFO_REQ, gsm48_cc_tx_userinfo},
+	/* clearing */
+	{SBIT(GSM_CSTATE_INITIATED),
+	 MNCC_REJ_REQ, gsm48_cc_tx_release_compl},
+	{ALL_STATES - SBIT(GSM_CSTATE_NULL) - SBIT(GSM_CSTATE_DISCONNECT_IND) - SBIT(GSM_CSTATE_RELEASE_REQ) - SBIT(GSM_CSTATE_DISCONNECT_REQ), /* 5.4.4 */
+	 MNCC_DISC_REQ, gsm48_cc_tx_disconnect},
+	{ALL_STATES - SBIT(GSM_CSTATE_NULL) - SBIT(GSM_CSTATE_RELEASE_REQ), /* 5.4.3.2 */
+	 MNCC_REL_REQ, gsm48_cc_tx_release},
+};
+
+#define DOWNSLLEN \
+	(sizeof(downstatelist) / sizeof(struct downstate))
+
+
+int mncc_tx_to_cc(struct gsm_network *net, int msg_type, void *arg)
+{
+	int i, rc = 0;
+	struct gsm_trans *trans = NULL, *transt;
+	struct gsm_subscriber_connection *conn = NULL;
+	struct gsm_mncc *data = arg, rel;
+
+	DEBUGP(DMNCC, "receive message %s\n", get_mncc_name(msg_type));
+
+	/* handle special messages */
+	switch(msg_type) {
+	case MNCC_BRIDGE:
+		rc = tch_bridge(net, arg);
+		if (rc < 0)
+			disconnect_bridge(net, arg, -rc);
+		return rc;
+	case MNCC_RTP_CREATE:
+		return tch_rtp_create(net, data->callref);
+	case MNCC_RTP_CONNECT:
+		return tch_rtp_connect(net, arg);
+	case MNCC_RTP_FREE:
+		/* unused right now */
+		return -EIO;
+
+	case MNCC_FRAME_DROP:
+	case MNCC_FRAME_RECV:
+	case GSM_TCHF_FRAME:
+	case GSM_TCHF_FRAME_EFR:
+	case GSM_TCHH_FRAME:
+	case GSM_TCH_FRAME_AMR:
+		LOGP(DMNCC, LOGL_ERROR, "RTP streams must be handled externally; %s not supported.\n",
+		     get_mncc_name(msg_type));
+		return -ENOTSUP;
+	}
+
+	memset(&rel, 0, sizeof(struct gsm_mncc));
+	rel.callref = data->callref;
+
+	/* Find callref */
+	trans = trans_find_by_callref(net, data->callref);
+
+	/* Callref unknown */
+	if (!trans) {
+		struct vlr_subscr *vsub;
+
+		if (msg_type != MNCC_SETUP_REQ) {
+			DEBUGP(DCC, "(bts - trx - ts - ti -- sub %s) "
+				"Received '%s' from MNCC with "
+				"unknown callref %d\n", data->called.number,
+				get_mncc_name(msg_type), data->callref);
+			/* Invalid call reference */
+			return mncc_release_ind(net, NULL, data->callref,
+						GSM48_CAUSE_LOC_PRN_S_LU,
+						GSM48_CC_CAUSE_INVAL_TRANS_ID);
+		}
+		if (!data->called.number[0] && !data->imsi[0]) {
+			DEBUGP(DCC, "(bts - trx - ts - ti) "
+				"Received '%s' from MNCC with "
+				"no number or IMSI\n", get_mncc_name(msg_type));
+			/* Invalid number */
+			return mncc_release_ind(net, NULL, data->callref,
+						GSM48_CAUSE_LOC_PRN_S_LU,
+						GSM48_CC_CAUSE_INV_NR_FORMAT);
+		}
+		/* New transaction due to setup, find subscriber */
+		if (data->called.number[0])
+			vsub = vlr_subscr_find_by_msisdn(net->vlr,
+							 data->called.number);
+		else
+			vsub = vlr_subscr_find_by_imsi(net->vlr, data->imsi);
+
+		/* update the subscriber we deal with */
+		log_set_context(LOG_CTX_VLR_SUBSCR, vsub);
+
+		/* If subscriber is not found */
+		if (!vsub) {
+			DEBUGP(DCC, "(bts - trx - ts - ti -- sub %s) "
+				"Received '%s' from MNCC with "
+				"unknown subscriber %s\n", data->called.number,
+				get_mncc_name(msg_type), data->called.number);
+			/* Unknown subscriber */
+			return mncc_release_ind(net, NULL, data->callref,
+						GSM48_CAUSE_LOC_PRN_S_LU,
+						GSM48_CC_CAUSE_UNASSIGNED_NR);
+		}
+		/* If subscriber is not "attached" */
+		if (!vsub->lac) {
+			DEBUGP(DCC, "(bts - trx - ts - ti -- sub %s) "
+				"Received '%s' from MNCC with "
+				"detached subscriber %s\n", data->called.number,
+				get_mncc_name(msg_type), vlr_subscr_name(vsub));
+			vlr_subscr_put(vsub);
+			/* Temporarily out of order */
+			return mncc_release_ind(net, NULL, data->callref,
+						GSM48_CAUSE_LOC_PRN_S_LU,
+						GSM48_CC_CAUSE_DEST_OOO);
+		}
+		/* Create transaction */
+		trans = trans_alloc(net, vsub, GSM48_PDISC_CC, 0xff, data->callref);
+		if (!trans) {
+			DEBUGP(DCC, "No memory for trans.\n");
+			vlr_subscr_put(vsub);
+			/* Ressource unavailable */
+			mncc_release_ind(net, NULL, data->callref,
+					 GSM48_CAUSE_LOC_PRN_S_LU,
+					 GSM48_CC_CAUSE_RESOURCE_UNAVAIL);
+			return -ENOMEM;
+		}
+
+		/* Find conn */
+		conn = connection_for_subscr(vsub);
+
+		/* If subscriber has no conn */
+		if (!conn) {
+			/* 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;
+				DEBUGP(DCC, "(bts - trx - ts - ti -- sub %s) "
+					"Received '%s' from MNCC with "
+					"unallocated channel, paging already "
+					"started for lac %d.\n",
+					data->called.number,
+					get_mncc_name(msg_type), vsub->lac);
+				vlr_subscr_put(vsub);
+				trans_free(trans);
+				return 0;
+			}
+			/* store setup information until paging succeeds */
+			memcpy(&trans->cc.msg, data, sizeof(struct gsm_mncc));
+
+			/* Request a channel */
+			trans->paging_request = subscr_request_conn(
+							vsub,
+							setup_trig_pag_evt,
+							trans,
+							"MNCC: establish call");
+			if (!trans->paging_request) {
+				LOGP(DCC, LOGL_ERROR, "Failed to allocate paging token.\n");
+				vlr_subscr_put(vsub);
+				trans_free(trans);
+				return 0;
+			}
+			vlr_subscr_put(vsub);
+			return 0;
+		}
+
+		/* Assign conn */
+		trans->conn = msc_subscr_conn_get(conn, MSC_CONN_USE_TRANS_CC);
+		trans->dlci = 0x00; /* SAPI=0, not SACCH */
+		vlr_subscr_put(vsub);
+	} else {
+		/* update the subscriber we deal with */
+		log_set_context(LOG_CTX_VLR_SUBSCR, trans->vsub);
+	}
+
+	gsm48_start_guard_timer(trans);
+
+	if (trans->conn)
+		conn = trans->conn;
+
+	/* if paging did not respond yet */
+	if (!conn) {
+		DEBUGP(DCC, "(sub %s) "
+			"Received '%s' from MNCC in paging state\n",
+			vlr_subscr_msisdn_or_name(trans->vsub),
+			get_mncc_name(msg_type));
+		mncc_set_cause(&rel, GSM48_CAUSE_LOC_PRN_S_LU,
+				GSM48_CC_CAUSE_NORM_CALL_CLEAR);
+		if (msg_type == MNCC_REL_REQ)
+			rc = mncc_recvmsg(net, trans, MNCC_REL_CNF, &rel);
+		else
+			rc = mncc_recvmsg(net, trans, MNCC_REL_IND, &rel);
+		trans->callref = 0;
+		trans_free(trans);
+		return rc;
+	} else {
+		DEBUGP(DCC, "(ti %02x sub %s) "
+		       "Received '%s' from MNCC in state %d (%s)\n",
+		       trans->transaction_id,
+		       vlr_subscr_msisdn_or_name(trans->conn->vsub),
+		       get_mncc_name(msg_type), trans->cc.state,
+		       gsm48_cc_state_name(trans->cc.state));
+	}
+
+	/* Find function for current state and message */
+	for (i = 0; i < DOWNSLLEN; i++)
+		if ((msg_type == downstatelist[i].type)
+		 && ((1 << trans->cc.state) & downstatelist[i].states))
+			break;
+	if (i == DOWNSLLEN) {
+		DEBUGP(DCC, "Message unhandled at this state.\n");
+		return 0;
+	}
+
+	rc = downstatelist[i].rout(trans, arg);
+
+	return rc;
+}
+
+
+static struct datastate {
+	uint32_t	states;
+	int		type;
+	int		(*rout) (struct gsm_trans *trans, struct msgb *msg);
+} datastatelist[] = {
+	/* mobile originating call establishment */
+	{SBIT(GSM_CSTATE_NULL), /* 5.2.1.2 */
+	 GSM48_MT_CC_SETUP, gsm48_cc_rx_setup},
+	{SBIT(GSM_CSTATE_NULL), /* 5.2.1.2 */
+	 GSM48_MT_CC_EMERG_SETUP, gsm48_cc_rx_setup},
+	{SBIT(GSM_CSTATE_CONNECT_IND), /* 5.2.1.2 */
+	 GSM48_MT_CC_CONNECT_ACK, gsm48_cc_rx_connect_ack},
+	/* mobile terminating call establishment */
+	{SBIT(GSM_CSTATE_CALL_PRESENT), /* 5.2.2.3.2 */
+	 GSM48_MT_CC_CALL_CONF, gsm48_cc_rx_call_conf},
+	{SBIT(GSM_CSTATE_CALL_PRESENT) | SBIT(GSM_CSTATE_MO_TERM_CALL_CONF), /* ???? | 5.2.2.3.2 */
+	 GSM48_MT_CC_ALERTING, gsm48_cc_rx_alerting},
+	{SBIT(GSM_CSTATE_CALL_PRESENT) | SBIT(GSM_CSTATE_MO_TERM_CALL_CONF) | SBIT(GSM_CSTATE_CALL_RECEIVED), /* (5.2.2.6) | 5.2.2.6 | 5.2.2.6 */
+	 GSM48_MT_CC_CONNECT, gsm48_cc_rx_connect},
+	 /* signalling during call */
+	{ALL_STATES - SBIT(GSM_CSTATE_NULL),
+	 GSM48_MT_CC_FACILITY, gsm48_cc_rx_facility},
+	{SBIT(GSM_CSTATE_ACTIVE),
+	 GSM48_MT_CC_NOTIFY, gsm48_cc_rx_notify},
+	{ALL_STATES,
+	 GSM48_MT_CC_START_DTMF, gsm48_cc_rx_start_dtmf},
+	{ALL_STATES,
+	 GSM48_MT_CC_STOP_DTMF, gsm48_cc_rx_stop_dtmf},
+	{ALL_STATES,
+	 GSM48_MT_CC_STATUS_ENQ, gsm48_cc_rx_status_enq},
+	{SBIT(GSM_CSTATE_ACTIVE),
+	 GSM48_MT_CC_HOLD, gsm48_cc_rx_hold},
+	{SBIT(GSM_CSTATE_ACTIVE),
+	 GSM48_MT_CC_RETR, gsm48_cc_rx_retrieve},
+	{SBIT(GSM_CSTATE_ACTIVE),
+	 GSM48_MT_CC_MODIFY, gsm48_cc_rx_modify},
+	{SBIT(GSM_CSTATE_MO_TERM_MODIFY),
+	 GSM48_MT_CC_MODIFY_COMPL, gsm48_cc_rx_modify_complete},
+	{SBIT(GSM_CSTATE_MO_TERM_MODIFY),
+	 GSM48_MT_CC_MODIFY_REJECT, gsm48_cc_rx_modify_reject},
+	{SBIT(GSM_CSTATE_ACTIVE),
+	 GSM48_MT_CC_USER_INFO, gsm48_cc_rx_userinfo},
+	/* clearing */
+	{ALL_STATES - SBIT(GSM_CSTATE_NULL) - SBIT(GSM_CSTATE_RELEASE_REQ), /* 5.4.3.2 */
+	 GSM48_MT_CC_DISCONNECT, gsm48_cc_rx_disconnect},
+	{ALL_STATES - SBIT(GSM_CSTATE_NULL), /* 5.4.4.1.2.2 */
+	 GSM48_MT_CC_RELEASE, gsm48_cc_rx_release},
+	{ALL_STATES, /* 5.4.3.4 */
+	 GSM48_MT_CC_RELEASE_COMPL, gsm48_cc_rx_release_compl},
+};
+
+#define DATASLLEN \
+	(sizeof(datastatelist) / sizeof(struct datastate))
+
+int gsm0408_rcv_cc(struct gsm_subscriber_connection *conn, struct msgb *msg)
+{
+	struct gsm48_hdr *gh = msgb_l3(msg);
+	uint8_t msg_type = gsm48_hdr_msg_type(gh);
+	uint8_t transaction_id = gsm48_hdr_trans_id_flip_ti(gh);
+	struct gsm_trans *trans = NULL;
+	int i, rc = 0;
+
+	if (msg_type & 0x80) {
+		DEBUGP(DCC, "MSG 0x%2x not defined for PD error\n", msg_type);
+		return -EINVAL;
+	}
+
+	if (!conn->vsub) {
+		LOGP(DCC, LOGL_ERROR, "Invalid conn: no subscriber\n");
+		return -EINVAL;
+	}
+
+	/* Find transaction */
+	trans = trans_find_by_id(conn, GSM48_PDISC_CC, transaction_id);
+
+#if BEFORE_MSCSPLIT
+	/* Re-enable this log output once we can obtain this information via
+	 * A-interface, see OS#2391. */
+	DEBUGP(DCC, "(bts %d trx %d ts %d ti %x sub %s) "
+		"Received '%s' from MS in state %d (%s)\n",
+		conn->bts->nr, conn->lchan->ts->trx->nr, conn->lchan->ts->nr,
+		transaction_id, vlr_subscr_msisdn_or_name(conn->vsub),
+		gsm48_cc_msg_name(msg_type), trans?(trans->cc.state):0,
+		gsm48_cc_state_name(trans?(trans->cc.state):0));
+#endif
+
+	/* Create transaction */
+	if (!trans) {
+		DEBUGP(DCC, "Unknown transaction ID %x, "
+			"creating new trans.\n", transaction_id);
+		/* Create transaction */
+		trans = trans_alloc(conn->network, conn->vsub,
+				    GSM48_PDISC_CC,
+				    transaction_id, new_callref++);
+		if (!trans) {
+			DEBUGP(DCC, "No memory for trans.\n");
+			rc = gsm48_tx_simple(conn,
+					     GSM48_PDISC_CC | (transaction_id << 4),
+					     GSM48_MT_CC_RELEASE_COMPL);
+			return -ENOMEM;
+		}
+		/* Assign transaction */
+		trans->conn = msc_subscr_conn_get(conn, MSC_CONN_USE_TRANS_CC);
+		trans->dlci = OMSC_LINKID_CB(msg); /* DLCI as received from BSC */
+		cm_service_request_concludes(conn, msg);
+	}
+
+	/* find function for current state and message */
+	for (i = 0; i < DATASLLEN; i++)
+		if ((msg_type == datastatelist[i].type)
+		 && ((1 << trans->cc.state) & datastatelist[i].states))
+			break;
+	if (i == DATASLLEN) {
+		DEBUGP(DCC, "Message unhandled at this state.\n");
+		return 0;
+	}
+
+	assert(trans->vsub);
+
+	rc = datastatelist[i].rout(trans, msg);
+
+	msc_subscr_conn_communicating(conn);
+	return rc;
+}
diff --git a/src/libmsc/gsm_04_11.c b/src/libmsc/gsm_04_11.c
new file mode 100644
index 0000000..14f9f57
--- /dev/null
+++ b/src/libmsc/gsm_04_11.c
@@ -0,0 +1,1188 @@
+/* Point-to-Point (PP) Short Message Service (SMS)
+ * Support on Mobile Radio Interface
+ * 3GPP TS 04.11 version 7.1.0 Release 1998 / ETSI TS 100 942 V7.1.0 */
+
+/* (C) 2008 by Daniel Willmann <daniel@totalueberwachung.de>
+ * (C) 2009 by Harald Welte <laforge@gnumonks.org>
+ * (C) 2010-2012 by Holger Hans Peter Freyther <zecke@selfish.org>
+ * (C) 2010 by On-Waves
+ * (C) 2011 by Andreas Eversberg <jolly@eversberg.eu>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <time.h>
+#include <netinet/in.h>
+
+#include "bscconfig.h"
+
+#include <osmocom/core/msgb.h>
+#include <osmocom/core/talloc.h>
+#include <osmocom/core/utils.h>
+
+#include <osmocom/gsm/gsm_utils.h>
+#include <osmocom/gsm/gsm0411_utils.h>
+#include <osmocom/gsm/protocol/gsm_04_11.h>
+
+#include <osmocom/msc/debug.h>
+#include <osmocom/msc/gsm_data.h>
+#include <osmocom/msc/db.h>
+#include <osmocom/msc/gsm_subscriber.h>
+#include <osmocom/msc/gsm_04_08.h>
+#include <osmocom/msc/signal.h>
+#include <osmocom/msc/db.h>
+#include <osmocom/msc/transaction.h>
+#include <osmocom/msc/msc_ifaces.h>
+#include <osmocom/msc/osmo_msc.h>
+#include <osmocom/msc/vlr.h>
+
+#ifdef BUILD_SMPP
+#include "smpp_smsc.h"
+#endif
+
+void *tall_gsms_ctx;
+static uint32_t new_callref = 0x40000001;
+
+
+struct gsm_sms *sms_alloc(void)
+{
+	return talloc_zero(tall_gsms_ctx, struct gsm_sms);
+}
+
+void sms_free(struct gsm_sms *sms)
+{
+	/* drop references to subscriber structure */
+	if (sms->receiver)
+		vlr_subscr_put(sms->receiver);
+#ifdef BUILD_SMPP
+	if (sms->smpp.esme)
+		smpp_esme_put(sms->smpp.esme);
+#endif
+
+	talloc_free(sms);
+}
+
+struct gsm_sms *sms_from_text(struct vlr_subscr *receiver,
+			      const char *sender_msisdn,
+                              int dcs, const char *text)
+{
+	struct gsm_sms *sms = sms_alloc();
+
+	if (!sms)
+		return NULL;
+
+	sms->receiver = vlr_subscr_get(receiver);
+	OSMO_STRLCPY_ARRAY(sms->text, text);
+
+	OSMO_STRLCPY_ARRAY(sms->src.addr, sender_msisdn);
+	sms->reply_path_req = 0;
+	sms->status_rep_req = 0;
+	sms->ud_hdr_ind = 0;
+	sms->protocol_id = 0; /* implicit */
+	sms->data_coding_scheme = dcs;
+	OSMO_STRLCPY_ARRAY(sms->dst.addr, receiver->msisdn);
+	/* Generate user_data */
+	sms->user_data_len = gsm_7bit_encode_n(sms->user_data, sizeof(sms->user_data),
+						sms->text, NULL);
+
+	return sms;
+}
+
+
+static void send_signal(int sig_no,
+			struct gsm_trans *trans,
+			struct gsm_sms *sms,
+			int paging_result)
+{
+	struct sms_signal_data sig;
+	sig.trans = trans;
+	sig.sms = sms;
+	sig.paging_result = paging_result;
+	osmo_signal_dispatch(SS_SMS, sig_no, &sig);
+}
+
+static int gsm411_sendmsg(struct gsm_subscriber_connection *conn, struct msgb *msg)
+{
+	DEBUGP(DLSMS, "GSM4.11 TX %s\n", msgb_hexdump(msg));
+	msg->l3h = msg->data;
+	return msc_tx_dtap(conn, msg);
+}
+
+/* Prefix msg with a 04.08/04.11 CP header */
+static int gsm411_cp_sendmsg(struct msgb *msg, struct gsm_trans *trans,
+			     uint8_t msg_type)
+{
+	struct gsm48_hdr *gh;
+
+	gh = (struct gsm48_hdr *) msgb_push(msg, sizeof(*gh));
+	/* Outgoing needs the highest bit set */
+	gh->proto_discr = trans->protocol | (trans->transaction_id<<4);
+	gh->msg_type = msg_type;
+	OMSC_LINKID_CB(msg) = trans->dlci;
+
+	DEBUGP(DLSMS, "sending CP message (trans=%x)\n", trans->transaction_id);
+
+	return gsm411_sendmsg(trans->conn, msg);
+}
+
+/* mm_send: receive MMCCSMS sap message from SMC */
+static int gsm411_mm_send(struct gsm411_smc_inst *inst, int msg_type,
+			struct msgb *msg, int cp_msg_type)
+{
+	struct gsm_trans *trans =
+		container_of(inst, struct gsm_trans, sms.smc_inst);
+	int rc = 0;
+
+	switch (msg_type) {
+	case GSM411_MMSMS_EST_REQ:
+		/* recycle msg */
+		rc = gsm411_smc_recv(inst, GSM411_MMSMS_EST_CNF, msg, 0);
+		msgb_free(msg); /* upper layer does not free msg */
+		break;
+	case GSM411_MMSMS_DATA_REQ:
+		rc = gsm411_cp_sendmsg(msg, trans, cp_msg_type);
+		break;
+	case GSM411_MMSMS_REL_REQ:
+		DEBUGP(DLSMS, "Got MMSMS_REL_REQ, destroying transaction.\n");
+		msgb_free(msg);
+		trans_free(trans);
+		break;
+	default:
+		LOGP(DLSMS, LOGL_NOTICE, "Unhandled MMCCSMS msg 0x%x\n", msg_type);
+		msgb_free(msg);
+		rc = -EINVAL;
+	}
+
+	return rc;
+}
+
+/* mm_send: receive MNCCSMS sap message from SMR */
+int gsm411_mn_send(struct gsm411_smr_inst *inst, int msg_type,
+			struct msgb *msg)
+{
+	struct gsm_trans *trans =
+		container_of(inst, struct gsm_trans, sms.smr_inst);
+
+	/* forward to SMC */
+	return gsm411_smc_send(&trans->sms.smc_inst, msg_type, msg);
+}
+
+static int gsm340_rx_sms_submit(struct gsm_sms *gsms)
+{
+	if (db_sms_store(gsms) != 0) {
+		LOGP(DLSMS, LOGL_ERROR, "Failed to store SMS in Database\n");
+		return GSM411_RP_CAUSE_MO_NET_OUT_OF_ORDER;
+	}
+	/* dispatch a signal to tell higher level about it */
+	send_signal(S_SMS_SUBMITTED, NULL, gsms, 0);
+
+	return 0;
+}
+
+/* generate a TPDU address field compliant with 03.40 sec. 9.1.2.5 */
+static int gsm340_gen_oa_sub(uint8_t *oa, unsigned int oa_len,
+			 const struct gsm_sms_addr *src)
+{
+	/* network specific, private numbering plan */
+	return gsm340_gen_oa(oa, oa_len, src->ton, src->npi, src->addr);
+}
+
+/* generate a msgb containing an 03.40 9.2.2.1 SMS-DELIVER TPDU derived from
+ * struct gsm_sms, returns total size of TPDU */
+static int gsm340_gen_sms_deliver_tpdu(struct msgb *msg, struct gsm_sms *sms)
+{
+	uint8_t *smsp;
+	uint8_t oa[12];	/* max len per 03.40 */
+	uint8_t octet_len;
+	unsigned int old_msg_len = msg->len;
+	int oa_len;
+
+	/* generate first octet with masked bits */
+	smsp = msgb_put(msg, 1);
+	/* TP-MTI (message type indicator) */
+	*smsp = GSM340_SMS_DELIVER_SC2MS;
+	/* TP-MMS (more messages to send) */
+	if (0 /* FIXME */)
+		*smsp |= 0x04;
+	/* TP-SRI(deliver)/SRR(submit) */
+	if (sms->status_rep_req)
+		*smsp |= 0x20;
+	/* TP-UDHI (indicating TP-UD contains a header) */
+	if (sms->ud_hdr_ind)
+		*smsp |= 0x40;
+
+	/* generate originator address */
+	oa_len = gsm340_gen_oa_sub(oa, sizeof(oa), &sms->src);
+	if (oa_len < 0)
+		return -ENOSPC;
+
+	smsp = msgb_put(msg, oa_len);
+	memcpy(smsp, oa, oa_len);
+
+	/* generate TP-PID */
+	smsp = msgb_put(msg, 1);
+	*smsp = sms->protocol_id;
+
+	/* generate TP-DCS */
+	smsp = msgb_put(msg, 1);
+	*smsp = sms->data_coding_scheme;
+
+	/* generate TP-SCTS */
+	smsp = msgb_put(msg, 7);
+	gsm340_gen_scts(smsp, time(NULL));
+
+	/* generate TP-UDL */
+	smsp = msgb_put(msg, 1);
+	*smsp = sms->user_data_len;
+
+	/* generate TP-UD */
+	switch (gsm338_get_sms_alphabet(sms->data_coding_scheme)) {
+	case DCS_7BIT_DEFAULT:
+		octet_len = sms->user_data_len*7/8;
+		if (sms->user_data_len*7%8 != 0)
+			octet_len++;
+		/* Warning, user_data_len indicates the amount of septets
+		 * (characters), we need amount of octets occupied */
+		smsp = msgb_put(msg, octet_len);
+		memcpy(smsp, sms->user_data, octet_len);
+		break;
+	case DCS_UCS2:
+	case DCS_8BIT_DATA:
+		smsp = msgb_put(msg, sms->user_data_len);
+		memcpy(smsp, sms->user_data, sms->user_data_len);
+		break;
+	default:
+		LOGP(DLSMS, LOGL_NOTICE, "Unhandled Data Coding Scheme: 0x%02X\n",
+		     sms->data_coding_scheme);
+		break;
+	}
+
+	return msg->len - old_msg_len;
+}
+
+/* As defined by GSM 03.40, Section 9.2.2.3. */
+static int gsm340_gen_sms_status_report_tpdu(struct msgb *msg,
+					     struct gsm_sms *sms)
+{
+	unsigned int old_msg_len = msg->len;
+	uint8_t oa[12];	/* max len per 03.40 */
+	uint8_t *smsp;
+	int oa_len;
+
+	/* generate first octet with masked bits */
+	smsp = msgb_put(msg, 1);
+	/* TP-MTI (message type indicator) */
+	*smsp = GSM340_SMS_STATUS_REP_SC2MS;
+	/* TP-MMS (more messages to send) */
+	if (0 /* FIXME */)
+		*smsp |= 0x04;
+	/* TP-MR (message reference) */
+	smsp = msgb_put(msg, 1);
+	*smsp = sms->msg_ref;
+
+	/* generate recipient address */
+	oa_len = gsm340_gen_oa_sub(oa, sizeof(oa), &sms->src);
+	if (oa_len < 0)
+		return -ENOSPC;
+
+	smsp = msgb_put(msg, oa_len);
+	memcpy(smsp, oa, oa_len);
+
+	/* generate TP-SCTS (Service centre timestamp) */
+	smsp = msgb_put(msg, 7);
+	gsm340_gen_scts(smsp, sms->created);
+
+	/* generate TP-DT (Discharge time, in TP-SCTS format). */
+	smsp = msgb_put(msg, 7);
+	gsm340_gen_scts(smsp, sms->created);
+
+	/* TP-ST (status) */
+	smsp = msgb_put(msg, 1);
+	/* From GSM 03.40, Section 9.2.3.15, 0x00 means OK. */
+	*smsp = 0x00;
+
+	LOGP(DLSMS, LOGL_INFO, "sending status report for SMS reference %x\n",
+	     sms->msg_ref);
+
+	return msg->len - old_msg_len;
+}
+
+static int sms_route_mt_sms(struct gsm_subscriber_connection *conn,
+			    struct gsm_sms *gsms)
+{
+	int rc;
+
+#ifdef BUILD_SMPP
+	int smpp_first = smpp_route_smpp_first(gsms, conn);
+
+	/*
+	 * Route through SMPP first before going to the local database. In case
+	 * of a unroutable message and no local subscriber, SMPP will be tried
+	 * twice. In case of an unknown subscriber continue with the normal
+	 * delivery of the SMS.
+	 */
+	if (smpp_first) {
+		rc = smpp_try_deliver(gsms, conn);
+		if (rc == GSM411_RP_CAUSE_MO_NUM_UNASSIGNED)
+			/* unknown subscriber, try local */
+			goto try_local;
+		if (rc < 0) {
+	 		LOGP(DLSMS, LOGL_ERROR, "%s: SMS delivery error: %d.",
+			     vlr_subscr_name(conn->vsub), rc);
+	 		rc = GSM411_RP_CAUSE_MO_TEMP_FAIL;
+			/* rc will be logged by gsm411_send_rp_error() */
+			rate_ctr_inc(&conn->network->msc_ctrs->ctr[
+					MSC_CTR_SMS_DELIVER_UNKNOWN_ERROR]);
+		}
+		return rc;
+	}
+
+try_local:
+#endif
+
+	/* determine gsms->receiver based on dialled number */
+	gsms->receiver = vlr_subscr_find_by_msisdn(conn->network->vlr,
+						   gsms->dst.addr);
+	if (!gsms->receiver) {
+#ifdef BUILD_SMPP
+		/* Avoid a second look-up */
+		if (smpp_first) {
+			rate_ctr_inc(&conn->network->msc_ctrs->ctr[MSC_CTR_SMS_NO_RECEIVER]);
+			return GSM411_RP_CAUSE_MO_NUM_UNASSIGNED;
+		}
+
+		rc = smpp_try_deliver(gsms, conn);
+		if (rc == GSM411_RP_CAUSE_MO_NUM_UNASSIGNED) {
+			rate_ctr_inc(&conn->network->msc_ctrs->ctr[MSC_CTR_SMS_NO_RECEIVER]);
+		} else if (rc < 0) {
+	 		LOGP(DLSMS, LOGL_ERROR, "%s: SMS delivery error: %d.",
+			     vlr_subscr_name(conn->vsub), rc);
+	 		rc = GSM411_RP_CAUSE_MO_TEMP_FAIL;
+			/* rc will be logged by gsm411_send_rp_error() */
+			rate_ctr_inc(&conn->network->msc_ctrs->ctr[
+					MSC_CTR_SMS_DELIVER_UNKNOWN_ERROR]);
+		}
+#else
+		rc = GSM411_RP_CAUSE_MO_NUM_UNASSIGNED;
+		rate_ctr_inc(&conn->network->msc_ctrs->ctr[MSC_CTR_SMS_NO_RECEIVER]);
+#endif
+	} else
+		rc = 0;
+
+	return rc;
+}
+
+
+/* process an incoming TPDU (called from RP-DATA)
+ * return value > 0: RP CAUSE for ERROR; < 0: silent error; 0 = success */
+static int gsm340_rx_tpdu(struct gsm_trans *trans, struct msgb *msg,
+			  uint32_t gsm411_msg_ref)
+{
+	struct gsm_subscriber_connection *conn = trans->conn;
+	uint8_t *smsp = msgb_sms(msg);
+	struct gsm_sms *gsms;
+	unsigned int sms_alphabet;
+	uint8_t sms_mti, sms_vpf;
+	uint8_t *sms_vp;
+	uint8_t da_len_bytes;
+	uint8_t address_lv[12]; /* according to 03.40 / 9.1.2.5 */
+	int rc = 0;
+
+	rate_ctr_inc(&conn->network->msc_ctrs->ctr[MSC_CTR_SMS_SUBMITTED]);
+
+	gsms = sms_alloc();
+	if (!gsms)
+		return GSM411_RP_CAUSE_MO_NET_OUT_OF_ORDER;
+
+	/* invert those fields where 0 means active/present */
+	sms_mti = *smsp & 0x03;
+	sms_vpf = (*smsp & 0x18) >> 3;
+	gsms->status_rep_req = (*smsp & 0x20) >> 5;
+	gsms->ud_hdr_ind = (*smsp & 0x40);
+	/*
+	 * Not evaluating MMS (More Messages to Send) because the
+	 * lchan stays open anyway.
+	 * Not evaluating RP (Reply Path) because we're not aware of its
+	 * benefits.
+	 */
+
+	smsp++;
+	gsms->msg_ref = *smsp++;
+
+	gsms->gsm411.transaction_id = trans->transaction_id;
+	gsms->gsm411.msg_ref = gsm411_msg_ref;
+
+	/* length in bytes of the destination address */
+	da_len_bytes = 2 + *smsp/2 + *smsp%2;
+	if (da_len_bytes > 12) {
+		LOGP(DLSMS, LOGL_ERROR, "Destination Address > 12 bytes ?!?\n");
+		rc = GSM411_RP_CAUSE_SEMANT_INC_MSG;
+		goto out;
+	} else if (da_len_bytes < 4) {
+		LOGP(DLSMS, LOGL_ERROR, "Destination Address < 4 bytes ?!?\n");
+		rc = GSM411_RP_CAUSE_SEMANT_INC_MSG;
+		goto out;
+	}
+	memset(address_lv, 0, sizeof(address_lv));
+	memcpy(address_lv, smsp, da_len_bytes);
+	/* mangle first byte to reflect length in bytes, not digits */
+	address_lv[0] = da_len_bytes - 1;
+
+	gsms->dst.ton = (address_lv[1] >> 4) & 7;
+	gsms->dst.npi = address_lv[1] & 0xF;
+	/* convert to real number */
+	gsm48_decode_bcd_number(gsms->dst.addr,
+				sizeof(gsms->dst.addr), address_lv, 1);
+	smsp += da_len_bytes;
+
+	gsms->protocol_id = *smsp++;
+	gsms->data_coding_scheme = *smsp++;
+
+	sms_alphabet = gsm338_get_sms_alphabet(gsms->data_coding_scheme);
+	if (sms_alphabet == 0xffffffff) {
+		rc = GSM411_RP_CAUSE_MO_NET_OUT_OF_ORDER;
+		goto out;
+	}
+
+	switch (sms_vpf) {
+	case GSM340_TP_VPF_RELATIVE:
+		sms_vp = smsp++;
+		break;
+	case GSM340_TP_VPF_ABSOLUTE:
+	case GSM340_TP_VPF_ENHANCED:
+		sms_vp = smsp;
+		/* the additional functionality indicator... */
+		if (sms_vpf == GSM340_TP_VPF_ENHANCED && *smsp & (1<<7))
+			smsp++;
+		smsp += 7;
+		break;
+	case GSM340_TP_VPF_NONE:
+		sms_vp = 0;
+		break;
+	default:
+		LOGP(DLSMS, LOGL_NOTICE,
+		     "SMS Validity period not implemented: 0x%02x\n", sms_vpf);
+		rc = GSM411_RP_CAUSE_MO_NET_OUT_OF_ORDER;
+		goto out;
+	}
+	gsms->user_data_len = *smsp++;
+	if (gsms->user_data_len) {
+		memcpy(gsms->user_data, smsp, gsms->user_data_len);
+
+		switch (sms_alphabet) {
+		case DCS_7BIT_DEFAULT:
+			gsm_7bit_decode_n(gsms->text, sizeof(gsms->text), smsp,
+					  gsms->user_data_len);
+			break;
+		case DCS_8BIT_DATA:
+		case DCS_UCS2:
+		case DCS_NONE:
+			break;
+		}
+	}
+
+	OSMO_STRLCPY_ARRAY(gsms->src.addr, conn->vsub->msisdn);
+
+	LOGP(DLSMS, LOGL_INFO, "RX SMS: Sender: %s, MTI: 0x%02x, VPF: 0x%02x, "
+	     "MR: 0x%02x PID: 0x%02x, DCS: 0x%02x, DA: %s, "
+	     "UserDataLength: 0x%02x, UserData: \"%s\"\n",
+	     vlr_subscr_name(conn->vsub), sms_mti, sms_vpf, gsms->msg_ref,
+	     gsms->protocol_id, gsms->data_coding_scheme, gsms->dst.addr,
+	     gsms->user_data_len,
+			sms_alphabet == DCS_7BIT_DEFAULT ? gsms->text :
+				osmo_hexdump(gsms->user_data, gsms->user_data_len));
+
+	gsms->validity_minutes = gsm340_validity_period(sms_vpf, sms_vp);
+
+	/* FIXME: This looks very wrong */
+	send_signal(0, NULL, gsms, 0);
+
+	rc = sms_route_mt_sms(conn, gsms);
+
+	/*
+	 * This SMS got routed through SMPP or no receiver exists.
+	 * In any case, we store it in the database for further processing.
+	 */
+
+	switch (sms_mti) {
+	case GSM340_SMS_SUBMIT_MS2SC:
+		/* MS is submitting a SMS */
+		rc = gsm340_rx_sms_submit(gsms);
+		break;
+	case GSM340_SMS_COMMAND_MS2SC:
+	case GSM340_SMS_DELIVER_REP_MS2SC:
+		LOGP(DLSMS, LOGL_NOTICE, "Unimplemented MTI 0x%02x\n", sms_mti);
+		rc = GSM411_RP_CAUSE_IE_NOTEXIST;
+		break;
+	default:
+		LOGP(DLSMS, LOGL_NOTICE, "Undefined MTI 0x%02x\n", sms_mti);
+		rc = GSM411_RP_CAUSE_IE_NOTEXIST;
+		break;
+	}
+out:
+	sms_free(gsms);
+
+	return rc;
+}
+
+/* Prefix msg with a RP-DATA header and send as SMR DATA */
+static int gsm411_rp_sendmsg(struct gsm411_smr_inst *inst, struct msgb *msg,
+			     uint8_t rp_msg_type, uint8_t rp_msg_ref,
+			     int rl_msg_type)
+{
+	struct gsm411_rp_hdr *rp;
+	uint8_t len = msg->len;
+
+	/* GSM 04.11 RP-DATA header */
+	rp = (struct gsm411_rp_hdr *)msgb_push(msg, sizeof(*rp));
+	rp->len = len + 2;
+	rp->msg_type = rp_msg_type;
+	rp->msg_ref = rp_msg_ref;
+
+	return gsm411_smr_send(inst, rl_msg_type, msg);
+}
+
+int gsm411_send_rp_ack(struct gsm_trans *trans, uint8_t msg_ref)
+{
+	struct msgb *msg = gsm411_msgb_alloc();
+
+	DEBUGP(DLSMS, "TX: SMS RP ACK\n");
+
+	return gsm411_rp_sendmsg(&trans->sms.smr_inst, msg, GSM411_MT_RP_ACK_MT,
+		msg_ref, GSM411_SM_RL_REPORT_REQ);
+}
+
+int gsm411_send_rp_error(struct gsm_trans *trans, uint8_t msg_ref,
+			 uint8_t cause)
+{
+	struct msgb *msg = gsm411_msgb_alloc();
+
+	msgb_tv_put(msg, 1, cause);
+
+	LOGP(DLSMS, LOGL_NOTICE, "TX: SMS RP ERROR, cause %d (%s)\n", cause,
+		get_value_string(gsm411_rp_cause_strs, cause));
+
+	return gsm411_rp_sendmsg(&trans->sms.smr_inst, msg,
+		GSM411_MT_RP_ERROR_MT, msg_ref, GSM411_SM_RL_REPORT_REQ);
+}
+
+/* Receive a 04.11 TPDU inside RP-DATA / user data */
+static int gsm411_rx_rp_ud(struct msgb *msg, struct gsm_trans *trans,
+			  struct gsm411_rp_hdr *rph)
+{
+	int rc = 0;
+
+	rc = gsm340_rx_tpdu(trans, msg, rph->msg_ref);
+	if (rc == 0)
+		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;
+}
+
+/* Receive a 04.11 RP-DATA message in accordance with Section 7.3.1.2 */
+static int gsm411_rx_rp_data(struct msgb *msg, struct gsm_trans *trans,
+			     struct gsm411_rp_hdr *rph)
+{
+	uint8_t src_len, dst_len, rpud_len;
+	uint8_t *src = NULL, *dst = NULL , *rp_ud = NULL;
+
+	/* in the MO case, this should always be zero length */
+	src_len = rph->data[0];
+	if (src_len)
+		src = &rph->data[1];
+
+	dst_len = rph->data[1+src_len];
+	if (dst_len)
+		dst = &rph->data[1+src_len+1];
+
+	rpud_len = rph->data[1+src_len+1+dst_len];
+	if (rpud_len)
+		rp_ud = &rph->data[1+src_len+1+dst_len+1];
+
+	DEBUGP(DLSMS, "RX_RP-DATA: src_len=%u, dst_len=%u ud_len=%u\n",
+		src_len, dst_len, rpud_len);
+
+	if (src_len && src)
+		LOGP(DLSMS, LOGL_ERROR, "RP-DATA (MO) with SRC ?!?\n");
+
+	if (!dst_len || !dst || !rpud_len || !rp_ud) {
+		LOGP(DLSMS, LOGL_ERROR,
+			"RP-DATA (MO) without DST or TPDU ?!?\n");
+		gsm411_send_rp_error(trans, rph->msg_ref,
+				     GSM411_RP_CAUSE_INV_MAND_INF);
+		return -EIO;
+	}
+
+	msg->l4h = rp_ud;
+
+	DEBUGP(DLSMS, "DST(%u,%s)\n", dst_len, osmo_hexdump(dst, dst_len));
+
+	return gsm411_rx_rp_ud(msg, trans, rph);
+}
+
+static struct gsm_sms *sms_report_alloc(struct gsm_sms *sms)
+{
+	struct gsm_sms *sms_report;
+	int len;
+
+	sms_report = sms_alloc();
+	OSMO_ASSERT(sms_report);
+
+	sms_report->msg_ref = sms->msg_ref;
+	sms_report->protocol_id = sms->protocol_id;
+	sms_report->data_coding_scheme = GSM338_DCS_1111_8BIT_DATA;
+
+	/* Invert address to send status report back to origin. */
+	sms_report->src = sms->dst;
+	sms_report->dst = sms->src;
+
+	/* As specified by Appendix B. Delivery Receipt Format.
+	 * TODO: Many fields in this string are just set with dummy values,
+	 * 	 revisit this.
+	 */
+	len = snprintf((char *)sms_report->user_data,
+		       sizeof(sms_report->user_data),
+		       "id:%.08llu sub:000 dlvrd:000 submit date:YYMMDDhhmm done date:YYMMDDhhmm stat:DELIVRD err:000 text:%.20s",
+		       sms->id, sms->text);
+	sms_report->user_data_len = len;
+	LOGP(DLSMS, LOGL_NOTICE, "%s\n", sms_report->user_data);
+
+	/* This represents a sms report. */
+	sms_report->is_report = true;
+
+	return sms_report;
+}
+
+static void sms_status_report(struct gsm_sms *gsms,
+			      struct gsm_subscriber_connection *conn)
+{
+	struct gsm_sms *sms_report;
+	int rc;
+
+	sms_report = sms_report_alloc(gsms);
+
+	rc = sms_route_mt_sms(conn, sms_report);
+	if (rc < 0) {
+		LOGP(DLSMS, LOGL_ERROR,
+		     "Failed to send status report! err=%d\n", rc);
+	}
+
+	/* No route via SMPP, send the GSM 03.40 status-report now. */
+	if (sms_report->receiver)
+		gsm340_rx_sms_submit(sms_report);
+
+	LOGP(DLSMS, LOGL_NOTICE, "Status report has been sent\n");
+
+	sms_free(sms_report);
+}
+
+/* Receive a 04.11 RP-ACK message (response to RP-DATA from us) */
+static int gsm411_rx_rp_ack(struct gsm_trans *trans,
+			    struct gsm411_rp_hdr *rph)
+{
+	struct gsm_sms *sms = trans->sms.sms;
+
+	/* Acnkowledgement to MT RP_DATA, i.e. the MS confirms it
+	 * successfully received a SMS.  We can now safely mark it as
+	 * transmitted */
+
+	if (!sms) {
+		LOGP(DLSMS, LOGL_ERROR, "RX RP-ACK but no sms in transaction?!?\n");
+		return gsm411_send_rp_error(trans, rph->msg_ref,
+					    GSM411_RP_CAUSE_PROTOCOL_ERR);
+	}
+
+	/* mark this SMS as sent in database */
+	db_sms_mark_delivered(sms);
+
+	send_signal(S_SMS_DELIVERED, trans, sms, 0);
+
+	if (sms->status_rep_req)
+		sms_status_report(sms, trans->conn);
+
+	sms_free(sms);
+	trans->sms.sms = NULL;
+
+	return 0;
+}
+
+static int gsm411_rx_rp_error(struct gsm_trans *trans,
+			      struct gsm411_rp_hdr *rph)
+{
+	struct gsm_network *net = trans->conn->network;
+	struct gsm_sms *sms = trans->sms.sms;
+	uint8_t cause_len = rph->data[0];
+	uint8_t cause = rph->data[1];
+
+	/* Error in response to MT RP_DATA, i.e. the MS did not
+	 * successfully receive the SMS.  We need to investigate
+	 * the cause and take action depending on it */
+
+	LOGP(DLSMS, LOGL_NOTICE, "%s: RX SMS RP-ERROR, cause %d:%d (%s)\n",
+	     vlr_subscr_name(trans->conn->vsub), cause_len, cause,
+	     get_value_string(gsm411_rp_cause_strs, cause));
+
+	if (!sms) {
+		LOGP(DLSMS, LOGL_ERROR,
+			"RX RP-ERR, but no sms in transaction?!?\n");
+		return -EINVAL;
+#if 0
+		return gsm411_send_rp_error(trans, rph->msg_ref,
+					    GSM411_RP_CAUSE_PROTOCOL_ERR);
+#endif
+	}
+
+	if (cause == GSM411_RP_CAUSE_MT_MEM_EXCEEDED) {
+		/* MS has not enough memory to store the message.  We need
+		 * 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]);
+	} else {
+		send_signal(S_SMS_UNKNOWN_ERROR, trans, sms, 0);
+		rate_ctr_inc(&net->msc_ctrs->ctr[MSC_CTR_SMS_RP_ERR_OTHER]);
+	}
+
+	sms_free(sms);
+	trans->sms.sms = NULL;
+
+	return 0;
+}
+
+static int gsm411_rx_rp_smma(struct msgb *msg, struct gsm_trans *trans,
+			     struct gsm411_rp_hdr *rph)
+{
+	int rc;
+
+	rc = gsm411_send_rp_ack(trans, rph->msg_ref);
+
+	/* MS tells us that it has memory for more SMS, we need
+	 * to check if we have any pending messages for it and then
+	 * transfer those */
+	send_signal(S_SMS_SMMA, trans, NULL, 0);
+
+	return rc;
+}
+
+/* receive RL DATA */
+static int gsm411_rx_rl_data(struct msgb *msg, struct gsm48_hdr *gh,
+			     struct gsm_trans *trans)
+{
+	struct gsm411_rp_hdr *rp_data = (struct gsm411_rp_hdr*)&gh->data;
+	uint8_t msg_type =  rp_data->msg_type & 0x07;
+	int rc = 0;
+
+	switch (msg_type) {
+	case GSM411_MT_RP_DATA_MO:
+		DEBUGP(DLSMS, "RX SMS RP-DATA (MO)\n");
+		rc = gsm411_rx_rp_data(msg, trans, rp_data);
+		break;
+	case GSM411_MT_RP_SMMA_MO:
+		DEBUGP(DLSMS, "RX SMS RP-SMMA\n");
+		rc = gsm411_rx_rp_smma(msg, trans, rp_data);
+		break;
+	default:
+		LOGP(DLSMS, LOGL_NOTICE, "Invalid RP type 0x%02x\n", msg_type);
+		rc = -EINVAL;
+		break;
+	}
+
+	return rc;
+}
+
+/* receive RL REPORT */
+static int gsm411_rx_rl_report(struct msgb *msg, struct gsm48_hdr *gh,
+			     struct gsm_trans *trans)
+{
+	struct gsm411_rp_hdr *rp_data = (struct gsm411_rp_hdr*)&gh->data;
+	uint8_t msg_type =  rp_data->msg_type & 0x07;
+	int rc = 0;
+
+	switch (msg_type) {
+	case GSM411_MT_RP_ACK_MO:
+		DEBUGP(DLSMS, "RX SMS RP-ACK (MO)\n");
+		rc = gsm411_rx_rp_ack(trans, rp_data);
+		break;
+	case GSM411_MT_RP_ERROR_MO:
+		DEBUGP(DLSMS, "RX SMS RP-ERROR (MO)\n");
+		rc = gsm411_rx_rp_error(trans, rp_data);
+		break;
+	default:
+		LOGP(DLSMS, LOGL_NOTICE, "Invalid RP type 0x%02x\n", msg_type);
+		rc = -EINVAL;
+		break;
+	}
+
+	return rc;
+}
+
+/* receive SM-RL sap message from SMR
+ * NOTE: Message is freed by sender
+ */
+int gsm411_rl_recv(struct gsm411_smr_inst *inst, int msg_type,
+                        struct msgb *msg)
+{
+	struct gsm_trans *trans =
+		container_of(inst, struct gsm_trans, sms.smr_inst);
+	struct gsm48_hdr *gh = msgb_l3(msg);
+	int rc = 0;
+
+	switch (msg_type) {
+	case GSM411_SM_RL_DATA_IND:
+		rc = gsm411_rx_rl_data(msg, gh, trans);
+		break;
+	case GSM411_SM_RL_REPORT_IND:
+		if (gh)
+			rc = gsm411_rx_rl_report(msg, gh, trans);
+		break;
+	default:
+		LOGP(DLSMS, LOGL_NOTICE, "Unhandled SM-RL message 0x%x\n", msg_type);
+		rc = -EINVAL;
+	}
+
+	return rc;
+}
+
+/* receive MNCCSMS sap message from SMC
+ * NOTE: Message is freed by sender
+ */
+static int gsm411_mn_recv(struct gsm411_smc_inst *inst, int msg_type,
+			struct msgb *msg)
+{
+	struct gsm_trans *trans =
+		container_of(inst, struct gsm_trans, sms.smc_inst);
+	struct gsm48_hdr *gh = msgb_l3(msg);
+	int rc = 0;
+
+	switch (msg_type) {
+	case GSM411_MNSMS_EST_IND:
+	case GSM411_MNSMS_DATA_IND:
+		DEBUGP(DLSMS, "MNSMS-DATA/EST-IND\n");
+		rc = gsm411_smr_recv(&trans->sms.smr_inst, msg_type, msg);
+		break;
+	case GSM411_MNSMS_ERROR_IND:
+		if (gh)
+			DEBUGP(DLSMS, "MNSMS-ERROR-IND, cause %d (%s)\n",
+				gh->data[0],
+				get_value_string(gsm411_cp_cause_strs,
+				gh->data[0]));
+		else
+			DEBUGP(DLSMS, "MNSMS-ERROR-IND, no cause\n");
+		rc = gsm411_smr_recv(&trans->sms.smr_inst, msg_type, msg);
+		break;
+	default:
+		LOGP(DLSMS, LOGL_NOTICE, "Unhandled MNCCSMS msg 0x%x\n", msg_type);
+		rc = -EINVAL;
+	}
+
+	return rc;
+}
+
+/* Entry point for incoming GSM48_PDISC_SMS from abis_rsl.c */
+int gsm0411_rcv_sms(struct gsm_subscriber_connection *conn,
+		    struct msgb *msg)
+{
+	struct gsm48_hdr *gh = msgb_l3(msg);
+	uint8_t msg_type = gh->msg_type;
+	uint8_t transaction_id = gsm48_hdr_trans_id_flip_ti(gh);
+	struct gsm_trans *trans;
+	int new_trans = 0;
+	int rc = 0;
+
+	if (!conn->vsub)
+		return -EIO;
+		/* FIXME: send some error message */
+
+	DEBUGP(DLSMS, "receiving data (trans_id=%x, msg_type=%s)\n", transaction_id,
+	       gsm48_pdisc_msgtype_name(gsm48_hdr_pdisc(gh), gsm48_hdr_msg_type(gh)));
+
+	trans = trans_find_by_id(conn, GSM48_PDISC_SMS, transaction_id);
+
+	/*
+	 * A transaction we created but don't know about?
+	 */
+	if (!trans && (transaction_id & 0x8) == 0) {
+		LOGP(DLSMS, LOGL_ERROR, "trans_id=%x allocated by us but known "
+			"to us anymore. We are ignoring it, maybe a CP-ERROR "
+			"from a MS?\n",
+			transaction_id);
+		return -EINVAL;
+	}
+
+	if (!trans) {
+		DEBUGP(DLSMS, " -> (new transaction)\n");
+		trans = trans_alloc(conn->network, conn->vsub,
+				    GSM48_PDISC_SMS,
+				    transaction_id, new_callref++);
+		if (!trans) {
+			DEBUGP(DLSMS, " -> No memory for trans\n");
+			/* FIXME: send some error message */
+			return -ENOMEM;
+		}
+		gsm411_smc_init(&trans->sms.smc_inst, 0, 1,
+			gsm411_mn_recv, gsm411_mm_send);
+		gsm411_smr_init(&trans->sms.smr_inst, 0, 1,
+			gsm411_rl_recv, gsm411_mn_send);
+
+		trans->conn = msc_subscr_conn_get(conn, MSC_CONN_USE_TRANS_SMS);
+		trans->dlci = OMSC_LINKID_CB(msg); /* DLCI as received from BSC */
+
+		new_trans = 1;
+		cm_service_request_concludes(conn, msg);
+	}
+
+	/* 5.4: For MO, if a CP-DATA is received for a new
+	 * transaction, equals reception of an implicit
+	 * last CP-ACK for previous transaction */
+	if (trans->sms.smc_inst.cp_state == GSM411_CPS_IDLE
+	 && msg_type == GSM411_MT_CP_DATA) {
+		int i;
+		struct gsm_trans *ptrans;
+
+		/* Scan through all remote initiated transactions */
+		for (i=8; i<15; i++) {
+			if (i == transaction_id)
+				continue;
+
+			ptrans = trans_find_by_id(conn, GSM48_PDISC_SMS, i);
+			if (!ptrans)
+				continue;
+
+			DEBUGP(DLSMS, "Implicit CP-ACK for trans_id=%x\n", i);
+
+			/* Finish it for good */
+			trans_free(ptrans);
+		}
+	}
+
+	msc_subscr_conn_communicating(conn);
+
+	gsm411_smc_recv(&trans->sms.smc_inst,
+		(new_trans) ? GSM411_MMSMS_EST_IND : GSM411_MMSMS_DATA_IND,
+		msg, msg_type);
+
+	return rc;
+}
+
+/* Take a SMS in gsm_sms structure and send it through an already
+ * existing conn. We also assume that the caller ensured this conn already
+ * has a SAPI3 RLL connection! */
+int gsm411_send_sms(struct gsm_subscriber_connection *conn, struct gsm_sms *sms)
+{
+	struct msgb *msg = gsm411_msgb_alloc();
+	struct gsm_trans *trans;
+	uint8_t *data, *rp_ud_len;
+	uint8_t msg_ref = conn->next_rp_ref++;
+	int transaction_id;
+	int rc;
+
+	transaction_id =
+		trans_assign_trans_id(conn->network, conn->vsub,
+				      GSM48_PDISC_SMS, 0);
+	if (transaction_id == -1) {
+		LOGP(DLSMS, LOGL_ERROR, "No available transaction ids\n");
+		send_signal(S_SMS_UNKNOWN_ERROR, NULL, sms, 0);
+		sms_free(sms);
+		msgb_free(msg);
+		return -EBUSY;
+	}
+
+	DEBUGP(DLSMS, "%s()\n", __func__);
+
+	/* FIXME: allocate transaction with message reference */
+	trans = trans_alloc(conn->network, conn->vsub,
+			    GSM48_PDISC_SMS,
+			    transaction_id, new_callref++);
+	if (!trans) {
+		LOGP(DLSMS, LOGL_ERROR, "No memory for trans\n");
+		send_signal(S_SMS_UNKNOWN_ERROR, NULL, sms, 0);
+		sms_free(sms);
+		msgb_free(msg);
+		/* FIXME: send some error message */
+		return -ENOMEM;
+	}
+	gsm411_smc_init(&trans->sms.smc_inst, sms->id, 1,
+		gsm411_mn_recv, gsm411_mm_send);
+	gsm411_smr_init(&trans->sms.smr_inst, sms->id, 1,
+		gsm411_rl_recv, gsm411_mn_send);
+	trans->sms.sms = sms;
+
+	trans->conn = msc_subscr_conn_get(conn, MSC_CONN_USE_TRANS_SMS);
+	trans->dlci = 0x03;
+	/* FIXME: specify SACCH in case we already have active TCH */
+
+	/* Hardcode SMSC Originating Address for now */
+	data = (uint8_t *)msgb_put(msg, 8);
+	data[0] = 0x07;	/* originator length == 7 */
+	data[1] = 0x91; /* type of number: international, ISDN */
+	data[2] = 0x44; /* 447785016005 */
+	data[3] = 0x77;
+	data[4] = 0x58;
+	data[5] = 0x10;
+	data[6] = 0x06;
+	data[7] = 0x50;
+
+	/* Hardcoded Destination Address */
+	data = (uint8_t *)msgb_put(msg, 1);
+	data[0] = 0;	/* destination length == 0 */
+
+	/* obtain a pointer for the rp_ud_len, so we can fill it later */
+	rp_ud_len = (uint8_t *)msgb_put(msg, 1);
+
+	if (sms->is_report) {
+		/* generate the 03.40 SMS-STATUS-REPORT TPDU */
+		rc = gsm340_gen_sms_status_report_tpdu(msg, sms);
+	} else {
+		/* generate the 03.40 SMS-DELIVER TPDU */
+		rc = gsm340_gen_sms_deliver_tpdu(msg, sms);
+	}
+	if (rc < 0) {
+		send_signal(S_SMS_UNKNOWN_ERROR, trans, sms, 0);
+		sms_free(sms);
+		trans->sms.sms = NULL;
+		trans_free(trans);
+		msgb_free(msg);
+		return rc;
+	}
+
+	*rp_ud_len = rc;
+
+	DEBUGP(DLSMS, "TX: SMS DELIVER\n");
+
+	rate_ctr_inc(&conn->network->msc_ctrs->ctr[MSC_CTR_SMS_DELIVERED]);
+	db_sms_inc_deliver_attempts(trans->sms.sms);
+
+	return gsm411_rp_sendmsg(&trans->sms.smr_inst, msg,
+		GSM411_MT_RP_DATA_MT, msg_ref, GSM411_SM_RL_DATA_REQ);
+}
+
+/* paging callback. Here we get called if paging a subscriber has
+ * succeeded or failed. */
+static int paging_cb_send_sms(unsigned int hooknum, unsigned int event,
+			      struct msgb *msg, void *_conn, void *_sms)
+{
+	struct gsm_subscriber_connection *conn = _conn;
+	struct gsm_sms *sms = _sms;
+	int rc = 0;
+
+	DEBUGP(DLSMS, "paging_cb_send_sms(hooknum=%u, event=%u, msg=%p,"
+		"conn=%p, sms=%p/id: %llu)\n", hooknum, event, msg, conn, sms, sms->id);
+
+	if (hooknum != GSM_HOOK_RR_PAGING)
+		return -EINVAL;
+
+	switch (event) {
+	case GSM_PAGING_SUCCEEDED:
+		gsm411_send_sms(conn, sms);
+		break;
+	case GSM_PAGING_EXPIRED:
+	case GSM_PAGING_BUSY:
+		send_signal(S_SMS_UNKNOWN_ERROR, NULL, sms, event);
+		sms_free(sms);
+		rc = -ETIMEDOUT;
+		break;
+	default:
+		LOGP(DLSMS, LOGL_ERROR, "Unhandled paging event: %d\n", event);
+	}
+
+	return rc;
+}
+
+/* high-level function to send a SMS to a given subscriber. The function
+ * will take care of paging the subscriber, establishing the RLL SAPI3
+ * connection, etc. */
+int gsm411_send_sms_subscr(struct vlr_subscr *vsub,
+			   struct gsm_sms *sms)
+{
+	struct gsm_subscriber_connection *conn;
+	void *res;
+
+	/* check if we already have an open conn to the subscriber.
+	 * if yes, send the SMS this way */
+	conn = connection_for_subscr(vsub);
+	if (conn) {
+		LOGP(DLSMS, LOGL_DEBUG, "Sending SMS via already open connection %p to %s\n",
+		     conn, vlr_subscr_name(vsub));
+		return gsm411_send_sms(conn, sms);
+	}
+
+	/* if not, we have to start paging */
+	LOGP(DLSMS, LOGL_DEBUG, "Sending SMS: no connection open, start paging %s\n",
+	     vlr_subscr_name(vsub));
+	res = subscr_request_conn(vsub, paging_cb_send_sms, sms, "send SMS");
+	if (!res) {
+		send_signal(S_SMS_UNKNOWN_ERROR, NULL, sms, GSM_PAGING_BUSY);
+		sms_free(sms);
+	}
+	return 0;
+}
+
+void _gsm411_sms_trans_free(struct gsm_trans *trans)
+{
+	/* cleanup SMS instance */
+	gsm411_smr_clear(&trans->sms.smr_inst);
+	trans->sms.smr_inst.rl_recv = NULL;
+	trans->sms.smr_inst.mn_send = NULL;
+
+	gsm411_smc_clear(&trans->sms.smc_inst);
+	trans->sms.smc_inst.mn_recv = NULL;
+	trans->sms.smc_inst.mm_send = NULL;
+
+	if (trans->sms.sms) {
+		LOGP(DLSMS, LOGL_ERROR, "Transaction contains SMS.\n");
+		send_signal(S_SMS_UNKNOWN_ERROR, trans, trans->sms.sms, 0);
+		sms_free(trans->sms.sms);
+		trans->sms.sms = NULL;
+	}
+}
+
+/* Process incoming SAPI N-REJECT from BSC */
+void gsm411_sapi_n_reject(struct gsm_subscriber_connection *conn)
+{
+	struct gsm_network *net;
+	struct gsm_trans *trans, *tmp;
+
+	net = conn->network;
+
+	llist_for_each_entry_safe(trans, tmp, &net->trans_list, entry) {
+		struct gsm_sms *sms;
+
+		if (trans->conn != conn)
+			continue;
+		if (trans->protocol != GSM48_PDISC_SMS)
+			continue;
+
+		sms = trans->sms.sms;
+		if (!sms) {
+			LOGP(DLSMS, LOGL_ERROR, "SAPI Reject but no SMS.\n");
+			continue;
+		}
+
+		send_signal(S_SMS_UNKNOWN_ERROR, trans, sms, 0);
+		sms_free(sms);
+		trans->sms.sms = NULL;
+		trans_free(trans);
+	}
+}
+
diff --git a/src/libmsc/gsm_04_14.c b/src/libmsc/gsm_04_14.c
new file mode 100644
index 0000000..2be534c
--- /dev/null
+++ b/src/libmsc/gsm_04_14.c
@@ -0,0 +1,131 @@
+/* GSM MS Testing  Layer 3 messages
+ * 3GPP TS 44.014 / GSM TS 04.14 */
+
+/* (C) 2017 by Harald Welte <laforge@gnumonks.org>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+
+#include "bscconfig.h"
+
+#include <osmocom/msc/debug.h>
+#include <osmocom/msc/gsm_data.h>
+#include <osmocom/msc/gsm_subscriber.h>
+#include <osmocom/msc/gsm_04_08.h>
+#include <osmocom/msc/msc_ifaces.h>
+
+#include <osmocom/gsm/gsm48.h>
+#include <osmocom/gsm/gsm_utils.h>
+#include <osmocom/gsm/protocol/gsm_04_14.h>
+#include <osmocom/gsm/tlv.h>
+#include <osmocom/core/msgb.h>
+#include <osmocom/core/talloc.h>
+#include <osmocom/core/utils.h>
+
+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->proto_discr = GSM48_PDISC_TEST;
+	gh->msg_type = msg_type;
+	return msg;
+}
+
+static int gsm0414_conn_sendmsg(struct gsm_subscriber_connection *conn, struct msgb *msg)
+{
+	return msc_tx_dtap(conn, msg);
+}
+
+static int gsm0414_tx_simple(struct gsm_subscriber_connection *conn, uint8_t msg_type)
+{
+	struct msgb *msg = create_gsm0414_msg(msg_type);
+
+	return gsm0414_conn_sendmsg(conn, msg);
+}
+
+
+/* Send a CLOSE_TCH_LOOOP_CMD according to Section 8.1 */
+int gsm0414_tx_close_tch_loop_cmd(struct gsm_subscriber_connection *conn,
+				  enum gsm414_tch_loop_mode loop_mode)
+{
+	struct msgb *msg = create_gsm0414_msg(GSM414_MT_CLOSE_TCH_LOOP_CMD);
+	uint8_t subch;
+
+	subch = (loop_mode << 1);
+	msgb_put_u8(msg, subch);
+
+	return gsm0414_conn_sendmsg(conn, msg);
+}
+
+/* Send a OPEN_LOOP_CMD according to Section 8.3 */
+int gsm0414_tx_open_loop_cmd(struct gsm_subscriber_connection *conn)
+{
+	return gsm0414_tx_simple(conn, GSM414_MT_OPEN_LOOP_CMD);
+}
+
+/* Send a ACT_EMMI_CMD according to Section 8.8 */
+int gsm0414_tx_act_emmi_cmd(struct gsm_subscriber_connection *conn)
+{
+	return gsm0414_tx_simple(conn, GSM414_MT_ACT_EMMI_CMD);
+}
+
+/* Send a DEACT_EMMI_CMD according to Section 8.10 */
+int gsm0414_tx_deact_emmi_cmd(struct gsm_subscriber_connection *conn)
+{
+	return gsm0414_tx_simple(conn, GSM414_MT_DEACT_EMMI_CMD);
+}
+
+/* Send a TEST_INTERFACE according to Section 8.11 */
+int gsm0414_tx_test_interface(struct gsm_subscriber_connection *conn,
+			      uint8_t tested_devs)
+{
+	struct msgb *msg = create_gsm0414_msg(GSM414_MT_TEST_INTERFACE);
+	msgb_put_u8(msg, tested_devs);
+	return gsm0414_conn_sendmsg(conn, msg);
+}
+
+/* Send a RESET_MS_POSITION_STORED according to Section 8.11 */
+int gsm0414_tx_reset_ms_pos_store(struct gsm_subscriber_connection *conn,
+				  uint8_t technology)
+{
+	struct msgb *msg = create_gsm0414_msg(GSM414_MT_RESET_MS_POS_STORED);
+	msgb_put_u8(msg, technology);
+	return gsm0414_conn_sendmsg(conn, msg);
+}
+
+
+
+/* Entry point for incoming GSM48_PDISC_TEST received from MS */
+int gsm0414_rcv_test(struct gsm_subscriber_connection *conn,
+		     struct msgb *msg)
+{
+	struct gsm48_hdr *gh = msgb_l3(msg);
+
+	if (msgb_l3len(msg) < sizeof(*gh))
+		return -1;
+
+	LOGP(DMM, LOGL_NOTICE, "%s: Received TEST class message '%s'\n", "FIXME",
+		get_value_string(gsm414_msgt_names, gh->msg_type));
+
+	return 0;
+}
diff --git a/src/libmsc/gsm_04_80.c b/src/libmsc/gsm_04_80.c
new file mode 100644
index 0000000..81f2001
--- /dev/null
+++ b/src/libmsc/gsm_04_80.c
@@ -0,0 +1,87 @@
+/* GSM Mobile Radio Interface Layer 3 messages on the A-bis interface
+ * 3GPP TS 04.08 version 7.21.0 Release 1998 / ETSI TS 100 940 V7.21.0 */
+
+/* (C) 2008-2009 by Harald Welte <laforge@gnumonks.org>
+ * (C) 2008, 2009, 2010 by Holger Hans Peter Freyther <zecke@selfish.org>
+ * (C) 2009 by Mike Haben <michael.haben@btinternet.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 <stdint.h>
+#include <errno.h>
+
+#include <osmocom/msc/gsm_04_80.h>
+#include <osmocom/msc/msc_ifaces.h>
+
+#include <osmocom/gsm/protocol/gsm_04_80.h>
+#include <osmocom/gsm/gsm0480.h>
+#include <osmocom/core/msgb.h>
+#include <osmocom/gsm/tlv.h>
+
+/*! Send a MT RELEASE COMPLETE message with Reject component
+ *  (see section 3.6.1) and given error code (see section 3.6.7).
+ *
+ * \param[in]  conn            Active subscriber connection
+ * \param[in]  transaction_id  Transaction ID with TI flag set
+ * \param[in]  invoke_id       InvokeID of the request
+ * \param[in]  problem_tag     Problem code tag (table 3.13)
+ * \param[in]  problem_code    Problem code (tables 3.14-17)
+ * \return     result of \ref msc_tx_dtap
+ *
+ * Note: if InvokeID is not available, e.g. when message parsing
+ * failed, any incorrect value can be passed (0x00 > x > 0xff), so
+ * the universal NULL-tag (see table 3.6) will be used instead.
+ */
+int msc_send_ussd_reject(struct gsm_subscriber_connection *conn,
+			     uint8_t transaction_id, int invoke_id,
+			     uint8_t problem_tag, uint8_t problem_code)
+{
+	struct gsm48_hdr *gh;
+	struct msgb *msg;
+
+	msg = gsm0480_gen_reject(invoke_id, problem_tag, problem_code);
+	if (!msg)
+		return -1;
+
+	/* Wrap the component in a Facility message */
+	msgb_wrap_with_TL(msg, GSM0480_IE_FACILITY);
+
+	/* And finally pre-pend the L3 header */
+	gh = (struct gsm48_hdr *) msgb_push(msg, sizeof(*gh));
+	gh->proto_discr  = GSM48_PDISC_NC_SS;
+	gh->proto_discr |= transaction_id << 4;
+	gh->msg_type = GSM0480_MTYPE_RELEASE_COMPLETE;
+
+	return msc_tx_dtap(conn, msg);
+}
+
+int msc_send_ussd_notify(struct gsm_subscriber_connection *conn, int level, const char *text)
+{
+	struct msgb *msg = gsm0480_create_ussd_notify(level, text);
+	if (!msg)
+		return -1;
+	return msc_tx_dtap(conn, msg);
+}
+
+int msc_send_ussd_release_complete(struct gsm_subscriber_connection *conn)
+{
+	struct msgb *msg = gsm0480_create_ussd_release_complete();
+	if (!msg)
+		return -1;
+	return msc_tx_dtap(conn, msg);
+}
diff --git a/src/libmsc/gsm_09_11.c b/src/libmsc/gsm_09_11.c
new file mode 100644
index 0000000..b863ce8
--- /dev/null
+++ b/src/libmsc/gsm_09_11.c
@@ -0,0 +1,498 @@
+/* (C) 2008-2009 by Harald Welte <laforge@gnumonks.org>
+ * (C) 2008, 2009 by Holger Hans Peter Freyther <zecke@selfish.org>
+ * (C) 2009 by Mike Haben <michael.haben@btinternet.com>
+ * (C) 2018 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/>.
+ *
+ */
+
+/**
+ * MSC-specific handling of call independent Supplementary
+ * Services messages (NC_SS) according to GSM TS 09.11
+ * "Signalling interworking for supplementary services".
+ */
+
+#include <stdio.h>
+#include <errno.h>
+#include <stdbool.h>
+
+#include <osmocom/core/linuxlist.h>
+#include <osmocom/core/rate_ctr.h>
+#include <osmocom/core/utils.h>
+#include <osmocom/core/msgb.h>
+
+#include <osmocom/gsm/protocol/gsm_04_80.h>
+#include <osmocom/gsm/gsm0480.h>
+#include <osmocom/gsm/tlv.h>
+
+#include <osmocom/msc/gsm_04_80.h>
+#include <osmocom/msc/gsm_subscriber.h>
+#include <osmocom/msc/debug.h>
+#include <osmocom/msc/osmo_msc.h>
+#include <osmocom/msc/vlr.h>
+#include <osmocom/msc/gsm_04_08.h>
+#include <osmocom/msc/transaction.h>
+#include <osmocom/gsupclient/gsup_client.h>
+#include <osmocom/msc/msc_ifaces.h>
+
+/* FIXME: choose a proper range */
+static uint32_t new_callref = 0x20000001;
+
+/* Entry point for call independent MO SS messages */
+int gsm0911_rcv_nc_ss(struct gsm_subscriber_connection *conn, struct msgb *msg)
+{
+	struct gsm48_hdr *gh = msgb_l3(msg);
+	struct osmo_gsup_message gsup_msg;
+	struct gsm_trans *trans;
+	struct msgb *gsup_msgb;
+	uint16_t facility_ie_len;
+	uint8_t *facility_ie;
+	uint8_t pdisc, tid;
+	uint8_t msg_type;
+	int rc;
+
+	pdisc = gsm48_hdr_pdisc(gh);
+	msg_type = gsm48_hdr_msg_type(gh);
+	tid = gsm48_hdr_trans_id_flip_ti(gh);
+
+	/* Associate logging messages with this subscriber */
+	log_set_context(LOG_CTX_VLR_SUBSCR, conn->vsub);
+
+	DEBUGP(DMM, "Received SS/USSD data (trans_id=%x, msg_type=%s)\n",
+		tid, gsm48_pdisc_msgtype_name(pdisc, msg_type));
+
+	/* Reuse existing transaction, or create a new one */
+	trans = trans_find_by_id(conn, pdisc, tid);
+	if (!trans) {
+		/* Count MS-initiated attempts to establish a NC SS/USSD session */
+		rate_ctr_inc(&conn->network->msc_ctrs->ctr[MSC_CTR_NC_SS_MO_REQUESTS]);
+
+		/**
+		 * According to GSM TS 04.80, section 2.4.2 "Register
+		 * (mobile station to network direction)", the REGISTER
+		 * message is sent by the mobile station to the network
+		 * to assign a new transaction identifier for call independent
+		 * supplementary service control and to request or acknowledge
+		 * a supplementary service.
+		 */
+		if (msg_type != GSM0480_MTYPE_REGISTER) {
+			LOGP(DMM, LOGL_ERROR, "Unexpected message (msg_type=%s), "
+				"transaction is not allocated yet\n",
+				gsm48_pdisc_msgtype_name(pdisc, msg_type));
+			gsm48_tx_simple(conn,
+				GSM48_PDISC_NC_SS | (tid << 4),
+				GSM0480_MTYPE_RELEASE_COMPLETE);
+			return -EINVAL;
+		}
+
+		DEBUGP(DMM, " -> (new transaction)\n");
+		trans = trans_alloc(conn->network, conn->vsub,
+			pdisc, tid, new_callref++);
+		if (!trans) {
+			DEBUGP(DMM, " -> No memory for trans\n");
+			gsm48_tx_simple(conn,
+				GSM48_PDISC_NC_SS | (tid << 4),
+				GSM0480_MTYPE_RELEASE_COMPLETE);
+			return -ENOMEM;
+		}
+
+		/* Count active NC SS/USSD sessions */
+		osmo_counter_inc(conn->network->active_nc_ss);
+
+		trans->conn = msc_subscr_conn_get(conn, MSC_CONN_USE_TRANS_NC_SS);
+		trans->dlci = OMSC_LINKID_CB(msg);
+		cm_service_request_concludes(conn, msg);
+	}
+
+	/* Attempt to extract Facility IE */
+	rc = gsm0480_extract_ie_by_tag(gh, msgb_l3len(msg),
+		&facility_ie, &facility_ie_len, GSM0480_IE_FACILITY);
+	if (rc) {
+		LOGP(DMM, LOGL_ERROR, "GSM 04.80 message parsing error, "
+			"couldn't extract Facility IE\n");
+		goto error;
+	}
+
+	/* Facility IE is optional for RELEASE COMPLETE */
+	if (msg_type != GSM0480_MTYPE_RELEASE_COMPLETE) {
+		if (!facility_ie || facility_ie_len < 2) {
+			LOGP(DMM, LOGL_ERROR, "GSM 04.80 message parsing error, "
+				"missing mandatory Facility IE\n");
+			rc = -EINVAL;
+			goto error;
+		}
+	}
+
+	/* Compose a mew GSUP message */
+	memset(&gsup_msg, 0x00, sizeof(gsup_msg));
+	gsup_msg.message_type = OSMO_GSUP_MSGT_PROC_SS_REQUEST;
+	gsup_msg.session_id = trans->callref;
+
+	/**
+	 * Perform A-interface to GSUP-interface mapping,
+	 * according to GSM TS 09.11, table 4.2.
+	 */
+	switch (msg_type) {
+	case GSM0480_MTYPE_REGISTER:
+		gsup_msg.session_state = OSMO_GSUP_SESSION_STATE_BEGIN;
+		break;
+	case GSM0480_MTYPE_FACILITY:
+		gsup_msg.session_state = OSMO_GSUP_SESSION_STATE_CONTINUE;
+		break;
+	case GSM0480_MTYPE_RELEASE_COMPLETE:
+		gsup_msg.session_state = OSMO_GSUP_SESSION_STATE_END;
+		break;
+	}
+
+	/* Fill in the (optional) message payload */
+	if (facility_ie) {
+		gsup_msg.ss_info_len = facility_ie_len;
+		gsup_msg.ss_info = facility_ie;
+	}
+
+	/* Fill in subscriber's IMSI */
+	OSMO_STRLCPY_ARRAY(gsup_msg.imsi, conn->vsub->imsi);
+
+	/* Allocate GSUP message buffer */
+	gsup_msgb = osmo_gsup_client_msgb_alloc();
+	if (!gsup_msgb) {
+		LOGP(DMM, LOGL_ERROR, "Couldn't allocate GSUP message\n");
+		rc = -ENOMEM;
+		goto error;
+	}
+
+	/* Encode GSUP message */
+	rc = osmo_gsup_encode(gsup_msgb, &gsup_msg);
+	if (rc) {
+		LOGP(DMM, LOGL_ERROR, "Couldn't encode GSUP message\n");
+		goto error;
+	}
+
+	/* Finally send */
+	rc = osmo_gsup_client_send(conn->network->vlr->gsup_client, gsup_msgb);
+	if (rc) {
+		LOGP(DMM, LOGL_ERROR, "Couldn't send GSUP message\n");
+		goto error;
+	}
+
+	/* Should we release connection? Or wait for response? */
+	if (msg_type == GSM0480_MTYPE_RELEASE_COMPLETE)
+		trans_free(trans);
+	else
+		msc_subscr_conn_communicating(conn);
+
+	/* Count established MS-initiated NC SS/USSD sessions */
+	if (msg_type == GSM0480_MTYPE_REGISTER)
+		rate_ctr_inc(&conn->network->msc_ctrs->ctr[MSC_CTR_NC_SS_MO_ESTABLISHED]);
+
+	return 0;
+
+error:
+	/* Abort transaction on DTAP-interface */
+	msc_send_ussd_reject(conn, tid, -1,
+		GSM_0480_PROBLEM_CODE_TAG_GENERAL,
+		GSM_0480_GEN_PROB_CODE_UNRECOGNISED);
+	if (trans)
+		trans_free(trans);
+
+	/* TODO: abort transaction on GSUP interface if any */
+	return rc;
+}
+
+/* Call-back from paging the B-end of the connection */
+static int handle_paging_event(unsigned int hooknum, unsigned int event,
+			      struct msgb *msg, void *_conn, void *_transt)
+{
+	struct gsm_subscriber_connection *conn = _conn;
+	enum gsm_paging_event paging_event = event;
+	struct gsm_trans *transt = _transt;
+	struct gsm48_hdr *gh;
+	struct msgb *ss_msg;
+
+	OSMO_ASSERT(!transt->conn);
+	OSMO_ASSERT(transt->ss.msg);
+
+	switch (paging_event) {
+	case GSM_PAGING_SUCCEEDED:
+		DEBUGP(DMM, "Paging subscr %s succeeded!\n",
+			vlr_subscr_msisdn_or_name(transt->vsub));
+
+		/* Assign connection */
+		transt->conn = msc_subscr_conn_get(conn, MSC_CONN_USE_TRANS_NC_SS);
+		transt->paging_request = NULL;
+
+		/* Send stored message */
+		ss_msg = transt->ss.msg;
+		OSMO_ASSERT(ss_msg);
+
+		gh = (struct gsm48_hdr *) msgb_push(ss_msg, sizeof(*gh));
+		gh->proto_discr  = GSM48_PDISC_NC_SS;
+		gh->proto_discr |= transt->transaction_id << 4;
+		gh->msg_type = GSM0480_MTYPE_REGISTER;
+
+		/* Sent to the MS, give ownership of ss_msg */
+		msc_tx_dtap(transt->conn, ss_msg);
+		transt->ss.msg = NULL;
+
+		/* Count established network-initiated NC SS/USSD sessions */
+		rate_ctr_inc(&conn->network->msc_ctrs->ctr[MSC_CTR_NC_SS_MT_ESTABLISHED]);
+		break;
+	case GSM_PAGING_EXPIRED:
+	case GSM_PAGING_BUSY:
+		DEBUGP(DMM, "Paging subscr %s %s!\n",
+			vlr_subscr_msisdn_or_name(transt->vsub),
+			paging_event == GSM_PAGING_EXPIRED ? "expired" : "busy");
+
+		/* TODO: inform HLR about this failure */
+
+		msgb_free(transt->ss.msg);
+		transt->ss.msg = NULL;
+
+		transt->callref = 0;
+		transt->paging_request = NULL;
+		trans_free(transt);
+		break;
+	}
+
+	return 0;
+}
+
+static struct gsm_trans *establish_nc_ss_trans(struct gsm_network *net,
+	struct vlr_subscr *vsub, struct osmo_gsup_message *gsup_msg)
+{
+	struct gsm_subscriber_connection *conn;
+	struct gsm_trans *trans, *transt;
+	int tid;
+
+	if (gsup_msg->session_state != OSMO_GSUP_SESSION_STATE_BEGIN) {
+		LOGP(DMM, LOGL_ERROR, "Received non-BEGIN message "
+			"for non-existing transaction\n");
+		return NULL;
+	}
+
+	if (!gsup_msg->ss_info || gsup_msg->ss_info_len < 2) {
+		LOGP(DMM, LOGL_ERROR, "Missing mandatory Facility IE\n");
+		return NULL;
+	}
+
+	/* If subscriber is not "attached" */
+	if (!vsub->lac) {
+		LOGP(DMM, LOGL_ERROR, "Network-originated session "
+			"rejected - subscriber is not attached\n");
+		return NULL;
+	}
+
+	DEBUGP(DMM, "Establishing network-originated session\n");
+
+	/* Allocate a new transaction */
+	trans = trans_alloc(net, vsub, GSM48_PDISC_NC_SS,
+		0xff, gsup_msg->session_id);
+	if (!trans) {
+		DEBUGP(DMM, " -> No memory for trans\n");
+		return NULL;
+	}
+
+	/* 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, GSM48_PDISC_NC_SS, 0);
+	if (tid < 0) {
+		LOGP(DMM, LOGL_ERROR, "No free transaction ID\n");
+		/* TODO: inform HLR about this */
+		/* TODO: release connection with subscriber */
+		trans->callref = 0;
+		trans_free(trans);
+		return NULL;
+	}
+	trans->transaction_id = tid;
+
+	/* Attempt to find connection */
+	conn = connection_for_subscr(vsub);
+	if (conn) {
+		/* Assign connection */
+		trans->conn = msc_subscr_conn_get(conn, MSC_CONN_USE_TRANS_NC_SS);
+		trans->dlci = 0x00; /* SAPI=0, not SACCH */
+		return trans;
+	}
+
+	DEBUGP(DMM, "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;
+
+		LOGP(DMM, LOGL_ERROR, "Paging already started, "
+			"rejecting message...\n");
+		trans_free(trans);
+		return NULL;
+	}
+
+	/* Trigger Paging Request */
+	trans->paging_request = subscr_request_conn(vsub,
+		&handle_paging_event, trans, "GSM 09.11 SS/USSD");
+	if (!trans->paging_request) {
+		LOGP(DMM, LOGL_ERROR, "Failed to allocate paging token\n");
+		trans_free(trans);
+		return NULL;
+	}
+
+	/* Store the Facility IE to be sent */
+	OSMO_ASSERT(trans->ss.msg == NULL);
+	trans->ss.msg = gsm48_msgb_alloc_name("GSM 04.08 SS/USSD");
+	msgb_tlv_put(trans->ss.msg, GSM0480_IE_FACILITY,
+		gsup_msg->ss_info_len, gsup_msg->ss_info);
+
+	return NULL;
+}
+
+/* NC SS specific transaction release.
+ * Gets called by trans_free, DO NOT CALL YOURSELF! */
+void _gsm911_nc_ss_trans_free(struct gsm_trans *trans)
+{
+	/**
+	 * TODO: if transaction wasn't properly terminated,
+	 * we need to do it here by releasing the subscriber
+	 * connection and sending notification via GSUP...
+	 */
+	if (trans->ss.msg != NULL)
+		msgb_free(trans->ss.msg);
+
+	/* One session less */
+	osmo_counter_dec(trans->net->active_nc_ss);
+}
+
+int gsm0911_gsup_handler(struct vlr_subscr *vsub,
+			 struct osmo_gsup_message *gsup_msg)
+{
+	struct vlr_instance *vlr;
+	struct gsm_network *net;
+	struct gsm_trans *trans;
+	struct gsm48_hdr *gh;
+	struct msgb *ss_msg;
+	bool trans_end;
+
+	/* 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);
+
+	/* Handle errors */
+	if (OSMO_GSUP_IS_MSGT_ERROR(gsup_msg->message_type)) {
+		/* FIXME: handle this error somehow! */
+		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]);
+
+		/* Attempt to establish a new transaction */
+		trans = establish_nc_ss_trans(net, vsub, gsup_msg);
+		if (!trans) {
+			/* FIXME: send ERROR back to the HLR */
+			return -EINVAL;
+		}
+
+		/* Wait for Paging Response */
+		if (trans->paging_request)
+			return 0;
+	}
+
+	/* Allocate and prepare a new MT message */
+	ss_msg = gsm48_msgb_alloc_name("GSM 04.08 SS/USSD");
+	gh = (struct gsm48_hdr *) msgb_push(ss_msg, sizeof(*gh));
+	gh->proto_discr  = GSM48_PDISC_NC_SS;
+	gh->proto_discr |= trans->transaction_id << 4;
+
+	/**
+	 * Perform GSUP-interface to A-interface mapping,
+	 * according to GSM TS 09.11, table 4.1.
+	 *
+	 * TODO: see (note 3), both CONTINUE and END may
+	 * be also mapped to REGISTER if a new transaction
+	 * has to be established.
+	 */
+	switch (gsup_msg->session_state) {
+	case OSMO_GSUP_SESSION_STATE_BEGIN:
+		gh->msg_type = GSM0480_MTYPE_REGISTER;
+		break;
+	case OSMO_GSUP_SESSION_STATE_CONTINUE:
+		gh->msg_type = GSM0480_MTYPE_FACILITY;
+		break;
+	case OSMO_GSUP_SESSION_STATE_END:
+		gh->msg_type = GSM0480_MTYPE_RELEASE_COMPLETE;
+		break;
+
+	/* Missing or incorrect session state */
+	case OSMO_GSUP_SESSION_STATE_NONE:
+	default:
+		LOGP(DMM, LOGL_ERROR, "Unexpected session state %d\n",
+			gsup_msg->session_state);
+		/* FIXME: send ERROR back to the HLR */
+		msgb_free(ss_msg);
+		return -EINVAL;
+	}
+
+	/* Facility IE is optional only for RELEASE COMPLETE */
+	if (gh->msg_type != GSM0480_MTYPE_RELEASE_COMPLETE) {
+		if (!gsup_msg->ss_info || gsup_msg->ss_info_len < 2) {
+			LOGP(DMM, LOGL_ERROR, "Missing mandatory Facility IE "
+				"for mapped 0x%02x message\n", gh->msg_type);
+			/* FIXME: send ERROR back to the HLR */
+			msgb_free(ss_msg);
+			return -EINVAL;
+		}
+	}
+
+	/* Append Facility IE if preset */
+	if (gsup_msg->ss_info && gsup_msg->ss_info_len > 2) {
+		/* Facility IE carries LV, others carry TLV */
+		if (gh->msg_type == GSM0480_MTYPE_FACILITY)
+			msgb_lv_put(ss_msg, gsup_msg->ss_info_len, gsup_msg->ss_info);
+		else
+			msgb_tlv_put(ss_msg, GSM0480_IE_FACILITY,
+				gsup_msg->ss_info_len, gsup_msg->ss_info);
+	}
+
+	/* Should we release the transaction? */
+	trans_end = (gh->msg_type == GSM0480_MTYPE_RELEASE_COMPLETE);
+
+	/* Sent to the MS, give ownership of ss_msg */
+	msc_tx_dtap(trans->conn, ss_msg);
+
+	/* Release transaction if required */
+	if (trans_end)
+		trans_free(trans);
+
+	/* 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]);
+
+	return 0;
+}
diff --git a/src/libmsc/gsm_subscriber.c b/src/libmsc/gsm_subscriber.c
new file mode 100644
index 0000000..fb61209
--- /dev/null
+++ b/src/libmsc/gsm_subscriber.c
@@ -0,0 +1,203 @@
+/* The concept of a subscriber for the MSC, roughly HLR/VLR functionality */
+
+/* (C) 2008 by Harald Welte <laforge@gnumonks.org>
+ * (C) 2009,2013 by Holger Hans Peter Freyther <zecke@selfish.org>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "../../bscconfig.h"
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+#include <time.h>
+#include <stdbool.h>
+
+#include <osmocom/core/talloc.h>
+
+#include <osmocom/vty/vty.h>
+
+#ifdef BUILD_IU
+#include <osmocom/ranap/iu_client.h>
+#else
+#include <osmocom/msc/iu_dummy.h>
+#endif
+
+#include <osmocom/msc/gsm_subscriber.h>
+#include <osmocom/msc/gsm_04_08.h>
+#include <osmocom/msc/debug.h>
+#include <osmocom/msc/signal.h>
+#include <osmocom/msc/db.h>
+#include <osmocom/msc/vlr.h>
+#include <osmocom/msc/osmo_msc.h>
+#include <osmocom/msc/msc_ifaces.h>
+#include <osmocom/msc/a_iface.h>
+
+void subscr_paging_cancel(struct vlr_subscr *vsub, enum gsm_paging_event event)
+{
+	subscr_paging_dispatch(GSM_HOOK_RR_PAGING, event, NULL, NULL, vsub);
+}
+
+int subscr_paging_dispatch(unsigned int hooknum, unsigned int event,
+			   struct msgb *msg, void *data, void *param)
+{
+	struct subscr_request *request, *tmp;
+	struct gsm_subscriber_connection *conn = data;
+	struct vlr_subscr *vsub = param;
+	struct paging_signal_data sig_data;
+
+	OSMO_ASSERT(vsub);
+	OSMO_ASSERT(hooknum == GSM_HOOK_RR_PAGING);
+	OSMO_ASSERT(!(conn && (conn->vsub != vsub)));
+	OSMO_ASSERT(!((event == GSM_PAGING_SUCCEEDED) && !conn));
+
+	LOGP(DPAG, LOGL_DEBUG, "Paging %s for %s (event=%d)\n",
+	     event == GSM_PAGING_SUCCEEDED ? "success" : "failure",
+	     vlr_subscr_name(vsub), event);
+
+	if (!vsub->cs.is_paging) {
+		LOGP(DPAG, LOGL_ERROR,
+		     "Paging Response received for subscriber"
+		     " that is not paging.\n");
+		return -EINVAL;
+	}
+
+	osmo_timer_del(&vsub->cs.paging_response_timer);
+
+	if (event == GSM_PAGING_SUCCEEDED
+	    || event == GSM_PAGING_EXPIRED)
+		msc_stop_paging(vsub);
+
+	/* Inform parts of the system we don't know */
+	sig_data.vsub = vsub;
+	sig_data.conn = conn;
+	sig_data.paging_result = event;
+	osmo_signal_dispatch(SS_PAGING,
+			     event == GSM_PAGING_SUCCEEDED ?
+				S_PAGING_SUCCEEDED : S_PAGING_EXPIRED,
+			     &sig_data);
+
+	llist_for_each_entry_safe(request, tmp, &vsub->cs.requests, entry) {
+		llist_del(&request->entry);
+		if (request->cbfn) {
+			LOGP(DPAG, LOGL_DEBUG, "Calling paging cbfn.\n");
+			request->cbfn(hooknum, event, msg, data, request->param);
+		} else
+			LOGP(DPAG, LOGL_DEBUG, "Paging without action.\n");
+		talloc_free(request);
+	}
+
+	/* balanced with the moment we start paging */
+	vsub->cs.is_paging = false;
+	vlr_subscr_put(vsub);
+	return 0;
+}
+
+int msc_paging_request(struct vlr_subscr *vsub)
+{
+	/* The subscriber was last seen in subscr->lac. Find out which
+	 * BSCs/RNCs are responsible and send them a paging request via open
+	 * SCCP connections (if any). */
+	switch (vsub->cs.attached_via_ran) {
+	case RAN_GERAN_A:
+		return a_iface_tx_paging(vsub->imsi, vsub->tmsi, vsub->lac);
+	case RAN_UTRAN_IU:
+		return ranap_iu_page_cs(vsub->imsi,
+					vsub->tmsi == GSM_RESERVED_TMSI?
+					NULL : &vsub->tmsi,
+					vsub->lac);
+	default:
+		break;
+	}
+
+	LOGP(DPAG, LOGL_ERROR, "%s: Cannot page, subscriber not attached\n",
+	     vlr_subscr_name(vsub));
+	return -EINVAL;
+}
+
+static void paging_response_timer_cb(void *data)
+{
+	struct vlr_subscr *vsub = data;
+	subscr_paging_cancel(vsub, GSM_PAGING_EXPIRED);
+}
+
+/*! \brief Start a paging request for vsub, call cbfn(param) when done.
+ * \param vsub  subscriber to page.
+ * \param cbfn  function to call when the conn is established.
+ * \param param  caller defined param to pass to cbfn().
+ * \param label  human readable label of the request kind used for logging.
+ */
+struct subscr_request *subscr_request_conn(struct vlr_subscr *vsub,
+					   gsm_cbfn *cbfn, void *param,
+					   const char *label)
+{
+	int rc;
+	struct subscr_request *request;
+	struct gsm_network *net = vsub->vlr->user_ctx;
+
+	/* Start paging.. we know it is async so we can do it before */
+	if (!vsub->cs.is_paging) {
+		LOGP(DMM, LOGL_DEBUG, "Subscriber %s not paged yet, start paging.\n",
+		     vlr_subscr_name(vsub));
+		rc = msc_paging_request(vsub);
+		if (rc <= 0) {
+			LOGP(DMM, LOGL_ERROR, "Subscriber %s paging failed: %d\n",
+			     vlr_subscr_name(vsub), rc);
+			return NULL;
+		}
+		/* reduced on the first paging callback */
+		vlr_subscr_get(vsub);
+		vsub->cs.is_paging = true;
+		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);
+	} else {
+		LOGP(DMM, LOGL_DEBUG, "Subscriber %s already paged.\n",
+			vlr_subscr_name(vsub));
+	}
+
+	/* TODO: Stop paging in case of memory allocation failure */
+	request = talloc_zero(vsub, struct subscr_request);
+	if (!request)
+		return NULL;
+
+	request->cbfn = cbfn;
+	request->param = param;
+	llist_add_tail(&request->entry, &vsub->cs.requests);
+	return request;
+}
+
+void subscr_remove_request(struct subscr_request *request)
+{
+	llist_del(&request->entry);
+	talloc_free(request);
+}
+
+struct gsm_subscriber_connection *connection_for_subscr(struct vlr_subscr *vsub)
+{
+	struct gsm_network *net = vsub->vlr->user_ctx;
+	struct gsm_subscriber_connection *conn;
+
+	llist_for_each_entry(conn, &net->subscr_conns, entry) {
+		if (conn->vsub == vsub)
+			return conn;
+	}
+
+	return NULL;
+}
diff --git a/src/libmsc/iu_dummy.c b/src/libmsc/iu_dummy.c
new file mode 100644
index 0000000..bb53367
--- /dev/null
+++ b/src/libmsc/iu_dummy.c
@@ -0,0 +1,99 @@
+/* Trivial switch-off of external Iu dependencies,
+ * allowing to run full unit tests even when built without Iu support. */
+
+/*
+ * (C) 2016,2017 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>
+ *
+ * Author: Neels Hofmeyr <nhofmeyr@sysmocom.de>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "../../bscconfig.h"
+#ifndef BUILD_IU
+
+#include <osmocom/msc/iu_dummy.h>
+
+#include <osmocom/core/logging.h>
+#include <osmocom/vty/logging.h>
+#include <osmocom/core/msgb.h>
+
+struct msgb;
+struct ranap_ue_conn_ctx;
+struct gsm_auth_tuple;
+struct RANAP_Cause;
+struct osmo_auth_vector;
+
+int ranap_iu_tx(struct msgb *msg, uint8_t sapi)
+{
+	LOGP(DLGLOBAL, LOGL_INFO, "iu_tx() dummy called, NOT transmitting %d bytes: %s\n",
+	     msg->len, osmo_hexdump(msg->data, msg->len));
+	return 0;
+}
+
+int ranap_iu_tx_sec_mode_cmd(struct ranap_ue_conn_ctx *uectx, struct osmo_auth_vector *vec,
+			     int send_ck)
+{
+	LOGP(DLGLOBAL, LOGL_INFO, "iu_tx_sec_mode_cmd() dummy called, NOT transmitting Security Mode Command\n");
+	return 0;
+}
+
+int ranap_iu_page_cs(const char *imsi, const uint32_t *tmsi, uint16_t lac)
+{
+	LOGP(DLGLOBAL, LOGL_INFO, "iu_page_cs() dummy called, NOT paging\n");
+	return 23;
+}
+
+int ranap_iu_page_ps(const char *imsi, const uint32_t *ptmsi, uint16_t lac, uint8_t rac)
+{
+	LOGP(DLGLOBAL, LOGL_INFO, "iu_page_ps() dummy called, NOT paging\n");
+	return 0;
+}
+
+struct msgb *ranap_new_msg_rab_assign_voice(uint8_t rab_id, uint32_t rtp_ip,
+					    uint16_t rtp_port,
+					    bool use_x213_nsap)
+{
+	LOGP(DLGLOBAL, LOGL_INFO, "ranap_new_msg_rab_assign_voice() dummy called, NOT composing RAB Assignment\n");
+	return NULL;
+}
+
+int ranap_iu_rab_act(struct ranap_ue_conn_ctx *ue_ctx, struct msgb *msg)
+{
+	LOGP(DLGLOBAL, LOGL_INFO, "iu_rab_act() dummy called, NOT activating RAB\n");
+	return 0;
+}
+
+int ranap_iu_tx_common_id(struct ranap_ue_conn_ctx *uectx, const char *imsi)
+{
+	LOGP(DLGLOBAL, LOGL_INFO, "iu_tx_common_id() dummy called, NOT sending CommonID\n");
+	return 0;
+}
+
+int ranap_iu_tx_release(struct ranap_ue_conn_ctx *ctx, const struct RANAP_Cause *cause)
+{
+	LOGP(DLGLOBAL, LOGL_INFO, "iu_tx_release() dummy called, NOT sending Release\n");
+	return 0;
+}
+
+uint32_t iu_get_conn_id(const struct ranap_ue_conn_ctx *ue)
+{
+	LOGP(DLGLOBAL, LOGL_INFO, "iu_get_conn_id() dummy called, returning BOGUS value\n");
+	return 23;
+}
+
+#endif
diff --git a/src/libmsc/iucs.c b/src/libmsc/iucs.c
new file mode 100644
index 0000000..95bbbee
--- /dev/null
+++ b/src/libmsc/iucs.c
@@ -0,0 +1,252 @@
+/* Code to manage MSC subscriber connections over IuCS interface */
+
+/*
+ * (C) 2016,2017 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>
+ *
+ * Author: Neels Hofmeyr <nhofmeyr@sysmocom.de>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <inttypes.h>
+
+#include <osmocom/core/logging.h>
+#include <osmocom/ranap/iu_client.h>
+#include <osmocom/msc/debug.h>
+
+#include <osmocom/msc/gsm_data.h>
+#include <osmocom/msc/gsm_subscriber.h>
+#include <osmocom/msc/transaction.h>
+#include <osmocom/msc/osmo_msc.h>
+#include <osmocom/msc/vlr.h>
+#include <osmocom/core/byteswap.h>
+
+#include "../../bscconfig.h"
+
+#ifdef BUILD_IU
+#include <osmocom/ranap/iu_client.h>
+extern struct msgb *ranap_new_msg_rab_assign_voice(uint8_t rab_id,
+						   uint32_t rtp_ip,
+						   uint16_t rtp_port,
+						   bool use_x213_nsap);
+#else
+#include <osmocom/msc/iu_dummy.h>
+#endif /* BUILD_IU */
+
+/* For A-interface see libbsc/bsc_api.c subscr_con_allocate() */
+static struct gsm_subscriber_connection *subscr_conn_allocate_iu(struct gsm_network *network,
+								 struct ranap_ue_conn_ctx *ue,
+								 uint16_t lac)
+{
+	struct gsm_subscriber_connection *conn;
+
+	DEBUGP(DIUCS, "Allocating IuCS subscriber conn: lac %d, conn_id %" PRIx32 "\n",
+	       lac, ue->conn_id);
+
+	conn = msc_subscr_conn_alloc(network, RAN_UTRAN_IU, lac);
+	if (!conn)
+		return NULL;
+
+	conn->iu.ue_ctx = ue;
+	conn->iu.ue_ctx->rab_assign_addr_enc = network->iu.rab_assign_addr_enc;
+	return conn;
+}
+
+static int same_ue_conn(struct ranap_ue_conn_ctx *a, struct ranap_ue_conn_ctx *b)
+{
+	if (a == b)
+		return 1;
+	return (a->conn_id == b->conn_id);
+}
+
+static inline void log_subscribers(struct gsm_network *network)
+{
+	if (!log_check_level(DIUCS, LOGL_DEBUG))
+		return;
+
+	struct gsm_subscriber_connection *conn;
+	int i = 0;
+	llist_for_each_entry(conn, &network->subscr_conns, entry) {
+		DEBUGP(DIUCS, "%3d: %s", i, vlr_subscr_name(conn->vsub));
+		switch (conn->via_ran) {
+		case RAN_UTRAN_IU:
+			DEBUGPC(DIUCS, " Iu");
+			if (conn->iu.ue_ctx) {
+				DEBUGPC(DIUCS, " conn_id %d",
+					conn->iu.ue_ctx->conn_id
+				       );
+			}
+			break;
+		case RAN_GERAN_A:
+			DEBUGPC(DIUCS, " A");
+			/* TODO log A-interface connection details */
+			break;
+		case RAN_UNKNOWN:
+			DEBUGPC(DIUCS, " ?");
+			break;
+		default:
+			DEBUGPC(DIUCS, " invalid");
+			break;
+		}
+		DEBUGPC(DIUCS, "\n");
+		i++;
+	}
+	DEBUGP(DIUCS, "subscribers registered: %d\n", i);
+}
+
+/* Return an existing IuCS subscriber connection record for the given
+ * connection IDs, or return NULL if not found. */
+struct gsm_subscriber_connection *subscr_conn_lookup_iu(
+						struct gsm_network *network,
+						struct ranap_ue_conn_ctx *ue)
+{
+	struct gsm_subscriber_connection *conn;
+
+	DEBUGP(DIUCS, "Looking for IuCS subscriber: conn_id %" PRIx32 "\n",
+	       ue->conn_id);
+	log_subscribers(network);
+
+	llist_for_each_entry(conn, &network->subscr_conns, entry) {
+		if (conn->via_ran != RAN_UTRAN_IU)
+			continue;
+		if (!same_ue_conn(conn->iu.ue_ctx, ue))
+			continue;
+		DEBUGP(DIUCS, "Found IuCS subscriber for conn_id %" PRIx32 "\n",
+		       ue->conn_id);
+		return conn;
+	}
+	DEBUGP(DIUCS, "No IuCS subscriber found for conn_id %" PRIx32 "\n",
+	       ue->conn_id);
+	return NULL;
+}
+
+/* Receive MM/CC/... message from IuCS (SCCP user SAP).
+ * msg->dst must reference a struct ranap_ue_conn_ctx, which identifies the peer that
+ * sent the msg.
+ *
+ * For A-interface see libbsc/bsc_api.c gsm0408_rcvmsg(). */
+int gsm0408_rcvmsg_iucs(struct gsm_network *network, struct msgb *msg,
+			uint16_t *lac)
+{
+	int rc;
+	struct ranap_ue_conn_ctx *ue_ctx;
+	struct gsm_subscriber_connection *conn;
+
+	ue_ctx = (struct ranap_ue_conn_ctx*)msg->dst;
+
+	/* TODO: are there message types that could allow us to skip this
+	 * search? */
+	conn = subscr_conn_lookup_iu(network, ue_ctx);
+
+	if (conn && lac && (conn->lac != *lac)) {
+		LOGP(DIUCS, LOGL_ERROR, "IuCS subscriber has changed LAC"
+		     " within the same connection, discarding connection:"
+		     " %s from LAC %d to %d\n",
+		     vlr_subscr_name(conn->vsub), conn->lac, *lac);
+		/* Deallocate conn with previous LAC */
+		msc_subscr_conn_close(conn, GSM_CAUSE_INV_MAND_INFO);
+		/* At this point we could be tolerant and allocate a new
+		 * connection, but changing the LAC within the same connection
+		 * is shifty. Rather cancel everything. */
+		return -1;
+	}
+
+	if (conn) {
+		/* Make sure we don't receive RR over IuCS; otherwise all
+		 * messages handled by gsm0408_dispatch() are of interest (CC,
+		 * MM, SMS, NS_SS, maybe even MM_GPRS and SM_GPRS). */
+		struct gsm48_hdr *gh = msgb_l3(msg);
+		uint8_t pdisc = gh->proto_discr & 0x0f;
+		OSMO_ASSERT(pdisc != GSM48_PDISC_RR);
+
+		msc_dtap(conn, msg);
+		rc = 0;
+	} else {
+		/* allocate a new connection */
+
+		if (!lac) {
+			LOGP(DIUCS, LOGL_ERROR, "New IuCS subscriber"
+			     " but no LAC available. Expecting an InitialUE"
+			     " message containing a LAI IE."
+			     " Dropping connection.\n");
+			return -1;
+		}
+
+		conn = subscr_conn_allocate_iu(network, ue_ctx, *lac);
+		if (!conn)
+			abort();
+
+		/* ownership of conn hereby goes to the MSC: */
+		rc = msc_compl_l3(conn, msg, 0);
+	}
+
+	return rc;
+}
+
+int iu_rab_act_cs(struct gsm_trans *trans)
+{
+	struct gsm_subscriber_connection *conn;
+	struct msgb *msg;
+	bool use_x213_nsap;
+	uint32_t conn_id;
+	struct ranap_ue_conn_ctx *uectx;
+	uint8_t rab_id;
+	uint32_t rtp_ip;
+	uint16_t rtp_port;
+
+	conn = trans->conn;
+	uectx = conn->iu.ue_ctx;
+	rab_id = conn->iu.rab_id;
+	rtp_ip = osmo_htonl(inet_addr(conn->rtp.local_addr_ran));
+	rtp_port = conn->rtp.local_port_ran;
+	conn_id = uectx->conn_id;
+
+	if (rtp_ip == INADDR_NONE) {
+		LOGP(DIUCS, LOGL_DEBUG,
+		     "Assigning RAB: conn_id=%u, rab_id=%d, invalid RTP IP-Address\n",
+		     conn_id, rab_id);
+		return -EINVAL;
+	}
+	if (rtp_port == 0) {
+		LOGP(DIUCS, LOGL_DEBUG,
+		     "Assigning RAB: conn_id=%u, rab_id=%d, invalid RTP Port\n",
+		     conn_id, rab_id);
+		return -EINVAL;
+	}
+
+	use_x213_nsap =
+	    (uectx->rab_assign_addr_enc == RANAP_NSAP_ADDR_ENC_X213);
+
+	LOGP(DIUCS, LOGL_DEBUG,
+	     "Assigning RAB: conn_id=%u, rab_id=%d, rtp=%x:%u, use_x213_nsap=%d\n",
+	     conn_id, rab_id, rtp_ip, rtp_port, use_x213_nsap);
+
+	msg = ranap_new_msg_rab_assign_voice(rab_id, rtp_ip, rtp_port,
+					     use_x213_nsap);
+	msg->l2h = msg->data;
+
+	if (ranap_iu_rab_act(uectx, msg))
+		LOGP(DIUCS, LOGL_ERROR,
+		     "Failed to send RAB Assignment: conn_id=%d rab_id=%d rtp=%x:%u\n",
+		     conn_id, rab_id, rtp_ip, rtp_port);
+	return 0;
+}
+
+uint32_t iu_get_conn_id(const struct ranap_ue_conn_ctx *ue)
+{
+	return ue->conn_id;
+}
diff --git a/src/libmsc/iucs_ranap.c b/src/libmsc/iucs_ranap.c
new file mode 100644
index 0000000..ec0b569
--- /dev/null
+++ b/src/libmsc/iucs_ranap.c
@@ -0,0 +1,138 @@
+/* Implementation of RANAP messages to/from an MSC via an Iu-CS interface.
+ * This keeps direct RANAP dependencies out of libmsc. */
+
+/* (C) 2016 by sysmocom s.m.f.c. GmbH <info@sysmocom.de>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "../../bscconfig.h"
+
+#ifdef BUILD_IU
+
+#include <osmocom/core/logging.h>
+
+#include <osmocom/ranap/ranap_ies_defs.h>
+#include <osmocom/ranap/iu_client.h>
+#include <osmocom/ranap/RANAP_IuTransportAssociation.h>
+#include <osmocom/ranap/iu_helpers.h>
+
+#include <osmocom/msc/debug.h>
+#include <osmocom/msc/gsm_data.h>
+#include <osmocom/msc/gsm_subscriber.h>
+#include <osmocom/msc/iucs.h>
+#include <osmocom/msc/vlr.h>
+#include <osmocom/msc/iucs_ranap.h>
+#include <osmocom/msc/osmo_msc.h>
+#include <osmocom/msc/msc_mgcp.h>
+
+#include <asn1c/asn1helpers.h>
+
+/* To continue authorization after a Security Mode Complete */
+int gsm0408_authorize(struct gsm_subscriber_connection *conn);
+
+static int iucs_rx_rab_assign(struct gsm_subscriber_connection *conn, RANAP_RAB_SetupOrModifiedItemIEs_t * setup_ies)
+{
+	uint8_t rab_id;
+	RANAP_RAB_SetupOrModifiedItem_t *item = &setup_ies->raB_SetupOrModifiedItem;
+	RANAP_TransportLayerAddress_t *transp_layer_addr;
+	RANAP_IuTransportAssociation_t *transp_assoc;
+	uint16_t port = 0;
+	int rc;
+	char addr[INET_ADDRSTRLEN];
+
+	rab_id = item->rAB_ID.buf[0];
+
+	LOGP(DIUCS, LOGL_NOTICE,
+	     "Received RAB assignment event for %s rab_id=%hhd\n", vlr_subscr_name(conn->vsub), rab_id);
+
+	if (item->iuTransportAssociation && item->transportLayerAddress) {
+		transp_layer_addr = item->transportLayerAddress;
+		transp_assoc = item->iuTransportAssociation;
+
+		rc = ranap_transp_assoc_decode(&port, transp_assoc);
+		if (rc != 0) {
+			LOGP(DIUCS, LOGL_ERROR,
+			     "Unable to decode RTP port in RAB assignment (%s rab_id=%hhd)\n",
+			     vlr_subscr_name(conn->vsub), rab_id);
+			return 0;
+		}
+
+		rc = ranap_transp_layer_addr_decode(addr, sizeof(addr), transp_layer_addr);
+		if (rc != 0) {
+			LOGP(DIUCS, LOGL_ERROR,
+			     "Unable to decode IP-Address in RAB assignment (%s rab_id=%hhd)\n",
+			     vlr_subscr_name(conn->vsub), rab_id);
+			return 0;
+		}
+
+		return msc_mgcp_ass_complete(conn, port, addr);
+	}
+
+	LOGP(DIUCS, LOGL_ERROR,
+	     "RAB assignment lacks RTP connection information. (%s rab_id=%hhd)\n",
+	     vlr_subscr_name(conn->vsub), rab_id);
+	return 0;
+}
+
+int iucs_rx_sec_mode_compl(struct gsm_subscriber_connection *conn,
+			   RANAP_SecurityModeCompleteIEs_t *ies)
+{
+	OSMO_ASSERT(conn->via_ran == RAN_UTRAN_IU);
+
+	/* TODO evalute ies */
+
+	msc_rx_sec_mode_compl(conn);
+	return 0;
+}
+
+int iucs_rx_ranap_event(struct gsm_network *network,
+			struct ranap_ue_conn_ctx *ue_ctx, int type, void *data)
+{
+	struct gsm_subscriber_connection *conn;
+
+	conn = subscr_conn_lookup_iu(network, ue_ctx);
+
+	if (!conn) {
+		LOGP(DRANAP, LOGL_ERROR, "Cannot find subscriber for IU event %u\n", type);
+		return -1;
+	}
+
+	switch (type) {
+	case RANAP_IU_EVENT_IU_RELEASE:
+	case RANAP_IU_EVENT_LINK_INVALIDATED:
+		LOGP(DIUCS, LOGL_INFO, "IuCS release for %s\n",
+		     vlr_subscr_name(conn->vsub));
+		msc_subscr_conn_rx_iu_release_complete(conn);
+		return 0;
+
+	case RANAP_IU_EVENT_SECURITY_MODE_COMPLETE:
+		LOGP(DIUCS, LOGL_INFO, "IuCS security mode complete for %s\n",
+		     vlr_subscr_name(conn->vsub));
+		return iucs_rx_sec_mode_compl(conn,
+					      (RANAP_SecurityModeCompleteIEs_t*)data);
+	case RANAP_IU_EVENT_RAB_ASSIGN:
+		return iucs_rx_rab_assign(conn,
+				(RANAP_RAB_SetupOrModifiedItemIEs_t*)data);
+	default:
+		LOGP(DIUCS, LOGL_NOTICE, "Unknown message received:"
+		     " RANAP event: %i\n", type);
+		return -1;
+	}
+}
+
+#endif /* BUILD_IU */
diff --git a/src/libmsc/mncc.c b/src/libmsc/mncc.c
new file mode 100644
index 0000000..d2cd170
--- /dev/null
+++ b/src/libmsc/mncc.c
@@ -0,0 +1,288 @@
+/* mncc.c - utility routines for the MNCC API between the 04.08
+ *	    message parsing and the actual Call Control logic */
+
+/* (C) 2008-2018 by Harald Welte <laforge@gnumonks.org>
+ * (C) 2009 by Andreas Eversberg <Andreas.Eversberg@versatel.de>
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include <osmocom/core/talloc.h>
+#include <osmocom/core/utils.h>
+
+#include <osmocom/msc/gsm_04_08.h>
+#include <osmocom/msc/debug.h>
+#include <osmocom/msc/mncc.h>
+#include <osmocom/msc/gsm_data.h>
+#include <osmocom/msc/transaction.h>
+
+
+static const struct value_string mncc_names[] = {
+	{ MNCC_SETUP_REQ, "MNCC_SETUP_REQ" },
+	{ MNCC_SETUP_IND, "MNCC_SETUP_IND" },
+	{ MNCC_SETUP_RSP, "MNCC_SETUP_RSP" },
+	{ MNCC_SETUP_CNF, "MNCC_SETUP_CNF" },
+	{ MNCC_SETUP_COMPL_REQ, "MNCC_SETUP_COMPL_REQ" },
+	{ MNCC_SETUP_COMPL_IND, "MNCC_SETUP_COMPL_IND" },
+	{ MNCC_CALL_CONF_IND, "MNCC_CALL_CONF_IND" },
+	{ MNCC_CALL_PROC_REQ, "MNCC_CALL_PROC_REQ" },
+	{ MNCC_PROGRESS_REQ, "MNCC_PROGRESS_REQ" },
+	{ MNCC_ALERT_REQ, "MNCC_ALERT_REQ" },
+	{ MNCC_ALERT_IND, "MNCC_ALERT_IND" },
+	{ MNCC_NOTIFY_REQ, "MNCC_NOTIFY_REQ" },
+	{ MNCC_NOTIFY_IND, "MNCC_NOTIFY_IND" },
+	{ MNCC_DISC_REQ, "MNCC_DISC_REQ" },
+	{ MNCC_DISC_IND, "MNCC_DISC_IND" },
+	{ MNCC_REL_REQ, "MNCC_REL_REQ" },
+	{ MNCC_REL_IND, "MNCC_REL_IND" },
+	{ MNCC_REL_CNF, "MNCC_REL_CNF" },
+	{ MNCC_FACILITY_REQ, "MNCC_FACILITY_REQ" },
+	{ MNCC_FACILITY_IND, "MNCC_FACILITY_IND" },
+	{ MNCC_START_DTMF_IND, "MNCC_START_DTMF_IND" },
+	{ MNCC_START_DTMF_RSP, "MNCC_START_DTMF_RSP" },
+	{ MNCC_START_DTMF_REJ, "MNCC_START_DTMF_REJ" },
+	{ MNCC_STOP_DTMF_IND, "MNCC_STOP_DTMF_IND" },
+	{ MNCC_STOP_DTMF_RSP, "MNCC_STOP_DTMF_RSP" },
+	{ MNCC_MODIFY_REQ, "MNCC_MODIFY_REQ" },
+	{ MNCC_MODIFY_IND, "MNCC_MODIFY_IND" },
+	{ MNCC_MODIFY_RSP, "MNCC_MODIFY_RSP" },
+	{ MNCC_MODIFY_CNF, "MNCC_MODIFY_CNF" },
+	{ MNCC_MODIFY_REJ, "MNCC_MODIFY_REJ" },
+	{ MNCC_HOLD_IND, "MNCC_HOLD_IND" },
+	{ MNCC_HOLD_CNF, "MNCC_HOLD_CNF" },
+	{ MNCC_HOLD_REJ, "MNCC_HOLD_REJ" },
+	{ MNCC_RETRIEVE_IND, "MNCC_RETRIEVE_IND" },
+	{ MNCC_RETRIEVE_CNF, "MNCC_RETRIEVE_CNF" },
+	{ MNCC_RETRIEVE_REJ, "MNCC_RETRIEVE_REJ" },
+	{ MNCC_USERINFO_REQ, "MNCC_USERINFO_REQ" },
+	{ MNCC_USERINFO_IND, "MNCC_USERINFO_IND" },
+	{ MNCC_REJ_REQ, "MNCC_REJ_REQ" },
+	{ MNCC_REJ_IND, "MNCC_REJ_IND" },
+	{ MNCC_BRIDGE, "MNCC_BRIDGE" },
+	{ MNCC_FRAME_RECV, "MNCC_FRAME_RECV" },
+	{ MNCC_FRAME_DROP, "MNCC_FRAME_DROP" },
+	{ MNCC_LCHAN_MODIFY, "MNCC_LCHAN_MODIFY" },
+	{ MNCC_RTP_CREATE, "MNCC_RTP_CREATE" },
+	{ MNCC_RTP_CONNECT, "MNCC_RTP_CONNECT" },
+	{ MNCC_RTP_FREE, "MNCC_RTP_FREE" },
+	{ GSM_TCHF_FRAME, "GSM_TCHF_FRAME" },
+	{ GSM_TCHF_FRAME_EFR, "GSM_TCHF_FRAME_EFR" },
+	{ GSM_TCHH_FRAME, "GSM_TCHH_FRAME" },
+	{ GSM_TCH_FRAME_AMR, "GSM_TCH_FRAME_AMR" },
+	{ GSM_BAD_FRAME, "GSM_BAD_FRAME" },
+	{ 0, NULL },
+};
+
+const char *get_mncc_name(int value)
+{
+	return get_value_string(mncc_names, value);
+}
+
+void mncc_set_cause(struct gsm_mncc *data, int loc, int val)
+{
+	data->fields |= MNCC_F_CAUSE;
+	data->cause.location = loc;
+	data->cause.value = 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;
+	for (i = 0; i < size; i++) {
+		if (str[i] == 0)
+			return 0;
+	}
+	return -EINVAL;
+}
+
+static int mncc_check_number(const struct gsm_mncc_number *num, const char *str)
+{
+	int rc;
+	rc = check_string_terminated(num->number, ARRAY_SIZE(num->number));
+	if (rc < 0)
+		LOGP(DMNCC, LOGL_ERROR, "MNCC %s number not terminated\n", str);
+	return rc;
+}
+
+static int mncc_check_cause(const struct gsm_mncc_cause *cause)
+{
+	if (cause->diag_len > sizeof(cause->diag))
+		return -EINVAL;
+	return 0;
+}
+
+static int mncc_check_useruser(const struct gsm_mncc_useruser *uu)
+{
+	return check_string_terminated(uu->info, ARRAY_SIZE(uu->info));
+}
+
+static int mncc_check_facility(const struct gsm_mncc_facility *fac)
+{
+	return check_string_terminated(fac->info, ARRAY_SIZE(fac->info));
+}
+
+static int mncc_check_ssversion(const struct gsm_mncc_ssversion *ssv)
+{
+	return check_string_terminated(ssv->info, ARRAY_SIZE(ssv->info));
+}
+
+static int mncc_prim_check_sign(const struct gsm_mncc *mncc_prim)
+{
+	int rc;
+
+	if (mncc_prim->fields & ~ MNCC_F_ALL) {
+		LOGP(DMNCC, LOGL_ERROR, "Unknown MNCC field mask 0x%x\n", mncc_prim->fields);
+		return -EINVAL;
+	}
+
+	rc = check_string_terminated(mncc_prim->imsi, sizeof(mncc_prim->imsi));
+	if (rc < 0) {
+		LOGP(DMNCC, LOGL_ERROR, "MNCC IMSI not terminated\n");
+		return rc;
+	}
+
+	if (mncc_prim->fields & MNCC_F_CALLED) {
+		rc = mncc_check_number(&mncc_prim->called, "called");
+		if (rc < 0)
+			return rc;
+	}
+
+	if (mncc_prim->fields & MNCC_F_CALLING) {
+		rc = mncc_check_number(&mncc_prim->calling, "calling");
+		if (rc < 0)
+			return rc;
+	}
+
+	if (mncc_prim->fields & MNCC_F_REDIRECTING) {
+		rc = mncc_check_number(&mncc_prim->redirecting, "redirecting");
+		if (rc < 0)
+			return rc;
+	}
+
+	if (mncc_prim->fields & MNCC_F_CONNECTED) {
+		rc = mncc_check_number(&mncc_prim->connected, "connected");
+		if (rc < 0)
+			return rc;
+	}
+
+	if (mncc_prim->fields & MNCC_F_CAUSE) {
+		rc = mncc_check_cause(&mncc_prim->cause);
+		if (rc < 0)
+			return rc;
+	}
+
+	if (mncc_prim->fields & MNCC_F_USERUSER) {
+		rc = mncc_check_useruser(&mncc_prim->useruser);
+		if (rc < 0)
+			return rc;
+	}
+
+	if (mncc_prim->fields & MNCC_F_FACILITY) {
+		rc = mncc_check_facility(&mncc_prim->facility);
+		if (rc < 0)
+			return rc;
+	}
+
+	if (mncc_prim->fields & MNCC_F_SSVERSION) {
+		rc = mncc_check_ssversion(&mncc_prim->ssversion);
+		if (rc < 0)
+			return rc;
+	}
+
+	if (mncc_prim->fields & MNCC_F_BEARER_CAP) {
+		bool m1_found = false;
+		int i;
+
+		for (i = 0; i < ARRAY_SIZE(mncc_prim->bearer_cap.speech_ver); i++) {
+			if (mncc_prim->bearer_cap.speech_ver[i] == -1) {
+				m1_found = true;
+				break;
+			}
+		}
+		if (!m1_found) {
+			LOGP(DMNCC, LOGL_ERROR, "Unterminated MNCC bearer capability\n");
+			return -EINVAL;
+		}
+	}
+
+	return 0;
+}
+
+int mncc_prim_check(const struct gsm_mncc *mncc_prim, unsigned int len)
+{
+	if (len < sizeof(mncc_prim->msg_type)) {
+		LOGP(DMNCC, LOGL_ERROR, "Short MNCC Header\n");
+		return -EINVAL;
+	}
+
+	switch (mncc_prim->msg_type) {
+	case MNCC_SOCKET_HELLO:
+		if (len < sizeof(struct gsm_mncc_hello)) {
+			LOGP(DMNCC, LOGL_ERROR, "Short MNCC Hello\n");
+			return -EINVAL;
+		}
+		break;
+	case GSM_BAD_FRAME:
+	case GSM_TCH_FRAME_AMR:
+	case GSM_TCHH_FRAME:
+	case GSM_TCHF_FRAME_EFR:
+	case GSM_TCHF_FRAME:
+		if (len < sizeof(struct gsm_data_frame)) {
+			LOGP(DMNCC, LOGL_ERROR, "Short MNCC TCH\n");
+			return -EINVAL;
+		}
+		break;
+	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;
+	case MNCC_LCHAN_MODIFY:
+	case MNCC_FRAME_DROP:
+	case MNCC_FRAME_RECV:
+		/* FIXME */
+		break;
+	case MNCC_BRIDGE:
+		if (len < sizeof(struct gsm_mncc_bridge)) {
+			LOGP(DMNCC, LOGL_ERROR, "Short MNCC BRIDGE\n");
+			return -EINVAL;
+		}
+		break;
+	default:
+		if (len < sizeof(struct gsm_mncc)) {
+			LOGP(DMNCC, LOGL_ERROR, "Short MNCC Signalling\n");
+			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
new file mode 100644
index 0000000..d6f3e3d
--- /dev/null
+++ b/src/libmsc/mncc_builtin.c
@@ -0,0 +1,382 @@
+/* mncc_builtin.c - default, minimal built-in MNCC Application for
+ *		    standalone bsc_hack (network-in-the-box mode) */
+
+/* (C) 2008-2010 by Harald Welte <laforge@gnumonks.org>
+ * (C) 2009 by Andreas Eversberg <Andreas.Eversberg@versatel.de>
+ * 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
+ * (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.
+ *
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include <osmocom/msc/gsm_04_08.h>
+#include <osmocom/msc/debug.h>
+#include <osmocom/msc/mncc.h>
+#include <osmocom/msc/mncc_int.h>
+#include <osmocom/core/talloc.h>
+#include <osmocom/msc/gsm_data.h>
+#include <osmocom/msc/transaction.h>
+
+void *tall_call_ctx;
+
+static LLIST_HEAD(call_list);
+
+static uint32_t new_callref = 0x00000001;
+
+struct mncc_int mncc_int = {
+	.def_codec = { GSM48_CMODE_SPEECH_V1, GSM48_CMODE_SPEECH_V1 },
+};
+
+static void free_call(struct gsm_call *call)
+{
+	llist_del(&call->entry);
+	DEBUGP(DMNCC, "(call %x) Call removed.\n", call->callref);
+	talloc_free(call);
+}
+
+
+static struct gsm_call *get_call_ref(uint32_t callref)
+{
+	struct gsm_call *callt;
+
+	llist_for_each_entry(callt, &call_list, entry) {
+		if (callt->callref == callref)
+			return callt;
+	}
+	return NULL;
+}
+
+/* on incoming call, look up database and send setup to remote subscr. */
+static int mncc_setup_ind(struct gsm_call *call, int msg_type,
+			  struct gsm_mncc *setup)
+{
+	struct gsm_mncc mncc;
+	struct gsm_call *remote;
+
+	memset(&mncc, 0, sizeof(struct gsm_mncc));
+	mncc.callref = call->callref;
+
+	/* already have remote call */
+	if (call->remote_ref)
+		return 0;
+	
+	/* transfer mode 1 would be packet mode, which was never specified */
+	if (setup->bearer_cap.mode != 0) {
+		LOGP(DMNCC, LOGL_NOTICE, "(call %x) We don't support "
+			"packet mode\n", call->callref);
+		mncc_set_cause(&mncc, GSM48_CAUSE_LOC_PRN_S_LU,
+				GSM48_CC_CAUSE_BEARER_CA_UNAVAIL);
+		goto out_reject;
+	}
+
+	/* we currently only do speech */
+	if (setup->bearer_cap.transfer != GSM_MNCC_BCAP_SPEECH) {
+		LOGP(DMNCC, LOGL_NOTICE, "(call %x) We only support "
+			"voice calls\n", call->callref);
+		mncc_set_cause(&mncc, GSM48_CAUSE_LOC_PRN_S_LU,
+				GSM48_CC_CAUSE_BEARER_CA_UNAVAIL);
+		goto out_reject;
+	}
+
+	/* create remote call */
+	if (!(remote = talloc_zero(tall_call_ctx, struct gsm_call))) {
+		mncc_set_cause(&mncc, GSM48_CAUSE_LOC_PRN_S_LU,
+				GSM48_CC_CAUSE_RESOURCE_UNAVAIL);
+		goto out_reject;
+	}
+	llist_add_tail(&remote->entry, &call_list);
+	remote->net = call->net;
+	remote->callref = new_callref++;
+	DEBUGP(DMNCC, "(call %x) Creating new remote instance %x.\n",
+		call->callref, remote->callref);
+
+	/* link remote call */
+	call->remote_ref = remote->callref;
+	remote->remote_ref = call->callref;
+
+	/* send call proceeding */
+	memset(&mncc, 0, sizeof(struct gsm_mncc));
+	mncc.callref = call->callref;
+	DEBUGP(DMNCC, "(call %x) Accepting call.\n", call->callref);
+	mncc_tx_to_cc(call->net, MNCC_CALL_PROC_REQ, &mncc);
+
+	/* modify mode */
+	memset(&mncc, 0, sizeof(struct gsm_mncc));
+	mncc.callref = call->callref;
+	DEBUGP(DMNCC, "(call %x) Modify channel mode\n", call->callref);
+	mncc_tx_to_cc(call->net, MNCC_LCHAN_MODIFY, &mncc);
+
+	/* send setup to remote */
+//	setup->fields |= MNCC_F_SIGNAL;
+//	setup->signal = GSM48_SIGNAL_DIALTONE;
+	setup->callref = remote->callref;
+	DEBUGP(DMNCC, "(call %x) Forwarding SETUP to remote.\n", call->callref);
+	return mncc_tx_to_cc(remote->net, MNCC_SETUP_REQ, setup);
+
+out_reject:
+	mncc_tx_to_cc(call->net, MNCC_REJ_REQ, &mncc);
+	free_call(call);
+	return 0;
+}
+
+static int mncc_alert_ind(struct gsm_call *call, int msg_type,
+			  struct gsm_mncc *alert)
+{
+	struct gsm_call *remote;
+
+	/* send alerting to remote */
+	if (!(remote = get_call_ref(call->remote_ref)))
+		return 0;
+	alert->callref = remote->callref;
+	DEBUGP(DMNCC, "(call %x) Forwarding ALERT to remote.\n", call->callref);
+	return mncc_tx_to_cc(remote->net, MNCC_ALERT_REQ, alert);
+}
+
+static int mncc_notify_ind(struct gsm_call *call, int msg_type,
+			   struct gsm_mncc *notify)
+{
+	struct gsm_call *remote;
+
+	/* send notify to remote */
+	if (!(remote = get_call_ref(call->remote_ref)))
+		return 0;
+	notify->callref = remote->callref;
+	DEBUGP(DMNCC, "(call %x) Forwarding NOTIF to remote.\n", call->callref);
+	return mncc_tx_to_cc(remote->net, MNCC_NOTIFY_REQ, notify);
+}
+
+static int mncc_setup_cnf(struct gsm_call *call, int msg_type,
+			  struct gsm_mncc *connect)
+{
+	struct gsm_mncc connect_ack, frame_recv;
+	struct gsm_network *net = call->net;
+	struct gsm_call *remote;
+	struct gsm_mncc_bridge bridge = { .msg_type = MNCC_BRIDGE };
+
+	/* acknowledge connect */
+	memset(&connect_ack, 0, sizeof(struct gsm_mncc));
+	connect_ack.callref = call->callref;
+	DEBUGP(DMNCC, "(call %x) Acknowledge SETUP.\n", call->callref);
+	mncc_tx_to_cc(call->net, MNCC_SETUP_COMPL_REQ, &connect_ack);
+
+	/* send connect message to remote */
+	if (!(remote = get_call_ref(call->remote_ref)))
+		return 0;
+	connect->callref = remote->callref;
+	DEBUGP(DMNCC, "(call %x) Sending CONNECT to remote.\n", call->callref);
+	mncc_tx_to_cc(remote->net, MNCC_SETUP_RSP, connect);
+
+	/* bridge tch */
+	bridge.callref[0] = call->callref;
+	bridge.callref[1] = call->remote_ref;
+	DEBUGP(DMNCC, "(call %x) Bridging with remote.\n", call->callref);
+
+	/* proxy mode */
+	if (!net->handover.active) {
+		/* in the no-handover case, we can bridge, i.e. use
+		 * the old RTP proxy code */
+		return mncc_tx_to_cc(call->net, MNCC_BRIDGE, &bridge);
+	} else {
+		/* in case of handover, we need to re-write the RTP
+		 * SSRC, sequence and timestamp values and thus
+		 * need to enable RTP receive for both directions */
+		memset(&frame_recv, 0, sizeof(struct gsm_mncc));
+		frame_recv.callref = call->callref;
+		mncc_tx_to_cc(call->net, MNCC_FRAME_RECV, &frame_recv);
+		frame_recv.callref = call->remote_ref;
+		return mncc_tx_to_cc(call->net, MNCC_FRAME_RECV, &frame_recv);
+	}
+}
+
+static int mncc_disc_ind(struct gsm_call *call, int msg_type,
+			 struct gsm_mncc *disc)
+{
+	struct gsm_call *remote;
+
+	/* send release */
+	DEBUGP(DMNCC, "(call %x) Releasing call with cause %d\n",
+		call->callref, disc->cause.value);
+	mncc_tx_to_cc(call->net, MNCC_REL_REQ, disc);
+
+	/* send disc to remote */
+	if (!(remote = get_call_ref(call->remote_ref))) {
+		return 0;
+	}
+	disc->callref = remote->callref;
+	DEBUGP(DMNCC, "(call %x) Disconnecting remote with cause %d\n",
+		remote->callref, disc->cause.value);
+	return mncc_tx_to_cc(remote->net, MNCC_DISC_REQ, disc);
+}
+
+static int mncc_rel_ind(struct gsm_call *call, int msg_type, struct gsm_mncc *rel)
+{
+	struct gsm_call *remote;
+
+	/* send release to remote */
+	if (!(remote = get_call_ref(call->remote_ref))) {
+		free_call(call);
+		return 0;
+	}
+
+	rel->callref = remote->callref;
+	DEBUGP(DMNCC, "(call %x) Releasing remote with cause %d\n",
+		call->callref, rel->cause.value);
+
+	/*
+	 * Release this side of the call right now. Otherwise we end up
+	 * in this method for the other call and will also try to release
+	 * it and then we will end up with a double free and a crash
+	 */
+	free_call(call);
+	mncc_tx_to_cc(remote->net, MNCC_REL_REQ, rel);
+
+	return 0;
+}
+
+static int mncc_rel_cnf(struct gsm_call *call, int msg_type, struct gsm_mncc *rel)
+{
+	free_call(call);
+	return 0;
+}
+
+/* Internal MNCC handler input function (from CC -> MNCC -> here) */
+int int_mncc_recv(struct gsm_network *net, struct msgb *msg)
+{
+	void *arg = msgb_data(msg);
+	struct gsm_mncc *data = arg;
+	int msg_type = data->msg_type;
+	int callref;
+	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) {
+		if (callt->callref == callref) {
+			call = callt;
+			break;
+		}
+	}
+
+	/* create callref, if setup is received */
+	if (!call) {
+		if (msg_type != MNCC_SETUP_IND)
+			goto out_free; /* drop */
+		/* create call */
+		if (!(call = talloc_zero(tall_call_ctx, struct gsm_call))) {
+			struct gsm_mncc rel;
+			
+			memset(&rel, 0, sizeof(struct gsm_mncc));
+			rel.callref = callref;
+			mncc_set_cause(&rel, GSM48_CAUSE_LOC_PRN_S_LU,
+				       GSM48_CC_CAUSE_RESOURCE_UNAVAIL);
+			mncc_tx_to_cc(net, MNCC_REL_REQ, &rel);
+			goto out_free;
+		}
+		llist_add_tail(&call->entry, &call_list);
+		call->net = net;
+		call->callref = callref;
+		DEBUGP(DMNCC, "(call %x) Call created.\n", call->callref);
+	}
+
+	if (mncc_is_data_frame(msg_type)) {
+		LOGP(DMNCC, LOGL_ERROR, "(call %x) Received data frame, which is not supported.\n",
+		     call->callref);
+		goto out_free;
+	}
+
+	DEBUGP(DMNCC, "(call %x) Received message %s\n", call->callref,
+		get_mncc_name(msg_type));
+
+	switch(msg_type) {
+	case MNCC_SETUP_IND:
+		rc = mncc_setup_ind(call, msg_type, arg);
+		break;
+	case MNCC_SETUP_CNF:
+		rc = mncc_setup_cnf(call, msg_type, arg);
+		break;
+	case MNCC_SETUP_COMPL_IND:
+		break;
+	case MNCC_CALL_CONF_IND:
+		/* we now need to MODIFY the channel */
+		mncc_tx_to_cc(call->net, MNCC_LCHAN_MODIFY, data);
+		break;
+	case MNCC_ALERT_IND:
+		rc = mncc_alert_ind(call, msg_type, arg);
+		break;
+	case MNCC_NOTIFY_IND:
+		rc = mncc_notify_ind(call, msg_type, arg);
+		break;
+	case MNCC_DISC_IND:
+		rc = mncc_disc_ind(call, msg_type, arg);
+		break;
+	case MNCC_REL_IND:
+	case MNCC_REJ_IND:
+		rc = mncc_rel_ind(call, msg_type, arg);
+		break;
+	case MNCC_REL_CNF:
+		rc = mncc_rel_cnf(call, msg_type, arg);
+		break;
+	case MNCC_FACILITY_IND:
+		break;
+	case MNCC_START_DTMF_IND:
+		rc = mncc_tx_to_cc(net, MNCC_START_DTMF_REJ, data);
+		break;
+	case MNCC_STOP_DTMF_IND:
+		rc = mncc_tx_to_cc(net, MNCC_STOP_DTMF_RSP, data);
+		break;
+	case MNCC_MODIFY_IND:
+		mncc_set_cause(data, GSM48_CAUSE_LOC_PRN_S_LU,
+				GSM48_CC_CAUSE_SERV_OPT_UNIMPL);
+		DEBUGP(DMNCC, "(call %x) Rejecting MODIFY with cause %d\n",
+			call->callref, data->cause.value);
+		rc = mncc_tx_to_cc(net, MNCC_MODIFY_REJ, data);
+		break;
+	case MNCC_MODIFY_CNF:
+		break;
+	case MNCC_HOLD_IND:
+		mncc_set_cause(data, GSM48_CAUSE_LOC_PRN_S_LU,
+				GSM48_CC_CAUSE_SERV_OPT_UNIMPL);
+		DEBUGP(DMNCC, "(call %x) Rejecting HOLD with cause %d\n",
+			call->callref, data->cause.value);
+		rc = mncc_tx_to_cc(net, MNCC_HOLD_REJ, data);
+		break;
+	case MNCC_RETRIEVE_IND:
+		mncc_set_cause(data, GSM48_CAUSE_LOC_PRN_S_LU,
+				GSM48_CC_CAUSE_SERV_OPT_UNIMPL);
+		DEBUGP(DMNCC, "(call %x) Rejecting RETRIEVE with cause %d\n",
+			call->callref, data->cause.value);
+		rc = mncc_tx_to_cc(net, MNCC_RETRIEVE_REJ, data);
+		break;
+	default:
+		LOGP(DMNCC, LOGL_NOTICE, "(call %x) Message unhandled\n", callref);
+		break;
+	}
+
+out_free:
+	msgb_free(msg);
+
+	return rc;
+}
diff --git a/src/libmsc/mncc_sock.c b/src/libmsc/mncc_sock.c
new file mode 100644
index 0000000..57b4bd8
--- /dev/null
+++ b/src/libmsc/mncc_sock.c
@@ -0,0 +1,322 @@
+/* mncc_sock.c: Tie the MNCC interface to a unix domain socket */
+
+/* (C) 2008-2010 by Harald Welte <laforge@gnumonks.org>
+ * (C) 2009 by Andreas Eversberg <Andreas.Eversberg@versatel.de>
+ * (C) 2012 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 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.
+ *
+ * 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.
+ *
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <assert.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+
+#include <osmocom/core/talloc.h>
+#include <osmocom/core/select.h>
+#include <osmocom/core/socket.h>
+#include <osmocom/gsm/protocol/gsm_04_08.h>
+
+#include <osmocom/msc/debug.h>
+#include <osmocom/msc/mncc.h>
+#include <osmocom/msc/gsm_data.h>
+#include <osmocom/msc/gsm_04_08.h>
+
+struct mncc_sock_state {
+	struct gsm_network *net;
+	struct osmo_fd listen_bfd;	/* fd for listen socket */
+	struct osmo_fd conn_bfd;		/* fd for connection to lcr */
+};
+
+/* input from CC code into mncc_sock */
+int mncc_sock_from_cc(struct gsm_network *net, struct msgb *msg)
+{
+	struct gsm_mncc *mncc_in = (struct gsm_mncc *) msgb_data(msg);
+	int msg_type = mncc_in->msg_type;
+
+	/* Check if we currently have a MNCC handler connected */
+	if (net->mncc_state->conn_bfd.fd < 0) {
+		LOGP(DMNCC, LOGL_ERROR, "mncc_sock receives %s for external CC app "
+			"but socket is gone\n", get_mncc_name(msg_type));
+		if (!mncc_is_data_frame(msg_type)) {
+			/* release the request */
+			struct gsm_mncc mncc_out;
+			memset(&mncc_out, 0, sizeof(mncc_out));
+			mncc_out.callref = mncc_in->callref;
+			mncc_set_cause(&mncc_out, GSM48_CAUSE_LOC_PRN_S_LU,
+					GSM48_CC_CAUSE_TEMP_FAILURE);
+			mncc_tx_to_cc(net, MNCC_REL_REQ, &mncc_out);
+		}
+		/* free the original message */
+		msgb_free(msg);
+		return -1;
+	}
+
+	/* FIXME: check for some maximum queue depth? */
+
+	/* Actually enqueue the message and mark socket write need */
+	msgb_enqueue(&net->upqueue, msg);
+	net->mncc_state->conn_bfd.when |= BSC_FD_WRITE;
+	return 0;
+}
+
+static void mncc_sock_close(struct mncc_sock_state *state)
+{
+	struct osmo_fd *bfd = &state->conn_bfd;
+
+	LOGP(DMNCC, LOGL_NOTICE, "MNCC Socket has LOST connection\n");
+
+	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;
+
+	/* release all exisitng calls */
+	gsm0408_clear_all_trans(state->net, GSM48_PDISC_CC);
+
+	/* flush the queue */
+	while (!llist_empty(&state->net->upqueue)) {
+		struct msgb *msg = msgb_dequeue(&state->net->upqueue);
+		msgb_free(msg);
+	}
+}
+
+static int mncc_sock_read(struct osmo_fd *bfd)
+{
+	struct mncc_sock_state *state = (struct mncc_sock_state *)bfd->data;
+	struct gsm_mncc *mncc_prim;
+	struct msgb *msg;
+	int rc;
+
+	msg = msgb_alloc(sizeof(*mncc_prim)+256, "mncc_sock_rx");
+	if (!msg)
+		return -ENOMEM;
+
+	mncc_prim = (struct gsm_mncc *) msg->tail;
+
+	rc = recv(bfd->fd, msg->tail, msgb_tailroom(msg), 0);
+	if (rc == 0)
+		goto close;
+
+	if (rc < 0) {
+		if (errno == EAGAIN)
+			return 0;
+		goto close;
+	}
+	msgb_put(msg, rc);
+
+	rc = mncc_prim_check(mncc_prim, rc);
+	if (rc == 0)
+		rc = mncc_tx_to_cc(state->net, mncc_prim->msg_type, mncc_prim);
+
+	/* as we always synchronously process the message in mncc_send() and
+	 * its callbacks, we can free the message here. */
+	msgb_free(msg);
+
+	return rc;
+
+close:
+	msgb_free(msg);
+	mncc_sock_close(state);
+	return -1;
+}
+
+static int mncc_sock_write(struct osmo_fd *bfd)
+{
+	struct mncc_sock_state *state = bfd->data;
+	struct gsm_network *net = state->net;
+	int rc;
+
+	while (!llist_empty(&net->upqueue)) {
+		struct msgb *msg, *msg2;
+		struct gsm_mncc *mncc_prim;
+
+		/* peek at the beginning of the queue */
+		msg = llist_entry(net->upqueue.next, struct msgb, list);
+		mncc_prim = (struct gsm_mncc *)msg->data;
+
+		bfd->when &= ~BSC_FD_WRITE;
+
+		/* bug hunter 8-): maybe someone forgot msgb_put(...) ? */
+		if (!msgb_length(msg)) {
+			LOGP(DMNCC, LOGL_ERROR, "message type (%d) with ZERO "
+				"bytes!\n", mncc_prim->msg_type);
+			goto dontsend;
+		}
+
+		/* try to send it over the socket */
+		rc = write(bfd->fd, msgb_data(msg), msgb_length(msg));
+		if (rc == 0)
+			goto close;
+		if (rc < 0) {
+			if (errno == EAGAIN) {
+				bfd->when |= BSC_FD_WRITE;
+				break;
+			}
+			goto close;
+		}
+
+dontsend:
+		/* _after_ we send it, we can deueue */
+		msg2 = msgb_dequeue(&net->upqueue);
+		assert(msg == msg2);
+		msgb_free(msg);
+	}
+	return 0;
+
+close:
+	mncc_sock_close(state);
+
+	return -1;
+}
+
+static int mncc_sock_cb(struct osmo_fd *bfd, unsigned int flags)
+{
+	int rc = 0;
+
+	if (flags & BSC_FD_READ)
+		rc = mncc_sock_read(bfd);
+	if (rc < 0)
+		return rc;
+
+	if (flags & BSC_FD_WRITE)
+		rc = mncc_sock_write(bfd);
+
+	return rc;
+}
+
+/**
+ * Send a version indication to the remote.
+ */
+static void queue_hello(struct mncc_sock_state *mncc)
+{
+	struct gsm_mncc_hello *hello;
+	struct msgb *msg;
+
+	msg = msgb_alloc(512, "mncc hello");
+	if (!msg) {
+		LOGP(DMNCC, LOGL_ERROR, "Failed to allocate hello.\n");
+		mncc_sock_close(mncc);
+		return;
+	}
+
+	hello = (struct gsm_mncc_hello *) msgb_put(msg, sizeof(*hello));
+	hello->msg_type = MNCC_SOCKET_HELLO;
+	hello->version = MNCC_SOCK_VERSION;
+	hello->mncc_size = sizeof(struct gsm_mncc);
+	hello->data_frame_size = sizeof(struct gsm_data_frame);
+	hello->called_offset = offsetof(struct gsm_mncc, called);
+	hello->signal_offset = offsetof(struct gsm_mncc, signal);
+	hello->emergency_offset = offsetof(struct gsm_mncc, emergency);
+	hello->lchan_type_offset = offsetof(struct gsm_mncc, lchan_type);
+
+	msgb_enqueue(&mncc->net->upqueue, msg);
+	mncc->conn_bfd.when |= BSC_FD_WRITE;
+}
+
+/* accept a new connection */
+static int mncc_sock_accept(struct osmo_fd *bfd, unsigned int flags)
+{
+	struct mncc_sock_state *state = (struct mncc_sock_state *)bfd->data;
+	struct osmo_fd *conn_bfd = &state->conn_bfd;
+	struct sockaddr_un un_addr;
+	socklen_t len;
+	int rc;
+
+	len = sizeof(un_addr);
+	rc = accept(bfd->fd, (struct sockaddr *) &un_addr, &len);
+	if (rc < 0) {
+		LOGP(DMNCC, LOGL_ERROR, "Failed to accept a new connection\n");
+		return -1;
+	}
+
+	if (conn_bfd->fd >= 0) {
+		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;
+		close(rc);
+		return 0;
+	}
+
+	conn_bfd->fd = rc;
+	conn_bfd->when = BSC_FD_READ;
+	conn_bfd->cb = mncc_sock_cb;
+	conn_bfd->data = state;
+
+	if (osmo_fd_register(conn_bfd) != 0) {
+		LOGP(DMNCC, LOGL_ERROR, "Failed to register new connection fd\n");
+		close(conn_bfd->fd);
+		conn_bfd->fd = -1;
+		return -1;
+	}
+
+	LOGP(DMNCC, LOGL_NOTICE, "MNCC Socket has connection with external "
+		"call control application\n");
+
+	queue_hello(state);
+	return 0;
+}
+
+
+int mncc_sock_init(struct gsm_network *net, const char *sock_path)
+{
+	struct mncc_sock_state *state;
+	struct osmo_fd *bfd;
+	int rc;
+
+	state = talloc_zero(net, struct mncc_sock_state);
+	if (!state)
+		return -ENOMEM;
+
+	state->net = net;
+	state->conn_bfd.fd = -1;
+
+	bfd = &state->listen_bfd;
+
+	bfd->fd = osmo_sock_unix_init(SOCK_SEQPACKET, 0, sock_path,
+		OSMO_SOCK_F_BIND);
+	if (bfd->fd < 0) {
+		LOGP(DMNCC, LOGL_ERROR, "Could not create unix socket: %s: %s\n",
+		     sock_path, strerror(errno));
+		talloc_free(state);
+		return -1;
+	}
+
+	bfd->when = BSC_FD_READ;
+	bfd->cb = mncc_sock_accept;
+	bfd->data = state;
+
+	rc = osmo_fd_register(bfd);
+	if (rc < 0) {
+		LOGP(DMNCC, LOGL_ERROR, "Could not register listen fd: %d\n", rc);
+		close(bfd->fd);
+		talloc_free(state);
+		return rc;
+	}
+
+	net->mncc_state = state;
+
+	LOGP(DMNCC, LOGL_NOTICE, "MNCC socket at %s\n", sock_path);
+	return 0;
+}
diff --git a/src/libmsc/msc_ifaces.c b/src/libmsc/msc_ifaces.c
new file mode 100644
index 0000000..b76cdb4
--- /dev/null
+++ b/src/libmsc/msc_ifaces.c
@@ -0,0 +1,145 @@
+/* Implementation for MSC decisions which interface to send messages out on. */
+
+/* (C) 2016 by sysmocom s.m.f.c GmbH <info@sysmocom.de>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <osmocom/core/logging.h>
+
+#include <osmocom/msc/debug.h>
+#include <osmocom/msc/gsm_data.h>
+#include <osmocom/msc/msc_ifaces.h>
+#include <osmocom/msc/gsm_subscriber.h>
+#include <osmocom/msc/transaction.h>
+#include <osmocom/mgcp_client/mgcp_client.h>
+#include <osmocom/msc/vlr.h>
+#include <osmocom/msc/a_iface.h>
+#include <osmocom/msc/gsm_04_08.h>
+#include <osmocom/msc/msc_mgcp.h>
+
+#include "../../bscconfig.h"
+
+#ifdef BUILD_IU
+#include <osmocom/ranap/iu_client.h>
+#else
+#include <osmocom/msc/iu_dummy.h>
+#endif /* BUILD_IU */
+
+const struct value_string ran_type_names[] = {
+	OSMO_VALUE_STRING(RAN_UNKNOWN),
+	OSMO_VALUE_STRING(RAN_GERAN_A),
+	OSMO_VALUE_STRING(RAN_UTRAN_IU),
+	{ 0, NULL }
+};
+
+static int msc_tx(struct gsm_subscriber_connection *conn, struct msgb *msg)
+{
+	if (!msg)
+		return -EINVAL;
+	if (!conn) {
+		msgb_free(msg);
+		return -EINVAL;
+	}
+
+	DEBUGP(DMSC, "msc_tx %u bytes to %s via %s\n",
+	       msg->len, vlr_subscr_name(conn->vsub),
+	       ran_type_name(conn->via_ran));
+	switch (conn->via_ran) {
+	case RAN_GERAN_A:
+		msg->dst = conn;
+		return a_iface_tx_dtap(msg);
+
+	case RAN_UTRAN_IU:
+		msg->dst = conn->iu.ue_ctx;
+		return ranap_iu_tx(msg, 0);
+
+	default:
+		LOGP(DMSC, LOGL_ERROR,
+		     "msc_tx(): conn->via_ran invalid (%d)\n",
+		     conn->via_ran);
+		msgb_free(msg);
+		return -1;
+	}
+}
+
+
+int msc_tx_dtap(struct gsm_subscriber_connection *conn,
+		struct msgb *msg)
+{
+	return msc_tx(conn, msg);
+}
+
+
+/* 9.2.5 CM service accept */
+int msc_gsm48_tx_mm_serv_ack(struct gsm_subscriber_connection *conn)
+{
+	struct msgb *msg;
+	struct gsm48_hdr *gh;
+
+	if (!conn)
+		return -EINVAL;
+
+	msg = gsm48_msgb_alloc_name("GSM 04.08 SERV ACC");
+
+	gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
+	gh->proto_discr = GSM48_PDISC_MM;
+	gh->msg_type = GSM48_MT_MM_CM_SERV_ACC;
+
+	DEBUGP(DMM, "-> CM SERVICE ACCEPT %s\n",
+	       vlr_subscr_name(conn->vsub));
+
+	return msc_tx_dtap(conn, msg);
+}
+
+/* 9.2.6 CM service reject */
+int msc_gsm48_tx_mm_serv_rej(struct gsm_subscriber_connection *conn,
+			     enum gsm48_reject_value value)
+{
+	struct msgb *msg;
+
+	if (!conn)
+		return -EINVAL;
+
+	msg = gsm48_create_mm_serv_rej(value);
+	if (!msg) {
+		LOGP(DMM, LOGL_ERROR, "Failed to allocate CM Service Reject.\n");
+		return -1;
+	}
+
+	DEBUGP(DMM, "-> CM SERVICE Reject cause: %d\n", value);
+
+	return msc_tx_dtap(conn, msg);
+}
+
+int msc_tx_common_id(struct gsm_subscriber_connection *conn)
+{
+	if (!conn)
+		return -EINVAL;
+
+	/* Common ID is only sent over IuCS */
+	if (conn->via_ran != RAN_UTRAN_IU) {
+		LOGP(DMM, LOGL_INFO,
+		     "%s: Asked to transmit Common ID, but skipping"
+		     " because this is not on UTRAN\n",
+		     vlr_subscr_name(conn->vsub));
+		return 0;
+	}
+
+	DEBUGP(DIUCS, "%s: tx CommonID %s\n",
+	       vlr_subscr_name(conn->vsub), conn->vsub->imsi);
+	return ranap_iu_tx_common_id(conn->iu.ue_ctx, conn->vsub->imsi);
+}
diff --git a/src/libmsc/msc_mgcp.c b/src/libmsc/msc_mgcp.c
new file mode 100644
index 0000000..c2bbe5f
--- /dev/null
+++ b/src/libmsc/msc_mgcp.c
@@ -0,0 +1,1183 @@
+/* (C) 2017 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
+ * All Rights Reserved
+ *
+ * Author: Philipp Maier
+ *
+ * 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 <arpa/inet.h>
+
+#include <osmocom/mgcp_client/mgcp_client.h>
+#include <osmocom/core/logging.h>
+#include <osmocom/core/utils.h>
+#include <osmocom/core/timer.h>
+#include <osmocom/core/fsm.h>
+#include <osmocom/core/byteswap.h>
+#include <osmocom/msc/msc_mgcp.h>
+#include <osmocom/msc/debug.h>
+#include <osmocom/msc/transaction.h>
+#include <osmocom/msc/a_iface.h>
+#include <osmocom/msc/msc_ifaces.h>
+#include <osmocom/msc/gsm_04_08.h>
+#include <osmocom/msc/iucs.h>
+#include <osmocom/msc/vlr.h>
+
+#include "../../bscconfig.h"
+
+#define S(x)	(1 << (x))
+
+#define CONN_ID_RAN 1
+#define CONN_ID_CN 2
+
+#define MGCP_MGW_TIMEOUT 4	/* in seconds */
+#define MGCP_MGW_TIMEOUT_TIMER_NR 1
+#define MGCP_RAN_TIMEOUT 120	/* in seconds */
+#define MGCP_RAN_TIMEOUT_TIMER_NR 2
+#define MGCP_REL_TIMEOUT 60	/* in seconds */
+#define MGCP_REL_TIMEOUT_TIMER_NR 3
+#define MGCP_ASS_TIMEOUT 10	/* in seconds */
+#define MGCP_ASS_TIMEOUT_TIMER_NR 4
+
+#define ENDPOINT_ID "rtpbridge/*@mgw"
+
+/* Some internal cause codes to indicate fault condition inside the FSM */
+enum msc_mgcp_cause_code {
+	MGCP_ERR_MGW_FAIL,
+	MGCP_ERR_MGW_INVAL_RESP,
+	MGCP_ERR_MGW_TX_FAIL,
+	MGCP_ERR_MGW_TIMEOUT,
+	MGCP_ERR_UNEXP_TEARDOWN,
+	MGCP_ERR_UNSUPP_ADDR_FMT,
+	MGCP_ERR_RAN_TIMEOUT,
+	MGCP_ERR_ASS_TIMEOUT,
+	MGCP_ERR_TOOLONG,
+	MGCP_ERR_ASSGMNT_FAIL
+};
+
+/* Human readable respresentation of the faul codes, will be displayed by
+ * handle_error() */
+static const struct value_string msc_mgcp_cause_codes_names[] = {
+	{MGCP_ERR_MGW_FAIL, "operation failed on MGW"},
+	{MGCP_ERR_MGW_INVAL_RESP, "invalid / unparseable response from MGW"},
+	{MGCP_ERR_MGW_TX_FAIL, "failed to transmit MGCP message to MGW"},
+	{MGCP_ERR_MGW_TIMEOUT, "request to MGW timed out"},
+	{MGCP_ERR_UNEXP_TEARDOWN, "unexpected connection teardown"},
+	{MGCP_ERR_UNSUPP_ADDR_FMT, "unsupported network address format used (RAN)"},
+	{MGCP_ERR_RAN_TIMEOUT, "call could not be completed in time (RAN)"},
+	{MGCP_ERR_ASS_TIMEOUT, "assignment could not be completed in time (RAN)"},
+	{MGCP_ERR_TOOLONG, "string value too long"},
+	{MGCP_ERR_ASSGMNT_FAIL, "assignment failure (RAN)"},
+	{0, NULL}
+};
+
+enum fsm_msc_mgcp_states {
+	ST_CRCX_RAN,
+	ST_CRCX_CN,
+	ST_CRCX_COMPL,
+	ST_MDCX_CN,
+	ST_MDCX_CN_COMPL,
+	ST_MDCX_RAN,
+	ST_MDCX_RAN_COMPL,
+	ST_CALL,
+	ST_HALT,
+};
+
+enum msc_mgcp_fsm_evt {
+	/* Initial event: start off the state machine */
+	EV_INIT,
+
+	/* External event: Notify that the Assignment is complete and we
+	 * may now forward IP/Port of the remote call leg to the MGW */
+	EV_ASSIGN,
+
+	/* External event: Notify that the Call is complete and that the
+	 * two half open connections on the MGW should now be connected */
+	EV_CONNECT,
+
+	/* External event: Notify that the call is over and the connections
+	 * on the mgw shall be removed */
+	EV_TEARDOWN,
+
+	/* Internal event: An error occurred that requires a controlled
+	 * teardown of the RTP connections */
+	EV_TEARDOWN_ERROR,
+
+	/* Internal event: The mgcp_gw has sent its CRCX response for
+	 * the RAN side */
+	EV_CRCX_RAN_RESP,
+
+	/* Internal event: The mgcp_gw has sent its CRCX response for
+	 * the CN side */
+	EV_CRCX_CN_RESP,
+
+	/* Internal event: The mgcp_gw has sent its MDCX response for
+	 * the RAN side */
+	EV_MDCX_RAN_RESP,
+
+	/* Internal event: The mgcp_gw has sent its MDCX response for
+	 * the CN side */
+	EV_MDCX_CN_RESP,
+
+	/* Internal event: The mgcp_gw has sent its DLCX response for
+	 * the RAN and CN side */
+	EV_DLCX_ALL_RESP,
+};
+
+static const struct value_string msc_mgcp_fsm_evt_names[] = {
+	OSMO_VALUE_STRING(EV_INIT),
+	OSMO_VALUE_STRING(EV_ASSIGN),
+	OSMO_VALUE_STRING(EV_CONNECT),
+	OSMO_VALUE_STRING(EV_TEARDOWN),
+	OSMO_VALUE_STRING(EV_TEARDOWN_ERROR),
+	OSMO_VALUE_STRING(EV_CRCX_RAN_RESP),
+	OSMO_VALUE_STRING(EV_CRCX_CN_RESP),
+	OSMO_VALUE_STRING(EV_DLCX_ALL_RESP),
+	{0, NULL}
+};
+
+/* A general error handler function. On error we still have an interest to
+ * remove a half open connection (if possible). This function will execute
+ * a controlled jump to the DLCX phase. From there, the FSM will then just
+ * continue like the call were ended normally */
+#define handle_error(mgcp_ctx, cause, dlcx) _handle_error(mgcp_ctx, cause, dlcx, __FILE__, __LINE__)
+static void _handle_error(struct mgcp_ctx *mgcp_ctx, enum msc_mgcp_cause_code cause, bool dlcx, const char *file,
+			  int line)
+{
+	bool dlcx_possible = true;
+	struct osmo_fsm_inst *fi;
+	struct gsm_mncc mncc;
+
+	OSMO_ASSERT(mgcp_ctx);
+	fi = mgcp_ctx->fsm;
+	OSMO_ASSERT(fi);
+
+	/* Check if the endpoint identifier is a specific endpoint identifier,
+	 * since in order to perform a DLCX we must know the specific
+	 * identifier of the endpoint we want to release. If we do not have
+	 * this information because of errornous communication we can not
+	 * perform a DLCX. */
+	if (strstr(mgcp_ctx->rtp_endpoint, "*"))
+		dlcx_possible = false;
+
+	LOGPFSMLSRC(mgcp_ctx->fsm, LOGL_ERROR, file, line, "%s -- graceful shutdown...\n",
+		    get_value_string(msc_mgcp_cause_codes_names, cause));
+
+	/* Request the higher layers (gsm_04_08.c) to release the call. If the
+	 * problem occured after msc_mgcp_call_release() was calls, remain
+	 * silent because we already got informed and the higher layers might
+	 * already freed their context information (trans). */
+	if (!mgcp_ctx->free_ctx) {
+		mncc = (struct gsm_mncc) {
+			.msg_type = MNCC_REL_REQ,
+			.callref = mgcp_ctx->trans->callref,
+			.cause = {
+				.location = GSM48_CAUSE_LOC_PRN_S_LU,
+				.coding = 0, /* FIXME */
+				.value = GSM48_CC_CAUSE_RESOURCE_UNAVAIL
+			}
+		};
+
+		mncc_set_cause(&mncc, GSM48_CAUSE_LOC_TRANS_NET,
+			       GSM48_CC_CAUSE_RESOURCE_UNAVAIL);
+		mncc_tx_to_cc(mgcp_ctx->trans->net, MNCC_REL_REQ, &mncc);
+	}
+
+	/* For the shutdown we have two options. Whenever it makes sense to
+	 * send a DLCX to the MGW in order to be sure that the connection is
+	 * properly cleaned up, the dlcx flag should be set. In other cases
+	 * where a DLCX does not make sense (e.g. the MGW times out), halting
+	 * directly is the better options. In those cases, the dlcx flag
+	 * should not be set */
+	if (dlcx && dlcx_possible) {
+		/* Fast-forward the FSM into call state. In this state the FSM
+		 * expects either an EV_TEARDOWN or an EV_TEARDOWN_ERROR. When
+		 * one of the two events is received a DLCX will be send to
+		 * the MGW. After that. The FSM automatically halts but will
+		 * still expect a call msc_mgcp_call_release() to be freed
+		 * completely */
+		osmo_fsm_inst_state_chg(fi, ST_CALL, 0, 0);
+		osmo_fsm_inst_dispatch(mgcp_ctx->fsm, EV_TEARDOWN_ERROR, mgcp_ctx);
+	} else {
+		/* Halt the state machine immediately. The FSM will not be
+		 * freed yet, we stil require the higher layers to call
+		 * msc_mgcp_call_release() */
+		osmo_fsm_inst_state_chg(fi, ST_HALT, 0, 0);
+		osmo_fsm_inst_dispatch(fi, EV_TEARDOWN_ERROR, mgcp_ctx);
+	}
+}
+
+/* Timer callback to shut down in case of connectivity problems */
+static int fsm_timeout_cb(struct osmo_fsm_inst *fi)
+{
+	struct mgcp_ctx *mgcp_ctx = fi->priv;
+	struct mgcp_client *mgcp;
+
+	OSMO_ASSERT(mgcp_ctx);
+	mgcp = mgcp_ctx->mgcp;
+	OSMO_ASSERT(mgcp);
+
+	if (fi->T == MGCP_MGW_TIMEOUT_TIMER_NR) {
+		/* We were unable to communicate with the MGW, unfortunately
+		 * there is no meaningful action we can take now other than
+		 * giving up. */
+
+		/* Cancel the transaction that timed out */
+		mgcp_client_cancel(mgcp, mgcp_ctx->mgw_pending_trans);
+
+		/* halt of the FSM */
+		handle_error(mgcp_ctx, MGCP_ERR_MGW_TIMEOUT, false);
+	} else if (fi->T == MGCP_RAN_TIMEOUT_TIMER_NR) {
+		/* If the logic that controls the RAN is unable to negotiate a
+		 * connection, we presumably still have a working connection to
+		 * the MGW, we will try to shut down gracefully. */
+		handle_error(mgcp_ctx, MGCP_ERR_RAN_TIMEOUT, true);
+	} else if (fi->T == MGCP_REL_TIMEOUT_TIMER_NR) {
+		/* Under normal conditions, the MSC logic should always command
+		 * to release the call at some point. However, the release may
+		 * be missing due to errors in the MSC logic and we may have
+		 * reached ST_HALT because of cascading errors and timeouts. In
+		 * this and only in this case we will allow ST_HALT to free all
+		 * context information on its own authority. */
+		mgcp_ctx->free_ctx = true;
+
+		/* Initiate self destruction of the FSM */
+		osmo_fsm_inst_state_chg(fi, ST_HALT, 0, 0);
+		osmo_fsm_inst_dispatch(fi, EV_TEARDOWN, mgcp_ctx);
+	} else if (fi->T == MGCP_ASS_TIMEOUT_TIMER_NR) {
+		/* There may be rare cases in which the MSC is unable to
+		 * complete the call assignment */
+		handle_error(mgcp_ctx, MGCP_ERR_ASS_TIMEOUT, true);
+	} else {
+		/* Ther must not be any unsolicited timers in this FSM. If so,
+		 * we have serious problem. */
+		OSMO_ASSERT(false);
+	}
+
+	return 0;
+}
+
+static void mgw_crcx_ran_resp_cb(struct mgcp_response *r, void *priv);
+
+/* Callback for ST_CRCX_RAN: Send CRCX for RAN side to MGW */
+static void fsm_crcx_ran_cb(struct osmo_fsm_inst *fi, uint32_t event, void *data)
+{
+	struct mgcp_ctx *mgcp_ctx = data;
+	struct mgcp_client *mgcp;
+	struct mgcp_msg mgcp_msg;
+	struct msgb *msg;
+	int rc;
+	struct gsm_trans *trans;
+	struct gsm_subscriber_connection *conn;
+
+	OSMO_ASSERT(mgcp_ctx);
+	mgcp = mgcp_ctx->mgcp;
+	OSMO_ASSERT(mgcp);
+	trans = mgcp_ctx->trans;
+	OSMO_ASSERT(trans);
+	conn = trans->conn;
+	OSMO_ASSERT(conn);
+
+	/* NOTE: In case of error, we will not be able to perform any DLCX
+	 * operation because until this point we do not have requested any
+	 * endpoint yet. */
+
+	LOGPFSML(fi, LOGL_DEBUG,
+		 "CRCX/RAN: creating connection for the RAN side on MGW endpoint:%s...\n", mgcp_ctx->rtp_endpoint);
+
+	/* Generate MGCP message string */
+	mgcp_msg = (struct mgcp_msg) {
+		.verb = MGCP_VERB_CRCX,
+		.presence = (MGCP_MSG_PRESENCE_ENDPOINT | MGCP_MSG_PRESENCE_CALL_ID | MGCP_MSG_PRESENCE_CONN_MODE),
+		.call_id = mgcp_ctx->call_id,
+		.conn_mode = MGCP_CONN_RECV_ONLY
+	};
+	if (osmo_strlcpy(mgcp_msg.endpoint, mgcp_ctx->rtp_endpoint, sizeof(mgcp_msg.endpoint)) >=
+	    MGCP_ENDPOINT_MAXLEN) {
+		handle_error(mgcp_ctx, MGCP_ERR_TOOLONG, false);
+		return;
+	}
+
+	/* 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. */
+#ifdef BUILD_IU
+	if (conn->via_ran == RAN_UTRAN_IU)
+		mgcp_msg.conn_mode = MGCP_CONN_LOOPBACK;
+#endif
+
+	msg = mgcp_msg_gen(mgcp, &mgcp_msg);
+	OSMO_ASSERT(msg);
+
+	/* Transmit MGCP message to MGW */
+	mgcp_ctx->mgw_pending_trans = mgcp_msg_trans_id(msg);
+	rc = mgcp_client_tx(mgcp, msg, mgw_crcx_ran_resp_cb, mgcp_ctx);
+	if (rc < 0) {
+		handle_error(mgcp_ctx, MGCP_ERR_MGW_TX_FAIL, false);
+		return;
+	}
+
+	osmo_fsm_inst_state_chg(fi, ST_CRCX_CN, MGCP_MGW_TIMEOUT, MGCP_MGW_TIMEOUT_TIMER_NR);
+}
+
+/* Callback for MGCP-Client: handle response for RAN associated CRCX */
+static void mgw_crcx_ran_resp_cb(struct mgcp_response *r, void *priv)
+{
+	struct mgcp_ctx *mgcp_ctx = priv;
+	int rc;
+	struct gsm_trans *trans;
+	struct gsm_subscriber_connection *conn;
+
+	/* NOTE: In case of error, we will not be able to perform any DLCX
+	 * operation because until we either get a parseable message that
+	 * contains an error code (no endpoint is seized in those cases)
+	 * or we get an unparseable message. In this case we can not be
+	 * sure, but we also can not draw any assumptions from unparseable
+	 * messages. */
+
+	OSMO_ASSERT(mgcp_ctx);
+	trans = mgcp_ctx->trans;
+	OSMO_ASSERT(trans);
+	conn = trans->conn;
+	OSMO_ASSERT(conn);
+
+	if (r->head.response_code != 200) {
+		LOGPFSML(mgcp_ctx->fsm, LOGL_ERROR,
+			 "CRCX/RAN: response yields error: %d %s\n", r->head.response_code, r->head.comment);
+		handle_error(mgcp_ctx, MGCP_ERR_MGW_FAIL, false);
+		return;
+	}
+
+	/* memorize connection identifier and specific endpoint id */
+	osmo_strlcpy(mgcp_ctx->conn_id_ran, r->head.conn_id, sizeof(mgcp_ctx->conn_id_ran));
+	LOGPFSML(mgcp_ctx->fsm, LOGL_DEBUG, "CRCX/RAN: MGW responded with CI: %s\n", mgcp_ctx->conn_id_ran);
+	osmo_strlcpy(mgcp_ctx->rtp_endpoint, r->head.endpoint, sizeof(mgcp_ctx->rtp_endpoint));
+	LOGPFSML(mgcp_ctx->fsm, LOGL_DEBUG, "CRCX/RAN: MGW assigned endpoint: %s\n", mgcp_ctx->rtp_endpoint);
+
+	rc = mgcp_response_parse_params(r);
+	if (rc) {
+		LOGPFSML(mgcp_ctx->fsm, LOGL_ERROR, "CRCX/RAN: Cannot parse response\n");
+		handle_error(mgcp_ctx, MGCP_ERR_MGW_INVAL_RESP, false);
+		return;
+	}
+
+	LOGPFSML(mgcp_ctx->fsm, LOGL_DEBUG, "CRCX/BTS: MGW responded with address %s:%u\n", r->audio_ip, r->audio_port);
+
+	conn->rtp.local_port_ran = r->audio_port;
+	osmo_strlcpy(conn->rtp.local_addr_ran, r->audio_ip, sizeof(conn->rtp.local_addr_ran));
+
+	/* Notify the FSM that we got the response. */
+	osmo_fsm_inst_dispatch(mgcp_ctx->fsm, EV_CRCX_RAN_RESP, mgcp_ctx);
+}
+
+static void mgw_crcx_cn_resp_cb(struct mgcp_response *r, void *priv);
+
+/* Callback for ST_CRCX_CN: check MGW response and send CRCX for CN side to MGW */
+static void fsm_crcx_cn_cb(struct osmo_fsm_inst *fi, uint32_t event, void *data)
+{
+	struct mgcp_ctx *mgcp_ctx = data;
+	struct mgcp_client *mgcp;
+	struct mgcp_msg mgcp_msg;
+	struct msgb *msg;
+	int rc;
+	struct gsm_trans *trans;
+	struct gsm_subscriber_connection *conn;
+
+	OSMO_ASSERT(mgcp_ctx);
+	mgcp = mgcp_ctx->mgcp;
+	OSMO_ASSERT(mgcp);
+	trans = mgcp_ctx->trans;
+	OSMO_ASSERT(trans);
+	conn = trans->conn;
+	OSMO_ASSERT(conn);
+
+	switch (event) {
+	case EV_CRCX_RAN_RESP:
+		break;
+	default:
+		handle_error(mgcp_ctx, MGCP_ERR_UNEXP_TEARDOWN, true);
+		return;
+	}
+
+	LOGPFSML(fi, LOGL_DEBUG,
+		 "CRCX/CN creating connection for the CN side on MGW endpoint:%s...\n", mgcp_ctx->rtp_endpoint);
+
+	/* Generate MGCP message string */
+	mgcp_msg = (struct mgcp_msg) {
+		.verb = MGCP_VERB_CRCX,
+		.presence = (MGCP_MSG_PRESENCE_ENDPOINT | MGCP_MSG_PRESENCE_CALL_ID | MGCP_MSG_PRESENCE_CONN_MODE),
+		.call_id = mgcp_ctx->call_id,
+		.conn_mode = MGCP_CONN_RECV_ONLY
+	};
+	if (osmo_strlcpy(mgcp_msg.endpoint, mgcp_ctx->rtp_endpoint, sizeof(mgcp_msg.endpoint)) >=
+	    MGCP_ENDPOINT_MAXLEN) {
+		handle_error(mgcp_ctx, MGCP_ERR_TOOLONG, true);
+		return;
+	}
+
+	msg = mgcp_msg_gen(mgcp, &mgcp_msg);
+	OSMO_ASSERT(msg);
+
+	/* Transmit MGCP message to MGW */
+	mgcp_ctx->mgw_pending_trans = mgcp_msg_trans_id(msg);
+	rc = mgcp_client_tx(mgcp, msg, mgw_crcx_cn_resp_cb, mgcp_ctx);
+	if (rc < 0) {
+		handle_error(mgcp_ctx, MGCP_ERR_MGW_TX_FAIL, true);
+		return;
+	}
+
+	osmo_fsm_inst_state_chg(fi, ST_CRCX_COMPL, MGCP_MGW_TIMEOUT, MGCP_MGW_TIMEOUT_TIMER_NR);
+}
+
+/* Callback for MGCP-Client: handle response for CN associated CRCX */
+static void mgw_crcx_cn_resp_cb(struct mgcp_response *r, void *priv)
+{
+	struct mgcp_ctx *mgcp_ctx = priv;
+	int rc;
+	struct gsm_trans *trans;
+	struct gsm_subscriber_connection *conn;
+
+	OSMO_ASSERT(mgcp_ctx);
+	trans = mgcp_ctx->trans;
+	OSMO_ASSERT(trans);
+	conn = trans->conn;
+	OSMO_ASSERT(conn);
+
+	if (r->head.response_code != 200) {
+		LOGPFSML(mgcp_ctx->fsm, LOGL_ERROR,
+			 "CRCX/CN: response yields error: %d %s\n", r->head.response_code, r->head.comment);
+		handle_error(mgcp_ctx, MGCP_ERR_MGW_FAIL, true);
+		return;
+	}
+
+	/* memorize connection identifier */
+	osmo_strlcpy(mgcp_ctx->conn_id_cn, r->head.conn_id, sizeof(mgcp_ctx->conn_id_cn));
+	LOGPFSML(mgcp_ctx->fsm, LOGL_DEBUG, "CRCX/CN: MGW responded with CI: %s\n", mgcp_ctx->conn_id_cn);
+
+	rc = mgcp_response_parse_params(r);
+	if (rc) {
+		LOGPFSML(mgcp_ctx->fsm, LOGL_ERROR, "CRCX/CN: Cannot parse response\n");
+		handle_error(mgcp_ctx, MGCP_ERR_MGW_INVAL_RESP, true);
+		return;
+	}
+
+	LOGPFSML(mgcp_ctx->fsm, LOGL_DEBUG, "CRCX/CN: MGW responded with address %s:%u\n", r->audio_ip, r->audio_port);
+
+	conn->rtp.local_port_cn = r->audio_port;
+	osmo_strlcpy(conn->rtp.local_addr_cn, r->audio_ip, sizeof(conn->rtp.local_addr_cn));
+
+	/* Notify the FSM that we got the response. */
+	osmo_fsm_inst_dispatch(mgcp_ctx->fsm, EV_CRCX_CN_RESP, mgcp_ctx);
+}
+
+/* Callback for ST_CRCX_COMPL: check MGW response, start assignment */
+static void fsm_crcx_compl(struct osmo_fsm_inst *fi, uint32_t event, void *data)
+{
+	struct mgcp_ctx *mgcp_ctx = data;
+	struct gsm_trans *trans;
+	struct gsm_subscriber_connection *conn;
+
+	OSMO_ASSERT(mgcp_ctx);
+	trans = mgcp_ctx->trans;
+	OSMO_ASSERT(trans);
+	conn = trans->conn;
+	OSMO_ASSERT(conn);
+
+	switch (event) {
+	case EV_CRCX_CN_RESP:
+		break;
+	default:
+		handle_error(mgcp_ctx, MGCP_ERR_UNEXP_TEARDOWN, true);
+		return;
+	}
+
+	/* Forward assignment request to A/RANAP */
+	if (conn->via_ran == RAN_UTRAN_IU) {
+#ifdef BUILD_IU
+		/* Assign a voice channel via RANAP on 3G */
+		if (iu_rab_act_cs(trans))
+			goto error;
+#else
+		LOGPFSML(fi, LOGL_ERROR, "Cannot send Iu RAB Assignment: built without Iu support\n");
+		goto error;
+#endif
+	} else if (conn->via_ran == RAN_GERAN_A) {
+		/* Assign a voice channel via A on 2G */
+		if (a_iface_tx_assignment(trans))
+			goto error;
+	} else {
+		/* Unset or unimplemented new RAN type */
+		LOGPFSML(fi, LOGL_ERROR, "Unknown RAN type: %d\n", conn->via_ran);
+		return;
+	}
+
+	/* Respond back to MNCC (if requested) */
+	if (trans->tch_rtp_create) {
+		if (gsm48_tch_rtp_create(trans))
+			goto error;
+	}
+
+	/* Note: When we reach this point then the situation is basically that
+	 * we have two sides connected, both are in loopback. The local ports
+	 * of the side pointing towards the BSS should be already communicated
+	 * and we are waiting now the other end to pick up. */
+	osmo_fsm_inst_state_chg(fi, ST_MDCX_CN, MGCP_RAN_TIMEOUT, MGCP_RAN_TIMEOUT_TIMER_NR);
+	return;
+
+error:
+	handle_error(mgcp_ctx, MGCP_ERR_ASSGMNT_FAIL, true);
+}
+
+static void mgw_mdcx_cn_resp_cb(struct mgcp_response *r, void *priv);
+
+/* Callback for ST_MDCX_CN: send MDCX for RAN side to MGW */
+static void fsm_mdcx_cn_cb(struct osmo_fsm_inst *fi, uint32_t event, void *data)
+{
+	struct mgcp_ctx *mgcp_ctx = data;
+	struct mgcp_client *mgcp;
+	struct gsm_trans *trans;
+	struct gsm_subscriber_connection *conn;
+	struct mgcp_msg mgcp_msg;
+	struct msgb *msg;
+	int rc;
+
+	OSMO_ASSERT(mgcp_ctx);
+	mgcp = mgcp_ctx->mgcp;
+	OSMO_ASSERT(mgcp);
+	trans = mgcp_ctx->trans;
+	OSMO_ASSERT(trans);
+	conn = trans->conn;
+	OSMO_ASSERT(conn);
+
+	switch (event) {
+	case EV_CONNECT:
+		break;
+	default:
+		handle_error(mgcp_ctx, MGCP_ERR_UNEXP_TEARDOWN, true);
+		return;
+	}
+
+	LOGPFSML(fi, LOGL_DEBUG,
+		 "MDCX/CN: completing connection for the CN side on MGW endpoint:%p, remote leg expects RTP input on address %s:%u\n",
+		 mgcp_ctx->rtp_endpoint, conn->rtp.remote_addr_cn, conn->rtp.remote_port_cn);
+
+	/* Generate MGCP message string */
+	mgcp_msg = (struct mgcp_msg) {
+		.verb = MGCP_VERB_MDCX,
+		.presence = (MGCP_MSG_PRESENCE_ENDPOINT | MGCP_MSG_PRESENCE_CALL_ID | MGCP_MSG_PRESENCE_CONN_ID |
+			     MGCP_MSG_PRESENCE_CONN_MODE | MGCP_MSG_PRESENCE_AUDIO_IP |
+			     MGCP_MSG_PRESENCE_AUDIO_PORT),
+		.call_id = mgcp_ctx->call_id,
+		.conn_id = mgcp_ctx->conn_id_cn,
+		.conn_mode = MGCP_CONN_RECV_SEND,
+		.audio_ip = conn->rtp.remote_addr_cn,
+		.audio_port = conn->rtp.remote_port_cn,
+		.codecs[0] = conn->rtp.codec_cn,
+		.codecs_len = 1
+	};
+	if (osmo_strlcpy(mgcp_msg.endpoint, mgcp_ctx->rtp_endpoint, sizeof(mgcp_msg.endpoint)) >=
+	    MGCP_ENDPOINT_MAXLEN) {
+		handle_error(mgcp_ctx, MGCP_ERR_TOOLONG, true);
+		return;
+	}
+
+	msg = mgcp_msg_gen(mgcp, &mgcp_msg);
+	OSMO_ASSERT(msg);
+
+	/* Transmit MGCP message to MGW */
+	mgcp_ctx->mgw_pending_trans = mgcp_msg_trans_id(msg);
+	rc = mgcp_client_tx(mgcp, msg, mgw_mdcx_cn_resp_cb, mgcp_ctx);
+	if (rc < 0) {
+		handle_error(mgcp_ctx, MGCP_ERR_MGW_TX_FAIL, true);
+		return;
+	}
+
+	osmo_fsm_inst_state_chg(fi, ST_MDCX_CN_COMPL, MGCP_MGW_TIMEOUT, MGCP_MGW_TIMEOUT_TIMER_NR);
+}
+
+/* Callback for MGCP-Client: handle response for CN associated CRCX */
+static void mgw_mdcx_cn_resp_cb(struct mgcp_response *r, void *priv)
+{
+	struct mgcp_ctx *mgcp_ctx = priv;
+
+	OSMO_ASSERT(mgcp_ctx);
+
+	if (r->head.response_code != 200) {
+		LOGPFSML(mgcp_ctx->fsm, LOGL_ERROR,
+			 "MDCX/CN: response yields error: %d %s\n", r->head.response_code, r->head.comment);
+		handle_error(mgcp_ctx, MGCP_ERR_MGW_FAIL, true);
+		return;
+	}
+
+	/* Notify the FSM that we got the response. */
+	osmo_fsm_inst_dispatch(mgcp_ctx->fsm, EV_MDCX_CN_RESP, mgcp_ctx);
+}
+
+/* Callback for ST_MDCX_CN_COMPL: wait for mgw response, move on with the MDCX
+ * for the RAN side if we already have valid IP/Port data for the RAN sided
+ * RTP stream. */
+static void fsm_mdcx_cn_compl_cb(struct osmo_fsm_inst *fi, uint32_t event, void *data)
+{
+	struct mgcp_ctx *mgcp_ctx = data;
+	struct gsm_subscriber_connection *conn;
+	struct gsm_trans *trans;
+
+	OSMO_ASSERT(mgcp_ctx);
+	trans = mgcp_ctx->trans;
+	OSMO_ASSERT(trans);
+	conn = trans->conn;
+	OSMO_ASSERT(conn);
+
+	switch (event) {
+	case EV_MDCX_CN_RESP:
+		break;
+	default:
+		handle_error(mgcp_ctx, MGCP_ERR_UNEXP_TEARDOWN, true);
+		return;
+	}
+
+	/* Enter MDCX phase, but we must be sure that the Assigmnet on the A or
+	 * IuCS interface is complete (IP-Address and Port are valid) */
+	osmo_fsm_inst_state_chg(fi, ST_MDCX_RAN, MGCP_ASS_TIMEOUT, MGCP_ASS_TIMEOUT_TIMER_NR);
+
+	/* If we already have a valid remote port and IP-Address from the RAN side
+	 * call leg, the assignment has been completed before we got here, so we
+	 * may move on immediately */
+	if (conn->rtp.remote_port_ran != 0 || strlen(conn->rtp.remote_addr_ran) > 0)
+		osmo_fsm_inst_dispatch(mgcp_ctx->fsm, EV_ASSIGN, mgcp_ctx);
+}
+
+static void mgw_mdcx_ran_resp_cb(struct mgcp_response *r, void *priv);
+
+/* Callback for ST_MDCX_RAN: wait for assignment completion, send MDCX for CN side to MGW */
+static void fsm_mdcx_ran_cb(struct osmo_fsm_inst *fi, uint32_t event, void *data)
+{
+	struct mgcp_ctx *mgcp_ctx = data;
+	struct mgcp_client *mgcp;
+	struct gsm_trans *trans;
+	struct gsm_subscriber_connection *conn;
+	struct mgcp_msg mgcp_msg;
+	struct msgb *msg;
+	int rc;
+
+	OSMO_ASSERT(mgcp_ctx);
+	mgcp = mgcp_ctx->mgcp;
+	OSMO_ASSERT(mgcp);
+	trans = mgcp_ctx->trans;
+	OSMO_ASSERT(trans);
+	conn = trans->conn;
+	OSMO_ASSERT(conn);
+
+	switch (event) {
+	case EV_ASSIGN:
+		break;
+	default:
+		handle_error(mgcp_ctx, MGCP_ERR_UNEXP_TEARDOWN, true);
+		return;
+	}
+
+	LOGPFSML(fi, LOGL_DEBUG,
+		 "MDCX/RAN: completing connection for the CN side on MGW endpoint:%p, RAN expects RTP input on address %s:%u\n",
+		 mgcp_ctx->rtp_endpoint, conn->rtp.remote_addr_ran, conn->rtp.remote_port_ran);
+
+	/* Generate MGCP message string */
+	mgcp_msg = (struct mgcp_msg) {
+		.verb = MGCP_VERB_MDCX,
+		.presence = (MGCP_MSG_PRESENCE_ENDPOINT | MGCP_MSG_PRESENCE_CALL_ID | MGCP_MSG_PRESENCE_CONN_ID |
+			     MGCP_MSG_PRESENCE_CONN_MODE | MGCP_MSG_PRESENCE_AUDIO_IP |
+			     MGCP_MSG_PRESENCE_AUDIO_PORT),
+		.call_id = mgcp_ctx->call_id,
+		.conn_id = mgcp_ctx->conn_id_ran,
+		.conn_mode = MGCP_CONN_RECV_SEND,
+		.audio_ip = conn->rtp.remote_addr_ran,
+		.audio_port = conn->rtp.remote_port_ran,
+		.codecs[0] = conn->rtp.codec_ran,
+		.codecs_len = 1
+	};
+	if (osmo_strlcpy(mgcp_msg.endpoint, mgcp_ctx->rtp_endpoint, sizeof(mgcp_msg.endpoint)) >=
+	    MGCP_ENDPOINT_MAXLEN) {
+		handle_error(mgcp_ctx, MGCP_ERR_TOOLONG, true);
+		return;
+	}
+
+	msg = mgcp_msg_gen(mgcp, &mgcp_msg);
+	OSMO_ASSERT(msg);
+
+	/* Transmit MGCP message to MGW */
+	mgcp_ctx->mgw_pending_trans = mgcp_msg_trans_id(msg);
+	rc = mgcp_client_tx(mgcp, msg, mgw_mdcx_ran_resp_cb, mgcp_ctx);
+	if (rc < 0) {
+		handle_error(mgcp_ctx, MGCP_ERR_MGW_TX_FAIL, true);
+		return;
+	}
+
+	osmo_fsm_inst_state_chg(fi, ST_MDCX_RAN_COMPL, MGCP_MGW_TIMEOUT, MGCP_MGW_TIMEOUT_TIMER_NR);
+}
+
+/* Callback for MGCP-Client: handle response for CN associated CRCX */
+static void mgw_mdcx_ran_resp_cb(struct mgcp_response *r, void *priv)
+{
+	struct mgcp_ctx *mgcp_ctx = priv;
+
+	OSMO_ASSERT(mgcp_ctx);
+
+	if (r->head.response_code != 200) {
+		LOGPFSML(mgcp_ctx->fsm, LOGL_ERROR,
+			 "MDCX/RAN: response yields error: %d %s\n", r->head.response_code, r->head.comment);
+		handle_error(mgcp_ctx, MGCP_ERR_MGW_FAIL, true);
+		return;
+	}
+
+	/* Notify the FSM that we got the response. */
+	osmo_fsm_inst_dispatch(mgcp_ctx->fsm, EV_MDCX_RAN_RESP, mgcp_ctx);
+}
+
+/* Callback for ST_MDCX_RAN_COMPL: check MGW response */
+static void fsm_mdcx_ran_compl_cb(struct osmo_fsm_inst *fi, uint32_t event, void *data)
+{
+	struct mgcp_ctx *mgcp_ctx = data;
+	OSMO_ASSERT(mgcp_ctx);
+
+	switch (event) {
+	case EV_MDCX_RAN_RESP:
+		break;
+	default:
+		handle_error(mgcp_ctx, MGCP_ERR_UNEXP_TEARDOWN, true);
+		return;
+	}
+
+	LOGPFSML(fi, LOGL_DEBUG, "call active, waiting for teardown...\n");
+	osmo_fsm_inst_state_chg(fi, ST_CALL, 0, 0);
+}
+
+static void mgw_dlcx_all_resp_cb(struct mgcp_response *r, void *priv);
+
+/* Callback for ST_CALL: call is active, send DLCX for both sides on teardown */
+static void fsm_call_cb(struct osmo_fsm_inst *fi, uint32_t event, void *data)
+{
+
+	struct mgcp_ctx *mgcp_ctx = (struct mgcp_ctx *)data;
+	struct mgcp_client *mgcp;
+	struct mgcp_msg mgcp_msg;
+	struct msgb *msg;
+	int rc;
+
+	OSMO_ASSERT(mgcp_ctx);
+	mgcp = mgcp_ctx->mgcp;
+	OSMO_ASSERT(mgcp);
+
+	LOGPFSML(fi, LOGL_DEBUG,
+		 "DLCX: removing connection for the RAN and CN side on MGW endpoint:%s...\n", mgcp_ctx->rtp_endpoint);
+
+	/* Generate MGCP message string */
+	mgcp_msg = (struct mgcp_msg) {
+		.verb = MGCP_VERB_DLCX,
+		.presence = (MGCP_MSG_PRESENCE_ENDPOINT | MGCP_MSG_PRESENCE_CALL_ID),
+		.call_id = mgcp_ctx->call_id
+	};
+	if (osmo_strlcpy(mgcp_msg.endpoint, mgcp_ctx->rtp_endpoint, sizeof(mgcp_msg.endpoint)) >=
+	    MGCP_ENDPOINT_MAXLEN) {
+		handle_error(mgcp_ctx, MGCP_ERR_TOOLONG, true);
+		return;
+	}
+
+	msg = mgcp_msg_gen(mgcp, &mgcp_msg);
+	OSMO_ASSERT(msg);
+
+	/* Transmit MGCP message to MGW */
+	mgcp_ctx->mgw_pending_trans = mgcp_msg_trans_id(msg);
+	rc = mgcp_client_tx(mgcp, msg, mgw_dlcx_all_resp_cb, mgcp_ctx);
+	if (rc < 0) {
+		handle_error(mgcp_ctx, MGCP_ERR_MGW_TX_FAIL, true);
+		return;
+	}
+
+	osmo_fsm_inst_state_chg(fi, ST_HALT, MGCP_MGW_TIMEOUT, MGCP_MGW_TIMEOUT_TIMER_NR);
+}
+
+/* Callback for MGCP-Client: handle response for CN associated CRCX */
+static void mgw_dlcx_all_resp_cb(struct mgcp_response *r, void *priv)
+{
+	struct mgcp_ctx *mgcp_ctx = priv;
+
+	OSMO_ASSERT(mgcp_ctx);
+
+	/* DLCX is the only command where 250 is permitted as positive result */
+	if (r->head.response_code != 200 && r->head.response_code != 250) {
+		LOGPFSML(mgcp_ctx->fsm, LOGL_ERROR,
+			 "DLCX: response yields error: %d %s\n", r->head.response_code, r->head.comment);
+		handle_error(mgcp_ctx, MGCP_ERR_MGW_FAIL, true);
+		return;
+	}
+
+	/* Notify the FSM that we got the response. */
+	osmo_fsm_inst_dispatch(mgcp_ctx->fsm, EV_DLCX_ALL_RESP, mgcp_ctx);
+}
+
+/* Callback for ST_HALT: Terminate the state machine */
+static void fsm_halt_cb(struct osmo_fsm_inst *fi, uint32_t event, void *data)
+{
+	struct mgcp_ctx *mgcp_ctx = data;
+	struct mgcp_client *mgcp;
+
+	OSMO_ASSERT(mgcp_ctx);
+	mgcp = mgcp_ctx->mgcp;
+	OSMO_ASSERT(mgcp);
+
+	/* NOTE: We must not free the context information now, we have to
+	 * wait until msc_mgcp_call_release() is called. Then we are sure
+	 * that the logic controlling us is fully aware that the context
+	 * information is freed. If we would free early now the controlling
+	 * logic might mistakenly think that the context info is still alive,
+	 * so lets keep the context info until we are explicitly asked for
+	 * throwing it away. */
+	if (mgcp_ctx->free_ctx) {
+		/* Be sure that there is no pending MGW transaction */
+		mgcp_client_cancel(mgcp, mgcp_ctx->mgw_pending_trans);
+
+		/* Free FSM and its context information  */
+		osmo_fsm_inst_free(mgcp_ctx->fsm);
+		talloc_free(mgcp_ctx);
+		return;
+	}
+
+	osmo_fsm_inst_state_chg(fi, ST_HALT, MGCP_REL_TIMEOUT, MGCP_REL_TIMEOUT_TIMER_NR);
+}
+
+static struct osmo_fsm_state fsm_msc_mgcp_states[] = {
+
+	/* Startup state machine, send CRCX for RAN side. */
+	[ST_CRCX_RAN] = {
+			 .in_event_mask = S(EV_INIT),
+			 .out_state_mask = S(ST_HALT) | S(ST_CALL) | S(ST_CRCX_CN),
+			 .name = OSMO_STRINGIFY(ST_CRCX_RAN),
+			 .action = fsm_crcx_ran_cb,
+			 },
+	/* When the response to the RAN CRCX is received, then proceed with
+	   sending the CRCX for CN side */
+	[ST_CRCX_CN] = {
+			.in_event_mask = S(EV_TEARDOWN) | S(EV_TEARDOWN_ERROR) | S(EV_CRCX_RAN_RESP),
+			.out_state_mask = S(ST_HALT) | S(ST_CALL) | S(ST_CRCX_COMPL),
+			.name = OSMO_STRINGIFY(ST_CRCX_CN),
+			.action = fsm_crcx_cn_cb,
+			},
+	/* Complete the CRCX phase by starting the assignment. Depending on the
+	 * RAT (Radio Access Technology), this will either trigger an
+	 * Assignment Request on the A-Interface or an RAB-Assignment on the
+	 * IU-interface */
+	[ST_CRCX_COMPL] = {
+			   .in_event_mask = S(EV_TEARDOWN) | S(EV_TEARDOWN_ERROR) | S(EV_CRCX_CN_RESP),
+			   .out_state_mask = S(ST_HALT) | S(ST_CALL) | S(ST_MDCX_CN),
+			   .name = OSMO_STRINGIFY(ST_CRCX_COMPL),
+			   .action = fsm_crcx_compl,
+			   },
+	/* Wait for MSC to complete the assignment request, when complete, we
+	 * will enter the MDCX phase by sending an MDCX for the CN side to the
+	 * MGW */
+	[ST_MDCX_CN] = {
+			.in_event_mask = S(EV_TEARDOWN) | S(EV_TEARDOWN_ERROR) | S(EV_CONNECT),
+			.out_state_mask = S(ST_HALT) | S(ST_CALL) | S(ST_MDCX_CN_COMPL),
+			.name = OSMO_STRINGIFY(ST_MDCX_CN),
+			.action = fsm_mdcx_cn_cb,
+			},
+	/* We arrive in this state when the MDCX phase for the CN side has
+	 * completed we will check the IP/Port of the RAN connection. If this
+	 * data is valid we may continue with the MDCX phase for the RAN side.
+	 * If not we wait until the assinment completes on the A or on the IuCS
+	 * interface. The completion of the assignment will fill in the port and
+	 * IP-Address of the RAN side and way may continue then. */
+	[ST_MDCX_CN_COMPL] = {
+			      .in_event_mask = S(EV_TEARDOWN) | S(EV_MDCX_CN_RESP),
+			      .out_state_mask = S(ST_HALT) | S(ST_CALL) | S(ST_MDCX_RAN),
+			      .name = OSMO_STRINGIFY(ST_MDCX_CN_COMPL),
+			      .action = fsm_mdcx_cn_compl_cb,
+			      },
+	/* When the response for the CN MDCX is received, send the MDCX for the
+	 * RAN side to the MGW */
+	[ST_MDCX_RAN] = {
+			 .in_event_mask = S(EV_TEARDOWN) | S(EV_TEARDOWN_ERROR) | S(EV_ASSIGN),
+			 .out_state_mask = S(ST_HALT) | S(ST_CALL) | S(ST_MDCX_RAN_COMPL),
+			 .name = OSMO_STRINGIFY(ST_MDCX_RAN),
+			 .action = fsm_mdcx_ran_cb,
+			 },
+	/* The RAN side MDCX phase is complete when the response is received
+	 * from the MGW. The call is then active, we change to ST_CALL and wait
+	 * there until the call ends. */
+	[ST_MDCX_RAN_COMPL] = {
+			       .in_event_mask = S(EV_TEARDOWN) | S(EV_TEARDOWN_ERROR) | S(EV_MDCX_RAN_RESP),
+			       .out_state_mask = S(ST_HALT) | S(ST_CALL),
+			       .name = OSMO_STRINGIFY(ST_MDCX_RAN_COMPL),
+			       .action = fsm_mdcx_ran_compl_cb,
+			       },
+	/* We are now in the active call phase, wait until the call is done
+	 * and send a DLCX then to remove all connections from the MGW */
+	[ST_CALL] = {
+		     .in_event_mask = S(EV_TEARDOWN) | S(EV_TEARDOWN_ERROR),
+		     .out_state_mask = S(ST_HALT),
+		     .name = OSMO_STRINGIFY(ST_CALL),
+		     .action = fsm_call_cb,
+		     },
+	/* When the MGW confirms that the connections are terminated, then halt
+	 * the state machine. */
+	[ST_HALT] = {
+		     .in_event_mask = S(EV_TEARDOWN) | S(EV_TEARDOWN_ERROR) | S(EV_DLCX_ALL_RESP),
+		     .out_state_mask = S(ST_HALT),
+		     .name = OSMO_STRINGIFY(ST_HALT),
+		     .action = fsm_halt_cb,
+		     },
+};
+
+/* State machine definition */
+static struct osmo_fsm fsm_msc_mgcp = {
+	.name = "MGW",
+	.states = fsm_msc_mgcp_states,
+	.num_states = ARRAY_SIZE(fsm_msc_mgcp_states),
+	.log_subsys = DMGCP,
+	.timer_cb = fsm_timeout_cb,
+	.event_names = msc_mgcp_fsm_evt_names,
+};
+
+/* Notify that a new call begins. This will create a connection for the
+ * RAN and the CN on the MGW.
+ * Parameter:
+ * trans: transaction context.
+ * Returns -EINVAL on error, 0 on success. */
+int msc_mgcp_call_assignment(struct gsm_trans *trans)
+{
+	struct mgcp_ctx *mgcp_ctx;
+	char name[32];
+	static bool fsm_registered = false;
+	struct gsm_subscriber_connection *conn;
+	struct mgcp_client *mgcp;
+
+	OSMO_ASSERT(trans);
+
+	if (!trans->conn) {
+		LOGP(DMGCP, LOGL_ERROR, "(subscriber:%s) invalid conn, call assignment failed\n",
+		     vlr_subscr_name(trans->vsub));
+		return -EINVAL;
+	}
+
+	conn = trans->conn;
+	mgcp = conn->network->mgw.client;
+	OSMO_ASSERT(mgcp);
+
+	if (conn->rtp.mgcp_ctx) {
+		LOGP(DMGCP, LOGL_ERROR, "(subscriber:%s) double assignment detected, dropping...\n",
+		     vlr_subscr_name(trans->vsub));
+		return -EINVAL;
+	}
+
+#ifdef BUILD_IU
+	/* FIXME: HACK. where to scope the RAB Id? At the conn / subscriber / ranap_ue_conn_ctx? */
+	static uint8_t next_iu_rab_id = 1;
+	if (conn->via_ran == RAN_UTRAN_IU)
+		conn->iu.rab_id = next_iu_rab_id++;
+#endif
+
+	if (snprintf(name, sizeof(name), "MGW_%i", trans->transaction_id) >= sizeof(name))
+		return -EINVAL;
+
+	/* Register the fsm description (if not already done) */
+	if (fsm_registered == false) {
+		osmo_fsm_register(&fsm_msc_mgcp);
+		fsm_registered = true;
+	}
+
+	/* Allocate and configure a new fsm instance */
+	mgcp_ctx = talloc_zero(NULL, struct mgcp_ctx);
+	OSMO_ASSERT(mgcp_ctx);
+	if (osmo_strlcpy(mgcp_ctx->rtp_endpoint, ENDPOINT_ID, sizeof(mgcp_ctx->rtp_endpoint)) >=
+	    MGCP_ENDPOINT_MAXLEN) {
+		talloc_free(mgcp_ctx);
+		LOGP(DMGCP, LOGL_ERROR, "(subscriber:%s) endpoint identifier (%s) exceeds maximum length...\n",
+		     vlr_subscr_name(trans->vsub), ENDPOINT_ID);
+		return -EINVAL;
+	}
+	mgcp_ctx->fsm = osmo_fsm_inst_alloc(&fsm_msc_mgcp, NULL, NULL, LOGL_DEBUG, name);
+	OSMO_ASSERT(mgcp_ctx->fsm);
+	mgcp_ctx->fsm->priv = mgcp_ctx;
+	mgcp_ctx->mgcp = mgcp;
+	mgcp_ctx->trans = trans;
+	mgcp_ctx->call_id = trans->callref;
+
+	/* start state machine */
+	OSMO_ASSERT(mgcp_ctx->fsm->state == ST_CRCX_RAN);
+	osmo_fsm_inst_dispatch(mgcp_ctx->fsm, EV_INIT, mgcp_ctx);
+
+	conn->rtp.mgcp_ctx = mgcp_ctx;
+
+	LOGP(DMGCP, LOGL_DEBUG, "(subscriber:%s) call assignment initiated\n",
+	     vlr_subscr_name(conn->vsub));
+
+	return 0;
+}
+
+/* Inform the FSM that the assignment (RAN connection) is now complete.
+ * Parameter:
+ * conn: subscriber connection context.
+ * port: port number of the remote leg.
+ * addr: IP-address of the remote leg.
+ * Returns -EINVAL on error, 0 on success. */
+int msc_mgcp_ass_complete(struct gsm_subscriber_connection *conn, uint16_t port, char *addr)
+{
+	struct mgcp_ctx *mgcp_ctx;
+
+	OSMO_ASSERT(conn);
+
+	if (port == 0) {
+		LOGP(DMGCP, LOGL_ERROR, "(subscriber:%s) invalid remote call leg port, assignment completion failed\n",
+		     vlr_subscr_name(conn->vsub));
+		return -EINVAL;
+	}
+	if (!addr || strlen(addr) <= 0) {
+		LOGP(DMGCP, LOGL_ERROR, "(subscriber:%s) missing remote call leg address, assignment completion failed\n",
+		     vlr_subscr_name(conn->vsub));
+		return -EINVAL;
+	}
+
+	mgcp_ctx = conn->rtp.mgcp_ctx;
+	if (!mgcp_ctx) {
+		LOGP(DMGCP, LOGL_ERROR, "(subscriber:%s) invalid mgcp context, assignment completion failed.\n",
+		     vlr_subscr_name(conn->vsub));
+		return -EINVAL;
+	}
+
+	/* Memorize port and IP-Address of the remote RAN call leg. We need this
+	 * information at latest when we enter the MDCX phase for the RAN side. */
+	conn->rtp.remote_port_ran = port;
+	osmo_strlcpy(conn->rtp.remote_addr_ran, addr, sizeof(conn->rtp.remote_addr_ran));
+
+	LOGP(DMGCP, LOGL_DEBUG, "(subscriber:%s) assignment completed, rtp %s:%d.\n",
+	     vlr_subscr_name(conn->vsub), conn->rtp.remote_addr_ran, port);
+
+	/* Note: We only dispatch the event if we are really waiting for the
+	 * assignment, if we are not yet waiting, there is no need to loudly
+	 * broadcast an event that the all other states do not understand anyway */
+	if (mgcp_ctx->fsm->state == ST_MDCX_RAN)
+		osmo_fsm_inst_dispatch(mgcp_ctx->fsm, EV_ASSIGN, mgcp_ctx);
+
+	return 0;
+}
+
+/* Make the connection of a previously assigned call complete
+ * Parameter:
+ * trans: transaction context.
+ * port: port number of the remote leg.
+ * addr: IP-address of the remote leg.
+ * Returns -EINVAL on error, 0 on success. */
+int msc_mgcp_call_complete(struct gsm_trans *trans, uint16_t port, char *addr)
+{
+	struct mgcp_ctx *mgcp_ctx;
+	struct gsm_subscriber_connection *conn;
+
+	OSMO_ASSERT(trans);
+	OSMO_ASSERT(addr);
+
+	if (port == 0) {
+		LOGP(DMGCP, LOGL_ERROR, "(subscriber:%s) invalid remote call leg port, call completion failed\n",
+		     vlr_subscr_name(trans->vsub));
+		return -EINVAL;
+	}
+	if (!addr || strlen(addr) <= 0) {
+		LOGP(DMGCP, LOGL_ERROR, "(subscriber:%s) missing remote call leg address, call completion failed\n",
+		     vlr_subscr_name(trans->vsub));
+		return -EINVAL;
+	}
+	if (!trans->conn) {
+		LOGP(DMGCP, LOGL_ERROR, "(subscriber:%s) invalid conn, call completion failed\n",
+		     vlr_subscr_name(trans->vsub));
+		return -EINVAL;
+	}
+	if (!trans->conn->rtp.mgcp_ctx) {
+		LOGP(DMGCP, LOGL_ERROR, "(subscriber:%s) invalid mgcp context, call completion failed.\n",
+		     vlr_subscr_name(trans->vsub));
+		return -EINVAL;
+	}
+	if (!trans->conn->rtp.mgcp_ctx->fsm) {
+		LOGP(DMGCP, LOGL_ERROR, "(subscriber:%s) no FSM, call completion failed\n",
+		     vlr_subscr_name(trans->vsub));
+		return -EINVAL;
+	}
+
+	mgcp_ctx = trans->conn->rtp.mgcp_ctx;
+
+	/* The FSM should already have passed all CRCX phases and be ready to move
+	 * on with the MDCX phases. */
+	if (mgcp_ctx->fsm->state != ST_MDCX_CN) {
+		LOGP(DMGCP, LOGL_ERROR, "(subscriber:%s) invalid call state, call completion failed\n",
+		     vlr_subscr_name(trans->vsub));
+		return -EINVAL;
+	}
+
+	conn = trans->conn;
+	osmo_strlcpy(conn->rtp.remote_addr_cn, addr, sizeof(conn->rtp.remote_addr_cn));
+	conn->rtp.remote_port_cn = port;
+
+	osmo_fsm_inst_dispatch(mgcp_ctx->fsm, EV_CONNECT, mgcp_ctx);
+
+	LOGP(DMGCP, LOGL_DEBUG, "(subscriber:%s) call completion initiated\n",
+	     vlr_subscr_name(conn->vsub));
+
+	return 0;
+}
+
+/* Release ongoing call.
+ * Parameter:
+ * trans: connection context.
+ * Returns -EINVAL on error, 0 on success. */
+int msc_mgcp_call_release(struct gsm_trans *trans)
+{
+	struct mgcp_ctx *mgcp_ctx;
+
+	OSMO_ASSERT(trans);
+
+	if (!trans->conn) {
+		LOGP(DMGCP, LOGL_ERROR, "(subscriber:%s) invalid conn, call release failed\n",
+		     vlr_subscr_name(trans->vsub));
+		return -EINVAL;
+	}
+	if (!trans->conn->rtp.mgcp_ctx) {
+		LOGP(DMGCP, LOGL_ERROR, "(subscriber:%s) invalid mgcp context, call release failed.\n",
+		     vlr_subscr_name(trans->vsub));
+		return -EINVAL;
+	}
+	if (!trans->conn->rtp.mgcp_ctx->fsm) {
+		LOGP(DMGCP, LOGL_ERROR, "(subscriber:%s) no FSM, call release failed\n",
+		     vlr_subscr_name(trans->vsub));
+		return -EINVAL;
+	}
+
+	mgcp_ctx = trans->conn->rtp.mgcp_ctx;
+
+	/* Inform the FSM that as soon as it reaches ST_HALT it may free
+	 * all context information immediately */
+	mgcp_ctx->free_ctx = true;
+
+	/* Initaite teardown, regardless of which state we are currently
+	 * in */
+	osmo_fsm_inst_dispatch(mgcp_ctx->fsm, EV_TEARDOWN, mgcp_ctx);
+
+	/* Prevent any further operation that is triggered from outside by
+	 * overwriting the context pointer with NULL. The FSM will now
+	 * take care for a graceful shutdown and when done it will free
+	 * all related context information */
+	trans->conn->rtp.mgcp_ctx = NULL;
+
+	LOGP(DMGCP, LOGL_DEBUG, "(subscriber:%s) call release initiated\n",
+	     vlr_subscr_name(trans->vsub));
+
+	return 0;
+}
diff --git a/src/libmsc/msc_vty.c b/src/libmsc/msc_vty.c
new file mode 100644
index 0000000..cdf3184
--- /dev/null
+++ b/src/libmsc/msc_vty.c
@@ -0,0 +1,1503 @@
+/* MSC interface to quagga VTY */
+/* (C) 2016-2018 by sysmocom s.m.f.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
+ * 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/>.
+ *
+ */
+
+/* NOTE: I would have liked to call this the MSC_NODE instead of the MSC_NODE,
+ * but MSC_NODE already exists to configure a remote MSC for osmo-bsc. */
+
+#include "../../bscconfig.h"
+
+#include <inttypes.h>
+#include <limits.h>
+
+#include <osmocom/gsm/protocol/gsm_08_58.h>
+#include <osmocom/gsm/protocol/gsm_04_14.h>
+
+#include <osmocom/sigtran/sccp_helpers.h>
+
+#include <osmocom/vty/command.h>
+#include <osmocom/vty/logging.h>
+#include <osmocom/vty/misc.h>
+#include <osmocom/vty/stats.h>
+
+#ifdef BUILD_IU
+#include <osmocom/ranap/iu_client.h>
+#endif
+
+#include <osmocom/msc/vty.h>
+#include <osmocom/msc/osmo_msc.h>
+#include <osmocom/msc/gsm_data.h>
+#include <osmocom/msc/gsm_subscriber.h>
+#include <osmocom/msc/vlr.h>
+#include <osmocom/msc/transaction.h>
+#include <osmocom/msc/db.h>
+#include <osmocom/msc/a_iface.h>
+#include <osmocom/msc/sms_queue.h>
+#include <osmocom/msc/silent_call.h>
+#include <osmocom/msc/gsm_04_80.h>
+#include <osmocom/msc/gsm_04_14.h>
+#include <osmocom/msc/signal.h>
+#include <osmocom/msc/mncc_int.h>
+#include <osmocom/msc/rrlp.h>
+
+static struct gsm_network *gsmnet = NULL;
+
+struct cmd_node net_node = {
+	GSMNET_NODE,
+	"%s(config-net)# ",
+	1,
+};
+
+#define NETWORK_STR "Configure the GSM network\n"
+#define CODE_CMD_STR "Code commands\n"
+#define NAME_CMD_STR "Name Commands\n"
+#define NAME_STR "Name to use\n"
+
+DEFUN(cfg_net,
+      cfg_net_cmd,
+      "network", NETWORK_STR)
+{
+	vty->index = gsmnet;
+	vty->node = GSMNET_NODE;
+
+	return CMD_SUCCESS;
+}
+
+DEFUN(cfg_net_ncc,
+      cfg_net_ncc_cmd,
+      "network country code <1-999>",
+      "Set the GSM network country code\n"
+      "Country commands\n"
+      CODE_CMD_STR
+      "Network Country Code to use\n")
+{
+	gsmnet->plmn.mcc = atoi(argv[0]);
+
+	return CMD_SUCCESS;
+}
+
+DEFUN(cfg_net_mnc,
+      cfg_net_mnc_cmd,
+      "mobile network code <0-999>",
+      "Set the GSM mobile network code\n"
+      "Network Commands\n"
+      CODE_CMD_STR
+      "Mobile Network Code to use\n")
+{
+	uint16_t mnc;
+	bool mnc_3_digits;
+
+	if (osmo_mnc_from_str(argv[0], &mnc, &mnc_3_digits)) {
+		vty_out(vty, "%% Error decoding MNC: %s%s", argv[0], VTY_NEWLINE);
+		return CMD_WARNING;
+	}
+
+	gsmnet->plmn.mnc = mnc;
+	gsmnet->plmn.mnc_3_digits = mnc_3_digits;
+
+	return CMD_SUCCESS;
+}
+
+DEFUN(cfg_net_name_short,
+      cfg_net_name_short_cmd,
+      "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]);
+	return CMD_SUCCESS;
+}
+
+DEFUN(cfg_net_name_long,
+      cfg_net_name_long_cmd,
+      "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]);
+	return CMD_SUCCESS;
+}
+
+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"
+	"A5/n Algorithm Number\n"
+	"A5/n Algorithm Number\n"
+	"A5/n Algorithm Number\n"
+	"A5/n Algorithm Number\n")
+{
+	unsigned int i;
+
+	gsmnet->a5_encryption_mask = 0;
+	for (i = 0; i < argc; i++)
+		gsmnet->a5_encryption_mask |= (1 << atoi(argv[i]));
+
+	return CMD_SUCCESS;
+}
+
+DEFUN(cfg_net_authentication,
+      cfg_net_authentication_cmd,
+      "authentication (optional|required)",
+	"Whether to enforce MS authentication in 2G\n"
+	"Allow MS to attach via 2G BSC without authentication\n"
+	"Always do authentication\n")
+{
+	gsmnet->authentication_required = (argv[0][0] == 'r') ? true : false;
+
+	return CMD_SUCCESS;
+}
+
+DEFUN(cfg_net_rrlp_mode, cfg_net_rrlp_mode_cmd,
+      "rrlp mode (none|ms-based|ms-preferred|ass-preferred)",
+	"Radio Resource Location Protocol\n"
+	"Set the Radio Resource Location Protocol Mode\n"
+	"Don't send RRLP request\n"
+	"Request MS-based location\n"
+	"Request any location, prefer MS-based\n"
+	"Request any location, prefer MS-assisted\n")
+{
+	gsmnet->rrlp.mode = msc_rrlp_mode_parse(argv[0]);
+
+	return CMD_SUCCESS;
+}
+
+DEFUN(cfg_net_mm_info, cfg_net_mm_info_cmd,
+      "mm info (0|1)",
+	"Mobility Management\n"
+	"Send MM INFO after LOC UPD ACCEPT\n"
+	"Disable\n" "Enable\n")
+{
+	gsmnet->send_mm_info = atoi(argv[0]);
+
+	return CMD_SUCCESS;
+}
+
+DEFUN(cfg_net_timezone,
+      cfg_net_timezone_cmd,
+      "timezone <-19-19> (0|15|30|45)",
+      "Set the Timezone Offset of the network\n"
+      "Timezone offset (hours)\n"
+      "Timezone offset (00 minutes)\n"
+      "Timezone offset (15 minutes)\n"
+      "Timezone offset (30 minutes)\n"
+      "Timezone offset (45 minutes)\n"
+      )
+{
+	struct gsm_network *net = vty->index;
+	int tzhr = atoi(argv[0]);
+	int tzmn = atoi(argv[1]);
+
+	net->tz.hr = tzhr;
+	net->tz.mn = tzmn;
+	net->tz.dst = 0;
+	net->tz.override = 1;
+
+	return CMD_SUCCESS;
+}
+
+DEFUN(cfg_net_timezone_dst,
+      cfg_net_timezone_dst_cmd,
+      "timezone <-19-19> (0|15|30|45) <0-2>",
+      "Set the Timezone Offset of the network\n"
+      "Timezone offset (hours)\n"
+      "Timezone offset (00 minutes)\n"
+      "Timezone offset (15 minutes)\n"
+      "Timezone offset (30 minutes)\n"
+      "Timezone offset (45 minutes)\n"
+      "DST offset (hours)\n"
+      )
+{
+	struct gsm_network *net = vty->index;
+	int tzhr = atoi(argv[0]);
+	int tzmn = atoi(argv[1]);
+	int tzdst = atoi(argv[2]);
+
+	net->tz.hr = tzhr;
+	net->tz.mn = tzmn;
+	net->tz.dst = tzdst;
+	net->tz.override = 1;
+
+	return CMD_SUCCESS;
+}
+
+DEFUN(cfg_net_no_timezone,
+      cfg_net_no_timezone_cmd,
+      "no timezone",
+      NO_STR
+      "Disable network timezone override, use system tz\n")
+{
+	struct gsm_network *net = vty->index;
+
+	net->tz.override = 0;
+
+	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")
+{
+	struct gsm_network *net = vty->index;
+
+	net->t3212 = atoi(argv[0]) / 6;
+
+	return CMD_SUCCESS;
+}
+
+DEFUN(cfg_net_no_per_loc_upd, cfg_net_no_per_loc_upd_cmd,
+      "no periodic location update",
+      NO_STR
+      "Periodic Location Updating Interval\n"
+      "Periodic Location Updating Interval\n"
+      "Periodic Location Updating Interval\n")
+{
+	struct gsm_network *net = vty->index;
+
+	net->t3212 = 0;
+
+	return CMD_SUCCESS;
+}
+
+static int config_write_net(struct vty *vty)
+{
+	int i;
+
+	vty_out(vty, "network%s", VTY_NEWLINE);
+	vty_out(vty, " network country code %s%s", osmo_mcc_name(gsmnet->plmn.mcc), VTY_NEWLINE);
+	vty_out(vty, " mobile network code %s%s",
+		osmo_mnc_name(gsmnet->plmn.mnc, gsmnet->plmn.mnc_3_digits), VTY_NEWLINE);
+	vty_out(vty, " short name %s%s", gsmnet->name_short, VTY_NEWLINE);
+	vty_out(vty, " long name %s%s", gsmnet->name_long, VTY_NEWLINE);
+	vty_out(vty, " encryption a5");
+	for (i = 0; i < 8; i++) {
+		if (gsmnet->a5_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),
+		VTY_NEWLINE);
+	vty_out(vty, " mm info %u%s", gsmnet->send_mm_info, VTY_NEWLINE);
+	if (gsmnet->tz.override != 0) {
+		if (gsmnet->tz.dst)
+			vty_out(vty, " timezone %d %d %d%s",
+				gsmnet->tz.hr, gsmnet->tz.mn, gsmnet->tz.dst,
+				VTY_NEWLINE);
+		else
+			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);
+	}
+
+	return CMD_SUCCESS;
+}
+
+static struct cmd_node msc_node = {
+	MSC_NODE,
+	"%s(config-msc)# ",
+	1,
+};
+
+DEFUN(cfg_msc, cfg_msc_cmd,
+      "msc", "Configure MSC options")
+{
+	vty->node = MSC_NODE;
+	return CMD_SUCCESS;
+}
+
+DEFUN(cfg_msc_mncc_guard_timeout,
+      cfg_msc_mncc_guard_timeout_cmd,
+      "mncc-guard-timeout <0-255>",
+      "Set global guard timer for mncc interface activity\n"
+      "guard timer value (sec.)")
+{
+	gsmnet->mncc_guard_timeout = atoi(argv[0]);
+	return CMD_SUCCESS;
+}
+
+DEFUN(cfg_msc_assign_tmsi, cfg_msc_assign_tmsi_cmd,
+      "assign-tmsi",
+      "Assign TMSI during Location Updating.\n")
+{
+	gsmnet->vlr->cfg.assign_tmsi = true;
+	return CMD_SUCCESS;
+}
+
+DEFUN(cfg_msc_no_assign_tmsi, cfg_msc_no_assign_tmsi_cmd,
+      "no assign-tmsi",
+      NO_STR "Assign TMSI during Location Updating.\n")
+{
+	gsmnet->vlr->cfg.assign_tmsi = false;
+	return CMD_SUCCESS;
+}
+
+DEFUN(cfg_msc_cs7_instance_a,
+      cfg_msc_cs7_instance_a_cmd,
+      "cs7-instance-a <0-15>",
+      "Set SS7 to be used by the A-Interface.\n" "SS7 instance reference number\n")
+{
+	gsmnet->a.cs7_instance = atoi(argv[0]);
+	return CMD_SUCCESS;
+}
+
+DEFUN(cfg_msc_cs7_instance_iu,
+      cfg_msc_cs7_instance_iu_cmd,
+      "cs7-instance-iu <0-15>",
+      "Set SS7 to be used by the Iu-Interface.\n" "SS7 instance reference number\n")
+{
+#if BUILD_IU
+	gsmnet->iu.cs7_instance = atoi(argv[0]);
+	return CMD_SUCCESS;
+#else
+	vty_out(vty, "WARNING: 'cs7-instance-iu' without effect: built without Iu support%s",
+		VTY_NEWLINE);
+	return CMD_WARNING;
+#endif
+}
+
+DEFUN(cfg_msc_auth_tuple_max_reuse_count, cfg_msc_auth_tuple_max_reuse_count_cmd,
+      "auth-tuple-max-reuse-count <-1-2147483647>",
+      "Configure authentication tuple re-use\n"
+      "0 to use each auth tuple at most once (default), >0 to limit re-use, -1 to re-use infinitely (vulnerable!).\n")
+{
+	gsmnet->vlr->cfg.auth_tuple_max_reuse_count = atoi(argv[0]);
+	return CMD_SUCCESS;
+}
+
+DEFUN(cfg_msc_auth_tuple_reuse_on_error, cfg_msc_auth_tuple_reuse_on_error_cmd,
+      "auth-tuple-reuse-on-error (0|1)",
+      "Configure authentication tuple re-use when HLR is not responsive\n"
+      "0 = never re-use auth tuples beyond auth-tuple-max-reuse-count (default)\n"
+      "1 = if the HLR does not deliver new tuples, do re-use already available old ones.\n")
+{
+	gsmnet->vlr->cfg.auth_reuse_old_sets_on_error = atoi(argv[0]) ? true : false;
+	return CMD_SUCCESS;
+}
+
+DEFUN(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"
+      " BSS or RNC\n"
+      "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;
+	else
+		gsmnet->paging_response_timer = atoi(argv[0]);
+	return CMD_SUCCESS;
+}
+
+DEFUN(cfg_msc_emergency_msisdn, cfg_msc_emergency_msisdn_cmd,
+      "emergency-call route-to-msisdn MSISDN",
+      "Configure Emergency Call Behaviour\n"
+      "MSISDN to which Emergency Calls are Dispatched\n"
+      "MSISDN (E.164 Phone Number)\n")
+{
+	osmo_talloc_replace_string(gsmnet, &gsmnet->emergency.route_to_msisdn, argv[0]);
+
+	return CMD_SUCCESS;
+}
+
+static int config_write_msc(struct vty *vty)
+{
+	vty_out(vty, "msc%s", VTY_NEWLINE);
+	vty_out(vty, " mncc-guard-timeout %i%s",
+		gsmnet->mncc_guard_timeout, VTY_NEWLINE);
+	vty_out(vty, " %sassign-tmsi%s",
+		gsmnet->vlr->cfg.assign_tmsi? "" : "no ", VTY_NEWLINE);
+
+	vty_out(vty, " cs7-instance-a %u%s", gsmnet->a.cs7_instance,
+		VTY_NEWLINE);
+#if BUILD_IU
+	vty_out(vty, " cs7-instance-iu %u%s", gsmnet->iu.cs7_instance,
+		VTY_NEWLINE);
+#endif
+
+	if (gsmnet->vlr->cfg.auth_tuple_max_reuse_count)
+		vty_out(vty, " auth-tuple-max-reuse-count %d%s",
+			OSMO_MAX(-1, gsmnet->vlr->cfg.auth_tuple_max_reuse_count),
+			VTY_NEWLINE);
+	if (gsmnet->vlr->cfg.auth_reuse_old_sets_on_error)
+		vty_out(vty, " auth-tuple-reuse-on-error 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);
+	}
+
+	mgcp_client_config_write(vty, " ");
+#ifdef BUILD_IU
+	ranap_iu_vty_config_write(vty, " ");
+#endif
+
+	return CMD_SUCCESS;
+}
+
+DEFUN(show_bsc, show_bsc_cmd,
+	"show bsc", SHOW_STR "BSC\n")
+{
+	struct bsc_context *bsc_ctx;
+	struct osmo_ss7_instance *ss7 = osmo_ss7_instance_find(gsmnet->a.cs7_instance);
+
+	llist_for_each_entry(bsc_ctx, &gsmnet->a.bscs, list) {
+		vty_out(vty, "BSC %s%s", osmo_sccp_addr_name(ss7, &bsc_ctx->bsc_addr), VTY_NEWLINE);
+	}
+
+	return CMD_SUCCESS;
+}
+
+static void vty_conn_hdr(struct vty *vty)
+{
+	vty_out(vty, "--ConnId ------------Subscriber RAN --LAC Use --Tokens C A5 State%s",
+		VTY_NEWLINE);
+}
+
+static void vty_dump_one_conn(struct vty *vty, const struct gsm_subscriber_connection *conn)
+{
+	vty_out(vty, "%08x %22s %3s %5u %3u %08x %c /%1u %27s %s",
+		conn->a.conn_id,
+		conn->vsub ? vlr_subscr_name(conn->vsub) : "-",
+		conn->via_ran == RAN_UTRAN_IU ? "Iu" : "A",
+		conn->lac,
+		conn->use_count,
+		conn->use_tokens,
+		conn->received_cm_service_request ? 'C' : '-',
+		conn->encr.alg_id,
+		conn->fi ? osmo_fsm_inst_state_name(conn->fi) : "-",
+		VTY_NEWLINE);
+}
+
+DEFUN(show_msc_conn, show_msc_conn_cmd,
+	"show connection", SHOW_STR "Subscriber Connections\n")
+{
+	struct gsm_subscriber_connection *conn;
+
+	vty_conn_hdr(vty);
+	llist_for_each_entry(conn, &gsmnet->subscr_conns, entry)
+		vty_dump_one_conn(vty, conn);
+
+	return CMD_SUCCESS;
+}
+
+static void vty_trans_hdr(struct vty *vty)
+{
+	vty_out(vty, "------------Subscriber --ConnId -P TI -CallRef Proto%s",
+		VTY_NEWLINE);
+}
+
+static const char *get_trans_proto_str(const struct gsm_trans *trans)
+{
+	static char buf[256];
+
+	switch (trans->protocol) {
+	case GSM48_PDISC_CC:
+		snprintf(buf, sizeof(buf), "%s %4u %4u",
+			 gsm48_cc_state_name(trans->cc.state),
+			 trans->cc.Tcurrent,
+			 trans->cc.T308_second);
+		break;
+	case GSM48_PDISC_SMS:
+		snprintf(buf, sizeof(buf), "%s %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 buf;
+}
+
+static void vty_dump_one_trans(struct vty *vty, const struct gsm_trans *trans)
+{
+	vty_out(vty, "%22s %08x %s %02u %08x %s%s",
+		trans->vsub ? vlr_subscr_name(trans->vsub) : "-",
+		trans->conn ? trans->conn->a.conn_id : 0,
+		gsm48_pdisc_name(trans->protocol),
+		trans->transaction_id,
+		trans->callref,
+		get_trans_proto_str(trans), VTY_NEWLINE);
+}
+
+DEFUN(show_msc_transaction, show_msc_transaction_cmd,
+	"show transaction", SHOW_STR "Transactions\n")
+{
+	struct gsm_trans *trans;
+
+	vty_trans_hdr(vty);
+	llist_for_each_entry(trans, &gsmnet->trans_list, entry)
+		vty_dump_one_trans(vty, trans);
+
+	return CMD_SUCCESS;
+}
+
+static void subscr_dump_full_vty(struct vty *vty, struct vlr_subscr *vsub)
+{
+	struct gsm_trans *trans;
+	int reqs;
+	struct llist_head *entry;
+
+	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->lac, vsub->lac, 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 0
+	/* TODO: add this to vlr_subscr? */
+	if (vsub->auth_info.auth_algo != AUTH_ALGO_NONE) {
+		struct gsm_auth_info *i = &vsub->auth_info;
+		vty_out(vty, "    A3A8 algorithm id: %d%s",
+			i->auth_algo, VTY_NEWLINE);
+		vty_out(vty, "    A3A8 Ki: %s%s",
+			osmo_hexdump(i->a3a8_ki, i->a3a8_ki_len),
+			VTY_NEWLINE);
+	}
+#endif
+
+	if (vsub->last_tuple) {
+		struct gsm_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);
+	}
+
+	reqs = 0;
+	llist_for_each(entry, &vsub->cs.requests)
+		reqs += 1;
+	vty_out(vty, "    Paging: %s paging for %d requests%s",
+		vsub->cs.is_paging ? "is" : "not", reqs, VTY_NEWLINE);
+	vty_out(vty, "    Use count: %u%s", vsub->use_count, VTY_NEWLINE);
+
+	/* Connection */
+	if (vsub->msc_conn_ref) {
+		struct gsm_subscriber_connection *conn = vsub->msc_conn_ref;
+		vty_conn_hdr(vty);
+		vty_dump_one_conn(vty, conn);
+	}
+
+	/* 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);
+	}
+}
+
+/* Subscriber */
+DEFUN(show_subscr_cache,
+      show_subscr_cache_cmd,
+      "show subscriber cache",
+	SHOW_STR "Show information about subscribers\n"
+	"Display contents of subscriber cache\n")
+{
+	struct vlr_subscr *vsub;
+	int count = 0;
+
+	llist_for_each_entry(vsub, &gsmnet->vlr->subscribers, list) {
+		if (++count > 100) {
+			vty_out(vty, "%% More than %d subscribers in cache,"
+				" stopping here.%s", count-1, VTY_NEWLINE);
+			break;
+		}
+		vty_out(vty, "  Subscriber:%s", VTY_NEWLINE);
+		subscr_dump_full_vty(vty, vsub);
+	}
+
+	return CMD_SUCCESS;
+}
+
+DEFUN(sms_send_pend,
+      sms_send_pend_cmd,
+      "sms send pending",
+      "SMS related commands\n" "SMS Sending related commands\n"
+      "Send all pending SMS")
+{
+	struct gsm_sms *sms;
+	unsigned long long sms_id = 0;
+
+	while (1) {
+		sms = db_sms_get_next_unsent(gsmnet, sms_id, UINT_MAX);
+		if (!sms)
+			break;
+
+		if (sms->receiver)
+			gsm411_send_sms_subscr(sms->receiver, sms);
+
+		sms_id = sms->id + 1;
+	}
+
+	return CMD_SUCCESS;
+}
+
+DEFUN(sms_delete_expired,
+      sms_delete_expired_cmd,
+      "sms delete expired",
+      "SMS related commands\n" "SMS Database related commands\n"
+      "Delete all expired SMS")
+{
+	struct gsm_sms *sms;
+	unsigned long long sms_id = 0;
+	long long num_deleted = 0;
+
+	while (1) {
+		sms = db_sms_get_next_unsent(gsmnet, sms_id, UINT_MAX);
+		if (!sms)
+			break;
+
+		/* Skip SMS which are currently queued for sending. */
+		if (sms_queue_sms_is_pending(gsmnet->sms_queue, sms->id))
+			continue;
+
+		/* Expiration check is performed by the DB layer. */
+		if (db_sms_delete_expired_message_by_id(sms->id) == 0)
+			num_deleted++;
+
+		sms_id = sms->id + 1;
+	}
+
+	if (num_deleted == 0) {
+		vty_out(vty, "No expired SMS in database%s", VTY_NEWLINE);
+		return CMD_WARNING;
+	}
+
+	vty_out(vty, "Deleted %llu expired SMS from database%s", num_deleted, VTY_NEWLINE);
+	return CMD_SUCCESS;
+}
+
+static int _send_sms_str(struct vlr_subscr *receiver,
+			 const char *sender_msisdn,
+			 char *str, uint8_t tp_pid)
+{
+	struct gsm_network *net = receiver->vlr->user_ctx;
+	struct gsm_sms *sms;
+
+	sms = sms_from_text(receiver, sender_msisdn, 0, str);
+	sms->protocol_id = tp_pid;
+
+	/* store in database for the queue */
+	if (db_sms_store(sms) != 0) {
+		LOGP(DLSMS, LOGL_ERROR, "Failed to store SMS in Database\n");
+		sms_free(sms);
+		return CMD_WARNING;
+	}
+	LOGP(DLSMS, LOGL_DEBUG, "SMS stored in DB\n");
+
+	sms_free(sms);
+	sms_queue_trigger(net->sms_queue);
+	return CMD_SUCCESS;
+}
+
+static struct vlr_subscr *get_vsub_by_argv(struct gsm_network *gsmnet,
+					       const char *type,
+					       const char *id)
+{
+	if (!strcmp(type, "extension") || !strcmp(type, "msisdn"))
+		return vlr_subscr_find_by_msisdn(gsmnet->vlr, id);
+	else if (!strcmp(type, "imsi") || !strcmp(type, "id"))
+		return vlr_subscr_find_by_imsi(gsmnet->vlr, id);
+	else if (!strcmp(type, "tmsi"))
+		return vlr_subscr_find_by_tmsi(gsmnet->vlr, atoi(id));
+
+	return NULL;
+}
+#define SUBSCR_TYPES "(msisdn|extension|imsi|tmsi|id)"
+#define SUBSCR_HELP "Operations on a Subscriber\n"			\
+	"Identify subscriber by MSISDN (phone number)\n"		\
+	"Legacy alias for 'msisdn'\n"		\
+	"Identify subscriber by IMSI\n"					\
+	"Identify subscriber by TMSI\n"					\
+	"Identify subscriber by database ID\n"				\
+	"Identifier for the subscriber\n"
+
+DEFUN(show_subscr,
+      show_subscr_cmd,
+      "show subscriber " SUBSCR_TYPES " ID",
+	SHOW_STR SUBSCR_HELP)
+{
+	struct vlr_subscr *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);
+		return CMD_WARNING;
+	}
+
+	subscr_dump_full_vty(vty, vsub);
+
+	vlr_subscr_put(vsub);
+
+	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")
+{
+	vty_out(vty, "%% 'subscriber create' now needs to be done at osmo-hlr%s",
+		VTY_NEWLINE);
+	return CMD_WARNING;
+}
+
+DEFUN(subscriber_send_pending_sms,
+      subscriber_send_pending_sms_cmd,
+      "subscriber " SUBSCR_TYPES " ID sms pending-send",
+	SUBSCR_HELP "SMS Operations\n" "Send pending SMS\n")
+{
+	struct vlr_subscr *vsub;
+	struct gsm_sms *sms;
+
+	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);
+		return CMD_WARNING;
+	}
+
+	sms = db_sms_get_unsent_for_subscr(vsub, UINT_MAX);
+	if (sms)
+		gsm411_send_sms_subscr(sms->receiver, sms);
+
+	vlr_subscr_put(vsub);
+
+	return CMD_SUCCESS;
+}
+
+DEFUN(subscriber_send_sms,
+      subscriber_send_sms_cmd,
+      "subscriber " SUBSCR_TYPES " ID sms sender " SUBSCR_TYPES " SENDER_ID send .LINE",
+	SUBSCR_HELP "SMS Operations\n" SUBSCR_HELP "Send SMS\n" "Actual SMS Text\n")
+{
+	struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
+	const char *sender_msisdn;
+	char *str;
+	int rc;
+
+	if (!vsub) {
+		vty_out(vty, "%% No subscriber found for %s %s%s",
+			argv[0], argv[1], VTY_NEWLINE);
+		rc = CMD_WARNING;
+		goto err;
+	}
+
+	if (!strcmp(argv[2], "msisdn"))
+		sender_msisdn = argv[3];
+	else {
+		struct vlr_subscr *sender = get_vsub_by_argv(gsmnet, argv[2], argv[3]);
+		if (!sender) {
+			vty_out(vty, "%% No sender found for %s %s%s", argv[2], argv[3], VTY_NEWLINE);
+			rc = CMD_WARNING;
+			goto err;
+		}
+		sender_msisdn = sender->msisdn;
+		vlr_subscr_put(sender);
+	}
+
+	str = argv_concat(argv, argc, 4);
+	rc = _send_sms_str(vsub, sender_msisdn, str, 0);
+	talloc_free(str);
+
+err:
+	if (vsub)
+		vlr_subscr_put(vsub);
+
+	return rc;
+}
+
+DEFUN(subscriber_silent_sms,
+      subscriber_silent_sms_cmd,
+
+      "subscriber " SUBSCR_TYPES " ID silent-sms sender " SUBSCR_TYPES " SENDER_ID send .LINE",
+	SUBSCR_HELP "Silent SMS Operations\n" SUBSCR_HELP "Send SMS\n" "Actual SMS Text\n")
+{
+	struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
+	const char *sender_msisdn;
+	char *str;
+	int rc;
+
+	if (!vsub) {
+		vty_out(vty, "%% No subscriber found for %s %s%s",
+			argv[0], argv[1], VTY_NEWLINE);
+		rc = CMD_WARNING;
+		goto err;
+	}
+
+	if (!strcmp(argv[2], "msisdn")) {
+		sender_msisdn = argv[3];
+	} else {
+		struct vlr_subscr *sender = get_vsub_by_argv(gsmnet, argv[2], argv[3]);
+		if (!sender) {
+			vty_out(vty, "%% No sender found for %s %s%s", argv[2], argv[3], VTY_NEWLINE);
+			rc = CMD_WARNING;
+			goto err;
+		}
+		sender_msisdn = sender->msisdn;
+		vlr_subscr_put(sender);
+	}
+
+	str = argv_concat(argv, argc, 4);
+	rc = _send_sms_str(vsub, sender_msisdn, str, 64);
+	talloc_free(str);
+
+err:
+	if (vsub)
+		vlr_subscr_put(vsub);
+
+	return rc;
+}
+
+#define CHAN_TYPES "(any|tch/f|tch/any|sdcch)"
+#define CHAN_TYPE_HELP 			\
+		"Any channel\n"		\
+		"TCH/F channel\n"	\
+		"Any TCH channel\n"	\
+		"SDCCH channel\n"
+
+DEFUN(subscriber_silent_call_start,
+      subscriber_silent_call_start_cmd,
+      "subscriber " SUBSCR_TYPES " ID silent-call start (any|tch/f|tch/any|sdcch)",
+	SUBSCR_HELP "Silent call operation\n" "Start silent call\n"
+	CHAN_TYPE_HELP)
+{
+	struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
+	int rc, type;
+
+	if (!vsub) {
+		vty_out(vty, "%% No subscriber found for %s %s%s",
+			argv[0], argv[1], VTY_NEWLINE);
+		return CMD_WARNING;
+	}
+
+	if (!strcmp(argv[2], "tch/f"))
+		type = RSL_CHANNEED_TCH_F;
+	else if (!strcmp(argv[2], "tch/any"))
+		type = RSL_CHANNEED_TCH_ForH;
+	else if (!strcmp(argv[2], "sdcch"))
+		type = RSL_CHANNEED_SDCCH;
+	else
+		type = RSL_CHANNEED_ANY;	/* Defaults to ANY */
+
+	rc = gsm_silent_call_start(vsub, vty, type);
+	switch (rc) {
+	case -ENODEV:
+		vty_out(vty, "%% Subscriber not attached%s", VTY_NEWLINE);
+		break;
+	default:
+		if (rc)
+			vty_out(vty, "%% Cannot start silent call (rc=%d)%s", rc, VTY_NEWLINE);
+		else
+			vty_out(vty, "%% Silent call initiated%s", VTY_NEWLINE);
+		break;
+	}
+
+	vlr_subscr_put(vsub);
+	return rc ? CMD_WARNING : CMD_SUCCESS;
+}
+
+DEFUN(subscriber_silent_call_stop,
+      subscriber_silent_call_stop_cmd,
+      "subscriber " SUBSCR_TYPES " ID silent-call stop",
+	SUBSCR_HELP "Silent call operation\n" "Stop silent call\n"
+	CHAN_TYPE_HELP)
+{
+	struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
+	int rc;
+
+	if (!vsub) {
+		vty_out(vty, "%% No subscriber found for %s %s%s",
+			argv[0], argv[1], VTY_NEWLINE);
+		return CMD_WARNING;
+	}
+
+	rc = gsm_silent_call_stop(vsub);
+	switch (rc) {
+	case -ENODEV:
+		vty_out(vty, "%% No active connection for subscriber%s", VTY_NEWLINE);
+		break;
+	case -ENOENT:
+		vty_out(vty, "%% Subscriber has no silent call active%s",
+			VTY_NEWLINE);
+		break;
+	default:
+		if (rc)
+			vty_out(vty, "%% Cannot stop silent call (rc=%d)%s", rc, VTY_NEWLINE);
+		else
+			vty_out(vty, "%% Silent call stopped%s", VTY_NEWLINE);
+		break;
+	}
+
+	vlr_subscr_put(vsub);
+	return rc ? CMD_WARNING : CMD_SUCCESS;
+}
+
+DEFUN(subscriber_ussd_notify,
+      subscriber_ussd_notify_cmd,
+      "subscriber " SUBSCR_TYPES " ID ussd-notify (0|1|2) .TEXT",
+      SUBSCR_HELP "Send a USSD notify to the subscriber\n"
+      "Alerting Level 0\n"
+      "Alerting Level 1\n"
+      "Alerting Level 2\n"
+      "Text of USSD message to send\n")
+{
+	char *text;
+	struct gsm_subscriber_connection *conn;
+	struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
+	int level;
+
+	if (!vsub) {
+		vty_out(vty, "%% No subscriber found for %s %s%s",
+			argv[0], argv[1], VTY_NEWLINE);
+		return CMD_WARNING;
+	}
+
+	level = atoi(argv[2]);
+	text = argv_concat(argv, argc, 3);
+	if (!text) {
+		vlr_subscr_put(vsub);
+		return CMD_WARNING;
+	}
+
+	conn = connection_for_subscr(vsub);
+	if (!conn) {
+		vty_out(vty, "%% An active connection is required for %s %s%s",
+			argv[0], argv[1], VTY_NEWLINE);
+		vlr_subscr_put(vsub);
+		talloc_free(text);
+		return CMD_WARNING;
+	}
+
+	msc_send_ussd_notify(conn, level, text);
+	msc_send_ussd_release_complete(conn);
+
+	vlr_subscr_put(vsub);
+	talloc_free(text);
+	return CMD_SUCCESS;
+}
+
+DEFUN(subscriber_paging,
+      subscriber_paging_cmd,
+      "subscriber " SUBSCR_TYPES " ID paging",
+      SUBSCR_HELP "Issue an empty Paging for the subscriber (for debugging)\n")
+{
+	struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
+	struct subscr_request *req;
+
+	if (!vsub) {
+		vty_out(vty, "%% No subscriber found for %s %s%s",
+			argv[0], argv[1], VTY_NEWLINE);
+		return CMD_WARNING;
+	}
+
+	req = subscr_request_conn(vsub, NULL, NULL, "manual Paging from VTY");
+	if (req)
+		vty_out(vty, "%% paging subscriber%s", VTY_NEWLINE);
+	else
+		vty_out(vty, "%% paging subscriber failed%s", VTY_NEWLINE);
+
+	vlr_subscr_put(vsub);
+	return req ? CMD_SUCCESS : CMD_WARNING;
+}
+
+static int loop_by_char(uint8_t ch)
+{
+	switch (ch) {
+	case 'a':
+		return GSM414_LOOP_A;
+	case 'b':
+		return GSM414_LOOP_B;
+	case 'c':
+		return GSM414_LOOP_C;
+	case 'd':
+		return GSM414_LOOP_D;
+	case 'e':
+		return GSM414_LOOP_E;
+	case 'f':
+		return GSM414_LOOP_F;
+	case 'i':
+		return GSM414_LOOP_I;
+	}
+	return -1;
+}
+
+DEFUN(subscriber_mstest_close,
+      subscriber_mstest_close_cmd,
+      "subscriber " SUBSCR_TYPES " ID ms-test close-loop (a|b|c|d|e|f|i)",
+      SUBSCR_HELP "Send a TS 04.14 MS Test Command to subscriber\n"
+      "Close a TCH Loop inside the MS\n"
+      "Loop Type A\n"
+      "Loop Type B\n"
+      "Loop Type C\n"
+      "Loop Type D\n"
+      "Loop Type E\n"
+      "Loop Type F\n"
+      "Loop Type I\n")
+{
+	struct gsm_subscriber_connection *conn;
+	struct vlr_subscr *vsub = get_vsub_by_argv(gsmnet, argv[0], argv[1]);
+	const char *loop_str;
+	int loop_mode;
+
+	if (!vsub) {
+		vty_out(vty, "%% No subscriber found for %s %s%s",
+			argv[0], argv[1], VTY_NEWLINE);
+		return CMD_WARNING;
+	}
+
+	loop_str = argv[2];
+	loop_mode = loop_by_char(loop_str[0]);
+
+	conn = connection_for_subscr(vsub);
+	if (!conn) {
+		vty_out(vty, "%% An active connection is required for %s %s%s",
+			argv[0], argv[1], VTY_NEWLINE);
+		vlr_subscr_put(vsub);
+		return CMD_WARNING;
+	}
+
+	gsm0414_tx_close_tch_loop_cmd(conn, loop_mode);
+
+	return CMD_SUCCESS;
+}
+
+DEFUN(subscriber_mstest_open,
+      subscriber_mstest_open_cmd,
+      "subscriber " SUBSCR_TYPES " ID ms-test open-loop",
+      SUBSCR_HELP "Send a TS 04.14 MS Test Command to subscriber\n"
+      "Open a TCH Loop inside the MS\n")
+{
+	struct gsm_subscriber_connection *conn;
+	struct vlr_subscr *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);
+		return CMD_WARNING;
+	}
+
+	conn = connection_for_subscr(vsub);
+	if (!conn) {
+		vty_out(vty, "%% An active connection is required for %s %s%s",
+			argv[0], argv[1], VTY_NEWLINE);
+		vlr_subscr_put(vsub);
+		return CMD_WARNING;
+	}
+
+	gsm0414_tx_open_loop_cmd(conn);
+
+	return CMD_SUCCESS;
+}
+
+DEFUN(ena_subscr_expire,
+      ena_subscr_expire_cmd,
+      "subscriber " SUBSCR_TYPES " ID expire",
+	SUBSCR_HELP "Expire the subscriber Now\n")
+{
+	struct vlr_subscr *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);
+		return CMD_WARNING;
+	}
+
+	if (vlr_subscr_expire(vsub))
+		vty_out(vty, "%% VLR released subscriber %s%s",
+			vlr_subscr_name(vsub), VTY_NEWLINE);
+
+	if (vsub->use_count > 1)
+		vty_out(vty, "%% Subscriber %s is still in use,"
+			" should be released soon%s",
+			vlr_subscr_name(vsub), VTY_NEWLINE);
+
+	vlr_subscr_put(vsub);
+	return CMD_SUCCESS;
+}
+
+static int scall_cbfn(unsigned int subsys, unsigned int signal,
+			void *handler_data, void *signal_data)
+{
+	struct scall_signal_data *sigdata = signal_data;
+	struct vty *vty = sigdata->data;
+
+	switch (signal) {
+	case S_SCALL_SUCCESS:
+		vty_out(vty, "%% silent call success%s", VTY_NEWLINE);
+		break;
+	case S_SCALL_EXPIRED:
+		vty_out(vty, "%% silent call expired paging%s", VTY_NEWLINE);
+		break;
+	}
+	return 0;
+}
+
+DEFUN(show_stats,
+      show_stats_cmd,
+      "show statistics",
+	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,
+		VTY_NEWLINE);
+	vty_out(vty, "IMSI Detach Indications : %" PRIu64 "%s",
+		gsmnet->msc_ctrs->ctr[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,
+		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,
+		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,
+		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,
+		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,
+		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,
+		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,
+		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")
+{
+	vty->node = MNCC_INT_NODE;
+
+	return CMD_SUCCESS;
+}
+
+static struct cmd_node mncc_int_node = {
+	MNCC_INT_NODE,
+	"%s(config-mncc-int)# ",
+	1,
+};
+
+static const struct value_string tchf_codec_names[] = {
+	{ GSM48_CMODE_SPEECH_V1,	"fr" },
+	{ GSM48_CMODE_SPEECH_EFR,	"efr" },
+	{ GSM48_CMODE_SPEECH_AMR,	"amr" },
+	{ 0, NULL }
+};
+
+static const struct value_string tchh_codec_names[] = {
+	{ GSM48_CMODE_SPEECH_V1,	"hr" },
+	{ GSM48_CMODE_SPEECH_AMR,	"amr" },
+	{ 0, NULL }
+};
+
+static int config_write_mncc_int(struct vty *vty)
+{
+	vty_out(vty, "mncc-int%s", VTY_NEWLINE);
+	vty_out(vty, " default-codec tch-f %s%s",
+		get_value_string(tchf_codec_names, mncc_int.def_codec[0]),
+		VTY_NEWLINE);
+	vty_out(vty, " default-codec tch-h %s%s",
+		get_value_string(tchh_codec_names, mncc_int.def_codec[1]),
+		VTY_NEWLINE);
+
+	return CMD_SUCCESS;
+}
+
+DEFUN(mnccint_def_codec_f,
+      mnccint_def_codec_f_cmd,
+      "default-codec tch-f (fr|efr|amr)",
+      "Set default codec\n" "Codec for TCH/F\n"
+      "Full-Rate\n" "Enhanced Full-Rate\n" "Adaptive Multi-Rate\n")
+{
+	mncc_int.def_codec[0] = get_string_value(tchf_codec_names, argv[0]);
+
+	return CMD_SUCCESS;
+}
+
+DEFUN(mnccint_def_codec_h,
+      mnccint_def_codec_h_cmd,
+      "default-codec tch-h (hr|amr)",
+      "Set default codec\n" "Codec for TCH/H\n"
+      "Half-Rate\n" "Adaptive Multi-Rate\n")
+{
+	mncc_int.def_codec[1] = get_string_value(tchh_codec_names, argv[0]);
+
+	return CMD_SUCCESS;
+}
+
+
+DEFUN(logging_fltr_imsi,
+      logging_fltr_imsi_cmd,
+      "logging filter imsi IMSI",
+	LOGGING_STR FILTER_STR
+      "Filter log messages by IMSI\n" "IMSI to be used as filter\n")
+{
+	struct vlr_subscr *vlr_subscr;
+	struct log_target *tgt = osmo_log_vty2tgt(vty);
+	const char *imsi = argv[0];
+
+	if (!tgt)
+		return CMD_WARNING;
+
+	vlr_subscr = vlr_subscr_find_by_imsi(gsmnet->vlr, imsi);
+
+	if (!vlr_subscr) {
+		vty_out(vty, "%%no subscriber with IMSI(%s)%s",
+			argv[0], VTY_NEWLINE);
+		return CMD_WARNING;
+	}
+
+	log_set_filter_vlr_subscr(tgt, vlr_subscr);
+	return CMD_SUCCESS;
+}
+
+static struct cmd_node hlr_node = {
+	HLR_NODE,
+	"%s(config-hlr)# ",
+	1,
+};
+
+DEFUN(cfg_hlr, cfg_hlr_cmd,
+      "hlr", "Configure connection to the HLR")
+{
+	vty->node = HLR_NODE;
+	return CMD_SUCCESS;
+}
+
+DEFUN(cfg_hlr_remote_ip, cfg_hlr_remote_ip_cmd, "remote-ip A.B.C.D",
+      "Remote GSUP address of the HLR\n"
+      "Remote GSUP address (default: " MSC_HLR_REMOTE_IP_DEFAULT ")")
+{
+	talloc_free((void*)gsmnet->gsup_server_addr_str);
+	gsmnet->gsup_server_addr_str = talloc_strdup(gsmnet, argv[0]);
+	return CMD_SUCCESS;
+}
+
+DEFUN(cfg_hlr_remote_port, cfg_hlr_remote_port_cmd, "remote-port <1-65535>",
+      "Remote GSUP port of the HLR\n"
+      "Remote GSUP port (default: " OSMO_STRINGIFY(MSC_HLR_REMOTE_PORT_DEFAULT) ")")
+{
+	gsmnet->gsup_server_port = atoi(argv[0]);
+	return CMD_SUCCESS;
+}
+
+static int config_write_hlr(struct vty *vty)
+{
+	vty_out(vty, "hlr%s", VTY_NEWLINE);
+	vty_out(vty, " remote-ip %s%s",
+		gsmnet->gsup_server_addr_str, VTY_NEWLINE);
+	vty_out(vty, " remote-port %u%s",
+		gsmnet->gsup_server_port, VTY_NEWLINE);
+	return CMD_SUCCESS;
+}
+
+void msc_vty_init(struct gsm_network *msc_network)
+{
+	OSMO_ASSERT(gsmnet == NULL);
+	gsmnet = msc_network;
+
+	osmo_stats_vty_add_cmds();
+
+	install_element(CONFIG_NODE, &cfg_net_cmd);
+	install_node(&net_node, config_write_net);
+	install_element(GSMNET_NODE, &cfg_net_ncc_cmd);
+	install_element(GSMNET_NODE, &cfg_net_mnc_cmd);
+	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_authentication_cmd);
+	install_element(GSMNET_NODE, &cfg_net_rrlp_mode_cmd);
+	install_element(GSMNET_NODE, &cfg_net_mm_info_cmd);
+	install_element(GSMNET_NODE, &cfg_net_timezone_cmd);
+	install_element(GSMNET_NODE, &cfg_net_timezone_dst_cmd);
+	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(CONFIG_NODE, &cfg_msc_cmd);
+	install_node(&msc_node, config_write_msc);
+	install_element(MSC_NODE, &cfg_msc_assign_tmsi_cmd);
+	install_element(MSC_NODE, &cfg_msc_mncc_guard_timeout_cmd);
+	install_element(MSC_NODE, &cfg_msc_no_assign_tmsi_cmd);
+	install_element(MSC_NODE, &cfg_msc_auth_tuple_max_reuse_count_cmd);
+	install_element(MSC_NODE, &cfg_msc_auth_tuple_reuse_on_error_cmd);
+	install_element(MSC_NODE, &cfg_msc_cs7_instance_a_cmd);
+	install_element(MSC_NODE, &cfg_msc_cs7_instance_iu_cmd);
+	install_element(MSC_NODE, &cfg_msc_paging_response_timer_cmd);
+	install_element(MSC_NODE, &cfg_msc_emergency_msisdn_cmd);
+
+	mgcp_client_vty_init(msc_network, MSC_NODE, &msc_network->mgw.conf);
+#ifdef BUILD_IU
+	ranap_iu_vty_init(MSC_NODE, &msc_network->iu.rab_assign_addr_enc);
+#endif
+	osmo_fsm_vty_add_cmds();
+
+	osmo_signal_register_handler(SS_SCALL, scall_cbfn, NULL);
+
+	install_element_ve(&show_subscr_cmd);
+	install_element_ve(&show_subscr_cache_cmd);
+	install_element_ve(&show_bsc_cmd);
+	install_element_ve(&show_msc_conn_cmd);
+	install_element_ve(&show_msc_transaction_cmd);
+
+	install_element_ve(&sms_send_pend_cmd);
+	install_element_ve(&sms_delete_expired_cmd);
+
+	install_element_ve(&subscriber_create_cmd);
+	install_element_ve(&subscriber_send_sms_cmd);
+	install_element_ve(&subscriber_silent_sms_cmd);
+	install_element_ve(&subscriber_silent_call_start_cmd);
+	install_element_ve(&subscriber_silent_call_stop_cmd);
+	install_element_ve(&subscriber_ussd_notify_cmd);
+	install_element_ve(&subscriber_mstest_close_cmd);
+	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(CONFIG_NODE, &cfg_mncc_int_cmd);
+	install_node(&mncc_int_node, config_write_mncc_int);
+	install_element(MNCC_INT_NODE, &mnccint_def_codec_f_cmd);
+	install_element(MNCC_INT_NODE, &mnccint_def_codec_h_cmd);
+
+	install_element(CFG_LOG_NODE, &logging_fltr_imsi_cmd);
+
+	install_element(CONFIG_NODE, &cfg_hlr_cmd);
+	install_node(&hlr_node, config_write_hlr);
+	install_element(HLR_NODE, &cfg_hlr_remote_ip_cmd);
+	install_element(HLR_NODE, &cfg_hlr_remote_port_cmd);
+}
diff --git a/src/libmsc/osmo_msc.c b/src/libmsc/osmo_msc.c
new file mode 100644
index 0000000..f2c84e6
--- /dev/null
+++ b/src/libmsc/osmo_msc.c
@@ -0,0 +1,354 @@
+/* main MSC management code... */
+
+/*
+ * (C) 2010,2013 by Holger Hans Peter Freyther <zecke@selfish.org>
+ * (C) 2010 by On-Waves
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <osmocom/msc/osmo_msc.h>
+#include <osmocom/msc/debug.h>
+#include <osmocom/msc/transaction.h>
+#include <osmocom/msc/db.h>
+#include <osmocom/msc/vlr.h>
+#include <osmocom/msc/osmo_msc.h>
+#include <osmocom/msc/a_iface.h>
+#include <osmocom/msc/gsm_04_08.h>
+#include <osmocom/msc/gsm_04_11.h>
+
+#include "../../bscconfig.h"
+#ifdef BUILD_IU
+#include <osmocom/ranap/iu_client.h>
+#else
+#include <osmocom/msc/iu_dummy.h>
+#endif
+
+struct gsm_network *gsm_network_init(void *ctx, mncc_recv_cb_t mncc_recv)
+{
+	struct gsm_network *net;
+
+	net = talloc_zero(ctx, struct gsm_network);
+	if (!net)
+		return NULL;
+
+	net->plmn = (struct osmo_plmn_id){ .mcc=1, .mnc=1 };
+
+	/* 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;
+
+	net->mncc_guard_timeout = 180;
+
+	net->paging_response_timer = MSC_PAGING_RESPONSE_TIMER_DEFAULT;
+
+	INIT_LLIST_HEAD(&net->trans_list);
+	INIT_LLIST_HEAD(&net->upqueue);
+	INIT_LLIST_HEAD(&net->subscr_conns);
+
+	/* init statistics */
+	net->msc_ctrs = rate_ctr_group_alloc(net, &msc_ctrg_desc, 0);
+	if (!net->msc_ctrs) {
+		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->mncc_recv = mncc_recv;
+
+	INIT_LLIST_HEAD(&net->a.bscs);
+
+	return net;
+}
+
+/* Receive a SAPI-N-REJECT from BSC */
+void msc_sapi_n_reject(struct gsm_subscriber_connection *conn, int dlci)
+{
+	int sapi = dlci & 0x7;
+
+	if (sapi == UM_SAPI_SMS)
+		gsm411_sapi_n_reject(conn);
+}
+
+/* receive a Level 3 Complete message and return MSC_CONN_ACCEPT or
+ * MSC_CONN_REJECT */
+int msc_compl_l3(struct gsm_subscriber_connection *conn,
+		 struct msgb *msg, uint16_t chosen_channel)
+{
+	msc_subscr_conn_get(conn, MSC_CONN_USE_COMPL_L3);
+	gsm0408_dispatch(conn, msg);
+
+	msc_subscr_conn_put(conn, MSC_CONN_USE_COMPL_L3);
+
+	/* Always return acceptance, because even if the conn was not accepted,
+	 * we assumed ownership of it and the caller shall not interfere with
+	 * that. We may even already have discarded the conn. */
+	return MSC_CONN_ACCEPT;
+
+#if 0
+	/*
+	 * If this is a silent call we want the channel to remain open as long as
+	 * possible and this is why we accept this connection regardless of any
+	 * pending transaction or ongoing operation.
+	 */
+	if (conn->silent_call)
+		return MSC_CONN_ACCEPT;
+	if (conn->loc_operation || conn->sec_operation || conn->anch_operation)
+		return MSC_CONN_ACCEPT;
+	if (trans_has_conn(conn))
+		return MSC_CONN_ACCEPT;
+
+	LOGP(DRR, LOGL_INFO, "MSC Complete L3: Rejecting connection.\n");
+	return MSC_CONN_REJECT;
+#endif
+}
+
+/* Receive a DTAP message from BSC */
+void msc_dtap(struct gsm_subscriber_connection *conn, struct msgb *msg)
+{
+	msc_subscr_conn_get(conn, MSC_CONN_USE_DTAP);
+	gsm0408_dispatch(conn, msg);
+
+	msc_subscr_conn_put(conn, MSC_CONN_USE_DTAP);
+}
+
+/* Receive an ASSIGNMENT COMPLETE from BSC */
+void msc_assign_compl(struct gsm_subscriber_connection *conn,
+		      uint8_t rr_cause, uint8_t chosen_channel,
+		      uint8_t encr_alg_id, uint8_t speec)
+{
+	LOGP(DRR, LOGL_DEBUG, "MSC assign complete (do nothing).\n");
+}
+
+/* Receive an ASSIGNMENT FAILURE from BSC */
+void msc_assign_fail(struct gsm_subscriber_connection *conn,
+		     uint8_t cause, uint8_t *rr_cause)
+{
+	LOGP(DRR, LOGL_DEBUG, "MSC assign failure (do nothing).\n");
+}
+
+/* Receive a CLASSMARK CHANGE from BSC */
+void msc_classmark_chg(struct gsm_subscriber_connection *conn,
+		       const uint8_t *cm2, uint8_t cm2_len,
+		       const uint8_t *cm3, uint8_t cm3_len)
+{
+	struct gsm_classmark *cm;
+
+	if (!conn->vsub)
+		cm = &conn->temporary_classmark;
+	else
+		cm = &conn->vsub->classmark;
+
+	if (cm2 && cm2_len) {
+		if (cm2_len > sizeof(cm->classmark2)) {
+			LOGP(DRR, LOGL_NOTICE, "%s: classmark2 is %u bytes, truncating at %zu bytes\n",
+			     vlr_subscr_name(conn->vsub), cm2_len, sizeof(cm->classmark2));
+			cm2_len = sizeof(cm->classmark2);
+		}
+		cm->classmark2_len = cm2_len;
+		memcpy(cm->classmark2, cm2, cm2_len);
+	}
+	if (cm3 && cm3_len) {
+		if (cm3_len > sizeof(cm->classmark3)) {
+			LOGP(DRR, LOGL_NOTICE, "%s: classmark3 is %u bytes, truncating at %zu bytes\n",
+			     vlr_subscr_name(conn->vsub), cm3_len, sizeof(cm->classmark3));
+			cm3_len = sizeof(cm->classmark3);
+		}
+		cm->classmark3_len = cm3_len;
+		memcpy(cm->classmark3, cm3, cm3_len);
+	}
+
+	/* bump subscr conn FSM in case it is waiting for a Classmark Update */
+	if (conn->fi->state == SUBSCR_CONN_S_WAIT_CLASSMARK_UPDATE)
+		osmo_fsm_inst_dispatch(conn->fi, SUBSCR_CONN_E_CLASSMARK_UPDATE, NULL);
+}
+
+/* Receive a CIPHERING MODE COMPLETE from BSC */
+void msc_cipher_mode_compl(struct gsm_subscriber_connection *conn,
+			   struct msgb *msg, uint8_t alg_id)
+{
+	struct vlr_ciph_result ciph_res = { .cause = VLR_CIPH_REJECT };
+
+	if (!conn) {
+		LOGP(DRR, LOGL_ERROR, "invalid: rx Ciphering Mode Complete on NULL conn\n");
+		return;
+	}
+	if (!conn->vsub) {
+		LOGP(DRR, LOGL_ERROR, "invalid: rx Ciphering Mode Complete for NULL subscr\n");
+		return;
+	}
+
+	DEBUGP(DRR, "%s: CIPHERING MODE COMPLETE\n", vlr_subscr_name(conn->vsub));
+
+	if (msg) {
+		struct gsm48_hdr *gh = msgb_l3(msg);
+		unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
+		struct tlv_parsed tp;
+		uint8_t mi_type;
+
+		if (!gh) {
+			LOGP(DRR, LOGL_ERROR, "invalid: msgb without l3 header\n");
+			return;
+		}
+
+		tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len, 0, 0);
+
+		/* bearer capability */
+		if (TLVP_PRESENT(&tp, GSM48_IE_MOBILE_ID)) {
+			mi_type = TLVP_VAL(&tp, GSM48_IE_MOBILE_ID)[0] & GSM_MI_TYPE_MASK;
+			if (mi_type == GSM_MI_TYPE_IMEISV
+			    && TLVP_LEN(&tp, GSM48_IE_MOBILE_ID) > 0) {
+				gsm48_mi_to_string(ciph_res.imeisv, sizeof(ciph_res.imeisv),
+						   TLVP_VAL(&tp, GSM48_IE_MOBILE_ID),
+						   TLVP_LEN(&tp, GSM48_IE_MOBILE_ID));
+			}
+		}
+	}
+
+	ciph_res.cause = VLR_CIPH_COMPL;
+	vlr_subscr_rx_ciph_res(conn->vsub, &ciph_res);
+}
+
+/* Receive a CLEAR REQUEST from BSC */
+int msc_clear_request(struct gsm_subscriber_connection *conn, uint32_t cause)
+{
+	msc_subscr_conn_close(conn, cause);
+	return 1;
+}
+
+static const char *used_ref_counts_str(struct gsm_subscriber_connection *conn)
+{
+	static char buf[256];
+	int bit_nr;
+	char *pos = buf;
+	*pos = '\0';
+
+	if (conn->use_tokens < 0)
+		return "invalid";
+
+#define APPEND_STR(fmt, args...) do { \
+		int remain = sizeof(buf) - (pos - buf) - 1; \
+		int l = -1; \
+		if (remain > 0) \
+		    l = snprintf(pos, remain, "%s" fmt, (pos == buf? "" : ","), ##args); \
+		if (l < 0 || l > remain) { \
+			buf[sizeof(buf) - 1] = '\0'; \
+			return buf; \
+		} \
+		pos += l; \
+	} while(0)
+
+	for (bit_nr = 0; (1 << bit_nr) <= conn->use_tokens; bit_nr++) {
+		if (conn->use_tokens & (1 << bit_nr)) {
+			APPEND_STR("%s", get_value_string(msc_subscr_conn_use_names, bit_nr));
+		}
+	}
+	return buf;
+#undef APPEND_STR
+}
+
+/* increment the ref-count. Needs to be called by every user */
+struct gsm_subscriber_connection *
+_msc_subscr_conn_get(struct gsm_subscriber_connection *conn,
+		     enum msc_subscr_conn_use balance_token,
+		     const char *file, int line)
+{
+	OSMO_ASSERT(conn);
+
+	if (balance_token != MSC_CONN_USE_UNTRACKED) {
+		uint32_t flag = 1 << balance_token;
+		OSMO_ASSERT(balance_token < 32);
+		if (conn->use_tokens & flag)
+			LOGPSRC(DREF, LOGL_ERROR, file, line,
+				"%s: MSC conn use error: using an already used token: %s\n",
+				vlr_subscr_name(conn->vsub),
+				msc_subscr_conn_use_name(balance_token));
+		conn->use_tokens |= flag;
+	}
+
+	conn->use_count++;
+	LOGPSRC(DREF, LOGL_DEBUG, file, line,
+		"%s: MSC conn use + %s == %u (0x%x: %s)\n",
+		vlr_subscr_name(conn->vsub), msc_subscr_conn_use_name(balance_token),
+		conn->use_count, conn->use_tokens, used_ref_counts_str(conn));
+
+	return conn;
+}
+
+/* decrement the ref-count. Once it reaches zero, we release */
+void _msc_subscr_conn_put(struct gsm_subscriber_connection *conn,
+			  enum msc_subscr_conn_use balance_token,
+			  const char *file, int line)
+{
+	OSMO_ASSERT(conn);
+
+	if (balance_token != MSC_CONN_USE_UNTRACKED) {
+		uint32_t flag = 1 << balance_token;
+		OSMO_ASSERT(balance_token < 32);
+		if (!(conn->use_tokens & flag))
+			LOGPSRC(DREF, LOGL_ERROR, file, line,
+				"%s: MSC conn use error: freeing an unused token: %s\n",
+				vlr_subscr_name(conn->vsub),
+				msc_subscr_conn_use_name(balance_token));
+		conn->use_tokens &= ~flag;
+	}
+
+	if (conn->use_count == 0) {
+		LOGPSRC(DREF, LOGL_ERROR, file, line,
+			"%s: MSC conn use - %s failed: is already 0\n",
+			vlr_subscr_name(conn->vsub),
+			msc_subscr_conn_use_name(balance_token));
+		return;
+	}
+
+	conn->use_count--;
+	LOGPSRC(DREF, LOGL_DEBUG, file, line,
+		"%s: MSC conn use - %s == %u (0x%x: %s)\n",
+		vlr_subscr_name(conn->vsub), msc_subscr_conn_use_name(balance_token),
+		conn->use_count, conn->use_tokens, used_ref_counts_str(conn));
+
+	if (conn->use_count == 0)
+		osmo_fsm_inst_dispatch(conn->fi, SUBSCR_CONN_E_UNUSED, NULL);
+}
+
+bool msc_subscr_conn_used_by(struct gsm_subscriber_connection *conn, enum msc_subscr_conn_use token)
+{
+	return conn && (conn->use_tokens & (1 << token));
+}
+
+const struct value_string msc_subscr_conn_use_names[] = {
+	{MSC_CONN_USE_UNTRACKED,	"UNTRACKED"},
+	{MSC_CONN_USE_COMPL_L3,		"compl_l3"},
+	{MSC_CONN_USE_DTAP,		"dtap"},
+	{MSC_CONN_USE_AUTH_CIPH,	"auth+ciph"},
+	{MSC_CONN_USE_CM_SERVICE,	"cm_service"},
+	{MSC_CONN_USE_TRANS_CC,		"trans_cc"},
+	{MSC_CONN_USE_TRANS_SMS,	"trans_sms"},
+	{MSC_CONN_USE_TRANS_NC_SS,	"trans_nc_ss"},
+	{MSC_CONN_USE_SILENT_CALL,	"silent_call"},
+	{MSC_CONN_USE_RELEASE,		"release"},
+	{0, NULL},
+};
+
+void msc_stop_paging(struct vlr_subscr *vsub)
+{
+	DEBUGP(DPAG, "Paging can stop for %s\n", vlr_subscr_name(vsub));
+	/* tell BSCs and RNCs to stop paging? How? */
+}
diff --git a/src/libmsc/rrlp.c b/src/libmsc/rrlp.c
new file mode 100644
index 0000000..2a5c1aa
--- /dev/null
+++ b/src/libmsc/rrlp.c
@@ -0,0 +1,127 @@
+/* Radio Resource LCS (Location) Protocol, GMS TS 04.31 */
+
+/* (C) 2009 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 <stdint.h>
+
+#include <osmocom/core/utils.h>
+
+#include <osmocom/msc/gsm_04_08.h>
+#include <osmocom/msc/signal.h>
+#include <osmocom/msc/debug.h>
+#include <osmocom/msc/gsm_subscriber.h>
+
+/* RRLP msPositionReq, nsBased,
+ *	Accuracy=60, Method=gps, ResponseTime=2, oneSet */
+static const uint8_t ms_based_pos_req[] = { 0x40, 0x01, 0x78, 0xa8 };
+
+/* RRLP msPositionReq, msBasedPref,
+	Accuracy=60, Method=gpsOrEOTD, ResponseTime=5, multipleSets */
+static const uint8_t ms_pref_pos_req[]  = { 0x40, 0x02, 0x79, 0x50 };
+
+/* RRLP msPositionReq, msAssistedPref,
+	Accuracy=60, Method=gpsOrEOTD, ResponseTime=5, multipleSets */
+static const uint8_t ass_pref_pos_req[] = { 0x40, 0x03, 0x79, 0x50 };
+
+static const struct value_string rrlp_mode_names[] = {
+	{ RRLP_MODE_NONE,	"none" },
+	{ RRLP_MODE_MS_BASED,	"ms-based" },
+	{ RRLP_MODE_MS_PREF,	"ms-preferred" },
+	{ RRLP_MODE_ASS_PREF,	"ass-preferred" },
+	{ 0,			NULL }
+};
+
+enum rrlp_mode msc_rrlp_mode_parse(const char *arg)
+{
+	return get_string_value(rrlp_mode_names, arg);
+}
+
+const char *msc_rrlp_mode_name(enum rrlp_mode mode)
+{
+	return get_value_string(rrlp_mode_names, mode);
+}
+
+static int send_rrlp_req(struct gsm_subscriber_connection *conn)
+{
+	struct gsm_network *net = conn->network;
+	const uint8_t *req;
+
+	switch (net->rrlp.mode) {
+	case RRLP_MODE_MS_BASED:
+		req = ms_based_pos_req;
+		break;
+	case RRLP_MODE_MS_PREF:
+		req = ms_pref_pos_req;
+		break;
+	case RRLP_MODE_ASS_PREF:
+		req = ass_pref_pos_req;
+		break;
+	case RRLP_MODE_NONE:
+	default:
+		return 0;
+	}
+
+	LOGP(DRR, LOGL_INFO, "Sending '%s' RRLP position request\n",
+		msc_rrlp_mode_name(net->rrlp.mode));
+
+	return gsm48_send_rr_app_info(conn, 0x00,
+				      sizeof(ms_based_pos_req), req);
+}
+
+static int subscr_sig_cb(unsigned int subsys, unsigned int signal,
+			 void *handler_data, void *signal_data)
+{
+	struct vlr_subscr *vsub;
+	struct gsm_subscriber_connection *conn;
+
+	switch (signal) {
+	case S_SUBSCR_ATTACHED:
+		/* A subscriber has attached. */
+		vsub = signal_data;
+		conn = connection_for_subscr(vsub);
+		if (!conn)
+			break;
+		send_rrlp_req(conn);
+		break;
+	}
+	return 0;
+}
+
+static int paging_sig_cb(unsigned int subsys, unsigned int signal,
+			 void *handler_data, void *signal_data)
+{
+	struct paging_signal_data *psig_data = signal_data;
+
+	switch (signal) {
+	case S_PAGING_SUCCEEDED:
+		/* A subscriber has attached. */
+		send_rrlp_req(psig_data->conn);
+		break;
+	case S_PAGING_EXPIRED:
+		break;
+	}
+	return 0;
+}
+
+void msc_rrlp_init(void)
+{
+	osmo_signal_register_handler(SS_SUBSCR, subscr_sig_cb, NULL);
+	osmo_signal_register_handler(SS_PAGING, paging_sig_cb, NULL);
+}
diff --git a/src/libmsc/silent_call.c b/src/libmsc/silent_call.c
new file mode 100644
index 0000000..9888894
--- /dev/null
+++ b/src/libmsc/silent_call.c
@@ -0,0 +1,168 @@
+/* GSM silent call feature */
+
+/*
+ * (C) 2009 by Harald Welte <laforge@gnumonks.org>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include <osmocom/core/msgb.h>
+#include <osmocom/msc/signal.h>
+#include <osmocom/msc/debug.h>
+#include <osmocom/msc/gsm_data.h>
+#include <osmocom/msc/gsm_subscriber.h>
+#include <osmocom/msc/osmo_msc.h>
+#include <osmocom/msc/vlr.h>
+
+/* paging of the requested subscriber has completed */
+static int paging_cb_silent(unsigned int hooknum, unsigned int event,
+			    struct msgb *msg, void *_conn, void *_data)
+{
+	struct gsm_subscriber_connection *conn = _conn;
+	struct scall_signal_data sigdata;
+	int rc = 0;
+
+	if (hooknum != GSM_HOOK_RR_PAGING)
+		return -EINVAL;
+
+	DEBUGP(DLSMS, "paging_cb_silent: ");
+
+	sigdata.conn = conn;
+	sigdata.data = _data;
+
+	switch (event) {
+	case GSM_PAGING_SUCCEEDED:
+#if BEFORE_MSCSPLIT
+		/* Re-enable this log output once we can obtain this information via
+		 * A-interface, see OS#2391. */
+		DEBUGPC(DLSMS, "success, using Timeslot %u on ARFCN %u\n",
+			conn->lchan->ts->nr, conn->lchan->ts->trx->arfcn);
+#endif
+		conn->silent_call = 1;
+		msc_subscr_conn_get(conn, MSC_CONN_USE_SILENT_CALL);
+		/* increment lchan reference count */
+		osmo_signal_dispatch(SS_SCALL, S_SCALL_SUCCESS, &sigdata);
+		break;
+	case GSM_PAGING_EXPIRED:
+	case GSM_PAGING_BUSY:
+		DEBUGP(DLSMS, "expired\n");
+		osmo_signal_dispatch(SS_SCALL, S_SCALL_EXPIRED, &sigdata);
+		break;
+	default:
+		rc = -EINVAL;
+		break;
+	}
+
+	return rc;
+}
+
+#if 0
+/* receive a layer 3 message from a silent call */
+int silent_call_rx(struct gsm_subscriber_connection *conn, struct msgb *msg)
+{
+	/* FIXME: do something like sending it through a UDP port */
+	LOGP(DLSMS, LOGL_NOTICE, "Discarding L3 message from a silent call.\n");
+	return 0;
+}
+
+struct msg_match {
+	uint8_t pdisc;
+	uint8_t msg_type;
+};
+
+/* list of messages that are handled inside OpenBSC, even in a silent call */
+static const struct msg_match silent_call_accept[] = {
+	{ GSM48_PDISC_MM, GSM48_MT_MM_LOC_UPD_REQUEST },
+	{ GSM48_PDISC_MM, GSM48_MT_MM_CM_SERV_REQ },
+};
+
+/* decide if we need to reroute a message as part of a silent call */
+int silent_call_reroute(struct gsm_subscriber_connection *conn, struct msgb *msg)
+{
+	struct gsm48_hdr *gh = msgb_l3(msg);
+	uint8_t pdisc = gsm48_hdr_pdisc(gh);
+	uint8_t msg_type = gsm48_hdr_msg_type(gh);
+	int i;
+
+	/* if we're not part of a silent call, never reroute */
+	if (!conn->silent_call)
+		return 0;
+
+	/* check if we are a special message that is handled in openbsc */
+	for (i = 0; i < ARRAY_SIZE(silent_call_accept); i++) {
+		if (silent_call_accept[i].pdisc == pdisc &&
+		    silent_call_accept[i].msg_type == msg_type)
+			return 0;
+	}
+
+	/* otherwise, reroute */
+	LOGP(DLSMS, LOGL_INFO, "Rerouting L3 message from a silent call.\n");
+	return 1;
+}
+#endif
+
+
+/* initiate a silent call with a given subscriber */
+int gsm_silent_call_start(struct vlr_subscr *vsub, void *data, int type)
+{
+	struct subscr_request *req;
+
+	/* FIXME the VTY command allows selecting a silent call channel type.
+	 * This doesn't apply to the situation after MSCSPLIT with an
+	 * A-interface. */
+	req = subscr_request_conn(vsub, paging_cb_silent, data,
+				  "establish silent call");
+	if (!req)
+		return -ENODEV;
+	return 0;
+}
+
+/* end a silent call with a given subscriber */
+int gsm_silent_call_stop(struct vlr_subscr *vsub)
+{
+	struct gsm_subscriber_connection *conn;
+
+	conn = connection_for_subscr(vsub);
+	if (!conn) {
+		LOGP(DMM, LOGL_ERROR, "%s: Cannot stop silent call, no connection for subscriber\n",
+		     vlr_subscr_name(vsub));
+		return -ENODEV;
+	}
+
+	/* did we actually establish a silent call for this guy? */
+	if (!conn->silent_call) {
+		LOGP(DMM, LOGL_ERROR, "%s: Cannot stop silent call, subscriber has no active silent call\n",
+		     vlr_subscr_name(vsub));
+		return -ENOENT;
+	}
+
+#if BEFORE_MSCSPLIT
+	/* Re-enable this log output once we can obtain this information via
+	 * A-interface, see OS#2391. */
+	DEBUGPC(DLSMS, "Stopping silent call using Timeslot %u on ARFCN %u\n",
+		conn->lchan->ts->nr, conn->lchan->ts->trx->arfcn);
+#endif
+
+	conn->silent_call = 0;
+	msc_subscr_conn_put(conn, MSC_CONN_USE_SILENT_CALL);
+
+	return 0;
+}
diff --git a/src/libmsc/smpp_openbsc.c b/src/libmsc/smpp_openbsc.c
new file mode 100644
index 0000000..c12db5f
--- /dev/null
+++ b/src/libmsc/smpp_openbsc.c
@@ -0,0 +1,798 @@
+/* OpenBSC SMPP 3.4 interface, SMSC-side implementation */
+
+/* (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 <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdint.h>
+#include <errno.h>
+
+#include <smpp34.h>
+#include <smpp34_structs.h>
+#include <smpp34_params.h>
+
+#include <osmocom/core/utils.h>
+#include <osmocom/core/msgb.h>
+#include <osmocom/core/logging.h>
+#include <osmocom/core/talloc.h>
+#include <osmocom/gsm/protocol/gsm_04_11.h>
+#include <osmocom/gsm/protocol/smpp34_osmocom.h>
+
+#include <osmocom/msc/gsm_subscriber.h>
+#include <osmocom/msc/debug.h>
+#include <osmocom/msc/db.h>
+#include <osmocom/msc/gsm_04_11.h>
+#include <osmocom/msc/gsm_data.h>
+#include <osmocom/msc/signal.h>
+#include <osmocom/msc/transaction.h>
+#include <osmocom/msc/gsm_subscriber.h>
+#include <osmocom/msc/vlr.h>
+
+#include "smpp_smsc.h"
+
+/*! \brief find vlr_subscr for a given SMPP NPI/TON/Address */
+static struct vlr_subscr *subscr_by_dst(struct gsm_network *net,
+					    uint8_t npi, uint8_t ton,
+					    const char *addr)
+{
+	struct vlr_subscr *vsub = NULL;
+
+	switch (npi) {
+	case NPI_Land_Mobile_E212:
+		vsub = vlr_subscr_find_by_imsi(net->vlr, addr);
+		break;
+	case NPI_ISDN_E163_E164:
+	case NPI_Private:
+		vsub = vlr_subscr_find_by_msisdn(net->vlr, addr);
+		break;
+	default:
+		LOGP(DSMPP, LOGL_NOTICE, "Unsupported NPI: %u\n", npi);
+		break;
+	}
+
+	log_set_context(LOG_CTX_VLR_SUBSCR, vsub);
+	return vsub;
+}
+
+static int smpp34_submit_tlv_msg_payload(const struct tlv_t *t,
+					 const struct submit_sm_t *submit,
+					 const uint8_t **sms_msg,
+					 unsigned int *sms_msg_len)
+{
+	if (submit->sm_length) {
+		LOGP(DLSMS, LOGL_ERROR,
+		     "SMPP cannot have payload in TLV _and_ in the header\n");
+		return -1;
+	}
+	*sms_msg = t->value.octet;
+	*sms_msg_len = t->length;
+
+	return 0;
+}
+
+/*! \brief convert from submit_sm_t to gsm_sms */
+static int submit_to_sms(struct gsm_sms **psms, struct gsm_network *net,
+			 const struct submit_sm_t *submit)
+{
+	const uint8_t *sms_msg = NULL;
+	unsigned int sms_msg_len = 0;
+	struct vlr_subscr *dest;
+	uint16_t msg_ref = 0;
+	struct gsm_sms *sms;
+	struct tlv_t *t;
+	int mode;
+	int can_store_sms = ((submit->esm_class & SMPP34_MSG_MODE_MASK) != 2); /* != forward mode */
+
+	dest = subscr_by_dst(net, submit->dest_addr_npi,
+			     submit->dest_addr_ton,
+			     (const char *)submit->destination_addr);
+	if (!dest && !can_store_sms) {
+		LOGP(DLSMS, LOGL_NOTICE, "SMPP SUBMIT-SM for unknown subscriber: "
+		     "%s (NPI=%u)\n", submit->destination_addr,
+		     submit->dest_addr_npi);
+		return ESME_RINVDSTADR;
+	}
+
+	smpp34_tlv_for_each(t, submit->tlv) {
+		switch (t->tag) {
+		case TLVID_message_payload:
+			if (smpp34_submit_tlv_msg_payload(t, submit, &sms_msg,
+							  &sms_msg_len) < 0) {
+				if (dest)
+					vlr_subscr_put(dest);
+				return ESME_ROPTPARNOTALLWD;
+			}
+			break;
+		case TLVID_user_message_reference:
+			msg_ref = t->value.val16;
+			break;
+		default:
+			break;
+		}
+	}
+
+	if (!sms_msg) {
+		if (submit->sm_length > 0 && submit->sm_length < 255) {
+			sms_msg = submit->short_message;
+			sms_msg_len = submit->sm_length;
+		} else {
+			LOGP(DLSMS, LOGL_ERROR,
+			     "SMPP neither message payload nor valid sm_length.\n");
+			vlr_subscr_put(dest);
+			return ESME_RINVPARLEN;
+		}
+	}
+
+	sms = sms_alloc();
+	sms->source = SMS_SOURCE_SMPP;
+	sms->smpp.sequence_nr = submit->sequence_number;
+	sms->status_rep_req = submit->registered_delivery;
+	sms->msg_ref = msg_ref;
+
+	/* fill in the destination address */
+	sms->receiver = dest;
+	sms->dst.ton = submit->dest_addr_ton;
+	sms->dst.npi = submit->dest_addr_npi;
+	if (dest)
+		OSMO_STRLCPY_ARRAY(sms->dst.addr, dest->msisdn);
+	else
+		OSMO_STRLCPY_ARRAY(sms->dst.addr,
+				   (const char *)submit->destination_addr);
+
+	/* fill in the source address */
+	sms->src.ton = submit->source_addr_ton;
+	sms->src.npi = submit->source_addr_npi;
+	OSMO_STRLCPY_ARRAY(sms->src.addr, (char *)submit->source_addr);
+
+	if (submit->esm_class == SMPP34_DELIVERY_ACK)
+		sms->is_report = true;
+
+	if (submit->esm_class & SMPP34_UDHI_IND)
+		sms->ud_hdr_ind = 1;
+
+	if (submit->esm_class & SMPP34_REPLY_PATH) {
+		sms->reply_path_req = 1;
+#warning Implement reply path
+	}
+
+	if (submit->data_coding == 0x00 ||	/* SMSC default */
+	    submit->data_coding == 0x01) {	/* GSM default alphabet */
+		sms->data_coding_scheme = GSM338_DCS_1111_7BIT;
+		mode = MODE_7BIT;
+	} else if ((submit->data_coding & 0xFC) == 0xF0) { /* 03.38 DCS default */
+		/* pass DCS 1:1 through from SMPP to GSM */
+		sms->data_coding_scheme = submit->data_coding;
+		mode = MODE_7BIT;
+	} else if (submit->data_coding == 0x02 ||
+		   submit->data_coding == 0x04) {
+		/* 8-bit binary */
+		sms->data_coding_scheme = GSM338_DCS_1111_8BIT_DATA;
+		mode = MODE_8BIT;
+	} else if ((submit->data_coding & 0xFC) == 0xF4) { /* 03.38 DCS 8bit */
+		/* pass DCS 1:1 through from SMPP to GSM */
+		sms->data_coding_scheme = submit->data_coding;
+		mode = MODE_8BIT;
+	} else if (submit->data_coding == 0x08) {
+		/* UCS-2 */
+		sms->data_coding_scheme = (2 << 2);
+		mode = MODE_8BIT;
+	} else {
+		sms_free(sms);
+		LOGP(DLSMS, LOGL_ERROR, "SMPP Unknown Data Coding 0x%02x\n",
+			submit->data_coding);
+		return ESME_RUNKNOWNERR;
+	}
+
+	if (mode == MODE_7BIT) {
+		uint8_t ud_len = 0, padbits = 0;
+		sms->data_coding_scheme = GSM338_DCS_1111_7BIT;
+		if (sms->ud_hdr_ind) {
+			ud_len = *sms_msg + 1;
+			printf("copying %u bytes user data...\n", ud_len);
+			memcpy(sms->user_data, sms_msg,
+				OSMO_MIN(ud_len, sizeof(sms->user_data)));
+			sms_msg += ud_len;
+			sms_msg_len -= ud_len;
+			padbits = 7 - (ud_len % 7);
+		}
+		gsm_septets2octets(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 {
+		memcpy(sms->user_data, sms_msg, sms_msg_len);
+		sms->user_data_len = sms_msg_len;
+	}
+
+	*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,
+		       struct submit_sm_resp_t *submit_r)
+{
+	struct gsm_sms *sms;
+	struct gsm_network *net = esme->smsc->priv;
+	struct sms_signal_data sig;
+	int rc = -1;
+
+	rc = submit_to_sms(&sms, net, submit);
+	if (rc != ESME_ROK) {
+		submit_r->command_status = rc;
+		return 0;
+	}
+	smpp_esme_get(esme);
+	sms->smpp.esme = esme;
+	sms->protocol_id = submit->protocol_id;
+
+	switch (submit->esm_class & SMPP34_MSG_MODE_MASK) {
+	case 0: /* default */
+	case 1: /* datagram */
+	case 3: /* store-and-forward */
+		rc = db_sms_store(sms);
+		sms_free(sms);
+		sms = NULL;
+		if (rc < 0) {
+			LOGP(DLSMS, LOGL_ERROR, "SMPP SUBMIT-SM: Unable to "
+				"store SMS in database\n");
+			submit_r->command_status = ESME_RSYSERR;
+			return 0;
+		}
+		strcpy((char *)submit_r->message_id, "msg_id_not_implemented");
+		LOGP(DLSMS, LOGL_INFO, "SMPP SUBMIT-SM: Stored in DB\n");
+
+		memset(&sig, 0, sizeof(sig));
+		osmo_signal_dispatch(SS_SMS, S_SMS_SUBMITTED, &sig);
+		rc = 0;
+		break;
+	case 2: /* forward (i.e. transaction) mode */
+		LOGP(DLSMS, LOGL_DEBUG, "SMPP SUBMIT-SM: Forwarding in "
+			"real time (Transaction/Forward mode)\n");
+		sms->smpp.transaction_mode = 1;
+		gsm411_send_sms_subscr(sms->receiver, sms);
+		rc = 1; /* don't send any response yet */
+		break;
+	}
+	return rc;
+}
+
+static void alert_all_esme(struct smsc *smsc, struct vlr_subscr *vsub,
+			   uint8_t smpp_avail_status)
+{
+	struct osmo_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
+		 * pending flag to be set before,  FIXME: make this VTY
+		 * configurable */
+		if (esme->acl && esme->acl->deliver_src_imsi) {
+			smpp_tx_alert(esme, TON_Subscriber_Number,
+				      NPI_Land_Mobile_E212,
+				      vsub->imsi, smpp_avail_status);
+		} else {
+			smpp_tx_alert(esme, TON_Network_Specific,
+				      NPI_ISDN_E163_E164,
+				      vsub->msisdn, smpp_avail_status);
+		}
+	}
+}
+
+
+/*! \brief signal handler for status of attempted SMS deliveries */
+static int smpp_sms_cb(unsigned int subsys, unsigned int signal,
+			void *handler_data, void *signal_data)
+{
+	struct sms_signal_data *sig_sms = signal_data;
+	struct gsm_sms *sms = sig_sms->sms;
+	struct smsc *smsc = handler_data;
+	int rc = 0;
+
+	if (!sms)
+		return 0;
+
+	if (sms->source != SMS_SOURCE_SMPP)
+		return 0;
+
+	switch (signal) {
+	case S_SMS_MEM_EXCEEDED:
+		/* fall-through: There is no ESME_Rxxx result code to
+		 * indicate a MEMORY EXCEEDED in transaction mode back
+		 * to the ESME */
+	case S_SMS_UNKNOWN_ERROR:
+		if (sms->smpp.transaction_mode) {
+			/* Send back the SUBMIT-SM response with apropriate error */
+			LOGP(DLSMS, LOGL_INFO, "SMPP SUBMIT-SM: Error\n");
+			rc = smpp_tx_submit_r(sms->smpp.esme,
+					      sms->smpp.sequence_nr,
+					      ESME_RDELIVERYFAILURE,
+					      sms->smpp.msg_id);
+		}
+		break;
+	case S_SMS_DELIVERED:
+		/* SMS layer tells us the delivery has been completed */
+		if (sms->smpp.transaction_mode) {
+			/* Send back the SUBMIT-SM response */
+			LOGP(DLSMS, LOGL_INFO, "SMPP SUBMIT-SM: Success\n");
+			rc = smpp_tx_submit_r(sms->smpp.esme,
+					      sms->smpp.sequence_nr,
+					      ESME_ROK, sms->smpp.msg_id);
+		}
+		break;
+	case S_SMS_SMMA:
+		if (!sig_sms->trans || !sig_sms->trans->vsub) {
+			/* SMMA without a subscriber? strange... */
+			LOGP(DLSMS, LOGL_NOTICE, "SMMA without subscriber?\n");
+			break;
+		}
+
+		/* There's no real 1:1 match for SMMA in SMPP.  However,
+		 * an ALERT NOTIFICATION seems to be the most logical
+		 * choice */
+		alert_all_esme(smsc, sig_sms->trans->vsub, 0);
+		break;
+	}
+
+	return rc;
+}
+
+/*! \brief signal handler for subscriber related signals */
+static int smpp_subscr_cb(unsigned int subsys, unsigned int signal,
+			  void *handler_data, void *signal_data)
+{
+	struct vlr_subscr *vsub = signal_data;
+	struct smsc *smsc = handler_data;
+	uint8_t smpp_avail_status;
+
+	/* determine the smpp_avail_status depending on attach/detach */
+	switch (signal) {
+	case S_SUBSCR_ATTACHED:
+		smpp_avail_status = 0;
+		break;
+	case S_SUBSCR_DETACHED:
+		smpp_avail_status = 2;
+		break;
+	default:
+		return 0;
+	}
+
+	alert_all_esme(smsc, vsub, smpp_avail_status);
+
+	return 0;
+}
+
+/* GSM 03.38 6.2.1 Character expanding (no decode!) */
+static int gsm_7bit_expand(char *text, const uint8_t *user_data, uint8_t septet_l, uint8_t ud_hdr_ind)
+{
+	int i = 0;
+	int shift = 0;
+	uint8_t c;
+
+	/* skip the user data header */
+	if (ud_hdr_ind) {
+		/* get user data header length + 1 (for the 'user data header length'-field) */
+		shift = ((user_data[0] + 1) * 8) / 7;
+		if ((((user_data[0] + 1) * 8) % 7) != 0)
+			shift++;
+		septet_l = septet_l - shift;
+	}
+
+	for (i = 0; i < septet_l; i++) {
+		c =
+			((user_data[((i + shift) * 7 + 7) >> 3] <<
+			  (7 - (((i + shift) * 7 + 7) & 7))) |
+			 (user_data[((i + shift) * 7) >> 3] >>
+			  (((i + shift) * 7) & 7))) & 0x7f;
+
+		*(text++) = c;
+	}
+
+	*text = '\0';
+
+	return i;
+}
+
+
+/* FIXME: libsmpp34 helpers, they should  be part of libsmpp34! */
+void append_tlv(tlv_t **req_tlv, uint16_t tag,
+	        const uint8_t *data, uint16_t len)
+{
+	tlv_t tlv;
+
+	memset(&tlv, 0, sizeof(tlv));
+	tlv.tag = tag;
+	tlv.length = len;
+	memcpy(tlv.value.octet, data, tlv.length);
+	build_tlv(req_tlv, &tlv);
+}
+void append_tlv_u8(tlv_t **req_tlv, uint16_t tag, uint8_t val)
+{
+	tlv_t tlv;
+
+	memset(&tlv, 0, sizeof(tlv));
+	tlv.tag = tag;
+	tlv.length = 1;
+	tlv.value.val08 = val;
+	build_tlv(req_tlv, &tlv);
+}
+void append_tlv_u16(tlv_t **req_tlv, uint16_t tag, uint16_t val)
+{
+	tlv_t tlv;
+
+	memset(&tlv, 0, sizeof(tlv));
+	tlv.tag = tag;
+	tlv.length = 2;
+	tlv.value.val16 = val;
+	build_tlv(req_tlv, &tlv);
+}
+
+#if BEFORE_MSCSPLIT
+/* We currently have no lchan information. Re-add after A-interface, see OS#2390. */
+/* Append the Osmocom vendor-specific additional TLVs to a SMPP msg */
+static void append_osmo_tlvs(tlv_t **req_tlv, const struct gsm_lchan *lchan)
+{
+	int idx = calc_initial_idx(ARRAY_SIZE(lchan->meas_rep),
+				   lchan->meas_rep_idx, 1);
+	const struct gsm_meas_rep *mr = &lchan->meas_rep[idx];
+	const struct gsm_meas_rep_unidir *ul_meas = &mr->ul;
+	const struct gsm_meas_rep_unidir *dl_meas = &mr->dl;
+
+	/* Osmocom vendor-specific SMPP34 extensions */
+	append_tlv_u16(req_tlv, TLVID_osmo_arfcn, lchan->ts->trx->arfcn);
+	if (mr->flags & MEAS_REP_F_MS_L1) {
+		uint8_t ms_dbm;
+		append_tlv_u8(req_tlv, TLVID_osmo_ta, mr->ms_l1.ta);
+		ms_dbm = ms_pwr_dbm(lchan->ts->trx->bts->band, mr->ms_l1.pwr);
+		append_tlv_u8(req_tlv, TLVID_osmo_ms_l1_txpwr, ms_dbm);
+	} else if (mr->flags & MEAS_REP_F_MS_TO) /* Save Timing Offset field = MS Timing Offset + 63 */
+		append_tlv_u8(req_tlv, TLVID_osmo_ta, mr->ms_timing_offset + 63);
+
+	append_tlv_u16(req_tlv, TLVID_osmo_rxlev_ul,
+		       rxlev2dbm(ul_meas->full.rx_lev));
+	append_tlv_u8(req_tlv, TLVID_osmo_rxqual_ul, ul_meas->full.rx_qual);
+
+	if (mr->flags & MEAS_REP_F_DL_VALID) {
+		append_tlv_u16(req_tlv, TLVID_osmo_rxlev_dl,
+			       rxlev2dbm(dl_meas->full.rx_lev));
+		append_tlv_u8(req_tlv, TLVID_osmo_rxqual_dl,
+			      dl_meas->full.rx_qual);
+	}
+
+	if (lchan->conn && lchan->conn->vsub) {
+		struct vlr_subscr *vsub = lchan->conn->vsub;
+		size_t imei_len = strlen(vsub->imei);
+		if (imei_len)
+			append_tlv(req_tlv, TLVID_osmo_imei,
+				   (uint8_t *)vsub->imei, imei_len+1);
+	}
+}
+#endif
+
+struct {
+	uint32_t smpp_status_code;
+	uint8_t gsm411_cause;
+} smpp_to_gsm411_err_array[] = {
+
+	/* Seems like most phones don't care about the failure cause,
+	 * although some will display a different notification for
+	 * GSM411_RP_CAUSE_MO_NUM_UNASSIGNED
+	 * Some provoke a display of "Try again later"
+	 * while others a more definitive "Message sending failed"
+	 */
+
+	{ ESME_RSYSERR, 	GSM411_RP_CAUSE_MO_DEST_OUT_OF_ORDER	},
+	{ ESME_RINVDSTADR,	GSM411_RP_CAUSE_MO_NUM_UNASSIGNED	},
+	{ ESME_RMSGQFUL,	GSM411_RP_CAUSE_MO_CONGESTION		},
+	{ ESME_RINVSRCADR,	GSM411_RP_CAUSE_MO_SMS_REJECTED		},
+	{ ESME_RINVMSGID,	GSM411_RP_CAUSE_INV_TRANS_REF		}
+};
+
+static int smpp_to_gsm411_err(uint32_t smpp_status_code, int *gsm411_cause)
+{
+	int i;
+	for (i = 0; i < ARRAY_SIZE(smpp_to_gsm411_err_array); i++) {
+		if (smpp_to_gsm411_err_array[i].smpp_status_code != smpp_status_code)
+			continue;
+		*gsm411_cause = smpp_to_gsm411_err_array[i].gsm411_cause;
+		return 0;
+	}
+	return -1;
+}
+
+static void smpp_cmd_free(struct osmo_smpp_cmd *cmd)
+{
+	osmo_timer_del(&cmd->response_timer);
+	llist_del(&cmd->list);
+	vlr_subscr_put(cmd->vsub);
+	talloc_free(cmd);
+}
+
+void smpp_cmd_flush_pending(struct osmo_esme *esme)
+{
+	struct osmo_smpp_cmd *cmd, *next;
+
+	llist_for_each_entry_safe(cmd, next, &esme->smpp_cmd_list, list)
+		smpp_cmd_free(cmd);
+}
+
+void smpp_cmd_ack(struct osmo_smpp_cmd *cmd)
+{
+	struct gsm_subscriber_connection *conn;
+	struct gsm_trans *trans;
+
+	if (cmd->is_report)
+		goto out;
+
+	conn = connection_for_subscr(cmd->vsub);
+	if (!conn) {
+		LOGP(DSMPP, LOGL_ERROR, "No connection to subscriber anymore\n");
+		goto out;
+	}
+
+	trans = trans_find_by_id(conn, GSM48_PDISC_SMS, cmd->gsm411_trans_id);
+	if (!trans) {
+		LOGP(DSMPP, LOGL_ERROR, "GSM transaction %u is gone\n",
+		     cmd->gsm411_trans_id);
+		goto out;
+	}
+
+	gsm411_send_rp_ack(trans, cmd->gsm411_msg_ref);
+out:
+	smpp_cmd_free(cmd);
+}
+
+void smpp_cmd_err(struct osmo_smpp_cmd *cmd, uint32_t status)
+{
+	struct gsm_subscriber_connection *conn;
+	struct gsm_trans *trans;
+	int gsm411_cause;
+
+	if (cmd->is_report)
+		goto out;
+
+	conn = connection_for_subscr(cmd->vsub);
+	if (!conn) {
+		LOGP(DSMPP, LOGL_ERROR, "No connection to subscriber anymore\n");
+		goto out;
+	}
+
+	trans = trans_find_by_id(conn, GSM48_PDISC_SMS, cmd->gsm411_trans_id);
+	if (!trans) {
+		LOGP(DSMPP, LOGL_ERROR, "GSM transaction %u is gone\n",
+		     cmd->gsm411_trans_id);
+		goto out;
+	}
+
+	if (smpp_to_gsm411_err(status, &gsm411_cause) < 0)
+		gsm411_cause = GSM411_RP_CAUSE_MO_NET_OUT_OF_ORDER;
+
+	gsm411_send_rp_error(trans, cmd->gsm411_msg_ref, gsm411_cause);
+out:
+	smpp_cmd_free(cmd);
+}
+
+static void smpp_deliver_sm_cb(void *data)
+{
+	smpp_cmd_err(data, ESME_RSYSERR);
+}
+
+static int smpp_cmd_enqueue(struct osmo_esme *esme,
+			    struct vlr_subscr *vsub, struct gsm_sms *sms,
+			    uint32_t sequence_number)
+{
+	struct osmo_smpp_cmd *cmd;
+
+	cmd = talloc_zero(esme, struct osmo_smpp_cmd);
+	if (!cmd)
+		return -1;
+
+	cmd->sequence_nr	= sequence_number;
+	cmd->is_report		= sms->is_report;
+	cmd->gsm411_msg_ref	= sms->gsm411.msg_ref;
+	cmd->gsm411_trans_id	= sms->gsm411.transaction_id;
+	cmd->vsub		= vlr_subscr_get(vsub);
+
+	/* FIXME: No predefined value for this response_timer as specified by
+	 * SMPP 3.4 specs, section 7.2. Make this configurable? Don't forget
+	 * lchan keeps busy until we get a reply to this SMPP command. Too high
+	 * value may exhaust resources.
+	 */
+	osmo_timer_setup(&cmd->response_timer, smpp_deliver_sm_cb, cmd);
+	osmo_timer_schedule(&cmd->response_timer, 5, 0);
+	llist_add_tail(&cmd->list, &esme->smpp_cmd_list);
+
+	return 0;
+}
+
+struct osmo_smpp_cmd *smpp_cmd_find_by_seqnum(struct osmo_esme *esme,
+					      uint32_t sequence_nr)
+{
+	struct osmo_smpp_cmd *cmd;
+
+	llist_for_each_entry(cmd, &esme->smpp_cmd_list, list) {
+		if (cmd->sequence_nr == sequence_nr)
+			return cmd;
+	}
+	return NULL;
+}
+
+static int deliver_to_esme(struct osmo_esme *esme, struct gsm_sms *sms,
+			   struct gsm_subscriber_connection *conn)
+{
+	struct deliver_sm_t deliver;
+	int mode, ret;
+	uint8_t dcs;
+
+	memset(&deliver, 0, sizeof(deliver));
+	deliver.command_length	= 0;
+	deliver.command_id	= DELIVER_SM;
+	deliver.command_status	= ESME_ROK;
+
+	strcpy((char *)deliver.service_type, "CMT");
+	if (esme->acl && esme->acl->deliver_src_imsi) {
+		deliver.source_addr_ton	= TON_Subscriber_Number;
+		deliver.source_addr_npi = NPI_Land_Mobile_E212;
+		snprintf((char *)deliver.source_addr,
+			sizeof(deliver.source_addr), "%s",
+			conn->vsub->imsi);
+	} else {
+		deliver.source_addr_ton = TON_Network_Specific;
+		deliver.source_addr_npi = NPI_ISDN_E163_E164;
+		snprintf((char *)deliver.source_addr,
+			 sizeof(deliver.source_addr), "%s",
+			 conn->vsub->msisdn);
+	}
+
+	deliver.dest_addr_ton	= sms->dst.ton;
+	deliver.dest_addr_npi	= sms->dst.npi;
+	memcpy(deliver.destination_addr, sms->dst.addr,
+		sizeof(deliver.destination_addr));
+
+	if (sms->is_report)
+		deliver.esm_class = SMPP34_DELIVERY_RECEIPT;
+	else
+		deliver.esm_class = SMPP34_DATAGRAM_MODE;
+
+	if (sms->ud_hdr_ind)
+		deliver.esm_class |= SMPP34_UDHI_IND;
+	if (sms->reply_path_req)
+		deliver.esm_class |= SMPP34_REPLY_PATH;
+
+	deliver.protocol_id 	= sms->protocol_id;
+	deliver.priority_flag	= 0;
+	if (sms->status_rep_req)
+		deliver.registered_delivery = SMPP34_DELIVERY_RECEIPT_ON;
+
+	/* Figure out SMPP DCS from TP-DCS */
+	dcs = sms->data_coding_scheme;
+	if (smpp_determine_scheme(dcs, &deliver.data_coding, &mode) == -1)
+		return -1;
+
+	/* Transparently pass on DCS via SMPP if requested */
+	if (esme->acl && esme->acl->dcs_transparent)
+		deliver.data_coding = dcs;
+
+	if (mode == MODE_7BIT) {
+		uint8_t *dst = deliver.short_message;
+
+		/* SMPP has this strange notion of putting 7bit SMS in
+		 * an octet-aligned mode */
+		if (sms->ud_hdr_ind) {
+			/* length (bytes) of UDH inside UD */
+			uint8_t udh_len = sms->user_data[0] + 1;
+
+			/* copy over the UDH */
+			memcpy(dst, sms->user_data, udh_len);
+			dst += udh_len;
+			deliver.sm_length = udh_len;
+		}
+		/* add decoded text */
+		deliver.sm_length += gsm_7bit_expand((char *)dst, sms->user_data, sms->user_data_len, sms->ud_hdr_ind);
+	} else {
+		deliver.sm_length = sms->user_data_len;
+		memcpy(deliver.short_message, sms->user_data, deliver.sm_length);
+	}
+
+#if BEFORE_MSCSPLIT
+	/* We currently have no lchan information. Re-add after A-interface, see OS#2390. */
+	if (esme->acl && esme->acl->osmocom_ext && conn->lchan)
+		append_osmo_tlvs(&deliver.tlv, conn->lchan);
+#endif
+
+	append_tlv_u16(&deliver.tlv, TLVID_user_message_reference,
+		       sms->msg_ref);
+
+	ret = smpp_tx_deliver(esme, &deliver);
+	if (ret < 0)
+		return ret;
+
+	return smpp_cmd_enqueue(esme, conn->vsub, sms,
+				deliver.sequence_number);
+}
+
+static struct smsc *g_smsc;
+
+int smpp_route_smpp_first(struct gsm_sms *sms, struct gsm_subscriber_connection *conn)
+{
+	return g_smsc->smpp_first;
+}
+
+int smpp_try_deliver(struct gsm_sms *sms,
+		     struct gsm_subscriber_connection *conn)
+{
+	struct osmo_esme *esme;
+	struct osmo_smpp_addr dst;
+	int rc;
+
+	memset(&dst, 0, sizeof(dst));
+	dst.ton = sms->dst.ton;
+	dst.npi = sms->dst.npi;
+	memcpy(dst.addr, sms->dst.addr, sizeof(dst.addr));
+
+	rc = smpp_route(g_smsc, &dst, &esme);
+	if (!rc)
+		rc = deliver_to_esme(esme, sms, conn);
+
+	return rc;
+}
+
+struct smsc *smsc_from_vty(struct vty *v)
+{
+	/* FIXME: this is ugly */
+	return g_smsc;
+}
+
+/*! \brief Allocate the OpenBSC SMPP interface struct and init VTY. */
+int smpp_openbsc_alloc_init(void *ctx)
+{
+	g_smsc = smpp_smsc_alloc_init(ctx);
+	if (!g_smsc) {
+		LOGP(DSMPP, LOGL_FATAL, "Cannot allocate smsc struct\n");
+		return -1;
+	}
+	return smpp_vty_init();
+}
+
+/*! \brief Launch the OpenBSC SMPP interface with the parameters set from VTY.
+ */
+int smpp_openbsc_start(struct gsm_network *net)
+{
+	int rc;
+	g_smsc->priv = net;
+
+	/* If a VTY configuration has taken place, the values have been stored
+	 * in the smsc struct. Otherwise, use the defaults (NULL -> any, 0 ->
+	 * default SMPP port, see smpp_smsc_bind()). */
+	rc = smpp_smsc_start(g_smsc, g_smsc->bind_addr, g_smsc->listen_port);
+	if (rc < 0)
+		return rc;
+
+	rc = osmo_signal_register_handler(SS_SMS, smpp_sms_cb, g_smsc);
+	if (rc < 0)
+		return rc;
+	rc = osmo_signal_register_handler(SS_SUBSCR, smpp_subscr_cb, g_smsc);
+	if (rc < 0)
+		return rc;
+
+	return 0;
+}
+
diff --git a/src/libmsc/smpp_smsc.c b/src/libmsc/smpp_smsc.c
new file mode 100644
index 0000000..ea5303c
--- /dev/null
+++ b/src/libmsc/smpp_smsc.c
@@ -0,0 +1,1047 @@
+/* SMPP 3.4 interface, SMSC-side implementation */
+/* (C) 2012 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 <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdint.h>
+#include <errno.h>
+#include <limits.h>
+
+#include <sys/socket.h>
+#include <netinet/in.h>
+
+#include <smpp34.h>
+#include <smpp34_structs.h>
+#include <smpp34_params.h>
+
+#include <osmocom/core/utils.h>
+#include <osmocom/core/socket.h>
+#include <osmocom/core/msgb.h>
+#include <osmocom/core/logging.h>
+#include <osmocom/core/write_queue.h>
+#include <osmocom/core/talloc.h>
+
+#include "smpp_smsc.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)
+
+enum emse_bind {
+	ESME_BIND_RX = 0x01,
+	ESME_BIND_TX = 0x02,
+};
+
+const struct value_string smpp_status_strs[] = {
+	{ ESME_ROK,		"No Error" },
+	{ ESME_RINVMSGLEN,	"Message Length is invalid" },
+	{ ESME_RINVCMDLEN,	"Command Length is invalid" },
+	{ ESME_RINVCMDID,	"Invalid Command ID" },
+	{ ESME_RINVBNDSTS,	"Incorrect BIND Status for given command" },
+	{ ESME_RALYBND,		"ESME Already in Bound State" },
+	{ ESME_RINVPRTFLG,	"Invalid Priority Flag" },
+	{ ESME_RINVREGDLVFLG,	"Invalid Registered Delivery Flag" },
+	{ ESME_RSYSERR,		"System Error" },
+	{ ESME_RINVSRCADR,	"Invalid Source Address" },
+	{ ESME_RINVDSTADR,	"Invalid Destination Address" },
+	{ ESME_RINVMSGID,	"Message ID is invalid" },
+	{ ESME_RBINDFAIL,	"Bind failed" },
+	{ ESME_RINVPASWD,	"Invalid Password" },
+	{ ESME_RINVSYSID,	"Invalid System ID" },
+	{ ESME_RCANCELFAIL,	"Cancel SM Failed" },
+	{ ESME_RREPLACEFAIL,	"Replace SM Failed" },
+	{ ESME_RMSGQFUL,	"Message Queue Full" },
+	{ ESME_RINVSERTYP,	"Invalid Service Type" },
+	{ ESME_RINVNUMDESTS,	"Invalid number of destinations" },
+	{ ESME_RINVDLNAME,	"Invalid Distribution List name" },
+	{ ESME_RINVDESTFLAG,	"Destination flag is invalid" },
+	{ ESME_RINVSUBREP,	"Invalid submit with replace request" },
+	{ ESME_RINVESMCLASS,	"Invalid esm_class field data" },
+	{ ESME_RCNTSUBDL,	"Cannot Submit to Distribution List" },
+	{ ESME_RSUBMITFAIL,	"submit_sm or submit_multi failed" },
+	{ ESME_RINVSRCTON,	"Invalid Source address TON" },
+	{ ESME_RINVSRCNPI,	"Invalid Sourec address NPI" },
+	{ ESME_RINVDSTTON,	"Invalid Destination address TON" },
+	{ ESME_RINVDSTNPI,	"Invalid Desetination address NPI" },
+	{ ESME_RINVSYSTYP,	"Invalid system_type field" },
+	{ ESME_RINVREPFLAG,	"Invalid replace_if_present field" },
+	{ ESME_RINVNUMMSGS,	"Invalid number of messages" },
+	{ ESME_RTHROTTLED,	"Throttling error (ESME has exceeded message limits)" },
+	{ ESME_RINVSCHED,	"Invalid Scheduled Delivery Time" },
+	{ ESME_RINVEXPIRY,	"Invalid message validity period (Expiry time)" },
+	{ ESME_RINVDFTMSGID,	"Predefined Message Invalid or Not Found" },
+	{ ESME_RX_T_APPN,	"ESME Receiver Temporary App Error Code" },
+	{ ESME_RX_P_APPN,	"ESME Receiver Permanent App Error Code" },
+	{ ESME_RX_R_APPN,	"ESME Receiver Reject Message Error Code" },
+	{ ESME_RQUERYFAIL,	"query_sm request failed" },
+	{ ESME_RINVOPTPARSTREAM,"Error in the optional part of the PDU Body" },
+	{ ESME_ROPTPARNOTALLWD,	"Optional Parameter not allowed" },
+	{ ESME_RINVPARLEN,	"Invalid Parameter Length" },
+	{ ESME_RMISSINGOPTPARAM,"Expected Optional Parameter missing" },
+	{ ESME_RINVOPTPARAMVAL,	"Invalid Optional Parameter Value" },
+	{ ESME_RDELIVERYFAILURE,"Delivery Failure (used for data_sm_resp)" },
+	{ ESME_RUNKNOWNERR,	"Unknown Error" },
+	{ 0, NULL }
+};
+
+/*! \brief compare if two SMPP addresses are equal */
+int smpp_addr_eq(const struct osmo_smpp_addr *a,
+		 const struct osmo_smpp_addr *b)
+{
+	if (a->ton == b->ton &&
+	    a->npi == b->npi &&
+	    !strcmp(a->addr, b->addr))
+		return 1;
+
+	return 0;
+}
+
+
+struct osmo_smpp_acl *smpp_acl_by_system_id(struct smsc *smsc,
+					    const char *sys_id)
+{
+	struct osmo_smpp_acl *acl;
+
+	llist_for_each_entry(acl, &smsc->acl_list, list) {
+		if (!strcmp(acl->system_id, sys_id))
+			return acl;
+	}
+
+	return NULL;
+}
+
+struct osmo_smpp_acl *smpp_acl_alloc(struct smsc *smsc, const char *sys_id)
+{
+	struct osmo_smpp_acl *acl;
+
+	if (strlen(sys_id) > SMPP_SYS_ID_LEN)
+		return NULL;
+
+	if (smpp_acl_by_system_id(smsc, sys_id))
+		return NULL;
+
+	acl = talloc_zero(smsc, struct osmo_smpp_acl);
+	if (!acl)
+		return NULL;
+
+	acl->smsc = smsc;
+	strcpy(acl->system_id, sys_id);
+	INIT_LLIST_HEAD(&acl->route_list);
+
+	llist_add_tail(&acl->list, &smsc->acl_list);
+
+	return acl;
+}
+
+void smpp_acl_delete(struct osmo_smpp_acl *acl)
+{
+	struct osmo_smpp_route *r, *r2;
+
+	llist_del(&acl->list);
+
+	/* kill any active ESMEs */
+	if (acl->esme) {
+		struct osmo_esme *esme = acl->esme;
+		osmo_fd_unregister(&esme->wqueue.bfd);
+		close(esme->wqueue.bfd.fd);
+		esme->wqueue.bfd.fd = -1;
+		esme->acl = NULL;
+		smpp_esme_put(esme);
+	}
+
+	/* delete all routes for this ACL */
+	llist_for_each_entry_safe(r, r2, &acl->route_list, list) {
+		llist_del(&r->list);
+		llist_del(&r->global_list);
+		talloc_free(r);
+	}
+
+	talloc_free(acl);
+}
+
+static struct osmo_smpp_route *route_alloc(struct osmo_smpp_acl *acl)
+{
+	struct osmo_smpp_route *r;
+
+	r = talloc_zero(acl, struct osmo_smpp_route);
+	if (!r)
+		return NULL;
+
+	llist_add_tail(&r->list, &acl->route_list);
+	llist_add_tail(&r->global_list, &acl->smsc->route_list);
+
+	return r;
+}
+
+int smpp_route_pfx_add(struct osmo_smpp_acl *acl,
+			const struct osmo_smpp_addr *pfx)
+{
+	struct osmo_smpp_route *r;
+
+	llist_for_each_entry(r, &acl->route_list, list) {
+		if (r->type == SMPP_ROUTE_PREFIX &&
+		    smpp_addr_eq(&r->u.prefix, pfx))
+			return -EEXIST;
+	}
+
+	r = route_alloc(acl);
+	if (!r)
+		return -ENOMEM;
+	r->type = SMPP_ROUTE_PREFIX;
+	r->acl = acl;
+	memcpy(&r->u.prefix, pfx, sizeof(r->u.prefix));
+
+	return 0;
+}
+
+int smpp_route_pfx_del(struct osmo_smpp_acl *acl,
+		       const struct osmo_smpp_addr *pfx)
+{
+	struct osmo_smpp_route *r, *r2;
+
+	llist_for_each_entry_safe(r, r2, &acl->route_list, list) {
+		if (r->type == SMPP_ROUTE_PREFIX &&
+		    smpp_addr_eq(&r->u.prefix, pfx)) {
+			llist_del(&r->list);
+			talloc_free(r);
+			return 0;
+		}
+	}
+
+	return -ENODEV;
+}
+
+
+/*! \brief increaes the use/reference count */
+void smpp_esme_get(struct osmo_esme *esme)
+{
+	esme->use++;
+}
+
+static void esme_destroy(struct osmo_esme *esme)
+{
+	osmo_wqueue_clear(&esme->wqueue);
+	if (esme->wqueue.bfd.fd >= 0) {
+		osmo_fd_unregister(&esme->wqueue.bfd);
+		close(esme->wqueue.bfd.fd);
+	}
+	smpp_cmd_flush_pending(esme);
+	llist_del(&esme->list);
+	if (esme->acl)
+		esme->acl->esme = NULL;
+	talloc_free(esme);
+}
+
+static uint32_t esme_inc_seq_nr(struct osmo_esme *esme)
+{
+	esme->own_seq_nr++;
+	if (esme->own_seq_nr > 0x7fffffff)
+		esme->own_seq_nr = 1;
+
+	return esme->own_seq_nr;
+}
+
+/*! \brief decrease the use/reference count, free if it is 0 */
+void smpp_esme_put(struct osmo_esme *esme)
+{
+	esme->use--;
+	if (esme->use <= 0)
+		esme_destroy(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)
+{
+	struct osmo_smpp_route *r;
+	struct osmo_smpp_acl *acl = NULL;
+
+	DEBUGP(DSMPP, "Looking up route for (%u/%u/%s)\n",
+		dest->ton, dest->npi, dest->addr);
+
+	/* search for a specific route */
+	llist_for_each_entry(r, &smsc->route_list, global_list) {
+		switch (r->type) {
+		case SMPP_ROUTE_PREFIX:
+			DEBUGP(DSMPP, "Checking prefix route (%u/%u/%s)->%s\n",
+				r->u.prefix.ton, r->u.prefix.npi, r->u.prefix.addr,
+				r->acl->system_id);
+			if (r->u.prefix.ton == dest->ton &&
+			    r->u.prefix.npi == dest->npi &&
+			    !strncmp(r->u.prefix.addr, dest->addr,
+				     strlen(r->u.prefix.addr))) {
+				DEBUGP(DSMPP, "Found prefix route ACL\n");
+				acl = r->acl;
+			}
+			break;
+		default:
+			break;
+		}
+
+		if (acl)
+			break;
+	}
+
+	if (!acl) {
+		/* check for default route */
+		if (smsc->def_route) {
+			DEBUGP(DSMPP, "Using existing default route\n");
+			acl = smsc->def_route;
+		}
+	}
+
+	if (acl && acl->esme) {
+		struct osmo_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);
+	}
+
+	*pesme = NULL;
+	if (acl)
+		return GSM48_CC_CAUSE_NETWORK_OOO;
+	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;	\
+}
+
+/*! \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)
+{
+	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;
+}
+
+/*! \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)
+{
+	struct generic_nack_t nack;
+	char buf[SMALL_BUFF];
+
+	nack.command_length = 0;
+	nack.command_id = GENERIC_NACK;
+	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));
+
+	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)
+{
+	uint8_t *tmp = msgb_data(msg);
+	return ntohl(*(uint32_t *)tmp);
+}
+
+/*! \brief handle an incoming SMPP generic NACK */
+static int smpp_handle_gen_nack(struct osmo_esme *esme, struct msgb *msg)
+{
+	struct generic_nack_t nack;
+	char buf[SMALL_BUFF];
+	int rc;
+
+	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);
+		return rc;
+	}
+
+	LOGP(DSMPP, LOGL_ERROR, "[%s] Rx GENERIC NACK: %s\n",
+	     esme->system_id, str_command_status(nack.command_status, buf));
+
+	return 0;
+}
+
+static int _process_bind(struct osmo_esme *esme, uint8_t if_version,
+			 uint32_t bind_flags, const char *sys_id,
+			 const char *passwd)
+{
+	struct osmo_smpp_acl *acl;
+
+	if (if_version != SMPP_VERSION)
+		return ESME_RSYSERR;
+
+	if (esme->bind_flags)
+		return ESME_RALYBND;
+
+	esme->smpp_version = if_version;
+	snprintf(esme->system_id, sizeof(esme->system_id), "%s", sys_id);
+
+	acl = smpp_acl_by_system_id(esme->smsc, esme->system_id);
+	if (!esme->smsc->accept_all) {
+		if (!acl) {
+			/* This system is unknown */
+			return ESME_RINVSYSID;
+		} else {
+			if (strlen(acl->passwd) &&
+			    strcmp(acl->passwd, passwd)) {
+				return ESME_RINVPASWD;
+			}
+		}
+	}
+	if (acl) {
+		esme->acl = acl;
+		acl->esme = esme;
+	}
+
+	esme->bind_flags = bind_flags;
+
+	return ESME_ROK;
+}
+
+
+/*! \brief handle an incoming SMPP BIND RECEIVER */
+static int smpp_handle_bind_rx(struct osmo_esme *esme, struct msgb *msg)
+{
+	struct bind_receiver_t bind;
+	struct bind_receiver_resp_t bind_r;
+	int rc;
+
+	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);
+		return rc;
+	}
+
+	INIT_RESP(BIND_TRANSMITTER_RESP, &bind_r, &bind);
+
+	LOGP(DSMPP, LOGL_INFO, "[%s] Rx BIND Rx from (Version %02x)\n",
+		bind.system_id, bind.interface_version);
+
+	rc = _process_bind(esme, bind.interface_version, ESME_BIND_RX,
+			   (const char *)bind.system_id, (const char *)bind.password);
+	bind_r.command_status = rc;
+
+	return PACK_AND_SEND(esme, &bind_r);
+}
+
+/*! \brief handle an incoming SMPP BIND TRANSMITTER */
+static int smpp_handle_bind_tx(struct osmo_esme *esme, struct msgb *msg)
+{
+	struct bind_transmitter_t bind;
+	struct bind_transmitter_resp_t bind_r;
+	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);
+		return rc;
+	}
+
+	INIT_RESP(BIND_TRANSMITTER_RESP, &bind_r, &bind);
+
+	LOGP(DSMPP, LOGL_INFO, "[%s] Rx BIND Tx (Version %02x)\n",
+		bind.system_id, bind.interface_version);
+
+	rc = _process_bind(esme, bind.interface_version, ESME_BIND_TX,
+			   (const char *)bind.system_id, (const char *)bind.password);
+	bind_r.command_status = rc;
+
+	/* build response */
+	osmo_strlcpy((char*)bind_r.system_id, esme->smsc->system_id, sizeof(bind_r.system_id));
+
+	/* add interface version TLV */
+	tlv.tag = TLVID_sc_interface_version;
+	tlv.length = sizeof(uint8_t);
+	tlv.value.val16 = esme->smpp_version;
+	build_tlv(&bind_r.tlv, &tlv);
+
+	return PACK_AND_SEND(esme, &bind_r);
+}
+
+/*! \brief handle an incoming SMPP BIND TRANSCEIVER */
+static int smpp_handle_bind_trx(struct osmo_esme *esme, struct msgb *msg)
+{
+	struct bind_transceiver_t bind;
+	struct bind_transceiver_resp_t bind_r;
+	int rc;
+
+	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);
+		return rc;
+	}
+
+	INIT_RESP(BIND_TRANSCEIVER_RESP, &bind_r, &bind);
+
+	LOGP(DSMPP, LOGL_INFO, "[%s] Rx BIND Trx (Version %02x)\n",
+		bind.system_id, bind.interface_version);
+
+	rc = _process_bind(esme, bind.interface_version, ESME_BIND_RX|ESME_BIND_TX,
+			   (const char *)bind.system_id, (const char *)bind.password);
+	bind_r.command_status = rc;
+
+	return PACK_AND_SEND(esme, &bind_r);
+}
+
+/*! \brief handle an incoming SMPP UNBIND */
+static int smpp_handle_unbind(struct osmo_esme *esme, struct msgb *msg)
+{
+	struct unbind_t unbind;
+	struct unbind_resp_t unbind_r;
+	int rc;
+
+	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);
+		return rc;
+	}
+
+	INIT_RESP(UNBIND_RESP, &unbind_r, &unbind);
+
+	LOGP(DSMPP, LOGL_INFO, "[%s] Rx UNBIND\n", esme->system_id);
+
+	if (esme->bind_flags == 0) {
+		unbind_r.command_status = ESME_RINVBNDSTS;
+		goto err;
+	}
+
+	esme->bind_flags = 0;
+err:
+	return PACK_AND_SEND(esme, &unbind_r);
+}
+
+/*! \brief handle an incoming SMPP ENQUIRE LINK */
+static int smpp_handle_enq_link(struct osmo_esme *esme, struct msgb *msg)
+{
+	struct enquire_link_t enq;
+	struct enquire_link_resp_t enq_r;
+	int rc;
+
+	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);
+		return rc;
+	}
+
+	LOGP(DSMPP, LOGL_DEBUG, "[%s] Rx Enquire Link\n", esme->system_id);
+
+	INIT_RESP(ENQUIRE_LINK_RESP, &enq_r, &enq);
+
+	LOGP(DSMPP, LOGL_DEBUG, "[%s] Tx Enquire Link Response\n", esme->system_id);
+
+	return PACK_AND_SEND(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,
+		     uint32_t command_status, char *msg_id)
+{
+	struct submit_sm_resp_t submit_r;
+
+	memset(&submit_r, 0, sizeof(submit_r));
+	submit_r.command_length	= 0;
+	submit_r.command_id	= SUBMIT_SM_RESP;
+	submit_r.command_status	= command_status;
+	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);
+}
+
+static const struct value_string smpp_avail_strs[] = {
+	{ 0,	"Available" },
+	{ 1,	"Denied" },
+	{ 2,	"Unavailable" },
+	{ 0,	NULL }
+};
+
+/*! \brief send an ALERT_NOTIFICATION to a remote ESME */
+int smpp_tx_alert(struct osmo_esme *esme, uint8_t ton, uint8_t npi,
+		  const char *addr, uint8_t avail_status)
+{
+	struct alert_notification_t alert;
+	struct tlv_t tlv;
+
+	memset(&alert, 0, sizeof(alert));
+	alert.command_length	= 0;
+	alert.command_id	= ALERT_NOTIFICATION;
+	alert.command_status	= ESME_ROK;
+	alert.sequence_number	= esme_inc_seq_nr(esme);
+	alert.source_addr_ton 	= ton;
+	alert.source_addr_npi	= npi;
+	snprintf((char *)alert.source_addr, sizeof(alert.source_addr), "%s", addr);
+
+	tlv.tag = TLVID_ms_availability_status;
+	tlv.length = sizeof(uint8_t);
+	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));
+
+	return PACK_AND_SEND(esme, &alert);
+}
+
+/* \brief send a DELIVER-SM message to given ESME */
+int smpp_tx_deliver(struct osmo_esme *esme, struct deliver_sm_t *deliver)
+{
+	deliver->sequence_number = esme_inc_seq_nr(esme);
+
+	LOGP(DSMPP, LOGL_DEBUG, "[%s] Tx DELIVER-SM (from %s)\n",
+		esme->system_id, deliver->source_addr);
+
+	return PACK_AND_SEND(esme, deliver);
+}
+
+/*! \brief handle an incoming SMPP DELIVER-SM RESPONSE */
+static int smpp_handle_deliver_resp(struct osmo_esme *esme, struct msgb *msg)
+{
+	struct deliver_sm_resp_t deliver_r;
+	struct osmo_smpp_cmd *cmd;
+	int rc;
+
+	memset(&deliver_r, 0, sizeof(deliver_r));
+	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);
+		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));
+		return -1;
+	}
+
+	if (deliver_r.command_status == ESME_ROK)
+		smpp_cmd_ack(cmd);
+	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));
+
+	return 0;
+}
+
+/*! \brief handle an incoming SMPP SUBMIT-SM */
+static int smpp_handle_submit(struct osmo_esme *esme, struct msgb *msg)
+{
+	struct submit_sm_t submit;
+	struct submit_sm_resp_t submit_r;
+	int rc;
+
+	memset(&submit, 0, sizeof(submit));
+	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);
+		return rc;
+	}
+
+	INIT_RESP(SUBMIT_SM_RESP, &submit_r, &submit);
+
+	if (!(esme->bind_flags & ESME_BIND_TX)) {
+		submit_r.command_status = ESME_RINVBNDSTS;
+		return PACK_AND_SEND(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);
+
+	INIT_RESP(SUBMIT_SM_RESP, &submit_r, &submit);
+
+	rc = handle_smpp_submit(esme, &submit, &submit_r);
+	if (rc == 0)
+		return PACK_AND_SEND(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)
+{
+	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));
+
+	switch (cmd_id) {
+	case GENERIC_NACK:
+		rc = smpp_handle_gen_nack(esme, msg);
+		break;
+	case BIND_RECEIVER:
+		rc = smpp_handle_bind_rx(esme, msg);
+		break;
+	case BIND_TRANSMITTER:
+		rc = smpp_handle_bind_tx(esme, msg);
+		break;
+	case BIND_TRANSCEIVER:
+		rc = smpp_handle_bind_trx(esme, msg);
+		break;
+	case UNBIND:
+		rc = smpp_handle_unbind(esme, msg);
+		break;
+	case ENQUIRE_LINK:
+		rc = smpp_handle_enq_link(esme, msg);
+		break;
+	case SUBMIT_SM:
+		rc = smpp_handle_submit(esme, msg);
+		break;
+	case DELIVER_SM_RESP:
+		rc = smpp_handle_deliver_resp(esme, msg);
+		break;
+	case DELIVER_SM:
+		break;
+	case DATA_SM:
+		break;
+	case CANCEL_SM:
+	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);
+		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);
+		break;
+	}
+
+	return rc;
+}
+
+/* This macro should be called after a call to read() in the read_cb of an
+ * osmo_fd to properly check for errors.
+ * rc is the return value of read, err_label is the label to jump to in case of
+ * an error. The code there should handle closing the connection.
+ * FIXME: This code should go in libosmocore utils.h so it can be used by other
+ * projects as well.
+ * */
+#define OSMO_FD_CHECK_READ(rc, err_label) \
+	if (rc < 0) { \
+		/* EINTR is a non-fatal error, just try again */ \
+		if (errno == EINTR) \
+			return 0; \
+		goto err_label; \
+	} else if (rc == 0) { \
+		goto err_label; \
+	}
+
+/* !\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;
+	uint32_t len;
+	uint8_t *lenptr = (uint8_t *) &len;
+	uint8_t *cur;
+	struct msgb *msg;
+	ssize_t rdlen, rc;
+
+	switch (esme->read_state) {
+	case READ_ST_IN_LEN:
+		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));
+		OSMO_FD_CHECK_READ(rc, dead_socket);
+
+		esme->read_idx += rc;
+
+		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);
+				goto dead_socket;
+			}
+
+			msg = msgb_alloc(esme->read_len, "SMPP Rx");
+			if (!msg)
+				return -ENOMEM;
+			esme->read_msg = msg;
+			cur = msgb_put(msg, sizeof(uint32_t));
+			memcpy(cur, lenptr, sizeof(uint32_t));
+			esme->read_state = READ_ST_IN_MSG;
+			esme->read_idx = sizeof(uint32_t);
+		}
+		break;
+	case READ_ST_IN_MSG:
+		msg = esme->read_msg;
+		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));
+		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);
+			msgb_free(esme->read_msg);
+			esme->read_msg = NULL;
+			esme->read_idx = 0;
+			esme->read_len = 0;
+			esme->read_state = READ_ST_IN_LEN;
+		}
+		break;
+	}
+
+	return 0;
+dead_socket:
+	msgb_free(esme->read_msg);
+	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);
+
+	return 0;
+}
+
+/* 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;
+	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;
+		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);
+		return -1;
+	}
+
+	return 0;
+}
+
+/* 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);
+	if (!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;
+
+	if (osmo_fd_register(&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);
+
+	llist_add_tail(&esme->list, &smsc->esme_list);
+
+	return 0;
+}
+
+/* callback of listening TCP socket */
+static int smsc_fd_cb(struct osmo_fd *ofd, unsigned int what)
+{
+	int rc;
+	struct sockaddr_storage sa;
+	socklen_t sa_len = sizeof(sa);
+
+	rc = accept(ofd->fd, (struct sockaddr *)&sa, &sa_len);
+	if (rc < 0) {
+		LOGP(DSMPP, LOGL_ERROR, "Accept returns %d (%s)\n",
+		     rc, strerror(errno));
+		return rc;
+	}
+	return link_accept_cb(ofd->data, rc, &sa, sa_len);
+}
+
+/*! \brief allocate and initialize an smsc struct from talloc context ctx. */
+struct smsc *smpp_smsc_alloc_init(void *ctx)
+{
+	struct smsc *smsc = talloc_zero(ctx, struct smsc);
+
+	INIT_LLIST_HEAD(&smsc->esme_list);
+	INIT_LLIST_HEAD(&smsc->acl_list);
+	INIT_LLIST_HEAD(&smsc->route_list);
+
+	smsc->listen_ofd.data = smsc;
+	smsc->listen_ofd.cb = smsc_fd_cb;
+
+	return smsc;
+}
+
+/*! \brief Set the SMPP address and port without binding. */
+int smpp_smsc_conf(struct smsc *smsc, const char *bind_addr, uint16_t port)
+{
+	smsc->listen_port = port;
+
+	/* Avoid use-after-free if bind_addr == smsc->bind_addr */
+	if (smsc->bind_addr == bind_addr)
+		return 0;
+
+	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 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).
+ */
+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);
+
+	rc = osmo_sock_init_ofd(&smsc->listen_ofd, AF_UNSPEC, SOCK_STREAM,
+				IPPROTO_TCP, bind_addr, port,
+				OSMO_SOCK_F_BIND);
+	if (rc < 0)
+		return rc;
+
+	/* store new address and port */
+	rc = smpp_smsc_conf(smsc, bind_addr, port);
+	if (rc)
+		smpp_smsc_stop(smsc);
+	return rc;
+}
+
+/*! \brief Change a running connection to a different address/port, and upon
+ * error switch back to the running configuration. */
+int smpp_smsc_restart(struct smsc *smsc, const char *bind_addr, uint16_t port)
+{
+	int rc;
+
+	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/libmsc/smpp_smsc.h b/src/libmsc/smpp_smsc.h
new file mode 100644
index 0000000..755e685
--- /dev/null
+++ b/src/libmsc/smpp_smsc.h
@@ -0,0 +1,167 @@
+#ifndef _SMPP_SMSC_H
+#define _SMPP_SMSC_H
+
+#include <sys/socket.h>
+#include <netinet/in.h>
+
+#include <osmocom/core/utils.h>
+#include <osmocom/core/msgb.h>
+#include <osmocom/core/write_queue.h>
+#include <osmocom/core/timer.h>
+
+#include <smpp34.h>
+#include <smpp34_structs.h>
+#include <smpp34_params.h>
+
+#define SMPP_SYS_ID_LEN	16
+#define SMPP_PASSWD_LEN	16
+
+#define MODE_7BIT	7
+#define MODE_8BIT	8
+
+enum esme_read_state {
+	READ_ST_IN_LEN = 0,
+	READ_ST_IN_MSG = 1,
+};
+
+struct osmo_smpp_acl;
+
+struct osmo_smpp_addr {
+	uint8_t ton;
+	uint8_t npi;
+	char addr[21+1];
+};
+
+struct osmo_esme {
+	struct llist_head list;
+	struct smsc *smsc;
+	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;
+	char *description;
+	char system_id[SMPP_SYS_ID_LEN+1];
+	char passwd[SMPP_PASSWD_LEN+1];
+	int default_route;
+	int deliver_src_imsi;
+	int osmocom_ext;
+	int dcs_transparent;
+	struct llist_head route_list;
+};
+
+enum osmo_smpp_rtype {
+	SMPP_ROUTE_NONE,
+	SMPP_ROUTE_PREFIX,
+};
+
+struct osmo_smpp_route {
+	struct llist_head list;	/*!< in acl.route_list */
+	struct llist_head global_list; /*!< in smsc->route_list */
+	struct osmo_smpp_acl *acl;
+	enum osmo_smpp_rtype type;
+	union {
+		struct osmo_smpp_addr prefix;
+	} u;
+};
+
+struct osmo_smpp_cmd {
+	struct llist_head	list;
+	struct vlr_subscr	*vsub;
+	uint32_t		sequence_nr;
+	uint32_t		gsm411_msg_ref;
+	uint8_t			gsm411_trans_id;
+	bool			is_report;
+	struct osmo_timer_list	response_timer;
+};
+
+struct osmo_smpp_cmd *smpp_cmd_find_by_seqnum(struct osmo_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);
+
+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;
+	uint16_t listen_port;
+	char system_id[SMPP_SYS_ID_LEN+1];
+	int accept_all;
+	int smpp_first;
+	struct osmo_smpp_acl *def_route;
+	void *priv;
+};
+
+int smpp_addr_eq(const struct osmo_smpp_addr *a,
+		 const struct osmo_smpp_addr *b);
+
+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);
+
+int smpp_route(const struct smsc *smsc, const struct osmo_smpp_addr *dest, struct osmo_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,
+		     uint32_t command_status, char *msg_id);
+
+int smpp_tx_alert(struct osmo_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 handle_smpp_submit(struct osmo_esme *esme, struct submit_sm_t *submit,
+			struct submit_sm_resp_t *submit_r);
+
+int smpp_route_pfx_add(struct osmo_smpp_acl *acl,
+		       const struct osmo_smpp_addr *pfx);
+int smpp_route_pfx_del(struct osmo_smpp_acl *acl,
+		       const struct osmo_smpp_addr *pfx);
+
+int smpp_vty_init(void);
+
+int smpp_determine_scheme(uint8_t dcs, uint8_t *data_coding, int *mode);
+
+
+
+struct gsm_sms;
+struct gsm_subscriber_connection;
+
+int smpp_route_smpp_first(struct gsm_sms *sms,
+			    struct gsm_subscriber_connection *conn);
+int smpp_try_deliver(struct gsm_sms *sms,
+		     struct gsm_subscriber_connection *conn);
+#endif
diff --git a/src/libmsc/smpp_utils.c b/src/libmsc/smpp_utils.c
new file mode 100644
index 0000000..7fffdd2
--- /dev/null
+++ b/src/libmsc/smpp_utils.c
@@ -0,0 +1,61 @@
+
+/* (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/smpp_vty.c b/src/libmsc/smpp_vty.c
new file mode 100644
index 0000000..be55c4d
--- /dev/null
+++ b/src/libmsc/smpp_vty.c
@@ -0,0 +1,610 @@
+/* SMPP vty interface */
+
+/* (C) 2012 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 <ctype.h>
+#include <string.h>
+#include <errno.h>
+#include <netdb.h>
+#include <sys/socket.h>
+
+#include <osmocom/vty/command.h>
+#include <osmocom/vty/buffer.h>
+#include <osmocom/vty/vty.h>
+
+#include <osmocom/core/linuxlist.h>
+#include <osmocom/core/utils.h>
+#include <osmocom/core/talloc.h>
+
+#include <osmocom/msc/vty.h>
+
+#include "smpp_smsc.h"
+
+struct smsc *smsc_from_vty(struct vty *v);
+
+static struct cmd_node smpp_node = {
+	SMPP_NODE,
+	"%s(config-smpp)# ",
+	1,
+};
+
+static struct cmd_node esme_node = {
+	SMPP_ESME_NODE,
+	"%s(config-smpp-esme)# ",
+	1,
+};
+
+DEFUN(cfg_smpp, cfg_smpp_cmd,
+	"smpp", "Configure SMPP SMS Interface")
+{
+	vty->node = SMPP_NODE;
+
+	return CMD_SUCCESS;
+}
+
+DEFUN(cfg_smpp_first, cfg_smpp_first_cmd,
+	"smpp-first",
+	"Try SMPP routes before the subscriber DB\n")
+{
+	struct smsc *smsc = smsc_from_vty(vty);
+	smsc->smpp_first = 1;
+	return CMD_SUCCESS;
+}
+
+DEFUN(cfg_no_smpp_first, cfg_no_smpp_first_cmd,
+	"no smpp-first",
+	NO_STR "Try SMPP before routes before the subscriber DB\n")
+{
+	struct smsc *smsc = smsc_from_vty(vty);
+	smsc->smpp_first = 0;
+	return CMD_SUCCESS;
+}
+
+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;
+	int rc;
+
+	/* If it is not up yet, don't rebind, just set values. */
+	if (!is_running) {
+		rc = smpp_smsc_conf(smsc, bind_addr, port);
+		if (rc < 0) {
+			vty_out(vty, "%% Cannot configure new address:port%s",
+				VTY_NEWLINE);
+			return CMD_WARNING;
+		}
+		return CMD_SUCCESS;
+	}
+
+	rc = smpp_smsc_restart(smsc, bind_addr, port);
+	if (rc < 0) {
+		vty_out(vty, "%% Cannot bind to new port %s:%u nor to"
+			" old port %s:%u%s",
+			bind_addr? bind_addr : "0.0.0.0",
+			port,
+			smsc->bind_addr? smsc->bind_addr : "0.0.0.0",
+			smsc->listen_port,
+			VTY_NEWLINE);
+		return CMD_WARNING;
+	}
+
+	same_bind_addr = (bind_addr == smsc->bind_addr)
+		|| (bind_addr && smsc->bind_addr
+		    && (strcmp(bind_addr, smsc->bind_addr) == 0));
+
+	if (!same_bind_addr || port != smsc->listen_port) {
+		vty_out(vty, "%% Cannot bind to new port %s:%u, staying on"
+			" old port %s:%u%s",
+			bind_addr? bind_addr : "0.0.0.0",
+			port,
+			smsc->bind_addr? smsc->bind_addr : "0.0.0.0",
+			smsc->listen_port,
+			VTY_NEWLINE);
+		return CMD_WARNING;
+	}
+
+	return CMD_SUCCESS;
+}
+
+DEFUN(cfg_smpp_port, cfg_smpp_port_cmd,
+	"local-tcp-port <1-65535>",
+	"Set the local TCP port on which we listen for SMPP\n"
+	"TCP port number")
+{
+	struct smsc *smsc = smsc_from_vty(vty);
+	uint16_t port = atoi(argv[0]);
+	return smpp_local_tcp(vty, smsc->bind_addr, port);
+}
+
+DEFUN(cfg_smpp_addr_port, cfg_smpp_addr_port_cmd,
+	"local-tcp-ip A.B.C.D <1-65535>",
+	"Set the local IP address and TCP port on which we listen for SMPP\n"
+	"Local IP address\n"
+	"TCP port number")
+{
+	const char *bind_addr = argv[0];
+	uint16_t port = atoi(argv[1]);
+	return smpp_local_tcp(vty, bind_addr, port);
+}
+
+DEFUN(cfg_smpp_sys_id, cfg_smpp_sys_id_cmd,
+	"system-id ID",
+	"Set the System ID of this SMSC\n"
+	"Alphanumeric SMSC System ID\n")
+{
+	struct smsc *smsc = smsc_from_vty(vty);
+
+	if (strlen(argv[0])+1 > sizeof(smsc->system_id))
+		return CMD_WARNING;
+
+	strcpy(smsc->system_id, argv[0]);
+
+	return CMD_SUCCESS;
+}
+
+DEFUN(cfg_smpp_policy, cfg_smpp_policy_cmd,
+	"policy (accept-all|closed)",
+	"Set the authentication policy of this SMSC\n"
+	"Accept all SMPP connections independeint of system ID / passwd\n"
+	"Accept only SMPP connections from ESMEs explicitly configured")
+{
+	struct smsc *smsc = smsc_from_vty(vty);
+
+	if (!strcmp(argv[0], "accept-all"))
+		smsc->accept_all = 1;
+	else
+		smsc->accept_all = 0;
+
+	return CMD_SUCCESS;
+}
+
+
+static int config_write_smpp(struct vty *vty)
+{
+	struct smsc *smsc = smsc_from_vty(vty);
+
+	vty_out(vty, "smpp%s", VTY_NEWLINE);
+	if (smsc->bind_addr)
+		vty_out(vty, " local-tcp-ip %s %u%s", smsc->bind_addr,
+			smsc->listen_port, VTY_NEWLINE);
+	else
+		vty_out(vty, " local-tcp-port %u%s", smsc->listen_port,
+			VTY_NEWLINE);
+	if (strlen(smsc->system_id) > 0)
+		vty_out(vty, " system-id %s%s", smsc->system_id, VTY_NEWLINE);
+	vty_out(vty, " policy %s%s",
+		smsc->accept_all ? "accept-all" : "closed", VTY_NEWLINE);
+	vty_out(vty, " %ssmpp-first%s",
+		smsc->smpp_first ? "" : "no ", VTY_NEWLINE);
+
+	return CMD_SUCCESS;
+}
+
+DEFUN(cfg_esme, cfg_esme_cmd,
+	"esme NAME",
+	"Configure a particular ESME\n"
+	"Alphanumeric System ID of the ESME to be configured\n")
+{
+	struct smsc *smsc = smsc_from_vty(vty);
+	struct osmo_smpp_acl *acl;
+	const char *id = argv[0];
+
+	if (strlen(id) > 16) {
+		vty_out(vty, "%% System ID cannot be more than 16 "
+			"characters long%s", VTY_NEWLINE);
+		return CMD_WARNING;
+	}
+	acl = smpp_acl_by_system_id(smsc, id);
+	if (!acl) {
+		acl = smpp_acl_alloc(smsc, id);
+		if (!acl)
+			return CMD_WARNING;
+	}
+
+	vty->index = acl;
+	vty->index_sub = &acl->description;
+	vty->node = SMPP_ESME_NODE;
+
+	return CMD_SUCCESS;
+}
+
+DEFUN(cfg_no_esme, cfg_no_esme_cmd,
+	"no esme NAME",
+	NO_STR "Remove ESME configuration\n"
+	"Alphanumeric System ID of the ESME to be removed\n")
+{
+	struct smsc *smsc = smsc_from_vty(vty);
+	struct osmo_smpp_acl *acl;
+	const char *id = argv[0];
+
+	acl = smpp_acl_by_system_id(smsc, id);
+	if (!acl) {
+		vty_out(vty, "%% ESME with system id '%s' unknown%s",
+			id, VTY_NEWLINE);
+		return CMD_WARNING;
+	}
+
+	/* FIXME: close the connection, free data structure, etc. */
+
+	smpp_acl_delete(acl);
+
+	return CMD_SUCCESS;
+}
+
+
+DEFUN(cfg_esme_passwd, cfg_esme_passwd_cmd,
+	"password PASSWORD",
+	"Set the password for this ESME\n"
+	"Alphanumeric password string\n")
+{
+	struct osmo_smpp_acl *acl = vty->index;
+
+	if (strlen(argv[0])+1 > sizeof(acl->passwd))
+		return CMD_WARNING;
+
+	strcpy(acl->passwd, argv[0]);
+
+	return CMD_SUCCESS;
+}
+
+DEFUN(cfg_esme_no_passwd, cfg_esme_no_passwd_cmd,
+	"no password",
+	NO_STR "Remove the password for this ESME\n")
+{
+	struct osmo_smpp_acl *acl = vty->index;
+
+	memset(acl->passwd, 0, sizeof(acl->passwd));
+
+	return CMD_SUCCESS;
+}
+
+static int osmo_is_digits(const char *str)
+{
+	int i;
+	for (i = 0; i < strlen(str); i++) {
+		if (!isdigit(str[i]))
+			return 0;
+	}
+	return 1;
+}
+
+static const struct value_string route_errstr[] = {
+	{ -EEXIST,	"Route already exists" },
+	{ -ENODEV,	"Route does not exist" },
+	{ -ENOMEM,	"No memory" },
+	{ -EINVAL,	"Invalid" },
+	{ 0, NULL }
+};
+
+static const struct value_string smpp_ton_str_short[] = {
+	{ TON_Unknown,		"unknown" },
+	{ TON_International,	"international" },
+	{ TON_National,		"national" },
+	{ TON_Network_Specific,	"network" },
+	{ TON_Subscriber_Number,"subscriber" },
+	{ TON_Alphanumeric,	"alpha" },
+	{ TON_Abbreviated,	"abbrev" },
+	{ 0, NULL }
+};
+
+static const struct value_string smpp_npi_str_short[] = {
+	{ NPI_Unknown,		"unknown" },
+	{ NPI_ISDN_E163_E164,	"isdn" },
+	{ NPI_Data_X121,	"x121" },
+	{ NPI_Telex_F69,	"f69" },
+	{ NPI_Land_Mobile_E212,	"e212" },
+	{ NPI_National,		"national" },
+	{ NPI_Private,		"private" },
+	{ NPI_ERMES,		"ermes" },
+	{ NPI_Internet_IP,	"ip" },
+	{ NPI_WAP_Client_Id,	"wap" },
+	{ 0, NULL }
+};
+
+
+#define SMPP_ROUTE_STR "Configure a route for MO-SMS to be sent to this ESME\n"
+#define SMPP_ROUTE_P_STR SMPP_ROUTE_STR "Prefix-match route\n"
+#define SMPP_PREFIX_STR "Destination number prefix\n"
+
+#define TON_CMD "(unknown|international|national|network|subscriber|alpha|abbrev)"
+#define NPI_CMD "(unknown|isdn|x121|f69|e212|national|private|ermes|ip|wap)"
+#define TON_STR "Unknown type-of-number\n"		\
+		"International type-of-number\n"	\
+		"National type-of-number\n"		\
+		"Network specific type-of-number\n"	\
+		"Subscriber type-of-number\n"		\
+		"Alphanumeric type-of-number\n"		\
+		"Abbreviated type-of-number\n"
+#define NPI_STR "Unknown numbering plan\n"		\
+		"ISDN (E.164) numbering plan\n"		\
+		"X.121 numbering plan\n"		\
+		"F.69 numbering plan\n"			\
+		"E.212 numbering plan\n"		\
+		"National numbering plan\n"		\
+		"Private numbering plan\n"		\
+		"ERMES numbering plan\n"		\
+		"IP numbering plan\n"			\
+		"WAP numbeing plan\n"
+
+DEFUN(cfg_esme_route_pfx, cfg_esme_route_pfx_cmd,
+	"route prefix " TON_CMD " " NPI_CMD " PREFIX",
+	SMPP_ROUTE_P_STR TON_STR NPI_STR SMPP_PREFIX_STR)
+{
+	struct osmo_smpp_acl *acl = vty->index;
+	struct osmo_smpp_addr pfx;
+	int rc;
+
+	/* check if DESTINATION is all-digits */
+	if (!osmo_is_digits(argv[2])) {
+		vty_out(vty, "%% PREFIX has to be numeric%s", VTY_NEWLINE);
+		return CMD_WARNING;
+	}
+
+	pfx.ton = get_string_value(smpp_ton_str_short, argv[0]);
+	pfx.npi = get_string_value(smpp_npi_str_short, argv[1]);
+	snprintf(pfx.addr, sizeof(pfx.addr), "%s", argv[2]);
+
+	rc = smpp_route_pfx_add(acl, &pfx);
+	if (rc < 0) {
+		vty_out(vty, "%% error adding prefix route: %s%s",
+			get_value_string(route_errstr, rc), VTY_NEWLINE);
+		return CMD_WARNING;
+	}
+
+	return CMD_SUCCESS;
+}
+
+DEFUN(cfg_esme_no_route_pfx, cfg_esme_no_route_pfx_cmd,
+	"no route prefix " TON_CMD " " NPI_CMD " PREFIX",
+	NO_STR SMPP_ROUTE_P_STR TON_STR NPI_STR SMPP_PREFIX_STR)
+{
+	struct osmo_smpp_acl *acl = vty->index;
+	struct osmo_smpp_addr pfx;
+	int rc;
+
+	/* check if DESTINATION is all-digits */
+	if (!osmo_is_digits(argv[2])) {
+		vty_out(vty, "%% PREFIX has to be numeric%s", VTY_NEWLINE);
+		return CMD_WARNING;
+	}
+
+	pfx.ton = get_string_value(smpp_ton_str_short, argv[0]);
+	pfx.npi = get_string_value(smpp_npi_str_short, argv[1]);
+	snprintf(pfx.addr, sizeof(pfx.addr), "%s", argv[2]);
+
+	rc = smpp_route_pfx_del(acl, &pfx);
+	if (rc < 0) {
+		vty_out(vty, "%% error removing prefix route: %s%s",
+			get_value_string(route_errstr, rc), VTY_NEWLINE);
+		return CMD_WARNING;
+	}
+
+	return CMD_SUCCESS;
+
+}
+
+
+DEFUN(cfg_esme_defaultroute, cfg_esme_defaultroute_cmd,
+	"default-route",
+	"Set this ESME as default-route for all SMS to unknown destinations")
+{
+	struct osmo_smpp_acl *acl = vty->index;
+
+	acl->default_route = 1;
+
+	if (!acl->smsc->def_route)
+		acl->smsc->def_route = acl;
+
+	return CMD_SUCCESS;
+}
+
+DEFUN(cfg_no_esme_defaultroute, cfg_esme_no_defaultroute_cmd,
+	"no default-route", NO_STR
+	"Remove this ESME as default-route for all SMS to unknown destinations")
+{
+	struct osmo_smpp_acl *acl = vty->index;
+
+	acl->default_route = 0;
+
+	/* remove currently active default route, if it was created by
+	 * this ACL */
+	if (acl->smsc->def_route && acl->smsc->def_route == acl)
+		acl->smsc->def_route = NULL;
+
+	return CMD_SUCCESS;
+}
+
+DEFUN(cfg_esme_del_src_imsi, cfg_esme_del_src_imsi_cmd,
+	"deliver-src-imsi",
+	"Enable the use of IMSI as source address in DELIVER")
+{
+	struct osmo_smpp_acl *acl = vty->index;
+
+	acl->deliver_src_imsi = 1;
+
+	return CMD_SUCCESS;
+}
+
+DEFUN(cfg_esme_no_del_src_imsi, cfg_esme_no_del_src_imsi_cmd,
+	"no deliver-src-imsi", NO_STR
+	"Disable the use of IMSI as source address in DELIVER")
+{
+	struct osmo_smpp_acl *acl = vty->index;
+
+	acl->deliver_src_imsi = 0;
+
+	return CMD_SUCCESS;
+}
+
+DEFUN(cfg_esme_osmo_ext, cfg_esme_osmo_ext_cmd,
+	"osmocom-extensions",
+	"Enable the use of Osmocom SMPP Extensions for this ESME")
+{
+	struct osmo_smpp_acl *acl = vty->index;
+
+	acl->osmocom_ext = 1;
+
+	return CMD_SUCCESS;
+}
+
+DEFUN(cfg_esme_no_osmo_ext, cfg_esme_no_osmo_ext_cmd,
+	"no osmocom-extensions", NO_STR
+	"Disable the use of Osmocom SMPP Extensions for this ESME")
+{
+	struct osmo_smpp_acl *acl = vty->index;
+
+	acl->osmocom_ext = 0;
+
+	return CMD_SUCCESS;
+}
+
+DEFUN(cfg_esme_dcs_transp, cfg_esme_dcs_transp_cmd,
+	"dcs-transparent",
+	"Enable the transparent pass-through of TP-DCS to SMPP DataCoding")
+{
+	struct osmo_smpp_acl *acl = vty->index;
+
+	acl->dcs_transparent = 1;
+
+	return CMD_SUCCESS;
+}
+
+DEFUN(cfg_esme_no_dcs_transp, cfg_esme_no_dcs_transp_cmd,
+	"no dcs-transparent", NO_STR
+	"Disable the transparent pass-through of TP-DCS to SMPP DataCoding")
+{
+	struct osmo_smpp_acl *acl = vty->index;
+
+	acl->dcs_transparent = 0;
+
+	return CMD_SUCCESS;
+}
+
+
+static void dump_one_esme(struct vty *vty, struct osmo_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->smpp_version, VTY_NEWLINE);
+	vty_out(vty, "  Connected from: %s:%s%s", host, serv, VTY_NEWLINE);
+	if (esme->smsc->def_route == esme->acl)
+		vty_out(vty, "  Is current default route%s", VTY_NEWLINE);
+}
+
+DEFUN(show_esme, show_esme_cmd,
+	"show smpp esme",
+	SHOW_STR "SMPP Interface\n" "SMPP Extrenal SMS Entity\n")
+{
+	struct smsc *smsc = smsc_from_vty(vty);
+	struct osmo_esme *esme;
+
+	llist_for_each_entry(esme, &smsc->esme_list, list)
+		dump_one_esme(vty, esme);
+
+	return CMD_SUCCESS;
+}
+
+static void write_esme_route_single(struct vty *vty, struct osmo_smpp_route *r)
+{
+	switch (r->type) {
+	case SMPP_ROUTE_PREFIX:
+		vty_out(vty, "   route prefix %s ",
+			get_value_string(smpp_ton_str_short, r->u.prefix.ton));
+		vty_out(vty, "%s %s%s",
+			get_value_string(smpp_npi_str_short, r->u.prefix.npi),
+			r->u.prefix.addr, VTY_NEWLINE);
+		break;
+	case SMPP_ROUTE_NONE:
+		break;
+	}
+}
+
+static void config_write_esme_single(struct vty *vty, struct osmo_smpp_acl *acl)
+{
+	struct osmo_smpp_route *r;
+
+	vty_out(vty, " esme %s%s", acl->system_id, VTY_NEWLINE);
+	if (strlen(acl->passwd))
+		vty_out(vty, "  password %s%s", acl->passwd, VTY_NEWLINE);
+	if (acl->default_route)
+		vty_out(vty, "  default-route%s", VTY_NEWLINE);
+	if (acl->deliver_src_imsi)
+		vty_out(vty, "  deliver-src-imsi%s", VTY_NEWLINE);
+	if (acl->osmocom_ext)
+		vty_out(vty, "  osmocom-extensions%s", VTY_NEWLINE);
+	if (acl->dcs_transparent)
+		vty_out(vty, "  dcs-transparent%s", VTY_NEWLINE);
+
+	llist_for_each_entry(r, &acl->route_list, list)
+		write_esme_route_single(vty, r);
+}
+
+static int config_write_esme(struct vty *v)
+{
+	struct smsc *smsc = smsc_from_vty(v);
+	struct osmo_smpp_acl *acl;
+
+	llist_for_each_entry(acl, &smsc->acl_list, list)
+		config_write_esme_single(v, acl);
+
+	return CMD_SUCCESS;
+}
+
+int smpp_vty_init(void)
+{
+	install_node(&smpp_node, config_write_smpp);
+	install_element(CONFIG_NODE, &cfg_smpp_cmd);
+
+	install_element(SMPP_NODE, &cfg_smpp_first_cmd);
+	install_element(SMPP_NODE, &cfg_no_smpp_first_cmd);
+	install_element(SMPP_NODE, &cfg_smpp_port_cmd);
+	install_element(SMPP_NODE, &cfg_smpp_addr_port_cmd);
+	install_element(SMPP_NODE, &cfg_smpp_sys_id_cmd);
+	install_element(SMPP_NODE, &cfg_smpp_policy_cmd);
+	install_element(SMPP_NODE, &cfg_esme_cmd);
+	install_element(SMPP_NODE, &cfg_no_esme_cmd);
+
+	install_node(&esme_node, config_write_esme);
+	install_element(SMPP_ESME_NODE, &cfg_esme_passwd_cmd);
+	install_element(SMPP_ESME_NODE, &cfg_esme_no_passwd_cmd);
+	install_element(SMPP_ESME_NODE, &cfg_esme_route_pfx_cmd);
+	install_element(SMPP_ESME_NODE, &cfg_esme_no_route_pfx_cmd);
+	install_element(SMPP_ESME_NODE, &cfg_esme_defaultroute_cmd);
+	install_element(SMPP_ESME_NODE, &cfg_esme_no_defaultroute_cmd);
+	install_element(SMPP_ESME_NODE, &cfg_esme_del_src_imsi_cmd);
+	install_element(SMPP_ESME_NODE, &cfg_esme_no_del_src_imsi_cmd);
+	install_element(SMPP_ESME_NODE, &cfg_esme_osmo_ext_cmd);
+	install_element(SMPP_ESME_NODE, &cfg_esme_no_osmo_ext_cmd);
+	install_element(SMPP_ESME_NODE, &cfg_esme_dcs_transp_cmd);
+	install_element(SMPP_ESME_NODE, &cfg_esme_no_dcs_transp_cmd);
+
+	install_element_ve(&show_esme_cmd);
+
+	return 0;
+}
diff --git a/src/libmsc/sms_queue.c b/src/libmsc/sms_queue.c
new file mode 100644
index 0000000..252e529
--- /dev/null
+++ b/src/libmsc/sms_queue.c
@@ -0,0 +1,578 @@
+/* SMS queue to continously attempt to deliver SMS */
+/*
+ * (C) 2010 by Holger Hans Peter Freyther <zecke@selfish.org>
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/**
+ * The difficulty of such a queue is to send a lot of SMS without
+ * overloading the paging subsystem and the database and other users
+ * of the MSC. To make the best use we would need to know the number
+ * of pending paging requests, then throttle the number of SMS we
+ * want to send and such.
+ * We will start with a very simple SMS Queue and then try to speed
+ * things up by collecting data from other parts of the system.
+ */
+
+#include <limits.h>
+
+#include <osmocom/msc/sms_queue.h>
+#include <osmocom/msc/db.h>
+#include <osmocom/msc/debug.h>
+#include <osmocom/msc/gsm_data.h>
+#include <osmocom/msc/gsm_04_11.h>
+#include <osmocom/msc/gsm_subscriber.h>
+#include <osmocom/msc/signal.h>
+#include <osmocom/msc/vlr.h>
+
+#include <osmocom/core/talloc.h>
+
+#include <osmocom/vty/vty.h>
+
+/*
+ * One pending SMS that we wait for.
+ */
+struct gsm_sms_pending {
+	struct llist_head entry;
+
+	struct vlr_subscr *vsub;
+	unsigned long long sms_id;
+	int failed_attempts;
+	int resend;
+};
+
+struct gsm_sms_queue {
+	struct osmo_timer_list resend_pending;
+	struct osmo_timer_list push_queue;
+	struct gsm_network *network;
+	int max_fail;
+	int max_pending;
+	int pending;
+
+	struct llist_head pending_sms;
+
+	char last_msisdn[GSM_EXTENSION_LENGTH+1];
+};
+
+static int sms_subscr_cb(unsigned int, unsigned int, void *, void *);
+static int sms_sms_cb(unsigned int, unsigned int, void *, void *);
+
+static struct gsm_sms_pending *sms_find_pending(struct gsm_sms_queue *smsq,
+						unsigned long long sms_id)
+{
+	struct gsm_sms_pending *pending;
+
+	llist_for_each_entry(pending, &smsq->pending_sms, entry) {
+		if (pending->sms_id == sms_id)
+			return pending;
+	}
+
+	return NULL;
+}
+
+int sms_queue_sms_is_pending(struct gsm_sms_queue *smsq, unsigned long long sms_id)
+{
+	return sms_find_pending(smsq, sms_id) != NULL;
+}
+
+static struct gsm_sms_pending *sms_subscriber_find_pending(
+					struct gsm_sms_queue *smsq,
+					struct vlr_subscr *vsub)
+{
+	struct gsm_sms_pending *pending;
+
+	llist_for_each_entry(pending, &smsq->pending_sms, entry) {
+		if (pending->vsub == vsub)
+			return pending;
+	}
+
+	return NULL;
+}
+
+static int sms_subscriber_is_pending(struct gsm_sms_queue *smsq,
+				     struct vlr_subscr *vsub)
+{
+	return sms_subscriber_find_pending(smsq, vsub) != NULL;
+}
+
+static struct gsm_sms_pending *sms_pending_from(struct gsm_sms_queue *smsq,
+						struct gsm_sms *sms)
+{
+	struct gsm_sms_pending *pending;
+
+	pending = talloc_zero(smsq, struct gsm_sms_pending);
+	if (!pending)
+		return NULL;
+
+	pending->vsub = vlr_subscr_get(sms->receiver);
+	pending->sms_id = sms->id;
+	return pending;
+}
+
+static void sms_pending_free(struct gsm_sms_pending *pending)
+{
+	vlr_subscr_put(pending->vsub);
+	llist_del(&pending->entry);
+	talloc_free(pending);
+}
+
+static void sms_pending_resend(struct gsm_sms_pending *pending)
+{
+	struct gsm_network *net = pending->vsub->vlr->user_ctx;
+	struct gsm_sms_queue *smsq;
+	LOGP(DLSMS, LOGL_DEBUG,
+	     "Scheduling resend of SMS %llu.\n", pending->sms_id);
+
+	pending->resend = 1;
+
+	smsq = net->sms_queue;
+	if (osmo_timer_pending(&smsq->resend_pending))
+		return;
+
+	osmo_timer_schedule(&smsq->resend_pending, 1, 0);
+}
+
+static void sms_pending_failed(struct gsm_sms_pending *pending, int paging_error)
+{
+	struct gsm_network *net = pending->vsub->vlr->user_ctx;
+	struct gsm_sms_queue *smsq;
+
+	LOGP(DLSMS, LOGL_NOTICE, "Sending SMS %llu failed %d times.\n",
+	     pending->sms_id, pending->failed_attempts);
+
+	smsq = net->sms_queue;
+	if (++pending->failed_attempts < smsq->max_fail)
+		return sms_pending_resend(pending);
+
+	sms_pending_free(pending);
+	smsq->pending -= 1;
+	sms_queue_trigger(smsq);
+}
+
+/*
+ * Resend all SMS that are scheduled for a resend. This is done to
+ * avoid an immediate failure.
+ */
+static void sms_resend_pending(void *_data)
+{
+	struct gsm_sms_pending *pending, *tmp;
+	struct gsm_sms_queue *smsq = _data;
+
+	llist_for_each_entry_safe(pending, tmp, &smsq->pending_sms, entry) {
+		struct gsm_sms *sms;
+		if (!pending->resend)
+			continue;
+
+		sms = db_sms_get(smsq->network, pending->sms_id);
+
+		/* the sms is gone? Move to the next */
+		if (!sms) {
+			sms_pending_free(pending);
+			smsq->pending -= 1;
+			sms_queue_trigger(smsq);
+		} else {
+			pending->resend = 0;
+			gsm411_send_sms_subscr(sms->receiver, sms);
+		}
+	}
+}
+
+/* Find the next pending SMS by cycling through the recipients. We could also
+ * cycle through the pending SMS, but that might cause us to keep trying to
+ * send SMS to the same few subscribers repeatedly while not servicing other
+ * subscribers for a long time. By walking the list of recipient MSISDNs, we
+ * ensure that all subscribers get their fair time to receive SMS. */
+struct gsm_sms *smsq_take_next_sms(struct gsm_network *net,
+				   char *last_msisdn,
+				   size_t last_msisdn_buflen)
+{
+	struct gsm_sms *sms;
+	int wrapped = 0;
+	int sanity = 100;
+	char started_with_msisdn[last_msisdn_buflen];
+
+	OSMO_STRLCPY_ARRAY(started_with_msisdn, last_msisdn);
+
+	while (wrapped < 2 && (--sanity)) {
+		/* If we wrapped around and passed the first msisdn, we're
+		 * through the entire SMS DB; end it. */
+		if (wrapped && strcmp(last_msisdn, started_with_msisdn) >= 0)
+			break;
+
+		sms = db_sms_get_next_unsent_rr_msisdn(net, last_msisdn, 9);
+		if (!sms) {
+			last_msisdn[0] = '\0';
+			wrapped++;
+			continue;
+		}
+
+		/* Whatever happens, next time around service another recipient
+		 */
+		osmo_strlcpy(last_msisdn, sms->dst.addr, last_msisdn_buflen);
+
+		/* Is the subscriber attached? If not, go to next SMS */
+		if (!sms->receiver || !sms->receiver->lu_complete)
+			continue;
+
+		return sms;
+	}
+
+	DEBUGP(DLSMS, "SMS queue: no SMS to be sent\n");
+	return NULL;
+}
+
+/**
+ * I will submit up to max_pending - pending SMS to the
+ * subsystem.
+ */
+static void sms_submit_pending(void *_data)
+{
+	struct gsm_sms_queue *smsq = _data;
+	int attempts = smsq->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);
+
+	do {
+		struct gsm_sms_pending *pending;
+		struct gsm_sms *sms;
+
+
+		sms = smsq_take_next_sms(smsq->network, smsq->last_msisdn,
+					 sizeof(smsq->last_msisdn));
+		if (!sms) {
+			LOGP(DLSMS, LOGL_DEBUG, "Sending SMS done (%d attempted)\n",
+			     attempted);
+			break;
+		}
+
+		rounds += 1;
+		LOGP(DLSMS, LOGL_DEBUG, "Sending SMS round %d\n", rounds);
+
+		/*
+		 * This code needs to detect a loop. It assumes that no SMS
+		 * will vanish during the time this is executed. We will remember
+		 * the id of the first GSM subscriber we see and then will
+		 * compare this. The Database code should make sure that we will
+		 * see all other subscribers first before seeing this one again.
+		 *
+		 * It is always scary to have an infinite loop like this.
+		 */
+		if (!initialized) {
+			first_sub = sms->receiver->id;
+			initialized = 1;
+		} else if (first_sub == sms->receiver->id) {
+			LOGP(DLSMS, LOGL_DEBUG, "Sending SMS done (loop) (%d attempted)\n",
+			     attempted);
+			sms_free(sms);
+			break;
+		}
+
+		/* no need to send a pending sms */
+		if (sms_queue_sms_is_pending(smsq, sms->id)) {
+			LOGP(DLSMS, LOGL_DEBUG,
+			     "SMSqueue with pending sms: %llu. Skipping\n", sms->id);
+			sms_free(sms);
+			continue;
+		}
+
+		/* no need to send a SMS with the same receiver */
+		if (sms_subscriber_is_pending(smsq, sms->receiver)) {
+			LOGP(DLSMS, LOGL_DEBUG,
+			     "SMSqueue with pending sub: %llu. Skipping\n", sms->receiver->id);
+			sms_free(sms);
+			continue;
+		}
+
+		pending = sms_pending_from(smsq, sms);
+		if (!pending) {
+			LOGP(DLSMS, LOGL_ERROR,
+			     "Failed to create pending SMS entry.\n");
+			sms_free(sms);
+			continue;
+		}
+
+		attempted += 1;
+		smsq->pending += 1;
+		llist_add_tail(&pending->entry, &smsq->pending_sms);
+		gsm411_send_sms_subscr(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
+ */
+static void sms_send_next(struct vlr_subscr *vsub)
+{
+	struct gsm_network *net = vsub->vlr->user_ctx;
+	struct gsm_sms_queue *smsq = net->sms_queue;
+	struct gsm_sms_pending *pending;
+	struct gsm_sms *sms;
+
+	/* the subscriber should not be in the queue */
+	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);
+	if (!sms)
+		goto no_pending_sms;
+
+	/* The sms should not be scheduled right now */
+	OSMO_ASSERT(!sms_queue_sms_is_pending(smsq, sms->id));
+
+	/* Remember that we deliver this SMS and send it */
+	pending = sms_pending_from(smsq, sms);
+	if (!pending) {
+		LOGP(DLSMS, LOGL_ERROR,
+			"Failed to create pending SMS entry.\n");
+		sms_free(sms);
+		goto no_pending_sms;
+	}
+
+	smsq->pending += 1;
+	llist_add_tail(&pending->entry, &smsq->pending_sms);
+	gsm411_send_sms_subscr(sms->receiver, sms);
+	return;
+
+no_pending_sms:
+	/* Try to send the SMS to avoid the queue being stuck */
+	sms_submit_pending(net->sms_queue);
+}
+
+/*
+ * Kick off the queue again.
+ */
+int sms_queue_trigger(struct gsm_sms_queue *smsq)
+{
+	LOGP(DLSMS, LOGL_DEBUG, "Triggering SMS queue\n");
+	if (osmo_timer_pending(&smsq->push_queue))
+		return 0;
+
+	osmo_timer_schedule(&smsq->push_queue, 1, 0);
+	return 0;
+}
+
+int sms_queue_start(struct gsm_network *network, int max_pending)
+{
+	struct gsm_sms_queue *sms = talloc_zero(network, struct gsm_sms_queue);
+	if (!sms) {
+		LOGP(DMSC, LOGL_ERROR, "Failed to create the SMS queue.\n");
+		return -1;
+	}
+
+	osmo_signal_register_handler(SS_SUBSCR, sms_subscr_cb, network);
+	osmo_signal_register_handler(SS_SMS, sms_sms_cb, network);
+
+	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);
+
+	sms_submit_pending(sms);
+
+	return 0;
+}
+
+static int sub_ready_for_sm(struct gsm_network *net, struct vlr_subscr *vsub)
+{
+	struct gsm_sms *sms;
+	struct gsm_sms_pending *pending;
+	struct gsm_subscriber_connection *conn;
+
+	/*
+	 * The code used to be very clever and tried to submit
+	 * a SMS during the Location Updating Request. This has
+	 * two issues:
+	 *   1.) The Phone might not be ready yet, e.g. the C155
+	 *       will not respond to the Submit when it is booting.
+	 *   2.) The queue is already trying to submit SMS to the
+	 *	 user and by not responding to the paging request
+	 *	 we will set the LAC back to 0. We would have to
+	 *	 stop the paging and move things over.
+	 *
+	 * We need to be careful in what we try here.
+	 */
+
+	/* check if we have pending requests */
+	pending = sms_subscriber_find_pending(net->sms_queue, vsub);
+	if (pending) {
+		LOGP(DMSC, LOGL_NOTICE,
+		     "Pending paging while subscriber %llu attached.\n",
+		      vsub->id);
+		return 0;
+	}
+
+	conn = connection_for_subscr(vsub);
+	if (!conn)
+		return -1;
+
+	/* Now try to deliver any pending SMS to this sub */
+	sms = db_sms_get_unsent_for_subscr(vsub, UINT_MAX);
+	if (!sms)
+		return -1;
+	gsm411_send_sms(conn, sms);
+	return 0;
+}
+
+static int sms_subscr_cb(unsigned int subsys, unsigned int signal,
+			 void *handler_data, void *signal_data)
+{
+	struct vlr_subscr *vsub = signal_data;
+
+	if (signal != S_SUBSCR_ATTACHED)
+		return 0;
+
+	/* this is readyForSM */
+	return sub_ready_for_sm(handler_data, vsub);
+}
+
+static int sms_sms_cb(unsigned int subsys, unsigned int signal,
+		      void *handler_data, void *signal_data)
+{
+	struct gsm_network *network = handler_data;
+	struct sms_signal_data *sig_sms = signal_data;
+	struct gsm_sms_pending *pending;
+	struct vlr_subscr *vsub;
+
+	/* 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);
+		return 0;
+	}
+
+	if (!sig_sms->sms)
+		return -1;
+
+
+	/*
+	 * Find the entry of our queue. The SMS subsystem will submit
+	 * 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);
+	if (!pending)
+		return 0;
+
+	switch (signal) {
+	case S_SMS_DELIVERED:
+		/* Remember the subscriber and clear the pending entry */
+		network->sms_queue->pending -= 1;
+		vsub = vlr_subscr_get(pending->vsub);
+		db_sms_delete_sent_message_by_id(pending->sms_id);
+		sms_pending_free(pending);
+		/* Attempt to send another SMS to this subscriber */
+		sms_send_next(vsub);
+		vlr_subscr_put(vsub);
+		break;
+	case S_SMS_MEM_EXCEEDED:
+		network->sms_queue->pending -= 1;
+		sms_pending_free(pending);
+		sms_queue_trigger(network->sms_queue);
+		break;
+	case S_SMS_UNKNOWN_ERROR:
+		/*
+		 * There can be many reasons for this failure. E.g. the paging
+		 * timed out, the subscriber was not paged at all, or there was
+		 * a protocol error. The current strategy is to try sending the
+		 * next SMS for busy/oom and to retransmit when we have paged.
+		 *
+		 * When the paging expires three times we will disable the
+		 * subscriber. If we have some kind of other transmit error we
+		 * should flag the SMS as bad.
+		 */
+		switch (sig_sms->paging_result) {
+		case 0:
+			/* BAD SMS? */
+			db_sms_inc_deliver_attempts(sig_sms->sms);
+			sms_pending_failed(pending, 0);
+			break;
+		case GSM_PAGING_EXPIRED:
+			sms_pending_failed(pending, 1);
+			break;
+		case GSM_PAGING_BUSY:
+			network->sms_queue->pending -= 1;
+			sms_pending_free(pending);
+			sms_queue_trigger(network->sms_queue);
+			break;
+		default:
+			LOGP(DLSMS, LOGL_ERROR, "Unhandled result: %d\n",
+			     sig_sms->paging_result);
+		}
+		break;
+	default:
+		LOGP(DLSMS, LOGL_ERROR, "Unhandled result: %d\n",
+		     sig_sms->paging_result);
+	}
+
+	/* While here, attempt to remove an expired SMS from the DB. */
+	db_sms_delete_oldest_expired_message();
+
+	return 0;
+}
+
+/* VTY helper functions */
+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);
+
+	llist_for_each_entry(pending, &smsq->pending_sms, entry)
+		vty_out(vty, " SMS Pending for Subscriber: %llu SMS: %llu Failed: %d.%s",
+			pending->vsub->id, pending->sms_id,
+			pending->failed_attempts, VTY_NEWLINE);
+	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;
+
+	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);
+	}
+
+	smsq->pending = 0;
+	return 0;
+}
diff --git a/src/libmsc/subscr_conn.c b/src/libmsc/subscr_conn.c
new file mode 100644
index 0000000..e6fa7e1
--- /dev/null
+++ b/src/libmsc/subscr_conn.c
@@ -0,0 +1,709 @@
+/* MSC subscriber connection implementation */
+
+/*
+ * (C) 2016 by sysmocom s.m.f.c. <info@sysmocom.de>
+ * All Rights Reserved
+ *
+ * Author: Neels Hofmeyr
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <osmocom/core/logging.h>
+#include <osmocom/core/fsm.h>
+#include <osmocom/core/signal.h>
+
+#include <osmocom/msc/osmo_msc.h>
+#include <osmocom/msc/vlr.h>
+#include <osmocom/msc/debug.h>
+#include <osmocom/msc/transaction.h>
+#include <osmocom/msc/signal.h>
+#include <osmocom/msc/a_iface.h>
+#include <osmocom/msc/iucs.h>
+
+#include "../../bscconfig.h"
+#ifdef BUILD_IU
+#include <osmocom/ranap/iu_client.h>
+#else
+#include <osmocom/msc/iu_dummy.h>
+#endif
+
+#define SUBSCR_CONN_TIMEOUT 5 /* seconds */
+
+static const struct value_string subscr_conn_fsm_event_names[] = {
+	OSMO_VALUE_STRING(SUBSCR_CONN_E_INVALID),
+	OSMO_VALUE_STRING(SUBSCR_CONN_E_COMPLETE_LAYER_3),
+	OSMO_VALUE_STRING(SUBSCR_CONN_E_CLASSMARK_UPDATE),
+	OSMO_VALUE_STRING(SUBSCR_CONN_E_ACCEPTED),
+	OSMO_VALUE_STRING(SUBSCR_CONN_E_COMMUNICATING),
+	OSMO_VALUE_STRING(SUBSCR_CONN_E_RELEASE_WHEN_UNUSED),
+	OSMO_VALUE_STRING(SUBSCR_CONN_E_MO_CLOSE),
+	OSMO_VALUE_STRING(SUBSCR_CONN_E_CN_CLOSE),
+	OSMO_VALUE_STRING(SUBSCR_CONN_E_UNUSED),
+	{ 0, NULL }
+};
+
+static void update_counters(struct osmo_fsm_inst *fi, bool conn_accepted)
+{
+	struct gsm_subscriber_connection *conn = fi->priv;
+	switch (conn->complete_layer3_type) {
+	case COMPLETE_LAYER3_LU:
+		rate_ctr_inc(&conn->network->msc_ctrs->ctr[
+				conn_accepted ? MSC_CTR_LOC_UPDATE_COMPLETED
+					      : MSC_CTR_LOC_UPDATE_FAILED]);
+		break;
+	case COMPLETE_LAYER3_CM_SERVICE_REQ:
+		rate_ctr_inc(&conn->network->msc_ctrs->ctr[
+				conn_accepted ? MSC_CTR_CM_SERVICE_REQUEST_ACCEPTED
+					      : MSC_CTR_CM_SERVICE_REQUEST_REJECTED]);
+		break;
+	case COMPLETE_LAYER3_PAGING_RESP:
+		rate_ctr_inc(&conn->network->msc_ctrs->ctr[
+				conn_accepted ? MSC_CTR_PAGING_RESP_ACCEPTED
+					      : MSC_CTR_PAGING_RESP_REJECTED]);
+		break;
+	default:
+		break;
+	}
+}
+
+static void evaluate_acceptance_outcome(struct osmo_fsm_inst *fi, bool conn_accepted)
+{
+	struct gsm_subscriber_connection *conn = fi->priv;
+
+	update_counters(fi, conn_accepted);
+
+	/* Trigger transactions that we paged for */
+	if (conn->complete_layer3_type == COMPLETE_LAYER3_PAGING_RESP) {
+		subscr_paging_dispatch(GSM_HOOK_RR_PAGING,
+				       conn_accepted ? GSM_PAGING_SUCCEEDED : GSM_PAGING_EXPIRED,
+				       NULL, conn, conn->vsub);
+	}
+
+	if (conn->complete_layer3_type == COMPLETE_LAYER3_CM_SERVICE_REQ
+	    && conn_accepted) {
+		conn->received_cm_service_request = true;
+		msc_subscr_conn_get(conn, MSC_CONN_USE_CM_SERVICE);
+	}
+
+	if (conn_accepted)
+		osmo_signal_dispatch(SS_SUBSCR, S_SUBSCR_ATTACHED, conn->vsub);
+}
+
+static void log_close_event(struct osmo_fsm_inst *fi, uint32_t event, void *data)
+{
+	enum gsm48_reject_value *cause = data;
+	/* The close event itself is logged by the FSM. We can only add the cause value, if present. */
+	if (!cause || !*cause)
+		return;
+	LOGPFSML(fi, LOGL_NOTICE, "Close event, cause: %s\n", gsm48_reject_value_name(*cause));
+}
+
+static void subscr_conn_fsm_new(struct osmo_fsm_inst *fi, uint32_t event, void *data)
+{
+	switch (event) {
+	case SUBSCR_CONN_E_COMPLETE_LAYER_3:
+		osmo_fsm_inst_state_chg(fi, SUBSCR_CONN_S_AUTH_CIPH, SUBSCR_CONN_TIMEOUT, 0);
+		return;
+
+	case SUBSCR_CONN_E_ACCEPTED:
+		evaluate_acceptance_outcome(fi, true);
+		osmo_fsm_inst_state_chg(fi, SUBSCR_CONN_S_ACCEPTED, SUBSCR_CONN_TIMEOUT, 0);
+		return;
+
+	case SUBSCR_CONN_E_MO_CLOSE:
+	case SUBSCR_CONN_E_CN_CLOSE:
+		log_close_event(fi, event, data);
+		evaluate_acceptance_outcome(fi, false);
+		/* fall through */
+	case SUBSCR_CONN_E_UNUSED:
+		osmo_fsm_inst_state_chg(fi, SUBSCR_CONN_S_RELEASING, SUBSCR_CONN_TIMEOUT, 0);
+		return;
+
+	default:
+		OSMO_ASSERT(false);
+	}
+}
+
+void subscr_conn_fsm_auth_ciph(struct osmo_fsm_inst *fi, uint32_t event, void *data)
+{
+	/* If accepted, transition the state, all other cases mean failure. */
+	switch (event) {
+	case SUBSCR_CONN_E_ACCEPTED:
+		evaluate_acceptance_outcome(fi, true);
+		osmo_fsm_inst_state_chg(fi, SUBSCR_CONN_S_ACCEPTED, SUBSCR_CONN_TIMEOUT, 0);
+		return;
+
+	case SUBSCR_CONN_E_UNUSED:
+		LOGPFSML(fi, LOGL_DEBUG, "Awaiting results for Auth+Ciph, overruling event %s\n",
+			 osmo_fsm_event_name(fi->fsm, event));
+		return;
+
+	case SUBSCR_CONN_E_MO_CLOSE:
+	case SUBSCR_CONN_E_CN_CLOSE:
+		log_close_event(fi, event, data);
+		evaluate_acceptance_outcome(fi, false);
+		osmo_fsm_inst_state_chg(fi, SUBSCR_CONN_S_RELEASING, SUBSCR_CONN_TIMEOUT, 0);
+		return;
+
+
+	default:
+		OSMO_ASSERT(false);
+	}
+}
+
+int msc_classmark_request_then_cipher_mode_cmd(struct gsm_subscriber_connection *conn, bool umts_aka,
+					       bool retrieve_imeisv)
+{
+	int rc;
+	conn->geran_set_cipher_mode.umts_aka = umts_aka;
+	conn->geran_set_cipher_mode.retrieve_imeisv = retrieve_imeisv;
+
+	rc = a_iface_tx_classmark_request(conn);
+	if (rc) {
+		LOGP(DMM, LOGL_ERROR, "%s: cannot send BSSMAP Classmark Request\n",
+		     vlr_subscr_name(conn->vsub));
+		return -EIO;
+	}
+
+	osmo_fsm_inst_state_chg(conn->fi, SUBSCR_CONN_S_WAIT_CLASSMARK_UPDATE, SUBSCR_CONN_TIMEOUT, 0);
+	return 0;
+}
+
+static void subscr_conn_fsm_wait_classmark_update(struct osmo_fsm_inst *fi, uint32_t event, void *data)
+{
+	struct gsm_subscriber_connection *conn = fi->priv;
+	switch (event) {
+	case SUBSCR_CONN_E_CLASSMARK_UPDATE:
+		/* Theoretically, this event can be used for requesting Classmark in various situations.
+		 * So far though, the only time we send a Classmark Request is during Ciphering. As soon
+		 * as more such situations arise, we need to add state to indicate what action should
+		 * follow after a Classmark Update is received (e.g.
+		 * msc_classmark_request_then_cipher_mode_cmd() sets an enum value to indicate that
+		 * Ciphering should continue afterwards). But right now, it is accurate to always
+		 * continue with Ciphering: */
+
+		/* During Ciphering, we needed Classmark information. The Classmark Update has come in,
+		 * go back into the Set Ciphering Command procedure. */
+		osmo_fsm_inst_state_chg(fi, SUBSCR_CONN_S_AUTH_CIPH, SUBSCR_CONN_TIMEOUT, 0);
+		if (msc_geran_set_cipher_mode(conn, conn->geran_set_cipher_mode.umts_aka,
+					      conn->geran_set_cipher_mode.retrieve_imeisv)) {
+			LOGPFSML(fi, LOGL_ERROR,
+				 "Sending Cipher Mode Command failed, aborting attach\n");
+			vlr_subscr_cancel_attach_fsm(conn->vsub, OSMO_FSM_TERM_ERROR,
+						     GSM48_REJECT_NETWORK_FAILURE);
+		}
+		return;
+
+	case SUBSCR_CONN_E_UNUSED:
+		LOGPFSML(fi, LOGL_DEBUG, "Awaiting results for Auth+Ciph, overruling event %s\n",
+			 osmo_fsm_event_name(fi->fsm, event));
+		return;
+
+	case SUBSCR_CONN_E_MO_CLOSE:
+	case SUBSCR_CONN_E_CN_CLOSE:
+		log_close_event(fi, event, data);
+		evaluate_acceptance_outcome(fi, false);
+		osmo_fsm_inst_state_chg(fi, SUBSCR_CONN_S_RELEASING, SUBSCR_CONN_TIMEOUT, 0);
+		return;
+
+	default:
+		OSMO_ASSERT(false);
+	}
+}
+
+static bool subscr_conn_fsm_has_active_transactions(struct osmo_fsm_inst *fi)
+{
+	struct gsm_subscriber_connection *conn = fi->priv;
+	struct gsm_trans *trans;
+
+	if (conn->silent_call) {
+		LOGPFSML(fi, LOGL_DEBUG, "%s: silent call still active\n", __func__);
+		return true;
+	}
+
+	if (conn->received_cm_service_request) {
+		LOGPFSML(fi, LOGL_DEBUG, "%s: still awaiting first request after a CM Service Request\n",
+			 __func__);
+		return true;
+	}
+
+	if (conn->vsub && !llist_empty(&conn->vsub->cs.requests)) {
+		struct subscr_request *sr;
+		if (!log_check_level(fi->fsm->log_subsys, LOGL_DEBUG)) {
+			llist_for_each_entry(sr, &conn->vsub->cs.requests, entry) {
+				LOGPFSML(fi, LOGL_DEBUG, "%s: still active: %s\n",
+					 __func__, sr->label);
+			}
+		}
+		return true;
+	}
+
+	if ((trans = trans_has_conn(conn))) {
+		LOGPFSML(fi, LOGL_DEBUG,
+			 "%s: connection still has active transaction: %s\n",
+			 __func__, gsm48_pdisc_name(trans->protocol));
+		return true;
+	}
+
+	return false;
+}
+
+static void subscr_conn_fsm_accepted_enter(struct osmo_fsm_inst *fi, uint32_t prev_state)
+{
+	struct gsm_subscriber_connection *conn = fi->priv;
+
+	/* Stop Location Update expiry for this subscriber. While the subscriber
+	 * has an open connection the LU expiry timer must remain disabled.
+	 * Otherwise we would kick the subscriber off the network when the timer
+	 * expires e.g. during a long phone call.
+	 * The LU expiry timer will restart once the connection is closed. */
+	conn->vsub->expire_lu = VLR_SUBSCRIBER_NO_EXPIRATION;
+
+	if (!subscr_conn_fsm_has_active_transactions(fi))
+		osmo_fsm_inst_dispatch(fi, SUBSCR_CONN_E_UNUSED, NULL);
+}
+
+static void subscr_conn_fsm_accepted(struct osmo_fsm_inst *fi, uint32_t event, void *data)
+{
+	switch (event) {
+	case SUBSCR_CONN_E_COMPLETE_LAYER_3:
+		/* When Authentication is off, we may already be in the Accepted state when the code
+		 * evaluates the Compl L3. Simply ignore. This just cosmetically mutes the error log
+		 * about the useless event. */
+		return;
+
+	case SUBSCR_CONN_E_COMMUNICATING:
+		osmo_fsm_inst_state_chg(fi, SUBSCR_CONN_S_COMMUNICATING, 0, 0);
+		return;
+
+	case SUBSCR_CONN_E_MO_CLOSE:
+	case SUBSCR_CONN_E_CN_CLOSE:
+		log_close_event(fi, event, data);
+		/* fall through */
+	case SUBSCR_CONN_E_UNUSED:
+		osmo_fsm_inst_state_chg(fi, SUBSCR_CONN_S_RELEASING, SUBSCR_CONN_TIMEOUT, 0);
+		return;
+
+	default:
+		OSMO_ASSERT(false);
+	}
+}
+
+static void subscr_conn_fsm_communicating(struct osmo_fsm_inst *fi, uint32_t event, void *data)
+{
+	switch (event) {
+	case SUBSCR_CONN_E_COMMUNICATING:
+		/* no-op */
+		return;
+
+	case SUBSCR_CONN_E_MO_CLOSE:
+	case SUBSCR_CONN_E_CN_CLOSE:
+		log_close_event(fi, event, data);
+		/* fall through */
+	case SUBSCR_CONN_E_UNUSED:
+		osmo_fsm_inst_state_chg(fi, SUBSCR_CONN_S_RELEASING, SUBSCR_CONN_TIMEOUT, 0);
+		return;
+
+	default:
+		OSMO_ASSERT(false);
+	}
+}
+
+static int subscr_conn_fsm_timeout(struct osmo_fsm_inst *fi)
+{
+	struct gsm_subscriber_connection *conn = fi->priv;
+	if (msc_subscr_conn_in_release(conn)) {
+		LOGPFSML(fi, LOGL_ERROR, "Timeout while releasing, discarding right now\n");
+		osmo_fsm_inst_term(fi, OSMO_FSM_TERM_TIMEOUT, NULL);
+	} else {
+		enum gsm48_reject_value cause = GSM48_REJECT_CONGESTION;
+		osmo_fsm_inst_dispatch(fi, SUBSCR_CONN_E_CN_CLOSE, &cause);
+	}
+	return 0;
+}
+
+static void subscr_conn_fsm_releasing_onenter(struct osmo_fsm_inst *fi, uint32_t prev_state)
+{
+	struct gsm_subscriber_connection *conn = fi->priv;
+
+	/* Use count for either conn->a.waiting_for_clear_complete or
+	 * conn->iu.waiting_for_release_complete. 'get' it early, so we don't deallocate after tearing
+	 * down active transactions. Safeguard against double-get (though it shouldn't happen). */
+	if (!msc_subscr_conn_used_by(conn, MSC_CONN_USE_RELEASE))
+		msc_subscr_conn_get(conn, MSC_CONN_USE_RELEASE);
+
+	/* Cancel pending CM Service Requests */
+	if (conn->received_cm_service_request) {
+		conn->received_cm_service_request = false;
+		msc_subscr_conn_put(conn, MSC_CONN_USE_CM_SERVICE);
+	}
+
+	/* Cancel all VLR FSMs, if any */
+	vlr_subscr_cancel_attach_fsm(conn->vsub, OSMO_FSM_TERM_ERROR, GSM48_REJECT_CONGESTION);
+
+	if (conn->vsub) {
+		/* The subscriber has no active connection anymore.
+		 * Restart the periodic Location Update expiry timer for this subscriber. */
+		vlr_subscr_enable_expire_lu(conn->vsub);
+	}
+
+	/* If we're closing in a middle of a trans, we need to clean up */
+	trans_conn_closed(conn);
+
+	switch (conn->via_ran) {
+	case RAN_GERAN_A:
+		a_iface_tx_clear_cmd(conn);
+		if (conn->a.waiting_for_clear_complete) {
+			LOGPFSML(fi, LOGL_ERROR,
+				 "Unexpected: conn is already waiting for BSSMAP Clear Complete\n");
+			break;
+		}
+		conn->a.waiting_for_clear_complete = true;
+		break;
+	case RAN_UTRAN_IU:
+		ranap_iu_tx_release(conn->iu.ue_ctx, NULL);
+		if (conn->iu.waiting_for_release_complete) {
+			LOGPFSML(fi, LOGL_ERROR,
+				 "Unexpected: conn is already waiting for Iu Release Complete\n");
+			break;
+		}
+		conn->iu.waiting_for_release_complete = true;
+		break;
+	default:
+		LOGP(DMM, LOGL_ERROR, "%s: Unknown RAN type, cannot tx release/clear\n",
+		     vlr_subscr_name(conn->vsub));
+		break;
+	}
+}
+
+static void subscr_conn_fsm_releasing(struct osmo_fsm_inst *fi, uint32_t event, void *data)
+{
+	OSMO_ASSERT(event == SUBSCR_CONN_E_UNUSED);
+	osmo_fsm_inst_state_chg(fi, SUBSCR_CONN_S_RELEASED, 0, 0);
+}
+
+static void subscr_conn_fsm_released(struct osmo_fsm_inst *fi, uint32_t prev_state)
+{
+	/* Terminate, deallocate and also deallocate the gsm_subscriber_connection, which is allocated as
+	 * a talloc child of fi. Also calls the cleanup function. */
+	osmo_fsm_inst_term(fi, OSMO_FSM_TERM_REGULAR, NULL);
+}
+
+#define S(x)	(1 << (x))
+
+static const struct osmo_fsm_state subscr_conn_fsm_states[] = {
+	[SUBSCR_CONN_S_NEW] = {
+		.name = OSMO_STRINGIFY(SUBSCR_CONN_S_NEW),
+		.in_event_mask = S(SUBSCR_CONN_E_COMPLETE_LAYER_3) |
+				 S(SUBSCR_CONN_E_ACCEPTED) |
+				 S(SUBSCR_CONN_E_MO_CLOSE) |
+				 S(SUBSCR_CONN_E_CN_CLOSE) |
+				 S(SUBSCR_CONN_E_UNUSED),
+		.out_state_mask = S(SUBSCR_CONN_S_AUTH_CIPH) |
+				  S(SUBSCR_CONN_S_ACCEPTED) |
+				  S(SUBSCR_CONN_S_RELEASING),
+		.action = subscr_conn_fsm_new,
+	},
+	[SUBSCR_CONN_S_AUTH_CIPH] = {
+		.name = OSMO_STRINGIFY(SUBSCR_CONN_S_AUTH_CIPH),
+		.in_event_mask = S(SUBSCR_CONN_E_ACCEPTED) |
+				 S(SUBSCR_CONN_E_MO_CLOSE) |
+				 S(SUBSCR_CONN_E_CN_CLOSE) |
+				 S(SUBSCR_CONN_E_UNUSED),
+		.out_state_mask = S(SUBSCR_CONN_S_WAIT_CLASSMARK_UPDATE) |
+				  S(SUBSCR_CONN_S_ACCEPTED) |
+				  S(SUBSCR_CONN_S_RELEASING),
+		.action = subscr_conn_fsm_auth_ciph,
+	},
+	[SUBSCR_CONN_S_WAIT_CLASSMARK_UPDATE] = {
+		.name = OSMO_STRINGIFY(SUBSCR_CONN_S_WAIT_CLASSMARK_UPDATE),
+		.in_event_mask = S(SUBSCR_CONN_E_CLASSMARK_UPDATE) |
+				 S(SUBSCR_CONN_E_MO_CLOSE) |
+				 S(SUBSCR_CONN_E_CN_CLOSE) |
+				 S(SUBSCR_CONN_E_UNUSED),
+		.out_state_mask = S(SUBSCR_CONN_S_AUTH_CIPH) |
+				  S(SUBSCR_CONN_S_RELEASING),
+		.action = subscr_conn_fsm_wait_classmark_update,
+	},
+	[SUBSCR_CONN_S_ACCEPTED] = {
+		.name = OSMO_STRINGIFY(SUBSCR_CONN_S_ACCEPTED),
+		/* allow everything to release for any odd behavior */
+		.in_event_mask = S(SUBSCR_CONN_E_COMPLETE_LAYER_3) |
+				 S(SUBSCR_CONN_E_COMMUNICATING) |
+		                 S(SUBSCR_CONN_E_RELEASE_WHEN_UNUSED) |
+				 S(SUBSCR_CONN_E_ACCEPTED) |
+				 S(SUBSCR_CONN_E_MO_CLOSE) |
+				 S(SUBSCR_CONN_E_CN_CLOSE) |
+				 S(SUBSCR_CONN_E_UNUSED),
+		.out_state_mask = S(SUBSCR_CONN_S_RELEASING) |
+				  S(SUBSCR_CONN_S_COMMUNICATING),
+		.onenter = subscr_conn_fsm_accepted_enter,
+		.action = subscr_conn_fsm_accepted,
+	},
+	[SUBSCR_CONN_S_COMMUNICATING] = {
+		.name = OSMO_STRINGIFY(SUBSCR_CONN_S_COMMUNICATING),
+		/* allow everything to release for any odd behavior */
+		.in_event_mask = S(SUBSCR_CONN_E_RELEASE_WHEN_UNUSED) |
+				 S(SUBSCR_CONN_E_ACCEPTED) |
+				 S(SUBSCR_CONN_E_COMMUNICATING) |
+				 S(SUBSCR_CONN_E_MO_CLOSE) |
+				 S(SUBSCR_CONN_E_CN_CLOSE) |
+				 S(SUBSCR_CONN_E_UNUSED),
+		.out_state_mask = S(SUBSCR_CONN_S_RELEASING),
+		.action = subscr_conn_fsm_communicating,
+	},
+	[SUBSCR_CONN_S_RELEASING] = {
+		.name = OSMO_STRINGIFY(SUBSCR_CONN_S_RELEASING),
+		.in_event_mask = S(SUBSCR_CONN_E_UNUSED),
+		.out_state_mask = S(SUBSCR_CONN_S_RELEASED),
+		.onenter = subscr_conn_fsm_releasing_onenter,
+		.action = subscr_conn_fsm_releasing,
+	},
+	[SUBSCR_CONN_S_RELEASED] = {
+		.name = OSMO_STRINGIFY(SUBSCR_CONN_S_RELEASED),
+		.onenter = subscr_conn_fsm_released,
+	},
+};
+
+static void subscr_conn_fsm_cleanup(struct osmo_fsm_inst *fi, enum osmo_fsm_term_cause cause);
+
+static struct osmo_fsm subscr_conn_fsm = {
+	.name = "Subscr_Conn",
+	.states = subscr_conn_fsm_states,
+	.num_states = ARRAY_SIZE(subscr_conn_fsm_states),
+	.allstate_event_mask = 0,
+	.allstate_action = NULL,
+	.log_subsys = DMM,
+	.event_names = subscr_conn_fsm_event_names,
+	.cleanup = subscr_conn_fsm_cleanup,
+	.timer_cb = subscr_conn_fsm_timeout,
+};
+
+char *msc_subscr_conn_get_conn_id(struct gsm_subscriber_connection *conn)
+{
+	char *id;
+
+	switch (conn->via_ran) {
+	case RAN_GERAN_A:
+		id = talloc_asprintf(conn, "GERAN_A-%08x", conn->a.conn_id);
+		break;
+	case RAN_UTRAN_IU:
+		id = talloc_asprintf(conn, "UTRAN_IU-%08x", iu_get_conn_id(conn->iu.ue_ctx));
+		break;
+	default:
+		LOGP(DMM, LOGL_ERROR, "RAN of conn %p unknown!\n", conn);
+		return NULL;
+	}
+
+	return id;
+}
+
+/* Tidy up before the FSM deallocates */
+static void subscr_conn_fsm_cleanup(struct osmo_fsm_inst *fi, enum osmo_fsm_term_cause cause)
+{
+	struct gsm_subscriber_connection *conn = fi->priv;
+
+	if (subscr_conn_fsm_has_active_transactions(fi))
+		LOGPFSML(fi, LOGL_ERROR, "Deallocating despite active transactions\n");
+
+	if (!conn) {
+		LOGP(DRLL, LOGL_ERROR, "Freeing NULL subscriber connection\n");
+		return;
+	}
+
+	if (conn->vsub) {
+		DEBUGP(DRLL, "%s: Freeing subscriber connection\n", vlr_subscr_name(conn->vsub));
+		conn->vsub->lu_fsm = NULL;
+		conn->vsub->msc_conn_ref = NULL;
+		vlr_subscr_put(conn->vsub);
+		conn->vsub = NULL;
+	} else
+		DEBUGP(DRLL, "Freeing subscriber connection with NULL subscriber\n");
+
+	llist_del(&conn->entry);
+}
+
+/* Signal success of Complete Layer 3. Allow to keep the conn open for Auth and Ciph. */
+void msc_subscr_conn_complete_layer_3(struct gsm_subscriber_connection *conn)
+{
+	if (!conn)
+		return;
+	osmo_fsm_inst_dispatch(conn->fi, SUBSCR_CONN_E_COMPLETE_LAYER_3, NULL);
+}
+
+void subscr_conn_release_when_unused(struct gsm_subscriber_connection *conn)
+{
+	if (!conn)
+		return;
+	if (msc_subscr_conn_in_release(conn)) {
+		DEBUGP(DMM, "%s: %s: conn already in release (%s)\n",
+		       vlr_subscr_name(conn->vsub), __func__,
+		       osmo_fsm_inst_state_name(conn->fi));
+		return;
+	}
+	if (conn->fi->state == SUBSCR_CONN_S_NEW) {
+		DEBUGP(DMM, "%s: %s: conn still being established (%s)\n",
+		       vlr_subscr_name(conn->vsub), __func__,
+		       osmo_fsm_inst_state_name(conn->fi));
+		return;
+	}
+	osmo_fsm_inst_dispatch(conn->fi, SUBSCR_CONN_E_RELEASE_WHEN_UNUSED, NULL);
+}
+
+static void conn_close(struct gsm_subscriber_connection *conn, uint32_t cause, uint32_t event)
+{
+	if (!conn) {
+		LOGP(DMM, LOGL_ERROR, "Cannot release NULL connection\n");
+		return;
+	}
+	if (msc_subscr_conn_in_release(conn)) {
+		DEBUGP(DMM, "%s(vsub=%s, cause=%u): already in release, ignore.\n",
+		       __func__, vlr_subscr_name(conn->vsub), cause);
+		return;
+	}
+	osmo_fsm_inst_dispatch(conn->fi, event, &cause);
+}
+
+void msc_subscr_conn_close(struct gsm_subscriber_connection *conn, uint32_t cause)
+{
+	return conn_close(conn, cause, SUBSCR_CONN_E_CN_CLOSE);
+}
+
+void msc_subscr_conn_mo_close(struct gsm_subscriber_connection *conn, uint32_t cause)
+{
+	return conn_close(conn, cause, SUBSCR_CONN_E_MO_CLOSE);
+}
+
+bool msc_subscr_conn_in_release(struct gsm_subscriber_connection *conn)
+{
+	if (!conn || !conn->fi)
+		return true;
+	if (conn->fi->state == SUBSCR_CONN_S_RELEASING)
+		return true;
+	if (conn->fi->state == SUBSCR_CONN_S_RELEASED)
+		return true;
+	return false;
+}
+
+bool msc_subscr_conn_is_accepted(const struct gsm_subscriber_connection *conn)
+{
+	if (!conn)
+		return false;
+	if (!conn->vsub)
+		return false;
+	if (!(conn->fi->state == SUBSCR_CONN_S_ACCEPTED
+	      || conn->fi->state == SUBSCR_CONN_S_COMMUNICATING))
+		return false;
+	return true;
+}
+
+/* Indicate that *some* communication is happening with the phone, so that the conn FSM no longer times
+ * out to release within a few seconds. */
+void msc_subscr_conn_communicating(struct gsm_subscriber_connection *conn)
+{
+	osmo_fsm_inst_dispatch(conn->fi, SUBSCR_CONN_E_COMMUNICATING, NULL);
+}
+
+void msc_subscr_conn_init(void)
+{
+	osmo_fsm_register(&subscr_conn_fsm);
+}
+
+/* Allocate a new subscriber conn and FSM.
+ * Deallocation is by msc_subscr_conn_put(): when the use count reaches zero, the
+ * SUBSCR_CONN_E_RELEASE_COMPLETE event is dispatched, the FSM terminates and deallocates both FSM and
+ * conn. As long as the FSM is waiting for responses from the subscriber, it will itself hold a use count
+ * on the conn. */
+struct gsm_subscriber_connection *msc_subscr_conn_alloc(struct gsm_network *network,
+							enum ran_type via_ran, uint16_t lac)
+{
+	struct gsm_subscriber_connection *conn;
+	struct osmo_fsm_inst *fi;
+
+	fi = osmo_fsm_inst_alloc(&subscr_conn_fsm, network, NULL, LOGL_DEBUG, NULL);
+	if (!fi) {
+		LOGP(DMM, LOGL_ERROR, "Failed to allocate conn FSM\n");
+		return NULL;
+	}
+
+	conn = talloc_zero(fi, struct gsm_subscriber_connection);
+	if (!conn) {
+		osmo_fsm_inst_free(fi);
+		return NULL;
+	}
+
+	*conn = (struct gsm_subscriber_connection){
+		.network = network,
+		.via_ran = via_ran,
+		.lac = lac,
+		.fi = fi,
+	};
+
+	fi->priv = conn;
+	llist_add_tail(&conn->entry, &network->subscr_conns);
+	return conn;
+}
+
+bool msc_subscr_conn_is_establishing_auth_ciph(const struct gsm_subscriber_connection *conn)
+{
+	if (!conn)
+		return false;
+	return conn->fi->state == SUBSCR_CONN_S_AUTH_CIPH;
+}
+
+
+const struct value_string complete_layer3_type_names[] = {
+	{ COMPLETE_LAYER3_NONE, "NONE" },
+	{ COMPLETE_LAYER3_LU, "LU" },
+	{ COMPLETE_LAYER3_CM_SERVICE_REQ, "CM_SERVICE_REQ" },
+	{ COMPLETE_LAYER3_PAGING_RESP, "PAGING_RESP" },
+	{ 0, NULL }
+};
+
+void msc_subscr_conn_update_id(struct gsm_subscriber_connection *conn,
+			       enum complete_layer3_type from, const char *id)
+{
+       conn->complete_layer3_type = from;
+       osmo_fsm_inst_update_id_f(conn->fi, "%s:%s", complete_layer3_type_name(from), id);
+       LOGPFSML(conn->fi, LOGL_DEBUG, "Updated ID\n");
+}
+
+static void rx_close_complete(struct gsm_subscriber_connection *conn, const char *label, bool *flag)
+{
+	if (!conn)
+		return;
+	if (!msc_subscr_conn_in_release(conn)) {
+		LOGPFSML(conn->fi, LOGL_ERROR, "Received unexpected %s, discarding right now\n",
+			 label);
+		trans_conn_closed(conn);
+		osmo_fsm_inst_term(conn->fi, OSMO_FSM_TERM_ERROR, NULL);
+		return;
+	}
+	if (*flag) {
+		*flag = false;
+		msc_subscr_conn_put(conn, MSC_CONN_USE_RELEASE);
+	}
+}
+
+void msc_subscr_conn_rx_bssmap_clear_complete(struct gsm_subscriber_connection *conn)
+{
+	rx_close_complete(conn, "BSSMAP Clear Complete", &conn->a.waiting_for_clear_complete);
+}
+
+void msc_subscr_conn_rx_iu_release_complete(struct gsm_subscriber_connection *conn)
+{
+	rx_close_complete(conn, "Iu Release Complete", &conn->iu.waiting_for_release_complete);
+}
diff --git a/src/libmsc/transaction.c b/src/libmsc/transaction.c
new file mode 100644
index 0000000..680d7f3
--- /dev/null
+++ b/src/libmsc/transaction.c
@@ -0,0 +1,232 @@
+/* GSM 04.07 Transaction handling */
+
+/* (C) 2009 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 <osmocom/msc/transaction.h>
+#include <osmocom/msc/gsm_data.h>
+#include <osmocom/msc/mncc.h>
+#include <osmocom/msc/debug.h>
+#include <osmocom/core/talloc.h>
+#include <osmocom/msc/gsm_04_08.h>
+#include <osmocom/msc/mncc.h>
+#include <osmocom/msc/osmo_msc.h>
+#include <osmocom/msc/vlr.h>
+
+void *tall_trans_ctx;
+
+void _gsm48_cc_trans_free(struct gsm_trans *trans);
+void _gsm411_sms_trans_free(struct gsm_trans *trans);
+void _gsm911_nc_ss_trans_free(struct gsm_trans *trans);
+
+/*! Find a transaction in connection for given protocol + transaction ID
+ * \param[in] conn Connection in which we want to find transaction
+ * \param[in] proto Protocol of transaction
+ * \param[in] trans_id Transaction ID of transaction
+ * \returns Matching transaction, if any
+ */
+struct gsm_trans *trans_find_by_id(struct gsm_subscriber_connection *conn,
+				   uint8_t proto, uint8_t trans_id)
+{
+	struct gsm_trans *trans;
+	struct gsm_network *net = conn->network;
+	struct vlr_subscr *vsub = conn->vsub;
+
+	llist_for_each_entry(trans, &net->trans_list, entry) {
+		if (trans->vsub == vsub &&
+		    trans->protocol == proto &&
+		    trans->transaction_id == trans_id)
+			return trans;
+	}
+	return NULL;
+}
+
+/*! Find a transaction by call reference
+ * \param[in] net Network in which we should search
+ * \param[in] callref Call Reference of transaction
+ * \returns Matching transaction, if any
+ */
+struct gsm_trans *trans_find_by_callref(struct gsm_network *net,
+					uint32_t callref)
+{
+	struct gsm_trans *trans;
+
+	llist_for_each_entry(trans, &net->trans_list, entry) {
+		if (trans->callref == callref)
+			return trans;
+	}
+	return NULL;
+}
+
+/*! Allocate a new transaction and add it to network list
+ *  \param[in] net Netwokr 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
+ *  \returns Transaction
+ */
+struct gsm_trans *trans_alloc(struct gsm_network *net,
+			      struct vlr_subscr *vsub,
+			      uint8_t protocol, uint8_t trans_id,
+			      uint32_t callref)
+{
+	struct gsm_trans *trans;
+
+	/* a valid subscriber is indispensable */
+	if (vsub == NULL) {
+		LOGP(DCC, LOGL_NOTICE,
+		     "unable to alloc transaction, invalid subscriber (NULL)\n");
+		return NULL;
+	}
+
+	DEBUGP(DCC, "(ti %02x sub %s callref %x) New transaction\n",
+	       trans_id, vlr_subscr_name(vsub), callref);
+
+	trans = talloc_zero(tall_trans_ctx, struct gsm_trans);
+	if (!trans)
+		return NULL;
+
+	trans->vsub = vlr_subscr_get(vsub);
+
+	trans->protocol = protocol;
+	trans->transaction_id = trans_id;
+	trans->callref = callref;
+
+	trans->net = net;
+	llist_add_tail(&trans->entry, &net->trans_list);
+
+	return trans;
+}
+
+/*! Release a transaction
+ * \param[in] trans Transaction to be released
+ */
+void trans_free(struct gsm_trans *trans)
+{
+	enum msc_subscr_conn_use conn_usage_token = MSC_CONN_USE_UNTRACKED;
+	struct gsm_subscriber_connection *conn;
+
+	switch (trans->protocol) {
+	case GSM48_PDISC_CC:
+		_gsm48_cc_trans_free(trans);
+		conn_usage_token = MSC_CONN_USE_TRANS_CC;
+		break;
+	case GSM48_PDISC_SMS:
+		_gsm411_sms_trans_free(trans);
+		conn_usage_token = MSC_CONN_USE_TRANS_SMS;
+		break;
+	case GSM48_PDISC_NC_SS:
+		_gsm911_nc_ss_trans_free(trans);
+		conn_usage_token = MSC_CONN_USE_TRANS_NC_SS;
+		break;
+	}
+
+	if (trans->paging_request) {
+		subscr_remove_request(trans->paging_request);
+		trans->paging_request = NULL;
+	}
+
+	if (trans->vsub) {
+		vlr_subscr_put(trans->vsub);
+		trans->vsub = NULL;
+	}
+
+	conn = trans->conn;
+	trans->conn = NULL;
+	llist_del(&trans->entry);
+	talloc_free(trans);
+
+	if (conn)
+		msc_subscr_conn_put(conn, conn_usage_token);
+}
+
+/*! allocate an unused transaction ID for the given subscriber
+ * in the given protocol using the ti_flag specified
+ * \param[in] net GSM network
+ * \param[in] subscr Subscriber for which to find ID
+ * \param[in] protocol Protocol for whihc to find ID
+ * \param[in] ti_flag FIXME
+ */
+int trans_assign_trans_id(struct gsm_network *net, struct vlr_subscr *vsub,
+			  uint8_t protocol, uint8_t ti_flag)
+{
+	struct gsm_trans *trans;
+	unsigned int used_tid_bitmask = 0;
+	int i, j, h;
+
+	if (ti_flag)
+		ti_flag = 0x8;
+
+	/* generate bitmask of already-used TIDs for this (subscr,proto) */
+	llist_for_each_entry(trans, &net->trans_list, entry) {
+		if (trans->vsub != vsub ||
+		    trans->protocol != protocol ||
+		    trans->transaction_id == 0xff)
+			continue;
+		used_tid_bitmask |= (1 << trans->transaction_id);
+	}
+
+	/* find a new one, trying to go in a 'circular' pattern */
+	for (h = 6; h > 0; h--)
+		if (used_tid_bitmask & (1 << (h | ti_flag)))
+			break;
+	for (i = 0; i < 7; i++) {
+		j = ((h + i) % 7) | ti_flag;
+		if ((used_tid_bitmask & (1 << j)) == 0)
+			return j;
+	}
+
+	return -1;
+}
+
+/*! Check if we have any transaction for given connection
+ * \param[in] conn Connection to check
+ * \returns 1 in case there is a transaction, 0 otherwise
+ */
+struct gsm_trans *trans_has_conn(const struct gsm_subscriber_connection *conn)
+{
+	struct gsm_trans *trans;
+
+	llist_for_each_entry(trans, &conn->network->trans_list, entry)
+		if (trans->conn == conn)
+			return trans;
+
+	return NULL;
+}
+
+/*! Free all transactions associated with a connection, presumably when the
+ * conn is being closed. The transaction code will inform the CC or SMS
+ * facilities, which will then send the necessary release indications.
+ * \param[in] conn Connection that is going to be closed.
+ */
+void trans_conn_closed(struct gsm_subscriber_connection *conn)
+{
+	struct gsm_trans *trans;
+
+	/* As part of the CC REL_IND the remote leg might be released and this
+	 * will trigger another call to trans_free. This is something the llist
+	 * macro can not handle and we need to re-iterate the list every time.
+	 */
+restart:
+	llist_for_each_entry(trans, &conn->network->trans_list, entry) {
+		if (trans->conn == conn) {
+			trans_free(trans);
+			goto restart;
+		}
+	}
+}
diff --git a/src/libvlr/Makefile.am b/src/libvlr/Makefile.am
new file mode 100644
index 0000000..dcae1c7
--- /dev/null
+++ b/src/libvlr/Makefile.am
@@ -0,0 +1,28 @@
+AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir)
+AM_CFLAGS= \
+	   -Wall \
+	   $(LIBOSMOCORE_CFLAGS) \
+	   $(LIBOSMOVTY_CFLAGS) \
+	   $(LIBOSMOSCCP_CFLAGS) \
+	   $(LIBOSMOMGCPCLIENT_CFLAGS) \
+	   $(LIBOSMOGSUPCLIENT_CFLAGS) \
+	   $(LIBOSMOABIS_CFLAGS) \
+	   $(LIBOSMORANAP_CFLAGS) \
+	   $(COVERAGE_CFLAGS) \
+	   $(NULL)
+
+noinst_HEADERS = \
+	vlr_access_req_fsm.h \
+	vlr_auth_fsm.h \
+	vlr_core.h \
+	vlr_lu_fsm.h \
+	$(NULL)
+
+noinst_LIBRARIES = libvlr.a
+
+libvlr_a_SOURCES = \
+	vlr.c \
+	vlr_access_req_fsm.c \
+	vlr_auth_fsm.c \
+	vlr_lu_fsm.c \
+	$(NULL)
diff --git a/src/libvlr/vlr.c b/src/libvlr/vlr.c
new file mode 100644
index 0000000..f7ac864
--- /dev/null
+++ b/src/libvlr/vlr.c
@@ -0,0 +1,1337 @@
+/* Osmocom Visitor Location Register (VLR) code base */
+
+/* (C) 2016 by Harald Welte <laforge@gnumonks.org>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <osmocom/core/linuxlist.h>
+#include <osmocom/core/fsm.h>
+#include <osmocom/core/utils.h>
+#include <osmocom/core/timer.h>
+#include <osmocom/gsm/protocol/gsm_04_08_gprs.h>
+#include <osmocom/gsm/gsup.h>
+#include <osmocom/gsm/apn.h>
+#include <osmocom/gsm/gsm48.h>
+#include <osmocom/msc/gsm_subscriber.h>
+#include <osmocom/gsupclient/gsup_client.h>
+#include <osmocom/msc/vlr.h>
+#include <osmocom/msc/debug.h>
+
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <limits.h>
+#include <errno.h>
+
+#include "vlr_core.h"
+#include "vlr_auth_fsm.h"
+#include "vlr_lu_fsm.h"
+#include "vlr_access_req_fsm.h"
+
+#define SGSN_SUBSCR_MAX_RETRIES 3
+#define SGSN_SUBSCR_RETRY_INTERVAL 10
+
+/***********************************************************************
+ * Convenience functions
+ ***********************************************************************/
+
+const struct value_string vlr_ciph_names[] = {
+	OSMO_VALUE_STRING(VLR_CIPH_NONE),
+	OSMO_VALUE_STRING(VLR_CIPH_A5_1),
+	OSMO_VALUE_STRING(VLR_CIPH_A5_2),
+	OSMO_VALUE_STRING(VLR_CIPH_A5_3),
+	{ 0, NULL }
+};
+
+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];
+}
+
+/* return static buffer with printable name of VLR subscriber */
+const char *vlr_subscr_name(struct vlr_subscr *vsub)
+{
+	static char buf[32];
+	if (!vsub)
+		return "unknown";
+	if (vsub->msisdn[0])
+		snprintf(buf, sizeof(buf), "MSISDN:%s", vsub->msisdn);
+	else if (vsub->imsi[0])
+		snprintf(buf, sizeof(buf), "IMSI:%s", vsub->imsi);
+	else if (vsub->tmsi != GSM_RESERVED_TMSI)
+		snprintf(buf, sizeof(buf), "TMSI:0x%08x", vsub->tmsi);
+	else if (vsub->tmsi_new != GSM_RESERVED_TMSI)
+		snprintf(buf, sizeof(buf), "TMSI(new):0x%08x", vsub->tmsi_new);
+	else
+		return "unknown";
+	buf[sizeof(buf)-1] = '\0';
+	return buf;
+}
+
+const char *vlr_subscr_msisdn_or_name(struct vlr_subscr *vsub)
+{
+	if (!vsub || !vsub->msisdn[0])
+		return vlr_subscr_name(vsub);
+	return vsub->msisdn;
+}
+
+struct vlr_subscr *_vlr_subscr_find_by_imsi(struct vlr_instance *vlr,
+					    const char *imsi,
+					    const char *file, int line)
+{
+	struct vlr_subscr *vsub;
+
+	if (!imsi || !*imsi)
+		return NULL;
+
+	llist_for_each_entry(vsub, &vlr->subscribers, list) {
+		if (vlr_subscr_matches_imsi(vsub, imsi))
+			return _vlr_subscr_get(vsub, file, line);
+	}
+	return NULL;
+}
+
+struct vlr_subscr *_vlr_subscr_find_by_tmsi(struct vlr_instance *vlr,
+					    uint32_t tmsi,
+					    const char *file, int line)
+{
+	struct vlr_subscr *vsub;
+
+	if (tmsi == GSM_RESERVED_TMSI)
+		return NULL;
+
+	llist_for_each_entry(vsub, &vlr->subscribers, list) {
+		if (vlr_subscr_matches_tmsi(vsub, tmsi))
+			return _vlr_subscr_get(vsub, file, line);
+	}
+	return NULL;
+}
+
+struct vlr_subscr *_vlr_subscr_find_by_msisdn(struct vlr_instance *vlr,
+					      const char *msisdn,
+					      const char *file, int line)
+{
+	struct vlr_subscr *vsub;
+
+	if (!msisdn || !*msisdn)
+		return NULL;
+
+	llist_for_each_entry(vsub, &vlr->subscribers, list) {
+		if (vlr_subscr_matches_msisdn(vsub, msisdn))
+			return _vlr_subscr_get(vsub, file, line);
+	}
+	return NULL;
+}
+
+/* Transmit GSUP message to HLR */
+static int vlr_tx_gsup_message(const struct vlr_instance *vlr,
+			       const struct osmo_gsup_message *gsup_msg)
+{
+	struct msgb *msg = osmo_gsup_client_msgb_alloc();
+
+	int rc = osmo_gsup_encode(msg, gsup_msg);
+	if (rc < 0) {
+		LOGP(DVLR, LOGL_ERROR, "GSUP encoding failure: %s\n", strerror(-rc));
+		return rc;
+	}
+
+	if (!vlr->gsup_client) {
+		LOGP(DVLR, LOGL_NOTICE, "GSUP link is down, cannot "
+			"send GSUP: %s\n", msgb_hexdump(msg));
+		msgb_free(msg);
+		return -ENOTSUP;
+	}
+
+	LOGP(DVLR, LOGL_DEBUG, "GSUP tx: %s\n",
+	     osmo_hexdump_nospc(msg->data, msg->len));
+
+	return osmo_gsup_client_send(vlr->gsup_client, msg);
+}
+
+/* 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)
+{
+	struct vlr_instance *vlr = vsub->vlr;
+
+	if (strlen(gsup_msg->imsi) == 0)
+		OSMO_STRLCPY_ARRAY(gsup_msg->imsi, vsub->imsi);
+
+	return vlr_tx_gsup_message(vlr, gsup_msg);
+}
+
+/* Transmit GSUP error in response to original message */
+static int vlr_tx_gsup_error_reply(const struct vlr_instance *vlr,
+				   struct osmo_gsup_message *gsup_orig,
+				   enum gsm48_gmm_cause cause)
+{
+	struct osmo_gsup_message gsup_reply = {0};
+
+	OSMO_STRLCPY_ARRAY(gsup_reply.imsi, gsup_orig->imsi);
+	gsup_reply.cause = cause;
+	gsup_reply.message_type =
+		OSMO_GSUP_TO_MSGT_ERROR(gsup_orig->message_type);
+
+	return vlr_tx_gsup_message(vlr, &gsup_reply);
+}
+
+struct vlr_subscr *_vlr_subscr_get(struct vlr_subscr *sub, const char *file, int line)
+{
+	if (!sub)
+		return NULL;
+	OSMO_ASSERT(sub->use_count < INT_MAX);
+	sub->use_count++;
+	LOGPSRC(DREF, LOGL_DEBUG, file, line,
+		"VLR subscr %s usage increases to: %d\n",
+		vlr_subscr_name(sub), sub->use_count);
+	return sub;
+}
+
+struct vlr_subscr *_vlr_subscr_put(struct vlr_subscr *sub, const char *file, int line)
+{
+	if (!sub)
+		return NULL;
+	sub->use_count--;
+	LOGPSRC(DREF, sub->use_count >= 0? LOGL_DEBUG : LOGL_ERROR,
+		file, line,
+		"VLR subscr %s usage decreases to: %d\n",
+		vlr_subscr_name(sub), sub->use_count);
+	if (sub->use_count <= 0)
+		vlr_subscr_free(sub);
+	return NULL;
+}
+
+/* Allocate a new subscriber and insert it into list */
+static struct vlr_subscr *_vlr_subscr_alloc(struct vlr_instance *vlr)
+{
+	struct vlr_subscr *vsub;
+	int i;
+
+	vsub = talloc_zero(vlr, struct vlr_subscr);
+	vsub->vlr = vlr;
+	vsub->tmsi = GSM_RESERVED_TMSI;
+	vsub->tmsi_new = GSM_RESERVED_TMSI;
+
+	for (i = 0; i < ARRAY_SIZE(vsub->auth_tuples); i++)
+		vsub->auth_tuples[i].key_seq = GSM_KEY_SEQ_INVAL;
+
+	INIT_LLIST_HEAD(&vsub->cs.requests);
+	INIT_LLIST_HEAD(&vsub->ps.pdp_list);
+
+	llist_add_tail(&vsub->list, &vlr->subscribers);
+	return vsub;
+}
+
+struct vlr_subscr *vlr_subscr_alloc(struct vlr_instance *vlr)
+{
+	return vlr_subscr_get(_vlr_subscr_alloc(vlr));
+}
+
+/* Send a GSUP Purge MS request.
+ * TODO: this should be sent to the *previous* VLR when this VLR is "taking"
+ * this subscriber, not to the HLR? */
+int vlr_subscr_purge(struct vlr_subscr *vsub)
+{
+	struct osmo_gsup_message gsup_msg = {0};
+
+	gsup_msg.message_type = OSMO_GSUP_MSGT_PURGE_MS_REQUEST;
+
+	/* provide HLR number in case we know it */
+	gsup_msg.hlr_enc_len = vsub->hlr.len;
+	gsup_msg.hlr_enc = vsub->hlr.buf;
+
+	return vlr_subscr_tx_gsup_message(vsub, &gsup_msg);
+}
+
+void vlr_subscr_cancel_attach_fsm(struct vlr_subscr *vsub,
+				  enum osmo_fsm_term_cause fsm_cause,
+				  uint8_t gsm48_cause)
+{
+	if (!vsub)
+		return;
+
+	vlr_subscr_get(vsub);
+	if (vsub->lu_fsm)
+		vlr_loc_update_cancel(vsub->lu_fsm, fsm_cause, gsm48_cause);
+	if (vsub->proc_arq_fsm)
+		vlr_parq_cancel(vsub->proc_arq_fsm, fsm_cause, gsm48_cause);
+	vlr_subscr_put(vsub);
+}
+
+/* Call vlr_subscr_cancel(), then completely drop the entry from the VLR */
+void vlr_subscr_free(struct vlr_subscr *vsub)
+{
+	llist_del(&vsub->list);
+	DEBUGP(DREF, "freeing VLR subscr %s\n", vlr_subscr_name(vsub));
+	talloc_free(vsub);
+}
+
+/* Generate a new TMSI and store in vsub->tmsi_new.
+ * Search all known subscribers to ensure that the TMSI is unique. */
+int vlr_subscr_alloc_tmsi(struct vlr_subscr *vsub)
+{
+	struct vlr_instance *vlr = vsub->vlr;
+	uint32_t tmsi;
+	int tried, rc;
+
+	for (tried = 0; tried < 100; tried++) {
+		rc = osmo_get_rand_id((uint8_t *) &tmsi, sizeof(tmsi));
+		if (rc < 0) {
+			LOGP(DDB, LOGL_ERROR, "osmo_get_rand_id() failed: %s\n", strerror(-rc));
+			return rc;
+		}
+		/* throw the dice again, if the TSMI doesn't fit */
+		if (tmsi == GSM_RESERVED_TMSI)
+			continue;
+
+		/* Section 2.4 of 23.003: MSC has two MSB 00/01/10, SGSN 11 */
+		if (vlr->cfg.is_ps) {
+			/* SGSN */
+			tmsi |= 0xC000000;
+		} else {
+			/* MSC */
+			if ((tmsi & 0xC0000000) == 0xC0000000)
+				tmsi &= ~0xC0000000;
+		}
+
+		/* If this TMSI is already in use, try another one. */
+		if (vlr_subscr_find_by_tmsi(vlr, tmsi))
+			continue;
+
+		vsub->tmsi_new = tmsi;
+		return 0;
+	}
+
+	LOGP(DVLR, LOGL_ERROR, "subscr %s: unable to generate valid TMSI"
+	     " after %d tries\n", vlr_subscr_name(vsub), tried);
+	return -1;
+}
+
+/* Find subscriber by IMSI, or create new subscriber if not found.
+ * \param[in] vlr  VLR instace.
+ * \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,
+						      const char *imsi,
+						      bool *created,
+						      const char *file,
+						      int line)
+{
+	struct vlr_subscr *vsub;
+	vsub = _vlr_subscr_find_by_imsi(vlr, imsi, file, line);
+	if (vsub) {
+		if (created)
+			*created = false;
+		return vsub;
+	}
+
+	vsub = _vlr_subscr_get(_vlr_subscr_alloc(vlr), file, line);
+	if (!vsub)
+		return NULL;
+	vlr_subscr_set_imsi(vsub, imsi);
+	LOGP(DVLR, LOGL_INFO, "New subscr, IMSI: %s\n", vsub->imsi);
+	if (created)
+		*created = true;
+	return vsub;
+}
+
+/* Find subscriber by TMSI, or create new subscriber if not found.
+ * \param[in] vlr  VLR instace.
+ * \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,
+						      uint32_t tmsi,
+						      bool *created,
+						      const char *file,
+						      int line)
+{
+	struct vlr_subscr *vsub;
+	vsub = _vlr_subscr_find_by_tmsi(vlr, tmsi, file, line);
+	if (vsub) {
+		if (created)
+			*created = false;
+		return vsub;
+	}
+
+	vsub = _vlr_subscr_get(_vlr_subscr_alloc(vlr), file, line);
+	if (!vsub)
+		return NULL;
+	vsub->tmsi = tmsi;
+	LOGP(DVLR, LOGL_INFO, "New subscr, TMSI: 0x%08x\n", vsub->tmsi);
+	if (created)
+		*created = true;
+	return vsub;
+}
+
+void vlr_subscr_set_imsi(struct vlr_subscr *vsub, const char *imsi)
+{
+	if (!vsub)
+		return;
+
+	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);
+		/* XXX Set truncated IMSI anyway, we currently cannot return an error from here. */
+	}
+
+	vsub->id = atoll(vsub->imsi);
+	DEBUGP(DVLR, "set IMSI on subscriber; IMSI=%s id=%llu\n",
+	       vsub->imsi, vsub->id);
+}
+
+void vlr_subscr_set_imei(struct vlr_subscr *vsub, const char *imei)
+{
+	if (!vsub)
+		return;
+	OSMO_STRLCPY_ARRAY(vsub->imei, imei);
+	DEBUGP(DVLR, "set IMEI on subscriber; IMSI=%s IMEI=%s\n",
+	       vsub->imsi, vsub->imei);
+}
+
+void vlr_subscr_set_imeisv(struct vlr_subscr *vsub, const char *imeisv)
+{
+	if (!vsub)
+		return;
+	OSMO_STRLCPY_ARRAY(vsub->imeisv, imeisv);
+	DEBUGP(DVLR, "set IMEISV on subscriber; IMSI=%s IMEISV=%s\n",
+	       vsub->imsi, vsub->imeisv);
+}
+
+/* Safely copy the given MSISDN string to vsub->msisdn */
+void vlr_subscr_set_msisdn(struct vlr_subscr *vsub, const char *msisdn)
+{
+	if (!vsub)
+		return;
+	OSMO_STRLCPY_ARRAY(vsub->msisdn, msisdn);
+	DEBUGP(DVLR, "set MSISDN on subscriber; IMSI=%s MSISDN=%s\n",
+	       vsub->imsi, vsub->msisdn);
+}
+
+bool vlr_subscr_matches_imsi(struct vlr_subscr *vsub, const char *imsi)
+{
+	return vsub && imsi && vsub->imsi[0] && !strcmp(vsub->imsi, imsi);
+}
+
+bool vlr_subscr_matches_tmsi(struct vlr_subscr *vsub, uint32_t tmsi)
+{
+	return vsub && tmsi != GSM_RESERVED_TMSI
+		&& (vsub->tmsi == tmsi || vsub->tmsi_new == tmsi);
+}
+
+bool vlr_subscr_matches_msisdn(struct vlr_subscr *vsub, const char *msisdn)
+{
+	return vsub && msisdn && vsub->msisdn[0]
+		&& !strcmp(vsub->msisdn, msisdn);
+}
+
+bool vlr_subscr_matches_imei(struct vlr_subscr *vsub, const char *imei)
+{
+	return vsub && imei && vsub->imei[0]
+		&& !strcmp(vsub->imei, imei);
+}
+
+/* Send updated subscriber information to HLR */
+int vlr_subscr_changed(struct vlr_subscr *vsub)
+{
+	/* FIXME */
+	LOGP(DVLR, LOGL_ERROR, "Not implemented: %s\n", __func__);
+	return 0;
+}
+
+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. */
+	if (osmo_clock_gettime(CLOCK_MONOTONIC, &now) == 0) {
+		vsub->expire_lu = now.tv_sec + (net->t3212 * 60 * 6 * 2) + 60;
+	} else {
+		LOGP(DVLR, LOGL_ERROR,
+		     "%s: Could not enable Location Update expiry: unable to read current time\n", vlr_subscr_name(vsub));
+		/* Disable LU expiry for this subscriber. This subscriber will only be freed after an explicit IMSI detach. */
+		vsub->expire_lu = VLR_SUBSCRIBER_NO_EXPIRATION;
+	}
+}
+
+void vlr_subscr_expire_lu(void *data)
+{
+	struct vlr_instance *vlr = data;
+	struct vlr_subscr *vsub, *vsub_tmp;
+	struct timespec now;
+
+	if (llist_empty(&vlr->subscribers))
+		goto done;
+
+	if (osmo_clock_gettime(CLOCK_MONOTONIC, &now) != 0) {
+		LOGP(DVLR, LOGL_ERROR, "Skipping Location Update expiry: Could not read current time\n");
+		goto done;
+	}
+
+	llist_for_each_entry_safe(vsub, vsub_tmp, &vlr->subscribers, list) {
+		if (vsub->expire_lu == VLR_SUBSCRIBER_NO_EXPIRATION || vsub->expire_lu > now.tv_sec)
+			continue;
+
+		LOGP(DVLR, LOGL_DEBUG, "%s: Location Update expired\n", vlr_subscr_name(vsub));
+		vlr_subscr_rx_imsi_detach(vsub);
+	}
+
+done:
+	osmo_timer_schedule(&vlr->lu_expire_timer, VLR_SUBSCRIBER_LU_EXPIRATION_INTERVAL, 0);
+}
+
+/***********************************************************************
+ * PDP context data
+ ***********************************************************************/
+
+#define GSM_APN_LENGTH 102
+
+/* 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 sgsn_subscriber_pdp_data *
+vlr_subscr_pdp_data_alloc(struct vlr_subscr *vsub)
+{
+	struct sgsn_subscriber_pdp_data* pdata;
+
+	pdata = talloc_zero(vsub, struct sgsn_subscriber_pdp_data);
+
+	llist_add_tail(&pdata->list, &vsub->ps.pdp_list);
+
+	return pdata;
+}
+
+static int vlr_subscr_pdp_data_clear(struct vlr_subscr *vsub)
+{
+	struct sgsn_subscriber_pdp_data *pdp, *pdp2;
+	int count = 0;
+
+	llist_for_each_entry_safe(pdp, pdp2, &vsub->ps.pdp_list, list) {
+		llist_del(&pdp->list);
+		talloc_free(pdp);
+		count += 1;
+	}
+
+	return count;
+}
+
+static struct sgsn_subscriber_pdp_data *
+vlr_subscr_pdp_data_get_by_id(struct vlr_subscr *vsub, unsigned context_id)
+{
+	struct sgsn_subscriber_pdp_data *pdp;
+
+	llist_for_each_entry(pdp, &vsub->ps.pdp_list, list) {
+		if (pdp->context_id == context_id)
+			return pdp;
+	}
+
+	return NULL;
+}
+
+/***********************************************************************
+ * Actual Implementation
+ ***********************************************************************/
+
+static int vlr_rx_gsup_unknown_imsi(struct vlr_instance *vlr,
+				   struct osmo_gsup_message *gsup_msg)
+{
+	if (OSMO_GSUP_IS_MSGT_REQUEST(gsup_msg->message_type)) {
+		int rc = vlr_tx_gsup_error_reply(vlr, gsup_msg, GMM_CAUSE_IMSI_UNKNOWN);
+		if (rc < 0)
+			LOGP(DVLR, LOGL_ERROR, "Failed to send error reply for IMSI %s\n", gsup_msg->imsi);
+
+		LOGP(DVLR, LOGL_NOTICE,
+		     "Unknown IMSI %s, discarding GSUP request "
+		     "of type 0x%02x\n",
+		     gsup_msg->imsi, gsup_msg->message_type);
+	} else if (OSMO_GSUP_IS_MSGT_ERROR(gsup_msg->message_type)) {
+		LOGP(DVLR, LOGL_NOTICE,
+		     "Unknown IMSI %s, discarding GSUP error "
+		     "of type 0x%02x, cause '%s' (%d)\n",
+		     gsup_msg->imsi, gsup_msg->message_type,
+		     get_value_string(gsm48_gmm_cause_names, gsup_msg->cause),
+		     gsup_msg->cause);
+	} else {
+		LOGP(DVLR, LOGL_NOTICE,
+		     "Unknown IMSI %s, discarding GSUP response "
+		     "of type 0x%02x\n",
+		     gsup_msg->imsi, gsup_msg->message_type);
+	}
+
+	return -GMM_CAUSE_IMSI_UNKNOWN;
+}
+
+static int vlr_rx_gsup_purge_no_subscr(struct vlr_instance *vlr,
+				struct osmo_gsup_message *gsup_msg)
+{
+	if (OSMO_GSUP_IS_MSGT_ERROR(gsup_msg->message_type)) {
+		LOGGSUPP(LOGL_NOTICE, gsup_msg,
+			 "Purge MS has failed with cause '%s' (%d)\n",
+			 get_value_string(gsm48_gmm_cause_names, gsup_msg->cause),
+			 gsup_msg->cause);
+		return -gsup_msg->cause;
+	}
+	LOGGSUPP(LOGL_INFO, gsup_msg, "Completing purge MS\n");
+	return 0;
+}
+
+/* VLR internal call to request UpdateLocation from HLR */
+int vlr_subscr_req_lu(struct vlr_subscr *vsub)
+{
+	struct osmo_gsup_message gsup_msg = {0};
+	int rc;
+
+	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);
+
+	return rc;
+}
+
+/* VLR internal call to request tuples from HLR */
+int vlr_subscr_req_sai(struct vlr_subscr *vsub,
+		       const uint8_t *auts, const uint8_t *auts_rand)
+{
+	struct osmo_gsup_message gsup_msg = {0};
+
+	gsup_msg.message_type = OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST;
+	gsup_msg.auts = auts;
+	gsup_msg.rand = auts_rand;
+
+	return vlr_subscr_tx_gsup_message(vsub, &gsup_msg);
+}
+
+/* Tell HLR that authentication failure occurred */
+int vlr_subscr_tx_auth_fail_rep(const struct vlr_subscr *vsub)
+{
+	struct osmo_gsup_message gsup_msg = {0};
+
+	gsup_msg.message_type = OSMO_GSUP_MSGT_AUTH_FAIL_REPORT;
+	OSMO_STRLCPY_ARRAY(gsup_msg.imsi, vsub->imsi);
+	return vlr_tx_gsup_message(vsub->vlr, &gsup_msg);
+}
+
+/* Update the subscriber with GSUP-received auth tuples */
+void vlr_subscr_update_tuples(struct vlr_subscr *vsub,
+			      const struct osmo_gsup_message *gsup)
+{
+	unsigned int i;
+	unsigned int got_tuples;
+
+	if (gsup->num_auth_vectors) {
+		memset(&vsub->auth_tuples, 0, sizeof(vsub->auth_tuples));
+		for (i = 0; i < ARRAY_SIZE(vsub->auth_tuples); i++)
+			vsub->auth_tuples[i].key_seq = GSM_KEY_SEQ_INVAL;
+	}
+
+	got_tuples = 0;
+	for (i = 0; i < gsup->num_auth_vectors; i++) {
+		size_t key_seq = i;
+
+		if (key_seq >= ARRAY_SIZE(vsub->auth_tuples)) {
+			LOGVSUBP(LOGL_NOTICE, vsub,
+				"Skipping auth tuple wih invalid cksn %zu\n",
+				key_seq);
+			continue;
+		}
+		vsub->auth_tuples[i].vec = gsup->auth_vectors[i];
+		vsub->auth_tuples[i].key_seq = key_seq;
+		got_tuples++;
+	}
+
+	LOGVSUBP(LOGL_DEBUG, vsub, "Received %u auth tuples\n", got_tuples);
+
+	if (!got_tuples) {
+		/* FIXME what now? */
+		// vlr_subscr_cancel(vsub, GMM_CAUSE_GSM_AUTH_UNACCEPT); ?
+	}
+
+	/* New tuples means last_tuple becomes invalid */
+	vsub->last_tuple = NULL;
+}
+
+/* Handle SendAuthInfo Result/Error from HLR */
+static int vlr_subscr_handle_sai_res(struct vlr_subscr *vsub,
+				     const struct osmo_gsup_message *gsup)
+{
+	struct osmo_fsm_inst *auth_fi = vsub->auth_fsm;
+	void *data = (void *) gsup;
+
+	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);
+		break;
+	case OSMO_GSUP_MSGT_SEND_AUTH_INFO_ERROR:
+		osmo_fsm_inst_dispatch(auth_fi, VLR_AUTH_E_HLR_SAI_NACK, data);
+		break;
+	default:
+		return -1;
+	}
+
+	return 0;
+}
+
+static int decode_bcd_number_safe(char *output, int output_len,
+				  const uint8_t *bcd_lv, int input_len,
+				  int h_len)
+{
+	uint8_t len;
+	OSMO_ASSERT(output_len >= 1);
+	*output = '\0';
+	if (input_len < 1)
+		return -EIO;
+	len = bcd_lv[0];
+	if (input_len < len)
+		return -EIO;
+	return gsm48_decode_bcd_number(output, output_len, bcd_lv, h_len);
+}
+
+static void vlr_subscr_gsup_insert_data(struct vlr_subscr *vsub,
+					const struct osmo_gsup_message *gsup_msg)
+{
+	unsigned idx;
+	int rc;
+
+	if (gsup_msg->msisdn_enc) {//FIXME: vlr_subscr_set_msisdn()?
+		decode_bcd_number_safe(vsub->msisdn, sizeof(vsub->msisdn),
+				       gsup_msg->msisdn_enc,
+				       gsup_msg->msisdn_enc_len, 0);
+		LOGP(DVLR, LOGL_DEBUG, "IMSI:%s has MSISDN:%s\n",
+		     vsub->imsi, vsub->msisdn);
+	}
+
+	if (gsup_msg->hlr_enc) {
+		if (gsup_msg->hlr_enc_len > sizeof(vsub->hlr.buf)) {
+			LOGP(DVLR, LOGL_ERROR, "HLR-Number too long (%zu)\n",
+				gsup_msg->hlr_enc_len);
+			vsub->hlr.len = 0;
+		} else {
+			memcpy(vsub->hlr.buf, gsup_msg->hlr_enc,
+				gsup_msg->hlr_enc_len);
+			vsub->hlr.len = gsup_msg->hlr_enc_len;
+		}
+	}
+
+	if (gsup_msg->pdp_info_compl) {
+		rc = vlr_subscr_pdp_data_clear(vsub);
+		if (rc > 0)
+			LOGP(DVLR, LOGL_INFO, "Cleared existing PDP info\n");
+	}
+
+	for (idx = 0; idx < gsup_msg->num_pdp_infos; idx++) {
+		const struct osmo_gsup_pdp_info *pdp_info = &gsup_msg->pdp_infos[idx];
+		size_t ctx_id = pdp_info->context_id;
+		struct sgsn_subscriber_pdp_data *pdp_data;
+
+		if (pdp_info->apn_enc_len >= sizeof(pdp_data->apn_str)-1) {
+			LOGVSUBP(LOGL_ERROR, vsub,
+			     "APN too long, context id = %zu, APN = %s\n",
+			     ctx_id, osmo_hexdump(pdp_info->apn_enc,
+						  pdp_info->apn_enc_len));
+			continue;
+		}
+
+		if (pdp_info->qos_enc_len > sizeof(pdp_data->qos_subscribed)) {
+			LOGVSUBP(LOGL_ERROR, vsub,
+				"QoS info too long (%zu)\n",
+				pdp_info->qos_enc_len);
+			continue;
+		}
+
+		LOGVSUBP(LOGL_INFO, vsub,
+		     "Will set PDP info, context id = %zu, APN = %s\n",
+		     ctx_id, osmo_hexdump(pdp_info->apn_enc, pdp_info->apn_enc_len));
+
+		/* Set PDP info [ctx_id] */
+		pdp_data = vlr_subscr_pdp_data_get_by_id(vsub, ctx_id);
+		if (!pdp_data) {
+			pdp_data = vlr_subscr_pdp_data_alloc(vsub);
+			pdp_data->context_id = ctx_id;
+		}
+
+		OSMO_ASSERT(pdp_data != NULL);
+		pdp_data->pdp_type = pdp_info->pdp_type;
+		osmo_apn_to_str(pdp_data->apn_str,
+				pdp_info->apn_enc, pdp_info->apn_enc_len);
+		memcpy(pdp_data->qos_subscribed, pdp_info->qos_enc, pdp_info->qos_enc_len);
+		pdp_data->qos_subscribed_len = pdp_info->qos_enc_len;
+	}
+}
+
+
+/* Handle InsertSubscrData Result from HLR */
+static int vlr_subscr_handle_isd_req(struct vlr_subscr *vsub,
+				     const struct osmo_gsup_message *gsup)
+{
+	struct osmo_gsup_message gsup_reply = {0};
+
+	vlr_subscr_gsup_insert_data(vsub, gsup);
+	vsub->vlr->ops.subscr_update(vsub);
+
+	gsup_reply.message_type = OSMO_GSUP_MSGT_INSERT_DATA_RESULT;
+	return vlr_subscr_tx_gsup_message(vsub, &gsup_reply);
+}
+
+/* Handle UpdateLocation Result from HLR */
+static int vlr_subscr_handle_lu_res(struct vlr_subscr *vsub,
+				    const struct osmo_gsup_message *gsup)
+{
+	if (!vsub->lu_fsm) {
+		LOGVSUBP(LOGL_ERROR, vsub, "Rx GSUP LU Result "
+			 "without LU in progress\n");
+		return -ENODEV;
+	}
+
+	/* contrary to MAP, we allow piggy-backing subscriber data onto the
+	 * UPDATE LOCATION RESULT, and don't mandate the use of a separate
+	 * nested INSERT SUBSCRIBER DATA transaction */
+	vlr_subscr_gsup_insert_data(vsub, gsup);
+
+	osmo_fsm_inst_dispatch(vsub->lu_fsm, VLR_ULA_E_HLR_LU_RES, NULL);
+
+	return 0;
+}
+
+/* Handle UpdateLocation Result from HLR */
+static int vlr_subscr_handle_lu_err(struct vlr_subscr *vsub,
+				    const struct osmo_gsup_message *gsup)
+{
+	if (!vsub->lu_fsm) {
+		LOGVSUBP(LOGL_ERROR, vsub, "Rx GSUP LU Error "
+			 "without LU in progress\n");
+		return -ENODEV;
+	}
+
+	LOGVSUBP(LOGL_DEBUG, vsub, "UpdateLocation failed; gmm_cause: %s\n",
+		 get_value_string(gsm48_gmm_cause_names, gsup->cause));
+
+	osmo_fsm_inst_dispatch(vsub->lu_fsm, VLR_ULA_E_HLR_LU_RES,
+				(void *)&gsup->cause);
+
+	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)
+{
+	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:
+		gsm48_rej = GSM48_REJECT_IMSI_UNKNOWN_IN_HLR;
+		break;
+	case GMM_CAUSE_ILLEGAL_MS:
+		gsm48_rej = GSM48_REJECT_ILLEGAL_MS;
+		break;
+	case GMM_CAUSE_IMEI_NOT_ACCEPTED:
+		gsm48_rej = GSM48_REJECT_IMEI_NOT_ACCEPTED;
+		break;
+	case GMM_CAUSE_ILLEGAL_ME:
+		gsm48_rej = GSM48_REJECT_ILLEGAL_ME;
+		break;
+	case GMM_CAUSE_GPRS_NOTALLOWED:
+		gsm48_rej = GSM48_REJECT_GPRS_NOT_ALLOWED;
+		break;
+	case GMM_CAUSE_GPRS_OTHER_NOTALLOWED:
+		gsm48_rej = GSM48_REJECT_SERVICES_NOT_ALLOWED;
+		break;
+	case GMM_CAUSE_MS_ID_NOT_DERIVED:
+		gsm48_rej = GSM48_REJECT_MS_IDENTITY_NOT_DERVIVABLE;
+		break;
+	case GMM_CAUSE_IMPL_DETACHED:
+		gsm48_rej = GSM48_REJECT_IMPLICITLY_DETACHED;
+		break;
+	case GMM_CAUSE_PLMN_NOTALLOWED:
+		gsm48_rej = GSM48_REJECT_PLMN_NOT_ALLOWED;
+		break;
+	case GMM_CAUSE_LA_NOTALLOWED:
+		gsm48_rej = GSM48_REJECT_LOC_NOT_ALLOWED;
+		break;
+	case GMM_CAUSE_ROAMING_NOTALLOWED:
+		gsm48_rej = GSM48_REJECT_ROAMING_NOT_ALLOWED;
+		break;
+	case GMM_CAUSE_NO_GPRS_PLMN:
+		gsm48_rej = GSM48_REJECT_GPRS_NOT_ALLOWED_IN_PLMN;
+		break;
+	case GMM_CAUSE_MSC_TEMP_NOTREACH:
+		gsm48_rej = GSM48_REJECT_MSC_TMP_NOT_REACHABLE;
+		break;
+	case GMM_CAUSE_SYNC_FAIL:
+		gsm48_rej = GSM48_REJECT_SYNCH_FAILURE;
+		break;
+	case GMM_CAUSE_CONGESTION:
+		gsm48_rej = GSM48_REJECT_CONGESTION;
+		break;
+	case GMM_CAUSE_SEM_INCORR_MSG:
+		gsm48_rej = GSM48_REJECT_INCORRECT_MESSAGE;
+		break;
+	case GMM_CAUSE_INV_MAND_INFO:
+		gsm48_rej = GSM48_REJECT_INVALID_MANDANTORY_INF;
+		break;
+	case GMM_CAUSE_MSGT_NOTEXIST_NOTIMPL:
+		gsm48_rej = GSM48_REJECT_MSG_TYPE_NOT_IMPLEMENTED;
+		break;
+	case GMM_CAUSE_MSGT_INCOMP_P_STATE:
+		gsm48_rej = GSM48_REJECT_MSG_TYPE_NOT_COMPATIBLE;
+		break;
+	case GMM_CAUSE_IE_NOTEXIST_NOTIMPL:
+		gsm48_rej = GSM48_REJECT_INF_ELEME_NOT_IMPLEMENTED;
+		break;
+	case GMM_CAUSE_COND_IE_ERR:
+		gsm48_rej = GSM48_REJECT_CONDTIONAL_IE_ERROR;
+		break;
+	case GMM_CAUSE_MSG_INCOMP_P_STATE:
+		gsm48_rej = GSM48_REJECT_MSG_NOT_COMPATIBLE;
+		break;
+	case GMM_CAUSE_PROTO_ERR_UNSPEC:
+		gsm48_rej = GSM48_REJECT_PROTOCOL_ERROR;
+		break;
+
+	case GMM_CAUSE_NO_SUIT_CELL_IN_LA:
+	case GMM_CAUSE_MAC_FAIL:
+	case GMM_CAUSE_GSM_AUTH_UNACCEPT:
+	case GMM_CAUSE_NOT_AUTH_FOR_CSG:
+	case GMM_CAUSE_SMS_VIA_GPRS_IN_RA:
+	case GMM_CAUSE_NO_PDP_ACTIVATED:
+	case GMM_CAUSE_NET_FAIL:
+		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;
+}
+
+/* Handle LOCATION CANCEL request from HLR */
+static int vlr_subscr_handle_cancel_req(struct vlr_subscr *vsub,
+					struct osmo_gsup_message *gsup_msg)
+{
+	enum gsm48_reject_value gsm48_rej;
+	enum osmo_fsm_term_cause fsm_cause;
+	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;
+
+	LOGVSUBP(LOGL_INFO, vsub, "Cancelling MS subscriber (%s)\n",
+		 is_update_procedure ?
+		 "update procedure" : "subscription withdraw");
+
+	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_subscr_cancel_attach_fsm(vsub, fsm_cause, gsm48_rej);
+
+	return rc;
+}
+
+/* Incoming handler for GSUP from HLR.
+ * Keep this function non-static for direct invocation by unit tests. */
+int vlr_gsupc_read_cb(struct osmo_gsup_client *gsupc, struct msgb *msg)
+{
+	struct vlr_instance *vlr = (struct vlr_instance *) gsupc->data;
+	struct vlr_subscr *vsub;
+	struct osmo_gsup_message gsup;
+	int rc;
+
+	DEBUGP(DVLR, "GSUP rx %u: %s\n", msgb_l2len(msg),
+	       osmo_hexdump_nospc(msgb_l2(msg), msgb_l2len(msg)));
+
+	rc = osmo_gsup_decode(msgb_l2(msg), msgb_l2len(msg), &gsup);
+	if (rc < 0) {
+		LOGP(DVLR, LOGL_ERROR,
+			"decoding GSUP message fails with error '%s' (%d)\n",
+			get_value_string(gsm48_gmm_cause_names, -rc), -rc);
+		goto msgb_free_and_return;
+	}
+
+	if (!gsup.imsi[0]) {
+		LOGP(DVLR, LOGL_ERROR, "Missing IMSI in GSUP message\n");
+		if (OSMO_GSUP_IS_MSGT_REQUEST(gsup.message_type)) {
+			rc = vlr_tx_gsup_error_reply(vlr, &gsup, GMM_CAUSE_INV_MAND_INFO);
+			if (rc < 0)
+				LOGP(DVLR, LOGL_ERROR, "Failed to send error reply for IMSI %s\n", gsup.imsi);
+		}
+		rc = -GMM_CAUSE_INV_MAND_INFO;
+		goto msgb_free_and_return;
+	}
+
+	vsub = vlr_subscr_find_by_imsi(vlr, gsup.imsi);
+	if (!vsub) {
+		switch (gsup.message_type) {
+		case OSMO_GSUP_MSGT_PURGE_MS_RESULT:
+		case OSMO_GSUP_MSGT_PURGE_MS_ERROR:
+			rc = vlr_rx_gsup_purge_no_subscr(vlr, &gsup);
+			goto msgb_free_and_return;
+		default:
+			rc = vlr_rx_gsup_unknown_imsi(vlr, &gsup);
+			goto msgb_free_and_return;
+		}
+	}
+
+	switch (gsup.message_type) {
+	case OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT:
+	case OSMO_GSUP_MSGT_SEND_AUTH_INFO_ERROR:
+		rc = vlr_subscr_handle_sai_res(vsub, &gsup);
+		break;
+	case OSMO_GSUP_MSGT_INSERT_DATA_REQUEST:
+		rc = vlr_subscr_handle_isd_req(vsub, &gsup);
+		break;
+	case OSMO_GSUP_MSGT_LOCATION_CANCEL_REQUEST:
+		rc = vlr_subscr_handle_cancel_req(vsub, &gsup);
+		break;
+	case OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT:
+		rc = vlr_subscr_handle_lu_res(vsub, &gsup);
+		break;
+	case OSMO_GSUP_MSGT_UPDATE_LOCATION_ERROR:
+		rc = vlr_subscr_handle_lu_err(vsub, &gsup);
+		break;
+	case OSMO_GSUP_MSGT_PURGE_MS_ERROR:
+	case OSMO_GSUP_MSGT_PURGE_MS_RESULT:
+	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;
+	default:
+		/* Forward message towards MSC */
+		rc = vlr->ops.forward_gsup_msg(vsub, &gsup);
+		break;
+	}
+
+	vlr_subscr_put(vsub);
+
+msgb_free_and_return:
+	msgb_free(msg);
+	return rc;
+}
+
+/* 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)
+{
+	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) {
+	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)) {
+			LOGVSUBP(LOGL_ERROR, vsub, "IMSI in ID RESP differs:"
+				 " %s\n", mi_string);
+			/* XXX Should we return an error, e.g. -EINVAL ? */
+		} else
+			vlr_subscr_set_imsi(vsub, mi_string);
+		break;
+	case GSM_MI_TYPE_IMEI:
+		vlr_subscr_set_imei(vsub, mi_string);
+		break;
+	case GSM_MI_TYPE_IMEISV:
+		vlr_subscr_set_imeisv(vsub, mi_string);
+		break;
+	}
+
+	if (vsub->auth_fsm) {
+		switch (mi_type) {
+		case GSM_MI_TYPE_IMSI:
+			osmo_fsm_inst_dispatch(vsub->auth_fsm,
+					VLR_AUTH_E_MS_ID_IMSI, mi_string);
+			break;
+		}
+	}
+
+	if (vsub->lu_fsm) {
+		uint32_t event = 0;
+		switch (mi_type) {
+		case GSM_MI_TYPE_IMSI:
+			event = VLR_ULA_E_ID_IMSI;
+			break;
+		case GSM_MI_TYPE_IMEI:
+			event = VLR_ULA_E_ID_IMEI;
+			break;
+		case GSM_MI_TYPE_IMEISV:
+			event = VLR_ULA_E_ID_IMEISV;
+			break;
+		default:
+			OSMO_ASSERT(0);
+			break;
+		}
+		osmo_fsm_inst_dispatch(vsub->lu_fsm, event, mi_string);
+	} else {
+		LOGVSUBP(LOGL_NOTICE,  vsub, "gratuitous ID RESPONSE?!?\n");
+	}
+
+	return 0;
+}
+
+/* MSC->VLR: Subscriber has provided IDENTITY RESPONSE */
+int vlr_subscr_rx_tmsi_reall_compl(struct vlr_subscr *vsub)
+{
+	if (vsub->lu_fsm) {
+		return osmo_fsm_inst_dispatch(vsub->lu_fsm,
+					      VLR_ULA_E_NEW_TMSI_ACK, NULL);
+	} else if (vsub->proc_arq_fsm) {
+		return osmo_fsm_inst_dispatch(vsub->proc_arq_fsm,
+					      PR_ARQ_E_TMSI_ACK, NULL);
+	} else {
+		LOGVSUBP(LOGL_NOTICE, vsub,
+			 "gratuitous TMSI REALLOC COMPL");
+		return -EINVAL;
+	}
+}
+
+bool vlr_subscr_expire(struct vlr_subscr *vsub)
+{
+	if (vsub->lu_complete) {
+		vsub->lu_complete = false;
+		vlr_subscr_put(vsub);
+
+		return true;
+	}
+
+	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)
+{
+	/* 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);
+
+	vsub->imsi_detached_flag = true;
+	vsub->expire_lu = VLR_SUBSCRIBER_NO_EXPIRATION;
+
+	/* balancing the get from vlr_lu_compl_fsm_success() */
+	vlr_subscr_expire(vsub);
+
+	return 0;
+}
+
+/* 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.
+ * \param[in] vsub  subscriber to tear down
+ */
+void vlr_subscr_conn_timeout(struct vlr_subscr *vsub)
+{
+	vlr_subscr_cancel_attach_fsm(vsub, OSMO_FSM_TERM_TIMEOUT, GSM48_REJECT_CONGESTION);
+}
+
+struct vlr_instance *vlr_alloc(void *ctx, const struct vlr_ops *ops)
+{
+	struct vlr_instance *vlr = talloc_zero(ctx, struct vlr_instance);
+	OSMO_ASSERT(vlr);
+
+	/* Some of these are needed only on UTRAN, but in case the caller wants
+	 * only GERAN, she should just provide dummy callbacks. */
+	OSMO_ASSERT(ops->tx_auth_req);
+	OSMO_ASSERT(ops->tx_auth_rej);
+	OSMO_ASSERT(ops->tx_id_req);
+	OSMO_ASSERT(ops->tx_lu_acc);
+	OSMO_ASSERT(ops->tx_lu_rej);
+	OSMO_ASSERT(ops->tx_cm_serv_acc);
+	OSMO_ASSERT(ops->tx_cm_serv_rej);
+	OSMO_ASSERT(ops->set_ciph_mode);
+	OSMO_ASSERT(ops->tx_common_id);
+	OSMO_ASSERT(ops->subscr_update);
+	OSMO_ASSERT(ops->subscr_assoc);
+	OSMO_ASSERT(ops->forward_gsup_msg);
+
+	INIT_LLIST_HEAD(&vlr->subscribers);
+	INIT_LLIST_HEAD(&vlr->operations);
+	memcpy(&vlr->ops, ops, sizeof(vlr->ops));
+
+	/* defaults */
+	vlr->cfg.assign_tmsi = true;
+
+	/* osmo_auth_fsm.c */
+	osmo_fsm_register(&vlr_auth_fsm);
+	/* osmo_lu_fsm.c */
+	vlr_lu_fsm_init();
+	/* vlr_access_request_fsm.c */
+	vlr_parq_fsm_init();
+
+	return vlr;
+}
+
+int vlr_start(const char *gsup_unit_name, struct vlr_instance *vlr,
+	      const char *gsup_server_addr_str, uint16_t gsup_server_port)
+{
+	OSMO_ASSERT(vlr);
+
+	vlr->gsup_client = osmo_gsup_client_create(vlr, gsup_unit_name,
+						   gsup_server_addr_str,
+						   gsup_server_port,
+						   &vlr_gsupc_read_cb, NULL);
+	if (!vlr->gsup_client)
+		return -ENOMEM;
+	vlr->gsup_client->data = vlr;
+
+	osmo_timer_setup(&vlr->lu_expire_timer, vlr_subscr_expire_lu, vlr);
+	osmo_timer_schedule(&vlr->lu_expire_timer, VLR_SUBSCRIBER_LU_EXPIRATION_INTERVAL, 0);
+	return 0;
+}
+
+/* MSC->VLR: Subscribre has disconnected */
+int vlr_subscr_disconnected(struct vlr_subscr *vsub)
+{
+	/* This corresponds to a MAP-ABORT from MSC->VLR on a classic B
+	 * interface */
+	osmo_fsm_inst_term(vsub->lu_fsm, OSMO_FSM_TERM_REQUEST, NULL);
+	osmo_fsm_inst_term(vsub->auth_fsm, OSMO_FSM_TERM_REQUEST, NULL);
+	vsub->msc_conn_ref = NULL;
+
+	return 0;
+}
+
+/* MSC->VLR: Receive Authentication Failure from Subscriber */
+int vlr_subscr_rx_auth_fail(struct vlr_subscr *vsub, const uint8_t *auts)
+{
+	struct vlr_auth_resp_par par = {0};
+	par.auts = auts;
+
+	osmo_fsm_inst_dispatch(vsub->auth_fsm, VLR_AUTH_E_MS_AUTH_FAIL, &par);
+	return 0;
+}
+
+/* MSC->VLR: Receive Authentication Response from MS
+ * \returns 1 in case of success, 0 in case of delay, -1 on auth error */
+int vlr_subscr_rx_auth_resp(struct vlr_subscr *vsub, bool is_r99,
+			 bool is_utran, const uint8_t *res, uint8_t res_len)
+{
+	struct osmo_fsm_inst *auth_fi = vsub->auth_fsm;
+	struct vlr_auth_resp_par par;
+
+	par.is_r99 = is_r99;
+	par.is_utran = is_utran;
+	par.res = res;
+	par.res_len = res_len;
+	osmo_fsm_inst_dispatch(auth_fi, VLR_AUTH_E_MS_AUTH_RESP, (void *) &par);
+
+	return 0;
+}
+
+/* MSC->VLR: Receive result of Ciphering Mode Command from MS */
+void vlr_subscr_rx_ciph_res(struct vlr_subscr *vsub, struct vlr_ciph_result *res)
+{
+	if (vsub->lu_fsm && vsub->lu_fsm->state == VLR_ULA_S_WAIT_CIPH)
+		osmo_fsm_inst_dispatch(vsub->lu_fsm, VLR_ULA_E_CIPH_RES, res);
+	if (vsub->proc_arq_fsm
+	    && vsub->proc_arq_fsm->state == PR_ARQ_S_WAIT_CIPH)
+		osmo_fsm_inst_dispatch(vsub->proc_arq_fsm, PR_ARQ_E_CIPH_RES,
+				       res);
+}
+
+/* Internal evaluation of requested ciphering mode.
+ * Send set_ciph_mode() to MSC depending on the ciph_mode argument.
+ * \param[in] vlr  VLR instance.
+ * \param[in] fi  Calling FSM instance, for logging.
+ * \param[in] msc_conn_ref  MSC conn to send to.
+ * \param[in] ciph_mode  Ciphering config, to decide whether to do ciphering.
+ * \returns 0 if no ciphering is needed or message was sent successfully,
+ *          or a negative value if ciph_mode is invalid or sending failed.
+ */
+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);
+}
+
+/* Decide whether UMTS AKA should be used.
+ * UTRAN networks are by definition R99 capable, and the auth vector is required to contain UMTS AKA
+ * tokens. This is expected to be verified by the caller. On GERAN, UMTS AKA must be used iff MS and
+ * GERAN are R99 capable and UMTS AKA tokens are available.
+ * \param[in] vec  Auth tokens (received from the HLR).
+ * \param[in] is_r99  True when BTS and GERAN are R99 capable.
+ * \returns true to use UMTS AKA, false to use pre-R99 GSM AKA.
+ */
+bool vlr_use_umts_aka(struct osmo_auth_vector *vec, bool is_r99)
+{
+	if (!is_r99)
+		return false;
+	if (!(vec->auth_types & OSMO_AUTH_TYPE_UMTS))
+		return false;
+	return true;
+}
+
+void log_set_filter_vlr_subscr(struct log_target *target,
+			       struct vlr_subscr *vlr_subscr)
+{
+	struct vlr_subscr **fsub = (void*)&target->filter_data[LOG_FLT_VLR_SUBSCR];
+
+	/* free the old data */
+	if (*fsub) {
+		vlr_subscr_put(*fsub);
+		*fsub = NULL;
+	}
+
+	if (vlr_subscr) {
+		target->filter_map |= (1 << LOG_FLT_VLR_SUBSCR);
+		*fsub = vlr_subscr_get(vlr_subscr);
+	} else
+		target->filter_map &= ~(1 << LOG_FLT_VLR_SUBSCR);
+}
diff --git a/src/libvlr/vlr_access_req_fsm.c b/src/libvlr/vlr_access_req_fsm.c
new file mode 100644
index 0000000..3a0760d
--- /dev/null
+++ b/src/libvlr/vlr_access_req_fsm.c
@@ -0,0 +1,774 @@
+/* Osmocom Visitor Location Register (VLR): Access Request FSMs */
+
+/* (C) 2016 by Harald Welte <laforge@gnumonks.org>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <osmocom/core/fsm.h>
+#include <osmocom/gsm/gsup.h>
+#include <osmocom/gsm/gsm48.h>
+#include <osmocom/msc/vlr.h>
+#include <osmocom/msc/debug.h>
+
+#include "vlr_core.h"
+#include "vlr_auth_fsm.h"
+#include "vlr_lu_fsm.h"
+#include "vlr_access_req_fsm.h"
+
+#define S(x)	(1 << (x))
+
+/***********************************************************************
+ * Process_Access_Request_VLR, TS 29.002 Chapter 25.4.2
+ ***********************************************************************/
+
+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_CIPH_RES),
+	OSMO_VALUE_STRING(PR_ARQ_E_UPD_LOC_RES),
+	OSMO_VALUE_STRING(PR_ARQ_E_TRACE_RES),
+	OSMO_VALUE_STRING(PR_ARQ_E_IMEI_RES),
+	OSMO_VALUE_STRING(PR_ARQ_E_PRES_RES),
+	OSMO_VALUE_STRING(PR_ARQ_E_TMSI_ACK),
+	{ 0, NULL }
+};
+
+struct proc_arq_priv {
+	struct vlr_instance *vlr;
+	struct vlr_subscr *vsub;
+	void *msc_conn_ref;
+	struct osmo_fsm_inst *ul_child_fsm;
+	struct osmo_fsm_inst *sub_pres_vlr_fsm;
+	uint32_t parent_event_success;
+	uint32_t parent_event_failure;
+	void *parent_event_data;
+
+	enum vlr_parq_type type;
+	enum gsm48_reject_value result; /*< 0 on success */
+	bool by_tmsi;
+	char imsi[16];
+	uint32_t tmsi;
+	struct osmo_location_area_id lai;
+	bool authentication_required;
+	bool ciphering_required;
+	bool is_r99;
+	bool is_utran;
+	bool implicitly_accepted_parq_by_ciphering_cmd;
+};
+
+static void assoc_par_with_subscr(struct osmo_fsm_inst *fi, struct vlr_subscr *vsub)
+{
+	struct proc_arq_priv *par = fi->priv;
+	struct vlr_instance *vlr = par->vlr;
+
+	vsub->msc_conn_ref = par->msc_conn_ref;
+	par->vsub = vsub;
+	/* Tell MSC to associate this subscriber with the given
+	 * connection */
+	vlr->ops.subscr_assoc(par->msc_conn_ref, par->vsub);
+}
+
+static const char *vlr_proc_arq_result_name(const struct osmo_fsm_inst *fi)
+{
+	struct proc_arq_priv *par = fi->priv;
+	return par->result? gsm48_reject_value_name(par->result) : "PASSED";
+}
+
+#define proc_arq_fsm_done(fi, res) _proc_arq_fsm_done(fi, res, __FILE__, __LINE__)
+static void _proc_arq_fsm_done(struct osmo_fsm_inst *fi,
+			       enum gsm48_reject_value gsm48_rej,
+			       const char *file, int line)
+{
+	struct proc_arq_priv *par = fi->priv;
+	par->result = gsm48_rej;
+	LOGPFSMSRC(fi, file, line, "proc_arq_fsm_done(%s)\n", vlr_proc_arq_result_name(fi));
+	osmo_fsm_inst_state_chg(fi, PR_ARQ_S_DONE, 0, 0);
+}
+
+static void proc_arq_vlr_dispatch_result(struct osmo_fsm_inst *fi,
+					 uint32_t prev_state)
+{
+	struct proc_arq_priv *par = fi->priv;
+	bool success;
+	int rc;
+	LOGPFSM(fi, "Process Access Request result: %s\n", vlr_proc_arq_result_name(fi));
+
+	success = (par->result == 0);
+
+	/* It would be logical to first dispatch the success event to the
+	 * parent FSM, but that could start actions that send messages to the
+	 * MS. Rather send the CM Service Accept message first and then signal
+	 * success. Since messages are handled synchronously, the success event
+	 * will be processed before we handle new incoming data from the MS. */
+
+	if (par->type == VLR_PR_ARQ_T_CM_SERV_REQ) {
+		if (success
+		    && !par->implicitly_accepted_parq_by_ciphering_cmd) {
+			rc = par->vlr->ops.tx_cm_serv_acc(par->msc_conn_ref);
+			if (rc) {
+				LOGPFSML(fi, LOGL_ERROR,
+					 "Failed to send CM Service Accept\n");
+				success = false;
+			}
+		}
+		if (!success) {
+			rc = par->vlr->ops.tx_cm_serv_rej(par->msc_conn_ref,
+							  par->result);
+			if (rc)
+				LOGPFSML(fi, LOGL_ERROR,
+					 "Failed to send CM Service Reject\n");
+		}
+	}
+
+	/* For VLR_PR_ARQ_T_PAGING_RESP, there is nothing to send. The conn_fsm
+	 * will start handling pending paging transactions. */
+
+	if (!fi->proc.parent) {
+		LOGPFSML(fi, LOGL_ERROR, "No parent FSM");
+		return;
+	}
+	osmo_fsm_inst_dispatch(fi->proc.parent,
+			       success ? par->parent_event_success
+				       : par->parent_event_failure,
+			       par->parent_event_data);
+}
+
+void proc_arq_vlr_cleanup(struct osmo_fsm_inst *fi,
+			  enum osmo_fsm_term_cause cause)
+{
+	struct proc_arq_priv *par = fi->priv;
+	if (par->vsub && par->vsub->proc_arq_fsm == fi)
+		par->vsub->proc_arq_fsm = NULL;
+}
+
+static void _proc_arq_vlr_post_imei(struct osmo_fsm_inst *fi)
+{
+	struct proc_arq_priv *par = fi->priv;
+	struct vlr_subscr *vsub = par->vsub;
+
+	LOGPFSM(fi, "%s()\n", __func__);
+
+	/* See 3GPP TS 29.002 Proc_Acc_Req_VLR3. */
+	/* TODO: Identity := IMSI */
+	if (0 /* TODO: TMSI reallocation at access: vlr->cfg.alloc_tmsi_arq */) {
+		vlr_subscr_alloc_tmsi(vsub);
+		/* TODO: forward TMSI to MS, wait for TMSI
+		 * REALLOC COMPLETE */
+		/* TODO: Freeze old TMSI */
+		osmo_fsm_inst_state_chg(fi, PR_ARQ_S_WAIT_TMSI_ACK, 0, 0);
+		return;
+	}
+
+	proc_arq_fsm_done(fi, 0);
+}
+
+static void _proc_arq_vlr_post_trace(struct osmo_fsm_inst *fi)
+{
+	struct proc_arq_priv *par = fi->priv;
+	struct vlr_subscr *vsub = par->vsub;
+	struct vlr_instance *vlr = vsub->vlr;
+
+	LOGPFSM(fi, "%s()\n", __func__);
+
+	/* Node 3 */
+	/* See 3GPP TS 29.002 Proc_Acc_Req_VLR3. */
+	if (0 /* IMEI check required */) {
+		/* Chck_IMEI_VLR */
+		vlr->ops.tx_id_req(par->msc_conn_ref, GSM_MI_TYPE_IMEI);
+		osmo_fsm_inst_state_chg(fi, PR_ARQ_S_WAIT_CHECK_IMEI,
+					vlr_timer(vlr, 3270), 3270);
+	} else
+		_proc_arq_vlr_post_imei(fi);
+}
+
+/* After Subscriber_Present_VLR */
+static void _proc_arq_vlr_post_pres(struct osmo_fsm_inst *fi)
+{
+	LOGPFSM(fi, "%s()\n", __func__);
+	/* See 3GPP TS 29.002 Proc_Acc_Req_VLR3. */
+	if (0 /* TODO: tracing required */) {
+		/* TODO: Trace_Subscriber_Activity_VLR */
+		osmo_fsm_inst_state_chg(fi, PR_ARQ_S_WAIT_TRACE_SUB, 0, 0);
+	}
+	_proc_arq_vlr_post_trace(fi);
+}
+
+/* After Update_Location_Child_VLR */
+static void _proc_arq_vlr_node2_post_vlr(struct osmo_fsm_inst *fi)
+{
+	struct proc_arq_priv *par = fi->priv;
+	struct vlr_subscr *vsub = par->vsub;
+
+	LOGPFSM(fi, "%s()\n", __func__);
+
+	if (!vsub->sub_dataconf_by_hlr_ind) {
+		/* Set User Error: Unidentified Subscriber */
+		proc_arq_fsm_done(fi, GSM48_REJECT_IMSI_UNKNOWN_IN_HLR);
+		return;
+	}
+	/* We don't feature location area specific blocking (yet). */
+	if (0 /* roaming not allowed in LA */) {
+		/* Set User Error: Roaming not allowed in this LA */
+		proc_arq_fsm_done(fi, GSM48_REJECT_ROAMING_NOT_ALLOWED);
+		return;
+	}
+	vsub->imsi_detached_flag = false;
+	if (vsub->ms_not_reachable_flag) {
+		/* Start Subscriber_Present_VLR */
+		osmo_fsm_inst_state_chg(fi, PR_ARQ_S_WAIT_SUB_PRES, 0, 0);
+		sub_pres_vlr_fsm_start(&par->sub_pres_vlr_fsm, fi, vsub, PR_ARQ_E_PRES_RES);
+		return;
+	}
+	_proc_arq_vlr_post_pres(fi);
+}
+
+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;
+
+	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);
+	}
+
+	vsub->conf_by_radio_contact_ind = true;
+	if (vsub->loc_conf_in_hlr_ind == false) {
+		/* start Update_Location_Child_VLR.  WE use
+		 * Update_HLR_VLR instead, the differences appear
+		 * insignificant for now. */
+		par->ul_child_fsm = upd_hlr_vlr_proc_start(fi, vsub,
+							PR_ARQ_E_UPD_LOC_RES);
+		osmo_fsm_inst_state_chg(fi, PR_ARQ_S_WAIT_UPD_LOC_CHILD, 0, 0);
+		return;
+	}
+	_proc_arq_vlr_node2_post_vlr(fi);
+}
+
+static bool is_ciph_required(struct proc_arq_priv *par)
+{
+	return par->ciphering_required;
+}
+
+static void _proc_arq_vlr_node2(struct osmo_fsm_inst *fi)
+{
+	struct proc_arq_priv *par = fi->priv;
+	struct vlr_subscr *vsub = par->vsub;
+	bool umts_aka;
+
+	LOGPFSM(fi, "%s()\n", __func__);
+
+	if (!is_ciph_required(par)) {
+		_proc_arq_vlr_node2_post_ciph(fi);
+		return;
+	}
+
+	switch (vsub->sec_ctx) {
+	case VLR_SEC_CTX_GSM:
+		umts_aka = false;
+		break;
+	case VLR_SEC_CTX_UMTS:
+		umts_aka = true;
+		break;
+	default:
+		LOGPFSML(fi, LOGL_ERROR, "Cannot start ciphering, security context is not established\n");
+		proc_arq_fsm_done(fi, GSM48_REJECT_NETWORK_FAILURE);
+		return;
+	}
+
+	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,
+			 "Failed to send Ciphering Mode Command\n");
+		proc_arq_fsm_done(fi, GSM48_REJECT_NETWORK_FAILURE);
+		return;
+	}
+
+	par->implicitly_accepted_parq_by_ciphering_cmd = true;
+	osmo_fsm_inst_state_chg(fi, PR_ARQ_S_WAIT_CIPH, 0, 0);
+}
+
+static bool is_auth_required(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;
+}
+
+/* after the IMSI is known */
+static void proc_arq_vlr_fn_post_imsi(struct osmo_fsm_inst *fi)
+{
+	struct proc_arq_priv *par = fi->priv;
+	struct vlr_subscr *vsub = par->vsub;
+
+	LOGPFSM(fi, "%s()\n", __func__);
+
+	OSMO_ASSERT(vsub);
+
+	/* TODO: Identity IMEI -> System Failure */
+	if (is_auth_required(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,
+						PR_ARQ_E_AUTH_RES,
+						par->is_r99,
+						par->is_utran);
+	} else {
+		_proc_arq_vlr_node2(fi);
+	}
+}
+
+static void proc_arq_vlr_fn_init(struct osmo_fsm_inst *fi,
+				 uint32_t event, void *data)
+{
+	struct proc_arq_priv *par = fi->priv;
+	struct vlr_instance *vlr = par->vlr;
+	struct vlr_subscr *vsub = NULL;
+
+	OSMO_ASSERT(event == PR_ARQ_E_START);
+
+	/* Obtain_Identity_VLR */
+	if (!par->by_tmsi) {
+		/* IMSI was included */
+		vsub = vlr_subscr_find_by_imsi(par->vlr, par->imsi);
+	} else {
+		/* TMSI was included */
+		vsub = vlr_subscr_find_by_tmsi(par->vlr, par->tmsi);
+	}
+	if (vsub) {
+		log_set_context(LOG_CTX_VLR_SUBSCR, vsub);
+		if (vsub->proc_arq_fsm && fi != vsub->proc_arq_fsm) {
+			LOGPFSML(fi, LOGL_ERROR,
+				 "Another proc_arq_fsm is already"
+				 " associated with subscr %s,"
+				 " terminating the other FSM.\n",
+				 vlr_subscr_name(vsub));
+			proc_arq_fsm_done(vsub->proc_arq_fsm,
+					  GSM48_REJECT_NETWORK_FAILURE);
+		}
+		vsub->proc_arq_fsm = fi;
+		assoc_par_with_subscr(fi, vsub);
+		proc_arq_vlr_fn_post_imsi(fi);
+		vlr_subscr_put(vsub);
+		return;
+	}
+	/* No VSUB could be resolved. What now? */
+
+	if (!par->by_tmsi) {
+		/* We couldn't find a subscriber even by IMSI,
+		 * Set User Error: Unidentified Subscriber */
+		proc_arq_fsm_done(fi, GSM48_REJECT_IMSI_UNKNOWN_IN_VLR);
+		return;
+	} else {
+		/* TMSI was included, are we permitted to use it? */
+		if (vlr->cfg.parq_retrieve_imsi) {
+			/* Obtain_IMSI_VLR */
+			osmo_fsm_inst_state_chg(fi, PR_ARQ_S_WAIT_OBTAIN_IMSI,
+						vlr_timer(vlr, 3270), 3270);
+			return;
+		} else {
+			/* Set User Error: Unidentified Subscriber */
+			proc_arq_fsm_done(fi, GSM48_REJECT_IMSI_UNKNOWN_IN_VLR);
+			return;
+		}
+	}
+}
+
+/* ID REQ(IMSI) has returned */
+static void proc_arq_vlr_fn_w_obt_imsi(struct osmo_fsm_inst *fi,
+					uint32_t event, void *data)
+{
+	struct proc_arq_priv *par = fi->priv;
+	struct vlr_instance *vlr = par->vlr;
+	struct vlr_subscr *vsub;
+
+	OSMO_ASSERT(event == PR_ARQ_E_ID_IMSI);
+
+	vsub = vlr_subscr_find_by_imsi(vlr, par->imsi);
+	if (!vsub) {
+		/* Set User Error: Unidentified Subscriber */
+		proc_arq_fsm_done(fi, GSM48_REJECT_IMSI_UNKNOWN_IN_VLR);
+		return;
+	}
+	assoc_par_with_subscr(fi, vsub);
+	proc_arq_vlr_fn_post_imsi(fi);
+	vlr_subscr_put(vsub);
+}
+
+/* Authenticate_VLR has completed */
+static void proc_arq_vlr_fn_w_auth(struct osmo_fsm_inst *fi,
+				   uint32_t event, void *data)
+{
+	enum gsm48_reject_value *cause = data;
+
+	OSMO_ASSERT(event == PR_ARQ_E_AUTH_RES);
+
+	if (!cause || *cause) {
+		proc_arq_fsm_done(fi, cause? *cause : GSM48_REJECT_NETWORK_FAILURE);
+		return;
+	}
+
+	/* Node 2 */
+	_proc_arq_vlr_node2(fi);
+}
+
+static void proc_arq_vlr_fn_w_ciph(struct osmo_fsm_inst *fi,
+				   uint32_t event, void *data)
+{
+	struct proc_arq_priv *par = fi->priv;
+	struct vlr_subscr *vsub = par->vsub;
+	struct vlr_ciph_result res = { .cause = VLR_CIPH_REJECT };
+
+	OSMO_ASSERT(event == PR_ARQ_E_CIPH_RES);
+
+	if (!data)
+		LOGPFSML(fi, LOGL_ERROR, "invalid ciphering result: NULL\n");
+	else
+		res = *(struct vlr_ciph_result*)data;
+
+	switch (res.cause) {
+	case VLR_CIPH_COMPL:
+		break;
+	case VLR_CIPH_REJECT:
+		LOGPFSM(fi, "ciphering rejected\n");
+		proc_arq_fsm_done(fi, GSM48_REJECT_ILLEGAL_MS);
+		return;
+	default:
+		LOGPFSML(fi, LOGL_ERROR, "invalid ciphering result: %d\n",
+			 res.cause);
+		proc_arq_fsm_done(fi, GSM48_REJECT_ILLEGAL_MS);
+		return;
+	}
+
+
+	if (*res.imeisv) {
+		LOGPFSM(fi, "got IMEISV: %s\n", res.imeisv);
+		vlr_subscr_set_imeisv(vsub, res.imeisv);
+	}
+	_proc_arq_vlr_node2_post_ciph(fi);
+}
+
+/* Update_Location_Child_VLR has completed */
+static void proc_arq_vlr_fn_w_upd_loc(struct osmo_fsm_inst *fi,
+					uint32_t event, void *data)
+{
+	OSMO_ASSERT(event == PR_ARQ_E_UPD_LOC_RES);
+
+	_proc_arq_vlr_node2_post_vlr(fi);
+}
+
+/* Subscriber_Present_VLR has completed */
+static void proc_arq_vlr_fn_w_pres(struct osmo_fsm_inst *fi,
+					uint32_t event, void *data)
+{
+	OSMO_ASSERT(event == PR_ARQ_E_PRES_RES);
+
+	_proc_arq_vlr_post_pres(fi);
+}
+
+static void proc_arq_vlr_fn_w_trace(struct osmo_fsm_inst *fi,
+					uint32_t event, void *data)
+{
+	OSMO_ASSERT(event == PR_ARQ_E_TRACE_RES);
+
+	_proc_arq_vlr_post_trace(fi);
+}
+
+/* we have received the ID RESPONSE (IMEI) */
+static void proc_arq_vlr_fn_w_imei(struct osmo_fsm_inst *fi,
+				uint32_t event, void *data)
+{
+	OSMO_ASSERT(event == PR_ARQ_E_IMEI_RES);
+
+	_proc_arq_vlr_post_imei(fi);
+}
+
+/* MSC tells us that MS has acknowleded TMSI re-allocation */
+static void proc_arq_vlr_fn_w_tmsi(struct osmo_fsm_inst *fi,
+				uint32_t event, void *data)
+{
+	OSMO_ASSERT(event == PR_ARQ_E_TMSI_ACK);
+
+	/* FIXME: check confirmation? unfreeze? */
+	proc_arq_fsm_done(fi, 0);
+}
+
+static const struct osmo_fsm_state proc_arq_vlr_states[] = {
+	[PR_ARQ_S_INIT] = {
+		.name = OSMO_STRINGIFY(PR_ARQ_S_INIT),
+		.in_event_mask = S(PR_ARQ_E_START),
+		.out_state_mask = S(PR_ARQ_S_DONE) |
+				  S(PR_ARQ_S_WAIT_OBTAIN_IMSI) |
+				  S(PR_ARQ_S_WAIT_AUTH) |
+				  S(PR_ARQ_S_WAIT_UPD_LOC_CHILD) |
+				  S(PR_ARQ_S_WAIT_SUB_PRES) |
+				  S(PR_ARQ_S_WAIT_TRACE_SUB) |
+				  S(PR_ARQ_S_WAIT_CHECK_IMEI) |
+				  S(PR_ARQ_S_WAIT_TMSI_ACK),
+		.action = proc_arq_vlr_fn_init,
+	},
+	[PR_ARQ_S_WAIT_OBTAIN_IMSI] = {
+		.name = OSMO_STRINGIFY(PR_ARQ_S_WAIT_OBTAIN_IMSI),
+		.in_event_mask = S(PR_ARQ_E_ID_IMSI),
+		.out_state_mask = S(PR_ARQ_S_DONE) |
+				  S(PR_ARQ_S_WAIT_AUTH) |
+				  S(PR_ARQ_S_WAIT_UPD_LOC_CHILD) |
+				  S(PR_ARQ_S_WAIT_SUB_PRES) |
+				  S(PR_ARQ_S_WAIT_TRACE_SUB) |
+				  S(PR_ARQ_S_WAIT_CHECK_IMEI) |
+				  S(PR_ARQ_S_WAIT_TMSI_ACK),
+		.action = proc_arq_vlr_fn_w_obt_imsi,
+	},
+	[PR_ARQ_S_WAIT_AUTH] = {
+		.name = OSMO_STRINGIFY(PR_ARQ_S_WAIT_AUTH),
+		.in_event_mask = S(PR_ARQ_E_AUTH_RES),
+		.out_state_mask = S(PR_ARQ_S_DONE) |
+				  S(PR_ARQ_S_WAIT_CIPH) |
+				  S(PR_ARQ_S_WAIT_UPD_LOC_CHILD) |
+				  S(PR_ARQ_S_WAIT_SUB_PRES) |
+				  S(PR_ARQ_S_WAIT_TRACE_SUB) |
+				  S(PR_ARQ_S_WAIT_CHECK_IMEI) |
+				  S(PR_ARQ_S_WAIT_TMSI_ACK),
+		.action = proc_arq_vlr_fn_w_auth,
+	},
+	[PR_ARQ_S_WAIT_CIPH] = {
+		.name = OSMO_STRINGIFY(PR_ARQ_S_WAIT_CIPH),
+		.in_event_mask = S(PR_ARQ_E_CIPH_RES),
+		.out_state_mask = S(PR_ARQ_S_DONE) |
+				  S(PR_ARQ_S_WAIT_UPD_LOC_CHILD) |
+				  S(PR_ARQ_S_WAIT_SUB_PRES) |
+				  S(PR_ARQ_S_WAIT_TRACE_SUB) |
+				  S(PR_ARQ_S_WAIT_CHECK_IMEI) |
+				  S(PR_ARQ_S_WAIT_TMSI_ACK),
+		.action = proc_arq_vlr_fn_w_ciph,
+	},
+	[PR_ARQ_S_WAIT_UPD_LOC_CHILD] = {
+		.name = OSMO_STRINGIFY(PR_ARQ_S_WAIT_UPD_LOC_CHILD),
+		.in_event_mask = S(PR_ARQ_E_UPD_LOC_RES),
+		.out_state_mask = S(PR_ARQ_S_DONE) |
+				  S(PR_ARQ_S_WAIT_SUB_PRES) |
+				  S(PR_ARQ_S_WAIT_TRACE_SUB) |
+				  S(PR_ARQ_S_WAIT_CHECK_IMEI) |
+				  S(PR_ARQ_S_WAIT_TMSI_ACK),
+		.action = proc_arq_vlr_fn_w_upd_loc,
+	},
+	[PR_ARQ_S_WAIT_SUB_PRES] = {
+		.name = OSMO_STRINGIFY(PR_ARQ_S_WAIT_SUB_PRES),
+		.in_event_mask = S(PR_ARQ_E_PRES_RES),
+		.out_state_mask = S(PR_ARQ_S_DONE) |
+				  S(PR_ARQ_S_WAIT_TRACE_SUB) |
+				  S(PR_ARQ_S_WAIT_CHECK_IMEI) |
+				  S(PR_ARQ_S_WAIT_TMSI_ACK),
+		.action = proc_arq_vlr_fn_w_pres,
+	},
+	[PR_ARQ_S_WAIT_TRACE_SUB] = {
+		.name = OSMO_STRINGIFY(PR_ARQ_S_WAIT_TRACE_SUB),
+		.in_event_mask = S(PR_ARQ_E_TRACE_RES),
+		.out_state_mask = S(PR_ARQ_S_DONE) |
+				  S(PR_ARQ_S_WAIT_CHECK_IMEI) |
+				  S(PR_ARQ_S_WAIT_TMSI_ACK),
+		.action = proc_arq_vlr_fn_w_trace,
+	},
+	[PR_ARQ_S_WAIT_CHECK_IMEI] = {
+		.name = OSMO_STRINGIFY(PR_ARQ_S_WAIT_CHECK_IMEI),
+		.in_event_mask = S(PR_ARQ_E_IMEI_RES),
+		.out_state_mask = S(PR_ARQ_S_DONE) |
+				  S(PR_ARQ_S_WAIT_TMSI_ACK),
+		.action = proc_arq_vlr_fn_w_imei,
+	},
+	[PR_ARQ_S_WAIT_TMSI_ACK] = {
+		.name = OSMO_STRINGIFY(PR_ARQ_S_WAIT_TMSI_ACK),
+		.in_event_mask = S(PR_ARQ_E_TMSI_ACK),
+		.out_state_mask = S(PR_ARQ_S_DONE),
+		.action = proc_arq_vlr_fn_w_tmsi,
+	},
+	[PR_ARQ_S_DONE] = {
+		.name = OSMO_STRINGIFY(PR_ARQ_S_DONE),
+		.onenter = proc_arq_vlr_dispatch_result,
+	},
+};
+
+static struct osmo_fsm proc_arq_vlr_fsm = {
+	.name = "Process_Access_Request_VLR",
+	.states = proc_arq_vlr_states,
+	.num_states = ARRAY_SIZE(proc_arq_vlr_states),
+	.allstate_event_mask = 0,
+	.allstate_action = NULL,
+	.log_subsys = DVLR,
+	.event_names = proc_arq_vlr_event_names,
+	.cleanup = proc_arq_vlr_cleanup,
+};
+
+void
+vlr_proc_acc_req(struct osmo_fsm_inst *parent,
+		 uint32_t parent_event_success,
+		 uint32_t parent_event_failure,
+		 void *parent_event_data,
+		 struct vlr_instance *vlr, void *msc_conn_ref,
+		 enum vlr_parq_type type, const uint8_t *mi_lv,
+		 const struct osmo_location_area_id *lai,
+		 bool authentication_required,
+		 bool ciphering_required,
+		 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;
+
+	fi = osmo_fsm_inst_alloc_child(&proc_arq_vlr_fsm, parent,
+				       parent_event_failure);
+	if (!fi)
+		return;
+
+	par = talloc_zero(fi, struct proc_arq_priv);
+	fi->priv = par;
+	par->vlr = vlr;
+	par->msc_conn_ref = msc_conn_ref;
+	par->type = type;
+	par->lai = *lai;
+	par->parent_event_success = parent_event_success;
+	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_r99 = is_r99;
+	par->is_utran = is_utran;
+
+	LOGPFSM(fi, "rev=%s net=%s%s%s\n",
+		is_r99 ? "R99" : "GSM",
+		is_utran ? "UTRAN" : "GERAN",
+		(authentication_required || ciphering_required)?
+		" Auth" : " (no Auth)",
+		(authentication_required || ciphering_required)?
+			(ciphering_required? "+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) {
+	case GSM_MI_TYPE_IMSI:
+		osmo_strlcpy(par->imsi, mi_string, sizeof(par->imsi));
+		par->by_tmsi = false;
+		break;
+	case GSM_MI_TYPE_TMSI:
+		par->by_tmsi = true;
+		par->tmsi = osmo_load32be(mi_lv+2);
+		break;
+	case GSM_MI_TYPE_IMEI:
+		/* TODO: IMEI (emergency call) */
+	default:
+		proc_arq_fsm_done(fi, GSM48_REJECT_INVALID_MANDANTORY_INF);
+		return;
+	}
+
+	osmo_fsm_inst_dispatch(fi, PR_ARQ_E_START, NULL);
+}
+
+/* Gracefully terminate an FSM created by vlr_proc_acc_req() in case of
+ * external timeout (i.e. from MSC). */
+void vlr_parq_cancel(struct osmo_fsm_inst *fi,
+		     enum osmo_fsm_term_cause fsm_cause,
+		     enum gsm48_reject_value gsm48_cause)
+{
+	if (!fi || fi->state == PR_ARQ_S_DONE)
+		return;
+	LOGPFSM(fi, "Cancel: %s\n", osmo_fsm_term_cause_name(fsm_cause));
+	proc_arq_fsm_done(fi, gsm48_cause);
+}
+
+
+#if 0
+/***********************************************************************
+ * Update_Location_Child_VLR, TS 29.002 Chapter 25.4.4
+ ***********************************************************************/
+
+enum upd_loc_child_vlr_state {
+	ULC_S_IDLE,
+	ULC_S_WAIT_HLR_RESP,
+	ULC_S_DONE,
+};
+
+enum upd_loc_child_vlr_event {
+	ULC_E_START,
+};
+
+static const struct value_string upd_loc_child_vlr_event_names[] = {
+	{ ULC_E_START, "START" },
+	{ 0, NULL }
+};
+
+static void upd_loc_child_f_idle(struct osmo_fsm_inst *fi, uint32_t event,
+				 void *data)
+{
+	OSMO_ASSERT(event == ULC_E_START);
+
+	/* send update location */
+}
+
+static void upd_loc_child_f_w_hlr(struct osmo_fsm_inst *fi, uint32_t event,
+				  void *data)
+{
+}
+
+static const struct osmo_fsm_state upd_loc_child_vlr_states[] = {
+	[ULC_S_IDLE] = {
+		.in_event_mask = ,
+		.out_state_mask = S(ULC_S_WAIT_HLR_RESP) |
+				  S(ULC_S_DONE),
+		.name = "IDLE",
+		.action = upd_loc_child_f_idle,
+	},
+	[ULC_S_WAIT_HLR_RESP] = {
+		.in_event_mask = ,
+		.out_state_mask = S(ULC_S_DONE),
+		.name = "WAIT-HLR-RESP",
+		.action = upd_loc_child_f_w_hlr,
+	},
+	[ULC_S_DONE] = {
+		.name = "DONE",
+	},
+};
+
+static struct osmo_fsm upd_loc_child_vlr_fsm = {
+	.name = "Update_Location_Child_VLR",
+	.states = upd_loc_child_vlr_states,
+	.num_states = ARRAY_SIZE(upd_loc_child_vlr_states),
+	.log_subsys = DVLR,
+	.event_names = upd_loc_child_vlr_event_names,
+};
+#endif
+
+void vlr_parq_fsm_init(void)
+{
+	//osmo_fsm_register(&upd_loc_child_vlr_fsm);
+	osmo_fsm_register(&proc_arq_vlr_fsm);
+}
diff --git a/src/libvlr/vlr_access_req_fsm.h b/src/libvlr/vlr_access_req_fsm.h
new file mode 100644
index 0000000..8386da6
--- /dev/null
+++ b/src/libvlr/vlr_access_req_fsm.h
@@ -0,0 +1,17 @@
+#pragma once
+
+enum proc_arq_vlr_state {
+	PR_ARQ_S_INIT,
+	/* Waiting for Obtain_Identity_VLR (IMSI) result */
+	PR_ARQ_S_WAIT_OBTAIN_IMSI,
+	/* Waiting for Authenticate_VLR result */
+	PR_ARQ_S_WAIT_AUTH,
+	PR_ARQ_S_WAIT_CIPH,
+	PR_ARQ_S_WAIT_UPD_LOC_CHILD,
+	PR_ARQ_S_WAIT_SUB_PRES,
+	PR_ARQ_S_WAIT_TRACE_SUB,
+	PR_ARQ_S_WAIT_CHECK_IMEI,
+	PR_ARQ_S_WAIT_TMSI_ACK,
+	PR_ARQ_S_WAIT_CECK_CONF,
+	PR_ARQ_S_DONE,
+};
diff --git a/src/libvlr/vlr_auth_fsm.c b/src/libvlr/vlr_auth_fsm.c
new file mode 100644
index 0000000..d5a8555
--- /dev/null
+++ b/src/libvlr/vlr_auth_fsm.c
@@ -0,0 +1,627 @@
+/* Osmocom Visitor Location Register (VLR) Autentication FSM */
+
+/* (C) 2016 by Harald Welte <laforge@gnumonks.org>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include <osmocom/core/fsm.h>
+#include <osmocom/core/utils.h>
+#include <osmocom/gsm/gsup.h>
+#include <osmocom/msc/vlr.h>
+#include <osmocom/msc/debug.h>
+
+#include "vlr_core.h"
+#include "vlr_auth_fsm.h"
+
+#define S(x)	(1 << (x))
+
+static const struct value_string fsm_auth_event_names[] = {
+	OSMO_VALUE_STRING(VLR_AUTH_E_START),
+	OSMO_VALUE_STRING(VLR_AUTH_E_HLR_SAI_ACK),
+	OSMO_VALUE_STRING(VLR_AUTH_E_HLR_SAI_NACK),
+	OSMO_VALUE_STRING(VLR_AUTH_E_HLR_SAI_ABORT),
+	OSMO_VALUE_STRING(VLR_AUTH_E_MS_AUTH_RESP),
+	OSMO_VALUE_STRING(VLR_AUTH_E_MS_AUTH_FAIL),
+	OSMO_VALUE_STRING(VLR_AUTH_E_MS_ID_IMSI),
+	{ 0, NULL }
+};
+
+/* private state of the auth_fsm_instance */
+struct auth_fsm_priv {
+	struct vlr_subscr *vsub;
+	bool by_imsi;
+	bool is_r99;
+	bool is_utran;
+	bool auth_requested;
+
+	int auth_tuple_max_reuse_count; /* see vlr->cfg instead */
+};
+
+/***********************************************************************
+ * Utility functions
+ ***********************************************************************/
+
+/* Always use either vlr_subscr_get_auth_tuple() or vlr_subscr_has_auth_tuple()
+ * instead, to ensure proper use count.
+ * Return an auth tuple with the lowest use_count among the auth tuples. If
+ * max_reuse_count >= 0, return NULL if all available auth tuples have a use
+ * count > max_reuse_count. If max_reuse_count is negative, return a currently
+ * least used auth tuple without enforcing a maximum use count.  If there are
+ * no auth tuples, return NULL.
+ */
+static struct gsm_auth_tuple *
+_vlr_subscr_next_auth_tuple(struct vlr_subscr *vsub, int max_reuse_count)
+{
+	unsigned int count;
+	unsigned int idx;
+	struct gsm_auth_tuple *at = NULL;
+	unsigned int key_seq = GSM_KEY_SEQ_INVAL;
+
+	if (!vsub)
+		return NULL;
+
+	if (vsub->last_tuple)
+		key_seq = vsub->last_tuple->key_seq;
+
+	if (key_seq == GSM_KEY_SEQ_INVAL)
+		/* Start with 0 after increment modulo array size */
+		idx = ARRAY_SIZE(vsub->auth_tuples) - 1;
+	else
+		idx = key_seq;
+
+	for (count = ARRAY_SIZE(vsub->auth_tuples); count > 0; count--) {
+		idx = (idx + 1) % ARRAY_SIZE(vsub->auth_tuples);
+
+		if (vsub->auth_tuples[idx].key_seq == GSM_KEY_SEQ_INVAL)
+			continue;
+
+		if (!at || vsub->auth_tuples[idx].use_count < at->use_count)
+			at = &vsub->auth_tuples[idx];
+	}
+
+	if (!at || (max_reuse_count >= 0 && at->use_count > max_reuse_count))
+		return NULL;
+
+	return at;
+}
+
+/* Return an auth tuple and increment its use count. */
+static struct gsm_auth_tuple *
+vlr_subscr_get_auth_tuple(struct vlr_subscr *vsub, int max_reuse_count)
+{
+	struct gsm_auth_tuple *at = _vlr_subscr_next_auth_tuple(vsub,
+							       max_reuse_count);
+	if (!at)
+		return NULL;
+	at->use_count++;
+	return at;
+}
+
+/* Return whether an auth tuple with a matching use_count is available. */
+static bool vlr_subscr_has_auth_tuple(struct vlr_subscr *vsub,
+				      int max_reuse_count)
+{
+	return _vlr_subscr_next_auth_tuple(vsub, max_reuse_count) != NULL;
+}
+
+static bool check_auth_resp(struct vlr_subscr *vsub, bool is_r99,
+			    bool is_utran, const uint8_t *res,
+			    uint8_t res_len)
+{
+	struct gsm_auth_tuple *at = vsub->last_tuple;
+	struct osmo_auth_vector *vec = &at->vec;
+	bool check_umts;
+	bool res_is_umts_aka;
+	OSMO_ASSERT(at);
+
+	LOGVSUBP(LOGL_DEBUG, vsub, "AUTH on %s received %s: %s (%u bytes)\n",
+		 is_utran ? "UTRAN" : "GERAN",
+		 is_utran ? "RES" : "SRES/RES",
+		 osmo_hexdump_nospc(res, res_len), res_len);
+
+	/* RES must be present and at least 32bit */
+	if (!res || !res_len) {
+		LOGVSUBP(LOGL_NOTICE, vsub, "AUTH SRES/RES missing\n");
+		goto out_false;
+	}
+
+	/* We're deciding the UMTS AKA-ness of the response by the RES size. So let's make sure we can't
+	 * mix them up by size. On UTRAN, we expect full length RES always, no way to mix up there. */
+	if (!is_utran && vec->res_len == sizeof(vec->sres))
+		LOGVSUBP(LOGL_ERROR, vsub, "Unforeseen situation: UMTS AKA's RES length"
+			 " equals the size of SRES: %u -- this code wants to differentiate"
+			 " the two by their size, which won't work properly now.\n", vec->res_len);
+
+	/* RES must be either vec->res_len (UMTS AKA) or sizeof(sres) (GSM AKA) */
+	if (res_len == vec->res_len)
+		res_is_umts_aka = true;
+	else if (res_len == sizeof(vec->sres))
+		res_is_umts_aka = false;
+	else {
+		if (is_utran)
+			LOGVSUBP(LOGL_NOTICE, vsub, "AUTH RES has invalid length: %u."
+				 " Expected %u (UMTS AKA)\n",
+				 res_len, vec->res_len);
+		else
+			LOGVSUBP(LOGL_NOTICE, vsub, "AUTH SRES/RES has invalid length: %u."
+				 " Expected either %zu (GSM AKA) or %u (UMTS AKA)\n",
+				 res_len, sizeof(vec->sres), vec->res_len);
+		goto out_false;
+	}
+
+	check_umts = (is_r99
+		      && (vec->auth_types & OSMO_AUTH_TYPE_UMTS)
+		      && res_is_umts_aka);
+
+	/* Even on an R99 capable MS with a UMTS AKA capable USIM,
+	 * the MS may still choose to only perform GSM AKA, as
+	 * long as the bearer is GERAN -- never on UTRAN: */
+	if (is_utran && !check_umts) {
+		LOGVSUBP(LOGL_ERROR, vsub,
+			 "AUTH via UTRAN, cannot allow GSM AKA"
+			 " (MS is %sR99 capable, vec has %sUMTS AKA tokens, res_len=%u is %s)\n",
+			 is_r99 ? "" : "NOT ",
+			 (vec->auth_types & OSMO_AUTH_TYPE_UMTS) ? "" : "NO ",
+			 res_len, (res_len == vec->res_len)? "valid" : "INVALID on UTRAN");
+		goto out_false;
+	}
+
+	if (check_umts) {
+		if (res_len != vec->res_len
+		    || memcmp(res, vec->res, res_len)) {
+			LOGVSUBP(LOGL_INFO, vsub, "UMTS AUTH failure:"
+				 " mismatching res (expected res=%s)\n",
+				 osmo_hexdump(vec->res, vec->res_len));
+			goto out_false;
+		}
+
+		LOGVSUBP(LOGL_INFO, vsub, "AUTH established UMTS security"
+			 " context\n");
+		vsub->sec_ctx = VLR_SEC_CTX_UMTS;
+		return true;
+	} else {
+		if (res_len != sizeof(vec->sres)
+		    || memcmp(res, vec->sres, sizeof(vec->sres))) {
+			LOGVSUBP(LOGL_INFO, vsub, "GSM AUTH failure:"
+				 " mismatching sres (expected sres=%s)\n",
+				 osmo_hexdump(vec->sres, sizeof(vec->sres)));
+			goto out_false;
+		}
+
+		LOGVSUBP(LOGL_INFO, vsub, "AUTH established GSM security"
+			 " context\n");
+		vsub->sec_ctx = VLR_SEC_CTX_GSM;
+		return true;
+	}
+
+out_false:
+	vsub->sec_ctx = VLR_SEC_CTX_NONE;
+	return false;
+}
+
+static void auth_fsm_onenter_failed(struct osmo_fsm_inst *fi, uint32_t prev_state)
+{
+	struct auth_fsm_priv *afp = fi->priv;
+	struct vlr_subscr *vsub = afp->vsub;
+
+	/* If authentication hasn't even started, e.g. the HLR sent no auth
+	 * info, then we also don't need to tell the HLR about an auth failure.
+	 */
+	if (afp->auth_requested) {
+		int rc = vlr_subscr_tx_auth_fail_rep(vsub);
+		if (rc < 0)
+			LOGVSUBP(LOGL_ERROR, vsub, "Failed to communicate AUTH failure to HLR\n");
+	}
+}
+
+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);
+}
+
+/* Terminate the Auth FSM Instance and notify parent */
+static void auth_fsm_term(struct osmo_fsm_inst *fi, enum gsm48_reject_value result)
+{
+	struct auth_fsm_priv *afp = fi->priv;
+	struct vlr_subscr *vsub = afp->vsub;
+
+	LOGPFSM(fi, "Authentication terminating with result %s\n",
+		vlr_auth_fsm_result_name(result));
+
+	/* Do one final state transition (mostly for logging purpose) */
+	if (!result)
+		osmo_fsm_inst_state_chg(fi, VLR_SUB_AS_AUTHENTICATED, 0, 0);
+	else
+		osmo_fsm_inst_state_chg(fi, VLR_SUB_AS_AUTH_FAILED, 0, 0);
+
+	/* return the result to the parent FSM */
+	osmo_fsm_inst_term(fi, OSMO_FSM_TERM_REGULAR, &result);
+	vsub->auth_fsm = NULL;
+}
+
+/* back-end function transmitting authentication. Caller ensures we have valid
+ * tuple */
+static int _vlr_subscr_authenticate(struct osmo_fsm_inst *fi)
+{
+	struct auth_fsm_priv *afp = fi->priv;
+	struct vlr_subscr *vsub = afp->vsub;
+	struct gsm_auth_tuple *at;
+	bool use_umts_aka;
+
+	/* Caller ensures we have vectors available */
+	at = vlr_subscr_get_auth_tuple(vsub, afp->auth_tuple_max_reuse_count);
+	if (!at) {
+		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);
+		return -1;
+	}
+
+	use_umts_aka = vlr_use_umts_aka(&at->vec, afp->is_r99);
+	LOGPFSM(fi, "got auth tuple: use_count=%d key_seq=%d"
+		" -- will use %s AKA (is_r99=%s, at->vec.auth_types=0x%x)\n",
+		at->use_count, at->key_seq,
+		use_umts_aka ? "UMTS" : "GSM", afp->is_r99 ? "yes" : "no", at->vec.auth_types);
+
+	/* Transmit auth req to subscriber */
+	afp->auth_requested = true;
+	vsub->last_tuple = at;
+	vsub->vlr->ops.tx_auth_req(vsub->msc_conn_ref, at, use_umts_aka);
+	return 0;
+}
+
+/***********************************************************************
+ * FSM State Action functions
+ ***********************************************************************/
+
+/* Initial State of TS 23.018 AUT_VLR */
+static void auth_fsm_needs_auth(struct osmo_fsm_inst *fi, uint32_t event, void *data)
+{
+	struct auth_fsm_priv *afp = fi->priv;
+	struct vlr_subscr *vsub = afp->vsub;
+
+	OSMO_ASSERT(event == VLR_AUTH_E_START);
+
+	/* Start off with the default max_reuse_count, possibly change that if we
+	 * need to re-use an old tuple. */
+	afp->auth_tuple_max_reuse_count = vsub->vlr->cfg.auth_tuple_max_reuse_count;
+
+	/* Check if we have vectors available */
+	if (!vlr_subscr_has_auth_tuple(vsub, afp->auth_tuple_max_reuse_count)) {
+		/* Obtain_Authentication_Sets_VLR */
+		int rc = vlr_subscr_req_sai(vsub, NULL, NULL);
+		if (rc < 0)
+			LOGPFSM(fi, "Failed to request Authentication Sets from VLR\n");
+		osmo_fsm_inst_state_chg(fi, VLR_SUB_AS_NEEDS_AUTH_WAIT_AI,
+					GSM_29002_TIMER_M, 0);
+	} else {
+		/* go straight ahead with sending auth request */
+		osmo_fsm_inst_state_chg(fi, VLR_SUB_AS_WAIT_RESP,
+					vlr_timer(vsub->vlr, 3260), 3260);
+		_vlr_subscr_authenticate(fi);
+	}
+}
+
+/* Waiting for Authentication Info from HLR */
+static void auth_fsm_wait_ai(struct osmo_fsm_inst *fi, uint32_t event,
+			     void *data)
+{
+	struct auth_fsm_priv *afp = fi->priv;
+	struct vlr_subscr *vsub = afp->vsub;
+	struct osmo_gsup_message *gsup = data;
+
+	if (event == VLR_AUTH_E_HLR_SAI_NACK)
+		LOGPFSM(fi, "GSUP: rx Auth Info Error cause: %d: %s\n",
+			gsup->cause,
+			get_value_string(gsm48_gmm_cause_names, gsup->cause));
+
+	/* We are in what corresponds to the
+	 * Wait_For_Authentication_Sets state of TS 23.018 OAS_VLR */
+	if ((event == VLR_AUTH_E_HLR_SAI_ACK && !gsup->num_auth_vectors)
+	    || (event == VLR_AUTH_E_HLR_SAI_NACK &&
+		gsup->cause != GMM_CAUSE_IMSI_UNKNOWN)
+	    || (event == VLR_AUTH_E_HLR_SAI_ABORT)) {
+		if (vsub->vlr->cfg.auth_reuse_old_sets_on_error
+		    && vlr_subscr_has_auth_tuple(vsub, -1)) {
+			/* To re-use an old tuple, disable the max_reuse_count
+			 * constraint. */
+			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:
+		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);
+		break;
+	}
+
+	return;
+pass:
+	osmo_fsm_inst_state_chg(fi, VLR_SUB_AS_WAIT_RESP,
+				vlr_timer(vsub->vlr, 3260), 3260);
+	_vlr_subscr_authenticate(fi);
+}
+
+/* Waiting for Authentication Response from MS */
+static void auth_fsm_wait_auth_resp(struct osmo_fsm_inst *fi, uint32_t event,
+				    void *data)
+{
+	struct auth_fsm_priv *afp = fi->priv;
+	struct vlr_subscr *vsub = afp->vsub;
+	struct vlr_instance *vlr = vsub->vlr;
+	struct vlr_auth_resp_par *par = data;
+	int rc;
+
+	switch (event) {
+	case VLR_AUTH_E_MS_AUTH_RESP:
+		rc = check_auth_resp(vsub, par->is_r99, par->is_utran,
+				     par->res, par->res_len);
+		if (rc == false) {
+			if (!afp->by_imsi) {
+				vlr->ops.tx_id_req(vsub->msc_conn_ref,
+						   GSM_MI_TYPE_IMSI);
+				osmo_fsm_inst_state_chg(fi,
+						VLR_SUB_AS_WAIT_ID_IMSI,
+						vlr_timer(vlr, 3270), 3270);
+			} else {
+				auth_fsm_term(fi, GSM48_REJECT_ILLEGAL_MS);
+			}
+		} else {
+			auth_fsm_term(fi, 0);
+		}
+		break;
+	case VLR_AUTH_E_MS_AUTH_FAIL:
+		if (par->auts) {
+			/* First failure, start re-sync attempt */
+			rc = vlr_subscr_req_sai(vsub, par->auts,
+					   vsub->last_tuple->vec.rand);
+			osmo_fsm_inst_state_chg(fi,
+					VLR_SUB_AS_NEEDS_AUTH_WAIT_SAI_RESYNC,
+					GSM_29002_TIMER_M, 0);
+		} else
+			auth_fsm_term(fi, GSM48_REJECT_ILLEGAL_MS);
+		break;
+	}
+}
+
+/* Waiting for Authentication Info from HLR (resync case) */
+static void auth_fsm_wait_ai_resync(struct osmo_fsm_inst *fi,
+				    uint32_t event, void *data)
+{
+	struct auth_fsm_priv *afp = fi->priv;
+	struct vlr_subscr *vsub = afp->vsub;
+	struct osmo_gsup_message *gsup = data;
+
+	/* We are in what corresponds to the
+	 * Wait_For_Authentication_Sets state of TS 23.018 OAS_VLR */
+	if ((event == VLR_AUTH_E_HLR_SAI_ACK && !gsup->num_auth_vectors) ||
+	    (event == VLR_AUTH_E_HLR_SAI_NACK &&
+	     gsup->cause != GMM_CAUSE_IMSI_UNKNOWN) ||
+	    (event == VLR_AUTH_E_HLR_SAI_ABORT)) {
+		/* result = procedure error */
+		auth_fsm_term(fi, GSM48_REJECT_NETWORK_FAILURE);
+	}
+	switch (event) {
+	case VLR_AUTH_E_HLR_SAI_ACK:
+		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);
+		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) */
+static void auth_fsm_wait_auth_resp_resync(struct osmo_fsm_inst *fi,
+					   uint32_t event, void *data)
+{
+	struct auth_fsm_priv *afp = fi->priv;
+	struct vlr_subscr *vsub = afp->vsub;
+	struct vlr_auth_resp_par *par = data;
+	struct vlr_instance *vlr = vsub->vlr;
+	int rc;
+
+	switch (event) {
+	case VLR_AUTH_E_MS_AUTH_RESP:
+		rc = check_auth_resp(vsub, par->is_r99, par->is_utran,
+				     par->res, par->res_len);
+		if (rc == false) {
+			if (!afp->by_imsi) {
+				vlr->ops.tx_id_req(vsub->msc_conn_ref,
+						   GSM_MI_TYPE_IMSI);
+				osmo_fsm_inst_state_chg(fi,
+						VLR_SUB_AS_WAIT_ID_IMSI,
+						vlr_timer(vlr, 3270), 3270);
+			} else {
+				/* Result = Aborted */
+				auth_fsm_term(fi, GSM48_REJECT_SYNCH_FAILURE);
+			}
+		} else {
+			/* Result = Pass */
+			auth_fsm_term(fi, 0);
+		}
+		break;
+	case VLR_AUTH_E_MS_AUTH_FAIL:
+		/* Second failure: Result = Fail */
+		auth_fsm_term(fi, GSM48_REJECT_SYNCH_FAILURE);
+		break;
+	}
+}
+
+/* AUT_VLR waiting for Obtain_IMSI_VLR result */
+static void auth_fsm_wait_imsi(struct osmo_fsm_inst *fi, uint32_t event,
+				void *data)
+{
+	struct auth_fsm_priv *afp = fi->priv;
+	struct vlr_subscr *vsub = afp->vsub;
+	const char *mi_string = data;
+
+	switch (event) {
+	case VLR_AUTH_E_MS_ID_IMSI:
+		if (vsub->imsi[0]
+		    && !vlr_subscr_matches_imsi(vsub, mi_string)) {
+			LOGVSUBP(LOGL_ERROR, vsub, "IMSI in ID RESP differs:"
+				 " %s\n", mi_string);
+		} else {
+			strncpy(vsub->imsi, mi_string, sizeof(vsub->imsi));
+			vsub->imsi[sizeof(vsub->imsi)-1] = '\0';
+		}
+		/* retry with identity=IMSI */
+		afp->by_imsi = true;
+		osmo_fsm_inst_state_chg(fi, VLR_SUB_AS_NEEDS_AUTH, 0, 0);
+		osmo_fsm_inst_dispatch(fi, VLR_AUTH_E_START, NULL);
+		break;
+	}
+}
+
+static const struct osmo_fsm_state auth_fsm_states[] = {
+	[VLR_SUB_AS_NEEDS_AUTH] = {
+		.name = OSMO_STRINGIFY(VLR_SUB_AS_NEEDS_AUTH),
+		.in_event_mask = S(VLR_AUTH_E_START),
+		.out_state_mask = S(VLR_SUB_AS_NEEDS_AUTH_WAIT_AI) |
+				  S(VLR_SUB_AS_WAIT_RESP),
+		.action = auth_fsm_needs_auth,
+	},
+	[VLR_SUB_AS_NEEDS_AUTH_WAIT_AI] = {
+		.name = OSMO_STRINGIFY(VLR_SUB_AS_NEEDS_AUTH_WAIT_AI),
+		.in_event_mask = S(VLR_AUTH_E_HLR_SAI_ACK) |
+				 S(VLR_AUTH_E_HLR_SAI_NACK),
+		.out_state_mask = S(VLR_SUB_AS_AUTH_FAILED) |
+				  S(VLR_SUB_AS_WAIT_RESP),
+		.action = auth_fsm_wait_ai,
+	},
+	[VLR_SUB_AS_WAIT_RESP] = {
+		.name = OSMO_STRINGIFY(VLR_SUB_AS_WAIT_RESP),
+		.in_event_mask = S(VLR_AUTH_E_MS_AUTH_RESP) |
+				 S(VLR_AUTH_E_MS_AUTH_FAIL),
+		.out_state_mask = S(VLR_SUB_AS_WAIT_ID_IMSI) |
+				  S(VLR_SUB_AS_AUTH_FAILED) |
+				  S(VLR_SUB_AS_AUTHENTICATED) |
+				  S(VLR_SUB_AS_NEEDS_AUTH_WAIT_SAI_RESYNC),
+		.action = auth_fsm_wait_auth_resp,
+	},
+	[VLR_SUB_AS_NEEDS_AUTH_WAIT_SAI_RESYNC] = {
+		.name = OSMO_STRINGIFY(VLR_SUB_AS_NEEDS_AUTH_WAIT_SAI_RESYNC),
+		.in_event_mask = S(VLR_AUTH_E_HLR_SAI_ACK) |
+				 S(VLR_AUTH_E_HLR_SAI_NACK),
+		.out_state_mask = S(VLR_SUB_AS_AUTH_FAILED) |
+				  S(VLR_SUB_AS_WAIT_RESP_RESYNC),
+		.action = auth_fsm_wait_ai_resync,
+	},
+	[VLR_SUB_AS_WAIT_RESP_RESYNC] = {
+		.name = OSMO_STRINGIFY(VLR_SUB_AS_WAIT_RESP_RESYNC),
+		.in_event_mask = S(VLR_AUTH_E_MS_AUTH_RESP) |
+				 S(VLR_AUTH_E_MS_AUTH_FAIL),
+		.out_state_mask = S(VLR_SUB_AS_AUTH_FAILED) |
+				  S(VLR_SUB_AS_AUTHENTICATED),
+		.action = auth_fsm_wait_auth_resp_resync,
+	},
+	[VLR_SUB_AS_WAIT_ID_IMSI] = {
+		.name = OSMO_STRINGIFY(VLR_SUB_AS_WAIT_ID_IMSI),
+		.in_event_mask = S(VLR_AUTH_E_MS_ID_IMSI),
+		.out_state_mask = S(VLR_SUB_AS_NEEDS_AUTH),
+		.action = auth_fsm_wait_imsi,
+	},
+	[VLR_SUB_AS_AUTHENTICATED] = {
+		.name = OSMO_STRINGIFY(VLR_SUB_AS_AUTHENTICATED),
+		.in_event_mask = 0,
+		.out_state_mask = 0,
+	},
+	[VLR_SUB_AS_AUTH_FAILED] = {
+		.name = OSMO_STRINGIFY(VLR_SUB_AS_AUTH_FAILED),
+		.in_event_mask = 0,
+		.out_state_mask = 0,
+		.onenter = auth_fsm_onenter_failed,
+	},
+};
+
+struct osmo_fsm vlr_auth_fsm = {
+	.name = "VLR_Authenticate",
+	.states = auth_fsm_states,
+	.num_states = ARRAY_SIZE(auth_fsm_states),
+	.allstate_event_mask = 0,
+	.allstate_action = NULL,
+	.log_subsys = DVLR,
+	.event_names = fsm_auth_event_names,
+};
+
+/***********************************************************************
+ * User API (for SGSN/MSC code)
+ ***********************************************************************/
+
+/* 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,
+				     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);
+	if (!fi) {
+		osmo_fsm_inst_dispatch(parent, parent_term_event, 0);
+		return NULL;
+	}
+
+	afp = talloc_zero(fi, struct auth_fsm_priv);
+	if (!afp) {
+		osmo_fsm_inst_dispatch(parent, parent_term_event, 0);
+		return NULL;
+	}
+
+	afp->vsub = vsub;
+	if (vsub->imsi[0])
+		afp->by_imsi = true;
+	afp->is_r99 = is_r99;
+	afp->is_utran = is_utran;
+	fi->priv = afp;
+	vsub->auth_fsm = fi;
+
+	osmo_fsm_inst_dispatch(fi, VLR_AUTH_E_START, NULL);
+
+	return fi;
+}
diff --git a/src/libvlr/vlr_auth_fsm.h b/src/libvlr/vlr_auth_fsm.h
new file mode 100644
index 0000000..618462f
--- /dev/null
+++ b/src/libvlr/vlr_auth_fsm.h
@@ -0,0 +1,37 @@
+#pragma once
+
+#include <osmocom/core/utils.h>
+
+/* Parameters to VLR_AUTH_E_MS_AUTH_RESP */
+struct vlr_auth_resp_par {
+	bool is_r99;
+	bool is_utran;
+	const uint8_t *res;
+	unsigned int res_len;
+	const uint8_t *auts;
+};
+
+enum vlr_fsm_auth_event {
+	VLR_AUTH_E_START,
+	/* TS 23.018 OAS_VLR1(2): SendAuthInfo ACK from HLR */
+	VLR_AUTH_E_HLR_SAI_ACK,
+	/* TS 23.018 OAS_VLR1(2): SendAuthInfo NACK from HLR */
+	VLR_AUTH_E_HLR_SAI_NACK,
+	/* FIXME: merge with NACK? */
+	VLR_AUTH_E_HLR_SAI_ABORT,
+	/* Authentication Response from MS */
+	VLR_AUTH_E_MS_AUTH_RESP,
+	/* Authentication Failure from MS */
+	VLR_AUTH_E_MS_AUTH_FAIL,
+	/* Identity Response (IMSI) from MS */
+	VLR_AUTH_E_MS_ID_IMSI,
+};
+
+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,
+				     bool is_r99,
+				     bool is_utran);
diff --git a/src/libvlr/vlr_core.h b/src/libvlr/vlr_core.h
new file mode 100644
index 0000000..d336b1b
--- /dev/null
+++ b/src/libvlr/vlr_core.h
@@ -0,0 +1,13 @@
+#pragma once
+
+#include <osmocom/msc/vlr.h>
+
+struct osmo_gsup_message;
+
+const char *vlr_subscr_name(struct vlr_subscr *vsub);
+int vlr_subscr_req_lu(struct vlr_subscr *vsub) __attribute__((warn_unused_result));
+int vlr_subscr_req_sai(struct vlr_subscr *vsub, const uint8_t *auts,
+		       const uint8_t *auts_rand) __attribute__((warn_unused_result));
+struct vlr_subscr *vlr_subscr_alloc(struct vlr_instance *vlr);
+void vlr_subscr_update_tuples(struct vlr_subscr *vsub,
+			      const struct osmo_gsup_message *gsup);
diff --git a/src/libvlr/vlr_lu_fsm.c b/src/libvlr/vlr_lu_fsm.c
new file mode 100644
index 0000000..02e49e0
--- /dev/null
+++ b/src/libvlr/vlr_lu_fsm.c
@@ -0,0 +1,1488 @@
+/* Osmocom Visitor Location Register (VLR): Location Update FSMs */
+
+/* (C) 2016 by Harald Welte <laforge@gnumonks.org>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <osmocom/core/fsm.h>
+#include <osmocom/gsm/gsm48.h>
+#include <osmocom/msc/vlr.h>
+#include <osmocom/msc/debug.h>
+
+#include "vlr_core.h"
+#include "vlr_auth_fsm.h"
+#include "vlr_lu_fsm.h"
+
+#define S(x)	(1 << (x))
+
+#define LU_TIMEOUT_LONG		30
+
+enum vlr_fsm_result {
+	VLR_FSM_RESULT_NONE,
+	VLR_FSM_RESULT_SUCCESS,
+	VLR_FSM_RESULT_FAILURE,
+};
+
+
+/***********************************************************************
+ * Update_HLR_VLR, TS 23.012 Chapter 4.1.2.4
+ ***********************************************************************/
+
+enum upd_hlr_vlr_state {
+	UPD_HLR_VLR_S_INIT,
+	UPD_HLR_VLR_S_WAIT_FOR_DATA,
+	UPD_HLR_VLR_S_DONE,
+};
+
+enum upd_hlr_vlr_evt {
+	UPD_HLR_VLR_E_START,
+	UPD_HLR_VLR_E_INS_SUB_DATA,
+	UPD_HLR_VLR_E_ACT_TRACE_MODE,
+	UPD_HLR_VLR_E_FW_CHECK_SS_IND,
+	UPD_HLR_VLR_E_UPD_LOC_ACK,
+	UPD_HLR_VLR_E_UPD_LOC_NACK,
+};
+
+static const struct value_string upd_hlr_vlr_event_names[] = {
+	OSMO_VALUE_STRING(UPD_HLR_VLR_E_START),
+	OSMO_VALUE_STRING(UPD_HLR_VLR_E_INS_SUB_DATA),
+	OSMO_VALUE_STRING(UPD_HLR_VLR_E_ACT_TRACE_MODE),
+	OSMO_VALUE_STRING(UPD_HLR_VLR_E_FW_CHECK_SS_IND),
+	OSMO_VALUE_STRING(UPD_HLR_VLR_E_UPD_LOC_ACK),
+	OSMO_VALUE_STRING(UPD_HLR_VLR_E_UPD_LOC_NACK),
+	{ 0, NULL }
+};
+
+static inline struct vlr_subscr *upd_hlr_vlr_fi_priv(struct osmo_fsm_inst *fi);
+
+static void upd_hlr_vlr_fsm_init(struct osmo_fsm_inst *fi, uint32_t event,
+				 void *data)
+{
+	struct vlr_subscr *vsub = upd_hlr_vlr_fi_priv(fi);
+	int rc;
+
+	OSMO_ASSERT(event == UPD_HLR_VLR_E_START);
+
+	/* Send UpdateLocation to HLR */
+	rc = vlr_subscr_req_lu(vsub);
+	if (rc < 0)
+		LOGPFSML(fi, LOGL_ERROR, "Failed to send UpdateLocation to HLR\n");
+	osmo_fsm_inst_state_chg(fi, UPD_HLR_VLR_S_WAIT_FOR_DATA,
+				LU_TIMEOUT_LONG, 0);
+}
+
+static void upd_hlr_vlr_fsm_wait_data(struct osmo_fsm_inst *fi, uint32_t event,
+				      void *data)
+{
+	struct vlr_subscr *vsub = upd_hlr_vlr_fi_priv(fi);
+
+	switch (event) {
+	case UPD_HLR_VLR_E_INS_SUB_DATA:
+		/* FIXME: Insert_Subscr_Data_VLR */
+		break;
+	case UPD_HLR_VLR_E_ACT_TRACE_MODE:
+		/* TODO: Activate_Tracing_VLR */
+		break;
+	case UPD_HLR_VLR_E_FW_CHECK_SS_IND:
+		/* TODO: Forward Check SS Ind to MSC */
+		break;
+	case UPD_HLR_VLR_E_UPD_LOC_ACK:
+		/* Inside Update_HLR_VLR after UpdateLocationAck */
+		vsub->sub_dataconf_by_hlr_ind = true;
+		vsub->loc_conf_in_hlr_ind = true;
+		osmo_fsm_inst_state_chg(fi, UPD_HLR_VLR_S_DONE, 0, 0);
+		osmo_fsm_inst_term(fi, OSMO_FSM_TERM_REGULAR, NULL);
+		break;
+	case UPD_HLR_VLR_E_UPD_LOC_NACK:
+		/* Inside Update_HLR_VLR after UpdateLocationNack */
+		/* TODO: Check_User_Error_In_Serving_Network_Entity */
+		vsub->sub_dataconf_by_hlr_ind = false;
+		vsub->loc_conf_in_hlr_ind = false;
+		osmo_fsm_inst_state_chg(fi, UPD_HLR_VLR_S_DONE, 0, 0);
+		/* Data is a pointer to a gsm48_gmm_cause which we
+		 * simply pass through */
+		osmo_fsm_inst_term(fi, OSMO_FSM_TERM_REGULAR, data);
+		break;
+	}
+}
+
+static const struct osmo_fsm_state upd_hlr_vlr_states[] = {
+	[UPD_HLR_VLR_S_INIT] = {
+		.in_event_mask = S(UPD_HLR_VLR_E_START),
+		.out_state_mask = S(UPD_HLR_VLR_S_WAIT_FOR_DATA),
+		.name = OSMO_STRINGIFY(UPD_HLR_VLR_S_INIT),
+		.action = upd_hlr_vlr_fsm_init,
+	},
+	[UPD_HLR_VLR_S_WAIT_FOR_DATA] = {
+		.in_event_mask = S(UPD_HLR_VLR_E_INS_SUB_DATA) |
+				 S(UPD_HLR_VLR_E_ACT_TRACE_MODE) |
+				 S(UPD_HLR_VLR_E_FW_CHECK_SS_IND) |
+				 S(UPD_HLR_VLR_E_UPD_LOC_ACK) |
+				 S(UPD_HLR_VLR_E_UPD_LOC_NACK),
+		.out_state_mask = S(UPD_HLR_VLR_S_DONE),
+		.name = OSMO_STRINGIFY(UPD_HLR_VLR_S_WAIT_FOR_DATA),
+		.action = upd_hlr_vlr_fsm_wait_data,
+	},
+	[UPD_HLR_VLR_S_DONE] = {
+		.name = OSMO_STRINGIFY(UPD_HLR_VLR_S_DONE),
+	},
+};
+
+static struct osmo_fsm upd_hlr_vlr_fsm = {
+	.name = "upd_hlr_vlr_fsm",
+	.states = upd_hlr_vlr_states,
+	.num_states = ARRAY_SIZE(upd_hlr_vlr_states),
+	.allstate_event_mask = 0,
+	.allstate_action = NULL,
+	.log_subsys = DVLR,
+	.event_names = upd_hlr_vlr_event_names,
+};
+
+static inline struct vlr_subscr *upd_hlr_vlr_fi_priv(struct osmo_fsm_inst *fi)
+{
+	OSMO_ASSERT(fi->fsm == &upd_hlr_vlr_fsm);
+	return (struct vlr_subscr*)fi->priv;
+}
+
+struct osmo_fsm_inst *
+upd_hlr_vlr_proc_start(struct osmo_fsm_inst *parent,
+		       struct vlr_subscr *vsub,
+		       uint32_t parent_event)
+{
+	struct osmo_fsm_inst *fi;
+
+	fi = osmo_fsm_inst_alloc_child(&upd_hlr_vlr_fsm, parent,
+					parent_event);
+	if (!fi)
+		return NULL;
+
+	fi->priv = vsub;
+	osmo_fsm_inst_dispatch(fi, UPD_HLR_VLR_E_START, NULL);
+
+	return fi;
+}
+
+
+/***********************************************************************
+ * Subscriber_Present_VLR, TS 29.002 Chapter 25.10.1
+ ***********************************************************************/
+
+enum sub_pres_vlr_state {
+	SUB_PRES_VLR_S_INIT,
+	SUB_PRES_VLR_S_WAIT_FOR_HLR,
+	SUB_PRES_VLR_S_DONE,
+};
+
+enum sub_pres_vlr_event {
+	SUB_PRES_VLR_E_START,
+	SUB_PRES_VLR_E_READY_SM_CNF,
+	SUB_PRES_VLR_E_READY_SM_ERR,
+};
+
+static const struct value_string sub_pres_vlr_event_names[] = {
+	OSMO_VALUE_STRING(SUB_PRES_VLR_E_START),
+	OSMO_VALUE_STRING(SUB_PRES_VLR_E_READY_SM_CNF),
+	OSMO_VALUE_STRING(SUB_PRES_VLR_E_READY_SM_ERR),
+	{ 0, NULL }
+};
+
+static inline struct vlr_subscr *sub_pres_vlr_fi_priv(struct osmo_fsm_inst *fi);
+
+static void sub_pres_vlr_fsm_init(struct osmo_fsm_inst *fi, uint32_t event,
+				  void *data)
+{
+	struct vlr_subscr *vsub = sub_pres_vlr_fi_priv(fi);
+	OSMO_ASSERT(event == SUB_PRES_VLR_E_START);
+
+	if (!vsub->ms_not_reachable_flag) {
+		osmo_fsm_inst_state_chg(fi, SUB_PRES_VLR_S_DONE, 0, 0);
+		osmo_fsm_inst_term(fi, OSMO_FSM_TERM_REGULAR, NULL);
+		return;
+	}
+	/* FIXME: Send READY_FOR_SM via GSUP */
+	osmo_fsm_inst_state_chg(fi, SUB_PRES_VLR_S_WAIT_FOR_HLR,
+				LU_TIMEOUT_LONG, 0);
+}
+
+static void sub_pres_vlr_fsm_wait_hlr(struct osmo_fsm_inst *fi, uint32_t event,
+				      void *data)
+{
+	struct vlr_subscr *vsub = sub_pres_vlr_fi_priv(fi);
+
+	switch (event) {
+	case SUB_PRES_VLR_E_READY_SM_CNF:
+		vsub->ms_not_reachable_flag = false;
+		break;
+	case SUB_PRES_VLR_E_READY_SM_ERR:
+		break;
+	}
+	osmo_fsm_inst_state_chg(fi, SUB_PRES_VLR_S_DONE, 0, 0);
+	osmo_fsm_inst_term(fi, OSMO_FSM_TERM_REGULAR, NULL);
+}
+
+static const struct osmo_fsm_state sub_pres_vlr_states[] = {
+	[SUB_PRES_VLR_S_INIT] = {
+		.in_event_mask = S(SUB_PRES_VLR_E_START),
+		.out_state_mask = S(SUB_PRES_VLR_S_WAIT_FOR_HLR) |
+				  S(SUB_PRES_VLR_S_DONE),
+		.name = OSMO_STRINGIFY(SUB_PRES_VLR_S_INIT),
+		.action = sub_pres_vlr_fsm_init,
+	},
+	[SUB_PRES_VLR_S_WAIT_FOR_HLR] = {
+		.in_event_mask = S(SUB_PRES_VLR_E_READY_SM_CNF) |
+				 S(SUB_PRES_VLR_E_READY_SM_ERR),
+		.out_state_mask = S(SUB_PRES_VLR_S_DONE),
+		.name = OSMO_STRINGIFY(SUB_PRES_VLR_S_WAIT_FOR_HLR),
+		.action = sub_pres_vlr_fsm_wait_hlr,
+	},
+	[SUB_PRES_VLR_S_DONE] = {
+		.name = OSMO_STRINGIFY(SUB_PRES_VLR_S_DONE),
+	},
+};
+
+static struct osmo_fsm sub_pres_vlr_fsm = {
+	.name = "sub_pres_vlr_fsm",
+	.states = sub_pres_vlr_states,
+	.num_states = ARRAY_SIZE(sub_pres_vlr_states),
+	.allstate_event_mask = 0,
+	.allstate_action = NULL,
+	.log_subsys = DVLR,
+	.event_names = sub_pres_vlr_event_names,
+};
+
+static inline struct vlr_subscr *sub_pres_vlr_fi_priv(struct osmo_fsm_inst *fi)
+{
+	OSMO_ASSERT(fi->fsm == &sub_pres_vlr_fsm);
+	return (struct vlr_subscr*)fi->priv;
+}
+
+/* Note that the start event is dispatched right away, so in case the FSM immediately concludes from that
+ * event, the created FSM struct may no longer be valid as it already deallocated again, and it may
+ * furthermore already have invoked the parent FSM instance's deallocation as well. Hence, instead of
+ * returning, store the created FSM instance address in *fi_p before dispatching the event. It is thus
+ * possible to store the instance's pointer in a parent FSM instance without running danger of using
+ * already freed memory. */
+void sub_pres_vlr_fsm_start(struct osmo_fsm_inst **fi_p,
+			    struct osmo_fsm_inst *parent,
+			    struct vlr_subscr *vsub,
+			    uint32_t term_event)
+{
+	struct osmo_fsm_inst *fi;
+
+	OSMO_ASSERT(fi_p);
+
+	fi = osmo_fsm_inst_alloc_child(&sub_pres_vlr_fsm, parent,
+					term_event);
+	*fi_p = fi;
+	if (!fi)
+		return;
+
+	fi->priv = vsub;
+	osmo_fsm_inst_dispatch(fi, SUB_PRES_VLR_E_START, NULL);
+}
+
+/***********************************************************************
+ * Location_Update_Completion_VLR, TS 23.012 Chapter 4.1.2.3
+ ***********************************************************************/
+
+enum lu_compl_vlr_state {
+	LU_COMPL_VLR_S_INIT,
+	LU_COMPL_VLR_S_WAIT_SUB_PRES,
+	LU_COMPL_VLR_S_WAIT_IMEI,
+	LU_COMPL_VLR_S_WAIT_IMEI_TMSI,
+	LU_COMPL_VLR_S_WAIT_TMSI_CNF,
+	LU_COMPL_VLR_S_DONE,
+};
+
+enum lu_compl_vlr_event {
+	LU_COMPL_VLR_E_START,
+	LU_COMPL_VLR_E_SUB_PRES_COMPL,
+	LU_COMPL_VLR_E_IMEI_CHECK_ACK,
+	LU_COMPL_VLR_E_IMEI_CHECK_NACK,
+	LU_COMPL_VLR_E_NEW_TMSI_ACK,
+};
+
+static const struct value_string lu_compl_vlr_event_names[] = {
+	OSMO_VALUE_STRING(LU_COMPL_VLR_E_START),
+	OSMO_VALUE_STRING(LU_COMPL_VLR_E_SUB_PRES_COMPL),
+	OSMO_VALUE_STRING(LU_COMPL_VLR_E_IMEI_CHECK_ACK),
+	OSMO_VALUE_STRING(LU_COMPL_VLR_E_IMEI_CHECK_NACK),
+	OSMO_VALUE_STRING(LU_COMPL_VLR_E_NEW_TMSI_ACK),
+	{ 0, NULL }
+};
+
+struct lu_compl_vlr_priv {
+	struct vlr_subscr *vsub;
+	void *msc_conn_ref;
+	struct osmo_fsm_inst *sub_pres_vlr_fsm;
+	uint32_t parent_event_success;
+	uint32_t parent_event_failure;
+	void *parent_event_data;
+	enum vlr_fsm_result result;
+	uint8_t cause;
+	bool assign_tmsi;
+};
+
+static inline struct lu_compl_vlr_priv *lu_compl_vlr_fi_priv(struct osmo_fsm_inst *fi);
+
+static void _vlr_lu_compl_fsm_done(struct osmo_fsm_inst *fi,
+				   enum vlr_fsm_result result,
+				   uint8_t cause)
+{
+	struct lu_compl_vlr_priv *lcvp = lu_compl_vlr_fi_priv(fi);
+	lcvp->result = result;
+	lcvp->cause = cause;
+	osmo_fsm_inst_state_chg(fi, LU_COMPL_VLR_S_DONE, 0, 0);
+}
+
+static void vlr_lu_compl_fsm_success(struct osmo_fsm_inst *fi)
+{
+	struct lu_compl_vlr_priv *lcvp = lu_compl_vlr_fi_priv(fi);
+	struct vlr_subscr *vsub = lcvp->vsub;
+	if (!vsub->lu_complete) {
+		vsub->lu_complete = true;
+		/* Balanced by vlr_subscr_expire() */
+		vlr_subscr_get(vsub);
+	}
+	_vlr_lu_compl_fsm_done(fi, VLR_FSM_RESULT_SUCCESS, 0);
+}
+
+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)
+{
+	struct lu_compl_vlr_priv *lcvp = lu_compl_vlr_fi_priv(fi);
+	if (!fi->proc.parent) {
+		LOGPFSML(fi, LOGL_ERROR, "No parent FSM\n");
+		return;
+	}
+	osmo_fsm_inst_dispatch(fi->proc.parent,
+			       (lcvp->result == VLR_FSM_RESULT_SUCCESS)
+			       ? lcvp->parent_event_success
+			       : lcvp->parent_event_failure,
+			       &lcvp->cause);
+}
+
+static void lu_compl_vlr_init(struct osmo_fsm_inst *fi, uint32_t event,
+			      void *data)
+{
+	struct lu_compl_vlr_priv *lcvp = lu_compl_vlr_fi_priv(fi);
+	struct vlr_subscr *vsub = lcvp->vsub;
+	struct vlr_instance *vlr;
+	OSMO_ASSERT(vsub);
+	vlr = vsub->vlr;
+	OSMO_ASSERT(vlr);
+
+	OSMO_ASSERT(event == LU_COMPL_VLR_E_START);
+
+	/* TODO: National Roaming restrictions? */
+	/* TODO: Roaming restriction due to unsupported feature in subscriber
+	 * data? */
+	/* TODO: Regional subscription restriction? */
+	/* TODO: Administrative restriction of subscribres' access feature? */
+	/* TODO: AccessRestrictuionData parameter available? */
+	/* TODO: AccessRestrictionData permits RAT? */
+	/* Node 1 */
+	/* TODO: Autonomous CSG supported in VPLMN and allowed by HPLMN? */
+	/* TODO: Hybrid Cel / CSG Cell */
+	/* Node 2 */
+	vsub->la_allowed = true;
+	vsub->imsi_detached_flag = false;
+	/* Start Subscriber_Present_VLR Procedure */
+	osmo_fsm_inst_state_chg(fi, LU_COMPL_VLR_S_WAIT_SUB_PRES,
+				LU_TIMEOUT_LONG, 0);
+
+	sub_pres_vlr_fsm_start(&lcvp->sub_pres_vlr_fsm, fi, vsub, LU_COMPL_VLR_E_SUB_PRES_COMPL);
+}
+
+static void lu_compl_vlr_new_tmsi(struct osmo_fsm_inst *fi)
+{
+	struct lu_compl_vlr_priv *lcvp = lu_compl_vlr_fi_priv(fi);
+	struct vlr_subscr *vsub = lcvp->vsub;
+	struct vlr_instance *vlr = vsub->vlr;
+
+	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);
+		return;
+	}
+
+	osmo_fsm_inst_state_chg(fi, LU_COMPL_VLR_S_WAIT_TMSI_CNF,
+				vlr_timer(vlr, 3250), 3250);
+
+	vlr->ops.tx_lu_acc(lcvp->msc_conn_ref, vsub->tmsi_new);
+}
+
+/* After completion of Subscriber_Present_VLR */
+static void lu_compl_vlr_wait_subscr_pres(struct osmo_fsm_inst *fi,
+					  uint32_t event,
+					  void *data)
+{
+	struct lu_compl_vlr_priv *lcvp = lu_compl_vlr_fi_priv(fi);
+	struct vlr_subscr *vsub = lcvp->vsub;
+	struct vlr_instance *vlr = vsub->vlr;
+
+	OSMO_ASSERT(event == LU_COMPL_VLR_E_SUB_PRES_COMPL);
+
+	lcvp->sub_pres_vlr_fsm = NULL;
+
+	/* TODO: Trace_Subscriber_Activity_VLR */
+
+	if (vlr->cfg.check_imei_rqd) {
+		/* Check IMEI VLR */
+		osmo_fsm_inst_state_chg(fi,
+					lcvp->assign_tmsi ?
+					  LU_COMPL_VLR_S_WAIT_IMEI_TMSI
+					: LU_COMPL_VLR_S_WAIT_IMEI,
+					vlr_timer(vlr, 3270), 3270);
+		vlr->ops.tx_id_req(lcvp->msc_conn_ref, GSM_MI_TYPE_IMEI);
+		return;
+	}
+
+	/* Do we need to allocate a TMSI? */
+	if (lcvp->assign_tmsi) {
+		lu_compl_vlr_new_tmsi(fi);
+		return;
+	}
+
+	/* Location Updating Accept */
+	vlr->ops.tx_lu_acc(lcvp->msc_conn_ref, GSM_RESERVED_TMSI);
+	vlr_lu_compl_fsm_success(fi);
+}
+
+/* Waiting for completion of CHECK_IMEI_VLR */
+static void lu_compl_vlr_wait_imei(struct osmo_fsm_inst *fi, uint32_t event,
+				   void *data)
+{
+	struct lu_compl_vlr_priv *lcvp = lu_compl_vlr_fi_priv(fi);
+	struct vlr_subscr *vsub = lcvp->vsub;
+	struct vlr_instance *vlr = vsub->vlr;
+
+	switch (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);
+			return;
+		}
+		/* Pass */
+		break;
+
+	case LU_COMPL_VLR_E_IMEI_CHECK_NACK:
+		vlr_lu_compl_fsm_failure(fi, GSM48_REJECT_ILLEGAL_ME);
+		/* FIXME: IMEI Check Fail to VLR Application (Detach IMSI VLR) */
+		return;
+	}
+
+	/* IMEI is available. Allocate TMSI if needed. */
+	if (lcvp->assign_tmsi) {
+		if (fi->state != LU_COMPL_VLR_S_WAIT_IMEI_TMSI)
+			LOGPFSML(fi, LOGL_ERROR,
+				 "TMSI required, expected to be in state"
+				 " LU_COMPL_VLR_S_WAIT_IMEI_TMSI,"
+				 " am in %s instead\n",
+				 osmo_fsm_state_name(fi->fsm, fi->state));
+			/* Logged an error, continue anyway. */
+
+		lu_compl_vlr_new_tmsi(fi);
+
+		/* Wait for TMSI ack */
+		return;
+	}
+
+	/* No TMSI needed, accept now. */
+	vlr->ops.tx_lu_acc(lcvp->msc_conn_ref, GSM_RESERVED_TMSI);
+	vlr_lu_compl_fsm_success(fi);
+}
+
+static inline struct lu_compl_vlr_priv *lu_compl_vlr_fi_priv(struct osmo_fsm_inst *fi);
+
+/* Waiting for TMSI confirmation */
+static void lu_compl_vlr_wait_tmsi(struct osmo_fsm_inst *fi, uint32_t event,
+				   void *data)
+{
+	struct lu_compl_vlr_priv *lcvp = lu_compl_vlr_fi_priv(fi);
+	struct vlr_subscr *vsub = lcvp->vsub;
+
+	OSMO_ASSERT(event == LU_COMPL_VLR_E_NEW_TMSI_ACK);
+
+	if (!vsub || vsub->tmsi_new == GSM_RESERVED_TMSI) {
+		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);
+		return;
+	}
+
+	vsub->tmsi = vsub->tmsi_new;
+	vsub->tmsi_new = GSM_RESERVED_TMSI;
+
+	vlr_lu_compl_fsm_success(fi);
+}
+
+static const struct osmo_fsm_state lu_compl_vlr_states[] = {
+	[LU_COMPL_VLR_S_INIT] = {
+		.in_event_mask = S(LU_COMPL_VLR_E_START),
+		.out_state_mask = S(LU_COMPL_VLR_S_DONE) |
+				  S(LU_COMPL_VLR_S_WAIT_SUB_PRES) |
+				  S(LU_COMPL_VLR_S_WAIT_IMEI),
+		.name = OSMO_STRINGIFY(LU_COMPL_VLR_S_INIT),
+		.action = lu_compl_vlr_init,
+	},
+	[LU_COMPL_VLR_S_WAIT_SUB_PRES] = {
+		.in_event_mask = S(LU_COMPL_VLR_E_SUB_PRES_COMPL),
+		.out_state_mask = S(LU_COMPL_VLR_S_WAIT_IMEI) |
+				  S(LU_COMPL_VLR_S_WAIT_IMEI_TMSI) |
+				  S(LU_COMPL_VLR_S_WAIT_TMSI_CNF) |
+				  S(LU_COMPL_VLR_S_DONE),
+		.name = OSMO_STRINGIFY(LU_COMPL_VLR_S_WAIT_SUB_PRES),
+		.action = lu_compl_vlr_wait_subscr_pres,
+	},
+	[LU_COMPL_VLR_S_WAIT_IMEI] = {
+		.in_event_mask = S(LU_COMPL_VLR_E_IMEI_CHECK_ACK) |
+				 S(LU_COMPL_VLR_E_IMEI_CHECK_NACK),
+		.out_state_mask = S(LU_COMPL_VLR_S_DONE),
+		.name = OSMO_STRINGIFY(LU_COMPL_VLR_S_WAIT_IMEI),
+		.action = lu_compl_vlr_wait_imei,
+	},
+	[LU_COMPL_VLR_S_WAIT_IMEI_TMSI] = {
+		.in_event_mask = S(LU_COMPL_VLR_E_IMEI_CHECK_ACK) |
+				 S(LU_COMPL_VLR_E_IMEI_CHECK_NACK),
+		.out_state_mask = S(LU_COMPL_VLR_S_DONE) |
+				  S(LU_COMPL_VLR_S_WAIT_TMSI_CNF),
+		.name = OSMO_STRINGIFY(LU_COMPL_VLR_S_WAIT_IMEI_TMSI),
+		.action = lu_compl_vlr_wait_imei,
+	},
+	[LU_COMPL_VLR_S_WAIT_TMSI_CNF] = {
+		.in_event_mask = S(LU_COMPL_VLR_E_NEW_TMSI_ACK),
+		.out_state_mask = S(LU_COMPL_VLR_S_DONE),
+		.name = OSMO_STRINGIFY(LU_COMPL_VLR_S_WAIT_TMSI_CNF),
+		.action = lu_compl_vlr_wait_tmsi,
+	},
+	[LU_COMPL_VLR_S_DONE] = {
+		.name = OSMO_STRINGIFY(LU_COMPL_VLR_S_DONE),
+		.onenter = vlr_lu_compl_fsm_dispatch_result,
+	},
+};
+
+static struct osmo_fsm lu_compl_vlr_fsm = {
+	.name = "lu_compl_vlr_fsm",
+	.states = lu_compl_vlr_states,
+	.num_states = ARRAY_SIZE(lu_compl_vlr_states),
+	.allstate_event_mask = 0,
+	.allstate_action = NULL,
+	.log_subsys = DVLR,
+	.event_names = lu_compl_vlr_event_names,
+};
+
+static inline struct lu_compl_vlr_priv *lu_compl_vlr_fi_priv(struct osmo_fsm_inst *fi)
+{
+	OSMO_ASSERT(fi->fsm == &lu_compl_vlr_fsm);
+	return (struct lu_compl_vlr_priv*)fi->priv;
+}
+
+struct osmo_fsm_inst *
+lu_compl_vlr_proc_alloc(struct osmo_fsm_inst *parent,
+			struct vlr_subscr *vsub,
+			void *msc_conn_ref,
+			uint32_t parent_event_success,
+			uint32_t parent_event_failure,
+			bool assign_tmsi)
+{
+	struct osmo_fsm_inst *fi;
+	struct lu_compl_vlr_priv *lcvp;
+
+	fi = osmo_fsm_inst_alloc_child(&lu_compl_vlr_fsm, parent,
+				       parent_event_failure);
+	if (!fi)
+		return NULL;
+
+	lcvp = talloc_zero(fi, struct lu_compl_vlr_priv);
+	lcvp->vsub = vsub;
+	lcvp->msc_conn_ref = msc_conn_ref;
+	lcvp->parent_event_success = parent_event_success;
+	lcvp->parent_event_failure = parent_event_failure;
+	lcvp->assign_tmsi = assign_tmsi;
+	fi->priv = lcvp;
+
+	return fi;
+}
+
+
+/***********************************************************************
+ * Update_Location_Area_VLR, TS 23.012 Chapter 4.1.2.1
+ ***********************************************************************/
+
+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_CIPH_RES),
+	OSMO_VALUE_STRING(VLR_ULA_E_ID_IMSI),
+	OSMO_VALUE_STRING(VLR_ULA_E_ID_IMEI),
+	OSMO_VALUE_STRING(VLR_ULA_E_ID_IMEISV),
+	OSMO_VALUE_STRING(VLR_ULA_E_HLR_LU_RES),
+	OSMO_VALUE_STRING(VLR_ULA_E_UPD_HLR_COMPL),
+	OSMO_VALUE_STRING(VLR_ULA_E_LU_COMPL_SUCCESS),
+	OSMO_VALUE_STRING(VLR_ULA_E_LU_COMPL_FAILURE),
+	OSMO_VALUE_STRING(VLR_ULA_E_NEW_TMSI_ACK),
+	{ 0, NULL }
+};
+
+struct lu_fsm_priv {
+	struct vlr_instance *vlr;
+	struct vlr_subscr *vsub;
+	void *msc_conn_ref;
+	struct osmo_fsm_inst *upd_hlr_vlr_fsm;
+	struct osmo_fsm_inst *lu_compl_vlr_fsm;
+	uint32_t parent_event_success;
+	uint32_t parent_event_failure;
+	void *parent_event_data;
+	enum vlr_fsm_result result;
+	uint8_t rej_cause;
+
+	enum vlr_lu_type type;
+	bool lu_by_tmsi;
+	char imsi[16];
+	uint32_t tmsi;
+	struct osmo_location_area_id old_lai;
+	struct osmo_location_area_id new_lai;
+	bool authentication_required;
+	bool ciphering_required;
+	bool is_r99;
+	bool is_utran;
+	bool assign_tmsi;
+};
+
+
+/* Determine if given location area is served by this VLR */
+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 */
+	return true;
+}
+
+/* Determine if authentication is required */
+static bool is_auth_required(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;
+}
+
+/* Determine if ciphering is required */
+static bool is_ciph_required(struct lu_fsm_priv *lfp)
+{
+	return lfp->ciphering_required;
+}
+
+/* Determine if a HLR Update is required */
+static bool hlr_update_needed(struct vlr_subscr *vsub)
+{
+	/* TODO: properly decide this, rather than always assuming we
+	 * need to update the HLR. */
+	return true;
+}
+
+static inline struct lu_fsm_priv *lu_fsm_fi_priv(struct osmo_fsm_inst *fi);
+
+static void lu_fsm_dispatch_result(struct osmo_fsm_inst *fi,
+				   uint32_t prev_state)
+{
+	struct lu_fsm_priv *lfp = lu_fsm_fi_priv(fi);
+	if (!fi->proc.parent) {
+		LOGPFSML(fi, LOGL_ERROR, "No parent FSM\n");
+		return;
+	}
+	osmo_fsm_inst_dispatch(fi->proc.parent,
+			       (lfp->result == VLR_FSM_RESULT_SUCCESS)
+			       ? lfp->parent_event_success
+			       : lfp->parent_event_failure,
+			       lfp->parent_event_data);
+}
+
+static void _lu_fsm_done(struct osmo_fsm_inst *fi,
+			 enum vlr_fsm_result result)
+{
+	struct lu_fsm_priv *lfp = lu_fsm_fi_priv(fi);
+	lfp->result = result;
+	osmo_fsm_inst_state_chg(fi, VLR_ULA_S_DONE, 0, 0);
+}
+
+static void lu_fsm_success(struct osmo_fsm_inst *fi)
+{
+	_lu_fsm_done(fi, VLR_FSM_RESULT_SUCCESS);
+}
+
+static void lu_fsm_failure(struct osmo_fsm_inst *fi, enum gsm48_reject_value rej_cause)
+{
+	struct lu_fsm_priv *lfp = lu_fsm_fi_priv(fi);
+	lfp->vlr->ops.tx_lu_rej(lfp->msc_conn_ref, rej_cause ? : GSM48_REJECT_NETWORK_FAILURE);
+	_lu_fsm_done(fi, VLR_FSM_RESULT_FAILURE);
+}
+
+static void vlr_loc_upd_start_lu_compl_fsm(struct osmo_fsm_inst *fi)
+{
+	struct lu_fsm_priv *lfp = lu_fsm_fi_priv(fi);
+	lfp->lu_compl_vlr_fsm =
+		lu_compl_vlr_proc_alloc(fi, lfp->vsub, lfp->msc_conn_ref,
+					VLR_ULA_E_LU_COMPL_SUCCESS,
+					VLR_ULA_E_LU_COMPL_FAILURE,
+					lfp->assign_tmsi);
+
+	osmo_fsm_inst_dispatch(lfp->lu_compl_vlr_fsm, LU_COMPL_VLR_E_START, NULL);
+}
+
+static void lu_fsm_discard_lu_compl_fsm(struct osmo_fsm_inst *fi)
+{
+	struct lu_fsm_priv *lfp = lu_fsm_fi_priv(fi);
+	if (!lfp->lu_compl_vlr_fsm)
+		return;
+	osmo_fsm_inst_term(lfp->lu_compl_vlr_fsm, OSMO_FSM_TERM_PARENT, NULL);
+}
+
+/* 4.1.2.1 Node 4 */
+static void vlr_loc_upd_node_4(struct osmo_fsm_inst *fi)
+{
+	struct lu_fsm_priv *lfp = lu_fsm_fi_priv(fi);
+	struct vlr_subscr *vsub = lfp->vsub;
+	bool hlr_unknown = false;
+
+	LOGPFSM(fi, "%s()\n", __func__);
+
+	if (hlr_unknown) {
+		/* FIXME: Delete subscriber record */
+		/* LU REJ: Roaming not allowed */
+		lu_fsm_failure(fi, GSM48_REJECT_ROAMING_NOT_ALLOWED);
+	} else {
+		/* Update_HLR_VLR */
+		osmo_fsm_inst_state_chg(fi, VLR_ULA_S_WAIT_HLR_UPD,
+					LU_TIMEOUT_LONG, 0);
+		lfp->upd_hlr_vlr_fsm =
+			upd_hlr_vlr_proc_start(fi, vsub, VLR_ULA_E_UPD_HLR_COMPL);
+	}
+}
+
+/* 4.1.2.1 Node B */
+static void vlr_loc_upd_node_b(struct osmo_fsm_inst *fi)
+{
+	LOGPFSM(fi, "%s()\n", __func__);
+
+	/* OsmoHLR does not support PgA, neither stores the IMEISV, so we have no need to update the HLR
+	 * with either. TODO: depend on actual HLR configuration. See 3GPP TS 23.012 Release 14, process
+	 * Update_Location_Area_VLR (ULA_VLR2). */
+	if (0) { /* IMEISV or PgA to send */
+		vlr_loc_upd_node_4(fi);
+	} else {
+		/* Location_Update_Completion */
+		osmo_fsm_inst_state_chg(fi, VLR_ULA_S_WAIT_LU_COMPL,
+					LU_TIMEOUT_LONG, 0);
+		vlr_loc_upd_start_lu_compl_fsm(fi);
+	}
+}
+
+/* Non-standard: after Ciphering Mode Complete (or no ciph required) */
+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;
+
+	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);
+	}
+
+	vsub->conf_by_radio_contact_ind = true;
+	/* Update LAI */
+	vsub->cgi.lai = lfp->new_lai;
+	vsub->dormant_ind = false;
+	vsub->cancel_loc_rx = false;
+	if (hlr_update_needed(vsub)) {
+		vlr_loc_upd_node_4(fi);
+	} else {
+		/* TODO: ADD Support */
+		/* TODO: Node A: PgA Support */
+		vlr_loc_upd_node_b(fi);
+	}
+}
+
+/* 4.1.2.1 after Authentication successful (or no auth rqd) */
+static void vlr_loc_upd_post_auth(struct osmo_fsm_inst *fi)
+{
+	struct lu_fsm_priv *lfp = lu_fsm_fi_priv(fi);
+	struct vlr_subscr *vsub = lfp->vsub;
+	bool umts_aka;
+
+	LOGPFSM(fi, "%s()\n", __func__);
+
+	OSMO_ASSERT(vsub);
+
+	if (!is_ciph_required(lfp)) {
+		vlr_loc_upd_post_ciph(fi);
+		return;
+	}
+
+	if (!vsub->last_tuple) {
+		LOGPFSML(fi, LOGL_ERROR, "No auth tuple available\n");
+		lu_fsm_failure(fi, GSM48_REJECT_NETWORK_FAILURE);
+		return;
+	}
+
+	switch (vsub->sec_ctx) {
+	case VLR_SEC_CTX_GSM:
+		umts_aka = false;
+		break;
+	case VLR_SEC_CTX_UMTS:
+		umts_aka = true;
+		break;
+	default:
+		LOGPFSML(fi, LOGL_ERROR, "Cannot start ciphering, security context is not established\n");
+		lu_fsm_failure(fi, GSM48_REJECT_NETWORK_FAILURE);
+		return;
+	}
+
+	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,
+			 "Failed to send Ciphering Mode Command\n");
+		lu_fsm_failure(fi, GSM48_REJECT_NETWORK_FAILURE);
+		return;
+	}
+
+	osmo_fsm_inst_state_chg(fi, VLR_ULA_S_WAIT_CIPH, LU_TIMEOUT_LONG, 0);
+}
+
+static void vlr_loc_upd_node1(struct osmo_fsm_inst *fi)
+{
+	struct lu_fsm_priv *lfp = lu_fsm_fi_priv(fi);
+	struct vlr_subscr *vsub = lfp->vsub;
+
+	LOGPFSM(fi, "%s()\n", __func__);
+
+	OSMO_ASSERT(vsub);
+
+	if (is_auth_required(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,
+						lfp->is_r99,
+						lfp->is_utran);
+	} else {
+		/* no need for authentication */
+		vlr_loc_upd_post_auth(fi);
+	}
+}
+
+static void vlr_loc_upd_want_imsi(struct osmo_fsm_inst *fi)
+{
+	struct lu_fsm_priv *lfp = lu_fsm_fi_priv(fi);
+	struct vlr_instance *vlr = lfp->vlr;
+
+	LOGPFSM(fi, "%s()\n", __func__);
+
+	OSMO_ASSERT(lfp->vsub);
+
+	/* Obtain_IMSI_VLR */
+	osmo_fsm_inst_state_chg(fi, VLR_ULA_S_WAIT_IMSI,
+				vlr_timer(vlr, 3270), 3270);
+	vlr->ops.tx_id_req(lfp->msc_conn_ref, GSM_MI_TYPE_IMSI);
+	/* will continue at vlr_loc_upd_node1() once IMSI arrives */
+}
+
+static int assoc_lfp_with_sub(struct osmo_fsm_inst *fi, struct vlr_subscr *vsub)
+{
+	struct lu_fsm_priv *lfp = lu_fsm_fi_priv(fi);
+	struct vlr_instance *vlr = lfp->vlr;
+
+	if (vsub->lu_fsm) {
+		LOGPFSML(fi, LOGL_ERROR,
+			 "A Location Updating process is already pending for"
+			 " this subscriber. Aborting.\n");
+		/* Also get rid of the other pending LU attempt? */
+		/*lu_fsm_failure(vsub->lu_fsm, GSM48_REJECT_CONGESTION);*/
+		lu_fsm_failure(fi, GSM48_REJECT_CONGESTION);
+		return -EINVAL;
+	}
+	vsub->lu_fsm = fi;
+	vsub->msc_conn_ref = lfp->msc_conn_ref;
+	/* FIXME: send new LAC to HLR? */
+	vsub->lac = lfp->new_lai.lac;
+	lfp->vsub = vsub;
+	/* Tell MSC to associate this subscriber with the given
+	 * connection */
+	vlr->ops.subscr_assoc(lfp->msc_conn_ref, lfp->vsub);
+	return 0;
+}
+
+static int _lu_fsm_associate_vsub(struct osmo_fsm_inst *fi)
+{
+	struct lu_fsm_priv *lfp = lu_fsm_fi_priv(fi);
+	struct vlr_instance *vlr = lfp->vlr;
+	struct vlr_subscr *vsub = NULL;
+
+	if (!lfp->imsi[0]) {
+		/* TMSI was used */
+		lfp->lu_by_tmsi = true;
+		/* TMSI clash: if a different subscriber already has this TMSI,
+		 * we will find that other subscriber in the VLR. So the IMSIs
+		 * would mismatch, but we don't know about it. Theoretically,
+		 * an authentication process would thwart any attempt to use
+		 * someone else's TMSI.
+		 * TODO: Otherwise we can ask for the IMSI and verify that it
+		 * matches the IMSI on record. */
+		vsub = vlr_subscr_find_or_create_by_tmsi(vlr, lfp->tmsi, NULL);
+
+		if (!vsub) {
+			LOGPFSML(fi, LOGL_ERROR, "VLR subscriber allocation failed\n");
+			lu_fsm_failure(fi, GSM48_REJECT_SRV_OPT_TMP_OUT_OF_ORDER);
+			return -1;
+		}
+
+		vsub->sub_dataconf_by_hlr_ind = false;
+		if (assoc_lfp_with_sub(fi, vsub)) {
+			vlr_subscr_put(vsub);
+			return -1; /* error, fsm failure invoked in assoc_lfp_with_sub() */
+		}
+		vlr_subscr_put(vsub);
+	} else {
+		/* IMSI was used */
+		vsub = vlr_subscr_find_or_create_by_imsi(vlr, lfp->imsi, NULL);
+
+		if (!vsub) {
+			LOGPFSML(fi, LOGL_ERROR, "VLR subscriber allocation failed\n");
+			lu_fsm_failure(fi, GSM48_REJECT_SRV_OPT_TMP_OUT_OF_ORDER);
+			vlr_subscr_put(vsub);
+			return -1;
+		}
+
+		vsub->sub_dataconf_by_hlr_ind = false;
+		if (assoc_lfp_with_sub(fi, vsub)) {
+			vlr_subscr_put(vsub);
+			return -1; /* error, fsm failure invoked in assoc_lfp_with_sub() */
+		}
+		vlr_subscr_put(vsub);
+	}
+	return 0;
+}
+
+/* 4.1.2.1: Subscriber (via MSC/SGSN) requests location update */
+static void _start_lu_main(struct osmo_fsm_inst *fi)
+{
+	struct lu_fsm_priv *lfp = lu_fsm_fi_priv(fi);
+	struct vlr_instance *vlr = lfp->vlr;
+
+	/* TODO: PUESBINE related handling */
+
+	/* Is previous LAI in this VLR? */
+	if (!lai_in_this_vlr(vlr, &lfp->old_lai)) {
+#if 0
+		/* FIXME: check previous VLR, (3) */
+		osmo_fsm_inst_state_chg(fi, VLR_ULA_S_WAIT_PVLR,
+					LU_TIMEOUT_LONG, 0);
+		return;
+#endif
+		LOGPFSML(fi, LOGL_NOTICE, "LAI change from %s,"
+			 " but checking previous VLR not implemented\n",
+			 osmo_lai_name(&lfp->old_lai));
+	}
+
+	/* If this is a TMSI based LU, we may not have the IMSI. Make sure that
+	 * we know the IMSI, either on record, or request it. */
+	if (!lfp->vsub->imsi[0])
+		vlr_loc_upd_want_imsi(fi);
+	else
+		vlr_loc_upd_node1(fi);
+}
+
+static void lu_fsm_idle(struct osmo_fsm_inst *fi, uint32_t event,
+			void *data)
+{
+	struct lu_fsm_priv *lfp = lu_fsm_fi_priv(fi);
+	struct vlr_instance *vlr = lfp->vlr;
+
+	OSMO_ASSERT(event == VLR_ULA_E_UPDATE_LA);
+
+	if (_lu_fsm_associate_vsub(fi))
+		return; /* error. FSM already terminated. */
+
+	OSMO_ASSERT(lfp->vsub);
+
+	/* See 3GPP TS 23.012, procedure Retrieve_IMEISV_If_Required */
+	if ((!vlr->cfg.retrieve_imeisv_early)
+	    || (lfp->type == VLR_LU_TYPE_PERIODIC && lfp->vsub->imeisv[0])) {
+		/* R_IMEISV_IR1 passed */
+		_start_lu_main(fi);
+	} else {
+		vlr->ops.tx_id_req(lfp->msc_conn_ref, GSM_MI_TYPE_IMEISV);
+		osmo_fsm_inst_state_chg(fi, VLR_ULA_S_WAIT_IMEISV,
+					vlr_timer(vlr, 3270), 3270);
+	}
+}
+
+static void lu_fsm_wait_imeisv(struct osmo_fsm_inst *fi, uint32_t event,
+			       void *data)
+{
+	switch (event) {
+	case VLR_ULA_E_ID_IMEISV:
+		/* IMEISV was copied in vlr_subscr_rx_id_resp(), and that's
+		 * where we received this event from. */
+		_start_lu_main(fi);
+		break;
+	default:
+		LOGPFSML(fi, LOGL_ERROR, "event without effect: %s\n",
+			 osmo_fsm_event_name(fi->fsm, event));
+		break;
+	}
+}
+
+/* Wait for response from Send_Identification to PVLR */
+static void lu_fsm_wait_pvlr(struct osmo_fsm_inst *fi, uint32_t event,
+			     void *data)
+{
+	switch (event) {
+	case VLR_ULA_E_SEND_ID_ACK:
+		vlr_loc_upd_node1(fi);
+		break;
+	case VLR_ULA_E_SEND_ID_NACK:
+		vlr_loc_upd_want_imsi(fi);
+		break;
+	default:
+		LOGPFSML(fi, LOGL_ERROR, "event without effect: %s\n",
+			 osmo_fsm_event_name(fi->fsm, event));
+		break;
+	}
+}
+
+/* Wait for result of Authenticate_VLR procedure */
+static void lu_fsm_wait_auth(struct osmo_fsm_inst *fi, uint32_t event,
+			     void *data)
+{
+	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);
+		return;
+	}
+
+	/* Result == Pass */
+	vlr_loc_upd_post_auth(fi);
+}
+
+static void lu_fsm_wait_ciph(struct osmo_fsm_inst *fi, uint32_t event,
+			     void *data)
+{
+	struct lu_fsm_priv *lfp = lu_fsm_fi_priv(fi);
+	struct vlr_subscr *vsub = lfp->vsub;
+	struct vlr_ciph_result res = { .cause = VLR_CIPH_REJECT };
+
+	OSMO_ASSERT(event == VLR_ULA_E_CIPH_RES);
+
+	if (!data)
+		LOGPFSML(fi, LOGL_ERROR, "invalid ciphering result: NULL\n");
+	else
+		res = *(struct vlr_ciph_result*)data;
+
+	switch (res.cause) {
+	case VLR_CIPH_COMPL:
+		break;
+	case VLR_CIPH_REJECT:
+		LOGPFSM(fi, "ciphering rejected\n");
+		lu_fsm_failure(fi, GSM48_REJECT_INVALID_MANDANTORY_INF);
+		return;
+	default:
+		LOGPFSML(fi, LOGL_ERROR, "invalid ciphering result: %d\n",
+			 res.cause);
+		lu_fsm_failure(fi, GSM48_REJECT_INVALID_MANDANTORY_INF);
+		return;
+	}
+
+	if (*res.imeisv) {
+		LOGPFSM(fi, "got IMEISV: %s\n", res.imeisv);
+		vlr_subscr_set_imeisv(vsub, res.imeisv);
+	}
+	vlr_loc_upd_post_ciph(fi);
+}
+
+static void lu_fsm_wait_imsi(struct osmo_fsm_inst *fi, uint32_t event,
+			     void *data)
+{
+	struct lu_fsm_priv *lfp = lu_fsm_fi_priv(fi);
+	struct vlr_subscr *vsub = lfp->vsub;
+	char *mi_string = data;
+
+	switch (event) {
+	case VLR_ULA_E_ID_IMSI:
+		vlr_subscr_set_imsi(vsub, mi_string);
+		vlr_loc_upd_node1(fi);
+		break;
+	default:
+		LOGPFSML(fi, LOGL_ERROR, "event without effect: %s\n",
+			 osmo_fsm_event_name(fi->fsm, event));
+		break;
+	}
+}
+
+/* At the end of Update_HLR_VLR */
+static void lu_fsm_wait_hlr_ul_res(struct osmo_fsm_inst *fi, uint32_t event,
+				   void *data)
+{
+	struct lu_fsm_priv *lfp = lu_fsm_fi_priv(fi);
+
+	switch (event) {
+	case VLR_ULA_E_HLR_LU_RES:
+		/* pass-through this event to Update_HLR_VLR */
+		if (data == NULL)
+			osmo_fsm_inst_dispatch(lfp->upd_hlr_vlr_fsm, UPD_HLR_VLR_E_UPD_LOC_ACK, NULL);
+		else
+			osmo_fsm_inst_dispatch(lfp->upd_hlr_vlr_fsm, UPD_HLR_VLR_E_UPD_LOC_NACK, data);
+		break;
+	case VLR_ULA_E_UPD_HLR_COMPL:
+		if (data == NULL) {
+			/* successful case */
+			osmo_fsm_inst_state_chg(fi, VLR_ULA_S_WAIT_LU_COMPL,
+						LU_TIMEOUT_LONG, 0);
+			vlr_loc_upd_start_lu_compl_fsm(fi);
+			/* continue in MSC ?!? */
+		} else {
+			/* unsuccessful case */
+			enum gsm48_reject_value cause =
+				*(enum gsm48_reject_value *)data;
+			/* Ignoring standalone mode for now. */
+			if (0 /* procedure_error && vlr->cfg.standalone_mode */) {
+				osmo_fsm_inst_state_chg(fi,
+						VLR_ULA_S_WAIT_LU_COMPL_STANDALONE,
+						LU_TIMEOUT_LONG, 0);
+				vlr_loc_upd_start_lu_compl_fsm(fi);
+			} else {
+				lu_fsm_failure(fi, cause);
+			}
+		}
+		break;
+	default:
+		LOGPFSML(fi, LOGL_ERROR, "event without effect: %s\n",
+			 osmo_fsm_event_name(fi->fsm, event));
+		break;
+	}
+}
+
+/* Wait for end of Location_Update_Completion_VLR */
+static void lu_fsm_wait_lu_compl(struct osmo_fsm_inst *fi, uint32_t event,
+				 void *data)
+{
+	struct lu_fsm_priv *lfp = lu_fsm_fi_priv(fi);
+	uint8_t cause;
+
+	switch (event) {
+	case VLR_ULA_E_NEW_TMSI_ACK:
+		osmo_fsm_inst_dispatch(lfp->lu_compl_vlr_fsm,
+				       LU_COMPL_VLR_E_NEW_TMSI_ACK, NULL);
+		break;
+	case VLR_ULA_E_ID_IMEI:
+		osmo_fsm_inst_dispatch(lfp->lu_compl_vlr_fsm,
+				       LU_COMPL_VLR_E_IMEI_CHECK_ACK, NULL);
+		break;
+	case VLR_ULA_E_LU_COMPL_SUCCESS:
+		lu_fsm_discard_lu_compl_fsm(fi);
+
+		/* Update Register */
+		/* TODO: Set_Notification_Type 23.078 */
+		/* TODO: Notify_gsmSCF 23.078 */
+		/* TODO: Authenticated Radio Contact Established -> ARC */
+
+		if (lfp->type == VLR_LU_TYPE_IMSI_ATTACH)
+			lfp->vlr->ops.tx_mm_info(lfp->msc_conn_ref);
+
+		lu_fsm_success(fi);
+		break;
+	case VLR_ULA_E_LU_COMPL_FAILURE:
+		cause = GSM48_REJECT_NETWORK_FAILURE;
+		if (data)
+			cause = *(uint8_t*)data;
+		lu_fsm_discard_lu_compl_fsm(fi);
+		lu_fsm_failure(fi, cause);
+		break;
+	default:
+		LOGPFSML(fi, LOGL_ERROR, "event without effect: %s\n",
+			 osmo_fsm_event_name(fi->fsm, event));
+		break;
+	}
+}
+
+/* Wait for end of Location_Update_Completion_VLR (standalone case) */
+static void lu_fsm_wait_lu_compl_standalone(struct osmo_fsm_inst *fi,
+					uint32_t event, void *data)
+{
+	struct lu_fsm_priv *lfp = lu_fsm_fi_priv(fi);
+	struct vlr_subscr *vsub = lfp->vsub;
+	uint8_t cause;
+
+	switch (event) {
+	case VLR_ULA_E_NEW_TMSI_ACK:
+		osmo_fsm_inst_dispatch(lfp->lu_compl_vlr_fsm,
+				       LU_COMPL_VLR_E_NEW_TMSI_ACK, NULL);
+		break;
+	case VLR_ULA_E_LU_COMPL_SUCCESS:
+		lu_fsm_discard_lu_compl_fsm(fi);
+		vsub->sub_dataconf_by_hlr_ind = false;
+		lu_fsm_success(fi);
+		break;
+	case VLR_ULA_E_LU_COMPL_FAILURE:
+		vsub->sub_dataconf_by_hlr_ind = false;
+		cause = GSM48_REJECT_NETWORK_FAILURE;
+		if (data)
+			cause = *(uint8_t*)data;
+		lu_fsm_discard_lu_compl_fsm(fi);
+		lu_fsm_failure(fi, cause);
+		break;
+	default:
+		LOGPFSML(fi, LOGL_ERROR, "event without effect: %s\n",
+			 osmo_fsm_event_name(fi->fsm, event));
+		break;
+	}
+}
+
+static const struct osmo_fsm_state vlr_lu_fsm_states[] = {
+	[VLR_ULA_S_IDLE] = {
+		.in_event_mask = S(VLR_ULA_E_UPDATE_LA),
+		.out_state_mask = S(VLR_ULA_S_WAIT_IMEISV) |
+				  S(VLR_ULA_S_WAIT_PVLR) |
+				  S(VLR_ULA_S_WAIT_IMSI) |
+				  S(VLR_ULA_S_WAIT_AUTH) |
+				  S(VLR_ULA_S_WAIT_HLR_UPD) |
+				  S(VLR_ULA_S_DONE),
+		.name = OSMO_STRINGIFY(VLR_ULA_S_IDLE),
+		.action = lu_fsm_idle,
+	},
+	[VLR_ULA_S_WAIT_IMEISV] = {
+		.in_event_mask = S(VLR_ULA_E_ID_IMEISV),
+		.out_state_mask = S(VLR_ULA_S_WAIT_PVLR) |
+				  S(VLR_ULA_S_WAIT_IMSI) |
+				  S(VLR_ULA_S_WAIT_AUTH) |
+				  S(VLR_ULA_S_WAIT_HLR_UPD) |
+				  S(VLR_ULA_S_DONE),
+		.name = OSMO_STRINGIFY(VLR_ULA_S_WAIT_IMEISV),
+		.action = lu_fsm_wait_imeisv,
+	},
+	[VLR_ULA_S_WAIT_PVLR] = {
+		.in_event_mask = S(VLR_ULA_E_SEND_ID_ACK) |
+				 S(VLR_ULA_E_SEND_ID_NACK),
+		.out_state_mask = S(VLR_ULA_S_WAIT_IMSI) |
+				  S(VLR_ULA_S_WAIT_AUTH) |
+				  S(VLR_ULA_S_DONE),
+		.name = OSMO_STRINGIFY(VLR_ULA_S_WAIT_PVLR),
+		.action = lu_fsm_wait_pvlr,
+	},
+	[VLR_ULA_S_WAIT_AUTH] = {
+		.in_event_mask = S(VLR_ULA_E_AUTH_RES),
+		.out_state_mask = S(VLR_ULA_S_WAIT_CIPH) |
+				  S(VLR_ULA_S_WAIT_LU_COMPL) |
+				  S(VLR_ULA_S_WAIT_HLR_UPD) |
+				  S(VLR_ULA_S_DONE),
+		.name = OSMO_STRINGIFY(VLR_ULA_S_WAIT_AUTH),
+		.action = lu_fsm_wait_auth,
+	},
+	[VLR_ULA_S_WAIT_CIPH] = {
+		.name = OSMO_STRINGIFY(VLR_ULA_S_WAIT_CIPH),
+		.in_event_mask = S(VLR_ULA_E_CIPH_RES),
+		.out_state_mask = S(VLR_ULA_S_WAIT_LU_COMPL) |
+				  S(VLR_ULA_S_WAIT_HLR_UPD) |
+				  S(VLR_ULA_S_DONE),
+		.action = lu_fsm_wait_ciph,
+	},
+	[VLR_ULA_S_WAIT_IMSI] = {
+		.in_event_mask = S(VLR_ULA_E_ID_IMSI),
+		.out_state_mask = S(VLR_ULA_S_WAIT_AUTH) |
+				  S(VLR_ULA_S_WAIT_HLR_UPD) |
+				  S(VLR_ULA_S_DONE),
+		.name = OSMO_STRINGIFY(VLR_ULA_S_WAIT_IMSI),
+		.action = lu_fsm_wait_imsi,
+	},
+	[VLR_ULA_S_WAIT_HLR_UPD] = {
+		.in_event_mask = S(VLR_ULA_E_HLR_LU_RES) |
+				 S(VLR_ULA_E_UPD_HLR_COMPL),
+		.out_state_mask = S(VLR_ULA_S_WAIT_LU_COMPL) |
+				  S(VLR_ULA_S_WAIT_LU_COMPL_STANDALONE) |
+				  S(VLR_ULA_S_DONE),
+		.name = OSMO_STRINGIFY(VLR_ULA_S_WAIT_HLR_UPD),
+		.action = lu_fsm_wait_hlr_ul_res,
+	},
+	[VLR_ULA_S_WAIT_LU_COMPL] = {
+		.in_event_mask = S(VLR_ULA_E_LU_COMPL_SUCCESS) |
+				 S(VLR_ULA_E_LU_COMPL_FAILURE) |
+				 S(VLR_ULA_E_NEW_TMSI_ACK) |
+				 S(VLR_ULA_E_ID_IMEI) |
+				 S(VLR_ULA_E_ID_IMEISV),
+		.out_state_mask = S(VLR_ULA_S_DONE),
+		.name = OSMO_STRINGIFY(VLR_ULA_S_WAIT_LU_COMPL),
+		.action = lu_fsm_wait_lu_compl,
+	},
+	[VLR_ULA_S_WAIT_LU_COMPL_STANDALONE] = {
+		.in_event_mask = S(VLR_ULA_E_LU_COMPL_SUCCESS) |
+				 S(VLR_ULA_E_LU_COMPL_FAILURE) |
+				 S(VLR_ULA_E_NEW_TMSI_ACK),
+		.out_state_mask = S(VLR_ULA_S_DONE),
+		.name = OSMO_STRINGIFY(VLR_ULA_S_WAIT_LU_COMPL_STANDALONE),
+		.action = lu_fsm_wait_lu_compl_standalone,
+	},
+	[VLR_ULA_S_DONE] = {
+		.name = OSMO_STRINGIFY(VLR_ULA_S_DONE),
+		.onenter = lu_fsm_dispatch_result,
+	},
+};
+
+static void fsm_lu_cleanup(struct osmo_fsm_inst *fi, enum osmo_fsm_term_cause cause)
+{
+	struct lu_fsm_priv *lfp = lu_fsm_fi_priv(fi);
+	struct vlr_subscr *vsub = lfp->vsub;
+
+	LOGPFSM(fi, "fsm_lu_cleanup called with cause %s\n",
+		osmo_fsm_term_cause_name(cause));
+	if (vsub && vsub->lu_fsm == fi)
+		vsub->lu_fsm = NULL;
+}
+
+static struct osmo_fsm vlr_lu_fsm = {
+	.name = "vlr_lu_fsm",
+	.states = vlr_lu_fsm_states,
+	.num_states = ARRAY_SIZE(vlr_lu_fsm_states),
+	.allstate_event_mask = 0,
+	.allstate_action = NULL,
+	.log_subsys = DVLR,
+	.event_names = fsm_lu_event_names,
+	.cleanup = fsm_lu_cleanup,
+};
+
+static inline struct lu_fsm_priv *lu_fsm_fi_priv(struct osmo_fsm_inst *fi)
+{
+	OSMO_ASSERT(fi->fsm == &vlr_lu_fsm);
+	return (struct lu_fsm_priv*)fi->priv;
+}
+
+struct osmo_fsm_inst *
+vlr_loc_update(struct osmo_fsm_inst *parent,
+	       uint32_t parent_event_success,
+	       uint32_t parent_event_failure,
+	       void *parent_event_data,
+	       struct vlr_instance *vlr, void *msc_conn_ref,
+	       enum vlr_lu_type type, uint32_t tmsi, const char *imsi,
+	       const struct osmo_location_area_id *old_lai,
+	       const struct osmo_location_area_id *new_lai,
+	       bool authentication_required,
+	       bool ciphering_required,
+	       bool is_r99, bool is_utran,
+	       bool assign_tmsi)
+{
+	struct osmo_fsm_inst *fi;
+	struct lu_fsm_priv *lfp;
+
+	fi = osmo_fsm_inst_alloc_child(&vlr_lu_fsm, parent, parent_event_failure);
+	if (!fi)
+		return NULL;
+
+	lfp = talloc_zero(fi, struct lu_fsm_priv);
+	lfp->vlr = vlr;
+	lfp->msc_conn_ref = msc_conn_ref;
+	lfp->tmsi = tmsi;
+	lfp->type = type;
+	lfp->old_lai = *old_lai;
+	lfp->new_lai = *new_lai;
+	lfp->lu_by_tmsi = true;
+	lfp->parent_event_success = parent_event_success;
+	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_r99 = is_r99;
+	lfp->is_utran = is_utran;
+	lfp->assign_tmsi = assign_tmsi;
+	if (imsi) {
+		strncpy(lfp->imsi, imsi, sizeof(lfp->imsi)-1);
+		lfp->imsi[sizeof(lfp->imsi)-1] = '\0';
+		lfp->lu_by_tmsi = false;
+	}
+	fi->priv = lfp;
+
+	LOGPFSM(fi, "rev=%s net=%s%s%s\n",
+		is_r99 ? "R99" : "GSM",
+		is_utran ? "UTRAN" : "GERAN",
+		(authentication_required || ciphering_required)?
+		" Auth" : " (no Auth)",
+		(authentication_required || ciphering_required)?
+			(ciphering_required? "+Ciph" : " (no Ciph)")
+			: "");
+
+	if (is_utran && !authentication_required)
+		LOGPFSML(fi, LOGL_ERROR,
+			 "Authentication off on UTRAN network. Good luck.\n");
+
+	osmo_fsm_inst_dispatch(fi, VLR_ULA_E_UPDATE_LA, NULL);
+
+	return fi;
+}
+
+void vlr_loc_update_cancel(struct osmo_fsm_inst *fi,
+			   enum osmo_fsm_term_cause fsm_cause,
+			   uint8_t gsm48_cause)
+{
+	struct lu_fsm_priv *lfp;
+
+	OSMO_ASSERT(fi);
+	OSMO_ASSERT(fi->fsm == &vlr_lu_fsm);
+
+	lfp = fi->priv;
+	lfp->rej_cause = gsm48_cause;
+
+	if (fi->state != VLR_ULA_S_DONE)
+		lu_fsm_failure(fi, gsm48_cause);
+}
+
+void vlr_lu_fsm_init(void)
+{
+	osmo_fsm_register(&vlr_lu_fsm);
+	osmo_fsm_register(&upd_hlr_vlr_fsm);
+	osmo_fsm_register(&sub_pres_vlr_fsm);
+	osmo_fsm_register(&lu_compl_vlr_fsm);
+}
diff --git a/src/libvlr/vlr_lu_fsm.h b/src/libvlr/vlr_lu_fsm.h
new file mode 100644
index 0000000..5cf13c7
--- /dev/null
+++ b/src/libvlr/vlr_lu_fsm.h
@@ -0,0 +1,18 @@
+#pragma once
+
+#include <osmocom/core/fsm.h>
+
+enum vlr_lu_state {
+	VLR_ULA_S_IDLE,
+	VLR_ULA_S_WAIT_IMEISV,
+	VLR_ULA_S_WAIT_PVLR,	/* Waiting for ID from PVLR */
+	VLR_ULA_S_WAIT_AUTH,	/* Waiting for Authentication */
+	VLR_ULA_S_WAIT_CIPH,	/* Waiting for Ciphering Complete */
+	VLR_ULA_S_WAIT_IMSI,	/* Waiting for IMSI from MS */
+	VLR_ULA_S_WAIT_HLR_UPD,	/* Waiting for end of HLR update */
+	VLR_ULA_S_WAIT_LU_COMPL,/* Waiting for LU complete */
+	VLR_ULA_S_WAIT_LU_COMPL_STANDALONE, /* Standalone VLR */
+	VLR_ULA_S_DONE
+};
+
+void vlr_lu_fsm_init(void);
diff --git a/src/osmo-msc/Makefile.am b/src/osmo-msc/Makefile.am
new file mode 100644
index 0000000..bcc4ada
--- /dev/null
+++ b/src/osmo-msc/Makefile.am
@@ -0,0 +1,53 @@
+AM_CPPFLAGS = \
+	$(all_includes) \
+	-I$(top_srcdir)/include \
+	-I$(top_builddir) \
+	$(NULL)
+
+AM_CFLAGS = \
+	-Wall \
+	$(COVERAGE_CFLAGS) \
+	$(LIBOSMOCORE_CFLAGS) \
+	$(LIBOSMOGSM_CFLAGS) \
+	$(LIBOSMOVTY_CFLAGS) \
+	$(LIBOSMOCTRL_CFLAGS) \
+	$(LIBOSMOABIS_CFLAGS) \
+	$(LIBSMPP34_CFLAGS) \
+	$(LIBOSMORANAP_CFLAGS) \
+	$(LIBASN1C_CFLAGS) \
+	$(LIBOSMOSIGTRAN_CFLAGS) \
+	$(LIBOSMOMGCPCLIENT_CFLAGS) \
+	$(LIBOSMOGSUPCLIENT_CFLAGS) \
+	$(NULL)
+
+AM_LDFLAGS = \
+	$(COVERAGE_LDFLAGS) \
+	$(NULL)
+
+bin_PROGRAMS = \
+	osmo-msc \
+	$(NULL)
+
+osmo_msc_SOURCES = \
+	msc_main.c \
+	$(NULL)
+
+osmo_msc_LDADD = \
+	$(top_builddir)/src/libmsc/libmsc.a \
+	$(top_builddir)/src/libvlr/libvlr.a \
+	$(LIBOSMOGSM_LIBS) \
+	$(LIBOSMOVTY_LIBS) \
+	$(LIBOSMOCORE_LIBS) \
+	$(LIBOSMOCTRL_LIBS) \
+	$(LIBOSMOABIS_LIBS) \
+	$(LIBSMPP34_LIBS) \
+	$(LIBOSMOSIGTRAN_LIBS) \
+	$(LIBOSMOMGCPCLIENT_LIBS) \
+	$(LIBOSMOGSUPCLIENT_LIBS) \
+	-ldbi \
+	$(NULL)
+if BUILD_IU
+osmo_msc_LDADD += \
+	$(LIBOSMORANAP_LIBS) \
+	$(NULL)
+endif
diff --git a/src/osmo-msc/msc_main.c b/src/osmo-msc/msc_main.c
new file mode 100644
index 0000000..53d27d3
--- /dev/null
+++ b/src/osmo-msc/msc_main.c
@@ -0,0 +1,728 @@
+/* OsmoMSC - Circuit-Switched Core Network (MSC+VLR+HLR+SMSC) implementation
+ */
+
+/* (C) 2016 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>
+ * All Rights Reserved
+ *
+ * Based on OsmoNITB:
+ * (C) 2008-2010 by Harald Welte <laforge@gnumonks.org>
+ * (C) 2009-2012 by Holger Hans Peter Freyther <zecke@selfish.org>
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <unistd.h>
+#include <time.h>
+#include <errno.h>
+#include <signal.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+
+#define _GNU_SOURCE
+#include <getopt.h>
+
+/* build switches from the configure script */
+#include "../../bscconfig.h"
+
+#include <osmocom/msc/db.h>
+#include <osmocom/core/application.h>
+#include <osmocom/core/select.h>
+#include <osmocom/core/stats.h>
+#include <osmocom/msc/debug.h>
+#include <osmocom/abis/abis.h>
+#include <osmocom/abis/e1_input.h>
+#include <osmocom/core/talloc.h>
+#include <osmocom/msc/signal.h>
+#include <osmocom/msc/osmo_msc.h>
+#include <osmocom/msc/sms_queue.h>
+#include <osmocom/vty/telnet_interface.h>
+#include <osmocom/vty/ports.h>
+#include <osmocom/vty/logging.h>
+#include <osmocom/vty/misc.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/sigtran/osmo_ss7.h>
+#include <osmocom/mgcp_client/mgcp_client.h>
+
+#ifdef BUILD_IU
+#include <osmocom/ranap/iu_client.h>
+#endif
+
+#include <osmocom/msc/msc_ifaces.h>
+#include <osmocom/msc/iucs.h>
+#include <osmocom/msc/iucs_ranap.h>
+#include <osmocom/msc/a_iface.h>
+
+static const char * const osmomsc_copyright =
+	"OsmoMSC - Osmocom Circuit-Switched Core Network implementation\r\n"
+	"Copyright (C) 2016 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>\r\n"
+	"Based on OsmoNITB:\r\n"
+	"  (C) 2008-2010 by Harald Welte <laforge@gnumonks.org>\r\n"
+	"  (C) 2009-2012 by Holger Hans Peter Freyther <zecke@selfish.org>\r\n"
+	"Contributions by Daniel Willmann, Jan Lübbe, Stefan Schmidt\r\n"
+	"Dieter Spaar, Andreas Eversberg, Sylvain Munaut, Neels Hofmeyr\r\n\r\n"
+	"License AGPLv3+: GNU AGPL version 3 or later <http://gnu.org/licenses/agpl-3.0.html>\r\n"
+	"This is free software: you are free to change and redistribute it.\r\n"
+	"There is NO WARRANTY, to the extent permitted by law.\r\n";
+
+void *tall_msc_ctx = NULL;
+
+/* satisfy deps from libbsc legacy.
+   TODO double check these */
+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;
+	int use_db_counter;
+} msc_cmdline_config = {
+	"sms.db",
+	"osmo-msc.cfg",
+	0,
+	0,
+	1
+};
+
+/* timer to store statistics */
+#define DB_SYNC_INTERVAL	60, 0
+#define EXPIRE_INTERVAL		10, 0
+
+static struct osmo_timer_list db_sync_timer;
+
+static int quit = 0;
+
+static void print_usage()
+{
+	printf("Usage: osmo-msc\n");
+}
+
+static void print_help()
+{
+	printf("  Some useful help...\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("  -C --no-dbcounter          Disable regular syncing of counters to database.\n");
+}
+
+static void handle_options(int argc, char **argv)
+{
+	while (1) {
+		int option_index = 0, c;
+		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'},
+			{"timestamp", 0, 0, 'T'},
+			{"version", 0, 0, 'V' },
+			{"log-level", 1, 0, 'e'},
+			{"mncc-sock-path", 1, 0, 'M'},
+			{"no-dbcounter", 0, 0, 'C'},
+			{0, 0, 0, 0}
+		};
+
+		c = getopt_long(argc, argv, "hd:Dsl:TVc:e:CM:",
+				long_options, &option_index);
+		if (c == -1)
+			break;
+
+		switch (c) {
+		case 'h':
+			print_usage();
+			print_help();
+			exit(0);
+		case 's':
+			log_set_use_color(osmo_stderr_target, 0);
+			break;
+		case 'd':
+			log_parse_category_mask(osmo_stderr_target, optarg);
+			break;
+		case 'D':
+			msc_cmdline_config.daemonize = 1;
+			break;
+		case 'l':
+			msc_cmdline_config.database_name = optarg;
+			break;
+		case 'c':
+			msc_cmdline_config.config_file = optarg;
+			break;
+		case 'T':
+			log_set_print_timestamp(osmo_stderr_target, 1);
+			break;
+		case 'e':
+			log_set_log_level(osmo_stderr_target, atoi(optarg));
+			break;
+		case 'M':
+			msc_cmdline_config.mncc_sock_path = optarg;
+			break;
+		case 'C':
+			msc_cmdline_config.use_db_counter = 0;
+			break;
+		case 'V':
+			print_version(1);
+			exit(0);
+			break;
+		default:
+			/* catch unknown options *as well as* missing arguments. */
+			fprintf(stderr, "Error in command line options. Exiting.\n");
+			exit(-1);
+		}
+	}
+}
+
+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)
+		return NULL;
+
+	net->name_long = talloc_strdup(net, "OsmoMSC");
+	net->name_short = talloc_strdup(net, "OsmoMSC");
+
+	net->gsup_server_addr_str = talloc_strdup(net,
+						  MSC_HLR_REMOTE_IP_DEFAULT);
+	net->gsup_server_port = MSC_HLR_REMOTE_PORT_DEFAULT;
+
+	mgcp_client_conf_init(&net->mgw.conf);
+
+	return net;
+}
+
+void msc_network_shutdown(struct gsm_network *net)
+{
+	/* nothing here yet */
+}
+
+static struct gsm_network *msc_network = NULL;
+
+extern void *tall_vty_ctx;
+static void signal_handler(int signal)
+{
+	fprintf(stdout, "signal %u received\n", signal);
+
+	switch (signal) {
+	case SIGINT:
+	case SIGTERM:
+		LOGP(DMSC, LOGL_NOTICE, "Terminating due to signal %d\n", signal);
+		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 */
+	case SIGUSR1:
+		talloc_report(tall_vty_ctx, stderr);
+		talloc_report_full(tall_msc_ctx, stderr);
+		break;
+	case SIGUSR2:
+		talloc_report_full(tall_vty_ctx, stderr);
+		break;
+	default:
+		break;
+	}
+}
+
+/* timer handling */
+static int _db_store_counter(struct osmo_counter *counter, void *data)
+{
+	return db_store_counter(counter);
+}
+
+static void db_sync_timer_cb(void *data)
+{
+	/* store counters to database and re-schedule */
+	osmo_counters_for_each(_db_store_counter, NULL);
+	osmo_timer_schedule(&db_sync_timer, DB_SYNC_INTERVAL);
+}
+
+static int msc_vty_go_parent(struct vty *vty)
+{
+	switch (vty->node) {
+	case GSMNET_NODE:
+		vty->node = CONFIG_NODE;
+		vty->index = NULL;
+		break;
+	case SMPP_ESME_NODE:
+		vty->node = SMPP_NODE;
+		vty->index = NULL;
+		break;
+	case SMPP_NODE:
+	case MSC_NODE:
+	case MNCC_INT_NODE:
+		vty->node = CONFIG_NODE;
+		vty->index = NULL;
+		break;
+	case SUBSCR_NODE:
+		vty->node = ENABLE_NODE;
+		vty->index = NULL;
+		break;
+	default:
+		osmo_ss7_vty_go_parent(vty);
+	}
+
+	return vty->node;
+}
+
+static int msc_vty_is_config_node(struct vty *vty, int node)
+{
+	/* Check if libosmo-sccp declares the node in
+	 * question as config node */
+	if (osmo_ss7_is_config_node(vty, node))
+		return 1;
+
+	switch (node) {
+	/* add items that are not config */
+	case SUBSCR_NODE:
+	case CONFIG_NODE:
+		return 0;
+
+	default:
+		return 1;
+	}
+}
+
+static struct vty_app_info msc_vty_info = {
+	.name		= "OsmoMSC",
+	.version	= PACKAGE_VERSION,
+	.go_parent_cb	= msc_vty_go_parent,
+	.is_config_node	= msc_vty_is_config_node,
+};
+
+#ifdef BUILD_IU
+static int rcvmsg_iu_cs(struct msgb *msg, struct gprs_ra_id *ra_id, uint16_t *sai)
+{
+	DEBUGP(DIUCS, "got IuCS message %d bytes: %s\n", msg->len, msgb_hexdump(msg));
+	if (ra_id) {
+		DEBUGP(DIUCS, "got IuCS message on %s\n", osmo_rai_name(ra_id));
+	}
+
+	return gsm0408_rcvmsg_iucs(msc_network, msg, ra_id? &ra_id->lac : NULL);
+}
+
+static int rx_iu_event(struct ranap_ue_conn_ctx *ctx, enum ranap_iu_event_type type,
+		       void *data)
+{
+	DEBUGP(DIUCS, "got IuCS event %u: %s\n", type,
+	       ranap_iu_event_type_str(type));
+
+	return iucs_rx_ranap_event(msc_network, ctx, type, data);
+}
+#endif
+
+#define DEFAULT_M3UA_REMOTE_IP "127.0.0.1"
+#define DEFAULT_PC "0.23.1"
+
+static struct osmo_sccp_instance *sccp_setup(void *ctx, uint32_t cs7_instance,
+					     const char *label, const char *default_pc_str)
+{
+	int default_pc = osmo_ss7_pointcode_parse(NULL, default_pc_str);
+	if (default_pc < 0)
+		return NULL;
+
+	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, /* 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
+	 * 'cs7' / 'asp' / 'remote-ip', and this default remote IP has no effect.
+	 * Similarly, 'cs7' / 'listen' can specify the local IP address. */
+}
+
+static int ss7_setup(void *ctx)
+{
+	uint32_t cs7_instance_a = msc_network->a.cs7_instance;
+#if BUILD_IU
+	uint32_t cs7_instance_iu = msc_network->iu.cs7_instance;
+
+	if (cs7_instance_a == cs7_instance_iu) {
+		/* Create one single SCCP instance which will be used for both,
+		 * Iu and A at the same time, under the same point-code */
+		LOGP(DMSC, LOGL_NOTICE, "CS7 Instance identifiers: A = Iu = %u\n", cs7_instance_a);
+
+		msc_network->a.sccp = sccp_setup(ctx, cs7_instance_a, "OsmoMSC-A-Iu", DEFAULT_PC);
+		if (!msc_network->a.sccp)
+			return -EINVAL;
+
+		msc_network->iu.sccp = msc_network->a.sccp;
+	} else {
+		/* Create two separate SCCP instances to run A and Iu independently on different
+		 * pointcodes */
+		LOGP(DMSC, LOGL_NOTICE, "CS7 Instance identifiers: A = %u, Iu = %u\n",
+		     cs7_instance_a, cs7_instance_iu);
+
+		msc_network->a.sccp = sccp_setup(ctx, cs7_instance_a, "OsmoMSC-A", DEFAULT_PC);
+		if (!msc_network->a.sccp)
+			return -EINVAL;
+
+		msc_network->iu.sccp = sccp_setup(ctx, cs7_instance_iu, "OsmoMSC-Iu", DEFAULT_PC);
+		if (!msc_network->iu.sccp)
+			return -EINVAL;
+	}
+#else
+	/* No Iu support, just open up an A instance */
+	msc_network->a.sccp = sccp_setup(ctx, cs7_instance_a, "OsmoMSC-A", DEFAULT_PC);
+	if (!msc_network->a.sccp)
+		return -EINVAL;
+#endif
+
+	return 0;
+}
+
+static const struct log_info_cat msc_default_categories[] = {
+	[DRLL] = {
+		.name = "DRLL",
+		.description = "A-bis Radio Link Layer (RLL)",
+		.color = "\033[1;31m",
+		.enabled = 1, .loglevel = LOGL_NOTICE,
+	},
+	[DCC] = {
+		.name = "DCC",
+		.description = "Layer3 Call Control (CC)",
+		.color = "\033[1;32m",
+		.enabled = 1, .loglevel = LOGL_NOTICE,
+	},
+	[DMM] = {
+		.name = "DMM",
+		.description = "Layer3 Mobility Management (MM)",
+		.color = "\033[1;33m",
+		.enabled = 1, .loglevel = LOGL_NOTICE,
+	},
+	[DRR] = {
+		.name = "DRR",
+		.description = "Layer3 Radio Resource (RR)",
+		.color = "\033[1;34m",
+		.enabled = 1, .loglevel = LOGL_NOTICE,
+	},
+	[DMNCC] = {
+		.name = "DMNCC",
+		.description = "MNCC API for Call Control application",
+		.color = "\033[1;39m",
+		.enabled = 1, .loglevel = LOGL_NOTICE,
+	},
+	[DPAG]	= {
+		.name = "DPAG",
+		.description = "Paging Subsystem",
+		.color = "\033[1;38m",
+		.enabled = 1, .loglevel = LOGL_NOTICE,
+	},
+	[DMSC] = {
+		.name = "DMSC",
+		.description = "Mobile Switching Center",
+		.enabled = 1, .loglevel = LOGL_NOTICE,
+	},
+	[DMGCP] = {
+		.name = "DMGCP",
+		.description = "Media Gateway Control Protocol",
+		.enabled = 1, .loglevel = LOGL_NOTICE,
+	},
+	[DHO] = {
+		.name = "DHO",
+		.description = "Hand-Over",
+		.enabled = 1, .loglevel = LOGL_NOTICE,
+	},
+	[DDB] = {
+		.name = "DDB",
+		.description = "Database Layer",
+		.enabled = 1, .loglevel = LOGL_NOTICE,
+	},
+	[DREF] = {
+		.name = "DREF",
+		.description = "Reference Counting",
+		.enabled = 0, .loglevel = LOGL_NOTICE,
+	},
+	[DCTRL] = {
+		.name = "DCTRL",
+		.description = "Control interface",
+		.enabled = 1, .loglevel = LOGL_NOTICE,
+	},
+	[DSMPP] = {
+		.name = "DSMPP",
+		.description = "SMPP interface for external SMS apps",
+		.enabled = 1, .loglevel = LOGL_DEBUG,
+	},
+	[DRANAP] = {
+		.name = "DRANAP",
+		.description = "Radio Access Network Application Part Protocol",
+		.enabled = 1, .loglevel = LOGL_DEBUG,
+	},
+	[DVLR] = {
+		.name = "DVLR",
+		.description = "Visitor Location Register",
+		.enabled = 1, .loglevel = LOGL_DEBUG,
+	},
+	[DIUCS] = {
+		.name = "DIUCS",
+		.description = "Iu-CS Protocol",
+		.enabled = 1, .loglevel = LOGL_DEBUG,
+	},
+	[DBSSAP] = {
+		.name = "DBSSAP",
+		.description = "BSSAP Protocol (A Interface)",
+		.enabled = 1, .loglevel = LOGL_NOTICE,
+	},
+
+};
+
+static int filter_fn(const struct log_context *ctx, struct log_target *tar)
+{
+	const struct vlr_subscr *vsub = ctx->ctx[LOG_CTX_VLR_SUBSCR];
+
+	if ((tar->filter_map & (1 << LOG_FLT_VLR_SUBSCR)) != 0
+	    && vsub && vsub == tar->filter_data[LOG_FLT_VLR_SUBSCR])
+		return 1;
+
+	return 0;
+}
+
+const struct log_info log_info = {
+	.filter_fn = filter_fn,
+	.cat = msc_default_categories,
+	.num_cat = ARRAY_SIZE(msc_default_categories),
+};
+
+extern void *tall_gsms_ctx;
+extern void *tall_call_ctx;
+extern void *tall_trans_ctx;
+
+int main(int argc, char **argv)
+{
+	int rc;
+
+	/* Track the use of talloc NULL memory contexts */
+	talloc_enable_null_tracking();
+
+	msc_vty_info.copyright	= osmomsc_copyright;
+
+	tall_msc_ctx = talloc_named_const(NULL, 1, "osmo_msc");
+	msc_vty_info.tall_ctx = tall_msc_ctx;
+
+	msgb_talloc_ctx_init(tall_msc_ctx, 0);
+	osmo_signal_talloc_ctx_init(tall_msc_ctx);
+	tall_gsms_ctx = talloc_named_const(tall_msc_ctx, 0, "sms");
+	tall_call_ctx = talloc_named_const(tall_msc_ctx, 0, "gsm_call");
+	tall_trans_ctx = talloc_named_const(tall_msc_ctx, 0, "transaction");
+
+	osmo_init_logging2(tall_msc_ctx, &log_info);
+	osmo_stats_init(tall_msc_ctx);
+
+	/* For --version, vty_init() must be called before handling options */
+	vty_init(&msc_vty_info);
+
+	osmo_ss7_init();
+	osmo_ss7_vty_init_asp(tall_msc_ctx);
+	osmo_sccp_vty_init();
+
+	/* Parse options */
+	handle_options(argc, argv);
+
+	/* Allocate global gsm_network struct; choose socket/internal MNCC */
+	msc_network = msc_network_alloc(tall_msc_ctx,
+				        msc_cmdline_config.mncc_sock_path?
+						mncc_sock_from_cc
+						: int_mncc_recv);
+	if (!msc_network)
+		return -ENOMEM;
+
+	if (msc_vlr_alloc(msc_network)) {
+		fprintf(stderr, "Failed to allocate VLR\n");
+		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)
+		return -1;
+#endif
+
+	rc = vty_read_config_file(msc_cmdline_config.config_file, NULL);
+	if (rc < 0) {
+		LOGP(DMSC, LOGL_FATAL, "Failed to parse the config file: '%s'\n",
+		     msc_cmdline_config.config_file);
+		return 1;
+	}
+
+	/* Initialize MNCC socket if appropriate */
+	if (msc_cmdline_config.mncc_sock_path) {
+		rc = mncc_sock_init(msc_network,
+				    msc_cmdline_config.mncc_sock_path);
+		if (rc) {
+			fprintf(stderr, "MNCC socket initialization failed. exiting.\n");
+			exit(1);
+		}
+	} else
+		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);
+	if (rc < 0)
+		return 2;
+
+	/* BSC stuff is to be split behind an A-interface to be used with
+	 * OsmoBSC, but there is no need to remove it yet. Most of the
+	 * following code until iu_init() is legacy. */
+
+#ifdef BUILD_SMPP
+	smpp_openbsc_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);
+	if (!msc_network->ctrl) {
+		printf("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");
+		return -1;
+	}
+#endif
+
+	if (msc_ctrl_cmds_install(msc_network) != 0) {
+		printf("Failed to initialize the MSC control commands.\n");
+		return -1;
+	}
+
+	/* seed the PRNG */
+	srand(time(NULL));
+	/* 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;
+	}
+
+	osmo_fsm_log_addr(true);
+	if (msc_vlr_start(msc_network)) {
+		fprintf(stderr, "Failed to start VLR\n");
+		exit(1);
+	}
+
+	msc_subscr_conn_init();
+
+	if (db_prepare()) {
+		printf("DB: Failed to prepare database.\n");
+		return 5;
+	}
+
+	/* setup the timer */
+	osmo_timer_setup(&db_sync_timer, db_sync_timer_cb, NULL);
+	if (msc_cmdline_config.use_db_counter)
+		osmo_timer_schedule(&db_sync_timer, DB_SYNC_INTERVAL);
+
+	signal(SIGINT, &signal_handler);
+	signal(SIGTERM, &signal_handler);
+	signal(SIGABRT, &signal_handler);
+	signal(SIGUSR1, &signal_handler);
+	signal(SIGUSR2, &signal_handler);
+	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 (mgcp_client_connect(msc_network->mgw.client)) {
+		printf("MGCPGW connect failed\n");
+		return 7;
+	}
+
+	if (ss7_setup(tall_msc_ctx)) {
+		printf("Setting up SCCP client failed.\n");
+		return 8;
+	}
+
+#ifdef BUILD_IU
+	/* Set up IuCS */
+	ranap_iu_init(tall_msc_ctx, DRANAP, "OsmoMSC-IuCS", msc_network->iu.sccp, rcvmsg_iu_cs, rx_iu_event);
+#endif
+
+	/* Set up A interface */
+	a_init(msc_network->a.sccp, msc_network);
+
+	/* Init RRLP handlers */
+	msc_rrlp_init();
+
+	if (msc_cmdline_config.daemonize) {
+		rc = osmo_daemonize();
+		if (rc < 0) {
+			perror("Error during daemonize");
+			return 6;
+		}
+	}
+
+	while (!quit) {
+		log_reset_context();
+		osmo_select_main(0);
+	}
+
+	msc_network_shutdown(msc_network);
+	osmo_signal_dispatch(SS_L_GLOBAL, S_L_GLOBAL_SHUTDOWN, NULL);
+	sleep(3);
+
+	log_fini();
+
+	/**
+	 * Report the heap state of root context, then free,
+	 * so both ASAN and Valgrind are happy...
+	 */
+	talloc_report_full(tall_msc_ctx, stderr);
+	talloc_free(tall_msc_ctx);
+
+	/* FIXME: VTY code still uses NULL-context */
+	talloc_free(tall_vty_ctx);
+
+	/**
+	 * Report the heap state of NULL context, then free,
+	 * so both ASAN and Valgrind are happy...
+	 */
+	talloc_report_full(NULL, stderr);
+	talloc_disable_null_tracking();
+	return 0;
+}
diff --git a/src/utils/Makefile.am b/src/utils/Makefile.am
new file mode 100644
index 0000000..2d67102
--- /dev/null
+++ b/src/utils/Makefile.am
@@ -0,0 +1,46 @@
+AM_CPPFLAGS = \
+	$(all_includes) \
+	-I$(top_srcdir)/include \
+	-I$(top_builddir) \
+	$(NULL)
+
+AM_CFLAGS = \
+	-Wall \
+	$(LIBOSMOCORE_CFLAGS) \
+	$(LIBOSMOGSM_CFLAGS) \
+	$(LIBOSMOABIS_CFLAGS) \
+	$(COVERAGE_CFLAGS) \
+	$(SQLITE3_CFLAGS) \
+	$(LIBSMPP34_CFLAGS) \
+	$(NULL)
+
+AM_LDFLAGS = \
+	$(COVERAGE_LDFLAGS) \
+	$(NULL)
+
+noinst_HEADERS = \
+	$(NULL)
+
+bin_PROGRAMS = \
+	$(NULL)
+
+if BUILD_SMPP
+noinst_PROGRAMS = \
+	smpp_mirror \
+	$(NULL)
+
+smpp_mirror_SOURCES = \
+	smpp_mirror.c \
+	$(NULL)
+
+smpp_mirror_CFLAGS = \
+	$(LIBOSMOCORE_CFLAGS) \
+	$(LIBSMPP34_CFLAGS) \
+	$(NULL)
+
+smpp_mirror_LDADD = \
+	$(LIBOSMOCORE_LIBS) \
+	$(LIBOSMOGSM_LIBS) \
+	$(LIBSMPP34_LIBS) \
+	$(NULL)
+endif
diff --git a/src/utils/smpp_mirror.c b/src/utils/smpp_mirror.c
new file mode 100644
index 0000000..3053553
--- /dev/null
+++ b/src/utils/smpp_mirror.c
@@ -0,0 +1,372 @@
+#include <stdio.h>
+#include <unistd.h>
+#include <stdint.h>
+#include <errno.h>
+#include <string.h>
+
+#include <netinet/in.h>
+
+#include <smpp34.h>
+#include <smpp34_structs.h>
+#include <smpp34_params.h>
+
+#include <osmocom/core/application.h>
+#include <osmocom/core/utils.h>
+#include <osmocom/core/msgb.h>
+#include <osmocom/core/talloc.h>
+#include <osmocom/core/select.h>
+#include <osmocom/core/socket.h>
+#include <osmocom/core/write_queue.h>
+
+#include <osmocom/msc/debug.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)
+{
+	struct tlv_t *t;
+
+	for (t = head; t != NULL; t = t->next) {
+		if (t->tag == tag)
+			return t;
+	}
+	return NULL;
+}
+
+static int smpp_handle_deliver(struct esme *esme, struct msgb *msg)
+{
+	struct deliver_sm_t deliver;
+	struct deliver_sm_resp_t deliver_r;
+	struct submit_sm_t submit;
+	tlv_t *t;
+	int rc;
+
+	memset(&deliver, 0, sizeof(deliver));
+	SMPP34_UNPACK(rc, DELIVER_SM, &deliver, msgb_data(msg), msgb_length(msg));
+	if (rc < 0)
+		return rc;
+
+	INIT_RESP(DELIVER_SM_RESP, &deliver_r, &deliver);
+
+	PACK_AND_SEND(esme, &deliver_r);
+
+	memset(&submit, 0, sizeof(submit));
+	submit.command_id = SUBMIT_SM;
+	submit.command_status = ESME_ROK;
+	submit.sequence_number = esme_inc_seq_nr(esme);
+
+	submit.dest_addr_ton =  deliver.source_addr_ton;
+	submit.dest_addr_npi =  deliver.source_addr_npi;
+	memcpy(submit.destination_addr, deliver.source_addr,
+		OSMO_MIN(sizeof(submit.destination_addr),
+			 sizeof(deliver.source_addr)));
+
+	submit.source_addr_ton = deliver.dest_addr_ton;
+	submit.source_addr_npi = deliver.dest_addr_npi;
+	memcpy(submit.source_addr, deliver.destination_addr,
+		OSMO_MIN(sizeof(submit.source_addr),
+			 sizeof(deliver.destination_addr)));
+
+	/* Mirror delivery receipts as a delivery acknowledgements. */
+	if (deliver.esm_class == 0x04) {
+		LOGP(DSMPP, LOGL_DEBUG, "%s\n", deliver.short_message);
+		submit.esm_class = 0x08;
+	} else {
+		submit.esm_class = deliver.esm_class;
+	}
+
+	submit.registered_delivery = deliver.registered_delivery;
+	submit.protocol_id = deliver.protocol_id;
+	submit.priority_flag = deliver.priority_flag;
+	memcpy(submit.schedule_delivery_time, deliver.schedule_delivery_time,
+	       OSMO_MIN(sizeof(submit.schedule_delivery_time),
+		        sizeof(deliver.schedule_delivery_time)));
+	memcpy(submit.validity_period, deliver.validity_period,
+		OSMO_MIN(sizeof(submit.validity_period),
+			 sizeof(deliver.validity_period)));
+	submit.registered_delivery = deliver.registered_delivery;
+	submit.replace_if_present_flag = deliver.replace_if_present_flag;
+	submit.data_coding = deliver.data_coding;
+	submit.sm_default_msg_id = deliver.sm_default_msg_id;
+	submit.sm_length = deliver.sm_length;
+	memcpy(submit.short_message, deliver.short_message,
+		OSMO_MIN(sizeof(submit.short_message),
+			 sizeof(deliver.short_message)));
+
+	/* FIXME: More TLV? */
+	t = find_tlv(deliver.tlv, TLVID_user_message_reference);
+	if (t) {
+		tlv_t tlv;
+
+		memset(&tlv, 0, sizeof(tlv));
+		tlv.tag = TLVID_user_message_reference;
+		tlv.length = 2;
+		tlv.value.val16 = t->value.val16;
+		build_tlv(&submit.tlv, &tlv);
+	}
+
+	return PACK_AND_SEND(esme, &submit);
+}
+
+static int bind_transceiver(struct esme *esme)
+{
+	struct bind_transceiver_t bind;
+
+	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_type, sizeof(bind.system_type), "mirror");
+	bind.interface_version = esme->smpp_version;
+
+	return PACK_AND_SEND(esme, &bind);
+}
+
+static int smpp_pdu_rx(struct esme *esme, struct msgb *msg)
+{
+	uint32_t cmd_id = smpp_msgb_cmdid(msg);
+	int rc;
+
+	switch (cmd_id) {
+	case DELIVER_SM:
+		rc = smpp_handle_deliver(esme, msg);
+		break;
+	default:
+		LOGP(DSMPP, LOGL_NOTICE, "unhandled case %d\n", cmd_id);
+		rc = 0;
+		break;
+	}
+
+	return rc;
+}
+
+/* FIXME: merge with smpp_smsc.c */
+static int esme_read_cb(struct osmo_fd *ofd)
+{
+	struct esme *esme = ofd->data;
+	uint32_t len;
+	uint8_t *lenptr = (uint8_t *) &len;
+	uint8_t *cur;
+	struct msgb *msg;
+	int rdlen;
+	int rc;
+
+	switch (esme->read_state) {
+	case READ_ST_IN_LEN:
+		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);
+		} else if (rc == 0) {
+			goto dead_socket;
+		} else
+			esme->read_idx += rc;
+		if (esme->read_idx >= sizeof(uint32_t)) {
+			esme->read_len = ntohl(len);
+			msg = msgb_alloc(esme->read_len, "SMPP Rx");
+			if (!msg)
+				return -ENOMEM;
+			esme->read_msg = msg;
+			cur = msgb_put(msg, sizeof(uint32_t));
+			memcpy(cur, lenptr, sizeof(uint32_t));
+			esme->read_state = READ_ST_IN_MSG;
+			esme->read_idx = sizeof(uint32_t);
+		}
+		break;
+	case READ_ST_IN_MSG:
+		msg = esme->read_msg;
+		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);
+		} else if (rc == 0) {
+			goto dead_socket;
+		} else {
+			esme->read_idx += rc;
+			msgb_put(msg, rc);
+		}
+
+		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;
+		}
+		break;
+	}
+
+	return 0;
+dead_socket:
+	msgb_free(esme->read_msg);
+	osmo_fd_unregister(&esme->wqueue.bfd);
+	close(esme->wqueue.bfd.fd);
+	esme->wqueue.bfd.fd = -1;
+	exit(2342);
+
+	return 0;
+}
+
+static int esme_write_cb(struct osmo_fd *ofd, struct msgb *msg)
+{
+	struct 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;
+		exit(99);
+	} else if (rc < msgb_length(msg)) {
+		LOGP(DSMPP, LOGL_ERROR, "[%s] Short write\n", esme->system_id);
+		return 0;
+	}
+
+	return 0;
+}
+
+static int smpp_esme_init(struct esme *esme, const char *host, uint16_t port)
+{
+	int rc;
+
+	if (port == 0)
+		port = 2775;
+
+	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;
+
+	rc = osmo_sock_init_ofd(&esme->wqueue.bfd, AF_UNSPEC, SOCK_STREAM,
+				IPPROTO_TCP, host, port, OSMO_SOCK_F_CONNECT);
+	if (rc < 0)
+		return rc;
+
+	return bind_transceiver(esme);
+}
+
+static const struct log_info_cat smpp_mirror_default_categories[] = {
+	[DSMPP] = {
+		.name = "DSMPP",
+		.description = "SMPP interface for external SMS apps",
+		.enabled = 1, .loglevel = LOGL_DEBUG,
+	},
+};
+
+const struct log_info log_info = {
+	.cat = smpp_mirror_default_categories,
+	.num_cat = ARRAY_SIZE(smpp_mirror_default_categories),
+};
+
+int main(int argc, char **argv)
+{
+	struct esme esme;
+	char *host = "localhost";
+	int port = 0;
+	int rc;
+	void *ctx = talloc_named_const(NULL, 0, "smpp_mirror");
+
+	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;
+
+	if (argc >= 2)
+		host = argv[1];
+	if (argc >= 3)
+		port = atoi(argv[2]);
+
+	rc = smpp_esme_init(&esme, host, port);
+	if (rc < 0)
+		exit(1);
+
+	while (1) {
+		osmo_select_main(0);
+	}
+
+	exit(0);
+}
diff --git a/tests/Makefile.am b/tests/Makefile.am
new file mode 100644
index 0000000..c225afa
--- /dev/null
+++ b/tests/Makefile.am
@@ -0,0 +1,76 @@
+SUBDIRS = \
+	sms_queue \
+	msc_vlr \
+	$(NULL)
+
+if BUILD_SMPP
+SUBDIRS += \
+	smpp \
+	$(NULL)
+endif
+
+# The `:;' works around a Bash 3.2 bug when the output is not writeable.
+$(srcdir)/package.m4: $(top_srcdir)/configure.ac
+	:;{ \
+               echo '# Signature of the current package.' && \
+               echo 'm4_define([AT_PACKAGE_NAME],' && \
+               echo '  [$(PACKAGE_NAME)])' && \
+               echo 'm4_define([AT_PACKAGE_TARNAME],' && \
+               echo '  [$(PACKAGE_TARNAME)])' && \
+               echo 'm4_define([AT_PACKAGE_VERSION],' && \
+               echo '  [$(PACKAGE_VERSION)])' && \
+               echo 'm4_define([AT_PACKAGE_STRING],' && \
+               echo '  [$(PACKAGE_STRING)])' && \
+               echo 'm4_define([AT_PACKAGE_BUGREPORT],' && \
+               echo '  [$(PACKAGE_BUGREPORT)])'; \
+               echo 'm4_define([AT_PACKAGE_URL],' && \
+               echo '  [$(PACKAGE_URL)])'; \
+             } >'$(srcdir)/package.m4'
+
+EXTRA_DIST = \
+	testsuite.at \
+	$(srcdir)/package.m4 \
+	$(TESTSUITE) \
+	vty_test_runner.py \
+	ctrl_test_runner.py \
+	smpp_test_runner.py \
+	$(NULL)
+
+TESTSUITE = $(srcdir)/testsuite
+
+DISTCLEANFILES = \
+	atconfig \
+	$(NULL)
+
+if ENABLE_EXT_TESTS
+python-tests: $(BUILT_SOURCES)
+	osmotestvty.py -p $(abs_top_srcdir) -w $(abs_top_builddir) -v
+	osmotestconfig.py -p $(abs_top_srcdir) -w $(abs_top_builddir) -v
+	$(PYTHON) $(srcdir)/vty_test_runner.py -w $(abs_top_builddir) -v
+	$(PYTHON) $(srcdir)/ctrl_test_runner.py -w $(abs_top_builddir) -v
+if BUILD_SMPP
+	$(PYTHON) $(srcdir)/smpp_test_runner.py -w $(abs_top_builddir) -v
+endif
+	rm -f $(top_builddir)/sms.db
+else
+python-tests: $(BUILT_SOURCES)
+	echo "Not running python-based tests (determined at configure-time)"
+endif
+
+check-local: atconfig $(TESTSUITE)
+	$(SHELL) '$(TESTSUITE)' $(TESTSUITEFLAGS)
+	$(MAKE) $(AM_MAKEFLAGS) python-tests
+
+installcheck-local: atconfig $(TESTSUITE)
+	$(SHELL) '$(TESTSUITE)' AUTOTEST_PATH='$(bindir)' \
+		$(TESTSUITEFLAGS)
+
+clean-local:
+	test ! -f '$(TESTSUITE)' || \
+		$(SHELL) '$(TESTSUITE)' --clean
+
+AUTOM4TE = $(SHELL) $(top_srcdir)/missing --run autom4te
+AUTOTEST = $(AUTOM4TE) --language=autotest
+$(TESTSUITE): $(srcdir)/testsuite.at $(srcdir)/package.m4
+	$(AUTOTEST) -I '$(srcdir)' -o $@.tmp $@.at
+	mv $@.tmp $@
diff --git a/tests/atlocal.in b/tests/atlocal.in
new file mode 100644
index 0000000..f361387
--- /dev/null
+++ b/tests/atlocal.in
@@ -0,0 +1 @@
+enable_smpp_test='@osmo_ac_build_smpp@'
diff --git a/tests/ctrl_test_runner.py b/tests/ctrl_test_runner.py
new file mode 100644
index 0000000..05d3e30
--- /dev/null
+++ b/tests/ctrl_test_runner.py
@@ -0,0 +1,192 @@
+#!/usr/bin/env python
+
+# (C) 2013 by Jacob Erlbeck <jerlbeck@sysmocom.de>
+# (C) 2014 by Holger Hans Peter Freyther
+# based on vty_test_runner.py:
+# (C) 2013 by Katerina Barone-Adesi <kat.obsc@gmail.com>
+# (C) 2013 by Holger Hans Peter Freyther
+# based on bsc_control.py.
+
+# 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/>.
+
+import os
+import time
+import unittest
+import socket
+import sys
+import struct
+
+import osmopy.obscvty as obscvty
+import osmopy.osmoutil as osmoutil
+from osmopy.osmo_ipa import Ctrl, IPA
+
+# to be able to find $top_srcdir/doc/...
+confpath = os.path.join(sys.path[0], '..')
+verbose = False
+
+class TestCtrlBase(unittest.TestCase):
+
+    def ctrl_command(self):
+        raise Exception("Needs to be implemented by a subclass")
+
+    def ctrl_app(self):
+        raise Exception("Needs to be implemented by a subclass")
+
+    def setUp(self):
+        osmo_ctrl_cmd = self.ctrl_command()[:]
+        config_index = osmo_ctrl_cmd.index('-c')
+        if config_index:
+            cfi = config_index + 1
+            osmo_ctrl_cmd[cfi] = os.path.join(confpath, osmo_ctrl_cmd[cfi])
+
+        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"
+        time.sleep(2)
+
+        appstring = self.ctrl_app()[2]
+        appport = self.ctrl_app()[0]
+        self.connect("127.0.0.1", appport)
+        self.next_id = 1000
+
+    def tearDown(self):
+        self.disconnect()
+        osmoutil.end_proc(self.proc)
+
+    def disconnect(self):
+        if not (self.sock is None):
+            self.sock.close()
+
+    def connect(self, host, port):
+        if verbose:
+            print "Connecting to host %s:%i" % (host, port)
+
+        retries = 30
+        while True:
+            try:
+                sck = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+                sck.setblocking(1)
+                sck.connect((host, port))
+            except IOError:
+                retries -= 1
+                if retries <= 0:
+                    raise
+                time.sleep(.1)
+                continue
+            break
+        self.sock = sck
+        return sck
+
+    def send(self, data):
+        if verbose:
+            print "Sending \"%s\"" %(data)
+        data = Ctrl().add_header(data)
+        return self.sock.send(data) == len(data)
+
+    def send_set(self, var, value, id):
+        setmsg = "SET %s %s %s" %(id, var, value)
+        return self.send(setmsg)
+
+    def send_get(self, var, id):
+        getmsg = "GET %s %s" %(id, var)
+        return self.send(getmsg)
+
+    def do_set(self, var, value):
+        id = self.next_id
+        self.next_id += 1
+        self.send_set(var, value, id)
+        return self.recv_msgs()[id]
+
+    def do_get(self, var):
+        id = self.next_id
+        self.next_id += 1
+        self.send_get(var, id)
+        return self.recv_msgs()[id]
+
+    def recv_msgs(self):
+        responses = {}
+        data = self.sock.recv(4096)
+        while (len(data)>0):
+            (head, data) = IPA().split_combined(data)
+            answer = Ctrl().rem_header(head)
+            if verbose:
+                print "Got message:", answer
+            (mtype, id, msg) = answer.split(None, 2)
+            id = int(id)
+            rsp = {'mtype': mtype, 'id': id}
+            if mtype == "ERROR":
+                rsp['error'] = msg
+            else:
+                split = msg.split(None, 1)
+                rsp['var'] = split[0]
+                if len(split) > 1:
+                    rsp['value'] = split[1]
+                else:
+                    rsp['value'] = None
+            responses[id] = rsp
+
+        if verbose:
+            print "Decoded replies: ", responses
+
+        return responses
+
+
+class TestCtrlMSC(TestCtrlBase):
+    def ctrl_command(self):
+        return ["./src/osmo-msc/osmo-msc", "-c",
+                "doc/examples/osmo-msc/osmo-msc.cfg"]
+
+    def ctrl_app(self):
+        return (4255, "./src/osmo-msc/osmo-msc", "OsmoMSC", "msc")
+
+    def testRateCounters(self):
+        r = self.do_get('rate_ctr.*')
+
+    # FIXME: add MSC-specific CTRL test in here
+
+if __name__ == '__main__':
+    import argparse
+    import sys
+
+    workdir = '.'
+
+    parser = argparse.ArgumentParser()
+    parser.add_argument("-v", "--verbose", dest="verbose",
+                        action="store_true", help="verbose mode")
+    parser.add_argument("-p", "--pythonconfpath", dest="p",
+                        help="searchpath for config")
+    parser.add_argument("-w", "--workdir", dest="w",
+                        help="Working directory")
+    args = parser.parse_args()
+
+    verbose_level = 1
+    if args.verbose:
+        verbose_level = 2
+        verbose = True
+
+    if args.w:
+        workdir = args.w
+
+    if args.p:
+        confpath = args.p
+
+    print "confpath %s, workdir %s" % (confpath, workdir)
+    os.chdir(workdir)
+    print "Running tests for specific control commands"
+    suite = unittest.TestSuite()
+    suite.addTest(unittest.TestLoader().loadTestsFromTestCase(TestCtrlMSC))
+    res = unittest.TextTestRunner(verbosity=verbose_level).run(suite)
+    sys.exit(len(res.errors) + len(res.failures))
diff --git a/tests/db/Makefile.am b/tests/db/Makefile.am
new file mode 100644
index 0000000..249a873
--- /dev/null
+++ b/tests/db/Makefile.am
@@ -0,0 +1,44 @@
+AM_CPPFLAGS = \
+	$(all_includes) \
+	-I$(top_srcdir)/include \
+	$(NULL)
+
+AM_CFLAGS = \
+	-Wall \
+	-ggdb3 \
+	$(LIBOSMOCORE_CFLAGS) \
+	$(LIBOSMOGSM_CFLAGS) \
+	$(LIBOSMOABIS_CFLAGS) \
+	$(LIBSMPP34_CFLAGS) \
+	$(COVERAGE_CFLAGS) \
+	$(NULL)
+
+AM_LDFLAGS = \
+	$(COVERAGE_LDFLAGS) \
+	$(NULL)
+
+EXTRA_DIST = \
+	db_test.ok \
+	db_test.err \
+	hlr.sqlite3 \
+	$(NULL)
+
+noinst_PROGRAMS = \
+	db_test \
+	$(NULL)
+
+db_test_SOURCES = \
+	db_test.c \
+	$(NULL)
+
+db_test_LDADD = \
+	$(top_builddir)/src/libmsc/libmsc.a \
+	$(top_builddir)/src/libtrau/libtrau.a \
+	$(top_builddir)/tests/libiudummy/libiudummy.a \
+	$(LIBOSMOCORE_LIBS) \
+	$(LIBOSMOABIS_LIBS) \
+	$(LIBOSMOGSM_LIBS) \
+	$(LIBSMPP34_LIBS) \
+	$(LIBOSMOVTY_LIBS) \
+	-ldbi \
+	$(NULL)
diff --git a/tests/db/db_test.c b/tests/db/db_test.c
new file mode 100644
index 0000000..63099f6
--- /dev/null
+++ b/tests/db/db_test.c
@@ -0,0 +1,286 @@
+/* (C) 2008 by Jan Luebbe <jluebbe@debian.org>
+ * (C) 2009-2016 by Holger Hans Peter Freyther <zecke@selfish.org>
+ * (C) 2014 by Alexander Chemeris <Alexander.Chemeris@fairwaves.co>
+ * 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 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/debug.h>
+#include <osmocom/msc/db.h>
+#include <osmocom/msc/gsm_subscriber.h>
+#include <osmocom/msc/gsm_04_11.h>
+#include <osmocom/msc/mgcp.h>
+
+#include <osmocom/core/application.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <inttypes.h>
+
+static struct gsm_network dummy_net;
+static struct gsm_subscriber_group dummy_sgrp;
+
+#define SUBSCR_PUT(sub) \
+	sub->group = &dummy_sgrp;	\
+	subscr_put(sub);
+
+#define COMPARE(original, copy) \
+	if (original->id != copy->id) \
+		printf("Ids do not match in %s:%d %llu %llu\n", \
+			__FUNCTION__, __LINE__, original->id, copy->id); \
+	if (original->lac != copy->lac) \
+		printf("LAC do not match in %s:%d %d %d\n", \
+			__FUNCTION__, __LINE__, original->lac, copy->lac); \
+	if (original->authorized != copy->authorized) \
+		printf("Authorize do not match in %s:%d %d %d\n", \
+			__FUNCTION__, __LINE__, original->authorized, \
+			copy->authorized); \
+	if (strcmp(original->imsi, copy->imsi) != 0) \
+		printf("IMSIs do not match in %s:%d '%s' '%s'\n", \
+			__FUNCTION__, __LINE__, original->imsi, copy->imsi); \
+	if (original->tmsi != copy->tmsi) \
+		printf("TMSIs do not match in %s:%d '%u' '%u'\n", \
+			__FUNCTION__, __LINE__, original->tmsi, copy->tmsi); \
+	if (strcmp(original->name, copy->name) != 0) \
+		printf("names do not match in %s:%d '%s' '%s'\n", \
+			__FUNCTION__, __LINE__, original->name, copy->name); \
+	if (strcmp(original->extension, copy->extension) != 0) \
+		printf("Extensions do not match in %s:%d '%s' '%s'\n", \
+			__FUNCTION__, __LINE__, original->extension, copy->extension); \
+
+/*
+ * Create/Store a SMS and then try to load it.
+ */
+static void test_sms(void)
+{
+	int rc;
+	struct gsm_sms *sms;
+	struct gsm_subscriber *subscr;
+	subscr = db_get_subscriber(GSM_SUBSCRIBER_IMSI, "9993245423445");
+	OSMO_ASSERT(subscr);
+	subscr->group = &dummy_sgrp;
+
+	sms = sms_alloc();
+	sms->receiver = subscr_get(subscr);
+
+	sms->src.ton = 0x23;
+	sms->src.npi = 0x24;
+	memcpy(sms->src.addr, "1234", strlen("1234") + 1);
+
+	sms->dst.ton = 0x32;
+	sms->dst.npi = 0x42;
+	memcpy(sms->dst.addr, subscr->extension, sizeof(subscr->extension));
+
+	memcpy(sms->text, "Text123", strlen("Text123") + 1);
+	memcpy(sms->user_data, "UserData123", strlen("UserData123") + 1);
+	sms->user_data_len = strlen("UserData123");
+
+	/* random values */
+	sms->reply_path_req = 1;
+	sms->status_rep_req = 2;
+	sms->ud_hdr_ind = 3;
+	sms->protocol_id = 4;
+	sms->data_coding_scheme = 5;
+
+	rc = db_sms_store(sms);
+	sms_free(sms);
+	OSMO_ASSERT(rc == 0);
+
+	/* now query */
+	sms = db_sms_get_unsent_for_subscr(subscr);
+	OSMO_ASSERT(sms);
+	OSMO_ASSERT(sms->receiver == subscr);
+	OSMO_ASSERT(sms->reply_path_req == 1);
+	OSMO_ASSERT(sms->status_rep_req == 2);
+	OSMO_ASSERT(sms->ud_hdr_ind == 3);
+	OSMO_ASSERT(sms->protocol_id == 4);
+	OSMO_ASSERT(sms->data_coding_scheme == 5);
+	OSMO_ASSERT(sms->src.ton == 0x23);
+	OSMO_ASSERT(sms->src.npi == 0x24);
+	OSMO_ASSERT(sms->dst.ton == 0x32);
+	OSMO_ASSERT(sms->dst.npi == 0x42);
+	OSMO_ASSERT(strcmp((char *) sms->text, "Text123") == 0);
+	OSMO_ASSERT(sms->user_data_len == strlen("UserData123"));
+	OSMO_ASSERT(strcmp((char *) sms->user_data, "UserData123") == 0);
+
+	/* Mark the SMS as delivered */
+	db_sms_mark_delivered(sms);
+	sms_free(sms);
+
+	sms = db_sms_get_unsent_for_subscr(subscr);
+	OSMO_ASSERT(!sms);
+
+	subscr_put(subscr);
+}
+
+static void test_sms_migrate(void)
+{
+	struct gsm_subscriber *rcv_subscr;
+	struct gsm_sms *sms;
+	static const uint8_t user_data_1[] = {
+		0x41, 0xf1, 0xd8, 0x05, 0x22, 0x96, 0xcd, 0x2e,
+		0x90, 0xf1, 0xfd, 0x06, 0x00 };
+	static const uint8_t user_data_2[] = {
+		0x41, 0xf1, 0xd8, 0x05, 0x22, 0x96, 0xcd, 0x2e,
+		0xd0, 0xf1, 0xfd, 0x06, 0x00 };
+
+	rcv_subscr = db_get_subscriber(GSM_SUBSCRIBER_IMSI, "901010000001111");
+	rcv_subscr->group = &dummy_sgrp;
+
+	sms = db_sms_get(&dummy_net, 1);
+	OSMO_ASSERT(sms->id == 1);
+	OSMO_ASSERT(sms->receiver == rcv_subscr);
+	OSMO_ASSERT(strcmp(sms->text, "Abc. Def. Foo") == 0);
+	OSMO_ASSERT(sms->user_data_len == ARRAY_SIZE(user_data_1));
+	OSMO_ASSERT(memcmp(sms->user_data, user_data_1, ARRAY_SIZE(user_data_1)) == 0);
+	sms_free(sms);
+
+	sms = db_sms_get(&dummy_net, 2);
+	OSMO_ASSERT(sms->id == 2);
+	OSMO_ASSERT(sms->receiver == rcv_subscr);
+	OSMO_ASSERT(strcmp(sms->text, "Abc. Def. Goo") == 0);
+	OSMO_ASSERT(sms->user_data_len == ARRAY_SIZE(user_data_2));
+	OSMO_ASSERT(memcmp(sms->user_data, user_data_2, ARRAY_SIZE(user_data_2)) == 0);
+	sms_free(sms);
+
+	subscr_put(rcv_subscr);
+}
+
+static void test_subs(const char *imsi, char *imei1, char *imei2, bool make_ext)
+{
+	struct gsm_subscriber *alice = NULL, *alice_db;
+	char scratch_str[256];
+
+	alice = db_create_subscriber(imsi, GSM_MIN_EXTEN, GSM_MAX_EXTEN,
+				     make_ext);
+	db_subscriber_assoc_imei(alice, imei1);
+	if (imei2)
+		db_subscriber_assoc_imei(alice, imei2);
+	db_subscriber_alloc_tmsi(alice);
+	alice->lac=42;
+	db_sync_subscriber(alice);
+	/* Get by TMSI */
+	snprintf(scratch_str, sizeof(scratch_str), "%"PRIu32, alice->tmsi);
+	alice_db = db_get_subscriber(GSM_SUBSCRIBER_TMSI, scratch_str);
+	COMPARE(alice, alice_db);
+	SUBSCR_PUT(alice_db);
+	/* Get by IMSI */
+	alice_db = db_get_subscriber(GSM_SUBSCRIBER_IMSI, imsi);
+	COMPARE(alice, alice_db);
+	SUBSCR_PUT(alice_db);
+	/* Get by id */
+	snprintf(scratch_str, sizeof(scratch_str), "%llu", alice->id);
+	alice_db = db_get_subscriber(GSM_SUBSCRIBER_ID, scratch_str);
+	COMPARE(alice, alice_db);
+	SUBSCR_PUT(alice_db);
+	/* Get by extension */
+	alice_db = db_get_subscriber(GSM_SUBSCRIBER_EXTENSION, alice->extension);
+	if (alice_db) {
+		if (!make_ext)
+			printf("FAIL: bogus extension created for IMSI %s\n",
+			       imsi);
+		COMPARE(alice, alice_db);
+		SUBSCR_PUT(alice_db);
+	} else if (make_ext)
+		printf("FAIL: no subscriber extension for IMSI %s\n", imsi);
+	SUBSCR_PUT(alice);
+}
+
+int main()
+{
+	printf("Testing subscriber database code.\n");
+	osmo_init_logging(&log_info);
+	log_set_print_filename(osmo_stderr_target, 0);
+
+	dummy_net.subscr_group = &dummy_sgrp;
+	dummy_sgrp.net         = &dummy_net;
+
+	if (db_init("hlr.sqlite3")) {
+		printf("DB: Failed to init database. Please check the option settings.\n");
+		return 1;
+	}	 
+	printf("DB: Database initialized.\n");
+
+	if (db_prepare()) {
+		printf("DB: Failed to prepare database.\n");
+		return 1;
+	}
+	printf("DB: Database prepared.\n");
+
+	struct gsm_subscriber *alice = NULL;
+	struct gsm_subscriber *alice_db;
+
+	char *alice_imsi = "3243245432345";
+	alice = db_create_subscriber(alice_imsi, GSM_MIN_EXTEN, GSM_MAX_EXTEN,
+				     true);
+	db_sync_subscriber(alice);
+	alice_db = db_get_subscriber(GSM_SUBSCRIBER_IMSI, alice->imsi);
+	COMPARE(alice, alice_db);
+	SUBSCR_PUT(alice_db);
+	SUBSCR_PUT(alice);
+
+	test_subs("3693245423445", "1234567890", NULL, true);
+	test_subs("9993245423445", "1234567890", "6543560920", true);
+	test_subs("3123122223445", "1234567890", NULL, false);
+	test_subs("9123121223445", "1234567890", "6543560920", false);
+
+	/* create it again and see it fails */
+	alice = db_create_subscriber(alice_imsi, GSM_MIN_EXTEN, GSM_MAX_EXTEN,
+				     true);
+	OSMO_ASSERT(!alice);
+
+	test_sms();
+	test_sms_migrate();
+
+	db_fini();
+
+	printf("Done\n");
+	return 0;
+}
+
+/* stubs */
+void vty_out() {}
+void vlr_subscr_disconnected() {}
+void vlr_subscr_rx_tmsi_reall_compl() {}
+void vlr_subscr_rx_id_resp() {}
+void vlr_subscr_rx_auth_resp() {}
+void vlr_loc_update() {}
+void vlr_proc_acc_req() {}
+void vlr_init() {}
+unsigned int mgcpgw_client_next_endpoint(struct mgcpgw_client *client)
+{ return 0; }
+struct msgb *mgcp_msg_crcx(struct mgcpgw_client *mgcp,
+			   uint16_t rtp_endpoint, unsigned int call_id,
+			   enum mgcp_connection_mode mode)
+{ return NULL; }
+struct msgb *mgcp_msg_mdcx(struct mgcpgw_client *mgcp,
+			   uint16_t rtp_endpoint, const char *rtp_conn_addr,
+			   uint16_t rtp_port, enum mgcp_connection_mode mode)
+{ return NULL; }
+int mgcpgw_client_tx(struct mgcpgw_client *mgcp, struct msgb *msg,
+		     mgcp_response_cb_t response_cb, void *priv)
+{ return -EINVAL; }
+const char *mgcpgw_client_remote_addr_str(struct mgcpgw_client *mgcp)
+{ return "0.0.0.0"; }
+uint32_t mgcpgw_client_remote_addr_n(struct mgcpgw_client *mgcp)
+{ return 0; }
+int mgcp_response_parse_params(struct mgcp_response *r)
+{ return -EINVAL; }
+struct RANAP_Cause;
+int iu_tx_release(struct ue_conn_ctx *ctx, const struct RANAP_Cause *cause)
+{ return 0; }
diff --git a/tests/db/db_test.err b/tests/db/db_test.err
new file mode 100644
index 0000000..27e5703
--- /dev/null
+++ b/tests/db/db_test.err
@@ -0,0 +1,3 @@
+Going to migrate from revision 3
+Going to migrate from revision 4
+
\ No newline at end of file
diff --git a/tests/db/db_test.ok b/tests/db/db_test.ok
new file mode 100644
index 0000000..2632a8c
--- /dev/null
+++ b/tests/db/db_test.ok
@@ -0,0 +1,4 @@
+Testing subscriber database code.
+DB: Database initialized.
+DB: Database prepared.
+Done
diff --git a/tests/db/hlr.sqlite3 b/tests/db/hlr.sqlite3
new file mode 100644
index 0000000..e59dcdc
--- /dev/null
+++ b/tests/db/hlr.sqlite3
Binary files differ
diff --git a/tests/msc_vlr/Makefile.am b/tests/msc_vlr/Makefile.am
new file mode 100644
index 0000000..1d1956a
--- /dev/null
+++ b/tests/msc_vlr/Makefile.am
@@ -0,0 +1,177 @@
+AM_CPPFLAGS = \
+	$(all_includes) \
+	-I$(top_srcdir)/include \
+	$(NULL)
+
+AM_CFLAGS = \
+	-Wall \
+	-ggdb3 \
+	$(LIBOSMOCORE_CFLAGS) \
+	$(LIBOSMOGSM_CFLAGS) \
+	$(LIBSMPP34_CFLAGS) \
+	$(LIBOSMOVTY_CFLAGS) \
+	$(LIBOSMOABIS_CFLAGS) \
+	$(LIBOSMOSIGTRAN_CFLAGS) \
+	$(LIBOSMORANAP_CFLAGS) \
+	$(LIBASN1C_CFLAGS) \
+	$(LIBOSMOMGCPCLIENT_CFLAGS) \
+	$(LIBOSMOGSUPCLIENT_CFLAGS) \
+	$(NULL)
+
+AM_LDFLAGS = \
+	-Wl,--wrap=osmo_gsup_client_create \
+	-Wl,--wrap=osmo_gsup_client_send \
+	-Wl,--wrap=a_iface_tx_dtap \
+	-Wl,--wrap=a_iface_tx_clear_cmd \
+	-Wl,--wrap=a_iface_tx_paging \
+	-Wl,--wrap=ranap_iu_tx \
+	-Wl,--wrap=ranap_iu_tx_release \
+	-Wl,--wrap=ranap_iu_tx_common_id \
+	-Wl,--wrap=ranap_iu_page_cs \
+	-Wl,--wrap=msc_stop_paging \
+	-Wl,--wrap=gsm340_gen_scts \
+	-Wl,--wrap=osmo_get_rand_id \
+	-Wl,--wrap=msc_mgcp_call_release \
+	-Wl,--wrap=msc_mgcp_call_assignment \
+	-Wl,--wrap=a_iface_tx_cipher_mode \
+	-Wl,--wrap=ranap_iu_tx_sec_mode_cmd \
+	-Wl,--wrap=osmo_sccp_tx_data_msg \
+	$(NULL)
+
+LDADD = \
+	$(top_builddir)/src/libmsc/libmsc.a \
+	$(top_builddir)/src/libvlr/libvlr.a \
+	$(LIBSMPP34_LIBS) \
+	$(LIBOSMOCORE_LIBS) \
+	$(LIBOSMOGSM_LIBS) \
+	$(LIBOSMOVTY_LIBS) \
+	$(LIBOSMOABIS_LIBS) \
+	$(LIBOSMOSIGTRAN_LIBS) \
+	$(LIBOSMORANAP_LIBS) \
+	$(LIBOSMOMGCPCLIENT_LIBS) \
+	$(LIBOSMOGSUPCLIENT_LIBS) \
+	$(LIBRARY_GSM) \
+	-ldbi \
+	-lrt \
+	$(NULL)
+
+noinst_HEADERS = \
+	msc_vlr_tests.h \
+	$(NULL)
+
+EXTRA_DIST = \
+	msc_vlr_test_no_authen.ok \
+	msc_vlr_test_no_authen.err \
+	msc_vlr_test_gsm_authen.ok \
+	msc_vlr_test_gsm_authen.err \
+	msc_vlr_test_gsm_ciph.ok \
+	msc_vlr_test_gsm_ciph.err \
+	msc_vlr_test_umts_authen.ok \
+	msc_vlr_test_umts_authen.err \
+	msc_vlr_test_authen_reuse.ok \
+	msc_vlr_test_authen_reuse.err \
+	msc_vlr_test_hlr_reject.ok \
+	msc_vlr_test_hlr_reject.err \
+	msc_vlr_test_hlr_timeout.ok \
+	msc_vlr_test_hlr_timeout.err \
+	msc_vlr_test_ms_timeout.ok \
+	msc_vlr_test_ms_timeout.err \
+	msc_vlr_test_reject_concurrency.ok \
+	msc_vlr_test_reject_concurrency.err \
+	msc_vlr_test_call.ok \
+	msc_vlr_test_call.err \
+	msc_vlr_test_rest.ok \
+	msc_vlr_test_rest.err \
+	msc_vlr_test_ss.ok \
+	msc_vlr_test_ss.err \
+	$(NULL)
+
+noinst_PROGRAMS = \
+	msc_vlr_test_no_authen \
+	msc_vlr_test_gsm_authen \
+	msc_vlr_test_gsm_ciph \
+	msc_vlr_test_umts_authen \
+	msc_vlr_test_authen_reuse \
+	msc_vlr_test_hlr_reject \
+	msc_vlr_test_hlr_timeout \
+	msc_vlr_test_ms_timeout \
+	msc_vlr_test_reject_concurrency \
+	msc_vlr_test_call \
+	msc_vlr_test_rest \
+	msc_vlr_test_ss \
+	$(NULL)
+
+msc_vlr_test_no_authen_SOURCES = \
+	msc_vlr_test_no_authen.c \
+	msc_vlr_tests.c \
+	$(NULL)
+
+msc_vlr_test_gsm_authen_SOURCES = \
+	msc_vlr_test_gsm_authen.c \
+	msc_vlr_tests.c \
+	$(NULL)
+
+msc_vlr_test_gsm_ciph_SOURCES = \
+	msc_vlr_test_gsm_ciph.c \
+	msc_vlr_tests.c \
+	$(NULL)
+
+msc_vlr_test_umts_authen_SOURCES = \
+	msc_vlr_test_umts_authen.c \
+	msc_vlr_tests.c \
+	$(NULL)
+
+msc_vlr_test_authen_reuse_SOURCES = \
+	msc_vlr_test_authen_reuse.c \
+	msc_vlr_tests.c \
+	$(NULL)
+
+msc_vlr_test_hlr_reject_SOURCES = \
+	msc_vlr_test_hlr_reject.c \
+	msc_vlr_tests.c \
+	$(NULL)
+
+msc_vlr_test_hlr_timeout_SOURCES = \
+	msc_vlr_test_hlr_timeout.c \
+	msc_vlr_tests.c \
+	$(NULL)
+
+msc_vlr_test_ms_timeout_SOURCES = \
+	msc_vlr_test_ms_timeout.c \
+	msc_vlr_tests.c \
+	$(NULL)
+
+msc_vlr_test_reject_concurrency_SOURCES = \
+	msc_vlr_test_reject_concurrency.c \
+	msc_vlr_tests.c \
+	$(NULL)
+
+msc_vlr_test_call_SOURCES = \
+	msc_vlr_test_call.c \
+	msc_vlr_tests.c \
+	$(NULL)
+
+msc_vlr_test_rest_SOURCES = \
+	msc_vlr_test_rest.c \
+	msc_vlr_tests.c \
+	$(NULL)
+
+msc_vlr_test_ss_SOURCES = \
+	msc_vlr_test_ss.c \
+	msc_vlr_tests.c \
+	$(NULL)
+
+.PHONY: update_exp
+update_exp:
+	$(builddir)/msc_vlr_test_no_authen >$(srcdir)/msc_vlr_test_no_authen.ok 2>$(srcdir)/msc_vlr_test_no_authen.err
+	$(builddir)/msc_vlr_test_gsm_authen >$(srcdir)/msc_vlr_test_gsm_authen.ok 2>$(srcdir)/msc_vlr_test_gsm_authen.err
+	$(builddir)/msc_vlr_test_gsm_ciph >$(srcdir)/msc_vlr_test_gsm_ciph.ok 2>$(srcdir)/msc_vlr_test_gsm_ciph.err
+	$(builddir)/msc_vlr_test_umts_authen >$(srcdir)/msc_vlr_test_umts_authen.ok 2>$(srcdir)/msc_vlr_test_umts_authen.err
+	$(builddir)/msc_vlr_test_authen_reuse >$(srcdir)/msc_vlr_test_authen_reuse.ok 2>$(srcdir)/msc_vlr_test_authen_reuse.err
+	$(builddir)/msc_vlr_test_hlr_reject >$(srcdir)/msc_vlr_test_hlr_reject.ok 2>$(srcdir)/msc_vlr_test_hlr_reject.err
+	$(builddir)/msc_vlr_test_hlr_timeout >$(srcdir)/msc_vlr_test_hlr_timeout.ok 2>$(srcdir)/msc_vlr_test_hlr_timeout.err
+	$(builddir)/msc_vlr_test_ms_timeout >$(srcdir)/msc_vlr_test_ms_timeout.ok 2>$(srcdir)/msc_vlr_test_ms_timeout.err
+	$(builddir)/msc_vlr_test_reject_concurrency >$(srcdir)/msc_vlr_test_reject_concurrency.ok 2>$(srcdir)/msc_vlr_test_reject_concurrency.err
+	$(builddir)/msc_vlr_test_call >$(srcdir)/msc_vlr_test_call.ok 2>$(srcdir)/msc_vlr_test_call.err
+	$(builddir)/msc_vlr_test_rest >$(srcdir)/msc_vlr_test_rest.ok 2>$(srcdir)/msc_vlr_test_rest.err
+	$(builddir)/msc_vlr_test_ss >$(srcdir)/msc_vlr_test_ss.ok 2>$(srcdir)/msc_vlr_test_ss.err
diff --git a/tests/msc_vlr/msc_vlr_test_authen_reuse.c b/tests/msc_vlr/msc_vlr_test_authen_reuse.c
new file mode 100644
index 0000000..6591557
--- /dev/null
+++ b/tests/msc_vlr/msc_vlr_test_authen_reuse.c
@@ -0,0 +1,322 @@
+/* Osmocom MSC+VLR end-to-end tests */
+
+/* (C) 2017 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
+ *
+ * All Rights Reserved
+ *
+ * Author: Neels Hofmeyr <nhofmeyr@sysmocom.de>
+ *
+ * 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/>.
+ *
+ */
+
+/* NOTE that further auth re-use tests exist in msc_vlr_test_hlr_reject.c */
+
+#include "msc_vlr_tests.h"
+
+static void _test_auth_reuse(enum ran_type via_ran,
+			     int set_max_reuse_count,
+			     int loop_requests_without_hlr,
+			     bool final_request_with_hlr)
+{
+	struct vlr_subscr *vsub;
+	const char *imsi = "901700000010650";
+	int expected_use_count;
+	int i;
+
+	net->authentication_required = true;
+	net->vlr->cfg.assign_tmsi = true;
+	net->vlr->cfg.auth_tuple_max_reuse_count = set_max_reuse_count;
+	net->vlr->cfg.auth_reuse_old_sets_on_error = false;
+	rx_from_ran = 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");
+	ms_sends_msg("0508" /* MM LU */
+		     "7" /* ciph key seq: no key available */
+		     "0" /* LU type: normal */
+		     "ffffff" "0000" /* 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("from HLR, rx _SEND_AUTH_INFO_RESULT, only one tuple; VLR sends Auth Req to MS");
+	/* based on auc_3g:
+	 * K = 'EB215756028D60E3275E613320AEC880',
+	 * OPC = 'FB2A3D1B360F599ABAB99DB8669F8308'
+	 * SQN = 0
+	 */
+	auth_request_sent = false;
+	auth_request_expect_rand = "39fa2f4e3d523d8619a73b4f65c3e14d";
+	auth_request_expect_autn = "8704f5ba55f30000d2ee44b22c8ea919";
+	gsup_rx("0a"
+		/* imsi */
+		"0108" "09710000000156f0"
+		/* TL    TL     rand */
+		"0362"  "2010" "39fa2f4e3d523d8619a73b4f65c3e14d"
+		/*       TL     sres       TL     kc */
+			"2104" "9b36efdf" "2208" "059a4f668f6fbe39"
+		/*       TL     3G IK */
+			"2310" "27497388b6cb044648f396aa155b95ef"
+		/*       TL     3G CK */
+			"2410" "f64735036e5871319c679f4742a75ea1"
+		/*       TL     AUTN */
+			"2510" "8704f5ba55f30000d2ee44b22c8ea919"
+		/*       TL     RES */
+			"2708" "e229c19e791f2e41",
+		NULL);
+	VERBOSE_ASSERT(auth_request_sent, == true, "%d");
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	if (via_ran == RAN_GERAN_A) {
+		btw("MS sends Authen Response, VLR accepts and sends GSUP LU Req to HLR");
+		gsup_expect_tx("04010809710000000156f0280102");
+		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");
+		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");
+		ms_sends_security_mode_complete();
+		VERBOSE_ASSERT(gsup_tx_confirmed, == true, "%d");
+		VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+	}
+
+	btw("HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT");
+	gsup_rx("10010809710000000156f00804032443f2",
+		"12010809710000000156f0");
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("HLR also sends GSUP _UPDATE_LOCATION_RESULT");
+	gsup_rx("06010809710000000156f0", NULL);
+
+	VERBOSE_ASSERT(lu_result_sent, == RES_ACCEPT, "%d");
+
+	btw("a LU Accept with a new TMSI was sent, waiting for TMSI Realloc Compl");
+	EXPECT_CONN_COUNT(1);
+	EXPECT_ACCEPTED(false);
+	thwart_rx_non_initial_requests();
+
+	btw("even though the TMSI is not acked, we can already find the subscr with it");
+	vsub = vlr_subscr_find_by_tmsi(net->vlr, 0x03020100);
+	VERBOSE_ASSERT(vsub != NULL, == true, "%d");
+	VERBOSE_ASSERT(strcmp(vsub->imsi, imsi), == 0, "%d");
+	VERBOSE_ASSERT(vsub->tmsi_new, == 0x03020100, "0x%08x");
+	VERBOSE_ASSERT(vsub->tmsi, == GSM_RESERVED_TMSI, "0x%08x");
+	vlr_subscr_put(vsub);
+
+	btw("MS sends TMSI Realloc Complete");
+	expect_release_clear(via_ran);
+	ms_sends_msg("055b");
+	ASSERT_RELEASE_CLEAR(via_ran);
+	bss_rnc_sends_release_clear_complete(via_ran);
+
+	btw("LU was successful, and the conn has already been closed");
+	EXPECT_CONN_COUNT(0);
+
+	expected_use_count = 1;
+
+	for (i = 0; i < loop_requests_without_hlr; i++, expected_use_count++) {
+		BTW("Now the auth tuple has use_count == %d", expected_use_count);
+		vsub = vlr_subscr_find_by_imsi(net->vlr, imsi);
+		OSMO_ASSERT(vsub);
+		OSMO_ASSERT(vsub->last_tuple);
+		VERBOSE_ASSERT(vsub->last_tuple->use_count, == expected_use_count, "%d");
+		vlr_subscr_put(vsub);
+
+		BTW("after a while, a new conn sends a CM Service Request. VLR responds with Auth Req,"
+		    " and reuses old auth vector");
+		auth_request_sent = true;
+		cm_service_result_sent = RES_NONE;
+		ms_sends_msg("052478"
+			     "03575886" /* classmark 2 */
+			     "089910070000106005" /* IMSI */);
+		OSMO_ASSERT(g_conn);
+		OSMO_ASSERT(g_conn->fi);
+		OSMO_ASSERT(g_conn->vsub);
+		VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d");
+		VERBOSE_ASSERT(auth_request_sent, == true, "%d");
+
+		if (via_ran == RAN_GERAN_A) {
+			btw("MS sends Authen Response, VLR accepts with a CM Service Accept");
+			gsup_expect_tx(NULL);
+			ms_sends_msg("0554" "e229c19e" "2104" "791f2e41");
+			VERBOSE_ASSERT(cm_service_result_sent, == RES_ACCEPT, "%d");
+		} else {
+			/* On UTRAN */
+			btw("MS sends Authen Response, VLR accepts and sends SecurityModeControl");
+			expect_security_mode_ctrl(NULL, "27497388b6cb044648f396aa155b95ef");
+			ms_sends_msg("0554" "e229c19e" "2104" "791f2e41");
+			VERBOSE_ASSERT(security_mode_ctrl_sent, == true, "%d");
+			VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d");
+
+			btw("MS sends SecurityModeControl acceptance, VLR accepts; above Ciphering is an implicit CM Service Accept");
+			ms_sends_security_mode_complete();
+			VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d");
+		}
+
+		/* Release connection */
+		expect_release_clear(via_ran);
+		conn_conclude_cm_service_req(g_conn, via_ran);
+		bss_rnc_sends_release_clear_complete(via_ran);
+
+		btw("all requests serviced, conn has been released");
+		EXPECT_CONN_COUNT(0);
+	}
+
+	if (final_request_with_hlr) {
+		BTW("Now the auth tuple has use_count == %d, as much as is allowed.", expected_use_count);
+		vsub = vlr_subscr_find_by_imsi(net->vlr, imsi);
+		OSMO_ASSERT(vsub);
+		OSMO_ASSERT(vsub->last_tuple);
+		VERBOSE_ASSERT(vsub->last_tuple->use_count, == expected_use_count, "%d");
+		vlr_subscr_put(vsub);
+
+		BTW("after a while, a new conn sends a CM Service Request. VLR responds with Auth Req,"
+		    " 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");
+		ms_sends_msg("052478"
+			     "03575886" /* classmark 2 */
+			     "089910070000106005" /* IMSI */);
+		OSMO_ASSERT(g_conn);
+		OSMO_ASSERT(g_conn->fi);
+		OSMO_ASSERT(g_conn->vsub);
+		VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d");
+		VERBOSE_ASSERT(auth_request_sent, == false, "%d");
+		VERBOSE_ASSERT(gsup_tx_confirmed, == true, "%d");
+
+		btw("from HLR, rx _SEND_AUTH_INFO_RESULT, second tuple; VLR sends Auth Req to MS");
+		auth_request_expect_rand = "c187a53a5e6b9d573cac7c74451fd46d";
+		auth_request_expect_autn = "1843a645b98d00005b2d666af46c45d9";
+		gsup_rx("0a"
+			/* imsi */
+			"0108" "09710000000156f0"
+			/* TL    TL     rand */
+			/*       TL     sres       TL     kc */
+			/*       TL     3G IK */
+			/*       TL     3G CK */
+			/*       TL     AUTN */
+			/*       TL     RES */
+			"0362"  "2010" "c187a53a5e6b9d573cac7c74451fd46d"
+				"2104" "85aa3130" "2208" "d3d50a000bf04f6e"
+				"2310" "1159ec926a50e98c034a6b7d7c9f418d"
+				"2410" "df3a03d9ca5335641efc8e36d76cd20b"
+				"2510" "1843a645b98d00005b2d666af46c45d9"
+				"2708" "7db47cf7f81e4dc7",
+			NULL);
+		VERBOSE_ASSERT(auth_request_sent, == true, "%d");
+		VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d");
+
+		if (via_ran == RAN_GERAN_A) {
+			btw("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");
+			expect_security_mode_ctrl(NULL, "1159ec926a50e98c034a6b7d7c9f418d");
+			ms_sends_msg("0554" "7db47cf7" "2104" "f81e4dc7"); /* 2nd vector's res, s.a. */
+			VERBOSE_ASSERT(security_mode_ctrl_sent, == true, "%d");
+			VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d");
+
+			btw("MS sends SecurityModeControl acceptance, VLR accepts; above Ciphering is an implicit CM Service Accept");
+			ms_sends_security_mode_complete();
+			VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d");
+		}
+
+		/* Release connection */
+		expect_release_clear(via_ran);
+		conn_conclude_cm_service_req(g_conn, via_ran);
+		bss_rnc_sends_release_clear_complete(via_ran);
+
+		btw("all requests serviced, conn has been released");
+		EXPECT_CONN_COUNT(0);
+	}
+
+	BTW("subscriber detaches");
+	expect_release_clear(via_ran);
+	ms_sends_msg("050130"
+		     "089910070000106005" /* IMSI */);
+	ASSERT_RELEASE_CLEAR(via_ran);
+	bss_rnc_sends_release_clear_complete(via_ran);
+
+	EXPECT_CONN_COUNT(0);
+	clear_vlr();
+}
+
+static void test_auth_use_twice_geran()
+{
+	comment_start();
+	_test_auth_reuse(RAN_GERAN_A, 1, 1, true);
+	comment_end();
+}
+
+static void test_auth_use_twice_utran()
+{
+	comment_start();
+	_test_auth_reuse(RAN_UTRAN_IU, 1, 1, true);
+	comment_end();
+}
+
+static void test_auth_use_infinitely_geran()
+{
+	comment_start();
+	_test_auth_reuse(RAN_GERAN_A, -1, 3, false);
+	comment_end();
+}
+
+static void test_auth_use_infinitely_utran()
+{
+	comment_start();
+	_test_auth_reuse(RAN_UTRAN_IU, -1, 3, false);
+	comment_end();
+}
+
+static void test_no_auth_reuse_geran()
+{
+	comment_start();
+	_test_auth_reuse(RAN_GERAN_A, 0, 0, true);
+	comment_end();
+}
+
+static void test_no_auth_reuse_utran()
+{
+	comment_start();
+	_test_auth_reuse(RAN_UTRAN_IU, 0, 0, true);
+	comment_end();
+}
+
+msc_vlr_test_func_t msc_vlr_tests[] = {
+	test_auth_use_twice_geran,
+	test_auth_use_twice_utran,
+	test_auth_use_infinitely_geran,
+	test_auth_use_infinitely_utran,
+	test_no_auth_reuse_geran,
+	test_no_auth_reuse_utran,
+	NULL
+};
diff --git a/tests/msc_vlr/msc_vlr_test_authen_reuse.err b/tests/msc_vlr/msc_vlr_test_authen_reuse.err
new file mode 100644
index 0000000..5f5db2f
--- /dev/null
+++ b/tests/msc_vlr/msc_vlr_test_authen_reuse.err
@@ -0,0 +1,2606 @@
+full talloc report on 'msgb' (total      0 bytes in   1 blocks)
+talloc_total_blocks(tall_bsc_ctx) == 12
+
+===== test_auth_use_twice_geran
+- Location Update request causes a GSUP Send Auth Info request to HLR
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8)
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_NEW}: Updated ID
+DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000010650 type=NORMAL
+DMM LU/new-LAC: 0/23
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: Allocated
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: is child of Subscr_Conn(LU:901700000010650)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: rev=R99 net=GERAN Auth (no Ciph)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA
+DREF VLR subscr unknown usage increases to: 1
+DVLR set IMSI on subscriber; IMSI=901700000010650 id=901700000010650
+DVLR New subscr, IMSI: 901700000010650
+DREF VLR subscr IMSI:901700000010650 usage increases to: 2
+DREF VLR subscr IMSI:901700000010650 usage decreases to: 1
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Allocated
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(LU:901700000010650)
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
+DVLR GSUP tx: 08010809710000000156f0
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f0
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF IMSI:901700000010650: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  lu_result_sent == 0
+- from HLR, rx _SEND_AUTH_INFO_RESULT, only one tuple; VLR sends Auth Req to MS
+<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT: 0a010809710000000156f00362201039fa2f4e3d523d8619a73b4f65c3e14d21049b36efdf2208059a4f668f6fbe39231027497388b6cb044648f396aa155b95ef2410f64735036e5871319c679f4742a75ea125108704f5ba55f30000d2ee44b22c8ea9192708e229c19e791f2e41
+DVLR GSUP rx 111: 0a010809710000000156f00362201039fa2f4e3d523d8619a73b4f65c3e14d21049b36efdf2208059a4f668f6fbe39231027497388b6cb044648f396aa155b95ef2410f64735036e5871319c679f4742a75ea125108704f5ba55f30000d2ee44b22c8ea9192708e229c19e791f2e41
+DREF VLR subscr IMSI:901700000010650 usage increases to: 2
+DVLR VLR_Authenticate(LU:901700000010650){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(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: state_chg to VLR_SUB_AS_WAIT_RESP
+DVLR VLR_Authenticate(LU:901700000010650){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: tuple use_count=1 key_seq=0 auth_types=0x3 and...
+- ...rand=39fa2f4e3d523d8619a73b4f65c3e14d
+- ...autn=8704f5ba55f30000d2ee44b22c8ea919
+- ...expecting res=e229c19e791f2e41
+DREF VLR subscr IMSI:901700000010650 usage decreases to: 1
+<-- 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
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_AUTH_RESP
+DREF IMSI:901700000010650: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14)
+DMM IMSI:901700000010650: MM UMTS AUTHENTICATION RESPONSE (res = e229c19e791f2e41)
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP
+DVLR SUBSCR(IMSI:901700000010650) AUTH on GERAN received SRES/RES: e229c19e791f2e41 (8 bytes)
+DVLR SUBSCR(IMSI:901700000010650) AUTH established UMTS security context
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result PASSED
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(LU:901700000010650)
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Freeing instance
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth()
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_ciph()
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_node_4()
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_INIT}: Allocated
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000010650)
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START
+DVLR GSUP tx: 04010809710000000156f0280102
+GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000000156f0280102
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA
+DREF IMSI:901700000010650: MSC conn use - dtap == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  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: 10010809710000000156f00804032443f2
+DVLR GSUP rx 17: 10010809710000000156f00804032443f2
+DREF VLR subscr IMSI:901700000010650 usage increases to: 2
+DVLR IMSI:901700000010650 has MSISDN:42342
+DVLR SUBSCR(MSISDN:42342) VLR: update for IMSI=901700000010650 (MSISDN=42342, used=2)
+DVLR GSUP tx: 12010809710000000156f0
+GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000000156f0
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+<-- 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: 06010809710000000156f0
+DVLR GSUP rx 11: 06010809710000000156f0
+DREF VLR subscr MSISDN:42342 usage increases to: 2
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000010650)
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_DONE}: Freeing instance
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_INIT}: Allocated
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000010650)
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_INIT}: Allocated
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(LU:901700000010650)
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(LU:901700000010650)
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_DONE}: Freeing instance
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_DONE}: Deallocated
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_WAIT_SUB_PRES}: lu_compl_vlr_new_tmsi()
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_WAIT_TMSI_CNF
+- sending LU Accept for MSISDN:42342, with TMSI 0x03020100
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+<-- 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(&net->subscr_conns) == 1
+msc_subscr_conn_is_accepted() == false
+  requests shall be thwarted
+DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5)
+DRLL subscr MSISDN:42342: Message not permitted for initial conn: GSM48_MT_CC_SETUP
+DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33)
+DRLL subscr MSISDN:42342: Message not permitted for initial conn: unknown 0x33
+DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19)
+DRLL subscr MSISDN:42342: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1
+DRLL Dispatching 04.08 message SMS:0x01 (0x9:0x1)
+DRLL subscr MSISDN:42342: Message not permitted for initial conn: SMS:0x01
+- even though the TMSI is not acked, we can already find the subscr with it
+DREF VLR subscr MSISDN:42342 usage increases to: 2
+  vsub != NULL == 1
+  strcmp(vsub->imsi, imsi) == 0
+  vsub->tmsi_new == 0x03020100
+  vsub->tmsi == 0xffffffff
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+- MS sends TMSI Realloc Complete
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_TMSI_REALL_COMPL
+DREF MSISDN:42342: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_TMSI_REALL_COMPL (0x5:0x1b)
+DMM TMSI Reallocation Completed. Subscriber: MSISDN:42342
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_NEW_TMSI_ACK
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_WAIT_TMSI_CNF}: Received Event LU_COMPL_VLR_E_NEW_TMSI_ACK
+DREF VLR subscr MSISDN:42342 usage increases to: 2
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_WAIT_TMSI_CNF}: state_chg to LU_COMPL_VLR_S_DONE
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000010650)
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_DONE}: Freeing instance
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_ACCEPTED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:42342: MSC conn use + release == 2 (0x102: dtap,release)
+DREF VLR subscr MSISDN:42342 usage increases to: 3
+DREF VLR subscr MSISDN:42342 usage decreases to: 2
+- BSSAP Clear --RAN_GERAN_A--> MS
+DREF MSISDN:42342: MSC conn use - dtap == 1 (0x100: release)
+  bssap_clear_sent == 1
+- BSS sends BSSMAP Clear Complete
+DREF MSISDN:42342: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(LU:901700000010650)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: Freeing instance
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: Deallocated
+DRLL MSISDN:42342: Freeing subscriber connection
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASED}: Deallocated
+- LU was successful, and the conn has already been closed
+  llist_count(&net->subscr_conns) == 0
+---
+- Now the auth tuple has use_count == 1
+DREF VLR subscr MSISDN:42342 usage increases to: 2
+  vsub->last_tuple->use_count == 1
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+---
+- after a while, a new conn sends a CM Service Request. VLR responds with Auth Req, and reuses old auth vector
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_CM_SERV_REQ
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_CM_SERV_REQ (0x5:0x24)
+DMM <- CM SERVICE REQUEST serv_type=0x08 MI(IMSI)=901700000010650
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_NEW}: Updated ID
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: Allocated
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: is child of Subscr_Conn(CM_SERVICE_REQ:901700000010650)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: rev=R99 net=GERAN Auth (no Ciph)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START
+DREF VLR subscr MSISDN:42342 usage increases to: 2
+DREF VLR subscr MSISDN:42342 usage increases to: 3
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_WAIT_AUTH
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Allocated
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: is child of Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650)
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_WAIT_RESP
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_WAIT_RESP}: got auth tuple: use_count=2 key_seq=0 -- will use UMTS AKA (is_r99=yes, at->vec.auth_types=0x3)
+- sending UMTS Auth Request for MSISDN:42342: tuple use_count=2 key_seq=0 auth_types=0x3 and...
+- ...rand=39fa2f4e3d523d8619a73b4f65c3e14d
+- ...autn=8704f5ba55f30000d2ee44b22c8ea919
+- ...expecting res=e229c19e791f2e41
+DREF VLR subscr MSISDN:42342 usage decreases to: 2
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF MSISDN:42342: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  cm_service_result_sent == 0
+  auth_request_sent == 1
+- MS sends Authen Response, VLR accepts with a CM Service Accept
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_AUTH_RESP
+DREF MSISDN:42342: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14)
+DMM MSISDN:42342: MM UMTS AUTHENTICATION RESPONSE (res = e229c19e791f2e41)
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP
+DVLR SUBSCR(MSISDN:42342) AUTH on GERAN received SRES/RES: e229c19e791f2e41 (8 bytes)
+DVLR SUBSCR(MSISDN:42342) AUTH established UMTS security context
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result PASSED
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Removing from parent Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650)
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Freeing instance
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Deallocated
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: Received Event PR_ARQ_E_AUTH_RES
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2_post_ciph()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2_post_vlr()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_pres()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_trace()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_imei()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: proc_arq_fsm_done(PASSED)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: state_chg to PR_ARQ_S_DONE
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_DONE}: Process Access Request result: PASSED
+- sending CM Service Accept for MSISDN:42342
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_ACCEPTED
+DREF MSISDN:42342: MSC conn use + cm_service == 2 (0xa: dtap,cm_service)
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_ACCEPTED}: subscr_conn_fsm_has_active_transactions: still awaiting first request after a CM Service Request
+DREF MSISDN:42342: MSC conn use - dtap == 1 (0x8: cm_service)
+  cm_service_result_sent == 1
+- Concluding CM Service Request
+DREF MSISDN:42342: MSC conn use - cm_service == 0 (0x0: )
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:42342: MSC conn use + release == 1 (0x100: release)
+DREF VLR subscr MSISDN:42342 usage increases to: 3
+DREF VLR subscr MSISDN:42342 usage decreases to: 2
+- BSSAP Clear --RAN_GERAN_A--> MS
+  bssap_clear_sent == 1
+- BSS sends BSSMAP Clear Complete
+DREF MSISDN:42342: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_DONE}: Removing from parent Subscr_Conn(CM_SERVICE_REQ:901700000010650)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_DONE}: Freeing instance
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_DONE}: Deallocated
+DRLL MSISDN:42342: Freeing subscriber connection
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_RELEASED}: Deallocated
+- all requests serviced, conn has been released
+  llist_count(&net->subscr_conns) == 0
+---
+- Now the auth tuple has use_count == 2, as much as is allowed.
+DREF VLR subscr MSISDN:42342 usage increases to: 2
+  vsub->last_tuple->use_count == 2
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+---
+- after a while, a new conn sends a CM Service Request. VLR responds with Auth Req, and needs to request a second auth vector from HLR
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_CM_SERV_REQ
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_CM_SERV_REQ (0x5:0x24)
+DMM <- CM SERVICE REQUEST serv_type=0x08 MI(IMSI)=901700000010650
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_NEW}: Updated ID
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: Allocated
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: is child of Subscr_Conn(CM_SERVICE_REQ:901700000010650)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: rev=R99 net=GERAN Auth (no Ciph)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START
+DREF VLR subscr MSISDN:42342 usage increases to: 2
+DREF VLR subscr MSISDN:42342 usage increases to: 3
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_WAIT_AUTH
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Allocated
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: is child of Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650)
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
+DVLR GSUP tx: 08010809710000000156f0
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f0
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
+DREF VLR subscr MSISDN:42342 usage decreases to: 2
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF MSISDN:42342: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  cm_service_result_sent == 0
+  auth_request_sent == 0
+  gsup_tx_confirmed == 1
+- from HLR, rx _SEND_AUTH_INFO_RESULT, second tuple; VLR sends Auth Req to MS
+<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT: 0a010809710000000156f003622010c187a53a5e6b9d573cac7c74451fd46d210485aa31302208d3d50a000bf04f6e23101159ec926a50e98c034a6b7d7c9f418d2410df3a03d9ca5335641efc8e36d76cd20b25101843a645b98d00005b2d666af46c45d927087db47cf7f81e4dc7
+DVLR GSUP rx 111: 0a010809710000000156f003622010c187a53a5e6b9d573cac7c74451fd46d210485aa31302208d3d50a000bf04f6e23101159ec926a50e98c034a6b7d7c9f418d2410df3a03d9ca5335641efc8e36d76cd20b25101843a645b98d00005b2d666af46c45d927087db47cf7f81e4dc7
+DREF VLR subscr MSISDN:42342 usage increases to: 3
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: Received Event VLR_AUTH_E_HLR_SAI_ACK
+DVLR SUBSCR(MSISDN:42342) Received 1 auth tuples
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: state_chg to VLR_SUB_AS_WAIT_RESP
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){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 MSISDN:42342: tuple use_count=1 key_seq=0 auth_types=0x3 and...
+- ...rand=c187a53a5e6b9d573cac7c74451fd46d
+- ...autn=1843a645b98d00005b2d666af46c45d9
+- ...expecting res=7db47cf7f81e4dc7
+DREF VLR subscr MSISDN:42342 usage decreases to: 2
+<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT: vlr_gsupc_read_cb() returns 0
+  auth_request_sent == 1
+  cm_service_result_sent == 0
+- MS sends Authen Response, VLR accepts with a CM Service Accept
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_AUTH_RESP
+DREF MSISDN:42342: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14)
+DMM MSISDN:42342: MM UMTS AUTHENTICATION RESPONSE (res = 7db47cf7f81e4dc7)
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP
+DVLR SUBSCR(MSISDN:42342) AUTH on GERAN received SRES/RES: 7db47cf7f81e4dc7 (8 bytes)
+DVLR SUBSCR(MSISDN:42342) AUTH established UMTS security context
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result PASSED
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Removing from parent Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650)
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Freeing instance
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Deallocated
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: Received Event PR_ARQ_E_AUTH_RES
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2_post_ciph()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2_post_vlr()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_pres()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_trace()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_imei()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: proc_arq_fsm_done(PASSED)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: state_chg to PR_ARQ_S_DONE
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_DONE}: Process Access Request result: PASSED
+- sending CM Service Accept for MSISDN:42342
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_ACCEPTED
+DREF MSISDN:42342: MSC conn use + cm_service == 2 (0xa: dtap,cm_service)
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_ACCEPTED}: subscr_conn_fsm_has_active_transactions: still awaiting first request after a CM Service Request
+DREF MSISDN:42342: MSC conn use - dtap == 1 (0x8: cm_service)
+  cm_service_result_sent == 1
+- Concluding CM Service Request
+DREF MSISDN:42342: MSC conn use - cm_service == 0 (0x0: )
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:42342: MSC conn use + release == 1 (0x100: release)
+DREF VLR subscr MSISDN:42342 usage increases to: 3
+DREF VLR subscr MSISDN:42342 usage decreases to: 2
+- BSSAP Clear --RAN_GERAN_A--> MS
+  bssap_clear_sent == 1
+- BSS sends BSSMAP Clear Complete
+DREF MSISDN:42342: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_DONE}: Removing from parent Subscr_Conn(CM_SERVICE_REQ:901700000010650)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_DONE}: Freeing instance
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_DONE}: Deallocated
+DRLL MSISDN:42342: Freeing subscriber connection
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_RELEASED}: Deallocated
+- all requests serviced, conn has been released
+  llist_count(&net->subscr_conns) == 0
+---
+- subscriber detaches
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_IMSI_DETACH_IND
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_IMSI_DETACH_IND (0x5:0x1)
+DMM IMSI DETACH INDICATION: MI(IMSI)=901700000010650
+DREF VLR subscr MSISDN:42342 usage increases to: 2
+DMM IMSI DETACH for MSISDN:42342
+DREF VLR subscr MSISDN:42342 usage increases to: 3
+DREF VLR subscr MSISDN:42342 usage decreases to: 2
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+DREF VLR subscr MSISDN:42342 usage decreases to: 0
+DREF freeing VLR subscr MSISDN:42342
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_CN_CLOSE
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF unknown: MSC conn use + release == 2 (0x101: compl_l3,release)
+- BSSAP Clear --RAN_GERAN_A--> MS
+DREF unknown: MSC conn use - compl_l3 == 1 (0x100: release)
+  bssap_clear_sent == 1
+- BSS sends BSSMAP Clear Complete
+DREF unknown: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DRLL Freeing subscriber connection with NULL subscriber
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+===== test_auth_use_twice_geran: SUCCESS
+
+full talloc report on 'msgb' (total      0 bytes in   1 blocks)
+talloc_total_blocks(tall_bsc_ctx) == 12
+
+===== test_auth_use_twice_utran
+- Location Update request causes a GSUP Send Auth Info request to HLR
+  MSC <--RAN_UTRAN_IU-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8)
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_NEW}: Updated ID
+DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000010650 type=NORMAL
+DMM LU/new-LAC: 0/23
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: Allocated
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: is child of Subscr_Conn(LU:901700000010650)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: rev=R99 net=UTRAN Auth+Ciph
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA
+DREF VLR subscr unknown usage increases to: 1
+DVLR set IMSI on subscriber; IMSI=901700000010650 id=901700000010650
+DVLR New subscr, IMSI: 901700000010650
+DREF VLR subscr IMSI:901700000010650 usage increases to: 2
+DREF VLR subscr IMSI:901700000010650 usage decreases to: 1
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Allocated
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(LU:901700000010650)
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
+DVLR GSUP tx: 08010809710000000156f0
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f0
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF IMSI:901700000010650: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  lu_result_sent == 0
+- from HLR, rx _SEND_AUTH_INFO_RESULT, only one tuple; VLR sends Auth Req to MS
+<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT: 0a010809710000000156f00362201039fa2f4e3d523d8619a73b4f65c3e14d21049b36efdf2208059a4f668f6fbe39231027497388b6cb044648f396aa155b95ef2410f64735036e5871319c679f4742a75ea125108704f5ba55f30000d2ee44b22c8ea9192708e229c19e791f2e41
+DVLR GSUP rx 111: 0a010809710000000156f00362201039fa2f4e3d523d8619a73b4f65c3e14d21049b36efdf2208059a4f668f6fbe39231027497388b6cb044648f396aa155b95ef2410f64735036e5871319c679f4742a75ea125108704f5ba55f30000d2ee44b22c8ea9192708e229c19e791f2e41
+DREF VLR subscr IMSI:901700000010650 usage increases to: 2
+DVLR VLR_Authenticate(LU:901700000010650){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(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: state_chg to VLR_SUB_AS_WAIT_RESP
+DVLR VLR_Authenticate(LU:901700000010650){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: tuple use_count=1 key_seq=0 auth_types=0x3 and...
+- ...rand=39fa2f4e3d523d8619a73b4f65c3e14d
+- ...autn=8704f5ba55f30000d2ee44b22c8ea919
+- ...expecting res=e229c19e791f2e41
+DREF VLR subscr IMSI:901700000010650 usage decreases to: 1
+<-- 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
+  MSC <--RAN_UTRAN_IU-- MS: GSM48_MT_MM_AUTH_RESP
+DREF IMSI:901700000010650: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14)
+DMM IMSI:901700000010650: MM UMTS AUTHENTICATION RESPONSE (res = e229c19e791f2e41)
+DVLR VLR_Authenticate(LU:901700000010650){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(LU:901700000010650){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result PASSED
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(LU:901700000010650)
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Freeing instance
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth()
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_AUTH}: Set Ciphering Mode
+DMM -> SECURITY MODE CONTROL IMSI:901700000010650
+- sending SecurityModeControl for UE ctx 42 send_ck=0 new_key=1
+- ...ik=27497388b6cb044648f396aa155b95ef
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_WAIT_CIPH
+DREF IMSI:901700000010650: MSC conn use - dtap == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  security_mode_ctrl_sent == 1
+  lu_result_sent == 0
+- MS sends SecurityModeControl acceptance, VLR accepts and sends GSUP LU Req to HLR
+DMM <- SECURITY MODE COMPLETE IMSI:901700000010650
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_CIPH}: Received Event VLR_ULA_E_CIPH_RES
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_CIPH}: vlr_loc_upd_post_ciph()
+DIUCS IMSI:901700000010650: tx CommonID 901700000010650
+- Iu Common ID --RAN_UTRAN_IU--> MS (IMSI=901700000010650)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_CIPH}: vlr_loc_upd_node_4()
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_CIPH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_INIT}: Allocated
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000010650)
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START
+DVLR GSUP tx: 04010809710000000156f0280102
+GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000000156f0280102
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){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: 10010809710000000156f00804032443f2
+DVLR GSUP rx 17: 10010809710000000156f00804032443f2
+DREF VLR subscr IMSI:901700000010650 usage increases to: 2
+DVLR IMSI:901700000010650 has MSISDN:42342
+DVLR SUBSCR(MSISDN:42342) VLR: update for IMSI=901700000010650 (MSISDN=42342, used=2)
+DVLR GSUP tx: 12010809710000000156f0
+GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000000156f0
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+<-- 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: 06010809710000000156f0
+DVLR GSUP rx 11: 06010809710000000156f0
+DREF VLR subscr MSISDN:42342 usage increases to: 2
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000010650)
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_DONE}: Freeing instance
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_INIT}: Allocated
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000010650)
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_INIT}: Allocated
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(LU:901700000010650)
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(LU:901700000010650)
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_DONE}: Freeing instance
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_DONE}: Deallocated
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_WAIT_SUB_PRES}: lu_compl_vlr_new_tmsi()
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_WAIT_TMSI_CNF
+- sending LU Accept for MSISDN:42342, with TMSI 0x03020100
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+<-- 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(&net->subscr_conns) == 1
+msc_subscr_conn_is_accepted() == false
+  requests shall be thwarted
+DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5)
+DRLL subscr MSISDN:42342: Message not permitted for initial conn: GSM48_MT_CC_SETUP
+DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33)
+DRLL subscr MSISDN:42342: Message not permitted for initial conn: unknown 0x33
+DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19)
+DRLL subscr MSISDN:42342: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1
+DRLL Dispatching 04.08 message SMS:0x01 (0x9:0x1)
+DRLL subscr MSISDN:42342: Message not permitted for initial conn: SMS:0x01
+- even though the TMSI is not acked, we can already find the subscr with it
+DREF VLR subscr MSISDN:42342 usage increases to: 2
+  vsub != NULL == 1
+  strcmp(vsub->imsi, imsi) == 0
+  vsub->tmsi_new == 0x03020100
+  vsub->tmsi == 0xffffffff
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+- MS sends TMSI Realloc Complete
+  MSC <--RAN_UTRAN_IU-- MS: GSM48_MT_MM_TMSI_REALL_COMPL
+DREF MSISDN:42342: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_TMSI_REALL_COMPL (0x5:0x1b)
+DMM TMSI Reallocation Completed. Subscriber: MSISDN:42342
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_NEW_TMSI_ACK
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_WAIT_TMSI_CNF}: Received Event LU_COMPL_VLR_E_NEW_TMSI_ACK
+DREF VLR subscr MSISDN:42342 usage increases to: 2
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_WAIT_TMSI_CNF}: state_chg to LU_COMPL_VLR_S_DONE
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000010650)
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_DONE}: Freeing instance
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_ACCEPTED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:42342: MSC conn use + release == 2 (0x102: dtap,release)
+DREF VLR subscr MSISDN:42342 usage increases to: 3
+DREF VLR subscr MSISDN:42342 usage decreases to: 2
+- Iu Release --RAN_UTRAN_IU--> MS
+DREF MSISDN:42342: MSC conn use - dtap == 1 (0x100: release)
+  iu_release_sent == 1
+- RNC sends Iu Release Complete
+DREF MSISDN:42342: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(LU:901700000010650)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: Freeing instance
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: Deallocated
+DRLL MSISDN:42342: Freeing subscriber connection
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASED}: Deallocated
+- LU was successful, and the conn has already been closed
+  llist_count(&net->subscr_conns) == 0
+---
+- Now the auth tuple has use_count == 1
+DREF VLR subscr MSISDN:42342 usage increases to: 2
+  vsub->last_tuple->use_count == 1
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+---
+- after a while, a new conn sends a CM Service Request. VLR responds with Auth Req, and reuses old auth vector
+  MSC <--RAN_UTRAN_IU-- MS: GSM48_MT_MM_CM_SERV_REQ
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_CM_SERV_REQ (0x5:0x24)
+DMM <- CM SERVICE REQUEST serv_type=0x08 MI(IMSI)=901700000010650
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_NEW}: Updated ID
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: Allocated
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: is child of Subscr_Conn(CM_SERVICE_REQ:901700000010650)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: rev=R99 net=UTRAN Auth+Ciph
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START
+DREF VLR subscr MSISDN:42342 usage increases to: 2
+DREF VLR subscr MSISDN:42342 usage increases to: 3
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_WAIT_AUTH
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Allocated
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: is child of Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650)
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_WAIT_RESP
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_WAIT_RESP}: got auth tuple: use_count=2 key_seq=0 -- will use UMTS AKA (is_r99=yes, at->vec.auth_types=0x3)
+- sending UMTS Auth Request for MSISDN:42342: tuple use_count=2 key_seq=0 auth_types=0x3 and...
+- ...rand=39fa2f4e3d523d8619a73b4f65c3e14d
+- ...autn=8704f5ba55f30000d2ee44b22c8ea919
+- ...expecting res=e229c19e791f2e41
+DREF VLR subscr MSISDN:42342 usage decreases to: 2
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF MSISDN:42342: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  cm_service_result_sent == 0
+  auth_request_sent == 1
+- MS sends Authen Response, VLR accepts and sends SecurityModeControl
+  MSC <--RAN_UTRAN_IU-- MS: GSM48_MT_MM_AUTH_RESP
+DREF MSISDN:42342: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14)
+DMM MSISDN:42342: MM UMTS AUTHENTICATION RESPONSE (res = e229c19e791f2e41)
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP
+DVLR SUBSCR(MSISDN:42342) AUTH on UTRAN received RES: e229c19e791f2e41 (8 bytes)
+DVLR SUBSCR(MSISDN:42342) AUTH established UMTS security context
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result PASSED
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Removing from parent Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650)
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Freeing instance
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Deallocated
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: Received Event PR_ARQ_E_AUTH_RES
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: Set Ciphering Mode
+DMM -> SECURITY MODE CONTROL MSISDN:42342
+- sending SecurityModeControl for UE ctx 42 send_ck=0 new_key=1
+- ...ik=27497388b6cb044648f396aa155b95ef
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: state_chg to PR_ARQ_S_WAIT_CIPH
+DREF MSISDN:42342: MSC conn use - dtap == 0 (0x0: )
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  security_mode_ctrl_sent == 1
+  cm_service_result_sent == 0
+- MS sends SecurityModeControl acceptance, VLR accepts; above Ciphering is an implicit CM Service Accept
+DMM <- SECURITY MODE COMPLETE MSISDN:42342
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_CIPH}: Received Event PR_ARQ_E_CIPH_RES
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_node2_post_ciph()
+DIUCS MSISDN:42342: tx CommonID 901700000010650
+- Iu Common ID --RAN_UTRAN_IU--> MS (IMSI=901700000010650)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_node2_post_vlr()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_pres()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_trace()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_imei()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_CIPH}: proc_arq_fsm_done(PASSED)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_CIPH}: state_chg to PR_ARQ_S_DONE
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_DONE}: Process Access Request result: PASSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_ACCEPTED
+DREF MSISDN:42342: MSC conn use + cm_service == 1 (0x8: cm_service)
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_ACCEPTED}: subscr_conn_fsm_has_active_transactions: still awaiting first request after a CM Service Request
+  cm_service_result_sent == 0
+- Concluding CM Service Request
+DREF MSISDN:42342: MSC conn use - cm_service == 0 (0x0: )
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:42342: MSC conn use + release == 1 (0x100: release)
+DREF VLR subscr MSISDN:42342 usage increases to: 3
+DREF VLR subscr MSISDN:42342 usage decreases to: 2
+- Iu Release --RAN_UTRAN_IU--> MS
+  iu_release_sent == 1
+- RNC sends Iu Release Complete
+DREF MSISDN:42342: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_DONE}: Removing from parent Subscr_Conn(CM_SERVICE_REQ:901700000010650)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_DONE}: Freeing instance
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_DONE}: Deallocated
+DRLL MSISDN:42342: Freeing subscriber connection
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_RELEASED}: Deallocated
+- all requests serviced, conn has been released
+  llist_count(&net->subscr_conns) == 0
+---
+- Now the auth tuple has use_count == 2, as much as is allowed.
+DREF VLR subscr MSISDN:42342 usage increases to: 2
+  vsub->last_tuple->use_count == 2
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+---
+- after a while, a new conn sends a CM Service Request. VLR responds with Auth Req, and needs to request a second auth vector from HLR
+  MSC <--RAN_UTRAN_IU-- MS: GSM48_MT_MM_CM_SERV_REQ
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_CM_SERV_REQ (0x5:0x24)
+DMM <- CM SERVICE REQUEST serv_type=0x08 MI(IMSI)=901700000010650
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_NEW}: Updated ID
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: Allocated
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: is child of Subscr_Conn(CM_SERVICE_REQ:901700000010650)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: rev=R99 net=UTRAN Auth+Ciph
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START
+DREF VLR subscr MSISDN:42342 usage increases to: 2
+DREF VLR subscr MSISDN:42342 usage increases to: 3
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_WAIT_AUTH
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Allocated
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: is child of Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650)
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
+DVLR GSUP tx: 08010809710000000156f0
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f0
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
+DREF VLR subscr MSISDN:42342 usage decreases to: 2
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF MSISDN:42342: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  cm_service_result_sent == 0
+  auth_request_sent == 0
+  gsup_tx_confirmed == 1
+- from HLR, rx _SEND_AUTH_INFO_RESULT, second tuple; VLR sends Auth Req to MS
+<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT: 0a010809710000000156f003622010c187a53a5e6b9d573cac7c74451fd46d210485aa31302208d3d50a000bf04f6e23101159ec926a50e98c034a6b7d7c9f418d2410df3a03d9ca5335641efc8e36d76cd20b25101843a645b98d00005b2d666af46c45d927087db47cf7f81e4dc7
+DVLR GSUP rx 111: 0a010809710000000156f003622010c187a53a5e6b9d573cac7c74451fd46d210485aa31302208d3d50a000bf04f6e23101159ec926a50e98c034a6b7d7c9f418d2410df3a03d9ca5335641efc8e36d76cd20b25101843a645b98d00005b2d666af46c45d927087db47cf7f81e4dc7
+DREF VLR subscr MSISDN:42342 usage increases to: 3
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: Received Event VLR_AUTH_E_HLR_SAI_ACK
+DVLR SUBSCR(MSISDN:42342) Received 1 auth tuples
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: state_chg to VLR_SUB_AS_WAIT_RESP
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){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 MSISDN:42342: tuple use_count=1 key_seq=0 auth_types=0x3 and...
+- ...rand=c187a53a5e6b9d573cac7c74451fd46d
+- ...autn=1843a645b98d00005b2d666af46c45d9
+- ...expecting res=7db47cf7f81e4dc7
+DREF VLR subscr MSISDN:42342 usage decreases to: 2
+<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT: vlr_gsupc_read_cb() returns 0
+  auth_request_sent == 1
+  cm_service_result_sent == 0
+- MS sends Authen Response, VLR accepts and sends SecurityModeControl
+  MSC <--RAN_UTRAN_IU-- MS: GSM48_MT_MM_AUTH_RESP
+DREF MSISDN:42342: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14)
+DMM MSISDN:42342: MM UMTS AUTHENTICATION RESPONSE (res = 7db47cf7f81e4dc7)
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP
+DVLR SUBSCR(MSISDN:42342) AUTH on UTRAN received RES: 7db47cf7f81e4dc7 (8 bytes)
+DVLR SUBSCR(MSISDN:42342) AUTH established UMTS security context
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result PASSED
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Removing from parent Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650)
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Freeing instance
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Deallocated
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: Received Event PR_ARQ_E_AUTH_RES
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: Set Ciphering Mode
+DMM -> SECURITY MODE CONTROL MSISDN:42342
+- sending SecurityModeControl for UE ctx 42 send_ck=0 new_key=1
+- ...ik=1159ec926a50e98c034a6b7d7c9f418d
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: state_chg to PR_ARQ_S_WAIT_CIPH
+DREF MSISDN:42342: MSC conn use - dtap == 0 (0x0: )
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  security_mode_ctrl_sent == 1
+  cm_service_result_sent == 0
+- MS sends SecurityModeControl acceptance, VLR accepts; above Ciphering is an implicit CM Service Accept
+DMM <- SECURITY MODE COMPLETE MSISDN:42342
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_CIPH}: Received Event PR_ARQ_E_CIPH_RES
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_node2_post_ciph()
+DIUCS MSISDN:42342: tx CommonID 901700000010650
+- Iu Common ID --RAN_UTRAN_IU--> MS (IMSI=901700000010650)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_node2_post_vlr()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_pres()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_trace()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_imei()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_CIPH}: proc_arq_fsm_done(PASSED)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_CIPH}: state_chg to PR_ARQ_S_DONE
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_DONE}: Process Access Request result: PASSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_ACCEPTED
+DREF MSISDN:42342: MSC conn use + cm_service == 1 (0x8: cm_service)
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_ACCEPTED}: subscr_conn_fsm_has_active_transactions: still awaiting first request after a CM Service Request
+  cm_service_result_sent == 0
+- Concluding CM Service Request
+DREF MSISDN:42342: MSC conn use - cm_service == 0 (0x0: )
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:42342: MSC conn use + release == 1 (0x100: release)
+DREF VLR subscr MSISDN:42342 usage increases to: 3
+DREF VLR subscr MSISDN:42342 usage decreases to: 2
+- Iu Release --RAN_UTRAN_IU--> MS
+  iu_release_sent == 1
+- RNC sends Iu Release Complete
+DREF MSISDN:42342: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_DONE}: Removing from parent Subscr_Conn(CM_SERVICE_REQ:901700000010650)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_DONE}: Freeing instance
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_DONE}: Deallocated
+DRLL MSISDN:42342: Freeing subscriber connection
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_RELEASED}: Deallocated
+- all requests serviced, conn has been released
+  llist_count(&net->subscr_conns) == 0
+---
+- subscriber detaches
+  MSC <--RAN_UTRAN_IU-- MS: GSM48_MT_MM_IMSI_DETACH_IND
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_IMSI_DETACH_IND (0x5:0x1)
+DMM IMSI DETACH INDICATION: MI(IMSI)=901700000010650
+DREF VLR subscr MSISDN:42342 usage increases to: 2
+DMM IMSI DETACH for MSISDN:42342
+DREF VLR subscr MSISDN:42342 usage increases to: 3
+DREF VLR subscr MSISDN:42342 usage decreases to: 2
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+DREF VLR subscr MSISDN:42342 usage decreases to: 0
+DREF freeing VLR subscr MSISDN:42342
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_CN_CLOSE
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF unknown: MSC conn use + release == 2 (0x101: compl_l3,release)
+- Iu Release --RAN_UTRAN_IU--> MS
+DREF unknown: MSC conn use - compl_l3 == 1 (0x100: release)
+  iu_release_sent == 1
+- RNC sends Iu Release Complete
+DREF unknown: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DRLL Freeing subscriber connection with NULL subscriber
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+===== test_auth_use_twice_utran: SUCCESS
+
+full talloc report on 'msgb' (total      0 bytes in   1 blocks)
+talloc_total_blocks(tall_bsc_ctx) == 12
+
+===== test_auth_use_infinitely_geran
+- Location Update request causes a GSUP Send Auth Info request to HLR
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8)
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_NEW}: Updated ID
+DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000010650 type=NORMAL
+DMM LU/new-LAC: 0/23
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: Allocated
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: is child of Subscr_Conn(LU:901700000010650)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: rev=R99 net=GERAN Auth (no Ciph)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA
+DREF VLR subscr unknown usage increases to: 1
+DVLR set IMSI on subscriber; IMSI=901700000010650 id=901700000010650
+DVLR New subscr, IMSI: 901700000010650
+DREF VLR subscr IMSI:901700000010650 usage increases to: 2
+DREF VLR subscr IMSI:901700000010650 usage decreases to: 1
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Allocated
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(LU:901700000010650)
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
+DVLR GSUP tx: 08010809710000000156f0
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f0
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF IMSI:901700000010650: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  lu_result_sent == 0
+- from HLR, rx _SEND_AUTH_INFO_RESULT, only one tuple; VLR sends Auth Req to MS
+<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT: 0a010809710000000156f00362201039fa2f4e3d523d8619a73b4f65c3e14d21049b36efdf2208059a4f668f6fbe39231027497388b6cb044648f396aa155b95ef2410f64735036e5871319c679f4742a75ea125108704f5ba55f30000d2ee44b22c8ea9192708e229c19e791f2e41
+DVLR GSUP rx 111: 0a010809710000000156f00362201039fa2f4e3d523d8619a73b4f65c3e14d21049b36efdf2208059a4f668f6fbe39231027497388b6cb044648f396aa155b95ef2410f64735036e5871319c679f4742a75ea125108704f5ba55f30000d2ee44b22c8ea9192708e229c19e791f2e41
+DREF VLR subscr IMSI:901700000010650 usage increases to: 2
+DVLR VLR_Authenticate(LU:901700000010650){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(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: state_chg to VLR_SUB_AS_WAIT_RESP
+DVLR VLR_Authenticate(LU:901700000010650){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: tuple use_count=1 key_seq=0 auth_types=0x3 and...
+- ...rand=39fa2f4e3d523d8619a73b4f65c3e14d
+- ...autn=8704f5ba55f30000d2ee44b22c8ea919
+- ...expecting res=e229c19e791f2e41
+DREF VLR subscr IMSI:901700000010650 usage decreases to: 1
+<-- 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
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_AUTH_RESP
+DREF IMSI:901700000010650: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14)
+DMM IMSI:901700000010650: MM UMTS AUTHENTICATION RESPONSE (res = e229c19e791f2e41)
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP
+DVLR SUBSCR(IMSI:901700000010650) AUTH on GERAN received SRES/RES: e229c19e791f2e41 (8 bytes)
+DVLR SUBSCR(IMSI:901700000010650) AUTH established UMTS security context
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result PASSED
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(LU:901700000010650)
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Freeing instance
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth()
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_ciph()
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_node_4()
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_INIT}: Allocated
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000010650)
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START
+DVLR GSUP tx: 04010809710000000156f0280102
+GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000000156f0280102
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA
+DREF IMSI:901700000010650: MSC conn use - dtap == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  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: 10010809710000000156f00804032443f2
+DVLR GSUP rx 17: 10010809710000000156f00804032443f2
+DREF VLR subscr IMSI:901700000010650 usage increases to: 2
+DVLR IMSI:901700000010650 has MSISDN:42342
+DVLR SUBSCR(MSISDN:42342) VLR: update for IMSI=901700000010650 (MSISDN=42342, used=2)
+DVLR GSUP tx: 12010809710000000156f0
+GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000000156f0
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+<-- 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: 06010809710000000156f0
+DVLR GSUP rx 11: 06010809710000000156f0
+DREF VLR subscr MSISDN:42342 usage increases to: 2
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000010650)
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_DONE}: Freeing instance
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_INIT}: Allocated
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000010650)
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_INIT}: Allocated
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(LU:901700000010650)
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(LU:901700000010650)
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_DONE}: Freeing instance
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_DONE}: Deallocated
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_WAIT_SUB_PRES}: lu_compl_vlr_new_tmsi()
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_WAIT_TMSI_CNF
+- sending LU Accept for MSISDN:42342, with TMSI 0x03020100
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+<-- 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(&net->subscr_conns) == 1
+msc_subscr_conn_is_accepted() == false
+  requests shall be thwarted
+DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5)
+DRLL subscr MSISDN:42342: Message not permitted for initial conn: GSM48_MT_CC_SETUP
+DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33)
+DRLL subscr MSISDN:42342: Message not permitted for initial conn: unknown 0x33
+DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19)
+DRLL subscr MSISDN:42342: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1
+DRLL Dispatching 04.08 message SMS:0x01 (0x9:0x1)
+DRLL subscr MSISDN:42342: Message not permitted for initial conn: SMS:0x01
+- even though the TMSI is not acked, we can already find the subscr with it
+DREF VLR subscr MSISDN:42342 usage increases to: 2
+  vsub != NULL == 1
+  strcmp(vsub->imsi, imsi) == 0
+  vsub->tmsi_new == 0x03020100
+  vsub->tmsi == 0xffffffff
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+- MS sends TMSI Realloc Complete
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_TMSI_REALL_COMPL
+DREF MSISDN:42342: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_TMSI_REALL_COMPL (0x5:0x1b)
+DMM TMSI Reallocation Completed. Subscriber: MSISDN:42342
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_NEW_TMSI_ACK
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_WAIT_TMSI_CNF}: Received Event LU_COMPL_VLR_E_NEW_TMSI_ACK
+DREF VLR subscr MSISDN:42342 usage increases to: 2
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_WAIT_TMSI_CNF}: state_chg to LU_COMPL_VLR_S_DONE
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000010650)
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_DONE}: Freeing instance
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_ACCEPTED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:42342: MSC conn use + release == 2 (0x102: dtap,release)
+DREF VLR subscr MSISDN:42342 usage increases to: 3
+DREF VLR subscr MSISDN:42342 usage decreases to: 2
+- BSSAP Clear --RAN_GERAN_A--> MS
+DREF MSISDN:42342: MSC conn use - dtap == 1 (0x100: release)
+  bssap_clear_sent == 1
+- BSS sends BSSMAP Clear Complete
+DREF MSISDN:42342: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(LU:901700000010650)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: Freeing instance
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: Deallocated
+DRLL MSISDN:42342: Freeing subscriber connection
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASED}: Deallocated
+- LU was successful, and the conn has already been closed
+  llist_count(&net->subscr_conns) == 0
+---
+- Now the auth tuple has use_count == 1
+DREF VLR subscr MSISDN:42342 usage increases to: 2
+  vsub->last_tuple->use_count == 1
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+---
+- after a while, a new conn sends a CM Service Request. VLR responds with Auth Req, and reuses old auth vector
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_CM_SERV_REQ
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_CM_SERV_REQ (0x5:0x24)
+DMM <- CM SERVICE REQUEST serv_type=0x08 MI(IMSI)=901700000010650
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_NEW}: Updated ID
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: Allocated
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: is child of Subscr_Conn(CM_SERVICE_REQ:901700000010650)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: rev=R99 net=GERAN Auth (no Ciph)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START
+DREF VLR subscr MSISDN:42342 usage increases to: 2
+DREF VLR subscr MSISDN:42342 usage increases to: 3
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_WAIT_AUTH
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Allocated
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: is child of Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650)
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_WAIT_RESP
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_WAIT_RESP}: got auth tuple: use_count=2 key_seq=0 -- will use UMTS AKA (is_r99=yes, at->vec.auth_types=0x3)
+- sending UMTS Auth Request for MSISDN:42342: tuple use_count=2 key_seq=0 auth_types=0x3 and...
+- ...rand=39fa2f4e3d523d8619a73b4f65c3e14d
+- ...autn=8704f5ba55f30000d2ee44b22c8ea919
+- ...expecting res=e229c19e791f2e41
+DREF VLR subscr MSISDN:42342 usage decreases to: 2
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF MSISDN:42342: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  cm_service_result_sent == 0
+  auth_request_sent == 1
+- MS sends Authen Response, VLR accepts with a CM Service Accept
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_AUTH_RESP
+DREF MSISDN:42342: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14)
+DMM MSISDN:42342: MM UMTS AUTHENTICATION RESPONSE (res = e229c19e791f2e41)
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP
+DVLR SUBSCR(MSISDN:42342) AUTH on GERAN received SRES/RES: e229c19e791f2e41 (8 bytes)
+DVLR SUBSCR(MSISDN:42342) AUTH established UMTS security context
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result PASSED
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Removing from parent Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650)
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Freeing instance
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Deallocated
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: Received Event PR_ARQ_E_AUTH_RES
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2_post_ciph()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2_post_vlr()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_pres()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_trace()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_imei()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: proc_arq_fsm_done(PASSED)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: state_chg to PR_ARQ_S_DONE
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_DONE}: Process Access Request result: PASSED
+- sending CM Service Accept for MSISDN:42342
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_ACCEPTED
+DREF MSISDN:42342: MSC conn use + cm_service == 2 (0xa: dtap,cm_service)
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_ACCEPTED}: subscr_conn_fsm_has_active_transactions: still awaiting first request after a CM Service Request
+DREF MSISDN:42342: MSC conn use - dtap == 1 (0x8: cm_service)
+  cm_service_result_sent == 1
+- Concluding CM Service Request
+DREF MSISDN:42342: MSC conn use - cm_service == 0 (0x0: )
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:42342: MSC conn use + release == 1 (0x100: release)
+DREF VLR subscr MSISDN:42342 usage increases to: 3
+DREF VLR subscr MSISDN:42342 usage decreases to: 2
+- BSSAP Clear --RAN_GERAN_A--> MS
+  bssap_clear_sent == 1
+- BSS sends BSSMAP Clear Complete
+DREF MSISDN:42342: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_DONE}: Removing from parent Subscr_Conn(CM_SERVICE_REQ:901700000010650)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_DONE}: Freeing instance
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_DONE}: Deallocated
+DRLL MSISDN:42342: Freeing subscriber connection
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_RELEASED}: Deallocated
+- all requests serviced, conn has been released
+  llist_count(&net->subscr_conns) == 0
+---
+- Now the auth tuple has use_count == 2
+DREF VLR subscr MSISDN:42342 usage increases to: 2
+  vsub->last_tuple->use_count == 2
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+---
+- after a while, a new conn sends a CM Service Request. VLR responds with Auth Req, and reuses old auth vector
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_CM_SERV_REQ
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_CM_SERV_REQ (0x5:0x24)
+DMM <- CM SERVICE REQUEST serv_type=0x08 MI(IMSI)=901700000010650
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_NEW}: Updated ID
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: Allocated
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: is child of Subscr_Conn(CM_SERVICE_REQ:901700000010650)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: rev=R99 net=GERAN Auth (no Ciph)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START
+DREF VLR subscr MSISDN:42342 usage increases to: 2
+DREF VLR subscr MSISDN:42342 usage increases to: 3
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_WAIT_AUTH
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Allocated
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: is child of Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650)
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_WAIT_RESP
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_WAIT_RESP}: got auth tuple: use_count=3 key_seq=0 -- will use UMTS AKA (is_r99=yes, at->vec.auth_types=0x3)
+- sending UMTS Auth Request for MSISDN:42342: tuple use_count=3 key_seq=0 auth_types=0x3 and...
+- ...rand=39fa2f4e3d523d8619a73b4f65c3e14d
+- ...autn=8704f5ba55f30000d2ee44b22c8ea919
+- ...expecting res=e229c19e791f2e41
+DREF VLR subscr MSISDN:42342 usage decreases to: 2
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF MSISDN:42342: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  cm_service_result_sent == 0
+  auth_request_sent == 1
+- MS sends Authen Response, VLR accepts with a CM Service Accept
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_AUTH_RESP
+DREF MSISDN:42342: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14)
+DMM MSISDN:42342: MM UMTS AUTHENTICATION RESPONSE (res = e229c19e791f2e41)
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP
+DVLR SUBSCR(MSISDN:42342) AUTH on GERAN received SRES/RES: e229c19e791f2e41 (8 bytes)
+DVLR SUBSCR(MSISDN:42342) AUTH established UMTS security context
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result PASSED
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Removing from parent Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650)
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Freeing instance
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Deallocated
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: Received Event PR_ARQ_E_AUTH_RES
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2_post_ciph()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2_post_vlr()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_pres()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_trace()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_imei()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: proc_arq_fsm_done(PASSED)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: state_chg to PR_ARQ_S_DONE
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_DONE}: Process Access Request result: PASSED
+- sending CM Service Accept for MSISDN:42342
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_ACCEPTED
+DREF MSISDN:42342: MSC conn use + cm_service == 2 (0xa: dtap,cm_service)
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_ACCEPTED}: subscr_conn_fsm_has_active_transactions: still awaiting first request after a CM Service Request
+DREF MSISDN:42342: MSC conn use - dtap == 1 (0x8: cm_service)
+  cm_service_result_sent == 1
+- Concluding CM Service Request
+DREF MSISDN:42342: MSC conn use - cm_service == 0 (0x0: )
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:42342: MSC conn use + release == 1 (0x100: release)
+DREF VLR subscr MSISDN:42342 usage increases to: 3
+DREF VLR subscr MSISDN:42342 usage decreases to: 2
+- BSSAP Clear --RAN_GERAN_A--> MS
+  bssap_clear_sent == 1
+- BSS sends BSSMAP Clear Complete
+DREF MSISDN:42342: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_DONE}: Removing from parent Subscr_Conn(CM_SERVICE_REQ:901700000010650)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_DONE}: Freeing instance
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_DONE}: Deallocated
+DRLL MSISDN:42342: Freeing subscriber connection
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_RELEASED}: Deallocated
+- all requests serviced, conn has been released
+  llist_count(&net->subscr_conns) == 0
+---
+- Now the auth tuple has use_count == 3
+DREF VLR subscr MSISDN:42342 usage increases to: 2
+  vsub->last_tuple->use_count == 3
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+---
+- after a while, a new conn sends a CM Service Request. VLR responds with Auth Req, and reuses old auth vector
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_CM_SERV_REQ
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_CM_SERV_REQ (0x5:0x24)
+DMM <- CM SERVICE REQUEST serv_type=0x08 MI(IMSI)=901700000010650
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_NEW}: Updated ID
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: Allocated
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: is child of Subscr_Conn(CM_SERVICE_REQ:901700000010650)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: rev=R99 net=GERAN Auth (no Ciph)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START
+DREF VLR subscr MSISDN:42342 usage increases to: 2
+DREF VLR subscr MSISDN:42342 usage increases to: 3
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_WAIT_AUTH
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Allocated
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: is child of Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650)
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_WAIT_RESP
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_WAIT_RESP}: got auth tuple: use_count=4 key_seq=0 -- will use UMTS AKA (is_r99=yes, at->vec.auth_types=0x3)
+- sending UMTS Auth Request for MSISDN:42342: tuple use_count=4 key_seq=0 auth_types=0x3 and...
+- ...rand=39fa2f4e3d523d8619a73b4f65c3e14d
+- ...autn=8704f5ba55f30000d2ee44b22c8ea919
+- ...expecting res=e229c19e791f2e41
+DREF VLR subscr MSISDN:42342 usage decreases to: 2
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF MSISDN:42342: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  cm_service_result_sent == 0
+  auth_request_sent == 1
+- MS sends Authen Response, VLR accepts with a CM Service Accept
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_AUTH_RESP
+DREF MSISDN:42342: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14)
+DMM MSISDN:42342: MM UMTS AUTHENTICATION RESPONSE (res = e229c19e791f2e41)
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP
+DVLR SUBSCR(MSISDN:42342) AUTH on GERAN received SRES/RES: e229c19e791f2e41 (8 bytes)
+DVLR SUBSCR(MSISDN:42342) AUTH established UMTS security context
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result PASSED
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Removing from parent Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650)
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Freeing instance
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Deallocated
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: Received Event PR_ARQ_E_AUTH_RES
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2_post_ciph()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2_post_vlr()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_pres()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_trace()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_imei()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: proc_arq_fsm_done(PASSED)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: state_chg to PR_ARQ_S_DONE
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_DONE}: Process Access Request result: PASSED
+- sending CM Service Accept for MSISDN:42342
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_ACCEPTED
+DREF MSISDN:42342: MSC conn use + cm_service == 2 (0xa: dtap,cm_service)
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_ACCEPTED}: subscr_conn_fsm_has_active_transactions: still awaiting first request after a CM Service Request
+DREF MSISDN:42342: MSC conn use - dtap == 1 (0x8: cm_service)
+  cm_service_result_sent == 1
+- Concluding CM Service Request
+DREF MSISDN:42342: MSC conn use - cm_service == 0 (0x0: )
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:42342: MSC conn use + release == 1 (0x100: release)
+DREF VLR subscr MSISDN:42342 usage increases to: 3
+DREF VLR subscr MSISDN:42342 usage decreases to: 2
+- BSSAP Clear --RAN_GERAN_A--> MS
+  bssap_clear_sent == 1
+- BSS sends BSSMAP Clear Complete
+DREF MSISDN:42342: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_DONE}: Removing from parent Subscr_Conn(CM_SERVICE_REQ:901700000010650)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_DONE}: Freeing instance
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_DONE}: Deallocated
+DRLL MSISDN:42342: Freeing subscriber connection
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_RELEASED}: Deallocated
+- all requests serviced, conn has been released
+  llist_count(&net->subscr_conns) == 0
+---
+- subscriber detaches
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_IMSI_DETACH_IND
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_IMSI_DETACH_IND (0x5:0x1)
+DMM IMSI DETACH INDICATION: MI(IMSI)=901700000010650
+DREF VLR subscr MSISDN:42342 usage increases to: 2
+DMM IMSI DETACH for MSISDN:42342
+DREF VLR subscr MSISDN:42342 usage increases to: 3
+DREF VLR subscr MSISDN:42342 usage decreases to: 2
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+DREF VLR subscr MSISDN:42342 usage decreases to: 0
+DREF freeing VLR subscr MSISDN:42342
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_CN_CLOSE
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF unknown: MSC conn use + release == 2 (0x101: compl_l3,release)
+- BSSAP Clear --RAN_GERAN_A--> MS
+DREF unknown: MSC conn use - compl_l3 == 1 (0x100: release)
+  bssap_clear_sent == 1
+- BSS sends BSSMAP Clear Complete
+DREF unknown: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DRLL Freeing subscriber connection with NULL subscriber
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+===== test_auth_use_infinitely_geran: SUCCESS
+
+full talloc report on 'msgb' (total      0 bytes in   1 blocks)
+talloc_total_blocks(tall_bsc_ctx) == 12
+
+===== test_auth_use_infinitely_utran
+- Location Update request causes a GSUP Send Auth Info request to HLR
+  MSC <--RAN_UTRAN_IU-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8)
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_NEW}: Updated ID
+DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000010650 type=NORMAL
+DMM LU/new-LAC: 0/23
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: Allocated
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: is child of Subscr_Conn(LU:901700000010650)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: rev=R99 net=UTRAN Auth+Ciph
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA
+DREF VLR subscr unknown usage increases to: 1
+DVLR set IMSI on subscriber; IMSI=901700000010650 id=901700000010650
+DVLR New subscr, IMSI: 901700000010650
+DREF VLR subscr IMSI:901700000010650 usage increases to: 2
+DREF VLR subscr IMSI:901700000010650 usage decreases to: 1
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Allocated
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(LU:901700000010650)
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
+DVLR GSUP tx: 08010809710000000156f0
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f0
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF IMSI:901700000010650: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  lu_result_sent == 0
+- from HLR, rx _SEND_AUTH_INFO_RESULT, only one tuple; VLR sends Auth Req to MS
+<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT: 0a010809710000000156f00362201039fa2f4e3d523d8619a73b4f65c3e14d21049b36efdf2208059a4f668f6fbe39231027497388b6cb044648f396aa155b95ef2410f64735036e5871319c679f4742a75ea125108704f5ba55f30000d2ee44b22c8ea9192708e229c19e791f2e41
+DVLR GSUP rx 111: 0a010809710000000156f00362201039fa2f4e3d523d8619a73b4f65c3e14d21049b36efdf2208059a4f668f6fbe39231027497388b6cb044648f396aa155b95ef2410f64735036e5871319c679f4742a75ea125108704f5ba55f30000d2ee44b22c8ea9192708e229c19e791f2e41
+DREF VLR subscr IMSI:901700000010650 usage increases to: 2
+DVLR VLR_Authenticate(LU:901700000010650){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(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: state_chg to VLR_SUB_AS_WAIT_RESP
+DVLR VLR_Authenticate(LU:901700000010650){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: tuple use_count=1 key_seq=0 auth_types=0x3 and...
+- ...rand=39fa2f4e3d523d8619a73b4f65c3e14d
+- ...autn=8704f5ba55f30000d2ee44b22c8ea919
+- ...expecting res=e229c19e791f2e41
+DREF VLR subscr IMSI:901700000010650 usage decreases to: 1
+<-- 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
+  MSC <--RAN_UTRAN_IU-- MS: GSM48_MT_MM_AUTH_RESP
+DREF IMSI:901700000010650: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14)
+DMM IMSI:901700000010650: MM UMTS AUTHENTICATION RESPONSE (res = e229c19e791f2e41)
+DVLR VLR_Authenticate(LU:901700000010650){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(LU:901700000010650){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result PASSED
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(LU:901700000010650)
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Freeing instance
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth()
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_AUTH}: Set Ciphering Mode
+DMM -> SECURITY MODE CONTROL IMSI:901700000010650
+- sending SecurityModeControl for UE ctx 42 send_ck=0 new_key=1
+- ...ik=27497388b6cb044648f396aa155b95ef
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_WAIT_CIPH
+DREF IMSI:901700000010650: MSC conn use - dtap == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  security_mode_ctrl_sent == 1
+  lu_result_sent == 0
+- MS sends SecurityModeControl acceptance, VLR accepts and sends GSUP LU Req to HLR
+DMM <- SECURITY MODE COMPLETE IMSI:901700000010650
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_CIPH}: Received Event VLR_ULA_E_CIPH_RES
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_CIPH}: vlr_loc_upd_post_ciph()
+DIUCS IMSI:901700000010650: tx CommonID 901700000010650
+- Iu Common ID --RAN_UTRAN_IU--> MS (IMSI=901700000010650)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_CIPH}: vlr_loc_upd_node_4()
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_CIPH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_INIT}: Allocated
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000010650)
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START
+DVLR GSUP tx: 04010809710000000156f0280102
+GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000000156f0280102
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){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: 10010809710000000156f00804032443f2
+DVLR GSUP rx 17: 10010809710000000156f00804032443f2
+DREF VLR subscr IMSI:901700000010650 usage increases to: 2
+DVLR IMSI:901700000010650 has MSISDN:42342
+DVLR SUBSCR(MSISDN:42342) VLR: update for IMSI=901700000010650 (MSISDN=42342, used=2)
+DVLR GSUP tx: 12010809710000000156f0
+GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000000156f0
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+<-- 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: 06010809710000000156f0
+DVLR GSUP rx 11: 06010809710000000156f0
+DREF VLR subscr MSISDN:42342 usage increases to: 2
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000010650)
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_DONE}: Freeing instance
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_INIT}: Allocated
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000010650)
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_INIT}: Allocated
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(LU:901700000010650)
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(LU:901700000010650)
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_DONE}: Freeing instance
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_DONE}: Deallocated
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_WAIT_SUB_PRES}: lu_compl_vlr_new_tmsi()
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_WAIT_TMSI_CNF
+- sending LU Accept for MSISDN:42342, with TMSI 0x03020100
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+<-- 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(&net->subscr_conns) == 1
+msc_subscr_conn_is_accepted() == false
+  requests shall be thwarted
+DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5)
+DRLL subscr MSISDN:42342: Message not permitted for initial conn: GSM48_MT_CC_SETUP
+DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33)
+DRLL subscr MSISDN:42342: Message not permitted for initial conn: unknown 0x33
+DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19)
+DRLL subscr MSISDN:42342: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1
+DRLL Dispatching 04.08 message SMS:0x01 (0x9:0x1)
+DRLL subscr MSISDN:42342: Message not permitted for initial conn: SMS:0x01
+- even though the TMSI is not acked, we can already find the subscr with it
+DREF VLR subscr MSISDN:42342 usage increases to: 2
+  vsub != NULL == 1
+  strcmp(vsub->imsi, imsi) == 0
+  vsub->tmsi_new == 0x03020100
+  vsub->tmsi == 0xffffffff
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+- MS sends TMSI Realloc Complete
+  MSC <--RAN_UTRAN_IU-- MS: GSM48_MT_MM_TMSI_REALL_COMPL
+DREF MSISDN:42342: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_TMSI_REALL_COMPL (0x5:0x1b)
+DMM TMSI Reallocation Completed. Subscriber: MSISDN:42342
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_NEW_TMSI_ACK
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_WAIT_TMSI_CNF}: Received Event LU_COMPL_VLR_E_NEW_TMSI_ACK
+DREF VLR subscr MSISDN:42342 usage increases to: 2
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_WAIT_TMSI_CNF}: state_chg to LU_COMPL_VLR_S_DONE
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000010650)
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_DONE}: Freeing instance
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_ACCEPTED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:42342: MSC conn use + release == 2 (0x102: dtap,release)
+DREF VLR subscr MSISDN:42342 usage increases to: 3
+DREF VLR subscr MSISDN:42342 usage decreases to: 2
+- Iu Release --RAN_UTRAN_IU--> MS
+DREF MSISDN:42342: MSC conn use - dtap == 1 (0x100: release)
+  iu_release_sent == 1
+- RNC sends Iu Release Complete
+DREF MSISDN:42342: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(LU:901700000010650)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: Freeing instance
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: Deallocated
+DRLL MSISDN:42342: Freeing subscriber connection
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASED}: Deallocated
+- LU was successful, and the conn has already been closed
+  llist_count(&net->subscr_conns) == 0
+---
+- Now the auth tuple has use_count == 1
+DREF VLR subscr MSISDN:42342 usage increases to: 2
+  vsub->last_tuple->use_count == 1
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+---
+- after a while, a new conn sends a CM Service Request. VLR responds with Auth Req, and reuses old auth vector
+  MSC <--RAN_UTRAN_IU-- MS: GSM48_MT_MM_CM_SERV_REQ
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_CM_SERV_REQ (0x5:0x24)
+DMM <- CM SERVICE REQUEST serv_type=0x08 MI(IMSI)=901700000010650
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_NEW}: Updated ID
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: Allocated
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: is child of Subscr_Conn(CM_SERVICE_REQ:901700000010650)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: rev=R99 net=UTRAN Auth+Ciph
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START
+DREF VLR subscr MSISDN:42342 usage increases to: 2
+DREF VLR subscr MSISDN:42342 usage increases to: 3
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_WAIT_AUTH
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Allocated
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: is child of Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650)
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_WAIT_RESP
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_WAIT_RESP}: got auth tuple: use_count=2 key_seq=0 -- will use UMTS AKA (is_r99=yes, at->vec.auth_types=0x3)
+- sending UMTS Auth Request for MSISDN:42342: tuple use_count=2 key_seq=0 auth_types=0x3 and...
+- ...rand=39fa2f4e3d523d8619a73b4f65c3e14d
+- ...autn=8704f5ba55f30000d2ee44b22c8ea919
+- ...expecting res=e229c19e791f2e41
+DREF VLR subscr MSISDN:42342 usage decreases to: 2
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF MSISDN:42342: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  cm_service_result_sent == 0
+  auth_request_sent == 1
+- MS sends Authen Response, VLR accepts and sends SecurityModeControl
+  MSC <--RAN_UTRAN_IU-- MS: GSM48_MT_MM_AUTH_RESP
+DREF MSISDN:42342: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14)
+DMM MSISDN:42342: MM UMTS AUTHENTICATION RESPONSE (res = e229c19e791f2e41)
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP
+DVLR SUBSCR(MSISDN:42342) AUTH on UTRAN received RES: e229c19e791f2e41 (8 bytes)
+DVLR SUBSCR(MSISDN:42342) AUTH established UMTS security context
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result PASSED
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Removing from parent Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650)
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Freeing instance
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Deallocated
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: Received Event PR_ARQ_E_AUTH_RES
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: Set Ciphering Mode
+DMM -> SECURITY MODE CONTROL MSISDN:42342
+- sending SecurityModeControl for UE ctx 42 send_ck=0 new_key=1
+- ...ik=27497388b6cb044648f396aa155b95ef
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: state_chg to PR_ARQ_S_WAIT_CIPH
+DREF MSISDN:42342: MSC conn use - dtap == 0 (0x0: )
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  security_mode_ctrl_sent == 1
+  cm_service_result_sent == 0
+- MS sends SecurityModeControl acceptance, VLR accepts; above Ciphering is an implicit CM Service Accept
+DMM <- SECURITY MODE COMPLETE MSISDN:42342
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_CIPH}: Received Event PR_ARQ_E_CIPH_RES
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_node2_post_ciph()
+DIUCS MSISDN:42342: tx CommonID 901700000010650
+- Iu Common ID --RAN_UTRAN_IU--> MS (IMSI=901700000010650)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_node2_post_vlr()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_pres()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_trace()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_imei()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_CIPH}: proc_arq_fsm_done(PASSED)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_CIPH}: state_chg to PR_ARQ_S_DONE
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_DONE}: Process Access Request result: PASSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_ACCEPTED
+DREF MSISDN:42342: MSC conn use + cm_service == 1 (0x8: cm_service)
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_ACCEPTED}: subscr_conn_fsm_has_active_transactions: still awaiting first request after a CM Service Request
+  cm_service_result_sent == 0
+- Concluding CM Service Request
+DREF MSISDN:42342: MSC conn use - cm_service == 0 (0x0: )
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:42342: MSC conn use + release == 1 (0x100: release)
+DREF VLR subscr MSISDN:42342 usage increases to: 3
+DREF VLR subscr MSISDN:42342 usage decreases to: 2
+- Iu Release --RAN_UTRAN_IU--> MS
+  iu_release_sent == 1
+- RNC sends Iu Release Complete
+DREF MSISDN:42342: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_DONE}: Removing from parent Subscr_Conn(CM_SERVICE_REQ:901700000010650)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_DONE}: Freeing instance
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_DONE}: Deallocated
+DRLL MSISDN:42342: Freeing subscriber connection
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_RELEASED}: Deallocated
+- all requests serviced, conn has been released
+  llist_count(&net->subscr_conns) == 0
+---
+- Now the auth tuple has use_count == 2
+DREF VLR subscr MSISDN:42342 usage increases to: 2
+  vsub->last_tuple->use_count == 2
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+---
+- after a while, a new conn sends a CM Service Request. VLR responds with Auth Req, and reuses old auth vector
+  MSC <--RAN_UTRAN_IU-- MS: GSM48_MT_MM_CM_SERV_REQ
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_CM_SERV_REQ (0x5:0x24)
+DMM <- CM SERVICE REQUEST serv_type=0x08 MI(IMSI)=901700000010650
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_NEW}: Updated ID
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: Allocated
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: is child of Subscr_Conn(CM_SERVICE_REQ:901700000010650)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: rev=R99 net=UTRAN Auth+Ciph
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START
+DREF VLR subscr MSISDN:42342 usage increases to: 2
+DREF VLR subscr MSISDN:42342 usage increases to: 3
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_WAIT_AUTH
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Allocated
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: is child of Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650)
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_WAIT_RESP
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_WAIT_RESP}: got auth tuple: use_count=3 key_seq=0 -- will use UMTS AKA (is_r99=yes, at->vec.auth_types=0x3)
+- sending UMTS Auth Request for MSISDN:42342: tuple use_count=3 key_seq=0 auth_types=0x3 and...
+- ...rand=39fa2f4e3d523d8619a73b4f65c3e14d
+- ...autn=8704f5ba55f30000d2ee44b22c8ea919
+- ...expecting res=e229c19e791f2e41
+DREF VLR subscr MSISDN:42342 usage decreases to: 2
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF MSISDN:42342: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  cm_service_result_sent == 0
+  auth_request_sent == 1
+- MS sends Authen Response, VLR accepts and sends SecurityModeControl
+  MSC <--RAN_UTRAN_IU-- MS: GSM48_MT_MM_AUTH_RESP
+DREF MSISDN:42342: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14)
+DMM MSISDN:42342: MM UMTS AUTHENTICATION RESPONSE (res = e229c19e791f2e41)
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP
+DVLR SUBSCR(MSISDN:42342) AUTH on UTRAN received RES: e229c19e791f2e41 (8 bytes)
+DVLR SUBSCR(MSISDN:42342) AUTH established UMTS security context
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result PASSED
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Removing from parent Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650)
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Freeing instance
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Deallocated
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: Received Event PR_ARQ_E_AUTH_RES
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: Set Ciphering Mode
+DMM -> SECURITY MODE CONTROL MSISDN:42342
+- sending SecurityModeControl for UE ctx 42 send_ck=0 new_key=1
+- ...ik=27497388b6cb044648f396aa155b95ef
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: state_chg to PR_ARQ_S_WAIT_CIPH
+DREF MSISDN:42342: MSC conn use - dtap == 0 (0x0: )
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  security_mode_ctrl_sent == 1
+  cm_service_result_sent == 0
+- MS sends SecurityModeControl acceptance, VLR accepts; above Ciphering is an implicit CM Service Accept
+DMM <- SECURITY MODE COMPLETE MSISDN:42342
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_CIPH}: Received Event PR_ARQ_E_CIPH_RES
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_node2_post_ciph()
+DIUCS MSISDN:42342: tx CommonID 901700000010650
+- Iu Common ID --RAN_UTRAN_IU--> MS (IMSI=901700000010650)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_node2_post_vlr()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_pres()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_trace()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_imei()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_CIPH}: proc_arq_fsm_done(PASSED)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_CIPH}: state_chg to PR_ARQ_S_DONE
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_DONE}: Process Access Request result: PASSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_ACCEPTED
+DREF MSISDN:42342: MSC conn use + cm_service == 1 (0x8: cm_service)
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_ACCEPTED}: subscr_conn_fsm_has_active_transactions: still awaiting first request after a CM Service Request
+  cm_service_result_sent == 0
+- Concluding CM Service Request
+DREF MSISDN:42342: MSC conn use - cm_service == 0 (0x0: )
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:42342: MSC conn use + release == 1 (0x100: release)
+DREF VLR subscr MSISDN:42342 usage increases to: 3
+DREF VLR subscr MSISDN:42342 usage decreases to: 2
+- Iu Release --RAN_UTRAN_IU--> MS
+  iu_release_sent == 1
+- RNC sends Iu Release Complete
+DREF MSISDN:42342: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_DONE}: Removing from parent Subscr_Conn(CM_SERVICE_REQ:901700000010650)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_DONE}: Freeing instance
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_DONE}: Deallocated
+DRLL MSISDN:42342: Freeing subscriber connection
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_RELEASED}: Deallocated
+- all requests serviced, conn has been released
+  llist_count(&net->subscr_conns) == 0
+---
+- Now the auth tuple has use_count == 3
+DREF VLR subscr MSISDN:42342 usage increases to: 2
+  vsub->last_tuple->use_count == 3
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+---
+- after a while, a new conn sends a CM Service Request. VLR responds with Auth Req, and reuses old auth vector
+  MSC <--RAN_UTRAN_IU-- MS: GSM48_MT_MM_CM_SERV_REQ
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_CM_SERV_REQ (0x5:0x24)
+DMM <- CM SERVICE REQUEST serv_type=0x08 MI(IMSI)=901700000010650
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_NEW}: Updated ID
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: Allocated
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: is child of Subscr_Conn(CM_SERVICE_REQ:901700000010650)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: rev=R99 net=UTRAN Auth+Ciph
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START
+DREF VLR subscr MSISDN:42342 usage increases to: 2
+DREF VLR subscr MSISDN:42342 usage increases to: 3
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_WAIT_AUTH
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Allocated
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: is child of Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650)
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_WAIT_RESP
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_WAIT_RESP}: got auth tuple: use_count=4 key_seq=0 -- will use UMTS AKA (is_r99=yes, at->vec.auth_types=0x3)
+- sending UMTS Auth Request for MSISDN:42342: tuple use_count=4 key_seq=0 auth_types=0x3 and...
+- ...rand=39fa2f4e3d523d8619a73b4f65c3e14d
+- ...autn=8704f5ba55f30000d2ee44b22c8ea919
+- ...expecting res=e229c19e791f2e41
+DREF VLR subscr MSISDN:42342 usage decreases to: 2
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF MSISDN:42342: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  cm_service_result_sent == 0
+  auth_request_sent == 1
+- MS sends Authen Response, VLR accepts and sends SecurityModeControl
+  MSC <--RAN_UTRAN_IU-- MS: GSM48_MT_MM_AUTH_RESP
+DREF MSISDN:42342: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14)
+DMM MSISDN:42342: MM UMTS AUTHENTICATION RESPONSE (res = e229c19e791f2e41)
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP
+DVLR SUBSCR(MSISDN:42342) AUTH on UTRAN received RES: e229c19e791f2e41 (8 bytes)
+DVLR SUBSCR(MSISDN:42342) AUTH established UMTS security context
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result PASSED
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Removing from parent Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650)
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Freeing instance
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Deallocated
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: Received Event PR_ARQ_E_AUTH_RES
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: Set Ciphering Mode
+DMM -> SECURITY MODE CONTROL MSISDN:42342
+- sending SecurityModeControl for UE ctx 42 send_ck=0 new_key=1
+- ...ik=27497388b6cb044648f396aa155b95ef
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: state_chg to PR_ARQ_S_WAIT_CIPH
+DREF MSISDN:42342: MSC conn use - dtap == 0 (0x0: )
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  security_mode_ctrl_sent == 1
+  cm_service_result_sent == 0
+- MS sends SecurityModeControl acceptance, VLR accepts; above Ciphering is an implicit CM Service Accept
+DMM <- SECURITY MODE COMPLETE MSISDN:42342
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_CIPH}: Received Event PR_ARQ_E_CIPH_RES
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_node2_post_ciph()
+DIUCS MSISDN:42342: tx CommonID 901700000010650
+- Iu Common ID --RAN_UTRAN_IU--> MS (IMSI=901700000010650)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_node2_post_vlr()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_pres()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_trace()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_imei()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_CIPH}: proc_arq_fsm_done(PASSED)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_CIPH}: state_chg to PR_ARQ_S_DONE
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_DONE}: Process Access Request result: PASSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_ACCEPTED
+DREF MSISDN:42342: MSC conn use + cm_service == 1 (0x8: cm_service)
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_ACCEPTED}: subscr_conn_fsm_has_active_transactions: still awaiting first request after a CM Service Request
+  cm_service_result_sent == 0
+- Concluding CM Service Request
+DREF MSISDN:42342: MSC conn use - cm_service == 0 (0x0: )
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:42342: MSC conn use + release == 1 (0x100: release)
+DREF VLR subscr MSISDN:42342 usage increases to: 3
+DREF VLR subscr MSISDN:42342 usage decreases to: 2
+- Iu Release --RAN_UTRAN_IU--> MS
+  iu_release_sent == 1
+- RNC sends Iu Release Complete
+DREF MSISDN:42342: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_DONE}: Removing from parent Subscr_Conn(CM_SERVICE_REQ:901700000010650)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_DONE}: Freeing instance
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_DONE}: Deallocated
+DRLL MSISDN:42342: Freeing subscriber connection
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_RELEASED}: Deallocated
+- all requests serviced, conn has been released
+  llist_count(&net->subscr_conns) == 0
+---
+- subscriber detaches
+  MSC <--RAN_UTRAN_IU-- MS: GSM48_MT_MM_IMSI_DETACH_IND
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_IMSI_DETACH_IND (0x5:0x1)
+DMM IMSI DETACH INDICATION: MI(IMSI)=901700000010650
+DREF VLR subscr MSISDN:42342 usage increases to: 2
+DMM IMSI DETACH for MSISDN:42342
+DREF VLR subscr MSISDN:42342 usage increases to: 3
+DREF VLR subscr MSISDN:42342 usage decreases to: 2
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+DREF VLR subscr MSISDN:42342 usage decreases to: 0
+DREF freeing VLR subscr MSISDN:42342
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_CN_CLOSE
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF unknown: MSC conn use + release == 2 (0x101: compl_l3,release)
+- Iu Release --RAN_UTRAN_IU--> MS
+DREF unknown: MSC conn use - compl_l3 == 1 (0x100: release)
+  iu_release_sent == 1
+- RNC sends Iu Release Complete
+DREF unknown: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DRLL Freeing subscriber connection with NULL subscriber
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+===== test_auth_use_infinitely_utran: SUCCESS
+
+full talloc report on 'msgb' (total      0 bytes in   1 blocks)
+talloc_total_blocks(tall_bsc_ctx) == 12
+
+===== test_no_auth_reuse_geran
+- Location Update request causes a GSUP Send Auth Info request to HLR
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8)
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_NEW}: Updated ID
+DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000010650 type=NORMAL
+DMM LU/new-LAC: 0/23
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: Allocated
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: is child of Subscr_Conn(LU:901700000010650)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: rev=R99 net=GERAN Auth (no Ciph)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA
+DREF VLR subscr unknown usage increases to: 1
+DVLR set IMSI on subscriber; IMSI=901700000010650 id=901700000010650
+DVLR New subscr, IMSI: 901700000010650
+DREF VLR subscr IMSI:901700000010650 usage increases to: 2
+DREF VLR subscr IMSI:901700000010650 usage decreases to: 1
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Allocated
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(LU:901700000010650)
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
+DVLR GSUP tx: 08010809710000000156f0
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f0
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF IMSI:901700000010650: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  lu_result_sent == 0
+- from HLR, rx _SEND_AUTH_INFO_RESULT, only one tuple; VLR sends Auth Req to MS
+<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT: 0a010809710000000156f00362201039fa2f4e3d523d8619a73b4f65c3e14d21049b36efdf2208059a4f668f6fbe39231027497388b6cb044648f396aa155b95ef2410f64735036e5871319c679f4742a75ea125108704f5ba55f30000d2ee44b22c8ea9192708e229c19e791f2e41
+DVLR GSUP rx 111: 0a010809710000000156f00362201039fa2f4e3d523d8619a73b4f65c3e14d21049b36efdf2208059a4f668f6fbe39231027497388b6cb044648f396aa155b95ef2410f64735036e5871319c679f4742a75ea125108704f5ba55f30000d2ee44b22c8ea9192708e229c19e791f2e41
+DREF VLR subscr IMSI:901700000010650 usage increases to: 2
+DVLR VLR_Authenticate(LU:901700000010650){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(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: state_chg to VLR_SUB_AS_WAIT_RESP
+DVLR VLR_Authenticate(LU:901700000010650){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: tuple use_count=1 key_seq=0 auth_types=0x3 and...
+- ...rand=39fa2f4e3d523d8619a73b4f65c3e14d
+- ...autn=8704f5ba55f30000d2ee44b22c8ea919
+- ...expecting res=e229c19e791f2e41
+DREF VLR subscr IMSI:901700000010650 usage decreases to: 1
+<-- 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
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_AUTH_RESP
+DREF IMSI:901700000010650: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14)
+DMM IMSI:901700000010650: MM UMTS AUTHENTICATION RESPONSE (res = e229c19e791f2e41)
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP
+DVLR SUBSCR(IMSI:901700000010650) AUTH on GERAN received SRES/RES: e229c19e791f2e41 (8 bytes)
+DVLR SUBSCR(IMSI:901700000010650) AUTH established UMTS security context
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result PASSED
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(LU:901700000010650)
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Freeing instance
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth()
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_ciph()
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_node_4()
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_INIT}: Allocated
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000010650)
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START
+DVLR GSUP tx: 04010809710000000156f0280102
+GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000000156f0280102
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA
+DREF IMSI:901700000010650: MSC conn use - dtap == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  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: 10010809710000000156f00804032443f2
+DVLR GSUP rx 17: 10010809710000000156f00804032443f2
+DREF VLR subscr IMSI:901700000010650 usage increases to: 2
+DVLR IMSI:901700000010650 has MSISDN:42342
+DVLR SUBSCR(MSISDN:42342) VLR: update for IMSI=901700000010650 (MSISDN=42342, used=2)
+DVLR GSUP tx: 12010809710000000156f0
+GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000000156f0
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+<-- 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: 06010809710000000156f0
+DVLR GSUP rx 11: 06010809710000000156f0
+DREF VLR subscr MSISDN:42342 usage increases to: 2
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000010650)
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_DONE}: Freeing instance
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_INIT}: Allocated
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000010650)
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_INIT}: Allocated
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(LU:901700000010650)
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(LU:901700000010650)
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_DONE}: Freeing instance
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_DONE}: Deallocated
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_WAIT_SUB_PRES}: lu_compl_vlr_new_tmsi()
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_WAIT_TMSI_CNF
+- sending LU Accept for MSISDN:42342, with TMSI 0x03020100
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+<-- 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(&net->subscr_conns) == 1
+msc_subscr_conn_is_accepted() == false
+  requests shall be thwarted
+DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5)
+DRLL subscr MSISDN:42342: Message not permitted for initial conn: GSM48_MT_CC_SETUP
+DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33)
+DRLL subscr MSISDN:42342: Message not permitted for initial conn: unknown 0x33
+DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19)
+DRLL subscr MSISDN:42342: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1
+DRLL Dispatching 04.08 message SMS:0x01 (0x9:0x1)
+DRLL subscr MSISDN:42342: Message not permitted for initial conn: SMS:0x01
+- even though the TMSI is not acked, we can already find the subscr with it
+DREF VLR subscr MSISDN:42342 usage increases to: 2
+  vsub != NULL == 1
+  strcmp(vsub->imsi, imsi) == 0
+  vsub->tmsi_new == 0x03020100
+  vsub->tmsi == 0xffffffff
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+- MS sends TMSI Realloc Complete
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_TMSI_REALL_COMPL
+DREF MSISDN:42342: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_TMSI_REALL_COMPL (0x5:0x1b)
+DMM TMSI Reallocation Completed. Subscriber: MSISDN:42342
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_NEW_TMSI_ACK
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_WAIT_TMSI_CNF}: Received Event LU_COMPL_VLR_E_NEW_TMSI_ACK
+DREF VLR subscr MSISDN:42342 usage increases to: 2
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_WAIT_TMSI_CNF}: state_chg to LU_COMPL_VLR_S_DONE
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000010650)
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_DONE}: Freeing instance
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_ACCEPTED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:42342: MSC conn use + release == 2 (0x102: dtap,release)
+DREF VLR subscr MSISDN:42342 usage increases to: 3
+DREF VLR subscr MSISDN:42342 usage decreases to: 2
+- BSSAP Clear --RAN_GERAN_A--> MS
+DREF MSISDN:42342: MSC conn use - dtap == 1 (0x100: release)
+  bssap_clear_sent == 1
+- BSS sends BSSMAP Clear Complete
+DREF MSISDN:42342: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(LU:901700000010650)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: Freeing instance
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: Deallocated
+DRLL MSISDN:42342: Freeing subscriber connection
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASED}: Deallocated
+- LU was successful, and the conn has already been closed
+  llist_count(&net->subscr_conns) == 0
+---
+- Now the auth tuple has use_count == 1, as much as is allowed.
+DREF VLR subscr MSISDN:42342 usage increases to: 2
+  vsub->last_tuple->use_count == 1
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+---
+- after a while, a new conn sends a CM Service Request. VLR responds with Auth Req, and needs to request a second auth vector from HLR
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_CM_SERV_REQ
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_CM_SERV_REQ (0x5:0x24)
+DMM <- CM SERVICE REQUEST serv_type=0x08 MI(IMSI)=901700000010650
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_NEW}: Updated ID
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: Allocated
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: is child of Subscr_Conn(CM_SERVICE_REQ:901700000010650)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: rev=R99 net=GERAN Auth (no Ciph)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START
+DREF VLR subscr MSISDN:42342 usage increases to: 2
+DREF VLR subscr MSISDN:42342 usage increases to: 3
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_WAIT_AUTH
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Allocated
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: is child of Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650)
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
+DVLR GSUP tx: 08010809710000000156f0
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f0
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
+DREF VLR subscr MSISDN:42342 usage decreases to: 2
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF MSISDN:42342: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  cm_service_result_sent == 0
+  auth_request_sent == 0
+  gsup_tx_confirmed == 1
+- from HLR, rx _SEND_AUTH_INFO_RESULT, second tuple; VLR sends Auth Req to MS
+<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT: 0a010809710000000156f003622010c187a53a5e6b9d573cac7c74451fd46d210485aa31302208d3d50a000bf04f6e23101159ec926a50e98c034a6b7d7c9f418d2410df3a03d9ca5335641efc8e36d76cd20b25101843a645b98d00005b2d666af46c45d927087db47cf7f81e4dc7
+DVLR GSUP rx 111: 0a010809710000000156f003622010c187a53a5e6b9d573cac7c74451fd46d210485aa31302208d3d50a000bf04f6e23101159ec926a50e98c034a6b7d7c9f418d2410df3a03d9ca5335641efc8e36d76cd20b25101843a645b98d00005b2d666af46c45d927087db47cf7f81e4dc7
+DREF VLR subscr MSISDN:42342 usage increases to: 3
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: Received Event VLR_AUTH_E_HLR_SAI_ACK
+DVLR SUBSCR(MSISDN:42342) Received 1 auth tuples
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: state_chg to VLR_SUB_AS_WAIT_RESP
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){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 MSISDN:42342: tuple use_count=1 key_seq=0 auth_types=0x3 and...
+- ...rand=c187a53a5e6b9d573cac7c74451fd46d
+- ...autn=1843a645b98d00005b2d666af46c45d9
+- ...expecting res=7db47cf7f81e4dc7
+DREF VLR subscr MSISDN:42342 usage decreases to: 2
+<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT: vlr_gsupc_read_cb() returns 0
+  auth_request_sent == 1
+  cm_service_result_sent == 0
+- MS sends Authen Response, VLR accepts with a CM Service Accept
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_AUTH_RESP
+DREF MSISDN:42342: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14)
+DMM MSISDN:42342: MM UMTS AUTHENTICATION RESPONSE (res = 7db47cf7f81e4dc7)
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP
+DVLR SUBSCR(MSISDN:42342) AUTH on GERAN received SRES/RES: 7db47cf7f81e4dc7 (8 bytes)
+DVLR SUBSCR(MSISDN:42342) AUTH established UMTS security context
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result PASSED
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Removing from parent Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650)
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Freeing instance
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Deallocated
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: Received Event PR_ARQ_E_AUTH_RES
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2_post_ciph()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2_post_vlr()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_pres()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_trace()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_imei()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: proc_arq_fsm_done(PASSED)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: state_chg to PR_ARQ_S_DONE
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_DONE}: Process Access Request result: PASSED
+- sending CM Service Accept for MSISDN:42342
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_ACCEPTED
+DREF MSISDN:42342: MSC conn use + cm_service == 2 (0xa: dtap,cm_service)
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_ACCEPTED}: subscr_conn_fsm_has_active_transactions: still awaiting first request after a CM Service Request
+DREF MSISDN:42342: MSC conn use - dtap == 1 (0x8: cm_service)
+  cm_service_result_sent == 1
+- Concluding CM Service Request
+DREF MSISDN:42342: MSC conn use - cm_service == 0 (0x0: )
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:42342: MSC conn use + release == 1 (0x100: release)
+DREF VLR subscr MSISDN:42342 usage increases to: 3
+DREF VLR subscr MSISDN:42342 usage decreases to: 2
+- BSSAP Clear --RAN_GERAN_A--> MS
+  bssap_clear_sent == 1
+- BSS sends BSSMAP Clear Complete
+DREF MSISDN:42342: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_DONE}: Removing from parent Subscr_Conn(CM_SERVICE_REQ:901700000010650)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_DONE}: Freeing instance
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_DONE}: Deallocated
+DRLL MSISDN:42342: Freeing subscriber connection
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_RELEASED}: Deallocated
+- all requests serviced, conn has been released
+  llist_count(&net->subscr_conns) == 0
+---
+- subscriber detaches
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_IMSI_DETACH_IND
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_IMSI_DETACH_IND (0x5:0x1)
+DMM IMSI DETACH INDICATION: MI(IMSI)=901700000010650
+DREF VLR subscr MSISDN:42342 usage increases to: 2
+DMM IMSI DETACH for MSISDN:42342
+DREF VLR subscr MSISDN:42342 usage increases to: 3
+DREF VLR subscr MSISDN:42342 usage decreases to: 2
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+DREF VLR subscr MSISDN:42342 usage decreases to: 0
+DREF freeing VLR subscr MSISDN:42342
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_CN_CLOSE
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF unknown: MSC conn use + release == 2 (0x101: compl_l3,release)
+- BSSAP Clear --RAN_GERAN_A--> MS
+DREF unknown: MSC conn use - compl_l3 == 1 (0x100: release)
+  bssap_clear_sent == 1
+- BSS sends BSSMAP Clear Complete
+DREF unknown: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DRLL Freeing subscriber connection with NULL subscriber
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+===== test_no_auth_reuse_geran: SUCCESS
+
+full talloc report on 'msgb' (total      0 bytes in   1 blocks)
+talloc_total_blocks(tall_bsc_ctx) == 12
+
+===== test_no_auth_reuse_utran
+- Location Update request causes a GSUP Send Auth Info request to HLR
+  MSC <--RAN_UTRAN_IU-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8)
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_NEW}: Updated ID
+DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000010650 type=NORMAL
+DMM LU/new-LAC: 0/23
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: Allocated
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: is child of Subscr_Conn(LU:901700000010650)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: rev=R99 net=UTRAN Auth+Ciph
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA
+DREF VLR subscr unknown usage increases to: 1
+DVLR set IMSI on subscriber; IMSI=901700000010650 id=901700000010650
+DVLR New subscr, IMSI: 901700000010650
+DREF VLR subscr IMSI:901700000010650 usage increases to: 2
+DREF VLR subscr IMSI:901700000010650 usage decreases to: 1
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Allocated
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(LU:901700000010650)
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
+DVLR GSUP tx: 08010809710000000156f0
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f0
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF IMSI:901700000010650: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  lu_result_sent == 0
+- from HLR, rx _SEND_AUTH_INFO_RESULT, only one tuple; VLR sends Auth Req to MS
+<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT: 0a010809710000000156f00362201039fa2f4e3d523d8619a73b4f65c3e14d21049b36efdf2208059a4f668f6fbe39231027497388b6cb044648f396aa155b95ef2410f64735036e5871319c679f4742a75ea125108704f5ba55f30000d2ee44b22c8ea9192708e229c19e791f2e41
+DVLR GSUP rx 111: 0a010809710000000156f00362201039fa2f4e3d523d8619a73b4f65c3e14d21049b36efdf2208059a4f668f6fbe39231027497388b6cb044648f396aa155b95ef2410f64735036e5871319c679f4742a75ea125108704f5ba55f30000d2ee44b22c8ea9192708e229c19e791f2e41
+DREF VLR subscr IMSI:901700000010650 usage increases to: 2
+DVLR VLR_Authenticate(LU:901700000010650){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(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: state_chg to VLR_SUB_AS_WAIT_RESP
+DVLR VLR_Authenticate(LU:901700000010650){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: tuple use_count=1 key_seq=0 auth_types=0x3 and...
+- ...rand=39fa2f4e3d523d8619a73b4f65c3e14d
+- ...autn=8704f5ba55f30000d2ee44b22c8ea919
+- ...expecting res=e229c19e791f2e41
+DREF VLR subscr IMSI:901700000010650 usage decreases to: 1
+<-- 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
+  MSC <--RAN_UTRAN_IU-- MS: GSM48_MT_MM_AUTH_RESP
+DREF IMSI:901700000010650: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14)
+DMM IMSI:901700000010650: MM UMTS AUTHENTICATION RESPONSE (res = e229c19e791f2e41)
+DVLR VLR_Authenticate(LU:901700000010650){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(LU:901700000010650){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result PASSED
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(LU:901700000010650)
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Freeing instance
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth()
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_AUTH}: Set Ciphering Mode
+DMM -> SECURITY MODE CONTROL IMSI:901700000010650
+- sending SecurityModeControl for UE ctx 42 send_ck=0 new_key=1
+- ...ik=27497388b6cb044648f396aa155b95ef
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_WAIT_CIPH
+DREF IMSI:901700000010650: MSC conn use - dtap == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  security_mode_ctrl_sent == 1
+  lu_result_sent == 0
+- MS sends SecurityModeControl acceptance, VLR accepts and sends GSUP LU Req to HLR
+DMM <- SECURITY MODE COMPLETE IMSI:901700000010650
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_CIPH}: Received Event VLR_ULA_E_CIPH_RES
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_CIPH}: vlr_loc_upd_post_ciph()
+DIUCS IMSI:901700000010650: tx CommonID 901700000010650
+- Iu Common ID --RAN_UTRAN_IU--> MS (IMSI=901700000010650)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_CIPH}: vlr_loc_upd_node_4()
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_CIPH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_INIT}: Allocated
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000010650)
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START
+DVLR GSUP tx: 04010809710000000156f0280102
+GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000000156f0280102
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){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: 10010809710000000156f00804032443f2
+DVLR GSUP rx 17: 10010809710000000156f00804032443f2
+DREF VLR subscr IMSI:901700000010650 usage increases to: 2
+DVLR IMSI:901700000010650 has MSISDN:42342
+DVLR SUBSCR(MSISDN:42342) VLR: update for IMSI=901700000010650 (MSISDN=42342, used=2)
+DVLR GSUP tx: 12010809710000000156f0
+GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000000156f0
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+<-- 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: 06010809710000000156f0
+DVLR GSUP rx 11: 06010809710000000156f0
+DREF VLR subscr MSISDN:42342 usage increases to: 2
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000010650)
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_DONE}: Freeing instance
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_INIT}: Allocated
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000010650)
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_INIT}: Allocated
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(LU:901700000010650)
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(LU:901700000010650)
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_DONE}: Freeing instance
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_DONE}: Deallocated
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_WAIT_SUB_PRES}: lu_compl_vlr_new_tmsi()
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_WAIT_TMSI_CNF
+- sending LU Accept for MSISDN:42342, with TMSI 0x03020100
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+<-- 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(&net->subscr_conns) == 1
+msc_subscr_conn_is_accepted() == false
+  requests shall be thwarted
+DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5)
+DRLL subscr MSISDN:42342: Message not permitted for initial conn: GSM48_MT_CC_SETUP
+DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33)
+DRLL subscr MSISDN:42342: Message not permitted for initial conn: unknown 0x33
+DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19)
+DRLL subscr MSISDN:42342: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1
+DRLL Dispatching 04.08 message SMS:0x01 (0x9:0x1)
+DRLL subscr MSISDN:42342: Message not permitted for initial conn: SMS:0x01
+- even though the TMSI is not acked, we can already find the subscr with it
+DREF VLR subscr MSISDN:42342 usage increases to: 2
+  vsub != NULL == 1
+  strcmp(vsub->imsi, imsi) == 0
+  vsub->tmsi_new == 0x03020100
+  vsub->tmsi == 0xffffffff
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+- MS sends TMSI Realloc Complete
+  MSC <--RAN_UTRAN_IU-- MS: GSM48_MT_MM_TMSI_REALL_COMPL
+DREF MSISDN:42342: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_TMSI_REALL_COMPL (0x5:0x1b)
+DMM TMSI Reallocation Completed. Subscriber: MSISDN:42342
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_NEW_TMSI_ACK
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_WAIT_TMSI_CNF}: Received Event LU_COMPL_VLR_E_NEW_TMSI_ACK
+DREF VLR subscr MSISDN:42342 usage increases to: 2
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_WAIT_TMSI_CNF}: state_chg to LU_COMPL_VLR_S_DONE
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000010650)
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_DONE}: Freeing instance
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_ACCEPTED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:42342: MSC conn use + release == 2 (0x102: dtap,release)
+DREF VLR subscr MSISDN:42342 usage increases to: 3
+DREF VLR subscr MSISDN:42342 usage decreases to: 2
+- Iu Release --RAN_UTRAN_IU--> MS
+DREF MSISDN:42342: MSC conn use - dtap == 1 (0x100: release)
+  iu_release_sent == 1
+- RNC sends Iu Release Complete
+DREF MSISDN:42342: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(LU:901700000010650)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: Freeing instance
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: Deallocated
+DRLL MSISDN:42342: Freeing subscriber connection
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASED}: Deallocated
+- LU was successful, and the conn has already been closed
+  llist_count(&net->subscr_conns) == 0
+---
+- Now the auth tuple has use_count == 1, as much as is allowed.
+DREF VLR subscr MSISDN:42342 usage increases to: 2
+  vsub->last_tuple->use_count == 1
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+---
+- after a while, a new conn sends a CM Service Request. VLR responds with Auth Req, and needs to request a second auth vector from HLR
+  MSC <--RAN_UTRAN_IU-- MS: GSM48_MT_MM_CM_SERV_REQ
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_CM_SERV_REQ (0x5:0x24)
+DMM <- CM SERVICE REQUEST serv_type=0x08 MI(IMSI)=901700000010650
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_NEW}: Updated ID
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: Allocated
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: is child of Subscr_Conn(CM_SERVICE_REQ:901700000010650)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: rev=R99 net=UTRAN Auth+Ciph
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START
+DREF VLR subscr MSISDN:42342 usage increases to: 2
+DREF VLR subscr MSISDN:42342 usage increases to: 3
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_WAIT_AUTH
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Allocated
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: is child of Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650)
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
+DVLR GSUP tx: 08010809710000000156f0
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f0
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
+DREF VLR subscr MSISDN:42342 usage decreases to: 2
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF MSISDN:42342: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  cm_service_result_sent == 0
+  auth_request_sent == 0
+  gsup_tx_confirmed == 1
+- from HLR, rx _SEND_AUTH_INFO_RESULT, second tuple; VLR sends Auth Req to MS
+<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT: 0a010809710000000156f003622010c187a53a5e6b9d573cac7c74451fd46d210485aa31302208d3d50a000bf04f6e23101159ec926a50e98c034a6b7d7c9f418d2410df3a03d9ca5335641efc8e36d76cd20b25101843a645b98d00005b2d666af46c45d927087db47cf7f81e4dc7
+DVLR GSUP rx 111: 0a010809710000000156f003622010c187a53a5e6b9d573cac7c74451fd46d210485aa31302208d3d50a000bf04f6e23101159ec926a50e98c034a6b7d7c9f418d2410df3a03d9ca5335641efc8e36d76cd20b25101843a645b98d00005b2d666af46c45d927087db47cf7f81e4dc7
+DREF VLR subscr MSISDN:42342 usage increases to: 3
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: Received Event VLR_AUTH_E_HLR_SAI_ACK
+DVLR SUBSCR(MSISDN:42342) Received 1 auth tuples
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: state_chg to VLR_SUB_AS_WAIT_RESP
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){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 MSISDN:42342: tuple use_count=1 key_seq=0 auth_types=0x3 and...
+- ...rand=c187a53a5e6b9d573cac7c74451fd46d
+- ...autn=1843a645b98d00005b2d666af46c45d9
+- ...expecting res=7db47cf7f81e4dc7
+DREF VLR subscr MSISDN:42342 usage decreases to: 2
+<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT: vlr_gsupc_read_cb() returns 0
+  auth_request_sent == 1
+  cm_service_result_sent == 0
+- MS sends Authen Response, VLR accepts and sends SecurityModeControl
+  MSC <--RAN_UTRAN_IU-- MS: GSM48_MT_MM_AUTH_RESP
+DREF MSISDN:42342: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14)
+DMM MSISDN:42342: MM UMTS AUTHENTICATION RESPONSE (res = 7db47cf7f81e4dc7)
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP
+DVLR SUBSCR(MSISDN:42342) AUTH on UTRAN received RES: 7db47cf7f81e4dc7 (8 bytes)
+DVLR SUBSCR(MSISDN:42342) AUTH established UMTS security context
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result PASSED
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Removing from parent Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650)
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Freeing instance
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Deallocated
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: Received Event PR_ARQ_E_AUTH_RES
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: Set Ciphering Mode
+DMM -> SECURITY MODE CONTROL MSISDN:42342
+- sending SecurityModeControl for UE ctx 42 send_ck=0 new_key=1
+- ...ik=1159ec926a50e98c034a6b7d7c9f418d
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: state_chg to PR_ARQ_S_WAIT_CIPH
+DREF MSISDN:42342: MSC conn use - dtap == 0 (0x0: )
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  security_mode_ctrl_sent == 1
+  cm_service_result_sent == 0
+- MS sends SecurityModeControl acceptance, VLR accepts; above Ciphering is an implicit CM Service Accept
+DMM <- SECURITY MODE COMPLETE MSISDN:42342
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_CIPH}: Received Event PR_ARQ_E_CIPH_RES
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_node2_post_ciph()
+DIUCS MSISDN:42342: tx CommonID 901700000010650
+- Iu Common ID --RAN_UTRAN_IU--> MS (IMSI=901700000010650)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_node2_post_vlr()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_pres()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_trace()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_imei()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_CIPH}: proc_arq_fsm_done(PASSED)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_CIPH}: state_chg to PR_ARQ_S_DONE
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_DONE}: Process Access Request result: PASSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_ACCEPTED
+DREF MSISDN:42342: MSC conn use + cm_service == 1 (0x8: cm_service)
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_ACCEPTED}: subscr_conn_fsm_has_active_transactions: still awaiting first request after a CM Service Request
+  cm_service_result_sent == 0
+- Concluding CM Service Request
+DREF MSISDN:42342: MSC conn use - cm_service == 0 (0x0: )
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:42342: MSC conn use + release == 1 (0x100: release)
+DREF VLR subscr MSISDN:42342 usage increases to: 3
+DREF VLR subscr MSISDN:42342 usage decreases to: 2
+- Iu Release --RAN_UTRAN_IU--> MS
+  iu_release_sent == 1
+- RNC sends Iu Release Complete
+DREF MSISDN:42342: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_DONE}: Removing from parent Subscr_Conn(CM_SERVICE_REQ:901700000010650)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_DONE}: Freeing instance
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_DONE}: Deallocated
+DRLL MSISDN:42342: Freeing subscriber connection
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_RELEASED}: Deallocated
+- all requests serviced, conn has been released
+  llist_count(&net->subscr_conns) == 0
+---
+- subscriber detaches
+  MSC <--RAN_UTRAN_IU-- MS: GSM48_MT_MM_IMSI_DETACH_IND
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_IMSI_DETACH_IND (0x5:0x1)
+DMM IMSI DETACH INDICATION: MI(IMSI)=901700000010650
+DREF VLR subscr MSISDN:42342 usage increases to: 2
+DMM IMSI DETACH for MSISDN:42342
+DREF VLR subscr MSISDN:42342 usage increases to: 3
+DREF VLR subscr MSISDN:42342 usage decreases to: 2
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+DREF VLR subscr MSISDN:42342 usage decreases to: 0
+DREF freeing VLR subscr MSISDN:42342
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_CN_CLOSE
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF unknown: MSC conn use + release == 2 (0x101: compl_l3,release)
+- Iu Release --RAN_UTRAN_IU--> MS
+DREF unknown: MSC conn use - compl_l3 == 1 (0x100: release)
+  iu_release_sent == 1
+- RNC sends Iu Release Complete
+DREF unknown: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DRLL Freeing subscriber connection with NULL subscriber
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+===== test_no_auth_reuse_utran: SUCCESS
+
+full talloc report on 'msgb' (total      0 bytes in   1 blocks)
+talloc_total_blocks(tall_bsc_ctx) == 12
+
+full talloc report on 'msgb' (total      0 bytes in   1 blocks)
+talloc_total_blocks(tall_bsc_ctx) == 12
+
diff --git a/tests/msc_vlr/msc_vlr_test_authen_reuse.ok b/tests/msc_vlr/msc_vlr_test_authen_reuse.ok
new file mode 100644
index 0000000..a965a70
--- /dev/null
+++ b/tests/msc_vlr/msc_vlr_test_authen_reuse.ok
@@ -0,0 +1 @@
+Done
diff --git a/tests/msc_vlr/msc_vlr_test_call.c b/tests/msc_vlr/msc_vlr_test_call.c
new file mode 100644
index 0000000..5819e51
--- /dev/null
+++ b/tests/msc_vlr/msc_vlr_test_call.c
@@ -0,0 +1,590 @@
+/* Osmocom MSC+VLR end-to-end tests */
+
+/* (C) 2017 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
+ *
+ * All Rights Reserved
+ *
+ * Author: Neels Hofmeyr <nhofmeyr@sysmocom.de>
+ *
+ * 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 "msc_vlr_tests.h"
+
+#include <osmocom/msc/gsm_04_08.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, msg_type, mncc);
+}
+
+static void on_call_release_mncc_sends_to_cc(uint32_t msg_type, struct gsm_mncc *mncc)
+{
+	mncc->msg_type = msg_type;
+	on_call_release_mncc_sends_to_cc_data = mncc;
+}
+
+#define IMSI "901700000010650"
+
+static void standard_lu()
+{
+	struct vlr_subscr *vsub;
+
+	net->authentication_required = true;
+	net->vlr->cfg.assign_tmsi = true;
+	rx_from_ran = RAN_UTRAN_IU;
+
+	btw("Location Update request causes a GSUP Send Auth Info request to HLR");
+	lu_result_sent = RES_NONE;
+	gsup_expect_tx("080108" "09710000000156f0");
+	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("from HLR, rx _SEND_AUTH_INFO_RESULT; VLR sends Auth Req to MS");
+	/* based on auc_3g:
+	 * K = 'EB215756028D60E3275E613320AEC880',
+	 * OPC = 'FB2A3D1B360F599ABAB99DB8669F8308'
+	 * SQN = 0
+	 */
+	auth_request_sent = false;
+	auth_request_expect_rand = "39fa2f4e3d523d8619a73b4f65c3e14d";
+	auth_request_expect_autn = "8704f5ba55f30000d2ee44b22c8ea919";
+	gsup_rx("0a"
+		/* imsi */
+		"0108" "09710000000156f0"
+		/* 5 auth vectors... */
+		/* TL    TL     rand */
+		"0362"  "2010" "39fa2f4e3d523d8619a73b4f65c3e14d"
+		/*       TL     sres       TL     kc */
+			"2104" "9b36efdf" "2208" "059a4f668f6fbe39"
+		/*       TL     3G IK */
+			"2310" "27497388b6cb044648f396aa155b95ef"
+		/*       TL     3G CK */
+			"2410" "f64735036e5871319c679f4742a75ea1"
+		/*       TL     AUTN */
+			"2510" "8704f5ba55f30000d2ee44b22c8ea919"
+		/*       TL     RES */
+			"2708" "e229c19e791f2e41"
+		/* TL    TL     rand */
+		"0362"  "2010" "c187a53a5e6b9d573cac7c74451fd46d"
+			"2104" "85aa3130" "2208" "d3d50a000bf04f6e"
+			"2310" "1159ec926a50e98c034a6b7d7c9f418d"
+			"2410" "df3a03d9ca5335641efc8e36d76cd20b"
+			"2510" "1843a645b98d00005b2d666af46c45d9"
+			"2708" "7db47cf7f81e4dc7"
+		"0362"  "2010" "efa9c29a9742148d5c9070348716e1bb"
+			"2104" "69d5f9fb" "2208" "3df176f0c29f1a3d"
+			"2310" "eb50e770ddcc3060101d2f43b6c2b884"
+			"2410" "76542abce5ff9345b0e8947f4c6e019c"
+			"2510" "f9375e6d41e1000096e7fe4ff1c27e39"
+			"2708" "706f996719ba609c"
+		"0362"  "2010" "f023d5a3b24726e0631b64b3840f8253"
+			"2104" "d570c03f" "2208" "ec011be8919883d6"
+			"2310" "c4e58af4ba43f3bcd904e16984f086d7"
+			"2410" "0593f65e752e5cb7f473862bda05aa0a"
+			"2510" "541ff1f077270000c5ea00d658bc7e9a"
+			"2708" "3fd26072eaa2a04d"
+		"0362"  "2010" "2f8f90c780d6a9c0c53da7ac57b6707e"
+			"2104" "b072446f220823f39f9f425ad6e6"
+			"2310" "65af0527fda95b0dc5ae4aa515cdf32f"
+			"2410" "537c3b35a3b13b08d08eeb28098f45cc"
+			"2510" "4bf4e564f75300009bc796706bc65744"
+			"2708" "0edb0eadbea94ac2",
+		NULL);
+	VERBOSE_ASSERT(auth_request_sent, == true, "%d");
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("MS sends Authen Response, VLR accepts and sends SecurityModeControl");
+	expect_security_mode_ctrl(NULL, "27497388b6cb044648f396aa155b95ef");
+	ms_sends_msg("0554" "e229c19e" "2104" "791f2e41");
+	VERBOSE_ASSERT(security_mode_ctrl_sent, == true, "%d");
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("MS sends SecurityModeControl acceptance, VLR accepts and sends GSUP LU Req to HLR");
+	gsup_expect_tx("04010809710000000156f0280102");
+	ms_sends_security_mode_complete();
+	VERBOSE_ASSERT(gsup_tx_confirmed, == true, "%d");
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT");
+	gsup_rx("10010809710000000156f00804032443f2",
+		"12010809710000000156f0");
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("HLR also sends GSUP _UPDATE_LOCATION_RESULT");
+	gsup_rx("06010809710000000156f0", NULL);
+
+	VERBOSE_ASSERT(lu_result_sent, == RES_ACCEPT, "%d");
+
+	btw("a LU Accept with a new TMSI was sent, waiting for TMSI Realloc Compl");
+	EXPECT_CONN_COUNT(1);
+	EXPECT_ACCEPTED(false);
+
+	btw("MS sends TMSI Realloc Complete");
+	iu_release_expected = true;
+	iu_release_sent = false;
+	ms_sends_msg("055b");
+	VERBOSE_ASSERT(iu_release_sent, == true, "%d"); \
+
+	btw("LU was successful, and the conn has already been closed");
+	rnc_sends_release_complete();
+	EXPECT_CONN_COUNT(0);
+
+	vsub = vlr_subscr_find_by_imsi(net->vlr, IMSI);
+	VERBOSE_ASSERT(vsub != NULL, == true, "%d");
+	VERBOSE_ASSERT(strcmp(vsub->imsi, IMSI), == 0, "%d");
+	VERBOSE_ASSERT(vsub->lac, == 23, "%u");
+	vlr_subscr_put(vsub);
+}
+
+static void test_call_mo()
+{
+	struct gsm_mncc mncc = {
+		.imsi = IMSI,
+	};
+
+	comment_start();
+
+	fake_time_start();
+
+	standard_lu();
+
+	BTW("after a while, a new conn sends a CM Service Request. VLR responds with Auth Req, 2nd auth vector");
+	auth_request_sent = false;
+	auth_request_expect_rand = "c187a53a5e6b9d573cac7c74451fd46d";
+	auth_request_expect_autn = "1843a645b98d00005b2d666af46c45d9";
+	cm_service_result_sent = RES_NONE;
+	ms_sends_msg("052478"
+		     "03575886" /* classmark 2 */
+		     "089910070000106005" /* IMSI */);
+	OSMO_ASSERT(g_conn);
+	OSMO_ASSERT(g_conn->fi);
+	OSMO_ASSERT(g_conn->vsub);
+	VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d");
+	VERBOSE_ASSERT(auth_request_sent, == true, "%d");
+
+	btw("needs auth, not yet accepted");
+	EXPECT_ACCEPTED(false);
+
+	/* On UTRAN */
+	btw("MS sends Authen Response, VLR accepts and sends SecurityModeControl");
+	expect_security_mode_ctrl(NULL, "1159ec926a50e98c034a6b7d7c9f418d");
+	ms_sends_msg("0554" "7db47cf7" "2104" "f81e4dc7"); /* 2nd vector's res, s.a. */
+	VERBOSE_ASSERT(security_mode_ctrl_sent, == true, "%d");
+	VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d");
+
+	btw("MS sends SecurityModeControl acceptance, VLR accepts; above Ciphering is an implicit CM Service Accept");
+	ms_sends_security_mode_complete();
+	VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d");
+
+	BTW("a call is initiated");
+
+	btw("SETUP gets forwarded to MNCC");
+	cc_to_mncc_expect_tx(IMSI, MNCC_SETUP_IND);
+	ms_sends_msg("0385" /* CC, seq = 2 -> 0x80 | CC Setup = 0x5 */
+		     "0406600402000581" /* 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 */
+		    );
+	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 */);
+	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");
+	dtap_expect_tx("8301" /* CC: Call Alerting */);
+	mncc_sends_to_cc(MNCC_ALERT_REQ, &mncc);
+	OSMO_ASSERT(dtap_tx_confirmed);
+
+	dtap_expect_tx("8307" /* CC: Connect */);
+	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);
+
+	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_iu_release();
+	ms_sends_msg("036a" /* CC: Release Complete */);
+	OSMO_ASSERT(cc_to_mncc_tx_confirmed);
+	OSMO_ASSERT(iu_release_sent);
+
+	rnc_sends_release_complete();
+	EXPECT_CONN_COUNT(0);
+	clear_vlr();
+	comment_end();
+}
+
+static void test_call_mt()
+{
+	struct gsm_mncc mncc = {
+		.imsi = IMSI,
+		.callref = 0x423,
+	};
+
+	comment_start();
+
+	fake_time_start();
+
+	standard_lu();
+
+	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);
+
+	VERBOSE_ASSERT(paging_sent, == true, "%d");
+	VERBOSE_ASSERT(paging_stopped, == false, "%d");
+
+	btw("MS replies with Paging Response, and VLR sends Auth Request");
+	auth_request_sent = false;
+	auth_request_expect_rand = "c187a53a5e6b9d573cac7c74451fd46d";
+	auth_request_expect_autn = "1843a645b98d00005b2d666af46c45d9";
+	ms_sends_msg("062707"
+		     "03575886" /* classmark 2 */
+		     "089910070000106005" /* IMSI */);
+	VERBOSE_ASSERT(auth_request_sent, == true, "%d");
+
+	btw("MS sends Authen Response, VLR accepts and sends SecurityModeControl");
+	expect_security_mode_ctrl(NULL, "1159ec926a50e98c034a6b7d7c9f418d");
+	ms_sends_msg("0554" "7db47cf7" "2104" "f81e4dc7"); /* 2nd vector's res, s.a. */
+	VERBOSE_ASSERT(security_mode_ctrl_sent, == true, "%d");
+
+	btw("MS sends SecurityModeControl acceptance, VLR accepts, sends CC Setup");
+	dtap_expect_tx("0305" /* CC: Setup */);
+	ms_sends_security_mode_complete();
+	VERBOSE_ASSERT(paging_stopped, == true, "%d");
+
+	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 */);
+
+	fake_time_passes(1, 23);
+
+	cc_to_mncc_expect_tx("", MNCC_ALERT_IND);
+	ms_sends_msg("8381" /* CC: Alerting */);
+
+	fake_time_passes(1, 23);
+
+	cc_to_mncc_expect_tx(IMSI, MNCC_SETUP_CNF);
+	ms_sends_msg("83c7" /* CC: Connect */);
+
+	dtap_expect_tx("030f" /* CC: Connect Acknowledge */);
+	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_iu_release();
+	ms_sends_msg("836a" /* CC: Release Complete */);
+	OSMO_ASSERT(cc_to_mncc_tx_confirmed);
+	OSMO_ASSERT(iu_release_sent);
+
+	rnc_sends_release_complete();
+	EXPECT_CONN_COUNT(0);
+	clear_vlr();
+	comment_end();
+}
+
+static void test_call_mt2()
+{
+	struct gsm_mncc mncc = {
+		.imsi = IMSI,
+		.callref = 0x423,
+	};
+
+	comment_start();
+
+	fake_time_start();
+
+	standard_lu();
+
+	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);
+
+	VERBOSE_ASSERT(paging_sent, == true, "%d");
+	VERBOSE_ASSERT(paging_stopped, == false, "%d");
+
+	btw("MS replies with Paging Response, and VLR sends Auth Request");
+	auth_request_sent = false;
+	auth_request_expect_rand = "c187a53a5e6b9d573cac7c74451fd46d";
+	auth_request_expect_autn = "1843a645b98d00005b2d666af46c45d9";
+	ms_sends_msg("062707"
+		     "03575886" /* classmark 2 */
+		     "089910070000106005" /* IMSI */);
+	VERBOSE_ASSERT(auth_request_sent, == true, "%d");
+
+	btw("MS sends Authen Response, VLR accepts and sends SecurityModeControl");
+	expect_security_mode_ctrl(NULL, "1159ec926a50e98c034a6b7d7c9f418d");
+	ms_sends_msg("0554" "7db47cf7" "2104" "f81e4dc7"); /* 2nd vector's res, s.a. */
+	VERBOSE_ASSERT(security_mode_ctrl_sent, == true, "%d");
+
+	btw("MS sends SecurityModeControl acceptance, VLR accepts, sends CC Setup");
+	dtap_expect_tx("0305" /* CC: Setup */);
+	ms_sends_security_mode_complete();
+	VERBOSE_ASSERT(paging_stopped, == true, "%d");
+
+	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(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(15, 23);
+
+	btw("The call failed, the BSC sends a BSSMAP Clear Request");
+	on_call_release_mncc_sends_to_cc(MNCC_REL_REQ, &mncc);
+	cc_to_mncc_expect_tx("", MNCC_REL_CNF);
+	dtap_expect_tx("032d"); /* CC: Release */
+	expect_iu_release();
+	msc_clear_request(g_conn, 0);
+	OSMO_ASSERT(cc_to_mncc_tx_confirmed);
+	OSMO_ASSERT(iu_release_sent);
+
+	rnc_sends_release_complete();
+	EXPECT_CONN_COUNT(0);
+
+	/* Make sure a pending release timer doesn't fire later to access freed data */
+	fake_time_passes(15, 23);
+
+	clear_vlr();
+	comment_end();
+}
+
+static void test_call_mo_to_unknown()
+{
+	struct gsm_mncc mncc = {
+		.imsi = IMSI,
+	};
+
+	comment_start();
+
+	fake_time_start();
+
+	standard_lu();
+
+	BTW("after a while, a new conn sends a CM Service Request. VLR responds with Auth Req, 2nd auth vector");
+	auth_request_sent = false;
+	auth_request_expect_rand = "c187a53a5e6b9d573cac7c74451fd46d";
+	auth_request_expect_autn = "1843a645b98d00005b2d666af46c45d9";
+	cm_service_result_sent = RES_NONE;
+	ms_sends_msg("052478"
+		     "03575886" /* classmark 2 */
+		     "089910070000106005" /* IMSI */);
+	OSMO_ASSERT(g_conn);
+	OSMO_ASSERT(g_conn->fi);
+	OSMO_ASSERT(g_conn->vsub);
+	VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d");
+	VERBOSE_ASSERT(auth_request_sent, == true, "%d");
+
+	btw("needs auth, not yet accepted");
+	EXPECT_ACCEPTED(false);
+
+	/* On UTRAN */
+	btw("MS sends Authen Response, VLR accepts and sends SecurityModeControl");
+	expect_security_mode_ctrl(NULL, "1159ec926a50e98c034a6b7d7c9f418d");
+	ms_sends_msg("0554" "7db47cf7" "2104" "f81e4dc7"); /* 2nd vector's res, s.a. */
+	VERBOSE_ASSERT(security_mode_ctrl_sent, == true, "%d");
+	VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d");
+
+	btw("MS sends SecurityModeControl acceptance, VLR accepts; above Ciphering is an implicit CM Service Accept");
+	ms_sends_security_mode_complete();
+	VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d");
+
+	BTW("a call is initiated");
+
+	btw("SETUP gets forwarded to MNCC");
+	cc_to_mncc_expect_tx(IMSI, MNCC_SETUP_IND);
+	ms_sends_msg("0385" /* CC, seq = 2 -> 0x80 | CC Setup = 0x5 */
+		     "0406600402000581" /* 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 */
+		    );
+	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 */);
+	mncc_sends_to_cc(MNCC_CALL_PROC_REQ, &mncc);
+	OSMO_ASSERT(dtap_tx_confirmed);
+
+	btw("But the other side's MSISDN could not be resolved, MNCC tells us to cancel");
+	dtap_expect_tx("832d" /* CC: Release Request */);
+	mncc_sends_to_cc(MNCC_REL_REQ, &mncc);
+
+	dtap_expect_tx("832d" /* CC: Release Request */);
+	fake_time_passes(10, 23);
+
+	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);
+
+	rnc_sends_release_complete();
+	EXPECT_CONN_COUNT(0);
+	clear_vlr();
+	comment_end();
+}
+
+static void test_call_mo_to_unknown_timeout()
+{
+	struct gsm_mncc mncc = {
+		.imsi = IMSI,
+	};
+
+	comment_start();
+
+	fake_time_start();
+
+	standard_lu();
+
+	BTW("after a while, a new conn sends a CM Service Request. VLR responds with Auth Req, 2nd auth vector");
+	auth_request_sent = false;
+	auth_request_expect_rand = "c187a53a5e6b9d573cac7c74451fd46d";
+	auth_request_expect_autn = "1843a645b98d00005b2d666af46c45d9";
+	cm_service_result_sent = RES_NONE;
+	ms_sends_msg("052478"
+		     "03575886" /* classmark 2 */
+		     "089910070000106005" /* IMSI */);
+	OSMO_ASSERT(g_conn);
+	OSMO_ASSERT(g_conn->fi);
+	OSMO_ASSERT(g_conn->vsub);
+	VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d");
+	VERBOSE_ASSERT(auth_request_sent, == true, "%d");
+
+	btw("needs auth, not yet accepted");
+	EXPECT_ACCEPTED(false);
+
+	/* On UTRAN */
+	btw("MS sends Authen Response, VLR accepts and sends SecurityModeControl");
+	expect_security_mode_ctrl(NULL, "1159ec926a50e98c034a6b7d7c9f418d");
+	ms_sends_msg("0554" "7db47cf7" "2104" "f81e4dc7"); /* 2nd vector's res, s.a. */
+	VERBOSE_ASSERT(security_mode_ctrl_sent, == true, "%d");
+	VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d");
+
+	btw("MS sends SecurityModeControl acceptance, VLR accepts; above Ciphering is an implicit CM Service Accept");
+	ms_sends_security_mode_complete();
+	VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d");
+
+	BTW("a call is initiated");
+
+	btw("SETUP gets forwarded to MNCC");
+	cc_to_mncc_expect_tx(IMSI, MNCC_SETUP_IND);
+	ms_sends_msg("0385" /* CC, seq = 2 -> 0x80 | CC Setup = 0x5 */
+		     "0406600402000581" /* 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 */
+		    );
+	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 */);
+	mncc_sends_to_cc(MNCC_CALL_PROC_REQ, &mncc);
+	OSMO_ASSERT(dtap_tx_confirmed);
+
+	btw("But the other side's MSISDN could not be resolved, MNCC tells us to cancel");
+	dtap_expect_tx("832d" /* CC: Release Request */);
+	mncc_sends_to_cc(MNCC_REL_REQ, &mncc);
+
+	btw("Despite our repeated CC Release Requests, the MS does not respond anymore");
+	dtap_expect_tx("832d" /* CC: Release Request */);
+	fake_time_passes(10, 23);
+
+	btw("The CC Release times out and we still properly clear the conn");
+	cc_to_mncc_expect_tx("", MNCC_REL_CNF);
+	expect_iu_release();
+	fake_time_passes(10, 23);
+	OSMO_ASSERT(cc_to_mncc_tx_confirmed);
+	OSMO_ASSERT(iu_release_sent);
+
+	rnc_sends_release_complete();
+	EXPECT_CONN_COUNT(0);
+	clear_vlr();
+	comment_end();
+}
+
+
+msc_vlr_test_func_t msc_vlr_tests[] = {
+	test_call_mo,
+	test_call_mt,
+	test_call_mt2,
+	test_call_mo_to_unknown,
+	test_call_mo_to_unknown_timeout,
+	NULL
+};
diff --git a/tests/msc_vlr/msc_vlr_test_call.err b/tests/msc_vlr/msc_vlr_test_call.err
new file mode 100644
index 0000000..936f61c
--- /dev/null
+++ b/tests/msc_vlr/msc_vlr_test_call.err
@@ -0,0 +1,1831 @@
+full talloc report on 'msgb' (total      0 bytes in   1 blocks)
+talloc_total_blocks(tall_bsc_ctx) == 12
+
+===== test_call_mo
+- Total time passed: 0.000000 s
+- Location Update request causes a GSUP Send Auth Info request to HLR
+  MSC <--RAN_UTRAN_IU-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8)
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_NEW}: Updated ID
+DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000010650 type=NORMAL
+DMM LU/new-LAC: 23/23
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: Allocated
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: is child of Subscr_Conn(LU:901700000010650)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: rev=R99 net=UTRAN Auth+Ciph
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA
+DREF VLR subscr unknown usage increases to: 1
+DVLR set IMSI on subscriber; IMSI=901700000010650 id=901700000010650
+DVLR New subscr, IMSI: 901700000010650
+DREF VLR subscr IMSI:901700000010650 usage increases to: 2
+DREF VLR subscr IMSI:901700000010650 usage decreases to: 1
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Allocated
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(LU:901700000010650)
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
+DVLR GSUP tx: 08010809710000000156f0
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f0
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF IMSI:901700000010650: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  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: 0a010809710000000156f00362201039fa2f4e3d523d8619a73b4f65c3e14d21049b36efdf2208059a4f668f6fbe39231027497388b6cb044648f396aa155b95ef2410f64735036e5871319c679f4742a75ea125108704f5ba55f30000d2ee44b22c8ea9192708e229c19e791f2e4103622010c187a53a5e6b9d573cac7c74451fd46d210485aa31302208d3d50a000bf04f6e23101159ec926a50e98c034a6b7d7c9f418d2410df3a03d9ca5335641efc8e36d76cd20b25101843a645b98d00005b2d666af46c45d927087db47cf7f81e4dc703622010efa9c29a9742148d5c9070348716e1bb210469d5f9fb22083df176f0c29f1a3d2310eb50e770ddcc3060101d2f43b6c2b884241076542abce5ff9345b0e8947f4c6e019c2510f9375e6d41e1000096e7fe4ff1c27e392708706f996719ba609c03622010f023d5a3b24726e0631b64b3840f82532104d570c03f2208ec011be8919883d62310c4e58af4ba43f3bcd904e16984f086d724100593f65e752e5cb7f473862bda05aa0a2510541ff1f077270000c5ea00d658bc7e9a27083fd26072eaa2a04d036220102f8f90c780d6a9c0c53da7ac57b6707e2104b072446f220823f39f9f425ad6e6231065af0527fda95b0dc5ae4aa515cdf32f2410537c3b35a3b13b08d08eeb28098f45cc25104bf4e564f75300009bc796706bc6574427080edb0eadbea94ac2
+DVLR GSUP rx 511: 0a010809710000000156f00362201039fa2f4e3d523d8619a73b4f65c3e14d21049b36efdf2208059a4f668f6fbe39231027497388b6cb044648f396aa155b95ef2410f64735036e5871319c679f4742a75ea125108704f5ba55f30000d2ee44b22c8ea9192708e229c19e791f2e4103622010c187a53a5e6b9d573cac7c74451fd46d210485aa31302208d3d50a000bf04f6e23101159ec926a50e98c034a6b7d7c9f418d2410df3a03d9ca5335641efc8e36d76cd20b25101843a645b98d00005b2d666af46c45d927087db47cf7f81e4dc703622010efa9c29a9742148d5c9070348716e1bb210469d5f9fb22083df176f0c29f1a3d2310eb50e770ddcc3060101d2f43b6c2b884241076542abce5ff9345b0e8947f4c6e019c2510f9375e6d41e1000096e7fe4ff1c27e392708706f996719ba609c03622010f023d5a3b24726e0631b64b3840f82532104d570c03f2208ec011be8919883d62310c4e58af4ba43f3bcd904e16984f086d724100593f65e752e5cb7f473862bda05aa0a2510541ff1f077270000c5ea00d658bc7e9a27083fd26072eaa2a04d036220102f8f90c780d6a9c0c53da7ac57b6707e2104b072446f220823f39f9f425ad6e6231065af0527fda95b0dc5ae4aa515cdf32f2410537c3b35a3b13b08d08eeb28098f45cc25104bf4e564f75300009bc796706bc6574427080edb0eadbea94ac2
+DREF VLR subscr IMSI:901700000010650 usage increases to: 2
+DVLR VLR_Authenticate(LU:901700000010650){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(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: state_chg to VLR_SUB_AS_WAIT_RESP
+DVLR VLR_Authenticate(LU:901700000010650){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: tuple use_count=1 key_seq=0 auth_types=0x3 and...
+- ...rand=39fa2f4e3d523d8619a73b4f65c3e14d
+- ...autn=8704f5ba55f30000d2ee44b22c8ea919
+- ...expecting res=e229c19e791f2e41
+DREF VLR subscr IMSI:901700000010650 usage decreases to: 1
+<-- 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
+  MSC <--RAN_UTRAN_IU-- MS: GSM48_MT_MM_AUTH_RESP
+DREF IMSI:901700000010650: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14)
+DMM IMSI:901700000010650: MM UMTS AUTHENTICATION RESPONSE (res = e229c19e791f2e41)
+DVLR VLR_Authenticate(LU:901700000010650){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(LU:901700000010650){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result PASSED
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(LU:901700000010650)
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Freeing instance
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth()
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_AUTH}: Set Ciphering Mode
+DMM -> SECURITY MODE CONTROL IMSI:901700000010650
+- sending SecurityModeControl for UE ctx 42 send_ck=0 new_key=1
+- ...ik=27497388b6cb044648f396aa155b95ef
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_WAIT_CIPH
+DREF IMSI:901700000010650: MSC conn use - dtap == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  security_mode_ctrl_sent == 1
+  lu_result_sent == 0
+- MS sends SecurityModeControl acceptance, VLR accepts and sends GSUP LU Req to HLR
+DMM <- SECURITY MODE COMPLETE IMSI:901700000010650
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_CIPH}: Received Event VLR_ULA_E_CIPH_RES
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_CIPH}: vlr_loc_upd_post_ciph()
+DIUCS IMSI:901700000010650: tx CommonID 901700000010650
+- Iu Common ID --RAN_UTRAN_IU--> MS (IMSI=901700000010650)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_CIPH}: vlr_loc_upd_node_4()
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_CIPH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_INIT}: Allocated
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000010650)
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START
+DVLR GSUP tx: 04010809710000000156f0280102
+GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000000156f0280102
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){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: 10010809710000000156f00804032443f2
+DVLR GSUP rx 17: 10010809710000000156f00804032443f2
+DREF VLR subscr IMSI:901700000010650 usage increases to: 2
+DVLR IMSI:901700000010650 has MSISDN:42342
+DVLR SUBSCR(MSISDN:42342) VLR: update for IMSI=901700000010650 (MSISDN=42342, used=2)
+DVLR GSUP tx: 12010809710000000156f0
+GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000000156f0
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+<-- 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: 06010809710000000156f0
+DVLR GSUP rx 11: 06010809710000000156f0
+DREF VLR subscr MSISDN:42342 usage increases to: 2
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000010650)
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_DONE}: Freeing instance
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_INIT}: Allocated
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000010650)
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_INIT}: Allocated
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(LU:901700000010650)
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(LU:901700000010650)
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_DONE}: Freeing instance
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_DONE}: Deallocated
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_WAIT_SUB_PRES}: lu_compl_vlr_new_tmsi()
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_WAIT_TMSI_CNF
+- sending LU Accept for MSISDN:42342, with TMSI 0x03020100
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+<-- 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(&net->subscr_conns) == 1
+msc_subscr_conn_is_accepted() == false
+- MS sends TMSI Realloc Complete
+  MSC <--RAN_UTRAN_IU-- MS: GSM48_MT_MM_TMSI_REALL_COMPL
+DREF MSISDN:42342: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_TMSI_REALL_COMPL (0x5:0x1b)
+DMM TMSI Reallocation Completed. Subscriber: MSISDN:42342
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_NEW_TMSI_ACK
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_WAIT_TMSI_CNF}: Received Event LU_COMPL_VLR_E_NEW_TMSI_ACK
+DREF VLR subscr MSISDN:42342 usage increases to: 2
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_WAIT_TMSI_CNF}: state_chg to LU_COMPL_VLR_S_DONE
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000010650)
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_DONE}: Freeing instance
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_ACCEPTED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:42342: MSC conn use + release == 2 (0x102: dtap,release)
+DREF VLR subscr MSISDN:42342 usage increases to: 3
+DREF VLR subscr MSISDN:42342 usage decreases to: 2
+- Iu Release --RAN_UTRAN_IU--> MS
+DREF MSISDN:42342: MSC conn use - dtap == 1 (0x100: release)
+  iu_release_sent == 1
+- LU was successful, and the conn has already been closed
+- RNC sends Iu Release Complete
+DREF MSISDN:42342: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(LU:901700000010650)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: Freeing instance
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: Deallocated
+DRLL MSISDN:42342: Freeing subscriber connection
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+DREF VLR subscr MSISDN:42342 usage increases to: 2
+  vsub != NULL == 1
+  strcmp(vsub->imsi, IMSI) == 0
+  vsub->lac == 23
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+---
+- after a while, a new conn sends a CM Service Request. VLR responds with Auth Req, 2nd auth vector
+  MSC <--RAN_UTRAN_IU-- MS: GSM48_MT_MM_CM_SERV_REQ
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_CM_SERV_REQ (0x5:0x24)
+DMM <- CM SERVICE REQUEST serv_type=0x08 MI(IMSI)=901700000010650
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_NEW}: Updated ID
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: Allocated
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: is child of Subscr_Conn(CM_SERVICE_REQ:901700000010650)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: rev=R99 net=UTRAN Auth+Ciph
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START
+DREF VLR subscr MSISDN:42342 usage increases to: 2
+DREF VLR subscr MSISDN:42342 usage increases to: 3
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_WAIT_AUTH
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Allocated
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: is child of Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650)
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_WAIT_RESP
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){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 MSISDN:42342: tuple use_count=1 key_seq=1 auth_types=0x3 and...
+- ...rand=c187a53a5e6b9d573cac7c74451fd46d
+- ...autn=1843a645b98d00005b2d666af46c45d9
+- ...expecting res=7db47cf7f81e4dc7
+DREF VLR subscr MSISDN:42342 usage decreases to: 2
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF MSISDN:42342: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  cm_service_result_sent == 0
+  auth_request_sent == 1
+- needs auth, not yet accepted
+msc_subscr_conn_is_accepted() == false
+- MS sends Authen Response, VLR accepts and sends SecurityModeControl
+  MSC <--RAN_UTRAN_IU-- MS: GSM48_MT_MM_AUTH_RESP
+DREF MSISDN:42342: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14)
+DMM MSISDN:42342: MM UMTS AUTHENTICATION RESPONSE (res = 7db47cf7f81e4dc7)
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP
+DVLR SUBSCR(MSISDN:42342) AUTH on UTRAN received RES: 7db47cf7f81e4dc7 (8 bytes)
+DVLR SUBSCR(MSISDN:42342) AUTH established UMTS security context
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result PASSED
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Removing from parent Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650)
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Freeing instance
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Deallocated
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: Received Event PR_ARQ_E_AUTH_RES
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: Set Ciphering Mode
+DMM -> SECURITY MODE CONTROL MSISDN:42342
+- sending SecurityModeControl for UE ctx 42 send_ck=0 new_key=1
+- ...ik=1159ec926a50e98c034a6b7d7c9f418d
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: state_chg to PR_ARQ_S_WAIT_CIPH
+DREF MSISDN:42342: MSC conn use - dtap == 0 (0x0: )
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  security_mode_ctrl_sent == 1
+  cm_service_result_sent == 0
+- MS sends SecurityModeControl acceptance, VLR accepts; above Ciphering is an implicit CM Service Accept
+DMM <- SECURITY MODE COMPLETE MSISDN:42342
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_CIPH}: Received Event PR_ARQ_E_CIPH_RES
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_node2_post_ciph()
+DIUCS MSISDN:42342: tx CommonID 901700000010650
+- Iu Common ID --RAN_UTRAN_IU--> MS (IMSI=901700000010650)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_node2_post_vlr()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_pres()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_trace()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_imei()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_CIPH}: proc_arq_fsm_done(PASSED)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_CIPH}: state_chg to PR_ARQ_S_DONE
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_DONE}: Process Access Request result: PASSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_ACCEPTED
+DREF MSISDN:42342: MSC conn use + cm_service == 1 (0x8: cm_service)
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_ACCEPTED}: subscr_conn_fsm_has_active_transactions: still awaiting first request after a CM Service Request
+  cm_service_result_sent == 0
+---
+- a call is initiated
+- SETUP gets forwarded to MNCC
+  MSC <--RAN_UTRAN_IU-- MS: GSM48_MT_CC_SETUP
+DREF MSISDN:42342: MSC conn use + dtap == 2 (0xa: dtap,cm_service)
+DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5)
+DCC Unknown transaction ID 8, creating new trans.
+DCC (ti 08 sub MSISDN:42342 callref 80000001) New transaction
+DREF VLR subscr MSISDN:42342 usage increases to: 3
+DREF MSISDN:42342: MSC conn use + trans_cc == 3 (0x1a: dtap,cm_service,trans_cc)
+DMM MSISDN:42342: rx msg GSM48_MT_CC_SETUP: received_cm_service_request changes to false
+DREF MSISDN:42342: MSC conn use - cm_service == 2 (0x12: dtap,trans_cc)
+DCC (sub 42342) starting guard timer with 180 seconds
+DCC (ti 08 sub MSISDN:42342) new state NULL -> INITIATED
+DCC Subscriber MSISDN:42342 (42342) sends SETUP to 123
+DMNCC transmit message MNCC_SETUP_IND
+DCC Sending 'MNCC_SETUP_IND' to MNCC.
+  MSC --> MNCC: callref 0x80000001: MNCC_SETUP_IND
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_COMMUNICATING
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_COMMUNICATING
+DREF MSISDN:42342: MSC conn use - dtap == 1 (0x10: trans_cc)
+- MNCC says that's fine
+DMNCC receive message MNCC_CALL_PROC_REQ
+DCC (sub 42342) stopping pending guard timer
+DCC (sub 42342) starting guard timer with 180 seconds
+DCC (ti 08 sub 42342) Received 'MNCC_CALL_PROC_REQ' from MNCC in state 1 (INITIATED)
+DCC (ti 08 sub MSISDN:42342) new state INITIATED -> MO_CALL_PROC
+DMSC msc_tx 2 bytes to MSISDN:42342 via RAN_UTRAN_IU
+- DTAP --RAN_UTRAN_IU--> MS: GSM48_MT_CC_CALL_PROC: 8302
+- DTAP matches expected message
+  MS <--Call Assignment-- MSC: subscr=MSISDN:42342 callref=0x80000001
+- Total time passed: 1.000023 s
+- The other call leg got established (not shown here), MNCC tells us so
+DMNCC receive message MNCC_ALERT_REQ
+DCC (sub 42342) stopping pending guard timer
+DCC (sub 42342) starting guard timer with 180 seconds
+DCC (ti 08 sub 42342) Received 'MNCC_ALERT_REQ' from MNCC in state 3 (MO_CALL_PROC)
+DCC (ti 08 sub MSISDN:42342) new state MO_CALL_PROC -> CALL_DELIVERED
+DMSC msc_tx 2 bytes to MSISDN:42342 via RAN_UTRAN_IU
+- DTAP --RAN_UTRAN_IU--> MS: GSM48_MT_CC_ALERTING: 8301
+- DTAP matches expected message
+DMNCC receive message MNCC_SETUP_RSP
+DCC (sub 42342) stopping pending guard timer
+DCC (sub 42342) starting guard timer with 180 seconds
+DCC (ti 08 sub 42342) Received 'MNCC_SETUP_RSP' from MNCC in state 4 (CALL_DELIVERED)
+DCC starting timer T313 with 30 seconds
+DCC (ti 08 sub MSISDN:42342) new state CALL_DELIVERED -> CONNECT_IND
+DMSC msc_tx 2 bytes to MSISDN:42342 via RAN_UTRAN_IU
+- DTAP --RAN_UTRAN_IU--> MS: GSM48_MT_CC_CONNECT: 8307
+- DTAP matches expected message
+- Total time passed: 2.000046 s
+  MSC <--RAN_UTRAN_IU-- MS: GSM48_MT_CC_CONNECT_ACK
+DREF MSISDN:42342: MSC conn use + dtap == 2 (0x12: dtap,trans_cc)
+DRLL Dispatching 04.08 message GSM48_MT_CC_CONNECT_ACK (0x3:0xf)
+DCC stopping pending timer T313
+DCC (ti 08 sub MSISDN:42342) new state CONNECT_IND -> ACTIVE
+DCC (sub 42342) stopping pending guard timer
+DMNCC transmit message MNCC_SETUP_COMPL_IND
+DCC Sending 'MNCC_SETUP_COMPL_IND' to MNCC.
+  MSC --> MNCC: callref 0x80000001: MNCC_SETUP_COMPL_IND
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_COMMUNICATING}: Received Event SUBSCR_CONN_E_COMMUNICATING
+DREF MSISDN:42342: MSC conn use - dtap == 1 (0x10: trans_cc)
+---
+- RTP stream goes ahead, not shown here.
+- Total time passed: 125.000091 s
+---
+- Call ends
+  MSC <--RAN_UTRAN_IU-- MS: GSM48_MT_CC_DISCONNECT
+DREF MSISDN:42342: MSC conn use + dtap == 2 (0x12: dtap,trans_cc)
+DRLL Dispatching 04.08 message GSM48_MT_CC_DISCONNECT (0x3:0x25)
+DCC (ti 08 sub MSISDN:42342) new state ACTIVE -> DISCONNECT_IND
+DMNCC transmit message MNCC_DISC_IND
+DCC Sending 'MNCC_DISC_IND' to MNCC.
+  MSC --> MNCC: callref 0x80000001: MNCC_DISC_IND
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_COMMUNICATING}: Received Event SUBSCR_CONN_E_COMMUNICATING
+DREF MSISDN:42342: MSC conn use - dtap == 1 (0x10: trans_cc)
+DMNCC receive message MNCC_REL_REQ
+DCC (sub 42342) starting guard timer with 180 seconds
+DCC (ti 08 sub 42342) Received 'MNCC_REL_REQ' from MNCC in state 12 (DISCONNECT_IND)
+DCC starting timer T308 with 10 seconds
+DCC (ti 08 sub MSISDN:42342) new state DISCONNECT_IND -> RELEASE_REQ
+DMSC msc_tx 2 bytes to MSISDN:42342 via RAN_UTRAN_IU
+- DTAP --RAN_UTRAN_IU--> MS: GSM48_MT_CC_RELEASE: 832d
+- DTAP matches expected message
+  MSC <--RAN_UTRAN_IU-- MS: GSM48_MT_CC_RELEASE_COMPL
+DREF MSISDN:42342: MSC conn use + dtap == 2 (0x12: dtap,trans_cc)
+DRLL Dispatching 04.08 message GSM48_MT_CC_RELEASE_COMPL (0x3:0x2a)
+DCC stopping pending timer T308
+DMNCC transmit message MNCC_REL_CNF
+DCC Sending 'MNCC_REL_CNF' to MNCC.
+  MSC --> MNCC: callref 0x80000001: MNCC_REL_CNF
+  MS <--Call Release-- MSC: subscr=MSISDN:42342 callref=0x0
+DCC (ti 08 sub MSISDN:42342) new state RELEASE_REQ -> NULL
+DCC (sub 42342) stopping pending guard timer
+DREF VLR subscr MSISDN:42342 usage decreases to: 2
+DREF MSISDN:42342: MSC conn use - trans_cc == 1 (0x2: dtap)
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_COMMUNICATING}: Received Event SUBSCR_CONN_E_COMMUNICATING
+DREF MSISDN:42342: MSC conn use - dtap == 0 (0x0: )
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_COMMUNICATING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_COMMUNICATING}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:42342: MSC conn use + release == 1 (0x100: release)
+DREF VLR subscr MSISDN:42342 usage increases to: 3
+DREF VLR subscr MSISDN:42342 usage decreases to: 2
+- Iu Release --RAN_UTRAN_IU--> MS
+- RNC sends Iu Release Complete
+DREF MSISDN:42342: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_DONE}: Removing from parent Subscr_Conn(CM_SERVICE_REQ:901700000010650)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_DONE}: Freeing instance
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_DONE}: Deallocated
+DRLL MSISDN:42342: Freeing subscriber connection
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+DREF freeing VLR subscr MSISDN:42342
+===== test_call_mo: SUCCESS
+
+full talloc report on 'msgb' (total      0 bytes in   1 blocks)
+talloc_total_blocks(tall_bsc_ctx) == 12
+
+===== test_call_mt
+- Total time passed: 0.000000 s
+- Location Update request causes a GSUP Send Auth Info request to HLR
+  MSC <--RAN_UTRAN_IU-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8)
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_NEW}: Updated ID
+DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000010650 type=NORMAL
+DMM LU/new-LAC: 23/23
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: Allocated
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: is child of Subscr_Conn(LU:901700000010650)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: rev=R99 net=UTRAN Auth+Ciph
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA
+DREF VLR subscr unknown usage increases to: 1
+DVLR set IMSI on subscriber; IMSI=901700000010650 id=901700000010650
+DVLR New subscr, IMSI: 901700000010650
+DREF VLR subscr IMSI:901700000010650 usage increases to: 2
+DREF VLR subscr IMSI:901700000010650 usage decreases to: 1
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Allocated
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(LU:901700000010650)
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
+DVLR GSUP tx: 08010809710000000156f0
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f0
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF IMSI:901700000010650: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  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: 0a010809710000000156f00362201039fa2f4e3d523d8619a73b4f65c3e14d21049b36efdf2208059a4f668f6fbe39231027497388b6cb044648f396aa155b95ef2410f64735036e5871319c679f4742a75ea125108704f5ba55f30000d2ee44b22c8ea9192708e229c19e791f2e4103622010c187a53a5e6b9d573cac7c74451fd46d210485aa31302208d3d50a000bf04f6e23101159ec926a50e98c034a6b7d7c9f418d2410df3a03d9ca5335641efc8e36d76cd20b25101843a645b98d00005b2d666af46c45d927087db47cf7f81e4dc703622010efa9c29a9742148d5c9070348716e1bb210469d5f9fb22083df176f0c29f1a3d2310eb50e770ddcc3060101d2f43b6c2b884241076542abce5ff9345b0e8947f4c6e019c2510f9375e6d41e1000096e7fe4ff1c27e392708706f996719ba609c03622010f023d5a3b24726e0631b64b3840f82532104d570c03f2208ec011be8919883d62310c4e58af4ba43f3bcd904e16984f086d724100593f65e752e5cb7f473862bda05aa0a2510541ff1f077270000c5ea00d658bc7e9a27083fd26072eaa2a04d036220102f8f90c780d6a9c0c53da7ac57b6707e2104b072446f220823f39f9f425ad6e6231065af0527fda95b0dc5ae4aa515cdf32f2410537c3b35a3b13b08d08eeb28098f45cc25104bf4e564f75300009bc796706bc6574427080edb0eadbea94ac2
+DVLR GSUP rx 511: 0a010809710000000156f00362201039fa2f4e3d523d8619a73b4f65c3e14d21049b36efdf2208059a4f668f6fbe39231027497388b6cb044648f396aa155b95ef2410f64735036e5871319c679f4742a75ea125108704f5ba55f30000d2ee44b22c8ea9192708e229c19e791f2e4103622010c187a53a5e6b9d573cac7c74451fd46d210485aa31302208d3d50a000bf04f6e23101159ec926a50e98c034a6b7d7c9f418d2410df3a03d9ca5335641efc8e36d76cd20b25101843a645b98d00005b2d666af46c45d927087db47cf7f81e4dc703622010efa9c29a9742148d5c9070348716e1bb210469d5f9fb22083df176f0c29f1a3d2310eb50e770ddcc3060101d2f43b6c2b884241076542abce5ff9345b0e8947f4c6e019c2510f9375e6d41e1000096e7fe4ff1c27e392708706f996719ba609c03622010f023d5a3b24726e0631b64b3840f82532104d570c03f2208ec011be8919883d62310c4e58af4ba43f3bcd904e16984f086d724100593f65e752e5cb7f473862bda05aa0a2510541ff1f077270000c5ea00d658bc7e9a27083fd26072eaa2a04d036220102f8f90c780d6a9c0c53da7ac57b6707e2104b072446f220823f39f9f425ad6e6231065af0527fda95b0dc5ae4aa515cdf32f2410537c3b35a3b13b08d08eeb28098f45cc25104bf4e564f75300009bc796706bc6574427080edb0eadbea94ac2
+DREF VLR subscr IMSI:901700000010650 usage increases to: 2
+DVLR VLR_Authenticate(LU:901700000010650){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(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: state_chg to VLR_SUB_AS_WAIT_RESP
+DVLR VLR_Authenticate(LU:901700000010650){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: tuple use_count=1 key_seq=0 auth_types=0x3 and...
+- ...rand=39fa2f4e3d523d8619a73b4f65c3e14d
+- ...autn=8704f5ba55f30000d2ee44b22c8ea919
+- ...expecting res=e229c19e791f2e41
+DREF VLR subscr IMSI:901700000010650 usage decreases to: 1
+<-- 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
+  MSC <--RAN_UTRAN_IU-- MS: GSM48_MT_MM_AUTH_RESP
+DREF IMSI:901700000010650: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14)
+DMM IMSI:901700000010650: MM UMTS AUTHENTICATION RESPONSE (res = e229c19e791f2e41)
+DVLR VLR_Authenticate(LU:901700000010650){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(LU:901700000010650){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result PASSED
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(LU:901700000010650)
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Freeing instance
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth()
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_AUTH}: Set Ciphering Mode
+DMM -> SECURITY MODE CONTROL IMSI:901700000010650
+- sending SecurityModeControl for UE ctx 42 send_ck=0 new_key=1
+- ...ik=27497388b6cb044648f396aa155b95ef
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_WAIT_CIPH
+DREF IMSI:901700000010650: MSC conn use - dtap == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  security_mode_ctrl_sent == 1
+  lu_result_sent == 0
+- MS sends SecurityModeControl acceptance, VLR accepts and sends GSUP LU Req to HLR
+DMM <- SECURITY MODE COMPLETE IMSI:901700000010650
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_CIPH}: Received Event VLR_ULA_E_CIPH_RES
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_CIPH}: vlr_loc_upd_post_ciph()
+DIUCS IMSI:901700000010650: tx CommonID 901700000010650
+- Iu Common ID --RAN_UTRAN_IU--> MS (IMSI=901700000010650)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_CIPH}: vlr_loc_upd_node_4()
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_CIPH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_INIT}: Allocated
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000010650)
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START
+DVLR GSUP tx: 04010809710000000156f0280102
+GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000000156f0280102
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){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: 10010809710000000156f00804032443f2
+DVLR GSUP rx 17: 10010809710000000156f00804032443f2
+DREF VLR subscr IMSI:901700000010650 usage increases to: 2
+DVLR IMSI:901700000010650 has MSISDN:42342
+DVLR SUBSCR(MSISDN:42342) VLR: update for IMSI=901700000010650 (MSISDN=42342, used=2)
+DVLR GSUP tx: 12010809710000000156f0
+GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000000156f0
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+<-- 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: 06010809710000000156f0
+DVLR GSUP rx 11: 06010809710000000156f0
+DREF VLR subscr MSISDN:42342 usage increases to: 2
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000010650)
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_DONE}: Freeing instance
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_INIT}: Allocated
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000010650)
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_INIT}: Allocated
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(LU:901700000010650)
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(LU:901700000010650)
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_DONE}: Freeing instance
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_DONE}: Deallocated
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_WAIT_SUB_PRES}: lu_compl_vlr_new_tmsi()
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_WAIT_TMSI_CNF
+- sending LU Accept for MSISDN:42342, with TMSI 0x03020100
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+<-- 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(&net->subscr_conns) == 1
+msc_subscr_conn_is_accepted() == false
+- MS sends TMSI Realloc Complete
+  MSC <--RAN_UTRAN_IU-- MS: GSM48_MT_MM_TMSI_REALL_COMPL
+DREF MSISDN:42342: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_TMSI_REALL_COMPL (0x5:0x1b)
+DMM TMSI Reallocation Completed. Subscriber: MSISDN:42342
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_NEW_TMSI_ACK
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_WAIT_TMSI_CNF}: Received Event LU_COMPL_VLR_E_NEW_TMSI_ACK
+DREF VLR subscr MSISDN:42342 usage increases to: 2
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_WAIT_TMSI_CNF}: state_chg to LU_COMPL_VLR_S_DONE
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000010650)
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_DONE}: Freeing instance
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_ACCEPTED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:42342: MSC conn use + release == 2 (0x102: dtap,release)
+DREF VLR subscr MSISDN:42342 usage increases to: 3
+DREF VLR subscr MSISDN:42342 usage decreases to: 2
+- Iu Release --RAN_UTRAN_IU--> MS
+DREF MSISDN:42342: MSC conn use - dtap == 1 (0x100: release)
+  iu_release_sent == 1
+- LU was successful, and the conn has already been closed
+- RNC sends Iu Release Complete
+DREF MSISDN:42342: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(LU:901700000010650)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: Freeing instance
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: Deallocated
+DRLL MSISDN:42342: Freeing subscriber connection
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+DREF VLR subscr MSISDN:42342 usage increases to: 2
+  vsub != NULL == 1
+  strcmp(vsub->imsi, IMSI) == 0
+  vsub->lac == 23
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+---
+- after a while, MNCC asks us to setup a call, causing Paging
+DMNCC receive message MNCC_SETUP_REQ
+DREF VLR subscr MSISDN:42342 usage increases to: 2
+DCC (ti ff sub MSISDN:42342 callref 423) New transaction
+DREF VLR subscr MSISDN:42342 usage increases to: 3
+DMM Subscriber MSISDN:42342 not paged yet, start paging.
+  RAN_UTRAN_IU sends out paging request to IMSI 901700000010650, TMSI 0x03020100, LAC 23
+  strcmp(paging_expecting_imsi, imsi) == 0
+DREF VLR subscr MSISDN:42342 usage increases to: 4
+DREF VLR subscr MSISDN:42342 usage decreases to: 3
+  paging_sent == 1
+  paging_stopped == 0
+- MS replies with Paging Response, and VLR sends Auth Request
+  MSC <--RAN_UTRAN_IU-- MS: GSM48_MT_RR_PAG_RESP
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_RR_PAG_RESP (0x6:0x27)
+DRR PAGING RESPONSE: MI(IMSI)=901700000010650
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_NEW}: Updated ID
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_INIT}: Allocated
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_INIT}: is child of Subscr_Conn(PAGING_RESP:901700000010650)
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_INIT}: rev=R99 net=UTRAN Auth+Ciph
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START
+DREF VLR subscr MSISDN:42342 usage increases to: 4
+DREF VLR subscr MSISDN:42342 usage increases to: 5
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi()
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_WAIT_AUTH
+DVLR VLR_Authenticate(PAGING_RESP:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Allocated
+DVLR VLR_Authenticate(PAGING_RESP:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: is child of Process_Access_Request_VLR(PAGING_RESP:901700000010650)
+DVLR VLR_Authenticate(PAGING_RESP:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
+DVLR VLR_Authenticate(PAGING_RESP:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_WAIT_RESP
+DVLR VLR_Authenticate(PAGING_RESP:901700000010650){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 MSISDN:42342: tuple use_count=1 key_seq=1 auth_types=0x3 and...
+- ...rand=c187a53a5e6b9d573cac7c74451fd46d
+- ...autn=1843a645b98d00005b2d666af46c45d9
+- ...expecting res=7db47cf7f81e4dc7
+DREF VLR subscr MSISDN:42342 usage decreases to: 4
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF MSISDN:42342: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  auth_request_sent == 1
+- MS sends Authen Response, VLR accepts and sends SecurityModeControl
+  MSC <--RAN_UTRAN_IU-- MS: GSM48_MT_MM_AUTH_RESP
+DREF MSISDN:42342: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14)
+DMM MSISDN:42342: MM UMTS AUTHENTICATION RESPONSE (res = 7db47cf7f81e4dc7)
+DVLR VLR_Authenticate(PAGING_RESP:901700000010650){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP
+DVLR SUBSCR(MSISDN:42342) AUTH on UTRAN received RES: 7db47cf7f81e4dc7 (8 bytes)
+DVLR SUBSCR(MSISDN:42342) AUTH established UMTS security context
+DVLR VLR_Authenticate(PAGING_RESP:901700000010650){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result PASSED
+DVLR VLR_Authenticate(PAGING_RESP:901700000010650){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
+DVLR VLR_Authenticate(PAGING_RESP:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR VLR_Authenticate(PAGING_RESP:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Removing from parent Process_Access_Request_VLR(PAGING_RESP:901700000010650)
+DVLR VLR_Authenticate(PAGING_RESP:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Freeing instance
+DVLR VLR_Authenticate(PAGING_RESP:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Deallocated
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_WAIT_AUTH}: Received Event PR_ARQ_E_AUTH_RES
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2()
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_WAIT_AUTH}: Set Ciphering Mode
+DMM -> SECURITY MODE CONTROL MSISDN:42342
+- sending SecurityModeControl for UE ctx 42 send_ck=0 new_key=1
+- ...ik=1159ec926a50e98c034a6b7d7c9f418d
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_WAIT_AUTH}: state_chg to PR_ARQ_S_WAIT_CIPH
+DREF MSISDN:42342: MSC conn use - dtap == 0 (0x0: )
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  security_mode_ctrl_sent == 1
+- MS sends SecurityModeControl acceptance, VLR accepts, sends CC Setup
+DMM <- SECURITY MODE COMPLETE MSISDN:42342
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_WAIT_CIPH}: Received Event PR_ARQ_E_CIPH_RES
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_node2_post_ciph()
+DIUCS MSISDN:42342: tx CommonID 901700000010650
+- Iu Common ID --RAN_UTRAN_IU--> MS (IMSI=901700000010650)
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_node2_post_vlr()
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_pres()
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_trace()
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_imei()
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_WAIT_CIPH}: proc_arq_fsm_done(PASSED)
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_WAIT_CIPH}: state_chg to PR_ARQ_S_DONE
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_DONE}: Process Access Request result: PASSED
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_ACCEPTED
+DPAG Paging success for MSISDN:42342 (event=0)
+DPAG Calling paging cbfn.
+DCC Paging subscr 42342 succeeded!
+DREF MSISDN:42342: MSC conn use + trans_cc == 1 (0x10: trans_cc)
+DCC starting timer T303 with 30 seconds
+DCC (ti 00 sub MSISDN:42342) new state NULL -> CALL_PRESENT
+DMSC msc_tx 2 bytes to MSISDN:42342 via RAN_UTRAN_IU
+- DTAP --RAN_UTRAN_IU--> MS: GSM48_MT_CC_SETUP: 0305
+- DTAP matches expected message
+DREF VLR subscr MSISDN:42342 usage decreases to: 3
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_ACCEPTED}: subscr_conn_fsm_has_active_transactions: connection still has active transaction: CC
+  paging_stopped == 1
+  MSC <--RAN_UTRAN_IU-- MS: GSM48_MT_CC_CALL_CONF
+DREF MSISDN:42342: MSC conn use + dtap == 2 (0x12: dtap,trans_cc)
+DRLL Dispatching 04.08 message GSM48_MT_CC_CALL_CONF (0x3:0x8)
+DCC stopping pending timer T303
+DCC starting timer T310 with 30 seconds
+DCC (ti 00 sub MSISDN:42342) new state CALL_PRESENT -> MO_TERM_CALL_CONF
+  MS <--Call Assignment-- MSC: subscr=MSISDN:42342 callref=0x423
+DMNCC transmit message MNCC_CALL_CONF_IND
+DCC Sending 'MNCC_CALL_CONF_IND' to MNCC.
+  MSC --> MNCC: callref 0x423: MNCC_CALL_CONF_IND
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_COMMUNICATING
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_COMMUNICATING
+DREF MSISDN:42342: MSC conn use - dtap == 1 (0x10: trans_cc)
+- Total time passed: 1.000023 s
+  MSC <--RAN_UTRAN_IU-- MS: GSM48_MT_CC_ALERTING
+DREF MSISDN:42342: MSC conn use + dtap == 2 (0x12: dtap,trans_cc)
+DRLL Dispatching 04.08 message GSM48_MT_CC_ALERTING (0x3:0x1)
+DCC stopping pending timer T310
+DCC starting timer T301 with 180 seconds
+DCC (ti 00 sub MSISDN:42342) new state MO_TERM_CALL_CONF -> CALL_RECEIVED
+DMNCC transmit message MNCC_ALERT_IND
+DCC Sending 'MNCC_ALERT_IND' to MNCC.
+  MSC --> MNCC: callref 0x423: MNCC_ALERT_IND
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_COMMUNICATING}: Received Event SUBSCR_CONN_E_COMMUNICATING
+DREF MSISDN:42342: MSC conn use - dtap == 1 (0x10: trans_cc)
+- Total time passed: 2.000046 s
+  MSC <--RAN_UTRAN_IU-- MS: GSM48_MT_CC_CONNECT
+DREF MSISDN:42342: MSC conn use + dtap == 2 (0x12: dtap,trans_cc)
+DRLL Dispatching 04.08 message GSM48_MT_CC_CONNECT (0x3:0x7)
+DCC stopping pending timer T301
+DCC (ti 00 sub MSISDN:42342) new state CALL_RECEIVED -> CONNECT_REQUEST
+DMNCC transmit message MNCC_SETUP_CNF
+DCC Sending 'MNCC_SETUP_CNF' to MNCC.
+  MSC --> MNCC: callref 0x423: MNCC_SETUP_CNF
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_COMMUNICATING}: Received Event SUBSCR_CONN_E_COMMUNICATING
+DREF MSISDN:42342: MSC conn use - dtap == 1 (0x10: trans_cc)
+DMNCC receive message MNCC_SETUP_COMPL_REQ
+DCC (sub 42342) starting guard timer with 180 seconds
+DCC (ti 00 sub 42342) Received 'MNCC_SETUP_COMPL_REQ' from MNCC in state 8 (CONNECT_REQUEST)
+DCC (ti 00 sub MSISDN:42342) new state CONNECT_REQUEST -> ACTIVE
+DCC (sub 42342) stopping pending guard timer
+DMSC msc_tx 2 bytes to MSISDN:42342 via RAN_UTRAN_IU
+- DTAP --RAN_UTRAN_IU--> MS: GSM48_MT_CC_CONNECT_ACK: 030f
+- DTAP matches expected message
+---
+- RTP stream goes ahead, not shown here.
+- Total time passed: 125.000091 s
+---
+- Call ends
+  MSC <--RAN_UTRAN_IU-- MS: GSM48_MT_CC_DISCONNECT
+DREF MSISDN:42342: MSC conn use + dtap == 2 (0x12: dtap,trans_cc)
+DRLL Dispatching 04.08 message GSM48_MT_CC_DISCONNECT (0x3:0x25)
+DCC (ti 00 sub MSISDN:42342) new state ACTIVE -> DISCONNECT_IND
+DMNCC transmit message MNCC_DISC_IND
+DCC Sending 'MNCC_DISC_IND' to MNCC.
+  MSC --> MNCC: callref 0x423: MNCC_DISC_IND
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_COMMUNICATING}: Received Event SUBSCR_CONN_E_COMMUNICATING
+DREF MSISDN:42342: MSC conn use - dtap == 1 (0x10: trans_cc)
+DMNCC receive message MNCC_REL_REQ
+DCC (sub 42342) starting guard timer with 180 seconds
+DCC (ti 00 sub 42342) Received 'MNCC_REL_REQ' from MNCC in state 12 (DISCONNECT_IND)
+DCC starting timer T308 with 10 seconds
+DCC (ti 00 sub MSISDN:42342) new state DISCONNECT_IND -> RELEASE_REQ
+DMSC msc_tx 2 bytes to MSISDN:42342 via RAN_UTRAN_IU
+- DTAP --RAN_UTRAN_IU--> MS: GSM48_MT_CC_RELEASE: 032d
+- DTAP matches expected message
+  MSC <--RAN_UTRAN_IU-- MS: GSM48_MT_CC_RELEASE_COMPL
+DREF MSISDN:42342: MSC conn use + dtap == 2 (0x12: dtap,trans_cc)
+DRLL Dispatching 04.08 message GSM48_MT_CC_RELEASE_COMPL (0x3:0x2a)
+DCC stopping pending timer T308
+DMNCC transmit message MNCC_REL_CNF
+DCC Sending 'MNCC_REL_CNF' to MNCC.
+  MSC --> MNCC: callref 0x423: MNCC_REL_CNF
+  MS <--Call Release-- MSC: subscr=MSISDN:42342 callref=0x0
+DCC (ti 00 sub MSISDN:42342) new state RELEASE_REQ -> NULL
+DCC (sub 42342) stopping pending guard timer
+DREF VLR subscr MSISDN:42342 usage decreases to: 2
+DREF MSISDN:42342: MSC conn use - trans_cc == 1 (0x2: dtap)
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_COMMUNICATING}: Received Event SUBSCR_CONN_E_COMMUNICATING
+DREF MSISDN:42342: MSC conn use - dtap == 0 (0x0: )
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_COMMUNICATING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_COMMUNICATING}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:42342: MSC conn use + release == 1 (0x100: release)
+DREF VLR subscr MSISDN:42342 usage increases to: 3
+DREF VLR subscr MSISDN:42342 usage decreases to: 2
+- Iu Release --RAN_UTRAN_IU--> MS
+- RNC sends Iu Release Complete
+DREF MSISDN:42342: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_DONE}: Removing from parent Subscr_Conn(PAGING_RESP:901700000010650)
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_DONE}: Freeing instance
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_DONE}: Deallocated
+DRLL MSISDN:42342: Freeing subscriber connection
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+DREF freeing VLR subscr MSISDN:42342
+===== test_call_mt: SUCCESS
+
+full talloc report on 'msgb' (total      0 bytes in   1 blocks)
+talloc_total_blocks(tall_bsc_ctx) == 12
+
+===== test_call_mt2
+- Total time passed: 0.000000 s
+- Location Update request causes a GSUP Send Auth Info request to HLR
+  MSC <--RAN_UTRAN_IU-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8)
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_NEW}: Updated ID
+DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000010650 type=NORMAL
+DMM LU/new-LAC: 23/23
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: Allocated
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: is child of Subscr_Conn(LU:901700000010650)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: rev=R99 net=UTRAN Auth+Ciph
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA
+DREF VLR subscr unknown usage increases to: 1
+DVLR set IMSI on subscriber; IMSI=901700000010650 id=901700000010650
+DVLR New subscr, IMSI: 901700000010650
+DREF VLR subscr IMSI:901700000010650 usage increases to: 2
+DREF VLR subscr IMSI:901700000010650 usage decreases to: 1
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Allocated
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(LU:901700000010650)
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
+DVLR GSUP tx: 08010809710000000156f0
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f0
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF IMSI:901700000010650: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  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: 0a010809710000000156f00362201039fa2f4e3d523d8619a73b4f65c3e14d21049b36efdf2208059a4f668f6fbe39231027497388b6cb044648f396aa155b95ef2410f64735036e5871319c679f4742a75ea125108704f5ba55f30000d2ee44b22c8ea9192708e229c19e791f2e4103622010c187a53a5e6b9d573cac7c74451fd46d210485aa31302208d3d50a000bf04f6e23101159ec926a50e98c034a6b7d7c9f418d2410df3a03d9ca5335641efc8e36d76cd20b25101843a645b98d00005b2d666af46c45d927087db47cf7f81e4dc703622010efa9c29a9742148d5c9070348716e1bb210469d5f9fb22083df176f0c29f1a3d2310eb50e770ddcc3060101d2f43b6c2b884241076542abce5ff9345b0e8947f4c6e019c2510f9375e6d41e1000096e7fe4ff1c27e392708706f996719ba609c03622010f023d5a3b24726e0631b64b3840f82532104d570c03f2208ec011be8919883d62310c4e58af4ba43f3bcd904e16984f086d724100593f65e752e5cb7f473862bda05aa0a2510541ff1f077270000c5ea00d658bc7e9a27083fd26072eaa2a04d036220102f8f90c780d6a9c0c53da7ac57b6707e2104b072446f220823f39f9f425ad6e6231065af0527fda95b0dc5ae4aa515cdf32f2410537c3b35a3b13b08d08eeb28098f45cc25104bf4e564f75300009bc796706bc6574427080edb0eadbea94ac2
+DVLR GSUP rx 511: 0a010809710000000156f00362201039fa2f4e3d523d8619a73b4f65c3e14d21049b36efdf2208059a4f668f6fbe39231027497388b6cb044648f396aa155b95ef2410f64735036e5871319c679f4742a75ea125108704f5ba55f30000d2ee44b22c8ea9192708e229c19e791f2e4103622010c187a53a5e6b9d573cac7c74451fd46d210485aa31302208d3d50a000bf04f6e23101159ec926a50e98c034a6b7d7c9f418d2410df3a03d9ca5335641efc8e36d76cd20b25101843a645b98d00005b2d666af46c45d927087db47cf7f81e4dc703622010efa9c29a9742148d5c9070348716e1bb210469d5f9fb22083df176f0c29f1a3d2310eb50e770ddcc3060101d2f43b6c2b884241076542abce5ff9345b0e8947f4c6e019c2510f9375e6d41e1000096e7fe4ff1c27e392708706f996719ba609c03622010f023d5a3b24726e0631b64b3840f82532104d570c03f2208ec011be8919883d62310c4e58af4ba43f3bcd904e16984f086d724100593f65e752e5cb7f473862bda05aa0a2510541ff1f077270000c5ea00d658bc7e9a27083fd26072eaa2a04d036220102f8f90c780d6a9c0c53da7ac57b6707e2104b072446f220823f39f9f425ad6e6231065af0527fda95b0dc5ae4aa515cdf32f2410537c3b35a3b13b08d08eeb28098f45cc25104bf4e564f75300009bc796706bc6574427080edb0eadbea94ac2
+DREF VLR subscr IMSI:901700000010650 usage increases to: 2
+DVLR VLR_Authenticate(LU:901700000010650){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(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: state_chg to VLR_SUB_AS_WAIT_RESP
+DVLR VLR_Authenticate(LU:901700000010650){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: tuple use_count=1 key_seq=0 auth_types=0x3 and...
+- ...rand=39fa2f4e3d523d8619a73b4f65c3e14d
+- ...autn=8704f5ba55f30000d2ee44b22c8ea919
+- ...expecting res=e229c19e791f2e41
+DREF VLR subscr IMSI:901700000010650 usage decreases to: 1
+<-- 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
+  MSC <--RAN_UTRAN_IU-- MS: GSM48_MT_MM_AUTH_RESP
+DREF IMSI:901700000010650: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14)
+DMM IMSI:901700000010650: MM UMTS AUTHENTICATION RESPONSE (res = e229c19e791f2e41)
+DVLR VLR_Authenticate(LU:901700000010650){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(LU:901700000010650){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result PASSED
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(LU:901700000010650)
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Freeing instance
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth()
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_AUTH}: Set Ciphering Mode
+DMM -> SECURITY MODE CONTROL IMSI:901700000010650
+- sending SecurityModeControl for UE ctx 42 send_ck=0 new_key=1
+- ...ik=27497388b6cb044648f396aa155b95ef
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_WAIT_CIPH
+DREF IMSI:901700000010650: MSC conn use - dtap == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  security_mode_ctrl_sent == 1
+  lu_result_sent == 0
+- MS sends SecurityModeControl acceptance, VLR accepts and sends GSUP LU Req to HLR
+DMM <- SECURITY MODE COMPLETE IMSI:901700000010650
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_CIPH}: Received Event VLR_ULA_E_CIPH_RES
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_CIPH}: vlr_loc_upd_post_ciph()
+DIUCS IMSI:901700000010650: tx CommonID 901700000010650
+- Iu Common ID --RAN_UTRAN_IU--> MS (IMSI=901700000010650)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_CIPH}: vlr_loc_upd_node_4()
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_CIPH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_INIT}: Allocated
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000010650)
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START
+DVLR GSUP tx: 04010809710000000156f0280102
+GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000000156f0280102
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){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: 10010809710000000156f00804032443f2
+DVLR GSUP rx 17: 10010809710000000156f00804032443f2
+DREF VLR subscr IMSI:901700000010650 usage increases to: 2
+DVLR IMSI:901700000010650 has MSISDN:42342
+DVLR SUBSCR(MSISDN:42342) VLR: update for IMSI=901700000010650 (MSISDN=42342, used=2)
+DVLR GSUP tx: 12010809710000000156f0
+GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000000156f0
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+<-- 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: 06010809710000000156f0
+DVLR GSUP rx 11: 06010809710000000156f0
+DREF VLR subscr MSISDN:42342 usage increases to: 2
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000010650)
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_DONE}: Freeing instance
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_INIT}: Allocated
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000010650)
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_INIT}: Allocated
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(LU:901700000010650)
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(LU:901700000010650)
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_DONE}: Freeing instance
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_DONE}: Deallocated
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_WAIT_SUB_PRES}: lu_compl_vlr_new_tmsi()
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_WAIT_TMSI_CNF
+- sending LU Accept for MSISDN:42342, with TMSI 0x03020100
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+<-- 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(&net->subscr_conns) == 1
+msc_subscr_conn_is_accepted() == false
+- MS sends TMSI Realloc Complete
+  MSC <--RAN_UTRAN_IU-- MS: GSM48_MT_MM_TMSI_REALL_COMPL
+DREF MSISDN:42342: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_TMSI_REALL_COMPL (0x5:0x1b)
+DMM TMSI Reallocation Completed. Subscriber: MSISDN:42342
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_NEW_TMSI_ACK
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_WAIT_TMSI_CNF}: Received Event LU_COMPL_VLR_E_NEW_TMSI_ACK
+DREF VLR subscr MSISDN:42342 usage increases to: 2
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_WAIT_TMSI_CNF}: state_chg to LU_COMPL_VLR_S_DONE
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000010650)
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_DONE}: Freeing instance
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_ACCEPTED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:42342: MSC conn use + release == 2 (0x102: dtap,release)
+DREF VLR subscr MSISDN:42342 usage increases to: 3
+DREF VLR subscr MSISDN:42342 usage decreases to: 2
+- Iu Release --RAN_UTRAN_IU--> MS
+DREF MSISDN:42342: MSC conn use - dtap == 1 (0x100: release)
+  iu_release_sent == 1
+- LU was successful, and the conn has already been closed
+- RNC sends Iu Release Complete
+DREF MSISDN:42342: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(LU:901700000010650)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: Freeing instance
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: Deallocated
+DRLL MSISDN:42342: Freeing subscriber connection
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+DREF VLR subscr MSISDN:42342 usage increases to: 2
+  vsub != NULL == 1
+  strcmp(vsub->imsi, IMSI) == 0
+  vsub->lac == 23
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+---
+- after a while, MNCC asks us to setup a call, causing Paging
+DMNCC receive message MNCC_SETUP_REQ
+DREF VLR subscr MSISDN:42342 usage increases to: 2
+DCC (ti ff sub MSISDN:42342 callref 423) New transaction
+DREF VLR subscr MSISDN:42342 usage increases to: 3
+DMM Subscriber MSISDN:42342 not paged yet, start paging.
+  RAN_UTRAN_IU sends out paging request to IMSI 901700000010650, TMSI 0x03020100, LAC 23
+  strcmp(paging_expecting_imsi, imsi) == 0
+DREF VLR subscr MSISDN:42342 usage increases to: 4
+DREF VLR subscr MSISDN:42342 usage decreases to: 3
+  paging_sent == 1
+  paging_stopped == 0
+- MS replies with Paging Response, and VLR sends Auth Request
+  MSC <--RAN_UTRAN_IU-- MS: GSM48_MT_RR_PAG_RESP
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_RR_PAG_RESP (0x6:0x27)
+DRR PAGING RESPONSE: MI(IMSI)=901700000010650
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_NEW}: Updated ID
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_INIT}: Allocated
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_INIT}: is child of Subscr_Conn(PAGING_RESP:901700000010650)
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_INIT}: rev=R99 net=UTRAN Auth+Ciph
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START
+DREF VLR subscr MSISDN:42342 usage increases to: 4
+DREF VLR subscr MSISDN:42342 usage increases to: 5
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi()
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_WAIT_AUTH
+DVLR VLR_Authenticate(PAGING_RESP:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Allocated
+DVLR VLR_Authenticate(PAGING_RESP:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: is child of Process_Access_Request_VLR(PAGING_RESP:901700000010650)
+DVLR VLR_Authenticate(PAGING_RESP:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
+DVLR VLR_Authenticate(PAGING_RESP:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_WAIT_RESP
+DVLR VLR_Authenticate(PAGING_RESP:901700000010650){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 MSISDN:42342: tuple use_count=1 key_seq=1 auth_types=0x3 and...
+- ...rand=c187a53a5e6b9d573cac7c74451fd46d
+- ...autn=1843a645b98d00005b2d666af46c45d9
+- ...expecting res=7db47cf7f81e4dc7
+DREF VLR subscr MSISDN:42342 usage decreases to: 4
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF MSISDN:42342: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  auth_request_sent == 1
+- MS sends Authen Response, VLR accepts and sends SecurityModeControl
+  MSC <--RAN_UTRAN_IU-- MS: GSM48_MT_MM_AUTH_RESP
+DREF MSISDN:42342: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14)
+DMM MSISDN:42342: MM UMTS AUTHENTICATION RESPONSE (res = 7db47cf7f81e4dc7)
+DVLR VLR_Authenticate(PAGING_RESP:901700000010650){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP
+DVLR SUBSCR(MSISDN:42342) AUTH on UTRAN received RES: 7db47cf7f81e4dc7 (8 bytes)
+DVLR SUBSCR(MSISDN:42342) AUTH established UMTS security context
+DVLR VLR_Authenticate(PAGING_RESP:901700000010650){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result PASSED
+DVLR VLR_Authenticate(PAGING_RESP:901700000010650){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
+DVLR VLR_Authenticate(PAGING_RESP:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR VLR_Authenticate(PAGING_RESP:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Removing from parent Process_Access_Request_VLR(PAGING_RESP:901700000010650)
+DVLR VLR_Authenticate(PAGING_RESP:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Freeing instance
+DVLR VLR_Authenticate(PAGING_RESP:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Deallocated
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_WAIT_AUTH}: Received Event PR_ARQ_E_AUTH_RES
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2()
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_WAIT_AUTH}: Set Ciphering Mode
+DMM -> SECURITY MODE CONTROL MSISDN:42342
+- sending SecurityModeControl for UE ctx 42 send_ck=0 new_key=1
+- ...ik=1159ec926a50e98c034a6b7d7c9f418d
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_WAIT_AUTH}: state_chg to PR_ARQ_S_WAIT_CIPH
+DREF MSISDN:42342: MSC conn use - dtap == 0 (0x0: )
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  security_mode_ctrl_sent == 1
+- MS sends SecurityModeControl acceptance, VLR accepts, sends CC Setup
+DMM <- SECURITY MODE COMPLETE MSISDN:42342
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_WAIT_CIPH}: Received Event PR_ARQ_E_CIPH_RES
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_node2_post_ciph()
+DIUCS MSISDN:42342: tx CommonID 901700000010650
+- Iu Common ID --RAN_UTRAN_IU--> MS (IMSI=901700000010650)
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_node2_post_vlr()
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_pres()
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_trace()
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_imei()
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_WAIT_CIPH}: proc_arq_fsm_done(PASSED)
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_WAIT_CIPH}: state_chg to PR_ARQ_S_DONE
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_DONE}: Process Access Request result: PASSED
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_ACCEPTED
+DPAG Paging success for MSISDN:42342 (event=0)
+DPAG Calling paging cbfn.
+DCC Paging subscr 42342 succeeded!
+DREF MSISDN:42342: MSC conn use + trans_cc == 1 (0x10: trans_cc)
+DCC starting timer T303 with 30 seconds
+DCC (ti 00 sub MSISDN:42342) new state NULL -> CALL_PRESENT
+DMSC msc_tx 2 bytes to MSISDN:42342 via RAN_UTRAN_IU
+- DTAP --RAN_UTRAN_IU--> MS: GSM48_MT_CC_SETUP: 0305
+- DTAP matches expected message
+DREF VLR subscr MSISDN:42342 usage decreases to: 3
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_ACCEPTED}: subscr_conn_fsm_has_active_transactions: connection still has active transaction: CC
+  paging_stopped == 1
+  MSC <--RAN_UTRAN_IU-- MS: GSM48_MT_CC_CALL_CONF
+DREF MSISDN:42342: MSC conn use + dtap == 2 (0x12: dtap,trans_cc)
+DRLL Dispatching 04.08 message GSM48_MT_CC_CALL_CONF (0x3:0x8)
+DCC stopping pending timer T303
+DCC starting timer T310 with 30 seconds
+DCC (ti 00 sub MSISDN:42342) new state CALL_PRESENT -> MO_TERM_CALL_CONF
+  MS <--Call Assignment-- MSC: subscr=MSISDN:42342 callref=0x423
+DMNCC transmit message MNCC_CALL_CONF_IND
+DCC Sending 'MNCC_CALL_CONF_IND' to MNCC.
+  MSC --> MNCC: callref 0x423: MNCC_CALL_CONF_IND
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_COMMUNICATING
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_COMMUNICATING
+DREF MSISDN:42342: MSC conn use - dtap == 1 (0x10: trans_cc)
+- Total time passed: 1.000023 s
+  MSC <--RAN_UTRAN_IU-- MS: GSM48_MT_CC_ALERTING
+DREF MSISDN:42342: MSC conn use + dtap == 2 (0x12: dtap,trans_cc)
+DRLL Dispatching 04.08 message GSM48_MT_CC_ALERTING (0x3:0x1)
+DCC stopping pending timer T310
+DCC starting timer T301 with 180 seconds
+DCC (ti 00 sub MSISDN:42342) new state MO_TERM_CALL_CONF -> CALL_RECEIVED
+DMNCC transmit message MNCC_ALERT_IND
+DCC Sending 'MNCC_ALERT_IND' to MNCC.
+  MSC --> MNCC: callref 0x423: MNCC_ALERT_IND
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_COMMUNICATING}: Received Event SUBSCR_CONN_E_COMMUNICATING
+DREF MSISDN:42342: MSC conn use - dtap == 1 (0x10: trans_cc)
+- Total time passed: 16.000046 s
+- The call failed, the BSC sends a BSSMAP Clear Request
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_COMMUNICATING}: Received Event SUBSCR_CONN_E_CN_CLOSE
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_COMMUNICATING}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:42342: MSC conn use + release == 2 (0x110: trans_cc,release)
+DREF VLR subscr MSISDN:42342 usage increases to: 4
+DREF VLR subscr MSISDN:42342 usage decreases to: 3
+DCC stopping pending timer T301
+  MS <--Call Release-- MSC: subscr=MSISDN:42342 callref=0x423
+DMNCC receive message MNCC_REL_REQ
+DCC (sub 42342) starting guard timer with 180 seconds
+DCC (ti 00 sub 42342) Received 'MNCC_REL_REQ' from MNCC in state 7 (CALL_RECEIVED)
+DCC starting timer T308 with 10 seconds
+DCC (ti 00 sub MSISDN:42342) new state CALL_RECEIVED -> RELEASE_REQ
+DMSC msc_tx 2 bytes to MSISDN:42342 via RAN_UTRAN_IU
+- DTAP --RAN_UTRAN_IU--> MS: GSM48_MT_CC_RELEASE: 032d
+- DTAP matches expected message
+DMNCC transmit message MNCC_REL_CNF
+DCC Sending 'MNCC_REL_CNF' to MNCC.
+  MSC --> MNCC: callref 0x423: MNCC_REL_CNF
+DCC stopping pending timer T308
+DCC (ti 00 sub MSISDN:42342) new state RELEASE_REQ -> NULL
+DCC (sub 42342) stopping pending guard timer
+DREF VLR subscr MSISDN:42342 usage decreases to: 2
+DREF MSISDN:42342: MSC conn use - trans_cc == 1 (0x100: release)
+- Iu Release --RAN_UTRAN_IU--> MS
+- RNC sends Iu Release Complete
+DREF MSISDN:42342: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_DONE}: Removing from parent Subscr_Conn(PAGING_RESP:901700000010650)
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_DONE}: Freeing instance
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_DONE}: Deallocated
+DRLL MSISDN:42342: Freeing subscriber connection
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+- Total time passed: 31.000069 s
+DREF freeing VLR subscr MSISDN:42342
+===== test_call_mt2: SUCCESS
+
+full talloc report on 'msgb' (total      0 bytes in   1 blocks)
+talloc_total_blocks(tall_bsc_ctx) == 12
+
+===== test_call_mo_to_unknown
+- Total time passed: 0.000000 s
+- Location Update request causes a GSUP Send Auth Info request to HLR
+  MSC <--RAN_UTRAN_IU-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8)
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_NEW}: Updated ID
+DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000010650 type=NORMAL
+DMM LU/new-LAC: 23/23
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: Allocated
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: is child of Subscr_Conn(LU:901700000010650)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: rev=R99 net=UTRAN Auth+Ciph
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA
+DREF VLR subscr unknown usage increases to: 1
+DVLR set IMSI on subscriber; IMSI=901700000010650 id=901700000010650
+DVLR New subscr, IMSI: 901700000010650
+DREF VLR subscr IMSI:901700000010650 usage increases to: 2
+DREF VLR subscr IMSI:901700000010650 usage decreases to: 1
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Allocated
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(LU:901700000010650)
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
+DVLR GSUP tx: 08010809710000000156f0
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f0
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF IMSI:901700000010650: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  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: 0a010809710000000156f00362201039fa2f4e3d523d8619a73b4f65c3e14d21049b36efdf2208059a4f668f6fbe39231027497388b6cb044648f396aa155b95ef2410f64735036e5871319c679f4742a75ea125108704f5ba55f30000d2ee44b22c8ea9192708e229c19e791f2e4103622010c187a53a5e6b9d573cac7c74451fd46d210485aa31302208d3d50a000bf04f6e23101159ec926a50e98c034a6b7d7c9f418d2410df3a03d9ca5335641efc8e36d76cd20b25101843a645b98d00005b2d666af46c45d927087db47cf7f81e4dc703622010efa9c29a9742148d5c9070348716e1bb210469d5f9fb22083df176f0c29f1a3d2310eb50e770ddcc3060101d2f43b6c2b884241076542abce5ff9345b0e8947f4c6e019c2510f9375e6d41e1000096e7fe4ff1c27e392708706f996719ba609c03622010f023d5a3b24726e0631b64b3840f82532104d570c03f2208ec011be8919883d62310c4e58af4ba43f3bcd904e16984f086d724100593f65e752e5cb7f473862bda05aa0a2510541ff1f077270000c5ea00d658bc7e9a27083fd26072eaa2a04d036220102f8f90c780d6a9c0c53da7ac57b6707e2104b072446f220823f39f9f425ad6e6231065af0527fda95b0dc5ae4aa515cdf32f2410537c3b35a3b13b08d08eeb28098f45cc25104bf4e564f75300009bc796706bc6574427080edb0eadbea94ac2
+DVLR GSUP rx 511: 0a010809710000000156f00362201039fa2f4e3d523d8619a73b4f65c3e14d21049b36efdf2208059a4f668f6fbe39231027497388b6cb044648f396aa155b95ef2410f64735036e5871319c679f4742a75ea125108704f5ba55f30000d2ee44b22c8ea9192708e229c19e791f2e4103622010c187a53a5e6b9d573cac7c74451fd46d210485aa31302208d3d50a000bf04f6e23101159ec926a50e98c034a6b7d7c9f418d2410df3a03d9ca5335641efc8e36d76cd20b25101843a645b98d00005b2d666af46c45d927087db47cf7f81e4dc703622010efa9c29a9742148d5c9070348716e1bb210469d5f9fb22083df176f0c29f1a3d2310eb50e770ddcc3060101d2f43b6c2b884241076542abce5ff9345b0e8947f4c6e019c2510f9375e6d41e1000096e7fe4ff1c27e392708706f996719ba609c03622010f023d5a3b24726e0631b64b3840f82532104d570c03f2208ec011be8919883d62310c4e58af4ba43f3bcd904e16984f086d724100593f65e752e5cb7f473862bda05aa0a2510541ff1f077270000c5ea00d658bc7e9a27083fd26072eaa2a04d036220102f8f90c780d6a9c0c53da7ac57b6707e2104b072446f220823f39f9f425ad6e6231065af0527fda95b0dc5ae4aa515cdf32f2410537c3b35a3b13b08d08eeb28098f45cc25104bf4e564f75300009bc796706bc6574427080edb0eadbea94ac2
+DREF VLR subscr IMSI:901700000010650 usage increases to: 2
+DVLR VLR_Authenticate(LU:901700000010650){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(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: state_chg to VLR_SUB_AS_WAIT_RESP
+DVLR VLR_Authenticate(LU:901700000010650){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: tuple use_count=1 key_seq=0 auth_types=0x3 and...
+- ...rand=39fa2f4e3d523d8619a73b4f65c3e14d
+- ...autn=8704f5ba55f30000d2ee44b22c8ea919
+- ...expecting res=e229c19e791f2e41
+DREF VLR subscr IMSI:901700000010650 usage decreases to: 1
+<-- 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
+  MSC <--RAN_UTRAN_IU-- MS: GSM48_MT_MM_AUTH_RESP
+DREF IMSI:901700000010650: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14)
+DMM IMSI:901700000010650: MM UMTS AUTHENTICATION RESPONSE (res = e229c19e791f2e41)
+DVLR VLR_Authenticate(LU:901700000010650){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(LU:901700000010650){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result PASSED
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(LU:901700000010650)
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Freeing instance
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth()
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_AUTH}: Set Ciphering Mode
+DMM -> SECURITY MODE CONTROL IMSI:901700000010650
+- sending SecurityModeControl for UE ctx 42 send_ck=0 new_key=1
+- ...ik=27497388b6cb044648f396aa155b95ef
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_WAIT_CIPH
+DREF IMSI:901700000010650: MSC conn use - dtap == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  security_mode_ctrl_sent == 1
+  lu_result_sent == 0
+- MS sends SecurityModeControl acceptance, VLR accepts and sends GSUP LU Req to HLR
+DMM <- SECURITY MODE COMPLETE IMSI:901700000010650
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_CIPH}: Received Event VLR_ULA_E_CIPH_RES
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_CIPH}: vlr_loc_upd_post_ciph()
+DIUCS IMSI:901700000010650: tx CommonID 901700000010650
+- Iu Common ID --RAN_UTRAN_IU--> MS (IMSI=901700000010650)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_CIPH}: vlr_loc_upd_node_4()
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_CIPH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_INIT}: Allocated
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000010650)
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START
+DVLR GSUP tx: 04010809710000000156f0280102
+GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000000156f0280102
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){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: 10010809710000000156f00804032443f2
+DVLR GSUP rx 17: 10010809710000000156f00804032443f2
+DREF VLR subscr IMSI:901700000010650 usage increases to: 2
+DVLR IMSI:901700000010650 has MSISDN:42342
+DVLR SUBSCR(MSISDN:42342) VLR: update for IMSI=901700000010650 (MSISDN=42342, used=2)
+DVLR GSUP tx: 12010809710000000156f0
+GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000000156f0
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+<-- 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: 06010809710000000156f0
+DVLR GSUP rx 11: 06010809710000000156f0
+DREF VLR subscr MSISDN:42342 usage increases to: 2
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000010650)
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_DONE}: Freeing instance
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_INIT}: Allocated
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000010650)
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_INIT}: Allocated
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(LU:901700000010650)
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(LU:901700000010650)
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_DONE}: Freeing instance
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_DONE}: Deallocated
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_WAIT_SUB_PRES}: lu_compl_vlr_new_tmsi()
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_WAIT_TMSI_CNF
+- sending LU Accept for MSISDN:42342, with TMSI 0x03020100
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+<-- 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(&net->subscr_conns) == 1
+msc_subscr_conn_is_accepted() == false
+- MS sends TMSI Realloc Complete
+  MSC <--RAN_UTRAN_IU-- MS: GSM48_MT_MM_TMSI_REALL_COMPL
+DREF MSISDN:42342: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_TMSI_REALL_COMPL (0x5:0x1b)
+DMM TMSI Reallocation Completed. Subscriber: MSISDN:42342
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_NEW_TMSI_ACK
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_WAIT_TMSI_CNF}: Received Event LU_COMPL_VLR_E_NEW_TMSI_ACK
+DREF VLR subscr MSISDN:42342 usage increases to: 2
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_WAIT_TMSI_CNF}: state_chg to LU_COMPL_VLR_S_DONE
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000010650)
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_DONE}: Freeing instance
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_ACCEPTED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:42342: MSC conn use + release == 2 (0x102: dtap,release)
+DREF VLR subscr MSISDN:42342 usage increases to: 3
+DREF VLR subscr MSISDN:42342 usage decreases to: 2
+- Iu Release --RAN_UTRAN_IU--> MS
+DREF MSISDN:42342: MSC conn use - dtap == 1 (0x100: release)
+  iu_release_sent == 1
+- LU was successful, and the conn has already been closed
+- RNC sends Iu Release Complete
+DREF MSISDN:42342: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(LU:901700000010650)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: Freeing instance
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: Deallocated
+DRLL MSISDN:42342: Freeing subscriber connection
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+DREF VLR subscr MSISDN:42342 usage increases to: 2
+  vsub != NULL == 1
+  strcmp(vsub->imsi, IMSI) == 0
+  vsub->lac == 23
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+---
+- after a while, a new conn sends a CM Service Request. VLR responds with Auth Req, 2nd auth vector
+  MSC <--RAN_UTRAN_IU-- MS: GSM48_MT_MM_CM_SERV_REQ
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_CM_SERV_REQ (0x5:0x24)
+DMM <- CM SERVICE REQUEST serv_type=0x08 MI(IMSI)=901700000010650
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_NEW}: Updated ID
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: Allocated
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: is child of Subscr_Conn(CM_SERVICE_REQ:901700000010650)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: rev=R99 net=UTRAN Auth+Ciph
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START
+DREF VLR subscr MSISDN:42342 usage increases to: 2
+DREF VLR subscr MSISDN:42342 usage increases to: 3
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_WAIT_AUTH
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Allocated
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: is child of Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650)
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_WAIT_RESP
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){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 MSISDN:42342: tuple use_count=1 key_seq=1 auth_types=0x3 and...
+- ...rand=c187a53a5e6b9d573cac7c74451fd46d
+- ...autn=1843a645b98d00005b2d666af46c45d9
+- ...expecting res=7db47cf7f81e4dc7
+DREF VLR subscr MSISDN:42342 usage decreases to: 2
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF MSISDN:42342: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  cm_service_result_sent == 0
+  auth_request_sent == 1
+- needs auth, not yet accepted
+msc_subscr_conn_is_accepted() == false
+- MS sends Authen Response, VLR accepts and sends SecurityModeControl
+  MSC <--RAN_UTRAN_IU-- MS: GSM48_MT_MM_AUTH_RESP
+DREF MSISDN:42342: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14)
+DMM MSISDN:42342: MM UMTS AUTHENTICATION RESPONSE (res = 7db47cf7f81e4dc7)
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP
+DVLR SUBSCR(MSISDN:42342) AUTH on UTRAN received RES: 7db47cf7f81e4dc7 (8 bytes)
+DVLR SUBSCR(MSISDN:42342) AUTH established UMTS security context
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result PASSED
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Removing from parent Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650)
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Freeing instance
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Deallocated
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: Received Event PR_ARQ_E_AUTH_RES
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: Set Ciphering Mode
+DMM -> SECURITY MODE CONTROL MSISDN:42342
+- sending SecurityModeControl for UE ctx 42 send_ck=0 new_key=1
+- ...ik=1159ec926a50e98c034a6b7d7c9f418d
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: state_chg to PR_ARQ_S_WAIT_CIPH
+DREF MSISDN:42342: MSC conn use - dtap == 0 (0x0: )
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  security_mode_ctrl_sent == 1
+  cm_service_result_sent == 0
+- MS sends SecurityModeControl acceptance, VLR accepts; above Ciphering is an implicit CM Service Accept
+DMM <- SECURITY MODE COMPLETE MSISDN:42342
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_CIPH}: Received Event PR_ARQ_E_CIPH_RES
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_node2_post_ciph()
+DIUCS MSISDN:42342: tx CommonID 901700000010650
+- Iu Common ID --RAN_UTRAN_IU--> MS (IMSI=901700000010650)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_node2_post_vlr()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_pres()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_trace()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_imei()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_CIPH}: proc_arq_fsm_done(PASSED)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_CIPH}: state_chg to PR_ARQ_S_DONE
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_DONE}: Process Access Request result: PASSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_ACCEPTED
+DREF MSISDN:42342: MSC conn use + cm_service == 1 (0x8: cm_service)
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_ACCEPTED}: subscr_conn_fsm_has_active_transactions: still awaiting first request after a CM Service Request
+  cm_service_result_sent == 0
+---
+- a call is initiated
+- SETUP gets forwarded to MNCC
+  MSC <--RAN_UTRAN_IU-- MS: GSM48_MT_CC_SETUP
+DREF MSISDN:42342: MSC conn use + dtap == 2 (0xa: dtap,cm_service)
+DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5)
+DCC Unknown transaction ID 8, creating new trans.
+DCC (ti 08 sub MSISDN:42342 callref 80000002) New transaction
+DREF VLR subscr MSISDN:42342 usage increases to: 3
+DREF MSISDN:42342: MSC conn use + trans_cc == 3 (0x1a: dtap,cm_service,trans_cc)
+DMM MSISDN:42342: rx msg GSM48_MT_CC_SETUP: received_cm_service_request changes to false
+DREF MSISDN:42342: MSC conn use - cm_service == 2 (0x12: dtap,trans_cc)
+DCC (sub 42342) starting guard timer with 180 seconds
+DCC (ti 08 sub MSISDN:42342) new state NULL -> INITIATED
+DCC Subscriber MSISDN:42342 (42342) sends SETUP to 123
+DMNCC transmit message MNCC_SETUP_IND
+DCC Sending 'MNCC_SETUP_IND' to MNCC.
+  MSC --> MNCC: callref 0x80000002: MNCC_SETUP_IND
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_COMMUNICATING
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_COMMUNICATING
+DREF MSISDN:42342: MSC conn use - dtap == 1 (0x10: trans_cc)
+- MNCC says that's fine
+DMNCC receive message MNCC_CALL_PROC_REQ
+DCC (sub 42342) stopping pending guard timer
+DCC (sub 42342) starting guard timer with 180 seconds
+DCC (ti 08 sub 42342) Received 'MNCC_CALL_PROC_REQ' from MNCC in state 1 (INITIATED)
+DCC (ti 08 sub MSISDN:42342) new state INITIATED -> MO_CALL_PROC
+DMSC msc_tx 2 bytes to MSISDN:42342 via RAN_UTRAN_IU
+- DTAP --RAN_UTRAN_IU--> MS: GSM48_MT_CC_CALL_PROC: 8302
+- DTAP matches expected message
+  MS <--Call Assignment-- MSC: subscr=MSISDN:42342 callref=0x80000002
+- But the other side's MSISDN could not be resolved, MNCC tells us to cancel
+DMNCC receive message MNCC_REL_REQ
+DCC (sub 42342) stopping pending guard timer
+DCC (sub 42342) starting guard timer with 180 seconds
+DCC (ti 08 sub 42342) Received 'MNCC_REL_REQ' from MNCC in state 3 (MO_CALL_PROC)
+DCC starting timer T308 with 10 seconds
+DCC (ti 08 sub MSISDN:42342) new state MO_CALL_PROC -> RELEASE_REQ
+DMSC msc_tx 2 bytes to MSISDN:42342 via RAN_UTRAN_IU
+- DTAP --RAN_UTRAN_IU--> MS: GSM48_MT_CC_RELEASE: 832d
+- DTAP matches expected message
+- Total time passed: 10.000023 s
+DCC starting timer T308 with 10 seconds
+DMSC msc_tx 2 bytes to MSISDN:42342 via RAN_UTRAN_IU
+- DTAP --RAN_UTRAN_IU--> MS: GSM48_MT_CC_RELEASE: 832d
+- DTAP matches expected message
+  MSC <--RAN_UTRAN_IU-- MS: GSM48_MT_CC_RELEASE_COMPL
+DREF MSISDN:42342: MSC conn use + dtap == 2 (0x12: dtap,trans_cc)
+DRLL Dispatching 04.08 message GSM48_MT_CC_RELEASE_COMPL (0x3:0x2a)
+DCC stopping pending timer T308
+DMNCC transmit message MNCC_REL_CNF
+DCC Sending 'MNCC_REL_CNF' to MNCC.
+  MSC --> MNCC: callref 0x80000002: MNCC_REL_CNF
+  MS <--Call Release-- MSC: subscr=MSISDN:42342 callref=0x0
+DCC (ti 08 sub MSISDN:42342) new state RELEASE_REQ -> NULL
+DCC (sub 42342) stopping pending guard timer
+DREF VLR subscr MSISDN:42342 usage decreases to: 2
+DREF MSISDN:42342: MSC conn use - trans_cc == 1 (0x2: dtap)
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_COMMUNICATING}: Received Event SUBSCR_CONN_E_COMMUNICATING
+DREF MSISDN:42342: MSC conn use - dtap == 0 (0x0: )
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_COMMUNICATING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_COMMUNICATING}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:42342: MSC conn use + release == 1 (0x100: release)
+DREF VLR subscr MSISDN:42342 usage increases to: 3
+DREF VLR subscr MSISDN:42342 usage decreases to: 2
+- Iu Release --RAN_UTRAN_IU--> MS
+- RNC sends Iu Release Complete
+DREF MSISDN:42342: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_DONE}: Removing from parent Subscr_Conn(CM_SERVICE_REQ:901700000010650)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_DONE}: Freeing instance
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_DONE}: Deallocated
+DRLL MSISDN:42342: Freeing subscriber connection
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+DREF freeing VLR subscr MSISDN:42342
+===== test_call_mo_to_unknown: SUCCESS
+
+full talloc report on 'msgb' (total      0 bytes in   1 blocks)
+talloc_total_blocks(tall_bsc_ctx) == 12
+
+===== test_call_mo_to_unknown_timeout
+- Total time passed: 0.000000 s
+- Location Update request causes a GSUP Send Auth Info request to HLR
+  MSC <--RAN_UTRAN_IU-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8)
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_NEW}: Updated ID
+DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000010650 type=NORMAL
+DMM LU/new-LAC: 23/23
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: Allocated
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: is child of Subscr_Conn(LU:901700000010650)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: rev=R99 net=UTRAN Auth+Ciph
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA
+DREF VLR subscr unknown usage increases to: 1
+DVLR set IMSI on subscriber; IMSI=901700000010650 id=901700000010650
+DVLR New subscr, IMSI: 901700000010650
+DREF VLR subscr IMSI:901700000010650 usage increases to: 2
+DREF VLR subscr IMSI:901700000010650 usage decreases to: 1
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Allocated
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(LU:901700000010650)
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
+DVLR GSUP tx: 08010809710000000156f0
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f0
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF IMSI:901700000010650: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  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: 0a010809710000000156f00362201039fa2f4e3d523d8619a73b4f65c3e14d21049b36efdf2208059a4f668f6fbe39231027497388b6cb044648f396aa155b95ef2410f64735036e5871319c679f4742a75ea125108704f5ba55f30000d2ee44b22c8ea9192708e229c19e791f2e4103622010c187a53a5e6b9d573cac7c74451fd46d210485aa31302208d3d50a000bf04f6e23101159ec926a50e98c034a6b7d7c9f418d2410df3a03d9ca5335641efc8e36d76cd20b25101843a645b98d00005b2d666af46c45d927087db47cf7f81e4dc703622010efa9c29a9742148d5c9070348716e1bb210469d5f9fb22083df176f0c29f1a3d2310eb50e770ddcc3060101d2f43b6c2b884241076542abce5ff9345b0e8947f4c6e019c2510f9375e6d41e1000096e7fe4ff1c27e392708706f996719ba609c03622010f023d5a3b24726e0631b64b3840f82532104d570c03f2208ec011be8919883d62310c4e58af4ba43f3bcd904e16984f086d724100593f65e752e5cb7f473862bda05aa0a2510541ff1f077270000c5ea00d658bc7e9a27083fd26072eaa2a04d036220102f8f90c780d6a9c0c53da7ac57b6707e2104b072446f220823f39f9f425ad6e6231065af0527fda95b0dc5ae4aa515cdf32f2410537c3b35a3b13b08d08eeb28098f45cc25104bf4e564f75300009bc796706bc6574427080edb0eadbea94ac2
+DVLR GSUP rx 511: 0a010809710000000156f00362201039fa2f4e3d523d8619a73b4f65c3e14d21049b36efdf2208059a4f668f6fbe39231027497388b6cb044648f396aa155b95ef2410f64735036e5871319c679f4742a75ea125108704f5ba55f30000d2ee44b22c8ea9192708e229c19e791f2e4103622010c187a53a5e6b9d573cac7c74451fd46d210485aa31302208d3d50a000bf04f6e23101159ec926a50e98c034a6b7d7c9f418d2410df3a03d9ca5335641efc8e36d76cd20b25101843a645b98d00005b2d666af46c45d927087db47cf7f81e4dc703622010efa9c29a9742148d5c9070348716e1bb210469d5f9fb22083df176f0c29f1a3d2310eb50e770ddcc3060101d2f43b6c2b884241076542abce5ff9345b0e8947f4c6e019c2510f9375e6d41e1000096e7fe4ff1c27e392708706f996719ba609c03622010f023d5a3b24726e0631b64b3840f82532104d570c03f2208ec011be8919883d62310c4e58af4ba43f3bcd904e16984f086d724100593f65e752e5cb7f473862bda05aa0a2510541ff1f077270000c5ea00d658bc7e9a27083fd26072eaa2a04d036220102f8f90c780d6a9c0c53da7ac57b6707e2104b072446f220823f39f9f425ad6e6231065af0527fda95b0dc5ae4aa515cdf32f2410537c3b35a3b13b08d08eeb28098f45cc25104bf4e564f75300009bc796706bc6574427080edb0eadbea94ac2
+DREF VLR subscr IMSI:901700000010650 usage increases to: 2
+DVLR VLR_Authenticate(LU:901700000010650){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(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: state_chg to VLR_SUB_AS_WAIT_RESP
+DVLR VLR_Authenticate(LU:901700000010650){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: tuple use_count=1 key_seq=0 auth_types=0x3 and...
+- ...rand=39fa2f4e3d523d8619a73b4f65c3e14d
+- ...autn=8704f5ba55f30000d2ee44b22c8ea919
+- ...expecting res=e229c19e791f2e41
+DREF VLR subscr IMSI:901700000010650 usage decreases to: 1
+<-- 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
+  MSC <--RAN_UTRAN_IU-- MS: GSM48_MT_MM_AUTH_RESP
+DREF IMSI:901700000010650: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14)
+DMM IMSI:901700000010650: MM UMTS AUTHENTICATION RESPONSE (res = e229c19e791f2e41)
+DVLR VLR_Authenticate(LU:901700000010650){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(LU:901700000010650){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result PASSED
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(LU:901700000010650)
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Freeing instance
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth()
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_AUTH}: Set Ciphering Mode
+DMM -> SECURITY MODE CONTROL IMSI:901700000010650
+- sending SecurityModeControl for UE ctx 42 send_ck=0 new_key=1
+- ...ik=27497388b6cb044648f396aa155b95ef
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_WAIT_CIPH
+DREF IMSI:901700000010650: MSC conn use - dtap == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  security_mode_ctrl_sent == 1
+  lu_result_sent == 0
+- MS sends SecurityModeControl acceptance, VLR accepts and sends GSUP LU Req to HLR
+DMM <- SECURITY MODE COMPLETE IMSI:901700000010650
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_CIPH}: Received Event VLR_ULA_E_CIPH_RES
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_CIPH}: vlr_loc_upd_post_ciph()
+DIUCS IMSI:901700000010650: tx CommonID 901700000010650
+- Iu Common ID --RAN_UTRAN_IU--> MS (IMSI=901700000010650)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_CIPH}: vlr_loc_upd_node_4()
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_CIPH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_INIT}: Allocated
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000010650)
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START
+DVLR GSUP tx: 04010809710000000156f0280102
+GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000000156f0280102
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){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: 10010809710000000156f00804032443f2
+DVLR GSUP rx 17: 10010809710000000156f00804032443f2
+DREF VLR subscr IMSI:901700000010650 usage increases to: 2
+DVLR IMSI:901700000010650 has MSISDN:42342
+DVLR SUBSCR(MSISDN:42342) VLR: update for IMSI=901700000010650 (MSISDN=42342, used=2)
+DVLR GSUP tx: 12010809710000000156f0
+GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000000156f0
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+<-- 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: 06010809710000000156f0
+DVLR GSUP rx 11: 06010809710000000156f0
+DREF VLR subscr MSISDN:42342 usage increases to: 2
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000010650)
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_DONE}: Freeing instance
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_INIT}: Allocated
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000010650)
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_INIT}: Allocated
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(LU:901700000010650)
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(LU:901700000010650)
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_DONE}: Freeing instance
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_DONE}: Deallocated
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_WAIT_SUB_PRES}: lu_compl_vlr_new_tmsi()
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_WAIT_TMSI_CNF
+- sending LU Accept for MSISDN:42342, with TMSI 0x03020100
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+<-- 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(&net->subscr_conns) == 1
+msc_subscr_conn_is_accepted() == false
+- MS sends TMSI Realloc Complete
+  MSC <--RAN_UTRAN_IU-- MS: GSM48_MT_MM_TMSI_REALL_COMPL
+DREF MSISDN:42342: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_TMSI_REALL_COMPL (0x5:0x1b)
+DMM TMSI Reallocation Completed. Subscriber: MSISDN:42342
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_NEW_TMSI_ACK
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_WAIT_TMSI_CNF}: Received Event LU_COMPL_VLR_E_NEW_TMSI_ACK
+DREF VLR subscr MSISDN:42342 usage increases to: 2
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_WAIT_TMSI_CNF}: state_chg to LU_COMPL_VLR_S_DONE
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000010650)
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_DONE}: Freeing instance
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_ACCEPTED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:42342: MSC conn use + release == 2 (0x102: dtap,release)
+DREF VLR subscr MSISDN:42342 usage increases to: 3
+DREF VLR subscr MSISDN:42342 usage decreases to: 2
+- Iu Release --RAN_UTRAN_IU--> MS
+DREF MSISDN:42342: MSC conn use - dtap == 1 (0x100: release)
+  iu_release_sent == 1
+- LU was successful, and the conn has already been closed
+- RNC sends Iu Release Complete
+DREF MSISDN:42342: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(LU:901700000010650)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: Freeing instance
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: Deallocated
+DRLL MSISDN:42342: Freeing subscriber connection
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+DREF VLR subscr MSISDN:42342 usage increases to: 2
+  vsub != NULL == 1
+  strcmp(vsub->imsi, IMSI) == 0
+  vsub->lac == 23
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+---
+- after a while, a new conn sends a CM Service Request. VLR responds with Auth Req, 2nd auth vector
+  MSC <--RAN_UTRAN_IU-- MS: GSM48_MT_MM_CM_SERV_REQ
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_CM_SERV_REQ (0x5:0x24)
+DMM <- CM SERVICE REQUEST serv_type=0x08 MI(IMSI)=901700000010650
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_NEW}: Updated ID
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: Allocated
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: is child of Subscr_Conn(CM_SERVICE_REQ:901700000010650)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: rev=R99 net=UTRAN Auth+Ciph
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START
+DREF VLR subscr MSISDN:42342 usage increases to: 2
+DREF VLR subscr MSISDN:42342 usage increases to: 3
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_WAIT_AUTH
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Allocated
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: is child of Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650)
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_WAIT_RESP
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){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 MSISDN:42342: tuple use_count=1 key_seq=1 auth_types=0x3 and...
+- ...rand=c187a53a5e6b9d573cac7c74451fd46d
+- ...autn=1843a645b98d00005b2d666af46c45d9
+- ...expecting res=7db47cf7f81e4dc7
+DREF VLR subscr MSISDN:42342 usage decreases to: 2
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF MSISDN:42342: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  cm_service_result_sent == 0
+  auth_request_sent == 1
+- needs auth, not yet accepted
+msc_subscr_conn_is_accepted() == false
+- MS sends Authen Response, VLR accepts and sends SecurityModeControl
+  MSC <--RAN_UTRAN_IU-- MS: GSM48_MT_MM_AUTH_RESP
+DREF MSISDN:42342: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14)
+DMM MSISDN:42342: MM UMTS AUTHENTICATION RESPONSE (res = 7db47cf7f81e4dc7)
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP
+DVLR SUBSCR(MSISDN:42342) AUTH on UTRAN received RES: 7db47cf7f81e4dc7 (8 bytes)
+DVLR SUBSCR(MSISDN:42342) AUTH established UMTS security context
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result PASSED
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Removing from parent Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650)
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Freeing instance
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Deallocated
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: Received Event PR_ARQ_E_AUTH_RES
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: Set Ciphering Mode
+DMM -> SECURITY MODE CONTROL MSISDN:42342
+- sending SecurityModeControl for UE ctx 42 send_ck=0 new_key=1
+- ...ik=1159ec926a50e98c034a6b7d7c9f418d
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: state_chg to PR_ARQ_S_WAIT_CIPH
+DREF MSISDN:42342: MSC conn use - dtap == 0 (0x0: )
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  security_mode_ctrl_sent == 1
+  cm_service_result_sent == 0
+- MS sends SecurityModeControl acceptance, VLR accepts; above Ciphering is an implicit CM Service Accept
+DMM <- SECURITY MODE COMPLETE MSISDN:42342
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_CIPH}: Received Event PR_ARQ_E_CIPH_RES
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_node2_post_ciph()
+DIUCS MSISDN:42342: tx CommonID 901700000010650
+- Iu Common ID --RAN_UTRAN_IU--> MS (IMSI=901700000010650)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_node2_post_vlr()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_pres()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_trace()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_imei()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_CIPH}: proc_arq_fsm_done(PASSED)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_CIPH}: state_chg to PR_ARQ_S_DONE
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_DONE}: Process Access Request result: PASSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_ACCEPTED
+DREF MSISDN:42342: MSC conn use + cm_service == 1 (0x8: cm_service)
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_ACCEPTED}: subscr_conn_fsm_has_active_transactions: still awaiting first request after a CM Service Request
+  cm_service_result_sent == 0
+---
+- a call is initiated
+- SETUP gets forwarded to MNCC
+  MSC <--RAN_UTRAN_IU-- MS: GSM48_MT_CC_SETUP
+DREF MSISDN:42342: MSC conn use + dtap == 2 (0xa: dtap,cm_service)
+DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5)
+DCC Unknown transaction ID 8, creating new trans.
+DCC (ti 08 sub MSISDN:42342 callref 80000003) New transaction
+DREF VLR subscr MSISDN:42342 usage increases to: 3
+DREF MSISDN:42342: MSC conn use + trans_cc == 3 (0x1a: dtap,cm_service,trans_cc)
+DMM MSISDN:42342: rx msg GSM48_MT_CC_SETUP: received_cm_service_request changes to false
+DREF MSISDN:42342: MSC conn use - cm_service == 2 (0x12: dtap,trans_cc)
+DCC (sub 42342) starting guard timer with 180 seconds
+DCC (ti 08 sub MSISDN:42342) new state NULL -> INITIATED
+DCC Subscriber MSISDN:42342 (42342) sends SETUP to 123
+DMNCC transmit message MNCC_SETUP_IND
+DCC Sending 'MNCC_SETUP_IND' to MNCC.
+  MSC --> MNCC: callref 0x80000003: MNCC_SETUP_IND
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_COMMUNICATING
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_COMMUNICATING
+DREF MSISDN:42342: MSC conn use - dtap == 1 (0x10: trans_cc)
+- MNCC says that's fine
+DMNCC receive message MNCC_CALL_PROC_REQ
+DCC (sub 42342) stopping pending guard timer
+DCC (sub 42342) starting guard timer with 180 seconds
+DCC (ti 08 sub 42342) Received 'MNCC_CALL_PROC_REQ' from MNCC in state 1 (INITIATED)
+DCC (ti 08 sub MSISDN:42342) new state INITIATED -> MO_CALL_PROC
+DMSC msc_tx 2 bytes to MSISDN:42342 via RAN_UTRAN_IU
+- DTAP --RAN_UTRAN_IU--> MS: GSM48_MT_CC_CALL_PROC: 8302
+- DTAP matches expected message
+  MS <--Call Assignment-- MSC: subscr=MSISDN:42342 callref=0x80000003
+- But the other side's MSISDN could not be resolved, MNCC tells us to cancel
+DMNCC receive message MNCC_REL_REQ
+DCC (sub 42342) stopping pending guard timer
+DCC (sub 42342) starting guard timer with 180 seconds
+DCC (ti 08 sub 42342) Received 'MNCC_REL_REQ' from MNCC in state 3 (MO_CALL_PROC)
+DCC starting timer T308 with 10 seconds
+DCC (ti 08 sub MSISDN:42342) new state MO_CALL_PROC -> RELEASE_REQ
+DMSC msc_tx 2 bytes to MSISDN:42342 via RAN_UTRAN_IU
+- DTAP --RAN_UTRAN_IU--> MS: GSM48_MT_CC_RELEASE: 832d
+- DTAP matches expected message
+- Despite our repeated CC Release Requests, the MS does not respond anymore
+- Total time passed: 10.000023 s
+DCC starting timer T308 with 10 seconds
+DMSC msc_tx 2 bytes to MSISDN:42342 via RAN_UTRAN_IU
+- DTAP --RAN_UTRAN_IU--> MS: GSM48_MT_CC_RELEASE: 832d
+- DTAP matches expected message
+- The CC Release times out and we still properly clear the conn
+- Total time passed: 20.000046 s
+  MS <--Call Release-- MSC: subscr=MSISDN:42342 callref=0x80000003
+DMNCC transmit message MNCC_REL_CNF
+DCC Sending 'MNCC_REL_CNF' to MNCC.
+  MSC --> MNCC: callref 0x80000003: MNCC_REL_CNF
+DCC (ti 08 sub MSISDN:42342) new state RELEASE_REQ -> NULL
+DCC (sub 42342) stopping pending guard timer
+DREF VLR subscr MSISDN:42342 usage decreases to: 2
+DREF MSISDN:42342: MSC conn use - trans_cc == 0 (0x0: )
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_COMMUNICATING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_COMMUNICATING}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:42342: MSC conn use + release == 1 (0x100: release)
+DREF VLR subscr MSISDN:42342 usage increases to: 3
+DREF VLR subscr MSISDN:42342 usage decreases to: 2
+- Iu Release --RAN_UTRAN_IU--> MS
+- RNC sends Iu Release Complete
+DREF MSISDN:42342: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_DONE}: Removing from parent Subscr_Conn(CM_SERVICE_REQ:901700000010650)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_DONE}: Freeing instance
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_DONE}: Deallocated
+DRLL MSISDN:42342: Freeing subscriber connection
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+DREF freeing VLR subscr MSISDN:42342
+===== test_call_mo_to_unknown_timeout: SUCCESS
+
+full talloc report on 'msgb' (total      0 bytes in   1 blocks)
+talloc_total_blocks(tall_bsc_ctx) == 12
+
+full talloc report on 'msgb' (total      0 bytes in   1 blocks)
+talloc_total_blocks(tall_bsc_ctx) == 12
+
diff --git a/tests/msc_vlr/msc_vlr_test_call.ok b/tests/msc_vlr/msc_vlr_test_call.ok
new file mode 100644
index 0000000..a965a70
--- /dev/null
+++ b/tests/msc_vlr/msc_vlr_test_call.ok
@@ -0,0 +1 @@
+Done
diff --git a/tests/msc_vlr/msc_vlr_test_gsm_authen.c b/tests/msc_vlr/msc_vlr_test_gsm_authen.c
new file mode 100644
index 0000000..8129781
--- /dev/null
+++ b/tests/msc_vlr/msc_vlr_test_gsm_authen.c
@@ -0,0 +1,1005 @@
+/* Osmocom MSC+VLR end-to-end tests */
+
+/* (C) 2017 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>
+ *
+ * All Rights Reserved
+ *
+ * Author: Neels Hofmeyr <nhofmeyr@sysmocom.de>
+ *
+ * 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 "msc_vlr_tests.h"
+
+static void test_gsm_authen()
+{
+	struct vlr_subscr *vsub;
+	const char *imsi = "901700000004620";
+
+	comment_start();
+
+	net->authentication_required = true;
+
+	btw("Location Update request causes a GSUP Send Auth Info request to HLR");
+	lu_result_sent = RES_NONE;
+	gsup_expect_tx("08010809710000004026f0");
+	ms_sends_msg("0508020081680001"
+		     "30" /* <-- Revision Level == 1, i.e. is_r99 == false */
+		     "089910070000006402");
+	OSMO_ASSERT(gsup_tx_confirmed);
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("from HLR, rx _SEND_AUTH_INFO_RESULT; VLR sends Auth Req to MS");
+	auth_request_sent = false;
+	auth_request_expect_rand = "585df1ae287f6e273dce07090d61320b";
+	auth_request_expect_autn = NULL;
+	/* Based on a Ki of 000102030405060708090a0b0c0d0e0f */
+	gsup_rx("0a"
+		/* imsi */
+		"0108" "09710000004026f0"
+		/* 5 auth vectors... */
+		/* TL    TL     rand */
+		"0322"  "2010" "585df1ae287f6e273dce07090d61320b"
+		/*       TL     sres       TL     kc */
+			"2104" "2d8b2c3e" "2208" "61855fb81fc2a800"
+		"0322"  "2010" "12aca96fb4ffdea5c985cbafa9b6e18b"
+			"2104" "20bde240" "2208" "07fa7502e07e1c00"
+		"0322"  "2010" "e7c03ba7cf0e2fde82b2dc4d63077d42"
+			"2104" "a29514ae" "2208" "e2b234f807886400"
+		"0322"  "2010" "fa8f20b781b5881329d4fea26b1a3c51"
+			"2104" "5afc8d72" "2208" "2392f14f709ae000"
+		"0322"  "2010" "0fd4cc8dbe8715d1f439e304edfd68dc"
+			"2104" "bc8d1c5b" "2208" "da7cdd6bfe2d7000",
+		NULL);
+	VERBOSE_ASSERT(auth_request_sent, == true, "%d");
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("If the HLR were to send a GSUP _UPDATE_LOCATION_RESULT we'd still reject");
+	gsup_rx("06010809710000004026f0", NULL);
+	EXPECT_ACCEPTED(false);
+
+	thwart_rx_non_initial_requests();
+
+	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");
+	ms_sends_msg("05542d8b2c3e");
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT");
+	gsup_rx("10010809710000004026f00804036470f1",
+		"12010809710000004026f0");
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("HLR also sends GSUP _UPDATE_LOCATION_RESULT");
+	expect_bssap_clear();
+	gsup_rx("06010809710000004026f0", NULL);
+	VERBOSE_ASSERT(bssap_clear_sent, == true, "%d");
+
+	btw("LU was successful, and the conn has already been closed");
+	VERBOSE_ASSERT(lu_result_sent, == RES_ACCEPT, "%d");
+	bss_sends_clear_complete();
+	EXPECT_CONN_COUNT(0);
+
+	BTW("after a while, a new conn sends a CM Service Request. VLR responds with Auth Req, 2nd auth vector");
+	auth_request_sent = false;
+	auth_request_expect_rand = "12aca96fb4ffdea5c985cbafa9b6e18b";
+	cm_service_result_sent = RES_NONE;
+	ms_sends_msg("05247803305886089910070000006402");
+	OSMO_ASSERT(g_conn);
+	OSMO_ASSERT(g_conn->fi);
+	OSMO_ASSERT(g_conn->vsub);
+	VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d");
+	VERBOSE_ASSERT(auth_request_sent, == true, "%d");
+
+	btw("needs auth, not yet accepted");
+	EXPECT_ACCEPTED(false);
+	thwart_rx_non_initial_requests();
+
+	btw("MS sends Authen Response, VLR accepts with a CM Service Accept");
+	gsup_expect_tx(NULL);
+	ms_sends_msg("0554" "20bde240" /* 2nd vector's sres, s.a. */);
+	VERBOSE_ASSERT(cm_service_result_sent, == RES_ACCEPT, "%d");
+
+	/* Release connection */
+	expect_bssap_clear(RAN_GERAN_A);
+	conn_conclude_cm_service_req(g_conn, RAN_GERAN_A);
+
+	btw("all requests serviced, conn has been released");
+	bss_sends_clear_complete();
+	EXPECT_CONN_COUNT(0);
+
+	BTW("an SMS is sent, MS is paged");
+	paging_expect_imsi(imsi);
+	paging_sent = false;
+	vsub = vlr_subscr_find_by_imsi(net->vlr, imsi);
+	OSMO_ASSERT(vsub);
+	VERBOSE_ASSERT(llist_count(&vsub->cs.requests), == 0, "%d");
+
+	send_sms(vsub, vsub,
+		 "Privacy in residential applications is a desirable"
+		 " marketing option.");
+
+	VERBOSE_ASSERT(llist_count(&vsub->cs.requests), == 1, "%d");
+	vlr_subscr_put(vsub);
+	vsub = NULL;
+	VERBOSE_ASSERT(paging_sent, == true, "%d");
+	VERBOSE_ASSERT(paging_stopped, == false, "%d");
+
+	btw("the subscriber and its pending request should remain");
+	vsub = vlr_subscr_find_by_imsi(net->vlr, imsi);
+	OSMO_ASSERT(vsub);
+	VERBOSE_ASSERT(llist_count(&vsub->cs.requests), == 1, "%d");
+	vlr_subscr_put(vsub);
+
+	btw("MS replies with Paging Response, and VLR sends Auth Request with third key");
+	auth_request_sent = false;
+	auth_request_expect_rand = "e7c03ba7cf0e2fde82b2dc4d63077d42";
+	ms_sends_msg("06270703305882089910070000006402");
+	VERBOSE_ASSERT(auth_request_sent, == true, "%d");
+
+	btw("needs auth, not yet accepted");
+	EXPECT_ACCEPTED(false);
+	thwart_rx_non_initial_requests();
+
+	btw("MS sends Authen Response, VLR accepts and sends pending SMS");
+	dtap_expect_tx("09" /* SMS messages */
+		       "01" /* CP-DATA */
+		       "58" /* length */
+		       "01" /* Network to MS */
+		       "00" /* reference */
+		       /* originator (gsm411_send_sms() hardcodes this weird nr) */
+		       "0791" "447758100650" /* 447785016005 */
+		       "00" /* dest */
+		       /* SMS TPDU */
+		       "4c" /* len */
+		       "00" /* SMS deliver */
+		       "05806470f1" /* originating address 46071 */
+		       "00" /* TP-PID */
+		       "00" /* GSM default alphabet */
+		       "071010" /* Y-M-D (from wrapped gsm340_gen_scts())*/
+		       "000000" /* H-M-S */
+		       "00" /* GMT+0 */
+		       "44" /* data length */
+		       "5079da1e1ee7416937485e9ea7c965373d1d6683c270383b3d0e"
+		       "d3d36ff71c949e83c22072799e9687c5ec32a81d96afcbf4b4fb"
+		       "0c7ac3e9e9b7db05");
+	ms_sends_msg("0554" "a29514ae" /* 3rd vector's sres, s.a. */);
+	VERBOSE_ASSERT(dtap_tx_confirmed, == true, "%d");
+	VERBOSE_ASSERT(paging_stopped, == true, "%d");
+
+	btw("SMS was delivered, no requests pending for subscr");
+	vsub = vlr_subscr_find_by_imsi(net->vlr, imsi);
+	OSMO_ASSERT(vsub);
+	VERBOSE_ASSERT(llist_count(&vsub->cs.requests), == 0, "%d");
+	vlr_subscr_put(vsub);
+
+	btw("conn is still open to wait for SMS ack dance");
+	EXPECT_CONN_COUNT(1);
+
+	btw("MS replies with CP-ACK for received SMS");
+	ms_sends_msg("8904");
+	EXPECT_CONN_COUNT(1);
+
+	btw("MS also sends RP-ACK, MSC in turn sends CP-ACK for that");
+	dtap_expect_tx("0904");
+	expect_bssap_clear();
+	ms_sends_msg("890106020041020000");
+	VERBOSE_ASSERT(dtap_tx_confirmed, == true, "%d");
+	VERBOSE_ASSERT(bssap_clear_sent, == true, "%d");
+
+	btw("SMS is done, conn is gone");
+	bss_sends_clear_complete();
+	EXPECT_CONN_COUNT(0);
+
+	BTW("subscriber detaches");
+	expect_bssap_clear();
+	ms_sends_msg("050130089910070000006402");
+	VERBOSE_ASSERT(bssap_clear_sent, == true, "%d");
+
+	bss_sends_clear_complete();
+	EXPECT_CONN_COUNT(0);
+	clear_vlr();
+	comment_end();
+}
+
+static void test_gsm_authen_tmsi()
+{
+	struct vlr_subscr *vsub;
+	const char *imsi = "901700000004620";
+
+	comment_start();
+
+	net->authentication_required = true;
+	net->vlr->cfg.assign_tmsi = true;
+
+	btw("Location Update request causes a GSUP Send Auth Info request to HLR");
+	lu_result_sent = RES_NONE;
+	gsup_expect_tx("08010809710000004026f0");
+	ms_sends_msg("0508020081680001"
+		     "30" /* <-- Revision Level == 1, i.e. is_r99 == false */
+		     "089910070000006402");
+	OSMO_ASSERT(gsup_tx_confirmed);
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("from HLR, rx _SEND_AUTH_INFO_RESULT; VLR sends Auth Req to MS");
+	auth_request_sent = false;
+	auth_request_expect_rand = "585df1ae287f6e273dce07090d61320b";
+	auth_request_expect_autn = NULL;
+	/* Based on a Ki of 000102030405060708090a0b0c0d0e0f */
+	gsup_rx("0a"
+		/* imsi */
+		"0108" "09710000004026f0"
+		/* 5 auth vectors... */
+		/* TL    TL     rand */
+		"0322"  "2010" "585df1ae287f6e273dce07090d61320b"
+		/*       TL     sres       TL     kc */
+			"2104" "2d8b2c3e" "2208" "61855fb81fc2a800"
+		"0322"  "2010" "12aca96fb4ffdea5c985cbafa9b6e18b"
+			"2104" "20bde240" "2208" "07fa7502e07e1c00"
+		"0322"  "2010" "e7c03ba7cf0e2fde82b2dc4d63077d42"
+			"2104" "a29514ae" "2208" "e2b234f807886400"
+		"0322"  "2010" "fa8f20b781b5881329d4fea26b1a3c51"
+			"2104" "5afc8d72" "2208" "2392f14f709ae000"
+		"0322"  "2010" "0fd4cc8dbe8715d1f439e304edfd68dc"
+			"2104" "bc8d1c5b" "2208" "da7cdd6bfe2d7000",
+		NULL);
+	VERBOSE_ASSERT(auth_request_sent, == true, "%d");
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("If the HLR were to send a GSUP _UPDATE_LOCATION_RESULT we'd still reject");
+	gsup_rx("06010809710000004026f0", NULL);
+	EXPECT_ACCEPTED(false);
+
+	thwart_rx_non_initial_requests();
+
+	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");
+	ms_sends_msg("05542d8b2c3e");
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT");
+	gsup_rx("10010809710000004026f00804036470f1",
+		"12010809710000004026f0");
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("HLR also sends GSUP _UPDATE_LOCATION_RESULT");
+	gsup_rx("06010809710000004026f0", NULL);
+
+	btw("a LU Accept with a new TMSI was sent, waiting for TMSI Realloc Compl");
+	EXPECT_CONN_COUNT(1);
+	VERBOSE_ASSERT(lu_result_sent, == RES_ACCEPT, "%d");
+	EXPECT_ACCEPTED(false);
+	thwart_rx_non_initial_requests();
+
+	btw("even though the TMSI is not acked, we can already find the subscr with it");
+	vsub = vlr_subscr_find_by_tmsi(net->vlr, 0x03020100);
+	VERBOSE_ASSERT(vsub != NULL, == true, "%d");
+	VERBOSE_ASSERT(strcmp(vsub->imsi, imsi), == 0, "%d");
+	VERBOSE_ASSERT(vsub->tmsi_new, == 0x03020100, "0x%08x");
+	VERBOSE_ASSERT(vsub->tmsi, == GSM_RESERVED_TMSI, "0x%08x");
+	vlr_subscr_put(vsub);
+
+	btw("MS sends TMSI Realloc Complete");
+	expect_bssap_clear();
+	ms_sends_msg("055b");
+	VERBOSE_ASSERT(bssap_clear_sent, == true, "%d");
+
+	btw("LU was successful, and the conn has already been closed");
+	bss_sends_clear_complete();
+	EXPECT_CONN_COUNT(0);
+
+	btw("Subscriber has the new TMSI");
+	vsub = vlr_subscr_find_by_imsi(net->vlr, imsi);
+	VERBOSE_ASSERT(vsub != NULL, == true, "%d");
+	VERBOSE_ASSERT(strcmp(vsub->imsi, imsi), == 0, "%d");
+	VERBOSE_ASSERT(vsub->tmsi_new, == GSM_RESERVED_TMSI, "0x%08x");
+	VERBOSE_ASSERT(vsub->tmsi, == 0x03020100, "0x%08x");
+	vlr_subscr_put(vsub);
+
+	BTW("after a while, a new conn sends a CM Service Request using above TMSI. VLR responds with Auth Req, 2nd auth vector");
+	auth_request_sent = false;
+	auth_request_expect_rand = "12aca96fb4ffdea5c985cbafa9b6e18b";
+	cm_service_result_sent = RES_NONE;
+	ms_sends_msg("05247803305886" "05f4" "03020100");
+	OSMO_ASSERT(g_conn);
+	OSMO_ASSERT(g_conn->fi);
+	OSMO_ASSERT(g_conn->vsub);
+	VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d");
+	VERBOSE_ASSERT(auth_request_sent, == true, "%d");
+
+	btw("needs auth, not yet accepted");
+	EXPECT_ACCEPTED(false);
+	thwart_rx_non_initial_requests();
+
+	btw("MS sends Authen Response, VLR accepts with a CM Service Accept");
+	gsup_expect_tx(NULL);
+	ms_sends_msg("0554" "20bde240" /* 2nd vector's sres, s.a. */);
+	VERBOSE_ASSERT(cm_service_result_sent, == RES_ACCEPT, "%d");
+
+	/* Release connection */
+	expect_bssap_clear(RAN_GERAN_A);
+	conn_conclude_cm_service_req(g_conn, RAN_GERAN_A);
+
+	btw("all requests serviced, conn has been released");
+	bss_sends_clear_complete();
+	EXPECT_CONN_COUNT(0);
+
+	BTW("an SMS is sent, MS is paged");
+	paging_expect_tmsi(0x03020100);
+	paging_sent = false;
+	vsub = vlr_subscr_find_by_tmsi(net->vlr, 0x03020100);
+	OSMO_ASSERT(vsub);
+	VERBOSE_ASSERT(llist_count(&vsub->cs.requests), == 0, "%d");
+
+	send_sms(vsub, vsub,
+		 "Privacy in residential applications is a desirable"
+		 " marketing option.");
+
+	VERBOSE_ASSERT(llist_count(&vsub->cs.requests), == 1, "%d");
+	vlr_subscr_put(vsub);
+	vsub = NULL;
+	VERBOSE_ASSERT(paging_sent, == true, "%d");
+	VERBOSE_ASSERT(paging_stopped, == false, "%d");
+
+	btw("the subscriber and its pending request should remain");
+	vsub = vlr_subscr_find_by_imsi(net->vlr, imsi);
+	OSMO_ASSERT(vsub);
+	VERBOSE_ASSERT(llist_count(&vsub->cs.requests), == 1, "%d");
+	vlr_subscr_put(vsub);
+
+	btw("MS replies with Paging Response using TMSI, and VLR sends Auth Request with third key");
+	auth_request_sent = false;
+	auth_request_expect_rand = "e7c03ba7cf0e2fde82b2dc4d63077d42";
+	ms_sends_msg("06270703305882" "05f4" "03020100");
+	VERBOSE_ASSERT(auth_request_sent, == true, "%d");
+
+	btw("needs auth, not yet accepted");
+	EXPECT_ACCEPTED(false);
+	thwart_rx_non_initial_requests();
+
+	btw("MS sends Authen Response, VLR accepts and sends pending SMS");
+	dtap_expect_tx("09" /* SMS messages */
+		       "01" /* CP-DATA */
+		       "58" /* length */
+		       "01" /* Network to MS */
+		       "00" /* reference */
+		       /* originator (gsm411_send_sms() hardcodes this weird nr) */
+		       "0791" "447758100650" /* 447785016005 */
+		       "00" /* dest */
+		       /* SMS TPDU */
+		       "4c" /* len */
+		       "00" /* SMS deliver */
+		       "05806470f1" /* originating address 46071 */
+		       "00" /* TP-PID */
+		       "00" /* GSM default alphabet */
+		       "071010" /* Y-M-D (from wrapped gsm340_gen_scts())*/
+		       "000000" /* H-M-S */
+		       "00" /* GMT+0 */
+		       "44" /* data length */
+		       "5079da1e1ee7416937485e9ea7c965373d1d6683c270383b3d0e"
+		       "d3d36ff71c949e83c22072799e9687c5ec32a81d96afcbf4b4fb"
+		       "0c7ac3e9e9b7db05");
+	ms_sends_msg("0554" "a29514ae" /* 3rd vector's sres, s.a. */);
+	VERBOSE_ASSERT(dtap_tx_confirmed, == true, "%d");
+	VERBOSE_ASSERT(paging_stopped, == true, "%d");
+
+	btw("SMS was delivered, no requests pending for subscr");
+	vsub = vlr_subscr_find_by_imsi(net->vlr, imsi);
+	OSMO_ASSERT(vsub);
+	VERBOSE_ASSERT(llist_count(&vsub->cs.requests), == 0, "%d");
+	vlr_subscr_put(vsub);
+
+	btw("conn is still open to wait for SMS ack dance");
+	EXPECT_CONN_COUNT(1);
+
+	btw("MS replies with CP-ACK for received SMS");
+	ms_sends_msg("8904");
+	EXPECT_CONN_COUNT(1);
+
+	btw("MS also sends RP-ACK, MSC in turn sends CP-ACK for that");
+	dtap_expect_tx("0904");
+	expect_bssap_clear();
+	ms_sends_msg("890106020041020000");
+	VERBOSE_ASSERT(dtap_tx_confirmed, == true, "%d");
+	VERBOSE_ASSERT(bssap_clear_sent, == true, "%d");
+
+	btw("SMS is done, conn is gone");
+	bss_sends_clear_complete();
+	EXPECT_CONN_COUNT(0);
+
+	/* TODO: when the subscriber detaches, the vlr_subscr gets
+	 * deallocated and we no longer know the TMSI. This case is covered by
+	 * test_lu_unknown_tmsi(), so here I'd like to still have the TMSI.
+	BTW("subscriber detaches, using TMSI");
+	expect_bssap_clear();
+	ms_sends_msg("050130" "05f4" "03020100");
+	VERBOSE_ASSERT(bssap_clear_sent, == true, "%d");
+	bss_sends_clear_complete();
+	EXPECT_CONN_COUNT(0);
+	 */
+
+	BTW("subscriber sends LU Request, this time with the TMSI");
+	btw("Location Update request causes an Auth Req to MS");
+	lu_result_sent = RES_NONE;
+	auth_request_sent = false;
+	auth_request_expect_rand = "fa8f20b781b5881329d4fea26b1a3c51";
+	ms_sends_msg("0508020081680001"
+		     "30" /* <-- Revision Level == 1, i.e. is_r99 == false */
+		     "05f4" "03020100");
+	VERBOSE_ASSERT(auth_request_sent, == true, "%d");
+	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");
+	ms_sends_msg("05545afc8d72");
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT");
+	gsup_rx("10010809710000004026f00804036470f1",
+		"12010809710000004026f0");
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("HLR also sends GSUP _UPDATE_LOCATION_RESULT");
+	gsup_rx("06010809710000004026f0", NULL);
+
+	btw("a LU Accept with a new TMSI was sent, waiting for TMSI Realloc Compl");
+	EXPECT_CONN_COUNT(1);
+	VERBOSE_ASSERT(lu_result_sent, == RES_ACCEPT, "%d");
+	EXPECT_ACCEPTED(false);
+	thwart_rx_non_initial_requests();
+
+	btw("even though the TMSI is not acked, we can already find the subscr with it");
+	vsub = vlr_subscr_find_by_tmsi(net->vlr, 0x07060504);
+	VERBOSE_ASSERT(vsub != NULL, == true, "%d");
+	VERBOSE_ASSERT(strcmp(vsub->imsi, imsi), == 0, "%d");
+	VERBOSE_ASSERT(vsub->tmsi_new, == 0x07060504, "0x%08x");
+	VERBOSE_ASSERT(vsub->tmsi, == 0x03020100, "0x%08x");
+	vlr_subscr_put(vsub);
+
+	btw("MS sends TMSI Realloc Complete");
+	expect_bssap_clear();
+	ms_sends_msg("055b");
+	VERBOSE_ASSERT(bssap_clear_sent, == true, "%d");
+
+	btw("LU was successful, and the conn has already been closed");
+	bss_sends_clear_complete();
+	EXPECT_CONN_COUNT(0);
+
+	btw("subscriber has the new TMSI");
+	vsub = vlr_subscr_find_by_tmsi(net->vlr, 0x07060504);
+	VERBOSE_ASSERT(vsub != NULL, == true, "%d");
+	VERBOSE_ASSERT(strcmp(vsub->imsi, imsi), == 0, "%d");
+	VERBOSE_ASSERT(vsub->tmsi_new, == GSM_RESERVED_TMSI, "0x%08x");
+	VERBOSE_ASSERT(vsub->tmsi, == 0x07060504, "0x%08x");
+	vlr_subscr_put(vsub);
+
+	BTW("subscriber detaches, using new TMSI");
+	expect_bssap_clear();
+	ms_sends_msg("050130" "05f4" "07060504");
+	VERBOSE_ASSERT(bssap_clear_sent, == true, "%d");
+
+	bss_sends_clear_complete();
+	EXPECT_CONN_COUNT(0);
+	clear_vlr();
+	comment_end();
+}
+
+static void test_gsm_authen_imei()
+{
+	struct vlr_subscr *vsub;
+	const char *imsi = "901700000004620";
+
+	comment_start();
+
+	net->authentication_required = true;
+	net->vlr->cfg.check_imei_rqd = true;
+
+	btw("Location Update request causes a GSUP Send Auth Info request to HLR");
+	lu_result_sent = RES_NONE;
+	gsup_expect_tx("08010809710000004026f0");
+	ms_sends_msg("0508020081680001"
+		     "30" /* <-- Revision Level == 1, i.e. is_r99 == false */
+		     "089910070000006402");
+	OSMO_ASSERT(gsup_tx_confirmed);
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("from HLR, rx _SEND_AUTH_INFO_RESULT; VLR sends Auth Req to MS");
+	auth_request_sent = false;
+	auth_request_expect_rand = "585df1ae287f6e273dce07090d61320b";
+	auth_request_expect_autn = NULL;
+	/* Based on a Ki of 000102030405060708090a0b0c0d0e0f */
+	gsup_rx("0a"
+		/* imsi */
+		"0108" "09710000004026f0"
+		/* 5 auth vectors... */
+		/* TL    TL     rand */
+		"0322"  "2010" "585df1ae287f6e273dce07090d61320b"
+		/*       TL     sres       TL     kc */
+			"2104" "2d8b2c3e" "2208" "61855fb81fc2a800"
+		"0322"  "2010" "12aca96fb4ffdea5c985cbafa9b6e18b"
+			"2104" "20bde240" "2208" "07fa7502e07e1c00"
+		"0322"  "2010" "e7c03ba7cf0e2fde82b2dc4d63077d42"
+			"2104" "a29514ae" "2208" "e2b234f807886400"
+		"0322"  "2010" "fa8f20b781b5881329d4fea26b1a3c51"
+			"2104" "5afc8d72" "2208" "2392f14f709ae000"
+		"0322"  "2010" "0fd4cc8dbe8715d1f439e304edfd68dc"
+			"2104" "bc8d1c5b" "2208" "da7cdd6bfe2d7000",
+		NULL);
+	VERBOSE_ASSERT(auth_request_sent, == true, "%d");
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("If the HLR were to send a GSUP _UPDATE_LOCATION_RESULT we'd still reject");
+	gsup_rx("06010809710000004026f0", NULL);
+	EXPECT_ACCEPTED(false);
+	thwart_rx_non_initial_requests();
+	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");
+	ms_sends_msg("05542d8b2c3e");
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT");
+	gsup_rx("10010809710000004026f00804036470f1",
+		"12010809710000004026f0");
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("HLR also sends GSUP _UPDATE_LOCATION_RESULT, and we send an ID Request for the IMEI to the MS");
+	dtap_expect_tx("051802");
+	gsup_rx("06010809710000004026f0", NULL);
+
+	btw("We will only do business when the IMEI is known");
+	EXPECT_CONN_COUNT(1);
+	vsub = vlr_subscr_find_by_imsi(net->vlr, imsi);
+	OSMO_ASSERT(vsub);
+	VERBOSE_ASSERT(vsub->imei[0], == 0, "%d");
+	vlr_subscr_put(vsub);
+	EXPECT_ACCEPTED(false);
+	thwart_rx_non_initial_requests();
+
+	btw("MS replies with an Identity Response");
+	expect_bssap_clear();
+	ms_sends_msg("0559084a32244332244302");
+	VERBOSE_ASSERT(bssap_clear_sent, == true, "%d");
+
+	btw("LU was successful, and the conn has already been closed");
+	VERBOSE_ASSERT(lu_result_sent, == RES_ACCEPT, "%d");
+	bss_sends_clear_complete();
+	EXPECT_CONN_COUNT(0);
+
+	btw("Subscriber has the IMEI");
+	vsub = vlr_subscr_find_by_imsi(net->vlr, imsi);
+	OSMO_ASSERT(vsub);
+	VERBOSE_ASSERT(strcmp(vsub->imei, "423423423423420"), == 0, "%d");
+	vlr_subscr_put(vsub);
+
+	BTW("subscriber detaches");
+	expect_bssap_clear();
+	ms_sends_msg("050130089910070000006402");
+	VERBOSE_ASSERT(bssap_clear_sent, == true, "%d");
+
+	bss_sends_clear_complete();
+	EXPECT_CONN_COUNT(0);
+	clear_vlr();
+	comment_end();
+}
+
+static void test_gsm_authen_tmsi_imei()
+{
+	struct vlr_subscr *vsub;
+	const char *imsi = "901700000004620";
+
+	comment_start();
+
+	net->authentication_required = true;
+	net->vlr->cfg.assign_tmsi = true;
+	net->vlr->cfg.check_imei_rqd = true;
+
+	btw("Location Update request causes a GSUP Send Auth Info request to HLR");
+	lu_result_sent = RES_NONE;
+	gsup_expect_tx("08010809710000004026f0");
+	ms_sends_msg("0508020081680001"
+		     "30" /* <-- Revision Level == 1, i.e. is_r99 == false */
+		     "089910070000006402");
+	OSMO_ASSERT(gsup_tx_confirmed);
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("from HLR, rx _SEND_AUTH_INFO_RESULT; VLR sends Auth Req to MS");
+	auth_request_sent = false;
+	auth_request_expect_rand = "585df1ae287f6e273dce07090d61320b";
+	auth_request_expect_autn = NULL;
+	/* Based on a Ki of 000102030405060708090a0b0c0d0e0f */
+	gsup_rx("0a"
+		/* imsi */
+		"0108" "09710000004026f0"
+		/* 5 auth vectors... */
+		/* TL    TL     rand */
+		"0322"  "2010" "585df1ae287f6e273dce07090d61320b"
+		/*       TL     sres       TL     kc */
+			"2104" "2d8b2c3e" "2208" "61855fb81fc2a800"
+		"0322"  "2010" "12aca96fb4ffdea5c985cbafa9b6e18b"
+			"2104" "20bde240" "2208" "07fa7502e07e1c00"
+		"0322"  "2010" "e7c03ba7cf0e2fde82b2dc4d63077d42"
+			"2104" "a29514ae" "2208" "e2b234f807886400"
+		"0322"  "2010" "fa8f20b781b5881329d4fea26b1a3c51"
+			"2104" "5afc8d72" "2208" "2392f14f709ae000"
+		"0322"  "2010" "0fd4cc8dbe8715d1f439e304edfd68dc"
+			"2104" "bc8d1c5b" "2208" "da7cdd6bfe2d7000",
+		NULL);
+	VERBOSE_ASSERT(auth_request_sent, == true, "%d");
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("If the HLR were to send a GSUP _UPDATE_LOCATION_RESULT we'd still reject");
+	gsup_rx("06010809710000004026f0", NULL);
+	EXPECT_ACCEPTED(false);
+
+	thwart_rx_non_initial_requests();
+
+	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");
+	ms_sends_msg("05542d8b2c3e");
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT");
+	gsup_rx("10010809710000004026f00804036470f1",
+		"12010809710000004026f0");
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("HLR also sends GSUP _UPDATE_LOCATION_RESULT, and we send an ID Request for the IMEI to the MS");
+	dtap_expect_tx("051802");
+	gsup_rx("06010809710000004026f0", NULL);
+
+	btw("We will only do business when the IMEI is known");
+	EXPECT_CONN_COUNT(1);
+	vsub = vlr_subscr_find_by_imsi(net->vlr, imsi);
+	OSMO_ASSERT(vsub);
+	VERBOSE_ASSERT(vsub->imei[0], == 0, "%d");
+	vlr_subscr_put(vsub);
+	EXPECT_ACCEPTED(false);
+	thwart_rx_non_initial_requests();
+
+	btw("MS replies with an Identity Response");
+	ms_sends_msg("0559084a32244332244302");
+
+	btw("a LU Accept with a new TMSI was sent, waiting for TMSI Realloc Compl");
+	EXPECT_CONN_COUNT(1);
+	VERBOSE_ASSERT(lu_result_sent, == RES_ACCEPT, "%d");
+	EXPECT_ACCEPTED(false);
+	thwart_rx_non_initial_requests();
+
+	btw("even though the TMSI is not acked, we can already find the subscr with it");
+	vsub = vlr_subscr_find_by_tmsi(net->vlr, 0x03020100);
+	VERBOSE_ASSERT(vsub != NULL, == true, "%d");
+	VERBOSE_ASSERT(strcmp(vsub->imsi, imsi), == 0, "%d");
+	VERBOSE_ASSERT(vsub->tmsi_new, == 0x03020100, "0x%08x");
+	VERBOSE_ASSERT(vsub->tmsi, == GSM_RESERVED_TMSI, "0x%08x");
+	vlr_subscr_put(vsub);
+
+	btw("MS sends TMSI Realloc Complete");
+	expect_bssap_clear();
+	ms_sends_msg("055b");
+	VERBOSE_ASSERT(bssap_clear_sent, == true, "%d");
+
+	btw("LU was successful, and the conn has already been closed");
+	bss_sends_clear_complete();
+	EXPECT_CONN_COUNT(0);
+
+	btw("Subscriber has the IMEI and TMSI");
+	vsub = vlr_subscr_find_by_imsi(net->vlr, imsi);
+	OSMO_ASSERT(vsub);
+	VERBOSE_ASSERT(strcmp(vsub->imei, "423423423423420"), == 0, "%d");
+	VERBOSE_ASSERT(vsub->tmsi, == 0x03020100, "0x%08x");
+	vlr_subscr_put(vsub);
+
+	BTW("subscriber detaches, using TMSI");
+	expect_bssap_clear();
+	ms_sends_msg("050130" "05f4" "03020100");
+	VERBOSE_ASSERT(bssap_clear_sent, == true, "%d");
+
+	bss_sends_clear_complete();
+	EXPECT_CONN_COUNT(0);
+	clear_vlr();
+	comment_end();
+}
+
+static void test_gsm_milenage_authen()
+{
+	struct vlr_subscr *vsub;
+	const char *imsi = "901700000010650";
+
+	comment_start();
+
+	net->authentication_required = true;
+	rx_from_ran = RAN_GERAN_A;
+
+	btw("Location Update request causes a GSUP Send Auth Info request to HLR");
+	lu_result_sent = RES_NONE;
+	gsup_expect_tx("080108" "09710000000156f0");
+	ms_sends_msg("0508" /* MM LU */
+		     "7" /* ciph key seq: no key available */
+		     "0" /* LU type: normal */
+		     "ffffff" "0000" /* LAI, LAC */
+		     "30" /* classmark 1: GSM phase 2 */
+		     "089910070000106005" /* IMSI */
+		     );
+	OSMO_ASSERT(gsup_tx_confirmed);
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("from HLR, rx _SEND_AUTH_INFO_RESULT; VLR sends Auth Req to MS");
+	/* based on auc_3g:
+	 * K = 'EB215756028D60E3275E613320AEC880',
+	 * OPC = 'FB2A3D1B360F599ABAB99DB8669F8308'
+	 * SQN = 0
+	 */
+	auth_request_sent = false;
+	auth_request_expect_rand = "39fa2f4e3d523d8619a73b4f65c3e14d";
+	auth_request_expect_autn = NULL;
+	gsup_rx("0a"
+		/* imsi */
+		"0108" "09710000000156f0"
+		/* 5 auth vectors... */
+		/* TL    TL     rand */
+		"0362"  "2010" "39fa2f4e3d523d8619a73b4f65c3e14d"
+		/*       TL     sres       TL     kc */
+			"2104" "9b36efdf" "2208" "059a4f668f6fbe39"
+		/*       TL     3G IK */
+			"2310" "27497388b6cb044648f396aa155b95ef"
+		/*       TL     3G CK */
+			"2410" "f64735036e5871319c679f4742a75ea1"
+		/*       TL     AUTN */
+			"2510" "8704f5ba55f30000d2ee44b22c8ea919"
+		/*       TL     RES */
+			"2708" "e229c19e791f2e41"
+		"0362"  "2010" "c187a53a5e6b9d573cac7c74451fd46d"
+			"2104" "85aa3130" "2208" "d3d50a000bf04f6e"
+			"2310" "1159ec926a50e98c034a6b7d7c9f418d"
+			"2410" "df3a03d9ca5335641efc8e36d76cd20b"
+			"2510" "1843a645b98d00005b2d666af46c45d9"
+			"2708" "7db47cf7f81e4dc7"
+		"0362"  "2010" "efa9c29a9742148d5c9070348716e1bb"
+			"2104" "69d5f9fb" "2208" "3df176f0c29f1a3d"
+			"2310" "eb50e770ddcc3060101d2f43b6c2b884"
+			"2410" "76542abce5ff9345b0e8947f4c6e019c"
+			"2510" "f9375e6d41e1000096e7fe4ff1c27e39"
+			"2708" "706f996719ba609c"
+		,NULL);
+	VERBOSE_ASSERT(auth_request_sent, == true, "%d");
+	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");
+	ms_sends_msg("0554" "9b36efdf");
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT");
+	gsup_rx("10010809710000000156f00804032443f2",
+		"12010809710000000156f0");
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("HLR also sends GSUP _UPDATE_LOCATION_RESULT");
+	expect_bssap_clear();
+	gsup_rx("06010809710000000156f0", NULL);
+	VERBOSE_ASSERT(bssap_clear_sent, == true, "%d");
+
+	btw("LU was successful, and the conn has already been closed");
+	VERBOSE_ASSERT(lu_result_sent, == RES_ACCEPT, "%d");
+	bss_sends_clear_complete();
+	EXPECT_CONN_COUNT(0);
+
+	BTW("after a while, a new conn sends a CM Service Request. VLR responds with Auth Req, 2nd auth vector");
+	auth_request_sent = false;
+	auth_request_expect_rand = "c187a53a5e6b9d573cac7c74451fd46d";
+	auth_request_expect_autn = NULL;
+	cm_service_result_sent = RES_NONE;
+	ms_sends_msg("052478"
+		     "03305886" /* classmark 2: GSM phase 2 */
+		     "089910070000106005" /* IMSI */);
+	OSMO_ASSERT(g_conn);
+	OSMO_ASSERT(g_conn->fi);
+	OSMO_ASSERT(g_conn->vsub);
+	VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d");
+	VERBOSE_ASSERT(auth_request_sent, == true, "%d");
+
+	btw("needs auth, not yet accepted");
+	EXPECT_ACCEPTED(false);
+	thwart_rx_non_initial_requests();
+
+	btw("MS sends Authen Response, VLR accepts with a CM Service Accept");
+	gsup_expect_tx(NULL);
+	ms_sends_msg("0554" "85aa3130"); /* 2nd vector's sres, s.a. */
+	VERBOSE_ASSERT(cm_service_result_sent, == RES_ACCEPT, "%d");
+
+	/* Release connection */
+	expect_bssap_clear(RAN_GERAN_A);
+	conn_conclude_cm_service_req(g_conn, RAN_GERAN_A);
+
+	btw("all requests serviced, conn has been released");
+	bss_sends_clear_complete();
+	EXPECT_CONN_COUNT(0);
+
+	BTW("an SMS is sent, MS is paged");
+	paging_expect_imsi(imsi);
+	paging_sent = false;
+	vsub = vlr_subscr_find_by_imsi(net->vlr, imsi);
+	OSMO_ASSERT(vsub);
+	VERBOSE_ASSERT(llist_count(&vsub->cs.requests), == 0, "%d");
+
+	send_sms(vsub, vsub,
+		 "Privacy in residential applications is a desirable"
+		 " marketing option.");
+
+	VERBOSE_ASSERT(llist_count(&vsub->cs.requests), == 1, "%d");
+	vlr_subscr_put(vsub);
+	vsub = NULL;
+	VERBOSE_ASSERT(paging_sent, == true, "%d");
+	VERBOSE_ASSERT(paging_stopped, == false, "%d");
+
+	btw("the subscriber and its pending request should remain");
+	vsub = vlr_subscr_find_by_imsi(net->vlr, imsi);
+	OSMO_ASSERT(vsub);
+	VERBOSE_ASSERT(llist_count(&vsub->cs.requests), == 1, "%d");
+	vlr_subscr_put(vsub);
+
+	btw("MS replies with Paging Response, and VLR sends Auth Request with third key");
+	auth_request_sent = false;
+	auth_request_expect_rand = "efa9c29a9742148d5c9070348716e1bb";
+	auth_request_expect_autn = NULL;
+	ms_sends_msg("062707"
+		     "03305886" /* classmark 2 */
+		     "089910070000106005" /* IMSI */);
+	VERBOSE_ASSERT(auth_request_sent, == true, "%d");
+
+	btw("needs auth, not yet accepted");
+	EXPECT_ACCEPTED(false);
+	thwart_rx_non_initial_requests();
+
+	btw("MS sends Authen Response, VLR accepts and sends pending SMS");
+	dtap_expect_tx("09" /* SMS messages */
+		       "01" /* CP-DATA */
+		       "58" /* length */
+		       "01" /* Network to MS */
+		       "00" /* reference */
+		       /* originator (gsm411_send_sms() hardcodes this weird nr) */
+		       "0791" "447758100650" /* 447785016005 */
+		       "00" /* dest */
+		       /* SMS TPDU */
+		       "4c" /* len */
+		       "00" /* SMS deliver */
+		       "05802443f2" /* originating address 42342 */
+		       "00" /* TP-PID */
+		       "00" /* GSM default alphabet */
+		       "071010" /* Y-M-D (from wrapped gsm340_gen_scts())*/
+		       "000000" /* H-M-S */
+		       "00" /* GMT+0 */
+		       "44" /* data length */
+		       "5079da1e1ee7416937485e9ea7c965373d1d6683c270383b3d0e"
+		       "d3d36ff71c949e83c22072799e9687c5ec32a81d96afcbf4b4fb"
+		       "0c7ac3e9e9b7db05");
+	ms_sends_msg("0554" "69d5f9fb"); /* 3nd vector's sres, s.a. */
+	VERBOSE_ASSERT(dtap_tx_confirmed, == true, "%d");
+	VERBOSE_ASSERT(paging_stopped, == true, "%d");
+
+	btw("SMS was delivered, no requests pending for subscr");
+	vsub = vlr_subscr_find_by_imsi(net->vlr, imsi);
+	OSMO_ASSERT(vsub);
+	VERBOSE_ASSERT(llist_count(&vsub->cs.requests), == 0, "%d");
+	vlr_subscr_put(vsub);
+
+	btw("conn is still open to wait for SMS ack dance");
+	EXPECT_CONN_COUNT(1);
+
+	btw("MS replies with CP-ACK for received SMS");
+	ms_sends_msg("8904");
+	EXPECT_CONN_COUNT(1);
+
+	btw("MS also sends RP-ACK, MSC in turn sends CP-ACK for that");
+	dtap_expect_tx("0904");
+	expect_bssap_clear();
+	ms_sends_msg("890106020041020000");
+	VERBOSE_ASSERT(dtap_tx_confirmed, == true, "%d");
+	VERBOSE_ASSERT(bssap_clear_sent, == true, "%d");
+
+	btw("SMS is done, conn is gone");
+	bss_sends_clear_complete();
+	EXPECT_CONN_COUNT(0);
+
+	BTW("subscriber detaches");
+	expect_bssap_clear();
+	ms_sends_msg("050130"
+		     "089910070000106005" /* IMSI */);
+	VERBOSE_ASSERT(bssap_clear_sent, == true, "%d");
+
+	bss_sends_clear_complete();
+	EXPECT_CONN_COUNT(0);
+	clear_vlr();
+	comment_end();
+}
+
+static void test_wrong_sres_length()
+{
+	comment_start();
+	fake_time_start();
+
+	net->authentication_required = true;
+
+	btw("Location Update request causes a GSUP Send Auth Info request to HLR");
+	lu_result_sent = RES_NONE;
+	gsup_expect_tx("08010809710000004026f0");
+	ms_sends_msg("0508020081680001"
+		     "30" /* <-- Revision Level == 1, i.e. is_r99 == false */
+		     "089910070000006402");
+	OSMO_ASSERT(gsup_tx_confirmed);
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("from HLR, rx _SEND_AUTH_INFO_RESULT; VLR sends Auth Req to MS");
+	auth_request_sent = false;
+	auth_request_expect_rand = "585df1ae287f6e273dce07090d61320b";
+	auth_request_expect_autn = NULL;
+	/* Based on a Ki of 000102030405060708090a0b0c0d0e0f */
+	gsup_rx("0a"
+		/* imsi */
+		"0108" "09710000004026f0"
+		/* 5 auth vectors... */
+		/* TL    TL     rand */
+		"0322"  "2010" "585df1ae287f6e273dce07090d61320b"
+		/*       TL     sres       TL     kc */
+			"2104" "2d8b2c3e" "2208" "61855fb81fc2a800"
+		"0322"  "2010" "12aca96fb4ffdea5c985cbafa9b6e18b"
+			"2104" "20bde240" "2208" "07fa7502e07e1c00"
+		"0322"  "2010" "e7c03ba7cf0e2fde82b2dc4d63077d42"
+			"2104" "a29514ae" "2208" "e2b234f807886400"
+		"0322"  "2010" "fa8f20b781b5881329d4fea26b1a3c51"
+			"2104" "5afc8d72" "2208" "2392f14f709ae000"
+		"0322"  "2010" "0fd4cc8dbe8715d1f439e304edfd68dc"
+			"2104" "bc8d1c5b" "2208" "da7cdd6bfe2d7000",
+		NULL);
+	VERBOSE_ASSERT(auth_request_sent, == true, "%d");
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("If the HLR were to send a GSUP _UPDATE_LOCATION_RESULT we'd still reject");
+	gsup_rx("06010809710000004026f0", NULL);
+	EXPECT_ACCEPTED(false);
+
+	thwart_rx_non_initial_requests();
+
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("MS sends Authen Response with too short SRES data, auth is thwarted.");
+	gsup_expect_tx("0b010809710000004026f0"); /* OSMO_GSUP_MSGT_AUTH_FAIL_REPORT */
+	expect_bssap_clear();
+	ms_sends_msg("05542d8b2c");
+	VERBOSE_ASSERT(lu_result_sent, == RES_REJECT, "%d");
+
+	bss_sends_clear_complete();
+	EXPECT_CONN_COUNT(0);
+	clear_vlr();
+	comment_end();
+}
+
+msc_vlr_test_func_t msc_vlr_tests[] = {
+	test_gsm_authen,
+	test_gsm_authen_tmsi,
+	test_gsm_authen_imei,
+	test_gsm_authen_tmsi_imei,
+	test_gsm_milenage_authen,
+	test_wrong_sres_length,
+	NULL
+};
diff --git a/tests/msc_vlr/msc_vlr_test_gsm_authen.err b/tests/msc_vlr/msc_vlr_test_gsm_authen.err
new file mode 100644
index 0000000..51f7367
--- /dev/null
+++ b/tests/msc_vlr/msc_vlr_test_gsm_authen.err
@@ -0,0 +1,2173 @@
+full talloc report on 'msgb' (total      0 bytes in   1 blocks)
+talloc_total_blocks(tall_bsc_ctx) == 12
+
+===== test_gsm_authen
+- Location Update request causes a GSUP Send Auth Info request to HLR
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8)
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Updated ID
+DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000004620 type=IMSI ATTACH
+DMM LU/new-LAC: 1/23
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Allocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: is child of Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: rev=GSM net=GERAN Auth (no Ciph)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA
+DREF VLR subscr unknown usage increases to: 1
+DVLR set IMSI on subscriber; IMSI=901700000004620 id=901700000004620
+DVLR New subscr, IMSI: 901700000004620
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DREF VLR subscr IMSI:901700000004620 usage decreases to: 1
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Allocated
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
+DVLR GSUP tx: 08010809710000004026f0
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f0
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF IMSI:901700000004620: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  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: 0a010809710000004026f003222010585df1ae287f6e273dce07090d61320b21042d8b2c3e220861855fb81fc2a8000322201012aca96fb4ffdea5c985cbafa9b6e18b210420bde240220807fa7502e07e1c0003222010e7c03ba7cf0e2fde82b2dc4d63077d422104a29514ae2208e2b234f80788640003222010fa8f20b781b5881329d4fea26b1a3c5121045afc8d7222082392f14f709ae000032220100fd4cc8dbe8715d1f439e304edfd68dc2104bc8d1c5b2208da7cdd6bfe2d7000
+DVLR GSUP rx 191: 0a010809710000004026f003222010585df1ae287f6e273dce07090d61320b21042d8b2c3e220861855fb81fc2a8000322201012aca96fb4ffdea5c985cbafa9b6e18b210420bde240220807fa7502e07e1c0003222010e7c03ba7cf0e2fde82b2dc4d63077d422104a29514ae2208e2b234f80788640003222010fa8f20b781b5881329d4fea26b1a3c5121045afc8d7222082392f14f709ae000032220100fd4cc8dbe8715d1f439e304edfd68dc2104bc8d1c5b2208da7cdd6bfe2d7000
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: Received Event VLR_AUTH_E_HLR_SAI_ACK
+DVLR SUBSCR(IMSI:901700000004620) Received 5 auth tuples
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: state_chg to VLR_SUB_AS_WAIT_RESP
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_WAIT_RESP}: got auth tuple: use_count=1 key_seq=0 -- will use GSM AKA (is_r99=no, at->vec.auth_types=0x1)
+- sending GSM Auth Request for IMSI:901700000004620: tuple use_count=1 key_seq=0 auth_types=0x1 and...
+- ...rand=585df1ae287f6e273dce07090d61320b
+- ...expecting sres=2d8b2c3e
+DREF VLR subscr IMSI:901700000004620 usage decreases to: 1
+<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT: vlr_gsupc_read_cb() returns 0
+  auth_request_sent == 1
+  lu_result_sent == 0
+- If the HLR were to send a GSUP _UPDATE_LOCATION_RESULT we'd still reject
+<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: 06010809710000004026f0
+DVLR GSUP rx 11: 06010809710000004026f0
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_HLR_LU_RES
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_AUTH}: Event VLR_ULA_E_HLR_LU_RES not permitted
+DREF VLR subscr IMSI:901700000004620 usage decreases to: 1
+<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: vlr_gsupc_read_cb() returns 0
+msc_subscr_conn_is_accepted() == false
+  requests shall be thwarted
+DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5)
+DRLL subscr IMSI:901700000004620: Message not permitted for initial conn: GSM48_MT_CC_SETUP
+DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33)
+DRLL subscr IMSI:901700000004620: Message not permitted for initial conn: unknown 0x33
+DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19)
+DRLL subscr IMSI:901700000004620: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1
+DRLL Dispatching 04.08 message SMS:0x01 (0x9:0x1)
+DRLL subscr IMSI:901700000004620: Message not permitted for initial conn: SMS:0x01
+  lu_result_sent == 0
+- MS sends Authen Response, VLR accepts and sends GSUP LU Req to HLR
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_AUTH_RESP
+DREF IMSI:901700000004620: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14)
+DMM IMSI:901700000004620: MM GSM AUTHENTICATION RESPONSE (sres = 2d8b2c3e)
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP
+DVLR SUBSCR(IMSI:901700000004620) AUTH on GERAN received SRES/RES: 2d8b2c3e (4 bytes)
+DVLR SUBSCR(IMSI:901700000004620) AUTH established GSM security context
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result PASSED
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_AUTHENTICATED}: Freeing instance
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_AUTHENTICATED}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_ciph()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_node_4()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: Allocated
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START
+DVLR GSUP tx: 04010809710000004026f0280102
+GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000004026f0280102
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA
+DREF IMSI:901700000004620: MSC conn use - dtap == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  lu_result_sent == 0
+- HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT
+<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: 10010809710000004026f00804036470f1
+DVLR GSUP rx 17: 10010809710000004026f00804036470f1
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DVLR IMSI:901700000004620 has MSISDN:46071
+DVLR SUBSCR(MSISDN:46071) VLR: update for IMSI=901700000004620 (MSISDN=46071, used=2)
+DVLR GSUP tx: 12010809710000004026f0
+GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000004026f0
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+<-- 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: 06010809710000004026f0
+DVLR GSUP rx 11: 06010809710000004026f0
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Freeing instance
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: Allocated
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: Allocated
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(LU:901700000004620)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(LU:901700000004620)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Freeing instance
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Deallocated
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL
+- sending LU Accept for MSISDN:46071
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_DONE
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Freeing instance
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_ACCEPTED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:46071: MSC conn use + release == 1 (0x100: release)
+DREF VLR subscr MSISDN:46071 usage increases to: 4
+DREF VLR subscr MSISDN:46071 usage decreases to: 3
+- BSSAP Clear --RAN_GERAN_A--> MS
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+<-- 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
+  lu_result_sent == 1
+- BSS sends BSSMAP Clear Complete
+DREF MSISDN:46071: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Freeing instance
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Deallocated
+DRLL MSISDN:46071: Freeing subscriber connection
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+---
+- after a while, a new conn sends a CM Service Request. VLR responds with Auth Req, 2nd auth vector
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_CM_SERV_REQ
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_CM_SERV_REQ (0x5:0x24)
+DMM <- CM SERVICE REQUEST serv_type=0x08 MI(IMSI)=901700000004620
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_NEW}: Updated ID
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_INIT}: Allocated
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_INIT}: is child of Subscr_Conn(CM_SERVICE_REQ:901700000004620)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_INIT}: rev=GSM net=GERAN Auth (no Ciph)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_WAIT_AUTH
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Allocated
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: is child of Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620)
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_WAIT_RESP
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000004620){VLR_SUB_AS_WAIT_RESP}: got auth tuple: use_count=1 key_seq=1 -- will use GSM AKA (is_r99=no, at->vec.auth_types=0x1)
+- sending GSM Auth Request for MSISDN:46071: tuple use_count=1 key_seq=1 auth_types=0x1 and...
+- ...rand=12aca96fb4ffdea5c985cbafa9b6e18b
+- ...expecting sres=20bde240
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF MSISDN:46071: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  cm_service_result_sent == 0
+  auth_request_sent == 1
+- needs auth, not yet accepted
+msc_subscr_conn_is_accepted() == false
+  requests shall be thwarted
+DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_CC_SETUP
+DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: unknown 0x33
+DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1
+DRLL Dispatching 04.08 message SMS:0x01 (0x9:0x1)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: SMS:0x01
+- MS sends Authen Response, VLR accepts with a CM Service Accept
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_AUTH_RESP
+DREF MSISDN:46071: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14)
+DMM MSISDN:46071: MM GSM AUTHENTICATION RESPONSE (sres = 20bde240)
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000004620){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP
+DVLR SUBSCR(MSISDN:46071) AUTH on GERAN received SRES/RES: 20bde240 (4 bytes)
+DVLR SUBSCR(MSISDN:46071) AUTH established GSM security context
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000004620){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result PASSED
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000004620){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000004620){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000004620){VLR_SUB_AS_AUTHENTICATED}: Removing from parent Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620)
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000004620){VLR_SUB_AS_AUTHENTICATED}: Freeing instance
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000004620){VLR_SUB_AS_AUTHENTICATED}: Deallocated
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_WAIT_AUTH}: Received Event PR_ARQ_E_AUTH_RES
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2_post_ciph()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2_post_vlr()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_pres()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_trace()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_imei()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_WAIT_AUTH}: proc_arq_fsm_done(PASSED)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_WAIT_AUTH}: state_chg to PR_ARQ_S_DONE
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_DONE}: Process Access Request result: PASSED
+- sending CM Service Accept for MSISDN:46071
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_ACCEPTED
+DREF MSISDN:46071: MSC conn use + cm_service == 2 (0xa: dtap,cm_service)
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_ACCEPTED}: subscr_conn_fsm_has_active_transactions: still awaiting first request after a CM Service Request
+DREF MSISDN:46071: MSC conn use - dtap == 1 (0x8: cm_service)
+  cm_service_result_sent == 1
+- Concluding CM Service Request
+DREF MSISDN:46071: MSC conn use - cm_service == 0 (0x0: )
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:46071: MSC conn use + release == 1 (0x100: release)
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+- BSSAP Clear --RAN_GERAN_A--> MS
+  bssap_clear_sent == 1
+- all requests serviced, conn has been released
+- BSS sends BSSMAP Clear Complete
+DREF MSISDN:46071: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_DONE}: Removing from parent Subscr_Conn(CM_SERVICE_REQ:901700000004620)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_DONE}: Freeing instance
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_DONE}: Deallocated
+DRLL MSISDN:46071: Freeing subscriber connection
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+---
+- an SMS is sent, MS is paged
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+  llist_count(&vsub->cs.requests) == 0
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DMM Subscriber MSISDN:46071 not paged yet, start paging.
+  RAN_GERAN_A sends out paging request to IMSI 901700000004620, TMSI 0xffffffff, LAC 23
+  strcmp(paging_expecting_imsi, imsi) == 0
+DREF VLR subscr MSISDN:46071 usage increases to: 4
+  llist_count(&vsub->cs.requests) == 1
+DREF VLR subscr MSISDN:46071 usage decreases to: 3
+  paging_sent == 1
+  paging_stopped == 0
+- the subscriber and its pending request should remain
+DREF VLR subscr MSISDN:46071 usage increases to: 4
+  llist_count(&vsub->cs.requests) == 1
+DREF VLR subscr MSISDN:46071 usage decreases to: 3
+- MS replies with Paging Response, and VLR sends Auth Request with third key
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_RR_PAG_RESP
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_RR_PAG_RESP (0x6:0x27)
+DRR PAGING RESPONSE: MI(IMSI)=901700000004620
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_NEW}: Updated ID
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_INIT}: Allocated
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_INIT}: is child of Subscr_Conn(PAGING_RESP:901700000004620)
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_INIT}: rev=GSM net=GERAN Auth (no Ciph)
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START
+DREF VLR subscr MSISDN:46071 usage increases to: 4
+DREF VLR subscr MSISDN:46071 usage increases to: 5
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi()
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_WAIT_AUTH
+DVLR VLR_Authenticate(PAGING_RESP:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Allocated
+DVLR VLR_Authenticate(PAGING_RESP:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: is child of Process_Access_Request_VLR(PAGING_RESP:901700000004620)
+DVLR VLR_Authenticate(PAGING_RESP:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
+DVLR VLR_Authenticate(PAGING_RESP:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_WAIT_RESP
+DVLR VLR_Authenticate(PAGING_RESP:901700000004620){VLR_SUB_AS_WAIT_RESP}: got auth tuple: use_count=1 key_seq=2 -- will use GSM AKA (is_r99=no, at->vec.auth_types=0x1)
+- sending GSM Auth Request for MSISDN:46071: tuple use_count=1 key_seq=2 auth_types=0x1 and...
+- ...rand=e7c03ba7cf0e2fde82b2dc4d63077d42
+- ...expecting sres=a29514ae
+DREF VLR subscr MSISDN:46071 usage decreases to: 4
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF MSISDN:46071: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  auth_request_sent == 1
+- needs auth, not yet accepted
+msc_subscr_conn_is_accepted() == false
+  requests shall be thwarted
+DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_CC_SETUP
+DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: unknown 0x33
+DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1
+DRLL Dispatching 04.08 message SMS:0x01 (0x9:0x1)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: SMS:0x01
+- MS sends Authen Response, VLR accepts and sends pending SMS
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_AUTH_RESP
+DREF MSISDN:46071: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14)
+DMM MSISDN:46071: MM GSM AUTHENTICATION RESPONSE (sres = a29514ae)
+DVLR VLR_Authenticate(PAGING_RESP:901700000004620){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP
+DVLR SUBSCR(MSISDN:46071) AUTH on GERAN received SRES/RES: a29514ae (4 bytes)
+DVLR SUBSCR(MSISDN:46071) AUTH established GSM security context
+DVLR VLR_Authenticate(PAGING_RESP:901700000004620){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result PASSED
+DVLR VLR_Authenticate(PAGING_RESP:901700000004620){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
+DVLR VLR_Authenticate(PAGING_RESP:901700000004620){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR VLR_Authenticate(PAGING_RESP:901700000004620){VLR_SUB_AS_AUTHENTICATED}: Removing from parent Process_Access_Request_VLR(PAGING_RESP:901700000004620)
+DVLR VLR_Authenticate(PAGING_RESP:901700000004620){VLR_SUB_AS_AUTHENTICATED}: Freeing instance
+DVLR VLR_Authenticate(PAGING_RESP:901700000004620){VLR_SUB_AS_AUTHENTICATED}: Deallocated
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_WAIT_AUTH}: Received Event PR_ARQ_E_AUTH_RES
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2()
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2_post_ciph()
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2_post_vlr()
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_pres()
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_trace()
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_imei()
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_WAIT_AUTH}: proc_arq_fsm_done(PASSED)
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_WAIT_AUTH}: state_chg to PR_ARQ_S_DONE
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_DONE}: Process Access Request result: PASSED
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_ACCEPTED
+DPAG Paging success for MSISDN:46071 (event=0)
+DPAG Calling paging cbfn.
+DCC (ti 00 sub MSISDN:46071 callref 40000001) New transaction
+DREF VLR subscr MSISDN:46071 usage increases to: 5
+DREF MSISDN:46071: MSC conn use + trans_sms == 2 (0x22: dtap,trans_sms)
+DMSC msc_tx 91 bytes to MSISDN:46071 via RAN_GERAN_A
+- DTAP --RAN_GERAN_A--> MS: SMS:0x01: 09015801000791447758100650004c0005806470f1000007101000000000445079da1e1ee7416937485e9ea7c965373d1d6683c270383b3d0ed3d36ff71c949e83c22072799e9687c5ec32a81d96afcbf4b4fb0c7ac3e9e9b7db05
+- DTAP matches expected message
+DREF VLR subscr MSISDN:46071 usage decreases to: 4
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_ACCEPTED}: subscr_conn_fsm_has_active_transactions: connection still has active transaction: SMS
+DREF MSISDN:46071: MSC conn use - dtap == 1 (0x20: trans_sms)
+  dtap_tx_confirmed == 1
+  paging_stopped == 1
+- SMS was delivered, no requests pending for subscr
+DREF VLR subscr MSISDN:46071 usage increases to: 5
+  llist_count(&vsub->cs.requests) == 0
+DREF VLR subscr MSISDN:46071 usage decreases to: 4
+- conn is still open to wait for SMS ack dance
+  llist_count(&net->subscr_conns) == 1
+- MS replies with CP-ACK for received SMS
+  MSC <--RAN_GERAN_A-- MS: SMS:0x04
+DREF MSISDN:46071: MSC conn use + dtap == 2 (0x22: dtap,trans_sms)
+DRLL Dispatching 04.08 message SMS:0x04 (0x9:0x4)
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_COMMUNICATING
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_COMMUNICATING
+DREF MSISDN:46071: MSC conn use - dtap == 1 (0x20: trans_sms)
+  llist_count(&net->subscr_conns) == 1
+- MS also sends RP-ACK, MSC in turn sends CP-ACK for that
+  MSC <--RAN_GERAN_A-- MS: SMS:0x01
+DREF MSISDN:46071: MSC conn use + dtap == 2 (0x22: dtap,trans_sms)
+DRLL Dispatching 04.08 message SMS:0x01 (0x9:0x1)
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_COMMUNICATING}: Received Event SUBSCR_CONN_E_COMMUNICATING
+DMSC msc_tx 2 bytes to MSISDN:46071 via RAN_GERAN_A
+- DTAP --RAN_GERAN_A--> MS: SMS:0x04: 0904
+- DTAP matches expected message
+DREF VLR subscr MSISDN:46071 usage decreases to: 3
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+DREF MSISDN:46071: MSC conn use - trans_sms == 1 (0x2: dtap)
+DREF MSISDN:46071: MSC conn use - dtap == 0 (0x0: )
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_COMMUNICATING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_COMMUNICATING}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:46071: MSC conn use + release == 1 (0x100: release)
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+- BSSAP Clear --RAN_GERAN_A--> MS
+  dtap_tx_confirmed == 1
+  bssap_clear_sent == 1
+- SMS is done, conn is gone
+- BSS sends BSSMAP Clear Complete
+DREF MSISDN:46071: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_DONE}: Removing from parent Subscr_Conn(PAGING_RESP:901700000004620)
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_DONE}: Freeing instance
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_DONE}: Deallocated
+DRLL MSISDN:46071: Freeing subscriber connection
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+---
+- subscriber detaches
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_IMSI_DETACH_IND
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_IMSI_DETACH_IND (0x5:0x1)
+DMM IMSI DETACH INDICATION: MI(IMSI)=901700000004620
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+DMM IMSI DETACH for MSISDN:46071
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+DREF VLR subscr MSISDN:46071 usage decreases to: 0
+DREF freeing VLR subscr MSISDN:46071
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_CN_CLOSE
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF unknown: MSC conn use + release == 2 (0x101: compl_l3,release)
+- BSSAP Clear --RAN_GERAN_A--> MS
+DREF unknown: MSC conn use - compl_l3 == 1 (0x100: release)
+  bssap_clear_sent == 1
+- BSS sends BSSMAP Clear Complete
+DREF unknown: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DRLL Freeing subscriber connection with NULL subscriber
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+===== test_gsm_authen: SUCCESS
+
+full talloc report on 'msgb' (total      0 bytes in   1 blocks)
+talloc_total_blocks(tall_bsc_ctx) == 12
+
+===== test_gsm_authen_tmsi
+- Location Update request causes a GSUP Send Auth Info request to HLR
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8)
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Updated ID
+DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000004620 type=IMSI ATTACH
+DMM LU/new-LAC: 1/23
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Allocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: is child of Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: rev=GSM net=GERAN Auth (no Ciph)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA
+DREF VLR subscr unknown usage increases to: 1
+DVLR set IMSI on subscriber; IMSI=901700000004620 id=901700000004620
+DVLR New subscr, IMSI: 901700000004620
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DREF VLR subscr IMSI:901700000004620 usage decreases to: 1
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Allocated
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
+DVLR GSUP tx: 08010809710000004026f0
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f0
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF IMSI:901700000004620: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  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: 0a010809710000004026f003222010585df1ae287f6e273dce07090d61320b21042d8b2c3e220861855fb81fc2a8000322201012aca96fb4ffdea5c985cbafa9b6e18b210420bde240220807fa7502e07e1c0003222010e7c03ba7cf0e2fde82b2dc4d63077d422104a29514ae2208e2b234f80788640003222010fa8f20b781b5881329d4fea26b1a3c5121045afc8d7222082392f14f709ae000032220100fd4cc8dbe8715d1f439e304edfd68dc2104bc8d1c5b2208da7cdd6bfe2d7000
+DVLR GSUP rx 191: 0a010809710000004026f003222010585df1ae287f6e273dce07090d61320b21042d8b2c3e220861855fb81fc2a8000322201012aca96fb4ffdea5c985cbafa9b6e18b210420bde240220807fa7502e07e1c0003222010e7c03ba7cf0e2fde82b2dc4d63077d422104a29514ae2208e2b234f80788640003222010fa8f20b781b5881329d4fea26b1a3c5121045afc8d7222082392f14f709ae000032220100fd4cc8dbe8715d1f439e304edfd68dc2104bc8d1c5b2208da7cdd6bfe2d7000
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: Received Event VLR_AUTH_E_HLR_SAI_ACK
+DVLR SUBSCR(IMSI:901700000004620) Received 5 auth tuples
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: state_chg to VLR_SUB_AS_WAIT_RESP
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_WAIT_RESP}: got auth tuple: use_count=1 key_seq=0 -- will use GSM AKA (is_r99=no, at->vec.auth_types=0x1)
+- sending GSM Auth Request for IMSI:901700000004620: tuple use_count=1 key_seq=0 auth_types=0x1 and...
+- ...rand=585df1ae287f6e273dce07090d61320b
+- ...expecting sres=2d8b2c3e
+DREF VLR subscr IMSI:901700000004620 usage decreases to: 1
+<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT: vlr_gsupc_read_cb() returns 0
+  auth_request_sent == 1
+  lu_result_sent == 0
+- If the HLR were to send a GSUP _UPDATE_LOCATION_RESULT we'd still reject
+<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: 06010809710000004026f0
+DVLR GSUP rx 11: 06010809710000004026f0
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_HLR_LU_RES
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_AUTH}: Event VLR_ULA_E_HLR_LU_RES not permitted
+DREF VLR subscr IMSI:901700000004620 usage decreases to: 1
+<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: vlr_gsupc_read_cb() returns 0
+msc_subscr_conn_is_accepted() == false
+  requests shall be thwarted
+DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5)
+DRLL subscr IMSI:901700000004620: Message not permitted for initial conn: GSM48_MT_CC_SETUP
+DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33)
+DRLL subscr IMSI:901700000004620: Message not permitted for initial conn: unknown 0x33
+DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19)
+DRLL subscr IMSI:901700000004620: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1
+DRLL Dispatching 04.08 message SMS:0x01 (0x9:0x1)
+DRLL subscr IMSI:901700000004620: Message not permitted for initial conn: SMS:0x01
+  lu_result_sent == 0
+- MS sends Authen Response, VLR accepts and sends GSUP LU Req to HLR
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_AUTH_RESP
+DREF IMSI:901700000004620: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14)
+DMM IMSI:901700000004620: MM GSM AUTHENTICATION RESPONSE (sres = 2d8b2c3e)
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP
+DVLR SUBSCR(IMSI:901700000004620) AUTH on GERAN received SRES/RES: 2d8b2c3e (4 bytes)
+DVLR SUBSCR(IMSI:901700000004620) AUTH established GSM security context
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result PASSED
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_AUTHENTICATED}: Freeing instance
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_AUTHENTICATED}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_ciph()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_node_4()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: Allocated
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START
+DVLR GSUP tx: 04010809710000004026f0280102
+GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000004026f0280102
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA
+DREF IMSI:901700000004620: MSC conn use - dtap == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  lu_result_sent == 0
+- HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT
+<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: 10010809710000004026f00804036470f1
+DVLR GSUP rx 17: 10010809710000004026f00804036470f1
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DVLR IMSI:901700000004620 has MSISDN:46071
+DVLR SUBSCR(MSISDN:46071) VLR: update for IMSI=901700000004620 (MSISDN=46071, used=2)
+DVLR GSUP tx: 12010809710000004026f0
+GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000004026f0
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+<-- 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: 06010809710000004026f0
+DVLR GSUP rx 11: 06010809710000004026f0
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Freeing instance
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: Allocated
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: Allocated
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(LU:901700000004620)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(LU:901700000004620)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Freeing instance
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Deallocated
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: lu_compl_vlr_new_tmsi()
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_WAIT_TMSI_CNF
+- sending LU Accept for MSISDN:46071, with TMSI 0x03020100
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: vlr_gsupc_read_cb() returns 0
+- a LU Accept with a new TMSI was sent, waiting for TMSI Realloc Compl
+  llist_count(&net->subscr_conns) == 1
+  lu_result_sent == 1
+msc_subscr_conn_is_accepted() == false
+  requests shall be thwarted
+DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_CC_SETUP
+DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: unknown 0x33
+DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1
+DRLL Dispatching 04.08 message SMS:0x01 (0x9:0x1)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: SMS:0x01
+- even though the TMSI is not acked, we can already find the subscr with it
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+  vsub != NULL == 1
+  strcmp(vsub->imsi, imsi) == 0
+  vsub->tmsi_new == 0x03020100
+  vsub->tmsi == 0xffffffff
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+- MS sends TMSI Realloc Complete
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_TMSI_REALL_COMPL
+DREF MSISDN:46071: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_TMSI_REALL_COMPL (0x5:0x1b)
+DMM TMSI Reallocation Completed. Subscriber: MSISDN:46071
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_NEW_TMSI_ACK
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_TMSI_CNF}: Received Event LU_COMPL_VLR_E_NEW_TMSI_ACK
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_TMSI_CNF}: state_chg to LU_COMPL_VLR_S_DONE
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Freeing instance
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_ACCEPTED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:46071: MSC conn use + release == 2 (0x102: dtap,release)
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+- BSSAP Clear --RAN_GERAN_A--> MS
+DREF MSISDN:46071: MSC conn use - dtap == 1 (0x100: release)
+  bssap_clear_sent == 1
+- LU was successful, and the conn has already been closed
+- BSS sends BSSMAP Clear Complete
+DREF MSISDN:46071: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Freeing instance
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Deallocated
+DRLL MSISDN:46071: Freeing subscriber connection
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+- Subscriber has the new TMSI
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+  vsub != NULL == 1
+  strcmp(vsub->imsi, imsi) == 0
+  vsub->tmsi_new == 0xffffffff
+  vsub->tmsi == 0x03020100
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+---
+- after a while, a new conn sends a CM Service Request using above TMSI. VLR responds with Auth Req, 2nd auth vector
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_CM_SERV_REQ
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_CM_SERV_REQ (0x5:0x24)
+DMM <- CM SERVICE REQUEST serv_type=0x08 MI(TMSI)=50462976
+DMM Subscr_Conn(CM_SERVICE_REQ:50462976){SUBSCR_CONN_S_NEW}: Updated ID
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:50462976){PR_ARQ_S_INIT}: Allocated
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:50462976){PR_ARQ_S_INIT}: is child of Subscr_Conn(CM_SERVICE_REQ:50462976)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:50462976){PR_ARQ_S_INIT}: rev=GSM net=GERAN Auth (no Ciph)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:50462976){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:50462976){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:50462976){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_WAIT_AUTH
+DVLR VLR_Authenticate(CM_SERVICE_REQ:50462976){VLR_SUB_AS_NEEDS_AUTH}: Allocated
+DVLR VLR_Authenticate(CM_SERVICE_REQ:50462976){VLR_SUB_AS_NEEDS_AUTH}: is child of Process_Access_Request_VLR(CM_SERVICE_REQ:50462976)
+DVLR VLR_Authenticate(CM_SERVICE_REQ:50462976){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
+DVLR VLR_Authenticate(CM_SERVICE_REQ:50462976){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_WAIT_RESP
+DVLR VLR_Authenticate(CM_SERVICE_REQ:50462976){VLR_SUB_AS_WAIT_RESP}: got auth tuple: use_count=1 key_seq=1 -- will use GSM AKA (is_r99=no, at->vec.auth_types=0x1)
+- sending GSM Auth Request for MSISDN:46071: tuple use_count=1 key_seq=1 auth_types=0x1 and...
+- ...rand=12aca96fb4ffdea5c985cbafa9b6e18b
+- ...expecting sres=20bde240
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+DMM Subscr_Conn(CM_SERVICE_REQ:50462976){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(CM_SERVICE_REQ:50462976){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF MSISDN:46071: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(CM_SERVICE_REQ:50462976){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(CM_SERVICE_REQ:50462976){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  cm_service_result_sent == 0
+  auth_request_sent == 1
+- needs auth, not yet accepted
+msc_subscr_conn_is_accepted() == false
+  requests shall be thwarted
+DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_CC_SETUP
+DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: unknown 0x33
+DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1
+DRLL Dispatching 04.08 message SMS:0x01 (0x9:0x1)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: SMS:0x01
+- MS sends Authen Response, VLR accepts with a CM Service Accept
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_AUTH_RESP
+DREF MSISDN:46071: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14)
+DMM MSISDN:46071: MM GSM AUTHENTICATION RESPONSE (sres = 20bde240)
+DVLR VLR_Authenticate(CM_SERVICE_REQ:50462976){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP
+DVLR SUBSCR(MSISDN:46071) AUTH on GERAN received SRES/RES: 20bde240 (4 bytes)
+DVLR SUBSCR(MSISDN:46071) AUTH established GSM security context
+DVLR VLR_Authenticate(CM_SERVICE_REQ:50462976){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result PASSED
+DVLR VLR_Authenticate(CM_SERVICE_REQ:50462976){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
+DVLR VLR_Authenticate(CM_SERVICE_REQ:50462976){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR VLR_Authenticate(CM_SERVICE_REQ:50462976){VLR_SUB_AS_AUTHENTICATED}: Removing from parent Process_Access_Request_VLR(CM_SERVICE_REQ:50462976)
+DVLR VLR_Authenticate(CM_SERVICE_REQ:50462976){VLR_SUB_AS_AUTHENTICATED}: Freeing instance
+DVLR VLR_Authenticate(CM_SERVICE_REQ:50462976){VLR_SUB_AS_AUTHENTICATED}: Deallocated
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:50462976){PR_ARQ_S_WAIT_AUTH}: Received Event PR_ARQ_E_AUTH_RES
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:50462976){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:50462976){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2_post_ciph()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:50462976){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2_post_vlr()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:50462976){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_pres()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:50462976){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_trace()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:50462976){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_imei()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:50462976){PR_ARQ_S_WAIT_AUTH}: proc_arq_fsm_done(PASSED)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:50462976){PR_ARQ_S_WAIT_AUTH}: state_chg to PR_ARQ_S_DONE
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:50462976){PR_ARQ_S_DONE}: Process Access Request result: PASSED
+- sending CM Service Accept for MSISDN:46071
+DMM Subscr_Conn(CM_SERVICE_REQ:50462976){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_ACCEPTED
+DREF MSISDN:46071: MSC conn use + cm_service == 2 (0xa: dtap,cm_service)
+DMM Subscr_Conn(CM_SERVICE_REQ:50462976){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(CM_SERVICE_REQ:50462976){SUBSCR_CONN_S_ACCEPTED}: subscr_conn_fsm_has_active_transactions: still awaiting first request after a CM Service Request
+DREF MSISDN:46071: MSC conn use - dtap == 1 (0x8: cm_service)
+  cm_service_result_sent == 1
+- Concluding CM Service Request
+DREF MSISDN:46071: MSC conn use - cm_service == 0 (0x0: )
+DMM Subscr_Conn(CM_SERVICE_REQ:50462976){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(CM_SERVICE_REQ:50462976){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:46071: MSC conn use + release == 1 (0x100: release)
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+- BSSAP Clear --RAN_GERAN_A--> MS
+  bssap_clear_sent == 1
+- all requests serviced, conn has been released
+- BSS sends BSSMAP Clear Complete
+DREF MSISDN:46071: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(CM_SERVICE_REQ:50462976){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(CM_SERVICE_REQ:50462976){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(CM_SERVICE_REQ:50462976){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:50462976){PR_ARQ_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:50462976){PR_ARQ_S_DONE}: Removing from parent Subscr_Conn(CM_SERVICE_REQ:50462976)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:50462976){PR_ARQ_S_DONE}: Freeing instance
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:50462976){PR_ARQ_S_DONE}: Deallocated
+DRLL MSISDN:46071: Freeing subscriber connection
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+DMM Subscr_Conn(CM_SERVICE_REQ:50462976){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(CM_SERVICE_REQ:50462976){SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+---
+- an SMS is sent, MS is paged
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+  llist_count(&vsub->cs.requests) == 0
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DMM Subscriber MSISDN:46071 not paged yet, start paging.
+  RAN_GERAN_A sends out paging request to IMSI 901700000004620, TMSI 0x03020100, LAC 23
+  paging_expecting_tmsi == 0x03020100
+DREF VLR subscr MSISDN:46071 usage increases to: 4
+  llist_count(&vsub->cs.requests) == 1
+DREF VLR subscr MSISDN:46071 usage decreases to: 3
+  paging_sent == 1
+  paging_stopped == 0
+- the subscriber and its pending request should remain
+DREF VLR subscr MSISDN:46071 usage increases to: 4
+  llist_count(&vsub->cs.requests) == 1
+DREF VLR subscr MSISDN:46071 usage decreases to: 3
+- MS replies with Paging Response using TMSI, and VLR sends Auth Request with third key
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_RR_PAG_RESP
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_RR_PAG_RESP (0x6:0x27)
+DRR PAGING RESPONSE: MI(TMSI)=50462976
+DMM Subscr_Conn(PAGING_RESP:50462976){SUBSCR_CONN_S_NEW}: Updated ID
+DVLR Process_Access_Request_VLR(PAGING_RESP:50462976){PR_ARQ_S_INIT}: Allocated
+DVLR Process_Access_Request_VLR(PAGING_RESP:50462976){PR_ARQ_S_INIT}: is child of Subscr_Conn(PAGING_RESP:50462976)
+DVLR Process_Access_Request_VLR(PAGING_RESP:50462976){PR_ARQ_S_INIT}: rev=GSM net=GERAN Auth (no Ciph)
+DVLR Process_Access_Request_VLR(PAGING_RESP:50462976){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START
+DREF VLR subscr MSISDN:46071 usage increases to: 4
+DREF VLR subscr MSISDN:46071 usage increases to: 5
+DVLR Process_Access_Request_VLR(PAGING_RESP:50462976){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi()
+DVLR Process_Access_Request_VLR(PAGING_RESP:50462976){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_WAIT_AUTH
+DVLR VLR_Authenticate(PAGING_RESP:50462976){VLR_SUB_AS_NEEDS_AUTH}: Allocated
+DVLR VLR_Authenticate(PAGING_RESP:50462976){VLR_SUB_AS_NEEDS_AUTH}: is child of Process_Access_Request_VLR(PAGING_RESP:50462976)
+DVLR VLR_Authenticate(PAGING_RESP:50462976){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
+DVLR VLR_Authenticate(PAGING_RESP:50462976){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_WAIT_RESP
+DVLR VLR_Authenticate(PAGING_RESP:50462976){VLR_SUB_AS_WAIT_RESP}: got auth tuple: use_count=1 key_seq=2 -- will use GSM AKA (is_r99=no, at->vec.auth_types=0x1)
+- sending GSM Auth Request for MSISDN:46071: tuple use_count=1 key_seq=2 auth_types=0x1 and...
+- ...rand=e7c03ba7cf0e2fde82b2dc4d63077d42
+- ...expecting sres=a29514ae
+DREF VLR subscr MSISDN:46071 usage decreases to: 4
+DMM Subscr_Conn(PAGING_RESP:50462976){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(PAGING_RESP:50462976){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF MSISDN:46071: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(PAGING_RESP:50462976){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(PAGING_RESP:50462976){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  auth_request_sent == 1
+- needs auth, not yet accepted
+msc_subscr_conn_is_accepted() == false
+  requests shall be thwarted
+DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_CC_SETUP
+DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: unknown 0x33
+DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1
+DRLL Dispatching 04.08 message SMS:0x01 (0x9:0x1)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: SMS:0x01
+- MS sends Authen Response, VLR accepts and sends pending SMS
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_AUTH_RESP
+DREF MSISDN:46071: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14)
+DMM MSISDN:46071: MM GSM AUTHENTICATION RESPONSE (sres = a29514ae)
+DVLR VLR_Authenticate(PAGING_RESP:50462976){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP
+DVLR SUBSCR(MSISDN:46071) AUTH on GERAN received SRES/RES: a29514ae (4 bytes)
+DVLR SUBSCR(MSISDN:46071) AUTH established GSM security context
+DVLR VLR_Authenticate(PAGING_RESP:50462976){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result PASSED
+DVLR VLR_Authenticate(PAGING_RESP:50462976){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
+DVLR VLR_Authenticate(PAGING_RESP:50462976){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR VLR_Authenticate(PAGING_RESP:50462976){VLR_SUB_AS_AUTHENTICATED}: Removing from parent Process_Access_Request_VLR(PAGING_RESP:50462976)
+DVLR VLR_Authenticate(PAGING_RESP:50462976){VLR_SUB_AS_AUTHENTICATED}: Freeing instance
+DVLR VLR_Authenticate(PAGING_RESP:50462976){VLR_SUB_AS_AUTHENTICATED}: Deallocated
+DVLR Process_Access_Request_VLR(PAGING_RESP:50462976){PR_ARQ_S_WAIT_AUTH}: Received Event PR_ARQ_E_AUTH_RES
+DVLR Process_Access_Request_VLR(PAGING_RESP:50462976){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2()
+DVLR Process_Access_Request_VLR(PAGING_RESP:50462976){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2_post_ciph()
+DVLR Process_Access_Request_VLR(PAGING_RESP:50462976){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2_post_vlr()
+DVLR Process_Access_Request_VLR(PAGING_RESP:50462976){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_pres()
+DVLR Process_Access_Request_VLR(PAGING_RESP:50462976){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_trace()
+DVLR Process_Access_Request_VLR(PAGING_RESP:50462976){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_imei()
+DVLR Process_Access_Request_VLR(PAGING_RESP:50462976){PR_ARQ_S_WAIT_AUTH}: proc_arq_fsm_done(PASSED)
+DVLR Process_Access_Request_VLR(PAGING_RESP:50462976){PR_ARQ_S_WAIT_AUTH}: state_chg to PR_ARQ_S_DONE
+DVLR Process_Access_Request_VLR(PAGING_RESP:50462976){PR_ARQ_S_DONE}: Process Access Request result: PASSED
+DMM Subscr_Conn(PAGING_RESP:50462976){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_ACCEPTED
+DPAG Paging success for MSISDN:46071 (event=0)
+DPAG Calling paging cbfn.
+DCC (ti 00 sub MSISDN:46071 callref 40000002) New transaction
+DREF VLR subscr MSISDN:46071 usage increases to: 5
+DREF MSISDN:46071: MSC conn use + trans_sms == 2 (0x22: dtap,trans_sms)
+DMSC msc_tx 91 bytes to MSISDN:46071 via RAN_GERAN_A
+- DTAP --RAN_GERAN_A--> MS: SMS:0x01: 09015801000791447758100650004c0005806470f1000007101000000000445079da1e1ee7416937485e9ea7c965373d1d6683c270383b3d0ed3d36ff71c949e83c22072799e9687c5ec32a81d96afcbf4b4fb0c7ac3e9e9b7db05
+- DTAP matches expected message
+DREF VLR subscr MSISDN:46071 usage decreases to: 4
+DMM Subscr_Conn(PAGING_RESP:50462976){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(PAGING_RESP:50462976){SUBSCR_CONN_S_ACCEPTED}: subscr_conn_fsm_has_active_transactions: connection still has active transaction: SMS
+DREF MSISDN:46071: MSC conn use - dtap == 1 (0x20: trans_sms)
+  dtap_tx_confirmed == 1
+  paging_stopped == 1
+- SMS was delivered, no requests pending for subscr
+DREF VLR subscr MSISDN:46071 usage increases to: 5
+  llist_count(&vsub->cs.requests) == 0
+DREF VLR subscr MSISDN:46071 usage decreases to: 4
+- conn is still open to wait for SMS ack dance
+  llist_count(&net->subscr_conns) == 1
+- MS replies with CP-ACK for received SMS
+  MSC <--RAN_GERAN_A-- MS: SMS:0x04
+DREF MSISDN:46071: MSC conn use + dtap == 2 (0x22: dtap,trans_sms)
+DRLL Dispatching 04.08 message SMS:0x04 (0x9:0x4)
+DMM Subscr_Conn(PAGING_RESP:50462976){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_COMMUNICATING
+DMM Subscr_Conn(PAGING_RESP:50462976){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_COMMUNICATING
+DREF MSISDN:46071: MSC conn use - dtap == 1 (0x20: trans_sms)
+  llist_count(&net->subscr_conns) == 1
+- MS also sends RP-ACK, MSC in turn sends CP-ACK for that
+  MSC <--RAN_GERAN_A-- MS: SMS:0x01
+DREF MSISDN:46071: MSC conn use + dtap == 2 (0x22: dtap,trans_sms)
+DRLL Dispatching 04.08 message SMS:0x01 (0x9:0x1)
+DMM Subscr_Conn(PAGING_RESP:50462976){SUBSCR_CONN_S_COMMUNICATING}: Received Event SUBSCR_CONN_E_COMMUNICATING
+DMSC msc_tx 2 bytes to MSISDN:46071 via RAN_GERAN_A
+- DTAP --RAN_GERAN_A--> MS: SMS:0x04: 0904
+- DTAP matches expected message
+DREF VLR subscr MSISDN:46071 usage decreases to: 3
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+DREF MSISDN:46071: MSC conn use - trans_sms == 1 (0x2: dtap)
+DREF MSISDN:46071: MSC conn use - dtap == 0 (0x0: )
+DMM Subscr_Conn(PAGING_RESP:50462976){SUBSCR_CONN_S_COMMUNICATING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(PAGING_RESP:50462976){SUBSCR_CONN_S_COMMUNICATING}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:46071: MSC conn use + release == 1 (0x100: release)
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+- BSSAP Clear --RAN_GERAN_A--> MS
+  dtap_tx_confirmed == 1
+  bssap_clear_sent == 1
+- SMS is done, conn is gone
+- BSS sends BSSMAP Clear Complete
+DREF MSISDN:46071: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(PAGING_RESP:50462976){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(PAGING_RESP:50462976){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(PAGING_RESP:50462976){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR Process_Access_Request_VLR(PAGING_RESP:50462976){PR_ARQ_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR Process_Access_Request_VLR(PAGING_RESP:50462976){PR_ARQ_S_DONE}: Removing from parent Subscr_Conn(PAGING_RESP:50462976)
+DVLR Process_Access_Request_VLR(PAGING_RESP:50462976){PR_ARQ_S_DONE}: Freeing instance
+DVLR Process_Access_Request_VLR(PAGING_RESP:50462976){PR_ARQ_S_DONE}: Deallocated
+DRLL MSISDN:46071: Freeing subscriber connection
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+DMM Subscr_Conn(PAGING_RESP:50462976){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(PAGING_RESP:50462976){SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+---
+- subscriber sends LU Request, this time with the TMSI
+- Location Update request causes an Auth Req to MS
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8)
+DMM Subscr_Conn(LU:50462976){SUBSCR_CONN_S_NEW}: Updated ID
+DMM LOCATION UPDATING REQUEST: MI(TMSI)=50462976 type=IMSI ATTACH
+DMM LU/new-LAC: 1/23
+DVLR vlr_lu_fsm(LU:50462976){VLR_ULA_S_IDLE}: Allocated
+DVLR vlr_lu_fsm(LU:50462976){VLR_ULA_S_IDLE}: is child of Subscr_Conn(LU:50462976)
+DVLR vlr_lu_fsm(LU:50462976){VLR_ULA_S_IDLE}: rev=GSM net=GERAN Auth (no Ciph)
+DVLR vlr_lu_fsm(LU:50462976){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+DVLR vlr_lu_fsm(LU:50462976){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
+DVLR vlr_lu_fsm(LU:50462976){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH
+DVLR VLR_Authenticate(LU:50462976){VLR_SUB_AS_NEEDS_AUTH}: Allocated
+DVLR VLR_Authenticate(LU:50462976){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(LU:50462976)
+DVLR VLR_Authenticate(LU:50462976){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
+DVLR VLR_Authenticate(LU:50462976){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_WAIT_RESP
+DVLR VLR_Authenticate(LU:50462976){VLR_SUB_AS_WAIT_RESP}: got auth tuple: use_count=1 key_seq=3 -- will use GSM AKA (is_r99=no, at->vec.auth_types=0x1)
+- sending GSM Auth Request for MSISDN:46071: tuple use_count=1 key_seq=3 auth_types=0x1 and...
+- ...rand=fa8f20b781b5881329d4fea26b1a3c51
+- ...expecting sres=5afc8d72
+DMM Subscr_Conn(LU:50462976){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(LU:50462976){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF MSISDN:46071: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(LU:50462976){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:50462976){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  auth_request_sent == 1
+  lu_result_sent == 0
+- MS sends Authen Response, VLR accepts and sends GSUP LU Req to HLR
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_AUTH_RESP
+DREF MSISDN:46071: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14)
+DMM MSISDN:46071: MM GSM AUTHENTICATION RESPONSE (sres = 5afc8d72)
+DVLR VLR_Authenticate(LU:50462976){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP
+DVLR SUBSCR(MSISDN:46071) AUTH on GERAN received SRES/RES: 5afc8d72 (4 bytes)
+DVLR SUBSCR(MSISDN:46071) AUTH established GSM security context
+DVLR VLR_Authenticate(LU:50462976){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result PASSED
+DVLR VLR_Authenticate(LU:50462976){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
+DVLR VLR_Authenticate(LU:50462976){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR VLR_Authenticate(LU:50462976){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(LU:50462976)
+DVLR VLR_Authenticate(LU:50462976){VLR_SUB_AS_AUTHENTICATED}: Freeing instance
+DVLR VLR_Authenticate(LU:50462976){VLR_SUB_AS_AUTHENTICATED}: Deallocated
+DVLR vlr_lu_fsm(LU:50462976){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES
+DVLR vlr_lu_fsm(LU:50462976){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth()
+DVLR vlr_lu_fsm(LU:50462976){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_ciph()
+DVLR vlr_lu_fsm(LU:50462976){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_node_4()
+DVLR vlr_lu_fsm(LU:50462976){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
+DVLR upd_hlr_vlr_fsm(LU:50462976){UPD_HLR_VLR_S_INIT}: Allocated
+DVLR upd_hlr_vlr_fsm(LU:50462976){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(LU:50462976)
+DVLR upd_hlr_vlr_fsm(LU:50462976){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START
+DVLR GSUP tx: 04010809710000004026f0280102
+GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000004026f0280102
+DVLR upd_hlr_vlr_fsm(LU:50462976){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA
+DREF MSISDN:46071: MSC conn use - dtap == 0 (0x0: )
+DMM Subscr_Conn(LU:50462976){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:50462976){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  lu_result_sent == 0
+- HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT
+<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: 10010809710000004026f00804036470f1
+DVLR GSUP rx 17: 10010809710000004026f00804036470f1
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DVLR IMSI:901700000004620 has MSISDN:46071
+DVLR SUBSCR(MSISDN:46071) VLR: update for IMSI=901700000004620 (MSISDN=46071, used=3)
+DVLR GSUP tx: 12010809710000004026f0
+GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000004026f0
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+<-- 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: 06010809710000004026f0
+DVLR GSUP rx 11: 06010809710000004026f0
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DVLR vlr_lu_fsm(LU:50462976){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES
+DVLR upd_hlr_vlr_fsm(LU:50462976){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK
+DVLR upd_hlr_vlr_fsm(LU:50462976){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE
+DVLR upd_hlr_vlr_fsm(LU:50462976){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR upd_hlr_vlr_fsm(LU:50462976){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:50462976)
+DVLR upd_hlr_vlr_fsm(LU:50462976){UPD_HLR_VLR_S_DONE}: Freeing instance
+DVLR upd_hlr_vlr_fsm(LU:50462976){UPD_HLR_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:50462976){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL
+DVLR vlr_lu_fsm(LU:50462976){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL
+DVLR lu_compl_vlr_fsm(LU:50462976){LU_COMPL_VLR_S_INIT}: Allocated
+DVLR lu_compl_vlr_fsm(LU:50462976){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(LU:50462976)
+DVLR lu_compl_vlr_fsm(LU:50462976){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START
+DVLR lu_compl_vlr_fsm(LU:50462976){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES
+DVLR sub_pres_vlr_fsm(LU:50462976){SUB_PRES_VLR_S_INIT}: Allocated
+DVLR sub_pres_vlr_fsm(LU:50462976){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(LU:50462976)
+DVLR sub_pres_vlr_fsm(LU:50462976){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START
+DVLR sub_pres_vlr_fsm(LU:50462976){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE
+DVLR sub_pres_vlr_fsm(LU:50462976){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR sub_pres_vlr_fsm(LU:50462976){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(LU:50462976)
+DVLR sub_pres_vlr_fsm(LU:50462976){SUB_PRES_VLR_S_DONE}: Freeing instance
+DVLR sub_pres_vlr_fsm(LU:50462976){SUB_PRES_VLR_S_DONE}: Deallocated
+DVLR lu_compl_vlr_fsm(LU:50462976){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL
+DVLR lu_compl_vlr_fsm(LU:50462976){LU_COMPL_VLR_S_WAIT_SUB_PRES}: lu_compl_vlr_new_tmsi()
+DVLR lu_compl_vlr_fsm(LU:50462976){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_WAIT_TMSI_CNF
+- sending LU Accept for MSISDN:46071, with TMSI 0x07060504
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: vlr_gsupc_read_cb() returns 0
+- a LU Accept with a new TMSI was sent, waiting for TMSI Realloc Compl
+  llist_count(&net->subscr_conns) == 1
+  lu_result_sent == 1
+msc_subscr_conn_is_accepted() == false
+  requests shall be thwarted
+DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_CC_SETUP
+DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: unknown 0x33
+DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1
+DRLL Dispatching 04.08 message SMS:0x01 (0x9:0x1)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: SMS:0x01
+- even though the TMSI is not acked, we can already find the subscr with it
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+  vsub != NULL == 1
+  strcmp(vsub->imsi, imsi) == 0
+  vsub->tmsi_new == 0x07060504
+  vsub->tmsi == 0x03020100
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+- MS sends TMSI Realloc Complete
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_TMSI_REALL_COMPL
+DREF MSISDN:46071: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_TMSI_REALL_COMPL (0x5:0x1b)
+DMM TMSI Reallocation Completed. Subscriber: MSISDN:46071
+DVLR vlr_lu_fsm(LU:50462976){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_NEW_TMSI_ACK
+DVLR lu_compl_vlr_fsm(LU:50462976){LU_COMPL_VLR_S_WAIT_TMSI_CNF}: Received Event LU_COMPL_VLR_E_NEW_TMSI_ACK
+DVLR lu_compl_vlr_fsm(LU:50462976){LU_COMPL_VLR_S_WAIT_TMSI_CNF}: state_chg to LU_COMPL_VLR_S_DONE
+DVLR vlr_lu_fsm(LU:50462976){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS
+DVLR lu_compl_vlr_fsm(LU:50462976){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR lu_compl_vlr_fsm(LU:50462976){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:50462976)
+DVLR lu_compl_vlr_fsm(LU:50462976){LU_COMPL_VLR_S_DONE}: Freeing instance
+DVLR lu_compl_vlr_fsm(LU:50462976){LU_COMPL_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:50462976){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE
+DMM Subscr_Conn(LU:50462976){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_ACCEPTED
+DMM Subscr_Conn(LU:50462976){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(LU:50462976){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:50462976){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:46071: MSC conn use + release == 2 (0x102: dtap,release)
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+- BSSAP Clear --RAN_GERAN_A--> MS
+DREF MSISDN:46071: MSC conn use - dtap == 1 (0x100: release)
+  bssap_clear_sent == 1
+- LU was successful, and the conn has already been closed
+- BSS sends BSSMAP Clear Complete
+DREF MSISDN:46071: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(LU:50462976){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:50462976){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(LU:50462976){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR vlr_lu_fsm(LU:50462976){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR vlr_lu_fsm(LU:50462976){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(LU:50462976)
+DVLR vlr_lu_fsm(LU:50462976){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT
+DVLR vlr_lu_fsm(LU:50462976){VLR_ULA_S_DONE}: Freeing instance
+DVLR vlr_lu_fsm(LU:50462976){VLR_ULA_S_DONE}: Deallocated
+DRLL MSISDN:46071: Freeing subscriber connection
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+DMM Subscr_Conn(LU:50462976){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(LU:50462976){SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+- subscriber has the new TMSI
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+  vsub != NULL == 1
+  strcmp(vsub->imsi, imsi) == 0
+  vsub->tmsi_new == 0xffffffff
+  vsub->tmsi == 0x07060504
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+---
+- subscriber detaches, using new TMSI
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_IMSI_DETACH_IND
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_IMSI_DETACH_IND (0x5:0x1)
+DMM IMSI DETACH INDICATION: MI(TMSI)=117835012
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+DMM IMSI DETACH for MSISDN:46071
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+DREF VLR subscr MSISDN:46071 usage decreases to: 0
+DREF freeing VLR subscr MSISDN:46071
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_CN_CLOSE
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF unknown: MSC conn use + release == 2 (0x101: compl_l3,release)
+- BSSAP Clear --RAN_GERAN_A--> MS
+DREF unknown: MSC conn use - compl_l3 == 1 (0x100: release)
+  bssap_clear_sent == 1
+- BSS sends BSSMAP Clear Complete
+DREF unknown: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DRLL Freeing subscriber connection with NULL subscriber
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+===== test_gsm_authen_tmsi: SUCCESS
+
+full talloc report on 'msgb' (total      0 bytes in   1 blocks)
+talloc_total_blocks(tall_bsc_ctx) == 12
+
+===== test_gsm_authen_imei
+- Location Update request causes a GSUP Send Auth Info request to HLR
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8)
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Updated ID
+DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000004620 type=IMSI ATTACH
+DMM LU/new-LAC: 1/23
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Allocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: is child of Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: rev=GSM net=GERAN Auth (no Ciph)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA
+DREF VLR subscr unknown usage increases to: 1
+DVLR set IMSI on subscriber; IMSI=901700000004620 id=901700000004620
+DVLR New subscr, IMSI: 901700000004620
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DREF VLR subscr IMSI:901700000004620 usage decreases to: 1
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Allocated
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
+DVLR GSUP tx: 08010809710000004026f0
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f0
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF IMSI:901700000004620: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  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: 0a010809710000004026f003222010585df1ae287f6e273dce07090d61320b21042d8b2c3e220861855fb81fc2a8000322201012aca96fb4ffdea5c985cbafa9b6e18b210420bde240220807fa7502e07e1c0003222010e7c03ba7cf0e2fde82b2dc4d63077d422104a29514ae2208e2b234f80788640003222010fa8f20b781b5881329d4fea26b1a3c5121045afc8d7222082392f14f709ae000032220100fd4cc8dbe8715d1f439e304edfd68dc2104bc8d1c5b2208da7cdd6bfe2d7000
+DVLR GSUP rx 191: 0a010809710000004026f003222010585df1ae287f6e273dce07090d61320b21042d8b2c3e220861855fb81fc2a8000322201012aca96fb4ffdea5c985cbafa9b6e18b210420bde240220807fa7502e07e1c0003222010e7c03ba7cf0e2fde82b2dc4d63077d422104a29514ae2208e2b234f80788640003222010fa8f20b781b5881329d4fea26b1a3c5121045afc8d7222082392f14f709ae000032220100fd4cc8dbe8715d1f439e304edfd68dc2104bc8d1c5b2208da7cdd6bfe2d7000
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: Received Event VLR_AUTH_E_HLR_SAI_ACK
+DVLR SUBSCR(IMSI:901700000004620) Received 5 auth tuples
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: state_chg to VLR_SUB_AS_WAIT_RESP
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_WAIT_RESP}: got auth tuple: use_count=1 key_seq=0 -- will use GSM AKA (is_r99=no, at->vec.auth_types=0x1)
+- sending GSM Auth Request for IMSI:901700000004620: tuple use_count=1 key_seq=0 auth_types=0x1 and...
+- ...rand=585df1ae287f6e273dce07090d61320b
+- ...expecting sres=2d8b2c3e
+DREF VLR subscr IMSI:901700000004620 usage decreases to: 1
+<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT: vlr_gsupc_read_cb() returns 0
+  auth_request_sent == 1
+  lu_result_sent == 0
+- If the HLR were to send a GSUP _UPDATE_LOCATION_RESULT we'd still reject
+<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: 06010809710000004026f0
+DVLR GSUP rx 11: 06010809710000004026f0
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_HLR_LU_RES
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_AUTH}: Event VLR_ULA_E_HLR_LU_RES not permitted
+DREF VLR subscr IMSI:901700000004620 usage decreases to: 1
+<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: vlr_gsupc_read_cb() returns 0
+msc_subscr_conn_is_accepted() == false
+  requests shall be thwarted
+DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5)
+DRLL subscr IMSI:901700000004620: Message not permitted for initial conn: GSM48_MT_CC_SETUP
+DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33)
+DRLL subscr IMSI:901700000004620: Message not permitted for initial conn: unknown 0x33
+DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19)
+DRLL subscr IMSI:901700000004620: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1
+DRLL Dispatching 04.08 message SMS:0x01 (0x9:0x1)
+DRLL subscr IMSI:901700000004620: Message not permitted for initial conn: SMS:0x01
+  lu_result_sent == 0
+- MS sends Authen Response, VLR accepts and sends GSUP LU Req to HLR
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_AUTH_RESP
+DREF IMSI:901700000004620: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14)
+DMM IMSI:901700000004620: MM GSM AUTHENTICATION RESPONSE (sres = 2d8b2c3e)
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP
+DVLR SUBSCR(IMSI:901700000004620) AUTH on GERAN received SRES/RES: 2d8b2c3e (4 bytes)
+DVLR SUBSCR(IMSI:901700000004620) AUTH established GSM security context
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result PASSED
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_AUTHENTICATED}: Freeing instance
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_AUTHENTICATED}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_ciph()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_node_4()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: Allocated
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START
+DVLR GSUP tx: 04010809710000004026f0280102
+GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000004026f0280102
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA
+DREF IMSI:901700000004620: MSC conn use - dtap == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  lu_result_sent == 0
+- HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT
+<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: 10010809710000004026f00804036470f1
+DVLR GSUP rx 17: 10010809710000004026f00804036470f1
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DVLR IMSI:901700000004620 has MSISDN:46071
+DVLR SUBSCR(MSISDN:46071) VLR: update for IMSI=901700000004620 (MSISDN=46071, used=2)
+DVLR GSUP tx: 12010809710000004026f0
+GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000004026f0
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+<-- 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, and we send an ID Request for the IMEI to the MS
+<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: 06010809710000004026f0
+DVLR GSUP rx 11: 06010809710000004026f0
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Freeing instance
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: Allocated
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: Allocated
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(LU:901700000004620)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(LU:901700000004620)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Freeing instance
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Deallocated
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_WAIT_IMEI
+DMSC msc_tx 3 bytes to MSISDN:46071 via RAN_GERAN_A
+- DTAP --RAN_GERAN_A--> MS: GSM48_MT_MM_ID_REQ: 051802
+- DTAP matches expected message
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: vlr_gsupc_read_cb() returns 0
+- We will only do business when the IMEI is known
+  llist_count(&net->subscr_conns) == 1
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+  vsub->imei[0] == 0
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+msc_subscr_conn_is_accepted() == false
+  requests shall be thwarted
+DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_CC_SETUP
+DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: unknown 0x33
+DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1
+DRLL Dispatching 04.08 message SMS:0x01 (0x9:0x1)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: SMS:0x01
+- MS replies with an Identity Response
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_ID_RESP
+DREF MSISDN:46071: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_ID_RESP (0x5:0x19)
+DMM IDENTITY RESPONSE: MI(IMEI)=423423423423420
+DVLR set IMEI on subscriber; IMSI=901700000004620 IMEI=423423423423420
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_ID_IMEI
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_IMEI}: Received Event LU_COMPL_VLR_E_IMEI_CHECK_ACK
+- sending LU Accept for MSISDN:46071
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_IMEI}: state_chg to LU_COMPL_VLR_S_DONE
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Freeing instance
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_ACCEPTED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:46071: MSC conn use + release == 2 (0x102: dtap,release)
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+- BSSAP Clear --RAN_GERAN_A--> MS
+DREF MSISDN:46071: MSC conn use - dtap == 1 (0x100: release)
+  bssap_clear_sent == 1
+- LU was successful, and the conn has already been closed
+  lu_result_sent == 1
+- BSS sends BSSMAP Clear Complete
+DREF MSISDN:46071: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Freeing instance
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Deallocated
+DRLL MSISDN:46071: Freeing subscriber connection
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+- Subscriber has the IMEI
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+  strcmp(vsub->imei, "423423423423420") == 0
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+---
+- subscriber detaches
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_IMSI_DETACH_IND
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_IMSI_DETACH_IND (0x5:0x1)
+DMM IMSI DETACH INDICATION: MI(IMSI)=901700000004620
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+DMM IMSI DETACH for MSISDN:46071
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+DREF VLR subscr MSISDN:46071 usage decreases to: 0
+DREF freeing VLR subscr MSISDN:46071
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_CN_CLOSE
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF unknown: MSC conn use + release == 2 (0x101: compl_l3,release)
+- BSSAP Clear --RAN_GERAN_A--> MS
+DREF unknown: MSC conn use - compl_l3 == 1 (0x100: release)
+  bssap_clear_sent == 1
+- BSS sends BSSMAP Clear Complete
+DREF unknown: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DRLL Freeing subscriber connection with NULL subscriber
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+===== test_gsm_authen_imei: SUCCESS
+
+full talloc report on 'msgb' (total      0 bytes in   1 blocks)
+talloc_total_blocks(tall_bsc_ctx) == 12
+
+===== test_gsm_authen_tmsi_imei
+- Location Update request causes a GSUP Send Auth Info request to HLR
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8)
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Updated ID
+DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000004620 type=IMSI ATTACH
+DMM LU/new-LAC: 1/23
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Allocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: is child of Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: rev=GSM net=GERAN Auth (no Ciph)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA
+DREF VLR subscr unknown usage increases to: 1
+DVLR set IMSI on subscriber; IMSI=901700000004620 id=901700000004620
+DVLR New subscr, IMSI: 901700000004620
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DREF VLR subscr IMSI:901700000004620 usage decreases to: 1
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Allocated
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
+DVLR GSUP tx: 08010809710000004026f0
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f0
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF IMSI:901700000004620: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  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: 0a010809710000004026f003222010585df1ae287f6e273dce07090d61320b21042d8b2c3e220861855fb81fc2a8000322201012aca96fb4ffdea5c985cbafa9b6e18b210420bde240220807fa7502e07e1c0003222010e7c03ba7cf0e2fde82b2dc4d63077d422104a29514ae2208e2b234f80788640003222010fa8f20b781b5881329d4fea26b1a3c5121045afc8d7222082392f14f709ae000032220100fd4cc8dbe8715d1f439e304edfd68dc2104bc8d1c5b2208da7cdd6bfe2d7000
+DVLR GSUP rx 191: 0a010809710000004026f003222010585df1ae287f6e273dce07090d61320b21042d8b2c3e220861855fb81fc2a8000322201012aca96fb4ffdea5c985cbafa9b6e18b210420bde240220807fa7502e07e1c0003222010e7c03ba7cf0e2fde82b2dc4d63077d422104a29514ae2208e2b234f80788640003222010fa8f20b781b5881329d4fea26b1a3c5121045afc8d7222082392f14f709ae000032220100fd4cc8dbe8715d1f439e304edfd68dc2104bc8d1c5b2208da7cdd6bfe2d7000
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: Received Event VLR_AUTH_E_HLR_SAI_ACK
+DVLR SUBSCR(IMSI:901700000004620) Received 5 auth tuples
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: state_chg to VLR_SUB_AS_WAIT_RESP
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_WAIT_RESP}: got auth tuple: use_count=1 key_seq=0 -- will use GSM AKA (is_r99=no, at->vec.auth_types=0x1)
+- sending GSM Auth Request for IMSI:901700000004620: tuple use_count=1 key_seq=0 auth_types=0x1 and...
+- ...rand=585df1ae287f6e273dce07090d61320b
+- ...expecting sres=2d8b2c3e
+DREF VLR subscr IMSI:901700000004620 usage decreases to: 1
+<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT: vlr_gsupc_read_cb() returns 0
+  auth_request_sent == 1
+  lu_result_sent == 0
+- If the HLR were to send a GSUP _UPDATE_LOCATION_RESULT we'd still reject
+<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: 06010809710000004026f0
+DVLR GSUP rx 11: 06010809710000004026f0
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_HLR_LU_RES
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_AUTH}: Event VLR_ULA_E_HLR_LU_RES not permitted
+DREF VLR subscr IMSI:901700000004620 usage decreases to: 1
+<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: vlr_gsupc_read_cb() returns 0
+msc_subscr_conn_is_accepted() == false
+  requests shall be thwarted
+DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5)
+DRLL subscr IMSI:901700000004620: Message not permitted for initial conn: GSM48_MT_CC_SETUP
+DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33)
+DRLL subscr IMSI:901700000004620: Message not permitted for initial conn: unknown 0x33
+DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19)
+DRLL subscr IMSI:901700000004620: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1
+DRLL Dispatching 04.08 message SMS:0x01 (0x9:0x1)
+DRLL subscr IMSI:901700000004620: Message not permitted for initial conn: SMS:0x01
+  lu_result_sent == 0
+- MS sends Authen Response, VLR accepts and sends GSUP LU Req to HLR
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_AUTH_RESP
+DREF IMSI:901700000004620: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14)
+DMM IMSI:901700000004620: MM GSM AUTHENTICATION RESPONSE (sres = 2d8b2c3e)
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP
+DVLR SUBSCR(IMSI:901700000004620) AUTH on GERAN received SRES/RES: 2d8b2c3e (4 bytes)
+DVLR SUBSCR(IMSI:901700000004620) AUTH established GSM security context
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result PASSED
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_AUTHENTICATED}: Freeing instance
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_AUTHENTICATED}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_ciph()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_node_4()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: Allocated
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START
+DVLR GSUP tx: 04010809710000004026f0280102
+GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000004026f0280102
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA
+DREF IMSI:901700000004620: MSC conn use - dtap == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  lu_result_sent == 0
+- HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT
+<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: 10010809710000004026f00804036470f1
+DVLR GSUP rx 17: 10010809710000004026f00804036470f1
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DVLR IMSI:901700000004620 has MSISDN:46071
+DVLR SUBSCR(MSISDN:46071) VLR: update for IMSI=901700000004620 (MSISDN=46071, used=2)
+DVLR GSUP tx: 12010809710000004026f0
+GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000004026f0
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+<-- 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, and we send an ID Request for the IMEI to the MS
+<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: 06010809710000004026f0
+DVLR GSUP rx 11: 06010809710000004026f0
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Freeing instance
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: Allocated
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: Allocated
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(LU:901700000004620)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(LU:901700000004620)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Freeing instance
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Deallocated
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_WAIT_IMEI_TMSI
+DMSC msc_tx 3 bytes to MSISDN:46071 via RAN_GERAN_A
+- DTAP --RAN_GERAN_A--> MS: GSM48_MT_MM_ID_REQ: 051802
+- DTAP matches expected message
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: vlr_gsupc_read_cb() returns 0
+- We will only do business when the IMEI is known
+  llist_count(&net->subscr_conns) == 1
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+  vsub->imei[0] == 0
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+msc_subscr_conn_is_accepted() == false
+  requests shall be thwarted
+DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_CC_SETUP
+DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: unknown 0x33
+DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1
+DRLL Dispatching 04.08 message SMS:0x01 (0x9:0x1)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: SMS:0x01
+- MS replies with an Identity Response
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_ID_RESP
+DREF MSISDN:46071: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_ID_RESP (0x5:0x19)
+DMM IDENTITY RESPONSE: MI(IMEI)=423423423423420
+DVLR set IMEI on subscriber; IMSI=901700000004620 IMEI=423423423423420
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_ID_IMEI
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_IMEI_TMSI}: Received Event LU_COMPL_VLR_E_IMEI_CHECK_ACK
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_IMEI_TMSI}: lu_compl_vlr_new_tmsi()
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_IMEI_TMSI}: state_chg to LU_COMPL_VLR_S_WAIT_TMSI_CNF
+- sending LU Accept for MSISDN:46071, with TMSI 0x03020100
+DREF MSISDN:46071: MSC conn use - dtap == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+- a LU Accept with a new TMSI was sent, waiting for TMSI Realloc Compl
+  llist_count(&net->subscr_conns) == 1
+  lu_result_sent == 1
+msc_subscr_conn_is_accepted() == false
+  requests shall be thwarted
+DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_CC_SETUP
+DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: unknown 0x33
+DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1
+DRLL Dispatching 04.08 message SMS:0x01 (0x9:0x1)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: SMS:0x01
+- even though the TMSI is not acked, we can already find the subscr with it
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+  vsub != NULL == 1
+  strcmp(vsub->imsi, imsi) == 0
+  vsub->tmsi_new == 0x03020100
+  vsub->tmsi == 0xffffffff
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+- MS sends TMSI Realloc Complete
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_TMSI_REALL_COMPL
+DREF MSISDN:46071: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_TMSI_REALL_COMPL (0x5:0x1b)
+DMM TMSI Reallocation Completed. Subscriber: MSISDN:46071
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_NEW_TMSI_ACK
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_TMSI_CNF}: Received Event LU_COMPL_VLR_E_NEW_TMSI_ACK
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_TMSI_CNF}: state_chg to LU_COMPL_VLR_S_DONE
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Freeing instance
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_ACCEPTED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:46071: MSC conn use + release == 2 (0x102: dtap,release)
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+- BSSAP Clear --RAN_GERAN_A--> MS
+DREF MSISDN:46071: MSC conn use - dtap == 1 (0x100: release)
+  bssap_clear_sent == 1
+- LU was successful, and the conn has already been closed
+- BSS sends BSSMAP Clear Complete
+DREF MSISDN:46071: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Freeing instance
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Deallocated
+DRLL MSISDN:46071: Freeing subscriber connection
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+- Subscriber has the IMEI and TMSI
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+  strcmp(vsub->imei, "423423423423420") == 0
+  vsub->tmsi == 0x03020100
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+---
+- subscriber detaches, using TMSI
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_IMSI_DETACH_IND
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_IMSI_DETACH_IND (0x5:0x1)
+DMM IMSI DETACH INDICATION: MI(TMSI)=50462976
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+DMM IMSI DETACH for MSISDN:46071
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+DREF VLR subscr MSISDN:46071 usage decreases to: 0
+DREF freeing VLR subscr MSISDN:46071
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_CN_CLOSE
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF unknown: MSC conn use + release == 2 (0x101: compl_l3,release)
+- BSSAP Clear --RAN_GERAN_A--> MS
+DREF unknown: MSC conn use - compl_l3 == 1 (0x100: release)
+  bssap_clear_sent == 1
+- BSS sends BSSMAP Clear Complete
+DREF unknown: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DRLL Freeing subscriber connection with NULL subscriber
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+===== test_gsm_authen_tmsi_imei: SUCCESS
+
+full talloc report on 'msgb' (total      0 bytes in   1 blocks)
+talloc_total_blocks(tall_bsc_ctx) == 12
+
+===== test_gsm_milenage_authen
+- Location Update request causes a GSUP Send Auth Info request to HLR
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8)
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_NEW}: Updated ID
+DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000010650 type=NORMAL
+DMM LU/new-LAC: 0/23
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: Allocated
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: is child of Subscr_Conn(LU:901700000010650)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: rev=GSM net=GERAN Auth (no Ciph)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA
+DREF VLR subscr unknown usage increases to: 1
+DVLR set IMSI on subscriber; IMSI=901700000010650 id=901700000010650
+DVLR New subscr, IMSI: 901700000010650
+DREF VLR subscr IMSI:901700000010650 usage increases to: 2
+DREF VLR subscr IMSI:901700000010650 usage decreases to: 1
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Allocated
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(LU:901700000010650)
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
+DVLR GSUP tx: 08010809710000000156f0
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f0
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF IMSI:901700000010650: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  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: 0a010809710000000156f00362201039fa2f4e3d523d8619a73b4f65c3e14d21049b36efdf2208059a4f668f6fbe39231027497388b6cb044648f396aa155b95ef2410f64735036e5871319c679f4742a75ea125108704f5ba55f30000d2ee44b22c8ea9192708e229c19e791f2e4103622010c187a53a5e6b9d573cac7c74451fd46d210485aa31302208d3d50a000bf04f6e23101159ec926a50e98c034a6b7d7c9f418d2410df3a03d9ca5335641efc8e36d76cd20b25101843a645b98d00005b2d666af46c45d927087db47cf7f81e4dc703622010efa9c29a9742148d5c9070348716e1bb210469d5f9fb22083df176f0c29f1a3d2310eb50e770ddcc3060101d2f43b6c2b884241076542abce5ff9345b0e8947f4c6e019c2510f9375e6d41e1000096e7fe4ff1c27e392708706f996719ba609c
+DVLR GSUP rx 311: 0a010809710000000156f00362201039fa2f4e3d523d8619a73b4f65c3e14d21049b36efdf2208059a4f668f6fbe39231027497388b6cb044648f396aa155b95ef2410f64735036e5871319c679f4742a75ea125108704f5ba55f30000d2ee44b22c8ea9192708e229c19e791f2e4103622010c187a53a5e6b9d573cac7c74451fd46d210485aa31302208d3d50a000bf04f6e23101159ec926a50e98c034a6b7d7c9f418d2410df3a03d9ca5335641efc8e36d76cd20b25101843a645b98d00005b2d666af46c45d927087db47cf7f81e4dc703622010efa9c29a9742148d5c9070348716e1bb210469d5f9fb22083df176f0c29f1a3d2310eb50e770ddcc3060101d2f43b6c2b884241076542abce5ff9345b0e8947f4c6e019c2510f9375e6d41e1000096e7fe4ff1c27e392708706f996719ba609c
+DREF VLR subscr IMSI:901700000010650 usage increases to: 2
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: Received Event VLR_AUTH_E_HLR_SAI_ACK
+DVLR SUBSCR(IMSI:901700000010650) Received 3 auth tuples
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: state_chg to VLR_SUB_AS_WAIT_RESP
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_WAIT_RESP}: got auth tuple: use_count=1 key_seq=0 -- will use GSM AKA (is_r99=no, at->vec.auth_types=0x3)
+- sending GSM Auth Request for IMSI:901700000010650: tuple use_count=1 key_seq=0 auth_types=0x3 and...
+- ...rand=39fa2f4e3d523d8619a73b4f65c3e14d
+- ...expecting sres=9b36efdf
+DREF VLR subscr IMSI:901700000010650 usage decreases to: 1
+<-- 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
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_AUTH_RESP
+DREF IMSI:901700000010650: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14)
+DMM IMSI:901700000010650: MM GSM AUTHENTICATION RESPONSE (sres = 9b36efdf)
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP
+DVLR SUBSCR(IMSI:901700000010650) AUTH on GERAN received SRES/RES: 9b36efdf (4 bytes)
+DVLR SUBSCR(IMSI:901700000010650) AUTH established GSM security context
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result PASSED
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(LU:901700000010650)
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Freeing instance
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth()
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_ciph()
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_node_4()
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_INIT}: Allocated
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000010650)
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START
+DVLR GSUP tx: 04010809710000000156f0280102
+GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000000156f0280102
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA
+DREF IMSI:901700000010650: MSC conn use - dtap == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  lu_result_sent == 0
+- HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT
+<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: 10010809710000000156f00804032443f2
+DVLR GSUP rx 17: 10010809710000000156f00804032443f2
+DREF VLR subscr IMSI:901700000010650 usage increases to: 2
+DVLR IMSI:901700000010650 has MSISDN:42342
+DVLR SUBSCR(MSISDN:42342) VLR: update for IMSI=901700000010650 (MSISDN=42342, used=2)
+DVLR GSUP tx: 12010809710000000156f0
+GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000000156f0
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+<-- 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: 06010809710000000156f0
+DVLR GSUP rx 11: 06010809710000000156f0
+DREF VLR subscr MSISDN:42342 usage increases to: 2
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000010650)
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_DONE}: Freeing instance
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_INIT}: Allocated
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000010650)
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_INIT}: Allocated
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(LU:901700000010650)
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(LU:901700000010650)
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_DONE}: Freeing instance
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_DONE}: Deallocated
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL
+- sending LU Accept for MSISDN:42342
+DREF VLR subscr MSISDN:42342 usage increases to: 3
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_DONE
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000010650)
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_DONE}: Freeing instance
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_ACCEPTED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:42342: MSC conn use + release == 1 (0x100: release)
+DREF VLR subscr MSISDN:42342 usage increases to: 4
+DREF VLR subscr MSISDN:42342 usage decreases to: 3
+- BSSAP Clear --RAN_GERAN_A--> MS
+DREF VLR subscr MSISDN:42342 usage decreases to: 2
+<-- 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
+  lu_result_sent == 1
+- BSS sends BSSMAP Clear Complete
+DREF MSISDN:42342: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(LU:901700000010650)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: Freeing instance
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: Deallocated
+DRLL MSISDN:42342: Freeing subscriber connection
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+---
+- after a while, a new conn sends a CM Service Request. VLR responds with Auth Req, 2nd auth vector
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_CM_SERV_REQ
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_CM_SERV_REQ (0x5:0x24)
+DMM <- CM SERVICE REQUEST serv_type=0x08 MI(IMSI)=901700000010650
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_NEW}: Updated ID
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: Allocated
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: is child of Subscr_Conn(CM_SERVICE_REQ:901700000010650)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: rev=GSM net=GERAN Auth (no Ciph)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START
+DREF VLR subscr MSISDN:42342 usage increases to: 2
+DREF VLR subscr MSISDN:42342 usage increases to: 3
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_WAIT_AUTH
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Allocated
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: is child of Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650)
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_WAIT_RESP
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_WAIT_RESP}: got auth tuple: use_count=1 key_seq=1 -- will use GSM AKA (is_r99=no, at->vec.auth_types=0x3)
+- sending GSM Auth Request for MSISDN:42342: tuple use_count=1 key_seq=1 auth_types=0x3 and...
+- ...rand=c187a53a5e6b9d573cac7c74451fd46d
+- ...expecting sres=85aa3130
+DREF VLR subscr MSISDN:42342 usage decreases to: 2
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF MSISDN:42342: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  cm_service_result_sent == 0
+  auth_request_sent == 1
+- needs auth, not yet accepted
+msc_subscr_conn_is_accepted() == false
+  requests shall be thwarted
+DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5)
+DRLL subscr MSISDN:42342: Message not permitted for initial conn: GSM48_MT_CC_SETUP
+DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33)
+DRLL subscr MSISDN:42342: Message not permitted for initial conn: unknown 0x33
+DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19)
+DRLL subscr MSISDN:42342: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1
+DRLL Dispatching 04.08 message SMS:0x01 (0x9:0x1)
+DRLL subscr MSISDN:42342: Message not permitted for initial conn: SMS:0x01
+- MS sends Authen Response, VLR accepts with a CM Service Accept
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_AUTH_RESP
+DREF MSISDN:42342: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14)
+DMM MSISDN:42342: MM GSM AUTHENTICATION RESPONSE (sres = 85aa3130)
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP
+DVLR SUBSCR(MSISDN:42342) AUTH on GERAN received SRES/RES: 85aa3130 (4 bytes)
+DVLR SUBSCR(MSISDN:42342) AUTH established GSM security context
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result PASSED
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Removing from parent Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650)
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Freeing instance
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Deallocated
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: Received Event PR_ARQ_E_AUTH_RES
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2_post_ciph()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2_post_vlr()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_pres()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_trace()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_imei()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: proc_arq_fsm_done(PASSED)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: state_chg to PR_ARQ_S_DONE
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_DONE}: Process Access Request result: PASSED
+- sending CM Service Accept for MSISDN:42342
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_ACCEPTED
+DREF MSISDN:42342: MSC conn use + cm_service == 2 (0xa: dtap,cm_service)
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_ACCEPTED}: subscr_conn_fsm_has_active_transactions: still awaiting first request after a CM Service Request
+DREF MSISDN:42342: MSC conn use - dtap == 1 (0x8: cm_service)
+  cm_service_result_sent == 1
+- Concluding CM Service Request
+DREF MSISDN:42342: MSC conn use - cm_service == 0 (0x0: )
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:42342: MSC conn use + release == 1 (0x100: release)
+DREF VLR subscr MSISDN:42342 usage increases to: 3
+DREF VLR subscr MSISDN:42342 usage decreases to: 2
+- BSSAP Clear --RAN_GERAN_A--> MS
+  bssap_clear_sent == 1
+- all requests serviced, conn has been released
+- BSS sends BSSMAP Clear Complete
+DREF MSISDN:42342: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_DONE}: Removing from parent Subscr_Conn(CM_SERVICE_REQ:901700000010650)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_DONE}: Freeing instance
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_DONE}: Deallocated
+DRLL MSISDN:42342: Freeing subscriber connection
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+---
+- an SMS is sent, MS is paged
+DREF VLR subscr MSISDN:42342 usage increases to: 2
+  llist_count(&vsub->cs.requests) == 0
+DREF VLR subscr MSISDN:42342 usage increases to: 3
+DMM Subscriber MSISDN:42342 not paged yet, start paging.
+  RAN_GERAN_A sends out paging request to IMSI 901700000010650, TMSI 0xffffffff, LAC 23
+  strcmp(paging_expecting_imsi, imsi) == 0
+DREF VLR subscr MSISDN:42342 usage increases to: 4
+  llist_count(&vsub->cs.requests) == 1
+DREF VLR subscr MSISDN:42342 usage decreases to: 3
+  paging_sent == 1
+  paging_stopped == 0
+- the subscriber and its pending request should remain
+DREF VLR subscr MSISDN:42342 usage increases to: 4
+  llist_count(&vsub->cs.requests) == 1
+DREF VLR subscr MSISDN:42342 usage decreases to: 3
+- MS replies with Paging Response, and VLR sends Auth Request with third key
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_RR_PAG_RESP
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_RR_PAG_RESP (0x6:0x27)
+DRR PAGING RESPONSE: MI(IMSI)=901700000010650
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_NEW}: Updated ID
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_INIT}: Allocated
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_INIT}: is child of Subscr_Conn(PAGING_RESP:901700000010650)
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_INIT}: rev=GSM net=GERAN Auth (no Ciph)
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START
+DREF VLR subscr MSISDN:42342 usage increases to: 4
+DREF VLR subscr MSISDN:42342 usage increases to: 5
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi()
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_WAIT_AUTH
+DVLR VLR_Authenticate(PAGING_RESP:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Allocated
+DVLR VLR_Authenticate(PAGING_RESP:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: is child of Process_Access_Request_VLR(PAGING_RESP:901700000010650)
+DVLR VLR_Authenticate(PAGING_RESP:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
+DVLR VLR_Authenticate(PAGING_RESP:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_WAIT_RESP
+DVLR VLR_Authenticate(PAGING_RESP:901700000010650){VLR_SUB_AS_WAIT_RESP}: got auth tuple: use_count=1 key_seq=2 -- will use GSM AKA (is_r99=no, at->vec.auth_types=0x3)
+- sending GSM Auth Request for MSISDN:42342: tuple use_count=1 key_seq=2 auth_types=0x3 and...
+- ...rand=efa9c29a9742148d5c9070348716e1bb
+- ...expecting sres=69d5f9fb
+DREF VLR subscr MSISDN:42342 usage decreases to: 4
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF MSISDN:42342: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  auth_request_sent == 1
+- needs auth, not yet accepted
+msc_subscr_conn_is_accepted() == false
+  requests shall be thwarted
+DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5)
+DRLL subscr MSISDN:42342: Message not permitted for initial conn: GSM48_MT_CC_SETUP
+DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33)
+DRLL subscr MSISDN:42342: Message not permitted for initial conn: unknown 0x33
+DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19)
+DRLL subscr MSISDN:42342: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1
+DRLL Dispatching 04.08 message SMS:0x01 (0x9:0x1)
+DRLL subscr MSISDN:42342: Message not permitted for initial conn: SMS:0x01
+- MS sends Authen Response, VLR accepts and sends pending SMS
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_AUTH_RESP
+DREF MSISDN:42342: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14)
+DMM MSISDN:42342: MM GSM AUTHENTICATION RESPONSE (sres = 69d5f9fb)
+DVLR VLR_Authenticate(PAGING_RESP:901700000010650){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP
+DVLR SUBSCR(MSISDN:42342) AUTH on GERAN received SRES/RES: 69d5f9fb (4 bytes)
+DVLR SUBSCR(MSISDN:42342) AUTH established GSM security context
+DVLR VLR_Authenticate(PAGING_RESP:901700000010650){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result PASSED
+DVLR VLR_Authenticate(PAGING_RESP:901700000010650){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
+DVLR VLR_Authenticate(PAGING_RESP:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR VLR_Authenticate(PAGING_RESP:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Removing from parent Process_Access_Request_VLR(PAGING_RESP:901700000010650)
+DVLR VLR_Authenticate(PAGING_RESP:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Freeing instance
+DVLR VLR_Authenticate(PAGING_RESP:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Deallocated
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_WAIT_AUTH}: Received Event PR_ARQ_E_AUTH_RES
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2()
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2_post_ciph()
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2_post_vlr()
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_pres()
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_trace()
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_imei()
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_WAIT_AUTH}: proc_arq_fsm_done(PASSED)
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_WAIT_AUTH}: state_chg to PR_ARQ_S_DONE
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_DONE}: Process Access Request result: PASSED
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_ACCEPTED
+DPAG Paging success for MSISDN:42342 (event=0)
+DPAG Calling paging cbfn.
+DCC (ti 00 sub MSISDN:42342 callref 40000003) New transaction
+DREF VLR subscr MSISDN:42342 usage increases to: 5
+DREF MSISDN:42342: MSC conn use + trans_sms == 2 (0x22: dtap,trans_sms)
+DMSC msc_tx 91 bytes to MSISDN:42342 via RAN_GERAN_A
+- DTAP --RAN_GERAN_A--> MS: SMS:0x01: 09015801000791447758100650004c0005802443f2000007101000000000445079da1e1ee7416937485e9ea7c965373d1d6683c270383b3d0ed3d36ff71c949e83c22072799e9687c5ec32a81d96afcbf4b4fb0c7ac3e9e9b7db05
+- DTAP matches expected message
+DREF VLR subscr MSISDN:42342 usage decreases to: 4
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_ACCEPTED}: subscr_conn_fsm_has_active_transactions: connection still has active transaction: SMS
+DREF MSISDN:42342: MSC conn use - dtap == 1 (0x20: trans_sms)
+  dtap_tx_confirmed == 1
+  paging_stopped == 1
+- SMS was delivered, no requests pending for subscr
+DREF VLR subscr MSISDN:42342 usage increases to: 5
+  llist_count(&vsub->cs.requests) == 0
+DREF VLR subscr MSISDN:42342 usage decreases to: 4
+- conn is still open to wait for SMS ack dance
+  llist_count(&net->subscr_conns) == 1
+- MS replies with CP-ACK for received SMS
+  MSC <--RAN_GERAN_A-- MS: SMS:0x04
+DREF MSISDN:42342: MSC conn use + dtap == 2 (0x22: dtap,trans_sms)
+DRLL Dispatching 04.08 message SMS:0x04 (0x9:0x4)
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_COMMUNICATING
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_COMMUNICATING
+DREF MSISDN:42342: MSC conn use - dtap == 1 (0x20: trans_sms)
+  llist_count(&net->subscr_conns) == 1
+- MS also sends RP-ACK, MSC in turn sends CP-ACK for that
+  MSC <--RAN_GERAN_A-- MS: SMS:0x01
+DREF MSISDN:42342: MSC conn use + dtap == 2 (0x22: dtap,trans_sms)
+DRLL Dispatching 04.08 message SMS:0x01 (0x9:0x1)
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_COMMUNICATING}: Received Event SUBSCR_CONN_E_COMMUNICATING
+DMSC msc_tx 2 bytes to MSISDN:42342 via RAN_GERAN_A
+- DTAP --RAN_GERAN_A--> MS: SMS:0x04: 0904
+- DTAP matches expected message
+DREF VLR subscr MSISDN:42342 usage decreases to: 3
+DREF VLR subscr MSISDN:42342 usage decreases to: 2
+DREF MSISDN:42342: MSC conn use - trans_sms == 1 (0x2: dtap)
+DREF MSISDN:42342: MSC conn use - dtap == 0 (0x0: )
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_COMMUNICATING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_COMMUNICATING}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:42342: MSC conn use + release == 1 (0x100: release)
+DREF VLR subscr MSISDN:42342 usage increases to: 3
+DREF VLR subscr MSISDN:42342 usage decreases to: 2
+- BSSAP Clear --RAN_GERAN_A--> MS
+  dtap_tx_confirmed == 1
+  bssap_clear_sent == 1
+- SMS is done, conn is gone
+- BSS sends BSSMAP Clear Complete
+DREF MSISDN:42342: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_DONE}: Removing from parent Subscr_Conn(PAGING_RESP:901700000010650)
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_DONE}: Freeing instance
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_DONE}: Deallocated
+DRLL MSISDN:42342: Freeing subscriber connection
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+---
+- subscriber detaches
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_IMSI_DETACH_IND
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_IMSI_DETACH_IND (0x5:0x1)
+DMM IMSI DETACH INDICATION: MI(IMSI)=901700000010650
+DREF VLR subscr MSISDN:42342 usage increases to: 2
+DMM IMSI DETACH for MSISDN:42342
+DREF VLR subscr MSISDN:42342 usage increases to: 3
+DREF VLR subscr MSISDN:42342 usage decreases to: 2
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+DREF VLR subscr MSISDN:42342 usage decreases to: 0
+DREF freeing VLR subscr MSISDN:42342
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_CN_CLOSE
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF unknown: MSC conn use + release == 2 (0x101: compl_l3,release)
+- BSSAP Clear --RAN_GERAN_A--> MS
+DREF unknown: MSC conn use - compl_l3 == 1 (0x100: release)
+  bssap_clear_sent == 1
+- BSS sends BSSMAP Clear Complete
+DREF unknown: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DRLL Freeing subscriber connection with NULL subscriber
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+===== test_gsm_milenage_authen: SUCCESS
+
+full talloc report on 'msgb' (total      0 bytes in   1 blocks)
+talloc_total_blocks(tall_bsc_ctx) == 12
+
+===== test_wrong_sres_length
+- Total time passed: 0.000000 s
+- Location Update request causes a GSUP Send Auth Info request to HLR
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8)
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Updated ID
+DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000004620 type=IMSI ATTACH
+DMM LU/new-LAC: 1/23
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Allocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: is child of Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: rev=GSM net=GERAN Auth (no Ciph)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA
+DREF VLR subscr unknown usage increases to: 1
+DVLR set IMSI on subscriber; IMSI=901700000004620 id=901700000004620
+DVLR New subscr, IMSI: 901700000004620
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DREF VLR subscr IMSI:901700000004620 usage decreases to: 1
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Allocated
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
+DVLR GSUP tx: 08010809710000004026f0
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f0
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF IMSI:901700000004620: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  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: 0a010809710000004026f003222010585df1ae287f6e273dce07090d61320b21042d8b2c3e220861855fb81fc2a8000322201012aca96fb4ffdea5c985cbafa9b6e18b210420bde240220807fa7502e07e1c0003222010e7c03ba7cf0e2fde82b2dc4d63077d422104a29514ae2208e2b234f80788640003222010fa8f20b781b5881329d4fea26b1a3c5121045afc8d7222082392f14f709ae000032220100fd4cc8dbe8715d1f439e304edfd68dc2104bc8d1c5b2208da7cdd6bfe2d7000
+DVLR GSUP rx 191: 0a010809710000004026f003222010585df1ae287f6e273dce07090d61320b21042d8b2c3e220861855fb81fc2a8000322201012aca96fb4ffdea5c985cbafa9b6e18b210420bde240220807fa7502e07e1c0003222010e7c03ba7cf0e2fde82b2dc4d63077d422104a29514ae2208e2b234f80788640003222010fa8f20b781b5881329d4fea26b1a3c5121045afc8d7222082392f14f709ae000032220100fd4cc8dbe8715d1f439e304edfd68dc2104bc8d1c5b2208da7cdd6bfe2d7000
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: Received Event VLR_AUTH_E_HLR_SAI_ACK
+DVLR SUBSCR(IMSI:901700000004620) Received 5 auth tuples
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: state_chg to VLR_SUB_AS_WAIT_RESP
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_WAIT_RESP}: got auth tuple: use_count=1 key_seq=0 -- will use GSM AKA (is_r99=no, at->vec.auth_types=0x1)
+- sending GSM Auth Request for IMSI:901700000004620: tuple use_count=1 key_seq=0 auth_types=0x1 and...
+- ...rand=585df1ae287f6e273dce07090d61320b
+- ...expecting sres=2d8b2c3e
+DREF VLR subscr IMSI:901700000004620 usage decreases to: 1
+<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT: vlr_gsupc_read_cb() returns 0
+  auth_request_sent == 1
+  lu_result_sent == 0
+- If the HLR were to send a GSUP _UPDATE_LOCATION_RESULT we'd still reject
+<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: 06010809710000004026f0
+DVLR GSUP rx 11: 06010809710000004026f0
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_HLR_LU_RES
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_AUTH}: Event VLR_ULA_E_HLR_LU_RES not permitted
+DREF VLR subscr IMSI:901700000004620 usage decreases to: 1
+<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: vlr_gsupc_read_cb() returns 0
+msc_subscr_conn_is_accepted() == false
+  requests shall be thwarted
+DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5)
+DRLL subscr IMSI:901700000004620: Message not permitted for initial conn: GSM48_MT_CC_SETUP
+DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33)
+DRLL subscr IMSI:901700000004620: Message not permitted for initial conn: unknown 0x33
+DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19)
+DRLL subscr IMSI:901700000004620: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1
+DRLL Dispatching 04.08 message SMS:0x01 (0x9:0x1)
+DRLL subscr IMSI:901700000004620: Message not permitted for initial conn: SMS:0x01
+  lu_result_sent == 0
+- MS sends Authen Response with too short SRES data, auth is thwarted.
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_AUTH_RESP
+DREF IMSI:901700000004620: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14)
+DMM IMSI:901700000004620: MM AUTHENTICATION RESPONSE: l3 length invalid: 5
+DMM IMSI:901700000004620: MM AUTHENTICATION RESPONSE: invalid: parsing GSM AKA Auth Response failed with rc=-22; dispatching zero length SRES/RES to trigger failure
+DMM IMSI:901700000004620: MM GSM AUTHENTICATION RESPONSE (sres = )
+DVLR VLR_Authenticate(LU:901700000004620){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(LU:901700000004620){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result Illegal MS
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTH_FAILED
+DVLR GSUP tx: 0b010809710000004026f0
+GSUP --> HLR: OSMO_GSUP_MSGT_AUTH_FAIL_REPORT: 0b010809710000004026f0
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_AUTH_FAILED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_AUTH_FAILED}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_AUTH_FAILED}: Freeing instance
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_AUTH_FAILED}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES
+- sending LU Reject for IMSI:901700000004620, cause 3
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_DONE
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_CN_CLOSE
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF IMSI:901700000004620: MSC conn use + release == 2 (0x102: dtap,release)
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DREF VLR subscr IMSI:901700000004620 usage decreases to: 1
+- BSSAP Clear --RAN_GERAN_A--> MS
+DREF IMSI:901700000004620: MSC conn use - dtap == 1 (0x100: release)
+  lu_result_sent == 2
+- BSS sends BSSMAP Clear Complete
+DREF IMSI:901700000004620: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Freeing instance
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Deallocated
+DRLL IMSI:901700000004620: Freeing subscriber connection
+DREF VLR subscr IMSI:901700000004620 usage decreases to: 0
+DREF freeing VLR subscr IMSI:901700000004620
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+===== test_wrong_sres_length: SUCCESS
+
+full talloc report on 'msgb' (total      0 bytes in   1 blocks)
+talloc_total_blocks(tall_bsc_ctx) == 12
+
+full talloc report on 'msgb' (total      0 bytes in   1 blocks)
+talloc_total_blocks(tall_bsc_ctx) == 12
+
diff --git a/tests/msc_vlr/msc_vlr_test_gsm_authen.ok b/tests/msc_vlr/msc_vlr_test_gsm_authen.ok
new file mode 100644
index 0000000..a965a70
--- /dev/null
+++ b/tests/msc_vlr/msc_vlr_test_gsm_authen.ok
@@ -0,0 +1 @@
+Done
diff --git a/tests/msc_vlr/msc_vlr_test_gsm_ciph.c b/tests/msc_vlr/msc_vlr_test_gsm_ciph.c
new file mode 100644
index 0000000..8f256b1
--- /dev/null
+++ b/tests/msc_vlr/msc_vlr_test_gsm_ciph.c
@@ -0,0 +1,1514 @@
+/* Osmocom MSC+VLR end-to-end tests */
+
+/* (C) 2017 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>
+ *
+ * All Rights Reserved
+ *
+ * Author: Neels Hofmeyr <nhofmeyr@sysmocom.de>
+ *
+ * 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 "msc_vlr_tests.h"
+
+static void test_ciph()
+{
+	struct vlr_subscr *vsub;
+	const char *imsi = "901700000004620";
+
+	comment_start();
+
+	/* implicit: net->authentication_required = true; */
+	net->a5_encryption_mask = (1 << 1);
+
+	btw("Location Update request causes a GSUP Send Auth Info request to HLR");
+	lu_result_sent = RES_NONE;
+	gsup_expect_tx("08010809710000004026f0");
+	ms_sends_msg("050802008168000130089910070000006402");
+	OSMO_ASSERT(gsup_tx_confirmed);
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("from HLR, rx _SEND_AUTH_INFO_RESULT; VLR sends Auth Req to MS");
+	/* Based on a Ki of 000102030405060708090a0b0c0d0e0f */
+	auth_request_sent = false;
+	auth_request_expect_rand = "585df1ae287f6e273dce07090d61320b";
+	auth_request_expect_autn = NULL;
+	gsup_rx("0a"
+		/* imsi */
+		"0108" "09710000004026f0"
+		/* 5 auth vectors... */
+		/* TL    TL     rand */
+		"0322"  "2010" "585df1ae287f6e273dce07090d61320b"
+		/*       TL     sres       TL     kc */
+			"2104" "2d8b2c3e" "2208" "61855fb81fc2a800"
+		"0322"  "2010" "12aca96fb4ffdea5c985cbafa9b6e18b"
+			"2104" "20bde240" "2208" "07fa7502e07e1c00"
+		"0322"  "2010" "e7c03ba7cf0e2fde82b2dc4d63077d42"
+			"2104" "a29514ae" "2208" "e2b234f807886400"
+		"0322"  "2010" "fa8f20b781b5881329d4fea26b1a3c51"
+			"2104" "5afc8d72" "2208" "2392f14f709ae000"
+		"0322"  "2010" "0fd4cc8dbe8715d1f439e304edfd68dc"
+			"2104" "bc8d1c5b" "2208" "da7cdd6bfe2d7000",
+		NULL);
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+	VERBOSE_ASSERT(auth_request_sent, == true, "%d");
+
+	btw("MS sends Authen Response, VLR accepts and sends Ciphering Mode Command to MS");
+	expect_cipher_mode_cmd("61855fb81fc2a800");
+	ms_sends_msg("05542d8b2c3e");
+	OSMO_ASSERT(cipher_mode_cmd_sent);
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("needs ciph, not yet accepted");
+	EXPECT_ACCEPTED(false);
+	thwart_rx_non_initial_requests();
+	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");
+	ms_sends_msg("0632");
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT");
+	gsup_rx("10010809710000004026f00804036470f1",
+		"12010809710000004026f0");
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("HLR also sends GSUP _UPDATE_LOCATION_RESULT");
+	expect_bssap_clear();
+	gsup_rx("06010809710000004026f0", NULL);
+	VERBOSE_ASSERT(bssap_clear_sent, == true, "%d");
+
+	btw("LU was successful, and the conn has already been closed");
+	VERBOSE_ASSERT(lu_result_sent, == RES_ACCEPT, "%d");
+	bss_sends_clear_complete();
+	EXPECT_CONN_COUNT(0);
+
+	BTW("after a while, a new conn sends a CM Service Request. VLR responds with Auth Req, 2nd auth vector");
+	cm_service_result_sent = RES_NONE;
+	auth_request_sent = false;
+	auth_request_expect_rand = "12aca96fb4ffdea5c985cbafa9b6e18b";
+	ms_sends_msg("05247803305886089910070000006402");
+	OSMO_ASSERT(g_conn);
+	OSMO_ASSERT(g_conn->fi);
+	OSMO_ASSERT(g_conn->vsub);
+	VERBOSE_ASSERT(auth_request_sent, == true, "%d");
+	VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d");
+
+	btw("needs auth, not yet accepted");
+	EXPECT_ACCEPTED(false);
+	thwart_rx_non_initial_requests();
+
+	btw("MS sends Authen Response, VLR accepts and requests Ciphering");
+	expect_cipher_mode_cmd("07fa7502e07e1c00");
+	ms_sends_msg("0554" "20bde240" /* 2nd vector's sres, s.a. */);
+	VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d");
+	VERBOSE_ASSERT(cipher_mode_cmd_sent, == true, "%d");
+
+	btw("needs ciph, not yet accepted");
+	EXPECT_ACCEPTED(false);
+	thwart_rx_non_initial_requests();
+
+	btw("MS sends Ciphering Mode Complete, VLR accepts; above Ciphering is an implicit CM Service Accept");
+	ms_sends_msg("0632");
+	VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d");
+
+	/* Release connection */
+	expect_bssap_clear(RAN_GERAN_A);
+	conn_conclude_cm_service_req(g_conn, RAN_GERAN_A);
+
+	btw("all requests serviced, conn has been released");
+	bss_sends_clear_complete();
+	EXPECT_CONN_COUNT(0);
+
+	BTW("an SMS is sent, MS is paged");
+	paging_expect_imsi(imsi);
+	paging_sent = false;
+	vsub = vlr_subscr_find_by_imsi(net->vlr, imsi);
+	OSMO_ASSERT(vsub);
+	VERBOSE_ASSERT(llist_count(&vsub->cs.requests), == 0, "%d");
+
+	send_sms(vsub, vsub,
+		 "Privacy in residential applications is a desirable"
+		 " marketing option.");
+
+	VERBOSE_ASSERT(llist_count(&vsub->cs.requests), == 1, "%d");
+	vlr_subscr_put(vsub);
+	vsub = NULL;
+	VERBOSE_ASSERT(paging_sent, == true, "%d");
+	VERBOSE_ASSERT(paging_stopped, == false, "%d");
+
+	btw("the subscriber and its pending request should remain");
+	vsub = vlr_subscr_find_by_imsi(net->vlr, imsi);
+	OSMO_ASSERT(vsub);
+	VERBOSE_ASSERT(llist_count(&vsub->cs.requests), == 1, "%d");
+	vlr_subscr_put(vsub);
+
+	btw("MS replies with Paging Response, and VLR sends Auth Request with third key");
+	auth_request_sent = false;
+	auth_request_expect_rand = "e7c03ba7cf0e2fde82b2dc4d63077d42";
+	ms_sends_msg("06270703305882089910070000006402");
+	VERBOSE_ASSERT(auth_request_sent, == true, "%d");
+
+	btw("needs auth, not yet accepted");
+	EXPECT_ACCEPTED(false);
+	thwart_rx_non_initial_requests();
+
+	btw("MS sends Authen Response, VLR accepts and requests Ciphering");
+	expect_cipher_mode_cmd("e2b234f807886400");
+	ms_sends_msg("0554" "a29514ae" /* 3rd vector's sres, s.a. */);
+	VERBOSE_ASSERT(cipher_mode_cmd_sent, == true, "%d");
+
+	btw("needs ciph, not yet accepted");
+	EXPECT_ACCEPTED(false);
+	thwart_rx_non_initial_requests();
+
+	btw("MS sends Ciphering Mode Complete, VLR accepts and sends pending SMS");
+	dtap_expect_tx("09" /* SMS messages */
+		       "01" /* CP-DATA */
+		       "58" /* length */
+		       "01" /* Network to MS */
+		       "00" /* reference */
+		       /* originator (gsm411_send_sms() hardcodes this weird nr) */
+		       "0791" "447758100650" /* 447785016005 */
+		       "00" /* dest */
+		       /* SMS TPDU */
+		       "4c" /* len */
+		       "00" /* SMS deliver */
+		       "05806470f1" /* originating address 46071 */
+		       "00" /* TP-PID */
+		       "00" /* GSM default alphabet */
+		       "071010" /* Y-M-D (from wrapped gsm340_gen_scts())*/
+		       "000000" /* H-M-S */
+		       "00" /* GMT+0 */
+		       "44" /* data length */
+		       "5079da1e1ee7416937485e9ea7c965373d1d6683c270383b3d0e"
+		       "d3d36ff71c949e83c22072799e9687c5ec32a81d96afcbf4b4fb"
+		       "0c7ac3e9e9b7db05");
+	ms_sends_msg("0632");
+	VERBOSE_ASSERT(dtap_tx_confirmed, == true, "%d");
+	VERBOSE_ASSERT(paging_stopped, == true, "%d");
+
+	btw("SMS was delivered, no requests pending for subscr");
+	vsub = vlr_subscr_find_by_imsi(net->vlr, imsi);
+	OSMO_ASSERT(vsub);
+	VERBOSE_ASSERT(llist_count(&vsub->cs.requests), == 0, "%d");
+	vlr_subscr_put(vsub);
+
+	btw("conn is still open to wait for SMS ack dance");
+	EXPECT_CONN_COUNT(1);
+
+	btw("MS replies with CP-ACK for received SMS");
+	ms_sends_msg("8904");
+	EXPECT_CONN_COUNT(1);
+
+	btw("MS also sends RP-ACK, MSC in turn sends CP-ACK for that");
+	dtap_expect_tx("0904");
+	expect_bssap_clear();
+	ms_sends_msg("890106020041020000");
+	VERBOSE_ASSERT(dtap_tx_confirmed, == true, "%d");
+	VERBOSE_ASSERT(bssap_clear_sent, == true, "%d");
+
+	btw("SMS is done, conn is gone");
+	bss_sends_clear_complete();
+	EXPECT_CONN_COUNT(0);
+
+	BTW("subscriber detaches");
+	expect_bssap_clear();
+	ms_sends_msg("050130089910070000006402");
+	VERBOSE_ASSERT(bssap_clear_sent, == true, "%d");
+
+	bss_sends_clear_complete();
+	EXPECT_CONN_COUNT(0);
+	clear_vlr();
+	comment_end();
+}
+
+static void test_ciph_tmsi()
+{
+	struct vlr_subscr *vsub;
+	const char *imsi = "901700000004620";
+
+	comment_start();
+
+	/* implicit: net->authentication_required = true; */
+	net->a5_encryption_mask = (1 << 1);
+	net->vlr->cfg.assign_tmsi = true;
+
+	btw("Location Update request causes a GSUP Send Auth Info request to HLR");
+	lu_result_sent = RES_NONE;
+	gsup_expect_tx("08010809710000004026f0");
+	ms_sends_msg("050802008168000130089910070000006402");
+	OSMO_ASSERT(gsup_tx_confirmed);
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("from HLR, rx _SEND_AUTH_INFO_RESULT; VLR sends Auth Req to MS");
+	/* Based on a Ki of 000102030405060708090a0b0c0d0e0f */
+	auth_request_sent = false;
+	auth_request_expect_rand = "585df1ae287f6e273dce07090d61320b";
+	auth_request_expect_autn = NULL;
+	gsup_rx("0a"
+		/* imsi */
+		"0108" "09710000004026f0"
+		/* 5 auth vectors... */
+		/* TL    TL     rand */
+		"0322"  "2010" "585df1ae287f6e273dce07090d61320b"
+		/*       TL     sres       TL     kc */
+			"2104" "2d8b2c3e" "2208" "61855fb81fc2a800"
+		"0322"  "2010" "12aca96fb4ffdea5c985cbafa9b6e18b"
+			"2104" "20bde240" "2208" "07fa7502e07e1c00"
+		"0322"  "2010" "e7c03ba7cf0e2fde82b2dc4d63077d42"
+			"2104" "a29514ae" "2208" "e2b234f807886400"
+		"0322"  "2010" "fa8f20b781b5881329d4fea26b1a3c51"
+			"2104" "5afc8d72" "2208" "2392f14f709ae000"
+		"0322"  "2010" "0fd4cc8dbe8715d1f439e304edfd68dc"
+			"2104" "bc8d1c5b" "2208" "da7cdd6bfe2d7000",
+		NULL);
+	VERBOSE_ASSERT(auth_request_sent, == true, "%d");
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("MS sends Authen Response, VLR accepts and sends Ciphering Mode Command to MS");
+	expect_cipher_mode_cmd("61855fb81fc2a800");
+	ms_sends_msg("05542d8b2c3e");
+	OSMO_ASSERT(cipher_mode_cmd_sent);
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+	VERBOSE_ASSERT(auth_request_sent, == true, "%d");
+
+	btw("needs ciph, not yet accepted");
+	EXPECT_ACCEPTED(false);
+	thwart_rx_non_initial_requests();
+	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");
+	ms_sends_msg("0632");
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT");
+	gsup_rx("10010809710000004026f00804036470f1",
+		"12010809710000004026f0");
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("HLR also sends GSUP _UPDATE_LOCATION_RESULT");
+	gsup_rx("06010809710000004026f0", NULL);
+
+	btw("a LU Accept with a new TMSI was sent, waiting for TMSI Realloc Compl");
+	EXPECT_CONN_COUNT(1);
+	VERBOSE_ASSERT(lu_result_sent, == RES_ACCEPT, "%d");
+	EXPECT_ACCEPTED(false);
+	thwart_rx_non_initial_requests();
+
+	btw("even though the TMSI is not acked, we can already find the subscr with it");
+	vsub = vlr_subscr_find_by_tmsi(net->vlr, 0x03020100);
+	VERBOSE_ASSERT(vsub != NULL, == true, "%d");
+	VERBOSE_ASSERT(strcmp(vsub->imsi, imsi), == 0, "%d");
+	VERBOSE_ASSERT(vsub->tmsi_new, == 0x03020100, "0x%08x");
+	VERBOSE_ASSERT(vsub->tmsi, == GSM_RESERVED_TMSI, "0x%08x");
+	vlr_subscr_put(vsub);
+
+	btw("MS sends TMSI Realloc Complete");
+	expect_bssap_clear();
+	ms_sends_msg("055b");
+	VERBOSE_ASSERT(bssap_clear_sent, == true, "%d");
+
+	btw("LU was successful, and the conn has already been closed");
+	bss_sends_clear_complete();
+	EXPECT_CONN_COUNT(0);
+
+	btw("Subscriber has the new TMSI");
+	vsub = vlr_subscr_find_by_imsi(net->vlr, imsi);
+	VERBOSE_ASSERT(vsub != NULL, == true, "%d");
+	VERBOSE_ASSERT(strcmp(vsub->imsi, imsi), == 0, "%d");
+	VERBOSE_ASSERT(vsub->tmsi_new, == GSM_RESERVED_TMSI, "0x%08x");
+	VERBOSE_ASSERT(vsub->tmsi, == 0x03020100, "0x%08x");
+	vlr_subscr_put(vsub);
+
+	BTW("after a while, a new conn sends a CM Service Request using above TMSI. VLR responds with Auth Req, 2nd auth vector");
+	cm_service_result_sent = RES_NONE;
+	auth_request_sent = false;
+	auth_request_expect_rand = "12aca96fb4ffdea5c985cbafa9b6e18b";
+	auth_request_expect_autn = NULL;
+	ms_sends_msg("05247803305886" "05f4" "03020100");
+	OSMO_ASSERT(g_conn);
+	OSMO_ASSERT(g_conn->fi);
+	OSMO_ASSERT(g_conn->vsub);
+	VERBOSE_ASSERT(auth_request_sent, == true, "%d");
+	VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d");
+
+	btw("needs auth, not yet accepted");
+	EXPECT_ACCEPTED(false);
+	thwart_rx_non_initial_requests();
+
+	btw("MS sends Authen Response, VLR accepts and requests Ciphering");
+	expect_cipher_mode_cmd("07fa7502e07e1c00");
+	ms_sends_msg("0554" "20bde240" /* 2nd vector's sres, s.a. */);
+	VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d");
+	VERBOSE_ASSERT(cipher_mode_cmd_sent, == true, "%d");
+
+	btw("needs ciph, not yet accepted");
+	EXPECT_ACCEPTED(false);
+	thwart_rx_non_initial_requests();
+
+	btw("MS sends Ciphering Mode Complete, VLR accepts; above Ciphering is an implicit CM Service Accept");
+	ms_sends_msg("0632");
+	VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d");
+
+	/* Release connection */
+	expect_bssap_clear(RAN_GERAN_A);
+	conn_conclude_cm_service_req(g_conn, RAN_GERAN_A);
+
+	btw("all requests serviced, conn has been released");
+	bss_sends_clear_complete();
+	EXPECT_CONN_COUNT(0);
+
+	BTW("an SMS is sent, MS is paged");
+	paging_expect_tmsi(0x03020100);
+	paging_sent = false;
+	vsub = vlr_subscr_find_by_tmsi(net->vlr, 0x03020100);
+	OSMO_ASSERT(vsub);
+	VERBOSE_ASSERT(llist_count(&vsub->cs.requests), == 0, "%d");
+
+	send_sms(vsub, vsub,
+		 "Privacy in residential applications is a desirable"
+		 " marketing option.");
+
+	VERBOSE_ASSERT(llist_count(&vsub->cs.requests), == 1, "%d");
+	vlr_subscr_put(vsub);
+	vsub = NULL;
+	VERBOSE_ASSERT(paging_sent, == true, "%d");
+	VERBOSE_ASSERT(paging_stopped, == false, "%d");
+
+	btw("the subscriber and its pending request should remain");
+	vsub = vlr_subscr_find_by_imsi(net->vlr, imsi);
+	OSMO_ASSERT(vsub);
+	VERBOSE_ASSERT(llist_count(&vsub->cs.requests), == 1, "%d");
+	vlr_subscr_put(vsub);
+
+	btw("MS replies with Paging Response using TMSI, and VLR sends Auth Request with third key");
+	auth_request_sent = false;
+	auth_request_expect_rand = "e7c03ba7cf0e2fde82b2dc4d63077d42";
+	ms_sends_msg("06270703305882" "05f4" "03020100");
+	VERBOSE_ASSERT(auth_request_sent, == true, "%d");
+
+	btw("needs auth, not yet accepted");
+	EXPECT_ACCEPTED(false);
+	thwart_rx_non_initial_requests();
+
+	btw("MS sends Authen Response, VLR accepts and requests Ciphering");
+	expect_cipher_mode_cmd("e2b234f807886400");
+	ms_sends_msg("0554" "a29514ae" /* 3rd vector's sres, s.a. */);
+	VERBOSE_ASSERT(cipher_mode_cmd_sent, == true, "%d");
+
+	btw("needs ciph, not yet accepted");
+	EXPECT_ACCEPTED(false);
+	thwart_rx_non_initial_requests();
+
+	btw("MS sends Ciphering Mode Complete, VLR accepts and sends pending SMS");
+	dtap_expect_tx("09" /* SMS messages */
+		       "01" /* CP-DATA */
+		       "58" /* length */
+		       "01" /* Network to MS */
+		       "00" /* reference */
+		       /* originator (gsm411_send_sms() hardcodes this weird nr) */
+		       "0791" "447758100650" /* 447785016005 */
+		       "00" /* dest */
+		       /* SMS TPDU */
+		       "4c" /* len */
+		       "00" /* SMS deliver */
+		       "05806470f1" /* originating address 46071 */
+		       "00" /* TP-PID */
+		       "00" /* GSM default alphabet */
+		       "071010" /* Y-M-D (from wrapped gsm340_gen_scts())*/
+		       "000000" /* H-M-S */
+		       "00" /* GMT+0 */
+		       "44" /* data length */
+		       "5079da1e1ee7416937485e9ea7c965373d1d6683c270383b3d0e"
+		       "d3d36ff71c949e83c22072799e9687c5ec32a81d96afcbf4b4fb"
+		       "0c7ac3e9e9b7db05");
+	ms_sends_msg("0632");
+	VERBOSE_ASSERT(dtap_tx_confirmed, == true, "%d");
+	VERBOSE_ASSERT(paging_stopped, == true, "%d");
+
+	btw("SMS was delivered, no requests pending for subscr");
+	vsub = vlr_subscr_find_by_imsi(net->vlr, imsi);
+	OSMO_ASSERT(vsub);
+	VERBOSE_ASSERT(llist_count(&vsub->cs.requests), == 0, "%d");
+	vlr_subscr_put(vsub);
+
+	btw("conn is still open to wait for SMS ack dance");
+	EXPECT_CONN_COUNT(1);
+
+	btw("MS replies with CP-ACK for received SMS");
+	ms_sends_msg("8904");
+	EXPECT_CONN_COUNT(1);
+
+	btw("MS also sends RP-ACK, MSC in turn sends CP-ACK for that");
+	dtap_expect_tx("0904");
+	expect_bssap_clear();
+	ms_sends_msg("890106020041020000");
+	VERBOSE_ASSERT(dtap_tx_confirmed, == true, "%d");
+	VERBOSE_ASSERT(bssap_clear_sent, == true, "%d");
+
+	btw("SMS is done, conn is gone");
+	bss_sends_clear_complete();
+	EXPECT_CONN_COUNT(0);
+
+	BTW("subscriber detaches, using TMSI");
+	expect_bssap_clear();
+	ms_sends_msg("050130" "05f4" "03020100");
+	VERBOSE_ASSERT(bssap_clear_sent, == true, "%d");
+
+	bss_sends_clear_complete();
+	EXPECT_CONN_COUNT(0);
+	clear_vlr();
+	comment_end();
+}
+
+static void test_ciph_imei()
+{
+	struct vlr_subscr *vsub;
+	const char *imsi = "901700000004620";
+
+	comment_start();
+
+	/* implicit: net->authentication_required = true; */
+	net->a5_encryption_mask = (1 << 1);
+	net->vlr->cfg.check_imei_rqd = true;
+
+	btw("Location Update request causes a GSUP Send Auth Info request to HLR");
+	lu_result_sent = RES_NONE;
+	gsup_expect_tx("08010809710000004026f0");
+	ms_sends_msg("050802008168000130089910070000006402");
+	OSMO_ASSERT(gsup_tx_confirmed);
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("from HLR, rx _SEND_AUTH_INFO_RESULT; VLR sends Auth Req to MS");
+	/* Based on a Ki of 000102030405060708090a0b0c0d0e0f */
+	auth_request_sent = false;
+	auth_request_expect_rand = "585df1ae287f6e273dce07090d61320b";
+	auth_request_expect_autn = NULL;
+	gsup_rx("0a"
+		/* imsi */
+		"0108" "09710000004026f0"
+		/* 5 auth vectors... */
+		/* TL    TL     rand */
+		"0322"  "2010" "585df1ae287f6e273dce07090d61320b"
+		/*       TL     sres       TL     kc */
+			"2104" "2d8b2c3e" "2208" "61855fb81fc2a800"
+		"0322"  "2010" "12aca96fb4ffdea5c985cbafa9b6e18b"
+			"2104" "20bde240" "2208" "07fa7502e07e1c00"
+		"0322"  "2010" "e7c03ba7cf0e2fde82b2dc4d63077d42"
+			"2104" "a29514ae" "2208" "e2b234f807886400"
+		"0322"  "2010" "fa8f20b781b5881329d4fea26b1a3c51"
+			"2104" "5afc8d72" "2208" "2392f14f709ae000"
+		"0322"  "2010" "0fd4cc8dbe8715d1f439e304edfd68dc"
+			"2104" "bc8d1c5b" "2208" "da7cdd6bfe2d7000",
+		NULL);
+	VERBOSE_ASSERT(auth_request_sent, == true, "%d");
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("MS sends Authen Response, VLR accepts and sends Ciphering Mode Command to MS");
+	expect_cipher_mode_cmd("61855fb81fc2a800");
+	ms_sends_msg("05542d8b2c3e");
+	OSMO_ASSERT(cipher_mode_cmd_sent);
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("needs ciph, not yet accepted");
+	EXPECT_ACCEPTED(false);
+	thwart_rx_non_initial_requests();
+	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");
+	ms_sends_msg("0632");
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT");
+	gsup_rx("10010809710000004026f00804036470f1",
+		"12010809710000004026f0");
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("HLR also sends GSUP _UPDATE_LOCATION_RESULT, and we send an ID Request for the IMEI to the MS");
+	dtap_expect_tx("051802");
+	gsup_rx("06010809710000004026f0", NULL);
+
+	btw("We will only do business when the IMEI is known");
+	EXPECT_CONN_COUNT(1);
+	vsub = vlr_subscr_find_by_imsi(net->vlr, imsi);
+	OSMO_ASSERT(vsub);
+	VERBOSE_ASSERT(vsub->imei[0], == 0, "%d");
+	vlr_subscr_put(vsub);
+	EXPECT_ACCEPTED(false);
+	thwart_rx_non_initial_requests();
+
+	btw("MS replies with an Identity Response");
+	expect_bssap_clear();
+	ms_sends_msg("0559084a32244332244302");
+	VERBOSE_ASSERT(bssap_clear_sent, == true, "%d");
+
+	btw("LU was successful, and the conn has already been closed");
+	VERBOSE_ASSERT(lu_result_sent, == RES_ACCEPT, "%d");
+	bss_sends_clear_complete();
+	EXPECT_CONN_COUNT(0);
+
+	btw("Subscriber has the IMEI");
+	vsub = vlr_subscr_find_by_imsi(net->vlr, imsi);
+	OSMO_ASSERT(vsub);
+	VERBOSE_ASSERT(strcmp(vsub->imei, "423423423423420"), == 0, "%d");
+	vlr_subscr_put(vsub);
+
+	BTW("subscriber detaches");
+	expect_bssap_clear();
+	ms_sends_msg("050130089910070000006402");
+	VERBOSE_ASSERT(bssap_clear_sent, == true, "%d");
+
+	bss_sends_clear_complete();
+	EXPECT_CONN_COUNT(0);
+	clear_vlr();
+	comment_end();
+}
+
+static void test_ciph_imeisv()
+{
+	struct vlr_subscr *vsub;
+	const char *imsi = "901700000004620";
+
+	comment_start();
+
+	/* implicit: net->authentication_required = true; */
+	net->a5_encryption_mask = (1 << 1);
+	net->vlr->cfg.retrieve_imeisv_ciphered = true;
+
+	btw("Location Update request causes a GSUP Send Auth Info request to HLR");
+	lu_result_sent = RES_NONE;
+	gsup_expect_tx("08010809710000004026f0");
+	ms_sends_msg("050802008168000130089910070000006402");
+	OSMO_ASSERT(gsup_tx_confirmed);
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("from HLR, rx _SEND_AUTH_INFO_RESULT; VLR sends Auth Req to MS");
+	/* Based on a Ki of 000102030405060708090a0b0c0d0e0f */
+	auth_request_sent = false;
+	auth_request_expect_rand = "585df1ae287f6e273dce07090d61320b";
+	auth_request_expect_autn = NULL;
+	gsup_rx("0a"
+		/* imsi */
+		"0108" "09710000004026f0"
+		/* 5 auth vectors... */
+		/* TL    TL     rand */
+		"0322"  "2010" "585df1ae287f6e273dce07090d61320b"
+		/*       TL     sres       TL     kc */
+			"2104" "2d8b2c3e" "2208" "61855fb81fc2a800"
+		"0322"  "2010" "12aca96fb4ffdea5c985cbafa9b6e18b"
+			"2104" "20bde240" "2208" "07fa7502e07e1c00"
+		"0322"  "2010" "e7c03ba7cf0e2fde82b2dc4d63077d42"
+			"2104" "a29514ae" "2208" "e2b234f807886400"
+		"0322"  "2010" "fa8f20b781b5881329d4fea26b1a3c51"
+			"2104" "5afc8d72" "2208" "2392f14f709ae000"
+		"0322"  "2010" "0fd4cc8dbe8715d1f439e304edfd68dc"
+			"2104" "bc8d1c5b" "2208" "da7cdd6bfe2d7000",
+		NULL);
+	VERBOSE_ASSERT(auth_request_sent, == true, "%d");
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("MS sends Authen Response, VLR accepts and sends Ciphering Mode Command to MS");
+	expect_cipher_mode_cmd("61855fb81fc2a800");
+	ms_sends_msg("05542d8b2c3e");
+	VERBOSE_ASSERT(cipher_mode_cmd_sent, == true, "%d");
+	VERBOSE_ASSERT(cipher_mode_cmd_sent_with_imeisv, == true, "%d");
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("needs ciph, not yet accepted");
+	EXPECT_ACCEPTED(false);
+	thwart_rx_non_initial_requests();
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	vsub = vlr_subscr_find_by_imsi(net->vlr, imsi);
+	OSMO_ASSERT(vsub);
+	VERBOSE_ASSERT(vsub->imeisv[0], == 0, "%d");
+	vlr_subscr_put(vsub);
+
+	btw("MS sends Ciphering Mode Complete with IMEISV, VLR accepts and sends GSUP LU Req to HLR");
+	gsup_expect_tx("04010809710000004026f0280102");
+	ms_sends_msg("063217094b32244332244372f5");
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("Subscriber has the IMEISV");
+	vsub = vlr_subscr_find_by_imsi(net->vlr, imsi);
+	OSMO_ASSERT(vsub);
+	VERBOSE_ASSERT(strcmp(vsub->imeisv, "4234234234234275"), == 0, "%d");
+	vlr_subscr_put(vsub);
+
+	EXPECT_ACCEPTED(false);
+	thwart_rx_non_initial_requests();
+
+	btw("HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT");
+	gsup_rx("10010809710000004026f00804036470f1",
+		"12010809710000004026f0");
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("HLR also sends GSUP _UPDATE_LOCATION_RESULT");
+	expect_bssap_clear();
+	gsup_rx("06010809710000004026f0", NULL);
+	VERBOSE_ASSERT(bssap_clear_sent, == true, "%d");
+
+	btw("LU was successful, and the conn has already been closed");
+	VERBOSE_ASSERT(lu_result_sent, == RES_ACCEPT, "%d");
+	bss_sends_clear_complete();
+	EXPECT_CONN_COUNT(0);
+
+	BTW("subscriber detaches");
+	expect_bssap_clear();
+	ms_sends_msg("050130089910070000006402");
+	VERBOSE_ASSERT(bssap_clear_sent, == true, "%d");
+
+	bss_sends_clear_complete();
+	EXPECT_CONN_COUNT(0);
+	clear_vlr();
+	comment_end();
+}
+
+static void test_ciph_tmsi_imei()
+{
+	struct vlr_subscr *vsub;
+	const char *imsi = "901700000004620";
+
+	comment_start();
+
+	/* implicit: net->authentication_required = true; */
+	net->a5_encryption_mask = (1 << 1);
+	net->vlr->cfg.assign_tmsi = true;
+	net->vlr->cfg.check_imei_rqd = true;
+
+	btw("Location Update request causes a GSUP Send Auth Info request to HLR");
+	lu_result_sent = RES_NONE;
+	gsup_expect_tx("08010809710000004026f0");
+	ms_sends_msg("050802008168000130089910070000006402");
+	OSMO_ASSERT(gsup_tx_confirmed);
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("from HLR, rx _SEND_AUTH_INFO_RESULT; VLR sends Auth Req to MS");
+	/* Based on a Ki of 000102030405060708090a0b0c0d0e0f */
+	auth_request_sent = false;
+	auth_request_expect_rand = "585df1ae287f6e273dce07090d61320b";
+	auth_request_expect_autn = NULL;
+	gsup_rx("0a"
+		/* imsi */
+		"0108" "09710000004026f0"
+		/* 5 auth vectors... */
+		/* TL    TL     rand */
+		"0322"  "2010" "585df1ae287f6e273dce07090d61320b"
+		/*       TL     sres       TL     kc */
+			"2104" "2d8b2c3e" "2208" "61855fb81fc2a800"
+		"0322"  "2010" "12aca96fb4ffdea5c985cbafa9b6e18b"
+			"2104" "20bde240" "2208" "07fa7502e07e1c00"
+		"0322"  "2010" "e7c03ba7cf0e2fde82b2dc4d63077d42"
+			"2104" "a29514ae" "2208" "e2b234f807886400"
+		"0322"  "2010" "fa8f20b781b5881329d4fea26b1a3c51"
+			"2104" "5afc8d72" "2208" "2392f14f709ae000"
+		"0322"  "2010" "0fd4cc8dbe8715d1f439e304edfd68dc"
+			"2104" "bc8d1c5b" "2208" "da7cdd6bfe2d7000",
+		NULL);
+	VERBOSE_ASSERT(auth_request_sent, == true, "%d");
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("MS sends Authen Response, VLR accepts and sends Ciphering Mode Command to MS");
+	expect_cipher_mode_cmd("61855fb81fc2a800");
+	ms_sends_msg("05542d8b2c3e");
+	OSMO_ASSERT(cipher_mode_cmd_sent);
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("needs ciph, not yet accepted");
+	EXPECT_ACCEPTED(false);
+	thwart_rx_non_initial_requests();
+	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");
+	ms_sends_msg("0632");
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT");
+	gsup_rx("10010809710000004026f00804036470f1",
+		"12010809710000004026f0");
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("HLR also sends GSUP _UPDATE_LOCATION_RESULT, and we send an ID Request for the IMEI to the MS");
+	dtap_expect_tx("051802");
+	gsup_rx("06010809710000004026f0", NULL);
+
+	btw("We will only do business when the IMEI is known");
+	EXPECT_CONN_COUNT(1);
+	vsub = vlr_subscr_find_by_imsi(net->vlr, imsi);
+	OSMO_ASSERT(vsub);
+	VERBOSE_ASSERT(vsub->imei[0], == 0, "%d");
+	vlr_subscr_put(vsub);
+	EXPECT_ACCEPTED(false);
+	thwart_rx_non_initial_requests();
+
+	btw("MS replies with an Identity Response");
+	ms_sends_msg("0559084a32244332244302");
+
+	btw("a LU Accept with a new TMSI was sent, waiting for TMSI Realloc Compl");
+	EXPECT_CONN_COUNT(1);
+	VERBOSE_ASSERT(lu_result_sent, == RES_ACCEPT, "%d");
+	EXPECT_ACCEPTED(false);
+	thwart_rx_non_initial_requests();
+
+	btw("even though the TMSI is not acked, we can already find the subscr with it");
+	vsub = vlr_subscr_find_by_tmsi(net->vlr, 0x03020100);
+	VERBOSE_ASSERT(vsub != NULL, == true, "%d");
+	VERBOSE_ASSERT(strcmp(vsub->imsi, imsi), == 0, "%d");
+	VERBOSE_ASSERT(vsub->tmsi_new, == 0x03020100, "0x%08x");
+	VERBOSE_ASSERT(vsub->tmsi, == GSM_RESERVED_TMSI, "0x%08x");
+	vlr_subscr_put(vsub);
+
+	btw("MS sends TMSI Realloc Complete");
+	expect_bssap_clear();
+	ms_sends_msg("055b");
+	VERBOSE_ASSERT(bssap_clear_sent, == true, "%d");
+
+	btw("LU was successful, and the conn has already been closed");
+	bss_sends_clear_complete();
+	EXPECT_CONN_COUNT(0);
+
+	btw("Subscriber has the IMEI and TMSI");
+	vsub = vlr_subscr_find_by_imsi(net->vlr, imsi);
+	OSMO_ASSERT(vsub);
+	VERBOSE_ASSERT(strcmp(vsub->imei, "423423423423420"), == 0, "%d");
+	VERBOSE_ASSERT(vsub->tmsi, == 0x03020100, "0x%08x");
+	vlr_subscr_put(vsub);
+
+	BTW("subscriber detaches, using TMSI");
+	expect_bssap_clear();
+	ms_sends_msg("050130" "05f4" "03020100");
+	VERBOSE_ASSERT(bssap_clear_sent, == true, "%d");
+
+	bss_sends_clear_complete();
+	EXPECT_CONN_COUNT(0);
+	clear_vlr();
+	comment_end();
+}
+
+static void test_gsm_ciph_in_umts_env()
+{
+	struct vlr_subscr *vsub;
+	const char *imsi = "901700000010650";
+	const char *sms =
+		"09" /* SMS messages */
+		"01" /* CP-DATA */
+		"58" /* length */
+		"01" /* Network to MS */
+		"00" /* reference */
+		/* originator (gsm411_send_sms() hardcodes this weird nr) */
+		"0791" "447758100650" /* 447785016005 */
+		"00" /* dest */
+		/* SMS TPDU */
+		"4c" /* len */
+		"00" /* SMS deliver */
+		"05802443f2" /* originating address 42342 */
+		"00" /* TP-PID */
+		"00" /* GSM default alphabet */
+		"071010" /* Y-M-D (from wrapped gsm340_gen_scts())*/
+		"000000" /* H-M-S */
+		"00" /* GMT+0 */
+		"44" /* data length */
+		"5079da1e1ee7416937485e9ea7c965373d1d6683c270383b3d0e"
+		"d3d36ff71c949e83c22072799e9687c5ec32a81d96afcbf4b4fb"
+		"0c7ac3e9e9b7db05";
+
+	comment_start();
+
+	/* implicit: net->authentication_required = true; */
+	net->a5_encryption_mask = (1 << 1);
+	rx_from_ran = RAN_GERAN_A;
+
+	btw("Location Update request causes a GSUP Send Auth Info request to HLR");
+	lu_result_sent = RES_NONE;
+	gsup_expect_tx("080108" "09710000000156f0");
+	ms_sends_msg("0508" /* MM LU */
+		     "7" /* ciph key seq: no key available */
+		     "0" /* LU type: normal */
+		     "ffffff" "0000" /* 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("from HLR, rx _SEND_AUTH_INFO_RESULT; VLR sends *UMTS AKA* Auth Req to MS");
+	/* based on
+	 * 2G auth: COMP128v1
+	 *          KI=7bcd108be4c3d551ee6c67faaf52bd68
+	 * 3G auth: MILENAGE
+	 *          K=7bcd108be4c3d551ee6c67faaf52bd68
+	 *          OPC=6e23f641ce724679b73d933515a8589d
+	 *          IND-bitlen=5 last-SQN=641
+	 * Note that the SRES will be calculated by COMP128v1, separately from 3G tokens;
+	 * the resulting Kc to use for ciphering returned by the HLR is also calculated from COMP128v1.
+	 */
+	auth_request_sent = false;
+	auth_request_expect_rand = "4ac8d1cd1a51937597ca1016fe69a0fa";
+	auth_request_expect_autn = "2d837d2b0d6f00004b282d5acf23428d";
+	gsup_rx("0a"
+		/* imsi */
+		"0108" "09710000000156f0"
+		/* 5 auth vectors... */
+		/* TL    TL     rand */
+		"0362" "2010" "4ac8d1cd1a51937597ca1016fe69a0fa"
+		/*       TL     sres       TL     kc */
+		       "2104" "dacc4b26" "2208" "7a75f0ac9b844400"
+		/*       TL     3G IK */
+		       "2310" "3747da4e31545baa2db59e500bdae047"
+		/*       TL     3G CK */
+		       "2410" "8544d35b945ccba01a7f1293575291c3"
+		/*       TL     AUTN */
+		       "2510" "2d837d2b0d6f00004b282d5acf23428d"
+		/*       TL     RES */
+		       "2708" "37527064741f8ddb"
+		/* TL    TL     rand */
+		"0362" "2010" "b2661531b97b12c5a2edc21a0ed16fc5"
+		       "2104" "2fb4cfad" "2208" "da149b11d473f400"
+		       "2310" "3fe013b1a428ea737c37f8f0288c8edf"
+		       "2410" "f275438c02b97e4d6f639dddda3d10b9"
+		       "2510" "78cdd96c60840000322f421b3bb778b1"
+		       "2708" "ed3ebf9cb6ea48ed"
+		"0362" "2010" "54d8f19778056666b41c8c25e52eb60c"
+		       "2104" "0ff61e0f" "2208" "26ec67fad3073000"
+		       "2310" "2868b0922c652616f1c975e3eaf7943a"
+		       "2410" "6a84a20b1bc13ec9840466406d2dd91e"
+		       "2510" "53f3e5632b3d00008865dd54d49663f2"
+		       "2708" "86e848a9e7ad8cd5"
+		"0362" "2010" "1f05607ff9c8984f46ad97f8c9a94982"
+		       "2104" "91a36e3d" "2208" "5d84421884fdcc00"
+		       "2310" "2171fef54b81e30c83a598a5e44f634c"
+		       "2410" "f02d088697509827565b46938fece211"
+		       "2510" "1b43bbf9815e00001cb9b2a9f6b8a77c"
+		       "2708" "373e67d62e719c51"
+		"0362" "2010" "80d89a58a2a41050918caf68a4e93c64"
+		       "2104" "a319f5f1" "2208" "883df2b867293000"
+		       "2310" "fa5d70f929ff298efb160413698dc107"
+		       "2410" "ae9a3d8ce70ce13bac297bdb91cd6c68"
+		       "2510" "5c0dc2eeaefa0000396882a1fe2cf80b"
+		       "2708" "65ab1cad216bfe87",
+		NULL);
+	VERBOSE_ASSERT(auth_request_sent, == true, "%d");
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("MS sends *GSM AKA* Authen Response, VLR accepts and sends Ciphering Mode Command to MS");
+	expect_cipher_mode_cmd("7a75f0ac9b844400");
+	ms_sends_msg("0554" "dacc4b26");
+	OSMO_ASSERT(cipher_mode_cmd_sent);
+	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");
+	ms_sends_msg("0632");
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT");
+	gsup_rx("10010809710000000156f00804032443f2",
+		"12010809710000000156f0");
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("HLR also sends GSUP _UPDATE_LOCATION_RESULT");
+	expect_bssap_clear();
+	gsup_rx("06010809710000000156f0", NULL);
+	VERBOSE_ASSERT(bssap_clear_sent, == true, "%d");
+
+	btw("LU was successful, and the conn has already been closed");
+	VERBOSE_ASSERT(lu_result_sent, == RES_ACCEPT, "%d");
+	bss_sends_clear_complete();
+	EXPECT_CONN_COUNT(0);
+
+	BTW("after a while, a new conn sends a CM Service Request. VLR responds with *UMTS AKA* Auth Req, 2nd auth vector");
+	auth_request_sent = false;
+	auth_request_expect_rand = "b2661531b97b12c5a2edc21a0ed16fc5";
+	auth_request_expect_autn = "78cdd96c60840000322f421b3bb778b1";
+	cm_service_result_sent = RES_NONE;
+	ms_sends_msg("052478"
+		     "03575886" /* classmark 2 */
+		     "089910070000106005" /* IMSI */);
+	OSMO_ASSERT(g_conn);
+	OSMO_ASSERT(g_conn->fi);
+	OSMO_ASSERT(g_conn->vsub);
+	VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d");
+	VERBOSE_ASSERT(auth_request_sent, == true, "%d");
+
+	btw("needs auth, not yet accepted");
+	EXPECT_ACCEPTED(false);
+	thwart_rx_non_initial_requests();
+
+	btw("MS sends *GSM AKA* Authen Response, VLR accepts and requests Ciphering");
+	expect_cipher_mode_cmd("da149b11d473f400");
+	ms_sends_msg("0554" "2fb4cfad");
+	VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d");
+	VERBOSE_ASSERT(cipher_mode_cmd_sent, == true, "%d");
+
+	btw("MS sends Ciphering Mode Complete, VLR accepts; above Ciphering is an implicit CM Service Accept");
+	ms_sends_msg("0632");
+	VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d");
+
+	/* Release connection */
+	expect_bssap_clear(RAN_GERAN_A);
+	conn_conclude_cm_service_req(g_conn, RAN_GERAN_A);
+
+	btw("all requests serviced, conn has been released");
+	bss_sends_clear_complete();
+	EXPECT_CONN_COUNT(0);
+
+	BTW("an SMS is sent, MS is paged");
+	paging_expect_imsi(imsi);
+	paging_sent = false;
+	vsub = vlr_subscr_find_by_imsi(net->vlr, imsi);
+	OSMO_ASSERT(vsub);
+	VERBOSE_ASSERT(llist_count(&vsub->cs.requests), == 0, "%d");
+
+	send_sms(vsub, vsub,
+		 "Privacy in residential applications is a desirable"
+		 " marketing option.");
+
+	VERBOSE_ASSERT(llist_count(&vsub->cs.requests), == 1, "%d");
+	vlr_subscr_put(vsub);
+	vsub = NULL;
+	VERBOSE_ASSERT(paging_sent, == true, "%d");
+	VERBOSE_ASSERT(paging_stopped, == false, "%d");
+
+	btw("the subscriber and its pending request should remain");
+	vsub = vlr_subscr_find_by_imsi(net->vlr, imsi);
+	OSMO_ASSERT(vsub);
+	VERBOSE_ASSERT(llist_count(&vsub->cs.requests), == 1, "%d");
+	vlr_subscr_put(vsub);
+
+	btw("MS replies with Paging Response, and VLR sends *UMTS AKA* Auth Request with third key");
+	auth_request_sent = false;
+	auth_request_expect_rand = "54d8f19778056666b41c8c25e52eb60c";
+	auth_request_expect_autn = "53f3e5632b3d00008865dd54d49663f2";
+	ms_sends_msg("062707"
+		     "03575886" /* classmark 2 */
+		     "089910070000106005" /* IMSI */);
+	VERBOSE_ASSERT(auth_request_sent, == true, "%d");
+
+	btw("needs auth, not yet accepted");
+	EXPECT_ACCEPTED(false);
+	thwart_rx_non_initial_requests();
+
+	btw("MS sends *GSM AKA* Authen Response, VLR accepts and requests Ciphering");
+	expect_cipher_mode_cmd("26ec67fad3073000");
+	ms_sends_msg("0554" "0ff61e0f");
+	VERBOSE_ASSERT(cipher_mode_cmd_sent, == true, "%d");
+
+	btw("MS sends Ciphering Mode Complete, VLR accepts and sends pending SMS");
+	dtap_expect_tx(sms);
+	ms_sends_msg("0632");
+	VERBOSE_ASSERT(dtap_tx_confirmed, == true, "%d");
+	VERBOSE_ASSERT(paging_stopped, == true, "%d");
+
+	btw("SMS was delivered, no requests pending for subscr");
+	vsub = vlr_subscr_find_by_imsi(net->vlr, imsi);
+	OSMO_ASSERT(vsub);
+	VERBOSE_ASSERT(llist_count(&vsub->cs.requests), == 0, "%d");
+	vlr_subscr_put(vsub);
+
+	btw("conn is still open to wait for SMS ack dance");
+	EXPECT_CONN_COUNT(1);
+
+	btw("MS replies with CP-ACK for received SMS");
+	ms_sends_msg("8904");
+	EXPECT_CONN_COUNT(1);
+
+	btw("MS also sends RP-ACK, MSC in turn sends CP-ACK for that");
+	dtap_expect_tx("0904");
+	expect_bssap_clear();
+	ms_sends_msg("890106020041020000");
+	VERBOSE_ASSERT(dtap_tx_confirmed, == true, "%d");
+	VERBOSE_ASSERT(bssap_clear_sent, == true, "%d");
+
+	btw("SMS is done, conn is gone");
+	bss_sends_clear_complete();
+	EXPECT_CONN_COUNT(0);
+
+	BTW("subscriber detaches");
+	expect_bssap_clear();
+	ms_sends_msg("050130"
+		     "089910070000106005" /* IMSI */);
+	VERBOSE_ASSERT(bssap_clear_sent, == true, "%d");
+
+	bss_sends_clear_complete();
+	EXPECT_CONN_COUNT(0);
+	clear_vlr();
+	comment_end();
+}
+
+static void test_a5_3_supported()
+{
+	struct vlr_subscr *vsub;
+	const char *imsi = "901700000004620";
+
+	comment_start();
+
+	/* implicit: net->authentication_required = true; */
+	net->a5_encryption_mask = (1 << 3); /* A5/3 */
+
+	btw("Location Update request causes a GSUP Send Auth Info request to HLR");
+	lu_result_sent = RES_NONE;
+	gsup_expect_tx("08010809710000004026f0");
+	ms_sends_msg("050802008168000130089910070000006402");
+	OSMO_ASSERT(gsup_tx_confirmed);
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("from HLR, rx _SEND_AUTH_INFO_RESULT; VLR sends Auth Req to MS");
+	/* Based on a Ki of 000102030405060708090a0b0c0d0e0f */
+	auth_request_sent = false;
+	auth_request_expect_rand = "585df1ae287f6e273dce07090d61320b";
+	auth_request_expect_autn = NULL;
+	gsup_rx("0a"
+		/* imsi */
+		"0108" "09710000004026f0"
+		/* 5 auth vectors... */
+		/* TL    TL     rand */
+		"0322"  "2010" "585df1ae287f6e273dce07090d61320b"
+		/*       TL     sres       TL     kc */
+			"2104" "2d8b2c3e" "2208" "61855fb81fc2a800"
+		"0322"  "2010" "12aca96fb4ffdea5c985cbafa9b6e18b"
+			"2104" "20bde240" "2208" "07fa7502e07e1c00"
+		"0322"  "2010" "e7c03ba7cf0e2fde82b2dc4d63077d42"
+			"2104" "a29514ae" "2208" "e2b234f807886400"
+		"0322"  "2010" "fa8f20b781b5881329d4fea26b1a3c51"
+			"2104" "5afc8d72" "2208" "2392f14f709ae000"
+		"0322"  "2010" "0fd4cc8dbe8715d1f439e304edfd68dc"
+			"2104" "bc8d1c5b" "2208" "da7cdd6bfe2d7000",
+		NULL);
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+	VERBOSE_ASSERT(auth_request_sent, == true, "%d");
+
+	BTW("MS sends Authen Response, VLR accepts and wants to send Ciphering Mode Command to MS"
+	    " -- but needs Classmark 2 to determine whether A5/3 is supported");
+	cipher_mode_cmd_sent = false;
+	ms_sends_msg("05542d8b2c3e");
+	OSMO_ASSERT(!cipher_mode_cmd_sent);
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("BSC sends back a BSSMAP Classmark Update, that triggers the Ciphering Mode Command in A5/3");
+	expect_cipher_mode_cmd("61855fb81fc2a800");
+	bss_sends_bssap_mgmt("541203505886130b6014042f6503b8800d2100");
+	OSMO_ASSERT(cipher_mode_cmd_sent);
+	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");
+	ms_sends_msg("0632");
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT");
+	gsup_rx("10010809710000004026f00804032443f2",
+		"12010809710000004026f0");
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("HLR also sends GSUP _UPDATE_LOCATION_RESULT");
+	expect_bssap_clear();
+	gsup_rx("06010809710000004026f0", NULL);
+	VERBOSE_ASSERT(bssap_clear_sent, == true, "%d");
+
+	btw("LU was successful, and the conn has already been closed");
+	VERBOSE_ASSERT(lu_result_sent, == RES_ACCEPT, "%d");
+	bss_sends_clear_complete();
+	EXPECT_CONN_COUNT(0);
+
+	BTW("after a while, a new conn sends a CM Service Request. VLR responds with Auth Req, 2nd auth vector");
+	cm_service_result_sent = RES_NONE;
+	auth_request_sent = false;
+	auth_request_expect_rand = "12aca96fb4ffdea5c985cbafa9b6e18b";
+	ms_sends_msg("05247803305886089910070000006402");
+	OSMO_ASSERT(g_conn);
+	OSMO_ASSERT(g_conn->fi);
+	OSMO_ASSERT(g_conn->vsub);
+	VERBOSE_ASSERT(auth_request_sent, == true, "%d");
+	VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d");
+
+	btw("needs auth, not yet accepted");
+	EXPECT_ACCEPTED(false);
+	thwart_rx_non_initial_requests();
+
+	btw("MS sends Authen Response, VLR accepts and requests Ciphering. We already know Classmark 3,"
+	    " so no need to request Classmark Update.");
+	expect_cipher_mode_cmd("07fa7502e07e1c00");
+	ms_sends_msg("0554" "20bde240" /* 2nd vector's sres, s.a. */);
+	VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d");
+	VERBOSE_ASSERT(cipher_mode_cmd_sent, == true, "%d");
+
+	btw("needs ciph, not yet accepted");
+	EXPECT_ACCEPTED(false);
+	thwart_rx_non_initial_requests();
+
+	btw("MS sends Ciphering Mode Complete, VLR accepts; above Ciphering is an implicit CM Service Accept");
+	ms_sends_msg("0632");
+	VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d");
+
+	/* Release connection */
+	expect_bssap_clear(RAN_GERAN_A);
+	conn_conclude_cm_service_req(g_conn, RAN_GERAN_A);
+
+	btw("all requests serviced, conn has been released");
+	bss_sends_clear_complete();
+	EXPECT_CONN_COUNT(0);
+
+	BTW("an SMS is sent, MS is paged");
+	paging_expect_imsi(imsi);
+	paging_sent = false;
+	vsub = vlr_subscr_find_by_imsi(net->vlr, imsi);
+	OSMO_ASSERT(vsub);
+	VERBOSE_ASSERT(llist_count(&vsub->cs.requests), == 0, "%d");
+
+	send_sms(vsub, vsub,
+		 "Privacy in residential applications is a desirable"
+		 " marketing option.");
+
+	VERBOSE_ASSERT(llist_count(&vsub->cs.requests), == 1, "%d");
+	vlr_subscr_put(vsub);
+	vsub = NULL;
+	VERBOSE_ASSERT(paging_sent, == true, "%d");
+	VERBOSE_ASSERT(paging_stopped, == false, "%d");
+
+	btw("the subscriber and its pending request should remain");
+	vsub = vlr_subscr_find_by_imsi(net->vlr, imsi);
+	OSMO_ASSERT(vsub);
+	VERBOSE_ASSERT(llist_count(&vsub->cs.requests), == 1, "%d");
+	vlr_subscr_put(vsub);
+
+	btw("MS replies with Paging Response, and VLR sends Auth Request with third key");
+	auth_request_sent = false;
+	auth_request_expect_rand = "e7c03ba7cf0e2fde82b2dc4d63077d42";
+	ms_sends_msg("06270703305882089910070000006402");
+	VERBOSE_ASSERT(auth_request_sent, == true, "%d");
+
+	btw("needs auth, not yet accepted");
+	EXPECT_ACCEPTED(false);
+	thwart_rx_non_initial_requests();
+
+	btw("MS sends Authen Response, VLR accepts and requests Ciphering");
+	expect_cipher_mode_cmd("e2b234f807886400");
+	ms_sends_msg("0554" "a29514ae" /* 3rd vector's sres, s.a. */);
+	VERBOSE_ASSERT(cipher_mode_cmd_sent, == true, "%d");
+
+	btw("needs ciph, not yet accepted");
+	EXPECT_ACCEPTED(false);
+	thwart_rx_non_initial_requests();
+
+	btw("MS sends Ciphering Mode Complete, VLR accepts and sends pending SMS");
+	dtap_expect_tx("09" /* SMS messages */
+		       "01" /* CP-DATA */
+		       "58" /* length */
+		       "01" /* Network to MS */
+		       "00" /* reference */
+		       /* originator (gsm411_send_sms() hardcodes this weird nr) */
+		       "0791" "447758100650" /* 447785016005 */
+		       "00" /* dest */
+		       /* SMS TPDU */
+		       "4c" /* len */
+		       "00" /* SMS deliver */
+		       "05802443f2" /* originating address 42342 */
+		       "00" /* TP-PID */
+		       "00" /* GSM default alphabet */
+		       "071010" /* Y-M-D (from wrapped gsm340_gen_scts())*/
+		       "000000" /* H-M-S */
+		       "00" /* GMT+0 */
+		       "44" /* data length */
+		       "5079da1e1ee7416937485e9ea7c965373d1d6683c270383b3d0e"
+		       "d3d36ff71c949e83c22072799e9687c5ec32a81d96afcbf4b4fb"
+		       "0c7ac3e9e9b7db05");
+	ms_sends_msg("0632");
+	VERBOSE_ASSERT(dtap_tx_confirmed, == true, "%d");
+	VERBOSE_ASSERT(paging_stopped, == true, "%d");
+
+	btw("SMS was delivered, no requests pending for subscr");
+	vsub = vlr_subscr_find_by_imsi(net->vlr, imsi);
+	OSMO_ASSERT(vsub);
+	VERBOSE_ASSERT(llist_count(&vsub->cs.requests), == 0, "%d");
+	vlr_subscr_put(vsub);
+
+	btw("conn is still open to wait for SMS ack dance");
+	EXPECT_CONN_COUNT(1);
+
+	btw("MS replies with CP-ACK for received SMS");
+	ms_sends_msg("8904");
+	EXPECT_CONN_COUNT(1);
+
+	btw("MS also sends RP-ACK, MSC in turn sends CP-ACK for that");
+	dtap_expect_tx("0904");
+	expect_bssap_clear();
+	ms_sends_msg("890106020041020000");
+	VERBOSE_ASSERT(dtap_tx_confirmed, == true, "%d");
+	VERBOSE_ASSERT(bssap_clear_sent, == true, "%d");
+
+	btw("SMS is done, conn is gone");
+	bss_sends_clear_complete();
+	EXPECT_CONN_COUNT(0);
+
+	BTW("subscriber detaches");
+	expect_bssap_clear();
+	ms_sends_msg("050130089910070000006402");
+	VERBOSE_ASSERT(bssap_clear_sent, == true, "%d");
+
+	bss_sends_clear_complete();
+	EXPECT_CONN_COUNT(0);
+	clear_vlr();
+	comment_end();
+}
+
+/* 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
+ * proc_arq_fsm needs a Classmark Update during Ciphering. Shouldn't happen in reality though. */
+static void test_cm_service_needs_classmark_update()
+{
+	struct vlr_subscr *vsub;
+	const char *imsi = "901700000004620";
+
+	comment_start();
+
+	/* A5/3 support is indicated in Classmark 3. By configuring A5/3, trigger the code paths that
+	 * send a Classmark Request. */
+	net->a5_encryption_mask = (1 << 3); /* A5/3 */
+        /* implicit: net->authentication_required = true; */
+
+	btw("Location Update request causes a GSUP Send Auth Info request to HLR");
+	lu_result_sent = RES_NONE;
+	gsup_expect_tx("08010809710000004026f0");
+	ms_sends_msg("050802008168000130089910070000006402");
+	OSMO_ASSERT(gsup_tx_confirmed);
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("from HLR, rx _SEND_AUTH_INFO_RESULT; VLR sends Auth Req to MS");
+	/* Based on a Ki of 000102030405060708090a0b0c0d0e0f */
+	auth_request_sent = false;
+	auth_request_expect_rand = "585df1ae287f6e273dce07090d61320b";
+	auth_request_expect_autn = NULL;
+	gsup_rx("0a"
+		/* imsi */
+		"0108" "09710000004026f0"
+		/* 5 auth vectors... */
+		/* TL    TL     rand */
+		"0322"  "2010" "585df1ae287f6e273dce07090d61320b"
+		/*       TL     sres       TL     kc */
+			"2104" "2d8b2c3e" "2208" "61855fb81fc2a800"
+		"0322"  "2010" "12aca96fb4ffdea5c985cbafa9b6e18b"
+			"2104" "20bde240" "2208" "07fa7502e07e1c00"
+		"0322"  "2010" "e7c03ba7cf0e2fde82b2dc4d63077d42"
+			"2104" "a29514ae" "2208" "e2b234f807886400"
+		"0322"  "2010" "fa8f20b781b5881329d4fea26b1a3c51"
+			"2104" "5afc8d72" "2208" "2392f14f709ae000"
+		"0322"  "2010" "0fd4cc8dbe8715d1f439e304edfd68dc"
+			"2104" "bc8d1c5b" "2208" "da7cdd6bfe2d7000",
+		NULL);
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+	VERBOSE_ASSERT(auth_request_sent, == true, "%d");
+
+	BTW("MS sends Authen Response, VLR accepts and wants to send Ciphering Mode Command to MS"
+	    " -- but needs Classmark 2 to determine whether A5/3 is supported");
+	cipher_mode_cmd_sent = false;
+	ms_sends_msg("05542d8b2c3e");
+	OSMO_ASSERT(!cipher_mode_cmd_sent);
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("BSC sends back a BSSMAP Classmark Update, that triggers the Ciphering Mode Command in A5/3");
+	expect_cipher_mode_cmd("61855fb81fc2a800");
+	bss_sends_bssap_mgmt("541203505886130b6014042f6503b8800d2100");
+	OSMO_ASSERT(cipher_mode_cmd_sent);
+	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");
+	ms_sends_msg("0632");
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT");
+	gsup_rx("10010809710000004026f00804032443f2",
+		"12010809710000004026f0");
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("HLR also sends GSUP _UPDATE_LOCATION_RESULT");
+	expect_bssap_clear();
+	gsup_rx("06010809710000004026f0", NULL);
+	VERBOSE_ASSERT(bssap_clear_sent, == true, "%d");
+
+	btw("LU was successful, and the conn has already been closed");
+	VERBOSE_ASSERT(lu_result_sent, == RES_ACCEPT, "%d");
+	bss_sends_clear_complete();
+	EXPECT_CONN_COUNT(0);
+
+
+	BTW("after a while, a new conn sends a CM Service Request. VLR responds with Auth Req, 2nd auth vector");
+	cm_service_result_sent = RES_NONE;
+	auth_request_sent = false;
+	auth_request_expect_rand = "12aca96fb4ffdea5c985cbafa9b6e18b";
+	ms_sends_msg("05247803305886089910070000006402");
+	OSMO_ASSERT(g_conn);
+	OSMO_ASSERT(g_conn->fi);
+	OSMO_ASSERT(g_conn->vsub);
+	VERBOSE_ASSERT(auth_request_sent, == true, "%d");
+	VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d");
+
+	btw("needs auth, not yet accepted");
+	EXPECT_ACCEPTED(false);
+	thwart_rx_non_initial_requests();
+
+	btw("MS sends Authen Response, VLR accepts and requests Ciphering. We already know Classmark 3,"
+	    " so no need to request Classmark Update.");
+	expect_cipher_mode_cmd("07fa7502e07e1c00");
+	ms_sends_msg("0554" "20bde240" /* 2nd vector's sres, s.a. */);
+	VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d");
+	VERBOSE_ASSERT(cipher_mode_cmd_sent, == true, "%d");
+
+	btw("needs ciph, not yet accepted");
+	EXPECT_ACCEPTED(false);
+	thwart_rx_non_initial_requests();
+
+	btw("MS sends Ciphering Mode Complete, VLR accepts; above Ciphering is an implicit CM Service Accept");
+	ms_sends_msg("0632");
+	VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d");
+
+	/* Release connection */
+	expect_bssap_clear(RAN_GERAN_A);
+	conn_conclude_cm_service_req(g_conn, RAN_GERAN_A);
+
+	btw("all requests serviced, conn has been released");
+	bss_sends_clear_complete();
+	EXPECT_CONN_COUNT(0);
+
+	BTW("an SMS is sent, MS is paged");
+	paging_expect_imsi(imsi);
+	paging_sent = false;
+	vsub = vlr_subscr_find_by_imsi(net->vlr, imsi);
+	OSMO_ASSERT(vsub);
+	VERBOSE_ASSERT(llist_count(&vsub->cs.requests), == 0, "%d");
+
+	send_sms(vsub, vsub, "Privacy in residential applications is a desirable marketing option.");
+
+	VERBOSE_ASSERT(llist_count(&vsub->cs.requests), == 1, "%d");
+	vlr_subscr_put(vsub);
+	vsub = NULL;
+	VERBOSE_ASSERT(paging_sent, == true, "%d");
+	VERBOSE_ASSERT(paging_stopped, == false, "%d");
+
+	btw("the subscriber and its pending request should remain");
+	vsub = vlr_subscr_find_by_imsi(net->vlr, imsi);
+	OSMO_ASSERT(vsub);
+	VERBOSE_ASSERT(llist_count(&vsub->cs.requests), == 1, "%d");
+	vlr_subscr_put(vsub);
+
+	btw("MS replies with Paging Response, and VLR sends Auth Request with third key");
+	auth_request_sent = false;
+	auth_request_expect_rand = "e7c03ba7cf0e2fde82b2dc4d63077d42";
+	ms_sends_msg("06270703305882089910070000006402");
+	VERBOSE_ASSERT(auth_request_sent, == true, "%d");
+
+	BTW("Fake a situation where Classmark 2 is unknown during proc_arq_fsm");
+	vsub = vlr_subscr_find_by_imsi(net->vlr, imsi);
+	OSMO_ASSERT(vsub);
+	vsub->classmark.classmark2_len = 0;
+	vsub->classmark.classmark3_len = 0;
+	vlr_subscr_put(vsub);
+	
+
+	btw("MS sends Authen Response, VLR accepts and requests Ciphering");
+	btw("MS sends Authen Response, VLR accepts and requests Ciphering."
+	    " Normally, we'd know Classmark 3, but this test removed it."
+	    " Hence a Classmark Request is generated.");
+	cipher_mode_cmd_sent = false;
+	ms_sends_msg("0554" "a29514ae" /* 3rd vector's sres, s.a. */);
+	OSMO_ASSERT(!cipher_mode_cmd_sent);
+
+	btw("BSC sends back a BSSMAP Classmark Update, that triggers the Ciphering Mode Command in A5/3");
+	expect_cipher_mode_cmd("e2b234f807886400");
+	bss_sends_bssap_mgmt("541203505886130b6014042f6503b8800d2100");
+	OSMO_ASSERT(cipher_mode_cmd_sent);
+
+	btw("needs ciph, not yet accepted");
+	EXPECT_ACCEPTED(false);
+
+	btw("MS sends Ciphering Mode Complete, VLR accepts and sends pending SMS");
+	dtap_expect_tx("09" /* SMS messages */
+		       "01" /* CP-DATA */
+		       "58" /* length */
+		       "01" /* Network to MS */
+		       "00" /* reference */
+		       /* originator (gsm411_send_sms() hardcodes this weird nr) */
+		       "0791" "447758100650" /* 447785016005 */
+		       "00" /* dest */
+		       /* SMS TPDU */
+		       "4c" /* len */
+		       "00" /* SMS deliver */
+		       "05802443f2" /* originating address 42342 */
+		       "00" /* TP-PID */
+		       "00" /* GSM default alphabet */
+		       "071010" /* Y-M-D (from wrapped gsm340_gen_scts())*/
+		       "000000" /* H-M-S */
+		       "00" /* GMT+0 */
+		       "44" /* data length */
+		       "5079da1e1ee7416937485e9ea7c965373d1d6683c270383b3d0e"
+		       "d3d36ff71c949e83c22072799e9687c5ec32a81d96afcbf4b4fb"
+		       "0c7ac3e9e9b7db05");
+	ms_sends_msg("0632");
+	VERBOSE_ASSERT(dtap_tx_confirmed, == true, "%d");
+	VERBOSE_ASSERT(paging_stopped, == true, "%d");
+
+	btw("SMS was delivered, no requests pending for subscr");
+	vsub = vlr_subscr_find_by_imsi(net->vlr, imsi);
+	OSMO_ASSERT(vsub);
+	VERBOSE_ASSERT(llist_count(&vsub->cs.requests), == 0, "%d");
+	vlr_subscr_put(vsub);
+
+	btw("conn is still open to wait for SMS ack dance");
+	EXPECT_CONN_COUNT(1);
+
+	btw("MS replies with CP-ACK for received SMS");
+	ms_sends_msg("8904");
+	EXPECT_CONN_COUNT(1);
+
+	btw("MS also sends RP-ACK, MSC in turn sends CP-ACK for that");
+	dtap_expect_tx("0904");
+	expect_bssap_clear();
+	ms_sends_msg("890106020041020000");
+	VERBOSE_ASSERT(dtap_tx_confirmed, == true, "%d");
+	VERBOSE_ASSERT(bssap_clear_sent, == true, "%d");
+
+	btw("SMS is done, conn is gone");
+	bss_sends_clear_complete();
+	EXPECT_CONN_COUNT(0);
+
+	BTW("subscriber detaches");
+	expect_bssap_clear();
+	ms_sends_msg("050130089910070000006402");
+	VERBOSE_ASSERT(bssap_clear_sent, == true, "%d");
+
+	bss_sends_clear_complete();
+	EXPECT_CONN_COUNT(0);
+	clear_vlr();
+	comment_end();
+}
+
+
+msc_vlr_test_func_t msc_vlr_tests[] = {
+	test_ciph,
+	test_ciph_tmsi,
+	test_ciph_imei,
+	test_ciph_imeisv,
+	test_ciph_tmsi_imei,
+	test_gsm_ciph_in_umts_env,
+	test_a5_3_supported,
+	test_cm_service_needs_classmark_update,
+	NULL
+};
diff --git a/tests/msc_vlr/msc_vlr_test_gsm_ciph.err b/tests/msc_vlr/msc_vlr_test_gsm_ciph.err
new file mode 100644
index 0000000..cc8659c
--- /dev/null
+++ b/tests/msc_vlr/msc_vlr_test_gsm_ciph.err
@@ -0,0 +1,3256 @@
+full talloc report on 'msgb' (total      0 bytes in   1 blocks)
+talloc_total_blocks(tall_bsc_ctx) == 12
+
+===== test_ciph
+- Location Update request causes a GSUP Send Auth Info request to HLR
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8)
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Updated ID
+DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000004620 type=IMSI ATTACH
+DMM LU/new-LAC: 1/23
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Allocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: is child of Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: rev=GSM net=GERAN Auth+Ciph
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA
+DREF VLR subscr unknown usage increases to: 1
+DVLR set IMSI on subscriber; IMSI=901700000004620 id=901700000004620
+DVLR New subscr, IMSI: 901700000004620
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DREF VLR subscr IMSI:901700000004620 usage decreases to: 1
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Allocated
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
+DVLR GSUP tx: 08010809710000004026f0
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f0
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF IMSI:901700000004620: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  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: 0a010809710000004026f003222010585df1ae287f6e273dce07090d61320b21042d8b2c3e220861855fb81fc2a8000322201012aca96fb4ffdea5c985cbafa9b6e18b210420bde240220807fa7502e07e1c0003222010e7c03ba7cf0e2fde82b2dc4d63077d422104a29514ae2208e2b234f80788640003222010fa8f20b781b5881329d4fea26b1a3c5121045afc8d7222082392f14f709ae000032220100fd4cc8dbe8715d1f439e304edfd68dc2104bc8d1c5b2208da7cdd6bfe2d7000
+DVLR GSUP rx 191: 0a010809710000004026f003222010585df1ae287f6e273dce07090d61320b21042d8b2c3e220861855fb81fc2a8000322201012aca96fb4ffdea5c985cbafa9b6e18b210420bde240220807fa7502e07e1c0003222010e7c03ba7cf0e2fde82b2dc4d63077d422104a29514ae2208e2b234f80788640003222010fa8f20b781b5881329d4fea26b1a3c5121045afc8d7222082392f14f709ae000032220100fd4cc8dbe8715d1f439e304edfd68dc2104bc8d1c5b2208da7cdd6bfe2d7000
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: Received Event VLR_AUTH_E_HLR_SAI_ACK
+DVLR SUBSCR(IMSI:901700000004620) Received 5 auth tuples
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: state_chg to VLR_SUB_AS_WAIT_RESP
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_WAIT_RESP}: got auth tuple: use_count=1 key_seq=0 -- will use GSM AKA (is_r99=no, at->vec.auth_types=0x1)
+- sending GSM Auth Request for IMSI:901700000004620: tuple use_count=1 key_seq=0 auth_types=0x1 and...
+- ...rand=585df1ae287f6e273dce07090d61320b
+- ...expecting sres=2d8b2c3e
+DREF VLR subscr IMSI:901700000004620 usage decreases to: 1
+<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT: vlr_gsupc_read_cb() returns 0
+  lu_result_sent == 0
+  auth_request_sent == 1
+- MS sends Authen Response, VLR accepts and sends Ciphering Mode Command to MS
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_AUTH_RESP
+DREF IMSI:901700000004620: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14)
+DMM IMSI:901700000004620: MM GSM AUTHENTICATION RESPONSE (sres = 2d8b2c3e)
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP
+DVLR SUBSCR(IMSI:901700000004620) AUTH on GERAN received SRES/RES: 2d8b2c3e (4 bytes)
+DVLR SUBSCR(IMSI:901700000004620) AUTH established GSM security context
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result PASSED
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_AUTHENTICATED}: Freeing instance
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_AUTHENTICATED}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_AUTH}: Set Ciphering Mode
+DMM -> CIPHER MODE COMMAND IMSI:901700000004620
+- sending Ciphering Mode Command for IMSI:901700000004620: include_imeisv=0
+- ...perm algo: A5/1
+- ...key: 61855fb81fc2a800
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_WAIT_CIPH
+DREF IMSI:901700000004620: MSC conn use - dtap == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  lu_result_sent == 0
+- needs ciph, not yet accepted
+msc_subscr_conn_is_accepted() == false
+  requests shall be thwarted
+DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5)
+DRLL subscr IMSI:901700000004620: Message not permitted for initial conn: GSM48_MT_CC_SETUP
+DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33)
+DRLL subscr IMSI:901700000004620: Message not permitted for initial conn: unknown 0x33
+DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19)
+DRLL subscr IMSI:901700000004620: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1
+DRLL Dispatching 04.08 message SMS:0x01 (0x9:0x1)
+DRLL subscr IMSI:901700000004620: Message not permitted for initial conn: SMS:0x01
+  lu_result_sent == 0
+- MS sends Ciphering Mode Complete, VLR accepts and sends GSUP LU Req to HLR
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_RR_CIPH_M_COMPL
+DRR IMSI:901700000004620: CIPHERING MODE COMPLETE
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_CIPH}: Received Event VLR_ULA_E_CIPH_RES
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_CIPH}: vlr_loc_upd_post_ciph()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_CIPH}: vlr_loc_upd_node_4()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_CIPH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: Allocated
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START
+DVLR GSUP tx: 04010809710000004026f0280102
+GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000004026f0280102
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA
+  lu_result_sent == 0
+- HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT
+<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: 10010809710000004026f00804036470f1
+DVLR GSUP rx 17: 10010809710000004026f00804036470f1
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DVLR IMSI:901700000004620 has MSISDN:46071
+DVLR SUBSCR(MSISDN:46071) VLR: update for IMSI=901700000004620 (MSISDN=46071, used=2)
+DVLR GSUP tx: 12010809710000004026f0
+GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000004026f0
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+<-- 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: 06010809710000004026f0
+DVLR GSUP rx 11: 06010809710000004026f0
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Freeing instance
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: Allocated
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: Allocated
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(LU:901700000004620)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(LU:901700000004620)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Freeing instance
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Deallocated
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL
+- sending LU Accept for MSISDN:46071
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_DONE
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Freeing instance
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_ACCEPTED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:46071: MSC conn use + release == 1 (0x100: release)
+DREF VLR subscr MSISDN:46071 usage increases to: 4
+DREF VLR subscr MSISDN:46071 usage decreases to: 3
+- BSSAP Clear --RAN_GERAN_A--> MS
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+<-- 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
+  lu_result_sent == 1
+- BSS sends BSSMAP Clear Complete
+DREF MSISDN:46071: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Freeing instance
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Deallocated
+DRLL MSISDN:46071: Freeing subscriber connection
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+---
+- after a while, a new conn sends a CM Service Request. VLR responds with Auth Req, 2nd auth vector
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_CM_SERV_REQ
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_CM_SERV_REQ (0x5:0x24)
+DMM <- CM SERVICE REQUEST serv_type=0x08 MI(IMSI)=901700000004620
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_NEW}: Updated ID
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_INIT}: Allocated
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_INIT}: is child of Subscr_Conn(CM_SERVICE_REQ:901700000004620)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_INIT}: rev=GSM net=GERAN Auth+Ciph
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_WAIT_AUTH
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Allocated
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: is child of Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620)
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_WAIT_RESP
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000004620){VLR_SUB_AS_WAIT_RESP}: got auth tuple: use_count=1 key_seq=1 -- will use GSM AKA (is_r99=no, at->vec.auth_types=0x1)
+- sending GSM Auth Request for MSISDN:46071: tuple use_count=1 key_seq=1 auth_types=0x1 and...
+- ...rand=12aca96fb4ffdea5c985cbafa9b6e18b
+- ...expecting sres=20bde240
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF MSISDN:46071: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  auth_request_sent == 1
+  cm_service_result_sent == 0
+- needs auth, not yet accepted
+msc_subscr_conn_is_accepted() == false
+  requests shall be thwarted
+DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_CC_SETUP
+DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: unknown 0x33
+DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1
+DRLL Dispatching 04.08 message SMS:0x01 (0x9:0x1)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: SMS:0x01
+- MS sends Authen Response, VLR accepts and requests Ciphering
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_AUTH_RESP
+DREF MSISDN:46071: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14)
+DMM MSISDN:46071: MM GSM AUTHENTICATION RESPONSE (sres = 20bde240)
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000004620){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP
+DVLR SUBSCR(MSISDN:46071) AUTH on GERAN received SRES/RES: 20bde240 (4 bytes)
+DVLR SUBSCR(MSISDN:46071) AUTH established GSM security context
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000004620){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result PASSED
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000004620){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000004620){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000004620){VLR_SUB_AS_AUTHENTICATED}: Removing from parent Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620)
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000004620){VLR_SUB_AS_AUTHENTICATED}: Freeing instance
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000004620){VLR_SUB_AS_AUTHENTICATED}: Deallocated
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_WAIT_AUTH}: Received Event PR_ARQ_E_AUTH_RES
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_WAIT_AUTH}: Set Ciphering Mode
+DMM -> CIPHER MODE COMMAND MSISDN:46071
+- sending Ciphering Mode Command for MSISDN:46071: include_imeisv=0
+- ...perm algo: A5/1
+- ...key: 07fa7502e07e1c00
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_WAIT_AUTH}: state_chg to PR_ARQ_S_WAIT_CIPH
+DREF MSISDN:46071: MSC conn use - dtap == 0 (0x0: )
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  cm_service_result_sent == 0
+  cipher_mode_cmd_sent == 1
+- needs ciph, not yet accepted
+msc_subscr_conn_is_accepted() == false
+  requests shall be thwarted
+DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_CC_SETUP
+DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: unknown 0x33
+DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1
+DRLL Dispatching 04.08 message SMS:0x01 (0x9:0x1)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: SMS:0x01
+- MS sends Ciphering Mode Complete, VLR accepts; above Ciphering is an implicit CM Service Accept
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_RR_CIPH_M_COMPL
+DRR MSISDN:46071: CIPHERING MODE COMPLETE
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_WAIT_CIPH}: Received Event PR_ARQ_E_CIPH_RES
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_node2_post_ciph()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_node2_post_vlr()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_pres()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_trace()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_imei()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_WAIT_CIPH}: proc_arq_fsm_done(PASSED)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_WAIT_CIPH}: state_chg to PR_ARQ_S_DONE
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_DONE}: Process Access Request result: PASSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_ACCEPTED
+DREF MSISDN:46071: MSC conn use + cm_service == 1 (0x8: cm_service)
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_ACCEPTED}: subscr_conn_fsm_has_active_transactions: still awaiting first request after a CM Service Request
+  cm_service_result_sent == 0
+- Concluding CM Service Request
+DREF MSISDN:46071: MSC conn use - cm_service == 0 (0x0: )
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:46071: MSC conn use + release == 1 (0x100: release)
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+- BSSAP Clear --RAN_GERAN_A--> MS
+  bssap_clear_sent == 1
+- all requests serviced, conn has been released
+- BSS sends BSSMAP Clear Complete
+DREF MSISDN:46071: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_DONE}: Removing from parent Subscr_Conn(CM_SERVICE_REQ:901700000004620)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_DONE}: Freeing instance
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_DONE}: Deallocated
+DRLL MSISDN:46071: Freeing subscriber connection
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+---
+- an SMS is sent, MS is paged
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+  llist_count(&vsub->cs.requests) == 0
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DMM Subscriber MSISDN:46071 not paged yet, start paging.
+  RAN_GERAN_A sends out paging request to IMSI 901700000004620, TMSI 0xffffffff, LAC 23
+  strcmp(paging_expecting_imsi, imsi) == 0
+DREF VLR subscr MSISDN:46071 usage increases to: 4
+  llist_count(&vsub->cs.requests) == 1
+DREF VLR subscr MSISDN:46071 usage decreases to: 3
+  paging_sent == 1
+  paging_stopped == 0
+- the subscriber and its pending request should remain
+DREF VLR subscr MSISDN:46071 usage increases to: 4
+  llist_count(&vsub->cs.requests) == 1
+DREF VLR subscr MSISDN:46071 usage decreases to: 3
+- MS replies with Paging Response, and VLR sends Auth Request with third key
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_RR_PAG_RESP
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_RR_PAG_RESP (0x6:0x27)
+DRR PAGING RESPONSE: MI(IMSI)=901700000004620
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_NEW}: Updated ID
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_INIT}: Allocated
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_INIT}: is child of Subscr_Conn(PAGING_RESP:901700000004620)
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_INIT}: rev=GSM net=GERAN Auth+Ciph
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START
+DREF VLR subscr MSISDN:46071 usage increases to: 4
+DREF VLR subscr MSISDN:46071 usage increases to: 5
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi()
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_WAIT_AUTH
+DVLR VLR_Authenticate(PAGING_RESP:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Allocated
+DVLR VLR_Authenticate(PAGING_RESP:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: is child of Process_Access_Request_VLR(PAGING_RESP:901700000004620)
+DVLR VLR_Authenticate(PAGING_RESP:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
+DVLR VLR_Authenticate(PAGING_RESP:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_WAIT_RESP
+DVLR VLR_Authenticate(PAGING_RESP:901700000004620){VLR_SUB_AS_WAIT_RESP}: got auth tuple: use_count=1 key_seq=2 -- will use GSM AKA (is_r99=no, at->vec.auth_types=0x1)
+- sending GSM Auth Request for MSISDN:46071: tuple use_count=1 key_seq=2 auth_types=0x1 and...
+- ...rand=e7c03ba7cf0e2fde82b2dc4d63077d42
+- ...expecting sres=a29514ae
+DREF VLR subscr MSISDN:46071 usage decreases to: 4
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF MSISDN:46071: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  auth_request_sent == 1
+- needs auth, not yet accepted
+msc_subscr_conn_is_accepted() == false
+  requests shall be thwarted
+DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_CC_SETUP
+DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: unknown 0x33
+DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1
+DRLL Dispatching 04.08 message SMS:0x01 (0x9:0x1)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: SMS:0x01
+- MS sends Authen Response, VLR accepts and requests Ciphering
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_AUTH_RESP
+DREF MSISDN:46071: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14)
+DMM MSISDN:46071: MM GSM AUTHENTICATION RESPONSE (sres = a29514ae)
+DVLR VLR_Authenticate(PAGING_RESP:901700000004620){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP
+DVLR SUBSCR(MSISDN:46071) AUTH on GERAN received SRES/RES: a29514ae (4 bytes)
+DVLR SUBSCR(MSISDN:46071) AUTH established GSM security context
+DVLR VLR_Authenticate(PAGING_RESP:901700000004620){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result PASSED
+DVLR VLR_Authenticate(PAGING_RESP:901700000004620){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
+DVLR VLR_Authenticate(PAGING_RESP:901700000004620){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR VLR_Authenticate(PAGING_RESP:901700000004620){VLR_SUB_AS_AUTHENTICATED}: Removing from parent Process_Access_Request_VLR(PAGING_RESP:901700000004620)
+DVLR VLR_Authenticate(PAGING_RESP:901700000004620){VLR_SUB_AS_AUTHENTICATED}: Freeing instance
+DVLR VLR_Authenticate(PAGING_RESP:901700000004620){VLR_SUB_AS_AUTHENTICATED}: Deallocated
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_WAIT_AUTH}: Received Event PR_ARQ_E_AUTH_RES
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2()
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_WAIT_AUTH}: Set Ciphering Mode
+DMM -> CIPHER MODE COMMAND MSISDN:46071
+- sending Ciphering Mode Command for MSISDN:46071: include_imeisv=0
+- ...perm algo: A5/1
+- ...key: e2b234f807886400
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_WAIT_AUTH}: state_chg to PR_ARQ_S_WAIT_CIPH
+DREF MSISDN:46071: MSC conn use - dtap == 0 (0x0: )
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  cipher_mode_cmd_sent == 1
+- needs ciph, not yet accepted
+msc_subscr_conn_is_accepted() == false
+  requests shall be thwarted
+DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_CC_SETUP
+DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: unknown 0x33
+DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1
+DRLL Dispatching 04.08 message SMS:0x01 (0x9:0x1)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: SMS:0x01
+- MS sends Ciphering Mode Complete, VLR accepts and sends pending SMS
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_RR_CIPH_M_COMPL
+DRR MSISDN:46071: CIPHERING MODE COMPLETE
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_WAIT_CIPH}: Received Event PR_ARQ_E_CIPH_RES
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_node2_post_ciph()
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_node2_post_vlr()
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_pres()
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_trace()
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_imei()
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_WAIT_CIPH}: proc_arq_fsm_done(PASSED)
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_WAIT_CIPH}: state_chg to PR_ARQ_S_DONE
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_DONE}: Process Access Request result: PASSED
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_ACCEPTED
+DPAG Paging success for MSISDN:46071 (event=0)
+DPAG Calling paging cbfn.
+DCC (ti 00 sub MSISDN:46071 callref 40000001) New transaction
+DREF VLR subscr MSISDN:46071 usage increases to: 5
+DREF MSISDN:46071: MSC conn use + trans_sms == 1 (0x20: trans_sms)
+DMSC msc_tx 91 bytes to MSISDN:46071 via RAN_GERAN_A
+- DTAP --RAN_GERAN_A--> MS: SMS:0x01: 09015801000791447758100650004c0005806470f1000007101000000000445079da1e1ee7416937485e9ea7c965373d1d6683c270383b3d0ed3d36ff71c949e83c22072799e9687c5ec32a81d96afcbf4b4fb0c7ac3e9e9b7db05
+- DTAP matches expected message
+DREF VLR subscr MSISDN:46071 usage decreases to: 4
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_ACCEPTED}: subscr_conn_fsm_has_active_transactions: connection still has active transaction: SMS
+  dtap_tx_confirmed == 1
+  paging_stopped == 1
+- SMS was delivered, no requests pending for subscr
+DREF VLR subscr MSISDN:46071 usage increases to: 5
+  llist_count(&vsub->cs.requests) == 0
+DREF VLR subscr MSISDN:46071 usage decreases to: 4
+- conn is still open to wait for SMS ack dance
+  llist_count(&net->subscr_conns) == 1
+- MS replies with CP-ACK for received SMS
+  MSC <--RAN_GERAN_A-- MS: SMS:0x04
+DREF MSISDN:46071: MSC conn use + dtap == 2 (0x22: dtap,trans_sms)
+DRLL Dispatching 04.08 message SMS:0x04 (0x9:0x4)
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_COMMUNICATING
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_COMMUNICATING
+DREF MSISDN:46071: MSC conn use - dtap == 1 (0x20: trans_sms)
+  llist_count(&net->subscr_conns) == 1
+- MS also sends RP-ACK, MSC in turn sends CP-ACK for that
+  MSC <--RAN_GERAN_A-- MS: SMS:0x01
+DREF MSISDN:46071: MSC conn use + dtap == 2 (0x22: dtap,trans_sms)
+DRLL Dispatching 04.08 message SMS:0x01 (0x9:0x1)
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_COMMUNICATING}: Received Event SUBSCR_CONN_E_COMMUNICATING
+DMSC msc_tx 2 bytes to MSISDN:46071 via RAN_GERAN_A
+- DTAP --RAN_GERAN_A--> MS: SMS:0x04: 0904
+- DTAP matches expected message
+DREF VLR subscr MSISDN:46071 usage decreases to: 3
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+DREF MSISDN:46071: MSC conn use - trans_sms == 1 (0x2: dtap)
+DREF MSISDN:46071: MSC conn use - dtap == 0 (0x0: )
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_COMMUNICATING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_COMMUNICATING}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:46071: MSC conn use + release == 1 (0x100: release)
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+- BSSAP Clear --RAN_GERAN_A--> MS
+  dtap_tx_confirmed == 1
+  bssap_clear_sent == 1
+- SMS is done, conn is gone
+- BSS sends BSSMAP Clear Complete
+DREF MSISDN:46071: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_DONE}: Removing from parent Subscr_Conn(PAGING_RESP:901700000004620)
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_DONE}: Freeing instance
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_DONE}: Deallocated
+DRLL MSISDN:46071: Freeing subscriber connection
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+---
+- subscriber detaches
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_IMSI_DETACH_IND
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_IMSI_DETACH_IND (0x5:0x1)
+DMM IMSI DETACH INDICATION: MI(IMSI)=901700000004620
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+DMM IMSI DETACH for MSISDN:46071
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+DREF VLR subscr MSISDN:46071 usage decreases to: 0
+DREF freeing VLR subscr MSISDN:46071
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_CN_CLOSE
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF unknown: MSC conn use + release == 2 (0x101: compl_l3,release)
+- BSSAP Clear --RAN_GERAN_A--> MS
+DREF unknown: MSC conn use - compl_l3 == 1 (0x100: release)
+  bssap_clear_sent == 1
+- BSS sends BSSMAP Clear Complete
+DREF unknown: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DRLL Freeing subscriber connection with NULL subscriber
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+===== test_ciph: SUCCESS
+
+full talloc report on 'msgb' (total      0 bytes in   1 blocks)
+talloc_total_blocks(tall_bsc_ctx) == 12
+
+===== test_ciph_tmsi
+- Location Update request causes a GSUP Send Auth Info request to HLR
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8)
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Updated ID
+DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000004620 type=IMSI ATTACH
+DMM LU/new-LAC: 1/23
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Allocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: is child of Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: rev=GSM net=GERAN Auth+Ciph
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA
+DREF VLR subscr unknown usage increases to: 1
+DVLR set IMSI on subscriber; IMSI=901700000004620 id=901700000004620
+DVLR New subscr, IMSI: 901700000004620
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DREF VLR subscr IMSI:901700000004620 usage decreases to: 1
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Allocated
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
+DVLR GSUP tx: 08010809710000004026f0
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f0
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF IMSI:901700000004620: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  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: 0a010809710000004026f003222010585df1ae287f6e273dce07090d61320b21042d8b2c3e220861855fb81fc2a8000322201012aca96fb4ffdea5c985cbafa9b6e18b210420bde240220807fa7502e07e1c0003222010e7c03ba7cf0e2fde82b2dc4d63077d422104a29514ae2208e2b234f80788640003222010fa8f20b781b5881329d4fea26b1a3c5121045afc8d7222082392f14f709ae000032220100fd4cc8dbe8715d1f439e304edfd68dc2104bc8d1c5b2208da7cdd6bfe2d7000
+DVLR GSUP rx 191: 0a010809710000004026f003222010585df1ae287f6e273dce07090d61320b21042d8b2c3e220861855fb81fc2a8000322201012aca96fb4ffdea5c985cbafa9b6e18b210420bde240220807fa7502e07e1c0003222010e7c03ba7cf0e2fde82b2dc4d63077d422104a29514ae2208e2b234f80788640003222010fa8f20b781b5881329d4fea26b1a3c5121045afc8d7222082392f14f709ae000032220100fd4cc8dbe8715d1f439e304edfd68dc2104bc8d1c5b2208da7cdd6bfe2d7000
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: Received Event VLR_AUTH_E_HLR_SAI_ACK
+DVLR SUBSCR(IMSI:901700000004620) Received 5 auth tuples
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: state_chg to VLR_SUB_AS_WAIT_RESP
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_WAIT_RESP}: got auth tuple: use_count=1 key_seq=0 -- will use GSM AKA (is_r99=no, at->vec.auth_types=0x1)
+- sending GSM Auth Request for IMSI:901700000004620: tuple use_count=1 key_seq=0 auth_types=0x1 and...
+- ...rand=585df1ae287f6e273dce07090d61320b
+- ...expecting sres=2d8b2c3e
+DREF VLR subscr IMSI:901700000004620 usage decreases to: 1
+<-- 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 Ciphering Mode Command to MS
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_AUTH_RESP
+DREF IMSI:901700000004620: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14)
+DMM IMSI:901700000004620: MM GSM AUTHENTICATION RESPONSE (sres = 2d8b2c3e)
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP
+DVLR SUBSCR(IMSI:901700000004620) AUTH on GERAN received SRES/RES: 2d8b2c3e (4 bytes)
+DVLR SUBSCR(IMSI:901700000004620) AUTH established GSM security context
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result PASSED
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_AUTHENTICATED}: Freeing instance
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_AUTHENTICATED}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_AUTH}: Set Ciphering Mode
+DMM -> CIPHER MODE COMMAND IMSI:901700000004620
+- sending Ciphering Mode Command for IMSI:901700000004620: include_imeisv=0
+- ...perm algo: A5/1
+- ...key: 61855fb81fc2a800
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_WAIT_CIPH
+DREF IMSI:901700000004620: MSC conn use - dtap == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  lu_result_sent == 0
+  auth_request_sent == 1
+- needs ciph, not yet accepted
+msc_subscr_conn_is_accepted() == false
+  requests shall be thwarted
+DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5)
+DRLL subscr IMSI:901700000004620: Message not permitted for initial conn: GSM48_MT_CC_SETUP
+DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33)
+DRLL subscr IMSI:901700000004620: Message not permitted for initial conn: unknown 0x33
+DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19)
+DRLL subscr IMSI:901700000004620: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1
+DRLL Dispatching 04.08 message SMS:0x01 (0x9:0x1)
+DRLL subscr IMSI:901700000004620: Message not permitted for initial conn: SMS:0x01
+  lu_result_sent == 0
+- MS sends Ciphering Mode Complete, VLR accepts and sends GSUP LU Req to HLR
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_RR_CIPH_M_COMPL
+DRR IMSI:901700000004620: CIPHERING MODE COMPLETE
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_CIPH}: Received Event VLR_ULA_E_CIPH_RES
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_CIPH}: vlr_loc_upd_post_ciph()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_CIPH}: vlr_loc_upd_node_4()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_CIPH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: Allocated
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START
+DVLR GSUP tx: 04010809710000004026f0280102
+GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000004026f0280102
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA
+  lu_result_sent == 0
+- HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT
+<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: 10010809710000004026f00804036470f1
+DVLR GSUP rx 17: 10010809710000004026f00804036470f1
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DVLR IMSI:901700000004620 has MSISDN:46071
+DVLR SUBSCR(MSISDN:46071) VLR: update for IMSI=901700000004620 (MSISDN=46071, used=2)
+DVLR GSUP tx: 12010809710000004026f0
+GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000004026f0
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+<-- 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: 06010809710000004026f0
+DVLR GSUP rx 11: 06010809710000004026f0
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Freeing instance
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: Allocated
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: Allocated
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(LU:901700000004620)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(LU:901700000004620)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Freeing instance
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Deallocated
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: lu_compl_vlr_new_tmsi()
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_WAIT_TMSI_CNF
+- sending LU Accept for MSISDN:46071, with TMSI 0x03020100
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: vlr_gsupc_read_cb() returns 0
+- a LU Accept with a new TMSI was sent, waiting for TMSI Realloc Compl
+  llist_count(&net->subscr_conns) == 1
+  lu_result_sent == 1
+msc_subscr_conn_is_accepted() == false
+  requests shall be thwarted
+DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_CC_SETUP
+DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: unknown 0x33
+DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1
+DRLL Dispatching 04.08 message SMS:0x01 (0x9:0x1)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: SMS:0x01
+- even though the TMSI is not acked, we can already find the subscr with it
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+  vsub != NULL == 1
+  strcmp(vsub->imsi, imsi) == 0
+  vsub->tmsi_new == 0x03020100
+  vsub->tmsi == 0xffffffff
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+- MS sends TMSI Realloc Complete
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_TMSI_REALL_COMPL
+DREF MSISDN:46071: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_TMSI_REALL_COMPL (0x5:0x1b)
+DMM TMSI Reallocation Completed. Subscriber: MSISDN:46071
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_NEW_TMSI_ACK
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_TMSI_CNF}: Received Event LU_COMPL_VLR_E_NEW_TMSI_ACK
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_TMSI_CNF}: state_chg to LU_COMPL_VLR_S_DONE
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Freeing instance
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_ACCEPTED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:46071: MSC conn use + release == 2 (0x102: dtap,release)
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+- BSSAP Clear --RAN_GERAN_A--> MS
+DREF MSISDN:46071: MSC conn use - dtap == 1 (0x100: release)
+  bssap_clear_sent == 1
+- LU was successful, and the conn has already been closed
+- BSS sends BSSMAP Clear Complete
+DREF MSISDN:46071: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Freeing instance
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Deallocated
+DRLL MSISDN:46071: Freeing subscriber connection
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+- Subscriber has the new TMSI
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+  vsub != NULL == 1
+  strcmp(vsub->imsi, imsi) == 0
+  vsub->tmsi_new == 0xffffffff
+  vsub->tmsi == 0x03020100
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+---
+- after a while, a new conn sends a CM Service Request using above TMSI. VLR responds with Auth Req, 2nd auth vector
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_CM_SERV_REQ
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_CM_SERV_REQ (0x5:0x24)
+DMM <- CM SERVICE REQUEST serv_type=0x08 MI(TMSI)=50462976
+DMM Subscr_Conn(CM_SERVICE_REQ:50462976){SUBSCR_CONN_S_NEW}: Updated ID
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:50462976){PR_ARQ_S_INIT}: Allocated
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:50462976){PR_ARQ_S_INIT}: is child of Subscr_Conn(CM_SERVICE_REQ:50462976)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:50462976){PR_ARQ_S_INIT}: rev=GSM net=GERAN Auth+Ciph
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:50462976){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:50462976){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:50462976){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_WAIT_AUTH
+DVLR VLR_Authenticate(CM_SERVICE_REQ:50462976){VLR_SUB_AS_NEEDS_AUTH}: Allocated
+DVLR VLR_Authenticate(CM_SERVICE_REQ:50462976){VLR_SUB_AS_NEEDS_AUTH}: is child of Process_Access_Request_VLR(CM_SERVICE_REQ:50462976)
+DVLR VLR_Authenticate(CM_SERVICE_REQ:50462976){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
+DVLR VLR_Authenticate(CM_SERVICE_REQ:50462976){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_WAIT_RESP
+DVLR VLR_Authenticate(CM_SERVICE_REQ:50462976){VLR_SUB_AS_WAIT_RESP}: got auth tuple: use_count=1 key_seq=1 -- will use GSM AKA (is_r99=no, at->vec.auth_types=0x1)
+- sending GSM Auth Request for MSISDN:46071: tuple use_count=1 key_seq=1 auth_types=0x1 and...
+- ...rand=12aca96fb4ffdea5c985cbafa9b6e18b
+- ...expecting sres=20bde240
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+DMM Subscr_Conn(CM_SERVICE_REQ:50462976){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(CM_SERVICE_REQ:50462976){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF MSISDN:46071: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(CM_SERVICE_REQ:50462976){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(CM_SERVICE_REQ:50462976){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  auth_request_sent == 1
+  cm_service_result_sent == 0
+- needs auth, not yet accepted
+msc_subscr_conn_is_accepted() == false
+  requests shall be thwarted
+DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_CC_SETUP
+DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: unknown 0x33
+DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1
+DRLL Dispatching 04.08 message SMS:0x01 (0x9:0x1)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: SMS:0x01
+- MS sends Authen Response, VLR accepts and requests Ciphering
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_AUTH_RESP
+DREF MSISDN:46071: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14)
+DMM MSISDN:46071: MM GSM AUTHENTICATION RESPONSE (sres = 20bde240)
+DVLR VLR_Authenticate(CM_SERVICE_REQ:50462976){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP
+DVLR SUBSCR(MSISDN:46071) AUTH on GERAN received SRES/RES: 20bde240 (4 bytes)
+DVLR SUBSCR(MSISDN:46071) AUTH established GSM security context
+DVLR VLR_Authenticate(CM_SERVICE_REQ:50462976){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result PASSED
+DVLR VLR_Authenticate(CM_SERVICE_REQ:50462976){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
+DVLR VLR_Authenticate(CM_SERVICE_REQ:50462976){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR VLR_Authenticate(CM_SERVICE_REQ:50462976){VLR_SUB_AS_AUTHENTICATED}: Removing from parent Process_Access_Request_VLR(CM_SERVICE_REQ:50462976)
+DVLR VLR_Authenticate(CM_SERVICE_REQ:50462976){VLR_SUB_AS_AUTHENTICATED}: Freeing instance
+DVLR VLR_Authenticate(CM_SERVICE_REQ:50462976){VLR_SUB_AS_AUTHENTICATED}: Deallocated
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:50462976){PR_ARQ_S_WAIT_AUTH}: Received Event PR_ARQ_E_AUTH_RES
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:50462976){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:50462976){PR_ARQ_S_WAIT_AUTH}: Set Ciphering Mode
+DMM -> CIPHER MODE COMMAND MSISDN:46071
+- sending Ciphering Mode Command for MSISDN:46071: include_imeisv=0
+- ...perm algo: A5/1
+- ...key: 07fa7502e07e1c00
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:50462976){PR_ARQ_S_WAIT_AUTH}: state_chg to PR_ARQ_S_WAIT_CIPH
+DREF MSISDN:46071: MSC conn use - dtap == 0 (0x0: )
+DMM Subscr_Conn(CM_SERVICE_REQ:50462976){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(CM_SERVICE_REQ:50462976){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  cm_service_result_sent == 0
+  cipher_mode_cmd_sent == 1
+- needs ciph, not yet accepted
+msc_subscr_conn_is_accepted() == false
+  requests shall be thwarted
+DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_CC_SETUP
+DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: unknown 0x33
+DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1
+DRLL Dispatching 04.08 message SMS:0x01 (0x9:0x1)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: SMS:0x01
+- MS sends Ciphering Mode Complete, VLR accepts; above Ciphering is an implicit CM Service Accept
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_RR_CIPH_M_COMPL
+DRR MSISDN:46071: CIPHERING MODE COMPLETE
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:50462976){PR_ARQ_S_WAIT_CIPH}: Received Event PR_ARQ_E_CIPH_RES
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:50462976){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_node2_post_ciph()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:50462976){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_node2_post_vlr()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:50462976){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_pres()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:50462976){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_trace()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:50462976){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_imei()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:50462976){PR_ARQ_S_WAIT_CIPH}: proc_arq_fsm_done(PASSED)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:50462976){PR_ARQ_S_WAIT_CIPH}: state_chg to PR_ARQ_S_DONE
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:50462976){PR_ARQ_S_DONE}: Process Access Request result: PASSED
+DMM Subscr_Conn(CM_SERVICE_REQ:50462976){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_ACCEPTED
+DREF MSISDN:46071: MSC conn use + cm_service == 1 (0x8: cm_service)
+DMM Subscr_Conn(CM_SERVICE_REQ:50462976){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(CM_SERVICE_REQ:50462976){SUBSCR_CONN_S_ACCEPTED}: subscr_conn_fsm_has_active_transactions: still awaiting first request after a CM Service Request
+  cm_service_result_sent == 0
+- Concluding CM Service Request
+DREF MSISDN:46071: MSC conn use - cm_service == 0 (0x0: )
+DMM Subscr_Conn(CM_SERVICE_REQ:50462976){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(CM_SERVICE_REQ:50462976){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:46071: MSC conn use + release == 1 (0x100: release)
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+- BSSAP Clear --RAN_GERAN_A--> MS
+  bssap_clear_sent == 1
+- all requests serviced, conn has been released
+- BSS sends BSSMAP Clear Complete
+DREF MSISDN:46071: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(CM_SERVICE_REQ:50462976){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(CM_SERVICE_REQ:50462976){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(CM_SERVICE_REQ:50462976){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:50462976){PR_ARQ_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:50462976){PR_ARQ_S_DONE}: Removing from parent Subscr_Conn(CM_SERVICE_REQ:50462976)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:50462976){PR_ARQ_S_DONE}: Freeing instance
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:50462976){PR_ARQ_S_DONE}: Deallocated
+DRLL MSISDN:46071: Freeing subscriber connection
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+DMM Subscr_Conn(CM_SERVICE_REQ:50462976){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(CM_SERVICE_REQ:50462976){SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+---
+- an SMS is sent, MS is paged
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+  llist_count(&vsub->cs.requests) == 0
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DMM Subscriber MSISDN:46071 not paged yet, start paging.
+  RAN_GERAN_A sends out paging request to IMSI 901700000004620, TMSI 0x03020100, LAC 23
+  paging_expecting_tmsi == 0x03020100
+DREF VLR subscr MSISDN:46071 usage increases to: 4
+  llist_count(&vsub->cs.requests) == 1
+DREF VLR subscr MSISDN:46071 usage decreases to: 3
+  paging_sent == 1
+  paging_stopped == 0
+- the subscriber and its pending request should remain
+DREF VLR subscr MSISDN:46071 usage increases to: 4
+  llist_count(&vsub->cs.requests) == 1
+DREF VLR subscr MSISDN:46071 usage decreases to: 3
+- MS replies with Paging Response using TMSI, and VLR sends Auth Request with third key
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_RR_PAG_RESP
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_RR_PAG_RESP (0x6:0x27)
+DRR PAGING RESPONSE: MI(TMSI)=50462976
+DMM Subscr_Conn(PAGING_RESP:50462976){SUBSCR_CONN_S_NEW}: Updated ID
+DVLR Process_Access_Request_VLR(PAGING_RESP:50462976){PR_ARQ_S_INIT}: Allocated
+DVLR Process_Access_Request_VLR(PAGING_RESP:50462976){PR_ARQ_S_INIT}: is child of Subscr_Conn(PAGING_RESP:50462976)
+DVLR Process_Access_Request_VLR(PAGING_RESP:50462976){PR_ARQ_S_INIT}: rev=GSM net=GERAN Auth+Ciph
+DVLR Process_Access_Request_VLR(PAGING_RESP:50462976){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START
+DREF VLR subscr MSISDN:46071 usage increases to: 4
+DREF VLR subscr MSISDN:46071 usage increases to: 5
+DVLR Process_Access_Request_VLR(PAGING_RESP:50462976){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi()
+DVLR Process_Access_Request_VLR(PAGING_RESP:50462976){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_WAIT_AUTH
+DVLR VLR_Authenticate(PAGING_RESP:50462976){VLR_SUB_AS_NEEDS_AUTH}: Allocated
+DVLR VLR_Authenticate(PAGING_RESP:50462976){VLR_SUB_AS_NEEDS_AUTH}: is child of Process_Access_Request_VLR(PAGING_RESP:50462976)
+DVLR VLR_Authenticate(PAGING_RESP:50462976){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
+DVLR VLR_Authenticate(PAGING_RESP:50462976){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_WAIT_RESP
+DVLR VLR_Authenticate(PAGING_RESP:50462976){VLR_SUB_AS_WAIT_RESP}: got auth tuple: use_count=1 key_seq=2 -- will use GSM AKA (is_r99=no, at->vec.auth_types=0x1)
+- sending GSM Auth Request for MSISDN:46071: tuple use_count=1 key_seq=2 auth_types=0x1 and...
+- ...rand=e7c03ba7cf0e2fde82b2dc4d63077d42
+- ...expecting sres=a29514ae
+DREF VLR subscr MSISDN:46071 usage decreases to: 4
+DMM Subscr_Conn(PAGING_RESP:50462976){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(PAGING_RESP:50462976){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF MSISDN:46071: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(PAGING_RESP:50462976){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(PAGING_RESP:50462976){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  auth_request_sent == 1
+- needs auth, not yet accepted
+msc_subscr_conn_is_accepted() == false
+  requests shall be thwarted
+DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_CC_SETUP
+DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: unknown 0x33
+DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1
+DRLL Dispatching 04.08 message SMS:0x01 (0x9:0x1)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: SMS:0x01
+- MS sends Authen Response, VLR accepts and requests Ciphering
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_AUTH_RESP
+DREF MSISDN:46071: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14)
+DMM MSISDN:46071: MM GSM AUTHENTICATION RESPONSE (sres = a29514ae)
+DVLR VLR_Authenticate(PAGING_RESP:50462976){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP
+DVLR SUBSCR(MSISDN:46071) AUTH on GERAN received SRES/RES: a29514ae (4 bytes)
+DVLR SUBSCR(MSISDN:46071) AUTH established GSM security context
+DVLR VLR_Authenticate(PAGING_RESP:50462976){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result PASSED
+DVLR VLR_Authenticate(PAGING_RESP:50462976){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
+DVLR VLR_Authenticate(PAGING_RESP:50462976){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR VLR_Authenticate(PAGING_RESP:50462976){VLR_SUB_AS_AUTHENTICATED}: Removing from parent Process_Access_Request_VLR(PAGING_RESP:50462976)
+DVLR VLR_Authenticate(PAGING_RESP:50462976){VLR_SUB_AS_AUTHENTICATED}: Freeing instance
+DVLR VLR_Authenticate(PAGING_RESP:50462976){VLR_SUB_AS_AUTHENTICATED}: Deallocated
+DVLR Process_Access_Request_VLR(PAGING_RESP:50462976){PR_ARQ_S_WAIT_AUTH}: Received Event PR_ARQ_E_AUTH_RES
+DVLR Process_Access_Request_VLR(PAGING_RESP:50462976){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2()
+DVLR Process_Access_Request_VLR(PAGING_RESP:50462976){PR_ARQ_S_WAIT_AUTH}: Set Ciphering Mode
+DMM -> CIPHER MODE COMMAND MSISDN:46071
+- sending Ciphering Mode Command for MSISDN:46071: include_imeisv=0
+- ...perm algo: A5/1
+- ...key: e2b234f807886400
+DVLR Process_Access_Request_VLR(PAGING_RESP:50462976){PR_ARQ_S_WAIT_AUTH}: state_chg to PR_ARQ_S_WAIT_CIPH
+DREF MSISDN:46071: MSC conn use - dtap == 0 (0x0: )
+DMM Subscr_Conn(PAGING_RESP:50462976){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(PAGING_RESP:50462976){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  cipher_mode_cmd_sent == 1
+- needs ciph, not yet accepted
+msc_subscr_conn_is_accepted() == false
+  requests shall be thwarted
+DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_CC_SETUP
+DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: unknown 0x33
+DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1
+DRLL Dispatching 04.08 message SMS:0x01 (0x9:0x1)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: SMS:0x01
+- MS sends Ciphering Mode Complete, VLR accepts and sends pending SMS
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_RR_CIPH_M_COMPL
+DRR MSISDN:46071: CIPHERING MODE COMPLETE
+DVLR Process_Access_Request_VLR(PAGING_RESP:50462976){PR_ARQ_S_WAIT_CIPH}: Received Event PR_ARQ_E_CIPH_RES
+DVLR Process_Access_Request_VLR(PAGING_RESP:50462976){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_node2_post_ciph()
+DVLR Process_Access_Request_VLR(PAGING_RESP:50462976){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_node2_post_vlr()
+DVLR Process_Access_Request_VLR(PAGING_RESP:50462976){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_pres()
+DVLR Process_Access_Request_VLR(PAGING_RESP:50462976){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_trace()
+DVLR Process_Access_Request_VLR(PAGING_RESP:50462976){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_imei()
+DVLR Process_Access_Request_VLR(PAGING_RESP:50462976){PR_ARQ_S_WAIT_CIPH}: proc_arq_fsm_done(PASSED)
+DVLR Process_Access_Request_VLR(PAGING_RESP:50462976){PR_ARQ_S_WAIT_CIPH}: state_chg to PR_ARQ_S_DONE
+DVLR Process_Access_Request_VLR(PAGING_RESP:50462976){PR_ARQ_S_DONE}: Process Access Request result: PASSED
+DMM Subscr_Conn(PAGING_RESP:50462976){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_ACCEPTED
+DPAG Paging success for MSISDN:46071 (event=0)
+DPAG Calling paging cbfn.
+DCC (ti 00 sub MSISDN:46071 callref 40000002) New transaction
+DREF VLR subscr MSISDN:46071 usage increases to: 5
+DREF MSISDN:46071: MSC conn use + trans_sms == 1 (0x20: trans_sms)
+DMSC msc_tx 91 bytes to MSISDN:46071 via RAN_GERAN_A
+- DTAP --RAN_GERAN_A--> MS: SMS:0x01: 09015801000791447758100650004c0005806470f1000007101000000000445079da1e1ee7416937485e9ea7c965373d1d6683c270383b3d0ed3d36ff71c949e83c22072799e9687c5ec32a81d96afcbf4b4fb0c7ac3e9e9b7db05
+- DTAP matches expected message
+DREF VLR subscr MSISDN:46071 usage decreases to: 4
+DMM Subscr_Conn(PAGING_RESP:50462976){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(PAGING_RESP:50462976){SUBSCR_CONN_S_ACCEPTED}: subscr_conn_fsm_has_active_transactions: connection still has active transaction: SMS
+  dtap_tx_confirmed == 1
+  paging_stopped == 1
+- SMS was delivered, no requests pending for subscr
+DREF VLR subscr MSISDN:46071 usage increases to: 5
+  llist_count(&vsub->cs.requests) == 0
+DREF VLR subscr MSISDN:46071 usage decreases to: 4
+- conn is still open to wait for SMS ack dance
+  llist_count(&net->subscr_conns) == 1
+- MS replies with CP-ACK for received SMS
+  MSC <--RAN_GERAN_A-- MS: SMS:0x04
+DREF MSISDN:46071: MSC conn use + dtap == 2 (0x22: dtap,trans_sms)
+DRLL Dispatching 04.08 message SMS:0x04 (0x9:0x4)
+DMM Subscr_Conn(PAGING_RESP:50462976){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_COMMUNICATING
+DMM Subscr_Conn(PAGING_RESP:50462976){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_COMMUNICATING
+DREF MSISDN:46071: MSC conn use - dtap == 1 (0x20: trans_sms)
+  llist_count(&net->subscr_conns) == 1
+- MS also sends RP-ACK, MSC in turn sends CP-ACK for that
+  MSC <--RAN_GERAN_A-- MS: SMS:0x01
+DREF MSISDN:46071: MSC conn use + dtap == 2 (0x22: dtap,trans_sms)
+DRLL Dispatching 04.08 message SMS:0x01 (0x9:0x1)
+DMM Subscr_Conn(PAGING_RESP:50462976){SUBSCR_CONN_S_COMMUNICATING}: Received Event SUBSCR_CONN_E_COMMUNICATING
+DMSC msc_tx 2 bytes to MSISDN:46071 via RAN_GERAN_A
+- DTAP --RAN_GERAN_A--> MS: SMS:0x04: 0904
+- DTAP matches expected message
+DREF VLR subscr MSISDN:46071 usage decreases to: 3
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+DREF MSISDN:46071: MSC conn use - trans_sms == 1 (0x2: dtap)
+DREF MSISDN:46071: MSC conn use - dtap == 0 (0x0: )
+DMM Subscr_Conn(PAGING_RESP:50462976){SUBSCR_CONN_S_COMMUNICATING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(PAGING_RESP:50462976){SUBSCR_CONN_S_COMMUNICATING}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:46071: MSC conn use + release == 1 (0x100: release)
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+- BSSAP Clear --RAN_GERAN_A--> MS
+  dtap_tx_confirmed == 1
+  bssap_clear_sent == 1
+- SMS is done, conn is gone
+- BSS sends BSSMAP Clear Complete
+DREF MSISDN:46071: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(PAGING_RESP:50462976){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(PAGING_RESP:50462976){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(PAGING_RESP:50462976){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR Process_Access_Request_VLR(PAGING_RESP:50462976){PR_ARQ_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR Process_Access_Request_VLR(PAGING_RESP:50462976){PR_ARQ_S_DONE}: Removing from parent Subscr_Conn(PAGING_RESP:50462976)
+DVLR Process_Access_Request_VLR(PAGING_RESP:50462976){PR_ARQ_S_DONE}: Freeing instance
+DVLR Process_Access_Request_VLR(PAGING_RESP:50462976){PR_ARQ_S_DONE}: Deallocated
+DRLL MSISDN:46071: Freeing subscriber connection
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+DMM Subscr_Conn(PAGING_RESP:50462976){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(PAGING_RESP:50462976){SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+---
+- subscriber detaches, using TMSI
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_IMSI_DETACH_IND
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_IMSI_DETACH_IND (0x5:0x1)
+DMM IMSI DETACH INDICATION: MI(TMSI)=50462976
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+DMM IMSI DETACH for MSISDN:46071
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+DREF VLR subscr MSISDN:46071 usage decreases to: 0
+DREF freeing VLR subscr MSISDN:46071
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_CN_CLOSE
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF unknown: MSC conn use + release == 2 (0x101: compl_l3,release)
+- BSSAP Clear --RAN_GERAN_A--> MS
+DREF unknown: MSC conn use - compl_l3 == 1 (0x100: release)
+  bssap_clear_sent == 1
+- BSS sends BSSMAP Clear Complete
+DREF unknown: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DRLL Freeing subscriber connection with NULL subscriber
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+===== test_ciph_tmsi: SUCCESS
+
+full talloc report on 'msgb' (total      0 bytes in   1 blocks)
+talloc_total_blocks(tall_bsc_ctx) == 12
+
+===== test_ciph_imei
+- Location Update request causes a GSUP Send Auth Info request to HLR
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8)
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Updated ID
+DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000004620 type=IMSI ATTACH
+DMM LU/new-LAC: 1/23
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Allocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: is child of Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: rev=GSM net=GERAN Auth+Ciph
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA
+DREF VLR subscr unknown usage increases to: 1
+DVLR set IMSI on subscriber; IMSI=901700000004620 id=901700000004620
+DVLR New subscr, IMSI: 901700000004620
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DREF VLR subscr IMSI:901700000004620 usage decreases to: 1
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Allocated
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
+DVLR GSUP tx: 08010809710000004026f0
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f0
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF IMSI:901700000004620: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  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: 0a010809710000004026f003222010585df1ae287f6e273dce07090d61320b21042d8b2c3e220861855fb81fc2a8000322201012aca96fb4ffdea5c985cbafa9b6e18b210420bde240220807fa7502e07e1c0003222010e7c03ba7cf0e2fde82b2dc4d63077d422104a29514ae2208e2b234f80788640003222010fa8f20b781b5881329d4fea26b1a3c5121045afc8d7222082392f14f709ae000032220100fd4cc8dbe8715d1f439e304edfd68dc2104bc8d1c5b2208da7cdd6bfe2d7000
+DVLR GSUP rx 191: 0a010809710000004026f003222010585df1ae287f6e273dce07090d61320b21042d8b2c3e220861855fb81fc2a8000322201012aca96fb4ffdea5c985cbafa9b6e18b210420bde240220807fa7502e07e1c0003222010e7c03ba7cf0e2fde82b2dc4d63077d422104a29514ae2208e2b234f80788640003222010fa8f20b781b5881329d4fea26b1a3c5121045afc8d7222082392f14f709ae000032220100fd4cc8dbe8715d1f439e304edfd68dc2104bc8d1c5b2208da7cdd6bfe2d7000
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: Received Event VLR_AUTH_E_HLR_SAI_ACK
+DVLR SUBSCR(IMSI:901700000004620) Received 5 auth tuples
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: state_chg to VLR_SUB_AS_WAIT_RESP
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_WAIT_RESP}: got auth tuple: use_count=1 key_seq=0 -- will use GSM AKA (is_r99=no, at->vec.auth_types=0x1)
+- sending GSM Auth Request for IMSI:901700000004620: tuple use_count=1 key_seq=0 auth_types=0x1 and...
+- ...rand=585df1ae287f6e273dce07090d61320b
+- ...expecting sres=2d8b2c3e
+DREF VLR subscr IMSI:901700000004620 usage decreases to: 1
+<-- 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 Ciphering Mode Command to MS
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_AUTH_RESP
+DREF IMSI:901700000004620: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14)
+DMM IMSI:901700000004620: MM GSM AUTHENTICATION RESPONSE (sres = 2d8b2c3e)
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP
+DVLR SUBSCR(IMSI:901700000004620) AUTH on GERAN received SRES/RES: 2d8b2c3e (4 bytes)
+DVLR SUBSCR(IMSI:901700000004620) AUTH established GSM security context
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result PASSED
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_AUTHENTICATED}: Freeing instance
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_AUTHENTICATED}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_AUTH}: Set Ciphering Mode
+DMM -> CIPHER MODE COMMAND IMSI:901700000004620
+- sending Ciphering Mode Command for IMSI:901700000004620: include_imeisv=0
+- ...perm algo: A5/1
+- ...key: 61855fb81fc2a800
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_WAIT_CIPH
+DREF IMSI:901700000004620: MSC conn use - dtap == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  lu_result_sent == 0
+- needs ciph, not yet accepted
+msc_subscr_conn_is_accepted() == false
+  requests shall be thwarted
+DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5)
+DRLL subscr IMSI:901700000004620: Message not permitted for initial conn: GSM48_MT_CC_SETUP
+DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33)
+DRLL subscr IMSI:901700000004620: Message not permitted for initial conn: unknown 0x33
+DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19)
+DRLL subscr IMSI:901700000004620: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1
+DRLL Dispatching 04.08 message SMS:0x01 (0x9:0x1)
+DRLL subscr IMSI:901700000004620: Message not permitted for initial conn: SMS:0x01
+  lu_result_sent == 0
+- MS sends Ciphering Mode Complete, VLR accepts and sends GSUP LU Req to HLR
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_RR_CIPH_M_COMPL
+DRR IMSI:901700000004620: CIPHERING MODE COMPLETE
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_CIPH}: Received Event VLR_ULA_E_CIPH_RES
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_CIPH}: vlr_loc_upd_post_ciph()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_CIPH}: vlr_loc_upd_node_4()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_CIPH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: Allocated
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START
+DVLR GSUP tx: 04010809710000004026f0280102
+GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000004026f0280102
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA
+  lu_result_sent == 0
+- HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT
+<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: 10010809710000004026f00804036470f1
+DVLR GSUP rx 17: 10010809710000004026f00804036470f1
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DVLR IMSI:901700000004620 has MSISDN:46071
+DVLR SUBSCR(MSISDN:46071) VLR: update for IMSI=901700000004620 (MSISDN=46071, used=2)
+DVLR GSUP tx: 12010809710000004026f0
+GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000004026f0
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+<-- 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, and we send an ID Request for the IMEI to the MS
+<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: 06010809710000004026f0
+DVLR GSUP rx 11: 06010809710000004026f0
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Freeing instance
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: Allocated
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: Allocated
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(LU:901700000004620)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(LU:901700000004620)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Freeing instance
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Deallocated
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_WAIT_IMEI
+DMSC msc_tx 3 bytes to MSISDN:46071 via RAN_GERAN_A
+- DTAP --RAN_GERAN_A--> MS: GSM48_MT_MM_ID_REQ: 051802
+- DTAP matches expected message
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: vlr_gsupc_read_cb() returns 0
+- We will only do business when the IMEI is known
+  llist_count(&net->subscr_conns) == 1
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+  vsub->imei[0] == 0
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+msc_subscr_conn_is_accepted() == false
+  requests shall be thwarted
+DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_CC_SETUP
+DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: unknown 0x33
+DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1
+DRLL Dispatching 04.08 message SMS:0x01 (0x9:0x1)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: SMS:0x01
+- MS replies with an Identity Response
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_ID_RESP
+DREF MSISDN:46071: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_ID_RESP (0x5:0x19)
+DMM IDENTITY RESPONSE: MI(IMEI)=423423423423420
+DVLR set IMEI on subscriber; IMSI=901700000004620 IMEI=423423423423420
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_ID_IMEI
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_IMEI}: Received Event LU_COMPL_VLR_E_IMEI_CHECK_ACK
+- sending LU Accept for MSISDN:46071
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_IMEI}: state_chg to LU_COMPL_VLR_S_DONE
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Freeing instance
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_ACCEPTED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:46071: MSC conn use + release == 2 (0x102: dtap,release)
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+- BSSAP Clear --RAN_GERAN_A--> MS
+DREF MSISDN:46071: MSC conn use - dtap == 1 (0x100: release)
+  bssap_clear_sent == 1
+- LU was successful, and the conn has already been closed
+  lu_result_sent == 1
+- BSS sends BSSMAP Clear Complete
+DREF MSISDN:46071: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Freeing instance
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Deallocated
+DRLL MSISDN:46071: Freeing subscriber connection
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+- Subscriber has the IMEI
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+  strcmp(vsub->imei, "423423423423420") == 0
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+---
+- subscriber detaches
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_IMSI_DETACH_IND
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_IMSI_DETACH_IND (0x5:0x1)
+DMM IMSI DETACH INDICATION: MI(IMSI)=901700000004620
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+DMM IMSI DETACH for MSISDN:46071
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+DREF VLR subscr MSISDN:46071 usage decreases to: 0
+DREF freeing VLR subscr MSISDN:46071
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_CN_CLOSE
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF unknown: MSC conn use + release == 2 (0x101: compl_l3,release)
+- BSSAP Clear --RAN_GERAN_A--> MS
+DREF unknown: MSC conn use - compl_l3 == 1 (0x100: release)
+  bssap_clear_sent == 1
+- BSS sends BSSMAP Clear Complete
+DREF unknown: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DRLL Freeing subscriber connection with NULL subscriber
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+===== test_ciph_imei: SUCCESS
+
+full talloc report on 'msgb' (total      0 bytes in   1 blocks)
+talloc_total_blocks(tall_bsc_ctx) == 12
+
+===== test_ciph_imeisv
+- Location Update request causes a GSUP Send Auth Info request to HLR
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8)
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Updated ID
+DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000004620 type=IMSI ATTACH
+DMM LU/new-LAC: 1/23
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Allocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: is child of Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: rev=GSM net=GERAN Auth+Ciph
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA
+DREF VLR subscr unknown usage increases to: 1
+DVLR set IMSI on subscriber; IMSI=901700000004620 id=901700000004620
+DVLR New subscr, IMSI: 901700000004620
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DREF VLR subscr IMSI:901700000004620 usage decreases to: 1
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Allocated
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
+DVLR GSUP tx: 08010809710000004026f0
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f0
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF IMSI:901700000004620: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  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: 0a010809710000004026f003222010585df1ae287f6e273dce07090d61320b21042d8b2c3e220861855fb81fc2a8000322201012aca96fb4ffdea5c985cbafa9b6e18b210420bde240220807fa7502e07e1c0003222010e7c03ba7cf0e2fde82b2dc4d63077d422104a29514ae2208e2b234f80788640003222010fa8f20b781b5881329d4fea26b1a3c5121045afc8d7222082392f14f709ae000032220100fd4cc8dbe8715d1f439e304edfd68dc2104bc8d1c5b2208da7cdd6bfe2d7000
+DVLR GSUP rx 191: 0a010809710000004026f003222010585df1ae287f6e273dce07090d61320b21042d8b2c3e220861855fb81fc2a8000322201012aca96fb4ffdea5c985cbafa9b6e18b210420bde240220807fa7502e07e1c0003222010e7c03ba7cf0e2fde82b2dc4d63077d422104a29514ae2208e2b234f80788640003222010fa8f20b781b5881329d4fea26b1a3c5121045afc8d7222082392f14f709ae000032220100fd4cc8dbe8715d1f439e304edfd68dc2104bc8d1c5b2208da7cdd6bfe2d7000
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: Received Event VLR_AUTH_E_HLR_SAI_ACK
+DVLR SUBSCR(IMSI:901700000004620) Received 5 auth tuples
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: state_chg to VLR_SUB_AS_WAIT_RESP
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_WAIT_RESP}: got auth tuple: use_count=1 key_seq=0 -- will use GSM AKA (is_r99=no, at->vec.auth_types=0x1)
+- sending GSM Auth Request for IMSI:901700000004620: tuple use_count=1 key_seq=0 auth_types=0x1 and...
+- ...rand=585df1ae287f6e273dce07090d61320b
+- ...expecting sres=2d8b2c3e
+DREF VLR subscr IMSI:901700000004620 usage decreases to: 1
+<-- 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 Ciphering Mode Command to MS
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_AUTH_RESP
+DREF IMSI:901700000004620: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14)
+DMM IMSI:901700000004620: MM GSM AUTHENTICATION RESPONSE (sres = 2d8b2c3e)
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP
+DVLR SUBSCR(IMSI:901700000004620) AUTH on GERAN received SRES/RES: 2d8b2c3e (4 bytes)
+DVLR SUBSCR(IMSI:901700000004620) AUTH established GSM security context
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result PASSED
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_AUTHENTICATED}: Freeing instance
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_AUTHENTICATED}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_AUTH}: Set Ciphering Mode
+DMM -> CIPHER MODE COMMAND IMSI:901700000004620
+- sending Ciphering Mode Command for IMSI:901700000004620: include_imeisv=1
+- ...perm algo: A5/1
+- ...key: 61855fb81fc2a800
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_WAIT_CIPH
+DREF IMSI:901700000004620: MSC conn use - dtap == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  cipher_mode_cmd_sent == 1
+  cipher_mode_cmd_sent_with_imeisv == 1
+  lu_result_sent == 0
+- needs ciph, not yet accepted
+msc_subscr_conn_is_accepted() == false
+  requests shall be thwarted
+DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5)
+DRLL subscr IMSI:901700000004620: Message not permitted for initial conn: GSM48_MT_CC_SETUP
+DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33)
+DRLL subscr IMSI:901700000004620: Message not permitted for initial conn: unknown 0x33
+DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19)
+DRLL subscr IMSI:901700000004620: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1
+DRLL Dispatching 04.08 message SMS:0x01 (0x9:0x1)
+DRLL subscr IMSI:901700000004620: Message not permitted for initial conn: SMS:0x01
+  lu_result_sent == 0
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+  vsub->imeisv[0] == 0
+DREF VLR subscr IMSI:901700000004620 usage decreases to: 1
+- MS sends Ciphering Mode Complete with IMEISV, VLR accepts and sends GSUP LU Req to HLR
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_RR_CIPH_M_COMPL
+DRR IMSI:901700000004620: CIPHERING MODE COMPLETE
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_CIPH}: Received Event VLR_ULA_E_CIPH_RES
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_CIPH}: got IMEISV: 4234234234234275F
+DVLR set IMEISV on subscriber; IMSI=901700000004620 IMEISV=4234234234234275
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_CIPH}: vlr_loc_upd_post_ciph()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_CIPH}: vlr_loc_upd_node_4()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_CIPH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: Allocated
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START
+DVLR GSUP tx: 04010809710000004026f0280102
+GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000004026f0280102
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA
+  lu_result_sent == 0
+- Subscriber has the IMEISV
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+  strcmp(vsub->imeisv, "4234234234234275") == 0
+DREF VLR subscr IMSI:901700000004620 usage decreases to: 1
+msc_subscr_conn_is_accepted() == false
+  requests shall be thwarted
+DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5)
+DRLL subscr IMSI:901700000004620: Message not permitted for initial conn: GSM48_MT_CC_SETUP
+DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33)
+DRLL subscr IMSI:901700000004620: Message not permitted for initial conn: unknown 0x33
+DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19)
+DRLL subscr IMSI:901700000004620: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1
+DRLL Dispatching 04.08 message SMS:0x01 (0x9:0x1)
+DRLL subscr IMSI:901700000004620: Message not permitted for initial conn: SMS:0x01
+- HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT
+<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: 10010809710000004026f00804036470f1
+DVLR GSUP rx 17: 10010809710000004026f00804036470f1
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DVLR IMSI:901700000004620 has MSISDN:46071
+DVLR SUBSCR(MSISDN:46071) VLR: update for IMSI=901700000004620 (MSISDN=46071, used=2)
+DVLR GSUP tx: 12010809710000004026f0
+GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000004026f0
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+<-- 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: 06010809710000004026f0
+DVLR GSUP rx 11: 06010809710000004026f0
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Freeing instance
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: Allocated
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: Allocated
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(LU:901700000004620)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(LU:901700000004620)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Freeing instance
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Deallocated
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL
+- sending LU Accept for MSISDN:46071
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_DONE
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Freeing instance
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_ACCEPTED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:46071: MSC conn use + release == 1 (0x100: release)
+DREF VLR subscr MSISDN:46071 usage increases to: 4
+DREF VLR subscr MSISDN:46071 usage decreases to: 3
+- BSSAP Clear --RAN_GERAN_A--> MS
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+<-- 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
+  lu_result_sent == 1
+- BSS sends BSSMAP Clear Complete
+DREF MSISDN:46071: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Freeing instance
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Deallocated
+DRLL MSISDN:46071: Freeing subscriber connection
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+---
+- subscriber detaches
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_IMSI_DETACH_IND
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_IMSI_DETACH_IND (0x5:0x1)
+DMM IMSI DETACH INDICATION: MI(IMSI)=901700000004620
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+DMM IMSI DETACH for MSISDN:46071
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+DREF VLR subscr MSISDN:46071 usage decreases to: 0
+DREF freeing VLR subscr MSISDN:46071
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_CN_CLOSE
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF unknown: MSC conn use + release == 2 (0x101: compl_l3,release)
+- BSSAP Clear --RAN_GERAN_A--> MS
+DREF unknown: MSC conn use - compl_l3 == 1 (0x100: release)
+  bssap_clear_sent == 1
+- BSS sends BSSMAP Clear Complete
+DREF unknown: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DRLL Freeing subscriber connection with NULL subscriber
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+===== test_ciph_imeisv: SUCCESS
+
+full talloc report on 'msgb' (total      0 bytes in   1 blocks)
+talloc_total_blocks(tall_bsc_ctx) == 12
+
+===== test_ciph_tmsi_imei
+- Location Update request causes a GSUP Send Auth Info request to HLR
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8)
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Updated ID
+DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000004620 type=IMSI ATTACH
+DMM LU/new-LAC: 1/23
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Allocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: is child of Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: rev=GSM net=GERAN Auth+Ciph
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA
+DREF VLR subscr unknown usage increases to: 1
+DVLR set IMSI on subscriber; IMSI=901700000004620 id=901700000004620
+DVLR New subscr, IMSI: 901700000004620
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DREF VLR subscr IMSI:901700000004620 usage decreases to: 1
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Allocated
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
+DVLR GSUP tx: 08010809710000004026f0
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f0
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF IMSI:901700000004620: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  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: 0a010809710000004026f003222010585df1ae287f6e273dce07090d61320b21042d8b2c3e220861855fb81fc2a8000322201012aca96fb4ffdea5c985cbafa9b6e18b210420bde240220807fa7502e07e1c0003222010e7c03ba7cf0e2fde82b2dc4d63077d422104a29514ae2208e2b234f80788640003222010fa8f20b781b5881329d4fea26b1a3c5121045afc8d7222082392f14f709ae000032220100fd4cc8dbe8715d1f439e304edfd68dc2104bc8d1c5b2208da7cdd6bfe2d7000
+DVLR GSUP rx 191: 0a010809710000004026f003222010585df1ae287f6e273dce07090d61320b21042d8b2c3e220861855fb81fc2a8000322201012aca96fb4ffdea5c985cbafa9b6e18b210420bde240220807fa7502e07e1c0003222010e7c03ba7cf0e2fde82b2dc4d63077d422104a29514ae2208e2b234f80788640003222010fa8f20b781b5881329d4fea26b1a3c5121045afc8d7222082392f14f709ae000032220100fd4cc8dbe8715d1f439e304edfd68dc2104bc8d1c5b2208da7cdd6bfe2d7000
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: Received Event VLR_AUTH_E_HLR_SAI_ACK
+DVLR SUBSCR(IMSI:901700000004620) Received 5 auth tuples
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: state_chg to VLR_SUB_AS_WAIT_RESP
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_WAIT_RESP}: got auth tuple: use_count=1 key_seq=0 -- will use GSM AKA (is_r99=no, at->vec.auth_types=0x1)
+- sending GSM Auth Request for IMSI:901700000004620: tuple use_count=1 key_seq=0 auth_types=0x1 and...
+- ...rand=585df1ae287f6e273dce07090d61320b
+- ...expecting sres=2d8b2c3e
+DREF VLR subscr IMSI:901700000004620 usage decreases to: 1
+<-- 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 Ciphering Mode Command to MS
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_AUTH_RESP
+DREF IMSI:901700000004620: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14)
+DMM IMSI:901700000004620: MM GSM AUTHENTICATION RESPONSE (sres = 2d8b2c3e)
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP
+DVLR SUBSCR(IMSI:901700000004620) AUTH on GERAN received SRES/RES: 2d8b2c3e (4 bytes)
+DVLR SUBSCR(IMSI:901700000004620) AUTH established GSM security context
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result PASSED
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_AUTHENTICATED}: Freeing instance
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_AUTHENTICATED}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_AUTH}: Set Ciphering Mode
+DMM -> CIPHER MODE COMMAND IMSI:901700000004620
+- sending Ciphering Mode Command for IMSI:901700000004620: include_imeisv=0
+- ...perm algo: A5/1
+- ...key: 61855fb81fc2a800
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_WAIT_CIPH
+DREF IMSI:901700000004620: MSC conn use - dtap == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  lu_result_sent == 0
+- needs ciph, not yet accepted
+msc_subscr_conn_is_accepted() == false
+  requests shall be thwarted
+DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5)
+DRLL subscr IMSI:901700000004620: Message not permitted for initial conn: GSM48_MT_CC_SETUP
+DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33)
+DRLL subscr IMSI:901700000004620: Message not permitted for initial conn: unknown 0x33
+DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19)
+DRLL subscr IMSI:901700000004620: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1
+DRLL Dispatching 04.08 message SMS:0x01 (0x9:0x1)
+DRLL subscr IMSI:901700000004620: Message not permitted for initial conn: SMS:0x01
+  lu_result_sent == 0
+- MS sends Ciphering Mode Complete, VLR accepts and sends GSUP LU Req to HLR
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_RR_CIPH_M_COMPL
+DRR IMSI:901700000004620: CIPHERING MODE COMPLETE
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_CIPH}: Received Event VLR_ULA_E_CIPH_RES
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_CIPH}: vlr_loc_upd_post_ciph()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_CIPH}: vlr_loc_upd_node_4()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_CIPH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: Allocated
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START
+DVLR GSUP tx: 04010809710000004026f0280102
+GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000004026f0280102
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA
+  lu_result_sent == 0
+- HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT
+<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: 10010809710000004026f00804036470f1
+DVLR GSUP rx 17: 10010809710000004026f00804036470f1
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DVLR IMSI:901700000004620 has MSISDN:46071
+DVLR SUBSCR(MSISDN:46071) VLR: update for IMSI=901700000004620 (MSISDN=46071, used=2)
+DVLR GSUP tx: 12010809710000004026f0
+GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000004026f0
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+<-- 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, and we send an ID Request for the IMEI to the MS
+<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: 06010809710000004026f0
+DVLR GSUP rx 11: 06010809710000004026f0
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Freeing instance
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: Allocated
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: Allocated
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(LU:901700000004620)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(LU:901700000004620)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Freeing instance
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Deallocated
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_WAIT_IMEI_TMSI
+DMSC msc_tx 3 bytes to MSISDN:46071 via RAN_GERAN_A
+- DTAP --RAN_GERAN_A--> MS: GSM48_MT_MM_ID_REQ: 051802
+- DTAP matches expected message
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: vlr_gsupc_read_cb() returns 0
+- We will only do business when the IMEI is known
+  llist_count(&net->subscr_conns) == 1
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+  vsub->imei[0] == 0
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+msc_subscr_conn_is_accepted() == false
+  requests shall be thwarted
+DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_CC_SETUP
+DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: unknown 0x33
+DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1
+DRLL Dispatching 04.08 message SMS:0x01 (0x9:0x1)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: SMS:0x01
+- MS replies with an Identity Response
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_ID_RESP
+DREF MSISDN:46071: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_ID_RESP (0x5:0x19)
+DMM IDENTITY RESPONSE: MI(IMEI)=423423423423420
+DVLR set IMEI on subscriber; IMSI=901700000004620 IMEI=423423423423420
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_ID_IMEI
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_IMEI_TMSI}: Received Event LU_COMPL_VLR_E_IMEI_CHECK_ACK
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_IMEI_TMSI}: lu_compl_vlr_new_tmsi()
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_IMEI_TMSI}: state_chg to LU_COMPL_VLR_S_WAIT_TMSI_CNF
+- sending LU Accept for MSISDN:46071, with TMSI 0x03020100
+DREF MSISDN:46071: MSC conn use - dtap == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+- a LU Accept with a new TMSI was sent, waiting for TMSI Realloc Compl
+  llist_count(&net->subscr_conns) == 1
+  lu_result_sent == 1
+msc_subscr_conn_is_accepted() == false
+  requests shall be thwarted
+DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_CC_SETUP
+DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: unknown 0x33
+DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1
+DRLL Dispatching 04.08 message SMS:0x01 (0x9:0x1)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: SMS:0x01
+- even though the TMSI is not acked, we can already find the subscr with it
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+  vsub != NULL == 1
+  strcmp(vsub->imsi, imsi) == 0
+  vsub->tmsi_new == 0x03020100
+  vsub->tmsi == 0xffffffff
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+- MS sends TMSI Realloc Complete
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_TMSI_REALL_COMPL
+DREF MSISDN:46071: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_TMSI_REALL_COMPL (0x5:0x1b)
+DMM TMSI Reallocation Completed. Subscriber: MSISDN:46071
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_NEW_TMSI_ACK
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_TMSI_CNF}: Received Event LU_COMPL_VLR_E_NEW_TMSI_ACK
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_TMSI_CNF}: state_chg to LU_COMPL_VLR_S_DONE
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Freeing instance
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_ACCEPTED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:46071: MSC conn use + release == 2 (0x102: dtap,release)
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+- BSSAP Clear --RAN_GERAN_A--> MS
+DREF MSISDN:46071: MSC conn use - dtap == 1 (0x100: release)
+  bssap_clear_sent == 1
+- LU was successful, and the conn has already been closed
+- BSS sends BSSMAP Clear Complete
+DREF MSISDN:46071: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Freeing instance
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Deallocated
+DRLL MSISDN:46071: Freeing subscriber connection
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+- Subscriber has the IMEI and TMSI
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+  strcmp(vsub->imei, "423423423423420") == 0
+  vsub->tmsi == 0x03020100
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+---
+- subscriber detaches, using TMSI
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_IMSI_DETACH_IND
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_IMSI_DETACH_IND (0x5:0x1)
+DMM IMSI DETACH INDICATION: MI(TMSI)=50462976
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+DMM IMSI DETACH for MSISDN:46071
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+DREF VLR subscr MSISDN:46071 usage decreases to: 0
+DREF freeing VLR subscr MSISDN:46071
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_CN_CLOSE
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF unknown: MSC conn use + release == 2 (0x101: compl_l3,release)
+- BSSAP Clear --RAN_GERAN_A--> MS
+DREF unknown: MSC conn use - compl_l3 == 1 (0x100: release)
+  bssap_clear_sent == 1
+- BSS sends BSSMAP Clear Complete
+DREF unknown: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DRLL Freeing subscriber connection with NULL subscriber
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+===== test_ciph_tmsi_imei: SUCCESS
+
+full talloc report on 'msgb' (total      0 bytes in   1 blocks)
+talloc_total_blocks(tall_bsc_ctx) == 12
+
+===== test_gsm_ciph_in_umts_env
+- Location Update request causes a GSUP Send Auth Info request to HLR
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8)
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_NEW}: Updated ID
+DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000010650 type=NORMAL
+DMM LU/new-LAC: 0/23
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: Allocated
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: is child of Subscr_Conn(LU:901700000010650)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: rev=R99 net=GERAN Auth+Ciph
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA
+DREF VLR subscr unknown usage increases to: 1
+DVLR set IMSI on subscriber; IMSI=901700000010650 id=901700000010650
+DVLR New subscr, IMSI: 901700000010650
+DREF VLR subscr IMSI:901700000010650 usage increases to: 2
+DREF VLR subscr IMSI:901700000010650 usage decreases to: 1
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Allocated
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(LU:901700000010650)
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
+DVLR GSUP tx: 08010809710000000156f0
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f0
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF IMSI:901700000010650: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  lu_result_sent == 0
+- from HLR, rx _SEND_AUTH_INFO_RESULT; VLR sends *UMTS AKA* Auth Req to MS
+<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT: 0a010809710000000156f0036220104ac8d1cd1a51937597ca1016fe69a0fa2104dacc4b2622087a75f0ac9b84440023103747da4e31545baa2db59e500bdae04724108544d35b945ccba01a7f1293575291c325102d837d2b0d6f00004b282d5acf23428d270837527064741f8ddb03622010b2661531b97b12c5a2edc21a0ed16fc521042fb4cfad2208da149b11d473f40023103fe013b1a428ea737c37f8f0288c8edf2410f275438c02b97e4d6f639dddda3d10b9251078cdd96c60840000322f421b3bb778b12708ed3ebf9cb6ea48ed0362201054d8f19778056666b41c8c25e52eb60c21040ff61e0f220826ec67fad307300023102868b0922c652616f1c975e3eaf7943a24106a84a20b1bc13ec9840466406d2dd91e251053f3e5632b3d00008865dd54d49663f2270886e848a9e7ad8cd5036220101f05607ff9c8984f46ad97f8c9a94982210491a36e3d22085d84421884fdcc0023102171fef54b81e30c83a598a5e44f634c2410f02d088697509827565b46938fece21125101b43bbf9815e00001cb9b2a9f6b8a77c2708373e67d62e719c510362201080d89a58a2a41050918caf68a4e93c642104a319f5f12208883df2b8672930002310fa5d70f929ff298efb160413698dc1072410ae9a3d8ce70ce13bac297bdb91cd6c6825105c0dc2eeaefa0000396882a1fe2cf80b270865ab1cad216bfe87
+DVLR GSUP rx 511: 0a010809710000000156f0036220104ac8d1cd1a51937597ca1016fe69a0fa2104dacc4b2622087a75f0ac9b84440023103747da4e31545baa2db59e500bdae04724108544d35b945ccba01a7f1293575291c325102d837d2b0d6f00004b282d5acf23428d270837527064741f8ddb03622010b2661531b97b12c5a2edc21a0ed16fc521042fb4cfad2208da149b11d473f40023103fe013b1a428ea737c37f8f0288c8edf2410f275438c02b97e4d6f639dddda3d10b9251078cdd96c60840000322f421b3bb778b12708ed3ebf9cb6ea48ed0362201054d8f19778056666b41c8c25e52eb60c21040ff61e0f220826ec67fad307300023102868b0922c652616f1c975e3eaf7943a24106a84a20b1bc13ec9840466406d2dd91e251053f3e5632b3d00008865dd54d49663f2270886e848a9e7ad8cd5036220101f05607ff9c8984f46ad97f8c9a94982210491a36e3d22085d84421884fdcc0023102171fef54b81e30c83a598a5e44f634c2410f02d088697509827565b46938fece21125101b43bbf9815e00001cb9b2a9f6b8a77c2708373e67d62e719c510362201080d89a58a2a41050918caf68a4e93c642104a319f5f12208883df2b8672930002310fa5d70f929ff298efb160413698dc1072410ae9a3d8ce70ce13bac297bdb91cd6c6825105c0dc2eeaefa0000396882a1fe2cf80b270865ab1cad216bfe87
+DREF VLR subscr IMSI:901700000010650 usage increases to: 2
+DVLR VLR_Authenticate(LU:901700000010650){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(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: state_chg to VLR_SUB_AS_WAIT_RESP
+DVLR VLR_Authenticate(LU:901700000010650){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: tuple use_count=1 key_seq=0 auth_types=0x3 and...
+- ...rand=4ac8d1cd1a51937597ca1016fe69a0fa
+- ...autn=2d837d2b0d6f00004b282d5acf23428d
+- ...expecting res=37527064741f8ddb
+DREF VLR subscr IMSI:901700000010650 usage decreases to: 1
+<-- 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 *GSM AKA* Authen Response, VLR accepts and sends Ciphering Mode Command to MS
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_AUTH_RESP
+DREF IMSI:901700000010650: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14)
+DMM IMSI:901700000010650: MM GSM AUTHENTICATION RESPONSE (sres = dacc4b26)
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP
+DVLR SUBSCR(IMSI:901700000010650) AUTH on GERAN received SRES/RES: dacc4b26 (4 bytes)
+DVLR SUBSCR(IMSI:901700000010650) AUTH established GSM security context
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result PASSED
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(LU:901700000010650)
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Freeing instance
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth()
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_AUTH}: Set Ciphering Mode
+DMM -> CIPHER MODE COMMAND IMSI:901700000010650
+- sending Ciphering Mode Command for IMSI:901700000010650: include_imeisv=0
+- ...perm algo: A5/1
+- ...key: 7a75f0ac9b844400
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_WAIT_CIPH
+DREF IMSI:901700000010650: MSC conn use - dtap == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  lu_result_sent == 0
+- MS sends Ciphering Mode Complete, VLR accepts and sends GSUP LU Req to HLR
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_RR_CIPH_M_COMPL
+DRR IMSI:901700000010650: CIPHERING MODE COMPLETE
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_CIPH}: Received Event VLR_ULA_E_CIPH_RES
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_CIPH}: vlr_loc_upd_post_ciph()
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_CIPH}: vlr_loc_upd_node_4()
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_CIPH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_INIT}: Allocated
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000010650)
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START
+DVLR GSUP tx: 04010809710000000156f0280102
+GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000000156f0280102
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA
+  lu_result_sent == 0
+- HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT
+<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: 10010809710000000156f00804032443f2
+DVLR GSUP rx 17: 10010809710000000156f00804032443f2
+DREF VLR subscr IMSI:901700000010650 usage increases to: 2
+DVLR IMSI:901700000010650 has MSISDN:42342
+DVLR SUBSCR(MSISDN:42342) VLR: update for IMSI=901700000010650 (MSISDN=42342, used=2)
+DVLR GSUP tx: 12010809710000000156f0
+GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000000156f0
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+<-- 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: 06010809710000000156f0
+DVLR GSUP rx 11: 06010809710000000156f0
+DREF VLR subscr MSISDN:42342 usage increases to: 2
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000010650)
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_DONE}: Freeing instance
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_INIT}: Allocated
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000010650)
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_INIT}: Allocated
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(LU:901700000010650)
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(LU:901700000010650)
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_DONE}: Freeing instance
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_DONE}: Deallocated
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL
+- sending LU Accept for MSISDN:42342
+DREF VLR subscr MSISDN:42342 usage increases to: 3
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_DONE
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000010650)
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_DONE}: Freeing instance
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_ACCEPTED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:42342: MSC conn use + release == 1 (0x100: release)
+DREF VLR subscr MSISDN:42342 usage increases to: 4
+DREF VLR subscr MSISDN:42342 usage decreases to: 3
+- BSSAP Clear --RAN_GERAN_A--> MS
+DREF VLR subscr MSISDN:42342 usage decreases to: 2
+<-- 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
+  lu_result_sent == 1
+- BSS sends BSSMAP Clear Complete
+DREF MSISDN:42342: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(LU:901700000010650)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: Freeing instance
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: Deallocated
+DRLL MSISDN:42342: Freeing subscriber connection
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+---
+- after a while, a new conn sends a CM Service Request. VLR responds with *UMTS AKA* Auth Req, 2nd auth vector
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_CM_SERV_REQ
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_CM_SERV_REQ (0x5:0x24)
+DMM <- CM SERVICE REQUEST serv_type=0x08 MI(IMSI)=901700000010650
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_NEW}: Updated ID
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: Allocated
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: is child of Subscr_Conn(CM_SERVICE_REQ:901700000010650)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: rev=R99 net=GERAN Auth+Ciph
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START
+DREF VLR subscr MSISDN:42342 usage increases to: 2
+DREF VLR subscr MSISDN:42342 usage increases to: 3
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_WAIT_AUTH
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Allocated
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: is child of Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650)
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_WAIT_RESP
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){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 MSISDN:42342: tuple use_count=1 key_seq=1 auth_types=0x3 and...
+- ...rand=b2661531b97b12c5a2edc21a0ed16fc5
+- ...autn=78cdd96c60840000322f421b3bb778b1
+- ...expecting res=ed3ebf9cb6ea48ed
+DREF VLR subscr MSISDN:42342 usage decreases to: 2
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF MSISDN:42342: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  cm_service_result_sent == 0
+  auth_request_sent == 1
+- needs auth, not yet accepted
+msc_subscr_conn_is_accepted() == false
+  requests shall be thwarted
+DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5)
+DRLL subscr MSISDN:42342: Message not permitted for initial conn: GSM48_MT_CC_SETUP
+DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33)
+DRLL subscr MSISDN:42342: Message not permitted for initial conn: unknown 0x33
+DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19)
+DRLL subscr MSISDN:42342: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1
+DRLL Dispatching 04.08 message SMS:0x01 (0x9:0x1)
+DRLL subscr MSISDN:42342: Message not permitted for initial conn: SMS:0x01
+- MS sends *GSM AKA* Authen Response, VLR accepts and requests Ciphering
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_AUTH_RESP
+DREF MSISDN:42342: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14)
+DMM MSISDN:42342: MM GSM AUTHENTICATION RESPONSE (sres = 2fb4cfad)
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP
+DVLR SUBSCR(MSISDN:42342) AUTH on GERAN received SRES/RES: 2fb4cfad (4 bytes)
+DVLR SUBSCR(MSISDN:42342) AUTH established GSM security context
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result PASSED
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Removing from parent Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650)
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Freeing instance
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Deallocated
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: Received Event PR_ARQ_E_AUTH_RES
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: Set Ciphering Mode
+DMM -> CIPHER MODE COMMAND MSISDN:42342
+- sending Ciphering Mode Command for MSISDN:42342: include_imeisv=0
+- ...perm algo: A5/1
+- ...key: da149b11d473f400
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: state_chg to PR_ARQ_S_WAIT_CIPH
+DREF MSISDN:42342: MSC conn use - dtap == 0 (0x0: )
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  cm_service_result_sent == 0
+  cipher_mode_cmd_sent == 1
+- MS sends Ciphering Mode Complete, VLR accepts; above Ciphering is an implicit CM Service Accept
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_RR_CIPH_M_COMPL
+DRR MSISDN:42342: CIPHERING MODE COMPLETE
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_CIPH}: Received Event PR_ARQ_E_CIPH_RES
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_node2_post_ciph()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_node2_post_vlr()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_pres()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_trace()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_imei()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_CIPH}: proc_arq_fsm_done(PASSED)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_CIPH}: state_chg to PR_ARQ_S_DONE
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_DONE}: Process Access Request result: PASSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_ACCEPTED
+DREF MSISDN:42342: MSC conn use + cm_service == 1 (0x8: cm_service)
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_ACCEPTED}: subscr_conn_fsm_has_active_transactions: still awaiting first request after a CM Service Request
+  cm_service_result_sent == 0
+- Concluding CM Service Request
+DREF MSISDN:42342: MSC conn use - cm_service == 0 (0x0: )
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:42342: MSC conn use + release == 1 (0x100: release)
+DREF VLR subscr MSISDN:42342 usage increases to: 3
+DREF VLR subscr MSISDN:42342 usage decreases to: 2
+- BSSAP Clear --RAN_GERAN_A--> MS
+  bssap_clear_sent == 1
+- all requests serviced, conn has been released
+- BSS sends BSSMAP Clear Complete
+DREF MSISDN:42342: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_DONE}: Removing from parent Subscr_Conn(CM_SERVICE_REQ:901700000010650)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_DONE}: Freeing instance
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_DONE}: Deallocated
+DRLL MSISDN:42342: Freeing subscriber connection
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+---
+- an SMS is sent, MS is paged
+DREF VLR subscr MSISDN:42342 usage increases to: 2
+  llist_count(&vsub->cs.requests) == 0
+DREF VLR subscr MSISDN:42342 usage increases to: 3
+DMM Subscriber MSISDN:42342 not paged yet, start paging.
+  RAN_GERAN_A sends out paging request to IMSI 901700000010650, TMSI 0xffffffff, LAC 23
+  strcmp(paging_expecting_imsi, imsi) == 0
+DREF VLR subscr MSISDN:42342 usage increases to: 4
+  llist_count(&vsub->cs.requests) == 1
+DREF VLR subscr MSISDN:42342 usage decreases to: 3
+  paging_sent == 1
+  paging_stopped == 0
+- the subscriber and its pending request should remain
+DREF VLR subscr MSISDN:42342 usage increases to: 4
+  llist_count(&vsub->cs.requests) == 1
+DREF VLR subscr MSISDN:42342 usage decreases to: 3
+- MS replies with Paging Response, and VLR sends *UMTS AKA* Auth Request with third key
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_RR_PAG_RESP
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_RR_PAG_RESP (0x6:0x27)
+DRR PAGING RESPONSE: MI(IMSI)=901700000010650
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_NEW}: Updated ID
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_INIT}: Allocated
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_INIT}: is child of Subscr_Conn(PAGING_RESP:901700000010650)
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_INIT}: rev=R99 net=GERAN Auth+Ciph
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START
+DREF VLR subscr MSISDN:42342 usage increases to: 4
+DREF VLR subscr MSISDN:42342 usage increases to: 5
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi()
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_WAIT_AUTH
+DVLR VLR_Authenticate(PAGING_RESP:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Allocated
+DVLR VLR_Authenticate(PAGING_RESP:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: is child of Process_Access_Request_VLR(PAGING_RESP:901700000010650)
+DVLR VLR_Authenticate(PAGING_RESP:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
+DVLR VLR_Authenticate(PAGING_RESP:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_WAIT_RESP
+DVLR VLR_Authenticate(PAGING_RESP:901700000010650){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 MSISDN:42342: tuple use_count=1 key_seq=2 auth_types=0x3 and...
+- ...rand=54d8f19778056666b41c8c25e52eb60c
+- ...autn=53f3e5632b3d00008865dd54d49663f2
+- ...expecting res=86e848a9e7ad8cd5
+DREF VLR subscr MSISDN:42342 usage decreases to: 4
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF MSISDN:42342: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  auth_request_sent == 1
+- needs auth, not yet accepted
+msc_subscr_conn_is_accepted() == false
+  requests shall be thwarted
+DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5)
+DRLL subscr MSISDN:42342: Message not permitted for initial conn: GSM48_MT_CC_SETUP
+DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33)
+DRLL subscr MSISDN:42342: Message not permitted for initial conn: unknown 0x33
+DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19)
+DRLL subscr MSISDN:42342: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1
+DRLL Dispatching 04.08 message SMS:0x01 (0x9:0x1)
+DRLL subscr MSISDN:42342: Message not permitted for initial conn: SMS:0x01
+- MS sends *GSM AKA* Authen Response, VLR accepts and requests Ciphering
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_AUTH_RESP
+DREF MSISDN:42342: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14)
+DMM MSISDN:42342: MM GSM AUTHENTICATION RESPONSE (sres = 0ff61e0f)
+DVLR VLR_Authenticate(PAGING_RESP:901700000010650){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP
+DVLR SUBSCR(MSISDN:42342) AUTH on GERAN received SRES/RES: 0ff61e0f (4 bytes)
+DVLR SUBSCR(MSISDN:42342) AUTH established GSM security context
+DVLR VLR_Authenticate(PAGING_RESP:901700000010650){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result PASSED
+DVLR VLR_Authenticate(PAGING_RESP:901700000010650){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
+DVLR VLR_Authenticate(PAGING_RESP:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR VLR_Authenticate(PAGING_RESP:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Removing from parent Process_Access_Request_VLR(PAGING_RESP:901700000010650)
+DVLR VLR_Authenticate(PAGING_RESP:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Freeing instance
+DVLR VLR_Authenticate(PAGING_RESP:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Deallocated
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_WAIT_AUTH}: Received Event PR_ARQ_E_AUTH_RES
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2()
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_WAIT_AUTH}: Set Ciphering Mode
+DMM -> CIPHER MODE COMMAND MSISDN:42342
+- sending Ciphering Mode Command for MSISDN:42342: include_imeisv=0
+- ...perm algo: A5/1
+- ...key: 26ec67fad3073000
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_WAIT_AUTH}: state_chg to PR_ARQ_S_WAIT_CIPH
+DREF MSISDN:42342: MSC conn use - dtap == 0 (0x0: )
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  cipher_mode_cmd_sent == 1
+- MS sends Ciphering Mode Complete, VLR accepts and sends pending SMS
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_RR_CIPH_M_COMPL
+DRR MSISDN:42342: CIPHERING MODE COMPLETE
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_WAIT_CIPH}: Received Event PR_ARQ_E_CIPH_RES
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_node2_post_ciph()
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_node2_post_vlr()
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_pres()
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_trace()
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_imei()
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_WAIT_CIPH}: proc_arq_fsm_done(PASSED)
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_WAIT_CIPH}: state_chg to PR_ARQ_S_DONE
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_DONE}: Process Access Request result: PASSED
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_ACCEPTED
+DPAG Paging success for MSISDN:42342 (event=0)
+DPAG Calling paging cbfn.
+DCC (ti 00 sub MSISDN:42342 callref 40000003) New transaction
+DREF VLR subscr MSISDN:42342 usage increases to: 5
+DREF MSISDN:42342: MSC conn use + trans_sms == 1 (0x20: trans_sms)
+DMSC msc_tx 91 bytes to MSISDN:42342 via RAN_GERAN_A
+- DTAP --RAN_GERAN_A--> MS: SMS:0x01: 09015801000791447758100650004c0005802443f2000007101000000000445079da1e1ee7416937485e9ea7c965373d1d6683c270383b3d0ed3d36ff71c949e83c22072799e9687c5ec32a81d96afcbf4b4fb0c7ac3e9e9b7db05
+- DTAP matches expected message
+DREF VLR subscr MSISDN:42342 usage decreases to: 4
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_ACCEPTED}: subscr_conn_fsm_has_active_transactions: connection still has active transaction: SMS
+  dtap_tx_confirmed == 1
+  paging_stopped == 1
+- SMS was delivered, no requests pending for subscr
+DREF VLR subscr MSISDN:42342 usage increases to: 5
+  llist_count(&vsub->cs.requests) == 0
+DREF VLR subscr MSISDN:42342 usage decreases to: 4
+- conn is still open to wait for SMS ack dance
+  llist_count(&net->subscr_conns) == 1
+- MS replies with CP-ACK for received SMS
+  MSC <--RAN_GERAN_A-- MS: SMS:0x04
+DREF MSISDN:42342: MSC conn use + dtap == 2 (0x22: dtap,trans_sms)
+DRLL Dispatching 04.08 message SMS:0x04 (0x9:0x4)
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_COMMUNICATING
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_COMMUNICATING
+DREF MSISDN:42342: MSC conn use - dtap == 1 (0x20: trans_sms)
+  llist_count(&net->subscr_conns) == 1
+- MS also sends RP-ACK, MSC in turn sends CP-ACK for that
+  MSC <--RAN_GERAN_A-- MS: SMS:0x01
+DREF MSISDN:42342: MSC conn use + dtap == 2 (0x22: dtap,trans_sms)
+DRLL Dispatching 04.08 message SMS:0x01 (0x9:0x1)
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_COMMUNICATING}: Received Event SUBSCR_CONN_E_COMMUNICATING
+DMSC msc_tx 2 bytes to MSISDN:42342 via RAN_GERAN_A
+- DTAP --RAN_GERAN_A--> MS: SMS:0x04: 0904
+- DTAP matches expected message
+DREF VLR subscr MSISDN:42342 usage decreases to: 3
+DREF VLR subscr MSISDN:42342 usage decreases to: 2
+DREF MSISDN:42342: MSC conn use - trans_sms == 1 (0x2: dtap)
+DREF MSISDN:42342: MSC conn use - dtap == 0 (0x0: )
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_COMMUNICATING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_COMMUNICATING}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:42342: MSC conn use + release == 1 (0x100: release)
+DREF VLR subscr MSISDN:42342 usage increases to: 3
+DREF VLR subscr MSISDN:42342 usage decreases to: 2
+- BSSAP Clear --RAN_GERAN_A--> MS
+  dtap_tx_confirmed == 1
+  bssap_clear_sent == 1
+- SMS is done, conn is gone
+- BSS sends BSSMAP Clear Complete
+DREF MSISDN:42342: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_DONE}: Removing from parent Subscr_Conn(PAGING_RESP:901700000010650)
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_DONE}: Freeing instance
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_DONE}: Deallocated
+DRLL MSISDN:42342: Freeing subscriber connection
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+---
+- subscriber detaches
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_IMSI_DETACH_IND
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_IMSI_DETACH_IND (0x5:0x1)
+DMM IMSI DETACH INDICATION: MI(IMSI)=901700000010650
+DREF VLR subscr MSISDN:42342 usage increases to: 2
+DMM IMSI DETACH for MSISDN:42342
+DREF VLR subscr MSISDN:42342 usage increases to: 3
+DREF VLR subscr MSISDN:42342 usage decreases to: 2
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+DREF VLR subscr MSISDN:42342 usage decreases to: 0
+DREF freeing VLR subscr MSISDN:42342
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_CN_CLOSE
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF unknown: MSC conn use + release == 2 (0x101: compl_l3,release)
+- BSSAP Clear --RAN_GERAN_A--> MS
+DREF unknown: MSC conn use - compl_l3 == 1 (0x100: release)
+  bssap_clear_sent == 1
+- BSS sends BSSMAP Clear Complete
+DREF unknown: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DRLL Freeing subscriber connection with NULL subscriber
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 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) == 12
+
+===== test_a5_3_supported
+- Location Update request causes a GSUP Send Auth Info request to HLR
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8)
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Updated ID
+DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000004620 type=IMSI ATTACH
+DMM LU/new-LAC: 1/23
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Allocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: is child of Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: rev=GSM net=GERAN Auth+Ciph
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA
+DREF VLR subscr unknown usage increases to: 1
+DVLR set IMSI on subscriber; IMSI=901700000004620 id=901700000004620
+DVLR New subscr, IMSI: 901700000004620
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DREF VLR subscr IMSI:901700000004620 usage decreases to: 1
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Allocated
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
+DVLR GSUP tx: 08010809710000004026f0
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f0
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF IMSI:901700000004620: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  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: 0a010809710000004026f003222010585df1ae287f6e273dce07090d61320b21042d8b2c3e220861855fb81fc2a8000322201012aca96fb4ffdea5c985cbafa9b6e18b210420bde240220807fa7502e07e1c0003222010e7c03ba7cf0e2fde82b2dc4d63077d422104a29514ae2208e2b234f80788640003222010fa8f20b781b5881329d4fea26b1a3c5121045afc8d7222082392f14f709ae000032220100fd4cc8dbe8715d1f439e304edfd68dc2104bc8d1c5b2208da7cdd6bfe2d7000
+DVLR GSUP rx 191: 0a010809710000004026f003222010585df1ae287f6e273dce07090d61320b21042d8b2c3e220861855fb81fc2a8000322201012aca96fb4ffdea5c985cbafa9b6e18b210420bde240220807fa7502e07e1c0003222010e7c03ba7cf0e2fde82b2dc4d63077d422104a29514ae2208e2b234f80788640003222010fa8f20b781b5881329d4fea26b1a3c5121045afc8d7222082392f14f709ae000032220100fd4cc8dbe8715d1f439e304edfd68dc2104bc8d1c5b2208da7cdd6bfe2d7000
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: Received Event VLR_AUTH_E_HLR_SAI_ACK
+DVLR SUBSCR(IMSI:901700000004620) Received 5 auth tuples
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: state_chg to VLR_SUB_AS_WAIT_RESP
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_WAIT_RESP}: got auth tuple: use_count=1 key_seq=0 -- will use GSM AKA (is_r99=no, at->vec.auth_types=0x1)
+- sending GSM Auth Request for IMSI:901700000004620: tuple use_count=1 key_seq=0 auth_types=0x1 and...
+- ...rand=585df1ae287f6e273dce07090d61320b
+- ...expecting sres=2d8b2c3e
+DREF VLR subscr IMSI:901700000004620 usage decreases to: 1
+<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT: vlr_gsupc_read_cb() returns 0
+  lu_result_sent == 0
+  auth_request_sent == 1
+---
+- MS sends Authen Response, VLR accepts and wants to send Ciphering Mode Command to MS -- but needs Classmark 2 to determine whether A5/3 is supported
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_AUTH_RESP
+DREF IMSI:901700000004620: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14)
+DMM IMSI:901700000004620: MM GSM AUTHENTICATION RESPONSE (sres = 2d8b2c3e)
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP
+DVLR SUBSCR(IMSI:901700000004620) AUTH on GERAN received SRES/RES: 2d8b2c3e (4 bytes)
+DVLR SUBSCR(IMSI:901700000004620) AUTH established GSM security context
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result PASSED
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_AUTHENTICATED}: Freeing instance
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_AUTHENTICATED}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_AUTH}: Set Ciphering Mode
+DMM IMSI:901700000004620: to determine whether A5/3 is supported, first ask for a Classmark Update to obtain Classmark 2
+  BSC <--BSSAP-BSS-MANAGEMENT-- MSC: CLASSMARK REQ [L3]> 00 01 58 
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_WAIT_CLASSMARK_UPDATE
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_WAIT_CIPH
+DREF IMSI:901700000004620: MSC conn use - dtap == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_WAIT_CLASSMARK_UPDATE}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_WAIT_CLASSMARK_UPDATE}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  lu_result_sent == 0
+- BSC sends back a BSSMAP Classmark Update, that triggers the Ciphering Mode Command in A5/3
+DMSC Looking for A subscriber: conn_id 0
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_WAIT_CLASSMARK_UPDATE}: Received Event SUBSCR_CONN_E_CLASSMARK_UPDATE
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_WAIT_CLASSMARK_UPDATE}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DMM -> CIPHER MODE COMMAND IMSI:901700000004620
+- sending Ciphering Mode Command for IMSI:901700000004620: include_imeisv=0
+- ...perm algo: A5/3
+- ...key: 61855fb81fc2a800
+  lu_result_sent == 0
+- MS sends Ciphering Mode Complete, VLR accepts and sends GSUP LU Req to HLR
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_RR_CIPH_M_COMPL
+DRR IMSI:901700000004620: CIPHERING MODE COMPLETE
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_CIPH}: Received Event VLR_ULA_E_CIPH_RES
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_CIPH}: vlr_loc_upd_post_ciph()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_CIPH}: vlr_loc_upd_node_4()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_CIPH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: Allocated
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START
+DVLR GSUP tx: 04010809710000004026f0280102
+GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000004026f0280102
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA
+  lu_result_sent == 0
+- HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT
+<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: 10010809710000004026f00804032443f2
+DVLR GSUP rx 17: 10010809710000004026f00804032443f2
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DVLR IMSI:901700000004620 has MSISDN:42342
+DVLR SUBSCR(MSISDN:42342) VLR: update for IMSI=901700000004620 (MSISDN=42342, used=2)
+DVLR GSUP tx: 12010809710000004026f0
+GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000004026f0
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+<-- 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: 06010809710000004026f0
+DVLR GSUP rx 11: 06010809710000004026f0
+DREF VLR subscr MSISDN:42342 usage increases to: 2
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Freeing instance
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: Allocated
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: Allocated
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(LU:901700000004620)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(LU:901700000004620)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Freeing instance
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Deallocated
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL
+- sending LU Accept for MSISDN:42342
+DREF VLR subscr MSISDN:42342 usage increases to: 3
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_DONE
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Freeing instance
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_ACCEPTED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:42342: MSC conn use + release == 1 (0x100: release)
+DREF VLR subscr MSISDN:42342 usage increases to: 4
+DREF VLR subscr MSISDN:42342 usage decreases to: 3
+- BSSAP Clear --RAN_GERAN_A--> MS
+DREF VLR subscr MSISDN:42342 usage decreases to: 2
+<-- 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
+  lu_result_sent == 1
+- BSS sends BSSMAP Clear Complete
+DREF MSISDN:42342: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Freeing instance
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Deallocated
+DRLL MSISDN:42342: Freeing subscriber connection
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+---
+- after a while, a new conn sends a CM Service Request. VLR responds with Auth Req, 2nd auth vector
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_CM_SERV_REQ
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_CM_SERV_REQ (0x5:0x24)
+DMM <- CM SERVICE REQUEST serv_type=0x08 MI(IMSI)=901700000004620
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_NEW}: Updated ID
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_INIT}: Allocated
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_INIT}: is child of Subscr_Conn(CM_SERVICE_REQ:901700000004620)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_INIT}: rev=GSM net=GERAN Auth+Ciph
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START
+DREF VLR subscr MSISDN:42342 usage increases to: 2
+DREF VLR subscr MSISDN:42342 usage increases to: 3
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_WAIT_AUTH
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Allocated
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: is child of Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620)
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_WAIT_RESP
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000004620){VLR_SUB_AS_WAIT_RESP}: got auth tuple: use_count=1 key_seq=1 -- will use GSM AKA (is_r99=no, at->vec.auth_types=0x1)
+- sending GSM Auth Request for MSISDN:42342: tuple use_count=1 key_seq=1 auth_types=0x1 and...
+- ...rand=12aca96fb4ffdea5c985cbafa9b6e18b
+- ...expecting sres=20bde240
+DREF VLR subscr MSISDN:42342 usage decreases to: 2
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF MSISDN:42342: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  auth_request_sent == 1
+  cm_service_result_sent == 0
+- needs auth, not yet accepted
+msc_subscr_conn_is_accepted() == false
+  requests shall be thwarted
+DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5)
+DRLL subscr MSISDN:42342: Message not permitted for initial conn: GSM48_MT_CC_SETUP
+DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33)
+DRLL subscr MSISDN:42342: Message not permitted for initial conn: unknown 0x33
+DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19)
+DRLL subscr MSISDN:42342: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1
+DRLL Dispatching 04.08 message SMS:0x01 (0x9:0x1)
+DRLL subscr MSISDN:42342: Message not permitted for initial conn: SMS:0x01
+- MS sends Authen Response, VLR accepts and requests Ciphering. We already know Classmark 3, so no need to request Classmark Update.
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_AUTH_RESP
+DREF MSISDN:42342: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14)
+DMM MSISDN:42342: MM GSM AUTHENTICATION RESPONSE (sres = 20bde240)
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000004620){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP
+DVLR SUBSCR(MSISDN:42342) AUTH on GERAN received SRES/RES: 20bde240 (4 bytes)
+DVLR SUBSCR(MSISDN:42342) AUTH established GSM security context
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000004620){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result PASSED
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000004620){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000004620){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000004620){VLR_SUB_AS_AUTHENTICATED}: Removing from parent Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620)
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000004620){VLR_SUB_AS_AUTHENTICATED}: Freeing instance
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000004620){VLR_SUB_AS_AUTHENTICATED}: Deallocated
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_WAIT_AUTH}: Received Event PR_ARQ_E_AUTH_RES
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_WAIT_AUTH}: Set Ciphering Mode
+DMM -> CIPHER MODE COMMAND MSISDN:42342
+- sending Ciphering Mode Command for MSISDN:42342: include_imeisv=0
+- ...perm algo: A5/3
+- ...key: 07fa7502e07e1c00
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_WAIT_AUTH}: state_chg to PR_ARQ_S_WAIT_CIPH
+DREF MSISDN:42342: MSC conn use - dtap == 0 (0x0: )
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  cm_service_result_sent == 0
+  cipher_mode_cmd_sent == 1
+- needs ciph, not yet accepted
+msc_subscr_conn_is_accepted() == false
+  requests shall be thwarted
+DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5)
+DRLL subscr MSISDN:42342: Message not permitted for initial conn: GSM48_MT_CC_SETUP
+DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33)
+DRLL subscr MSISDN:42342: Message not permitted for initial conn: unknown 0x33
+DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19)
+DRLL subscr MSISDN:42342: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1
+DRLL Dispatching 04.08 message SMS:0x01 (0x9:0x1)
+DRLL subscr MSISDN:42342: Message not permitted for initial conn: SMS:0x01
+- MS sends Ciphering Mode Complete, VLR accepts; above Ciphering is an implicit CM Service Accept
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_RR_CIPH_M_COMPL
+DRR MSISDN:42342: CIPHERING MODE COMPLETE
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_WAIT_CIPH}: Received Event PR_ARQ_E_CIPH_RES
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_node2_post_ciph()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_node2_post_vlr()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_pres()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_trace()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_imei()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_WAIT_CIPH}: proc_arq_fsm_done(PASSED)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_WAIT_CIPH}: state_chg to PR_ARQ_S_DONE
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_DONE}: Process Access Request result: PASSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_ACCEPTED
+DREF MSISDN:42342: MSC conn use + cm_service == 1 (0x8: cm_service)
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_ACCEPTED}: subscr_conn_fsm_has_active_transactions: still awaiting first request after a CM Service Request
+  cm_service_result_sent == 0
+- Concluding CM Service Request
+DREF MSISDN:42342: MSC conn use - cm_service == 0 (0x0: )
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:42342: MSC conn use + release == 1 (0x100: release)
+DREF VLR subscr MSISDN:42342 usage increases to: 3
+DREF VLR subscr MSISDN:42342 usage decreases to: 2
+- BSSAP Clear --RAN_GERAN_A--> MS
+  bssap_clear_sent == 1
+- all requests serviced, conn has been released
+- BSS sends BSSMAP Clear Complete
+DREF MSISDN:42342: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_DONE}: Removing from parent Subscr_Conn(CM_SERVICE_REQ:901700000004620)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_DONE}: Freeing instance
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_DONE}: Deallocated
+DRLL MSISDN:42342: Freeing subscriber connection
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+---
+- an SMS is sent, MS is paged
+DREF VLR subscr MSISDN:42342 usage increases to: 2
+  llist_count(&vsub->cs.requests) == 0
+DREF VLR subscr MSISDN:42342 usage increases to: 3
+DMM Subscriber MSISDN:42342 not paged yet, start paging.
+  RAN_GERAN_A sends out paging request to IMSI 901700000004620, TMSI 0xffffffff, LAC 23
+  strcmp(paging_expecting_imsi, imsi) == 0
+DREF VLR subscr MSISDN:42342 usage increases to: 4
+  llist_count(&vsub->cs.requests) == 1
+DREF VLR subscr MSISDN:42342 usage decreases to: 3
+  paging_sent == 1
+  paging_stopped == 0
+- the subscriber and its pending request should remain
+DREF VLR subscr MSISDN:42342 usage increases to: 4
+  llist_count(&vsub->cs.requests) == 1
+DREF VLR subscr MSISDN:42342 usage decreases to: 3
+- MS replies with Paging Response, and VLR sends Auth Request with third key
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_RR_PAG_RESP
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_RR_PAG_RESP (0x6:0x27)
+DRR PAGING RESPONSE: MI(IMSI)=901700000004620
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_NEW}: Updated ID
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_INIT}: Allocated
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_INIT}: is child of Subscr_Conn(PAGING_RESP:901700000004620)
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_INIT}: rev=GSM net=GERAN Auth+Ciph
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START
+DREF VLR subscr MSISDN:42342 usage increases to: 4
+DREF VLR subscr MSISDN:42342 usage increases to: 5
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi()
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_WAIT_AUTH
+DVLR VLR_Authenticate(PAGING_RESP:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Allocated
+DVLR VLR_Authenticate(PAGING_RESP:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: is child of Process_Access_Request_VLR(PAGING_RESP:901700000004620)
+DVLR VLR_Authenticate(PAGING_RESP:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
+DVLR VLR_Authenticate(PAGING_RESP:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_WAIT_RESP
+DVLR VLR_Authenticate(PAGING_RESP:901700000004620){VLR_SUB_AS_WAIT_RESP}: got auth tuple: use_count=1 key_seq=2 -- will use GSM AKA (is_r99=no, at->vec.auth_types=0x1)
+- sending GSM Auth Request for MSISDN:42342: tuple use_count=1 key_seq=2 auth_types=0x1 and...
+- ...rand=e7c03ba7cf0e2fde82b2dc4d63077d42
+- ...expecting sres=a29514ae
+DREF VLR subscr MSISDN:42342 usage decreases to: 4
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF MSISDN:42342: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  auth_request_sent == 1
+- needs auth, not yet accepted
+msc_subscr_conn_is_accepted() == false
+  requests shall be thwarted
+DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5)
+DRLL subscr MSISDN:42342: Message not permitted for initial conn: GSM48_MT_CC_SETUP
+DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33)
+DRLL subscr MSISDN:42342: Message not permitted for initial conn: unknown 0x33
+DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19)
+DRLL subscr MSISDN:42342: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1
+DRLL Dispatching 04.08 message SMS:0x01 (0x9:0x1)
+DRLL subscr MSISDN:42342: Message not permitted for initial conn: SMS:0x01
+- MS sends Authen Response, VLR accepts and requests Ciphering
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_AUTH_RESP
+DREF MSISDN:42342: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14)
+DMM MSISDN:42342: MM GSM AUTHENTICATION RESPONSE (sres = a29514ae)
+DVLR VLR_Authenticate(PAGING_RESP:901700000004620){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP
+DVLR SUBSCR(MSISDN:42342) AUTH on GERAN received SRES/RES: a29514ae (4 bytes)
+DVLR SUBSCR(MSISDN:42342) AUTH established GSM security context
+DVLR VLR_Authenticate(PAGING_RESP:901700000004620){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result PASSED
+DVLR VLR_Authenticate(PAGING_RESP:901700000004620){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
+DVLR VLR_Authenticate(PAGING_RESP:901700000004620){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR VLR_Authenticate(PAGING_RESP:901700000004620){VLR_SUB_AS_AUTHENTICATED}: Removing from parent Process_Access_Request_VLR(PAGING_RESP:901700000004620)
+DVLR VLR_Authenticate(PAGING_RESP:901700000004620){VLR_SUB_AS_AUTHENTICATED}: Freeing instance
+DVLR VLR_Authenticate(PAGING_RESP:901700000004620){VLR_SUB_AS_AUTHENTICATED}: Deallocated
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_WAIT_AUTH}: Received Event PR_ARQ_E_AUTH_RES
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2()
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_WAIT_AUTH}: Set Ciphering Mode
+DMM -> CIPHER MODE COMMAND MSISDN:42342
+- sending Ciphering Mode Command for MSISDN:42342: include_imeisv=0
+- ...perm algo: A5/3
+- ...key: e2b234f807886400
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_WAIT_AUTH}: state_chg to PR_ARQ_S_WAIT_CIPH
+DREF MSISDN:42342: MSC conn use - dtap == 0 (0x0: )
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  cipher_mode_cmd_sent == 1
+- needs ciph, not yet accepted
+msc_subscr_conn_is_accepted() == false
+  requests shall be thwarted
+DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5)
+DRLL subscr MSISDN:42342: Message not permitted for initial conn: GSM48_MT_CC_SETUP
+DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33)
+DRLL subscr MSISDN:42342: Message not permitted for initial conn: unknown 0x33
+DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19)
+DRLL subscr MSISDN:42342: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1
+DRLL Dispatching 04.08 message SMS:0x01 (0x9:0x1)
+DRLL subscr MSISDN:42342: Message not permitted for initial conn: SMS:0x01
+- MS sends Ciphering Mode Complete, VLR accepts and sends pending SMS
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_RR_CIPH_M_COMPL
+DRR MSISDN:42342: CIPHERING MODE COMPLETE
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_WAIT_CIPH}: Received Event PR_ARQ_E_CIPH_RES
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_node2_post_ciph()
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_node2_post_vlr()
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_pres()
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_trace()
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_imei()
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_WAIT_CIPH}: proc_arq_fsm_done(PASSED)
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_WAIT_CIPH}: state_chg to PR_ARQ_S_DONE
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_DONE}: Process Access Request result: PASSED
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_ACCEPTED
+DPAG Paging success for MSISDN:42342 (event=0)
+DPAG Calling paging cbfn.
+DCC (ti 00 sub MSISDN:42342 callref 40000004) New transaction
+DREF VLR subscr MSISDN:42342 usage increases to: 5
+DREF MSISDN:42342: MSC conn use + trans_sms == 1 (0x20: trans_sms)
+DMSC msc_tx 91 bytes to MSISDN:42342 via RAN_GERAN_A
+- DTAP --RAN_GERAN_A--> MS: SMS:0x01: 09015801000791447758100650004c0005802443f2000007101000000000445079da1e1ee7416937485e9ea7c965373d1d6683c270383b3d0ed3d36ff71c949e83c22072799e9687c5ec32a81d96afcbf4b4fb0c7ac3e9e9b7db05
+- DTAP matches expected message
+DREF VLR subscr MSISDN:42342 usage decreases to: 4
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_ACCEPTED}: subscr_conn_fsm_has_active_transactions: connection still has active transaction: SMS
+  dtap_tx_confirmed == 1
+  paging_stopped == 1
+- SMS was delivered, no requests pending for subscr
+DREF VLR subscr MSISDN:42342 usage increases to: 5
+  llist_count(&vsub->cs.requests) == 0
+DREF VLR subscr MSISDN:42342 usage decreases to: 4
+- conn is still open to wait for SMS ack dance
+  llist_count(&net->subscr_conns) == 1
+- MS replies with CP-ACK for received SMS
+  MSC <--RAN_GERAN_A-- MS: SMS:0x04
+DREF MSISDN:42342: MSC conn use + dtap == 2 (0x22: dtap,trans_sms)
+DRLL Dispatching 04.08 message SMS:0x04 (0x9:0x4)
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_COMMUNICATING
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_COMMUNICATING
+DREF MSISDN:42342: MSC conn use - dtap == 1 (0x20: trans_sms)
+  llist_count(&net->subscr_conns) == 1
+- MS also sends RP-ACK, MSC in turn sends CP-ACK for that
+  MSC <--RAN_GERAN_A-- MS: SMS:0x01
+DREF MSISDN:42342: MSC conn use + dtap == 2 (0x22: dtap,trans_sms)
+DRLL Dispatching 04.08 message SMS:0x01 (0x9:0x1)
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_COMMUNICATING}: Received Event SUBSCR_CONN_E_COMMUNICATING
+DMSC msc_tx 2 bytes to MSISDN:42342 via RAN_GERAN_A
+- DTAP --RAN_GERAN_A--> MS: SMS:0x04: 0904
+- DTAP matches expected message
+DREF VLR subscr MSISDN:42342 usage decreases to: 3
+DREF VLR subscr MSISDN:42342 usage decreases to: 2
+DREF MSISDN:42342: MSC conn use - trans_sms == 1 (0x2: dtap)
+DREF MSISDN:42342: MSC conn use - dtap == 0 (0x0: )
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_COMMUNICATING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_COMMUNICATING}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:42342: MSC conn use + release == 1 (0x100: release)
+DREF VLR subscr MSISDN:42342 usage increases to: 3
+DREF VLR subscr MSISDN:42342 usage decreases to: 2
+- BSSAP Clear --RAN_GERAN_A--> MS
+  dtap_tx_confirmed == 1
+  bssap_clear_sent == 1
+- SMS is done, conn is gone
+- BSS sends BSSMAP Clear Complete
+DREF MSISDN:42342: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_DONE}: Removing from parent Subscr_Conn(PAGING_RESP:901700000004620)
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_DONE}: Freeing instance
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_DONE}: Deallocated
+DRLL MSISDN:42342: Freeing subscriber connection
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+---
+- subscriber detaches
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_IMSI_DETACH_IND
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_IMSI_DETACH_IND (0x5:0x1)
+DMM IMSI DETACH INDICATION: MI(IMSI)=901700000004620
+DREF VLR subscr MSISDN:42342 usage increases to: 2
+DMM IMSI DETACH for MSISDN:42342
+DREF VLR subscr MSISDN:42342 usage increases to: 3
+DREF VLR subscr MSISDN:42342 usage decreases to: 2
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+DREF VLR subscr MSISDN:42342 usage decreases to: 0
+DREF freeing VLR subscr MSISDN:42342
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_CN_CLOSE
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF unknown: MSC conn use + release == 2 (0x101: compl_l3,release)
+- BSSAP Clear --RAN_GERAN_A--> MS
+DREF unknown: MSC conn use - compl_l3 == 1 (0x100: release)
+  bssap_clear_sent == 1
+- BSS sends BSSMAP Clear Complete
+DREF unknown: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DRLL Freeing subscriber connection with NULL subscriber
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+===== test_a5_3_supported: SUCCESS
+
+full talloc report on 'msgb' (total      0 bytes in   1 blocks)
+talloc_total_blocks(tall_bsc_ctx) == 12
+
+===== test_cm_service_needs_classmark_update
+- Location Update request causes a GSUP Send Auth Info request to HLR
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8)
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Updated ID
+DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000004620 type=IMSI ATTACH
+DMM LU/new-LAC: 1/23
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Allocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: is child of Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: rev=GSM net=GERAN Auth+Ciph
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA
+DREF VLR subscr unknown usage increases to: 1
+DVLR set IMSI on subscriber; IMSI=901700000004620 id=901700000004620
+DVLR New subscr, IMSI: 901700000004620
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DREF VLR subscr IMSI:901700000004620 usage decreases to: 1
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Allocated
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
+DVLR GSUP tx: 08010809710000004026f0
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f0
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF IMSI:901700000004620: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  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: 0a010809710000004026f003222010585df1ae287f6e273dce07090d61320b21042d8b2c3e220861855fb81fc2a8000322201012aca96fb4ffdea5c985cbafa9b6e18b210420bde240220807fa7502e07e1c0003222010e7c03ba7cf0e2fde82b2dc4d63077d422104a29514ae2208e2b234f80788640003222010fa8f20b781b5881329d4fea26b1a3c5121045afc8d7222082392f14f709ae000032220100fd4cc8dbe8715d1f439e304edfd68dc2104bc8d1c5b2208da7cdd6bfe2d7000
+DVLR GSUP rx 191: 0a010809710000004026f003222010585df1ae287f6e273dce07090d61320b21042d8b2c3e220861855fb81fc2a8000322201012aca96fb4ffdea5c985cbafa9b6e18b210420bde240220807fa7502e07e1c0003222010e7c03ba7cf0e2fde82b2dc4d63077d422104a29514ae2208e2b234f80788640003222010fa8f20b781b5881329d4fea26b1a3c5121045afc8d7222082392f14f709ae000032220100fd4cc8dbe8715d1f439e304edfd68dc2104bc8d1c5b2208da7cdd6bfe2d7000
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: Received Event VLR_AUTH_E_HLR_SAI_ACK
+DVLR SUBSCR(IMSI:901700000004620) Received 5 auth tuples
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: state_chg to VLR_SUB_AS_WAIT_RESP
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_WAIT_RESP}: got auth tuple: use_count=1 key_seq=0 -- will use GSM AKA (is_r99=no, at->vec.auth_types=0x1)
+- sending GSM Auth Request for IMSI:901700000004620: tuple use_count=1 key_seq=0 auth_types=0x1 and...
+- ...rand=585df1ae287f6e273dce07090d61320b
+- ...expecting sres=2d8b2c3e
+DREF VLR subscr IMSI:901700000004620 usage decreases to: 1
+<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT: vlr_gsupc_read_cb() returns 0
+  lu_result_sent == 0
+  auth_request_sent == 1
+---
+- MS sends Authen Response, VLR accepts and wants to send Ciphering Mode Command to MS -- but needs Classmark 2 to determine whether A5/3 is supported
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_AUTH_RESP
+DREF IMSI:901700000004620: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14)
+DMM IMSI:901700000004620: MM GSM AUTHENTICATION RESPONSE (sres = 2d8b2c3e)
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP
+DVLR SUBSCR(IMSI:901700000004620) AUTH on GERAN received SRES/RES: 2d8b2c3e (4 bytes)
+DVLR SUBSCR(IMSI:901700000004620) AUTH established GSM security context
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result PASSED
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_AUTHENTICATED}: Freeing instance
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_AUTHENTICATED}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_AUTH}: Set Ciphering Mode
+DMM IMSI:901700000004620: to determine whether A5/3 is supported, first ask for a Classmark Update to obtain Classmark 2
+  BSC <--BSSAP-BSS-MANAGEMENT-- MSC: CLASSMARK REQ [L3]> 00 01 58 
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_WAIT_CLASSMARK_UPDATE
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_WAIT_CIPH
+DREF IMSI:901700000004620: MSC conn use - dtap == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_WAIT_CLASSMARK_UPDATE}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_WAIT_CLASSMARK_UPDATE}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  lu_result_sent == 0
+- BSC sends back a BSSMAP Classmark Update, that triggers the Ciphering Mode Command in A5/3
+DMSC Looking for A subscriber: conn_id 0
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_WAIT_CLASSMARK_UPDATE}: Received Event SUBSCR_CONN_E_CLASSMARK_UPDATE
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_WAIT_CLASSMARK_UPDATE}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DMM -> CIPHER MODE COMMAND IMSI:901700000004620
+- sending Ciphering Mode Command for IMSI:901700000004620: include_imeisv=0
+- ...perm algo: A5/3
+- ...key: 61855fb81fc2a800
+  lu_result_sent == 0
+- MS sends Ciphering Mode Complete, VLR accepts and sends GSUP LU Req to HLR
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_RR_CIPH_M_COMPL
+DRR IMSI:901700000004620: CIPHERING MODE COMPLETE
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_CIPH}: Received Event VLR_ULA_E_CIPH_RES
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_CIPH}: vlr_loc_upd_post_ciph()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_CIPH}: vlr_loc_upd_node_4()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_CIPH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: Allocated
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START
+DVLR GSUP tx: 04010809710000004026f0280102
+GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000004026f0280102
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA
+  lu_result_sent == 0
+- HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT
+<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: 10010809710000004026f00804032443f2
+DVLR GSUP rx 17: 10010809710000004026f00804032443f2
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DVLR IMSI:901700000004620 has MSISDN:42342
+DVLR SUBSCR(MSISDN:42342) VLR: update for IMSI=901700000004620 (MSISDN=42342, used=2)
+DVLR GSUP tx: 12010809710000004026f0
+GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000004026f0
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+<-- 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: 06010809710000004026f0
+DVLR GSUP rx 11: 06010809710000004026f0
+DREF VLR subscr MSISDN:42342 usage increases to: 2
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Freeing instance
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: Allocated
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: Allocated
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(LU:901700000004620)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(LU:901700000004620)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Freeing instance
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Deallocated
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL
+- sending LU Accept for MSISDN:42342
+DREF VLR subscr MSISDN:42342 usage increases to: 3
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_DONE
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Freeing instance
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_ACCEPTED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:42342: MSC conn use + release == 1 (0x100: release)
+DREF VLR subscr MSISDN:42342 usage increases to: 4
+DREF VLR subscr MSISDN:42342 usage decreases to: 3
+- BSSAP Clear --RAN_GERAN_A--> MS
+DREF VLR subscr MSISDN:42342 usage decreases to: 2
+<-- 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
+  lu_result_sent == 1
+- BSS sends BSSMAP Clear Complete
+DREF MSISDN:42342: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Freeing instance
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Deallocated
+DRLL MSISDN:42342: Freeing subscriber connection
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+---
+- after a while, a new conn sends a CM Service Request. VLR responds with Auth Req, 2nd auth vector
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_CM_SERV_REQ
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_CM_SERV_REQ (0x5:0x24)
+DMM <- CM SERVICE REQUEST serv_type=0x08 MI(IMSI)=901700000004620
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_NEW}: Updated ID
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_INIT}: Allocated
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_INIT}: is child of Subscr_Conn(CM_SERVICE_REQ:901700000004620)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_INIT}: rev=GSM net=GERAN Auth+Ciph
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START
+DREF VLR subscr MSISDN:42342 usage increases to: 2
+DREF VLR subscr MSISDN:42342 usage increases to: 3
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_WAIT_AUTH
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Allocated
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: is child of Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620)
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_WAIT_RESP
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000004620){VLR_SUB_AS_WAIT_RESP}: got auth tuple: use_count=1 key_seq=1 -- will use GSM AKA (is_r99=no, at->vec.auth_types=0x1)
+- sending GSM Auth Request for MSISDN:42342: tuple use_count=1 key_seq=1 auth_types=0x1 and...
+- ...rand=12aca96fb4ffdea5c985cbafa9b6e18b
+- ...expecting sres=20bde240
+DREF VLR subscr MSISDN:42342 usage decreases to: 2
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF MSISDN:42342: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  auth_request_sent == 1
+  cm_service_result_sent == 0
+- needs auth, not yet accepted
+msc_subscr_conn_is_accepted() == false
+  requests shall be thwarted
+DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5)
+DRLL subscr MSISDN:42342: Message not permitted for initial conn: GSM48_MT_CC_SETUP
+DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33)
+DRLL subscr MSISDN:42342: Message not permitted for initial conn: unknown 0x33
+DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19)
+DRLL subscr MSISDN:42342: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1
+DRLL Dispatching 04.08 message SMS:0x01 (0x9:0x1)
+DRLL subscr MSISDN:42342: Message not permitted for initial conn: SMS:0x01
+- MS sends Authen Response, VLR accepts and requests Ciphering. We already know Classmark 3, so no need to request Classmark Update.
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_AUTH_RESP
+DREF MSISDN:42342: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14)
+DMM MSISDN:42342: MM GSM AUTHENTICATION RESPONSE (sres = 20bde240)
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000004620){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP
+DVLR SUBSCR(MSISDN:42342) AUTH on GERAN received SRES/RES: 20bde240 (4 bytes)
+DVLR SUBSCR(MSISDN:42342) AUTH established GSM security context
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000004620){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result PASSED
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000004620){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000004620){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000004620){VLR_SUB_AS_AUTHENTICATED}: Removing from parent Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620)
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000004620){VLR_SUB_AS_AUTHENTICATED}: Freeing instance
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000004620){VLR_SUB_AS_AUTHENTICATED}: Deallocated
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_WAIT_AUTH}: Received Event PR_ARQ_E_AUTH_RES
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_WAIT_AUTH}: Set Ciphering Mode
+DMM -> CIPHER MODE COMMAND MSISDN:42342
+- sending Ciphering Mode Command for MSISDN:42342: include_imeisv=0
+- ...perm algo: A5/3
+- ...key: 07fa7502e07e1c00
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_WAIT_AUTH}: state_chg to PR_ARQ_S_WAIT_CIPH
+DREF MSISDN:42342: MSC conn use - dtap == 0 (0x0: )
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  cm_service_result_sent == 0
+  cipher_mode_cmd_sent == 1
+- needs ciph, not yet accepted
+msc_subscr_conn_is_accepted() == false
+  requests shall be thwarted
+DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5)
+DRLL subscr MSISDN:42342: Message not permitted for initial conn: GSM48_MT_CC_SETUP
+DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33)
+DRLL subscr MSISDN:42342: Message not permitted for initial conn: unknown 0x33
+DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19)
+DRLL subscr MSISDN:42342: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1
+DRLL Dispatching 04.08 message SMS:0x01 (0x9:0x1)
+DRLL subscr MSISDN:42342: Message not permitted for initial conn: SMS:0x01
+- MS sends Ciphering Mode Complete, VLR accepts; above Ciphering is an implicit CM Service Accept
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_RR_CIPH_M_COMPL
+DRR MSISDN:42342: CIPHERING MODE COMPLETE
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_WAIT_CIPH}: Received Event PR_ARQ_E_CIPH_RES
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_node2_post_ciph()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_node2_post_vlr()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_pres()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_trace()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_imei()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_WAIT_CIPH}: proc_arq_fsm_done(PASSED)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_WAIT_CIPH}: state_chg to PR_ARQ_S_DONE
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_DONE}: Process Access Request result: PASSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_ACCEPTED
+DREF MSISDN:42342: MSC conn use + cm_service == 1 (0x8: cm_service)
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_ACCEPTED}: subscr_conn_fsm_has_active_transactions: still awaiting first request after a CM Service Request
+  cm_service_result_sent == 0
+- Concluding CM Service Request
+DREF MSISDN:42342: MSC conn use - cm_service == 0 (0x0: )
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:42342: MSC conn use + release == 1 (0x100: release)
+DREF VLR subscr MSISDN:42342 usage increases to: 3
+DREF VLR subscr MSISDN:42342 usage decreases to: 2
+- BSSAP Clear --RAN_GERAN_A--> MS
+  bssap_clear_sent == 1
+- all requests serviced, conn has been released
+- BSS sends BSSMAP Clear Complete
+DREF MSISDN:42342: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_DONE}: Removing from parent Subscr_Conn(CM_SERVICE_REQ:901700000004620)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_DONE}: Freeing instance
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_DONE}: Deallocated
+DRLL MSISDN:42342: Freeing subscriber connection
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+---
+- an SMS is sent, MS is paged
+DREF VLR subscr MSISDN:42342 usage increases to: 2
+  llist_count(&vsub->cs.requests) == 0
+DREF VLR subscr MSISDN:42342 usage increases to: 3
+DMM Subscriber MSISDN:42342 not paged yet, start paging.
+  RAN_GERAN_A sends out paging request to IMSI 901700000004620, TMSI 0xffffffff, LAC 23
+  strcmp(paging_expecting_imsi, imsi) == 0
+DREF VLR subscr MSISDN:42342 usage increases to: 4
+  llist_count(&vsub->cs.requests) == 1
+DREF VLR subscr MSISDN:42342 usage decreases to: 3
+  paging_sent == 1
+  paging_stopped == 0
+- the subscriber and its pending request should remain
+DREF VLR subscr MSISDN:42342 usage increases to: 4
+  llist_count(&vsub->cs.requests) == 1
+DREF VLR subscr MSISDN:42342 usage decreases to: 3
+- MS replies with Paging Response, and VLR sends Auth Request with third key
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_RR_PAG_RESP
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_RR_PAG_RESP (0x6:0x27)
+DRR PAGING RESPONSE: MI(IMSI)=901700000004620
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_NEW}: Updated ID
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_INIT}: Allocated
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_INIT}: is child of Subscr_Conn(PAGING_RESP:901700000004620)
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_INIT}: rev=GSM net=GERAN Auth+Ciph
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START
+DREF VLR subscr MSISDN:42342 usage increases to: 4
+DREF VLR subscr MSISDN:42342 usage increases to: 5
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi()
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_WAIT_AUTH
+DVLR VLR_Authenticate(PAGING_RESP:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Allocated
+DVLR VLR_Authenticate(PAGING_RESP:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: is child of Process_Access_Request_VLR(PAGING_RESP:901700000004620)
+DVLR VLR_Authenticate(PAGING_RESP:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
+DVLR VLR_Authenticate(PAGING_RESP:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_WAIT_RESP
+DVLR VLR_Authenticate(PAGING_RESP:901700000004620){VLR_SUB_AS_WAIT_RESP}: got auth tuple: use_count=1 key_seq=2 -- will use GSM AKA (is_r99=no, at->vec.auth_types=0x1)
+- sending GSM Auth Request for MSISDN:42342: tuple use_count=1 key_seq=2 auth_types=0x1 and...
+- ...rand=e7c03ba7cf0e2fde82b2dc4d63077d42
+- ...expecting sres=a29514ae
+DREF VLR subscr MSISDN:42342 usage decreases to: 4
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF MSISDN:42342: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  auth_request_sent == 1
+---
+- Fake a situation where Classmark 2 is unknown during proc_arq_fsm
+DREF VLR subscr MSISDN:42342 usage increases to: 5
+DREF VLR subscr MSISDN:42342 usage decreases to: 4
+- MS sends Authen Response, VLR accepts and requests Ciphering
+- MS sends Authen Response, VLR accepts and requests Ciphering. Normally, we'd know Classmark 3, but this test removed it. Hence a Classmark Request is generated.
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_AUTH_RESP
+DREF MSISDN:42342: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14)
+DMM MSISDN:42342: MM GSM AUTHENTICATION RESPONSE (sres = a29514ae)
+DVLR VLR_Authenticate(PAGING_RESP:901700000004620){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP
+DVLR SUBSCR(MSISDN:42342) AUTH on GERAN received SRES/RES: a29514ae (4 bytes)
+DVLR SUBSCR(MSISDN:42342) AUTH established GSM security context
+DVLR VLR_Authenticate(PAGING_RESP:901700000004620){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result PASSED
+DVLR VLR_Authenticate(PAGING_RESP:901700000004620){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
+DVLR VLR_Authenticate(PAGING_RESP:901700000004620){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR VLR_Authenticate(PAGING_RESP:901700000004620){VLR_SUB_AS_AUTHENTICATED}: Removing from parent Process_Access_Request_VLR(PAGING_RESP:901700000004620)
+DVLR VLR_Authenticate(PAGING_RESP:901700000004620){VLR_SUB_AS_AUTHENTICATED}: Freeing instance
+DVLR VLR_Authenticate(PAGING_RESP:901700000004620){VLR_SUB_AS_AUTHENTICATED}: Deallocated
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_WAIT_AUTH}: Received Event PR_ARQ_E_AUTH_RES
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2()
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_WAIT_AUTH}: Set Ciphering Mode
+DMM MSISDN:42342: to determine whether A5/3 is supported, first ask for a Classmark Update to obtain Classmark 2
+  BSC <--BSSAP-BSS-MANAGEMENT-- MSC: CLASSMARK REQ [L3]> 00 01 58 
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_WAIT_CLASSMARK_UPDATE
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_WAIT_AUTH}: state_chg to PR_ARQ_S_WAIT_CIPH
+DREF MSISDN:42342: MSC conn use - dtap == 0 (0x0: )
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_WAIT_CLASSMARK_UPDATE}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_WAIT_CLASSMARK_UPDATE}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+- BSC sends back a BSSMAP Classmark Update, that triggers the Ciphering Mode Command in A5/3
+DMSC Looking for A subscriber: conn_id 0
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_WAIT_CLASSMARK_UPDATE}: Received Event SUBSCR_CONN_E_CLASSMARK_UPDATE
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_WAIT_CLASSMARK_UPDATE}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DMM -> CIPHER MODE COMMAND MSISDN:42342
+- sending Ciphering Mode Command for MSISDN:42342: include_imeisv=0
+- ...perm algo: A5/3
+- ...key: e2b234f807886400
+- needs ciph, not yet accepted
+msc_subscr_conn_is_accepted() == false
+- MS sends Ciphering Mode Complete, VLR accepts and sends pending SMS
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_RR_CIPH_M_COMPL
+DRR MSISDN:42342: CIPHERING MODE COMPLETE
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_WAIT_CIPH}: Received Event PR_ARQ_E_CIPH_RES
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_node2_post_ciph()
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_node2_post_vlr()
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_pres()
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_trace()
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_imei()
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_WAIT_CIPH}: proc_arq_fsm_done(PASSED)
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_WAIT_CIPH}: state_chg to PR_ARQ_S_DONE
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_DONE}: Process Access Request result: PASSED
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_ACCEPTED
+DPAG Paging success for MSISDN:42342 (event=0)
+DPAG Calling paging cbfn.
+DCC (ti 00 sub MSISDN:42342 callref 40000005) New transaction
+DREF VLR subscr MSISDN:42342 usage increases to: 5
+DREF MSISDN:42342: MSC conn use + trans_sms == 1 (0x20: trans_sms)
+DMSC msc_tx 91 bytes to MSISDN:42342 via RAN_GERAN_A
+- DTAP --RAN_GERAN_A--> MS: SMS:0x01: 09015801000791447758100650004c0005802443f2000007101000000000445079da1e1ee7416937485e9ea7c965373d1d6683c270383b3d0ed3d36ff71c949e83c22072799e9687c5ec32a81d96afcbf4b4fb0c7ac3e9e9b7db05
+- DTAP matches expected message
+DREF VLR subscr MSISDN:42342 usage decreases to: 4
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_ACCEPTED}: subscr_conn_fsm_has_active_transactions: connection still has active transaction: SMS
+  dtap_tx_confirmed == 1
+  paging_stopped == 1
+- SMS was delivered, no requests pending for subscr
+DREF VLR subscr MSISDN:42342 usage increases to: 5
+  llist_count(&vsub->cs.requests) == 0
+DREF VLR subscr MSISDN:42342 usage decreases to: 4
+- conn is still open to wait for SMS ack dance
+  llist_count(&net->subscr_conns) == 1
+- MS replies with CP-ACK for received SMS
+  MSC <--RAN_GERAN_A-- MS: SMS:0x04
+DREF MSISDN:42342: MSC conn use + dtap == 2 (0x22: dtap,trans_sms)
+DRLL Dispatching 04.08 message SMS:0x04 (0x9:0x4)
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_COMMUNICATING
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_COMMUNICATING
+DREF MSISDN:42342: MSC conn use - dtap == 1 (0x20: trans_sms)
+  llist_count(&net->subscr_conns) == 1
+- MS also sends RP-ACK, MSC in turn sends CP-ACK for that
+  MSC <--RAN_GERAN_A-- MS: SMS:0x01
+DREF MSISDN:42342: MSC conn use + dtap == 2 (0x22: dtap,trans_sms)
+DRLL Dispatching 04.08 message SMS:0x01 (0x9:0x1)
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_COMMUNICATING}: Received Event SUBSCR_CONN_E_COMMUNICATING
+DMSC msc_tx 2 bytes to MSISDN:42342 via RAN_GERAN_A
+- DTAP --RAN_GERAN_A--> MS: SMS:0x04: 0904
+- DTAP matches expected message
+DREF VLR subscr MSISDN:42342 usage decreases to: 3
+DREF VLR subscr MSISDN:42342 usage decreases to: 2
+DREF MSISDN:42342: MSC conn use - trans_sms == 1 (0x2: dtap)
+DREF MSISDN:42342: MSC conn use - dtap == 0 (0x0: )
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_COMMUNICATING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_COMMUNICATING}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:42342: MSC conn use + release == 1 (0x100: release)
+DREF VLR subscr MSISDN:42342 usage increases to: 3
+DREF VLR subscr MSISDN:42342 usage decreases to: 2
+- BSSAP Clear --RAN_GERAN_A--> MS
+  dtap_tx_confirmed == 1
+  bssap_clear_sent == 1
+- SMS is done, conn is gone
+- BSS sends BSSMAP Clear Complete
+DREF MSISDN:42342: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_DONE}: Removing from parent Subscr_Conn(PAGING_RESP:901700000004620)
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_DONE}: Freeing instance
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_DONE}: Deallocated
+DRLL MSISDN:42342: Freeing subscriber connection
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+---
+- subscriber detaches
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_IMSI_DETACH_IND
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_IMSI_DETACH_IND (0x5:0x1)
+DMM IMSI DETACH INDICATION: MI(IMSI)=901700000004620
+DREF VLR subscr MSISDN:42342 usage increases to: 2
+DMM IMSI DETACH for MSISDN:42342
+DREF VLR subscr MSISDN:42342 usage increases to: 3
+DREF VLR subscr MSISDN:42342 usage decreases to: 2
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+DREF VLR subscr MSISDN:42342 usage decreases to: 0
+DREF freeing VLR subscr MSISDN:42342
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_CN_CLOSE
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF unknown: MSC conn use + release == 2 (0x101: compl_l3,release)
+- BSSAP Clear --RAN_GERAN_A--> MS
+DREF unknown: MSC conn use - compl_l3 == 1 (0x100: release)
+  bssap_clear_sent == 1
+- BSS sends BSSMAP Clear Complete
+DREF unknown: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DRLL Freeing subscriber connection with NULL subscriber
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 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) == 12
+
+full talloc report on 'msgb' (total      0 bytes in   1 blocks)
+talloc_total_blocks(tall_bsc_ctx) == 12
+
diff --git a/tests/msc_vlr/msc_vlr_test_gsm_ciph.ok b/tests/msc_vlr/msc_vlr_test_gsm_ciph.ok
new file mode 100644
index 0000000..a965a70
--- /dev/null
+++ b/tests/msc_vlr/msc_vlr_test_gsm_ciph.ok
@@ -0,0 +1 @@
+Done
diff --git a/tests/msc_vlr/msc_vlr_test_hlr_reject.c b/tests/msc_vlr/msc_vlr_test_hlr_reject.c
new file mode 100644
index 0000000..13bed42
--- /dev/null
+++ b/tests/msc_vlr/msc_vlr_test_hlr_reject.c
@@ -0,0 +1,458 @@
+/* Osmocom MSC+VLR end-to-end tests */
+
+/* (C) 2017 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>
+ *
+ * All Rights Reserved
+ *
+ * Author: Neels Hofmeyr <nhofmeyr@sysmocom.de>
+ *
+ * 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 "msc_vlr_tests.h"
+
+static void test_hlr_rej_auth_info_unknown_imsi()
+{
+	comment_start();
+
+	net->authentication_required = true;
+
+	btw("Location Update request causes a GSUP Send Auth Info request to HLR");
+	lu_result_sent = RES_NONE;
+	gsup_expect_tx("08010809710000004026f0");
+	ms_sends_msg("050802008168000130089910070000006402");
+	OSMO_ASSERT(gsup_tx_confirmed);
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("HLR sends _SEND_AUTH_INFO_ERROR = unknown IMSI");
+	auth_request_sent = false;
+	expect_bssap_clear();
+	gsup_rx("09" "010809710000004026f0" "020102", NULL);
+	VERBOSE_ASSERT(auth_request_sent, == false, "%d");
+	VERBOSE_ASSERT(lu_result_sent, == RES_REJECT, "%d");
+	VERBOSE_ASSERT(bssap_clear_sent, == true, "%d");
+
+	bss_sends_clear_complete();
+	EXPECT_CONN_COUNT(0);
+	clear_vlr();
+	comment_end();
+}
+
+static void test_hlr_rej_auth_info_net_fail()
+{
+	comment_start();
+
+	net->authentication_required = true;
+
+	btw("Location Update request causes a GSUP Send Auth Info request to HLR");
+	lu_result_sent = RES_NONE;
+	gsup_expect_tx("08010809710000004026f0");
+	ms_sends_msg("050802008168000130089910070000006402");
+	OSMO_ASSERT(gsup_tx_confirmed);
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("HLR sends _SEND_AUTH_INFO_ERROR = net fail");
+	auth_request_sent = false;
+	expect_bssap_clear();
+	gsup_rx("09" "010809710000004026f0" "020111", NULL);
+	VERBOSE_ASSERT(auth_request_sent, == false, "%d");
+	VERBOSE_ASSERT(lu_result_sent, == RES_REJECT, "%d");
+	VERBOSE_ASSERT(bssap_clear_sent, == true, "%d");
+
+	bss_sends_clear_complete();
+	EXPECT_CONN_COUNT(0);
+	clear_vlr();
+	comment_end();
+}
+
+static void test_hlr_rej_auth_info_net_fail_no_reuse_tuples()
+{
+	struct vlr_subscr *vsub;
+	const char *imsi = "901700000004620";
+
+	comment_start();
+
+	net->authentication_required = true;
+	net->vlr->cfg.auth_reuse_old_sets_on_error = false;
+	net->vlr->cfg.auth_tuple_max_reuse_count = 0;
+
+	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");
+	ms_sends_msg("050802008168000130089910070000006402");
+	OSMO_ASSERT(gsup_tx_confirmed);
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("from HLR, rx _SEND_AUTH_INFO_RESULT; VLR sends Auth Req to MS");
+	auth_request_sent = false;
+	auth_request_expect_rand = "585df1ae287f6e273dce07090d61320b";
+	auth_request_expect_autn = NULL;
+	/* Based on a Ki of 000102030405060708090a0b0c0d0e0f */
+	gsup_rx("0a"
+		/* imsi */
+		"0108" "09710000004026f0"
+		/* auth vectors... */
+		/* TL    TL     rand */
+		"0322"  "2010" "585df1ae287f6e273dce07090d61320b"
+		/*       TL     sres       TL     kc */
+			"2104" "2d8b2c3e" "2208" "61855fb81fc2a800"
+		,NULL);
+	VERBOSE_ASSERT(auth_request_sent, == true, "%d");
+	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");
+	ms_sends_msg("05542d8b2c3e");
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT");
+	gsup_rx("10010809710000004026f00804036470f1",
+		"12010809710000004026f0");
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("HLR also sends GSUP _UPDATE_LOCATION_RESULT");
+	expect_bssap_clear();
+	gsup_rx("06010809710000004026f0", NULL);
+	VERBOSE_ASSERT(bssap_clear_sent, == true, "%d");
+
+	btw("LU was successful, and the conn has already been closed");
+	VERBOSE_ASSERT(lu_result_sent, == RES_ACCEPT, "%d");
+	bss_sends_clear_complete();
+	EXPECT_CONN_COUNT(0);
+
+
+	BTW("Now one auth tuple is available, but used.");
+	vsub = vlr_subscr_find_by_imsi(net->vlr, imsi);
+	OSMO_ASSERT(vsub);
+	OSMO_ASSERT(vsub->last_tuple);
+	VERBOSE_ASSERT(vsub->last_tuple->use_count, == 1, "%d");
+	/* no need to look at all auth tuples, the ongoing test would take an
+	 * unexpected course if there were more. */
+	vlr_subscr_put(vsub);
+
+	BTW("Another LU wants to get new tuples; HLR sends Network Failure, we reject.");
+
+	btw("Location Update request causes a GSUP Send Auth Info request to HLR");
+	lu_result_sent = RES_NONE;
+	gsup_expect_tx("08010809710000004026f0");
+	ms_sends_msg("050802008168000130089910070000006402");
+	OSMO_ASSERT(gsup_tx_confirmed);
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("HLR sends _SEND_AUTH_INFO_ERROR = net fail");
+	auth_request_sent = false;
+	expect_bssap_clear();
+	gsup_rx("09" "010809710000004026f0" "020111", NULL);
+	VERBOSE_ASSERT(auth_request_sent, == false, "%d");
+	VERBOSE_ASSERT(lu_result_sent, == RES_REJECT, "%d");
+	VERBOSE_ASSERT(bssap_clear_sent, == true, "%d");
+
+	bss_sends_clear_complete();
+	EXPECT_CONN_COUNT(0);
+	clear_vlr();
+	comment_end();
+}
+
+static void test_hlr_rej_auth_info_unkown_imsi_no_reuse_tuples()
+{
+	struct vlr_subscr *vsub;
+	const char *imsi = "901700000004620";
+
+	comment_start();
+
+	net->authentication_required = true;
+	net->vlr->cfg.auth_reuse_old_sets_on_error = true;
+	net->vlr->cfg.auth_tuple_max_reuse_count = 0;
+
+	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");
+	ms_sends_msg("050802008168000130089910070000006402");
+	OSMO_ASSERT(gsup_tx_confirmed);
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("from HLR, rx _SEND_AUTH_INFO_RESULT; VLR sends Auth Req to MS");
+	auth_request_sent = false;
+	auth_request_expect_rand = "585df1ae287f6e273dce07090d61320b";
+	auth_request_expect_autn = NULL;
+	/* Based on a Ki of 000102030405060708090a0b0c0d0e0f */
+	gsup_rx("0a"
+		/* imsi */
+		"0108" "09710000004026f0"
+		/* auth vectors... */
+		/* TL    TL     rand */
+		"0322"  "2010" "585df1ae287f6e273dce07090d61320b"
+		/*       TL     sres       TL     kc */
+			"2104" "2d8b2c3e" "2208" "61855fb81fc2a800"
+		,NULL);
+	VERBOSE_ASSERT(auth_request_sent, == true, "%d");
+	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");
+	ms_sends_msg("05542d8b2c3e");
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT");
+	gsup_rx("10010809710000004026f00804036470f1",
+		"12010809710000004026f0");
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("HLR also sends GSUP _UPDATE_LOCATION_RESULT");
+	expect_bssap_clear();
+	gsup_rx("06010809710000004026f0", NULL);
+	VERBOSE_ASSERT(bssap_clear_sent, == true, "%d");
+
+	btw("LU was successful, and the conn has already been closed");
+	VERBOSE_ASSERT(lu_result_sent, == RES_ACCEPT, "%d");
+	bss_sends_clear_complete();
+	EXPECT_CONN_COUNT(0);
+
+
+	BTW("Now one auth tuple is available, but used.");
+	vsub = vlr_subscr_find_by_imsi(net->vlr, imsi);
+	OSMO_ASSERT(vsub);
+	OSMO_ASSERT(vsub->last_tuple);
+	VERBOSE_ASSERT(vsub->last_tuple->use_count, == 1, "%d");
+	/* no need to look at all auth tuples, the ongoing test would take an
+	 * unexpected course if there were more. */
+	vlr_subscr_put(vsub);
+
+	BTW("Another LU wants to get new tuples; HLR sends IMSI Unknown. Even though we would re-use an old tuple, reject the unknown IMSI.");
+	VERBOSE_ASSERT(net->vlr->cfg.auth_reuse_old_sets_on_error, == true, "%d");
+
+	btw("Location Update request causes a GSUP Send Auth Info request to HLR");
+	lu_result_sent = RES_NONE;
+	gsup_expect_tx("08010809710000004026f0");
+	ms_sends_msg("050802008168000130089910070000006402");
+	OSMO_ASSERT(gsup_tx_confirmed);
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("HLR sends _SEND_AUTH_INFO_ERROR = unknown IMSI");
+	auth_request_sent = false;
+	expect_bssap_clear();
+	gsup_rx("09" "010809710000004026f0" "020102", NULL);
+	VERBOSE_ASSERT(auth_request_sent, == false, "%d");
+	VERBOSE_ASSERT(lu_result_sent, == RES_REJECT, "%d");
+	VERBOSE_ASSERT(bssap_clear_sent, == true, "%d");
+
+	bss_sends_clear_complete();
+	EXPECT_CONN_COUNT(0);
+	clear_vlr();
+	comment_end();
+}
+
+static void test_hlr_acc_but_no_auth_tuples()
+{
+	comment_start();
+
+	net->authentication_required = true;
+	net->vlr->cfg.auth_reuse_old_sets_on_error = true;
+	net->vlr->cfg.auth_tuple_max_reuse_count = 0;
+
+	btw("Location Update request causes a GSUP Send Auth Info request to HLR");
+	lu_result_sent = RES_NONE;
+	gsup_expect_tx("08010809710000004026f0");
+	ms_sends_msg("050802008168000130089910070000006402");
+	OSMO_ASSERT(gsup_tx_confirmed);
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("from HLR, rx _SEND_AUTH_INFO_RESULT but it lacks auth tuples");
+	auth_request_sent = false;
+	expect_bssap_clear();
+	gsup_rx("0a"
+		/* imsi */
+		"0108" "09710000004026f0"
+		/* NO auth vectors */
+		,NULL);
+	VERBOSE_ASSERT(auth_request_sent, == false, "%d");
+	VERBOSE_ASSERT(lu_result_sent, == RES_REJECT, "%d");
+	VERBOSE_ASSERT(bssap_clear_sent, == true, "%d");
+
+	bss_sends_clear_complete();
+	EXPECT_CONN_COUNT(0);
+	clear_vlr();
+	comment_end();
+}
+
+static void test_hlr_rej_auth_info_net_fail_reuse_tuples()
+{
+	struct vlr_subscr *vsub;
+	const char *imsi = "901700000004620";
+
+	comment_start();
+
+	net->authentication_required = true;
+	net->vlr->cfg.auth_reuse_old_sets_on_error = true;
+	net->vlr->cfg.auth_tuple_max_reuse_count = 0;
+
+	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");
+	ms_sends_msg("050802008168000130089910070000006402");
+	OSMO_ASSERT(gsup_tx_confirmed);
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("from HLR, rx _SEND_AUTH_INFO_RESULT; VLR sends Auth Req to MS");
+	auth_request_sent = false;
+	auth_request_expect_rand = "585df1ae287f6e273dce07090d61320b";
+	auth_request_expect_autn = NULL;
+	/* Based on a Ki of 000102030405060708090a0b0c0d0e0f */
+	gsup_rx("0a"
+		/* imsi */
+		"0108" "09710000004026f0"
+		/* auth vectors... */
+		/* TL    TL     rand */
+		"0322"  "2010" "585df1ae287f6e273dce07090d61320b"
+		/*       TL     sres       TL     kc */
+			"2104" "2d8b2c3e" "2208" "61855fb81fc2a800"
+		,NULL);
+	VERBOSE_ASSERT(auth_request_sent, == true, "%d");
+	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");
+	ms_sends_msg("05542d8b2c3e");
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT");
+	gsup_rx("10010809710000004026f00804036470f1",
+		"12010809710000004026f0");
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("HLR also sends GSUP _UPDATE_LOCATION_RESULT");
+	expect_bssap_clear();
+	gsup_rx("06010809710000004026f0", NULL);
+	VERBOSE_ASSERT(bssap_clear_sent, == true, "%d");
+
+	btw("LU was successful, and the conn has already been closed");
+	VERBOSE_ASSERT(lu_result_sent, == RES_ACCEPT, "%d");
+	bss_sends_clear_complete();
+	EXPECT_CONN_COUNT(0);
+
+
+	BTW("Now one auth tuple is available, but used.");
+	vsub = vlr_subscr_find_by_imsi(net->vlr, imsi);
+	OSMO_ASSERT(vsub);
+	OSMO_ASSERT(vsub->last_tuple);
+	VERBOSE_ASSERT(vsub->last_tuple->use_count, == 1, "%d");
+	/* no need to look at all auth tuples, the ongoing test would take an
+	 * unexpected course if there were more. */
+	vlr_subscr_put(vsub);
+
+	BTW("Another LU wants to get new tuples; even though HLR sends Network Failure, we are reusing the old tuples.");
+
+	btw("Location Update request causes a GSUP Send Auth Info request to HLR");
+	lu_result_sent = RES_NONE;
+	gsup_expect_tx("08010809710000004026f0");
+	ms_sends_msg("050802008168000130089910070000006402");
+	OSMO_ASSERT(gsup_tx_confirmed);
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("HLR sends _SEND_AUTH_INFO_ERROR = net fail");
+	auth_request_sent = false;
+	gsup_rx("09" "010809710000004026f0" "020111", NULL);
+	VERBOSE_ASSERT(auth_request_sent, == true, "%d");
+	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");
+	ms_sends_msg("05542d8b2c3e");
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT");
+	gsup_rx("10010809710000004026f00804036470f1",
+		"12010809710000004026f0");
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("HLR also sends GSUP _UPDATE_LOCATION_RESULT");
+	expect_bssap_clear();
+	gsup_rx("06010809710000004026f0", NULL);
+	VERBOSE_ASSERT(bssap_clear_sent, == true, "%d");
+
+	btw("LU was successful, and the conn has already been closed");
+	VERBOSE_ASSERT(lu_result_sent, == RES_ACCEPT, "%d");
+	bss_sends_clear_complete();
+	EXPECT_CONN_COUNT(0);
+
+	clear_vlr();
+	comment_end();
+}
+
+static void test_hlr_rej_lu()
+{
+	comment_start();
+
+	btw("Location Update request causes a GSUP LU request to HLR");
+	lu_result_sent = RES_NONE;
+	gsup_expect_tx("04010809710000004026f0280102");
+	ms_sends_msg("050802008168000130089910070000006402");
+	OSMO_ASSERT(gsup_tx_confirmed);
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("HLR sends UPDATE_LOCATION_ERROR");
+	expect_bssap_clear();
+	gsup_rx("05" "010809710000004026f0" "020102",
+		NULL);
+	VERBOSE_ASSERT(lu_result_sent, == RES_REJECT, "%d");
+	VERBOSE_ASSERT(bssap_clear_sent, == true, "%d");
+	bss_sends_clear_complete();
+	EXPECT_CONN_COUNT(0);
+
+	clear_vlr();
+	comment_end();
+}
+
+static void test_hlr_no_insert_data()
+{
+	comment_start();
+
+	btw("Location Update request causes a GSUP LU request to HLR");
+	lu_result_sent = RES_NONE;
+	gsup_expect_tx("04010809710000004026f0280102");
+	ms_sends_msg("050802008168000130089910070000006402");
+	OSMO_ASSERT(gsup_tx_confirmed);
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("HLR sends only _UPDATE_LOCATION_RESULT, no INSERT DATA");
+	expect_bssap_clear();
+	gsup_rx("06010809710000004026f0", NULL);
+	VERBOSE_ASSERT(bssap_clear_sent, == true, "%d");
+
+	/* TODO should we wait for OSMO_GSUP_MSGT_INSERT_DATA_REQUEST? */
+
+	btw("LU was successful, and the conn has already been closed");
+	VERBOSE_ASSERT(lu_result_sent, == RES_ACCEPT, "%d");
+
+	bss_sends_clear_complete();
+	EXPECT_CONN_COUNT(0);
+	clear_vlr();
+	comment_end();
+}
+
+msc_vlr_test_func_t msc_vlr_tests[] = {
+	test_hlr_rej_auth_info_unknown_imsi,
+	test_hlr_rej_auth_info_net_fail,
+	test_hlr_rej_auth_info_net_fail_reuse_tuples,
+	test_hlr_rej_auth_info_net_fail_no_reuse_tuples,
+	test_hlr_rej_auth_info_unkown_imsi_no_reuse_tuples,
+	test_hlr_acc_but_no_auth_tuples,
+	test_hlr_rej_lu,
+	test_hlr_no_insert_data,
+	NULL
+};
diff --git a/tests/msc_vlr/msc_vlr_test_hlr_reject.err b/tests/msc_vlr/msc_vlr_test_hlr_reject.err
new file mode 100644
index 0000000..505a3b4
--- /dev/null
+++ b/tests/msc_vlr/msc_vlr_test_hlr_reject.err
@@ -0,0 +1,1220 @@
+full talloc report on 'msgb' (total      0 bytes in   1 blocks)
+talloc_total_blocks(tall_bsc_ctx) == 12
+
+===== test_hlr_rej_auth_info_unknown_imsi
+- Location Update request causes a GSUP Send Auth Info request to HLR
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8)
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Updated ID
+DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000004620 type=IMSI ATTACH
+DMM LU/new-LAC: 1/23
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Allocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: is child of Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: rev=GSM net=GERAN Auth (no Ciph)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA
+DREF VLR subscr unknown usage increases to: 1
+DVLR set IMSI on subscriber; IMSI=901700000004620 id=901700000004620
+DVLR New subscr, IMSI: 901700000004620
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DREF VLR subscr IMSI:901700000004620 usage decreases to: 1
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Allocated
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
+DVLR GSUP tx: 08010809710000004026f0
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f0
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF IMSI:901700000004620: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  lu_result_sent == 0
+- HLR sends _SEND_AUTH_INFO_ERROR = unknown IMSI
+<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_ERROR: 09010809710000004026f0020102
+DVLR GSUP rx 14: 09010809710000004026f0020102
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: Received Event VLR_AUTH_E_HLR_SAI_NACK
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: GSUP: rx Auth Info Error cause: 2: IMSI unknown in HLR
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: Authentication terminating with result IMSI unknown in HLR
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: state_chg to VLR_SUB_AS_AUTH_FAILED
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_AUTH_FAILED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_AUTH_FAILED}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_AUTH_FAILED}: Freeing instance
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_AUTH_FAILED}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES
+- sending LU Reject for IMSI:901700000004620, cause 2
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_DONE
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_CN_CLOSE
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF IMSI:901700000004620: MSC conn use + release == 1 (0x100: release)
+DREF VLR subscr IMSI:901700000004620 usage increases to: 3
+DREF VLR subscr IMSI:901700000004620 usage decreases to: 2
+- BSSAP Clear --RAN_GERAN_A--> MS
+DREF VLR subscr IMSI:901700000004620 usage decreases to: 1
+<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_ERROR: vlr_gsupc_read_cb() returns 0
+  auth_request_sent == 0
+  lu_result_sent == 2
+  bssap_clear_sent == 1
+- BSS sends BSSMAP Clear Complete
+DREF IMSI:901700000004620: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Freeing instance
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Deallocated
+DRLL IMSI:901700000004620: Freeing subscriber connection
+DREF VLR subscr IMSI:901700000004620 usage decreases to: 0
+DREF freeing VLR subscr IMSI:901700000004620
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 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) == 12
+
+===== test_hlr_rej_auth_info_net_fail
+- Location Update request causes a GSUP Send Auth Info request to HLR
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8)
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Updated ID
+DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000004620 type=IMSI ATTACH
+DMM LU/new-LAC: 1/23
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Allocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: is child of Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: rev=GSM net=GERAN Auth (no Ciph)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA
+DREF VLR subscr unknown usage increases to: 1
+DVLR set IMSI on subscriber; IMSI=901700000004620 id=901700000004620
+DVLR New subscr, IMSI: 901700000004620
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DREF VLR subscr IMSI:901700000004620 usage decreases to: 1
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Allocated
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
+DVLR GSUP tx: 08010809710000004026f0
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f0
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF IMSI:901700000004620: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  lu_result_sent == 0
+- HLR sends _SEND_AUTH_INFO_ERROR = net fail
+<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_ERROR: 09010809710000004026f0020111
+DVLR GSUP rx 14: 09010809710000004026f0020111
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: Received Event VLR_AUTH_E_HLR_SAI_NACK
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: GSUP: rx Auth Info Error cause: 17: Network failure
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: Authentication terminating with result Network failure
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: state_chg to VLR_SUB_AS_AUTH_FAILED
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_AUTH_FAILED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_AUTH_FAILED}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_AUTH_FAILED}: Freeing instance
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_AUTH_FAILED}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES
+- sending LU Reject for IMSI:901700000004620, cause 17
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_DONE
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_CN_CLOSE
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF IMSI:901700000004620: MSC conn use + release == 1 (0x100: release)
+DREF VLR subscr IMSI:901700000004620 usage increases to: 3
+DREF VLR subscr IMSI:901700000004620 usage decreases to: 2
+- BSSAP Clear --RAN_GERAN_A--> MS
+DREF VLR subscr IMSI:901700000004620 usage decreases to: 1
+<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_ERROR: vlr_gsupc_read_cb() returns 0
+  auth_request_sent == 0
+  lu_result_sent == 2
+  bssap_clear_sent == 1
+- BSS sends BSSMAP Clear Complete
+DREF IMSI:901700000004620: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Freeing instance
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Deallocated
+DRLL IMSI:901700000004620: Freeing subscriber connection
+DREF VLR subscr IMSI:901700000004620 usage decreases to: 0
+DREF freeing VLR subscr IMSI:901700000004620
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 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) == 12
+
+===== test_hlr_rej_auth_info_net_fail_reuse_tuples
+---
+- Submit a used auth tuple in the VLR
+- Location Update request causes a GSUP Send Auth Info request to HLR
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8)
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Updated ID
+DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000004620 type=IMSI ATTACH
+DMM LU/new-LAC: 1/23
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Allocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: is child of Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: rev=GSM net=GERAN Auth (no Ciph)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA
+DREF VLR subscr unknown usage increases to: 1
+DVLR set IMSI on subscriber; IMSI=901700000004620 id=901700000004620
+DVLR New subscr, IMSI: 901700000004620
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DREF VLR subscr IMSI:901700000004620 usage decreases to: 1
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Allocated
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
+DVLR GSUP tx: 08010809710000004026f0
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f0
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF IMSI:901700000004620: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  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: 0a010809710000004026f003222010585df1ae287f6e273dce07090d61320b21042d8b2c3e220861855fb81fc2a800
+DVLR GSUP rx 47: 0a010809710000004026f003222010585df1ae287f6e273dce07090d61320b21042d8b2c3e220861855fb81fc2a800
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: Received Event VLR_AUTH_E_HLR_SAI_ACK
+DVLR SUBSCR(IMSI:901700000004620) Received 1 auth tuples
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: state_chg to VLR_SUB_AS_WAIT_RESP
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_WAIT_RESP}: got auth tuple: use_count=1 key_seq=0 -- will use GSM AKA (is_r99=no, at->vec.auth_types=0x1)
+- sending GSM Auth Request for IMSI:901700000004620: tuple use_count=1 key_seq=0 auth_types=0x1 and...
+- ...rand=585df1ae287f6e273dce07090d61320b
+- ...expecting sres=2d8b2c3e
+DREF VLR subscr IMSI:901700000004620 usage decreases to: 1
+<-- 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
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_AUTH_RESP
+DREF IMSI:901700000004620: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14)
+DMM IMSI:901700000004620: MM GSM AUTHENTICATION RESPONSE (sres = 2d8b2c3e)
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP
+DVLR SUBSCR(IMSI:901700000004620) AUTH on GERAN received SRES/RES: 2d8b2c3e (4 bytes)
+DVLR SUBSCR(IMSI:901700000004620) AUTH established GSM security context
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result PASSED
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_AUTHENTICATED}: Freeing instance
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_AUTHENTICATED}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_ciph()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_node_4()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: Allocated
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START
+DVLR GSUP tx: 04010809710000004026f0280102
+GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000004026f0280102
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA
+DREF IMSI:901700000004620: MSC conn use - dtap == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  lu_result_sent == 0
+- HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT
+<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: 10010809710000004026f00804036470f1
+DVLR GSUP rx 17: 10010809710000004026f00804036470f1
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DVLR IMSI:901700000004620 has MSISDN:46071
+DVLR SUBSCR(MSISDN:46071) VLR: update for IMSI=901700000004620 (MSISDN=46071, used=2)
+DVLR GSUP tx: 12010809710000004026f0
+GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000004026f0
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+<-- 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: 06010809710000004026f0
+DVLR GSUP rx 11: 06010809710000004026f0
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Freeing instance
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: Allocated
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: Allocated
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(LU:901700000004620)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(LU:901700000004620)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Freeing instance
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Deallocated
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL
+- sending LU Accept for MSISDN:46071
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_DONE
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Freeing instance
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_ACCEPTED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:46071: MSC conn use + release == 1 (0x100: release)
+DREF VLR subscr MSISDN:46071 usage increases to: 4
+DREF VLR subscr MSISDN:46071 usage decreases to: 3
+- BSSAP Clear --RAN_GERAN_A--> MS
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+<-- 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
+  lu_result_sent == 1
+- BSS sends BSSMAP Clear Complete
+DREF MSISDN:46071: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Freeing instance
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Deallocated
+DRLL MSISDN:46071: Freeing subscriber connection
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+---
+- Now one auth tuple is available, but used.
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+  vsub->last_tuple->use_count == 1
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+---
+- Another LU wants to get new tuples; even though HLR sends Network Failure, we are reusing the old tuples.
+- Location Update request causes a GSUP Send Auth Info request to HLR
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8)
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Updated ID
+DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000004620 type=IMSI ATTACH
+DMM LU/new-LAC: 1/23
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Allocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: is child of Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: rev=GSM net=GERAN Auth (no Ciph)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Allocated
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
+DVLR GSUP tx: 08010809710000004026f0
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f0
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF MSISDN:46071: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  lu_result_sent == 0
+- HLR sends _SEND_AUTH_INFO_ERROR = net fail
+<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_ERROR: 09010809710000004026f0020111
+DVLR GSUP rx 14: 09010809710000004026f0020111
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: Received Event VLR_AUTH_E_HLR_SAI_NACK
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: GSUP: rx Auth Info Error cause: 17: Network failure
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: state_chg to VLR_SUB_AS_WAIT_RESP
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_WAIT_RESP}: got auth tuple: use_count=2 key_seq=0 -- will use GSM AKA (is_r99=no, at->vec.auth_types=0x1)
+- sending GSM Auth Request for MSISDN:46071: tuple use_count=2 key_seq=0 auth_types=0x1 and...
+- ...rand=585df1ae287f6e273dce07090d61320b
+- ...expecting sres=2d8b2c3e
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_ERROR: 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
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_AUTH_RESP
+DREF MSISDN:46071: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14)
+DMM MSISDN:46071: MM GSM AUTHENTICATION RESPONSE (sres = 2d8b2c3e)
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP
+DVLR SUBSCR(MSISDN:46071) AUTH on GERAN received SRES/RES: 2d8b2c3e (4 bytes)
+DVLR SUBSCR(MSISDN:46071) AUTH established GSM security context
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result PASSED
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_AUTHENTICATED}: Freeing instance
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_AUTHENTICATED}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_ciph()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_node_4()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: Allocated
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START
+DVLR GSUP tx: 04010809710000004026f0280102
+GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000004026f0280102
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA
+DREF MSISDN:46071: MSC conn use - dtap == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  lu_result_sent == 0
+- HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT
+<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: 10010809710000004026f00804036470f1
+DVLR GSUP rx 17: 10010809710000004026f00804036470f1
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DVLR IMSI:901700000004620 has MSISDN:46071
+DVLR SUBSCR(MSISDN:46071) VLR: update for IMSI=901700000004620 (MSISDN=46071, used=3)
+DVLR GSUP tx: 12010809710000004026f0
+GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000004026f0
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+<-- 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: 06010809710000004026f0
+DVLR GSUP rx 11: 06010809710000004026f0
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Freeing instance
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: Allocated
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: Allocated
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(LU:901700000004620)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(LU:901700000004620)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Freeing instance
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Deallocated
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL
+- sending LU Accept for MSISDN:46071
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_DONE
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Freeing instance
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_ACCEPTED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:46071: MSC conn use + release == 1 (0x100: release)
+DREF VLR subscr MSISDN:46071 usage increases to: 4
+DREF VLR subscr MSISDN:46071 usage decreases to: 3
+- BSSAP Clear --RAN_GERAN_A--> MS
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+<-- 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
+  lu_result_sent == 1
+- BSS sends BSSMAP Clear Complete
+DREF MSISDN:46071: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Freeing instance
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Deallocated
+DRLL MSISDN:46071: Freeing subscriber connection
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+DREF freeing VLR subscr MSISDN:46071
+===== 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) == 12
+
+===== test_hlr_rej_auth_info_net_fail_no_reuse_tuples
+---
+- Submit a used auth tuple in the VLR
+- Location Update request causes a GSUP Send Auth Info request to HLR
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8)
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Updated ID
+DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000004620 type=IMSI ATTACH
+DMM LU/new-LAC: 1/23
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Allocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: is child of Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: rev=GSM net=GERAN Auth (no Ciph)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA
+DREF VLR subscr unknown usage increases to: 1
+DVLR set IMSI on subscriber; IMSI=901700000004620 id=901700000004620
+DVLR New subscr, IMSI: 901700000004620
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DREF VLR subscr IMSI:901700000004620 usage decreases to: 1
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Allocated
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
+DVLR GSUP tx: 08010809710000004026f0
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f0
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF IMSI:901700000004620: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  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: 0a010809710000004026f003222010585df1ae287f6e273dce07090d61320b21042d8b2c3e220861855fb81fc2a800
+DVLR GSUP rx 47: 0a010809710000004026f003222010585df1ae287f6e273dce07090d61320b21042d8b2c3e220861855fb81fc2a800
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: Received Event VLR_AUTH_E_HLR_SAI_ACK
+DVLR SUBSCR(IMSI:901700000004620) Received 1 auth tuples
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: state_chg to VLR_SUB_AS_WAIT_RESP
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_WAIT_RESP}: got auth tuple: use_count=1 key_seq=0 -- will use GSM AKA (is_r99=no, at->vec.auth_types=0x1)
+- sending GSM Auth Request for IMSI:901700000004620: tuple use_count=1 key_seq=0 auth_types=0x1 and...
+- ...rand=585df1ae287f6e273dce07090d61320b
+- ...expecting sres=2d8b2c3e
+DREF VLR subscr IMSI:901700000004620 usage decreases to: 1
+<-- 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
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_AUTH_RESP
+DREF IMSI:901700000004620: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14)
+DMM IMSI:901700000004620: MM GSM AUTHENTICATION RESPONSE (sres = 2d8b2c3e)
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP
+DVLR SUBSCR(IMSI:901700000004620) AUTH on GERAN received SRES/RES: 2d8b2c3e (4 bytes)
+DVLR SUBSCR(IMSI:901700000004620) AUTH established GSM security context
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result PASSED
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_AUTHENTICATED}: Freeing instance
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_AUTHENTICATED}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_ciph()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_node_4()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: Allocated
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START
+DVLR GSUP tx: 04010809710000004026f0280102
+GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000004026f0280102
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA
+DREF IMSI:901700000004620: MSC conn use - dtap == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  lu_result_sent == 0
+- HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT
+<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: 10010809710000004026f00804036470f1
+DVLR GSUP rx 17: 10010809710000004026f00804036470f1
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DVLR IMSI:901700000004620 has MSISDN:46071
+DVLR SUBSCR(MSISDN:46071) VLR: update for IMSI=901700000004620 (MSISDN=46071, used=2)
+DVLR GSUP tx: 12010809710000004026f0
+GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000004026f0
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+<-- 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: 06010809710000004026f0
+DVLR GSUP rx 11: 06010809710000004026f0
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Freeing instance
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: Allocated
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: Allocated
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(LU:901700000004620)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(LU:901700000004620)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Freeing instance
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Deallocated
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL
+- sending LU Accept for MSISDN:46071
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_DONE
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Freeing instance
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_ACCEPTED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:46071: MSC conn use + release == 1 (0x100: release)
+DREF VLR subscr MSISDN:46071 usage increases to: 4
+DREF VLR subscr MSISDN:46071 usage decreases to: 3
+- BSSAP Clear --RAN_GERAN_A--> MS
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+<-- 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
+  lu_result_sent == 1
+- BSS sends BSSMAP Clear Complete
+DREF MSISDN:46071: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Freeing instance
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Deallocated
+DRLL MSISDN:46071: Freeing subscriber connection
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+---
+- Now one auth tuple is available, but used.
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+  vsub->last_tuple->use_count == 1
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+---
+- Another LU wants to get new tuples; HLR sends Network Failure, we reject.
+- Location Update request causes a GSUP Send Auth Info request to HLR
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8)
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Updated ID
+DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000004620 type=IMSI ATTACH
+DMM LU/new-LAC: 1/23
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Allocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: is child of Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: rev=GSM net=GERAN Auth (no Ciph)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Allocated
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
+DVLR GSUP tx: 08010809710000004026f0
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f0
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF MSISDN:46071: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  lu_result_sent == 0
+- HLR sends _SEND_AUTH_INFO_ERROR = net fail
+<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_ERROR: 09010809710000004026f0020111
+DVLR GSUP rx 14: 09010809710000004026f0020111
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: Received Event VLR_AUTH_E_HLR_SAI_NACK
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: GSUP: rx Auth Info Error cause: 17: Network failure
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: Authentication terminating with result Network failure
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: state_chg to VLR_SUB_AS_AUTH_FAILED
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_AUTH_FAILED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_AUTH_FAILED}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_AUTH_FAILED}: Freeing instance
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_AUTH_FAILED}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES
+- sending LU Reject for MSISDN:46071, cause 17
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_DONE
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_CN_CLOSE
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:46071: MSC conn use + release == 1 (0x100: release)
+DREF VLR subscr MSISDN:46071 usage increases to: 4
+DREF VLR subscr MSISDN:46071 usage decreases to: 3
+- BSSAP Clear --RAN_GERAN_A--> MS
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_ERROR: vlr_gsupc_read_cb() returns 0
+  auth_request_sent == 0
+  lu_result_sent == 2
+  bssap_clear_sent == 1
+- BSS sends BSSMAP Clear Complete
+DREF MSISDN:46071: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Freeing instance
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Deallocated
+DRLL MSISDN:46071: Freeing subscriber connection
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+DREF freeing VLR subscr MSISDN:46071
+===== 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) == 12
+
+===== test_hlr_rej_auth_info_unkown_imsi_no_reuse_tuples
+---
+- Submit a used auth tuple in the VLR
+- Location Update request causes a GSUP Send Auth Info request to HLR
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8)
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Updated ID
+DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000004620 type=IMSI ATTACH
+DMM LU/new-LAC: 1/23
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Allocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: is child of Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: rev=GSM net=GERAN Auth (no Ciph)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA
+DREF VLR subscr unknown usage increases to: 1
+DVLR set IMSI on subscriber; IMSI=901700000004620 id=901700000004620
+DVLR New subscr, IMSI: 901700000004620
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DREF VLR subscr IMSI:901700000004620 usage decreases to: 1
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Allocated
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
+DVLR GSUP tx: 08010809710000004026f0
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f0
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF IMSI:901700000004620: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  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: 0a010809710000004026f003222010585df1ae287f6e273dce07090d61320b21042d8b2c3e220861855fb81fc2a800
+DVLR GSUP rx 47: 0a010809710000004026f003222010585df1ae287f6e273dce07090d61320b21042d8b2c3e220861855fb81fc2a800
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: Received Event VLR_AUTH_E_HLR_SAI_ACK
+DVLR SUBSCR(IMSI:901700000004620) Received 1 auth tuples
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: state_chg to VLR_SUB_AS_WAIT_RESP
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_WAIT_RESP}: got auth tuple: use_count=1 key_seq=0 -- will use GSM AKA (is_r99=no, at->vec.auth_types=0x1)
+- sending GSM Auth Request for IMSI:901700000004620: tuple use_count=1 key_seq=0 auth_types=0x1 and...
+- ...rand=585df1ae287f6e273dce07090d61320b
+- ...expecting sres=2d8b2c3e
+DREF VLR subscr IMSI:901700000004620 usage decreases to: 1
+<-- 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
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_AUTH_RESP
+DREF IMSI:901700000004620: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14)
+DMM IMSI:901700000004620: MM GSM AUTHENTICATION RESPONSE (sres = 2d8b2c3e)
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP
+DVLR SUBSCR(IMSI:901700000004620) AUTH on GERAN received SRES/RES: 2d8b2c3e (4 bytes)
+DVLR SUBSCR(IMSI:901700000004620) AUTH established GSM security context
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result PASSED
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_AUTHENTICATED}: Freeing instance
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_AUTHENTICATED}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_ciph()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_node_4()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: Allocated
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START
+DVLR GSUP tx: 04010809710000004026f0280102
+GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000004026f0280102
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA
+DREF IMSI:901700000004620: MSC conn use - dtap == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  lu_result_sent == 0
+- HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT
+<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: 10010809710000004026f00804036470f1
+DVLR GSUP rx 17: 10010809710000004026f00804036470f1
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DVLR IMSI:901700000004620 has MSISDN:46071
+DVLR SUBSCR(MSISDN:46071) VLR: update for IMSI=901700000004620 (MSISDN=46071, used=2)
+DVLR GSUP tx: 12010809710000004026f0
+GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000004026f0
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+<-- 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: 06010809710000004026f0
+DVLR GSUP rx 11: 06010809710000004026f0
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Freeing instance
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: Allocated
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: Allocated
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(LU:901700000004620)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(LU:901700000004620)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Freeing instance
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Deallocated
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL
+- sending LU Accept for MSISDN:46071
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_DONE
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Freeing instance
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_ACCEPTED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:46071: MSC conn use + release == 1 (0x100: release)
+DREF VLR subscr MSISDN:46071 usage increases to: 4
+DREF VLR subscr MSISDN:46071 usage decreases to: 3
+- BSSAP Clear --RAN_GERAN_A--> MS
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+<-- 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
+  lu_result_sent == 1
+- BSS sends BSSMAP Clear Complete
+DREF MSISDN:46071: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Freeing instance
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Deallocated
+DRLL MSISDN:46071: Freeing subscriber connection
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+---
+- Now one auth tuple is available, but used.
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+  vsub->last_tuple->use_count == 1
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+---
+- Another LU wants to get new tuples; HLR sends IMSI Unknown. Even though we would re-use an old tuple, reject the unknown IMSI.
+  net->vlr->cfg.auth_reuse_old_sets_on_error == 1
+- Location Update request causes a GSUP Send Auth Info request to HLR
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8)
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Updated ID
+DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000004620 type=IMSI ATTACH
+DMM LU/new-LAC: 1/23
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Allocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: is child of Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: rev=GSM net=GERAN Auth (no Ciph)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Allocated
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
+DVLR GSUP tx: 08010809710000004026f0
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f0
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF MSISDN:46071: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  lu_result_sent == 0
+- HLR sends _SEND_AUTH_INFO_ERROR = unknown IMSI
+<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_ERROR: 09010809710000004026f0020102
+DVLR GSUP rx 14: 09010809710000004026f0020102
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: Received Event VLR_AUTH_E_HLR_SAI_NACK
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: GSUP: rx Auth Info Error cause: 2: IMSI unknown in HLR
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: Authentication terminating with result IMSI unknown in HLR
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: state_chg to VLR_SUB_AS_AUTH_FAILED
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_AUTH_FAILED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_AUTH_FAILED}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_AUTH_FAILED}: Freeing instance
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_AUTH_FAILED}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES
+- sending LU Reject for MSISDN:46071, cause 2
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_DONE
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_CN_CLOSE
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:46071: MSC conn use + release == 1 (0x100: release)
+DREF VLR subscr MSISDN:46071 usage increases to: 4
+DREF VLR subscr MSISDN:46071 usage decreases to: 3
+- BSSAP Clear --RAN_GERAN_A--> MS
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_ERROR: vlr_gsupc_read_cb() returns 0
+  auth_request_sent == 0
+  lu_result_sent == 2
+  bssap_clear_sent == 1
+- BSS sends BSSMAP Clear Complete
+DREF MSISDN:46071: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Freeing instance
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Deallocated
+DRLL MSISDN:46071: Freeing subscriber connection
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+DREF freeing VLR subscr MSISDN:46071
+===== 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) == 12
+
+===== test_hlr_acc_but_no_auth_tuples
+- Location Update request causes a GSUP Send Auth Info request to HLR
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8)
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Updated ID
+DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000004620 type=IMSI ATTACH
+DMM LU/new-LAC: 1/23
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Allocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: is child of Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: rev=GSM net=GERAN Auth (no Ciph)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA
+DREF VLR subscr unknown usage increases to: 1
+DVLR set IMSI on subscriber; IMSI=901700000004620 id=901700000004620
+DVLR New subscr, IMSI: 901700000004620
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DREF VLR subscr IMSI:901700000004620 usage decreases to: 1
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Allocated
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
+DVLR GSUP tx: 08010809710000004026f0
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f0
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF IMSI:901700000004620: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  lu_result_sent == 0
+- from HLR, rx _SEND_AUTH_INFO_RESULT but it lacks auth tuples
+<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT: 0a010809710000004026f0
+DVLR GSUP rx 11: 0a010809710000004026f0
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: Received Event VLR_AUTH_E_HLR_SAI_ACK
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: Authentication terminating with result Network failure
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: state_chg to VLR_SUB_AS_AUTH_FAILED
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_AUTH_FAILED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_AUTH_FAILED}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_AUTH_FAILED}: Freeing instance
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_AUTH_FAILED}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES
+- sending LU Reject for IMSI:901700000004620, cause 17
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_DONE
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_CN_CLOSE
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF IMSI:901700000004620: MSC conn use + release == 1 (0x100: release)
+DREF VLR subscr IMSI:901700000004620 usage increases to: 3
+DREF VLR subscr IMSI:901700000004620 usage decreases to: 2
+- BSSAP Clear --RAN_GERAN_A--> MS
+DREF VLR subscr IMSI:901700000004620 usage decreases to: 1
+<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT: vlr_gsupc_read_cb() returns 0
+  auth_request_sent == 0
+  lu_result_sent == 2
+  bssap_clear_sent == 1
+- BSS sends BSSMAP Clear Complete
+DREF IMSI:901700000004620: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Freeing instance
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Deallocated
+DRLL IMSI:901700000004620: Freeing subscriber connection
+DREF VLR subscr IMSI:901700000004620 usage decreases to: 0
+DREF freeing VLR subscr IMSI:901700000004620
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 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) == 12
+
+===== test_hlr_rej_lu
+- Location Update request causes a GSUP LU request to HLR
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8)
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Updated ID
+DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000004620 type=IMSI ATTACH
+DMM LU/new-LAC: 1/23
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Allocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: is child of Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: rev=GSM net=GERAN (no Auth)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA
+DREF VLR subscr unknown usage increases to: 1
+DVLR set IMSI on subscriber; IMSI=901700000004620 id=901700000004620
+DVLR New subscr, IMSI: 901700000004620
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DREF VLR subscr IMSI:901700000004620 usage decreases to: 1
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_post_auth()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_post_ciph()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node_4()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: Allocated
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START
+DVLR GSUP tx: 04010809710000004026f0280102
+GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000004026f0280102
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF IMSI:901700000004620: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  lu_result_sent == 0
+- HLR sends UPDATE_LOCATION_ERROR
+<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_ERROR: 05010809710000004026f0020102
+DVLR GSUP rx 14: 05010809710000004026f0020102
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DVLR SUBSCR(IMSI:901700000004620) UpdateLocation failed; gmm_cause: IMSI unknown in HLR
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_NACK
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Freeing instance
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL
+- sending LU Reject for IMSI:901700000004620, cause 2
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_DONE
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_CN_CLOSE
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF IMSI:901700000004620: MSC conn use + release == 1 (0x100: release)
+DREF VLR subscr IMSI:901700000004620 usage increases to: 3
+DREF VLR subscr IMSI:901700000004620 usage decreases to: 2
+- BSSAP Clear --RAN_GERAN_A--> MS
+DREF VLR subscr IMSI:901700000004620 usage decreases to: 1
+<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_ERROR: vlr_gsupc_read_cb() returns 0
+  lu_result_sent == 2
+  bssap_clear_sent == 1
+- BSS sends BSSMAP Clear Complete
+DREF IMSI:901700000004620: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Freeing instance
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Deallocated
+DRLL IMSI:901700000004620: Freeing subscriber connection
+DREF VLR subscr IMSI:901700000004620 usage decreases to: 0
+DREF freeing VLR subscr IMSI:901700000004620
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+===== test_hlr_rej_lu: SUCCESS
+
+full talloc report on 'msgb' (total      0 bytes in   1 blocks)
+talloc_total_blocks(tall_bsc_ctx) == 12
+
+===== test_hlr_no_insert_data
+- Location Update request causes a GSUP LU request to HLR
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8)
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Updated ID
+DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000004620 type=IMSI ATTACH
+DMM LU/new-LAC: 1/23
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Allocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: is child of Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: rev=GSM net=GERAN (no Auth)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA
+DREF VLR subscr unknown usage increases to: 1
+DVLR set IMSI on subscriber; IMSI=901700000004620 id=901700000004620
+DVLR New subscr, IMSI: 901700000004620
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DREF VLR subscr IMSI:901700000004620 usage decreases to: 1
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_post_auth()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_post_ciph()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node_4()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: Allocated
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START
+DVLR GSUP tx: 04010809710000004026f0280102
+GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000004026f0280102
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF IMSI:901700000004620: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  lu_result_sent == 0
+- HLR sends only _UPDATE_LOCATION_RESULT, no INSERT DATA
+<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: 06010809710000004026f0
+DVLR GSUP rx 11: 06010809710000004026f0
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Freeing instance
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: Allocated
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: Allocated
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(LU:901700000004620)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(LU:901700000004620)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Freeing instance
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Deallocated
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL
+- sending LU Accept for IMSI:901700000004620
+DREF VLR subscr IMSI:901700000004620 usage increases to: 3
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_DONE
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Freeing instance
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_ACCEPTED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF IMSI:901700000004620: MSC conn use + release == 1 (0x100: release)
+DREF VLR subscr IMSI:901700000004620 usage increases to: 4
+DREF VLR subscr IMSI:901700000004620 usage decreases to: 3
+- BSSAP Clear --RAN_GERAN_A--> MS
+DREF VLR subscr IMSI:901700000004620 usage decreases to: 2
+<-- 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
+  lu_result_sent == 1
+- BSS sends BSSMAP Clear Complete
+DREF IMSI:901700000004620: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Freeing instance
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Deallocated
+DRLL IMSI:901700000004620: Freeing subscriber connection
+DREF VLR subscr IMSI:901700000004620 usage decreases to: 1
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+DREF freeing VLR subscr IMSI:901700000004620
+===== test_hlr_no_insert_data: SUCCESS
+
+full talloc report on 'msgb' (total      0 bytes in   1 blocks)
+talloc_total_blocks(tall_bsc_ctx) == 12
+
+full talloc report on 'msgb' (total      0 bytes in   1 blocks)
+talloc_total_blocks(tall_bsc_ctx) == 12
+
diff --git a/tests/msc_vlr/msc_vlr_test_hlr_reject.ok b/tests/msc_vlr/msc_vlr_test_hlr_reject.ok
new file mode 100644
index 0000000..a965a70
--- /dev/null
+++ b/tests/msc_vlr/msc_vlr_test_hlr_reject.ok
@@ -0,0 +1 @@
+Done
diff --git a/tests/msc_vlr/msc_vlr_test_hlr_timeout.c b/tests/msc_vlr/msc_vlr_test_hlr_timeout.c
new file mode 100644
index 0000000..a237695
--- /dev/null
+++ b/tests/msc_vlr/msc_vlr_test_hlr_timeout.c
@@ -0,0 +1,120 @@
+/* Osmocom MSC+VLR end-to-end tests */
+
+/* (C) 2017 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>
+ *
+ * All Rights Reserved
+ *
+ * Author: Neels Hofmeyr <nhofmeyr@sysmocom.de>
+ *
+ * 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 "msc_vlr_tests.h"
+
+#include <osmocom/core/logging.h>
+
+static void test_hlr_timeout_lu_auth_info()
+{
+	comment_start();
+
+	fake_time_start();
+
+	net->authentication_required = true;
+
+	btw("Location Update request causes a GSUP Send Auth Info request to HLR");
+	lu_result_sent = RES_NONE;
+	gsup_expect_tx("08010809710000004026f0");
+	ms_sends_msg("050802008168000130089910070000006402");
+	OSMO_ASSERT(gsup_tx_confirmed);
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	BTW("HLR never replies");
+
+	btw("At first, we're still waiting");
+	fake_time_passes(0, 423);
+	EXPECT_CONN_COUNT(1);
+	fake_time_passes(1, 235);
+	EXPECT_CONN_COUNT(1);
+	fake_time_passes(1, 235);
+	EXPECT_CONN_COUNT(1);
+	fake_time_passes(1, 235);
+	EXPECT_CONN_COUNT(1);
+	fake_time_passes(1, 235);
+	EXPECT_CONN_COUNT(1);
+	expect_bssap_clear();
+	fake_time_passes(1, 235);
+	btw("SUBSCR_CONN_TIMEOUT has passed, conn is gone.");
+	VERBOSE_ASSERT(bssap_clear_sent, == true, "%d");
+	bss_sends_clear_complete();
+	EXPECT_CONN_COUNT(0);
+	VERBOSE_ASSERT(lu_result_sent, == RES_REJECT, "%d");
+
+	clear_vlr();
+	comment_end();
+}
+
+static void test_hlr_timeout_lu_upd_loc_result()
+{
+	comment_start();
+
+	fake_time_start();
+
+	btw("Location Update request causes a GSUP LU request to HLR");
+	lu_result_sent = RES_NONE;
+	gsup_expect_tx("04010809710000004026f0280102");
+	ms_sends_msg("050802008168000130089910070000006402");
+	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("10010809710000004026f00804036470f1",
+		"12010809710000004026f0");
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	BTW("HLR never sends GSUP _UPDATE_LOCATION_RESULT");
+
+	btw("At first, we're still waiting");
+	fake_time_passes(0, 423);
+	EXPECT_CONN_COUNT(1);
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+	fake_time_passes(1, 235);
+	EXPECT_CONN_COUNT(1);
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+	fake_time_passes(1, 235);
+	EXPECT_CONN_COUNT(1);
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+	fake_time_passes(1, 235);
+	EXPECT_CONN_COUNT(1);
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+	fake_time_passes(1, 235);
+	EXPECT_CONN_COUNT(1);
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+	expect_bssap_clear();
+	fake_time_passes(1, 235);
+	btw("SUBSCR_CONN_TIMEOUT has passed, conn is gone.");
+	VERBOSE_ASSERT(bssap_clear_sent, == true, "%d");
+	bss_sends_clear_complete();
+	EXPECT_CONN_COUNT(0);
+	VERBOSE_ASSERT(lu_result_sent, == RES_REJECT, "%d");
+
+	clear_vlr();
+	comment_end();
+}
+
+msc_vlr_test_func_t msc_vlr_tests[] = {
+	test_hlr_timeout_lu_auth_info,
+	test_hlr_timeout_lu_upd_loc_result,
+	NULL
+};
diff --git a/tests/msc_vlr/msc_vlr_test_hlr_timeout.err b/tests/msc_vlr/msc_vlr_test_hlr_timeout.err
new file mode 100644
index 0000000..c6cbeab
--- /dev/null
+++ b/tests/msc_vlr/msc_vlr_test_hlr_timeout.err
@@ -0,0 +1,201 @@
+full talloc report on 'msgb' (total      0 bytes in   1 blocks)
+talloc_total_blocks(tall_bsc_ctx) == 12
+
+===== test_hlr_timeout_lu_auth_info
+- Total time passed: 0.000000 s
+- Location Update request causes a GSUP Send Auth Info request to HLR
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8)
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Updated ID
+DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000004620 type=IMSI ATTACH
+DMM LU/new-LAC: 1/23
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Allocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: is child of Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: rev=GSM net=GERAN Auth (no Ciph)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA
+DREF VLR subscr unknown usage increases to: 1
+DVLR set IMSI on subscriber; IMSI=901700000004620 id=901700000004620
+DVLR New subscr, IMSI: 901700000004620
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DREF VLR subscr IMSI:901700000004620 usage decreases to: 1
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Allocated
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
+DVLR GSUP tx: 08010809710000004026f0
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f0
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF IMSI:901700000004620: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  lu_result_sent == 0
+---
+- HLR never replies
+- At first, we're still waiting
+- Total time passed: 0.000423 s
+  llist_count(&net->subscr_conns) == 1
+- Total time passed: 1.000658 s
+  llist_count(&net->subscr_conns) == 1
+- Total time passed: 2.000893 s
+  llist_count(&net->subscr_conns) == 1
+- Total time passed: 3.001128 s
+  llist_count(&net->subscr_conns) == 1
+- Total time passed: 4.001363 s
+  llist_count(&net->subscr_conns) == 1
+- Total time passed: 5.001598 s
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Timeout of T0
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_CN_CLOSE
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Close event, cause: CONGESTION
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF IMSI:901700000004620: MSC conn use + release == 1 (0x100: release)
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+- sending LU Reject for IMSI:901700000004620, cause 22
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_DONE
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_CN_CLOSE
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: Event SUBSCR_CONN_E_CN_CLOSE not permitted
+DREF VLR subscr IMSI:901700000004620 usage decreases to: 1
+- BSSAP Clear --RAN_GERAN_A--> MS
+- SUBSCR_CONN_TIMEOUT has passed, conn is gone.
+  bssap_clear_sent == 1
+- BSS sends BSSMAP Clear Complete
+DREF IMSI:901700000004620: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: Freeing instance
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Freeing instance
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Deallocated
+DRLL IMSI:901700000004620: Freeing subscriber connection
+DREF VLR subscr IMSI:901700000004620 usage decreases to: 0
+DREF freeing VLR subscr IMSI:901700000004620
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+  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) == 12
+
+===== test_hlr_timeout_lu_upd_loc_result
+- Total time passed: 0.000000 s
+- Location Update request causes a GSUP LU request to HLR
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8)
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Updated ID
+DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000004620 type=IMSI ATTACH
+DMM LU/new-LAC: 1/23
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Allocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: is child of Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: rev=GSM net=GERAN (no Auth)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA
+DREF VLR subscr unknown usage increases to: 1
+DVLR set IMSI on subscriber; IMSI=901700000004620 id=901700000004620
+DVLR New subscr, IMSI: 901700000004620
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DREF VLR subscr IMSI:901700000004620 usage decreases to: 1
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_post_auth()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_post_ciph()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node_4()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: Allocated
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START
+DVLR GSUP tx: 04010809710000004026f0280102
+GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000004026f0280102
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF IMSI:901700000004620: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  lu_result_sent == 0
+- HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT
+<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: 10010809710000004026f00804036470f1
+DVLR GSUP rx 17: 10010809710000004026f00804036470f1
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DVLR IMSI:901700000004620 has MSISDN:46071
+DVLR SUBSCR(MSISDN:46071) VLR: update for IMSI=901700000004620 (MSISDN=46071, used=2)
+DVLR GSUP tx: 12010809710000004026f0
+GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000004026f0
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: vlr_gsupc_read_cb() returns 0
+  lu_result_sent == 0
+---
+- HLR never sends GSUP _UPDATE_LOCATION_RESULT
+- At first, we're still waiting
+- Total time passed: 0.000423 s
+  llist_count(&net->subscr_conns) == 1
+  lu_result_sent == 0
+- Total time passed: 1.000658 s
+  llist_count(&net->subscr_conns) == 1
+  lu_result_sent == 0
+- Total time passed: 2.000893 s
+  llist_count(&net->subscr_conns) == 1
+  lu_result_sent == 0
+- Total time passed: 3.001128 s
+  llist_count(&net->subscr_conns) == 1
+  lu_result_sent == 0
+- Total time passed: 4.001363 s
+  llist_count(&net->subscr_conns) == 1
+  lu_result_sent == 0
+- Total time passed: 5.001598 s
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Timeout of T0
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_CN_CLOSE
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Close event, cause: CONGESTION
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:46071: MSC conn use + release == 1 (0x100: release)
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+- sending LU Reject for MSISDN:46071, cause 22
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_DONE
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_CN_CLOSE
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: Event SUBSCR_CONN_E_CN_CLOSE not permitted
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+- BSSAP Clear --RAN_GERAN_A--> MS
+- SUBSCR_CONN_TIMEOUT has passed, conn is gone.
+  bssap_clear_sent == 1
+- BSS sends BSSMAP Clear Complete
+DREF MSISDN:46071: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Freeing instance
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Freeing instance
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Deallocated
+DRLL MSISDN:46071: Freeing subscriber connection
+DREF VLR subscr MSISDN:46071 usage decreases to: 0
+DREF freeing VLR subscr MSISDN:46071
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+  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) == 12
+
+full talloc report on 'msgb' (total      0 bytes in   1 blocks)
+talloc_total_blocks(tall_bsc_ctx) == 12
+
diff --git a/tests/msc_vlr/msc_vlr_test_hlr_timeout.ok b/tests/msc_vlr/msc_vlr_test_hlr_timeout.ok
new file mode 100644
index 0000000..a965a70
--- /dev/null
+++ b/tests/msc_vlr/msc_vlr_test_hlr_timeout.ok
@@ -0,0 +1 @@
+Done
diff --git a/tests/msc_vlr/msc_vlr_test_ms_timeout.c b/tests/msc_vlr/msc_vlr_test_ms_timeout.c
new file mode 100644
index 0000000..a4851b3
--- /dev/null
+++ b/tests/msc_vlr/msc_vlr_test_ms_timeout.c
@@ -0,0 +1,370 @@
+/* Osmocom MSC+VLR end-to-end tests */
+
+/* (C) 2017 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>
+ *
+ * All Rights Reserved
+ *
+ * Author: Neels Hofmeyr <nhofmeyr@sysmocom.de>
+ *
+ * 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 "msc_vlr_tests.h"
+
+static void test_ms_timeout_lu_auth_resp()
+{
+	comment_start();
+
+	net->authentication_required = true;
+
+	fake_time_start();
+
+	btw("Location Update request causes a GSUP Send Auth Info request to HLR");
+	lu_result_sent = RES_NONE;
+	gsup_expect_tx("08010809710000004026f0");
+	ms_sends_msg("050802008168000130089910070000006402");
+	OSMO_ASSERT(gsup_tx_confirmed);
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("from HLR, rx _SEND_AUTH_INFO_RESULT; VLR sends Auth Req to MS");
+	auth_request_sent = false;
+	auth_request_expect_rand = "585df1ae287f6e273dce07090d61320b";
+	auth_request_expect_autn = NULL;
+	/* Based on a Ki of 000102030405060708090a0b0c0d0e0f */
+	gsup_rx("0a"
+		/* imsi */
+		"0108" "09710000004026f0"
+		/* auth vectors... */
+		/* TL    TL     rand */
+		"0322"  "2010" "585df1ae287f6e273dce07090d61320b"
+		/*       TL     sres       TL     kc */
+			"2104" "2d8b2c3e" "2208" "61855fb81fc2a800"
+		,NULL);
+	VERBOSE_ASSERT(auth_request_sent, == true, "%d");
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	BTW("MS fails to send an Authentication Response");
+
+	btw("At first, we're still waiting");
+	fake_time_passes(0, 423);
+	EXPECT_CONN_COUNT(1);
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+	fake_time_passes(1, 235);
+	EXPECT_CONN_COUNT(1);
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+	fake_time_passes(1, 235);
+	EXPECT_CONN_COUNT(1);
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+	fake_time_passes(1, 235);
+	EXPECT_CONN_COUNT(1);
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+	fake_time_passes(1, 235);
+	EXPECT_CONN_COUNT(1);
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+	expect_bssap_clear();
+	fake_time_passes(1, 235);
+	btw("SUBSCR_CONN_TIMEOUT has passed, conn is gone.");
+	VERBOSE_ASSERT(bssap_clear_sent, == true, "%d");
+	bss_sends_clear_complete();
+	EXPECT_CONN_COUNT(0);
+	VERBOSE_ASSERT(lu_result_sent, == RES_REJECT, "%d");
+
+	comment_end();
+}
+
+static void test_ms_timeout_cm_auth_resp()
+{
+	comment_start();
+
+	net->authentication_required = true;
+
+	fake_time_start();
+
+	btw("Location Update request causes a GSUP Send Auth Info request to HLR");
+	lu_result_sent = RES_NONE;
+	gsup_expect_tx("08010809710000004026f0");
+	ms_sends_msg("050802008168000130089910070000006402");
+	OSMO_ASSERT(gsup_tx_confirmed);
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("from HLR, rx _SEND_AUTH_INFO_RESULT; VLR sends Auth Req to MS");
+	auth_request_sent = false;
+	auth_request_expect_rand = "585df1ae287f6e273dce07090d61320b";
+	auth_request_expect_autn = NULL;
+	/* Based on a Ki of 000102030405060708090a0b0c0d0e0f */
+	gsup_rx("0a"
+		/* imsi */
+		"0108" "09710000004026f0"
+		/* 5 auth vectors... */
+		/* TL    TL     rand */
+		"0322"  "2010" "585df1ae287f6e273dce07090d61320b"
+		/*       TL     sres       TL     kc */
+			"2104" "2d8b2c3e" "2208" "61855fb81fc2a800"
+		"0322"  "2010" "12aca96fb4ffdea5c985cbafa9b6e18b"
+			"2104" "20bde240" "2208" "07fa7502e07e1c00"
+		"0322"  "2010" "e7c03ba7cf0e2fde82b2dc4d63077d42"
+			"2104" "a29514ae" "2208" "e2b234f807886400"
+		"0322"  "2010" "fa8f20b781b5881329d4fea26b1a3c51"
+			"2104" "5afc8d72" "2208" "2392f14f709ae000"
+		"0322"  "2010" "0fd4cc8dbe8715d1f439e304edfd68dc"
+			"2104" "bc8d1c5b" "2208" "da7cdd6bfe2d7000",
+		NULL);
+	VERBOSE_ASSERT(auth_request_sent, == true, "%d");
+	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");
+	ms_sends_msg("05542d8b2c3e");
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT");
+	gsup_rx("10010809710000004026f00804036470f1",
+		"12010809710000004026f0");
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("HLR also sends GSUP _UPDATE_LOCATION_RESULT");
+	expect_bssap_clear();
+	gsup_rx("06010809710000004026f0", NULL);
+	VERBOSE_ASSERT(bssap_clear_sent, == true, "%d");
+
+	btw("LU was successful, and the conn has already been closed");
+	VERBOSE_ASSERT(lu_result_sent, == RES_ACCEPT, "%d");
+	bss_sends_clear_complete();
+	EXPECT_CONN_COUNT(0);
+
+	BTW("after a while, a new conn sends a CM Service Request. VLR responds with Auth Req, 2nd auth vector");
+	auth_request_sent = false;
+	auth_request_expect_rand = "12aca96fb4ffdea5c985cbafa9b6e18b";
+	cm_service_result_sent = RES_NONE;
+	ms_sends_msg("05247803305886089910070000006402");
+	OSMO_ASSERT(g_conn);
+	OSMO_ASSERT(g_conn->fi);
+	OSMO_ASSERT(g_conn->vsub);
+	VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d");
+	VERBOSE_ASSERT(auth_request_sent, == true, "%d");
+
+	BTW("MS fails to send an Authentication Response");
+
+	btw("At first, we're still waiting");
+	fake_time_passes(0, 423);
+	EXPECT_CONN_COUNT(1);
+	VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d");
+	fake_time_passes(1, 235);
+	EXPECT_CONN_COUNT(1);
+	VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d");
+	fake_time_passes(1, 235);
+	EXPECT_CONN_COUNT(1);
+	VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d");
+	fake_time_passes(1, 235);
+	EXPECT_CONN_COUNT(1);
+	VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d");
+	fake_time_passes(1, 235);
+	EXPECT_CONN_COUNT(1);
+	VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d");
+	expect_bssap_clear();
+	fake_time_passes(1, 235);
+	btw("SUBSCR_CONN_TIMEOUT has passed, conn is gone.");
+	VERBOSE_ASSERT(bssap_clear_sent, == true, "%d");
+	bss_sends_clear_complete();
+	EXPECT_CONN_COUNT(0);
+	VERBOSE_ASSERT(cm_service_result_sent, == RES_REJECT, "%d");
+
+	clear_vlr();
+	comment_end();
+}
+
+static void test_ms_timeout_paging()
+{
+	struct vlr_subscr *vsub;
+	const char *imsi = "901700000004620";
+
+	rx_from_ran = RAN_GERAN_A;
+
+	comment_start();
+
+	fake_time_start();
+
+	btw("Location Update request causes a GSUP LU request to HLR");
+	lu_result_sent = RES_NONE;
+	gsup_expect_tx("04010809710000004026f0280102");
+	ms_sends_msg("050802008168000130089910070000006402");
+	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("10010809710000004026f00804036470f1",
+		"12010809710000004026f0");
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("HLR also sends GSUP _UPDATE_LOCATION_RESULT");
+	expect_bssap_clear();
+	gsup_rx("06010809710000004026f0", 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");
+	bss_sends_clear_complete();
+	EXPECT_CONN_COUNT(0);
+
+	BTW("an SMS is sent, MS is paged");
+	paging_expect_imsi(imsi);
+	paging_sent = false;
+	vsub = vlr_subscr_find_by_imsi(net->vlr, imsi);
+	OSMO_ASSERT(vsub);
+	VERBOSE_ASSERT(llist_count(&vsub->cs.requests), == 0, "%d");
+
+	send_sms(vsub, vsub,
+		 "Privacy in residential applications is a desirable"
+		 " marketing option.");
+
+	VERBOSE_ASSERT(llist_count(&vsub->cs.requests), == 1, "%d");
+	vlr_subscr_put(vsub);
+	vsub = NULL;
+	VERBOSE_ASSERT(paging_sent, == true, "%d");
+	VERBOSE_ASSERT(paging_stopped, == false, "%d");
+
+	btw("time passes and no paging result is received");
+
+	fake_time_passes(MSC_PAGING_RESPONSE_TIMER_DEFAULT - 1, 0);
+
+	btw("the paging timeout has not yet expired");
+	VERBOSE_ASSERT(paging_stopped, == false, "%d");
+	vsub = vlr_subscr_find_by_imsi(net->vlr, imsi);
+	OSMO_ASSERT(vsub);
+	VERBOSE_ASSERT(vsub->cs.is_paging, == true, "%d");
+	btw("another request is added to the list but does not cause another paging");
+	paging_sent = false;
+	paging_expect_imsi(NULL);
+	send_sms(vsub, vsub,
+		 "One paging ought to be enough for anyone.");
+	VERBOSE_ASSERT(llist_count(&vsub->cs.requests), == 2, "%d");
+	vlr_subscr_put(vsub);
+	vsub = NULL;
+	VERBOSE_ASSERT(paging_sent, == false, "%d");
+
+	btw("the paging timeout expires, the paging as well as the requests are canceled");
+	fake_time_passes(2, 0);
+	VERBOSE_ASSERT(paging_stopped, == true, "%d");
+
+	vsub = vlr_subscr_find_by_imsi(net->vlr, imsi);
+	OSMO_ASSERT(vsub);
+	VERBOSE_ASSERT(vsub->cs.is_paging, == false, "%d");
+	VERBOSE_ASSERT(llist_count(&vsub->cs.requests), == 0, "%d");
+
+	BTW("Now that the timeout has expired, another Paging is sent on request");
+	paging_expect_imsi(imsi);
+	paging_sent = false;
+
+	send_sms(vsub, vsub,
+		 "Privacy in residential applications is a desirable"
+		 " marketing option.");
+
+	VERBOSE_ASSERT(llist_count(&vsub->cs.requests), == 1, "%d");
+	vlr_subscr_put(vsub);
+	vsub = NULL;
+	VERBOSE_ASSERT(paging_sent, == true, "%d");
+	VERBOSE_ASSERT(paging_stopped, == false, "%d");
+
+	BTW("subscriber detaches, pagings are canceled");
+	expect_bssap_clear();
+	ms_sends_msg("050130089910070000006402");
+	VERBOSE_ASSERT(bssap_clear_sent, == true, "%d");
+	VERBOSE_ASSERT(paging_stopped, == true, "%d");
+
+	vsub = vlr_subscr_find_by_imsi(net->vlr, imsi);
+	OSMO_ASSERT(!vsub);
+
+	bss_sends_clear_complete();
+	EXPECT_CONN_COUNT(0);
+	clear_vlr();
+	comment_end();
+}
+
+static void test_classmark_update_timeout()
+{
+	comment_start();
+
+	fake_time_start();
+
+	/* implicit: net->authentication_required = true; */
+	net->a5_encryption_mask = (1 << 3); /* A5/3 */
+
+	btw("Location Update request causes a GSUP Send Auth Info request to HLR");
+	lu_result_sent = RES_NONE;
+	gsup_expect_tx("08010809710000004026f0");
+	ms_sends_msg("050802008168000130089910070000006402");
+	OSMO_ASSERT(gsup_tx_confirmed);
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("from HLR, rx _SEND_AUTH_INFO_RESULT; VLR sends Auth Req to MS");
+	/* Based on a Ki of 000102030405060708090a0b0c0d0e0f */
+	auth_request_sent = false;
+	auth_request_expect_rand = "585df1ae287f6e273dce07090d61320b";
+	auth_request_expect_autn = NULL;
+	gsup_rx("0a"
+		/* imsi */
+		"0108" "09710000004026f0"
+		/* TL    TL     rand */
+		"0322"  "2010" "585df1ae287f6e273dce07090d61320b"
+		/*       TL     sres       TL     kc */
+			"2104" "2d8b2c3e" "2208" "61855fb81fc2a800"
+		,
+		NULL);
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+	VERBOSE_ASSERT(auth_request_sent, == true, "%d");
+
+	BTW("MS sends Authen Response, VLR accepts and wants to send Ciphering Mode Command to MS"
+	    " -- but needs Classmark 2 to determine whether A5/3 is supported");
+	cipher_mode_cmd_sent = false;
+	ms_sends_msg("05542d8b2c3e");
+	OSMO_ASSERT(!cipher_mode_cmd_sent);
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	BTW("But the BSSMAP Classmark Update never arrives");
+	btw("At first, we're still waiting");
+	fake_time_passes(0, 423);
+	EXPECT_CONN_COUNT(1);
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+	fake_time_passes(1, 235);
+	EXPECT_CONN_COUNT(1);
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+	fake_time_passes(1, 235);
+	EXPECT_CONN_COUNT(1);
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+	fake_time_passes(1, 235);
+	EXPECT_CONN_COUNT(1);
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+	fake_time_passes(1, 235);
+	EXPECT_CONN_COUNT(1);
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+	expect_bssap_clear();
+	fake_time_passes(1, 235);
+	btw("SUBSCR_CONN_TIMEOUT has passed, conn is gone.");
+	VERBOSE_ASSERT(bssap_clear_sent, == true, "%d");
+	bss_sends_clear_complete();
+	EXPECT_CONN_COUNT(0);
+	VERBOSE_ASSERT(lu_result_sent, == RES_REJECT, "%d");
+
+	comment_end();
+}
+
+
+msc_vlr_test_func_t msc_vlr_tests[] = {
+	test_ms_timeout_lu_auth_resp,
+	test_ms_timeout_cm_auth_resp,
+	test_ms_timeout_paging,
+	test_classmark_update_timeout,
+	NULL
+};
diff --git a/tests/msc_vlr/msc_vlr_test_ms_timeout.err b/tests/msc_vlr/msc_vlr_test_ms_timeout.err
new file mode 100644
index 0000000..d2b7ef3
--- /dev/null
+++ b/tests/msc_vlr/msc_vlr_test_ms_timeout.err
@@ -0,0 +1,689 @@
+full talloc report on 'msgb' (total      0 bytes in   1 blocks)
+talloc_total_blocks(tall_bsc_ctx) == 12
+
+===== test_ms_timeout_lu_auth_resp
+- Total time passed: 0.000000 s
+- Location Update request causes a GSUP Send Auth Info request to HLR
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8)
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Updated ID
+DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000004620 type=IMSI ATTACH
+DMM LU/new-LAC: 1/23
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Allocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: is child of Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: rev=GSM net=GERAN Auth (no Ciph)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA
+DREF VLR subscr unknown usage increases to: 1
+DVLR set IMSI on subscriber; IMSI=901700000004620 id=901700000004620
+DVLR New subscr, IMSI: 901700000004620
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DREF VLR subscr IMSI:901700000004620 usage decreases to: 1
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Allocated
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
+DVLR GSUP tx: 08010809710000004026f0
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f0
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF IMSI:901700000004620: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  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: 0a010809710000004026f003222010585df1ae287f6e273dce07090d61320b21042d8b2c3e220861855fb81fc2a800
+DVLR GSUP rx 47: 0a010809710000004026f003222010585df1ae287f6e273dce07090d61320b21042d8b2c3e220861855fb81fc2a800
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: Received Event VLR_AUTH_E_HLR_SAI_ACK
+DVLR SUBSCR(IMSI:901700000004620) Received 1 auth tuples
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: state_chg to VLR_SUB_AS_WAIT_RESP
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_WAIT_RESP}: got auth tuple: use_count=1 key_seq=0 -- will use GSM AKA (is_r99=no, at->vec.auth_types=0x1)
+- sending GSM Auth Request for IMSI:901700000004620: tuple use_count=1 key_seq=0 auth_types=0x1 and...
+- ...rand=585df1ae287f6e273dce07090d61320b
+- ...expecting sres=2d8b2c3e
+DREF VLR subscr IMSI:901700000004620 usage decreases to: 1
+<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT: vlr_gsupc_read_cb() returns 0
+  auth_request_sent == 1
+  lu_result_sent == 0
+---
+- MS fails to send an Authentication Response
+- At first, we're still waiting
+- Total time passed: 0.000423 s
+  llist_count(&net->subscr_conns) == 1
+  lu_result_sent == 0
+- Total time passed: 1.000658 s
+  llist_count(&net->subscr_conns) == 1
+  lu_result_sent == 0
+- Total time passed: 2.000893 s
+  llist_count(&net->subscr_conns) == 1
+  lu_result_sent == 0
+- Total time passed: 3.001128 s
+  llist_count(&net->subscr_conns) == 1
+  lu_result_sent == 0
+- Total time passed: 4.001363 s
+  llist_count(&net->subscr_conns) == 1
+  lu_result_sent == 0
+- Total time passed: 5.001598 s
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Timeout of T0
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_CN_CLOSE
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Close event, cause: CONGESTION
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF IMSI:901700000004620: MSC conn use + release == 1 (0x100: release)
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+- sending LU Reject for IMSI:901700000004620, cause 22
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_DONE
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_CN_CLOSE
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: Event SUBSCR_CONN_E_CN_CLOSE not permitted
+DREF VLR subscr IMSI:901700000004620 usage decreases to: 1
+- BSSAP Clear --RAN_GERAN_A--> MS
+- SUBSCR_CONN_TIMEOUT has passed, conn is gone.
+  bssap_clear_sent == 1
+- BSS sends BSSMAP Clear Complete
+DREF IMSI:901700000004620: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_WAIT_RESP}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_WAIT_RESP}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_WAIT_RESP}: Freeing instance
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_WAIT_RESP}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Freeing instance
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Deallocated
+DRLL IMSI:901700000004620: Freeing subscriber connection
+DREF VLR subscr IMSI:901700000004620 usage decreases to: 0
+DREF freeing VLR subscr IMSI:901700000004620
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+  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) == 12
+
+===== test_ms_timeout_cm_auth_resp
+- Total time passed: 0.000000 s
+- Location Update request causes a GSUP Send Auth Info request to HLR
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8)
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Updated ID
+DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000004620 type=IMSI ATTACH
+DMM LU/new-LAC: 1/23
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Allocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: is child of Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: rev=GSM net=GERAN Auth (no Ciph)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA
+DREF VLR subscr unknown usage increases to: 1
+DVLR set IMSI on subscriber; IMSI=901700000004620 id=901700000004620
+DVLR New subscr, IMSI: 901700000004620
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DREF VLR subscr IMSI:901700000004620 usage decreases to: 1
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Allocated
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
+DVLR GSUP tx: 08010809710000004026f0
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f0
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF IMSI:901700000004620: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  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: 0a010809710000004026f003222010585df1ae287f6e273dce07090d61320b21042d8b2c3e220861855fb81fc2a8000322201012aca96fb4ffdea5c985cbafa9b6e18b210420bde240220807fa7502e07e1c0003222010e7c03ba7cf0e2fde82b2dc4d63077d422104a29514ae2208e2b234f80788640003222010fa8f20b781b5881329d4fea26b1a3c5121045afc8d7222082392f14f709ae000032220100fd4cc8dbe8715d1f439e304edfd68dc2104bc8d1c5b2208da7cdd6bfe2d7000
+DVLR GSUP rx 191: 0a010809710000004026f003222010585df1ae287f6e273dce07090d61320b21042d8b2c3e220861855fb81fc2a8000322201012aca96fb4ffdea5c985cbafa9b6e18b210420bde240220807fa7502e07e1c0003222010e7c03ba7cf0e2fde82b2dc4d63077d422104a29514ae2208e2b234f80788640003222010fa8f20b781b5881329d4fea26b1a3c5121045afc8d7222082392f14f709ae000032220100fd4cc8dbe8715d1f439e304edfd68dc2104bc8d1c5b2208da7cdd6bfe2d7000
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: Received Event VLR_AUTH_E_HLR_SAI_ACK
+DVLR SUBSCR(IMSI:901700000004620) Received 5 auth tuples
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: state_chg to VLR_SUB_AS_WAIT_RESP
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_WAIT_RESP}: got auth tuple: use_count=1 key_seq=0 -- will use GSM AKA (is_r99=no, at->vec.auth_types=0x1)
+- sending GSM Auth Request for IMSI:901700000004620: tuple use_count=1 key_seq=0 auth_types=0x1 and...
+- ...rand=585df1ae287f6e273dce07090d61320b
+- ...expecting sres=2d8b2c3e
+DREF VLR subscr IMSI:901700000004620 usage decreases to: 1
+<-- 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
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_AUTH_RESP
+DREF IMSI:901700000004620: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14)
+DMM IMSI:901700000004620: MM GSM AUTHENTICATION RESPONSE (sres = 2d8b2c3e)
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP
+DVLR SUBSCR(IMSI:901700000004620) AUTH on GERAN received SRES/RES: 2d8b2c3e (4 bytes)
+DVLR SUBSCR(IMSI:901700000004620) AUTH established GSM security context
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result PASSED
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_AUTHENTICATED}: Freeing instance
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_AUTHENTICATED}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_ciph()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_node_4()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: Allocated
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START
+DVLR GSUP tx: 04010809710000004026f0280102
+GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000004026f0280102
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA
+DREF IMSI:901700000004620: MSC conn use - dtap == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  lu_result_sent == 0
+- HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT
+<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: 10010809710000004026f00804036470f1
+DVLR GSUP rx 17: 10010809710000004026f00804036470f1
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DVLR IMSI:901700000004620 has MSISDN:46071
+DVLR SUBSCR(MSISDN:46071) VLR: update for IMSI=901700000004620 (MSISDN=46071, used=2)
+DVLR GSUP tx: 12010809710000004026f0
+GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000004026f0
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+<-- 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: 06010809710000004026f0
+DVLR GSUP rx 11: 06010809710000004026f0
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Freeing instance
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: Allocated
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: Allocated
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(LU:901700000004620)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(LU:901700000004620)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Freeing instance
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Deallocated
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL
+- sending LU Accept for MSISDN:46071
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_DONE
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Freeing instance
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_ACCEPTED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:46071: MSC conn use + release == 1 (0x100: release)
+DREF VLR subscr MSISDN:46071 usage increases to: 4
+DREF VLR subscr MSISDN:46071 usage decreases to: 3
+- BSSAP Clear --RAN_GERAN_A--> MS
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+<-- 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
+  lu_result_sent == 1
+- BSS sends BSSMAP Clear Complete
+DREF MSISDN:46071: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Freeing instance
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Deallocated
+DRLL MSISDN:46071: Freeing subscriber connection
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+---
+- after a while, a new conn sends a CM Service Request. VLR responds with Auth Req, 2nd auth vector
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_CM_SERV_REQ
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_CM_SERV_REQ (0x5:0x24)
+DMM <- CM SERVICE REQUEST serv_type=0x08 MI(IMSI)=901700000004620
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_NEW}: Updated ID
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_INIT}: Allocated
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_INIT}: is child of Subscr_Conn(CM_SERVICE_REQ:901700000004620)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_INIT}: rev=GSM net=GERAN Auth (no Ciph)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_WAIT_AUTH
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Allocated
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: is child of Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620)
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_WAIT_RESP
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000004620){VLR_SUB_AS_WAIT_RESP}: got auth tuple: use_count=1 key_seq=1 -- will use GSM AKA (is_r99=no, at->vec.auth_types=0x1)
+- sending GSM Auth Request for MSISDN:46071: tuple use_count=1 key_seq=1 auth_types=0x1 and...
+- ...rand=12aca96fb4ffdea5c985cbafa9b6e18b
+- ...expecting sres=20bde240
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF MSISDN:46071: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  cm_service_result_sent == 0
+  auth_request_sent == 1
+---
+- MS fails to send an Authentication Response
+- At first, we're still waiting
+- Total time passed: 0.000423 s
+  llist_count(&net->subscr_conns) == 1
+  cm_service_result_sent == 0
+- Total time passed: 1.000658 s
+  llist_count(&net->subscr_conns) == 1
+  cm_service_result_sent == 0
+- Total time passed: 2.000893 s
+  llist_count(&net->subscr_conns) == 1
+  cm_service_result_sent == 0
+- Total time passed: 3.001128 s
+  llist_count(&net->subscr_conns) == 1
+  cm_service_result_sent == 0
+- Total time passed: 4.001363 s
+  llist_count(&net->subscr_conns) == 1
+  cm_service_result_sent == 0
+- Total time passed: 5.001598 s
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Timeout of T0
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_CN_CLOSE
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Close event, cause: CONGESTION
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:46071: MSC conn use + release == 1 (0x100: release)
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_WAIT_AUTH}: Cancel: OSMO_FSM_TERM_ERROR
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_WAIT_AUTH}: proc_arq_fsm_done(CONGESTION)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_WAIT_AUTH}: state_chg to PR_ARQ_S_DONE
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_DONE}: Process Access Request result: CONGESTION
+- sending CM Service Reject for MSISDN:46071, cause: CONGESTION
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_CN_CLOSE
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_RELEASING}: Event SUBSCR_CONN_E_CN_CLOSE not permitted
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+- BSSAP Clear --RAN_GERAN_A--> MS
+- SUBSCR_CONN_TIMEOUT has passed, conn is gone.
+  bssap_clear_sent == 1
+- BSS sends BSSMAP Clear Complete
+DREF MSISDN:46071: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000004620){VLR_SUB_AS_WAIT_RESP}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000004620){VLR_SUB_AS_WAIT_RESP}: Removing from parent Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620)
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000004620){VLR_SUB_AS_WAIT_RESP}: Freeing instance
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000004620){VLR_SUB_AS_WAIT_RESP}: Deallocated
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_DONE}: Removing from parent Subscr_Conn(CM_SERVICE_REQ:901700000004620)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_DONE}: Freeing instance
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_DONE}: Deallocated
+DRLL MSISDN:46071: Freeing subscriber connection
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+  cm_service_result_sent == 2
+DREF freeing VLR subscr MSISDN:46071
+===== test_ms_timeout_cm_auth_resp: SUCCESS
+
+full talloc report on 'msgb' (total      0 bytes in   1 blocks)
+talloc_total_blocks(tall_bsc_ctx) == 12
+
+===== test_ms_timeout_paging
+- Total time passed: 0.000000 s
+- Location Update request causes a GSUP LU request to HLR
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8)
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Updated ID
+DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000004620 type=IMSI ATTACH
+DMM LU/new-LAC: 1/23
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Allocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: is child of Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: rev=GSM net=GERAN (no Auth)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA
+DREF VLR subscr unknown usage increases to: 1
+DVLR set IMSI on subscriber; IMSI=901700000004620 id=901700000004620
+DVLR New subscr, IMSI: 901700000004620
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DREF VLR subscr IMSI:901700000004620 usage decreases to: 1
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_post_auth()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_post_ciph()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node_4()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: Allocated
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START
+DVLR GSUP tx: 04010809710000004026f0280102
+GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000004026f0280102
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF IMSI:901700000004620: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  lu_result_sent == 0
+- HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT
+<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: 10010809710000004026f00804036470f1
+DVLR GSUP rx 17: 10010809710000004026f00804036470f1
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DVLR IMSI:901700000004620 has MSISDN:46071
+DVLR SUBSCR(MSISDN:46071) VLR: update for IMSI=901700000004620 (MSISDN=46071, used=2)
+DVLR GSUP tx: 12010809710000004026f0
+GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000004026f0
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+<-- 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: 06010809710000004026f0
+DVLR GSUP rx 11: 06010809710000004026f0
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Freeing instance
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: Allocated
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: Allocated
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(LU:901700000004620)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(LU:901700000004620)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Freeing instance
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Deallocated
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL
+- sending LU Accept for MSISDN:46071
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_DONE
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Freeing instance
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_ACCEPTED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:46071: MSC conn use + release == 1 (0x100: release)
+DREF VLR subscr MSISDN:46071 usage increases to: 4
+DREF VLR subscr MSISDN:46071 usage decreases to: 3
+- BSSAP Clear --RAN_GERAN_A--> MS
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+<-- 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
+- BSS sends BSSMAP Clear Complete
+DREF MSISDN:46071: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Freeing instance
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Deallocated
+DRLL MSISDN:46071: Freeing subscriber connection
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+---
+- an SMS is sent, MS is paged
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+  llist_count(&vsub->cs.requests) == 0
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DMM Subscriber MSISDN:46071 not paged yet, start paging.
+  RAN_GERAN_A sends out paging request to IMSI 901700000004620, TMSI 0xffffffff, LAC 23
+  strcmp(paging_expecting_imsi, imsi) == 0
+DREF VLR subscr MSISDN:46071 usage increases to: 4
+  llist_count(&vsub->cs.requests) == 1
+DREF VLR subscr MSISDN:46071 usage decreases to: 3
+  paging_sent == 1
+  paging_stopped == 0
+- time passes and no paging result is received
+- Total time passed: 9.000000 s
+- the paging timeout has not yet expired
+  paging_stopped == 0
+DREF VLR subscr MSISDN:46071 usage increases to: 4
+  vsub->cs.is_paging == 1
+- another request is added to the list but does not cause another paging
+DREF VLR subscr MSISDN:46071 usage increases to: 5
+DMM Subscriber MSISDN:46071 already paged.
+  llist_count(&vsub->cs.requests) == 2
+DREF VLR subscr MSISDN:46071 usage decreases to: 4
+  paging_sent == 0
+- the paging timeout expires, the paging as well as the requests are canceled
+- Total time passed: 11.000000 s
+DPAG Paging failure for MSISDN:46071 (event=1)
+DPAG Calling paging cbfn.
+DREF VLR subscr MSISDN:46071 usage decreases to: 3
+DPAG Calling paging cbfn.
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+  paging_stopped == 1
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+  vsub->cs.is_paging == 0
+  llist_count(&vsub->cs.requests) == 0
+---
+- Now that the timeout has expired, another Paging is sent on request
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DMM Subscriber MSISDN:46071 not paged yet, start paging.
+  RAN_GERAN_A sends out paging request to IMSI 901700000004620, TMSI 0xffffffff, LAC 23
+  strcmp(paging_expecting_imsi, imsi) == 0
+DREF VLR subscr MSISDN:46071 usage increases to: 4
+  llist_count(&vsub->cs.requests) == 1
+DREF VLR subscr MSISDN:46071 usage decreases to: 3
+  paging_sent == 1
+  paging_stopped == 0
+---
+- subscriber detaches, pagings are canceled
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_IMSI_DETACH_IND
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_IMSI_DETACH_IND (0x5:0x1)
+DMM IMSI DETACH INDICATION: MI(IMSI)=901700000004620
+DREF VLR subscr MSISDN:46071 usage increases to: 4
+DMM IMSI DETACH for MSISDN:46071
+DPAG Paging failure for MSISDN:46071 (event=1)
+DPAG Calling paging cbfn.
+DREF VLR subscr MSISDN:46071 usage decreases to: 3
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+DREF VLR subscr MSISDN:46071 usage decreases to: 0
+DREF freeing VLR subscr MSISDN:46071
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_CN_CLOSE
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF unknown: MSC conn use + release == 2 (0x101: compl_l3,release)
+- BSSAP Clear --RAN_GERAN_A--> MS
+DREF unknown: MSC conn use - compl_l3 == 1 (0x100: release)
+  bssap_clear_sent == 1
+  paging_stopped == 1
+- BSS sends BSSMAP Clear Complete
+DREF unknown: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DRLL Freeing subscriber connection with NULL subscriber
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+===== test_ms_timeout_paging: SUCCESS
+
+full talloc report on 'msgb' (total      0 bytes in   1 blocks)
+talloc_total_blocks(tall_bsc_ctx) == 12
+
+===== test_classmark_update_timeout
+- Total time passed: 0.000000 s
+- Location Update request causes a GSUP Send Auth Info request to HLR
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8)
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Updated ID
+DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000004620 type=IMSI ATTACH
+DMM LU/new-LAC: 1/23
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Allocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: is child of Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: rev=GSM net=GERAN Auth+Ciph
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA
+DREF VLR subscr unknown usage increases to: 1
+DVLR set IMSI on subscriber; IMSI=901700000004620 id=901700000004620
+DVLR New subscr, IMSI: 901700000004620
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DREF VLR subscr IMSI:901700000004620 usage decreases to: 1
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Allocated
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
+DVLR GSUP tx: 08010809710000004026f0
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000004026f0
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF IMSI:901700000004620: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  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: 0a010809710000004026f003222010585df1ae287f6e273dce07090d61320b21042d8b2c3e220861855fb81fc2a800
+DVLR GSUP rx 47: 0a010809710000004026f003222010585df1ae287f6e273dce07090d61320b21042d8b2c3e220861855fb81fc2a800
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: Received Event VLR_AUTH_E_HLR_SAI_ACK
+DVLR SUBSCR(IMSI:901700000004620) Received 1 auth tuples
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: state_chg to VLR_SUB_AS_WAIT_RESP
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_WAIT_RESP}: got auth tuple: use_count=1 key_seq=0 -- will use GSM AKA (is_r99=no, at->vec.auth_types=0x1)
+- sending GSM Auth Request for IMSI:901700000004620: tuple use_count=1 key_seq=0 auth_types=0x1 and...
+- ...rand=585df1ae287f6e273dce07090d61320b
+- ...expecting sres=2d8b2c3e
+DREF VLR subscr IMSI:901700000004620 usage decreases to: 1
+<-- GSUP rx OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT: vlr_gsupc_read_cb() returns 0
+  lu_result_sent == 0
+  auth_request_sent == 1
+---
+- MS sends Authen Response, VLR accepts and wants to send Ciphering Mode Command to MS -- but needs Classmark 2 to determine whether A5/3 is supported
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_AUTH_RESP
+DREF IMSI:901700000004620: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14)
+DMM IMSI:901700000004620: MM GSM AUTHENTICATION RESPONSE (sres = 2d8b2c3e)
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP
+DVLR SUBSCR(IMSI:901700000004620) AUTH on GERAN received SRES/RES: 2d8b2c3e (4 bytes)
+DVLR SUBSCR(IMSI:901700000004620) AUTH established GSM security context
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result PASSED
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_AUTHENTICATED}: Freeing instance
+DVLR VLR_Authenticate(LU:901700000004620){VLR_SUB_AS_AUTHENTICATED}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_AUTH}: Set Ciphering Mode
+DMM IMSI:901700000004620: to determine whether A5/3 is supported, first ask for a Classmark Update to obtain Classmark 2
+  BSC <--BSSAP-BSS-MANAGEMENT-- MSC: CLASSMARK REQ [L3]> 00 01 58 
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_WAIT_CLASSMARK_UPDATE
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_WAIT_CIPH
+DREF IMSI:901700000004620: MSC conn use - dtap == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_WAIT_CLASSMARK_UPDATE}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_WAIT_CLASSMARK_UPDATE}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  lu_result_sent == 0
+---
+- But the BSSMAP Classmark Update never arrives
+- At first, we're still waiting
+- Total time passed: 0.000423 s
+  llist_count(&net->subscr_conns) == 1
+  lu_result_sent == 0
+- Total time passed: 1.000658 s
+  llist_count(&net->subscr_conns) == 1
+  lu_result_sent == 0
+- Total time passed: 2.000893 s
+  llist_count(&net->subscr_conns) == 1
+  lu_result_sent == 0
+- Total time passed: 3.001128 s
+  llist_count(&net->subscr_conns) == 1
+  lu_result_sent == 0
+- Total time passed: 4.001363 s
+  llist_count(&net->subscr_conns) == 1
+  lu_result_sent == 0
+- Total time passed: 5.001598 s
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_WAIT_CLASSMARK_UPDATE}: Timeout of T0
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_WAIT_CLASSMARK_UPDATE}: Received Event SUBSCR_CONN_E_CN_CLOSE
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_WAIT_CLASSMARK_UPDATE}: Close event, cause: CONGESTION
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_WAIT_CLASSMARK_UPDATE}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF IMSI:901700000004620: MSC conn use + release == 1 (0x100: release)
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+- sending LU Reject for IMSI:901700000004620, cause 22
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_CIPH}: state_chg to VLR_ULA_S_DONE
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_CN_CLOSE
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: Event SUBSCR_CONN_E_CN_CLOSE not permitted
+DREF VLR subscr IMSI:901700000004620 usage decreases to: 1
+- BSSAP Clear --RAN_GERAN_A--> MS
+- SUBSCR_CONN_TIMEOUT has passed, conn is gone.
+  bssap_clear_sent == 1
+- BSS sends BSSMAP Clear Complete
+DREF IMSI:901700000004620: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Freeing instance
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Deallocated
+DRLL IMSI:901700000004620: Freeing subscriber connection
+DREF VLR subscr IMSI:901700000004620 usage decreases to: 0
+DREF freeing VLR subscr IMSI:901700000004620
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+  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) == 12
+
+full talloc report on 'msgb' (total      0 bytes in   1 blocks)
+talloc_total_blocks(tall_bsc_ctx) == 12
+
diff --git a/tests/msc_vlr/msc_vlr_test_ms_timeout.ok b/tests/msc_vlr/msc_vlr_test_ms_timeout.ok
new file mode 100644
index 0000000..a965a70
--- /dev/null
+++ b/tests/msc_vlr/msc_vlr_test_ms_timeout.ok
@@ -0,0 +1 @@
+Done
diff --git a/tests/msc_vlr/msc_vlr_test_no_authen.c b/tests/msc_vlr/msc_vlr_test_no_authen.c
new file mode 100644
index 0000000..b34ddd7
--- /dev/null
+++ b/tests/msc_vlr/msc_vlr_test_no_authen.c
@@ -0,0 +1,985 @@
+/* Osmocom MSC+VLR end-to-end tests */
+
+/* (C) 2017 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>
+ *
+ * All Rights Reserved
+ *
+ * Author: Neels Hofmeyr <nhofmeyr@sysmocom.de>
+ *
+ * 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 "msc_vlr_tests.h"
+
+static void test_no_authen()
+{
+	struct vlr_subscr *vsub;
+	const char *imsi = "901700000004620";
+	
+	/* No auth only works on GERAN */
+	rx_from_ran = RAN_GERAN_A;
+
+	comment_start();
+
+	btw("Location Update request causes a GSUP LU request to HLR");
+	lu_result_sent = RES_NONE;
+	gsup_expect_tx("04010809710000004026f0280102");
+	ms_sends_msg("050802008168000130089910070000006402");
+	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("10010809710000004026f00804036470f1",
+		"12010809710000004026f0");
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("having received subscriber data does not mean acceptance");
+	EXPECT_ACCEPTED(false);
+
+	thwart_rx_non_initial_requests();
+
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("HLR also sends GSUP _UPDATE_LOCATION_RESULT");
+	expect_bssap_clear();
+	gsup_rx("06010809710000004026f0", 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");
+
+	bss_sends_clear_complete();
+	EXPECT_CONN_COUNT(0);
+
+	BTW("after a while, a new conn sends a CM Service Request");
+	cm_service_result_sent = RES_NONE;
+	ms_sends_msg("05247803305886089910070000006402");
+	OSMO_ASSERT(g_conn);
+	OSMO_ASSERT(g_conn->fi);
+	OSMO_ASSERT(g_conn->vsub);
+	VERBOSE_ASSERT(cm_service_result_sent, == RES_ACCEPT, "%d");
+	EXPECT_ACCEPTED(true);
+
+	/* Release connection */
+	expect_bssap_clear(RAN_GERAN_A);
+	conn_conclude_cm_service_req(g_conn, RAN_GERAN_A);
+
+	btw("all requests serviced, conn has been released");
+	bss_sends_clear_complete();
+	EXPECT_CONN_COUNT(0);
+
+	BTW("an SMS is sent, MS is paged");
+	paging_expect_imsi(imsi);
+	paging_sent = false;
+	vsub = vlr_subscr_find_by_imsi(net->vlr, imsi);
+	OSMO_ASSERT(vsub);
+	VERBOSE_ASSERT(llist_count(&vsub->cs.requests), == 0, "%d");
+
+	send_sms(vsub, vsub,
+		 "Privacy in residential applications is a desirable"
+		 " marketing option.");
+
+	VERBOSE_ASSERT(llist_count(&vsub->cs.requests), == 1, "%d");
+	vlr_subscr_put(vsub);
+	vsub = NULL;
+	VERBOSE_ASSERT(paging_sent, == true, "%d");
+	VERBOSE_ASSERT(paging_stopped, == false, "%d");
+
+	btw("the subscriber and its pending request should remain");
+	vsub = vlr_subscr_find_by_imsi(net->vlr, imsi);
+	OSMO_ASSERT(vsub);
+	VERBOSE_ASSERT(llist_count(&vsub->cs.requests), == 1, "%d");
+	vlr_subscr_put(vsub);
+
+	btw("MS replies with Paging Response, we deliver the SMS");
+	dtap_expect_tx("09" /* SMS messages */
+		       "01" /* CP-DATA */
+		       "58" /* length */
+		       "01" /* Network to MS */
+		       "00" /* reference */
+		       /* originator (gsm411_send_sms() hardcodes this weird nr) */
+		       "0791" "447758100650" /* 447785016005 */
+		       "00" /* dest */
+		       /* SMS TPDU */
+		       "4c" /* len */
+		       "00" /* SMS deliver */
+		       "05806470f1" /* originating address 46071 */
+		       "00" /* TP-PID */
+		       "00" /* GSM default alphabet */
+		       "071010" /* Y-M-D (from wrapped gsm340_gen_scts())*/
+		       "000000" /* H-M-S */
+		       "00" /* GMT+0 */
+		       "44" /* data length */
+		       "5079da1e1ee7416937485e9ea7c965373d1d6683c270383b3d0e"
+		       "d3d36ff71c949e83c22072799e9687c5ec32a81d96afcbf4b4fb"
+		       "0c7ac3e9e9b7db05");
+	ms_sends_msg("06270703305882089910070000006402");
+	VERBOSE_ASSERT(dtap_tx_confirmed, == true, "%d");
+	VERBOSE_ASSERT(paging_stopped, == true, "%d");
+
+	btw("SMS was delivered, no requests pending for subscr");
+	vsub = vlr_subscr_find_by_imsi(net->vlr, imsi);
+	OSMO_ASSERT(vsub);
+	VERBOSE_ASSERT(llist_count(&vsub->cs.requests), == 0, "%d");
+	vlr_subscr_put(vsub);
+
+	btw("conn is still open to wait for SMS ack dance");
+	EXPECT_CONN_COUNT(1);
+
+	btw("MS replies with CP-ACK for received SMS");
+	ms_sends_msg("8904");
+	EXPECT_CONN_COUNT(1);
+
+	btw("MS also sends RP-ACK, MSC in turn sends CP-ACK for that");
+	dtap_expect_tx("0904");
+	expect_bssap_clear();
+	ms_sends_msg("890106020041020000");
+	VERBOSE_ASSERT(dtap_tx_confirmed, == true, "%d");
+	VERBOSE_ASSERT(bssap_clear_sent, == true, "%d");
+
+	btw("SMS is done, conn is gone");
+	bss_sends_clear_complete();
+	EXPECT_CONN_COUNT(0);
+
+	BTW("subscriber detaches");
+	expect_bssap_clear();
+	ms_sends_msg("050130089910070000006402");
+	VERBOSE_ASSERT(bssap_clear_sent, == true, "%d");
+
+	bss_sends_clear_complete();
+	EXPECT_CONN_COUNT(0);
+	clear_vlr();
+	comment_end();
+}
+
+static void test_no_authen_tmsi()
+{
+	struct vlr_subscr *vsub;
+	const char *imsi = "901700000004620";
+
+	rx_from_ran = RAN_GERAN_A;
+
+	comment_start();
+
+	net->vlr->cfg.assign_tmsi = true;
+
+	btw("Location Update request causes a GSUP LU request to HLR");
+	lu_result_sent = RES_NONE;
+	gsup_expect_tx("04010809710000004026f0280102");
+	ms_sends_msg("050802008168000130089910070000006402");
+	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("10010809710000004026f00804036470f1",
+		"12010809710000004026f0");
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("having received subscriber data does not mean acceptance");
+	EXPECT_ACCEPTED(false);
+	thwart_rx_non_initial_requests();
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("HLR also sends GSUP _UPDATE_LOCATION_RESULT");
+	gsup_rx("06010809710000004026f0", NULL);
+
+	btw("a LU Accept with a new TMSI was sent, waiting for TMSI Realloc Compl");
+	EXPECT_CONN_COUNT(1);
+	VERBOSE_ASSERT(lu_result_sent, == RES_ACCEPT, "%d");
+	EXPECT_ACCEPTED(false);
+	thwart_rx_non_initial_requests();
+
+	btw("even though the TMSI is not acked, we can already find the subscr with it");
+	vsub = vlr_subscr_find_by_tmsi(net->vlr, 0x03020100);
+	VERBOSE_ASSERT(vsub != NULL, == true, "%d");
+	VERBOSE_ASSERT(strcmp(vsub->imsi, imsi), == 0, "%d");
+	VERBOSE_ASSERT(vsub->tmsi_new, == 0x03020100, "0x%08x");
+	VERBOSE_ASSERT(vsub->tmsi, == GSM_RESERVED_TMSI, "0x%08x");
+	vlr_subscr_put(vsub);
+
+	btw("MS sends TMSI Realloc Complete");
+	expect_bssap_clear();
+	ms_sends_msg("055b");
+	VERBOSE_ASSERT(bssap_clear_sent, == true, "%d");
+
+	btw("LU was successful, and the conn has already been closed");
+	bss_sends_clear_complete();
+	EXPECT_CONN_COUNT(0);
+
+	btw("Subscriber has the new TMSI");
+	vsub = vlr_subscr_find_by_imsi(net->vlr, imsi);
+	VERBOSE_ASSERT(vsub != NULL, == true, "%d");
+	VERBOSE_ASSERT(strcmp(vsub->imsi, imsi), == 0, "%d");
+	VERBOSE_ASSERT(vsub->tmsi_new, == GSM_RESERVED_TMSI, "0x%08x");
+	VERBOSE_ASSERT(vsub->tmsi, == 0x03020100, "0x%08x");
+	vlr_subscr_put(vsub);
+
+	BTW("after a while, a new conn sends a CM Service Request using above TMSI");
+	cm_service_result_sent = RES_NONE;
+	ms_sends_msg("05247803305886" "05f4" "03020100");
+	OSMO_ASSERT(g_conn);
+	OSMO_ASSERT(g_conn->fi);
+	OSMO_ASSERT(g_conn->vsub);
+	VERBOSE_ASSERT(cm_service_result_sent, == RES_ACCEPT, "%d");
+	EXPECT_ACCEPTED(true);
+
+	/* Release connection */
+	expect_bssap_clear(RAN_GERAN_A);
+	conn_conclude_cm_service_req(g_conn, RAN_GERAN_A);
+
+	btw("all requests serviced, conn has been released");
+	bss_sends_clear_complete();
+	EXPECT_CONN_COUNT(0);
+
+	BTW("an SMS is sent, MS is paged using above TMSI");
+	paging_expect_tmsi(0x03020100);
+	paging_sent = false;
+	vsub = vlr_subscr_find_by_tmsi(net->vlr, 0x03020100);
+	OSMO_ASSERT(vsub);
+	VERBOSE_ASSERT(llist_count(&vsub->cs.requests), == 0, "%d");
+
+	send_sms(vsub, vsub,
+		 "Privacy in residential applications is a desirable"
+		 " marketing option.");
+
+	VERBOSE_ASSERT(llist_count(&vsub->cs.requests), == 1, "%d");
+	vlr_subscr_put(vsub);
+	vsub = NULL;
+	VERBOSE_ASSERT(paging_sent, == true, "%d");
+	VERBOSE_ASSERT(paging_stopped, == false, "%d");
+
+	btw("the subscriber and its pending request should remain");
+	vsub = vlr_subscr_find_by_imsi(net->vlr, imsi);
+	OSMO_ASSERT(vsub);
+	VERBOSE_ASSERT(llist_count(&vsub->cs.requests), == 1, "%d");
+	vlr_subscr_put(vsub);
+
+	btw("MS replies with Paging Response using TMSI, we deliver the SMS");
+	dtap_expect_tx("09" /* SMS messages */
+		       "01" /* CP-DATA */
+		       "58" /* length */
+		       "01" /* Network to MS */
+		       "00" /* reference */
+		       /* originator (gsm411_send_sms() hardcodes this weird nr) */
+		       "0791" "447758100650" /* 447785016005 */
+		       "00" /* dest */
+		       /* SMS TPDU */
+		       "4c" /* len */
+		       "00" /* SMS deliver */
+		       "05806470f1" /* originating address 46071 */
+		       "00" /* TP-PID */
+		       "00" /* GSM default alphabet */
+		       "071010" /* Y-M-D (from wrapped gsm340_gen_scts())*/
+		       "000000" /* H-M-S */
+		       "00" /* GMT+0 */
+		       "44" /* data length */
+		       "5079da1e1ee7416937485e9ea7c965373d1d6683c270383b3d0e"
+		       "d3d36ff71c949e83c22072799e9687c5ec32a81d96afcbf4b4fb"
+		       "0c7ac3e9e9b7db05");
+	ms_sends_msg("06270703305882" "05f4" "03020100");
+	VERBOSE_ASSERT(dtap_tx_confirmed, == true, "%d");
+	VERBOSE_ASSERT(paging_stopped, == true, "%d");
+
+	btw("SMS was delivered, no requests pending for subscr");
+	vsub = vlr_subscr_find_by_imsi(net->vlr, imsi);
+	OSMO_ASSERT(vsub);
+	VERBOSE_ASSERT(llist_count(&vsub->cs.requests), == 0, "%d");
+	vlr_subscr_put(vsub);
+
+	btw("conn is still open to wait for SMS ack dance");
+	EXPECT_CONN_COUNT(1);
+
+	btw("MS replies with CP-ACK for received SMS");
+	ms_sends_msg("8904");
+	EXPECT_CONN_COUNT(1);
+
+	btw("MS also sends RP-ACK, MSC in turn sends CP-ACK for that");
+	dtap_expect_tx("0904");
+	expect_bssap_clear();
+	ms_sends_msg("890106020041020000");
+	VERBOSE_ASSERT(dtap_tx_confirmed, == true, "%d");
+	VERBOSE_ASSERT(bssap_clear_sent, == true, "%d");
+
+	btw("SMS is done, conn is gone");
+	bss_sends_clear_complete();
+	EXPECT_CONN_COUNT(0);
+
+	/* TODO: when the subscriber detaches, the vlr_subscr gets
+	 * deallocated and we no longer know the TMSI. This case is covered by
+	 * test_lu_unknown_tmsi(), so here I'd like to still have the TMSI.
+	BTW("subscriber detaches, using TMSI");
+	ms_sends_msg("050130" "05f4" "03020100");
+	EXPECT_CONN_COUNT(0);
+	 */
+
+	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");
+	ms_sends_msg("050802008168000130" "05f4" "03020100");
+	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("10010809710000004026f00804036470f1",
+		"12010809710000004026f0");
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("having received subscriber data does not mean acceptance");
+	EXPECT_ACCEPTED(false);
+	thwart_rx_non_initial_requests();
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("HLR also sends GSUP _UPDATE_LOCATION_RESULT");
+	gsup_rx("06010809710000004026f0", NULL);
+
+	btw("a LU Accept with a new TMSI was sent, waiting for TMSI Realloc Compl");
+	EXPECT_CONN_COUNT(1);
+	VERBOSE_ASSERT(lu_result_sent, == RES_ACCEPT, "%d");
+	EXPECT_ACCEPTED(false);
+	thwart_rx_non_initial_requests();
+
+	btw("even though the TMSI is not acked, we can already find the subscr with it");
+	vsub = vlr_subscr_find_by_tmsi(net->vlr, 0x07060504);
+	VERBOSE_ASSERT(vsub != NULL, == true, "%d");
+	VERBOSE_ASSERT(strcmp(vsub->imsi, imsi), == 0, "%d");
+	VERBOSE_ASSERT(vsub->tmsi_new, == 0x07060504, "0x%08x");
+	VERBOSE_ASSERT(vsub->tmsi, == 0x03020100, "0x%08x");
+	vlr_subscr_put(vsub);
+
+	btw("MS sends TMSI Realloc Complete");
+	expect_bssap_clear();
+	ms_sends_msg("055b");
+	VERBOSE_ASSERT(bssap_clear_sent, == true, "%d");
+
+	btw("LU was successful, and the conn has already been closed");
+	bss_sends_clear_complete();
+	EXPECT_CONN_COUNT(0);
+
+	btw("subscriber has the new TMSI");
+	vsub = vlr_subscr_find_by_tmsi(net->vlr, 0x07060504);
+	VERBOSE_ASSERT(vsub != NULL, == true, "%d");
+	VERBOSE_ASSERT(strcmp(vsub->imsi, imsi), == 0, "%d");
+	VERBOSE_ASSERT(vsub->tmsi_new, == GSM_RESERVED_TMSI, "0x%08x");
+	VERBOSE_ASSERT(vsub->tmsi, == 0x07060504, "0x%08x");
+	vlr_subscr_put(vsub);
+
+	BTW("subscriber detaches, using new TMSI");
+	expect_bssap_clear();
+	ms_sends_msg("050130" "05f4" "07060504");
+	VERBOSE_ASSERT(bssap_clear_sent, == true, "%d");
+
+	bss_sends_clear_complete();
+	EXPECT_CONN_COUNT(0);
+	clear_vlr();
+	comment_end();
+}
+
+static void test_no_authen_imei()
+{
+	struct vlr_subscr *vsub;
+	const char *imsi = "901700000004620";
+
+	rx_from_ran = RAN_GERAN_A;
+
+	comment_start();
+
+	net->vlr->cfg.check_imei_rqd = true;
+
+	btw("Location Update request causes a GSUP LU request to HLR");
+	lu_result_sent = RES_NONE;
+	gsup_expect_tx("04010809710000004026f0280102");
+	ms_sends_msg("050802008168000130089910070000006402");
+	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("10010809710000004026f00804036470f1",
+		"12010809710000004026f0");
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("having received subscriber data does not mean acceptance");
+	EXPECT_ACCEPTED(false);
+	thwart_rx_non_initial_requests();
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("HLR also sends GSUP _UPDATE_LOCATION_RESULT, and we send an ID Request for the IMEI to the MS");
+	dtap_expect_tx("051802");
+	gsup_rx("06010809710000004026f0", NULL);
+
+	btw("We will only do business when the IMEI is known");
+	EXPECT_CONN_COUNT(1);
+	vsub = vlr_subscr_find_by_imsi(net->vlr, imsi);
+	OSMO_ASSERT(vsub);
+	VERBOSE_ASSERT(vsub->imei[0], == 0, "%d");
+	vlr_subscr_put(vsub);
+	EXPECT_ACCEPTED(false);
+	thwart_rx_non_initial_requests();
+
+	btw("MS replies with an Identity Response");
+	expect_bssap_clear();
+	/* 3GPP TS 23.003: 6.2.1 Composition of IMEI: the IMEI ends with a
+	 * spare digit that shall be sent as zero by the MS. */
+	ms_sends_msg("0559084a32244332244302");
+	VERBOSE_ASSERT(bssap_clear_sent, == true, "%d");
+
+	btw("LU was successful, and the conn has already been closed");
+	VERBOSE_ASSERT(lu_result_sent, == RES_ACCEPT, "%d");
+	bss_sends_clear_complete();
+	EXPECT_CONN_COUNT(0);
+
+	btw("Subscriber has the IMEI");
+	vsub = vlr_subscr_find_by_imsi(net->vlr, imsi);
+	OSMO_ASSERT(vsub);
+	VERBOSE_ASSERT(strcmp(vsub->imei, "423423423423420"), == 0, "%d");
+	vlr_subscr_put(vsub);
+
+	BTW("subscriber detaches");
+	expect_bssap_clear();
+	ms_sends_msg("050130089910070000006402");
+	VERBOSE_ASSERT(bssap_clear_sent, == true, "%d");
+
+	bss_sends_clear_complete();
+	EXPECT_CONN_COUNT(0);
+	clear_vlr();
+	comment_end();
+}
+
+static void test_no_authen_tmsi_imei()
+{
+	struct vlr_subscr *vsub;
+	const char *imsi = "901700000004620";
+
+	rx_from_ran = RAN_GERAN_A;
+
+	comment_start();
+
+	net->vlr->cfg.assign_tmsi = true;
+	net->vlr->cfg.check_imei_rqd = true;
+
+	btw("Location Update request causes a GSUP LU request to HLR");
+	lu_result_sent = RES_NONE;
+	gsup_expect_tx("04010809710000004026f0280102");
+	ms_sends_msg("050802008168000130089910070000006402");
+	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("10010809710000004026f00804036470f1",
+		"12010809710000004026f0");
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("having received subscriber data does not mean acceptance");
+	EXPECT_ACCEPTED(false);
+	thwart_rx_non_initial_requests();
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("HLR also sends GSUP _UPDATE_LOCATION_RESULT, and we send an ID Request for the IMEI to the MS");
+	dtap_expect_tx("051802");
+	gsup_rx("06010809710000004026f0", NULL);
+
+	btw("We will only do business when the IMEI is known");
+	EXPECT_CONN_COUNT(1);
+	vsub = vlr_subscr_find_by_imsi(net->vlr, imsi);
+	OSMO_ASSERT(vsub);
+	VERBOSE_ASSERT(vsub->imei[0], == 0, "%d");
+	vlr_subscr_put(vsub);
+	EXPECT_ACCEPTED(false);
+	thwart_rx_non_initial_requests();
+
+	btw("MS replies with an Identity Response");
+	ms_sends_msg("0559084a32244332244302");
+
+	btw("a LU Accept with a new TMSI was sent, waiting for TMSI Realloc Compl");
+	EXPECT_CONN_COUNT(1);
+	VERBOSE_ASSERT(lu_result_sent, == RES_ACCEPT, "%d");
+	EXPECT_ACCEPTED(false);
+	thwart_rx_non_initial_requests();
+
+	btw("MS sends TMSI Realloc Complete");
+	expect_bssap_clear();
+	ms_sends_msg("055b");
+	VERBOSE_ASSERT(bssap_clear_sent, == true, "%d");
+
+	btw("LU was successful, and the conn has already been closed");
+	VERBOSE_ASSERT(lu_result_sent, == RES_ACCEPT, "%d");
+	bss_sends_clear_complete();
+	EXPECT_CONN_COUNT(0);
+
+	btw("Subscriber has the IMEI and TMSI");
+	vsub = vlr_subscr_find_by_imsi(net->vlr, imsi);
+	OSMO_ASSERT(vsub);
+	VERBOSE_ASSERT(strcmp(vsub->imei, "423423423423420"), == 0, "%d");
+	VERBOSE_ASSERT(vsub->tmsi, == 0x03020100, "0x%08x");
+	vlr_subscr_put(vsub);
+
+	BTW("subscriber detaches");
+	expect_bssap_clear();
+	ms_sends_msg("050130089910070000006402");
+	VERBOSE_ASSERT(bssap_clear_sent, == true, "%d");
+
+	bss_sends_clear_complete();
+	EXPECT_CONN_COUNT(0);
+	clear_vlr();
+	comment_end();
+}
+
+static void test_no_authen_imeisv()
+{
+	struct vlr_subscr *vsub;
+	const char *imsi = "901700000004620";
+	
+	/* No auth only works on GERAN */
+	rx_from_ran = RAN_GERAN_A;
+
+	comment_start();
+
+	net->vlr->cfg.retrieve_imeisv_early = true;
+
+	btw("Location Update request causes an IMEISV ID request back to the MS");
+	lu_result_sent = RES_NONE;
+	dtap_expect_tx("051803");
+	ms_sends_msg("050802008168000130089910070000006402");
+	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");
+	ms_sends_msg("0559094332244332244372f5");
+	OSMO_ASSERT(gsup_tx_confirmed);
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("Subscriber has the IMEISV from the ID Response");
+	vsub = vlr_subscr_find_by_imsi(net->vlr, imsi);
+	OSMO_ASSERT(vsub);
+	VERBOSE_ASSERT(strcmp(vsub->imeisv, "4234234234234275"), == 0, "%d");
+	vlr_subscr_put(vsub);
+
+	btw("HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT");
+	gsup_rx("10010809710000004026f00804036470f1",
+		"12010809710000004026f0");
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("having received subscriber data does not mean acceptance");
+	EXPECT_ACCEPTED(false);
+
+	thwart_rx_non_initial_requests();
+
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("HLR also sends GSUP _UPDATE_LOCATION_RESULT");
+	expect_bssap_clear();
+	gsup_rx("06010809710000004026f0", 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");
+	bss_sends_clear_complete();
+	EXPECT_CONN_COUNT(0);
+
+	BTW("subscriber detaches");
+	expect_bssap_clear();
+	ms_sends_msg("050130089910070000006402");
+	VERBOSE_ASSERT(bssap_clear_sent, == true, "%d");
+
+	bss_sends_clear_complete();
+	EXPECT_CONN_COUNT(0);
+	clear_vlr();
+	comment_end();
+}
+
+static void test_no_authen_imeisv_imei()
+{
+	struct vlr_subscr *vsub;
+	const char *imsi = "901700000004620";
+
+	rx_from_ran = RAN_GERAN_A;
+
+	comment_start();
+
+	net->vlr->cfg.retrieve_imeisv_early = true;
+	net->vlr->cfg.check_imei_rqd = true;
+
+	btw("Location Update request causes an IMEISV ID request back to the MS");
+	lu_result_sent = RES_NONE;
+	dtap_expect_tx("051803");
+	ms_sends_msg("050802008168000130089910070000006402");
+	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");
+	ms_sends_msg("0559094332244332244372f5");
+	OSMO_ASSERT(gsup_tx_confirmed);
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("Subscriber has the IMEISV from the ID Response");
+	vsub = vlr_subscr_find_by_imsi(net->vlr, imsi);
+	OSMO_ASSERT(vsub);
+	VERBOSE_ASSERT(strcmp(vsub->imeisv, "4234234234234275"), == 0, "%d");
+	vlr_subscr_put(vsub);
+
+	btw("HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT");
+	gsup_rx("10010809710000004026f00804036470f1",
+		"12010809710000004026f0");
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("having received subscriber data does not mean acceptance");
+	EXPECT_ACCEPTED(false);
+	thwart_rx_non_initial_requests();
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("HLR also sends GSUP _UPDATE_LOCATION_RESULT, and we send an ID Request for the IMEI to the MS");
+	dtap_expect_tx("051802");
+	gsup_rx("06010809710000004026f0", NULL);
+
+	btw("We will only do business when the IMEI is known");
+	EXPECT_CONN_COUNT(1);
+	vsub = vlr_subscr_find_by_imsi(net->vlr, imsi);
+	OSMO_ASSERT(vsub);
+	VERBOSE_ASSERT(vsub->imei[0], == 0, "%d");
+	vlr_subscr_put(vsub);
+	EXPECT_ACCEPTED(false);
+	thwart_rx_non_initial_requests();
+
+	btw("MS replies with an Identity Response");
+	expect_bssap_clear();
+	ms_sends_msg("0559084a32244332244302");
+	VERBOSE_ASSERT(bssap_clear_sent, == true, "%d");
+
+	btw("LU was successful, and the conn has already been closed");
+	VERBOSE_ASSERT(lu_result_sent, == RES_ACCEPT, "%d");
+	bss_sends_clear_complete();
+	EXPECT_CONN_COUNT(0);
+
+	btw("Subscriber has the IMEI");
+	vsub = vlr_subscr_find_by_imsi(net->vlr, imsi);
+	OSMO_ASSERT(vsub);
+	VERBOSE_ASSERT(strcmp(vsub->imei, "423423423423420"), == 0, "%d");
+	vlr_subscr_put(vsub);
+
+	BTW("subscriber detaches");
+	expect_bssap_clear();
+	ms_sends_msg("050130089910070000006402");
+	VERBOSE_ASSERT(bssap_clear_sent, == true, "%d");
+
+	bss_sends_clear_complete();
+	EXPECT_CONN_COUNT(0);
+	clear_vlr();
+	comment_end();
+}
+
+static void test_no_authen_imeisv_tmsi()
+{
+	struct vlr_subscr *vsub;
+	const char *imsi = "901700000004620";
+
+	rx_from_ran = RAN_GERAN_A;
+
+	comment_start();
+
+	net->vlr->cfg.retrieve_imeisv_early = true;
+	net->vlr->cfg.assign_tmsi = true;
+
+	btw("Location Update request causes an IMEISV ID request back to the MS");
+	lu_result_sent = RES_NONE;
+	dtap_expect_tx("051803");
+	ms_sends_msg("050802008168000130089910070000006402");
+	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");
+	ms_sends_msg("0559094332244332244372f5");
+	OSMO_ASSERT(gsup_tx_confirmed);
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("Subscriber has the IMEISV from the ID Response");
+	vsub = vlr_subscr_find_by_imsi(net->vlr, imsi);
+	OSMO_ASSERT(vsub);
+	VERBOSE_ASSERT(strcmp(vsub->imeisv, "4234234234234275"), == 0, "%d");
+	vlr_subscr_put(vsub);
+
+	btw("HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT");
+	gsup_rx("10010809710000004026f00804036470f1",
+		"12010809710000004026f0");
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("having received subscriber data does not mean acceptance");
+	EXPECT_ACCEPTED(false);
+	thwart_rx_non_initial_requests();
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("HLR also sends GSUP _UPDATE_LOCATION_RESULT");
+	gsup_rx("06010809710000004026f0", NULL);
+
+	btw("a LU Accept with a new TMSI was sent, waiting for TMSI Realloc Compl");
+	EXPECT_CONN_COUNT(1);
+	VERBOSE_ASSERT(lu_result_sent, == RES_ACCEPT, "%d");
+	EXPECT_ACCEPTED(false);
+	thwart_rx_non_initial_requests();
+
+	btw("even though the TMSI is not acked, we can already find the subscr with it");
+	vsub = vlr_subscr_find_by_tmsi(net->vlr, 0x03020100);
+	VERBOSE_ASSERT(vsub != NULL, == true, "%d");
+	VERBOSE_ASSERT(strcmp(vsub->imsi, imsi), == 0, "%d");
+	VERBOSE_ASSERT(vsub->tmsi_new, == 0x03020100, "0x%08x");
+	VERBOSE_ASSERT(vsub->tmsi, == GSM_RESERVED_TMSI, "0x%08x");
+	vlr_subscr_put(vsub);
+
+	btw("MS sends TMSI Realloc Complete");
+	expect_bssap_clear();
+	ms_sends_msg("055b");
+	VERBOSE_ASSERT(bssap_clear_sent, == true, "%d");
+
+	btw("LU was successful, and the conn has already been closed");
+	bss_sends_clear_complete();
+	EXPECT_CONN_COUNT(0);
+
+
+	BTW("subscriber sends LU Request, this time with the TMSI");
+	btw("Location Update request causes an IMEISV ID request back to the MS");
+	lu_result_sent = RES_NONE;
+	dtap_expect_tx("051803");
+	ms_sends_msg("050802008168000130089910070000006402");
+	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");
+	ms_sends_msg("0559095332244332244372f6");
+	OSMO_ASSERT(gsup_tx_confirmed);
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("Subscriber has the IMEISV from the ID Response");
+	vsub = vlr_subscr_find_by_imsi(net->vlr, imsi);
+	OSMO_ASSERT(vsub);
+	VERBOSE_ASSERT(strcmp(vsub->imeisv, "5234234234234276"), == 0, "%d");
+	vlr_subscr_put(vsub);
+
+	btw("HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT");
+	gsup_rx("10010809710000004026f00804036470f1",
+		"12010809710000004026f0");
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("having received subscriber data does not mean acceptance");
+	EXPECT_ACCEPTED(false);
+	thwart_rx_non_initial_requests();
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("HLR also sends GSUP _UPDATE_LOCATION_RESULT");
+	gsup_rx("06010809710000004026f0", NULL);
+
+	btw("a LU Accept with a new TMSI was sent, waiting for TMSI Realloc Compl");
+	EXPECT_CONN_COUNT(1);
+	VERBOSE_ASSERT(lu_result_sent, == RES_ACCEPT, "%d");
+	EXPECT_ACCEPTED(false);
+	thwart_rx_non_initial_requests();
+
+	btw("even though the TMSI is not acked, we can already find the subscr with it");
+	vsub = vlr_subscr_find_by_tmsi(net->vlr, 0x07060504);
+	VERBOSE_ASSERT(vsub != NULL, == true, "%d");
+	VERBOSE_ASSERT(strcmp(vsub->imsi, imsi), == 0, "%d");
+	VERBOSE_ASSERT(vsub->tmsi_new, == 0x07060504, "0x%08x");
+	VERBOSE_ASSERT(vsub->tmsi, == 0x03020100, "0x%08x");
+	vlr_subscr_put(vsub);
+
+	btw("MS sends TMSI Realloc Complete");
+	expect_bssap_clear();
+	ms_sends_msg("055b");
+	VERBOSE_ASSERT(bssap_clear_sent, == true, "%d");
+
+	btw("LU was successful, and the conn has already been closed");
+	bss_sends_clear_complete();
+	EXPECT_CONN_COUNT(0);
+
+	btw("subscriber has the new TMSI");
+	vsub = vlr_subscr_find_by_tmsi(net->vlr, 0x07060504);
+	VERBOSE_ASSERT(vsub != NULL, == true, "%d");
+	VERBOSE_ASSERT(strcmp(vsub->imsi, imsi), == 0, "%d");
+	VERBOSE_ASSERT(vsub->tmsi_new, == GSM_RESERVED_TMSI, "0x%08x");
+	VERBOSE_ASSERT(vsub->tmsi, == 0x07060504, "0x%08x");
+	vlr_subscr_put(vsub);
+
+	BTW("subscriber detaches, using new TMSI");
+	expect_bssap_clear();
+	ms_sends_msg("050130" "05f4" "07060504");
+	VERBOSE_ASSERT(bssap_clear_sent, == true, "%d");
+
+	bss_sends_clear_complete();
+	EXPECT_CONN_COUNT(0);
+	clear_vlr();
+	comment_end();
+}
+
+static void test_no_authen_imeisv_tmsi_imei()
+{
+	struct vlr_subscr *vsub;
+	const char *imsi = "901700000004620";
+
+	rx_from_ran = RAN_GERAN_A;
+
+	comment_start();
+
+	net->vlr->cfg.retrieve_imeisv_early = true;
+	net->vlr->cfg.assign_tmsi = true;
+	net->vlr->cfg.check_imei_rqd = true;
+
+	btw("Location Update request causes an IMEISV ID request back to the MS");
+	lu_result_sent = RES_NONE;
+	dtap_expect_tx("051803");
+	ms_sends_msg("050802008168000130089910070000006402");
+	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");
+	ms_sends_msg("0559094332244332244372f5");
+	OSMO_ASSERT(gsup_tx_confirmed);
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("Subscriber has the IMEISV from the ID Response");
+	vsub = vlr_subscr_find_by_imsi(net->vlr, imsi);
+	OSMO_ASSERT(vsub);
+	VERBOSE_ASSERT(strcmp(vsub->imeisv, "4234234234234275"), == 0, "%d");
+	vlr_subscr_put(vsub);
+
+	btw("HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT");
+	gsup_rx("10010809710000004026f00804036470f1",
+		"12010809710000004026f0");
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("having received subscriber data does not mean acceptance");
+	EXPECT_ACCEPTED(false);
+	thwart_rx_non_initial_requests();
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("HLR also sends GSUP _UPDATE_LOCATION_RESULT, and we send an ID Request for the IMEI to the MS");
+	dtap_expect_tx("051802");
+	gsup_rx("06010809710000004026f0", NULL);
+
+	btw("We will only do business when the IMEI is known");
+	EXPECT_CONN_COUNT(1);
+	vsub = vlr_subscr_find_by_imsi(net->vlr, imsi);
+	OSMO_ASSERT(vsub);
+	VERBOSE_ASSERT(vsub->imei[0], == 0, "%d");
+	vlr_subscr_put(vsub);
+	EXPECT_ACCEPTED(false);
+	thwart_rx_non_initial_requests();
+
+	btw("MS replies with an Identity Response");
+	ms_sends_msg("0559084a32244332244302");
+
+	btw("a LU Accept with a new TMSI was sent, waiting for TMSI Realloc Compl");
+	EXPECT_CONN_COUNT(1);
+	VERBOSE_ASSERT(lu_result_sent, == RES_ACCEPT, "%d");
+	EXPECT_ACCEPTED(false);
+	thwart_rx_non_initial_requests();
+
+	btw("MS sends TMSI Realloc Complete");
+	expect_bssap_clear();
+	ms_sends_msg("055b");
+	VERBOSE_ASSERT(bssap_clear_sent, == true, "%d");
+
+	btw("LU was successful, and the conn has already been closed");
+	VERBOSE_ASSERT(lu_result_sent, == RES_ACCEPT, "%d");
+	bss_sends_clear_complete();
+	EXPECT_CONN_COUNT(0);
+
+	btw("Subscriber has the IMEISV, IMEI and TMSI");
+	vsub = vlr_subscr_find_by_imsi(net->vlr, imsi);
+	OSMO_ASSERT(vsub);
+	VERBOSE_ASSERT(strcmp(vsub->imeisv, "4234234234234275"), == 0, "%d");
+	VERBOSE_ASSERT(strcmp(vsub->imei, "423423423423420"), == 0, "%d");
+	VERBOSE_ASSERT(vsub->tmsi, == 0x03020100, "0x%08x");
+	vlr_subscr_put(vsub);
+
+	BTW("subscriber detaches");
+	expect_bssap_clear();
+	ms_sends_msg("050130089910070000006402");
+	VERBOSE_ASSERT(bssap_clear_sent, == true, "%d");
+
+	bss_sends_clear_complete();
+	EXPECT_CONN_COUNT(0);
+	clear_vlr();
+	comment_end();
+}
+
+static void test_no_authen_subscr_expire()
+{
+	struct vlr_subscr *vsub;
+	const char *imsi = "901700000004620";
+
+	/* No auth only works on GERAN */
+	rx_from_ran = RAN_GERAN_A;
+
+	comment_start();
+
+	fake_time_start();
+
+	/* The test framework has already started the VLR before fake time was active.
+	 * Manually schedule this timeout in fake time. */
+	osmo_timer_del(&net->vlr->lu_expire_timer);
+	osmo_timer_schedule(&net->vlr->lu_expire_timer, VLR_SUBSCRIBER_LU_EXPIRATION_INTERVAL, 0);
+
+	/* Let the LU expiration timer tick once */
+	fake_time_passes(VLR_SUBSCRIBER_LU_EXPIRATION_INTERVAL + 1, 0);
+
+	btw("Location Update request causes a GSUP LU request to HLR");
+	lu_result_sent = RES_NONE;
+	gsup_expect_tx("04010809710000004026f0280102");
+	ms_sends_msg("050802008168000130089910070000006402");
+	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("10010809710000004026f00804036470f1",
+		"12010809710000004026f0");
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("HLR also sends GSUP _UPDATE_LOCATION_RESULT");
+	expect_bssap_clear();
+	gsup_rx("06010809710000004026f0", 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");
+
+	bss_sends_clear_complete();
+	EXPECT_CONN_COUNT(0);
+
+	vsub = vlr_subscr_find_by_imsi(net->vlr, imsi);
+	OSMO_ASSERT(vsub);
+	vlr_subscr_put(vsub);
+
+	/* Let T3212 (periodic Location update timer) expire */
+	fake_time_passes((net->t3212 * 60 * 6 * 2) + 60*4, 0);
+
+	/* The subscriber should now be gone. */
+	vsub = vlr_subscr_find_by_imsi(net->vlr, imsi);
+	OSMO_ASSERT(vsub == NULL);
+
+	EXPECT_CONN_COUNT(0);
+	clear_vlr();
+	comment_end();
+}
+
+msc_vlr_test_func_t msc_vlr_tests[] = {
+	test_no_authen,
+	test_no_authen_tmsi,
+	test_no_authen_imei,
+	test_no_authen_tmsi_imei,
+	test_no_authen_imeisv,
+	test_no_authen_imeisv_imei,
+	test_no_authen_imeisv_tmsi,
+	test_no_authen_imeisv_tmsi_imei,
+	test_no_authen_subscr_expire,
+	NULL
+};
diff --git a/tests/msc_vlr/msc_vlr_test_no_authen.err b/tests/msc_vlr/msc_vlr_test_no_authen.err
new file mode 100644
index 0000000..fb0582b
--- /dev/null
+++ b/tests/msc_vlr/msc_vlr_test_no_authen.err
@@ -0,0 +1,2368 @@
+full talloc report on 'msgb' (total      0 bytes in   1 blocks)
+talloc_total_blocks(tall_bsc_ctx) == 12
+
+===== test_no_authen
+- Location Update request causes a GSUP LU request to HLR
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8)
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Updated ID
+DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000004620 type=IMSI ATTACH
+DMM LU/new-LAC: 1/23
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Allocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: is child of Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: rev=GSM net=GERAN (no Auth)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA
+DREF VLR subscr unknown usage increases to: 1
+DVLR set IMSI on subscriber; IMSI=901700000004620 id=901700000004620
+DVLR New subscr, IMSI: 901700000004620
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DREF VLR subscr IMSI:901700000004620 usage decreases to: 1
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_post_auth()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_post_ciph()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node_4()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: Allocated
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START
+DVLR GSUP tx: 04010809710000004026f0280102
+GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000004026f0280102
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF IMSI:901700000004620: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  lu_result_sent == 0
+- HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT
+<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: 10010809710000004026f00804036470f1
+DVLR GSUP rx 17: 10010809710000004026f00804036470f1
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DVLR IMSI:901700000004620 has MSISDN:46071
+DVLR SUBSCR(MSISDN:46071) VLR: update for IMSI=901700000004620 (MSISDN=46071, used=2)
+DVLR GSUP tx: 12010809710000004026f0
+GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000004026f0
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: vlr_gsupc_read_cb() returns 0
+  lu_result_sent == 0
+- having received subscriber data does not mean acceptance
+msc_subscr_conn_is_accepted() == false
+  requests shall be thwarted
+DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_CC_SETUP
+DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: unknown 0x33
+DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1
+DRLL Dispatching 04.08 message SMS:0x01 (0x9:0x1)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: SMS:0x01
+  lu_result_sent == 0
+- HLR also sends GSUP _UPDATE_LOCATION_RESULT
+<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: 06010809710000004026f0
+DVLR GSUP rx 11: 06010809710000004026f0
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Freeing instance
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: Allocated
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: Allocated
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(LU:901700000004620)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(LU:901700000004620)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Freeing instance
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Deallocated
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL
+- sending LU Accept for MSISDN:46071
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_DONE
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Freeing instance
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_ACCEPTED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:46071: MSC conn use + release == 1 (0x100: release)
+DREF VLR subscr MSISDN:46071 usage increases to: 4
+DREF VLR subscr MSISDN:46071 usage decreases to: 3
+- BSSAP Clear --RAN_GERAN_A--> MS
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+<-- 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
+- BSS sends BSSMAP Clear Complete
+DREF MSISDN:46071: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Freeing instance
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Deallocated
+DRLL MSISDN:46071: Freeing subscriber connection
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+---
+- after a while, a new conn sends a CM Service Request
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_CM_SERV_REQ
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_CM_SERV_REQ (0x5:0x24)
+DMM <- CM SERVICE REQUEST serv_type=0x08 MI(IMSI)=901700000004620
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_NEW}: Updated ID
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_INIT}: Allocated
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_INIT}: is child of Subscr_Conn(CM_SERVICE_REQ:901700000004620)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_INIT}: rev=GSM net=GERAN (no Auth)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_node2()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_ciph()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_vlr()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_post_pres()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_post_trace()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_post_imei()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_INIT}: proc_arq_fsm_done(PASSED)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_DONE
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_DONE}: Process Access Request result: PASSED
+- sending CM Service Accept for MSISDN:46071
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_ACCEPTED
+DREF MSISDN:46071: MSC conn use + cm_service == 2 (0x9: compl_l3,cm_service)
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_ACCEPTED}: subscr_conn_fsm_has_active_transactions: still awaiting first request after a CM Service Request
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DREF MSISDN:46071: MSC conn use - compl_l3 == 1 (0x8: cm_service)
+  cm_service_result_sent == 1
+msc_subscr_conn_is_accepted() == true
+- Concluding CM Service Request
+DREF MSISDN:46071: MSC conn use - cm_service == 0 (0x0: )
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:46071: MSC conn use + release == 1 (0x100: release)
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+- BSSAP Clear --RAN_GERAN_A--> MS
+  bssap_clear_sent == 1
+- all requests serviced, conn has been released
+- BSS sends BSSMAP Clear Complete
+DREF MSISDN:46071: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_DONE}: Removing from parent Subscr_Conn(CM_SERVICE_REQ:901700000004620)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_DONE}: Freeing instance
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_DONE}: Deallocated
+DRLL MSISDN:46071: Freeing subscriber connection
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+---
+- an SMS is sent, MS is paged
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+  llist_count(&vsub->cs.requests) == 0
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DMM Subscriber MSISDN:46071 not paged yet, start paging.
+  RAN_GERAN_A sends out paging request to IMSI 901700000004620, TMSI 0xffffffff, LAC 23
+  strcmp(paging_expecting_imsi, imsi) == 0
+DREF VLR subscr MSISDN:46071 usage increases to: 4
+  llist_count(&vsub->cs.requests) == 1
+DREF VLR subscr MSISDN:46071 usage decreases to: 3
+  paging_sent == 1
+  paging_stopped == 0
+- the subscriber and its pending request should remain
+DREF VLR subscr MSISDN:46071 usage increases to: 4
+  llist_count(&vsub->cs.requests) == 1
+DREF VLR subscr MSISDN:46071 usage decreases to: 3
+- MS replies with Paging Response, we deliver the SMS
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_RR_PAG_RESP
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_RR_PAG_RESP (0x6:0x27)
+DRR PAGING RESPONSE: MI(IMSI)=901700000004620
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_NEW}: Updated ID
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_INIT}: Allocated
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_INIT}: is child of Subscr_Conn(PAGING_RESP:901700000004620)
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_INIT}: rev=GSM net=GERAN (no Auth)
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START
+DREF VLR subscr MSISDN:46071 usage increases to: 4
+DREF VLR subscr MSISDN:46071 usage increases to: 5
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi()
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_node2()
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_ciph()
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_vlr()
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_post_pres()
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_post_trace()
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_post_imei()
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_INIT}: proc_arq_fsm_done(PASSED)
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_DONE
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_DONE}: Process Access Request result: PASSED
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_ACCEPTED
+DPAG Paging success for MSISDN:46071 (event=0)
+DPAG Calling paging cbfn.
+DCC (ti 00 sub MSISDN:46071 callref 40000001) New transaction
+DREF VLR subscr MSISDN:46071 usage increases to: 6
+DREF MSISDN:46071: MSC conn use + trans_sms == 2 (0x21: compl_l3,trans_sms)
+DMSC msc_tx 91 bytes to MSISDN:46071 via RAN_GERAN_A
+- DTAP --RAN_GERAN_A--> MS: SMS:0x01: 09015801000791447758100650004c0005806470f1000007101000000000445079da1e1ee7416937485e9ea7c965373d1d6683c270383b3d0ed3d36ff71c949e83c22072799e9687c5ec32a81d96afcbf4b4fb0c7ac3e9e9b7db05
+- DTAP matches expected message
+DREF VLR subscr MSISDN:46071 usage decreases to: 5
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_ACCEPTED}: subscr_conn_fsm_has_active_transactions: connection still has active transaction: SMS
+DREF VLR subscr MSISDN:46071 usage decreases to: 4
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DREF MSISDN:46071: MSC conn use - compl_l3 == 1 (0x20: trans_sms)
+  dtap_tx_confirmed == 1
+  paging_stopped == 1
+- SMS was delivered, no requests pending for subscr
+DREF VLR subscr MSISDN:46071 usage increases to: 5
+  llist_count(&vsub->cs.requests) == 0
+DREF VLR subscr MSISDN:46071 usage decreases to: 4
+- conn is still open to wait for SMS ack dance
+  llist_count(&net->subscr_conns) == 1
+- MS replies with CP-ACK for received SMS
+  MSC <--RAN_GERAN_A-- MS: SMS:0x04
+DREF MSISDN:46071: MSC conn use + dtap == 2 (0x22: dtap,trans_sms)
+DRLL Dispatching 04.08 message SMS:0x04 (0x9:0x4)
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_COMMUNICATING
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_COMMUNICATING
+DREF MSISDN:46071: MSC conn use - dtap == 1 (0x20: trans_sms)
+  llist_count(&net->subscr_conns) == 1
+- MS also sends RP-ACK, MSC in turn sends CP-ACK for that
+  MSC <--RAN_GERAN_A-- MS: SMS:0x01
+DREF MSISDN:46071: MSC conn use + dtap == 2 (0x22: dtap,trans_sms)
+DRLL Dispatching 04.08 message SMS:0x01 (0x9:0x1)
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_COMMUNICATING}: Received Event SUBSCR_CONN_E_COMMUNICATING
+DMSC msc_tx 2 bytes to MSISDN:46071 via RAN_GERAN_A
+- DTAP --RAN_GERAN_A--> MS: SMS:0x04: 0904
+- DTAP matches expected message
+DREF VLR subscr MSISDN:46071 usage decreases to: 3
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+DREF MSISDN:46071: MSC conn use - trans_sms == 1 (0x2: dtap)
+DREF MSISDN:46071: MSC conn use - dtap == 0 (0x0: )
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_COMMUNICATING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_COMMUNICATING}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:46071: MSC conn use + release == 1 (0x100: release)
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+- BSSAP Clear --RAN_GERAN_A--> MS
+  dtap_tx_confirmed == 1
+  bssap_clear_sent == 1
+- SMS is done, conn is gone
+- BSS sends BSSMAP Clear Complete
+DREF MSISDN:46071: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_DONE}: Removing from parent Subscr_Conn(PAGING_RESP:901700000004620)
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_DONE}: Freeing instance
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_DONE}: Deallocated
+DRLL MSISDN:46071: Freeing subscriber connection
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+---
+- subscriber detaches
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_IMSI_DETACH_IND
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_IMSI_DETACH_IND (0x5:0x1)
+DMM IMSI DETACH INDICATION: MI(IMSI)=901700000004620
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+DMM IMSI DETACH for MSISDN:46071
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+DREF VLR subscr MSISDN:46071 usage decreases to: 0
+DREF freeing VLR subscr MSISDN:46071
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_CN_CLOSE
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF unknown: MSC conn use + release == 2 (0x101: compl_l3,release)
+- BSSAP Clear --RAN_GERAN_A--> MS
+DREF unknown: MSC conn use - compl_l3 == 1 (0x100: release)
+  bssap_clear_sent == 1
+- BSS sends BSSMAP Clear Complete
+DREF unknown: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DRLL Freeing subscriber connection with NULL subscriber
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+===== test_no_authen: SUCCESS
+
+full talloc report on 'msgb' (total      0 bytes in   1 blocks)
+talloc_total_blocks(tall_bsc_ctx) == 12
+
+===== test_no_authen_tmsi
+- Location Update request causes a GSUP LU request to HLR
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8)
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Updated ID
+DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000004620 type=IMSI ATTACH
+DMM LU/new-LAC: 1/23
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Allocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: is child of Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: rev=GSM net=GERAN (no Auth)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA
+DREF VLR subscr unknown usage increases to: 1
+DVLR set IMSI on subscriber; IMSI=901700000004620 id=901700000004620
+DVLR New subscr, IMSI: 901700000004620
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DREF VLR subscr IMSI:901700000004620 usage decreases to: 1
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_post_auth()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_post_ciph()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node_4()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: Allocated
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START
+DVLR GSUP tx: 04010809710000004026f0280102
+GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000004026f0280102
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF IMSI:901700000004620: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  lu_result_sent == 0
+- HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT
+<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: 10010809710000004026f00804036470f1
+DVLR GSUP rx 17: 10010809710000004026f00804036470f1
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DVLR IMSI:901700000004620 has MSISDN:46071
+DVLR SUBSCR(MSISDN:46071) VLR: update for IMSI=901700000004620 (MSISDN=46071, used=2)
+DVLR GSUP tx: 12010809710000004026f0
+GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000004026f0
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: vlr_gsupc_read_cb() returns 0
+  lu_result_sent == 0
+- having received subscriber data does not mean acceptance
+msc_subscr_conn_is_accepted() == false
+  requests shall be thwarted
+DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_CC_SETUP
+DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: unknown 0x33
+DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1
+DRLL Dispatching 04.08 message SMS:0x01 (0x9:0x1)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: SMS:0x01
+  lu_result_sent == 0
+- HLR also sends GSUP _UPDATE_LOCATION_RESULT
+<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: 06010809710000004026f0
+DVLR GSUP rx 11: 06010809710000004026f0
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Freeing instance
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: Allocated
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: Allocated
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(LU:901700000004620)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(LU:901700000004620)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Freeing instance
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Deallocated
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: lu_compl_vlr_new_tmsi()
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_WAIT_TMSI_CNF
+- sending LU Accept for MSISDN:46071, with TMSI 0x03020100
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: vlr_gsupc_read_cb() returns 0
+- a LU Accept with a new TMSI was sent, waiting for TMSI Realloc Compl
+  llist_count(&net->subscr_conns) == 1
+  lu_result_sent == 1
+msc_subscr_conn_is_accepted() == false
+  requests shall be thwarted
+DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_CC_SETUP
+DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: unknown 0x33
+DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1
+DRLL Dispatching 04.08 message SMS:0x01 (0x9:0x1)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: SMS:0x01
+- even though the TMSI is not acked, we can already find the subscr with it
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+  vsub != NULL == 1
+  strcmp(vsub->imsi, imsi) == 0
+  vsub->tmsi_new == 0x03020100
+  vsub->tmsi == 0xffffffff
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+- MS sends TMSI Realloc Complete
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_TMSI_REALL_COMPL
+DREF MSISDN:46071: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_TMSI_REALL_COMPL (0x5:0x1b)
+DMM TMSI Reallocation Completed. Subscriber: MSISDN:46071
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_NEW_TMSI_ACK
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_TMSI_CNF}: Received Event LU_COMPL_VLR_E_NEW_TMSI_ACK
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_TMSI_CNF}: state_chg to LU_COMPL_VLR_S_DONE
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Freeing instance
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_ACCEPTED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:46071: MSC conn use + release == 2 (0x102: dtap,release)
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+- BSSAP Clear --RAN_GERAN_A--> MS
+DREF MSISDN:46071: MSC conn use - dtap == 1 (0x100: release)
+  bssap_clear_sent == 1
+- LU was successful, and the conn has already been closed
+- BSS sends BSSMAP Clear Complete
+DREF MSISDN:46071: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Freeing instance
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Deallocated
+DRLL MSISDN:46071: Freeing subscriber connection
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+- Subscriber has the new TMSI
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+  vsub != NULL == 1
+  strcmp(vsub->imsi, imsi) == 0
+  vsub->tmsi_new == 0xffffffff
+  vsub->tmsi == 0x03020100
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+---
+- after a while, a new conn sends a CM Service Request using above TMSI
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_CM_SERV_REQ
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_CM_SERV_REQ (0x5:0x24)
+DMM <- CM SERVICE REQUEST serv_type=0x08 MI(TMSI)=50462976
+DMM Subscr_Conn(CM_SERVICE_REQ:50462976){SUBSCR_CONN_S_NEW}: Updated ID
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:50462976){PR_ARQ_S_INIT}: Allocated
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:50462976){PR_ARQ_S_INIT}: is child of Subscr_Conn(CM_SERVICE_REQ:50462976)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:50462976){PR_ARQ_S_INIT}: rev=GSM net=GERAN (no Auth)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:50462976){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:50462976){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:50462976){PR_ARQ_S_INIT}: _proc_arq_vlr_node2()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:50462976){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_ciph()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:50462976){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_vlr()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:50462976){PR_ARQ_S_INIT}: _proc_arq_vlr_post_pres()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:50462976){PR_ARQ_S_INIT}: _proc_arq_vlr_post_trace()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:50462976){PR_ARQ_S_INIT}: _proc_arq_vlr_post_imei()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:50462976){PR_ARQ_S_INIT}: proc_arq_fsm_done(PASSED)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:50462976){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_DONE
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:50462976){PR_ARQ_S_DONE}: Process Access Request result: PASSED
+- sending CM Service Accept for MSISDN:46071
+DMM Subscr_Conn(CM_SERVICE_REQ:50462976){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_ACCEPTED
+DREF MSISDN:46071: MSC conn use + cm_service == 2 (0x9: compl_l3,cm_service)
+DMM Subscr_Conn(CM_SERVICE_REQ:50462976){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(CM_SERVICE_REQ:50462976){SUBSCR_CONN_S_ACCEPTED}: subscr_conn_fsm_has_active_transactions: still awaiting first request after a CM Service Request
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+DMM Subscr_Conn(CM_SERVICE_REQ:50462976){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DREF MSISDN:46071: MSC conn use - compl_l3 == 1 (0x8: cm_service)
+  cm_service_result_sent == 1
+msc_subscr_conn_is_accepted() == true
+- Concluding CM Service Request
+DREF MSISDN:46071: MSC conn use - cm_service == 0 (0x0: )
+DMM Subscr_Conn(CM_SERVICE_REQ:50462976){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(CM_SERVICE_REQ:50462976){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:46071: MSC conn use + release == 1 (0x100: release)
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+- BSSAP Clear --RAN_GERAN_A--> MS
+  bssap_clear_sent == 1
+- all requests serviced, conn has been released
+- BSS sends BSSMAP Clear Complete
+DREF MSISDN:46071: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(CM_SERVICE_REQ:50462976){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(CM_SERVICE_REQ:50462976){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(CM_SERVICE_REQ:50462976){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:50462976){PR_ARQ_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:50462976){PR_ARQ_S_DONE}: Removing from parent Subscr_Conn(CM_SERVICE_REQ:50462976)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:50462976){PR_ARQ_S_DONE}: Freeing instance
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:50462976){PR_ARQ_S_DONE}: Deallocated
+DRLL MSISDN:46071: Freeing subscriber connection
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+DMM Subscr_Conn(CM_SERVICE_REQ:50462976){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(CM_SERVICE_REQ:50462976){SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+---
+- an SMS is sent, MS is paged using above TMSI
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+  llist_count(&vsub->cs.requests) == 0
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DMM Subscriber MSISDN:46071 not paged yet, start paging.
+  RAN_GERAN_A sends out paging request to IMSI 901700000004620, TMSI 0x03020100, LAC 23
+  paging_expecting_tmsi == 0x03020100
+DREF VLR subscr MSISDN:46071 usage increases to: 4
+  llist_count(&vsub->cs.requests) == 1
+DREF VLR subscr MSISDN:46071 usage decreases to: 3
+  paging_sent == 1
+  paging_stopped == 0
+- the subscriber and its pending request should remain
+DREF VLR subscr MSISDN:46071 usage increases to: 4
+  llist_count(&vsub->cs.requests) == 1
+DREF VLR subscr MSISDN:46071 usage decreases to: 3
+- MS replies with Paging Response using TMSI, we deliver the SMS
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_RR_PAG_RESP
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_RR_PAG_RESP (0x6:0x27)
+DRR PAGING RESPONSE: MI(TMSI)=50462976
+DMM Subscr_Conn(PAGING_RESP:50462976){SUBSCR_CONN_S_NEW}: Updated ID
+DVLR Process_Access_Request_VLR(PAGING_RESP:50462976){PR_ARQ_S_INIT}: Allocated
+DVLR Process_Access_Request_VLR(PAGING_RESP:50462976){PR_ARQ_S_INIT}: is child of Subscr_Conn(PAGING_RESP:50462976)
+DVLR Process_Access_Request_VLR(PAGING_RESP:50462976){PR_ARQ_S_INIT}: rev=GSM net=GERAN (no Auth)
+DVLR Process_Access_Request_VLR(PAGING_RESP:50462976){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START
+DREF VLR subscr MSISDN:46071 usage increases to: 4
+DREF VLR subscr MSISDN:46071 usage increases to: 5
+DVLR Process_Access_Request_VLR(PAGING_RESP:50462976){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi()
+DVLR Process_Access_Request_VLR(PAGING_RESP:50462976){PR_ARQ_S_INIT}: _proc_arq_vlr_node2()
+DVLR Process_Access_Request_VLR(PAGING_RESP:50462976){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_ciph()
+DVLR Process_Access_Request_VLR(PAGING_RESP:50462976){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_vlr()
+DVLR Process_Access_Request_VLR(PAGING_RESP:50462976){PR_ARQ_S_INIT}: _proc_arq_vlr_post_pres()
+DVLR Process_Access_Request_VLR(PAGING_RESP:50462976){PR_ARQ_S_INIT}: _proc_arq_vlr_post_trace()
+DVLR Process_Access_Request_VLR(PAGING_RESP:50462976){PR_ARQ_S_INIT}: _proc_arq_vlr_post_imei()
+DVLR Process_Access_Request_VLR(PAGING_RESP:50462976){PR_ARQ_S_INIT}: proc_arq_fsm_done(PASSED)
+DVLR Process_Access_Request_VLR(PAGING_RESP:50462976){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_DONE
+DVLR Process_Access_Request_VLR(PAGING_RESP:50462976){PR_ARQ_S_DONE}: Process Access Request result: PASSED
+DMM Subscr_Conn(PAGING_RESP:50462976){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_ACCEPTED
+DPAG Paging success for MSISDN:46071 (event=0)
+DPAG Calling paging cbfn.
+DCC (ti 00 sub MSISDN:46071 callref 40000002) New transaction
+DREF VLR subscr MSISDN:46071 usage increases to: 6
+DREF MSISDN:46071: MSC conn use + trans_sms == 2 (0x21: compl_l3,trans_sms)
+DMSC msc_tx 91 bytes to MSISDN:46071 via RAN_GERAN_A
+- DTAP --RAN_GERAN_A--> MS: SMS:0x01: 09015801000791447758100650004c0005806470f1000007101000000000445079da1e1ee7416937485e9ea7c965373d1d6683c270383b3d0ed3d36ff71c949e83c22072799e9687c5ec32a81d96afcbf4b4fb0c7ac3e9e9b7db05
+- DTAP matches expected message
+DREF VLR subscr MSISDN:46071 usage decreases to: 5
+DMM Subscr_Conn(PAGING_RESP:50462976){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(PAGING_RESP:50462976){SUBSCR_CONN_S_ACCEPTED}: subscr_conn_fsm_has_active_transactions: connection still has active transaction: SMS
+DREF VLR subscr MSISDN:46071 usage decreases to: 4
+DMM Subscr_Conn(PAGING_RESP:50462976){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DREF MSISDN:46071: MSC conn use - compl_l3 == 1 (0x20: trans_sms)
+  dtap_tx_confirmed == 1
+  paging_stopped == 1
+- SMS was delivered, no requests pending for subscr
+DREF VLR subscr MSISDN:46071 usage increases to: 5
+  llist_count(&vsub->cs.requests) == 0
+DREF VLR subscr MSISDN:46071 usage decreases to: 4
+- conn is still open to wait for SMS ack dance
+  llist_count(&net->subscr_conns) == 1
+- MS replies with CP-ACK for received SMS
+  MSC <--RAN_GERAN_A-- MS: SMS:0x04
+DREF MSISDN:46071: MSC conn use + dtap == 2 (0x22: dtap,trans_sms)
+DRLL Dispatching 04.08 message SMS:0x04 (0x9:0x4)
+DMM Subscr_Conn(PAGING_RESP:50462976){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_COMMUNICATING
+DMM Subscr_Conn(PAGING_RESP:50462976){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_COMMUNICATING
+DREF MSISDN:46071: MSC conn use - dtap == 1 (0x20: trans_sms)
+  llist_count(&net->subscr_conns) == 1
+- MS also sends RP-ACK, MSC in turn sends CP-ACK for that
+  MSC <--RAN_GERAN_A-- MS: SMS:0x01
+DREF MSISDN:46071: MSC conn use + dtap == 2 (0x22: dtap,trans_sms)
+DRLL Dispatching 04.08 message SMS:0x01 (0x9:0x1)
+DMM Subscr_Conn(PAGING_RESP:50462976){SUBSCR_CONN_S_COMMUNICATING}: Received Event SUBSCR_CONN_E_COMMUNICATING
+DMSC msc_tx 2 bytes to MSISDN:46071 via RAN_GERAN_A
+- DTAP --RAN_GERAN_A--> MS: SMS:0x04: 0904
+- DTAP matches expected message
+DREF VLR subscr MSISDN:46071 usage decreases to: 3
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+DREF MSISDN:46071: MSC conn use - trans_sms == 1 (0x2: dtap)
+DREF MSISDN:46071: MSC conn use - dtap == 0 (0x0: )
+DMM Subscr_Conn(PAGING_RESP:50462976){SUBSCR_CONN_S_COMMUNICATING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(PAGING_RESP:50462976){SUBSCR_CONN_S_COMMUNICATING}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:46071: MSC conn use + release == 1 (0x100: release)
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+- BSSAP Clear --RAN_GERAN_A--> MS
+  dtap_tx_confirmed == 1
+  bssap_clear_sent == 1
+- SMS is done, conn is gone
+- BSS sends BSSMAP Clear Complete
+DREF MSISDN:46071: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(PAGING_RESP:50462976){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(PAGING_RESP:50462976){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(PAGING_RESP:50462976){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR Process_Access_Request_VLR(PAGING_RESP:50462976){PR_ARQ_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR Process_Access_Request_VLR(PAGING_RESP:50462976){PR_ARQ_S_DONE}: Removing from parent Subscr_Conn(PAGING_RESP:50462976)
+DVLR Process_Access_Request_VLR(PAGING_RESP:50462976){PR_ARQ_S_DONE}: Freeing instance
+DVLR Process_Access_Request_VLR(PAGING_RESP:50462976){PR_ARQ_S_DONE}: Deallocated
+DRLL MSISDN:46071: Freeing subscriber connection
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+DMM Subscr_Conn(PAGING_RESP:50462976){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(PAGING_RESP:50462976){SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+---
+- subscriber sends LU Request, this time with the TMSI
+- Location Update request causes a GSUP LU request to HLR
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8)
+DMM Subscr_Conn(LU:50462976){SUBSCR_CONN_S_NEW}: Updated ID
+DMM LOCATION UPDATING REQUEST: MI(TMSI)=50462976 type=IMSI ATTACH
+DMM LU/new-LAC: 1/23
+DVLR vlr_lu_fsm(LU:50462976){VLR_ULA_S_IDLE}: Allocated
+DVLR vlr_lu_fsm(LU:50462976){VLR_ULA_S_IDLE}: is child of Subscr_Conn(LU:50462976)
+DVLR vlr_lu_fsm(LU:50462976){VLR_ULA_S_IDLE}: rev=GSM net=GERAN (no Auth)
+DVLR vlr_lu_fsm(LU:50462976){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+DVLR vlr_lu_fsm(LU:50462976){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
+DVLR vlr_lu_fsm(LU:50462976){VLR_ULA_S_IDLE}: vlr_loc_upd_post_auth()
+DVLR vlr_lu_fsm(LU:50462976){VLR_ULA_S_IDLE}: vlr_loc_upd_post_ciph()
+DVLR vlr_lu_fsm(LU:50462976){VLR_ULA_S_IDLE}: vlr_loc_upd_node_4()
+DVLR vlr_lu_fsm(LU:50462976){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
+DVLR upd_hlr_vlr_fsm(LU:50462976){UPD_HLR_VLR_S_INIT}: Allocated
+DVLR upd_hlr_vlr_fsm(LU:50462976){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(LU:50462976)
+DVLR upd_hlr_vlr_fsm(LU:50462976){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START
+DVLR GSUP tx: 04010809710000004026f0280102
+GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000004026f0280102
+DVLR upd_hlr_vlr_fsm(LU:50462976){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA
+DMM Subscr_Conn(LU:50462976){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(LU:50462976){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF MSISDN:46071: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(LU:50462976){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:50462976){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  lu_result_sent == 0
+- HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT
+<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: 10010809710000004026f00804036470f1
+DVLR GSUP rx 17: 10010809710000004026f00804036470f1
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DVLR IMSI:901700000004620 has MSISDN:46071
+DVLR SUBSCR(MSISDN:46071) VLR: update for IMSI=901700000004620 (MSISDN=46071, used=3)
+DVLR GSUP tx: 12010809710000004026f0
+GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000004026f0
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: vlr_gsupc_read_cb() returns 0
+  lu_result_sent == 0
+- having received subscriber data does not mean acceptance
+msc_subscr_conn_is_accepted() == false
+  requests shall be thwarted
+DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_CC_SETUP
+DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: unknown 0x33
+DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1
+DRLL Dispatching 04.08 message SMS:0x01 (0x9:0x1)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: SMS:0x01
+  lu_result_sent == 0
+- HLR also sends GSUP _UPDATE_LOCATION_RESULT
+<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: 06010809710000004026f0
+DVLR GSUP rx 11: 06010809710000004026f0
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DVLR vlr_lu_fsm(LU:50462976){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES
+DVLR upd_hlr_vlr_fsm(LU:50462976){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK
+DVLR upd_hlr_vlr_fsm(LU:50462976){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE
+DVLR upd_hlr_vlr_fsm(LU:50462976){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR upd_hlr_vlr_fsm(LU:50462976){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:50462976)
+DVLR upd_hlr_vlr_fsm(LU:50462976){UPD_HLR_VLR_S_DONE}: Freeing instance
+DVLR upd_hlr_vlr_fsm(LU:50462976){UPD_HLR_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:50462976){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL
+DVLR vlr_lu_fsm(LU:50462976){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL
+DVLR lu_compl_vlr_fsm(LU:50462976){LU_COMPL_VLR_S_INIT}: Allocated
+DVLR lu_compl_vlr_fsm(LU:50462976){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(LU:50462976)
+DVLR lu_compl_vlr_fsm(LU:50462976){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START
+DVLR lu_compl_vlr_fsm(LU:50462976){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES
+DVLR sub_pres_vlr_fsm(LU:50462976){SUB_PRES_VLR_S_INIT}: Allocated
+DVLR sub_pres_vlr_fsm(LU:50462976){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(LU:50462976)
+DVLR sub_pres_vlr_fsm(LU:50462976){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START
+DVLR sub_pres_vlr_fsm(LU:50462976){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE
+DVLR sub_pres_vlr_fsm(LU:50462976){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR sub_pres_vlr_fsm(LU:50462976){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(LU:50462976)
+DVLR sub_pres_vlr_fsm(LU:50462976){SUB_PRES_VLR_S_DONE}: Freeing instance
+DVLR sub_pres_vlr_fsm(LU:50462976){SUB_PRES_VLR_S_DONE}: Deallocated
+DVLR lu_compl_vlr_fsm(LU:50462976){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL
+DVLR lu_compl_vlr_fsm(LU:50462976){LU_COMPL_VLR_S_WAIT_SUB_PRES}: lu_compl_vlr_new_tmsi()
+DVLR lu_compl_vlr_fsm(LU:50462976){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_WAIT_TMSI_CNF
+- sending LU Accept for MSISDN:46071, with TMSI 0x07060504
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: vlr_gsupc_read_cb() returns 0
+- a LU Accept with a new TMSI was sent, waiting for TMSI Realloc Compl
+  llist_count(&net->subscr_conns) == 1
+  lu_result_sent == 1
+msc_subscr_conn_is_accepted() == false
+  requests shall be thwarted
+DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_CC_SETUP
+DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: unknown 0x33
+DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1
+DRLL Dispatching 04.08 message SMS:0x01 (0x9:0x1)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: SMS:0x01
+- even though the TMSI is not acked, we can already find the subscr with it
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+  vsub != NULL == 1
+  strcmp(vsub->imsi, imsi) == 0
+  vsub->tmsi_new == 0x07060504
+  vsub->tmsi == 0x03020100
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+- MS sends TMSI Realloc Complete
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_TMSI_REALL_COMPL
+DREF MSISDN:46071: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_TMSI_REALL_COMPL (0x5:0x1b)
+DMM TMSI Reallocation Completed. Subscriber: MSISDN:46071
+DVLR vlr_lu_fsm(LU:50462976){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_NEW_TMSI_ACK
+DVLR lu_compl_vlr_fsm(LU:50462976){LU_COMPL_VLR_S_WAIT_TMSI_CNF}: Received Event LU_COMPL_VLR_E_NEW_TMSI_ACK
+DVLR lu_compl_vlr_fsm(LU:50462976){LU_COMPL_VLR_S_WAIT_TMSI_CNF}: state_chg to LU_COMPL_VLR_S_DONE
+DVLR vlr_lu_fsm(LU:50462976){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS
+DVLR lu_compl_vlr_fsm(LU:50462976){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR lu_compl_vlr_fsm(LU:50462976){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:50462976)
+DVLR lu_compl_vlr_fsm(LU:50462976){LU_COMPL_VLR_S_DONE}: Freeing instance
+DVLR lu_compl_vlr_fsm(LU:50462976){LU_COMPL_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:50462976){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE
+DMM Subscr_Conn(LU:50462976){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_ACCEPTED
+DMM Subscr_Conn(LU:50462976){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(LU:50462976){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:50462976){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:46071: MSC conn use + release == 2 (0x102: dtap,release)
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+- BSSAP Clear --RAN_GERAN_A--> MS
+DREF MSISDN:46071: MSC conn use - dtap == 1 (0x100: release)
+  bssap_clear_sent == 1
+- LU was successful, and the conn has already been closed
+- BSS sends BSSMAP Clear Complete
+DREF MSISDN:46071: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(LU:50462976){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:50462976){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(LU:50462976){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR vlr_lu_fsm(LU:50462976){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR vlr_lu_fsm(LU:50462976){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(LU:50462976)
+DVLR vlr_lu_fsm(LU:50462976){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT
+DVLR vlr_lu_fsm(LU:50462976){VLR_ULA_S_DONE}: Freeing instance
+DVLR vlr_lu_fsm(LU:50462976){VLR_ULA_S_DONE}: Deallocated
+DRLL MSISDN:46071: Freeing subscriber connection
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+DMM Subscr_Conn(LU:50462976){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(LU:50462976){SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+- subscriber has the new TMSI
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+  vsub != NULL == 1
+  strcmp(vsub->imsi, imsi) == 0
+  vsub->tmsi_new == 0xffffffff
+  vsub->tmsi == 0x07060504
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+---
+- subscriber detaches, using new TMSI
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_IMSI_DETACH_IND
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_IMSI_DETACH_IND (0x5:0x1)
+DMM IMSI DETACH INDICATION: MI(TMSI)=117835012
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+DMM IMSI DETACH for MSISDN:46071
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+DREF VLR subscr MSISDN:46071 usage decreases to: 0
+DREF freeing VLR subscr MSISDN:46071
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_CN_CLOSE
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF unknown: MSC conn use + release == 2 (0x101: compl_l3,release)
+- BSSAP Clear --RAN_GERAN_A--> MS
+DREF unknown: MSC conn use - compl_l3 == 1 (0x100: release)
+  bssap_clear_sent == 1
+- BSS sends BSSMAP Clear Complete
+DREF unknown: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DRLL Freeing subscriber connection with NULL subscriber
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+===== test_no_authen_tmsi: SUCCESS
+
+full talloc report on 'msgb' (total      0 bytes in   1 blocks)
+talloc_total_blocks(tall_bsc_ctx) == 12
+
+===== test_no_authen_imei
+- Location Update request causes a GSUP LU request to HLR
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8)
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Updated ID
+DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000004620 type=IMSI ATTACH
+DMM LU/new-LAC: 1/23
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Allocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: is child of Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: rev=GSM net=GERAN (no Auth)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA
+DREF VLR subscr unknown usage increases to: 1
+DVLR set IMSI on subscriber; IMSI=901700000004620 id=901700000004620
+DVLR New subscr, IMSI: 901700000004620
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DREF VLR subscr IMSI:901700000004620 usage decreases to: 1
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_post_auth()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_post_ciph()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node_4()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: Allocated
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START
+DVLR GSUP tx: 04010809710000004026f0280102
+GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000004026f0280102
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF IMSI:901700000004620: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  lu_result_sent == 0
+- HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT
+<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: 10010809710000004026f00804036470f1
+DVLR GSUP rx 17: 10010809710000004026f00804036470f1
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DVLR IMSI:901700000004620 has MSISDN:46071
+DVLR SUBSCR(MSISDN:46071) VLR: update for IMSI=901700000004620 (MSISDN=46071, used=2)
+DVLR GSUP tx: 12010809710000004026f0
+GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000004026f0
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: vlr_gsupc_read_cb() returns 0
+  lu_result_sent == 0
+- having received subscriber data does not mean acceptance
+msc_subscr_conn_is_accepted() == false
+  requests shall be thwarted
+DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_CC_SETUP
+DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: unknown 0x33
+DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1
+DRLL Dispatching 04.08 message SMS:0x01 (0x9:0x1)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: SMS:0x01
+  lu_result_sent == 0
+- HLR also sends GSUP _UPDATE_LOCATION_RESULT, and we send an ID Request for the IMEI to the MS
+<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: 06010809710000004026f0
+DVLR GSUP rx 11: 06010809710000004026f0
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Freeing instance
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: Allocated
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: Allocated
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(LU:901700000004620)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(LU:901700000004620)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Freeing instance
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Deallocated
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_WAIT_IMEI
+DMSC msc_tx 3 bytes to MSISDN:46071 via RAN_GERAN_A
+- DTAP --RAN_GERAN_A--> MS: GSM48_MT_MM_ID_REQ: 051802
+- DTAP matches expected message
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: vlr_gsupc_read_cb() returns 0
+- We will only do business when the IMEI is known
+  llist_count(&net->subscr_conns) == 1
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+  vsub->imei[0] == 0
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+msc_subscr_conn_is_accepted() == false
+  requests shall be thwarted
+DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_CC_SETUP
+DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: unknown 0x33
+DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1
+DRLL Dispatching 04.08 message SMS:0x01 (0x9:0x1)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: SMS:0x01
+- MS replies with an Identity Response
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_ID_RESP
+DREF MSISDN:46071: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_ID_RESP (0x5:0x19)
+DMM IDENTITY RESPONSE: MI(IMEI)=423423423423420
+DVLR set IMEI on subscriber; IMSI=901700000004620 IMEI=423423423423420
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_ID_IMEI
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_IMEI}: Received Event LU_COMPL_VLR_E_IMEI_CHECK_ACK
+- sending LU Accept for MSISDN:46071
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_IMEI}: state_chg to LU_COMPL_VLR_S_DONE
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Freeing instance
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_ACCEPTED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:46071: MSC conn use + release == 2 (0x102: dtap,release)
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+- BSSAP Clear --RAN_GERAN_A--> MS
+DREF MSISDN:46071: MSC conn use - dtap == 1 (0x100: release)
+  bssap_clear_sent == 1
+- LU was successful, and the conn has already been closed
+  lu_result_sent == 1
+- BSS sends BSSMAP Clear Complete
+DREF MSISDN:46071: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Freeing instance
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Deallocated
+DRLL MSISDN:46071: Freeing subscriber connection
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+- Subscriber has the IMEI
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+  strcmp(vsub->imei, "423423423423420") == 0
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+---
+- subscriber detaches
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_IMSI_DETACH_IND
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_IMSI_DETACH_IND (0x5:0x1)
+DMM IMSI DETACH INDICATION: MI(IMSI)=901700000004620
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+DMM IMSI DETACH for MSISDN:46071
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+DREF VLR subscr MSISDN:46071 usage decreases to: 0
+DREF freeing VLR subscr MSISDN:46071
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_CN_CLOSE
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF unknown: MSC conn use + release == 2 (0x101: compl_l3,release)
+- BSSAP Clear --RAN_GERAN_A--> MS
+DREF unknown: MSC conn use - compl_l3 == 1 (0x100: release)
+  bssap_clear_sent == 1
+- BSS sends BSSMAP Clear Complete
+DREF unknown: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DRLL Freeing subscriber connection with NULL subscriber
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+===== test_no_authen_imei: SUCCESS
+
+full talloc report on 'msgb' (total      0 bytes in   1 blocks)
+talloc_total_blocks(tall_bsc_ctx) == 12
+
+===== test_no_authen_tmsi_imei
+- Location Update request causes a GSUP LU request to HLR
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8)
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Updated ID
+DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000004620 type=IMSI ATTACH
+DMM LU/new-LAC: 1/23
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Allocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: is child of Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: rev=GSM net=GERAN (no Auth)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA
+DREF VLR subscr unknown usage increases to: 1
+DVLR set IMSI on subscriber; IMSI=901700000004620 id=901700000004620
+DVLR New subscr, IMSI: 901700000004620
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DREF VLR subscr IMSI:901700000004620 usage decreases to: 1
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_post_auth()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_post_ciph()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node_4()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: Allocated
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START
+DVLR GSUP tx: 04010809710000004026f0280102
+GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000004026f0280102
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF IMSI:901700000004620: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  lu_result_sent == 0
+- HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT
+<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: 10010809710000004026f00804036470f1
+DVLR GSUP rx 17: 10010809710000004026f00804036470f1
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DVLR IMSI:901700000004620 has MSISDN:46071
+DVLR SUBSCR(MSISDN:46071) VLR: update for IMSI=901700000004620 (MSISDN=46071, used=2)
+DVLR GSUP tx: 12010809710000004026f0
+GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000004026f0
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: vlr_gsupc_read_cb() returns 0
+  lu_result_sent == 0
+- having received subscriber data does not mean acceptance
+msc_subscr_conn_is_accepted() == false
+  requests shall be thwarted
+DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_CC_SETUP
+DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: unknown 0x33
+DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1
+DRLL Dispatching 04.08 message SMS:0x01 (0x9:0x1)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: SMS:0x01
+  lu_result_sent == 0
+- HLR also sends GSUP _UPDATE_LOCATION_RESULT, and we send an ID Request for the IMEI to the MS
+<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: 06010809710000004026f0
+DVLR GSUP rx 11: 06010809710000004026f0
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Freeing instance
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: Allocated
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: Allocated
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(LU:901700000004620)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(LU:901700000004620)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Freeing instance
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Deallocated
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_WAIT_IMEI_TMSI
+DMSC msc_tx 3 bytes to MSISDN:46071 via RAN_GERAN_A
+- DTAP --RAN_GERAN_A--> MS: GSM48_MT_MM_ID_REQ: 051802
+- DTAP matches expected message
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: vlr_gsupc_read_cb() returns 0
+- We will only do business when the IMEI is known
+  llist_count(&net->subscr_conns) == 1
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+  vsub->imei[0] == 0
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+msc_subscr_conn_is_accepted() == false
+  requests shall be thwarted
+DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_CC_SETUP
+DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: unknown 0x33
+DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1
+DRLL Dispatching 04.08 message SMS:0x01 (0x9:0x1)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: SMS:0x01
+- MS replies with an Identity Response
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_ID_RESP
+DREF MSISDN:46071: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_ID_RESP (0x5:0x19)
+DMM IDENTITY RESPONSE: MI(IMEI)=423423423423420
+DVLR set IMEI on subscriber; IMSI=901700000004620 IMEI=423423423423420
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_ID_IMEI
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_IMEI_TMSI}: Received Event LU_COMPL_VLR_E_IMEI_CHECK_ACK
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_IMEI_TMSI}: lu_compl_vlr_new_tmsi()
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_IMEI_TMSI}: state_chg to LU_COMPL_VLR_S_WAIT_TMSI_CNF
+- sending LU Accept for MSISDN:46071, with TMSI 0x03020100
+DREF MSISDN:46071: MSC conn use - dtap == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+- a LU Accept with a new TMSI was sent, waiting for TMSI Realloc Compl
+  llist_count(&net->subscr_conns) == 1
+  lu_result_sent == 1
+msc_subscr_conn_is_accepted() == false
+  requests shall be thwarted
+DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_CC_SETUP
+DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: unknown 0x33
+DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1
+DRLL Dispatching 04.08 message SMS:0x01 (0x9:0x1)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: SMS:0x01
+- MS sends TMSI Realloc Complete
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_TMSI_REALL_COMPL
+DREF MSISDN:46071: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_TMSI_REALL_COMPL (0x5:0x1b)
+DMM TMSI Reallocation Completed. Subscriber: MSISDN:46071
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_NEW_TMSI_ACK
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_TMSI_CNF}: Received Event LU_COMPL_VLR_E_NEW_TMSI_ACK
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_TMSI_CNF}: state_chg to LU_COMPL_VLR_S_DONE
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Freeing instance
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_ACCEPTED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:46071: MSC conn use + release == 2 (0x102: dtap,release)
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+- BSSAP Clear --RAN_GERAN_A--> MS
+DREF MSISDN:46071: MSC conn use - dtap == 1 (0x100: release)
+  bssap_clear_sent == 1
+- LU was successful, and the conn has already been closed
+  lu_result_sent == 1
+- BSS sends BSSMAP Clear Complete
+DREF MSISDN:46071: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Freeing instance
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Deallocated
+DRLL MSISDN:46071: Freeing subscriber connection
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+- Subscriber has the IMEI and TMSI
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+  strcmp(vsub->imei, "423423423423420") == 0
+  vsub->tmsi == 0x03020100
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+---
+- subscriber detaches
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_IMSI_DETACH_IND
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_IMSI_DETACH_IND (0x5:0x1)
+DMM IMSI DETACH INDICATION: MI(IMSI)=901700000004620
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+DMM IMSI DETACH for MSISDN:46071
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+DREF VLR subscr MSISDN:46071 usage decreases to: 0
+DREF freeing VLR subscr MSISDN:46071
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_CN_CLOSE
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF unknown: MSC conn use + release == 2 (0x101: compl_l3,release)
+- BSSAP Clear --RAN_GERAN_A--> MS
+DREF unknown: MSC conn use - compl_l3 == 1 (0x100: release)
+  bssap_clear_sent == 1
+- BSS sends BSSMAP Clear Complete
+DREF unknown: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DRLL Freeing subscriber connection with NULL subscriber
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+===== test_no_authen_tmsi_imei: SUCCESS
+
+full talloc report on 'msgb' (total      0 bytes in   1 blocks)
+talloc_total_blocks(tall_bsc_ctx) == 12
+
+===== test_no_authen_imeisv
+- Location Update request causes an IMEISV ID request back to the MS
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8)
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Updated ID
+DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000004620 type=IMSI ATTACH
+DMM LU/new-LAC: 1/23
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Allocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: is child of Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: rev=GSM net=GERAN (no Auth)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA
+DREF VLR subscr unknown usage increases to: 1
+DVLR set IMSI on subscriber; IMSI=901700000004620 id=901700000004620
+DVLR New subscr, IMSI: 901700000004620
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DREF VLR subscr IMSI:901700000004620 usage decreases to: 1
+DMSC msc_tx 3 bytes to IMSI:901700000004620 via RAN_GERAN_A
+- DTAP --RAN_GERAN_A--> MS: GSM48_MT_MM_ID_REQ: 051803
+- DTAP matches expected message
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_IMEISV
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF IMSI:901700000004620: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+- MS replies with an Identity Response, causes LU to commence with a GSUP LU request to HLR
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_ID_RESP
+DREF IMSI:901700000004620: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_ID_RESP (0x5:0x19)
+DMM IDENTITY RESPONSE: MI(IMEI-SV)=4234234234234275
+DVLR set IMEISV on subscriber; IMSI=901700000004620 IMEISV=4234234234234275
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_IMEISV}: Received Event VLR_ULA_E_ID_IMEISV
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_IMEISV}: vlr_loc_upd_node1()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_IMEISV}: vlr_loc_upd_post_auth()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_IMEISV}: vlr_loc_upd_post_ciph()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_IMEISV}: vlr_loc_upd_node_4()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_IMEISV}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: Allocated
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START
+DVLR GSUP tx: 04010809710000004026f0280102
+GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000004026f0280102
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA
+DREF IMSI:901700000004620: MSC conn use - dtap == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  lu_result_sent == 0
+- Subscriber has the IMEISV from the ID Response
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+  strcmp(vsub->imeisv, "4234234234234275") == 0
+DREF VLR subscr IMSI:901700000004620 usage decreases to: 1
+- HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT
+<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: 10010809710000004026f00804036470f1
+DVLR GSUP rx 17: 10010809710000004026f00804036470f1
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DVLR IMSI:901700000004620 has MSISDN:46071
+DVLR SUBSCR(MSISDN:46071) VLR: update for IMSI=901700000004620 (MSISDN=46071, used=2)
+DVLR GSUP tx: 12010809710000004026f0
+GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000004026f0
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: vlr_gsupc_read_cb() returns 0
+  lu_result_sent == 0
+- having received subscriber data does not mean acceptance
+msc_subscr_conn_is_accepted() == false
+  requests shall be thwarted
+DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_CC_SETUP
+DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: unknown 0x33
+DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1
+DRLL Dispatching 04.08 message SMS:0x01 (0x9:0x1)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: SMS:0x01
+  lu_result_sent == 0
+- HLR also sends GSUP _UPDATE_LOCATION_RESULT
+<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: 06010809710000004026f0
+DVLR GSUP rx 11: 06010809710000004026f0
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Freeing instance
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: Allocated
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: Allocated
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(LU:901700000004620)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(LU:901700000004620)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Freeing instance
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Deallocated
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL
+- sending LU Accept for MSISDN:46071
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_DONE
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Freeing instance
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_ACCEPTED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:46071: MSC conn use + release == 1 (0x100: release)
+DREF VLR subscr MSISDN:46071 usage increases to: 4
+DREF VLR subscr MSISDN:46071 usage decreases to: 3
+- BSSAP Clear --RAN_GERAN_A--> MS
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+<-- 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
+- BSS sends BSSMAP Clear Complete
+DREF MSISDN:46071: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Freeing instance
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Deallocated
+DRLL MSISDN:46071: Freeing subscriber connection
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+---
+- subscriber detaches
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_IMSI_DETACH_IND
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_IMSI_DETACH_IND (0x5:0x1)
+DMM IMSI DETACH INDICATION: MI(IMSI)=901700000004620
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+DMM IMSI DETACH for MSISDN:46071
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+DREF VLR subscr MSISDN:46071 usage decreases to: 0
+DREF freeing VLR subscr MSISDN:46071
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_CN_CLOSE
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF unknown: MSC conn use + release == 2 (0x101: compl_l3,release)
+- BSSAP Clear --RAN_GERAN_A--> MS
+DREF unknown: MSC conn use - compl_l3 == 1 (0x100: release)
+  bssap_clear_sent == 1
+- BSS sends BSSMAP Clear Complete
+DREF unknown: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DRLL Freeing subscriber connection with NULL subscriber
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+===== test_no_authen_imeisv: SUCCESS
+
+full talloc report on 'msgb' (total      0 bytes in   1 blocks)
+talloc_total_blocks(tall_bsc_ctx) == 12
+
+===== test_no_authen_imeisv_imei
+- Location Update request causes an IMEISV ID request back to the MS
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8)
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Updated ID
+DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000004620 type=IMSI ATTACH
+DMM LU/new-LAC: 1/23
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Allocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: is child of Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: rev=GSM net=GERAN (no Auth)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA
+DREF VLR subscr unknown usage increases to: 1
+DVLR set IMSI on subscriber; IMSI=901700000004620 id=901700000004620
+DVLR New subscr, IMSI: 901700000004620
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DREF VLR subscr IMSI:901700000004620 usage decreases to: 1
+DMSC msc_tx 3 bytes to IMSI:901700000004620 via RAN_GERAN_A
+- DTAP --RAN_GERAN_A--> MS: GSM48_MT_MM_ID_REQ: 051803
+- DTAP matches expected message
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_IMEISV
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF IMSI:901700000004620: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+- MS replies with an Identity Response, causes LU to commence with a GSUP LU request to HLR
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_ID_RESP
+DREF IMSI:901700000004620: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_ID_RESP (0x5:0x19)
+DMM IDENTITY RESPONSE: MI(IMEI-SV)=4234234234234275
+DVLR set IMEISV on subscriber; IMSI=901700000004620 IMEISV=4234234234234275
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_IMEISV}: Received Event VLR_ULA_E_ID_IMEISV
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_IMEISV}: vlr_loc_upd_node1()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_IMEISV}: vlr_loc_upd_post_auth()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_IMEISV}: vlr_loc_upd_post_ciph()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_IMEISV}: vlr_loc_upd_node_4()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_IMEISV}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: Allocated
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START
+DVLR GSUP tx: 04010809710000004026f0280102
+GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000004026f0280102
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA
+DREF IMSI:901700000004620: MSC conn use - dtap == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  lu_result_sent == 0
+- Subscriber has the IMEISV from the ID Response
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+  strcmp(vsub->imeisv, "4234234234234275") == 0
+DREF VLR subscr IMSI:901700000004620 usage decreases to: 1
+- HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT
+<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: 10010809710000004026f00804036470f1
+DVLR GSUP rx 17: 10010809710000004026f00804036470f1
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DVLR IMSI:901700000004620 has MSISDN:46071
+DVLR SUBSCR(MSISDN:46071) VLR: update for IMSI=901700000004620 (MSISDN=46071, used=2)
+DVLR GSUP tx: 12010809710000004026f0
+GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000004026f0
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: vlr_gsupc_read_cb() returns 0
+  lu_result_sent == 0
+- having received subscriber data does not mean acceptance
+msc_subscr_conn_is_accepted() == false
+  requests shall be thwarted
+DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_CC_SETUP
+DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: unknown 0x33
+DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1
+DRLL Dispatching 04.08 message SMS:0x01 (0x9:0x1)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: SMS:0x01
+  lu_result_sent == 0
+- HLR also sends GSUP _UPDATE_LOCATION_RESULT, and we send an ID Request for the IMEI to the MS
+<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: 06010809710000004026f0
+DVLR GSUP rx 11: 06010809710000004026f0
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Freeing instance
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: Allocated
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: Allocated
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(LU:901700000004620)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(LU:901700000004620)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Freeing instance
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Deallocated
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_WAIT_IMEI
+DMSC msc_tx 3 bytes to MSISDN:46071 via RAN_GERAN_A
+- DTAP --RAN_GERAN_A--> MS: GSM48_MT_MM_ID_REQ: 051802
+- DTAP matches expected message
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: vlr_gsupc_read_cb() returns 0
+- We will only do business when the IMEI is known
+  llist_count(&net->subscr_conns) == 1
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+  vsub->imei[0] == 0
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+msc_subscr_conn_is_accepted() == false
+  requests shall be thwarted
+DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_CC_SETUP
+DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: unknown 0x33
+DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1
+DRLL Dispatching 04.08 message SMS:0x01 (0x9:0x1)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: SMS:0x01
+- MS replies with an Identity Response
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_ID_RESP
+DREF MSISDN:46071: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_ID_RESP (0x5:0x19)
+DMM IDENTITY RESPONSE: MI(IMEI)=423423423423420
+DVLR set IMEI on subscriber; IMSI=901700000004620 IMEI=423423423423420
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_ID_IMEI
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_IMEI}: Received Event LU_COMPL_VLR_E_IMEI_CHECK_ACK
+- sending LU Accept for MSISDN:46071
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_IMEI}: state_chg to LU_COMPL_VLR_S_DONE
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Freeing instance
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_ACCEPTED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:46071: MSC conn use + release == 2 (0x102: dtap,release)
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+- BSSAP Clear --RAN_GERAN_A--> MS
+DREF MSISDN:46071: MSC conn use - dtap == 1 (0x100: release)
+  bssap_clear_sent == 1
+- LU was successful, and the conn has already been closed
+  lu_result_sent == 1
+- BSS sends BSSMAP Clear Complete
+DREF MSISDN:46071: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Freeing instance
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Deallocated
+DRLL MSISDN:46071: Freeing subscriber connection
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+- Subscriber has the IMEI
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+  strcmp(vsub->imei, "423423423423420") == 0
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+---
+- subscriber detaches
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_IMSI_DETACH_IND
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_IMSI_DETACH_IND (0x5:0x1)
+DMM IMSI DETACH INDICATION: MI(IMSI)=901700000004620
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+DMM IMSI DETACH for MSISDN:46071
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+DREF VLR subscr MSISDN:46071 usage decreases to: 0
+DREF freeing VLR subscr MSISDN:46071
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_CN_CLOSE
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF unknown: MSC conn use + release == 2 (0x101: compl_l3,release)
+- BSSAP Clear --RAN_GERAN_A--> MS
+DREF unknown: MSC conn use - compl_l3 == 1 (0x100: release)
+  bssap_clear_sent == 1
+- BSS sends BSSMAP Clear Complete
+DREF unknown: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DRLL Freeing subscriber connection with NULL subscriber
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+===== test_no_authen_imeisv_imei: SUCCESS
+
+full talloc report on 'msgb' (total      0 bytes in   1 blocks)
+talloc_total_blocks(tall_bsc_ctx) == 12
+
+===== test_no_authen_imeisv_tmsi
+- Location Update request causes an IMEISV ID request back to the MS
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8)
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Updated ID
+DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000004620 type=IMSI ATTACH
+DMM LU/new-LAC: 1/23
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Allocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: is child of Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: rev=GSM net=GERAN (no Auth)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA
+DREF VLR subscr unknown usage increases to: 1
+DVLR set IMSI on subscriber; IMSI=901700000004620 id=901700000004620
+DVLR New subscr, IMSI: 901700000004620
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DREF VLR subscr IMSI:901700000004620 usage decreases to: 1
+DMSC msc_tx 3 bytes to IMSI:901700000004620 via RAN_GERAN_A
+- DTAP --RAN_GERAN_A--> MS: GSM48_MT_MM_ID_REQ: 051803
+- DTAP matches expected message
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_IMEISV
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF IMSI:901700000004620: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+- MS replies with an Identity Response, causes LU to commence with a GSUP LU request to HLR
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_ID_RESP
+DREF IMSI:901700000004620: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_ID_RESP (0x5:0x19)
+DMM IDENTITY RESPONSE: MI(IMEI-SV)=4234234234234275
+DVLR set IMEISV on subscriber; IMSI=901700000004620 IMEISV=4234234234234275
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_IMEISV}: Received Event VLR_ULA_E_ID_IMEISV
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_IMEISV}: vlr_loc_upd_node1()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_IMEISV}: vlr_loc_upd_post_auth()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_IMEISV}: vlr_loc_upd_post_ciph()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_IMEISV}: vlr_loc_upd_node_4()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_IMEISV}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: Allocated
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START
+DVLR GSUP tx: 04010809710000004026f0280102
+GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000004026f0280102
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA
+DREF IMSI:901700000004620: MSC conn use - dtap == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  lu_result_sent == 0
+- Subscriber has the IMEISV from the ID Response
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+  strcmp(vsub->imeisv, "4234234234234275") == 0
+DREF VLR subscr IMSI:901700000004620 usage decreases to: 1
+- HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT
+<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: 10010809710000004026f00804036470f1
+DVLR GSUP rx 17: 10010809710000004026f00804036470f1
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DVLR IMSI:901700000004620 has MSISDN:46071
+DVLR SUBSCR(MSISDN:46071) VLR: update for IMSI=901700000004620 (MSISDN=46071, used=2)
+DVLR GSUP tx: 12010809710000004026f0
+GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000004026f0
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: vlr_gsupc_read_cb() returns 0
+  lu_result_sent == 0
+- having received subscriber data does not mean acceptance
+msc_subscr_conn_is_accepted() == false
+  requests shall be thwarted
+DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_CC_SETUP
+DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: unknown 0x33
+DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1
+DRLL Dispatching 04.08 message SMS:0x01 (0x9:0x1)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: SMS:0x01
+  lu_result_sent == 0
+- HLR also sends GSUP _UPDATE_LOCATION_RESULT
+<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: 06010809710000004026f0
+DVLR GSUP rx 11: 06010809710000004026f0
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Freeing instance
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: Allocated
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: Allocated
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(LU:901700000004620)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(LU:901700000004620)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Freeing instance
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Deallocated
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: lu_compl_vlr_new_tmsi()
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_WAIT_TMSI_CNF
+- sending LU Accept for MSISDN:46071, with TMSI 0x03020100
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: vlr_gsupc_read_cb() returns 0
+- a LU Accept with a new TMSI was sent, waiting for TMSI Realloc Compl
+  llist_count(&net->subscr_conns) == 1
+  lu_result_sent == 1
+msc_subscr_conn_is_accepted() == false
+  requests shall be thwarted
+DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_CC_SETUP
+DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: unknown 0x33
+DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1
+DRLL Dispatching 04.08 message SMS:0x01 (0x9:0x1)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: SMS:0x01
+- even though the TMSI is not acked, we can already find the subscr with it
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+  vsub != NULL == 1
+  strcmp(vsub->imsi, imsi) == 0
+  vsub->tmsi_new == 0x03020100
+  vsub->tmsi == 0xffffffff
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+- MS sends TMSI Realloc Complete
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_TMSI_REALL_COMPL
+DREF MSISDN:46071: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_TMSI_REALL_COMPL (0x5:0x1b)
+DMM TMSI Reallocation Completed. Subscriber: MSISDN:46071
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_NEW_TMSI_ACK
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_TMSI_CNF}: Received Event LU_COMPL_VLR_E_NEW_TMSI_ACK
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_TMSI_CNF}: state_chg to LU_COMPL_VLR_S_DONE
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Freeing instance
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_ACCEPTED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:46071: MSC conn use + release == 2 (0x102: dtap,release)
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+- BSSAP Clear --RAN_GERAN_A--> MS
+DREF MSISDN:46071: MSC conn use - dtap == 1 (0x100: release)
+  bssap_clear_sent == 1
+- LU was successful, and the conn has already been closed
+- BSS sends BSSMAP Clear Complete
+DREF MSISDN:46071: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Freeing instance
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Deallocated
+DRLL MSISDN:46071: Freeing subscriber connection
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+---
+- subscriber sends LU Request, this time with the TMSI
+- Location Update request causes an IMEISV ID request back to the MS
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8)
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Updated ID
+DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000004620 type=IMSI ATTACH
+DMM LU/new-LAC: 1/23
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Allocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: is child of Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: rev=GSM net=GERAN (no Auth)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+DMSC msc_tx 3 bytes to MSISDN:46071 via RAN_GERAN_A
+- DTAP --RAN_GERAN_A--> MS: GSM48_MT_MM_ID_REQ: 051803
+- DTAP matches expected message
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_IMEISV
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF MSISDN:46071: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+- MS replies with an Identity Response, causes LU to commence with a GSUP LU request to HLR
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_ID_RESP
+DREF MSISDN:46071: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_ID_RESP (0x5:0x19)
+DMM IDENTITY RESPONSE: MI(IMEI-SV)=5234234234234276
+DVLR set IMEISV on subscriber; IMSI=901700000004620 IMEISV=5234234234234276
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_IMEISV}: Received Event VLR_ULA_E_ID_IMEISV
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_IMEISV}: vlr_loc_upd_node1()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_IMEISV}: vlr_loc_upd_post_auth()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_IMEISV}: vlr_loc_upd_post_ciph()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_IMEISV}: vlr_loc_upd_node_4()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_IMEISV}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: Allocated
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START
+DVLR GSUP tx: 04010809710000004026f0280102
+GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000004026f0280102
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA
+DREF MSISDN:46071: MSC conn use - dtap == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  lu_result_sent == 0
+- Subscriber has the IMEISV from the ID Response
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+  strcmp(vsub->imeisv, "5234234234234276") == 0
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+- HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT
+<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: 10010809710000004026f00804036470f1
+DVLR GSUP rx 17: 10010809710000004026f00804036470f1
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DVLR IMSI:901700000004620 has MSISDN:46071
+DVLR SUBSCR(MSISDN:46071) VLR: update for IMSI=901700000004620 (MSISDN=46071, used=3)
+DVLR GSUP tx: 12010809710000004026f0
+GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000004026f0
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: vlr_gsupc_read_cb() returns 0
+  lu_result_sent == 0
+- having received subscriber data does not mean acceptance
+msc_subscr_conn_is_accepted() == false
+  requests shall be thwarted
+DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_CC_SETUP
+DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: unknown 0x33
+DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1
+DRLL Dispatching 04.08 message SMS:0x01 (0x9:0x1)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: SMS:0x01
+  lu_result_sent == 0
+- HLR also sends GSUP _UPDATE_LOCATION_RESULT
+<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: 06010809710000004026f0
+DVLR GSUP rx 11: 06010809710000004026f0
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Freeing instance
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: Allocated
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: Allocated
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(LU:901700000004620)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(LU:901700000004620)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Freeing instance
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Deallocated
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: lu_compl_vlr_new_tmsi()
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_WAIT_TMSI_CNF
+- sending LU Accept for MSISDN:46071, with TMSI 0x07060504
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: vlr_gsupc_read_cb() returns 0
+- a LU Accept with a new TMSI was sent, waiting for TMSI Realloc Compl
+  llist_count(&net->subscr_conns) == 1
+  lu_result_sent == 1
+msc_subscr_conn_is_accepted() == false
+  requests shall be thwarted
+DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_CC_SETUP
+DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: unknown 0x33
+DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1
+DRLL Dispatching 04.08 message SMS:0x01 (0x9:0x1)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: SMS:0x01
+- even though the TMSI is not acked, we can already find the subscr with it
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+  vsub != NULL == 1
+  strcmp(vsub->imsi, imsi) == 0
+  vsub->tmsi_new == 0x07060504
+  vsub->tmsi == 0x03020100
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+- MS sends TMSI Realloc Complete
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_TMSI_REALL_COMPL
+DREF MSISDN:46071: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_TMSI_REALL_COMPL (0x5:0x1b)
+DMM TMSI Reallocation Completed. Subscriber: MSISDN:46071
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_NEW_TMSI_ACK
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_TMSI_CNF}: Received Event LU_COMPL_VLR_E_NEW_TMSI_ACK
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_TMSI_CNF}: state_chg to LU_COMPL_VLR_S_DONE
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Freeing instance
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_ACCEPTED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:46071: MSC conn use + release == 2 (0x102: dtap,release)
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+- BSSAP Clear --RAN_GERAN_A--> MS
+DREF MSISDN:46071: MSC conn use - dtap == 1 (0x100: release)
+  bssap_clear_sent == 1
+- LU was successful, and the conn has already been closed
+- BSS sends BSSMAP Clear Complete
+DREF MSISDN:46071: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Freeing instance
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Deallocated
+DRLL MSISDN:46071: Freeing subscriber connection
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+- subscriber has the new TMSI
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+  vsub != NULL == 1
+  strcmp(vsub->imsi, imsi) == 0
+  vsub->tmsi_new == 0xffffffff
+  vsub->tmsi == 0x07060504
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+---
+- subscriber detaches, using new TMSI
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_IMSI_DETACH_IND
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_IMSI_DETACH_IND (0x5:0x1)
+DMM IMSI DETACH INDICATION: MI(TMSI)=117835012
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+DMM IMSI DETACH for MSISDN:46071
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+DREF VLR subscr MSISDN:46071 usage decreases to: 0
+DREF freeing VLR subscr MSISDN:46071
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_CN_CLOSE
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF unknown: MSC conn use + release == 2 (0x101: compl_l3,release)
+- BSSAP Clear --RAN_GERAN_A--> MS
+DREF unknown: MSC conn use - compl_l3 == 1 (0x100: release)
+  bssap_clear_sent == 1
+- BSS sends BSSMAP Clear Complete
+DREF unknown: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DRLL Freeing subscriber connection with NULL subscriber
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+===== test_no_authen_imeisv_tmsi: SUCCESS
+
+full talloc report on 'msgb' (total      0 bytes in   1 blocks)
+talloc_total_blocks(tall_bsc_ctx) == 12
+
+===== test_no_authen_imeisv_tmsi_imei
+- Location Update request causes an IMEISV ID request back to the MS
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8)
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Updated ID
+DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000004620 type=IMSI ATTACH
+DMM LU/new-LAC: 1/23
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Allocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: is child of Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: rev=GSM net=GERAN (no Auth)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA
+DREF VLR subscr unknown usage increases to: 1
+DVLR set IMSI on subscriber; IMSI=901700000004620 id=901700000004620
+DVLR New subscr, IMSI: 901700000004620
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DREF VLR subscr IMSI:901700000004620 usage decreases to: 1
+DMSC msc_tx 3 bytes to IMSI:901700000004620 via RAN_GERAN_A
+- DTAP --RAN_GERAN_A--> MS: GSM48_MT_MM_ID_REQ: 051803
+- DTAP matches expected message
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_IMEISV
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF IMSI:901700000004620: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+- MS replies with an Identity Response, causes LU to commence with a GSUP LU request to HLR
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_ID_RESP
+DREF IMSI:901700000004620: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_ID_RESP (0x5:0x19)
+DMM IDENTITY RESPONSE: MI(IMEI-SV)=4234234234234275
+DVLR set IMEISV on subscriber; IMSI=901700000004620 IMEISV=4234234234234275
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_IMEISV}: Received Event VLR_ULA_E_ID_IMEISV
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_IMEISV}: vlr_loc_upd_node1()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_IMEISV}: vlr_loc_upd_post_auth()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_IMEISV}: vlr_loc_upd_post_ciph()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_IMEISV}: vlr_loc_upd_node_4()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_IMEISV}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: Allocated
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START
+DVLR GSUP tx: 04010809710000004026f0280102
+GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000004026f0280102
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA
+DREF IMSI:901700000004620: MSC conn use - dtap == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  lu_result_sent == 0
+- Subscriber has the IMEISV from the ID Response
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+  strcmp(vsub->imeisv, "4234234234234275") == 0
+DREF VLR subscr IMSI:901700000004620 usage decreases to: 1
+- HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT
+<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: 10010809710000004026f00804036470f1
+DVLR GSUP rx 17: 10010809710000004026f00804036470f1
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DVLR IMSI:901700000004620 has MSISDN:46071
+DVLR SUBSCR(MSISDN:46071) VLR: update for IMSI=901700000004620 (MSISDN=46071, used=2)
+DVLR GSUP tx: 12010809710000004026f0
+GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000004026f0
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: vlr_gsupc_read_cb() returns 0
+  lu_result_sent == 0
+- having received subscriber data does not mean acceptance
+msc_subscr_conn_is_accepted() == false
+  requests shall be thwarted
+DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_CC_SETUP
+DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: unknown 0x33
+DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1
+DRLL Dispatching 04.08 message SMS:0x01 (0x9:0x1)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: SMS:0x01
+  lu_result_sent == 0
+- HLR also sends GSUP _UPDATE_LOCATION_RESULT, and we send an ID Request for the IMEI to the MS
+<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: 06010809710000004026f0
+DVLR GSUP rx 11: 06010809710000004026f0
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Freeing instance
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: Allocated
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: Allocated
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(LU:901700000004620)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(LU:901700000004620)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Freeing instance
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Deallocated
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_WAIT_IMEI_TMSI
+DMSC msc_tx 3 bytes to MSISDN:46071 via RAN_GERAN_A
+- DTAP --RAN_GERAN_A--> MS: GSM48_MT_MM_ID_REQ: 051802
+- DTAP matches expected message
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: vlr_gsupc_read_cb() returns 0
+- We will only do business when the IMEI is known
+  llist_count(&net->subscr_conns) == 1
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+  vsub->imei[0] == 0
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+msc_subscr_conn_is_accepted() == false
+  requests shall be thwarted
+DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_CC_SETUP
+DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: unknown 0x33
+DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1
+DRLL Dispatching 04.08 message SMS:0x01 (0x9:0x1)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: SMS:0x01
+- MS replies with an Identity Response
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_ID_RESP
+DREF MSISDN:46071: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_ID_RESP (0x5:0x19)
+DMM IDENTITY RESPONSE: MI(IMEI)=423423423423420
+DVLR set IMEI on subscriber; IMSI=901700000004620 IMEI=423423423423420
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_ID_IMEI
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_IMEI_TMSI}: Received Event LU_COMPL_VLR_E_IMEI_CHECK_ACK
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_IMEI_TMSI}: lu_compl_vlr_new_tmsi()
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_IMEI_TMSI}: state_chg to LU_COMPL_VLR_S_WAIT_TMSI_CNF
+- sending LU Accept for MSISDN:46071, with TMSI 0x03020100
+DREF MSISDN:46071: MSC conn use - dtap == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+- a LU Accept with a new TMSI was sent, waiting for TMSI Realloc Compl
+  llist_count(&net->subscr_conns) == 1
+  lu_result_sent == 1
+msc_subscr_conn_is_accepted() == false
+  requests shall be thwarted
+DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_CC_SETUP
+DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: unknown 0x33
+DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1
+DRLL Dispatching 04.08 message SMS:0x01 (0x9:0x1)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: SMS:0x01
+- MS sends TMSI Realloc Complete
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_TMSI_REALL_COMPL
+DREF MSISDN:46071: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_TMSI_REALL_COMPL (0x5:0x1b)
+DMM TMSI Reallocation Completed. Subscriber: MSISDN:46071
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_NEW_TMSI_ACK
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_TMSI_CNF}: Received Event LU_COMPL_VLR_E_NEW_TMSI_ACK
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_TMSI_CNF}: state_chg to LU_COMPL_VLR_S_DONE
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Freeing instance
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_ACCEPTED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:46071: MSC conn use + release == 2 (0x102: dtap,release)
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+- BSSAP Clear --RAN_GERAN_A--> MS
+DREF MSISDN:46071: MSC conn use - dtap == 1 (0x100: release)
+  bssap_clear_sent == 1
+- LU was successful, and the conn has already been closed
+  lu_result_sent == 1
+- BSS sends BSSMAP Clear Complete
+DREF MSISDN:46071: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Freeing instance
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Deallocated
+DRLL MSISDN:46071: Freeing subscriber connection
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+- Subscriber has the IMEISV, IMEI and TMSI
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+  strcmp(vsub->imeisv, "4234234234234275") == 0
+  strcmp(vsub->imei, "423423423423420") == 0
+  vsub->tmsi == 0x03020100
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+---
+- subscriber detaches
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_IMSI_DETACH_IND
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_IMSI_DETACH_IND (0x5:0x1)
+DMM IMSI DETACH INDICATION: MI(IMSI)=901700000004620
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+DMM IMSI DETACH for MSISDN:46071
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+DREF VLR subscr MSISDN:46071 usage decreases to: 0
+DREF freeing VLR subscr MSISDN:46071
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_CN_CLOSE
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF unknown: MSC conn use + release == 2 (0x101: compl_l3,release)
+- BSSAP Clear --RAN_GERAN_A--> MS
+DREF unknown: MSC conn use - compl_l3 == 1 (0x100: release)
+  bssap_clear_sent == 1
+- BSS sends BSSMAP Clear Complete
+DREF unknown: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DRLL Freeing subscriber connection with NULL subscriber
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 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) == 12
+
+===== test_no_authen_subscr_expire
+- Total time passed: 0.000000 s
+- Total time passed: 61.000000 s
+- Location Update request causes a GSUP LU request to HLR
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8)
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Updated ID
+DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000004620 type=IMSI ATTACH
+DMM LU/new-LAC: 1/23
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Allocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: is child of Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: rev=GSM net=GERAN (no Auth)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA
+DREF VLR subscr unknown usage increases to: 1
+DVLR set IMSI on subscriber; IMSI=901700000004620 id=901700000004620
+DVLR New subscr, IMSI: 901700000004620
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DREF VLR subscr IMSI:901700000004620 usage decreases to: 1
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_post_auth()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_post_ciph()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node_4()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: Allocated
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START
+DVLR GSUP tx: 04010809710000004026f0280102
+GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000004026f0280102
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF IMSI:901700000004620: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  lu_result_sent == 0
+- HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT
+<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: 10010809710000004026f00804036470f1
+DVLR GSUP rx 17: 10010809710000004026f00804036470f1
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DVLR IMSI:901700000004620 has MSISDN:46071
+DVLR SUBSCR(MSISDN:46071) VLR: update for IMSI=901700000004620 (MSISDN=46071, used=2)
+DVLR GSUP tx: 12010809710000004026f0
+GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000004026f0
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+<-- 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: 06010809710000004026f0
+DVLR GSUP rx 11: 06010809710000004026f0
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Freeing instance
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: Allocated
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: Allocated
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(LU:901700000004620)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(LU:901700000004620)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Freeing instance
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Deallocated
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL
+- sending LU Accept for MSISDN:46071
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_DONE
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Freeing instance
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_ACCEPTED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:46071: MSC conn use + release == 1 (0x100: release)
+DREF VLR subscr MSISDN:46071 usage increases to: 4
+DREF VLR subscr MSISDN:46071 usage decreases to: 3
+- BSSAP Clear --RAN_GERAN_A--> MS
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+<-- 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
+- BSS sends BSSMAP Clear Complete
+DREF MSISDN:46071: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Freeing instance
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Deallocated
+DRLL MSISDN:46071: Freeing subscriber connection
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+- Total time passed: 3901.000000 s
+DVLR MSISDN:46071: Location Update expired
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+DREF VLR subscr MSISDN:46071 usage decreases to: 0
+DREF freeing VLR subscr MSISDN:46071
+  llist_count(&net->subscr_conns) == 0
+===== test_no_authen_subscr_expire: SUCCESS
+
+full talloc report on 'msgb' (total      0 bytes in   1 blocks)
+talloc_total_blocks(tall_bsc_ctx) == 12
+
+full talloc report on 'msgb' (total      0 bytes in   1 blocks)
+talloc_total_blocks(tall_bsc_ctx) == 12
+
diff --git a/tests/msc_vlr/msc_vlr_test_no_authen.ok b/tests/msc_vlr/msc_vlr_test_no_authen.ok
new file mode 100644
index 0000000..a965a70
--- /dev/null
+++ b/tests/msc_vlr/msc_vlr_test_no_authen.ok
@@ -0,0 +1 @@
+Done
diff --git a/tests/msc_vlr/msc_vlr_test_reject_concurrency.c b/tests/msc_vlr/msc_vlr_test_reject_concurrency.c
new file mode 100644
index 0000000..d206571
--- /dev/null
+++ b/tests/msc_vlr/msc_vlr_test_reject_concurrency.c
@@ -0,0 +1,406 @@
+/* Osmocom MSC+VLR end-to-end tests */
+
+/* (C) 2017 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>
+ *
+ * All Rights Reserved
+ *
+ * Author: Neels Hofmeyr <nhofmeyr@sysmocom.de>
+ *
+ * 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 "msc_vlr_tests.h"
+
+static void test_reject_2nd_conn()
+{
+	struct gsm_subscriber_connection *conn1;
+	comment_start();
+
+	btw("Location Update Request on one connection");
+	lu_result_sent = RES_NONE;
+	gsup_expect_tx("04010809710000004026f0280102");
+	ms_sends_msg("050802008168000130089910070000006402");
+	OSMO_ASSERT(gsup_tx_confirmed);
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+	EXPECT_CONN_COUNT(1);
+
+	btw("Another Location Update Request from the same subscriber on another connection is rejected");
+	conn1 = g_conn;
+	g_conn = NULL;
+	expect_bssap_clear();
+	ms_sends_msg("050802008168000130089910070000006402");
+	VERBOSE_ASSERT(bssap_clear_sent, == true, "%d");
+	VERBOSE_ASSERT(lu_result_sent, == RES_REJECT, "%d");
+	bss_sends_clear_complete();
+	EXPECT_CONN_COUNT(1);
+
+
+	BTW("The first connection can still complete its LU");
+	btw("HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT");
+	g_conn = conn1;
+	lu_result_sent = RES_NONE;
+	gsup_rx("10010809710000004026f00804036470f1",
+		"12010809710000004026f0");
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("HLR also sends GSUP _UPDATE_LOCATION_RESULT");
+	expect_bssap_clear();
+	gsup_rx("06010809710000004026f0", NULL);
+	VERBOSE_ASSERT(bssap_clear_sent, == true, "%d");
+
+	btw("LU was successful, and the conn has already been closed");
+	VERBOSE_ASSERT(lu_result_sent, == RES_ACCEPT, "%d");
+	bss_sends_clear_complete();
+	EXPECT_CONN_COUNT(0);
+
+	clear_vlr();
+	comment_end();
+}
+
+static void _normal_lu_part1()
+{
+	btw("Location Update Request");
+	lu_result_sent = RES_NONE;
+	gsup_expect_tx("04010809710000004026f0280102");
+	ms_sends_msg("050802008168000130089910070000006402");
+	OSMO_ASSERT(gsup_tx_confirmed);
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+	EXPECT_CONN_COUNT(1);
+}
+
+static void _normal_lu_part2()
+{
+	btw("HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT");
+	lu_result_sent = RES_NONE;
+	gsup_rx("10010809710000004026f00804036470f1",
+		"12010809710000004026f0");
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("HLR also sends GSUP _UPDATE_LOCATION_RESULT");
+	expect_bssap_clear();
+	gsup_rx("06010809710000004026f0", NULL);
+	VERBOSE_ASSERT(bssap_clear_sent, == true, "%d");
+
+	btw("LU was successful, and the conn has already been closed");
+	VERBOSE_ASSERT(lu_result_sent, == RES_ACCEPT, "%d");
+	bss_sends_clear_complete();
+	EXPECT_CONN_COUNT(0);
+}
+
+static void _normal_lu()
+{
+	BTW("Subscriber does a normal LU");
+	_normal_lu_part1();
+	_normal_lu_part2();
+}
+
+static void _normal_cm_service_req()
+{
+	BTW("Subscriber does a normal CM Service Request");
+	cm_service_result_sent = RES_NONE;
+	ms_sends_msg("05247803305886089910070000006402");
+	OSMO_ASSERT(g_conn);
+	OSMO_ASSERT(g_conn->fi);
+	OSMO_ASSERT(g_conn->vsub);
+	VERBOSE_ASSERT(cm_service_result_sent, == RES_ACCEPT, "%d");
+	EXPECT_ACCEPTED(true);
+}
+
+static void _page()
+{
+	const char *imsi = "901700000004620";
+	struct vlr_subscr *vsub;
+
+	BTW("an SMS is sent, MS is paged");
+	paging_expect_imsi(imsi);
+	paging_sent = false;
+	vsub = vlr_subscr_find_by_imsi(net->vlr, imsi);
+	OSMO_ASSERT(vsub);
+	VERBOSE_ASSERT(llist_count(&vsub->cs.requests), == 0, "%d");
+
+	send_sms(vsub, vsub,
+		 "Privacy in residential applications is a desirable"
+		 " marketing option.");
+
+	VERBOSE_ASSERT(llist_count(&vsub->cs.requests), == 1, "%d");
+	vlr_subscr_put(vsub);
+	vsub = NULL;
+	VERBOSE_ASSERT(paging_sent, == true, "%d");
+	VERBOSE_ASSERT(paging_stopped, == false, "%d");
+}
+
+static void _paging_resp_part1()
+{
+	btw("MS replies with Paging Response, we deliver the SMS");
+	dtap_expect_tx("09" /* SMS messages */
+		       "01" /* CP-DATA */
+		       "58" /* length */
+		       "01" /* Network to MS */
+		       "00" /* reference */
+		       /* originator (gsm411_send_sms() hardcodes this weird nr) */
+		       "0791" "447758100650" /* 447785016005 */
+		       "00" /* dest */
+		       /* SMS TPDU */
+		       "4c" /* len */
+		       "00" /* SMS deliver */
+		       "05806470f1" /* originating address 46071 */
+		       "00" /* TP-PID */
+		       "00" /* GSM default alphabet */
+		       "071010" /* Y-M-D (from wrapped gsm340_gen_scts())*/
+		       "000000" /* H-M-S */
+		       "00" /* GMT+0 */
+		       "44" /* data length */
+		       "5079da1e1ee7416937485e9ea7c965373d1d6683c270383b3d0e"
+		       "d3d36ff71c949e83c22072799e9687c5ec32a81d96afcbf4b4fb"
+		       "0c7ac3e9e9b7db05");
+	ms_sends_msg("06270703305882089910070000006402");
+	VERBOSE_ASSERT(dtap_tx_confirmed, == true, "%d");
+	VERBOSE_ASSERT(paging_stopped, == true, "%d");
+
+	btw("conn is still open to wait for SMS ack dance");
+	EXPECT_CONN_COUNT(1);
+}
+
+static void _paging_resp_part2(int expect_conn_count, bool expect_clear)
+{
+	btw("MS replies with CP-ACK for received SMS");
+	ms_sends_msg("8904");
+	EXPECT_CONN_COUNT(1);
+
+	btw("MS also sends RP-ACK, MSC in turn sends CP-ACK for that");
+	dtap_expect_tx("0904");
+	if (expect_clear)
+		expect_bssap_clear();
+	ms_sends_msg("890106020041020000");
+	VERBOSE_ASSERT(dtap_tx_confirmed, == true, "%d");
+	if (expect_clear) {
+		VERBOSE_ASSERT(bssap_clear_sent, == true, "%d");
+		bss_sends_clear_complete();
+	}
+
+	btw("SMS is done");
+	EXPECT_CONN_COUNT(expect_conn_count);
+}
+
+static void test_reject_lu_during_lu()
+{
+	comment_start();
+
+	_normal_lu_part1();
+
+	BTW("Another Location Update Request from the same subscriber on the same conn is dropped silently");
+	ms_sends_msg("050802008168000130089910070000006402");
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+	EXPECT_CONN_COUNT(1);
+
+	BTW("The first LU can still complete");
+	_normal_lu_part2();
+
+	clear_vlr();
+	comment_end();
+}
+
+static void test_reject_cm_during_lu()
+{
+	comment_start();
+
+	_normal_lu_part1();
+
+	BTW("A CM Service Request in the middle of a LU is rejected");
+	cm_service_result_sent = RES_NONE;
+	dtap_expect_tx("052216");
+	ms_sends_msg("05247803305886089910070000006402");
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+	VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d");
+	VERBOSE_ASSERT(dtap_tx_confirmed, == true, "%d");
+	EXPECT_CONN_COUNT(1);
+
+	BTW("The first LU can still complete");
+	_normal_lu_part2();
+
+	clear_vlr();
+	comment_end();
+}
+
+static void test_reject_paging_resp_during_lu()
+{
+	comment_start();
+
+	_normal_lu_part1();
+
+	BTW("An erratic Paging Response is dropped silently");
+	ms_sends_msg("06270703305882089910070000006402");
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+	EXPECT_CONN_COUNT(1);
+
+	BTW("The first LU can still complete");
+	_normal_lu_part2();
+
+	clear_vlr();
+	comment_end();
+}
+
+static void test_reject_lu_during_cm()
+{
+	comment_start();
+
+	_normal_lu();
+	_normal_cm_service_req();
+
+	btw("A LU request on an open conn is dropped silently");
+	/* TODO: accept periodic LU on an already open conn? */
+	lu_result_sent = RES_NONE;
+	ms_sends_msg("050802008168000130089910070000006402");
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+	EXPECT_CONN_COUNT(1);
+
+	BTW("subscriber detaches");
+	expect_bssap_clear();
+	ms_sends_msg("050130089910070000006402");
+	VERBOSE_ASSERT(bssap_clear_sent, == true, "%d");
+	bss_sends_clear_complete();
+	EXPECT_CONN_COUNT(0);
+
+	clear_vlr();
+	comment_end();
+}
+
+static void test_reject_cm_during_cm()
+{
+	comment_start();
+
+	_normal_lu();
+	_normal_cm_service_req();
+
+	btw("A second CM Service Request on the same conn is accepted without another auth dance");
+	cm_service_result_sent = RES_NONE;
+	ms_sends_msg("05247803305886089910070000006402");
+	VERBOSE_ASSERT(cm_service_result_sent, == RES_ACCEPT, "%d");
+	EXPECT_CONN_COUNT(1);
+
+	BTW("subscriber detaches");
+	expect_bssap_clear();
+	ms_sends_msg("050130089910070000006402");
+	VERBOSE_ASSERT(bssap_clear_sent, == true, "%d");
+	bss_sends_clear_complete();
+	EXPECT_CONN_COUNT(0);
+
+	clear_vlr();
+	comment_end();
+}
+
+static void test_reject_paging_resp_during_cm()
+{
+	comment_start();
+
+	_normal_lu();
+	_normal_cm_service_req();
+
+	BTW("An erratic Paging Response on the same conn is dropped silently");
+	ms_sends_msg("06270703305882089910070000006402");
+	EXPECT_CONN_COUNT(1);
+
+	BTW("The original CM Service Request can conclude");
+
+	/* Release connection */
+	expect_bssap_clear(RAN_GERAN_A);
+	conn_conclude_cm_service_req(g_conn, RAN_GERAN_A);
+
+	btw("all requests serviced, conn has been released");
+	bss_sends_clear_complete();
+	EXPECT_CONN_COUNT(0);
+
+	clear_vlr();
+	comment_end();
+}
+
+static void test_reject_paging_resp_during_paging_resp()
+{
+	comment_start();
+
+	_normal_lu();
+	_page();
+	_paging_resp_part1();
+
+	BTW("MS sends another erratic Paging Response which is dropped silently");
+	ms_sends_msg("06270703305882089910070000006402");
+
+	_paging_resp_part2(0, true);
+
+	clear_vlr();
+	comment_end();
+}
+
+static void test_reject_lu_during_paging_resp()
+{
+	comment_start();
+
+	_normal_lu();
+	_page();
+	_paging_resp_part1();
+
+	BTW("MS sends erratic LU Request, which is dropped silently");
+	lu_result_sent = RES_NONE;
+	ms_sends_msg("050802008168000130089910070000006402");
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+	EXPECT_CONN_COUNT(1);
+
+	_paging_resp_part2(0, true);
+
+	clear_vlr();
+	comment_end();
+}
+
+static void test_accept_cm_during_paging_resp()
+{
+	comment_start();
+
+	_normal_lu();
+	_page();
+	_paging_resp_part1();
+
+	BTW("CM Service Request during open connection is accepted");
+	cm_service_result_sent = RES_NONE;
+	ms_sends_msg("05247803305886089910070000006402");
+	VERBOSE_ASSERT(cm_service_result_sent, == RES_ACCEPT, "%d");
+	EXPECT_CONN_COUNT(1);
+	VERBOSE_ASSERT(g_conn->received_cm_service_request, == true, "%d");
+
+	_paging_resp_part2(1, false);
+
+	BTW("subscriber detaches");
+	expect_bssap_clear();
+	ms_sends_msg("050130089910070000006402");
+	VERBOSE_ASSERT(bssap_clear_sent, == true, "%d");
+	bss_sends_clear_complete();
+	EXPECT_CONN_COUNT(0);
+
+	clear_vlr();
+	comment_end();
+}
+
+msc_vlr_test_func_t msc_vlr_tests[] = {
+	test_reject_2nd_conn,
+	test_reject_lu_during_lu,
+	test_reject_cm_during_lu,
+	test_reject_paging_resp_during_lu,
+	test_reject_lu_during_cm,
+	test_reject_cm_during_cm,
+	test_reject_paging_resp_during_cm,
+	test_reject_lu_during_paging_resp,
+	test_accept_cm_during_paging_resp,
+	test_reject_paging_resp_during_paging_resp,
+	NULL
+};
diff --git a/tests/msc_vlr/msc_vlr_test_reject_concurrency.err b/tests/msc_vlr/msc_vlr_test_reject_concurrency.err
new file mode 100644
index 0000000..0a964ac
--- /dev/null
+++ b/tests/msc_vlr/msc_vlr_test_reject_concurrency.err
@@ -0,0 +1,1846 @@
+full talloc report on 'msgb' (total      0 bytes in   1 blocks)
+talloc_total_blocks(tall_bsc_ctx) == 12
+
+===== test_reject_2nd_conn
+- Location Update Request on one connection
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8)
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Updated ID
+DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000004620 type=IMSI ATTACH
+DMM LU/new-LAC: 1/23
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Allocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: is child of Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: rev=GSM net=GERAN (no Auth)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA
+DREF VLR subscr unknown usage increases to: 1
+DVLR set IMSI on subscriber; IMSI=901700000004620 id=901700000004620
+DVLR New subscr, IMSI: 901700000004620
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DREF VLR subscr IMSI:901700000004620 usage decreases to: 1
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_post_auth()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_post_ciph()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node_4()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: Allocated
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START
+DVLR GSUP tx: 04010809710000004026f0280102
+GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000004026f0280102
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF IMSI:901700000004620: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  lu_result_sent == 0
+  llist_count(&net->subscr_conns) == 1
+- Another Location Update Request from the same subscriber on another connection is rejected
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8)
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Updated ID
+DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000004620 type=IMSI ATTACH
+DMM LU/new-LAC: 1/23
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Allocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: is child of Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: rev=GSM net=GERAN (no Auth)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: A Location Updating process is already pending for this subscriber. Aborting.
+- sending LU Reject for unknown, cause 22
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_DONE
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_CN_CLOSE
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF unknown: MSC conn use + release == 2 (0x101: compl_l3,release)
+- BSSAP Clear --RAN_GERAN_A--> MS
+DREF VLR subscr IMSI:901700000004620 usage decreases to: 1
+DRR 901700000004620: internal error during Location Updating attempt
+DREF unknown: MSC conn use - compl_l3 == 1 (0x100: release)
+  bssap_clear_sent == 1
+  lu_result_sent == 2
+- BSS sends BSSMAP Clear Complete
+DREF unknown: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Freeing instance
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Deallocated
+DRLL Freeing subscriber connection with NULL subscriber
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 1
+---
+- The first connection can still complete its LU
+- HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT
+<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: 10010809710000004026f00804036470f1
+DVLR GSUP rx 17: 10010809710000004026f00804036470f1
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DVLR IMSI:901700000004620 has MSISDN:46071
+DVLR SUBSCR(MSISDN:46071) VLR: update for IMSI=901700000004620 (MSISDN=46071, used=2)
+DVLR GSUP tx: 12010809710000004026f0
+GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000004026f0
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+<-- 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: 06010809710000004026f0
+DVLR GSUP rx 11: 06010809710000004026f0
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Freeing instance
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: Allocated
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: Allocated
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(LU:901700000004620)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(LU:901700000004620)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Freeing instance
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Deallocated
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL
+- sending LU Accept for MSISDN:46071
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_DONE
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Freeing instance
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_ACCEPTED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:46071: MSC conn use + release == 1 (0x100: release)
+DREF VLR subscr MSISDN:46071 usage increases to: 4
+DREF VLR subscr MSISDN:46071 usage decreases to: 3
+- BSSAP Clear --RAN_GERAN_A--> MS
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+<-- 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
+  lu_result_sent == 1
+- BSS sends BSSMAP Clear Complete
+DREF MSISDN:46071: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Freeing instance
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Deallocated
+DRLL MSISDN:46071: Freeing subscriber connection
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+DREF freeing VLR subscr MSISDN:46071
+===== test_reject_2nd_conn: SUCCESS
+
+full talloc report on 'msgb' (total      0 bytes in   1 blocks)
+talloc_total_blocks(tall_bsc_ctx) == 12
+
+===== test_reject_lu_during_lu
+- Location Update Request
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8)
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Updated ID
+DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000004620 type=IMSI ATTACH
+DMM LU/new-LAC: 1/23
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Allocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: is child of Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: rev=GSM net=GERAN (no Auth)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA
+DREF VLR subscr unknown usage increases to: 1
+DVLR set IMSI on subscriber; IMSI=901700000004620 id=901700000004620
+DVLR New subscr, IMSI: 901700000004620
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DREF VLR subscr IMSI:901700000004620 usage decreases to: 1
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_post_auth()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_post_ciph()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node_4()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: Allocated
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START
+DVLR GSUP tx: 04010809710000004026f0280102
+GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000004026f0280102
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF IMSI:901700000004620: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  lu_result_sent == 0
+  llist_count(&net->subscr_conns) == 1
+---
+- Another Location Update Request from the same subscriber on the same conn is dropped silently
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
+DREF IMSI:901700000004620: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8)
+DMM Cannot accept another LU, conn already busy establishing authenticity; extraneous LOCATION UPDATING REQUEST: MI(IMSI)=901700000004620 type=IMSI ATTACH
+DREF IMSI:901700000004620: MSC conn use - dtap == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  lu_result_sent == 0
+  llist_count(&net->subscr_conns) == 1
+---
+- The first LU can still complete
+- HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT
+<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: 10010809710000004026f00804036470f1
+DVLR GSUP rx 17: 10010809710000004026f00804036470f1
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DVLR IMSI:901700000004620 has MSISDN:46071
+DVLR SUBSCR(MSISDN:46071) VLR: update for IMSI=901700000004620 (MSISDN=46071, used=2)
+DVLR GSUP tx: 12010809710000004026f0
+GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000004026f0
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+<-- 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: 06010809710000004026f0
+DVLR GSUP rx 11: 06010809710000004026f0
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Freeing instance
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: Allocated
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: Allocated
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(LU:901700000004620)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(LU:901700000004620)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Freeing instance
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Deallocated
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL
+- sending LU Accept for MSISDN:46071
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_DONE
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Freeing instance
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_ACCEPTED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:46071: MSC conn use + release == 1 (0x100: release)
+DREF VLR subscr MSISDN:46071 usage increases to: 4
+DREF VLR subscr MSISDN:46071 usage decreases to: 3
+- BSSAP Clear --RAN_GERAN_A--> MS
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+<-- 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
+  lu_result_sent == 1
+- BSS sends BSSMAP Clear Complete
+DREF MSISDN:46071: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Freeing instance
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Deallocated
+DRLL MSISDN:46071: Freeing subscriber connection
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+DREF freeing VLR subscr MSISDN:46071
+===== test_reject_lu_during_lu: SUCCESS
+
+full talloc report on 'msgb' (total      0 bytes in   1 blocks)
+talloc_total_blocks(tall_bsc_ctx) == 12
+
+===== test_reject_cm_during_lu
+- Location Update Request
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8)
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Updated ID
+DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000004620 type=IMSI ATTACH
+DMM LU/new-LAC: 1/23
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Allocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: is child of Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: rev=GSM net=GERAN (no Auth)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA
+DREF VLR subscr unknown usage increases to: 1
+DVLR set IMSI on subscriber; IMSI=901700000004620 id=901700000004620
+DVLR New subscr, IMSI: 901700000004620
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DREF VLR subscr IMSI:901700000004620 usage decreases to: 1
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_post_auth()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_post_ciph()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node_4()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: Allocated
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START
+DVLR GSUP tx: 04010809710000004026f0280102
+GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000004026f0280102
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF IMSI:901700000004620: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  lu_result_sent == 0
+  llist_count(&net->subscr_conns) == 1
+---
+- A CM Service Request in the middle of a LU is rejected
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_CM_SERV_REQ
+DREF IMSI:901700000004620: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_CM_SERV_REQ (0x5:0x24)
+DMM <- CM SERVICE REQUEST serv_type=0x08 MI(IMSI)=901700000004620
+DMM Cannot accept CM Service Request, conn already busy establishing authenticity
+DMM -> CM SERVICE Reject cause: 22
+DMSC msc_tx 3 bytes to IMSI:901700000004620 via RAN_GERAN_A
+- DTAP --RAN_GERAN_A--> MS: GSM48_MT_MM_CM_SERV_REJ: 052216
+- DTAP matches expected message
+DREF IMSI:901700000004620: MSC conn use - dtap == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  lu_result_sent == 0
+  cm_service_result_sent == 0
+  dtap_tx_confirmed == 1
+  llist_count(&net->subscr_conns) == 1
+---
+- The first LU can still complete
+- HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT
+<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: 10010809710000004026f00804036470f1
+DVLR GSUP rx 17: 10010809710000004026f00804036470f1
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DVLR IMSI:901700000004620 has MSISDN:46071
+DVLR SUBSCR(MSISDN:46071) VLR: update for IMSI=901700000004620 (MSISDN=46071, used=2)
+DVLR GSUP tx: 12010809710000004026f0
+GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000004026f0
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+<-- 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: 06010809710000004026f0
+DVLR GSUP rx 11: 06010809710000004026f0
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Freeing instance
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: Allocated
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: Allocated
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(LU:901700000004620)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(LU:901700000004620)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Freeing instance
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Deallocated
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL
+- sending LU Accept for MSISDN:46071
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_DONE
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Freeing instance
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_ACCEPTED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:46071: MSC conn use + release == 1 (0x100: release)
+DREF VLR subscr MSISDN:46071 usage increases to: 4
+DREF VLR subscr MSISDN:46071 usage decreases to: 3
+- BSSAP Clear --RAN_GERAN_A--> MS
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+<-- 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
+  lu_result_sent == 1
+- BSS sends BSSMAP Clear Complete
+DREF MSISDN:46071: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Freeing instance
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Deallocated
+DRLL MSISDN:46071: Freeing subscriber connection
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+DREF freeing VLR subscr MSISDN:46071
+===== test_reject_cm_during_lu: SUCCESS
+
+full talloc report on 'msgb' (total      0 bytes in   1 blocks)
+talloc_total_blocks(tall_bsc_ctx) == 12
+
+===== test_reject_paging_resp_during_lu
+- Location Update Request
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8)
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Updated ID
+DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000004620 type=IMSI ATTACH
+DMM LU/new-LAC: 1/23
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Allocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: is child of Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: rev=GSM net=GERAN (no Auth)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA
+DREF VLR subscr unknown usage increases to: 1
+DVLR set IMSI on subscriber; IMSI=901700000004620 id=901700000004620
+DVLR New subscr, IMSI: 901700000004620
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DREF VLR subscr IMSI:901700000004620 usage decreases to: 1
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_post_auth()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_post_ciph()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node_4()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: Allocated
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START
+DVLR GSUP tx: 04010809710000004026f0280102
+GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000004026f0280102
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF IMSI:901700000004620: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  lu_result_sent == 0
+  llist_count(&net->subscr_conns) == 1
+---
+- An erratic Paging Response is dropped silently
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_RR_PAG_RESP
+DREF IMSI:901700000004620: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_RR_PAG_RESP (0x6:0x27)
+DMM Ignoring Paging Response, conn already busy establishing authenticity
+DREF IMSI:901700000004620: MSC conn use - dtap == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  lu_result_sent == 0
+  llist_count(&net->subscr_conns) == 1
+---
+- The first LU can still complete
+- HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT
+<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: 10010809710000004026f00804036470f1
+DVLR GSUP rx 17: 10010809710000004026f00804036470f1
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DVLR IMSI:901700000004620 has MSISDN:46071
+DVLR SUBSCR(MSISDN:46071) VLR: update for IMSI=901700000004620 (MSISDN=46071, used=2)
+DVLR GSUP tx: 12010809710000004026f0
+GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000004026f0
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+<-- 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: 06010809710000004026f0
+DVLR GSUP rx 11: 06010809710000004026f0
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Freeing instance
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: Allocated
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: Allocated
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(LU:901700000004620)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(LU:901700000004620)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Freeing instance
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Deallocated
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL
+- sending LU Accept for MSISDN:46071
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_DONE
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Freeing instance
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_ACCEPTED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:46071: MSC conn use + release == 1 (0x100: release)
+DREF VLR subscr MSISDN:46071 usage increases to: 4
+DREF VLR subscr MSISDN:46071 usage decreases to: 3
+- BSSAP Clear --RAN_GERAN_A--> MS
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+<-- 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
+  lu_result_sent == 1
+- BSS sends BSSMAP Clear Complete
+DREF MSISDN:46071: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Freeing instance
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Deallocated
+DRLL MSISDN:46071: Freeing subscriber connection
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+DREF freeing VLR subscr MSISDN:46071
+===== test_reject_paging_resp_during_lu: SUCCESS
+
+full talloc report on 'msgb' (total      0 bytes in   1 blocks)
+talloc_total_blocks(tall_bsc_ctx) == 12
+
+===== test_reject_lu_during_cm
+---
+- Subscriber does a normal LU
+- Location Update Request
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8)
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Updated ID
+DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000004620 type=IMSI ATTACH
+DMM LU/new-LAC: 1/23
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Allocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: is child of Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: rev=GSM net=GERAN (no Auth)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA
+DREF VLR subscr unknown usage increases to: 1
+DVLR set IMSI on subscriber; IMSI=901700000004620 id=901700000004620
+DVLR New subscr, IMSI: 901700000004620
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DREF VLR subscr IMSI:901700000004620 usage decreases to: 1
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_post_auth()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_post_ciph()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node_4()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: Allocated
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START
+DVLR GSUP tx: 04010809710000004026f0280102
+GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000004026f0280102
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF IMSI:901700000004620: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  lu_result_sent == 0
+  llist_count(&net->subscr_conns) == 1
+- HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT
+<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: 10010809710000004026f00804036470f1
+DVLR GSUP rx 17: 10010809710000004026f00804036470f1
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DVLR IMSI:901700000004620 has MSISDN:46071
+DVLR SUBSCR(MSISDN:46071) VLR: update for IMSI=901700000004620 (MSISDN=46071, used=2)
+DVLR GSUP tx: 12010809710000004026f0
+GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000004026f0
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+<-- 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: 06010809710000004026f0
+DVLR GSUP rx 11: 06010809710000004026f0
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Freeing instance
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: Allocated
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: Allocated
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(LU:901700000004620)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(LU:901700000004620)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Freeing instance
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Deallocated
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL
+- sending LU Accept for MSISDN:46071
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_DONE
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Freeing instance
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_ACCEPTED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:46071: MSC conn use + release == 1 (0x100: release)
+DREF VLR subscr MSISDN:46071 usage increases to: 4
+DREF VLR subscr MSISDN:46071 usage decreases to: 3
+- BSSAP Clear --RAN_GERAN_A--> MS
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+<-- 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
+  lu_result_sent == 1
+- BSS sends BSSMAP Clear Complete
+DREF MSISDN:46071: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Freeing instance
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Deallocated
+DRLL MSISDN:46071: Freeing subscriber connection
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+---
+- Subscriber does a normal CM Service Request
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_CM_SERV_REQ
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_CM_SERV_REQ (0x5:0x24)
+DMM <- CM SERVICE REQUEST serv_type=0x08 MI(IMSI)=901700000004620
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_NEW}: Updated ID
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_INIT}: Allocated
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_INIT}: is child of Subscr_Conn(CM_SERVICE_REQ:901700000004620)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_INIT}: rev=GSM net=GERAN (no Auth)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_node2()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_ciph()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_vlr()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_post_pres()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_post_trace()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_post_imei()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_INIT}: proc_arq_fsm_done(PASSED)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_DONE
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_DONE}: Process Access Request result: PASSED
+- sending CM Service Accept for MSISDN:46071
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_ACCEPTED
+DREF MSISDN:46071: MSC conn use + cm_service == 2 (0x9: compl_l3,cm_service)
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_ACCEPTED}: subscr_conn_fsm_has_active_transactions: still awaiting first request after a CM Service Request
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DREF MSISDN:46071: MSC conn use - compl_l3 == 1 (0x8: cm_service)
+  cm_service_result_sent == 1
+msc_subscr_conn_is_accepted() == true
+- A LU request on an open conn is dropped silently
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
+DREF MSISDN:46071: MSC conn use + dtap == 2 (0xa: dtap,cm_service)
+DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8)
+DMM Cannot accept another LU, conn already established; extraneous LOCATION UPDATING REQUEST: MI(IMSI)=901700000004620 type=IMSI ATTACH
+DREF MSISDN:46071: MSC conn use - dtap == 1 (0x8: cm_service)
+  lu_result_sent == 0
+  llist_count(&net->subscr_conns) == 1
+---
+- subscriber detaches
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_IMSI_DETACH_IND
+DREF MSISDN:46071: MSC conn use + dtap == 2 (0xa: dtap,cm_service)
+DRLL Dispatching 04.08 message GSM48_MT_MM_IMSI_DETACH_IND (0x5:0x1)
+DMM IMSI DETACH INDICATION: MI(IMSI)=901700000004620
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DMM IMSI DETACH for MSISDN:46071
+DREF VLR subscr MSISDN:46071 usage increases to: 4
+DREF VLR subscr MSISDN:46071 usage decreases to: 3
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_CN_CLOSE
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:46071: MSC conn use + release == 3 (0x10a: dtap,cm_service,release)
+DREF MSISDN:46071: MSC conn use - cm_service == 2 (0x102: dtap,release)
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+- BSSAP Clear --RAN_GERAN_A--> MS
+DREF MSISDN:46071: MSC conn use - dtap == 1 (0x100: release)
+  bssap_clear_sent == 1
+- BSS sends BSSMAP Clear Complete
+DREF MSISDN:46071: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_DONE}: Removing from parent Subscr_Conn(CM_SERVICE_REQ:901700000004620)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_DONE}: Freeing instance
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_DONE}: Deallocated
+DRLL MSISDN:46071: Freeing subscriber connection
+DREF VLR subscr MSISDN:46071 usage decreases to: 0
+DREF freeing VLR subscr MSISDN:46071
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+===== test_reject_lu_during_cm: SUCCESS
+
+full talloc report on 'msgb' (total      0 bytes in   1 blocks)
+talloc_total_blocks(tall_bsc_ctx) == 12
+
+===== test_reject_cm_during_cm
+---
+- Subscriber does a normal LU
+- Location Update Request
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8)
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Updated ID
+DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000004620 type=IMSI ATTACH
+DMM LU/new-LAC: 1/23
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Allocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: is child of Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: rev=GSM net=GERAN (no Auth)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA
+DREF VLR subscr unknown usage increases to: 1
+DVLR set IMSI on subscriber; IMSI=901700000004620 id=901700000004620
+DVLR New subscr, IMSI: 901700000004620
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DREF VLR subscr IMSI:901700000004620 usage decreases to: 1
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_post_auth()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_post_ciph()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node_4()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: Allocated
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START
+DVLR GSUP tx: 04010809710000004026f0280102
+GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000004026f0280102
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF IMSI:901700000004620: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  lu_result_sent == 0
+  llist_count(&net->subscr_conns) == 1
+- HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT
+<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: 10010809710000004026f00804036470f1
+DVLR GSUP rx 17: 10010809710000004026f00804036470f1
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DVLR IMSI:901700000004620 has MSISDN:46071
+DVLR SUBSCR(MSISDN:46071) VLR: update for IMSI=901700000004620 (MSISDN=46071, used=2)
+DVLR GSUP tx: 12010809710000004026f0
+GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000004026f0
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+<-- 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: 06010809710000004026f0
+DVLR GSUP rx 11: 06010809710000004026f0
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Freeing instance
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: Allocated
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: Allocated
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(LU:901700000004620)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(LU:901700000004620)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Freeing instance
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Deallocated
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL
+- sending LU Accept for MSISDN:46071
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_DONE
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Freeing instance
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_ACCEPTED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:46071: MSC conn use + release == 1 (0x100: release)
+DREF VLR subscr MSISDN:46071 usage increases to: 4
+DREF VLR subscr MSISDN:46071 usage decreases to: 3
+- BSSAP Clear --RAN_GERAN_A--> MS
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+<-- 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
+  lu_result_sent == 1
+- BSS sends BSSMAP Clear Complete
+DREF MSISDN:46071: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Freeing instance
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Deallocated
+DRLL MSISDN:46071: Freeing subscriber connection
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+---
+- Subscriber does a normal CM Service Request
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_CM_SERV_REQ
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_CM_SERV_REQ (0x5:0x24)
+DMM <- CM SERVICE REQUEST serv_type=0x08 MI(IMSI)=901700000004620
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_NEW}: Updated ID
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_INIT}: Allocated
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_INIT}: is child of Subscr_Conn(CM_SERVICE_REQ:901700000004620)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_INIT}: rev=GSM net=GERAN (no Auth)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_node2()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_ciph()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_vlr()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_post_pres()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_post_trace()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_post_imei()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_INIT}: proc_arq_fsm_done(PASSED)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_DONE
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_DONE}: Process Access Request result: PASSED
+- sending CM Service Accept for MSISDN:46071
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_ACCEPTED
+DREF MSISDN:46071: MSC conn use + cm_service == 2 (0x9: compl_l3,cm_service)
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_ACCEPTED}: subscr_conn_fsm_has_active_transactions: still awaiting first request after a CM Service Request
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DREF MSISDN:46071: MSC conn use - compl_l3 == 1 (0x8: cm_service)
+  cm_service_result_sent == 1
+msc_subscr_conn_is_accepted() == true
+- A second CM Service Request on the same conn is accepted without another auth dance
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_CM_SERV_REQ
+DREF MSISDN:46071: MSC conn use + dtap == 2 (0xa: dtap,cm_service)
+DRLL Dispatching 04.08 message GSM48_MT_MM_CM_SERV_REQ (0x5:0x24)
+DMM <- CM SERVICE REQUEST serv_type=0x08 MI(IMSI)=901700000004620
+DMM MSISDN:46071: re-using already accepted connection
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_ACCEPTED}: Updated ID
+- sending CM Service Accept for MSISDN:46071
+DREF MSISDN:46071: MSC conn use - dtap == 1 (0x8: cm_service)
+  cm_service_result_sent == 1
+  llist_count(&net->subscr_conns) == 1
+---
+- subscriber detaches
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_IMSI_DETACH_IND
+DREF MSISDN:46071: MSC conn use + dtap == 2 (0xa: dtap,cm_service)
+DRLL Dispatching 04.08 message GSM48_MT_MM_IMSI_DETACH_IND (0x5:0x1)
+DMM IMSI DETACH INDICATION: MI(IMSI)=901700000004620
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DMM IMSI DETACH for MSISDN:46071
+DREF VLR subscr MSISDN:46071 usage increases to: 4
+DREF VLR subscr MSISDN:46071 usage decreases to: 3
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_CN_CLOSE
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:46071: MSC conn use + release == 3 (0x10a: dtap,cm_service,release)
+DREF MSISDN:46071: MSC conn use - cm_service == 2 (0x102: dtap,release)
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+- BSSAP Clear --RAN_GERAN_A--> MS
+DREF MSISDN:46071: MSC conn use - dtap == 1 (0x100: release)
+  bssap_clear_sent == 1
+- BSS sends BSSMAP Clear Complete
+DREF MSISDN:46071: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_DONE}: Removing from parent Subscr_Conn(CM_SERVICE_REQ:901700000004620)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_DONE}: Freeing instance
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_DONE}: Deallocated
+DRLL MSISDN:46071: Freeing subscriber connection
+DREF VLR subscr MSISDN:46071 usage decreases to: 0
+DREF freeing VLR subscr MSISDN:46071
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+===== test_reject_cm_during_cm: SUCCESS
+
+full talloc report on 'msgb' (total      0 bytes in   1 blocks)
+talloc_total_blocks(tall_bsc_ctx) == 12
+
+===== test_reject_paging_resp_during_cm
+---
+- Subscriber does a normal LU
+- Location Update Request
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8)
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Updated ID
+DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000004620 type=IMSI ATTACH
+DMM LU/new-LAC: 1/23
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Allocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: is child of Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: rev=GSM net=GERAN (no Auth)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA
+DREF VLR subscr unknown usage increases to: 1
+DVLR set IMSI on subscriber; IMSI=901700000004620 id=901700000004620
+DVLR New subscr, IMSI: 901700000004620
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DREF VLR subscr IMSI:901700000004620 usage decreases to: 1
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_post_auth()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_post_ciph()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node_4()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: Allocated
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START
+DVLR GSUP tx: 04010809710000004026f0280102
+GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000004026f0280102
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF IMSI:901700000004620: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  lu_result_sent == 0
+  llist_count(&net->subscr_conns) == 1
+- HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT
+<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: 10010809710000004026f00804036470f1
+DVLR GSUP rx 17: 10010809710000004026f00804036470f1
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DVLR IMSI:901700000004620 has MSISDN:46071
+DVLR SUBSCR(MSISDN:46071) VLR: update for IMSI=901700000004620 (MSISDN=46071, used=2)
+DVLR GSUP tx: 12010809710000004026f0
+GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000004026f0
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+<-- 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: 06010809710000004026f0
+DVLR GSUP rx 11: 06010809710000004026f0
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Freeing instance
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: Allocated
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: Allocated
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(LU:901700000004620)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(LU:901700000004620)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Freeing instance
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Deallocated
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL
+- sending LU Accept for MSISDN:46071
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_DONE
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Freeing instance
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_ACCEPTED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:46071: MSC conn use + release == 1 (0x100: release)
+DREF VLR subscr MSISDN:46071 usage increases to: 4
+DREF VLR subscr MSISDN:46071 usage decreases to: 3
+- BSSAP Clear --RAN_GERAN_A--> MS
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+<-- 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
+  lu_result_sent == 1
+- BSS sends BSSMAP Clear Complete
+DREF MSISDN:46071: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Freeing instance
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Deallocated
+DRLL MSISDN:46071: Freeing subscriber connection
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+---
+- Subscriber does a normal CM Service Request
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_CM_SERV_REQ
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_CM_SERV_REQ (0x5:0x24)
+DMM <- CM SERVICE REQUEST serv_type=0x08 MI(IMSI)=901700000004620
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_NEW}: Updated ID
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_INIT}: Allocated
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_INIT}: is child of Subscr_Conn(CM_SERVICE_REQ:901700000004620)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_INIT}: rev=GSM net=GERAN (no Auth)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_node2()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_ciph()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_vlr()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_post_pres()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_post_trace()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_post_imei()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_INIT}: proc_arq_fsm_done(PASSED)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_DONE
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_DONE}: Process Access Request result: PASSED
+- sending CM Service Accept for MSISDN:46071
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_ACCEPTED
+DREF MSISDN:46071: MSC conn use + cm_service == 2 (0x9: compl_l3,cm_service)
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_ACCEPTED}: subscr_conn_fsm_has_active_transactions: still awaiting first request after a CM Service Request
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DREF MSISDN:46071: MSC conn use - compl_l3 == 1 (0x8: cm_service)
+  cm_service_result_sent == 1
+msc_subscr_conn_is_accepted() == true
+---
+- An erratic Paging Response on the same conn is dropped silently
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_RR_PAG_RESP
+DREF MSISDN:46071: MSC conn use + dtap == 2 (0xa: dtap,cm_service)
+DRLL Dispatching 04.08 message GSM48_MT_RR_PAG_RESP (0x6:0x27)
+DMM Ignoring Paging Response, conn already established
+DREF MSISDN:46071: MSC conn use - dtap == 1 (0x8: cm_service)
+  llist_count(&net->subscr_conns) == 1
+---
+- The original CM Service Request can conclude
+- Concluding CM Service Request
+DREF MSISDN:46071: MSC conn use - cm_service == 0 (0x0: )
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:46071: MSC conn use + release == 1 (0x100: release)
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+- BSSAP Clear --RAN_GERAN_A--> MS
+  bssap_clear_sent == 1
+- all requests serviced, conn has been released
+- BSS sends BSSMAP Clear Complete
+DREF MSISDN:46071: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_DONE}: Removing from parent Subscr_Conn(CM_SERVICE_REQ:901700000004620)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_DONE}: Freeing instance
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_DONE}: Deallocated
+DRLL MSISDN:46071: Freeing subscriber connection
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+DREF freeing VLR subscr MSISDN:46071
+===== test_reject_paging_resp_during_cm: SUCCESS
+
+full talloc report on 'msgb' (total      0 bytes in   1 blocks)
+talloc_total_blocks(tall_bsc_ctx) == 12
+
+===== test_reject_lu_during_paging_resp
+---
+- Subscriber does a normal LU
+- Location Update Request
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8)
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Updated ID
+DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000004620 type=IMSI ATTACH
+DMM LU/new-LAC: 1/23
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Allocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: is child of Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: rev=GSM net=GERAN (no Auth)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA
+DREF VLR subscr unknown usage increases to: 1
+DVLR set IMSI on subscriber; IMSI=901700000004620 id=901700000004620
+DVLR New subscr, IMSI: 901700000004620
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DREF VLR subscr IMSI:901700000004620 usage decreases to: 1
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_post_auth()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_post_ciph()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node_4()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: Allocated
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START
+DVLR GSUP tx: 04010809710000004026f0280102
+GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000004026f0280102
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF IMSI:901700000004620: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  lu_result_sent == 0
+  llist_count(&net->subscr_conns) == 1
+- HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT
+<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: 10010809710000004026f00804036470f1
+DVLR GSUP rx 17: 10010809710000004026f00804036470f1
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DVLR IMSI:901700000004620 has MSISDN:46071
+DVLR SUBSCR(MSISDN:46071) VLR: update for IMSI=901700000004620 (MSISDN=46071, used=2)
+DVLR GSUP tx: 12010809710000004026f0
+GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000004026f0
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+<-- 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: 06010809710000004026f0
+DVLR GSUP rx 11: 06010809710000004026f0
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Freeing instance
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: Allocated
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: Allocated
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(LU:901700000004620)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(LU:901700000004620)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Freeing instance
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Deallocated
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL
+- sending LU Accept for MSISDN:46071
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_DONE
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Freeing instance
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_ACCEPTED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:46071: MSC conn use + release == 1 (0x100: release)
+DREF VLR subscr MSISDN:46071 usage increases to: 4
+DREF VLR subscr MSISDN:46071 usage decreases to: 3
+- BSSAP Clear --RAN_GERAN_A--> MS
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+<-- 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
+  lu_result_sent == 1
+- BSS sends BSSMAP Clear Complete
+DREF MSISDN:46071: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Freeing instance
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Deallocated
+DRLL MSISDN:46071: Freeing subscriber connection
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+---
+- an SMS is sent, MS is paged
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+  llist_count(&vsub->cs.requests) == 0
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DMM Subscriber MSISDN:46071 not paged yet, start paging.
+  RAN_GERAN_A sends out paging request to IMSI 901700000004620, TMSI 0xffffffff, LAC 23
+  strcmp(paging_expecting_imsi, imsi) == 0
+DREF VLR subscr MSISDN:46071 usage increases to: 4
+  llist_count(&vsub->cs.requests) == 1
+DREF VLR subscr MSISDN:46071 usage decreases to: 3
+  paging_sent == 1
+  paging_stopped == 0
+- MS replies with Paging Response, we deliver the SMS
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_RR_PAG_RESP
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_RR_PAG_RESP (0x6:0x27)
+DRR PAGING RESPONSE: MI(IMSI)=901700000004620
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_NEW}: Updated ID
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_INIT}: Allocated
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_INIT}: is child of Subscr_Conn(PAGING_RESP:901700000004620)
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_INIT}: rev=GSM net=GERAN (no Auth)
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START
+DREF VLR subscr MSISDN:46071 usage increases to: 4
+DREF VLR subscr MSISDN:46071 usage increases to: 5
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi()
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_node2()
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_ciph()
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_vlr()
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_post_pres()
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_post_trace()
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_post_imei()
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_INIT}: proc_arq_fsm_done(PASSED)
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_DONE
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_DONE}: Process Access Request result: PASSED
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_ACCEPTED
+DPAG Paging success for MSISDN:46071 (event=0)
+DPAG Calling paging cbfn.
+DCC (ti 00 sub MSISDN:46071 callref 40000001) New transaction
+DREF VLR subscr MSISDN:46071 usage increases to: 6
+DREF MSISDN:46071: MSC conn use + trans_sms == 2 (0x21: compl_l3,trans_sms)
+DMSC msc_tx 91 bytes to MSISDN:46071 via RAN_GERAN_A
+- DTAP --RAN_GERAN_A--> MS: SMS:0x01: 09015801000791447758100650004c0005806470f1000007101000000000445079da1e1ee7416937485e9ea7c965373d1d6683c270383b3d0ed3d36ff71c949e83c22072799e9687c5ec32a81d96afcbf4b4fb0c7ac3e9e9b7db05
+- DTAP matches expected message
+DREF VLR subscr MSISDN:46071 usage decreases to: 5
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_ACCEPTED}: subscr_conn_fsm_has_active_transactions: connection still has active transaction: SMS
+DREF VLR subscr MSISDN:46071 usage decreases to: 4
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DREF MSISDN:46071: MSC conn use - compl_l3 == 1 (0x20: trans_sms)
+  dtap_tx_confirmed == 1
+  paging_stopped == 1
+- conn is still open to wait for SMS ack dance
+  llist_count(&net->subscr_conns) == 1
+---
+- MS sends erratic LU Request, which is dropped silently
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
+DREF MSISDN:46071: MSC conn use + dtap == 2 (0x22: dtap,trans_sms)
+DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8)
+DMM Cannot accept another LU, conn already established; extraneous LOCATION UPDATING REQUEST: MI(IMSI)=901700000004620 type=IMSI ATTACH
+DREF MSISDN:46071: MSC conn use - dtap == 1 (0x20: trans_sms)
+  lu_result_sent == 0
+  llist_count(&net->subscr_conns) == 1
+- MS replies with CP-ACK for received SMS
+  MSC <--RAN_GERAN_A-- MS: SMS:0x04
+DREF MSISDN:46071: MSC conn use + dtap == 2 (0x22: dtap,trans_sms)
+DRLL Dispatching 04.08 message SMS:0x04 (0x9:0x4)
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_COMMUNICATING
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_COMMUNICATING
+DREF MSISDN:46071: MSC conn use - dtap == 1 (0x20: trans_sms)
+  llist_count(&net->subscr_conns) == 1
+- MS also sends RP-ACK, MSC in turn sends CP-ACK for that
+  MSC <--RAN_GERAN_A-- MS: SMS:0x01
+DREF MSISDN:46071: MSC conn use + dtap == 2 (0x22: dtap,trans_sms)
+DRLL Dispatching 04.08 message SMS:0x01 (0x9:0x1)
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_COMMUNICATING}: Received Event SUBSCR_CONN_E_COMMUNICATING
+DMSC msc_tx 2 bytes to MSISDN:46071 via RAN_GERAN_A
+- DTAP --RAN_GERAN_A--> MS: SMS:0x04: 0904
+- DTAP matches expected message
+DREF VLR subscr MSISDN:46071 usage decreases to: 3
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+DREF MSISDN:46071: MSC conn use - trans_sms == 1 (0x2: dtap)
+DREF MSISDN:46071: MSC conn use - dtap == 0 (0x0: )
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_COMMUNICATING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_COMMUNICATING}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:46071: MSC conn use + release == 1 (0x100: release)
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+- BSSAP Clear --RAN_GERAN_A--> MS
+  dtap_tx_confirmed == 1
+  bssap_clear_sent == 1
+- BSS sends BSSMAP Clear Complete
+DREF MSISDN:46071: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_DONE}: Removing from parent Subscr_Conn(PAGING_RESP:901700000004620)
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_DONE}: Freeing instance
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_DONE}: Deallocated
+DRLL MSISDN:46071: Freeing subscriber connection
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated
+- SMS is done
+  llist_count(&net->subscr_conns) == 0
+DREF freeing VLR subscr MSISDN:46071
+===== test_reject_lu_during_paging_resp: SUCCESS
+
+full talloc report on 'msgb' (total      0 bytes in   1 blocks)
+talloc_total_blocks(tall_bsc_ctx) == 12
+
+===== test_accept_cm_during_paging_resp
+---
+- Subscriber does a normal LU
+- Location Update Request
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8)
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Updated ID
+DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000004620 type=IMSI ATTACH
+DMM LU/new-LAC: 1/23
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Allocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: is child of Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: rev=GSM net=GERAN (no Auth)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA
+DREF VLR subscr unknown usage increases to: 1
+DVLR set IMSI on subscriber; IMSI=901700000004620 id=901700000004620
+DVLR New subscr, IMSI: 901700000004620
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DREF VLR subscr IMSI:901700000004620 usage decreases to: 1
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_post_auth()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_post_ciph()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node_4()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: Allocated
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START
+DVLR GSUP tx: 04010809710000004026f0280102
+GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000004026f0280102
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF IMSI:901700000004620: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  lu_result_sent == 0
+  llist_count(&net->subscr_conns) == 1
+- HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT
+<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: 10010809710000004026f00804036470f1
+DVLR GSUP rx 17: 10010809710000004026f00804036470f1
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DVLR IMSI:901700000004620 has MSISDN:46071
+DVLR SUBSCR(MSISDN:46071) VLR: update for IMSI=901700000004620 (MSISDN=46071, used=2)
+DVLR GSUP tx: 12010809710000004026f0
+GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000004026f0
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+<-- 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: 06010809710000004026f0
+DVLR GSUP rx 11: 06010809710000004026f0
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Freeing instance
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: Allocated
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: Allocated
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(LU:901700000004620)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(LU:901700000004620)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Freeing instance
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Deallocated
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL
+- sending LU Accept for MSISDN:46071
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_DONE
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Freeing instance
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_ACCEPTED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:46071: MSC conn use + release == 1 (0x100: release)
+DREF VLR subscr MSISDN:46071 usage increases to: 4
+DREF VLR subscr MSISDN:46071 usage decreases to: 3
+- BSSAP Clear --RAN_GERAN_A--> MS
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+<-- 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
+  lu_result_sent == 1
+- BSS sends BSSMAP Clear Complete
+DREF MSISDN:46071: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Freeing instance
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Deallocated
+DRLL MSISDN:46071: Freeing subscriber connection
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+---
+- an SMS is sent, MS is paged
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+  llist_count(&vsub->cs.requests) == 0
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DMM Subscriber MSISDN:46071 not paged yet, start paging.
+  RAN_GERAN_A sends out paging request to IMSI 901700000004620, TMSI 0xffffffff, LAC 23
+  strcmp(paging_expecting_imsi, imsi) == 0
+DREF VLR subscr MSISDN:46071 usage increases to: 4
+  llist_count(&vsub->cs.requests) == 1
+DREF VLR subscr MSISDN:46071 usage decreases to: 3
+  paging_sent == 1
+  paging_stopped == 0
+- MS replies with Paging Response, we deliver the SMS
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_RR_PAG_RESP
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_RR_PAG_RESP (0x6:0x27)
+DRR PAGING RESPONSE: MI(IMSI)=901700000004620
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_NEW}: Updated ID
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_INIT}: Allocated
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_INIT}: is child of Subscr_Conn(PAGING_RESP:901700000004620)
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_INIT}: rev=GSM net=GERAN (no Auth)
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START
+DREF VLR subscr MSISDN:46071 usage increases to: 4
+DREF VLR subscr MSISDN:46071 usage increases to: 5
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi()
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_node2()
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_ciph()
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_vlr()
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_post_pres()
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_post_trace()
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_post_imei()
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_INIT}: proc_arq_fsm_done(PASSED)
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_DONE
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_DONE}: Process Access Request result: PASSED
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_ACCEPTED
+DPAG Paging success for MSISDN:46071 (event=0)
+DPAG Calling paging cbfn.
+DCC (ti 00 sub MSISDN:46071 callref 40000002) New transaction
+DREF VLR subscr MSISDN:46071 usage increases to: 6
+DREF MSISDN:46071: MSC conn use + trans_sms == 2 (0x21: compl_l3,trans_sms)
+DMSC msc_tx 91 bytes to MSISDN:46071 via RAN_GERAN_A
+- DTAP --RAN_GERAN_A--> MS: SMS:0x01: 09015801000791447758100650004c0005806470f1000007101000000000445079da1e1ee7416937485e9ea7c965373d1d6683c270383b3d0ed3d36ff71c949e83c22072799e9687c5ec32a81d96afcbf4b4fb0c7ac3e9e9b7db05
+- DTAP matches expected message
+DREF VLR subscr MSISDN:46071 usage decreases to: 5
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_ACCEPTED}: subscr_conn_fsm_has_active_transactions: connection still has active transaction: SMS
+DREF VLR subscr MSISDN:46071 usage decreases to: 4
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DREF MSISDN:46071: MSC conn use - compl_l3 == 1 (0x20: trans_sms)
+  dtap_tx_confirmed == 1
+  paging_stopped == 1
+- conn is still open to wait for SMS ack dance
+  llist_count(&net->subscr_conns) == 1
+---
+- CM Service Request during open connection is accepted
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_CM_SERV_REQ
+DREF MSISDN:46071: MSC conn use + dtap == 2 (0x22: dtap,trans_sms)
+DRLL Dispatching 04.08 message GSM48_MT_MM_CM_SERV_REQ (0x5:0x24)
+DMM <- CM SERVICE REQUEST serv_type=0x08 MI(IMSI)=901700000004620
+DMM MSISDN:46071: re-using already accepted connection
+DREF MSISDN:46071: MSC conn use + cm_service == 3 (0x2a: dtap,cm_service,trans_sms)
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_ACCEPTED}: Updated ID
+- sending CM Service Accept for MSISDN:46071
+DREF MSISDN:46071: MSC conn use - dtap == 2 (0x28: cm_service,trans_sms)
+  cm_service_result_sent == 1
+  llist_count(&net->subscr_conns) == 1
+  g_conn->received_cm_service_request == 1
+- MS replies with CP-ACK for received SMS
+  MSC <--RAN_GERAN_A-- MS: SMS:0x04
+DREF MSISDN:46071: MSC conn use + dtap == 3 (0x2a: dtap,cm_service,trans_sms)
+DRLL Dispatching 04.08 message SMS:0x04 (0x9:0x4)
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_COMMUNICATING
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_COMMUNICATING
+DREF MSISDN:46071: MSC conn use - dtap == 2 (0x28: cm_service,trans_sms)
+  llist_count(&net->subscr_conns) == 1
+- MS also sends RP-ACK, MSC in turn sends CP-ACK for that
+  MSC <--RAN_GERAN_A-- MS: SMS:0x01
+DREF MSISDN:46071: MSC conn use + dtap == 3 (0x2a: dtap,cm_service,trans_sms)
+DRLL Dispatching 04.08 message SMS:0x01 (0x9:0x1)
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_COMMUNICATING}: Received Event SUBSCR_CONN_E_COMMUNICATING
+DMSC msc_tx 2 bytes to MSISDN:46071 via RAN_GERAN_A
+- DTAP --RAN_GERAN_A--> MS: SMS:0x04: 0904
+- DTAP matches expected message
+DREF VLR subscr MSISDN:46071 usage decreases to: 3
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+DREF MSISDN:46071: MSC conn use - trans_sms == 2 (0xa: dtap,cm_service)
+DREF MSISDN:46071: MSC conn use - dtap == 1 (0x8: cm_service)
+  dtap_tx_confirmed == 1
+- SMS is done
+  llist_count(&net->subscr_conns) == 1
+---
+- subscriber detaches
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_IMSI_DETACH_IND
+DREF MSISDN:46071: MSC conn use + dtap == 2 (0xa: dtap,cm_service)
+DRLL Dispatching 04.08 message GSM48_MT_MM_IMSI_DETACH_IND (0x5:0x1)
+DMM IMSI DETACH INDICATION: MI(IMSI)=901700000004620
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DMM IMSI DETACH for MSISDN:46071
+DREF VLR subscr MSISDN:46071 usage increases to: 4
+DREF VLR subscr MSISDN:46071 usage decreases to: 3
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_COMMUNICATING}: Received Event SUBSCR_CONN_E_CN_CLOSE
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_COMMUNICATING}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:46071: MSC conn use + release == 3 (0x10a: dtap,cm_service,release)
+DREF MSISDN:46071: MSC conn use - cm_service == 2 (0x102: dtap,release)
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+- BSSAP Clear --RAN_GERAN_A--> MS
+DREF MSISDN:46071: MSC conn use - dtap == 1 (0x100: release)
+  bssap_clear_sent == 1
+- BSS sends BSSMAP Clear Complete
+DREF MSISDN:46071: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_DONE}: Removing from parent Subscr_Conn(PAGING_RESP:901700000004620)
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_DONE}: Freeing instance
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_DONE}: Deallocated
+DRLL MSISDN:46071: Freeing subscriber connection
+DREF VLR subscr MSISDN:46071 usage decreases to: 0
+DREF freeing VLR subscr MSISDN:46071
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 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) == 12
+
+===== test_reject_paging_resp_during_paging_resp
+---
+- Subscriber does a normal LU
+- Location Update Request
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8)
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Updated ID
+DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000004620 type=IMSI ATTACH
+DMM LU/new-LAC: 1/23
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Allocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: is child of Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: rev=GSM net=GERAN (no Auth)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA
+DREF VLR subscr unknown usage increases to: 1
+DVLR set IMSI on subscriber; IMSI=901700000004620 id=901700000004620
+DVLR New subscr, IMSI: 901700000004620
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DREF VLR subscr IMSI:901700000004620 usage decreases to: 1
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_post_auth()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_post_ciph()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node_4()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: Allocated
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START
+DVLR GSUP tx: 04010809710000004026f0280102
+GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000004026f0280102
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF IMSI:901700000004620: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  lu_result_sent == 0
+  llist_count(&net->subscr_conns) == 1
+- HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT
+<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: 10010809710000004026f00804036470f1
+DVLR GSUP rx 17: 10010809710000004026f00804036470f1
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DVLR IMSI:901700000004620 has MSISDN:46071
+DVLR SUBSCR(MSISDN:46071) VLR: update for IMSI=901700000004620 (MSISDN=46071, used=2)
+DVLR GSUP tx: 12010809710000004026f0
+GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000004026f0
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+<-- 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: 06010809710000004026f0
+DVLR GSUP rx 11: 06010809710000004026f0
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Freeing instance
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: Allocated
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: Allocated
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(LU:901700000004620)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(LU:901700000004620)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Freeing instance
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Deallocated
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL
+- sending LU Accept for MSISDN:46071
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_DONE
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Freeing instance
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_ACCEPTED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:46071: MSC conn use + release == 1 (0x100: release)
+DREF VLR subscr MSISDN:46071 usage increases to: 4
+DREF VLR subscr MSISDN:46071 usage decreases to: 3
+- BSSAP Clear --RAN_GERAN_A--> MS
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+<-- 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
+  lu_result_sent == 1
+- BSS sends BSSMAP Clear Complete
+DREF MSISDN:46071: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Freeing instance
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Deallocated
+DRLL MSISDN:46071: Freeing subscriber connection
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+---
+- an SMS is sent, MS is paged
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+  llist_count(&vsub->cs.requests) == 0
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DMM Subscriber MSISDN:46071 not paged yet, start paging.
+  RAN_GERAN_A sends out paging request to IMSI 901700000004620, TMSI 0xffffffff, LAC 23
+  strcmp(paging_expecting_imsi, imsi) == 0
+DREF VLR subscr MSISDN:46071 usage increases to: 4
+  llist_count(&vsub->cs.requests) == 1
+DREF VLR subscr MSISDN:46071 usage decreases to: 3
+  paging_sent == 1
+  paging_stopped == 0
+- MS replies with Paging Response, we deliver the SMS
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_RR_PAG_RESP
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_RR_PAG_RESP (0x6:0x27)
+DRR PAGING RESPONSE: MI(IMSI)=901700000004620
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_NEW}: Updated ID
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_INIT}: Allocated
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_INIT}: is child of Subscr_Conn(PAGING_RESP:901700000004620)
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_INIT}: rev=GSM net=GERAN (no Auth)
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START
+DREF VLR subscr MSISDN:46071 usage increases to: 4
+DREF VLR subscr MSISDN:46071 usage increases to: 5
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi()
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_node2()
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_ciph()
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_vlr()
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_post_pres()
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_post_trace()
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_post_imei()
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_INIT}: proc_arq_fsm_done(PASSED)
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_DONE
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_DONE}: Process Access Request result: PASSED
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_ACCEPTED
+DPAG Paging success for MSISDN:46071 (event=0)
+DPAG Calling paging cbfn.
+DCC (ti 00 sub MSISDN:46071 callref 40000003) New transaction
+DREF VLR subscr MSISDN:46071 usage increases to: 6
+DREF MSISDN:46071: MSC conn use + trans_sms == 2 (0x21: compl_l3,trans_sms)
+DMSC msc_tx 91 bytes to MSISDN:46071 via RAN_GERAN_A
+- DTAP --RAN_GERAN_A--> MS: SMS:0x01: 09015801000791447758100650004c0005806470f1000007101000000000445079da1e1ee7416937485e9ea7c965373d1d6683c270383b3d0ed3d36ff71c949e83c22072799e9687c5ec32a81d96afcbf4b4fb0c7ac3e9e9b7db05
+- DTAP matches expected message
+DREF VLR subscr MSISDN:46071 usage decreases to: 5
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_ACCEPTED}: subscr_conn_fsm_has_active_transactions: connection still has active transaction: SMS
+DREF VLR subscr MSISDN:46071 usage decreases to: 4
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DREF MSISDN:46071: MSC conn use - compl_l3 == 1 (0x20: trans_sms)
+  dtap_tx_confirmed == 1
+  paging_stopped == 1
+- conn is still open to wait for SMS ack dance
+  llist_count(&net->subscr_conns) == 1
+---
+- MS sends another erratic Paging Response which is dropped silently
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_RR_PAG_RESP
+DREF MSISDN:46071: MSC conn use + dtap == 2 (0x22: dtap,trans_sms)
+DRLL Dispatching 04.08 message GSM48_MT_RR_PAG_RESP (0x6:0x27)
+DMM Ignoring Paging Response, conn already established
+DREF MSISDN:46071: MSC conn use - dtap == 1 (0x20: trans_sms)
+- MS replies with CP-ACK for received SMS
+  MSC <--RAN_GERAN_A-- MS: SMS:0x04
+DREF MSISDN:46071: MSC conn use + dtap == 2 (0x22: dtap,trans_sms)
+DRLL Dispatching 04.08 message SMS:0x04 (0x9:0x4)
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_COMMUNICATING
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_COMMUNICATING
+DREF MSISDN:46071: MSC conn use - dtap == 1 (0x20: trans_sms)
+  llist_count(&net->subscr_conns) == 1
+- MS also sends RP-ACK, MSC in turn sends CP-ACK for that
+  MSC <--RAN_GERAN_A-- MS: SMS:0x01
+DREF MSISDN:46071: MSC conn use + dtap == 2 (0x22: dtap,trans_sms)
+DRLL Dispatching 04.08 message SMS:0x01 (0x9:0x1)
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_COMMUNICATING}: Received Event SUBSCR_CONN_E_COMMUNICATING
+DMSC msc_tx 2 bytes to MSISDN:46071 via RAN_GERAN_A
+- DTAP --RAN_GERAN_A--> MS: SMS:0x04: 0904
+- DTAP matches expected message
+DREF VLR subscr MSISDN:46071 usage decreases to: 3
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+DREF MSISDN:46071: MSC conn use - trans_sms == 1 (0x2: dtap)
+DREF MSISDN:46071: MSC conn use - dtap == 0 (0x0: )
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_COMMUNICATING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_COMMUNICATING}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:46071: MSC conn use + release == 1 (0x100: release)
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+- BSSAP Clear --RAN_GERAN_A--> MS
+  dtap_tx_confirmed == 1
+  bssap_clear_sent == 1
+- BSS sends BSSMAP Clear Complete
+DREF MSISDN:46071: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_DONE}: Removing from parent Subscr_Conn(PAGING_RESP:901700000004620)
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_DONE}: Freeing instance
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_DONE}: Deallocated
+DRLL MSISDN:46071: Freeing subscriber connection
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated
+- SMS is done
+  llist_count(&net->subscr_conns) == 0
+DREF freeing VLR subscr MSISDN:46071
+===== 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) == 12
+
+full talloc report on 'msgb' (total      0 bytes in   1 blocks)
+talloc_total_blocks(tall_bsc_ctx) == 12
+
diff --git a/tests/msc_vlr/msc_vlr_test_reject_concurrency.ok b/tests/msc_vlr/msc_vlr_test_reject_concurrency.ok
new file mode 100644
index 0000000..a965a70
--- /dev/null
+++ b/tests/msc_vlr/msc_vlr_test_reject_concurrency.ok
@@ -0,0 +1 @@
+Done
diff --git a/tests/msc_vlr/msc_vlr_test_rest.c b/tests/msc_vlr/msc_vlr_test_rest.c
new file mode 100644
index 0000000..247e7ae
--- /dev/null
+++ b/tests/msc_vlr/msc_vlr_test_rest.c
@@ -0,0 +1,205 @@
+/* Osmocom MSC+VLR end-to-end tests */
+
+/* (C) 2017 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>
+ *
+ * All Rights Reserved
+ *
+ * Author: Neels Hofmeyr <nhofmeyr@sysmocom.de>
+ *
+ * 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 "msc_vlr_tests.h"
+
+static void test_early_stage()
+{
+	comment_start();
+
+	btw("NULL conn");
+	EXPECT_ACCEPTED(false);
+
+	btw("freshly allocated conn");
+	g_conn = msc_subscr_conn_alloc(net, RAN_GERAN_A, 123);
+	EXPECT_ACCEPTED(false);
+
+	btw("conn_fsm present, in state NEW");
+	OSMO_ASSERT(g_conn->fi);
+	OSMO_ASSERT(g_conn->fi->state == SUBSCR_CONN_S_NEW);
+	EXPECT_ACCEPTED(false);
+
+	thwart_rx_non_initial_requests();
+
+	btw("fake: acceptance");
+	g_conn->vsub = vlr_subscr_alloc(net->vlr);
+	g_conn->via_ran = RAN_GERAN_A;
+	OSMO_ASSERT(g_conn->vsub);
+	/* mark as silent call so it sticks around */
+	g_conn->silent_call = 1;
+	osmo_fsm_inst_state_chg(g_conn->fi, SUBSCR_CONN_S_ACCEPTED, 0, 0);
+	EXPECT_CONN_COUNT(1);
+	EXPECT_ACCEPTED(true);
+
+	btw("CLOSE event marks conn_fsm as released and frees the conn");
+	expect_bssap_clear();
+	osmo_fsm_inst_dispatch(g_conn->fi, SUBSCR_CONN_E_CN_CLOSE, NULL);
+	VERBOSE_ASSERT(bssap_clear_sent, == true, "%d");
+	bss_sends_clear_complete();
+	EXPECT_CONN_COUNT(0);
+
+	clear_vlr();
+	comment_end();
+}
+
+static void test_cm_service_without_lu()
+{
+	comment_start();
+
+	btw("CM Service Request without a prior Location Updating");
+	expect_bssap_clear();
+	ms_sends_msg("05247803305886089910070000006402");
+	VERBOSE_ASSERT(bssap_clear_sent, == true, "%d");
+
+	btw("conn was released");
+	bss_sends_clear_complete();
+	EXPECT_CONN_COUNT(0);
+
+	clear_vlr();
+	comment_end();
+}
+
+static void test_two_lu()
+{
+	comment_start();
+
+	btw("Location Update request causes a GSUP LU request to HLR");
+	lu_result_sent = RES_NONE;
+	gsup_expect_tx("04010809710000004026f0280102");
+	ms_sends_msg("050802008168000130089910070000006402");
+	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("10010809710000004026f00804036470f1",
+		"12010809710000004026f0");
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("having received subscriber data does not mean acceptance");
+	EXPECT_ACCEPTED(false);
+
+	thwart_rx_non_initial_requests();
+
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("HLR also sends GSUP _UPDATE_LOCATION_RESULT");
+	expect_bssap_clear();
+	gsup_rx("06010809710000004026f0", NULL);
+	VERBOSE_ASSERT(bssap_clear_sent, == true, "%d");
+
+	btw("LU was successful, and the conn has already been closed");
+	VERBOSE_ASSERT(lu_result_sent, == RES_ACCEPT, "%d");
+	bss_sends_clear_complete();
+	EXPECT_CONN_COUNT(0);
+
+
+	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");
+	ms_sends_msg("050802008168000130089910070000006402");
+	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("10010809710000004026f00804036470f1",
+		"12010809710000004026f0");
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("having received subscriber data does not mean acceptance");
+	EXPECT_ACCEPTED(false);
+
+	thwart_rx_non_initial_requests();
+
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("HLR also sends GSUP _UPDATE_LOCATION_RESULT");
+	expect_bssap_clear();
+	gsup_rx("06010809710000004026f0", NULL);
+	VERBOSE_ASSERT(bssap_clear_sent, == true, "%d");
+
+	btw("LU was successful, and the conn has already been closed");
+	VERBOSE_ASSERT(lu_result_sent, == RES_ACCEPT, "%d");
+	bss_sends_clear_complete();
+	EXPECT_CONN_COUNT(0);
+
+	BTW("subscriber detaches");
+	expect_bssap_clear();
+	ms_sends_msg("050130089910070000006402");
+	VERBOSE_ASSERT(bssap_clear_sent, == true, "%d");
+
+	bss_sends_clear_complete();
+	EXPECT_CONN_COUNT(0);
+	clear_vlr();
+	comment_end();
+}
+
+static void test_lu_unknown_tmsi()
+{
+	comment_start();
+
+	btw("Location Update request with unknown TMSI sends ID Request for IMSI");
+	lu_result_sent = RES_NONE;
+	dtap_expect_tx("051801");
+	ms_sends_msg("050802008168000130" "05f4" "23422342");
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	EXPECT_ACCEPTED(false);
+	thwart_rx_non_initial_requests();
+
+	btw("MS tells us the IMSI, causes a GSUP LU request to HLR");
+	gsup_expect_tx("04010809710000004026f0280102");
+	ms_sends_msg("0559089910070000006402");
+	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("10010809710000004026f00804036470f1",
+		"12010809710000004026f0");
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("having received subscriber data does not mean acceptance");
+	EXPECT_ACCEPTED(false);
+	thwart_rx_non_initial_requests();
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("HLR also sends GSUP _UPDATE_LOCATION_RESULT");
+	expect_bssap_clear();
+	gsup_rx("06010809710000004026f0", NULL);
+	VERBOSE_ASSERT(bssap_clear_sent, == true, "%d");
+
+	btw("LU was successful, and the conn has already been closed");
+	VERBOSE_ASSERT(lu_result_sent, == RES_ACCEPT, "%d");
+	bss_sends_clear_complete();
+	EXPECT_CONN_COUNT(0);
+	clear_vlr();
+	comment_end();
+}
+
+msc_vlr_test_func_t msc_vlr_tests[] = {
+	test_early_stage,
+	test_cm_service_without_lu,
+	test_two_lu,
+	test_lu_unknown_tmsi,
+	NULL
+};
diff --git a/tests/msc_vlr/msc_vlr_test_rest.err b/tests/msc_vlr/msc_vlr_test_rest.err
new file mode 100644
index 0000000..fc3a85d
--- /dev/null
+++ b/tests/msc_vlr/msc_vlr_test_rest.err
@@ -0,0 +1,529 @@
+full talloc report on 'msgb' (total      0 bytes in   1 blocks)
+talloc_total_blocks(tall_bsc_ctx) == 12
+
+===== test_early_stage
+- NULL conn
+msc_subscr_conn_is_accepted() == false
+- freshly allocated conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+msc_subscr_conn_is_accepted() == false
+- conn_fsm present, in state NEW
+msc_subscr_conn_is_accepted() == false
+  requests shall be thwarted
+DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5)
+DRLL subscr unknown: Message not permitted for initial conn: GSM48_MT_CC_SETUP
+DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33)
+DRLL subscr unknown: Message not permitted for initial conn: unknown 0x33
+DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19)
+DRLL subscr unknown: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1
+DRLL Dispatching 04.08 message SMS:0x01 (0x9:0x1)
+DRLL subscr unknown: Message not permitted for initial conn: SMS:0x01
+- fake: acceptance
+DREF VLR subscr unknown usage increases to: 1
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn{SUBSCR_CONN_S_ACCEPTED}: subscr_conn_fsm_has_active_transactions: silent call still active
+  llist_count(&net->subscr_conns) == 1
+msc_subscr_conn_is_accepted() == true
+- CLOSE event marks conn_fsm as released and frees the conn
+DMM Subscr_Conn{SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_CN_CLOSE
+DMM Subscr_Conn{SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF unknown: MSC conn use + release == 1 (0x100: release)
+DREF VLR subscr unknown usage increases to: 2
+DREF VLR subscr unknown usage decreases to: 1
+- BSSAP Clear --RAN_GERAN_A--> MS
+  bssap_clear_sent == 1
+- BSS sends BSSMAP Clear Complete
+DREF unknown: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASED}: subscr_conn_fsm_has_active_transactions: silent call still active
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASED}: Deallocating despite active transactions
+DRLL unknown: Freeing subscriber connection
+DREF VLR subscr unknown usage decreases to: 0
+DREF freeing VLR subscr unknown
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+===== test_early_stage: SUCCESS
+
+full talloc report on 'msgb' (total      0 bytes in   1 blocks)
+talloc_total_blocks(tall_bsc_ctx) == 12
+
+===== test_cm_service_without_lu
+- CM Service Request without a prior Location Updating
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_CM_SERV_REQ
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_CM_SERV_REQ (0x5:0x24)
+DMM <- CM SERVICE REQUEST serv_type=0x08 MI(IMSI)=901700000004620
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_NEW}: Updated ID
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_INIT}: Allocated
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_INIT}: is child of Subscr_Conn(CM_SERVICE_REQ:901700000004620)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_INIT}: rev=GSM net=GERAN (no Auth)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_INIT}: proc_arq_fsm_done(IMSI_UNKNOWN_IN_VLR)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_DONE
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_DONE}: Process Access Request result: IMSI_UNKNOWN_IN_VLR
+- sending CM Service Reject for unknown, cause: IMSI_UNKNOWN_IN_VLR
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_CN_CLOSE
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF unknown: MSC conn use + release == 2 (0x101: compl_l3,release)
+- BSSAP Clear --RAN_GERAN_A--> MS
+DRR 901700000004620: subscriber not allowed to do a CM Service Request
+DREF unknown: MSC conn use - compl_l3 == 1 (0x100: release)
+  bssap_clear_sent == 1
+- conn was released
+- BSS sends BSSMAP Clear Complete
+DREF unknown: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_DONE}: Removing from parent Subscr_Conn(CM_SERVICE_REQ:901700000004620)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_DONE}: Freeing instance
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_DONE}: Deallocated
+DRLL Freeing subscriber connection with NULL subscriber
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+===== test_cm_service_without_lu: SUCCESS
+
+full talloc report on 'msgb' (total      0 bytes in   1 blocks)
+talloc_total_blocks(tall_bsc_ctx) == 12
+
+===== test_two_lu
+- Location Update request causes a GSUP LU request to HLR
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8)
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Updated ID
+DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000004620 type=IMSI ATTACH
+DMM LU/new-LAC: 1/23
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Allocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: is child of Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: rev=GSM net=GERAN (no Auth)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA
+DREF VLR subscr unknown usage increases to: 1
+DVLR set IMSI on subscriber; IMSI=901700000004620 id=901700000004620
+DVLR New subscr, IMSI: 901700000004620
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DREF VLR subscr IMSI:901700000004620 usage decreases to: 1
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_post_auth()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_post_ciph()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node_4()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: Allocated
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START
+DVLR GSUP tx: 04010809710000004026f0280102
+GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000004026f0280102
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF IMSI:901700000004620: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  lu_result_sent == 0
+- HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT
+<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: 10010809710000004026f00804036470f1
+DVLR GSUP rx 17: 10010809710000004026f00804036470f1
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DVLR IMSI:901700000004620 has MSISDN:46071
+DVLR SUBSCR(MSISDN:46071) VLR: update for IMSI=901700000004620 (MSISDN=46071, used=2)
+DVLR GSUP tx: 12010809710000004026f0
+GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000004026f0
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: vlr_gsupc_read_cb() returns 0
+  lu_result_sent == 0
+- having received subscriber data does not mean acceptance
+msc_subscr_conn_is_accepted() == false
+  requests shall be thwarted
+DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_CC_SETUP
+DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: unknown 0x33
+DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1
+DRLL Dispatching 04.08 message SMS:0x01 (0x9:0x1)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: SMS:0x01
+  lu_result_sent == 0
+- HLR also sends GSUP _UPDATE_LOCATION_RESULT
+<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: 06010809710000004026f0
+DVLR GSUP rx 11: 06010809710000004026f0
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Freeing instance
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: Allocated
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: Allocated
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(LU:901700000004620)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(LU:901700000004620)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Freeing instance
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Deallocated
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL
+- sending LU Accept for MSISDN:46071
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_DONE
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Freeing instance
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_ACCEPTED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:46071: MSC conn use + release == 1 (0x100: release)
+DREF VLR subscr MSISDN:46071 usage increases to: 4
+DREF VLR subscr MSISDN:46071 usage decreases to: 3
+- BSSAP Clear --RAN_GERAN_A--> MS
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+<-- 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
+  lu_result_sent == 1
+- BSS sends BSSMAP Clear Complete
+DREF MSISDN:46071: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Freeing instance
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Deallocated
+DRLL MSISDN:46071: Freeing subscriber connection
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+---
+- verify that the MS can send another LU request
+- Location Update request causes a GSUP LU request to HLR
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8)
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Updated ID
+DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000004620 type=IMSI ATTACH
+DMM LU/new-LAC: 1/23
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Allocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: is child of Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: rev=GSM net=GERAN (no Auth)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_post_auth()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_post_ciph()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node_4()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: Allocated
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START
+DVLR GSUP tx: 04010809710000004026f0280102
+GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000004026f0280102
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF MSISDN:46071: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  lu_result_sent == 0
+- HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT
+<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: 10010809710000004026f00804036470f1
+DVLR GSUP rx 17: 10010809710000004026f00804036470f1
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DVLR IMSI:901700000004620 has MSISDN:46071
+DVLR SUBSCR(MSISDN:46071) VLR: update for IMSI=901700000004620 (MSISDN=46071, used=3)
+DVLR GSUP tx: 12010809710000004026f0
+GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000004026f0
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: vlr_gsupc_read_cb() returns 0
+  lu_result_sent == 0
+- having received subscriber data does not mean acceptance
+msc_subscr_conn_is_accepted() == false
+  requests shall be thwarted
+DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_CC_SETUP
+DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: unknown 0x33
+DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1
+DRLL Dispatching 04.08 message SMS:0x01 (0x9:0x1)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: SMS:0x01
+  lu_result_sent == 0
+- HLR also sends GSUP _UPDATE_LOCATION_RESULT
+<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: 06010809710000004026f0
+DVLR GSUP rx 11: 06010809710000004026f0
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Freeing instance
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: Allocated
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: Allocated
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(LU:901700000004620)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(LU:901700000004620)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Freeing instance
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Deallocated
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL
+- sending LU Accept for MSISDN:46071
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_DONE
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Freeing instance
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_ACCEPTED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:46071: MSC conn use + release == 1 (0x100: release)
+DREF VLR subscr MSISDN:46071 usage increases to: 4
+DREF VLR subscr MSISDN:46071 usage decreases to: 3
+- BSSAP Clear --RAN_GERAN_A--> MS
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+<-- 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
+  lu_result_sent == 1
+- BSS sends BSSMAP Clear Complete
+DREF MSISDN:46071: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Freeing instance
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Deallocated
+DRLL MSISDN:46071: Freeing subscriber connection
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+---
+- subscriber detaches
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_IMSI_DETACH_IND
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_IMSI_DETACH_IND (0x5:0x1)
+DMM IMSI DETACH INDICATION: MI(IMSI)=901700000004620
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+DMM IMSI DETACH for MSISDN:46071
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+DREF VLR subscr MSISDN:46071 usage decreases to: 0
+DREF freeing VLR subscr MSISDN:46071
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_CN_CLOSE
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF unknown: MSC conn use + release == 2 (0x101: compl_l3,release)
+- BSSAP Clear --RAN_GERAN_A--> MS
+DREF unknown: MSC conn use - compl_l3 == 1 (0x100: release)
+  bssap_clear_sent == 1
+- BSS sends BSSMAP Clear Complete
+DREF unknown: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DRLL Freeing subscriber connection with NULL subscriber
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+===== test_two_lu: SUCCESS
+
+full talloc report on 'msgb' (total      0 bytes in   1 blocks)
+talloc_total_blocks(tall_bsc_ctx) == 12
+
+===== test_lu_unknown_tmsi
+- Location Update request with unknown TMSI sends ID Request for IMSI
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8)
+DMM Subscr_Conn(LU:591536962){SUBSCR_CONN_S_NEW}: Updated ID
+DMM LOCATION UPDATING REQUEST: MI(TMSI)=591536962 type=IMSI ATTACH
+DMM LU/new-LAC: 1/23
+DVLR vlr_lu_fsm(LU:591536962){VLR_ULA_S_IDLE}: Allocated
+DVLR vlr_lu_fsm(LU:591536962){VLR_ULA_S_IDLE}: is child of Subscr_Conn(LU:591536962)
+DVLR vlr_lu_fsm(LU:591536962){VLR_ULA_S_IDLE}: rev=GSM net=GERAN (no Auth)
+DVLR vlr_lu_fsm(LU:591536962){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA
+DREF VLR subscr unknown usage increases to: 1
+DVLR New subscr, TMSI: 0x23422342
+DREF VLR subscr TMSI:0x23422342 usage increases to: 2
+DREF VLR subscr TMSI:0x23422342 usage decreases to: 1
+DVLR vlr_lu_fsm(LU:591536962){VLR_ULA_S_IDLE}: vlr_loc_upd_want_imsi()
+DVLR vlr_lu_fsm(LU:591536962){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_IMSI
+DMSC msc_tx 3 bytes to TMSI:0x23422342 via RAN_GERAN_A
+- DTAP --RAN_GERAN_A--> MS: GSM48_MT_MM_ID_REQ: 051801
+- DTAP matches expected message
+DMM Subscr_Conn(LU:591536962){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(LU:591536962){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF TMSI:0x23422342: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(LU:591536962){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:591536962){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  lu_result_sent == 0
+msc_subscr_conn_is_accepted() == false
+  requests shall be thwarted
+DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5)
+DRLL subscr TMSI:0x23422342: Message not permitted for initial conn: GSM48_MT_CC_SETUP
+DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33)
+DRLL subscr TMSI:0x23422342: Message not permitted for initial conn: unknown 0x33
+DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19)
+DRLL subscr TMSI:0x23422342: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1
+DRLL Dispatching 04.08 message SMS:0x01 (0x9:0x1)
+DRLL subscr TMSI:0x23422342: Message not permitted for initial conn: SMS:0x01
+- MS tells us the IMSI, causes a GSUP LU request to HLR
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_ID_RESP
+DREF TMSI:0x23422342: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_ID_RESP (0x5:0x19)
+DMM IDENTITY RESPONSE: MI(IMSI)=901700000004620
+DVLR set IMSI on subscriber; IMSI=901700000004620 id=901700000004620
+DVLR vlr_lu_fsm(LU:591536962){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(LU:591536962){VLR_ULA_S_WAIT_IMSI}: vlr_loc_upd_node1()
+DVLR vlr_lu_fsm(LU:591536962){VLR_ULA_S_WAIT_IMSI}: vlr_loc_upd_post_auth()
+DVLR vlr_lu_fsm(LU:591536962){VLR_ULA_S_WAIT_IMSI}: vlr_loc_upd_post_ciph()
+DVLR vlr_lu_fsm(LU:591536962){VLR_ULA_S_WAIT_IMSI}: vlr_loc_upd_node_4()
+DVLR vlr_lu_fsm(LU:591536962){VLR_ULA_S_WAIT_IMSI}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
+DVLR upd_hlr_vlr_fsm(LU:591536962){UPD_HLR_VLR_S_INIT}: Allocated
+DVLR upd_hlr_vlr_fsm(LU:591536962){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(LU:591536962)
+DVLR upd_hlr_vlr_fsm(LU:591536962){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START
+DVLR GSUP tx: 04010809710000004026f0280102
+GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000004026f0280102
+DVLR upd_hlr_vlr_fsm(LU:591536962){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA
+DREF IMSI:901700000004620: MSC conn use - dtap == 0 (0x0: )
+DMM Subscr_Conn(LU:591536962){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:591536962){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  lu_result_sent == 0
+- HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT
+<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: 10010809710000004026f00804036470f1
+DVLR GSUP rx 17: 10010809710000004026f00804036470f1
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DVLR IMSI:901700000004620 has MSISDN:46071
+DVLR SUBSCR(MSISDN:46071) VLR: update for IMSI=901700000004620 (MSISDN=46071, used=2)
+DVLR GSUP tx: 12010809710000004026f0
+GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000004026f0
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: vlr_gsupc_read_cb() returns 0
+  lu_result_sent == 0
+- having received subscriber data does not mean acceptance
+msc_subscr_conn_is_accepted() == false
+  requests shall be thwarted
+DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_CC_SETUP
+DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: unknown 0x33
+DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1
+DRLL Dispatching 04.08 message SMS:0x01 (0x9:0x1)
+DRLL subscr MSISDN:46071: Message not permitted for initial conn: SMS:0x01
+  lu_result_sent == 0
+- HLR also sends GSUP _UPDATE_LOCATION_RESULT
+<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: 06010809710000004026f0
+DVLR GSUP rx 11: 06010809710000004026f0
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+DVLR vlr_lu_fsm(LU:591536962){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES
+DVLR upd_hlr_vlr_fsm(LU:591536962){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK
+DVLR upd_hlr_vlr_fsm(LU:591536962){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE
+DVLR upd_hlr_vlr_fsm(LU:591536962){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR upd_hlr_vlr_fsm(LU:591536962){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:591536962)
+DVLR upd_hlr_vlr_fsm(LU:591536962){UPD_HLR_VLR_S_DONE}: Freeing instance
+DVLR upd_hlr_vlr_fsm(LU:591536962){UPD_HLR_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:591536962){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL
+DVLR vlr_lu_fsm(LU:591536962){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL
+DVLR lu_compl_vlr_fsm(LU:591536962){LU_COMPL_VLR_S_INIT}: Allocated
+DVLR lu_compl_vlr_fsm(LU:591536962){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(LU:591536962)
+DVLR lu_compl_vlr_fsm(LU:591536962){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START
+DVLR lu_compl_vlr_fsm(LU:591536962){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES
+DVLR sub_pres_vlr_fsm(LU:591536962){SUB_PRES_VLR_S_INIT}: Allocated
+DVLR sub_pres_vlr_fsm(LU:591536962){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(LU:591536962)
+DVLR sub_pres_vlr_fsm(LU:591536962){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START
+DVLR sub_pres_vlr_fsm(LU:591536962){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE
+DVLR sub_pres_vlr_fsm(LU:591536962){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR sub_pres_vlr_fsm(LU:591536962){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(LU:591536962)
+DVLR sub_pres_vlr_fsm(LU:591536962){SUB_PRES_VLR_S_DONE}: Freeing instance
+DVLR sub_pres_vlr_fsm(LU:591536962){SUB_PRES_VLR_S_DONE}: Deallocated
+DVLR lu_compl_vlr_fsm(LU:591536962){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL
+- sending LU Accept for MSISDN:46071
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DVLR lu_compl_vlr_fsm(LU:591536962){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_DONE
+DVLR vlr_lu_fsm(LU:591536962){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS
+DVLR lu_compl_vlr_fsm(LU:591536962){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR lu_compl_vlr_fsm(LU:591536962){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:591536962)
+DVLR lu_compl_vlr_fsm(LU:591536962){LU_COMPL_VLR_S_DONE}: Freeing instance
+DVLR lu_compl_vlr_fsm(LU:591536962){LU_COMPL_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:591536962){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE
+DMM Subscr_Conn(LU:591536962){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_ACCEPTED
+DMM Subscr_Conn(LU:591536962){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(LU:591536962){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:591536962){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:46071: MSC conn use + release == 1 (0x100: release)
+DREF VLR subscr MSISDN:46071 usage increases to: 4
+DREF VLR subscr MSISDN:46071 usage decreases to: 3
+- BSSAP Clear --RAN_GERAN_A--> MS
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+<-- 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
+  lu_result_sent == 1
+- BSS sends BSSMAP Clear Complete
+DREF MSISDN:46071: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(LU:591536962){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:591536962){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(LU:591536962){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR vlr_lu_fsm(LU:591536962){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR vlr_lu_fsm(LU:591536962){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(LU:591536962)
+DVLR vlr_lu_fsm(LU:591536962){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT
+DVLR vlr_lu_fsm(LU:591536962){VLR_ULA_S_DONE}: Freeing instance
+DVLR vlr_lu_fsm(LU:591536962){VLR_ULA_S_DONE}: Deallocated
+DRLL MSISDN:46071: Freeing subscriber connection
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+DMM Subscr_Conn(LU:591536962){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(LU:591536962){SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+DREF freeing VLR subscr MSISDN:46071
+===== test_lu_unknown_tmsi: SUCCESS
+
+full talloc report on 'msgb' (total      0 bytes in   1 blocks)
+talloc_total_blocks(tall_bsc_ctx) == 12
+
+full talloc report on 'msgb' (total      0 bytes in   1 blocks)
+talloc_total_blocks(tall_bsc_ctx) == 12
+
diff --git a/tests/msc_vlr/msc_vlr_test_rest.ok b/tests/msc_vlr/msc_vlr_test_rest.ok
new file mode 100644
index 0000000..a965a70
--- /dev/null
+++ b/tests/msc_vlr/msc_vlr_test_rest.ok
@@ -0,0 +1 @@
+Done
diff --git a/tests/msc_vlr/msc_vlr_test_ss.c b/tests/msc_vlr/msc_vlr_test_ss.c
new file mode 100644
index 0000000..34aa634
--- /dev/null
+++ b/tests/msc_vlr/msc_vlr_test_ss.c
@@ -0,0 +1,215 @@
+/*
+ * Osmocom MSC+VLR end-to-end tests
+ *
+ * (C) 2018 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 "msc_vlr_tests.h"
+
+#define IMSI "901700000004620"
+
+#define FACILITY_IE_REQ \
+	"a113"    /* Invoke component, len=19 */ \
+	"020101"  /* InvokeID=1 */ \
+	"02013b"  /* OpCode=GSM0480_OP_CODE_PROCESS_USS_REQ */ \
+	"300b"    /* Sequence tag, len=11 */ \
+	"04010f"  /* DCS: Default 7-bit alphabet */ \
+	"0406aa510c061b01" /* USSD text: *#100#, len=6 */
+
+#define FACILITY_IE_RSP \
+	"a225"    /* ReturnResult, len=37 */ \
+	"020101"  /* InvokeID=1 */ \
+	"3020"    /* Sequence tag, len=32 */ \
+	"02013b"  /* OpCode=GSM0480_OP_CODE_PROCESS_USS_REQ */ \
+	"301b"    /* Sequence tag, len=27 */ \
+	"04010f"  /* DCS: Default 7-bit alphabet */ \
+	"0416d9775d0e2ae3e965f73cfd7683d27310cd06bbc51a0d"
+
+static void perform_lu(void)
+{
+	struct vlr_subscr *vsub;
+
+	btw("Location Update request causes a GSUP LU request to HLR");
+	lu_result_sent = RES_NONE;
+	gsup_expect_tx("04010809710000004026f0280102");
+	ms_sends_msg("050802008168000130089910070000006402");
+	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("10010809710000004026f00804036470f1",
+		"12010809710000004026f0");
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("HLR also sends GSUP _UPDATE_LOCATION_RESULT");
+	expect_bssap_clear();
+	gsup_rx("06010809710000004026f0", 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");
+
+	vsub = vlr_subscr_find_by_imsi(net->vlr, IMSI);
+	VERBOSE_ASSERT(vsub != NULL, == true, "%d");
+	VERBOSE_ASSERT(strcmp(vsub->imsi, IMSI), == 0, "%d");
+	VERBOSE_ASSERT(vsub->lac, == 23, "%u");
+	vlr_subscr_put(vsub);
+
+	bss_sends_clear_complete();
+	EXPECT_CONN_COUNT(0);
+}
+
+static void _test_ss_ussd_mo(enum ran_type via_ran)
+{
+	/* TODO: UTRAN requires auth and ciph */
+	rx_from_ran = via_ran;
+
+	/* Perform Location Update */
+	perform_lu();
+
+	BTW("after a while, a new conn sends a CM Service Request");
+
+	cm_service_result_sent = RES_NONE;
+	ms_sends_msg("05247803305886089910070000006402");
+	OSMO_ASSERT(g_conn);
+	OSMO_ASSERT(g_conn->fi);
+	OSMO_ASSERT(g_conn->vsub);
+	VERBOSE_ASSERT(cm_service_result_sent, == RES_ACCEPT, "%d");
+	EXPECT_ACCEPTED(true);
+
+	/* MT: GSM 04.80 RELEASE COMPLETE with Facility IE */
+	gsup_expect_tx("20" /* OSMO_GSUP_MSGT_PROC_SS_REQUEST */
+		"0108" "09710000004026f0" /* IMSI TLV */
+		"3004" "20000001" /* Session ID TLV */
+		"3101" "01" /* Session state: BEGIN */
+		"3515" FACILITY_IE_REQ);
+	dtap_expect_tx("8b2a" "1c27" FACILITY_IE_RSP);
+	expect_release_clear(via_ran);
+
+	/* MO: GSM 04.80 REGISTER with Facility IE and SS version IE */
+	ms_sends_msg("0b7b" "1c15" FACILITY_IE_REQ "7f0100");
+	gsup_rx("20" /* OSMO_GSUP_MSGT_PROC_SS_REQUEST */
+		"0108" "09710000004026f0" /* IMSI TLV */
+		"3004" "20000001" /* Session ID TLV */
+		"3101" "03" /* Session state: END */
+		"3527" FACILITY_IE_RSP, NULL);
+	VERBOSE_ASSERT(dtap_tx_confirmed, == true, "%d");
+	ASSERT_RELEASE_CLEAR(via_ran);
+
+	btw("all requests serviced, conn has been released");
+	bss_sends_clear_complete();
+	EXPECT_CONN_COUNT(0);
+}
+
+static void _test_ss_ussd_no(enum ran_type via_ran)
+{
+	struct vlr_subscr *vsub;
+
+	/* TODO: UTRAN requires auth and ciph */
+	rx_from_ran = via_ran;
+
+	/* Perform Location Update */
+	perform_lu();
+
+	BTW("after a while, HLR initiates SS/USSD session");
+
+	paging_expect_imsi(IMSI);
+	paging_sent = false;
+	vsub = vlr_subscr_find_by_imsi(net->vlr, IMSI);
+	OSMO_ASSERT(vsub);
+	VERBOSE_ASSERT(llist_count(&vsub->cs.requests), == 0, "%d");
+
+	/* MT: GSM 04.80 REGISTER with request */
+	gsup_rx("20" /* OSMO_GSUP_MSGT_PROC_SS_REQUEST */
+		"0108" "09710000004026f0" /* IMSI TLV */
+		"3004" "20000101" /* Session ID TLV */
+		"3101" "01" /* Session state: BEGIN */
+		"3515" FACILITY_IE_REQ, NULL);
+
+	VERBOSE_ASSERT(llist_count(&vsub->cs.requests), == 1, "%d");
+	vlr_subscr_put(vsub);
+	vsub = NULL;
+	VERBOSE_ASSERT(paging_sent, == true, "%d");
+	VERBOSE_ASSERT(paging_stopped, == false, "%d");
+
+	btw("the subscriber and its pending request should remain");
+	vsub = vlr_subscr_find_by_imsi(net->vlr, IMSI);
+	OSMO_ASSERT(vsub);
+	VERBOSE_ASSERT(llist_count(&vsub->cs.requests), == 1, "%d");
+	vlr_subscr_put(vsub);
+
+	btw("MS replies with Paging Response, we deliver the NC/USSD");
+
+	dtap_expect_tx("0b3b" "1c15" FACILITY_IE_REQ);
+	ms_sends_msg("06270703305882089910070000006402");
+	VERBOSE_ASSERT(dtap_tx_confirmed, == true, "%d");
+	VERBOSE_ASSERT(paging_stopped, == true, "%d");
+
+	btw("MS responds to SS/USSD request");
+
+	/* MO: GSM 04.80 FACILITY with response */
+	gsup_expect_tx("20" /* OSMO_GSUP_MSGT_PROC_SS_REQUEST */
+		"0108" "09710000004026f0" /* IMSI TLV */
+		"3004" "20000101" /* Session ID TLV */
+		"3101" "02" /* Session state: CONTINUE */
+		"3527" FACILITY_IE_RSP);
+	ms_sends_msg("8b3a" "27" FACILITY_IE_RSP);
+	VERBOSE_ASSERT(dtap_tx_confirmed, == true, "%d");
+	VERBOSE_ASSERT(paging_stopped, == true, "%d");
+
+	btw("HLR terminates the session");
+
+	/* MT: GSM 04.80 RELEASE COMPLETE without Facility IE */
+	dtap_expect_tx("0b2a");
+	expect_release_clear(via_ran);
+	gsup_rx("20" /* OSMO_GSUP_MSGT_PROC_SS_REQUEST */
+		"0108" "09710000004026f0" /* IMSI TLV */
+		"3004" "20000101" /* Session ID TLV */
+		"3101" "03", /* Session state: END */
+		NULL);
+	VERBOSE_ASSERT(dtap_tx_confirmed, == true, "%d");
+	ASSERT_RELEASE_CLEAR(via_ran);
+
+	btw("all requests serviced, conn has been released");
+	bss_sends_clear_complete();
+	EXPECT_CONN_COUNT(0);
+}
+
+static void test_ss_ussd_mo_geran()
+{
+	comment_start();
+	_test_ss_ussd_mo(RAN_GERAN_A);
+	clear_vlr();
+	comment_end();
+}
+
+static void test_ss_ussd_no_geran()
+{
+	comment_start();
+	_test_ss_ussd_no(RAN_GERAN_A);
+	clear_vlr();
+	comment_end();
+}
+
+msc_vlr_test_func_t msc_vlr_tests[] = {
+	/* TODO: UTRAN requires auth and enc */
+	test_ss_ussd_mo_geran, /* MS-originated */
+	test_ss_ussd_no_geran, /* Network-originated */
+	NULL
+};
diff --git a/tests/msc_vlr/msc_vlr_test_ss.err b/tests/msc_vlr/msc_vlr_test_ss.err
new file mode 100644
index 0000000..0f10910
--- /dev/null
+++ b/tests/msc_vlr/msc_vlr_test_ss.err
@@ -0,0 +1,443 @@
+full talloc report on 'msgb' (total      0 bytes in   1 blocks)
+talloc_total_blocks(tall_bsc_ctx) == 12
+
+===== test_ss_ussd_mo_geran
+- Location Update request causes a GSUP LU request to HLR
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8)
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Updated ID
+DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000004620 type=IMSI ATTACH
+DMM LU/new-LAC: 1/23
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Allocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: is child of Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: rev=GSM net=GERAN (no Auth)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA
+DREF VLR subscr unknown usage increases to: 1
+DVLR set IMSI on subscriber; IMSI=901700000004620 id=901700000004620
+DVLR New subscr, IMSI: 901700000004620
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DREF VLR subscr IMSI:901700000004620 usage decreases to: 1
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_post_auth()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_post_ciph()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node_4()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: Allocated
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START
+DVLR GSUP tx: 04010809710000004026f0280102
+GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000004026f0280102
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF IMSI:901700000004620: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  lu_result_sent == 0
+- HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT
+<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: 10010809710000004026f00804036470f1
+DVLR GSUP rx 17: 10010809710000004026f00804036470f1
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DVLR IMSI:901700000004620 has MSISDN:46071
+DVLR SUBSCR(MSISDN:46071) VLR: update for IMSI=901700000004620 (MSISDN=46071, used=2)
+DVLR GSUP tx: 12010809710000004026f0
+GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000004026f0
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+<-- 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: 06010809710000004026f0
+DVLR GSUP rx 11: 06010809710000004026f0
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Freeing instance
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: Allocated
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: Allocated
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(LU:901700000004620)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(LU:901700000004620)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Freeing instance
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Deallocated
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL
+- sending LU Accept for MSISDN:46071
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_DONE
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Freeing instance
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_ACCEPTED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:46071: MSC conn use + release == 1 (0x100: release)
+DREF VLR subscr MSISDN:46071 usage increases to: 4
+DREF VLR subscr MSISDN:46071 usage decreases to: 3
+- BSSAP Clear --RAN_GERAN_A--> MS
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+<-- 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
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+  vsub != NULL == 1
+  strcmp(vsub->imsi, IMSI) == 0
+  vsub->lac == 23
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+- BSS sends BSSMAP Clear Complete
+DREF MSISDN:46071: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Freeing instance
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Deallocated
+DRLL MSISDN:46071: Freeing subscriber connection
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+---
+- after a while, a new conn sends a CM Service Request
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_CM_SERV_REQ
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_CM_SERV_REQ (0x5:0x24)
+DMM <- CM SERVICE REQUEST serv_type=0x08 MI(IMSI)=901700000004620
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_NEW}: Updated ID
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_INIT}: Allocated
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_INIT}: is child of Subscr_Conn(CM_SERVICE_REQ:901700000004620)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_INIT}: rev=GSM net=GERAN (no Auth)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_node2()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_ciph()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_vlr()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_post_pres()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_post_trace()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_post_imei()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_INIT}: proc_arq_fsm_done(PASSED)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_DONE
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_DONE}: Process Access Request result: PASSED
+- sending CM Service Accept for MSISDN:46071
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_ACCEPTED
+DREF MSISDN:46071: MSC conn use + cm_service == 2 (0x9: compl_l3,cm_service)
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_ACCEPTED}: subscr_conn_fsm_has_active_transactions: still awaiting first request after a CM Service Request
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DREF MSISDN:46071: MSC conn use - compl_l3 == 1 (0x8: cm_service)
+  cm_service_result_sent == 1
+msc_subscr_conn_is_accepted() == true
+  MSC <--RAN_GERAN_A-- MS: GSM0480_MTYPE_REGISTER
+DREF MSISDN:46071: MSC conn use + dtap == 2 (0xa: dtap,cm_service)
+DRLL Dispatching 04.08 message GSM0480_MTYPE_REGISTER (0xb:0x3b)
+DMM Received SS/USSD data (trans_id=8, msg_type=GSM0480_MTYPE_REGISTER)
+DMM  -> (new transaction)
+DCC (ti 08 sub MSISDN:46071 callref 20000001) New transaction
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DREF MSISDN:46071: MSC conn use + trans_nc_ss == 3 (0x4a: dtap,cm_service,trans_nc_ss)
+DMM MSISDN:46071: rx msg GSM0480_MTYPE_REGISTER: received_cm_service_request changes to false
+DREF MSISDN:46071: MSC conn use - cm_service == 2 (0x42: dtap,trans_nc_ss)
+GSUP --> HLR: OSMO_GSUP_MSGT_PROC_SS_REQUEST: 20010809710000004026f03004200000013101013515a11302010102013b300b04010f0406aa510c061b01
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_COMMUNICATING
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_COMMUNICATING
+DREF MSISDN:46071: MSC conn use - dtap == 1 (0x40: trans_nc_ss)
+<-- GSUP rx OSMO_GSUP_MSGT_PROC_SS_REQUEST: 20010809710000004026f03004200000013101033527a225020101302002013b301b04010f0416d9775d0e2ae3e965f73cfd7683d27310cd06bbc51a0d
+DVLR GSUP rx 61: 20010809710000004026f03004200000013101033527a225020101302002013b301b04010f0416d9775d0e2ae3e965f73cfd7683d27310cd06bbc51a0d
+DREF VLR subscr MSISDN:46071 usage increases to: 4
+DMSC Routed to GSM 09.11 SS/USSD handler
+DMSC msc_tx 43 bytes to MSISDN:46071 via RAN_GERAN_A
+- DTAP --RAN_GERAN_A--> MS: GSM0480_MTYPE_RELEASE_COMPLETE: 8b2a1c27a225020101302002013b301b04010f0416d9775d0e2ae3e965f73cfd7683d27310cd06bbc51a0d
+- DTAP matches expected message
+DREF VLR subscr MSISDN:46071 usage decreases to: 3
+DREF MSISDN:46071: MSC conn use - trans_nc_ss == 0 (0x0: )
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_COMMUNICATING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_COMMUNICATING}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:46071: MSC conn use + release == 1 (0x100: release)
+DREF VLR subscr MSISDN:46071 usage increases to: 4
+DREF VLR subscr MSISDN:46071 usage decreases to: 3
+- BSSAP Clear --RAN_GERAN_A--> MS
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+<-- GSUP rx OSMO_GSUP_MSGT_PROC_SS_REQUEST: vlr_gsupc_read_cb() returns 0
+  dtap_tx_confirmed == 1
+  bssap_clear_sent == 1
+- all requests serviced, conn has been released
+- BSS sends BSSMAP Clear Complete
+DREF MSISDN:46071: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_DONE}: Removing from parent Subscr_Conn(CM_SERVICE_REQ:901700000004620)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_DONE}: Freeing instance
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000004620){PR_ARQ_S_DONE}: Deallocated
+DRLL MSISDN:46071: Freeing subscriber connection
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+DREF freeing VLR subscr MSISDN:46071
+===== test_ss_ussd_mo_geran: SUCCESS
+
+full talloc report on 'msgb' (total      0 bytes in   1 blocks)
+talloc_total_blocks(tall_bsc_ctx) == 12
+
+===== test_ss_ussd_no_geran
+- Location Update request causes a GSUP LU request to HLR
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8)
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Updated ID
+DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000004620 type=IMSI ATTACH
+DMM LU/new-LAC: 1/23
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Allocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: is child of Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: rev=GSM net=GERAN (no Auth)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA
+DREF VLR subscr unknown usage increases to: 1
+DVLR set IMSI on subscriber; IMSI=901700000004620 id=901700000004620
+DVLR New subscr, IMSI: 901700000004620
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DREF VLR subscr IMSI:901700000004620 usage decreases to: 1
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_post_auth()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_post_ciph()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node_4()
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: Allocated
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START
+DVLR GSUP tx: 04010809710000004026f0280102
+GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000004026f0280102
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF IMSI:901700000004620: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  lu_result_sent == 0
+- HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT
+<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: 10010809710000004026f00804036470f1
+DVLR GSUP rx 17: 10010809710000004026f00804036470f1
+DREF VLR subscr IMSI:901700000004620 usage increases to: 2
+DVLR IMSI:901700000004620 has MSISDN:46071
+DVLR SUBSCR(MSISDN:46071) VLR: update for IMSI=901700000004620 (MSISDN=46071, used=2)
+DVLR GSUP tx: 12010809710000004026f0
+GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000004026f0
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+<-- 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: 06010809710000004026f0
+DVLR GSUP rx 11: 06010809710000004026f0
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Freeing instance
+DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: Allocated
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000004620)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: Allocated
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(LU:901700000004620)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(LU:901700000004620)
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Freeing instance
+DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Deallocated
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL
+- sending LU Accept for MSISDN:46071
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_DONE
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000004620)
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Freeing instance
+DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_ACCEPTED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:46071: MSC conn use + release == 1 (0x100: release)
+DREF VLR subscr MSISDN:46071 usage increases to: 4
+DREF VLR subscr MSISDN:46071 usage decreases to: 3
+- BSSAP Clear --RAN_GERAN_A--> MS
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+<-- 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
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+  vsub != NULL == 1
+  strcmp(vsub->imsi, IMSI) == 0
+  vsub->lac == 23
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+- BSS sends BSSMAP Clear Complete
+DREF MSISDN:46071: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(LU:901700000004620)
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Freeing instance
+DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Deallocated
+DRLL MSISDN:46071: Freeing subscriber connection
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+---
+- after a while, HLR initiates SS/USSD session
+DREF VLR subscr MSISDN:46071 usage increases to: 2
+  llist_count(&vsub->cs.requests) == 0
+<-- GSUP rx OSMO_GSUP_MSGT_PROC_SS_REQUEST: 20010809710000004026f03004200001013101013515a11302010102013b300b04010f0406aa510c061b01
+DVLR GSUP rx 43: 20010809710000004026f03004200001013101013515a11302010102013b300b04010f0406aa510c061b01
+DREF VLR subscr MSISDN:46071 usage increases to: 3
+DMSC Routed to GSM 09.11 SS/USSD handler
+DMM Establishing network-originated session
+DCC (ti ff sub MSISDN:46071 callref 20000101) New transaction
+DREF VLR subscr MSISDN:46071 usage increases to: 4
+DMM Triggering Paging Request
+DMM Subscriber MSISDN:46071 not paged yet, start paging.
+  RAN_GERAN_A sends out paging request to IMSI 901700000004620, TMSI 0xffffffff, LAC 23
+  strcmp(paging_expecting_imsi, imsi) == 0
+DREF VLR subscr MSISDN:46071 usage increases to: 5
+DREF VLR subscr MSISDN:46071 usage decreases to: 4
+<-- GSUP rx OSMO_GSUP_MSGT_PROC_SS_REQUEST: vlr_gsupc_read_cb() returns -22
+  llist_count(&vsub->cs.requests) == 1
+DREF VLR subscr MSISDN:46071 usage decreases to: 3
+  paging_sent == 1
+  paging_stopped == 0
+- the subscriber and its pending request should remain
+DREF VLR subscr MSISDN:46071 usage increases to: 4
+  llist_count(&vsub->cs.requests) == 1
+DREF VLR subscr MSISDN:46071 usage decreases to: 3
+- MS replies with Paging Response, we deliver the NC/USSD
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_RR_PAG_RESP
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_RR_PAG_RESP (0x6:0x27)
+DRR PAGING RESPONSE: MI(IMSI)=901700000004620
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_NEW}: Updated ID
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_INIT}: Allocated
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_INIT}: is child of Subscr_Conn(PAGING_RESP:901700000004620)
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_INIT}: rev=GSM net=GERAN (no Auth)
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START
+DREF VLR subscr MSISDN:46071 usage increases to: 4
+DREF VLR subscr MSISDN:46071 usage increases to: 5
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi()
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_node2()
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_ciph()
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_node2_post_vlr()
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_post_pres()
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_post_trace()
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_INIT}: _proc_arq_vlr_post_imei()
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_INIT}: proc_arq_fsm_done(PASSED)
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_DONE
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_DONE}: Process Access Request result: PASSED
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_ACCEPTED
+DPAG Paging success for MSISDN:46071 (event=0)
+DPAG Calling paging cbfn.
+DMM Paging subscr 46071 succeeded!
+DREF MSISDN:46071: MSC conn use + trans_nc_ss == 2 (0x41: compl_l3,trans_nc_ss)
+DMSC msc_tx 25 bytes to MSISDN:46071 via RAN_GERAN_A
+- DTAP --RAN_GERAN_A--> MS: GSM0480_MTYPE_REGISTER: 0b3b1c15a11302010102013b300b04010f0406aa510c061b01
+- DTAP matches expected message
+DREF VLR subscr MSISDN:46071 usage decreases to: 4
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_ACCEPTED}: subscr_conn_fsm_has_active_transactions: connection still has active transaction: NCSS
+DREF VLR subscr MSISDN:46071 usage decreases to: 3
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DREF MSISDN:46071: MSC conn use - compl_l3 == 1 (0x40: trans_nc_ss)
+  dtap_tx_confirmed == 1
+  paging_stopped == 1
+- MS responds to SS/USSD request
+  MSC <--RAN_GERAN_A-- MS: GSM0480_MTYPE_FACILITY
+DREF MSISDN:46071: MSC conn use + dtap == 2 (0x42: dtap,trans_nc_ss)
+DRLL Dispatching 04.08 message GSM0480_MTYPE_FACILITY (0xb:0x3a)
+DMM Received SS/USSD data (trans_id=0, msg_type=GSM0480_MTYPE_FACILITY)
+GSUP --> HLR: OSMO_GSUP_MSGT_PROC_SS_REQUEST: 20010809710000004026f03004200001013101023527a225020101302002013b301b04010f0416d9775d0e2ae3e965f73cfd7683d27310cd06bbc51a0d
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_COMMUNICATING
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_COMMUNICATING
+DREF MSISDN:46071: MSC conn use - dtap == 1 (0x40: trans_nc_ss)
+  dtap_tx_confirmed == 1
+  paging_stopped == 1
+- HLR terminates the session
+<-- GSUP rx OSMO_GSUP_MSGT_PROC_SS_REQUEST: 20010809710000004026f0300420000101310103
+DVLR GSUP rx 20: 20010809710000004026f0300420000101310103
+DREF VLR subscr MSISDN:46071 usage increases to: 4
+DMSC Routed to GSM 09.11 SS/USSD handler
+DMSC msc_tx 2 bytes to MSISDN:46071 via RAN_GERAN_A
+- DTAP --RAN_GERAN_A--> MS: GSM0480_MTYPE_RELEASE_COMPLETE: 0b2a
+- DTAP matches expected message
+DREF VLR subscr MSISDN:46071 usage decreases to: 3
+DREF MSISDN:46071: MSC conn use - trans_nc_ss == 0 (0x0: )
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_COMMUNICATING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_COMMUNICATING}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:46071: MSC conn use + release == 1 (0x100: release)
+DREF VLR subscr MSISDN:46071 usage increases to: 4
+DREF VLR subscr MSISDN:46071 usage decreases to: 3
+- BSSAP Clear --RAN_GERAN_A--> MS
+DREF VLR subscr MSISDN:46071 usage decreases to: 2
+<-- GSUP rx OSMO_GSUP_MSGT_PROC_SS_REQUEST: vlr_gsupc_read_cb() returns 0
+  dtap_tx_confirmed == 1
+  bssap_clear_sent == 1
+- all requests serviced, conn has been released
+- BSS sends BSSMAP Clear Complete
+DREF MSISDN:46071: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_DONE}: Removing from parent Subscr_Conn(PAGING_RESP:901700000004620)
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_DONE}: Freeing instance
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000004620){PR_ARQ_S_DONE}: Deallocated
+DRLL MSISDN:46071: Freeing subscriber connection
+DREF VLR subscr MSISDN:46071 usage decreases to: 1
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(PAGING_RESP:901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+DREF freeing VLR subscr MSISDN:46071
+===== test_ss_ussd_no_geran: SUCCESS
+
+full talloc report on 'msgb' (total      0 bytes in   1 blocks)
+talloc_total_blocks(tall_bsc_ctx) == 12
+
+full talloc report on 'msgb' (total      0 bytes in   1 blocks)
+talloc_total_blocks(tall_bsc_ctx) == 12
+
diff --git a/tests/msc_vlr/msc_vlr_test_ss.ok b/tests/msc_vlr/msc_vlr_test_ss.ok
new file mode 100644
index 0000000..a965a70
--- /dev/null
+++ b/tests/msc_vlr/msc_vlr_test_ss.ok
@@ -0,0 +1 @@
+Done
diff --git a/tests/msc_vlr/msc_vlr_test_umts_authen.c b/tests/msc_vlr/msc_vlr_test_umts_authen.c
new file mode 100644
index 0000000..62e280e
--- /dev/null
+++ b/tests/msc_vlr/msc_vlr_test_umts_authen.c
@@ -0,0 +1,882 @@
+/* Osmocom MSC+VLR end-to-end tests */
+
+/* (C) 2017 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>
+ *
+ * All Rights Reserved
+ *
+ * Author: Neels Hofmeyr <nhofmeyr@sysmocom.de>
+ *
+ * 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 "msc_vlr_tests.h"
+
+static void _test_umts_authen(enum ran_type via_ran)
+{
+	struct vlr_subscr *vsub;
+	const char *imsi = "901700000010650";
+	const char *sms =
+		"09" /* SMS messages */
+		"01" /* CP-DATA */
+		"58" /* length */
+		"01" /* Network to MS */
+		"00" /* reference */
+		/* originator (gsm411_send_sms() hardcodes this weird nr) */
+		"0791" "447758100650" /* 447785016005 */
+		"00" /* dest */
+		/* SMS TPDU */
+		"4c" /* len */
+		"00" /* SMS deliver */
+		"05802443f2" /* originating address 42342 */
+		"00" /* TP-PID */
+		"00" /* GSM default alphabet */
+		"071010" /* Y-M-D (from wrapped gsm340_gen_scts())*/
+		"000000" /* H-M-S */
+		"00" /* GMT+0 */
+		"44" /* data length */
+		"5079da1e1ee7416937485e9ea7c965373d1d6683c270383b3d0e"
+		"d3d36ff71c949e83c22072799e9687c5ec32a81d96afcbf4b4fb"
+		"0c7ac3e9e9b7db05";
+
+	net->authentication_required = true;
+	net->vlr->cfg.assign_tmsi = true;
+	rx_from_ran = 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");
+	ms_sends_msg("0508" /* MM LU */
+		     "7" /* ciph key seq: no key available */
+		     "0" /* LU type: normal */
+		     "ffffff" "0000" /* 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("from HLR, rx _SEND_AUTH_INFO_RESULT; VLR sends Auth Req to MS");
+	/* based on auc_3g:
+	 * K = 'EB215756028D60E3275E613320AEC880',
+	 * OPC = 'FB2A3D1B360F599ABAB99DB8669F8308'
+	 * SQN = 0
+	 */
+	auth_request_sent = false;
+	auth_request_expect_rand = "39fa2f4e3d523d8619a73b4f65c3e14d";
+	auth_request_expect_autn = "8704f5ba55f30000d2ee44b22c8ea919";
+	gsup_rx("0a"
+		/* imsi */
+		"0108" "09710000000156f0"
+		/* 5 auth vectors... */
+		/* TL    TL     rand */
+		"0362"  "2010" "39fa2f4e3d523d8619a73b4f65c3e14d"
+		/*       TL     sres       TL     kc */
+			"2104" "9b36efdf" "2208" "059a4f668f6fbe39"
+		/*       TL     3G IK */
+			"2310" "27497388b6cb044648f396aa155b95ef"
+		/*       TL     3G CK */
+			"2410" "f64735036e5871319c679f4742a75ea1"
+		/*       TL     AUTN */
+			"2510" "8704f5ba55f30000d2ee44b22c8ea919"
+		/*       TL     RES */
+			"2708" "e229c19e791f2e41"
+		/* TL    TL     rand */
+		"0362"  "2010" "c187a53a5e6b9d573cac7c74451fd46d"
+			"2104" "85aa3130" "2208" "d3d50a000bf04f6e"
+			"2310" "1159ec926a50e98c034a6b7d7c9f418d"
+			"2410" "df3a03d9ca5335641efc8e36d76cd20b"
+			"2510" "1843a645b98d00005b2d666af46c45d9"
+			"2708" "7db47cf7f81e4dc7"
+		"0362"  "2010" "efa9c29a9742148d5c9070348716e1bb"
+			"2104" "69d5f9fb" "2208" "3df176f0c29f1a3d"
+			"2310" "eb50e770ddcc3060101d2f43b6c2b884"
+			"2410" "76542abce5ff9345b0e8947f4c6e019c"
+			"2510" "f9375e6d41e1000096e7fe4ff1c27e39"
+			"2708" "706f996719ba609c"
+		"0362"  "2010" "f023d5a3b24726e0631b64b3840f8253"
+			"2104" "d570c03f" "2208" "ec011be8919883d6"
+			"2310" "c4e58af4ba43f3bcd904e16984f086d7"
+			"2410" "0593f65e752e5cb7f473862bda05aa0a"
+			"2510" "541ff1f077270000c5ea00d658bc7e9a"
+			"2708" "3fd26072eaa2a04d"
+		"0362"  "2010" "2f8f90c780d6a9c0c53da7ac57b6707e"
+			"2104" "b072446f220823f39f9f425ad6e6"
+			"2310" "65af0527fda95b0dc5ae4aa515cdf32f"
+			"2410" "537c3b35a3b13b08d08eeb28098f45cc"
+			"2510" "4bf4e564f75300009bc796706bc65744"
+			"2708" "0edb0eadbea94ac2",
+		NULL);
+	VERBOSE_ASSERT(auth_request_sent, == true, "%d");
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	if (via_ran == RAN_GERAN_A) {
+		btw("MS sends Authen Response, VLR accepts and sends GSUP LU Req to HLR");
+		gsup_expect_tx("04010809710000000156f0280102");
+		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");
+		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");
+		ms_sends_security_mode_complete();
+		VERBOSE_ASSERT(gsup_tx_confirmed, == true, "%d");
+		VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+	}
+
+	btw("HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT");
+	gsup_rx("10010809710000000156f00804032443f2",
+		"12010809710000000156f0");
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("HLR also sends GSUP _UPDATE_LOCATION_RESULT");
+	gsup_rx("06010809710000000156f0", NULL);
+
+	VERBOSE_ASSERT(lu_result_sent, == RES_ACCEPT, "%d");
+
+	btw("a LU Accept with a new TMSI was sent, waiting for TMSI Realloc Compl");
+	EXPECT_CONN_COUNT(1);
+	EXPECT_ACCEPTED(false);
+	thwart_rx_non_initial_requests();
+
+	btw("even though the TMSI is not acked, we can already find the subscr with it");
+	vsub = vlr_subscr_find_by_tmsi(net->vlr, 0x03020100);
+	VERBOSE_ASSERT(vsub != NULL, == true, "%d");
+	VERBOSE_ASSERT(strcmp(vsub->imsi, imsi), == 0, "%d");
+	VERBOSE_ASSERT(vsub->tmsi_new, == 0x03020100, "0x%08x");
+	VERBOSE_ASSERT(vsub->tmsi, == GSM_RESERVED_TMSI, "0x%08x");
+	vlr_subscr_put(vsub);
+
+	btw("MS sends TMSI Realloc Complete");
+	expect_release_clear(via_ran);
+	ms_sends_msg("055b");
+	ASSERT_RELEASE_CLEAR(via_ran);
+	bss_rnc_sends_release_clear_complete(via_ran);
+
+	btw("LU was successful, and the conn has already been closed");
+	EXPECT_CONN_COUNT(0);
+
+	BTW("after a while, a new conn sends a CM Service Request. VLR responds with Auth Req, 2nd auth vector");
+	auth_request_sent = false;
+	auth_request_expect_rand = "c187a53a5e6b9d573cac7c74451fd46d";
+	auth_request_expect_autn = "1843a645b98d00005b2d666af46c45d9";
+	cm_service_result_sent = RES_NONE;
+	ms_sends_msg("052478"
+		     "03575886" /* classmark 2 */
+		     "089910070000106005" /* IMSI */);
+	OSMO_ASSERT(g_conn);
+	OSMO_ASSERT(g_conn->fi);
+	OSMO_ASSERT(g_conn->vsub);
+	VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d");
+	VERBOSE_ASSERT(auth_request_sent, == true, "%d");
+
+	btw("needs auth, not yet accepted");
+	EXPECT_ACCEPTED(false);
+	thwart_rx_non_initial_requests();
+
+	if (via_ran == RAN_GERAN_A) {
+		btw("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");
+		expect_security_mode_ctrl(NULL, "1159ec926a50e98c034a6b7d7c9f418d");
+		ms_sends_msg("0554" "7db47cf7" "2104" "f81e4dc7"); /* 2nd vector's res, s.a. */
+		VERBOSE_ASSERT(security_mode_ctrl_sent, == true, "%d");
+		VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d");
+
+		btw("MS sends SecurityModeControl acceptance, VLR accepts; above Ciphering is an implicit CM Service Accept");
+		ms_sends_security_mode_complete();
+		VERBOSE_ASSERT(cm_service_result_sent, == RES_NONE, "%d");
+	}
+
+	/* Release connection */
+	expect_release_clear(via_ran);
+	conn_conclude_cm_service_req(g_conn, via_ran);
+	bss_rnc_sends_release_clear_complete(via_ran);
+
+	btw("all requests serviced, conn has been released");
+	EXPECT_CONN_COUNT(0);
+
+	BTW("an SMS is sent, MS is paged");
+	paging_expect_imsi(imsi);
+	paging_sent = false;
+	vsub = vlr_subscr_find_by_imsi(net->vlr, imsi);
+	OSMO_ASSERT(vsub);
+	VERBOSE_ASSERT(llist_count(&vsub->cs.requests), == 0, "%d");
+
+	send_sms(vsub, vsub,
+		 "Privacy in residential applications is a desirable"
+		 " marketing option.");
+
+	VERBOSE_ASSERT(llist_count(&vsub->cs.requests), == 1, "%d");
+	vlr_subscr_put(vsub);
+	vsub = NULL;
+	VERBOSE_ASSERT(paging_sent, == true, "%d");
+	VERBOSE_ASSERT(paging_stopped, == false, "%d");
+
+	btw("the subscriber and its pending request should remain");
+	vsub = vlr_subscr_find_by_imsi(net->vlr, imsi);
+	OSMO_ASSERT(vsub);
+	VERBOSE_ASSERT(llist_count(&vsub->cs.requests), == 1, "%d");
+	vlr_subscr_put(vsub);
+
+	btw("MS replies with Paging Response, and VLR sends Auth Request with third key");
+	auth_request_sent = false;
+	auth_request_expect_rand = "efa9c29a9742148d5c9070348716e1bb";
+	auth_request_expect_autn = "f9375e6d41e1000096e7fe4ff1c27e39";
+	ms_sends_msg("062707"
+		     "03575886" /* classmark 2 */
+		     "089910070000106005" /* IMSI */);
+	VERBOSE_ASSERT(auth_request_sent, == true, "%d");
+
+	btw("needs auth, not yet accepted");
+	EXPECT_ACCEPTED(false);
+	thwart_rx_non_initial_requests();
+
+	if (via_ran == RAN_GERAN_A) {
+		btw("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");
+		VERBOSE_ASSERT(paging_stopped, == true, "%d");
+	} else {
+		/* On UTRAN */
+		btw("MS sends Authen Response, VLR accepts and sends SecurityModeControl");
+		expect_security_mode_ctrl(NULL, "eb50e770ddcc3060101d2f43b6c2b884");
+		ms_sends_msg("0554" "706f9967" "2104" "19ba609c"); /* 3nd vector's res, s.a. */
+		VERBOSE_ASSERT(security_mode_ctrl_sent, == true, "%d");
+		VERBOSE_ASSERT(paging_stopped, == false, "%d");
+
+		btw("MS sends SecurityModeControl acceptance, VLR accepts and sends SMS");
+		dtap_expect_tx(sms);
+		ms_sends_security_mode_complete();
+		VERBOSE_ASSERT(paging_stopped, == true, "%d");
+	}
+
+	btw("SMS was delivered, no requests pending for subscr");
+	vsub = vlr_subscr_find_by_imsi(net->vlr, imsi);
+	OSMO_ASSERT(vsub);
+	VERBOSE_ASSERT(llist_count(&vsub->cs.requests), == 0, "%d");
+	vlr_subscr_put(vsub);
+
+	btw("conn is still open to wait for SMS ack dance");
+	EXPECT_CONN_COUNT(1);
+
+	btw("MS replies with CP-ACK for received SMS");
+	ms_sends_msg("8904");
+	EXPECT_CONN_COUNT(1);
+
+	btw("MS also sends RP-ACK, MSC in turn sends CP-ACK for that");
+	dtap_expect_tx("0904");
+	expect_release_clear(via_ran);
+	ms_sends_msg("890106020041020000");
+	VERBOSE_ASSERT(dtap_tx_confirmed, == true, "%d");
+	ASSERT_RELEASE_CLEAR(via_ran);
+	bss_rnc_sends_release_clear_complete(via_ran);
+
+	btw("SMS is done, conn is gone");
+	EXPECT_CONN_COUNT(0);
+
+	BTW("subscriber detaches");
+	expect_release_clear(via_ran);
+	ms_sends_msg("050130"
+		     "089910070000106005" /* IMSI */);
+	ASSERT_RELEASE_CLEAR(via_ran);
+	bss_rnc_sends_release_clear_complete(via_ran);
+
+	EXPECT_CONN_COUNT(0);
+	clear_vlr();
+}
+
+static void test_umts_authen_geran()
+{
+	comment_start();
+	_test_umts_authen(RAN_GERAN_A);
+	comment_end();
+}
+
+static void test_umts_authen_utran()
+{
+	comment_start();
+	_test_umts_authen(RAN_UTRAN_IU);
+	comment_end();
+}
+
+#define RECALC_AUTS 0
+
+#if RECALC_AUTS
+typedef uint8_t u8;
+extern int milenage_f2345(const u8 *opc, const u8 *k, const u8 *_rand,
+			  u8 *res, u8 *ck, u8 *ik, u8 *ak, u8 *akstar);
+extern int milenage_f1(const u8 *opc, const u8 *k, const u8 *_rand,
+		       const u8 *sqn, const u8 *amf, u8 *mac_a, u8 *mac_s);
+#endif
+
+static void _test_umts_authen_resync(enum ran_type via_ran)
+{
+	struct vlr_subscr *vsub;
+	const char *imsi = "901700000010650";
+
+	net->authentication_required = true;
+	net->vlr->cfg.assign_tmsi = true;
+	rx_from_ran = 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");
+	ms_sends_msg("0508" /* MM LU */
+		     "7" /* ciph key seq: no key available */
+		     "0" /* LU type: normal */
+		     "ffffff" "0000" /* 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("from HLR, rx _SEND_AUTH_INFO_RESULT; VLR sends Auth Req to MS");
+	/* based on auc_3g:
+	 * K = 'EB215756028D60E3275E613320AEC880',
+	 * OPC = 'FB2A3D1B360F599ABAB99DB8669F8308'
+	 * SQN = 0
+	 */
+	auth_request_sent = false;
+	auth_request_expect_rand = "39fa2f4e3d523d8619a73b4f65c3e14d";
+	auth_request_expect_autn = "8704f5ba55f30000d2ee44b22c8ea919";
+	gsup_rx("0a"
+		/* imsi */
+		"0108" "09710000000156f0"
+		/* auth vectors... */
+		/* TL    TL     rand */
+		"0362"  "2010" "39fa2f4e3d523d8619a73b4f65c3e14d"
+		/*       TL     sres       TL     kc */
+			"2104" "9b36efdf" "2208" "059a4f668f6fbe39"
+		/*       TL     3G IK */
+			"2310" "27497388b6cb044648f396aa155b95ef"
+		/*       TL     3G CK */
+			"2410" "f64735036e5871319c679f4742a75ea1"
+		/*       TL     AUTN */
+			"2510" "8704f5ba55f30000d2ee44b22c8ea919"
+		/*       TL     RES */
+			"2708" "e229c19e791f2e41"
+		,NULL);
+	VERBOSE_ASSERT(auth_request_sent, == true, "%d");
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	/* The AUTN sent was 8704f5ba55f30000d2ee44b22c8ea919
+	 * (see expected error output)
+	 * with the first 6 bytes being SQN ^ AK.
+	 * K = EB215756028D60E3275E613320AEC880
+	 * OPC = FB2A3D1B360F599ABAB99DB8669F8308
+	 * RAND = 39fa2f4e3d523d8619a73b4f65c3e14d
+	 * --milenage-f5-->
+	 * AK = 8704f5ba55f3
+	 *
+	 * The first six bytes are 8704f5ba55f3,
+	 * and 8704f5ba55f3 ^ AK = 0.
+	 * --> SQN = 0.
+	 *
+	 * Say the USIM doesn't like that, let's say it is at SQN 23.
+	 * SQN_MS = 000000000017
+	 *
+	 * AUTS = Conc(SQN_MS) || MAC-S
+	 * Conc(SQN_MS) = SQN_MS ⊕ f5*[K](RAND)
+	 * MAC-S = f1*[K] (SQN MS || RAND || AMF)
+	 *
+	 * f5*--> Conc(SQN_MS) = 000000000017 ^ 979498b1f73a
+	 *                     = 979498b1f72d
+	 * AMF = 0000 (TS 33.102 v7.0.0, 6.3.3)
+	 *
+	 * MAC-S = f1*[K] (000000000017 || 39fa2f4e3d523d8619a73b4f65c3e14d || 0000)
+	 *       = 3e28c59fa2e72f9c
+	 *
+	 * AUTS = 979498b1f72d || 3e28c59fa2e72f9c
+	 */
+#if RECALC_AUTS
+	uint8_t ak[6];
+	uint8_t akstar[6];
+	uint8_t opc[16];
+	uint8_t k[16];
+	uint8_t rand[16];
+	osmo_hexparse("EB215756028D60E3275E613320AEC880", k, sizeof(k));
+	osmo_hexparse("FB2A3D1B360F599ABAB99DB8669F8308", opc, sizeof(opc));
+	osmo_hexparse("39fa2f4e3d523d8619a73b4f65c3e14d", rand, sizeof(rand));
+	milenage_f2345(opc, k, rand, NULL, NULL, NULL, ak, akstar);
+	btw("ak = %s", osmo_hexdump_nospc(ak, sizeof(ak)));
+	btw("akstar = %s", osmo_hexdump_nospc(akstar, sizeof(akstar)));
+
+	uint8_t sqn_ms[6] = { 0, 0, 0, 0, 0, 23 };
+	uint8_t amf[2] = { 0 };
+	uint8_t mac_s[8];
+	milenage_f1(opc, k, rand, sqn_ms, amf, NULL, mac_s);
+	btw("mac_s = %s", osmo_hexdump_nospc(mac_s, sizeof(mac_s)));
+	/* verify valid AUTS resulting in SQN 23 with:
+	   osmo-auc-gen -3 -a milenage -k EB215756028D60E3275E613320AEC880 \
+	                -o FB2A3D1B360F599ABAB99DB8669F8308 \
+	                -r 39fa2f4e3d523d8619a73b4f65c3e14d \
+	                -A 979498b1f72d3e28c59fa2e72f9c
+	 */
+#endif
+
+	btw("MS sends Authen Failure with Resync cause, VLR sends GSUP to HLR to resync");
+	auth_request_sent = false;
+	gsup_expect_tx("08" /* OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST */
+		       "0108" "09710000000156f0" /* IMSI */
+		       "260e" "979498b1f72d3e28c59fa2e72f9c" /* AUTS */
+		       "2010" "39fa2f4e3d523d8619a73b4f65c3e14d" /* RAND */);
+	ms_sends_msg("051c" /* 05 = MM; 1c = Auth Failure */
+		     "15"   /* cause = Synch Failure */
+		     "220e" "979498b1f72d3e28c59fa2e72f9c" /* AUTS */);
+	VERBOSE_ASSERT(gsup_tx_confirmed, == true, "%d");
+	VERBOSE_ASSERT(auth_request_sent, == false, "%d");
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("HLR replies with new tuples");
+	auth_request_sent = false;
+	auth_request_expect_rand = "0f1feb1623e1bf626334e37ec448ac18";
+	auth_request_expect_autn = "02a83f62e9470000660d51afc75f169d";
+	gsup_rx("0a"
+		/* imsi */
+		"0108" "09710000000156f0"
+		/* 1 auth vector */
+		/* TL    TL     rand */
+		"0362"  "2010" "0f1feb1623e1bf626334e37ec448ac18"
+		/*       TL     sres       TL     kc */
+			"2104" "efde99da" "2208" "14778c855c523730"
+		/*       TL     3G IK */
+			"2310" "8a90c769b7272f3bb7a1c1fbb1ea9349"
+		/*       TL     3G CK */
+			"2410" "43ffc1cf8c89a7fd6ab94bd8d6162cbf"
+		/*       TL     AUTN */
+			"2510" "02a83f62e9470000660d51afc75f169d"
+		/*       TL     RES */
+			"2708" "1df5f0b4f22b696e"
+		/* TL    TL     rand */
+		"0362"  "2010" "ac21d34937b4e1142a2c757af2949319"
+		/*       TL     sres       TL     kc */
+			"2104" "7818bfdc" "2208" "d175571f41f314a4"
+		/*       TL     3G IK */
+			"2310" "ff8edbceb6dd24799c77c3b9a6790c10"
+		/*       TL     3G CK */
+			"2410" "157c39022ca9d885a7f0766a7dfee448"
+		/*       TL     AUTN */
+			"2510" "8a43b91898e500002cf354c6f5d1f8c3"
+		/*       TL     RES */
+			"2708" "f748a7078f5018db"
+		,NULL);
+
+	VERBOSE_ASSERT(auth_request_sent, == true, "%d");
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	if (via_ran == RAN_GERAN_A) {
+		btw("MS sends Authen Response, VLR accepts and sends GSUP LU Req to HLR");
+		gsup_expect_tx("04010809710000000156f0280102");
+		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");
+		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");
+		ms_sends_security_mode_complete();
+		VERBOSE_ASSERT(gsup_tx_confirmed, == true, "%d");
+		VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+	}
+
+	btw("HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT");
+	gsup_rx("10010809710000000156f00804032443f2",
+		"12010809710000000156f0");
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("HLR also sends GSUP _UPDATE_LOCATION_RESULT");
+	gsup_rx("06010809710000000156f0", NULL);
+
+	VERBOSE_ASSERT(lu_result_sent, == RES_ACCEPT, "%d");
+
+	btw("a LU Accept with a new TMSI was sent, waiting for TMSI Realloc Compl");
+	EXPECT_CONN_COUNT(1);
+	EXPECT_ACCEPTED(false);
+	thwart_rx_non_initial_requests();
+
+	btw("even though the TMSI is not acked, we can already find the subscr with it");
+	vsub = vlr_subscr_find_by_tmsi(net->vlr, 0x03020100);
+	VERBOSE_ASSERT(vsub != NULL, == true, "%d");
+	VERBOSE_ASSERT(strcmp(vsub->imsi, imsi), == 0, "%d");
+	VERBOSE_ASSERT(vsub->tmsi_new, == 0x03020100, "0x%08x");
+	VERBOSE_ASSERT(vsub->tmsi, == GSM_RESERVED_TMSI, "0x%08x");
+	vlr_subscr_put(vsub);
+
+	btw("MS sends TMSI Realloc Complete");
+	expect_release_clear(via_ran);
+	ms_sends_msg("055b");
+	ASSERT_RELEASE_CLEAR(via_ran);
+	bss_rnc_sends_release_clear_complete(via_ran);
+
+	btw("LU was successful, and the conn has already been closed");
+	EXPECT_CONN_COUNT(0);
+
+	clear_vlr();
+}
+
+static void test_umts_authen_resync_geran()
+{
+	comment_start();
+	_test_umts_authen_resync(RAN_GERAN_A);
+	comment_end();
+}
+
+static void test_umts_authen_resync_utran()
+{
+	comment_start();
+	_test_umts_authen_resync(RAN_UTRAN_IU);
+	comment_end();
+}
+
+static void _test_umts_authen_too_short_res(enum ran_type via_ran)
+{
+	net->authentication_required = true;
+	net->vlr->cfg.assign_tmsi = true;
+	rx_from_ran = 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");
+	ms_sends_msg("0508" /* MM LU */
+		     "7" /* ciph key seq: no key available */
+		     "0" /* LU type: normal */
+		     "ffffff" "0000" /* 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("from HLR, rx _SEND_AUTH_INFO_RESULT; VLR sends Auth Req to MS");
+	/* based on auc_3g:
+	 * K = 'EB215756028D60E3275E613320AEC880',
+	 * OPC = 'FB2A3D1B360F599ABAB99DB8669F8308'
+	 * SQN = 0
+	 */
+	auth_request_sent = false;
+	auth_request_expect_rand = "39fa2f4e3d523d8619a73b4f65c3e14d";
+	auth_request_expect_autn = "8704f5ba55f30000d2ee44b22c8ea919";
+	gsup_rx("0a"
+		/* imsi */
+		"0108" "09710000000156f0"
+		/* 5 auth vectors... */
+		/* TL    TL     rand */
+		"0362"  "2010" "39fa2f4e3d523d8619a73b4f65c3e14d"
+		/*       TL     sres       TL     kc */
+			"2104" "9b36efdf" "2208" "059a4f668f6fbe39"
+		/*       TL     3G IK */
+			"2310" "27497388b6cb044648f396aa155b95ef"
+		/*       TL     3G CK */
+			"2410" "f64735036e5871319c679f4742a75ea1"
+		/*       TL     AUTN */
+			"2510" "8704f5ba55f30000d2ee44b22c8ea919"
+		/*       TL     RES */
+			"2708" "e229c19e791f2e41"
+		/* TL    TL     rand */
+		"0362"  "2010" "c187a53a5e6b9d573cac7c74451fd46d"
+			"2104" "85aa3130" "2208" "d3d50a000bf04f6e"
+			"2310" "1159ec926a50e98c034a6b7d7c9f418d"
+			"2410" "df3a03d9ca5335641efc8e36d76cd20b"
+			"2510" "1843a645b98d00005b2d666af46c45d9"
+			"2708" "7db47cf7f81e4dc7"
+		"0362"  "2010" "efa9c29a9742148d5c9070348716e1bb"
+			"2104" "69d5f9fb" "2208" "3df176f0c29f1a3d"
+			"2310" "eb50e770ddcc3060101d2f43b6c2b884"
+			"2410" "76542abce5ff9345b0e8947f4c6e019c"
+			"2510" "f9375e6d41e1000096e7fe4ff1c27e39"
+			"2708" "706f996719ba609c"
+		"0362"  "2010" "f023d5a3b24726e0631b64b3840f8253"
+			"2104" "d570c03f" "2208" "ec011be8919883d6"
+			"2310" "c4e58af4ba43f3bcd904e16984f086d7"
+			"2410" "0593f65e752e5cb7f473862bda05aa0a"
+			"2510" "541ff1f077270000c5ea00d658bc7e9a"
+			"2708" "3fd26072eaa2a04d"
+		"0362"  "2010" "2f8f90c780d6a9c0c53da7ac57b6707e"
+			"2104" "b072446f220823f39f9f425ad6e6"
+			"2310" "65af0527fda95b0dc5ae4aa515cdf32f"
+			"2410" "537c3b35a3b13b08d08eeb28098f45cc"
+			"2510" "4bf4e564f75300009bc796706bc65744"
+			"2708" "0edb0eadbea94ac2",
+		NULL);
+	VERBOSE_ASSERT(auth_request_sent, == true, "%d");
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("MS sends Authen Response of wrong RES size, VLR thwarts");
+	gsup_expect_tx("0b010809710000000156f0"); /* OSMO_GSUP_MSGT_AUTH_FAIL_REPORT */
+	expect_release_clear(via_ran);
+	ms_sends_msg("0554" "e229c19e" "2103" "791f2e" /* nipped one byte */);
+	VERBOSE_ASSERT(lu_result_sent, == RES_REJECT, "%d");
+	ASSERT_RELEASE_CLEAR(via_ran);
+	bss_rnc_sends_release_clear_complete(via_ran);
+
+	EXPECT_CONN_COUNT(0);
+	clear_vlr();
+}
+
+static void test_umts_authen_too_short_res_geran()
+{
+	comment_start();
+	_test_umts_authen_too_short_res(RAN_GERAN_A);
+	comment_end();
+}
+
+static void test_umts_authen_too_short_res_utran()
+{
+	comment_start();
+	_test_umts_authen_too_short_res(RAN_UTRAN_IU);
+	comment_end();
+}
+
+static void _test_umts_authen_too_long_res(enum ran_type via_ran)
+{
+	net->authentication_required = true;
+	net->vlr->cfg.assign_tmsi = true;
+	rx_from_ran = 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");
+	ms_sends_msg("0508" /* MM LU */
+		     "7" /* ciph key seq: no key available */
+		     "0" /* LU type: normal */
+		     "ffffff" "0000" /* 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("from HLR, rx _SEND_AUTH_INFO_RESULT; VLR sends Auth Req to MS");
+	/* based on auc_3g:
+	 * K = 'EB215756028D60E3275E613320AEC880',
+	 * OPC = 'FB2A3D1B360F599ABAB99DB8669F8308'
+	 * SQN = 0
+	 */
+	auth_request_sent = false;
+	auth_request_expect_rand = "39fa2f4e3d523d8619a73b4f65c3e14d";
+	auth_request_expect_autn = "8704f5ba55f30000d2ee44b22c8ea919";
+	gsup_rx("0a"
+		/* imsi */
+		"0108" "09710000000156f0"
+		/* 5 auth vectors... */
+		/* TL    TL     rand */
+		"0362"  "2010" "39fa2f4e3d523d8619a73b4f65c3e14d"
+		/*       TL     sres       TL     kc */
+			"2104" "9b36efdf" "2208" "059a4f668f6fbe39"
+		/*       TL     3G IK */
+			"2310" "27497388b6cb044648f396aa155b95ef"
+		/*       TL     3G CK */
+			"2410" "f64735036e5871319c679f4742a75ea1"
+		/*       TL     AUTN */
+			"2510" "8704f5ba55f30000d2ee44b22c8ea919"
+		/*       TL     RES */
+			"2708" "e229c19e791f2e41"
+		/* TL    TL     rand */
+		"0362"  "2010" "c187a53a5e6b9d573cac7c74451fd46d"
+			"2104" "85aa3130" "2208" "d3d50a000bf04f6e"
+			"2310" "1159ec926a50e98c034a6b7d7c9f418d"
+			"2410" "df3a03d9ca5335641efc8e36d76cd20b"
+			"2510" "1843a645b98d00005b2d666af46c45d9"
+			"2708" "7db47cf7f81e4dc7"
+		"0362"  "2010" "efa9c29a9742148d5c9070348716e1bb"
+			"2104" "69d5f9fb" "2208" "3df176f0c29f1a3d"
+			"2310" "eb50e770ddcc3060101d2f43b6c2b884"
+			"2410" "76542abce5ff9345b0e8947f4c6e019c"
+			"2510" "f9375e6d41e1000096e7fe4ff1c27e39"
+			"2708" "706f996719ba609c"
+		"0362"  "2010" "f023d5a3b24726e0631b64b3840f8253"
+			"2104" "d570c03f" "2208" "ec011be8919883d6"
+			"2310" "c4e58af4ba43f3bcd904e16984f086d7"
+			"2410" "0593f65e752e5cb7f473862bda05aa0a"
+			"2510" "541ff1f077270000c5ea00d658bc7e9a"
+			"2708" "3fd26072eaa2a04d"
+		"0362"  "2010" "2f8f90c780d6a9c0c53da7ac57b6707e"
+			"2104" "b072446f220823f39f9f425ad6e6"
+			"2310" "65af0527fda95b0dc5ae4aa515cdf32f"
+			"2410" "537c3b35a3b13b08d08eeb28098f45cc"
+			"2510" "4bf4e564f75300009bc796706bc65744"
+			"2708" "0edb0eadbea94ac2",
+		NULL);
+	VERBOSE_ASSERT(auth_request_sent, == true, "%d");
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	btw("MS sends Authen Response of wrong RES size, VLR thwarts");
+	gsup_expect_tx("0b010809710000000156f0"); /* OSMO_GSUP_MSGT_AUTH_FAIL_REPORT */
+	expect_release_clear(via_ran);
+	ms_sends_msg("0554" "e229c19e" "2105" "791f2e4123" /* added one byte */);
+	VERBOSE_ASSERT(lu_result_sent, == RES_REJECT, "%d");
+	ASSERT_RELEASE_CLEAR(via_ran);
+	bss_rnc_sends_release_clear_complete(via_ran);
+
+	EXPECT_CONN_COUNT(0);
+	clear_vlr();
+}
+
+static void test_umts_authen_too_long_res_geran()
+{
+	comment_start();
+	_test_umts_authen_too_long_res(RAN_GERAN_A);
+	comment_end();
+}
+
+static void test_umts_authen_too_long_res_utran()
+{
+	comment_start();
+	_test_umts_authen_too_long_res(RAN_UTRAN_IU);
+	comment_end();
+}
+
+static void _test_umts_authen_only_sres(enum ran_type via_ran)
+{
+	net->authentication_required = true;
+	net->vlr->cfg.assign_tmsi = true;
+	rx_from_ran = 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");
+	ms_sends_msg("0508" /* MM LU */
+		     "7" /* ciph key seq: no key available */
+		     "0" /* LU type: normal */
+		     "ffffff" "0000" /* 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("from HLR, rx _SEND_AUTH_INFO_RESULT; VLR sends Auth Req to MS");
+	/* based on auc_3g:
+	 * K = 'EB215756028D60E3275E613320AEC880',
+	 * OPC = 'FB2A3D1B360F599ABAB99DB8669F8308'
+	 * SQN = 0
+	 */
+	auth_request_sent = false;
+	auth_request_expect_rand = "39fa2f4e3d523d8619a73b4f65c3e14d";
+	auth_request_expect_autn = "8704f5ba55f30000d2ee44b22c8ea919";
+	gsup_rx("0a"
+		/* imsi */
+		"0108" "09710000000156f0"
+		/* 5 auth vectors... */
+		/* TL    TL     rand */
+		"0362"  "2010" "39fa2f4e3d523d8619a73b4f65c3e14d"
+		/*       TL     sres       TL     kc */
+			"2104" "9b36efdf" "2208" "059a4f668f6fbe39"
+		/*       TL     3G IK */
+			"2310" "27497388b6cb044648f396aa155b95ef"
+		/*       TL     3G CK */
+			"2410" "f64735036e5871319c679f4742a75ea1"
+		/*       TL     AUTN */
+			"2510" "8704f5ba55f30000d2ee44b22c8ea919"
+		/*       TL     RES */
+			"2708" "e229c19e791f2e41"
+		/* TL    TL     rand */
+		"0362"  "2010" "c187a53a5e6b9d573cac7c74451fd46d"
+			"2104" "85aa3130" "2208" "d3d50a000bf04f6e"
+			"2310" "1159ec926a50e98c034a6b7d7c9f418d"
+			"2410" "df3a03d9ca5335641efc8e36d76cd20b"
+			"2510" "1843a645b98d00005b2d666af46c45d9"
+			"2708" "7db47cf7f81e4dc7"
+		"0362"  "2010" "efa9c29a9742148d5c9070348716e1bb"
+			"2104" "69d5f9fb" "2208" "3df176f0c29f1a3d"
+			"2310" "eb50e770ddcc3060101d2f43b6c2b884"
+			"2410" "76542abce5ff9345b0e8947f4c6e019c"
+			"2510" "f9375e6d41e1000096e7fe4ff1c27e39"
+			"2708" "706f996719ba609c"
+		"0362"  "2010" "f023d5a3b24726e0631b64b3840f8253"
+			"2104" "d570c03f" "2208" "ec011be8919883d6"
+			"2310" "c4e58af4ba43f3bcd904e16984f086d7"
+			"2410" "0593f65e752e5cb7f473862bda05aa0a"
+			"2510" "541ff1f077270000c5ea00d658bc7e9a"
+			"2708" "3fd26072eaa2a04d"
+		"0362"  "2010" "2f8f90c780d6a9c0c53da7ac57b6707e"
+			"2104" "b072446f220823f39f9f425ad6e6"
+			"2310" "65af0527fda95b0dc5ae4aa515cdf32f"
+			"2410" "537c3b35a3b13b08d08eeb28098f45cc"
+			"2510" "4bf4e564f75300009bc796706bc65744"
+			"2708" "0edb0eadbea94ac2",
+		NULL);
+	VERBOSE_ASSERT(auth_request_sent, == true, "%d");
+	VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
+
+	if (via_ran == RAN_GERAN_A)
+		btw("MS sends Authen Response of wrong RES size, VLR thwarts:"
+		    " GERAN reports an SRES mismatch");
+	else
+		btw("MS sends Authen Response of wrong RES size, VLR thwarts:"
+		    " UTRAN disallows GSM AKA altogether");
+	gsup_expect_tx("0b010809710000000156f0"); /* OSMO_GSUP_MSGT_AUTH_FAIL_REPORT */
+	expect_release_clear(via_ran);
+	ms_sends_msg("0554" "e229c19e" /* Only the SRES half of the RES */);
+	VERBOSE_ASSERT(lu_result_sent, == RES_REJECT, "%d");
+	ASSERT_RELEASE_CLEAR(via_ran);
+	bss_rnc_sends_release_clear_complete(via_ran);
+
+	EXPECT_CONN_COUNT(0);
+	clear_vlr();
+}
+
+static void test_umts_authen_only_sres_geran()
+{
+	comment_start();
+	_test_umts_authen_only_sres(RAN_GERAN_A);
+	comment_end();
+}
+
+static void test_umts_authen_only_sres_utran()
+{
+	comment_start();
+	_test_umts_authen_only_sres(RAN_UTRAN_IU);
+	comment_end();
+}
+
+
+msc_vlr_test_func_t msc_vlr_tests[] = {
+	test_umts_authen_geran,
+	test_umts_authen_utran,
+	test_umts_authen_resync_geran,
+	test_umts_authen_resync_utran,
+	test_umts_authen_too_short_res_geran,
+	test_umts_authen_too_short_res_utran,
+	test_umts_authen_too_long_res_geran,
+	test_umts_authen_too_long_res_utran,
+	test_umts_authen_only_sres_geran,
+	test_umts_authen_only_sres_utran,
+	NULL
+};
diff --git a/tests/msc_vlr/msc_vlr_test_umts_authen.err b/tests/msc_vlr/msc_vlr_test_umts_authen.err
new file mode 100644
index 0000000..538a3d9
--- /dev/null
+++ b/tests/msc_vlr/msc_vlr_test_umts_authen.err
@@ -0,0 +1,2012 @@
+full talloc report on 'msgb' (total      0 bytes in   1 blocks)
+talloc_total_blocks(tall_bsc_ctx) == 12
+
+===== test_umts_authen_geran
+- Location Update request causes a GSUP Send Auth Info request to HLR
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8)
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_NEW}: Updated ID
+DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000010650 type=NORMAL
+DMM LU/new-LAC: 0/23
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: Allocated
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: is child of Subscr_Conn(LU:901700000010650)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: rev=R99 net=GERAN Auth (no Ciph)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA
+DREF VLR subscr unknown usage increases to: 1
+DVLR set IMSI on subscriber; IMSI=901700000010650 id=901700000010650
+DVLR New subscr, IMSI: 901700000010650
+DREF VLR subscr IMSI:901700000010650 usage increases to: 2
+DREF VLR subscr IMSI:901700000010650 usage decreases to: 1
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Allocated
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(LU:901700000010650)
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
+DVLR GSUP tx: 08010809710000000156f0
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f0
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF IMSI:901700000010650: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  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: 0a010809710000000156f00362201039fa2f4e3d523d8619a73b4f65c3e14d21049b36efdf2208059a4f668f6fbe39231027497388b6cb044648f396aa155b95ef2410f64735036e5871319c679f4742a75ea125108704f5ba55f30000d2ee44b22c8ea9192708e229c19e791f2e4103622010c187a53a5e6b9d573cac7c74451fd46d210485aa31302208d3d50a000bf04f6e23101159ec926a50e98c034a6b7d7c9f418d2410df3a03d9ca5335641efc8e36d76cd20b25101843a645b98d00005b2d666af46c45d927087db47cf7f81e4dc703622010efa9c29a9742148d5c9070348716e1bb210469d5f9fb22083df176f0c29f1a3d2310eb50e770ddcc3060101d2f43b6c2b884241076542abce5ff9345b0e8947f4c6e019c2510f9375e6d41e1000096e7fe4ff1c27e392708706f996719ba609c03622010f023d5a3b24726e0631b64b3840f82532104d570c03f2208ec011be8919883d62310c4e58af4ba43f3bcd904e16984f086d724100593f65e752e5cb7f473862bda05aa0a2510541ff1f077270000c5ea00d658bc7e9a27083fd26072eaa2a04d036220102f8f90c780d6a9c0c53da7ac57b6707e2104b072446f220823f39f9f425ad6e6231065af0527fda95b0dc5ae4aa515cdf32f2410537c3b35a3b13b08d08eeb28098f45cc25104bf4e564f75300009bc796706bc6574427080edb0eadbea94ac2
+DVLR GSUP rx 511: 0a010809710000000156f00362201039fa2f4e3d523d8619a73b4f65c3e14d21049b36efdf2208059a4f668f6fbe39231027497388b6cb044648f396aa155b95ef2410f64735036e5871319c679f4742a75ea125108704f5ba55f30000d2ee44b22c8ea9192708e229c19e791f2e4103622010c187a53a5e6b9d573cac7c74451fd46d210485aa31302208d3d50a000bf04f6e23101159ec926a50e98c034a6b7d7c9f418d2410df3a03d9ca5335641efc8e36d76cd20b25101843a645b98d00005b2d666af46c45d927087db47cf7f81e4dc703622010efa9c29a9742148d5c9070348716e1bb210469d5f9fb22083df176f0c29f1a3d2310eb50e770ddcc3060101d2f43b6c2b884241076542abce5ff9345b0e8947f4c6e019c2510f9375e6d41e1000096e7fe4ff1c27e392708706f996719ba609c03622010f023d5a3b24726e0631b64b3840f82532104d570c03f2208ec011be8919883d62310c4e58af4ba43f3bcd904e16984f086d724100593f65e752e5cb7f473862bda05aa0a2510541ff1f077270000c5ea00d658bc7e9a27083fd26072eaa2a04d036220102f8f90c780d6a9c0c53da7ac57b6707e2104b072446f220823f39f9f425ad6e6231065af0527fda95b0dc5ae4aa515cdf32f2410537c3b35a3b13b08d08eeb28098f45cc25104bf4e564f75300009bc796706bc6574427080edb0eadbea94ac2
+DREF VLR subscr IMSI:901700000010650 usage increases to: 2
+DVLR VLR_Authenticate(LU:901700000010650){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(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: state_chg to VLR_SUB_AS_WAIT_RESP
+DVLR VLR_Authenticate(LU:901700000010650){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: tuple use_count=1 key_seq=0 auth_types=0x3 and...
+- ...rand=39fa2f4e3d523d8619a73b4f65c3e14d
+- ...autn=8704f5ba55f30000d2ee44b22c8ea919
+- ...expecting res=e229c19e791f2e41
+DREF VLR subscr IMSI:901700000010650 usage decreases to: 1
+<-- 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
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_AUTH_RESP
+DREF IMSI:901700000010650: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14)
+DMM IMSI:901700000010650: MM UMTS AUTHENTICATION RESPONSE (res = e229c19e791f2e41)
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP
+DVLR SUBSCR(IMSI:901700000010650) AUTH on GERAN received SRES/RES: e229c19e791f2e41 (8 bytes)
+DVLR SUBSCR(IMSI:901700000010650) AUTH established UMTS security context
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result PASSED
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(LU:901700000010650)
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Freeing instance
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth()
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_ciph()
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_node_4()
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_INIT}: Allocated
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000010650)
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START
+DVLR GSUP tx: 04010809710000000156f0280102
+GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000000156f0280102
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA
+DREF IMSI:901700000010650: MSC conn use - dtap == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  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: 10010809710000000156f00804032443f2
+DVLR GSUP rx 17: 10010809710000000156f00804032443f2
+DREF VLR subscr IMSI:901700000010650 usage increases to: 2
+DVLR IMSI:901700000010650 has MSISDN:42342
+DVLR SUBSCR(MSISDN:42342) VLR: update for IMSI=901700000010650 (MSISDN=42342, used=2)
+DVLR GSUP tx: 12010809710000000156f0
+GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000000156f0
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+<-- 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: 06010809710000000156f0
+DVLR GSUP rx 11: 06010809710000000156f0
+DREF VLR subscr MSISDN:42342 usage increases to: 2
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000010650)
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_DONE}: Freeing instance
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_INIT}: Allocated
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000010650)
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_INIT}: Allocated
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(LU:901700000010650)
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(LU:901700000010650)
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_DONE}: Freeing instance
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_DONE}: Deallocated
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_WAIT_SUB_PRES}: lu_compl_vlr_new_tmsi()
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_WAIT_TMSI_CNF
+- sending LU Accept for MSISDN:42342, with TMSI 0x03020100
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+<-- 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(&net->subscr_conns) == 1
+msc_subscr_conn_is_accepted() == false
+  requests shall be thwarted
+DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5)
+DRLL subscr MSISDN:42342: Message not permitted for initial conn: GSM48_MT_CC_SETUP
+DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33)
+DRLL subscr MSISDN:42342: Message not permitted for initial conn: unknown 0x33
+DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19)
+DRLL subscr MSISDN:42342: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1
+DRLL Dispatching 04.08 message SMS:0x01 (0x9:0x1)
+DRLL subscr MSISDN:42342: Message not permitted for initial conn: SMS:0x01
+- even though the TMSI is not acked, we can already find the subscr with it
+DREF VLR subscr MSISDN:42342 usage increases to: 2
+  vsub != NULL == 1
+  strcmp(vsub->imsi, imsi) == 0
+  vsub->tmsi_new == 0x03020100
+  vsub->tmsi == 0xffffffff
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+- MS sends TMSI Realloc Complete
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_TMSI_REALL_COMPL
+DREF MSISDN:42342: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_TMSI_REALL_COMPL (0x5:0x1b)
+DMM TMSI Reallocation Completed. Subscriber: MSISDN:42342
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_NEW_TMSI_ACK
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_WAIT_TMSI_CNF}: Received Event LU_COMPL_VLR_E_NEW_TMSI_ACK
+DREF VLR subscr MSISDN:42342 usage increases to: 2
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_WAIT_TMSI_CNF}: state_chg to LU_COMPL_VLR_S_DONE
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000010650)
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_DONE}: Freeing instance
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_ACCEPTED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:42342: MSC conn use + release == 2 (0x102: dtap,release)
+DREF VLR subscr MSISDN:42342 usage increases to: 3
+DREF VLR subscr MSISDN:42342 usage decreases to: 2
+- BSSAP Clear --RAN_GERAN_A--> MS
+DREF MSISDN:42342: MSC conn use - dtap == 1 (0x100: release)
+  bssap_clear_sent == 1
+- BSS sends BSSMAP Clear Complete
+DREF MSISDN:42342: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(LU:901700000010650)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: Freeing instance
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: Deallocated
+DRLL MSISDN:42342: Freeing subscriber connection
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASED}: Deallocated
+- LU was successful, and the conn has already been closed
+  llist_count(&net->subscr_conns) == 0
+---
+- after a while, a new conn sends a CM Service Request. VLR responds with Auth Req, 2nd auth vector
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_CM_SERV_REQ
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_CM_SERV_REQ (0x5:0x24)
+DMM <- CM SERVICE REQUEST serv_type=0x08 MI(IMSI)=901700000010650
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_NEW}: Updated ID
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: Allocated
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: is child of Subscr_Conn(CM_SERVICE_REQ:901700000010650)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: rev=R99 net=GERAN Auth (no Ciph)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START
+DREF VLR subscr MSISDN:42342 usage increases to: 2
+DREF VLR subscr MSISDN:42342 usage increases to: 3
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_WAIT_AUTH
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Allocated
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: is child of Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650)
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_WAIT_RESP
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){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 MSISDN:42342: tuple use_count=1 key_seq=1 auth_types=0x3 and...
+- ...rand=c187a53a5e6b9d573cac7c74451fd46d
+- ...autn=1843a645b98d00005b2d666af46c45d9
+- ...expecting res=7db47cf7f81e4dc7
+DREF VLR subscr MSISDN:42342 usage decreases to: 2
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF MSISDN:42342: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  cm_service_result_sent == 0
+  auth_request_sent == 1
+- needs auth, not yet accepted
+msc_subscr_conn_is_accepted() == false
+  requests shall be thwarted
+DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5)
+DRLL subscr MSISDN:42342: Message not permitted for initial conn: GSM48_MT_CC_SETUP
+DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33)
+DRLL subscr MSISDN:42342: Message not permitted for initial conn: unknown 0x33
+DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19)
+DRLL subscr MSISDN:42342: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1
+DRLL Dispatching 04.08 message SMS:0x01 (0x9:0x1)
+DRLL subscr MSISDN:42342: Message not permitted for initial conn: SMS:0x01
+- MS sends Authen Response, VLR accepts with a CM Service Accept
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_AUTH_RESP
+DREF MSISDN:42342: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14)
+DMM MSISDN:42342: MM UMTS AUTHENTICATION RESPONSE (res = 7db47cf7f81e4dc7)
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP
+DVLR SUBSCR(MSISDN:42342) AUTH on GERAN received SRES/RES: 7db47cf7f81e4dc7 (8 bytes)
+DVLR SUBSCR(MSISDN:42342) AUTH established UMTS security context
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result PASSED
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Removing from parent Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650)
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Freeing instance
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Deallocated
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: Received Event PR_ARQ_E_AUTH_RES
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2_post_ciph()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2_post_vlr()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_pres()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_trace()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_imei()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: proc_arq_fsm_done(PASSED)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: state_chg to PR_ARQ_S_DONE
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_DONE}: Process Access Request result: PASSED
+- sending CM Service Accept for MSISDN:42342
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_ACCEPTED
+DREF MSISDN:42342: MSC conn use + cm_service == 2 (0xa: dtap,cm_service)
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_ACCEPTED}: subscr_conn_fsm_has_active_transactions: still awaiting first request after a CM Service Request
+DREF MSISDN:42342: MSC conn use - dtap == 1 (0x8: cm_service)
+  cm_service_result_sent == 1
+- Concluding CM Service Request
+DREF MSISDN:42342: MSC conn use - cm_service == 0 (0x0: )
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:42342: MSC conn use + release == 1 (0x100: release)
+DREF VLR subscr MSISDN:42342 usage increases to: 3
+DREF VLR subscr MSISDN:42342 usage decreases to: 2
+- BSSAP Clear --RAN_GERAN_A--> MS
+  bssap_clear_sent == 1
+- BSS sends BSSMAP Clear Complete
+DREF MSISDN:42342: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_DONE}: Removing from parent Subscr_Conn(CM_SERVICE_REQ:901700000010650)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_DONE}: Freeing instance
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_DONE}: Deallocated
+DRLL MSISDN:42342: Freeing subscriber connection
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_RELEASED}: Deallocated
+- all requests serviced, conn has been released
+  llist_count(&net->subscr_conns) == 0
+---
+- an SMS is sent, MS is paged
+DREF VLR subscr MSISDN:42342 usage increases to: 2
+  llist_count(&vsub->cs.requests) == 0
+DREF VLR subscr MSISDN:42342 usage increases to: 3
+DMM Subscriber MSISDN:42342 not paged yet, start paging.
+  RAN_GERAN_A sends out paging request to IMSI 901700000010650, TMSI 0x03020100, LAC 23
+  strcmp(paging_expecting_imsi, imsi) == 0
+DREF VLR subscr MSISDN:42342 usage increases to: 4
+  llist_count(&vsub->cs.requests) == 1
+DREF VLR subscr MSISDN:42342 usage decreases to: 3
+  paging_sent == 1
+  paging_stopped == 0
+- the subscriber and its pending request should remain
+DREF VLR subscr MSISDN:42342 usage increases to: 4
+  llist_count(&vsub->cs.requests) == 1
+DREF VLR subscr MSISDN:42342 usage decreases to: 3
+- MS replies with Paging Response, and VLR sends Auth Request with third key
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_RR_PAG_RESP
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_RR_PAG_RESP (0x6:0x27)
+DRR PAGING RESPONSE: MI(IMSI)=901700000010650
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_NEW}: Updated ID
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_INIT}: Allocated
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_INIT}: is child of Subscr_Conn(PAGING_RESP:901700000010650)
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_INIT}: rev=R99 net=GERAN Auth (no Ciph)
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START
+DREF VLR subscr MSISDN:42342 usage increases to: 4
+DREF VLR subscr MSISDN:42342 usage increases to: 5
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi()
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_WAIT_AUTH
+DVLR VLR_Authenticate(PAGING_RESP:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Allocated
+DVLR VLR_Authenticate(PAGING_RESP:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: is child of Process_Access_Request_VLR(PAGING_RESP:901700000010650)
+DVLR VLR_Authenticate(PAGING_RESP:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
+DVLR VLR_Authenticate(PAGING_RESP:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_WAIT_RESP
+DVLR VLR_Authenticate(PAGING_RESP:901700000010650){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 MSISDN:42342: tuple use_count=1 key_seq=2 auth_types=0x3 and...
+- ...rand=efa9c29a9742148d5c9070348716e1bb
+- ...autn=f9375e6d41e1000096e7fe4ff1c27e39
+- ...expecting res=706f996719ba609c
+DREF VLR subscr MSISDN:42342 usage decreases to: 4
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF MSISDN:42342: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  auth_request_sent == 1
+- needs auth, not yet accepted
+msc_subscr_conn_is_accepted() == false
+  requests shall be thwarted
+DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5)
+DRLL subscr MSISDN:42342: Message not permitted for initial conn: GSM48_MT_CC_SETUP
+DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33)
+DRLL subscr MSISDN:42342: Message not permitted for initial conn: unknown 0x33
+DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19)
+DRLL subscr MSISDN:42342: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1
+DRLL Dispatching 04.08 message SMS:0x01 (0x9:0x1)
+DRLL subscr MSISDN:42342: Message not permitted for initial conn: SMS:0x01
+- MS sends Authen Response, VLR accepts and sends pending SMS
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_AUTH_RESP
+DREF MSISDN:42342: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14)
+DMM MSISDN:42342: MM UMTS AUTHENTICATION RESPONSE (res = 706f996719ba609c)
+DVLR VLR_Authenticate(PAGING_RESP:901700000010650){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP
+DVLR SUBSCR(MSISDN:42342) AUTH on GERAN received SRES/RES: 706f996719ba609c (8 bytes)
+DVLR SUBSCR(MSISDN:42342) AUTH established UMTS security context
+DVLR VLR_Authenticate(PAGING_RESP:901700000010650){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result PASSED
+DVLR VLR_Authenticate(PAGING_RESP:901700000010650){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
+DVLR VLR_Authenticate(PAGING_RESP:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR VLR_Authenticate(PAGING_RESP:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Removing from parent Process_Access_Request_VLR(PAGING_RESP:901700000010650)
+DVLR VLR_Authenticate(PAGING_RESP:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Freeing instance
+DVLR VLR_Authenticate(PAGING_RESP:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Deallocated
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_WAIT_AUTH}: Received Event PR_ARQ_E_AUTH_RES
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2()
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2_post_ciph()
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2_post_vlr()
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_pres()
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_trace()
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_post_imei()
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_WAIT_AUTH}: proc_arq_fsm_done(PASSED)
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_WAIT_AUTH}: state_chg to PR_ARQ_S_DONE
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_DONE}: Process Access Request result: PASSED
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_ACCEPTED
+DPAG Paging success for MSISDN:42342 (event=0)
+DPAG Calling paging cbfn.
+DCC (ti 00 sub MSISDN:42342 callref 40000001) New transaction
+DREF VLR subscr MSISDN:42342 usage increases to: 5
+DREF MSISDN:42342: MSC conn use + trans_sms == 2 (0x22: dtap,trans_sms)
+DMSC msc_tx 91 bytes to MSISDN:42342 via RAN_GERAN_A
+- DTAP --RAN_GERAN_A--> MS: SMS:0x01: 09015801000791447758100650004c0005802443f2000007101000000000445079da1e1ee7416937485e9ea7c965373d1d6683c270383b3d0ed3d36ff71c949e83c22072799e9687c5ec32a81d96afcbf4b4fb0c7ac3e9e9b7db05
+- DTAP matches expected message
+DREF VLR subscr MSISDN:42342 usage decreases to: 4
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_ACCEPTED}: subscr_conn_fsm_has_active_transactions: connection still has active transaction: SMS
+DREF MSISDN:42342: MSC conn use - dtap == 1 (0x20: trans_sms)
+  dtap_tx_confirmed == 1
+  paging_stopped == 1
+- SMS was delivered, no requests pending for subscr
+DREF VLR subscr MSISDN:42342 usage increases to: 5
+  llist_count(&vsub->cs.requests) == 0
+DREF VLR subscr MSISDN:42342 usage decreases to: 4
+- conn is still open to wait for SMS ack dance
+  llist_count(&net->subscr_conns) == 1
+- MS replies with CP-ACK for received SMS
+  MSC <--RAN_GERAN_A-- MS: SMS:0x04
+DREF MSISDN:42342: MSC conn use + dtap == 2 (0x22: dtap,trans_sms)
+DRLL Dispatching 04.08 message SMS:0x04 (0x9:0x4)
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_COMMUNICATING
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_COMMUNICATING
+DREF MSISDN:42342: MSC conn use - dtap == 1 (0x20: trans_sms)
+  llist_count(&net->subscr_conns) == 1
+- MS also sends RP-ACK, MSC in turn sends CP-ACK for that
+  MSC <--RAN_GERAN_A-- MS: SMS:0x01
+DREF MSISDN:42342: MSC conn use + dtap == 2 (0x22: dtap,trans_sms)
+DRLL Dispatching 04.08 message SMS:0x01 (0x9:0x1)
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_COMMUNICATING}: Received Event SUBSCR_CONN_E_COMMUNICATING
+DMSC msc_tx 2 bytes to MSISDN:42342 via RAN_GERAN_A
+- DTAP --RAN_GERAN_A--> MS: SMS:0x04: 0904
+- DTAP matches expected message
+DREF VLR subscr MSISDN:42342 usage decreases to: 3
+DREF VLR subscr MSISDN:42342 usage decreases to: 2
+DREF MSISDN:42342: MSC conn use - trans_sms == 1 (0x2: dtap)
+DREF MSISDN:42342: MSC conn use - dtap == 0 (0x0: )
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_COMMUNICATING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_COMMUNICATING}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:42342: MSC conn use + release == 1 (0x100: release)
+DREF VLR subscr MSISDN:42342 usage increases to: 3
+DREF VLR subscr MSISDN:42342 usage decreases to: 2
+- BSSAP Clear --RAN_GERAN_A--> MS
+  dtap_tx_confirmed == 1
+  bssap_clear_sent == 1
+- BSS sends BSSMAP Clear Complete
+DREF MSISDN:42342: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_DONE}: Removing from parent Subscr_Conn(PAGING_RESP:901700000010650)
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_DONE}: Freeing instance
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_DONE}: Deallocated
+DRLL MSISDN:42342: Freeing subscriber connection
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_RELEASED}: Deallocated
+- SMS is done, conn is gone
+  llist_count(&net->subscr_conns) == 0
+---
+- subscriber detaches
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_IMSI_DETACH_IND
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_IMSI_DETACH_IND (0x5:0x1)
+DMM IMSI DETACH INDICATION: MI(IMSI)=901700000010650
+DREF VLR subscr MSISDN:42342 usage increases to: 2
+DMM IMSI DETACH for MSISDN:42342
+DREF VLR subscr MSISDN:42342 usage increases to: 3
+DREF VLR subscr MSISDN:42342 usage decreases to: 2
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+DREF VLR subscr MSISDN:42342 usage decreases to: 0
+DREF freeing VLR subscr MSISDN:42342
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_CN_CLOSE
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF unknown: MSC conn use + release == 2 (0x101: compl_l3,release)
+- BSSAP Clear --RAN_GERAN_A--> MS
+DREF unknown: MSC conn use - compl_l3 == 1 (0x100: release)
+  bssap_clear_sent == 1
+- BSS sends BSSMAP Clear Complete
+DREF unknown: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DRLL Freeing subscriber connection with NULL subscriber
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+===== test_umts_authen_geran: SUCCESS
+
+full talloc report on 'msgb' (total      0 bytes in   1 blocks)
+talloc_total_blocks(tall_bsc_ctx) == 12
+
+===== test_umts_authen_utran
+- Location Update request causes a GSUP Send Auth Info request to HLR
+  MSC <--RAN_UTRAN_IU-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8)
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_NEW}: Updated ID
+DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000010650 type=NORMAL
+DMM LU/new-LAC: 0/23
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: Allocated
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: is child of Subscr_Conn(LU:901700000010650)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: rev=R99 net=UTRAN Auth+Ciph
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA
+DREF VLR subscr unknown usage increases to: 1
+DVLR set IMSI on subscriber; IMSI=901700000010650 id=901700000010650
+DVLR New subscr, IMSI: 901700000010650
+DREF VLR subscr IMSI:901700000010650 usage increases to: 2
+DREF VLR subscr IMSI:901700000010650 usage decreases to: 1
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Allocated
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(LU:901700000010650)
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
+DVLR GSUP tx: 08010809710000000156f0
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f0
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF IMSI:901700000010650: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  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: 0a010809710000000156f00362201039fa2f4e3d523d8619a73b4f65c3e14d21049b36efdf2208059a4f668f6fbe39231027497388b6cb044648f396aa155b95ef2410f64735036e5871319c679f4742a75ea125108704f5ba55f30000d2ee44b22c8ea9192708e229c19e791f2e4103622010c187a53a5e6b9d573cac7c74451fd46d210485aa31302208d3d50a000bf04f6e23101159ec926a50e98c034a6b7d7c9f418d2410df3a03d9ca5335641efc8e36d76cd20b25101843a645b98d00005b2d666af46c45d927087db47cf7f81e4dc703622010efa9c29a9742148d5c9070348716e1bb210469d5f9fb22083df176f0c29f1a3d2310eb50e770ddcc3060101d2f43b6c2b884241076542abce5ff9345b0e8947f4c6e019c2510f9375e6d41e1000096e7fe4ff1c27e392708706f996719ba609c03622010f023d5a3b24726e0631b64b3840f82532104d570c03f2208ec011be8919883d62310c4e58af4ba43f3bcd904e16984f086d724100593f65e752e5cb7f473862bda05aa0a2510541ff1f077270000c5ea00d658bc7e9a27083fd26072eaa2a04d036220102f8f90c780d6a9c0c53da7ac57b6707e2104b072446f220823f39f9f425ad6e6231065af0527fda95b0dc5ae4aa515cdf32f2410537c3b35a3b13b08d08eeb28098f45cc25104bf4e564f75300009bc796706bc6574427080edb0eadbea94ac2
+DVLR GSUP rx 511: 0a010809710000000156f00362201039fa2f4e3d523d8619a73b4f65c3e14d21049b36efdf2208059a4f668f6fbe39231027497388b6cb044648f396aa155b95ef2410f64735036e5871319c679f4742a75ea125108704f5ba55f30000d2ee44b22c8ea9192708e229c19e791f2e4103622010c187a53a5e6b9d573cac7c74451fd46d210485aa31302208d3d50a000bf04f6e23101159ec926a50e98c034a6b7d7c9f418d2410df3a03d9ca5335641efc8e36d76cd20b25101843a645b98d00005b2d666af46c45d927087db47cf7f81e4dc703622010efa9c29a9742148d5c9070348716e1bb210469d5f9fb22083df176f0c29f1a3d2310eb50e770ddcc3060101d2f43b6c2b884241076542abce5ff9345b0e8947f4c6e019c2510f9375e6d41e1000096e7fe4ff1c27e392708706f996719ba609c03622010f023d5a3b24726e0631b64b3840f82532104d570c03f2208ec011be8919883d62310c4e58af4ba43f3bcd904e16984f086d724100593f65e752e5cb7f473862bda05aa0a2510541ff1f077270000c5ea00d658bc7e9a27083fd26072eaa2a04d036220102f8f90c780d6a9c0c53da7ac57b6707e2104b072446f220823f39f9f425ad6e6231065af0527fda95b0dc5ae4aa515cdf32f2410537c3b35a3b13b08d08eeb28098f45cc25104bf4e564f75300009bc796706bc6574427080edb0eadbea94ac2
+DREF VLR subscr IMSI:901700000010650 usage increases to: 2
+DVLR VLR_Authenticate(LU:901700000010650){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(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: state_chg to VLR_SUB_AS_WAIT_RESP
+DVLR VLR_Authenticate(LU:901700000010650){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: tuple use_count=1 key_seq=0 auth_types=0x3 and...
+- ...rand=39fa2f4e3d523d8619a73b4f65c3e14d
+- ...autn=8704f5ba55f30000d2ee44b22c8ea919
+- ...expecting res=e229c19e791f2e41
+DREF VLR subscr IMSI:901700000010650 usage decreases to: 1
+<-- 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
+  MSC <--RAN_UTRAN_IU-- MS: GSM48_MT_MM_AUTH_RESP
+DREF IMSI:901700000010650: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14)
+DMM IMSI:901700000010650: MM UMTS AUTHENTICATION RESPONSE (res = e229c19e791f2e41)
+DVLR VLR_Authenticate(LU:901700000010650){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(LU:901700000010650){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result PASSED
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(LU:901700000010650)
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Freeing instance
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth()
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_AUTH}: Set Ciphering Mode
+DMM -> SECURITY MODE CONTROL IMSI:901700000010650
+- sending SecurityModeControl for UE ctx 42 send_ck=0 new_key=1
+- ...ik=27497388b6cb044648f396aa155b95ef
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_WAIT_CIPH
+DREF IMSI:901700000010650: MSC conn use - dtap == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  security_mode_ctrl_sent == 1
+  lu_result_sent == 0
+- MS sends SecurityModeControl acceptance, VLR accepts and sends GSUP LU Req to HLR
+DMM <- SECURITY MODE COMPLETE IMSI:901700000010650
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_CIPH}: Received Event VLR_ULA_E_CIPH_RES
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_CIPH}: vlr_loc_upd_post_ciph()
+DIUCS IMSI:901700000010650: tx CommonID 901700000010650
+- Iu Common ID --RAN_UTRAN_IU--> MS (IMSI=901700000010650)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_CIPH}: vlr_loc_upd_node_4()
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_CIPH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_INIT}: Allocated
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000010650)
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START
+DVLR GSUP tx: 04010809710000000156f0280102
+GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000000156f0280102
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){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: 10010809710000000156f00804032443f2
+DVLR GSUP rx 17: 10010809710000000156f00804032443f2
+DREF VLR subscr IMSI:901700000010650 usage increases to: 2
+DVLR IMSI:901700000010650 has MSISDN:42342
+DVLR SUBSCR(MSISDN:42342) VLR: update for IMSI=901700000010650 (MSISDN=42342, used=2)
+DVLR GSUP tx: 12010809710000000156f0
+GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000000156f0
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+<-- 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: 06010809710000000156f0
+DVLR GSUP rx 11: 06010809710000000156f0
+DREF VLR subscr MSISDN:42342 usage increases to: 2
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000010650)
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_DONE}: Freeing instance
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_INIT}: Allocated
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000010650)
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_INIT}: Allocated
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(LU:901700000010650)
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(LU:901700000010650)
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_DONE}: Freeing instance
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_DONE}: Deallocated
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_WAIT_SUB_PRES}: lu_compl_vlr_new_tmsi()
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_WAIT_TMSI_CNF
+- sending LU Accept for MSISDN:42342, with TMSI 0x03020100
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+<-- 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(&net->subscr_conns) == 1
+msc_subscr_conn_is_accepted() == false
+  requests shall be thwarted
+DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5)
+DRLL subscr MSISDN:42342: Message not permitted for initial conn: GSM48_MT_CC_SETUP
+DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33)
+DRLL subscr MSISDN:42342: Message not permitted for initial conn: unknown 0x33
+DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19)
+DRLL subscr MSISDN:42342: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1
+DRLL Dispatching 04.08 message SMS:0x01 (0x9:0x1)
+DRLL subscr MSISDN:42342: Message not permitted for initial conn: SMS:0x01
+- even though the TMSI is not acked, we can already find the subscr with it
+DREF VLR subscr MSISDN:42342 usage increases to: 2
+  vsub != NULL == 1
+  strcmp(vsub->imsi, imsi) == 0
+  vsub->tmsi_new == 0x03020100
+  vsub->tmsi == 0xffffffff
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+- MS sends TMSI Realloc Complete
+  MSC <--RAN_UTRAN_IU-- MS: GSM48_MT_MM_TMSI_REALL_COMPL
+DREF MSISDN:42342: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_TMSI_REALL_COMPL (0x5:0x1b)
+DMM TMSI Reallocation Completed. Subscriber: MSISDN:42342
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_NEW_TMSI_ACK
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_WAIT_TMSI_CNF}: Received Event LU_COMPL_VLR_E_NEW_TMSI_ACK
+DREF VLR subscr MSISDN:42342 usage increases to: 2
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_WAIT_TMSI_CNF}: state_chg to LU_COMPL_VLR_S_DONE
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000010650)
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_DONE}: Freeing instance
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_ACCEPTED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:42342: MSC conn use + release == 2 (0x102: dtap,release)
+DREF VLR subscr MSISDN:42342 usage increases to: 3
+DREF VLR subscr MSISDN:42342 usage decreases to: 2
+- Iu Release --RAN_UTRAN_IU--> MS
+DREF MSISDN:42342: MSC conn use - dtap == 1 (0x100: release)
+  iu_release_sent == 1
+- RNC sends Iu Release Complete
+DREF MSISDN:42342: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(LU:901700000010650)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: Freeing instance
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: Deallocated
+DRLL MSISDN:42342: Freeing subscriber connection
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASED}: Deallocated
+- LU was successful, and the conn has already been closed
+  llist_count(&net->subscr_conns) == 0
+---
+- after a while, a new conn sends a CM Service Request. VLR responds with Auth Req, 2nd auth vector
+  MSC <--RAN_UTRAN_IU-- MS: GSM48_MT_MM_CM_SERV_REQ
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_CM_SERV_REQ (0x5:0x24)
+DMM <- CM SERVICE REQUEST serv_type=0x08 MI(IMSI)=901700000010650
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_NEW}: Updated ID
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: Allocated
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: is child of Subscr_Conn(CM_SERVICE_REQ:901700000010650)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: rev=R99 net=UTRAN Auth+Ciph
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START
+DREF VLR subscr MSISDN:42342 usage increases to: 2
+DREF VLR subscr MSISDN:42342 usage increases to: 3
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_WAIT_AUTH
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Allocated
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: is child of Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650)
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_WAIT_RESP
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){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 MSISDN:42342: tuple use_count=1 key_seq=1 auth_types=0x3 and...
+- ...rand=c187a53a5e6b9d573cac7c74451fd46d
+- ...autn=1843a645b98d00005b2d666af46c45d9
+- ...expecting res=7db47cf7f81e4dc7
+DREF VLR subscr MSISDN:42342 usage decreases to: 2
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF MSISDN:42342: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  cm_service_result_sent == 0
+  auth_request_sent == 1
+- needs auth, not yet accepted
+msc_subscr_conn_is_accepted() == false
+  requests shall be thwarted
+DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5)
+DRLL subscr MSISDN:42342: Message not permitted for initial conn: GSM48_MT_CC_SETUP
+DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33)
+DRLL subscr MSISDN:42342: Message not permitted for initial conn: unknown 0x33
+DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19)
+DRLL subscr MSISDN:42342: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1
+DRLL Dispatching 04.08 message SMS:0x01 (0x9:0x1)
+DRLL subscr MSISDN:42342: Message not permitted for initial conn: SMS:0x01
+- MS sends Authen Response, VLR accepts and sends SecurityModeControl
+  MSC <--RAN_UTRAN_IU-- MS: GSM48_MT_MM_AUTH_RESP
+DREF MSISDN:42342: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14)
+DMM MSISDN:42342: MM UMTS AUTHENTICATION RESPONSE (res = 7db47cf7f81e4dc7)
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP
+DVLR SUBSCR(MSISDN:42342) AUTH on UTRAN received RES: 7db47cf7f81e4dc7 (8 bytes)
+DVLR SUBSCR(MSISDN:42342) AUTH established UMTS security context
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result PASSED
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Removing from parent Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650)
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Freeing instance
+DVLR VLR_Authenticate(CM_SERVICE_REQ:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Deallocated
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: Received Event PR_ARQ_E_AUTH_RES
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: Set Ciphering Mode
+DMM -> SECURITY MODE CONTROL MSISDN:42342
+- sending SecurityModeControl for UE ctx 42 send_ck=0 new_key=1
+- ...ik=1159ec926a50e98c034a6b7d7c9f418d
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_AUTH}: state_chg to PR_ARQ_S_WAIT_CIPH
+DREF MSISDN:42342: MSC conn use - dtap == 0 (0x0: )
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  security_mode_ctrl_sent == 1
+  cm_service_result_sent == 0
+- MS sends SecurityModeControl acceptance, VLR accepts; above Ciphering is an implicit CM Service Accept
+DMM <- SECURITY MODE COMPLETE MSISDN:42342
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_CIPH}: Received Event PR_ARQ_E_CIPH_RES
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_node2_post_ciph()
+DIUCS MSISDN:42342: tx CommonID 901700000010650
+- Iu Common ID --RAN_UTRAN_IU--> MS (IMSI=901700000010650)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_node2_post_vlr()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_pres()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_trace()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_imei()
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_CIPH}: proc_arq_fsm_done(PASSED)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_WAIT_CIPH}: state_chg to PR_ARQ_S_DONE
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_DONE}: Process Access Request result: PASSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_ACCEPTED
+DREF MSISDN:42342: MSC conn use + cm_service == 1 (0x8: cm_service)
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_ACCEPTED}: subscr_conn_fsm_has_active_transactions: still awaiting first request after a CM Service Request
+  cm_service_result_sent == 0
+- Concluding CM Service Request
+DREF MSISDN:42342: MSC conn use - cm_service == 0 (0x0: )
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:42342: MSC conn use + release == 1 (0x100: release)
+DREF VLR subscr MSISDN:42342 usage increases to: 3
+DREF VLR subscr MSISDN:42342 usage decreases to: 2
+- Iu Release --RAN_UTRAN_IU--> MS
+  iu_release_sent == 1
+- RNC sends Iu Release Complete
+DREF MSISDN:42342: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_DONE}: Removing from parent Subscr_Conn(CM_SERVICE_REQ:901700000010650)
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_DONE}: Freeing instance
+DVLR Process_Access_Request_VLR(CM_SERVICE_REQ:901700000010650){PR_ARQ_S_DONE}: Deallocated
+DRLL MSISDN:42342: Freeing subscriber connection
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_RELEASED}: Deallocated
+- all requests serviced, conn has been released
+  llist_count(&net->subscr_conns) == 0
+---
+- an SMS is sent, MS is paged
+DREF VLR subscr MSISDN:42342 usage increases to: 2
+  llist_count(&vsub->cs.requests) == 0
+DREF VLR subscr MSISDN:42342 usage increases to: 3
+DMM Subscriber MSISDN:42342 not paged yet, start paging.
+  RAN_UTRAN_IU sends out paging request to IMSI 901700000010650, TMSI 0x03020100, LAC 23
+  strcmp(paging_expecting_imsi, imsi) == 0
+DREF VLR subscr MSISDN:42342 usage increases to: 4
+  llist_count(&vsub->cs.requests) == 1
+DREF VLR subscr MSISDN:42342 usage decreases to: 3
+  paging_sent == 1
+  paging_stopped == 0
+- the subscriber and its pending request should remain
+DREF VLR subscr MSISDN:42342 usage increases to: 4
+  llist_count(&vsub->cs.requests) == 1
+DREF VLR subscr MSISDN:42342 usage decreases to: 3
+- MS replies with Paging Response, and VLR sends Auth Request with third key
+  MSC <--RAN_UTRAN_IU-- MS: GSM48_MT_RR_PAG_RESP
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_RR_PAG_RESP (0x6:0x27)
+DRR PAGING RESPONSE: MI(IMSI)=901700000010650
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_NEW}: Updated ID
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_INIT}: Allocated
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_INIT}: is child of Subscr_Conn(PAGING_RESP:901700000010650)
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_INIT}: rev=R99 net=UTRAN Auth+Ciph
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_INIT}: Received Event PR_ARQ_E_START
+DREF VLR subscr MSISDN:42342 usage increases to: 4
+DREF VLR subscr MSISDN:42342 usage increases to: 5
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_INIT}: proc_arq_vlr_fn_post_imsi()
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_INIT}: state_chg to PR_ARQ_S_WAIT_AUTH
+DVLR VLR_Authenticate(PAGING_RESP:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Allocated
+DVLR VLR_Authenticate(PAGING_RESP:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: is child of Process_Access_Request_VLR(PAGING_RESP:901700000010650)
+DVLR VLR_Authenticate(PAGING_RESP:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
+DVLR VLR_Authenticate(PAGING_RESP:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_WAIT_RESP
+DVLR VLR_Authenticate(PAGING_RESP:901700000010650){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 MSISDN:42342: tuple use_count=1 key_seq=2 auth_types=0x3 and...
+- ...rand=efa9c29a9742148d5c9070348716e1bb
+- ...autn=f9375e6d41e1000096e7fe4ff1c27e39
+- ...expecting res=706f996719ba609c
+DREF VLR subscr MSISDN:42342 usage decreases to: 4
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF MSISDN:42342: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  auth_request_sent == 1
+- needs auth, not yet accepted
+msc_subscr_conn_is_accepted() == false
+  requests shall be thwarted
+DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5)
+DRLL subscr MSISDN:42342: Message not permitted for initial conn: GSM48_MT_CC_SETUP
+DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33)
+DRLL subscr MSISDN:42342: Message not permitted for initial conn: unknown 0x33
+DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19)
+DRLL subscr MSISDN:42342: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1
+DRLL Dispatching 04.08 message SMS:0x01 (0x9:0x1)
+DRLL subscr MSISDN:42342: Message not permitted for initial conn: SMS:0x01
+- MS sends Authen Response, VLR accepts and sends SecurityModeControl
+  MSC <--RAN_UTRAN_IU-- MS: GSM48_MT_MM_AUTH_RESP
+DREF MSISDN:42342: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14)
+DMM MSISDN:42342: MM UMTS AUTHENTICATION RESPONSE (res = 706f996719ba609c)
+DVLR VLR_Authenticate(PAGING_RESP:901700000010650){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_RESP
+DVLR SUBSCR(MSISDN:42342) AUTH on UTRAN received RES: 706f996719ba609c (8 bytes)
+DVLR SUBSCR(MSISDN:42342) AUTH established UMTS security context
+DVLR VLR_Authenticate(PAGING_RESP:901700000010650){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result PASSED
+DVLR VLR_Authenticate(PAGING_RESP:901700000010650){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTHENTICATED
+DVLR VLR_Authenticate(PAGING_RESP:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR VLR_Authenticate(PAGING_RESP:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Removing from parent Process_Access_Request_VLR(PAGING_RESP:901700000010650)
+DVLR VLR_Authenticate(PAGING_RESP:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Freeing instance
+DVLR VLR_Authenticate(PAGING_RESP:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Deallocated
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_WAIT_AUTH}: Received Event PR_ARQ_E_AUTH_RES
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_WAIT_AUTH}: _proc_arq_vlr_node2()
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_WAIT_AUTH}: Set Ciphering Mode
+DMM -> SECURITY MODE CONTROL MSISDN:42342
+- sending SecurityModeControl for UE ctx 42 send_ck=0 new_key=1
+- ...ik=eb50e770ddcc3060101d2f43b6c2b884
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_WAIT_AUTH}: state_chg to PR_ARQ_S_WAIT_CIPH
+DREF MSISDN:42342: MSC conn use - dtap == 0 (0x0: )
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  security_mode_ctrl_sent == 1
+  paging_stopped == 0
+- MS sends SecurityModeControl acceptance, VLR accepts and sends SMS
+DMM <- SECURITY MODE COMPLETE MSISDN:42342
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_WAIT_CIPH}: Received Event PR_ARQ_E_CIPH_RES
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_node2_post_ciph()
+DIUCS MSISDN:42342: tx CommonID 901700000010650
+- Iu Common ID --RAN_UTRAN_IU--> MS (IMSI=901700000010650)
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_node2_post_vlr()
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_pres()
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_trace()
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_WAIT_CIPH}: _proc_arq_vlr_post_imei()
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_WAIT_CIPH}: proc_arq_fsm_done(PASSED)
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_WAIT_CIPH}: state_chg to PR_ARQ_S_DONE
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_DONE}: Process Access Request result: PASSED
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_ACCEPTED
+DPAG Paging success for MSISDN:42342 (event=0)
+DPAG Calling paging cbfn.
+DCC (ti 00 sub MSISDN:42342 callref 40000002) New transaction
+DREF VLR subscr MSISDN:42342 usage increases to: 5
+DREF MSISDN:42342: MSC conn use + trans_sms == 1 (0x20: trans_sms)
+DMSC msc_tx 91 bytes to MSISDN:42342 via RAN_UTRAN_IU
+- DTAP --RAN_UTRAN_IU--> MS: SMS:0x01: 09015801000791447758100650004c0005802443f2000007101000000000445079da1e1ee7416937485e9ea7c965373d1d6683c270383b3d0ed3d36ff71c949e83c22072799e9687c5ec32a81d96afcbf4b4fb0c7ac3e9e9b7db05
+- DTAP matches expected message
+DREF VLR subscr MSISDN:42342 usage decreases to: 4
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_ACCEPTED}: subscr_conn_fsm_has_active_transactions: connection still has active transaction: SMS
+  paging_stopped == 1
+- SMS was delivered, no requests pending for subscr
+DREF VLR subscr MSISDN:42342 usage increases to: 5
+  llist_count(&vsub->cs.requests) == 0
+DREF VLR subscr MSISDN:42342 usage decreases to: 4
+- conn is still open to wait for SMS ack dance
+  llist_count(&net->subscr_conns) == 1
+- MS replies with CP-ACK for received SMS
+  MSC <--RAN_UTRAN_IU-- MS: SMS:0x04
+DREF MSISDN:42342: MSC conn use + dtap == 2 (0x22: dtap,trans_sms)
+DRLL Dispatching 04.08 message SMS:0x04 (0x9:0x4)
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_COMMUNICATING
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_COMMUNICATING
+DREF MSISDN:42342: MSC conn use - dtap == 1 (0x20: trans_sms)
+  llist_count(&net->subscr_conns) == 1
+- MS also sends RP-ACK, MSC in turn sends CP-ACK for that
+  MSC <--RAN_UTRAN_IU-- MS: SMS:0x01
+DREF MSISDN:42342: MSC conn use + dtap == 2 (0x22: dtap,trans_sms)
+DRLL Dispatching 04.08 message SMS:0x01 (0x9:0x1)
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_COMMUNICATING}: Received Event SUBSCR_CONN_E_COMMUNICATING
+DMSC msc_tx 2 bytes to MSISDN:42342 via RAN_UTRAN_IU
+- DTAP --RAN_UTRAN_IU--> MS: SMS:0x04: 0904
+- DTAP matches expected message
+DREF VLR subscr MSISDN:42342 usage decreases to: 3
+DREF VLR subscr MSISDN:42342 usage decreases to: 2
+DREF MSISDN:42342: MSC conn use - trans_sms == 1 (0x2: dtap)
+DREF MSISDN:42342: MSC conn use - dtap == 0 (0x0: )
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_COMMUNICATING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_COMMUNICATING}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:42342: MSC conn use + release == 1 (0x100: release)
+DREF VLR subscr MSISDN:42342 usage increases to: 3
+DREF VLR subscr MSISDN:42342 usage decreases to: 2
+- Iu Release --RAN_UTRAN_IU--> MS
+  dtap_tx_confirmed == 1
+  iu_release_sent == 1
+- RNC sends Iu Release Complete
+DREF MSISDN:42342: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_DONE}: Removing from parent Subscr_Conn(PAGING_RESP:901700000010650)
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_DONE}: Freeing instance
+DVLR Process_Access_Request_VLR(PAGING_RESP:901700000010650){PR_ARQ_S_DONE}: Deallocated
+DRLL MSISDN:42342: Freeing subscriber connection
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_RELEASED}: Deallocated
+- SMS is done, conn is gone
+  llist_count(&net->subscr_conns) == 0
+---
+- subscriber detaches
+  MSC <--RAN_UTRAN_IU-- MS: GSM48_MT_MM_IMSI_DETACH_IND
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_IMSI_DETACH_IND (0x5:0x1)
+DMM IMSI DETACH INDICATION: MI(IMSI)=901700000010650
+DREF VLR subscr MSISDN:42342 usage increases to: 2
+DMM IMSI DETACH for MSISDN:42342
+DREF VLR subscr MSISDN:42342 usage increases to: 3
+DREF VLR subscr MSISDN:42342 usage decreases to: 2
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+DREF VLR subscr MSISDN:42342 usage decreases to: 0
+DREF freeing VLR subscr MSISDN:42342
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_CN_CLOSE
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF unknown: MSC conn use + release == 2 (0x101: compl_l3,release)
+- Iu Release --RAN_UTRAN_IU--> MS
+DREF unknown: MSC conn use - compl_l3 == 1 (0x100: release)
+  iu_release_sent == 1
+- RNC sends Iu Release Complete
+DREF unknown: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DRLL Freeing subscriber connection with NULL subscriber
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn{SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 0
+===== test_umts_authen_utran: SUCCESS
+
+full talloc report on 'msgb' (total      0 bytes in   1 blocks)
+talloc_total_blocks(tall_bsc_ctx) == 12
+
+===== test_umts_authen_resync_geran
+- Location Update request causes a GSUP Send Auth Info request to HLR
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8)
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_NEW}: Updated ID
+DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000010650 type=NORMAL
+DMM LU/new-LAC: 0/23
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: Allocated
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: is child of Subscr_Conn(LU:901700000010650)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: rev=R99 net=GERAN Auth (no Ciph)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA
+DREF VLR subscr unknown usage increases to: 1
+DVLR set IMSI on subscriber; IMSI=901700000010650 id=901700000010650
+DVLR New subscr, IMSI: 901700000010650
+DREF VLR subscr IMSI:901700000010650 usage increases to: 2
+DREF VLR subscr IMSI:901700000010650 usage decreases to: 1
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Allocated
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(LU:901700000010650)
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
+DVLR GSUP tx: 08010809710000000156f0
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f0
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF IMSI:901700000010650: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  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: 0a010809710000000156f00362201039fa2f4e3d523d8619a73b4f65c3e14d21049b36efdf2208059a4f668f6fbe39231027497388b6cb044648f396aa155b95ef2410f64735036e5871319c679f4742a75ea125108704f5ba55f30000d2ee44b22c8ea9192708e229c19e791f2e41
+DVLR GSUP rx 111: 0a010809710000000156f00362201039fa2f4e3d523d8619a73b4f65c3e14d21049b36efdf2208059a4f668f6fbe39231027497388b6cb044648f396aa155b95ef2410f64735036e5871319c679f4742a75ea125108704f5ba55f30000d2ee44b22c8ea9192708e229c19e791f2e41
+DREF VLR subscr IMSI:901700000010650 usage increases to: 2
+DVLR VLR_Authenticate(LU:901700000010650){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(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: state_chg to VLR_SUB_AS_WAIT_RESP
+DVLR VLR_Authenticate(LU:901700000010650){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: tuple use_count=1 key_seq=0 auth_types=0x3 and...
+- ...rand=39fa2f4e3d523d8619a73b4f65c3e14d
+- ...autn=8704f5ba55f30000d2ee44b22c8ea919
+- ...expecting res=e229c19e791f2e41
+DREF VLR subscr IMSI:901700000010650 usage decreases to: 1
+<-- 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 <--RAN_GERAN_A-- MS: GSM48_MT_MM_AUTH_FAIL
+DREF IMSI:901700000010650: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_FAIL (0x5:0x1c)
+DMM IMSI:901700000010650: MM R99 AUTHENTICATION SYNCH (AUTS = 979498b1f72d3e28c59fa2e72f9c)
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_FAIL
+DVLR GSUP tx: 08010809710000000156f0260e979498b1f72d3e28c59fa2e72f9c201039fa2f4e3d523d8619a73b4f65c3e14d
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f0260e979498b1f72d3e28c59fa2e72f9c201039fa2f4e3d523d8619a73b4f65c3e14d
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_SAI_RESYNC
+DREF IMSI:901700000010650: MSC conn use - dtap == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  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: 0a010809710000000156f0036220100f1feb1623e1bf626334e37ec448ac182104efde99da220814778c855c52373023108a90c769b7272f3bb7a1c1fbb1ea9349241043ffc1cf8c89a7fd6ab94bd8d6162cbf251002a83f62e9470000660d51afc75f169d27081df5f0b4f22b696e03622010ac21d34937b4e1142a2c757af294931921047818bfdc2208d175571f41f314a42310ff8edbceb6dd24799c77c3b9a6790c102410157c39022ca9d885a7f0766a7dfee44825108a43b91898e500002cf354c6f5d1f8c32708f748a7078f5018db
+DVLR GSUP rx 211: 0a010809710000000156f0036220100f1feb1623e1bf626334e37ec448ac182104efde99da220814778c855c52373023108a90c769b7272f3bb7a1c1fbb1ea9349241043ffc1cf8c89a7fd6ab94bd8d6162cbf251002a83f62e9470000660d51afc75f169d27081df5f0b4f22b696e03622010ac21d34937b4e1142a2c757af294931921047818bfdc2208d175571f41f314a42310ff8edbceb6dd24799c77c3b9a6790c102410157c39022ca9d885a7f0766a7dfee44825108a43b91898e500002cf354c6f5d1f8c32708f748a7078f5018db
+DREF VLR subscr IMSI:901700000010650 usage increases to: 2
+DVLR VLR_Authenticate(LU:901700000010650){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(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH_WAIT_SAI_RESYNC}: state_chg to VLR_SUB_AS_WAIT_RESP_RESYNC
+DVLR VLR_Authenticate(LU:901700000010650){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: tuple use_count=1 key_seq=0 auth_types=0x3 and...
+- ...rand=0f1feb1623e1bf626334e37ec448ac18
+- ...autn=02a83f62e9470000660d51afc75f169d
+- ...expecting res=1df5f0b4f22b696e
+DREF VLR subscr IMSI:901700000010650 usage decreases to: 1
+<-- 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
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_AUTH_RESP
+DREF IMSI:901700000010650: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14)
+DMM IMSI:901700000010650: MM UMTS AUTHENTICATION RESPONSE (res = 1df5f0b4f22b696e)
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_WAIT_RESP_RESYNC}: Received Event VLR_AUTH_E_MS_AUTH_RESP
+DVLR SUBSCR(IMSI:901700000010650) AUTH on GERAN received SRES/RES: 1df5f0b4f22b696e (8 bytes)
+DVLR SUBSCR(IMSI:901700000010650) AUTH established UMTS security context
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_WAIT_RESP_RESYNC}: Authentication terminating with result PASSED
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_WAIT_RESP_RESYNC}: state_chg to VLR_SUB_AS_AUTHENTICATED
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(LU:901700000010650)
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Freeing instance
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth()
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_ciph()
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_node_4()
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_INIT}: Allocated
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000010650)
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START
+DVLR GSUP tx: 04010809710000000156f0280102
+GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000000156f0280102
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA
+DREF IMSI:901700000010650: MSC conn use - dtap == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  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: 10010809710000000156f00804032443f2
+DVLR GSUP rx 17: 10010809710000000156f00804032443f2
+DREF VLR subscr IMSI:901700000010650 usage increases to: 2
+DVLR IMSI:901700000010650 has MSISDN:42342
+DVLR SUBSCR(MSISDN:42342) VLR: update for IMSI=901700000010650 (MSISDN=42342, used=2)
+DVLR GSUP tx: 12010809710000000156f0
+GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000000156f0
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+<-- 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: 06010809710000000156f0
+DVLR GSUP rx 11: 06010809710000000156f0
+DREF VLR subscr MSISDN:42342 usage increases to: 2
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000010650)
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_DONE}: Freeing instance
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_INIT}: Allocated
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000010650)
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_INIT}: Allocated
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(LU:901700000010650)
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(LU:901700000010650)
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_DONE}: Freeing instance
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_DONE}: Deallocated
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_WAIT_SUB_PRES}: lu_compl_vlr_new_tmsi()
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_WAIT_TMSI_CNF
+- sending LU Accept for MSISDN:42342, with TMSI 0x03020100
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+<-- 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(&net->subscr_conns) == 1
+msc_subscr_conn_is_accepted() == false
+  requests shall be thwarted
+DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5)
+DRLL subscr MSISDN:42342: Message not permitted for initial conn: GSM48_MT_CC_SETUP
+DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33)
+DRLL subscr MSISDN:42342: Message not permitted for initial conn: unknown 0x33
+DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19)
+DRLL subscr MSISDN:42342: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1
+DRLL Dispatching 04.08 message SMS:0x01 (0x9:0x1)
+DRLL subscr MSISDN:42342: Message not permitted for initial conn: SMS:0x01
+- even though the TMSI is not acked, we can already find the subscr with it
+DREF VLR subscr MSISDN:42342 usage increases to: 2
+  vsub != NULL == 1
+  strcmp(vsub->imsi, imsi) == 0
+  vsub->tmsi_new == 0x03020100
+  vsub->tmsi == 0xffffffff
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+- MS sends TMSI Realloc Complete
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_TMSI_REALL_COMPL
+DREF MSISDN:42342: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_TMSI_REALL_COMPL (0x5:0x1b)
+DMM TMSI Reallocation Completed. Subscriber: MSISDN:42342
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_NEW_TMSI_ACK
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_WAIT_TMSI_CNF}: Received Event LU_COMPL_VLR_E_NEW_TMSI_ACK
+DREF VLR subscr MSISDN:42342 usage increases to: 2
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_WAIT_TMSI_CNF}: state_chg to LU_COMPL_VLR_S_DONE
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000010650)
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_DONE}: Freeing instance
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_ACCEPTED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:42342: MSC conn use + release == 2 (0x102: dtap,release)
+DREF VLR subscr MSISDN:42342 usage increases to: 3
+DREF VLR subscr MSISDN:42342 usage decreases to: 2
+- BSSAP Clear --RAN_GERAN_A--> MS
+DREF MSISDN:42342: MSC conn use - dtap == 1 (0x100: release)
+  bssap_clear_sent == 1
+- BSS sends BSSMAP Clear Complete
+DREF MSISDN:42342: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(LU:901700000010650)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: Freeing instance
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: Deallocated
+DRLL MSISDN:42342: Freeing subscriber connection
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASED}: Deallocated
+- LU was successful, and the conn has already been closed
+  llist_count(&net->subscr_conns) == 0
+DREF freeing VLR subscr MSISDN:42342
+===== test_umts_authen_resync_geran: SUCCESS
+
+full talloc report on 'msgb' (total      0 bytes in   1 blocks)
+talloc_total_blocks(tall_bsc_ctx) == 12
+
+===== test_umts_authen_resync_utran
+- Location Update request causes a GSUP Send Auth Info request to HLR
+  MSC <--RAN_UTRAN_IU-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8)
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_NEW}: Updated ID
+DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000010650 type=NORMAL
+DMM LU/new-LAC: 0/23
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: Allocated
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: is child of Subscr_Conn(LU:901700000010650)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: rev=R99 net=UTRAN Auth+Ciph
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA
+DREF VLR subscr unknown usage increases to: 1
+DVLR set IMSI on subscriber; IMSI=901700000010650 id=901700000010650
+DVLR New subscr, IMSI: 901700000010650
+DREF VLR subscr IMSI:901700000010650 usage increases to: 2
+DREF VLR subscr IMSI:901700000010650 usage decreases to: 1
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Allocated
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(LU:901700000010650)
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
+DVLR GSUP tx: 08010809710000000156f0
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f0
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF IMSI:901700000010650: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  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: 0a010809710000000156f00362201039fa2f4e3d523d8619a73b4f65c3e14d21049b36efdf2208059a4f668f6fbe39231027497388b6cb044648f396aa155b95ef2410f64735036e5871319c679f4742a75ea125108704f5ba55f30000d2ee44b22c8ea9192708e229c19e791f2e41
+DVLR GSUP rx 111: 0a010809710000000156f00362201039fa2f4e3d523d8619a73b4f65c3e14d21049b36efdf2208059a4f668f6fbe39231027497388b6cb044648f396aa155b95ef2410f64735036e5871319c679f4742a75ea125108704f5ba55f30000d2ee44b22c8ea9192708e229c19e791f2e41
+DREF VLR subscr IMSI:901700000010650 usage increases to: 2
+DVLR VLR_Authenticate(LU:901700000010650){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(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: state_chg to VLR_SUB_AS_WAIT_RESP
+DVLR VLR_Authenticate(LU:901700000010650){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: tuple use_count=1 key_seq=0 auth_types=0x3 and...
+- ...rand=39fa2f4e3d523d8619a73b4f65c3e14d
+- ...autn=8704f5ba55f30000d2ee44b22c8ea919
+- ...expecting res=e229c19e791f2e41
+DREF VLR subscr IMSI:901700000010650 usage decreases to: 1
+<-- 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 <--RAN_UTRAN_IU-- MS: GSM48_MT_MM_AUTH_FAIL
+DREF IMSI:901700000010650: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_FAIL (0x5:0x1c)
+DMM IMSI:901700000010650: MM R99 AUTHENTICATION SYNCH (AUTS = 979498b1f72d3e28c59fa2e72f9c)
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_WAIT_RESP}: Received Event VLR_AUTH_E_MS_AUTH_FAIL
+DVLR GSUP tx: 08010809710000000156f0260e979498b1f72d3e28c59fa2e72f9c201039fa2f4e3d523d8619a73b4f65c3e14d
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f0260e979498b1f72d3e28c59fa2e72f9c201039fa2f4e3d523d8619a73b4f65c3e14d
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_SAI_RESYNC
+DREF IMSI:901700000010650: MSC conn use - dtap == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  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: 0a010809710000000156f0036220100f1feb1623e1bf626334e37ec448ac182104efde99da220814778c855c52373023108a90c769b7272f3bb7a1c1fbb1ea9349241043ffc1cf8c89a7fd6ab94bd8d6162cbf251002a83f62e9470000660d51afc75f169d27081df5f0b4f22b696e03622010ac21d34937b4e1142a2c757af294931921047818bfdc2208d175571f41f314a42310ff8edbceb6dd24799c77c3b9a6790c102410157c39022ca9d885a7f0766a7dfee44825108a43b91898e500002cf354c6f5d1f8c32708f748a7078f5018db
+DVLR GSUP rx 211: 0a010809710000000156f0036220100f1feb1623e1bf626334e37ec448ac182104efde99da220814778c855c52373023108a90c769b7272f3bb7a1c1fbb1ea9349241043ffc1cf8c89a7fd6ab94bd8d6162cbf251002a83f62e9470000660d51afc75f169d27081df5f0b4f22b696e03622010ac21d34937b4e1142a2c757af294931921047818bfdc2208d175571f41f314a42310ff8edbceb6dd24799c77c3b9a6790c102410157c39022ca9d885a7f0766a7dfee44825108a43b91898e500002cf354c6f5d1f8c32708f748a7078f5018db
+DREF VLR subscr IMSI:901700000010650 usage increases to: 2
+DVLR VLR_Authenticate(LU:901700000010650){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(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH_WAIT_SAI_RESYNC}: state_chg to VLR_SUB_AS_WAIT_RESP_RESYNC
+DVLR VLR_Authenticate(LU:901700000010650){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: tuple use_count=1 key_seq=0 auth_types=0x3 and...
+- ...rand=0f1feb1623e1bf626334e37ec448ac18
+- ...autn=02a83f62e9470000660d51afc75f169d
+- ...expecting res=1df5f0b4f22b696e
+DREF VLR subscr IMSI:901700000010650 usage decreases to: 1
+<-- 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
+  MSC <--RAN_UTRAN_IU-- MS: GSM48_MT_MM_AUTH_RESP
+DREF IMSI:901700000010650: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14)
+DMM IMSI:901700000010650: MM UMTS AUTHENTICATION RESPONSE (res = 1df5f0b4f22b696e)
+DVLR VLR_Authenticate(LU:901700000010650){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(LU:901700000010650){VLR_SUB_AS_WAIT_RESP_RESYNC}: Authentication terminating with result PASSED
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_WAIT_RESP_RESYNC}: state_chg to VLR_SUB_AS_AUTHENTICATED
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Removing from parent vlr_lu_fsm(LU:901700000010650)
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Freeing instance
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_AUTHENTICATED}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_AUTH}: vlr_loc_upd_post_auth()
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_AUTH}: Set Ciphering Mode
+DMM -> SECURITY MODE CONTROL IMSI:901700000010650
+- sending SecurityModeControl for UE ctx 42 send_ck=0 new_key=1
+- ...ik=8a90c769b7272f3bb7a1c1fbb1ea9349
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_WAIT_CIPH
+DREF IMSI:901700000010650: MSC conn use - dtap == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  security_mode_ctrl_sent == 1
+  lu_result_sent == 0
+- MS sends SecurityModeControl acceptance, VLR accepts and sends GSUP LU Req to HLR
+DMM <- SECURITY MODE COMPLETE IMSI:901700000010650
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_CIPH}: Received Event VLR_ULA_E_CIPH_RES
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_CIPH}: vlr_loc_upd_post_ciph()
+DIUCS IMSI:901700000010650: tx CommonID 901700000010650
+- Iu Common ID --RAN_UTRAN_IU--> MS (IMSI=901700000010650)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_CIPH}: vlr_loc_upd_node_4()
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_CIPH}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_INIT}: Allocated
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000010650)
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START
+DVLR GSUP tx: 04010809710000000156f0280102
+GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000000156f0280102
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){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: 10010809710000000156f00804032443f2
+DVLR GSUP rx 17: 10010809710000000156f00804032443f2
+DREF VLR subscr IMSI:901700000010650 usage increases to: 2
+DVLR IMSI:901700000010650 has MSISDN:42342
+DVLR SUBSCR(MSISDN:42342) VLR: update for IMSI=901700000010650 (MSISDN=42342, used=2)
+DVLR GSUP tx: 12010809710000000156f0
+GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000000156f0
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+<-- 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: 06010809710000000156f0
+DVLR GSUP rx 11: 06010809710000000156f0
+DREF VLR subscr MSISDN:42342 usage increases to: 2
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000010650)
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_DONE}: Freeing instance
+DVLR upd_hlr_vlr_fsm(LU:901700000010650){UPD_HLR_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_INIT}: Allocated
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000010650)
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_INIT}: Allocated
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(LU:901700000010650)
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(LU:901700000010650)
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_DONE}: Freeing instance
+DVLR sub_pres_vlr_fsm(LU:901700000010650){SUB_PRES_VLR_S_DONE}: Deallocated
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_WAIT_SUB_PRES}: lu_compl_vlr_new_tmsi()
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_WAIT_TMSI_CNF
+- sending LU Accept for MSISDN:42342, with TMSI 0x03020100
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+<-- 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(&net->subscr_conns) == 1
+msc_subscr_conn_is_accepted() == false
+  requests shall be thwarted
+DRLL Dispatching 04.08 message GSM48_MT_CC_SETUP (0x3:0x5)
+DRLL subscr MSISDN:42342: Message not permitted for initial conn: GSM48_MT_CC_SETUP
+DRLL Dispatching 04.08 message unknown 0x33 (0x5:0x33)
+DRLL subscr MSISDN:42342: Message not permitted for initial conn: unknown 0x33
+DRLL Dispatching 04.08 message GSM48_MT_RR_SYSINFO_1 (0x6:0x19)
+DRLL subscr MSISDN:42342: Message not permitted for initial conn: GSM48_MT_RR_SYSINFO_1
+DRLL Dispatching 04.08 message SMS:0x01 (0x9:0x1)
+DRLL subscr MSISDN:42342: Message not permitted for initial conn: SMS:0x01
+- even though the TMSI is not acked, we can already find the subscr with it
+DREF VLR subscr MSISDN:42342 usage increases to: 2
+  vsub != NULL == 1
+  strcmp(vsub->imsi, imsi) == 0
+  vsub->tmsi_new == 0x03020100
+  vsub->tmsi == 0xffffffff
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+- MS sends TMSI Realloc Complete
+  MSC <--RAN_UTRAN_IU-- MS: GSM48_MT_MM_TMSI_REALL_COMPL
+DREF MSISDN:42342: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_TMSI_REALL_COMPL (0x5:0x1b)
+DMM TMSI Reallocation Completed. Subscriber: MSISDN:42342
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_NEW_TMSI_ACK
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_WAIT_TMSI_CNF}: Received Event LU_COMPL_VLR_E_NEW_TMSI_ACK
+DREF VLR subscr MSISDN:42342 usage increases to: 2
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_WAIT_TMSI_CNF}: state_chg to LU_COMPL_VLR_S_DONE
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000010650)
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_DONE}: Freeing instance
+DVLR lu_compl_vlr_fsm(LU:901700000010650){LU_COMPL_VLR_S_DONE}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_ACCEPTED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_ACCEPTED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF MSISDN:42342: MSC conn use + release == 2 (0x102: dtap,release)
+DREF VLR subscr MSISDN:42342 usage increases to: 3
+DREF VLR subscr MSISDN:42342 usage decreases to: 2
+- Iu Release --RAN_UTRAN_IU--> MS
+DREF MSISDN:42342: MSC conn use - dtap == 1 (0x100: release)
+  iu_release_sent == 1
+- RNC sends Iu Release Complete
+DREF MSISDN:42342: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(LU:901700000010650)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: Freeing instance
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: Deallocated
+DRLL MSISDN:42342: Freeing subscriber connection
+DREF VLR subscr MSISDN:42342 usage decreases to: 1
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASED}: Deallocated
+- LU was successful, and the conn has already been closed
+  llist_count(&net->subscr_conns) == 0
+DREF freeing VLR subscr MSISDN:42342
+===== test_umts_authen_resync_utran: SUCCESS
+
+full talloc report on 'msgb' (total      0 bytes in   1 blocks)
+talloc_total_blocks(tall_bsc_ctx) == 12
+
+===== test_umts_authen_too_short_res_geran
+- Location Update request causes a GSUP Send Auth Info request to HLR
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8)
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_NEW}: Updated ID
+DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000010650 type=NORMAL
+DMM LU/new-LAC: 0/23
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: Allocated
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: is child of Subscr_Conn(LU:901700000010650)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: rev=R99 net=GERAN Auth (no Ciph)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA
+DREF VLR subscr unknown usage increases to: 1
+DVLR set IMSI on subscriber; IMSI=901700000010650 id=901700000010650
+DVLR New subscr, IMSI: 901700000010650
+DREF VLR subscr IMSI:901700000010650 usage increases to: 2
+DREF VLR subscr IMSI:901700000010650 usage decreases to: 1
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Allocated
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(LU:901700000010650)
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
+DVLR GSUP tx: 08010809710000000156f0
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f0
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF IMSI:901700000010650: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  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: 0a010809710000000156f00362201039fa2f4e3d523d8619a73b4f65c3e14d21049b36efdf2208059a4f668f6fbe39231027497388b6cb044648f396aa155b95ef2410f64735036e5871319c679f4742a75ea125108704f5ba55f30000d2ee44b22c8ea9192708e229c19e791f2e4103622010c187a53a5e6b9d573cac7c74451fd46d210485aa31302208d3d50a000bf04f6e23101159ec926a50e98c034a6b7d7c9f418d2410df3a03d9ca5335641efc8e36d76cd20b25101843a645b98d00005b2d666af46c45d927087db47cf7f81e4dc703622010efa9c29a9742148d5c9070348716e1bb210469d5f9fb22083df176f0c29f1a3d2310eb50e770ddcc3060101d2f43b6c2b884241076542abce5ff9345b0e8947f4c6e019c2510f9375e6d41e1000096e7fe4ff1c27e392708706f996719ba609c03622010f023d5a3b24726e0631b64b3840f82532104d570c03f2208ec011be8919883d62310c4e58af4ba43f3bcd904e16984f086d724100593f65e752e5cb7f473862bda05aa0a2510541ff1f077270000c5ea00d658bc7e9a27083fd26072eaa2a04d036220102f8f90c780d6a9c0c53da7ac57b6707e2104b072446f220823f39f9f425ad6e6231065af0527fda95b0dc5ae4aa515cdf32f2410537c3b35a3b13b08d08eeb28098f45cc25104bf4e564f75300009bc796706bc6574427080edb0eadbea94ac2
+DVLR GSUP rx 511: 0a010809710000000156f00362201039fa2f4e3d523d8619a73b4f65c3e14d21049b36efdf2208059a4f668f6fbe39231027497388b6cb044648f396aa155b95ef2410f64735036e5871319c679f4742a75ea125108704f5ba55f30000d2ee44b22c8ea9192708e229c19e791f2e4103622010c187a53a5e6b9d573cac7c74451fd46d210485aa31302208d3d50a000bf04f6e23101159ec926a50e98c034a6b7d7c9f418d2410df3a03d9ca5335641efc8e36d76cd20b25101843a645b98d00005b2d666af46c45d927087db47cf7f81e4dc703622010efa9c29a9742148d5c9070348716e1bb210469d5f9fb22083df176f0c29f1a3d2310eb50e770ddcc3060101d2f43b6c2b884241076542abce5ff9345b0e8947f4c6e019c2510f9375e6d41e1000096e7fe4ff1c27e392708706f996719ba609c03622010f023d5a3b24726e0631b64b3840f82532104d570c03f2208ec011be8919883d62310c4e58af4ba43f3bcd904e16984f086d724100593f65e752e5cb7f473862bda05aa0a2510541ff1f077270000c5ea00d658bc7e9a27083fd26072eaa2a04d036220102f8f90c780d6a9c0c53da7ac57b6707e2104b072446f220823f39f9f425ad6e6231065af0527fda95b0dc5ae4aa515cdf32f2410537c3b35a3b13b08d08eeb28098f45cc25104bf4e564f75300009bc796706bc6574427080edb0eadbea94ac2
+DREF VLR subscr IMSI:901700000010650 usage increases to: 2
+DVLR VLR_Authenticate(LU:901700000010650){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(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: state_chg to VLR_SUB_AS_WAIT_RESP
+DVLR VLR_Authenticate(LU:901700000010650){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: tuple use_count=1 key_seq=0 auth_types=0x3 and...
+- ...rand=39fa2f4e3d523d8619a73b4f65c3e14d
+- ...autn=8704f5ba55f30000d2ee44b22c8ea919
+- ...expecting res=e229c19e791f2e41
+DREF VLR subscr IMSI:901700000010650 usage decreases to: 1
+<-- 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 of wrong RES size, VLR thwarts
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_AUTH_RESP
+DREF IMSI:901700000010650: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14)
+DMM IMSI:901700000010650: MM UMTS AUTHENTICATION RESPONSE (res = e229c19e791f2e)
+DVLR VLR_Authenticate(LU:901700000010650){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(LU:901700000010650){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result Illegal MS
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTH_FAILED
+DVLR GSUP tx: 0b010809710000000156f0
+GSUP --> HLR: OSMO_GSUP_MSGT_AUTH_FAIL_REPORT: 0b010809710000000156f0
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_AUTH_FAILED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_AUTH_FAILED}: Removing from parent vlr_lu_fsm(LU:901700000010650)
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_AUTH_FAILED}: Freeing instance
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_AUTH_FAILED}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES
+- sending LU Reject for IMSI:901700000010650, cause 3
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_DONE
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_CN_CLOSE
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF IMSI:901700000010650: MSC conn use + release == 2 (0x102: dtap,release)
+DREF VLR subscr IMSI:901700000010650 usage increases to: 2
+DREF VLR subscr IMSI:901700000010650 usage decreases to: 1
+- BSSAP Clear --RAN_GERAN_A--> MS
+DREF IMSI:901700000010650: MSC conn use - dtap == 1 (0x100: release)
+  lu_result_sent == 2
+  bssap_clear_sent == 1
+- BSS sends BSSMAP Clear Complete
+DREF IMSI:901700000010650: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(LU:901700000010650)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: Freeing instance
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: Deallocated
+DRLL IMSI:901700000010650: Freeing subscriber connection
+DREF VLR subscr IMSI:901700000010650 usage decreases to: 0
+DREF freeing VLR subscr IMSI:901700000010650
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 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) == 12
+
+===== test_umts_authen_too_short_res_utran
+- Location Update request causes a GSUP Send Auth Info request to HLR
+  MSC <--RAN_UTRAN_IU-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8)
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_NEW}: Updated ID
+DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000010650 type=NORMAL
+DMM LU/new-LAC: 0/23
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: Allocated
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: is child of Subscr_Conn(LU:901700000010650)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: rev=R99 net=UTRAN Auth+Ciph
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA
+DREF VLR subscr unknown usage increases to: 1
+DVLR set IMSI on subscriber; IMSI=901700000010650 id=901700000010650
+DVLR New subscr, IMSI: 901700000010650
+DREF VLR subscr IMSI:901700000010650 usage increases to: 2
+DREF VLR subscr IMSI:901700000010650 usage decreases to: 1
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Allocated
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(LU:901700000010650)
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
+DVLR GSUP tx: 08010809710000000156f0
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f0
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF IMSI:901700000010650: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  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: 0a010809710000000156f00362201039fa2f4e3d523d8619a73b4f65c3e14d21049b36efdf2208059a4f668f6fbe39231027497388b6cb044648f396aa155b95ef2410f64735036e5871319c679f4742a75ea125108704f5ba55f30000d2ee44b22c8ea9192708e229c19e791f2e4103622010c187a53a5e6b9d573cac7c74451fd46d210485aa31302208d3d50a000bf04f6e23101159ec926a50e98c034a6b7d7c9f418d2410df3a03d9ca5335641efc8e36d76cd20b25101843a645b98d00005b2d666af46c45d927087db47cf7f81e4dc703622010efa9c29a9742148d5c9070348716e1bb210469d5f9fb22083df176f0c29f1a3d2310eb50e770ddcc3060101d2f43b6c2b884241076542abce5ff9345b0e8947f4c6e019c2510f9375e6d41e1000096e7fe4ff1c27e392708706f996719ba609c03622010f023d5a3b24726e0631b64b3840f82532104d570c03f2208ec011be8919883d62310c4e58af4ba43f3bcd904e16984f086d724100593f65e752e5cb7f473862bda05aa0a2510541ff1f077270000c5ea00d658bc7e9a27083fd26072eaa2a04d036220102f8f90c780d6a9c0c53da7ac57b6707e2104b072446f220823f39f9f425ad6e6231065af0527fda95b0dc5ae4aa515cdf32f2410537c3b35a3b13b08d08eeb28098f45cc25104bf4e564f75300009bc796706bc6574427080edb0eadbea94ac2
+DVLR GSUP rx 511: 0a010809710000000156f00362201039fa2f4e3d523d8619a73b4f65c3e14d21049b36efdf2208059a4f668f6fbe39231027497388b6cb044648f396aa155b95ef2410f64735036e5871319c679f4742a75ea125108704f5ba55f30000d2ee44b22c8ea9192708e229c19e791f2e4103622010c187a53a5e6b9d573cac7c74451fd46d210485aa31302208d3d50a000bf04f6e23101159ec926a50e98c034a6b7d7c9f418d2410df3a03d9ca5335641efc8e36d76cd20b25101843a645b98d00005b2d666af46c45d927087db47cf7f81e4dc703622010efa9c29a9742148d5c9070348716e1bb210469d5f9fb22083df176f0c29f1a3d2310eb50e770ddcc3060101d2f43b6c2b884241076542abce5ff9345b0e8947f4c6e019c2510f9375e6d41e1000096e7fe4ff1c27e392708706f996719ba609c03622010f023d5a3b24726e0631b64b3840f82532104d570c03f2208ec011be8919883d62310c4e58af4ba43f3bcd904e16984f086d724100593f65e752e5cb7f473862bda05aa0a2510541ff1f077270000c5ea00d658bc7e9a27083fd26072eaa2a04d036220102f8f90c780d6a9c0c53da7ac57b6707e2104b072446f220823f39f9f425ad6e6231065af0527fda95b0dc5ae4aa515cdf32f2410537c3b35a3b13b08d08eeb28098f45cc25104bf4e564f75300009bc796706bc6574427080edb0eadbea94ac2
+DREF VLR subscr IMSI:901700000010650 usage increases to: 2
+DVLR VLR_Authenticate(LU:901700000010650){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(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: state_chg to VLR_SUB_AS_WAIT_RESP
+DVLR VLR_Authenticate(LU:901700000010650){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: tuple use_count=1 key_seq=0 auth_types=0x3 and...
+- ...rand=39fa2f4e3d523d8619a73b4f65c3e14d
+- ...autn=8704f5ba55f30000d2ee44b22c8ea919
+- ...expecting res=e229c19e791f2e41
+DREF VLR subscr IMSI:901700000010650 usage decreases to: 1
+<-- 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 of wrong RES size, VLR thwarts
+  MSC <--RAN_UTRAN_IU-- MS: GSM48_MT_MM_AUTH_RESP
+DREF IMSI:901700000010650: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14)
+DMM IMSI:901700000010650: MM UMTS AUTHENTICATION RESPONSE (res = e229c19e791f2e)
+DVLR VLR_Authenticate(LU:901700000010650){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(LU:901700000010650){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result Illegal MS
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTH_FAILED
+DVLR GSUP tx: 0b010809710000000156f0
+GSUP --> HLR: OSMO_GSUP_MSGT_AUTH_FAIL_REPORT: 0b010809710000000156f0
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_AUTH_FAILED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_AUTH_FAILED}: Removing from parent vlr_lu_fsm(LU:901700000010650)
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_AUTH_FAILED}: Freeing instance
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_AUTH_FAILED}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES
+- sending LU Reject for IMSI:901700000010650, cause 3
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_DONE
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_CN_CLOSE
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF IMSI:901700000010650: MSC conn use + release == 2 (0x102: dtap,release)
+DREF VLR subscr IMSI:901700000010650 usage increases to: 2
+DREF VLR subscr IMSI:901700000010650 usage decreases to: 1
+- Iu Release --RAN_UTRAN_IU--> MS
+DREF IMSI:901700000010650: MSC conn use - dtap == 1 (0x100: release)
+  lu_result_sent == 2
+  iu_release_sent == 1
+- RNC sends Iu Release Complete
+DREF IMSI:901700000010650: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(LU:901700000010650)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: Freeing instance
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: Deallocated
+DRLL IMSI:901700000010650: Freeing subscriber connection
+DREF VLR subscr IMSI:901700000010650 usage decreases to: 0
+DREF freeing VLR subscr IMSI:901700000010650
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 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) == 12
+
+===== test_umts_authen_too_long_res_geran
+- Location Update request causes a GSUP Send Auth Info request to HLR
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8)
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_NEW}: Updated ID
+DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000010650 type=NORMAL
+DMM LU/new-LAC: 0/23
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: Allocated
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: is child of Subscr_Conn(LU:901700000010650)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: rev=R99 net=GERAN Auth (no Ciph)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA
+DREF VLR subscr unknown usage increases to: 1
+DVLR set IMSI on subscriber; IMSI=901700000010650 id=901700000010650
+DVLR New subscr, IMSI: 901700000010650
+DREF VLR subscr IMSI:901700000010650 usage increases to: 2
+DREF VLR subscr IMSI:901700000010650 usage decreases to: 1
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Allocated
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(LU:901700000010650)
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
+DVLR GSUP tx: 08010809710000000156f0
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f0
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF IMSI:901700000010650: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  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: 0a010809710000000156f00362201039fa2f4e3d523d8619a73b4f65c3e14d21049b36efdf2208059a4f668f6fbe39231027497388b6cb044648f396aa155b95ef2410f64735036e5871319c679f4742a75ea125108704f5ba55f30000d2ee44b22c8ea9192708e229c19e791f2e4103622010c187a53a5e6b9d573cac7c74451fd46d210485aa31302208d3d50a000bf04f6e23101159ec926a50e98c034a6b7d7c9f418d2410df3a03d9ca5335641efc8e36d76cd20b25101843a645b98d00005b2d666af46c45d927087db47cf7f81e4dc703622010efa9c29a9742148d5c9070348716e1bb210469d5f9fb22083df176f0c29f1a3d2310eb50e770ddcc3060101d2f43b6c2b884241076542abce5ff9345b0e8947f4c6e019c2510f9375e6d41e1000096e7fe4ff1c27e392708706f996719ba609c03622010f023d5a3b24726e0631b64b3840f82532104d570c03f2208ec011be8919883d62310c4e58af4ba43f3bcd904e16984f086d724100593f65e752e5cb7f473862bda05aa0a2510541ff1f077270000c5ea00d658bc7e9a27083fd26072eaa2a04d036220102f8f90c780d6a9c0c53da7ac57b6707e2104b072446f220823f39f9f425ad6e6231065af0527fda95b0dc5ae4aa515cdf32f2410537c3b35a3b13b08d08eeb28098f45cc25104bf4e564f75300009bc796706bc6574427080edb0eadbea94ac2
+DVLR GSUP rx 511: 0a010809710000000156f00362201039fa2f4e3d523d8619a73b4f65c3e14d21049b36efdf2208059a4f668f6fbe39231027497388b6cb044648f396aa155b95ef2410f64735036e5871319c679f4742a75ea125108704f5ba55f30000d2ee44b22c8ea9192708e229c19e791f2e4103622010c187a53a5e6b9d573cac7c74451fd46d210485aa31302208d3d50a000bf04f6e23101159ec926a50e98c034a6b7d7c9f418d2410df3a03d9ca5335641efc8e36d76cd20b25101843a645b98d00005b2d666af46c45d927087db47cf7f81e4dc703622010efa9c29a9742148d5c9070348716e1bb210469d5f9fb22083df176f0c29f1a3d2310eb50e770ddcc3060101d2f43b6c2b884241076542abce5ff9345b0e8947f4c6e019c2510f9375e6d41e1000096e7fe4ff1c27e392708706f996719ba609c03622010f023d5a3b24726e0631b64b3840f82532104d570c03f2208ec011be8919883d62310c4e58af4ba43f3bcd904e16984f086d724100593f65e752e5cb7f473862bda05aa0a2510541ff1f077270000c5ea00d658bc7e9a27083fd26072eaa2a04d036220102f8f90c780d6a9c0c53da7ac57b6707e2104b072446f220823f39f9f425ad6e6231065af0527fda95b0dc5ae4aa515cdf32f2410537c3b35a3b13b08d08eeb28098f45cc25104bf4e564f75300009bc796706bc6574427080edb0eadbea94ac2
+DREF VLR subscr IMSI:901700000010650 usage increases to: 2
+DVLR VLR_Authenticate(LU:901700000010650){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(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: state_chg to VLR_SUB_AS_WAIT_RESP
+DVLR VLR_Authenticate(LU:901700000010650){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: tuple use_count=1 key_seq=0 auth_types=0x3 and...
+- ...rand=39fa2f4e3d523d8619a73b4f65c3e14d
+- ...autn=8704f5ba55f30000d2ee44b22c8ea919
+- ...expecting res=e229c19e791f2e41
+DREF VLR subscr IMSI:901700000010650 usage decreases to: 1
+<-- 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 of wrong RES size, VLR thwarts
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_AUTH_RESP
+DREF IMSI:901700000010650: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14)
+DMM IMSI:901700000010650: MM UMTS AUTHENTICATION RESPONSE (res = e229c19e791f2e4123)
+DVLR VLR_Authenticate(LU:901700000010650){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(LU:901700000010650){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result Illegal MS
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTH_FAILED
+DVLR GSUP tx: 0b010809710000000156f0
+GSUP --> HLR: OSMO_GSUP_MSGT_AUTH_FAIL_REPORT: 0b010809710000000156f0
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_AUTH_FAILED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_AUTH_FAILED}: Removing from parent vlr_lu_fsm(LU:901700000010650)
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_AUTH_FAILED}: Freeing instance
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_AUTH_FAILED}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES
+- sending LU Reject for IMSI:901700000010650, cause 3
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_DONE
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_CN_CLOSE
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF IMSI:901700000010650: MSC conn use + release == 2 (0x102: dtap,release)
+DREF VLR subscr IMSI:901700000010650 usage increases to: 2
+DREF VLR subscr IMSI:901700000010650 usage decreases to: 1
+- BSSAP Clear --RAN_GERAN_A--> MS
+DREF IMSI:901700000010650: MSC conn use - dtap == 1 (0x100: release)
+  lu_result_sent == 2
+  bssap_clear_sent == 1
+- BSS sends BSSMAP Clear Complete
+DREF IMSI:901700000010650: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(LU:901700000010650)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: Freeing instance
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: Deallocated
+DRLL IMSI:901700000010650: Freeing subscriber connection
+DREF VLR subscr IMSI:901700000010650 usage decreases to: 0
+DREF freeing VLR subscr IMSI:901700000010650
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 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) == 12
+
+===== test_umts_authen_too_long_res_utran
+- Location Update request causes a GSUP Send Auth Info request to HLR
+  MSC <--RAN_UTRAN_IU-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8)
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_NEW}: Updated ID
+DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000010650 type=NORMAL
+DMM LU/new-LAC: 0/23
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: Allocated
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: is child of Subscr_Conn(LU:901700000010650)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: rev=R99 net=UTRAN Auth+Ciph
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA
+DREF VLR subscr unknown usage increases to: 1
+DVLR set IMSI on subscriber; IMSI=901700000010650 id=901700000010650
+DVLR New subscr, IMSI: 901700000010650
+DREF VLR subscr IMSI:901700000010650 usage increases to: 2
+DREF VLR subscr IMSI:901700000010650 usage decreases to: 1
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Allocated
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(LU:901700000010650)
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
+DVLR GSUP tx: 08010809710000000156f0
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f0
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF IMSI:901700000010650: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  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: 0a010809710000000156f00362201039fa2f4e3d523d8619a73b4f65c3e14d21049b36efdf2208059a4f668f6fbe39231027497388b6cb044648f396aa155b95ef2410f64735036e5871319c679f4742a75ea125108704f5ba55f30000d2ee44b22c8ea9192708e229c19e791f2e4103622010c187a53a5e6b9d573cac7c74451fd46d210485aa31302208d3d50a000bf04f6e23101159ec926a50e98c034a6b7d7c9f418d2410df3a03d9ca5335641efc8e36d76cd20b25101843a645b98d00005b2d666af46c45d927087db47cf7f81e4dc703622010efa9c29a9742148d5c9070348716e1bb210469d5f9fb22083df176f0c29f1a3d2310eb50e770ddcc3060101d2f43b6c2b884241076542abce5ff9345b0e8947f4c6e019c2510f9375e6d41e1000096e7fe4ff1c27e392708706f996719ba609c03622010f023d5a3b24726e0631b64b3840f82532104d570c03f2208ec011be8919883d62310c4e58af4ba43f3bcd904e16984f086d724100593f65e752e5cb7f473862bda05aa0a2510541ff1f077270000c5ea00d658bc7e9a27083fd26072eaa2a04d036220102f8f90c780d6a9c0c53da7ac57b6707e2104b072446f220823f39f9f425ad6e6231065af0527fda95b0dc5ae4aa515cdf32f2410537c3b35a3b13b08d08eeb28098f45cc25104bf4e564f75300009bc796706bc6574427080edb0eadbea94ac2
+DVLR GSUP rx 511: 0a010809710000000156f00362201039fa2f4e3d523d8619a73b4f65c3e14d21049b36efdf2208059a4f668f6fbe39231027497388b6cb044648f396aa155b95ef2410f64735036e5871319c679f4742a75ea125108704f5ba55f30000d2ee44b22c8ea9192708e229c19e791f2e4103622010c187a53a5e6b9d573cac7c74451fd46d210485aa31302208d3d50a000bf04f6e23101159ec926a50e98c034a6b7d7c9f418d2410df3a03d9ca5335641efc8e36d76cd20b25101843a645b98d00005b2d666af46c45d927087db47cf7f81e4dc703622010efa9c29a9742148d5c9070348716e1bb210469d5f9fb22083df176f0c29f1a3d2310eb50e770ddcc3060101d2f43b6c2b884241076542abce5ff9345b0e8947f4c6e019c2510f9375e6d41e1000096e7fe4ff1c27e392708706f996719ba609c03622010f023d5a3b24726e0631b64b3840f82532104d570c03f2208ec011be8919883d62310c4e58af4ba43f3bcd904e16984f086d724100593f65e752e5cb7f473862bda05aa0a2510541ff1f077270000c5ea00d658bc7e9a27083fd26072eaa2a04d036220102f8f90c780d6a9c0c53da7ac57b6707e2104b072446f220823f39f9f425ad6e6231065af0527fda95b0dc5ae4aa515cdf32f2410537c3b35a3b13b08d08eeb28098f45cc25104bf4e564f75300009bc796706bc6574427080edb0eadbea94ac2
+DREF VLR subscr IMSI:901700000010650 usage increases to: 2
+DVLR VLR_Authenticate(LU:901700000010650){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(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: state_chg to VLR_SUB_AS_WAIT_RESP
+DVLR VLR_Authenticate(LU:901700000010650){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: tuple use_count=1 key_seq=0 auth_types=0x3 and...
+- ...rand=39fa2f4e3d523d8619a73b4f65c3e14d
+- ...autn=8704f5ba55f30000d2ee44b22c8ea919
+- ...expecting res=e229c19e791f2e41
+DREF VLR subscr IMSI:901700000010650 usage decreases to: 1
+<-- 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 of wrong RES size, VLR thwarts
+  MSC <--RAN_UTRAN_IU-- MS: GSM48_MT_MM_AUTH_RESP
+DREF IMSI:901700000010650: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14)
+DMM IMSI:901700000010650: MM UMTS AUTHENTICATION RESPONSE (res = e229c19e791f2e4123)
+DVLR VLR_Authenticate(LU:901700000010650){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(LU:901700000010650){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result Illegal MS
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTH_FAILED
+DVLR GSUP tx: 0b010809710000000156f0
+GSUP --> HLR: OSMO_GSUP_MSGT_AUTH_FAIL_REPORT: 0b010809710000000156f0
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_AUTH_FAILED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_AUTH_FAILED}: Removing from parent vlr_lu_fsm(LU:901700000010650)
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_AUTH_FAILED}: Freeing instance
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_AUTH_FAILED}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES
+- sending LU Reject for IMSI:901700000010650, cause 3
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_DONE
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_CN_CLOSE
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF IMSI:901700000010650: MSC conn use + release == 2 (0x102: dtap,release)
+DREF VLR subscr IMSI:901700000010650 usage increases to: 2
+DREF VLR subscr IMSI:901700000010650 usage decreases to: 1
+- Iu Release --RAN_UTRAN_IU--> MS
+DREF IMSI:901700000010650: MSC conn use - dtap == 1 (0x100: release)
+  lu_result_sent == 2
+  iu_release_sent == 1
+- RNC sends Iu Release Complete
+DREF IMSI:901700000010650: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(LU:901700000010650)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: Freeing instance
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: Deallocated
+DRLL IMSI:901700000010650: Freeing subscriber connection
+DREF VLR subscr IMSI:901700000010650 usage decreases to: 0
+DREF freeing VLR subscr IMSI:901700000010650
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 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) == 12
+
+===== test_umts_authen_only_sres_geran
+- Location Update request causes a GSUP Send Auth Info request to HLR
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8)
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_NEW}: Updated ID
+DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000010650 type=NORMAL
+DMM LU/new-LAC: 0/23
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: Allocated
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: is child of Subscr_Conn(LU:901700000010650)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: rev=R99 net=GERAN Auth (no Ciph)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA
+DREF VLR subscr unknown usage increases to: 1
+DVLR set IMSI on subscriber; IMSI=901700000010650 id=901700000010650
+DVLR New subscr, IMSI: 901700000010650
+DREF VLR subscr IMSI:901700000010650 usage increases to: 2
+DREF VLR subscr IMSI:901700000010650 usage decreases to: 1
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Allocated
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(LU:901700000010650)
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
+DVLR GSUP tx: 08010809710000000156f0
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f0
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF IMSI:901700000010650: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  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: 0a010809710000000156f00362201039fa2f4e3d523d8619a73b4f65c3e14d21049b36efdf2208059a4f668f6fbe39231027497388b6cb044648f396aa155b95ef2410f64735036e5871319c679f4742a75ea125108704f5ba55f30000d2ee44b22c8ea9192708e229c19e791f2e4103622010c187a53a5e6b9d573cac7c74451fd46d210485aa31302208d3d50a000bf04f6e23101159ec926a50e98c034a6b7d7c9f418d2410df3a03d9ca5335641efc8e36d76cd20b25101843a645b98d00005b2d666af46c45d927087db47cf7f81e4dc703622010efa9c29a9742148d5c9070348716e1bb210469d5f9fb22083df176f0c29f1a3d2310eb50e770ddcc3060101d2f43b6c2b884241076542abce5ff9345b0e8947f4c6e019c2510f9375e6d41e1000096e7fe4ff1c27e392708706f996719ba609c03622010f023d5a3b24726e0631b64b3840f82532104d570c03f2208ec011be8919883d62310c4e58af4ba43f3bcd904e16984f086d724100593f65e752e5cb7f473862bda05aa0a2510541ff1f077270000c5ea00d658bc7e9a27083fd26072eaa2a04d036220102f8f90c780d6a9c0c53da7ac57b6707e2104b072446f220823f39f9f425ad6e6231065af0527fda95b0dc5ae4aa515cdf32f2410537c3b35a3b13b08d08eeb28098f45cc25104bf4e564f75300009bc796706bc6574427080edb0eadbea94ac2
+DVLR GSUP rx 511: 0a010809710000000156f00362201039fa2f4e3d523d8619a73b4f65c3e14d21049b36efdf2208059a4f668f6fbe39231027497388b6cb044648f396aa155b95ef2410f64735036e5871319c679f4742a75ea125108704f5ba55f30000d2ee44b22c8ea9192708e229c19e791f2e4103622010c187a53a5e6b9d573cac7c74451fd46d210485aa31302208d3d50a000bf04f6e23101159ec926a50e98c034a6b7d7c9f418d2410df3a03d9ca5335641efc8e36d76cd20b25101843a645b98d00005b2d666af46c45d927087db47cf7f81e4dc703622010efa9c29a9742148d5c9070348716e1bb210469d5f9fb22083df176f0c29f1a3d2310eb50e770ddcc3060101d2f43b6c2b884241076542abce5ff9345b0e8947f4c6e019c2510f9375e6d41e1000096e7fe4ff1c27e392708706f996719ba609c03622010f023d5a3b24726e0631b64b3840f82532104d570c03f2208ec011be8919883d62310c4e58af4ba43f3bcd904e16984f086d724100593f65e752e5cb7f473862bda05aa0a2510541ff1f077270000c5ea00d658bc7e9a27083fd26072eaa2a04d036220102f8f90c780d6a9c0c53da7ac57b6707e2104b072446f220823f39f9f425ad6e6231065af0527fda95b0dc5ae4aa515cdf32f2410537c3b35a3b13b08d08eeb28098f45cc25104bf4e564f75300009bc796706bc6574427080edb0eadbea94ac2
+DREF VLR subscr IMSI:901700000010650 usage increases to: 2
+DVLR VLR_Authenticate(LU:901700000010650){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(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: state_chg to VLR_SUB_AS_WAIT_RESP
+DVLR VLR_Authenticate(LU:901700000010650){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: tuple use_count=1 key_seq=0 auth_types=0x3 and...
+- ...rand=39fa2f4e3d523d8619a73b4f65c3e14d
+- ...autn=8704f5ba55f30000d2ee44b22c8ea919
+- ...expecting res=e229c19e791f2e41
+DREF VLR subscr IMSI:901700000010650 usage decreases to: 1
+<-- 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 of wrong RES size, VLR thwarts: GERAN reports an SRES mismatch
+  MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_AUTH_RESP
+DREF IMSI:901700000010650: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14)
+DMM IMSI:901700000010650: MM GSM AUTHENTICATION RESPONSE (sres = e229c19e)
+DVLR VLR_Authenticate(LU:901700000010650){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(LU:901700000010650){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result Illegal MS
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTH_FAILED
+DVLR GSUP tx: 0b010809710000000156f0
+GSUP --> HLR: OSMO_GSUP_MSGT_AUTH_FAIL_REPORT: 0b010809710000000156f0
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_AUTH_FAILED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_AUTH_FAILED}: Removing from parent vlr_lu_fsm(LU:901700000010650)
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_AUTH_FAILED}: Freeing instance
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_AUTH_FAILED}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES
+- sending LU Reject for IMSI:901700000010650, cause 3
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_DONE
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_CN_CLOSE
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF IMSI:901700000010650: MSC conn use + release == 2 (0x102: dtap,release)
+DREF VLR subscr IMSI:901700000010650 usage increases to: 2
+DREF VLR subscr IMSI:901700000010650 usage decreases to: 1
+- BSSAP Clear --RAN_GERAN_A--> MS
+DREF IMSI:901700000010650: MSC conn use - dtap == 1 (0x100: release)
+  lu_result_sent == 2
+  bssap_clear_sent == 1
+- BSS sends BSSMAP Clear Complete
+DREF IMSI:901700000010650: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(LU:901700000010650)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: Freeing instance
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: Deallocated
+DRLL IMSI:901700000010650: Freeing subscriber connection
+DREF VLR subscr IMSI:901700000010650 usage decreases to: 0
+DREF freeing VLR subscr IMSI:901700000010650
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 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) == 12
+
+===== test_umts_authen_only_sres_utran
+- Location Update request causes a GSUP Send Auth Info request to HLR
+  MSC <--RAN_UTRAN_IU-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
+  new conn
+DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
+DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
+DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8)
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_NEW}: Updated ID
+DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000010650 type=NORMAL
+DMM LU/new-LAC: 0/23
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: Allocated
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: is child of Subscr_Conn(LU:901700000010650)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: rev=R99 net=UTRAN Auth+Ciph
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA
+DREF VLR subscr unknown usage increases to: 1
+DVLR set IMSI on subscriber; IMSI=901700000010650 id=901700000010650
+DVLR New subscr, IMSI: 901700000010650
+DREF VLR subscr IMSI:901700000010650 usage increases to: 2
+DREF VLR subscr IMSI:901700000010650 usage decreases to: 1
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_AUTH
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Allocated
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: is child of vlr_lu_fsm(LU:901700000010650)
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: Received Event VLR_AUTH_E_START
+DVLR GSUP tx: 08010809710000000156f0
+GSUP --> HLR: OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST: 08010809710000000156f0
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH}: state_chg to VLR_SUB_AS_NEEDS_AUTH_WAIT_AI
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
+DREF IMSI:901700000010650: MSC conn use - compl_l3 == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
+  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: 0a010809710000000156f00362201039fa2f4e3d523d8619a73b4f65c3e14d21049b36efdf2208059a4f668f6fbe39231027497388b6cb044648f396aa155b95ef2410f64735036e5871319c679f4742a75ea125108704f5ba55f30000d2ee44b22c8ea9192708e229c19e791f2e4103622010c187a53a5e6b9d573cac7c74451fd46d210485aa31302208d3d50a000bf04f6e23101159ec926a50e98c034a6b7d7c9f418d2410df3a03d9ca5335641efc8e36d76cd20b25101843a645b98d00005b2d666af46c45d927087db47cf7f81e4dc703622010efa9c29a9742148d5c9070348716e1bb210469d5f9fb22083df176f0c29f1a3d2310eb50e770ddcc3060101d2f43b6c2b884241076542abce5ff9345b0e8947f4c6e019c2510f9375e6d41e1000096e7fe4ff1c27e392708706f996719ba609c03622010f023d5a3b24726e0631b64b3840f82532104d570c03f2208ec011be8919883d62310c4e58af4ba43f3bcd904e16984f086d724100593f65e752e5cb7f473862bda05aa0a2510541ff1f077270000c5ea00d658bc7e9a27083fd26072eaa2a04d036220102f8f90c780d6a9c0c53da7ac57b6707e2104b072446f220823f39f9f425ad6e6231065af0527fda95b0dc5ae4aa515cdf32f2410537c3b35a3b13b08d08eeb28098f45cc25104bf4e564f75300009bc796706bc6574427080edb0eadbea94ac2
+DVLR GSUP rx 511: 0a010809710000000156f00362201039fa2f4e3d523d8619a73b4f65c3e14d21049b36efdf2208059a4f668f6fbe39231027497388b6cb044648f396aa155b95ef2410f64735036e5871319c679f4742a75ea125108704f5ba55f30000d2ee44b22c8ea9192708e229c19e791f2e4103622010c187a53a5e6b9d573cac7c74451fd46d210485aa31302208d3d50a000bf04f6e23101159ec926a50e98c034a6b7d7c9f418d2410df3a03d9ca5335641efc8e36d76cd20b25101843a645b98d00005b2d666af46c45d927087db47cf7f81e4dc703622010efa9c29a9742148d5c9070348716e1bb210469d5f9fb22083df176f0c29f1a3d2310eb50e770ddcc3060101d2f43b6c2b884241076542abce5ff9345b0e8947f4c6e019c2510f9375e6d41e1000096e7fe4ff1c27e392708706f996719ba609c03622010f023d5a3b24726e0631b64b3840f82532104d570c03f2208ec011be8919883d62310c4e58af4ba43f3bcd904e16984f086d724100593f65e752e5cb7f473862bda05aa0a2510541ff1f077270000c5ea00d658bc7e9a27083fd26072eaa2a04d036220102f8f90c780d6a9c0c53da7ac57b6707e2104b072446f220823f39f9f425ad6e6231065af0527fda95b0dc5ae4aa515cdf32f2410537c3b35a3b13b08d08eeb28098f45cc25104bf4e564f75300009bc796706bc6574427080edb0eadbea94ac2
+DREF VLR subscr IMSI:901700000010650 usage increases to: 2
+DVLR VLR_Authenticate(LU:901700000010650){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(LU:901700000010650){VLR_SUB_AS_NEEDS_AUTH_WAIT_AI}: state_chg to VLR_SUB_AS_WAIT_RESP
+DVLR VLR_Authenticate(LU:901700000010650){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: tuple use_count=1 key_seq=0 auth_types=0x3 and...
+- ...rand=39fa2f4e3d523d8619a73b4f65c3e14d
+- ...autn=8704f5ba55f30000d2ee44b22c8ea919
+- ...expecting res=e229c19e791f2e41
+DREF VLR subscr IMSI:901700000010650 usage decreases to: 1
+<-- 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 of wrong RES size, VLR thwarts: UTRAN disallows GSM AKA altogether
+  MSC <--RAN_UTRAN_IU-- MS: GSM48_MT_MM_AUTH_RESP
+DREF IMSI:901700000010650: MSC conn use + dtap == 1 (0x2: dtap)
+DRLL Dispatching 04.08 message GSM48_MT_MM_AUTH_RESP (0x5:0x14)
+DMM IMSI:901700000010650: MM GSM AUTHENTICATION RESPONSE (sres = e229c19e)
+DVLR VLR_Authenticate(LU:901700000010650){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(LU:901700000010650){VLR_SUB_AS_WAIT_RESP}: Authentication terminating with result Illegal MS
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_WAIT_RESP}: state_chg to VLR_SUB_AS_AUTH_FAILED
+DVLR GSUP tx: 0b010809710000000156f0
+GSUP --> HLR: OSMO_GSUP_MSGT_AUTH_FAIL_REPORT: 0b010809710000000156f0
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_AUTH_FAILED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_AUTH_FAILED}: Removing from parent vlr_lu_fsm(LU:901700000010650)
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_AUTH_FAILED}: Freeing instance
+DVLR VLR_Authenticate(LU:901700000010650){VLR_SUB_AS_AUTH_FAILED}: Deallocated
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_AUTH}: Received Event VLR_ULA_E_AUTH_RES
+- sending LU Reject for IMSI:901700000010650, cause 3
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_WAIT_AUTH}: state_chg to VLR_ULA_S_DONE
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_CN_CLOSE
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_RELEASING
+DREF IMSI:901700000010650: MSC conn use + release == 2 (0x102: dtap,release)
+DREF VLR subscr IMSI:901700000010650 usage increases to: 2
+DREF VLR subscr IMSI:901700000010650 usage decreases to: 1
+- Iu Release --RAN_UTRAN_IU--> MS
+DREF IMSI:901700000010650: MSC conn use - dtap == 1 (0x100: release)
+  lu_result_sent == 2
+  iu_release_sent == 1
+- RNC sends Iu Release Complete
+DREF IMSI:901700000010650: MSC conn use - release == 0 (0x0: )
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(LU:901700000010650)
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: Freeing instance
+DVLR vlr_lu_fsm(LU:901700000010650){VLR_ULA_S_DONE}: Deallocated
+DRLL IMSI:901700000010650: Freeing subscriber connection
+DREF VLR subscr IMSI:901700000010650 usage decreases to: 0
+DREF freeing VLR subscr IMSI:901700000010650
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASED}: Freeing instance
+DMM Subscr_Conn(LU:901700000010650){SUBSCR_CONN_S_RELEASED}: Deallocated
+  llist_count(&net->subscr_conns) == 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) == 12
+
+full talloc report on 'msgb' (total      0 bytes in   1 blocks)
+talloc_total_blocks(tall_bsc_ctx) == 12
+
diff --git a/tests/msc_vlr/msc_vlr_test_umts_authen.ok b/tests/msc_vlr/msc_vlr_test_umts_authen.ok
new file mode 100644
index 0000000..a965a70
--- /dev/null
+++ b/tests/msc_vlr/msc_vlr_test_umts_authen.ok
@@ -0,0 +1 @@
+Done
diff --git a/tests/msc_vlr/msc_vlr_tests.c b/tests/msc_vlr/msc_vlr_tests.c
new file mode 100644
index 0000000..6cf927c
--- /dev/null
+++ b/tests/msc_vlr/msc_vlr_tests.c
@@ -0,0 +1,1055 @@
+/* Osmocom MSC+VLR end-to-end tests */
+
+/* (C) 2017 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>
+ *
+ * All Rights Reserved
+ *
+ * Author: Neels Hofmeyr <nhofmeyr@sysmocom.de>
+ *
+ * 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 <getopt.h>
+#include <stdlib.h>
+
+#include <osmocom/core/logging.h>
+#include <osmocom/core/utils.h>
+#include <osmocom/core/msgb.h>
+#include <osmocom/core/application.h>
+#include <osmocom/gsm/protocol/gsm_04_11.h>
+#include <osmocom/gsm/gsup.h>
+#include <osmocom/gsupclient/gsup_client.h>
+#include <osmocom/msc/gsm_04_11.h>
+#include <osmocom/msc/debug.h>
+#include <osmocom/msc/gsm_04_08.h>
+#include <osmocom/msc/transaction.h>
+#include <osmocom/msc/a_iface_bssap.h>
+
+#if BUILD_IU
+#include <osmocom/msc/iucs_ranap.h>
+#include <osmocom/ranap/iu_client.h>
+#else
+#include <osmocom/msc/iu_dummy.h>
+#endif
+
+#include "msc_vlr_tests.h"
+
+void *msc_vlr_tests_ctx = NULL;
+
+bool _log_lines = false;
+
+struct gsm_network *net = NULL;
+
+const char *gsup_tx_expected = NULL;
+bool gsup_tx_confirmed;
+
+struct msgb *dtap_tx_expected = NULL;
+bool dtap_tx_confirmed;
+
+enum result_sent lu_result_sent;
+enum result_sent cm_service_result_sent;
+bool auth_request_sent;
+const char *auth_request_expect_rand;
+const char *auth_request_expect_autn;
+bool cipher_mode_cmd_sent;
+bool cipher_mode_cmd_sent_with_imeisv;
+const char *cipher_mode_expect_kc;
+bool security_mode_ctrl_sent;
+const char *security_mode_expect_ck;
+const char *security_mode_expect_ik;
+
+bool iu_release_expected = false;
+bool iu_release_sent = false;
+bool bssap_clear_expected = false;
+bool bssap_clear_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;
+
+extern int gsm0407_pdisc_ctr_bin(uint8_t pdisc);
+
+/* static state variables for the L3 send sequence numbers */
+static uint8_t n_sd[4];
+
+/* patch a correct send sequence number into the given message */
+static void patch_l3_seq_nr(struct msgb *msg)
+{
+	struct gsm48_hdr *gh = msgb_l3(msg);
+	uint8_t pdisc = gsm48_hdr_pdisc(gh);
+	uint8_t *msg_type_oct = &msg->l3h[1];
+	int bin = gsm0407_pdisc_ctr_bin(pdisc);
+
+	if (bin >= 0 && bin < ARRAY_SIZE(n_sd)) {
+		/* patch in n_sd into the msg_type octet */
+		*msg_type_oct = (*msg_type_oct & 0x3f) | ((n_sd[bin] & 0x3) << 6);
+		//fprintf(stderr, "pdisc=0x%02x bin=%d, patched n_sd=%u\n\n", pdisc, bin, n_sd[bin] & 3);
+		/* increment N(SD) */
+		n_sd[bin] = (n_sd[bin] + 1) % 4;
+	} else {
+		//fprintf(stderr, "pdisc=0x%02x NO SEQ\n\n", pdisc);
+	}
+}
+
+/* reset L3 sequence numbers (e.g. new RR connection) */
+static void reset_l3_seq_nr()
+{
+	memset(n_sd, 0, sizeof(n_sd));
+}
+
+struct msgb *msgb_from_hex(const char *label, uint16_t size, const char *hex)
+{
+	struct msgb *msg = msgb_alloc_headroom(size, 4, label);
+	unsigned char *rc;
+	msg->l2h = msg->data;
+	rc = msgb_put(msg, osmo_hexparse(hex, msg->data, msgb_tailroom(msg)));
+	OSMO_ASSERT(rc == msg->l2h);
+	return msg;
+}
+
+static const char *gh_type_name(struct gsm48_hdr *gh)
+{
+	return gsm48_pdisc_msgtype_name(gsm48_hdr_pdisc(gh),
+					gsm48_hdr_msg_type(gh));
+}
+
+void dtap_expect_tx(const char *hex)
+{
+	/* Has the previously expected dtap been received? */
+	OSMO_ASSERT(!dtap_tx_expected);
+	if (!hex)
+		return;
+	dtap_tx_expected = msgb_from_hex("dtap_tx_expected", 1024, hex);
+	/* Mask the sequence number out */
+	if (msgb_length(dtap_tx_expected) >= 2)
+		dtap_tx_expected->data[1] &= 0x3f;
+	dtap_tx_confirmed = false;
+}
+
+int vlr_gsupc_read_cb(struct osmo_gsup_client *gsupc, struct msgb *msg);
+
+void gsup_rx(const char *rx_hex, const char *expect_tx_hex)
+{
+	int rc;
+	struct msgb *msg;
+	const char *label;
+
+	gsup_expect_tx(expect_tx_hex);
+
+	msg = msgb_from_hex("gsup", 1024, rx_hex);
+	label = osmo_gsup_message_type_name(msg->l2h[0]);
+	fprintf(stderr, "<-- GSUP rx %s: %s\n", label,
+		osmo_hexdump_nospc(msgb_l2(msg), msgb_l2len(msg)));
+	/* GSUP read cb takes ownership of msgb */
+	rc = vlr_gsupc_read_cb(net->vlr->gsup_client, msg);
+	fprintf(stderr, "<-- GSUP rx %s: vlr_gsupc_read_cb() returns %d\n",
+		label, rc);
+	if (expect_tx_hex)
+		OSMO_ASSERT(gsup_tx_confirmed);
+}
+
+bool conn_exists(const struct gsm_subscriber_connection *conn)
+{
+	struct gsm_subscriber_connection *c;
+
+	if (!conn)
+		return false;
+
+	llist_for_each_entry(c, &net->subscr_conns, entry) {
+		if (c == conn)
+			return true;
+	}
+
+	return false;
+}
+
+/* Simplified version of the cm_service_request_concludes() */
+void conn_conclude_cm_service_req(struct gsm_subscriber_connection *conn,
+				  enum ran_type via_ran)
+{
+	btw("Concluding CM Service Request");
+
+	OSMO_ASSERT(conn);
+	OSMO_ASSERT(conn->received_cm_service_request);
+
+	conn->received_cm_service_request = false;
+	msc_subscr_conn_put(conn, MSC_CONN_USE_CM_SERVICE);
+
+	ASSERT_RELEASE_CLEAR(via_ran);
+}
+
+enum ran_type rx_from_ran = RAN_GERAN_A;
+
+struct gsm_subscriber_connection *conn_new(void)
+{
+	struct gsm_subscriber_connection *conn;
+	conn = msc_subscr_conn_alloc(net, rx_from_ran, 23);
+	if (conn->via_ran == RAN_UTRAN_IU) {
+		struct ranap_ue_conn_ctx *ue_ctx = talloc_zero(conn, struct ranap_ue_conn_ctx);
+		*ue_ctx = (struct ranap_ue_conn_ctx){
+			.conn_id = 42,
+		};
+		conn->iu.ue_ctx = ue_ctx;
+	}
+	return conn;
+}
+
+struct gsm_subscriber_connection *g_conn = NULL;
+
+void rx_from_ms(struct msgb *msg)
+{
+	struct gsm48_hdr *gh = msgb_l3(msg);
+
+	log("MSC <--%s-- MS: %s",
+	    ran_type_name(rx_from_ran),
+	    gh_type_name(gh));
+
+	if (!conn_exists(g_conn))
+		g_conn = NULL;
+
+	if (!g_conn) {
+		log("new conn");
+		g_conn = conn_new();
+		reset_l3_seq_nr();
+		patch_l3_seq_nr(msg);
+		msc_compl_l3(g_conn, msg, 23);
+	} else {
+		patch_l3_seq_nr(msg);
+		if ((gsm48_hdr_pdisc(gh) == GSM48_PDISC_RR)
+		    && (gsm48_hdr_msg_type(gh) == GSM48_MT_RR_CIPH_M_COMPL))
+			msc_cipher_mode_compl(g_conn, msg, 0);
+		else
+			msc_dtap(g_conn, msg);
+	}
+
+	if (!conn_exists(g_conn))
+		g_conn = NULL;
+}
+
+void ms_sends_msg(const char *hex)
+{
+	struct msgb *msg;
+
+	msg = msgb_from_hex("ms_sends_msg", 1024, hex);
+	msg->l1h = msg->l2h = msg->l3h = msg->data;
+	rx_from_ms(msg);
+	msgb_free(msg);
+}
+
+void bss_sends_bssap_mgmt(const char *hex)
+{
+	struct msgb *msg;
+	struct bssmap_header *bh;
+	struct a_conn_info a_conn_info;
+
+	msg = msgb_from_hex("bss_sends_bssap_mgmt", 1024, hex);
+	msg->l3h = msg->data;
+
+	msg->l2h = msgb_push(msg, sizeof(*bh));
+	bh = (void*)msg->l2h;
+	bh->type = BSSAP_MSG_BSS_MANAGEMENT;
+	bh->length = msgb_l3len(msg);
+
+	if (!conn_exists(g_conn))
+		g_conn = NULL;
+
+	OSMO_ASSERT(g_conn);
+	a_conn_info.network = net;
+	a_conn_info.conn_id = g_conn->a.conn_id;
+
+	a_sccp_rx_dt((struct osmo_sccp_user*)0x1, &a_conn_info, msg);
+	msgb_free(msg);
+}
+
+static int ms_sends_msg_fake(uint8_t pdisc, uint8_t msg_type)
+{
+	int rc;
+	struct msgb *msg;
+	struct gsm48_hdr *gh;
+
+	msg = msgb_alloc(1024, "ms_sends_msg_fake");
+	msg->l1h = msg->l2h = msg->l3h = msg->data;
+
+	gh = (struct gsm48_hdr*)msgb_put(msg, sizeof(*gh));
+	gh->proto_discr = pdisc;
+	gh->msg_type = msg_type;
+	/* some amount of data, whatever */
+	msgb_put(msg, 123);
+
+	patch_l3_seq_nr(msg);
+	rc = gsm0408_dispatch(g_conn, msg);
+
+	talloc_free(msg);
+	return rc;
+}
+
+static inline void ms_msg_log_err(uint8_t val, uint8_t msgtype)
+{
+	int rc = ms_sends_msg_fake(val, msgtype);
+	if (rc != -EACCES)
+		log("Unexpected return value %u != %u for %s/%s",
+		    -rc, -EACCES, gsm48_pdisc_name(val), gsm48_cc_msg_name(msgtype));
+}
+
+void thwart_rx_non_initial_requests()
+{
+	log("requests shall be thwarted");
+
+	ms_msg_log_err(GSM48_PDISC_CC, GSM48_MT_CC_SETUP);
+	ms_msg_log_err(GSM48_PDISC_MM, 0x33); /* nonexistent */
+	ms_msg_log_err(GSM48_PDISC_RR, GSM48_MT_RR_SYSINFO_1);
+	ms_msg_log_err(GSM48_PDISC_SMS, GSM411_MT_CP_DATA);
+}
+
+void send_sms(struct vlr_subscr *receiver,
+	      struct vlr_subscr *sender,
+	      char *str)
+{
+	struct gsm_sms *sms = sms_from_text(receiver, sender->msisdn, 0, str);
+	gsm411_send_sms_subscr(receiver, sms);
+}
+
+unsigned char next_rand_byte = 0;
+/* override, requires '-Wl,--wrap=osmo_get_rand_id' */
+int __real_osmo_get_rand_id(uint8_t *buf, size_t num);
+int __wrap_osmo_get_rand_id(uint8_t *buf, size_t num)
+{
+	size_t i;
+	for (i = 0; i < num; i++)
+		buf[i] = next_rand_byte++;
+	return 1;
+}
+
+/* override, requires '-Wl,--wrap=gsm340_gen_scts' */
+void __real_gsm340_gen_scts(uint8_t *scts, time_t time);
+void __wrap_gsm340_gen_scts(uint8_t *scts, time_t time)
+{
+	/* Write fixed time bytes for deterministic test results */
+	osmo_hexparse("07101000000000", scts, 7);
+}
+
+const char *paging_expecting_imsi = NULL;
+uint32_t paging_expecting_tmsi;
+bool paging_sent;
+bool paging_stopped;
+
+void paging_expect_imsi(const char *imsi)
+{
+	paging_expecting_imsi = imsi;
+	paging_expecting_tmsi = GSM_RESERVED_TMSI;
+}
+
+void paging_expect_tmsi(uint32_t tmsi)
+{
+	paging_expecting_tmsi = tmsi;
+	paging_expecting_imsi = NULL;
+}
+
+static int _paging_sent(enum ran_type via_ran, const char *imsi, uint32_t tmsi, uint32_t lac)
+{
+	log("%s sends out paging request to IMSI %s, TMSI 0x%08x, LAC %u",
+	    ran_type_name(via_ran), imsi, tmsi, lac);
+	OSMO_ASSERT(paging_expecting_imsi || (paging_expecting_tmsi != GSM_RESERVED_TMSI));
+	if (paging_expecting_imsi)
+		VERBOSE_ASSERT(strcmp(paging_expecting_imsi, imsi), == 0, "%d");
+	if (paging_expecting_tmsi != GSM_RESERVED_TMSI) {
+		VERBOSE_ASSERT(paging_expecting_tmsi, == tmsi, "0x%08x");
+	}
+	paging_sent = true;
+	paging_stopped = false;
+	return 1;
+}
+
+/* override, requires '-Wl,--wrap=ranap_iu_page_cs' */
+int __real_ranap_iu_page_cs(const char *imsi, const uint32_t *tmsi, uint16_t lac);
+int __wrap_ranap_iu_page_cs(const char *imsi, const uint32_t *tmsi, uint16_t lac)
+{
+	return _paging_sent(RAN_UTRAN_IU, imsi, tmsi ? *tmsi : GSM_RESERVED_TMSI, lac);
+}
+
+/* override, requires '-Wl,--wrap=a_iface_tx_paging' */
+int __real_a_iface_tx_paging(const char *imsi, uint32_t tmsi, uint16_t lac);
+int __wrap_a_iface_tx_paging(const char *imsi, uint32_t tmsi, uint16_t lac)
+{
+	return _paging_sent(RAN_GERAN_A, imsi, tmsi, lac);
+}
+
+/* override, requires '-Wl,--wrap=msc_stop_paging' */
+void __real_msc_stop_paging(struct vlr_subscr *vsub);
+void __wrap_msc_stop_paging(struct vlr_subscr *vsub)
+{
+	paging_stopped = true;
+}
+
+
+/* override, requires '-Wl,--wrap=osmo_sccp_tx_data_msg' */
+int __real_osmo_sccp_tx_data_msg(struct osmo_sccp_user *scu, uint32_t conn_id,
+				 struct msgb *msg);
+int __wrap_osmo_sccp_tx_data_msg(struct osmo_sccp_user *scu, uint32_t conn_id,
+				 struct msgb *msg)
+{
+	const char *proto_str;
+	const char *msg_str = gsm0808_bssmap_name(msg->l3h[2]);
+	switch (*msg->l3h) {
+	case BSSAP_MSG_BSS_MANAGEMENT:
+		proto_str = "BSSAP-BSS-MANAGEMENT";
+		break;
+	case BSSAP_MSG_DTAP:
+		proto_str = "BSSAP-DTAP";
+		break;
+	default:
+		proto_str = "";
+		msg_str = "";
+		break;
+	}
+
+	log("BSC <--%s-- MSC: %s %s", proto_str, msg_str, msgb_hexdump(msg));
+	msgb_free(msg);
+	return 0;
+}
+
+void clear_vlr()
+{
+	struct vlr_subscr *vsub, *n;
+	llist_for_each_entry_safe(vsub, n, &net->vlr->subscribers, list) {
+		vlr_subscr_free(vsub);
+	}
+
+	net->authentication_required = false;
+	net->a5_encryption_mask = (1 << 0);
+	net->vlr->cfg.check_imei_rqd = false;
+	net->vlr->cfg.assign_tmsi = false;
+	net->vlr->cfg.retrieve_imeisv_early = false;
+	net->vlr->cfg.retrieve_imeisv_ciphered = false;
+	net->vlr->cfg.auth_tuple_max_reuse_count = 0;
+	net->vlr->cfg.auth_reuse_old_sets_on_error = false;
+
+	rx_from_ran = RAN_GERAN_A;
+	auth_request_sent = false;
+	auth_request_expect_rand = NULL;
+	auth_request_expect_autn = NULL;
+
+	cipher_mode_cmd_sent = false;
+	cipher_mode_cmd_sent_with_imeisv = false;
+	cipher_mode_expect_kc = NULL;
+
+	security_mode_ctrl_sent = false;
+	security_mode_expect_ck = NULL;
+	security_mode_expect_ik = NULL;
+
+	next_rand_byte = 0;
+
+	iu_release_expected = false;
+	iu_release_sent = false;
+	bssap_clear_expected = false;
+	bssap_clear_sent = false;
+
+	osmo_gettimeofday_override = false;
+}
+
+static struct log_info_cat test_categories[] = {
+	[DMSC] = {
+		.name = "DMSC",
+		.description = "Mobile Switching Center",
+		.enabled = 1, .loglevel = LOGL_DEBUG,
+	},
+	[DRLL] = {
+		.name = "DRLL",
+		.description = "A-bis Radio Link Layer (RLL)",
+		.enabled = 1, .loglevel = LOGL_DEBUG,
+	},
+	[DMM] = {
+		.name = "DMM",
+		.description = "Layer3 Mobility Management (MM)",
+		.enabled = 1, .loglevel = LOGL_DEBUG,
+	},
+	[DRR] = {
+		.name = "DRR",
+		.description = "Layer3 Radio Resource (RR)",
+		.enabled = 1, .loglevel = LOGL_DEBUG,
+	},
+	[DCC] = {
+		.name = "DCC",
+		.description = "Layer3 Call Control (CC)",
+		.enabled = 1, .loglevel = LOGL_DEBUG,
+	},
+	[DVLR] = {
+		.name = "DVLR",
+		.description = "Visitor Location Register",
+		.enabled = 1, .loglevel = LOGL_DEBUG,
+	},
+	[DREF] = {
+		.name = "DREF",
+		.description = "Reference Counting",
+		.enabled = 1, .loglevel = LOGL_DEBUG,
+	},
+	[DPAG]	= {
+		.name = "DPAG",
+		.description = "Paging Subsystem",
+		.enabled = 1, .loglevel = LOGL_DEBUG,
+	},
+	[DIUCS] = {
+		.name = "DIUCS",
+		.description = "Iu-CS Protocol",
+		.enabled = 1, .loglevel = LOGL_DEBUG,
+	},
+	[DMNCC] = {
+		.name = "DMNCC",
+		.description = "MNCC API for Call Control application",
+		.enabled = 1, .loglevel = LOGL_DEBUG,
+	},
+};
+
+static struct log_info info = {
+	.cat = test_categories,
+	.num_cat = ARRAY_SIZE(test_categories),
+};
+
+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));
+
+	OSMO_ASSERT(cc_to_mncc_tx_expected_msg_type);
+	if (cc_to_mncc_tx_expected_msg_type != mncc->msg_type) {
+		log("Mismatch! Expected MNCC msg type: %s",
+		    get_mncc_name(cc_to_mncc_tx_expected_msg_type));
+		abort();
+	}
+
+	if (strcmp(cc_to_mncc_tx_expected_imsi, mncc->imsi)) {
+		log("Mismatch! Expected MNCC msg IMSI: '%s', got '%s'",
+		    cc_to_mncc_tx_expected_imsi,
+		    mncc->imsi);
+		abort();
+	}
+
+	cc_to_mncc_tx_confirmed = true;
+	cc_to_mncc_tx_got_callref = mncc->callref;
+	cc_to_mncc_tx_expected_imsi = NULL;
+	cc_to_mncc_tx_expected_msg_type = 0;
+	talloc_free(msg);
+	return 0;
+}
+
+/* override, requires '-Wl,--wrap=gsup_client_create' */
+struct osmo_gsup_client *
+__real_osmo_gsup_client_create(const char *ip_addr, unsigned int tcp_port,
+			  osmo_gsup_client_read_cb_t read_cb,
+			  struct osmo_oap_client_config *oap_config);
+struct osmo_gsup_client *
+__wrap_osmo_gsup_client_create(const char *ip_addr, unsigned int tcp_port,
+			  osmo_gsup_client_read_cb_t read_cb,
+			  struct osmo_oap_client_config *oap_config)
+{
+	struct osmo_gsup_client *gsupc;
+	gsupc = talloc_zero(msc_vlr_tests_ctx, struct osmo_gsup_client);
+	OSMO_ASSERT(gsupc);
+	return gsupc;
+}
+
+/* override, requires '-Wl,--wrap=gsup_client_send' */
+int __real_osmo_gsup_client_send(struct osmo_gsup_client *gsupc, struct msgb *msg);
+int __wrap_osmo_gsup_client_send(struct osmo_gsup_client *gsupc, struct msgb *msg)
+{
+	const char *is = osmo_hexdump_nospc(msg->data, msg->len);
+	fprintf(stderr, "GSUP --> HLR: %s: %s\n",
+		osmo_gsup_message_type_name(msg->data[0]), is);
+
+	OSMO_ASSERT(gsup_tx_expected);
+	if (strcmp(gsup_tx_expected, is)) {
+		fprintf(stderr, "Mismatch! Expected:\n%s\n", gsup_tx_expected);
+		abort();
+	}
+
+	talloc_free(msg);
+	gsup_tx_confirmed = true;
+	gsup_tx_expected = NULL;
+	return 0;
+}
+
+static int _validate_dtap(struct msgb *msg, enum ran_type to_ran)
+{
+	btw("DTAP --%s--> MS: %s: %s",
+	    ran_type_name(to_ran), gh_type_name((void*)msg->data),
+	    osmo_hexdump_nospc(msg->data, msg->len));
+
+	OSMO_ASSERT(dtap_tx_expected);
+
+	/* Mask the sequence number out before comparing */
+	msg->data[1] &= 0x3f;
+	if (msg->len != dtap_tx_expected->len
+	    || memcmp(msg->data, dtap_tx_expected->data, msg->len)) {
+		fprintf(stderr, "Mismatch! Expected:\n%s\n",
+		       osmo_hexdump_nospc(dtap_tx_expected->data,
+					  dtap_tx_expected->len));
+		abort();
+	}
+
+	btw("DTAP matches expected message");
+
+	talloc_free(msg);
+	dtap_tx_confirmed = true;
+	talloc_free(dtap_tx_expected);
+	dtap_tx_expected = NULL;
+	return 0;
+}
+
+/* override, requires '-Wl,--wrap=ranap_iu_tx' */
+int __real_ranap_iu_tx(struct msgb *msg, uint8_t sapi);
+int __wrap_ranap_iu_tx(struct msgb *msg, uint8_t sapi)
+{
+	return _validate_dtap(msg, RAN_UTRAN_IU);
+}
+
+/* override, requires '-Wl,--wrap=ranap_iu_tx_release' */
+int __real_ranap_iu_tx_release(struct ranap_ue_conn_ctx *ctx, const struct RANAP_Cause *cause);
+int __wrap_ranap_iu_tx_release(struct ranap_ue_conn_ctx *ctx, const struct RANAP_Cause *cause)
+{
+	btw("Iu Release --%s--> MS", ran_type_name(RAN_UTRAN_IU));
+	OSMO_ASSERT(iu_release_expected);
+	iu_release_expected = false;
+	iu_release_sent = true;
+	return 0;
+}
+
+/* override, requires '-Wl,--wrap=iu_tx_common_id' */
+int __real_ranap_iu_tx_common_id(struct ranap_ue_conn_ctx *ue_ctx, const char *imsi);
+int __wrap_ranap_iu_tx_common_id(struct ranap_ue_conn_ctx *ue_ctx, const char *imsi)
+{
+	btw("Iu Common ID --%s--> MS (IMSI=%s)", ran_type_name(RAN_UTRAN_IU), imsi);
+	return 0;
+}
+
+/* override, requires '-Wl,--wrap=a_iface_tx_dtap' */
+int __real_a_iface_tx_dtap(struct msgb *msg);
+int __wrap_a_iface_tx_dtap(struct msgb *msg)
+{
+	return _validate_dtap(msg, RAN_GERAN_A);
+}
+
+/* override, requires '-Wl,--wrap=a_iface_tx_clear_cmd' */
+int __real_a_iface_tx_clear_cmd(struct gsm_subscriber_connection *conn);
+int __wrap_a_iface_tx_clear_cmd(struct gsm_subscriber_connection *conn)
+{
+	btw("BSSAP Clear --%s--> MS", ran_type_name(RAN_GERAN_A));
+	OSMO_ASSERT(bssap_clear_expected);
+	bssap_clear_expected = false;
+	bssap_clear_sent = true;
+	return 0;
+}
+
+/* override, requires '-Wl,--wrap=msc_mgcp_call_assignment' */
+int __real_msc_mgcp_call_assignment(struct gsm_trans *trans);
+int __wrap_msc_mgcp_call_assignment(struct gsm_trans *trans)
+{
+	log("MS <--Call Assignment-- MSC: subscr=%s callref=0x%x",
+	    vlr_subscr_name(trans->vsub), trans->callref);
+	return 0;
+}
+
+struct gsm_mncc *on_call_release_mncc_sends_to_cc_data = NULL;
+
+/* override, requires '-Wl,--wrap=msc_mgcp_call_release' */
+void __real_msc_mgcp_call_release(struct gsm_trans *trans);
+void __wrap_msc_mgcp_call_release(struct gsm_trans *trans)
+{
+	log("MS <--Call Release-- MSC: subscr=%s callref=0x%x",
+	    vlr_subscr_name(trans->vsub), trans->callref);
+	if (on_call_release_mncc_sends_to_cc_data) {
+		mncc_tx_to_cc(trans->net, on_call_release_mncc_sends_to_cc_data->msg_type,
+			      on_call_release_mncc_sends_to_cc_data);
+		on_call_release_mncc_sends_to_cc_data = NULL;
+	}
+}
+
+static int fake_vlr_tx_lu_acc(void *msc_conn_ref, uint32_t send_tmsi)
+{
+	struct gsm_subscriber_connection *conn = msc_conn_ref;
+	if (send_tmsi == GSM_RESERVED_TMSI)
+		btw("sending LU Accept for %s", vlr_subscr_name(conn->vsub));
+	else
+		btw("sending LU Accept for %s, with TMSI 0x%08x",
+		    vlr_subscr_name(conn->vsub), send_tmsi);
+	lu_result_sent |= RES_ACCEPT;
+	return 0;
+}
+
+static int fake_vlr_tx_lu_rej(void *msc_conn_ref, enum gsm48_reject_value cause)
+{
+	struct gsm_subscriber_connection *conn = msc_conn_ref;
+	btw("sending LU Reject for %s, cause %u", vlr_subscr_name(conn->vsub), cause);
+	lu_result_sent |= RES_REJECT;
+	return 0;
+}
+
+static int fake_vlr_tx_cm_serv_acc(void *msc_conn_ref)
+{
+	struct gsm_subscriber_connection *conn = msc_conn_ref;
+	btw("sending CM Service Accept for %s", vlr_subscr_name(conn->vsub));
+	cm_service_result_sent |= RES_ACCEPT;
+	return 0;
+}
+
+static int fake_vlr_tx_cm_serv_rej(void *msc_conn_ref, enum gsm48_reject_value cause)
+{
+	struct gsm_subscriber_connection *conn = msc_conn_ref;
+	btw("sending CM Service Reject for %s, cause: %s",
+	    vlr_subscr_name(conn->vsub), gsm48_reject_value_name(cause));
+	cm_service_result_sent |= RES_REJECT;
+	return 0;
+}
+
+static int fake_vlr_tx_auth_req(void *msc_conn_ref, struct gsm_auth_tuple *at,
+				bool send_autn)
+{
+	struct gsm_subscriber_connection *conn = msc_conn_ref;
+	char *hex;
+	bool ok = true;
+	btw("sending %s Auth Request for %s: tuple use_count=%d key_seq=%d auth_types=0x%x and...",
+	    send_autn? "UMTS" : "GSM", vlr_subscr_name(conn->vsub),
+	    at->use_count, at->key_seq, at->vec.auth_types);
+
+	hex = osmo_hexdump_nospc((void*)&at->vec.rand, sizeof(at->vec.rand));
+	btw("...rand=%s", hex);
+	if (!auth_request_expect_rand
+	    || strcmp(hex, auth_request_expect_rand) != 0) {
+		ok = false;
+		log("FAILURE: expected rand=%s",
+		    auth_request_expect_rand ? auth_request_expect_rand : "-");
+	}
+
+	if (send_autn) {
+		hex = osmo_hexdump_nospc((void*)&at->vec.autn, sizeof(at->vec.autn));
+		btw("...autn=%s", hex);
+		if (!auth_request_expect_autn
+		    || strcmp(hex, auth_request_expect_autn) != 0) {
+			ok = false;
+			log("FAILURE: expected autn=%s",
+			    auth_request_expect_autn ? auth_request_expect_autn : "-");
+		}
+	} else if (auth_request_expect_autn) {
+		ok = false;
+		log("FAILURE: no AUTN sent, expected AUTN = %s",
+		    auth_request_expect_autn);
+	}
+
+	if (send_autn)
+		btw("...expecting res=%s",
+		    osmo_hexdump_nospc((void*)&at->vec.res, at->vec.res_len));
+	else
+		btw("...expecting sres=%s",
+		    osmo_hexdump_nospc((void*)&at->vec.sres, sizeof(at->vec.sres)));
+
+	auth_request_sent = ok;
+	return 0;
+}
+
+static int fake_vlr_tx_auth_rej(void *msc_conn_ref)
+{
+	struct gsm_subscriber_connection *conn = msc_conn_ref;
+	btw("sending Auth Reject for %s", vlr_subscr_name(conn->vsub));
+	return 0;
+}
+
+/* override, requires '-Wl,--wrap=a_iface_tx_cipher_mode' */
+int __real_a_iface_tx_cipher_mode(const struct gsm_subscriber_connection *conn,
+				  struct gsm0808_encrypt_info *ei, int include_imeisv);
+int __wrap_a_iface_tx_cipher_mode(const struct gsm_subscriber_connection *conn,
+				  struct gsm0808_encrypt_info *ei, int include_imeisv)
+{
+	int i;
+	btw("sending Ciphering Mode Command for %s: include_imeisv=%d",
+	    vlr_subscr_name(conn->vsub), include_imeisv);
+	for (i = 0; i < ei->perm_algo_len; i++)
+		btw("...perm algo: A5/%u", ei->perm_algo[i] - 1);
+	OSMO_ASSERT(ei->key_len <= sizeof(ei->key));
+	btw("...key: %s", osmo_hexdump_nospc(ei->key, ei->key_len));
+	cipher_mode_cmd_sent = true;
+	cipher_mode_cmd_sent_with_imeisv = include_imeisv;
+
+	if (!cipher_mode_expect_kc
+	    || strcmp(cipher_mode_expect_kc, osmo_hexdump_nospc(ei->key, ei->key_len))) {
+		log("FAILURE: expected kc=%s", cipher_mode_expect_kc ? : "NULL");
+		OSMO_ASSERT(false);
+	}
+	return 0;
+}
+
+/* override, requires '-Wl,--wrap=ranap_iu_tx_sec_mode_cmd' */
+int __real_ranap_iu_tx_sec_mode_cmd(struct ranap_ue_conn_ctx *uectx, struct osmo_auth_vector *vec,
+				    int send_ck, int new_key);
+int __wrap_ranap_iu_tx_sec_mode_cmd(struct ranap_ue_conn_ctx *uectx, struct osmo_auth_vector *vec,
+				    int send_ck, int new_key)
+{
+	btw("sending SecurityModeControl for UE ctx %u send_ck=%d new_key=%d",
+	    uectx->conn_id, send_ck, new_key);
+	btw("...ik=%s", osmo_hexdump_nospc(vec->ik, sizeof(vec->ik)));
+	if (send_ck)
+		btw("...ck=%s", osmo_hexdump_nospc(vec->ck, sizeof(vec->ck)));
+	security_mode_ctrl_sent = true;
+	if (!security_mode_expect_ik
+	    || strcmp(security_mode_expect_ik, osmo_hexdump_nospc(vec->ik, sizeof(vec->ik)))) {
+		log("FAILURE: expected ik=%s", security_mode_expect_ik ? : "NULL");
+		OSMO_ASSERT(false);
+	}
+	if (((!!send_ck) != (!!security_mode_expect_ck))
+	    || (security_mode_expect_ck
+		&& strcmp(security_mode_expect_ck, osmo_hexdump_nospc(vec->ck, sizeof(vec->ck))))) {
+		log("FAILURE: expected ck=%s", security_mode_expect_ck ? : "NULL");
+		OSMO_ASSERT(false);
+	}
+	return 0;
+}
+
+extern int msc_vlr_set_ciph_mode(void *msc_conn_ref, bool umts_aka, bool retrieve_imeisv);
+
+static int fake_vlr_tx_ciph_mode_cmd(void *msc_conn_ref, bool umts_aka, bool retrieve_imeisv)
+{
+	int rc;
+#ifndef BUILD_IU
+	/* If we built without support for IU, fake the IU part here. The root cause is that we don't
+	 * have differing sets of expected outputs for --enable-iu and --disable-iu. */
+	struct gsm_subscriber_connection *conn = msc_conn_ref;
+	if (conn->via_ran == RAN_UTRAN_IU) {
+		DEBUGP(DMM, "-> SECURITY MODE CONTROL %s\n", vlr_subscr_name(conn->vsub));
+		rc = __wrap_ranap_iu_tx_sec_mode_cmd(conn->iu.ue_ctx, &conn->vsub->last_tuple->vec,
+						     0, 1);
+	} else
+#endif
+	rc = msc_vlr_set_ciph_mode(msc_conn_ref, umts_aka, retrieve_imeisv);
+	if (rc)
+		btw("ERROR sending ciphering mode command: rc=%d", rc);
+	return rc;
+}
+
+void ms_sends_security_mode_complete()
+{
+	OSMO_ASSERT(g_conn);
+	OSMO_ASSERT(g_conn->via_ran == RAN_UTRAN_IU);
+	OSMO_ASSERT(g_conn->iu.ue_ctx);
+	msc_rx_sec_mode_compl(g_conn);
+}
+
+void bss_sends_clear_complete()
+{
+	btw("BSS sends BSSMAP Clear Complete");
+	OSMO_ASSERT(g_conn);
+	OSMO_ASSERT(g_conn->via_ran == RAN_GERAN_A);
+	msc_subscr_conn_rx_bssmap_clear_complete(g_conn);
+}
+
+void rnc_sends_release_complete()
+{
+	btw("RNC sends Iu Release Complete");
+	OSMO_ASSERT(g_conn);
+	OSMO_ASSERT(g_conn->via_ran == RAN_UTRAN_IU);
+	msc_subscr_conn_rx_iu_release_complete(g_conn);
+}
+
+const struct timeval fake_time_start_time = { 123, 456 };
+
+void fake_time_start()
+{
+	struct timespec *clock_override;
+
+	osmo_gettimeofday_override_time = fake_time_start_time;
+	osmo_gettimeofday_override = true;
+	clock_override = osmo_clock_override_gettimespec(CLOCK_MONOTONIC);
+	OSMO_ASSERT(clock_override);
+	clock_override->tv_sec = fake_time_start_time.tv_sec;
+	clock_override->tv_nsec = fake_time_start_time.tv_usec * 1000;
+	osmo_clock_override_enable(CLOCK_MONOTONIC, true);
+	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:
+	 * talloc_total_blocks(tall_bsc_ctx) == 12
+	 * full talloc report on 'msc_vlr_tests_ctx' (total   3636 bytes in  12 blocks)
+	 *     struct osmo_gsup_client        contains    248 bytes in   1 blocks (ref 0) 0x563a489c05f0
+	 *     struct gsm_network             contains   2031 bytes in   4 blocks (ref 0) 0x563a489bfbb0
+	 *         struct vlr_instance            contains    168 bytes in   1 blocks (ref 0) 0x563a489c04e0
+	 *         no_gsup_server                 contains     15 bytes in   1 blocks (ref 0) 0x563a489c0460
+	 *         ../../../src/libosmocore/src/rate_ctr.c:228 contains   1552 bytes in   1 blocks (ref 0) 0x563a489bfd40
+	 *     logging                        contains   1357 bytes in   5 blocks (ref 0) 0x563a489bf440
+	 *         struct log_target              contains    228 bytes in   2 blocks (ref 0) 0x563a489bf9f0
+	 *             struct log_category            contains     68 bytes in   1 blocks (ref 0) 0x563a489bfb00
+	 *         struct log_info                contains   1128 bytes in   2 blocks (ref 0) 0x563a489bf4b0
+	 *             struct log_info_cat            contains   1088 bytes in   1 blocks (ref 0) 0x563a489bf540
+	 *     msgb                           contains      0 bytes in   1 blocks (ref 0) 0x563a489bf3d0
+	 * (That's 12 counting the root ctx)
+	 */
+	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) != 12)
+		talloc_report_full(msc_vlr_tests_ctx, stderr);
+	fprintf(stderr, "\n");
+}
+
+static struct {
+	bool verbose;
+	int run_test_nr;
+} cmdline_opts = {
+	.verbose = false,
+	.run_test_nr = -1,
+};
+
+static void print_help(const char *program)
+{
+	printf("Usage:\n"
+	       "  %s [-v] [N [N...]]\n"
+	       "Options:\n"
+	       "  -h --help      show this text.\n"
+	       "  -v --verbose   print source file and line numbers\n"
+	       "  N              run only the Nth test (first test is N=1)\n",
+	       program
+	       );
+}
+
+static void handle_options(int argc, char **argv)
+{
+	while (1) {
+		int option_index = 0, c;
+		static struct option long_options[] = {
+			{"help", 0, 0, 'h'},
+			{"verbose", 1, 0, 'v'},
+			{0, 0, 0, 0}
+		};
+
+		c = getopt_long(argc, argv, "hv",
+				long_options, &option_index);
+		if (c == -1)
+			break;
+
+		switch (c) {
+		case 'h':
+			print_help(argv[0]);
+			exit(0);
+		case 'v':
+			cmdline_opts.verbose = true;
+			break;
+		default:
+			/* catch unknown options *as well as* missing arguments. */
+			fprintf(stderr, "Error in command line options. Exiting.\n");
+			exit(-1);
+			break;
+		}
+	}
+}
+
+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++) {
+		if (nr >= 0 && test_nr != nr)
+			continue;
+
+		if (cmdline_opts.verbose)
+			fprintf(stderr, "(test nr %d)\n", test_nr + 1);
+
+		msc_vlr_tests[test_nr]();
+
+		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);
+
+	net->gsup_server_addr_str = talloc_strdup(net, "no_gsup_server");
+	net->gsup_server_port = 0;
+
+	OSMO_ASSERT(msc_vlr_alloc(net) == 0);
+	OSMO_ASSERT(msc_vlr_start(net) == 0);
+	OSMO_ASSERT(net->vlr);
+	OSMO_ASSERT(net->vlr->gsup_client);
+
+	net->vlr->ops.tx_lu_acc = fake_vlr_tx_lu_acc;
+	net->vlr->ops.tx_lu_rej = fake_vlr_tx_lu_rej;
+	net->vlr->ops.tx_cm_serv_acc = fake_vlr_tx_cm_serv_acc;
+	net->vlr->ops.tx_cm_serv_rej = fake_vlr_tx_cm_serv_rej;
+	net->vlr->ops.tx_auth_req = fake_vlr_tx_auth_req;
+	net->vlr->ops.tx_auth_rej = fake_vlr_tx_auth_rej;
+	net->vlr->ops.set_ciph_mode = fake_vlr_tx_ciph_mode_cmd;
+
+	return net;
+}
+
+int main(int argc, char **argv)
+{
+	handle_options(argc, argv);
+
+	msc_vlr_tests_ctx = talloc_named_const(NULL, 0, "msc_vlr_tests_ctx");
+	msgb_ctx = msgb_talloc_ctx_init(msc_vlr_tests_ctx, 0);
+	osmo_init_logging2(msc_vlr_tests_ctx, &info);
+
+	_log_lines = cmdline_opts.verbose;
+
+	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, _log_lines? 1 : 0);
+	log_set_print_category(osmo_stderr_target, 1);
+
+	if (cmdline_opts.verbose)
+		log_set_category_filter(osmo_stderr_target, DLSMS, 1, LOGL_DEBUG);
+
+	net = test_net(msc_vlr_tests_ctx);
+
+	osmo_fsm_log_addr(false);
+
+	msc_subscr_conn_init();
+
+	clear_vlr();
+
+	if (optind >= argc)
+		run_tests(-1);
+	else {
+		int arg;
+		long int nr;
+		for (arg = optind; arg < argc; arg++) {
+			errno = 0;
+			nr = strtol(argv[arg], NULL, 10);
+			if (errno) {
+				fprintf(stderr, "Invalid argument: %s\n",
+					argv[arg]);
+				exit(1);
+			}
+
+			run_tests(nr);
+		}
+	}
+
+	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
new file mode 100644
index 0000000..40377c1
--- /dev/null
+++ b/tests/msc_vlr/msc_vlr_tests.h
@@ -0,0 +1,260 @@
+/* Osmocom MSC+VLR end-to-end tests */
+
+/* (C) 2017 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>
+ *
+ * All Rights Reserved
+ *
+ * Author: Neels Hofmeyr <nhofmeyr@sysmocom.de>
+ *
+ * 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 <stdbool.h>
+#include <stdio.h>
+
+#include <osmocom/msc/gsm_data.h>
+#include <osmocom/msc/osmo_msc.h>
+#include <osmocom/msc/vlr.h>
+#include <osmocom/msc/mncc.h>
+
+extern bool _log_lines;
+#define _log(fmt, args...) do { \
+		if (_log_lines) \
+			fprintf(stderr, " %4d:%s: " fmt "\n", \
+				__LINE__, __FILE__, ## args ); \
+		else \
+			fprintf(stderr, fmt "\n", ## args ); \
+	} while (false)
+
+/* btw means "by the way", the test tells the log what's happening.
+ * BTW() marks a larger section, btw() is the usual logging. */
+#define BTW(fmt, args...) _log("---\n- " fmt, ## args )
+#define btw(fmt, args...) _log("- " fmt, ## args )
+#define log(fmt, args...) _log("  " fmt, ## args )
+
+#define comment_start() fprintf(stderr, "===== %s\n", __func__);
+#define comment_end() fprintf(stderr, "===== %s: SUCCESS\n\n", __func__);
+
+extern struct gsm_subscriber_connection *g_conn;
+extern struct gsm_network *net;
+extern struct gsm_bts *the_bts;
+extern void *msgb_ctx;
+
+extern enum ran_type rx_from_ran;
+
+extern const char *gsup_tx_expected;
+extern bool gsup_tx_confirmed;
+
+extern struct msgb *dtap_tx_expected;
+extern bool dtap_tx_confirmed;
+
+enum result_sent {
+	RES_NONE = 0,
+	RES_ACCEPT = 1,
+	RES_REJECT = 2,
+};
+extern enum result_sent lu_result_sent;
+extern enum result_sent cm_service_result_sent;
+
+extern bool auth_request_sent;
+extern const char *auth_request_expect_rand;
+extern const char *auth_request_expect_autn;
+
+extern bool cipher_mode_cmd_sent;
+extern bool cipher_mode_cmd_sent_with_imeisv;
+extern const char *cipher_mode_expect_kc;
+
+extern bool security_mode_ctrl_sent;
+extern const char *security_mode_expect_ck;
+extern const char *security_mode_expect_ik;
+
+static inline void expect_cipher_mode_cmd(const char *kc)
+{
+	cipher_mode_cmd_sent = false;
+	cipher_mode_expect_kc = kc;
+	/* make sure we don't mix up the two */
+	security_mode_ctrl_sent = false;
+}
+
+static inline void expect_security_mode_ctrl(const char *ck, const char *ik)
+{
+	security_mode_ctrl_sent = false;
+	security_mode_expect_ck = ck;
+	security_mode_expect_ik = ik;
+	/* make sure we don't mix up the two */
+	cipher_mode_cmd_sent = false;
+}
+
+extern bool paging_sent;
+extern bool paging_stopped;
+
+extern bool iu_release_expected;
+extern bool iu_release_sent;
+extern bool bssap_clear_expected;
+extern bool bssap_clear_sent;
+
+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 struct gsm_mncc *on_call_release_mncc_sends_to_cc_data;
+
+static inline void expect_iu_release()
+{
+	iu_release_expected = true;
+	iu_release_sent = false;
+}
+
+static inline void expect_bssap_clear()
+{
+	bssap_clear_expected = true;
+	bssap_clear_sent = false;
+}
+
+static inline void expect_release_clear(enum ran_type via_ran)
+{
+	switch (via_ran) {
+	case RAN_GERAN_A:
+		expect_bssap_clear();
+		return;
+	case RAN_UTRAN_IU:
+		expect_iu_release();
+		return;
+	default:
+		OSMO_ASSERT(false);
+		break;
+	}
+}
+
+struct msc_vlr_test_cmdline_opts {
+	bool verbose;
+	int run_test_nr;
+};
+
+typedef void (* msc_vlr_test_func_t )(void);
+extern msc_vlr_test_func_t msc_vlr_tests[];
+
+struct msgb *msgb_from_hex(const char *label, uint16_t size, const char *hex);
+
+void clear_vlr();
+bool conn_exists(const struct gsm_subscriber_connection *conn);
+void conn_conclude_cm_service_req(struct gsm_subscriber_connection *conn,
+				  enum ran_type via_ran);
+
+void dtap_expect_tx(const char *hex);
+void dtap_expect_tx_ussd(char *ussd_text);
+void paging_expect_imsi(const char *imsi);
+void paging_expect_tmsi(uint32_t tmsi);
+
+void bss_sends_bssap_mgmt(const char *hex);
+void ms_sends_msg(const char *hex);
+void ms_sends_security_mode_complete();
+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 bss_sends_clear_complete();
+void rnc_sends_release_complete();
+
+void thwart_rx_non_initial_requests();
+
+#define EXPECT_ACCEPTED(expect_accepted) do { \
+		if (g_conn) \
+			OSMO_ASSERT(conn_exists(g_conn)); \
+		bool accepted = msc_subscr_conn_is_accepted(g_conn); \
+		fprintf(stderr, "msc_subscr_conn_is_accepted() == %s\n", \
+			accepted ? "true" : "false"); \
+		OSMO_ASSERT(accepted == expect_accepted); \
+	} while (false)
+
+#define VERBOSE_ASSERT(val, expect_op, fmt) \
+	do { \
+		log(#val " == " fmt, (val)); \
+		OSMO_ASSERT((val) expect_op); \
+	} while (0);
+
+#define EXPECT_CONN_COUNT(N) VERBOSE_ASSERT(llist_count(&net->subscr_conns), == N, "%d")
+
+#define gsup_expect_tx(hex) do \
+{ \
+	if (gsup_tx_expected) { \
+		log("Previous expected GSUP tx was not confirmed!"); \
+		OSMO_ASSERT(!gsup_tx_expected); \
+	} \
+	if (!hex) \
+		break; \
+	gsup_tx_expected = hex; \
+	gsup_tx_confirmed = false; \
+} while (0)
+
+#define cc_to_mncc_expect_tx(imsi, msg_type) do \
+{ \
+	if (cc_to_mncc_tx_expected_msg_type) { \
+		log("Previous expected MNCC tx was not confirmed!"); \
+		OSMO_ASSERT(!cc_to_mncc_tx_expected_msg_type); \
+	} \
+	cc_to_mncc_tx_expected_imsi = imsi; \
+	cc_to_mncc_tx_expected_msg_type = msg_type; \
+	cc_to_mncc_tx_confirmed = false; \
+} while (0)
+
+void fake_time_start();
+
+/* as macro to get the test file's source line number */
+#define fake_time_passes(secs, usecs) do \
+{ \
+	struct timeval diff; \
+	osmo_gettimeofday_override_add(secs, usecs); \
+	osmo_clock_override_add(CLOCK_MONOTONIC, secs, usecs * 1000); \
+	timersub(&osmo_gettimeofday_override_time, &fake_time_start_time, &diff); \
+	btw("Total time passed: %d.%06d s", \
+	    (int)diff.tv_sec, (int)diff.tv_usec); \
+	osmo_timers_prepare(); \
+	osmo_timers_update(); \
+} while (0)
+
+extern const struct timeval fake_time_start_time;
+
+#define ASSERT_RELEASE_CLEAR(via_ran) \
+	switch (via_ran) { \
+	case RAN_GERAN_A: \
+		VERBOSE_ASSERT(bssap_clear_sent, == true, "%d"); \
+		break; \
+	case RAN_UTRAN_IU: \
+		VERBOSE_ASSERT(iu_release_sent, == true, "%d"); \
+		break; \
+	default: \
+		OSMO_ASSERT(false); \
+		break; \
+	}
+
+static inline void bss_rnc_sends_release_clear_complete(enum ran_type via_ran)
+{
+	switch (via_ran) {
+	case RAN_GERAN_A:
+		bss_sends_clear_complete();
+		return;
+	case RAN_UTRAN_IU:
+		rnc_sends_release_complete();
+		return;
+	default:
+		OSMO_ASSERT(false);
+		break;
+	}
+}
diff --git a/tests/smpp/Makefile.am b/tests/smpp/Makefile.am
new file mode 100644
index 0000000..8d63119
--- /dev/null
+++ b/tests/smpp/Makefile.am
@@ -0,0 +1,39 @@
+AM_CPPFLAGS = \
+	$(all_includes) \
+	-I$(top_srcdir)/include \
+	-I$(top_srcdir)/src/libmsc \
+	$(NULL)
+
+AM_CFLAGS = \
+	-Wall \
+	-ggdb3 \
+	$(LIBOSMOCORE_CFLAGS) \
+	$(LIBOSMOGSM_CFLAGS) \
+	$(LIBOSMOSCCP_CFLAGS) \
+	$(LIBOSMOABIS_CFLAGS) \
+	$(COVERAGE_CFLAGS) \
+	$(LIBSMPP34_CFLAGS) \
+	$(NULL)
+
+AM_LDFLAGS = \
+	$(COVERAGE_LDFLAGS) \
+	$(NULL)
+
+EXTRA_DIST = \
+	smpp_test.ok \
+	smpp_test.err \
+	$(NULL)
+
+noinst_PROGRAMS = \
+	smpp_test \
+	$(NULL)
+
+smpp_test_SOURCES = \
+	smpp_test.c \
+	$(top_builddir)/src/libmsc/smpp_utils.c \
+	$(NULL)
+
+smpp_test_LDADD = \
+	$(LIBOSMOCORE_LIBS) \
+	$(LIBOSMOGSM_LIBS) \
+	$(NULL)
diff --git a/tests/smpp/smpp_test.c b/tests/smpp/smpp_test.c
new file mode 100644
index 0000000..1abb63b
--- /dev/null
+++ b/tests/smpp/smpp_test.c
@@ -0,0 +1,87 @@
+/*
+ * (C) 2013 by Holger Hans Peter Freyther
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <osmocom/msc/debug.h>
+
+#include <osmocom/core/application.h>
+#include <osmocom/core/backtrace.h>
+
+#include "smpp_smsc.h"
+
+struct coding_test {
+	uint8_t dcs;
+	uint8_t coding;
+	int	mode;
+	int	res;
+};
+
+static struct coding_test codecs[] = {
+	{ .dcs = 0xf6		, .coding = 0x02, .mode = MODE_8BIT,	.res = 0  },
+	{ .dcs = 0xf2		, .coding = 0x01, .mode = MODE_7BIT,	.res = 0  },
+	{ .dcs = 0x02		, .coding = 0x01, .mode = MODE_7BIT,	.res = 0  },
+	{ .dcs = 0x06		, .coding = 0x02, .mode = MODE_8BIT,	.res = 0  },
+	{ .dcs = 0x0A		, .coding = 0x08, .mode = MODE_8BIT,	.res = 0  },
+	{ .dcs = 0x0E		, .coding = 0xFF, .mode = 0xFF,		.res = -1 },
+	{ .dcs = 0xE0		, .coding = 0xFF, .mode = 0xFF,		.res = -1 },
+};
+
+static void test_coding_scheme(void)
+{
+	int i;
+	printf("Testing coding scheme support\n");
+
+	for (i = 0; i < ARRAY_SIZE(codecs); ++i) {
+		uint8_t coding;
+		int mode, res;
+
+		res = smpp_determine_scheme(codecs[i].dcs, &coding, &mode);
+		OSMO_ASSERT(res == codecs[i].res);
+		if (res != -1) {
+			OSMO_ASSERT(mode == codecs[i].mode);
+			OSMO_ASSERT(coding == codecs[i].coding);
+		}
+	}
+}
+
+static const struct log_info_cat smpp_mirror_default_categories[] = {
+	[DSMPP] = {
+		.name = "DSMPP",
+		.description = "SMPP interface for external SMS apps",
+		.enabled = 1, .loglevel = LOGL_DEBUG,
+	},
+};
+
+const struct log_info log_info = {
+	.cat = smpp_mirror_default_categories,
+	.num_cat = ARRAY_SIZE(smpp_mirror_default_categories),
+};
+
+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);
+
+	test_coding_scheme();
+	return EXIT_SUCCESS;
+}
diff --git a/tests/smpp/smpp_test.err b/tests/smpp/smpp_test.err
new file mode 100644
index 0000000..ec966ba
--- /dev/null
+++ b/tests/smpp/smpp_test.err
@@ -0,0 +1,2 @@
+SMPP MO Unknown Data Coding 0x0e
+SMPP MO Unknown Data Coding 0xe0
diff --git a/tests/smpp/smpp_test.ok b/tests/smpp/smpp_test.ok
new file mode 100644
index 0000000..fd44804
--- /dev/null
+++ b/tests/smpp/smpp_test.ok
@@ -0,0 +1 @@
+Testing coding scheme support
diff --git a/tests/smpp_test_runner.py b/tests/smpp_test_runner.py
new file mode 100644
index 0000000..7a3a342
--- /dev/null
+++ b/tests/smpp_test_runner.py
@@ -0,0 +1,137 @@
+#!/usr/bin/env python
+
+# (C) 2014 by Holger Hans Peter Freyther
+# based on vty_test_runner.py:
+# (C) 2013 by Katerina Barone-Adesi <kat.obsc@gmail.com>
+# (C) 2013 by Holger Hans Peter Freyther
+# 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/>.
+
+import os
+import sys
+import time
+import unittest
+import socket
+
+import osmopy.obscvty as obscvty
+import osmopy.osmoutil as osmoutil
+
+confpath = os.path.join(sys.path[0], '..')
+
+class TestVTYBase(unittest.TestCase):
+
+    def vty_command(self):
+        raise Exception("Needs to be implemented by a subclass")
+
+    def vty_app(self):
+        raise Exception("Needs to be implemented by a subclass")
+
+    def setUp(self):
+        osmo_vty_cmd = self.vty_command()[:]
+        config_index = osmo_vty_cmd.index('-c')
+        if config_index:
+            cfi = config_index + 1
+            osmo_vty_cmd[cfi] = os.path.join(confpath, osmo_vty_cmd[cfi])
+
+        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"
+
+        appstring = self.vty_app()[2]
+        appport = self.vty_app()[0]
+        self.vty = obscvty.VTYInteract(appstring, "127.0.0.1", appport)
+
+    def tearDown(self):
+        if self.vty:
+            self.vty._close_socket()
+        self.vty = None
+        osmoutil.end_proc(self.proc)
+
+
+class TestSMPPMSC(TestVTYBase):
+
+    def vty_command(self):
+        return ["./src/osmo-msc/osmo-msc", "-c",
+                "doc/examples/osmo-msc/osmo-msc.cfg"]
+
+    def vty_app(self):
+        return (4254, "./src/osmo-msc/osmo-msc", "OsmoMSC", "msc")
+
+    def testSMPPCrashes(self):
+        # Enable the configuration
+        self.vty.enable()
+        self.assertTrue(self.vty.verify("configure terminal", ['']))
+        self.assertEquals(self.vty.node(), 'config')
+
+        self.assertTrue(self.vty.verify('smpp', ['']))
+        self.assertEquals(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.assertTrue(self.vty.verify('default-route', ['']))
+        self.assertTrue(self.vty.verify('end', ['']))
+
+        # MSC should listen to 2775 now!
+        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.close()
+
+        # Check if the VTY is still there
+        self.vty.verify('disable',[''])
+
+        # Now for the second packet
+        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.close()
+
+        self.vty.verify('enable',[''])
+
+if __name__ == '__main__':
+    import argparse
+    import sys
+
+    workdir = '.'
+
+    parser = argparse.ArgumentParser()
+    parser.add_argument("-v", "--verbose", dest="verbose",
+                        action="store_true", help="verbose mode")
+    parser.add_argument("-p", "--pythonconfpath", dest="p",
+                        help="searchpath for config")
+    parser.add_argument("-w", "--workdir", dest="w",
+                        help="Working directory")
+    args = parser.parse_args()
+
+    verbose_level = 1
+    if args.verbose:
+        verbose_level = 2
+
+    if args.w:
+        workdir = args.w
+
+    if args.p:
+        confpath = args.p
+
+    print "confpath %s, workdir %s" % (confpath, workdir)
+    os.chdir(workdir)
+    print "Running tests for specific SMPP"
+    suite = unittest.TestSuite()
+    suite.addTest(unittest.TestLoader().loadTestsFromTestCase(TestSMPPMSC))
+    res = unittest.TextTestRunner(verbosity=verbose_level).run(suite)
+    sys.exit(len(res.errors) + len(res.failures))
diff --git a/tests/sms_queue/Makefile.am b/tests/sms_queue/Makefile.am
new file mode 100644
index 0000000..1ffbe1c
--- /dev/null
+++ b/tests/sms_queue/Makefile.am
@@ -0,0 +1,52 @@
+AM_CPPFLAGS = \
+	$(all_includes) \
+	-I$(top_srcdir)/include \
+	$(NULL)
+
+AM_CFLAGS = \
+	-Wall \
+	-ggdb3 \
+	$(LIBOSMOCORE_CFLAGS) \
+	$(LIBOSMOGSM_CFLAGS) \
+	$(LIBOSMOVTY_CFLAGS) \
+	$(LIBOSMOABIS_CFLAGS) \
+	$(LIBOSMOSIGTRAN_CFLAGS) \
+	$(LIBOSMORANAP_CFLAGS) \
+	$(LIBASN1C_CFLAGS) \
+	$(LIBOSMOMGCPCLIENT_CFLAGS) \
+	$(LIBOSMOGSUPCLIENT_CFLAGS) \
+	$(NULL)
+
+EXTRA_DIST = \
+	sms_queue_test.ok \
+	sms_queue_test.err \
+	$(NULL)
+
+noinst_PROGRAMS = \
+	sms_queue_test \
+	$(NULL)
+
+sms_queue_test_SOURCES = \
+	sms_queue_test.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) \
+	$(LIBOSMOABIS_LIBS) \
+	$(LIBOSMOSIGTRAN_LIBS) \
+	$(LIBOSMORANAP_LIBS) \
+	$(LIBOSMOMGCPCLIENT_LIBS) \
+	$(LIBOSMOGSUPCLIENT_LIBS) \
+	$(LIBRARY_GSM) \
+	-ldbi \
+	-lrt \
+	$(NULL)
+
+sms_queue_test_LDFLAGS = \
+	-Wl,--wrap=db_sms_get_next_unsent_rr_msisdn \
+	$(NULL)
diff --git a/tests/sms_queue/sms_queue_test.c b/tests/sms_queue/sms_queue_test.c
new file mode 100644
index 0000000..6ce0b88
--- /dev/null
+++ b/tests/sms_queue/sms_queue_test.c
@@ -0,0 +1,238 @@
+/* Test Osmocom SMS queue */
+
+/*
+ * (C) 2017 by sysmocom s.f.m.c. GmbH
+ * All Rights Reserved
+ *
+ * Author: Neels Hofmeyr <nhofmeyr@sysmocom.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <osmocom/core/application.h>
+
+#include <osmocom/msc/debug.h>
+#include <osmocom/msc/vlr.h>
+
+static void *talloc_ctx = NULL;
+
+struct gsm_sms *smsq_take_next_sms(struct gsm_network *net,
+				   char *last_msisdn,
+				   size_t last_msisdn_buflen);
+
+static void _test_take_next_sms_print(int i,
+				      struct gsm_sms *sms,
+				      const char *last_msisdn)
+{
+	printf("#%d: ", i);
+	if (sms)
+		printf("sending SMS to %s", sms->text);
+	else
+		printf("no SMS to send");
+	printf(" (last_msisdn='%s')\n", last_msisdn? last_msisdn : "NULL");
+}
+
+static struct gsm_sms fake_sms = { 0 };
+
+struct {
+	const char *msisdn;
+	int nr_of_sms;
+	int failed_attempts;
+	bool vsub_attached;
+} fake_sms_db[] = {
+	{
+		.msisdn = "1111",
+		.nr_of_sms = 0,
+		.vsub_attached = true,
+	},
+	{
+		.msisdn = "2222",
+		.nr_of_sms = 2,
+		.failed_attempts = 2,
+		.vsub_attached = true,
+	},
+	{
+		.msisdn = "3333",
+		.nr_of_sms = 2,
+		.failed_attempts = 3,
+		.vsub_attached = true,
+	},
+	{
+		.msisdn = "4444",
+		.nr_of_sms = 0,
+		.vsub_attached = true,
+	},
+	{
+		.msisdn = "5555",
+		.nr_of_sms = 2,
+		.failed_attempts = 5,
+		.vsub_attached = false,
+	},
+};
+
+/* override, requires '-Wl,--wrap=db_sms_get_next_unsent_rr_msisdn' */
+struct gsm_sms *__real_db_sms_get_next_unsent_rr_msisdn(struct gsm_network *net,
+							const char *last_msisdn,
+							unsigned int max_failed);
+struct gsm_sms *__wrap_db_sms_get_next_unsent_rr_msisdn(struct gsm_network *net,
+							const char *last_msisdn,
+							unsigned int max_failed)
+{
+	static struct vlr_subscr arbitrary_vsub = { .lu_complete = true };
+	int i;
+	printf("     hitting database: looking for MSISDN > '%s', failed_attempts <= %d\n",
+	       last_msisdn, max_failed);
+
+	for (i = 0; i < ARRAY_SIZE(fake_sms_db); i++) {
+		if (!fake_sms_db[i].nr_of_sms)
+			continue;
+		if (strcmp(fake_sms_db[i].msisdn, last_msisdn) <= 0)
+			continue;
+		if (fake_sms_db[i].failed_attempts > max_failed)
+			continue;
+		osmo_strlcpy(fake_sms.dst.addr, fake_sms_db[i].msisdn,
+			     sizeof(fake_sms.dst.addr));
+		fake_sms.receiver = fake_sms_db[i].vsub_attached? &arbitrary_vsub : NULL;
+		osmo_strlcpy(fake_sms.text, fake_sms_db[i].msisdn, sizeof(fake_sms.text));
+		if (fake_sms_db[i].vsub_attached)
+			fake_sms_db[i].nr_of_sms--;
+		return &fake_sms;
+	}
+	return NULL;
+}
+
+void show_fake_sms_db()
+{
+	int i;
+	for (i = 0; i < ARRAY_SIZE(fake_sms_db); i++) {
+		printf("  %s%s has %u SMS pending, %u failed attempts\n",
+		       fake_sms_db[i].msisdn,
+		       fake_sms_db[i].vsub_attached ? "" : " (NOT attached)",
+		       fake_sms_db[i].nr_of_sms,
+		       fake_sms_db[i].failed_attempts);
+	}
+	printf("-->\n");
+}
+
+static void test_next_sms()
+{
+	int i;
+	char last_msisdn[GSM_EXTENSION_LENGTH+1] = "";
+
+	printf("Testing smsq_take_next_sms()\n");
+
+	printf("\n- vsub 2, 3 and 5 each have 2 SMS pending, but 5 is not attached\n");
+	last_msisdn[0] = '\0';
+	show_fake_sms_db();
+	for (i = 0; i < 7; i++) {
+		struct gsm_sms *sms = smsq_take_next_sms(NULL, last_msisdn, sizeof(last_msisdn));
+		_test_take_next_sms_print(i, sms, last_msisdn);
+		OSMO_ASSERT(i >= 4 || sms);
+	}
+
+	printf("\n- SMS are pending at various nr failed attempts (cutoff at >= 10)\n");
+	last_msisdn[0] = '\0';
+	for (i = 0; i < ARRAY_SIZE(fake_sms_db); i++) {
+		fake_sms_db[i].vsub_attached = true;
+		fake_sms_db[i].nr_of_sms = 1 + i;
+		fake_sms_db[i].failed_attempts = i*5;
+
+	}
+	show_fake_sms_db();
+	for (i = 0; i < 7; i++) {
+		struct gsm_sms *sms = smsq_take_next_sms(NULL, last_msisdn, sizeof(last_msisdn));
+		_test_take_next_sms_print(i, sms, last_msisdn);
+		OSMO_ASSERT(i >= 2 || sms);
+	}
+
+	printf("\n- iterate the SMS DB at most once\n");
+	osmo_strlcpy(last_msisdn, "2345", sizeof(last_msisdn));
+	for (i = 0; i < ARRAY_SIZE(fake_sms_db); i++) {
+		fake_sms_db[i].vsub_attached = false;
+		fake_sms_db[i].nr_of_sms = 1;
+		fake_sms_db[i].failed_attempts = 0;
+	}
+	show_fake_sms_db();
+	for (i = 0; i < 3; i++) {
+		struct gsm_sms *sms = smsq_take_next_sms(NULL, last_msisdn, sizeof(last_msisdn));
+		_test_take_next_sms_print(i, sms, last_msisdn);
+		OSMO_ASSERT(!sms);
+	}
+
+	printf("\n- there are no SMS in the DB\n");
+	last_msisdn[0] = '\0';
+	for (i = 0; i < ARRAY_SIZE(fake_sms_db); i++) {
+		fake_sms_db[i].vsub_attached = true;
+		fake_sms_db[i].nr_of_sms = 0;
+		fake_sms_db[i].failed_attempts = 0;
+	}
+	show_fake_sms_db();
+	for (i = 0; i < 3; i++) {
+		struct gsm_sms *sms = smsq_take_next_sms(NULL, last_msisdn, sizeof(last_msisdn));
+		_test_take_next_sms_print(i, sms, last_msisdn);
+		OSMO_ASSERT(!sms);
+	}
+}
+
+
+static struct log_info_cat sms_queue_test_categories[] = {
+};
+
+static struct log_info info = {
+	.cat = sms_queue_test_categories,
+	.num_cat = ARRAY_SIZE(sms_queue_test_categories),
+};
+
+int main(int argc, char **argv)
+{
+	void *msgb_ctx;
+	void *logging_ctx;
+
+	talloc_ctx = talloc_named_const(NULL, 0, "sms_queue_test");
+	msgb_ctx = msgb_talloc_ctx_init(talloc_ctx, 0);
+	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_filename(osmo_stderr_target, 0);
+	log_set_print_category(osmo_stderr_target, 1);
+	log_parse_category_mask(osmo_stderr_target, "DLOAP,1");
+
+	test_next_sms();
+	printf("Done\n");
+
+	if (talloc_total_blocks(msgb_ctx) != 1
+	    || talloc_total_size(msgb_ctx) != 0) {
+		talloc_report_full(msgb_ctx, stderr);
+		fflush(stderr);
+	}
+
+	OSMO_ASSERT(talloc_total_blocks(msgb_ctx) == 1);
+	OSMO_ASSERT(talloc_total_size(msgb_ctx) == 0);
+	talloc_free(msgb_ctx);
+	talloc_free(logging_ctx);
+
+	if (talloc_total_blocks(talloc_ctx) != 1
+	    || talloc_total_size(talloc_ctx) != 0)
+		talloc_report_full(talloc_ctx, stderr);
+
+	OSMO_ASSERT(talloc_total_blocks(talloc_ctx) == 1);
+	OSMO_ASSERT(talloc_total_size(talloc_ctx) == 0);
+	talloc_free(talloc_ctx);
+
+	return 0;
+}
diff --git a/tests/sms_queue/sms_queue_test.err b/tests/sms_queue/sms_queue_test.err
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/sms_queue/sms_queue_test.err
diff --git a/tests/sms_queue/sms_queue_test.ok b/tests/sms_queue/sms_queue_test.ok
new file mode 100644
index 0000000..146400d
--- /dev/null
+++ b/tests/sms_queue/sms_queue_test.ok
@@ -0,0 +1,98 @@
+Testing smsq_take_next_sms()
+
+- vsub 2, 3 and 5 each have 2 SMS pending, but 5 is not attached
+  1111 has 0 SMS pending, 0 failed attempts
+  2222 has 2 SMS pending, 2 failed attempts
+  3333 has 2 SMS pending, 3 failed attempts
+  4444 has 0 SMS pending, 0 failed attempts
+  5555 (NOT attached) has 2 SMS pending, 5 failed attempts
+-->
+     hitting database: looking for MSISDN > '', failed_attempts <= 9
+#0: sending SMS to 2222 (last_msisdn='2222')
+     hitting database: looking for MSISDN > '2222', failed_attempts <= 9
+#1: sending SMS to 3333 (last_msisdn='3333')
+     hitting database: looking for MSISDN > '3333', failed_attempts <= 9
+     hitting database: looking for MSISDN > '5555', failed_attempts <= 9
+     hitting database: looking for MSISDN > '', failed_attempts <= 9
+#2: sending SMS to 2222 (last_msisdn='2222')
+     hitting database: looking for MSISDN > '2222', failed_attempts <= 9
+#3: sending SMS to 3333 (last_msisdn='3333')
+     hitting database: looking for MSISDN > '3333', failed_attempts <= 9
+     hitting database: looking for MSISDN > '5555', failed_attempts <= 9
+     hitting database: looking for MSISDN > '', failed_attempts <= 9
+#4: no SMS to send (last_msisdn='5555')
+     hitting database: looking for MSISDN > '5555', failed_attempts <= 9
+     hitting database: looking for MSISDN > '', failed_attempts <= 9
+#5: no SMS to send (last_msisdn='5555')
+     hitting database: looking for MSISDN > '5555', failed_attempts <= 9
+     hitting database: looking for MSISDN > '', failed_attempts <= 9
+#6: no SMS to send (last_msisdn='5555')
+
+- SMS are pending at various nr failed attempts (cutoff at >= 10)
+  1111 has 1 SMS pending, 0 failed attempts
+  2222 has 2 SMS pending, 5 failed attempts
+  3333 has 3 SMS pending, 10 failed attempts
+  4444 has 4 SMS pending, 15 failed attempts
+  5555 has 5 SMS pending, 20 failed attempts
+-->
+     hitting database: looking for MSISDN > '', failed_attempts <= 9
+#0: sending SMS to 1111 (last_msisdn='1111')
+     hitting database: looking for MSISDN > '1111', failed_attempts <= 9
+#1: sending SMS to 2222 (last_msisdn='2222')
+     hitting database: looking for MSISDN > '2222', failed_attempts <= 9
+     hitting database: looking for MSISDN > '', failed_attempts <= 9
+#2: sending SMS to 2222 (last_msisdn='2222')
+     hitting database: looking for MSISDN > '2222', failed_attempts <= 9
+     hitting database: looking for MSISDN > '', failed_attempts <= 9
+#3: no SMS to send (last_msisdn='')
+     hitting database: looking for MSISDN > '', failed_attempts <= 9
+#4: no SMS to send (last_msisdn='')
+     hitting database: looking for MSISDN > '', failed_attempts <= 9
+#5: no SMS to send (last_msisdn='')
+     hitting database: looking for MSISDN > '', failed_attempts <= 9
+#6: no SMS to send (last_msisdn='')
+
+- iterate the SMS DB at most once
+  1111 (NOT attached) has 1 SMS pending, 0 failed attempts
+  2222 (NOT attached) has 1 SMS pending, 0 failed attempts
+  3333 (NOT attached) has 1 SMS pending, 0 failed attempts
+  4444 (NOT attached) has 1 SMS pending, 0 failed attempts
+  5555 (NOT attached) has 1 SMS pending, 0 failed attempts
+-->
+     hitting database: looking for MSISDN > '2345', failed_attempts <= 9
+     hitting database: looking for MSISDN > '3333', failed_attempts <= 9
+     hitting database: looking for MSISDN > '4444', failed_attempts <= 9
+     hitting database: looking for MSISDN > '5555', failed_attempts <= 9
+     hitting database: looking for MSISDN > '', failed_attempts <= 9
+     hitting database: looking for MSISDN > '1111', failed_attempts <= 9
+     hitting database: looking for MSISDN > '2222', failed_attempts <= 9
+#0: no SMS to send (last_msisdn='3333')
+     hitting database: looking for MSISDN > '3333', failed_attempts <= 9
+     hitting database: looking for MSISDN > '4444', failed_attempts <= 9
+     hitting database: looking for MSISDN > '5555', failed_attempts <= 9
+     hitting database: looking for MSISDN > '', failed_attempts <= 9
+     hitting database: looking for MSISDN > '1111', failed_attempts <= 9
+     hitting database: looking for MSISDN > '2222', failed_attempts <= 9
+#1: no SMS to send (last_msisdn='3333')
+     hitting database: looking for MSISDN > '3333', failed_attempts <= 9
+     hitting database: looking for MSISDN > '4444', failed_attempts <= 9
+     hitting database: looking for MSISDN > '5555', failed_attempts <= 9
+     hitting database: looking for MSISDN > '', failed_attempts <= 9
+     hitting database: looking for MSISDN > '1111', failed_attempts <= 9
+     hitting database: looking for MSISDN > '2222', failed_attempts <= 9
+#2: no SMS to send (last_msisdn='3333')
+
+- there are no SMS in the DB
+  1111 has 0 SMS pending, 0 failed attempts
+  2222 has 0 SMS pending, 0 failed attempts
+  3333 has 0 SMS pending, 0 failed attempts
+  4444 has 0 SMS pending, 0 failed attempts
+  5555 has 0 SMS pending, 0 failed attempts
+-->
+     hitting database: looking for MSISDN > '', failed_attempts <= 9
+#0: no SMS to send (last_msisdn='')
+     hitting database: looking for MSISDN > '', failed_attempts <= 9
+#1: no SMS to send (last_msisdn='')
+     hitting database: looking for MSISDN > '', failed_attempts <= 9
+#2: no SMS to send (last_msisdn='')
+Done
diff --git a/tests/testsuite.at b/tests/testsuite.at
new file mode 100644
index 0000000..f27b60c
--- /dev/null
+++ b/tests/testsuite.at
@@ -0,0 +1,101 @@
+AT_INIT
+AT_BANNER([Regression tests.])
+
+AT_SETUP([smpp])
+AT_KEYWORDS([smpp])
+AT_CHECK([test "$enable_smpp_test" != no || exit 77])
+cat $abs_srcdir/smpp/smpp_test.ok > expout
+cat $abs_srcdir/smpp/smpp_test.err > experr
+AT_CHECK([$abs_top_builddir/tests/smpp/smpp_test], [], [expout], [experr])
+AT_CLEANUP
+
+AT_SETUP([sms_queue_test])
+AT_KEYWORDS([sms_queue_test])
+cat $abs_srcdir/sms_queue/sms_queue_test.ok > expout
+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([msc_vlr_test_no_authen])
+AT_KEYWORDS([msc_vlr_test_no_authen])
+cat $abs_srcdir/msc_vlr/msc_vlr_test_no_authen.ok > expout
+cat $abs_srcdir/msc_vlr/msc_vlr_test_no_authen.err > experr
+AT_CHECK([$abs_top_builddir/tests/msc_vlr/msc_vlr_test_no_authen], [], [expout], [experr])
+AT_CLEANUP
+
+AT_SETUP([msc_vlr_test_gsm_authen])
+AT_KEYWORDS([msc_vlr_test_gsm_authen])
+cat $abs_srcdir/msc_vlr/msc_vlr_test_gsm_authen.ok > expout
+cat $abs_srcdir/msc_vlr/msc_vlr_test_gsm_authen.err > experr
+AT_CHECK([$abs_top_builddir/tests/msc_vlr/msc_vlr_test_gsm_authen], [], [expout], [experr])
+AT_CLEANUP
+
+AT_SETUP([msc_vlr_test_gsm_ciph])
+AT_KEYWORDS([msc_vlr_test_gsm_ciph])
+cat $abs_srcdir/msc_vlr/msc_vlr_test_gsm_ciph.ok > expout
+cat $abs_srcdir/msc_vlr/msc_vlr_test_gsm_ciph.err > experr
+AT_CHECK([$abs_top_builddir/tests/msc_vlr/msc_vlr_test_gsm_ciph], [], [expout], [experr])
+AT_CLEANUP
+
+AT_SETUP([msc_vlr_test_umts_authen])
+AT_KEYWORDS([msc_vlr_test_umts_authen])
+cat $abs_srcdir/msc_vlr/msc_vlr_test_umts_authen.ok > expout
+cat $abs_srcdir/msc_vlr/msc_vlr_test_umts_authen.err > experr
+AT_CHECK([$abs_top_builddir/tests/msc_vlr/msc_vlr_test_umts_authen], [], [expout], [experr])
+AT_CLEANUP
+
+AT_SETUP([msc_vlr_test_authen_reuse])
+AT_KEYWORDS([msc_vlr_test_authen_reuse])
+cat $abs_srcdir/msc_vlr/msc_vlr_test_authen_reuse.ok > expout
+cat $abs_srcdir/msc_vlr/msc_vlr_test_authen_reuse.err > experr
+AT_CHECK([$abs_top_builddir/tests/msc_vlr/msc_vlr_test_authen_reuse], [], [expout], [experr])
+AT_CLEANUP
+
+AT_SETUP([msc_vlr_test_hlr_reject])
+AT_KEYWORDS([msc_vlr_test_hlr_reject])
+cat $abs_srcdir/msc_vlr/msc_vlr_test_hlr_reject.ok > expout
+cat $abs_srcdir/msc_vlr/msc_vlr_test_hlr_reject.err > experr
+AT_CHECK([$abs_top_builddir/tests/msc_vlr/msc_vlr_test_hlr_reject], [], [expout], [experr])
+AT_CLEANUP
+
+AT_SETUP([msc_vlr_test_hlr_timeout])
+AT_KEYWORDS([msc_vlr_test_hlr_timeout])
+cat $abs_srcdir/msc_vlr/msc_vlr_test_hlr_timeout.ok > expout
+cat $abs_srcdir/msc_vlr/msc_vlr_test_hlr_timeout.err > experr
+AT_CHECK([$abs_top_builddir/tests/msc_vlr/msc_vlr_test_hlr_timeout], [], [expout], [experr])
+AT_CLEANUP
+
+AT_SETUP([msc_vlr_test_ms_timeout])
+AT_KEYWORDS([msc_vlr_test_ms_timeout])
+cat $abs_srcdir/msc_vlr/msc_vlr_test_ms_timeout.ok > expout
+cat $abs_srcdir/msc_vlr/msc_vlr_test_ms_timeout.err > experr
+AT_CHECK([$abs_top_builddir/tests/msc_vlr/msc_vlr_test_ms_timeout], [], [expout], [experr])
+AT_CLEANUP
+
+AT_SETUP([msc_vlr_test_reject_concurrency])
+AT_KEYWORDS([msc_vlr_test_reject_concurrency])
+cat $abs_srcdir/msc_vlr/msc_vlr_test_reject_concurrency.ok > expout
+cat $abs_srcdir/msc_vlr/msc_vlr_test_reject_concurrency.err > experr
+AT_CHECK([$abs_top_builddir/tests/msc_vlr/msc_vlr_test_reject_concurrency], [], [expout], [experr])
+AT_CLEANUP
+
+AT_SETUP([msc_vlr_test_call])
+AT_KEYWORDS([msc_vlr_test_call])
+cat $abs_srcdir/msc_vlr/msc_vlr_test_call.ok > expout
+cat $abs_srcdir/msc_vlr/msc_vlr_test_call.err > experr
+AT_CHECK([$abs_top_builddir/tests/msc_vlr/msc_vlr_test_call], [], [expout], [experr])
+AT_CLEANUP
+
+AT_SETUP([msc_vlr_test_rest])
+AT_KEYWORDS([msc_vlr_test_rest])
+cat $abs_srcdir/msc_vlr/msc_vlr_test_rest.ok > expout
+cat $abs_srcdir/msc_vlr/msc_vlr_test_rest.err > experr
+AT_CHECK([$abs_top_builddir/tests/msc_vlr/msc_vlr_test_rest], [], [expout], [experr])
+AT_CLEANUP
+
+AT_SETUP([msc_vlr_test_ss])
+AT_KEYWORDS([msc_vlr_test_ss])
+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
diff --git a/tests/vty_test_runner.py b/tests/vty_test_runner.py
new file mode 100644
index 0000000..6d8ca6f
--- /dev/null
+++ b/tests/vty_test_runner.py
@@ -0,0 +1,298 @@
+#!/usr/bin/env python
+
+# (C) 2013 by Katerina Barone-Adesi <kat.obsc@gmail.com>
+# (C) 2013 by Holger Hans Peter Freyther
+# 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/>.
+
+import os, sys
+import time
+import unittest
+import socket
+import subprocess
+
+import osmopy.obscvty as obscvty
+import osmopy.osmoutil as osmoutil
+from osmopy.osmo_ipa import IPA
+
+# to be able to find $top_srcdir/doc/...
+confpath = os.path.join(sys.path[0], '..')
+
+class TestVTYBase(unittest.TestCase):
+
+    def checkForEndAndExit(self):
+        res = self.vty.command("list")
+        #print ('looking for "exit"\n')
+        self.assert_(res.find('  exit\r') > 0)
+        #print 'found "exit"\nlooking for "end"\n'
+        self.assert_(res.find('  end\r') > 0)
+        #print 'found "end"\n'
+
+    def vty_command(self):
+        raise Exception("Needs to be implemented by a subclass")
+
+    def vty_app(self):
+        raise Exception("Needs to be implemented by a subclass")
+
+    def setUp(self):
+        osmo_vty_cmd = self.vty_command()[:]
+        config_index = osmo_vty_cmd.index('-c')
+        if config_index:
+            cfi = config_index + 1
+            osmo_vty_cmd[cfi] = os.path.join(confpath, osmo_vty_cmd[cfi])
+
+        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"
+
+        appstring = self.vty_app()[2]
+        appport = self.vty_app()[0]
+        self.vty = obscvty.VTYInteract(appstring, "127.0.0.1", appport)
+
+    def tearDown(self):
+        if self.vty:
+            self.vty._close_socket()
+        self.vty = None
+        osmoutil.end_proc(self.proc)
+
+class TestVTYMSC(TestVTYBase):
+
+    def vty_command(self):
+        return ["./src/osmo-msc/osmo-msc", "-c",
+                "doc/examples/osmo-msc/osmo-msc.cfg"]
+
+    def vty_app(self):
+        return (4254, "./src/osmo-msc/osmo-msc", "OsmoMSC", "msc")
+
+    def testConfigNetworkTree(self, include_bsc_items=True):
+        self.vty.enable()
+        self.assertTrue(self.vty.verify("configure terminal",['']))
+        self.assertEquals(self.vty.node(), 'config')
+        self.checkForEndAndExit()
+        self.assertTrue(self.vty.verify("network",['']))
+        self.assertEquals(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.assertTrue(self.vty.verify("exit",['']))
+        self.assertTrue(self.vty.node() is None)
+
+    def checkForSmpp(self):
+        """SMPP is not always enabled, check if it is"""
+        res = self.vty.command("list")
+        return "smpp" in res
+
+    def testSmppFirst(self):
+        # enable the configuration
+        self.vty.enable()
+        self.vty.command("configure terminal")
+
+        if not self.checkForSmpp():
+            return
+
+        self.vty.command("smpp")
+
+        # check the default
+        res = self.vty.command("write terminal")
+        self.assert_(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.vty.verify("no smpp-first", [''])
+        res = self.vty.command("write terminal")
+        self.assert_(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.checkForEndAndExit()
+        self.assertTrue(self.vty.verify('mncc-int', ['']))
+        self.assertEquals(self.vty.node(), 'config-mncc-int')
+        self.checkForEndAndExit()
+        self.assertTrue(self.vty.verify('exit', ['']))
+
+        if self.checkForSmpp():
+            self.assertEquals(self.vty.node(), 'config')
+            self.assertTrue(self.vty.verify('smpp', ['']))
+            self.assertEquals(self.vty.node(), 'config-smpp')
+            self.checkForEndAndExit()
+            self.assertTrue(self.vty.verify("exit", ['']))
+
+        self.assertEquals(self.vty.node(), 'config')
+        self.assertTrue(self.vty.verify("exit", ['']))
+        self.assertTrue(self.vty.node() is None)
+
+        # Check searching for outer node's commands
+        self.vty.command("configure terminal")
+        self.vty.command('mncc-int')
+
+        if self.checkForSmpp():
+            self.vty.command('smpp')
+            self.assertEquals(self.vty.node(), 'config-smpp')
+            self.vty.command('mncc-int')
+
+        self.assertEquals(self.vty.node(), 'config-mncc-int')
+
+    def testSi2Q(self):
+        self.vty.enable()
+        self.vty.command("configure terminal")
+        self.vty.command("network")
+        self.vty.command("bts 0")
+        before = self.vty.command("show running-config")
+        self.vty.command("si2quater neighbor-list add earfcn 1911 threshold 11 2")
+        self.vty.command("si2quater neighbor-list add earfcn 1924 threshold 11 3")
+        self.vty.command("si2quater neighbor-list add earfcn 2111 threshold 11")
+        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.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")
+        self.vty.command("si2quater neighbor-list add uarfcn 1976 120 1")
+        self.vty.command("si2quater neighbor-list add uarfcn 1976 140 1")
+        self.vty.command("si2quater neighbor-list add uarfcn 1976 163 1")
+        self.vty.command("si2quater neighbor-list add uarfcn 1976 166 1")
+        self.vty.command("si2quater neighbor-list add uarfcn 1976 217 1")
+        self.vty.command("si2quater neighbor-list add uarfcn 1976 224 1")
+        self.vty.command("si2quater neighbor-list add uarfcn 1976 225 1")
+        self.vty.command("si2quater neighbor-list add uarfcn 1976 226 1")
+        self.vty.command("si2quater neighbor-list del uarfcn 1976 13")
+        self.vty.command("si2quater neighbor-list del uarfcn 1976 38")
+        self.vty.command("si2quater neighbor-list del uarfcn 1976 44")
+        self.vty.command("si2quater neighbor-list del uarfcn 1976 120")
+        self.vty.command("si2quater neighbor-list del uarfcn 1976 140")
+        self.vty.command("si2quater neighbor-list del uarfcn 1976 163")
+        self.vty.command("si2quater neighbor-list del uarfcn 1976 166")
+        self.vty.command("si2quater neighbor-list del uarfcn 1976 217")
+        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"))
+
+    def testEnableDisablePeriodicLU(self):
+        self.vty.enable()
+        self.vty.command("configure terminal")
+        self.vty.command("network")
+        self.vty.command("bts 0")
+
+        # Test invalid input
+        self.vty.verify("periodic location update 0", ['% Unknown command.'])
+        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", [''])
+        res = self.vty.command("write terminal")
+        self.assert_(res.find('periodic location update 60') > 0)
+        self.assertEquals(res.find('no periodic location update'), -1)
+
+        # Now disable it..
+        self.vty.verify("no periodic location update", [''])
+        res = self.vty.command("write terminal")
+        self.assertEquals(res.find('periodic location update 60'), -1)
+        self.assert_(res.find('no periodic location update') > 0)
+
+    def testShowNetwork(self):
+        res = self.vty.command("show network")
+        self.assert_(res.startswith('BSC is on Country Code') >= 0)
+
+def ipa_handle_small(x, verbose = False):
+    s = data2str(x.recv(4))
+    if len(s) != 4*2:
+      raise Exception("expected to receive 4 bytes, but got %d (%r)" % (len(s)/2, s))
+    if "0001fe00" == s:
+        if (verbose):
+            print "\tBSC <- NAT: PING?"
+        x.send(IPA().pong())
+    elif "0001fe06" == s:
+        if (verbose):
+            print "\tBSC <- NAT: IPA ID ACK"
+        x.send(IPA().id_ack())
+    elif "0001fe00" == s:
+        if (verbose):
+            print "\tBSC <- NAT: PONG!"
+    else:
+        if (verbose):
+            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"))
+            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"))
+                break
+            except:
+                print "\tfailed sending IPA identity at", time.strftime("%T")
+                if proc:
+                  print "\tproc.poll() = %r" % proc.poll()
+                if retries < 1:
+                    print "\tgiving up"
+                    raise
+                print "\tretrying (%d attempts left)" % retries
+                retries -= 1
+    else:
+        if (verbose):
+            print "\tBSC <- NAT: ", s
+
+if __name__ == '__main__':
+    import argparse
+    import sys
+
+    workdir = '.'
+
+    parser = argparse.ArgumentParser()
+    parser.add_argument("-v", "--verbose", dest="verbose",
+                        action="store_true", help="verbose mode")
+    parser.add_argument("-p", "--pythonconfpath", dest="p",
+                        help="searchpath for config")
+    parser.add_argument("-w", "--workdir", dest="w",
+                        help="Working directory")
+    parser.add_argument("test_name", nargs="*", help="(parts of) test names to run, case-insensitive")
+    args = parser.parse_args()
+
+    verbose_level = 1
+    if args.verbose:
+        verbose_level = 2
+
+    if args.w:
+        workdir = args.w
+
+    if args.p:
+        confpath = args.p
+
+    print "confpath %s, workdir %s" % (confpath, workdir)
+    os.chdir(workdir)
+    print "Running tests for specific VTY commands"
+    suite = unittest.TestSuite()
+    suite.addTest(unittest.TestLoader().loadTestsFromTestCase(TestVTYMSC))
+
+    if args.test_name:
+        osmoutil.pick_tests(suite, *args.test_name)
+
+    res = unittest.TextTestRunner(verbosity=verbose_level, stream=sys.stdout).run(suite)
+    sys.exit(len(res.errors) + len(res.failures))
+
+# vim: shiftwidth=4 expandtab nocin ai