Commit Graph

99 Commits

Author SHA1 Message Date
Neels Hofmeyr 4ac8009c29 rename bscconfig.h to config.h, cleanup
Get rid of the legacy name bscconfig.h from osmo-nitb times.

Remove the #include from some of the files that aren't actually using it.

Instead of '#include "../../config.h"', use plain '#include "config.h"'
because we're anyway passing $top_srcdir as -I during compilation.

Change-Id: Id4f683be1f36f0630c83da54e02868aae847aeec
2019-05-08 17:02:32 +02:00
Neels Hofmeyr c4628a3ad4 large refactoring: support inter-BSC and inter-MSC Handover
3GPP TS 49.008 '4.3 Roles of MSC-A, MSC-I and MSC-T' defines distinct roles:
- MSC-A is responsible for managing subscribers,
- MSC-I is the gateway to the RAN.
- MSC-T is a second transitory gateway to another RAN during Handover.

After inter-MSC Handover, the MSC-I is handled by a remote MSC instance, while
the original MSC-A retains the responsibility of subscriber management.

MSC-T exists in this patch but is not yet used, since Handover is only prepared
for, not yet implemented.

Facilitate Inter-MSC and inter-BSC Handover by the same internal split of MSC
roles.

Compared to inter-MSC Handover, mere inter-BSC has the obvious simplifications:
- all of MSC-A, MSC-I and MSC-T roles will be served by the same osmo-msc
  instance,
- messages between MSC-A and MSC-{I,T} don't need to be routed via E-interface
  (GSUP),
- no call routing between MSC-A and -I via MNCC necessary.

This is the largest code bomb I have submitted, ever. Out of principle, I
apologize to everyone trying to read this as a whole. Unfortunately, I see no
sense in trying to split this patch into smaller bits. It would be a huge
amount of work to introduce these changes in separate chunks, especially if
each should in turn be useful and pass all test suites. So, unfortunately, we
are stuck with this code bomb.

The following are some details and rationale for this rather huge refactoring:

* separate MSC subscriber management from ran_conn

struct ran_conn is reduced from the pivotal subscriber management entity it has
been so far to a mere storage for an SCCP connection ID and an MSC subscriber
reference.

The new pivotal subscriber management entity is struct msc_a -- struct msub
lists the msc_a, msc_i, msc_t roles, the vast majority of code paths however
use msc_a, since MSC-A is where all the interesting stuff happens.

Before handover, msc_i is an FSM implementation that encodes to the local
ran_conn. After inter-MSC Handover, msc_i is a compatible but different FSM
implementation that instead forwards via/from GSUP. Same goes for the msc_a
struct: if osmo-msc is the MSC-I "RAN proxy" for a remote MSC-A role, the
msc_a->fi is an FSM implementation that merely forwards via/from GSUP.

* New SCCP implementation for RAN access

To be able to forward BSSAP and RANAP messages via the GSUP interface, the
individual message layers need to be cleanly separated. The IuCS implementation
used until now (iu_client from libosmo-ranap) did not provide this level of
separation, and needed a complete rewrite. It was trivial to implement this in
such a way that both BSSAP and RANAP can be handled by the same SCCP code,
hence the new SCCP-RAN layer also replaces BSSAP handling.

sccp_ran.h: struct sccp_ran_inst provides an abstract handler for incoming RAN
connections. A set of callback functions provides implementation specific
details.

* RAN Abstraction (BSSAP vs. RANAP)

The common SCCP implementation did set the theme for the remaining refactoring:
make all other MSC code paths entirely RAN-implementation-agnostic.

ran_infra.c provides data structures that list RAN implementation specifics,
from logging to RAN de-/encoding to SCCP callbacks and timers. A ran_infra
pointer hence allows complete abstraction of RAN implementations:

- managing connected RAN peers (BSC, RNC) in ran_peer.c,
- classifying and de-/encoding RAN PDUs,
- recording connected LACs and cell IDs and sending out Paging requests to
  matching RAN peers.

* RAN RESET now also for RANAP

ran_peer.c absorbs the reset_fsm from a_reset.c; in consequence, RANAP also
supports proper RESET semantics now. Hence osmo-hnbgw now also needs to provide
proper RESET handling, which it so far duly ignores. (TODO)

* RAN de-/encoding abstraction

The RAN abstraction mentioned above serves not only to separate RANAP and BSSAP
implementations transparently, but also to be able to optionally handle RAN on
distinct levels. Before Handover, all RAN messages are handled by the MSC-A
role.  However, after an inter-MSC Handover, a standalone MSC-I will need to
decode RAN PDUs, at least in order to manage Assignment of RTP streams between
BSS/RNC and MNCC call forwarding.

ran_msg.h provides a common API with abstraction for:

- receiving events from RAN, i.e. passing RAN decode from the BSC/RNC and
  MS/UE: struct ran_dec_msg represents RAN messages decoded from either BSSMAP
  or RANAP;
- sending RAN events: ran_enc_msg is the counterpart to compose RAN messages
  that should be encoded to either BSSMAP or RANAP and passed down to the
  BSC/RNC and MS/UE.

The RAN-specific implementations are completely contained by ran_msg_a.c and
ran_msg_iu.c.

In particular, Assignment and Ciphering have so far been distinct code paths
for BSSAP and RANAP, with switch(via_ran){...} statements all over the place.
Using RAN_DEC_* and RAN_ENC_* abstractions, these are now completely unified.

Note that SGs does not qualify for RAN abstraction: the SGs interface always
remains with the MSC-A role, and SGs messages follow quite distinct semantics
from the fairly similar GERAN and UTRAN.

* MGW and RTP stream management

So far, managing MGW endpoints via MGCP was tightly glued in-between
GSM-04.08-CC on the one and MNCC on the other side. Prepare for switching RTP
streams between different RAN peers by moving to object-oriented
implementations: implement struct call_leg and struct rtp_stream with distinct
FSMs each. For MGW communication, use the osmo_mgcpc_ep API that has originated
from osmo-bsc and recently moved to libosmo-mgcp-client for this purpose.
Instead of implementing a sequence of events with code duplication for the RAN
and CN sides, the idea is to manage each RTP stream separately by firing and
receiving events as soon as codecs and RTP ports are negotiated, and letting
the individual FSMs take care of the MGW management "asynchronously". The
caller provides event IDs and an FSM instance that should be notified of RTP
stream setup progress. Hence it becomes possible to reconnect RTP streams from
one GSM-04.08-CC to another (inter-BSC Handover) or between CC and MNCC RTP
peers (inter-MSC Handover) without duplicating the MGCP code for each
transition.

The number of FSM implementations used for MGCP handling may seem a bit of an
overkill. But in fact, the number of perspectives on RTP forwarding are far
from trivial:
- an MGW endpoint is an entity with N connections, and MGCP "sessions" for
  configuring them by talking to the MGW;
- an RTP stream is a remote peer connected to one of the endpoint's
  connections, which is asynchronously notified of codec and RTP port choices;
- a call leg is the higher level view on either an MT or MO side of a voice
  call, a combination of two RTP streams to forward between two remote peers.

  BSC                 MGW                PBX
                CI          CI
                [MGW-endpoint]
  [--rtp_stream--]          [--rtp_stream--]
  [----------------call_leg----------------]

* Use counts

Introduce using the new osmo_use_count API added to libosmocore for this
purpose. Each use token has a distinct name in the logging, which can be a
globally constant name or ad-hoc, like the local __func__ string constant.  Use
in the new struct msc_a, as well as change vlr_subscr to the new osmo_use_count
API.

* FSM Timeouts

Introduce using the new osmo_tdef API, which provides a common VTY
implementation for all timer numbers, and FSM state transitions with the
correct timeout. Originated in osmo-bsc, recently moved to libosmocore.

Depends: Ife31e6798b4e728a23913179e346552a7dd338c0 (libosmocore)
         Ib9af67b100c4583342a2103669732dab2e577b04 (libosmocore)
	 Id617265337f09dfb6ddfe111ef5e578cd3dc9f63 (libosmocore)
	 Ie9e2add7bbfae651c04e230d62e37cebeb91b0f5 (libosmo-sccp)
	 I26be5c4b06a680f25f19797407ab56a5a4880ddc (osmo-mgw)
	 Ida0e59f9a1f2dd18efea0a51680a67b69f141efa (osmo-mgw)
	 I9a3effd38e72841529df6c135c077116981dea36 (osmo-mgw)
Change-Id: I27e4988e0371808b512c757d2b52ada1615067bd
2019-05-08 17:02:32 +02:00
Neels Hofmeyr 7c5346cd70 vlr_subscr: use osmo_use_count
Depends: Ife31e6798b4e728a23913179e346552a7dd338c0 (libosmocore)
Change-Id: Ib06d030e8464abe415ff597d462ed40eeddef475
2019-04-12 02:15:25 +02:00
Sylvain Munaut da9f37ed20 libvlr: Allow 2G auth tuples to be re-used without going through AUTH
If the key_seq we get in the first messages matches the last_tuple, then
both we and the MS already know the key to use and we don't need the
AUTH REQUEST/RESPONSE cycle.

Security wise ... not so good, and so IMHO the 'auth required' option
in the MSC should always be set. But this allows to turn on ciphering on
a channel without doing any MM transaction, and so the MS doesn't turn
on the T3240 timer which allows to have a ciphered silent-call channel
that won't timeout.

Change-Id: Ief840a2ae7a0ffd2bf0bf726f209a79e3f787646
Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
2019-03-19 15:24:01 +00:00
Harald Welte 0df904dea9 Add SGs Interface
Add an SGs interface (3GPP TS 29.118) to osmo-msc in order to support
SMS tunneling and Circuit Switched Fallback (CSFB)

Change-Id: I73359925fc1ca72b33a1466e6ac41307f2f0b11d
Related: OS#3615
2019-02-04 13:36:26 +01:00
Philipp Maier ec5901c8f2 gsm_04_08: Fix nullpointer deref
The pointers conn, conn->vsub and conn->vsub->last_tuple are checked,
but before the check those pointers are already dereferenced during
assignment. This defeats the purpose of the check. Lets dereference
those pointers after the check.

Fixes: CID#190404
Change-Id: Ice4992606f3799eac13154ec0b9f53e46d2e178e
2019-01-12 10:26:00 +00:00
Neels Hofmeyr 5769d36b44 err log: fully log MS supported A5 algos on mismatch
Change-Id: Icb18e0f0bb420de066e7eb8fc683f192ba2a7368
2019-01-12 09:51:22 +00:00
Neels Hofmeyr b62289aa27 mm_rx_id_resp(): use osmo_mi_name()
Change-Id: I6bb053def223ed698351ad9f52c1e36293df5d59
2019-01-12 09:51:22 +00:00
Neels Hofmeyr 361e571815 refactor log ctx for vlr_subscr and ran_conn
ran_conn_get_conn_id(): instead of a talloc allocated string, return a static
buffer in ran_conn_get_conn_id(). So far this function had no callers.

Refactor ran_conn_update_id() API: during early L3-Complete, when no subscriber
is associated yet, update the FSM Id by the MI type seen in the L3 Complete
message: ran_conn_update_id_from_mi(). Later on set the vsub and re-update.

Call vlr.ops->subscr_update when the TMSI is updated, so that log context
includes the TMSI from then on.

Enrich context for vlr_subscr_name and ran_conn fi name.

Include all available information in vlr_subscr_name(); instead of either IMSI
or MSISDN or TMSI, print all of them when present. Instead of a short log,
rather have more valuable context.

A context info would now look like:

  Process_Access_Request_VLR(IMSI-901700000014706:MSISDN-2023:TMSI-0x08BDE4EC:GERAN-A-3:PAGING_RESP)

It does get quite long, but ensures easy correlation of any BSSAP / IuCS
messages with log output, especially if multiple subscribers are busy at the
same time.

Print TMSI and TMSInew in uppercase hexadecimal, which is the typical
representation in the telecom world.

When showing the RAN conn id
  GERAN_A-00000017
becomes
  GERAN-A-23
- We usually write the conn_id in decimal.
- Leading zeros are clutter and might suggest hexadecimal format.
- 'GERAN-A' and 'UTRAN-Iu' are the strings defined by osmo_rat_type_name().

Depends: I7798c3ef983c2e333b2b9cbffef6f366f370bd81 (libosmocore)
Depends: Ica25919758ef6cba8348da199b0ae7e0ba628798 (libosmocore)
Change-Id: I66a68ce2eb8957a35855a3743d91a86299900834
2019-01-12 09:51:22 +00:00
Neels Hofmeyr 7ce21dc589 rx CM Service Req: reject double use sooner
When a CM Service Req is being rejected, we should do so before changing the
state of the current conn.

Concerning multiple CM Service Requests: in fact we should store multiple
requests, but first fix the status quo of rejecting multiple requests.

Change-Id: I39209ee6662694aa054a2fc0d21eae76fb33e2f1
2019-01-12 09:51:22 +00:00
Neels Hofmeyr 46c06e28c1 add LOG_RAN_CONN() to use the conn->fi->id for context
For each conn, set a default logging category, to distinguish categories for
BSSMAP and RANAP based conns.

LOG_RAN_CONN(): log with the conn's default category,

LOG_RAN_CONN_CAT(): log with a manually set category (mostly for keeping
previous DMM logging on the same category).

In some places, replace LOGP() using manual context with LOG_RAN_CONN(), and
remove the manual context info, now provided by the conn->fi->id.

This is loosely related to inter-BSC and inter-MSC handover: to speed up
refactoring, I want to avoid the need for manual logging context and just use
this LOG_RAN_CONN().

Change-Id: I0a7809840428b1e028df6eb683bc5ffcc8df474a
2019-01-12 09:51:22 +00:00
Neels Hofmeyr 55d22d9e5e use osmo_lu_type_name() from libosmocore
Change-Id: Ib562bb5fb272c0c3ae0849f32b28faa2c26f9bb7
2019-01-12 09:51:22 +00:00
Vadim Yanitskiy 82cc8a5cfa libmsc/gsm_04_11.c: accept MT SMS messages over GSUP
Change-Id: I57357982ca0e51f6722c24a4aa1d0fb3e6caef88
Depends-on: (core) Ibe325c64ae2d6c626b232533bb4cbc65fc2b5d71
Depends-on: (OsmoHLR) I0589ff27933e9bca2bcf93b8259004935778db8f
Related Change-Id: (TTCN) I63a25c8366cce0852df6b628365151661a22a25f
Related: OS#3587
2019-01-11 21:42:43 +00:00
Neels Hofmeyr 7814a83298 use osmo_rat_type from libosmocore
Replace locally defined enum ran_type with libosmocore's new enum
osmo_rat_type, and value_string ran_type_names with osmo_rat_type_names.

The string representations change, which has cosmetic effects on the test suite
expectations.

Depends: I659687aef7a4d67ca372a39fef31dee07aed7631 (libosmocore)
Change-Id: I2c78c265dc99df581e1b00e563d6912c7ffdb36b
2019-01-04 17:26:14 +00:00
Neels Hofmeyr 1035d90c17 fix vlr ops.subscr_assoc re-association
In rare cases, a conn is already associated with a subscriber. So far, we
abort()ed on that, bringing the entire osmo-msc down. Rather log an error and
keep the service running.

In vlr.ops.subscr_assoc, add success/failure return value, and abort the
LU/PARQ on error.

I haven't figured out in detail yet why/how a subscriber would re-launch a
LU/PARQ on a conn that is already associated, so far it is merely clear that we
do not want to crash the MSC if that happens. A log is in OS#3742.

Related: OS#3742, OS#3743
Change-Id: Ic0d54644bc735700220b1ef3a4384c217d57d20f
2019-01-04 01:46:46 +00:00
Vadim Yanitskiy 76ef72dda8 libmsc/gsm_04_11.c: forward MO SMS messages over GSUP
Change-Id: I7d651fde3d608d02f275a74043dc42262aabb1b8
Depends-on: (core) Ic37f3b2114b8095cfce22977e67133b9103942e3
Depends-on: (core) Ibe325c64ae2d6c626b232533bb4cbc65fc2b5d71
Depends-on: (OsmoHLR) I0589ff27933e9bca2bcf93b8259004935778db8f
Related Change-Id: (TTCN) I7abc95b8e416f7308d54e11be11c08586d18e6c5
Related Change-Id: (TTCN) Id14bbd8bd51558cdacefea0fe042769cd69ed5c8
Related: OS#3587
2018-12-30 11:48:22 +01:00
Stefan Sperling 36dedeeb12 provide software version information to gsup peer
Provide software version information to the GSUP peer. The version now
shows up in logs like this: Software_Version='osmo-msc-1.2.0.120-1263b'

Change-Id: I2eba32569349facdbb1fda201067c62cc804ccf4
Depends: I317d6c59f77e92fbb2b875a83dc0ec2fa5cb6006
Related: OS#3355
2018-12-11 13:08:00 +00:00
Stefan Sperling afa030d6f9 make gsup ipa name configurable in osmo-msc.cfg
Add a 'ipa-name' VTY command which overrides the default IPA name
used by the MSC. This is a prerequisite for inter-MSC handover.

Related: OS#3355
Change-Id: I317d6c59f77e92fbb2b875a83dc0ec2fa5cb6006
2018-12-11 13:08:00 +00:00
Neels Hofmeyr 325f106b34 drop gsm48 RR ciph mode compl from permitted initial messages
It is a message that is initially permitted, but it is in fact not handled in
the L3 code but already before, upon receiving
BSS_MAP_MSG_CIPHER_MODE_COMPLETE.

Change-Id: I0079f07271ca76bd457d0e700f3a736eb9066b47
2018-12-10 14:21:03 +01:00
Neels Hofmeyr 8b6e536007 move gsm_auth_tuple to vlr.h as vlr_auth_tuple
Along goes GSM_KEYSEQ_INVAL as VLR_*.

It's where it logically belongs, and is almost the only reason why vlr.h
includes gsm_data.h. The remaining reason, GSM_EXTENSION_LENGTH, will be moved
by upcoming patch.

Change-Id: I122feae7ee3cbc59e941daef35a954bce29fec76
2018-11-30 22:46:15 +01:00
Neels Hofmeyr 7992122bac combine several small .h in msc_common.h
For hysterical raisins, there are some header files that contain few
declarations, and where the name doesn't reflect the content. Combine them to
new msc_common.h:

- common.h
- common_cs.h
- osmo_msc.h

Change-Id: I9e3a587342f8d398fb27354a2f2475f8797cdb28
2018-11-30 22:46:15 +01:00
Neels Hofmeyr 3c20a5ee74 rename some RAN conn related stuff to ran_conn_*
Following previous rename of gsm_subscriber_connection:

Some functions and #defines are still called like "msc_conn" or just "msc_",
while they are clearly about a RAN conn.

To avoid confusion with the future separate concepts of MSC roles and a RAN
connection, rename all those to match the common "ran_conn" prefix.

Change-Id: Ia17a0a35f11911e00e19cafb5d7828d729a69640
2018-11-30 22:46:13 +01:00
Neels Hofmeyr c036b79918 rename gsm_subscriber_connection to ran_conn
In preparation for inter-BSC and inter-MSC handover, we need to separate the
subscriber management logic from the actual RAN connections. What better time
to finally rename gsm_subscriber_connection.

* Name choice:

In 2G, this is a connection to the BSS, but even though 3GPP TS commonly talk
of "BSS-A" and "BSS-B" when explaining handover, it's not good to call it
"bss_conn": in 3G a BSS is called RNS, IIUC.

The overall term for 2G (GERAN) and 3G (UTRAN) is RAN: Radio Access Network.

* Rationale:

A subscriber in the MSC so far has only one RAN connection, but e.g. for
inter-BSC handover, a second one needs to be created to handover to. Most of
the items in the former gsm_subscriber_connection are actually related to the
RAN, with only a few MM and RTP related items. So, as a first step, just rename
it to ran_conn, to cosmetically prepare for moving the not strictly RAN related
items away later.

Also:

- Rename some functions from msc_subscr_conn_* to ran_conn_*
- Rename "Subscr_Conn" FSM instance name to "RAN_conn"
- Rename SUBSCR_CONN_* to RAN_CONN_*

Change-Id: Ic595f7a558d3553c067f77dc67543ab59659707a
2018-11-30 22:45:42 +01:00
Neels Hofmeyr f41658d52e rename gsm_encr to geran_encr, it is only applicable on GERAN
On UTRAN, Security Mode is used instead of Ciphering Command, which does not
feature an A5 algorithm id.

Change-Id: Idc7ca9da1aa13ae16f5db2cb1024676cbc770820
2018-11-30 22:44:23 +01:00
Neels Hofmeyr b0779bbcab populate gsm_subscriber_connection->encr during Ciph
The gsm_subscriber_connection->encr is never used. Use it.

When sending the Ciphering Mode Command, populate the encryption key.
When receivint the Ciphering Mode Complete, populate the chosen alg_id.

Out of paranoia, store the enc key only if the size is large enough.

Hence the vty_dump_one_conn() now reports the actually chosen A5 algorithm ID
used.

For 3G connections, though, this will still remain 0 in the VTY, since there is
no explicit A5 algorithm negotiated on UTRAN. (Security Mode Command and
Security Mode Complete instead of the GERAN Ciphering.)

(Note, 'struct gsm_encr encr' will be renamed to 'struct geran_encr geran_encr'
in Idc7ca9da1aa13ae16f5db2cb1024676cbc770820)

Change-Id: Ice2c470c360612249f97301944c6fdf9443c7dce
2018-11-30 22:44:23 +01:00
Harald Welte f6400737f9 gsm0407_is_duplicate(): Handle error ret of gsm0407_pdisc_ctr_bin()
Change-Id: If9525694bcbc5c6c0e622e899dd634dc11ed61c4
Fixes: Coverity CID#182702
2018-10-21 12:56:20 +02:00
Neels Hofmeyr 68cf957bfd fix Classmark Update without VLR subscriber
This recent patch moves Classmark storage to the VLR subscriber, and introduced
a segfault when a Classmark Update is received during IMSI detach:

commit 986fe7ed18
change-id I27081bf6e9e017923b2d02607f7ea06beddad82a
Mon Sep 17 01:12:13 2018 +0200
"store classmark in vlr_subscr, not conn"

It assumed that we would never accept any Classmark Update messages unless we
also have a valid subscriber for it. Well, that is proven wrong by the
ttcn3-msc-test TC_imsi_detach_by_imsi(), which brings osmo-msc to its knees.

Fix: in case of no valid vlr_subscr being present, store Classmark in the conn
temporarily, and copy any received Classmark to VLR subscriber as soon as it
gets associated with the conn (if at all).

Change-Id: Ib2a2ae6bf86e8f29fc6751a8b5cdb7187cd70290
2018-09-18 16:13:58 +02:00
Neels Hofmeyr 3117b701c8 A5/n Ciph: request Classmark Update if missing
When the VLR requests a Ciphering Mode with vlr_ops.set_ciph_mode(), and if we
need a ciph algo flag from a Classmark information that is not yet known
(usually CM 2 during LU), send a BSSMAP Classmark Request to get it.

To manage the intermission of the Classmark Request, add
- msc_classmark_request_then_cipher_mode_cmd(),
- state SUBSCR_CONN_S_WAIT_CLASSMARK_UPDATE,
- event SUBSCR_CONN_E_CLASSMARK_UPDATE.

From state AUTH_CIPH, switch to state WAIT_CLASSMARK_UPDATE. Once the BSSMAP
Classmark Response, is received, switch back to SUBSCR_CONN_S_AUTH_CIPH and
re-initiate Ciphering Mode.

To be able to re-enter the Ciphering Mode algo decision, factor it out into
msc_geran_set_cipher_mode().

Rationale:

In the following commit, essentially we stopped supporting A5/3 ciphering:

commit 71330720b6
"MSC: Intersect configured A5 algorithms with MS-supported ones"
Change-Id: Id124923ee52a357cb7d3e04d33f585214774f3a3

A5/3 was no longer supported because from that commit on, we strictly checked
the MS-supported ciphers, but we did not have Classmark 2 available during
Location Updating.

This patch changes that: when Classmark 2 is missing, actively request it by a
BSSMAP Classmark Request; continue Ciphering only after the Response. Always
request missing Classmark, even if a lesser cipher were configured available.

If the Classmark Update response fails to come in, cause an attach failure.
Instead, we could attempt to use a lesser cipher that is also enabled. That is
left as a future feature, should that become relevant. I think it's unlikely.

Technically, we could now end up requesting a Classmark Updating both during LU
(vlr_lu_fsm) and CM Service/Paging Response (proc_arq_fsm), but in practice the
only time we lack a Classmark is: during Location Updating with A5/3 enabled.
A5/1 support is indicated in CM1 which is always available, and A5/3 support is
indicated in CM2, which is always available during CM Service Request as well
as Paging Response. So this patch has practical relevance only for Location
Updating. For networks that permit only A5/3, this patch fixes Location
Updating. For networks that support A5/3 and A5/1, so far we always used A5/1
during LU, and after this patch we request CM2 and likely use A5/3 instead.

In msc_vlr_test_gsm_ciph, verify that requesting Classmark 2 for A5/3 works
during LU. Also verify that the lack of a Classmark Response results in attach
failure.

In msc_vlr_test_gsm_ciph, a hacky unit test fakes a situation where a CM2 is
missing during proc_arq_fsm and proves that that code path works, even though
the practical relevance is currently zero. It would only become interesting if
ciphering algorithms A5/4 and higher became relevant, because support of those
would be indicated in Classmark 3, which would always require a Classmark
Request.

Related: OS#3043
Depends: I4a2e1d3923e33912579c4180aa1ff8e8f5abb7e7 (libosmocore)
Change-Id: I73c7cb6a86624695bd9c0f59abb72e2fdc655131
2018-09-17 02:08:07 +02:00
Neels Hofmeyr 986fe7ed18 store classmark in vlr_subscr, not conn
Store all Classmark information in the VLR.

So, we now always know the Classmark 1 (mandatory IE for LU). This is visible
in the msc_vlr_tests -- they no longer indicate "assuming A5/1 is supported"
because classmark 1 is missing, because we now know the Classmark 1.

Rationale:

During Location Updating, we receive Classmark 1; during CM Service Request and
Paging Response, we receive Classmark 2. So far we stored these only for the
duration of the conn, so as soon as a LU is complete, we would forget CM1.

In other words, for anything else than a LU Request, we had no Classmark 1
available at all.

During Ciphering Mode Command, we rely on Classmark 1 to determine whether A5/1
is supported. That is moot if we don't even have a Classmark 1 for any CM
Service Request or Paging Response initiated connections.

The only reason that A5/1 worked is that we assume A5/1 to work if Classmark 1
is missing. To add to the confusion, if a phone indicated that it did *not*
support A5/1 in the Classmark 1, according to spec we're supposed to not
service it at all. A code comment however says that we instead want to heed the
flag -- which so far was only present in a Location Updating initiated
connection. Now we can make this decision without assuming things.

This got my attention while hacking on sending a BSSMAP Classmark Request from
the MSC if it finds missing Classmark information, and was surprised to see it
it lacking CM1 to decide about A5/1.

Change-Id: I27081bf6e9e017923b2d02607f7ea06beddad82a
2018-09-17 01:12:13 +02:00
Vadim Yanitskiy 8a6ef55ec5 libmsc/gsm_09_11.c: forward SS/USSD messages to HLR over GSUP
In order to be able to support external SS/USSD gateway, we should
not terminate the GSM 04.80 messages at OsmoMSC. Instead, we need
to follow the GSM TS 09.11 specification, and forward all messages
unhandled by OsmoMSC to OsmoHLR over GSUP protocol.

This change implements forwarding of MO SS/USSD messages. The
forwarding assumes transcoding between GSM 04.80 messages and
GSUP messages. The payload of Facility IE is carried 'as is'.

As a side-effect, this will disable the osmo-msc internal handler
implementing the "*#100#" for obtaining the subscribers own phone
number.  In order to re-gain this functionality, you will need a
modern osmo-hlr (Change-Id I1d09fab810a6bb9ab02904de72dbc9e8a414f9f9)
and the following line in your osmo-hlr.cfg:
 hlr
  ussd route prefix *#100# internal own-msisdn

TTCN-3 test case: I01de73aced6057328a121577a5a83bc2615fb2d4
Change-Id: Ide5f7e350b537db80cd8326fc59c8bf2e01cb68c
2018-07-30 15:35:14 +00:00
Vadim Yanitskiy 8a0e2588e2 libvlr/vlr.c: forward unhandled GSUP messages towards MSC
Some internal sub-systems, such as SS/USSD or SMS implementation,
may also need to use GSUP connection with HLR. Previously, it was
only available within the libvlr code, and nowhere else.

Let's introduce the generic GSUP message router, which will
receive messages unhandled by VLR itself, and route them to
a handler depending on the message type.

Change-Id: Ib8146ce5788c8f249dcaa39d61bd0388574bf892
2018-07-29 16:22:06 +02:00
Harald Welte 27989d41dc libmsc: move L3 call-control to separate C file (gsm_04_08_cc.c)
The CC sub-layer is fairly self-contained, so let's move it to
a separate C source file.  The old gsm_04_08.c file now only
contains the 04.07 / DTAP core and MM sub-layer handling.

I did this initially as an experiment to see how self-contained
our CC implementation really is.  Given this rather straight-forward
patch builds fine, CC really is self-contained (yay!).

Change-Id: Idb8dd7a8d9d8b4a28c492f12da3cc3305b695cca
2018-07-25 18:53:57 +00:00
Vadim Yanitskiy f5b9e6cdf6 libmsc/gsm_04_08.c: expose gsm48_tx_simple()
This function could be also used by other parts of code, e.g.
by gsm_04_11.c or by gsm_09_11.c, during initialization of
a new transaction. No need to hide it.

Change-Id: I9a9d17fca4901163dae10d76455aa4cf54497156
2018-06-12 23:07:26 +07:00
Vadim Yanitskiy 5b860faf4e Use proper naming for GSM TS 09.11 implementation
During a long time, we had both file and symbol names, actually
related to Supplementary Services, with the 'ussd' abbreviation.
This is not absolutely wrong, but isn't correct at the same time.

USSD is a kind of Supplementary Services, this is only a part
of them. There are also 'structured' Supplementary Services,
which can be call related or call independent.

The "Signalling interworking for supplementary services" is
defined by GSM TS 09.11, and this is exactly what MSC should
implement. Let's use the specification number for naming, as
we do e.g. in the GSM 04.11 (SMS) implementation.

Change-Id: Ic1eaceddb58132318e4e941be542da34b8ebefe1
2018-06-12 06:14:36 +07:00
Pau Espin 86f212666a setup_trig_pag_evt: Fix heap-use-after-free
Catched by osmo-gsm-tester running test voice:octphy.

Fixes following AddressSanitizer report:
==18864==ERROR: AddressSanitizer: heap-use-after-free on address 0x61a000016f18 at pc 0x55f1b29eee5c bp 0x7ffdaa2ac000 sp 0x7ffdaa2abff8
WRITE of size 8 at 0x61a000016f18 thread T0
    #0 0x55f1b29eee5b in setup_trig_pag_evt osmo-msc/src/libmsc/gsm_04_08.c:1490
    #1 0x55f1b2a086c1 in subscr_paging_dispatch osmo-msc/src/libmsc/gsm_subscriber.c:101
    #2 0x7fb88e07c1c9 in osmo_timers_update libosmocore/src/timer.c:257
    #3 0x7fb88e07f1b1 in osmo_select_main libosmocore/src/select.c:253
    #4 0x55f1b29b600b in main osmo-msc/msc_main.c:694
    #5 0x7fb88bebe2e0 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x202e0)
    #6 0x55f1b29b69f9 in _start (osmo-msc/bin/osmo-msc+0xf09f9)

Related: OS#3198

Change-Id: Ie7fdca4d48e247c77a53e81aec2b6bacd8fef678
2018-04-24 14:02:03 +02:00
Pau Espin 3f8cec8f66 setup_trig_pag_evt: Always log correct paging failure case
Change-Id: I5c7a49b42b6ced1a5e0afb3485eaf94ef55bbf23
2018-04-24 13:52:00 +02:00
Pau Espin 25adebea4c setup_trig_pag_evt: Remove uneeded default case in switch statement
Take the chance to  pass a var of type enum instead, so the compiler
warns us if a new enum value is added. For instance, if we remove
GSM_PAGING_EXPIRED from the switch statement:

src/libmsc/gsm_04_08.c:1463:2: warning: enumeration value ‘GSM_PAGING_EXPIRED’ not handled in switch [-Wswitch]
  switch (paging_event) {
  ^~~~~~

Change-Id: I65d871704b9636c594dc982200fbe7f7ce6784f5
2018-04-24 11:47:00 +02:00
Neels Hofmeyr 158095960b refactor VLR FSM result handling
Instead of keeping separate enums for FSM results and translating between those
and the actual 04.08 reject causes that will ultimately reach the MS, just pass
enum gsm48_reject_value cause codes around everywhere.

Collapse some VLR *_timeout() and *_cancel() api to just *_cancel() with a
gsm48 cause arg.

(Hopefully) improve a few reject causes, but otherwise just aim for more
transparent decisions on which cause value is used, for future fixes of
returned causes.

Depends: I6661f139e68a498fb1bef10c266c2f064b72774a (libosmocore)
Change-Id: I27bf8d68737ff1f8dc6d11fb1eac3d391aab0cb1
2018-04-12 19:40:00 +00:00
Neels Hofmeyr e3d3dc6ea2 refactor subscr_conn and subscr_conn_fsm de-/alloc
Refactor:

1. Glue the gsm_subscriber_connection alloc to the subscr_conn_fsm.
2. Add separate AUTH_CIPH state to the FSM.
3. Use conn->use_count to trigger conn release.
4. Add separate RELEASING state to the FSM.
5. Add rate counters for each of the three Complete Layer 3 types.

Details:

1. Glue the gsm_subscriber_connection alloc to the subscr_conn_fsm.

Historically, a gsm_subscriber_connection was allocated in libbsc land, and
only upon Complete Layer 3 did libmsc add the fsm instance. After splitting
openbsc.git into a separate osmo-msc, this is no longer necessary, hence:

Closely tie gsm_subscriber_connection allocation to the subscr_conn_fsm
instance: talloc the conn as a child of the FSM instance, and discard the conn
as soon as the FSM terminates.

2. Add separate AUTH_CIPH state to the FSM.

Decoding the Complete Layer 3 message is distinctly separate from waiting for
the VLR FSMs to conclude. Use the NEW state as "we don't know if this is a
valid message yet", and the AUTH_CIPH state as "evaluating, don't release".

A profound effect of this: should we for any odd reason fail to leave the FSM's
NEW state, the conn will be released right at the end of msc_compl_l3(),
without needing to trigger release in each code path.

3. Use conn->use_count to trigger conn release.

Before, the FSM itself would hold a use count on the conn, and hence we would
need to ask it whether it is ready to release the conn yet by dispatching
events, to achieve a use_count decrement.

Instead, unite the FSM instance and conn, and do not hold a use count by the
FSM. Hence, trigger an FSM "UNUSED" event only when the use_count reaches zero.
As long as use counts are done correctly, the FSM will terminate correctly.

These exceptions:

- The new AUTH_CIPH state explicitly ignores UNUSED events, since we expect the
  use count to reach zero while evaluating Authentication and Ciphering. (I
  experimented with holding a use count by AUTH_CIPH onenter() and releasing by
  onleave(), but the use count and thus the conn are released before the next
  state can initiate transactions that would increment the use count again.
  Same thing for the VLR FSMs holding a use count, they should be done before
  we advance to the next state. The easiest is to simply expect zero use count
  during the AUTH_CIPH state.)

- A CM Service Request means that even though the MSC would be through with all
  it wants to do, we shall still wait for a request to follow from the MS.
  Hence the FSM holds a use count on itself while a CM Service is pending.

- While waiting for a Release/Clear Complete, the FSM holds a use count on
  itself.

4. Add separate RELEASING state to the FSM.

If we decide to release for other reasons than a use count reaching zero, we
still need to be able to wait for the msc_dtap() use count on the conn to
release.

(An upcoming patch will further use the RELEASING state to properly wait for
Clear Complete / Release Complete messages.)

5. Add rate counters for each of the three Complete Layer 3 types.

Besides LU, also count CM Service Request and Paging Response
acceptance/rejections. Without these counters, only very few of the auth+ciph
outcomes actually show in the counters.

Related: OS#3122
Change-Id: I55feb379e176a96a831e105b86202b17a0ffe889
2018-04-11 21:39:44 +00:00
Neels Hofmeyr dc2514b220 CC: intentionally release T308 on BSSMAP Clear Request from BSC
So far we hit a running T308 during CC release when caused by a BSSMAP Clear
Request, and we loudly log that as error.

However, now I understand that T308 is a direct cause of the dispatch of a REL
IND towards MNCC, which is used to indicate teardown to MNCC. So during
_gsm48_cc_trans_free(), we first clear all timers, then invoke
mncc_release_ind() which starts another timer (useful for graceful CC Release,
but in this code path the intention is immediate release). Simply immediately
cancel the timer again and release the conn.

A separate question is whether a BSSMAP Clear Request should be less aggressive
in releasing the connections; i.e. instead of calling trans_free() all around,
to rather ask each transaction to "please stop soon", somehow.

Related: OS#3062
Change-Id: I231fdb574a086a206321148474cbdc7ca9cf39f0
2018-04-11 21:39:44 +00:00
Harald Welte 0e2fa5dcb5 DTAP: Ensure proper DLCI is used in MSC-originated DTAP
The DLCI field of the DTAP header indicates the SAPI as well as the
data link (main DCCH or SACCH).  We must make sure to use the correct
DLCI when sending DTAP to the BSC.

We achieve this by
* storing the DLCI in the msgb->cb while parsing the DTAP header
* storing the received DLCI (from msgb->cb) in the transaction for
  mobile-originated transactions
* using the trans->dlci to sent msgb->cb when transmitting L3
* filling the DTAP DLCI value from msgb->cb when transmitting DTAP

For MSC-originated transactions, we choose a DLCI value corresponding
to the service (SAPI=0 for CC, SAPI=3 for SMS) and store that in
trans->dlci.

Closes: OS#3150
Change-Id: If511b20f52575054cab1346d99a8cb68d827fdbf
2018-04-09 16:41:10 +02:00
Neels Hofmeyr 16c42b5fba subscr_conn: store complete_layer3_type in conn, not FSM event arg
Instead of jumping through hoops to pass the Complete Layer 3 operation that
created this conn via FSM event dispatch parameters, put it right in the
gsm_subscriber_connection struct, where it always belonged.

Move definition of the enum complete_layer3_type to gsm_data.h, where
gsm_subscriber_connection is defined.

Introduce msc_subscr_conn_update_id() to set the complete_layer3_type of the
conn as soon as a Complete Layer 3 message is received.

In msc_subscr_conn_update_id(), already include an mi_string argument to
prepare for an upcoming patch where the FSM will be allocated much earlier when
the Mobile Identity is not known yet, and we'll also update the fi->id here.

The odd logging change in the msc_vlr_tests output uncovers a wrong use of the
osmo_fsm_inst_dispatch() data argument for SUBSCR_CONN_E_CN_CLOSE events: if a
child FSM signals unsuccessful result, instead of the failure cause, it passed
the complete_layer3_type, as requested upon FSM allocation, which was then
misinterpreted as a failure cause. Now a child FSM failure will pass NULL
instead, while other SUBSCR_CONN_E_CN_CLOSE events may still pass a valid cause
value.

Related: OS#3122
Change-Id: Iae30dd57a8861c4eaaf56999f872d4e635ba97fb
2018-04-03 02:13:16 +02:00
Neels Hofmeyr 1ba0df26dc cosmetic: rename subscr_conn_from to complete_layer3_type
'subscr_conn_from' could mean anything: from what, RAN type? BSS identifier? MM
action? Clearly name it as the Complete Layer 3 kind it represents.

Related: OS#3122
Change-Id: I6263a80e6db01c2ca48df6c58b05e2fd19347057
2018-04-03 02:13:09 +02:00
Neels Hofmeyr 4d3a66b3f8 cosmetic: rename gsm_subscriber_connection->conn_fsm to ->fi
Match osmo-bsc's naming of the subscriber connection's FSM instance; 'conn->fi'
makes more sense anyway than 'conn->conn_fsm'.

BTW, an upcoming commit will do away with the legacy from libbsc/libmsc duality
and firmly glue the conn allocation to the fi.

Related: OS#3122
Change-Id: If442f2ba78d9722b1065ec30c9a13f372b6a8caa
2018-04-03 02:13:04 +02:00
Neels Hofmeyr 79e580b6ff dissolve libcommon-cs: move gsm48_* code to libmsc, drop sms_next_rp_msg_ref()
Move gsm48_* functions from common_cs.c to libmsc/gsm_04_08.c.

Drop sms_next_rp_msg_ref(), it is just a bunch of bloat around "next_rp_ref++".
Apply the "++" instead, in gsm_04_11.c.

libcommon-cs is now empty, to be removed in subsequent commit.

Change-Id: Ibc410803ce8e273b626124ab9fc934f04df3ae50
2018-03-22 17:10:49 +01:00
Neels Hofmeyr 9d74425e27 dissolve libcommon: drop gsm_data.c, move code to libmsc
classmark_is_r99() is only used in gsm_04_08.c, move there as static.
rrlp_mode_* is only used in msc_vty.c, move there as static.
Move ran_type_names[] to msc_ifaces.c.

Change-Id: I5381c72af6841829fbc65940fd7d6f4d5cf583df
2018-03-22 17:06:51 +01:00
Neels Hofmeyr 3cffc2055d cosmetic: gsm_04_08.c: drop unused struct gsm_lai
Change-Id: I3236841b1701dc902754d4a388c7806b0685a91e
2018-03-21 18:07:20 +00:00
Philipp Maier c813355a73 cosmetic: remove disabled (debug) code gsm_04_08.c
gsm_04_08.c seems to contain some lines of old debug code that
is commented out. Presumably the commented lines are a leftover
from a debug session.

- remove those commented code lines

Change-Id: Ifb84e4b0696fef1326c3f9ebc8427581057db44f
2018-03-15 11:16:17 +00:00
Stefan Sperling 3a74128ccc restore sending of optional MM info messages
Since commit 2483f1b050 the function
gsm48_tx_mm_info() was not called anymore. No MM info messages were
transmitted to phones even if MM info messages were enabled via VTY.

With this commit, we call gsm48_tx_mm_info() after successfully
processing an IMSI ATTACH location update.

Change-Id: Ice5963d84253eb8c803cd2dfa8b25a4db5382827
Related: OS#2850
2018-03-13 21:13:27 +01:00
Neels Hofmeyr d97821f8e5 cosmetic: gsm48_rx_mm_auth_resp(): log 'UMTS AUTH', not 'R99 AUTH'
Change-Id: Iba43c685cbe238d96175267e9cc954b2f2f3e7fc
2018-03-10 22:22:56 +01:00