2010-03-29 06:47:44 +00:00
|
|
|
/* GSM Mobile Radio Interface Layer 3 messages on the A-bis interface
|
2008-12-23 20:25:15 +00:00
|
|
|
* 3GPP TS 04.08 version 7.21.0 Release 1998 / ETSI TS 100 940 V7.21.0 */
|
|
|
|
|
2016-06-19 16:06:02 +00:00
|
|
|
/* (C) 2008-2016 by Harald Welte <laforge@gnumonks.org>
|
2012-12-26 09:17:42 +00:00
|
|
|
* (C) 2008-2012 by Holger Hans Peter Freyther <zecke@selfish.org>
|
2008-12-25 23:28:35 +00:00
|
|
|
*
|
2008-12-23 20:25:15 +00:00
|
|
|
* All Rights Reserved
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
2011-01-01 14:25:50 +00:00
|
|
|
* 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
|
2008-12-23 20:25:15 +00:00
|
|
|
* (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
|
2011-01-01 14:25:50 +00:00
|
|
|
* GNU Affero General Public License for more details.
|
2008-12-23 20:25:15 +00:00
|
|
|
*
|
2011-01-01 14:25:50 +00:00
|
|
|
* 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/>.
|
2008-12-23 20:25:15 +00:00
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
2016-05-24 12:23:27 +00:00
|
|
|
#include <stdbool.h>
|
2008-12-23 20:25:15 +00:00
|
|
|
#include <errno.h>
|
2008-12-30 17:56:55 +00:00
|
|
|
#include <time.h>
|
2008-12-27 01:55:51 +00:00
|
|
|
#include <netinet/in.h>
|
2016-05-24 12:23:27 +00:00
|
|
|
#include <regex.h>
|
|
|
|
#include <sys/types.h>
|
2008-12-23 20:25:15 +00:00
|
|
|
|
2012-04-08 14:59:24 +00:00
|
|
|
#include "bscconfig.h"
|
|
|
|
|
2017-09-04 13:04:35 +00:00
|
|
|
#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>
|
2018-06-11 22:24:52 +00:00
|
|
|
#include <osmocom/msc/gsm_09_11.h>
|
2017-09-04 13:04:35 +00:00
|
|
|
#include <osmocom/msc/signal.h>
|
|
|
|
#include <osmocom/msc/transaction.h>
|
|
|
|
#include <osmocom/msc/silent_call.h>
|
|
|
|
#include <osmocom/msc/mncc_int.h>
|
src: port openBSC over libosmo-abis
This is a big patch that ports openBSC over libosmo-abis.
Sorry, the changes that are included here are all dependent
of libosmo-abis, splitting them into smaller pieces would
leave the repository in some intermediate state, which is
not desired.
The main changes are:
- The directory libabis/ has been removed as it now lives in
libosmo-abis.
- new configuration file format for nanoBTS and HSL femto, we
need to define the virtual e1_line and attach it to the OML
link.
- all the existing BTS drivers (nanoBTS, hsl femto, Nokia site,
BS11 and rbs2000) now use the new libosmo-abis framework.
- use r232 input driver available in libosmo-abis for bs11_config.
- use ipa_msg_recv instead of old ipaccess_read_msg function.
- delete definition of gsm_e1_subslot and input_signal_data.
These structures now lives in libosmo-abis.
Most of this patch are deletions of libabis/ which has been
moved to libosmo-abis.
This patch also modifies openBSC to use all the new definitions
available in libosmocore and libosmo-abis. In order to do that,
we have replaced the following:
- DINP, DMI, DMIB and DMUX by their respective DL* correspondences.
- SS_GLOBAL by SS_L_GLOBAL
- SS_INPUT by SS_L_INPUT
- S_GLOBAL_SHUTDOWN by S_L_GLOBAL_SHUTDOWN
- SS_INPUT by SS_L_INPUT
- S_INP_* by S_L_INP_* sub-signals
- E1INP_NODE by L_E1INP_NODE vty node
This patch has been tested with:
- one nanoBTS
- the HSL femto with the examples available under libosmo-abis
- BS11 with both dahdi and misdn drivers.
2011-08-17 20:44:07 +00:00
|
|
|
#include <osmocom/abis/e1_input.h>
|
2011-03-22 15:47:59 +00:00
|
|
|
#include <osmocom/core/bitvec.h>
|
2017-09-04 13:04:35 +00:00
|
|
|
#include <osmocom/msc/vlr.h>
|
|
|
|
#include <osmocom/msc/msc_ifaces.h>
|
2010-09-30 10:52:23 +00:00
|
|
|
|
2011-03-22 15:47:59 +00:00
|
|
|
#include <osmocom/gsm/gsm48.h>
|
|
|
|
#include <osmocom/gsm/gsm0480.h>
|
|
|
|
#include <osmocom/gsm/gsm_utils.h>
|
2016-04-18 21:11:18 +00:00
|
|
|
#include <osmocom/gsm/protocol/gsm_04_08.h>
|
2011-03-22 15:47:59 +00:00
|
|
|
#include <osmocom/core/msgb.h>
|
|
|
|
#include <osmocom/core/talloc.h>
|
2017-01-13 02:12:08 +00:00
|
|
|
#include <osmocom/core/utils.h>
|
2017-11-07 16:19:25 +00:00
|
|
|
#include <osmocom/core/byteswap.h>
|
2011-03-22 15:47:59 +00:00
|
|
|
#include <osmocom/gsm/tlv.h>
|
2016-05-20 19:59:55 +00:00
|
|
|
#include <osmocom/crypt/auth.h>
|
|
|
|
#ifdef BUILD_IU
|
2017-07-05 13:19:52 +00:00
|
|
|
#include <osmocom/ranap/iu_client.h>
|
2016-05-20 19:59:55 +00:00
|
|
|
#endif
|
2008-12-23 20:25:15 +00:00
|
|
|
|
2017-09-04 13:04:35 +00:00
|
|
|
#include <osmocom/msc/msc_ifaces.h>
|
|
|
|
#include <osmocom/msc/a_iface.h>
|
2017-11-07 16:19:25 +00:00
|
|
|
#include <osmocom/msc/msc_mgcp.h>
|
2017-04-09 10:32:51 +00:00
|
|
|
|
2013-07-06 09:45:38 +00:00
|
|
|
#include <assert.h>
|
|
|
|
|
mscsplit: various preparations to separate MSC from BSC
Disable large parts of the code that depend on BSC presence. The code sections
disabled by #if BEFORE_MSCSPLIT shall be modified or dropped in the course of
adding the A-interface.
Don't set msg->lchan nor msg->dst.
Don't use lchan in libmsc.
Decouple lac from bts.
Prepare entry/exit point for MSC -> BSC and MSC -> RNC communication:
Add msc_ifaces.[hc], a_iface.c, with a general msc_tx_dtap() to redirect to
different interfaces depending on the actual subscriber connection.
While iu_tx() is going to be functional fairly soon, the a_tx() is going to be
just a dummy for some time (see comment).
Add Iu specific fields in gsm_subscriber_connection: the UE connection pointer
and an indicator for the Integrity Protection status on Iu (to be fully
implemented in later commits).
Add lac member to gsm_subscriber_connection, to allow decoupling from
bts->location_area_code. The conn->lac will actually be set in iu.c in an
upcoming commit ("add iucs.[hc]").
move to libcommon-cs: gsm48_extract_mi(), gsm48_paging_extract_mi().
libmsc: duplicate gsm0808 / gsm48 functions (towards BSC).
In osmo-nitb, libmsc would directly call the functions on the BSC level, not
always via the bsc_api. When separating libmsc from libbsc, some functions are
missing from the linkage.
Hence duplicate these functions to libmsc, add an msc_ prefix for clarity, also
add a _tx to gsm0808_cipher_mode():
* add msc_gsm0808_tx_cipher_mode() (dummy/stub)
* add msc_gsm48_tx_mm_serv_ack()
* add msc_gsm48_tx_mm_serv_rej()
Call these from libmsc instead of
* gsm0808_cipher_mode()
* gsm48_tx_mm_serv_ack()
* gsm48_tx_mm_serv_rej()
Also add a comment related to msc_gsm0808_tx_cipher_mode() in two places.
Remove internal RTP streaming code; OsmoNITB supported that, but for OsmoMSC,
this will be done with an external MGCP gateway.
Remove LCHAN_MODIFY from internal MNCC state machine.
Temporarily disable all paging to be able to link libmsc without libbsc.
Skip the paging part of channel_test because the paging is now disabled.
Employ fake paging shims in order for msc_vlr_tests to still work.
msc_compl_l3(): publish in .h, tweak return value. Use new libmsc enum values
for return val, to avoid dependency on libbsc headers. Make callable from
other scopes: publish in osmo_msc.h and remove 'static' in osmo_msc.c
add gsm_encr to subscr_conn
move subscr_request to gsm_subscriber.h
subscr_request_channel() -> subscr_request_conn()
move to libmsc: osmo_stats_vty_add_cmds()
gsm_04_08: remove apply_codec_restrictions()
gsm0408_test: use NULL for root ctx
move to libbsc: gsm_bts_neighbor()
move to libbsc: lchan_next_meas_rep()
move vty config for t3212 to network level (periodic lu)
remove unneccessary linking from some tests
remove handle_abisip_signal()
abis_rsl.c: don't use libvlr from libbsc
gsm_subscriber_connection: put the LAC here, so that it is available without
accessing conn->bts. In bsc_api.c, place this lac in conn for the sake of
transition: Iu and A will use this new field to pass the LAC around, but in a
completely separate OsmoBSC this is not actually needed. It can be removed
again from osmo-bsc.git when the time has come.
Siemens MRPCI: completely drop sending the MRPCI messages for now, they shall
be added in osmo-bsc once the A-Interface code has settled. See OS#2389.
Related: OS#1845 OS#2257 OS#2389
Change-Id: Id3705236350d5f69e447046b0a764bbabc3d493c
2017-05-08 13:12:20 +00:00
|
|
|
|
2009-08-15 00:30:58 +00:00
|
|
|
void *tall_locop_ctx;
|
2009-12-23 23:27:26 +00:00
|
|
|
void *tall_authciphop_ctx;
|
2009-06-20 20:36:41 +00:00
|
|
|
|
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-29 21:37:51 +00:00
|
|
|
static int gsm0408_loc_upd_acc(struct ran_conn *conn,
|
2016-06-19 16:06:02 +00:00
|
|
|
uint32_t send_tmsi);
|
2008-12-29 01:55:35 +00:00
|
|
|
|
2018-06-21 18:39:20 +00:00
|
|
|
/*! Send a simple GSM 04.08 message without any payload
|
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-29 21:37:51 +00:00
|
|
|
* \param conn Active RAN connection
|
2018-06-21 18:39:20 +00:00
|
|
|
* \param[in] pdisc Protocol discriminator
|
|
|
|
* \param[in] msg_type Message type
|
|
|
|
* \return result of \ref gsm48_conn_sendmsg
|
|
|
|
*/
|
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-29 21:37:51 +00:00
|
|
|
int gsm48_tx_simple(struct ran_conn *conn,
|
2018-06-21 18:39:20 +00:00
|
|
|
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);
|
|
|
|
}
|
2009-06-10 15:11:52 +00:00
|
|
|
|
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-13 01:05:52 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2018-03-22 15:09:50 +00:00
|
|
|
static bool classmark_is_r99(struct gsm_classmark *cm)
|
|
|
|
{
|
|
|
|
if (cm->classmark1_set)
|
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-13 01:05:52 +00:00
|
|
|
return classmark1_is_r99(&cm->classmark1);
|
|
|
|
return classmark2_is_r99(cm->classmark2, cm->classmark2_len);
|
2018-03-22 15:09:50 +00:00
|
|
|
}
|
|
|
|
|
2018-12-18 02:13:51 +00:00
|
|
|
static const char *classmark_a5_name(const struct gsm_classmark *cm)
|
|
|
|
{
|
|
|
|
static char buf[128];
|
|
|
|
char cm1[42];
|
|
|
|
char cm2[42];
|
|
|
|
char cm3[42];
|
|
|
|
|
|
|
|
if (cm->classmark1_set)
|
|
|
|
snprintf(cm1, sizeof(cm1), "cm1{a5/1=%s}",
|
|
|
|
cm->classmark1.a5_1 ? "not-supported":"supported" /* inverted logic */);
|
|
|
|
else
|
|
|
|
snprintf(cm1, sizeof(cm1), "no-cm1");
|
|
|
|
|
|
|
|
if (cm->classmark2_len >= 3)
|
|
|
|
snprintf(cm2, sizeof(cm2), " cm2{0x%x=%s%s}",
|
|
|
|
cm->classmark2[2],
|
|
|
|
cm->classmark2[2] & 0x1 ? " A5/2" : "",
|
|
|
|
cm->classmark2[2] & 0x2 ? " A5/3" : "");
|
|
|
|
else
|
|
|
|
snprintf(cm2, sizeof(cm2), " no-cm2");
|
|
|
|
|
|
|
|
if (cm->classmark3_len >= 1)
|
|
|
|
snprintf(cm3, sizeof(cm3), " cm3{0x%x=%s%s%s%s}",
|
|
|
|
cm->classmark3[0],
|
|
|
|
cm->classmark3[0] & (1 << 0) ? " A5/4" : "",
|
|
|
|
cm->classmark3[0] & (1 << 1) ? " A5/5" : "",
|
|
|
|
cm->classmark3[0] & (1 << 2) ? " A5/6" : "",
|
|
|
|
cm->classmark3[0] & (1 << 3) ? " A5/7" : "");
|
|
|
|
else
|
|
|
|
snprintf(cm3, sizeof(cm3), " no-cm3");
|
|
|
|
|
|
|
|
snprintf(buf, sizeof(buf), "%s%s%s", cm1, cm2, cm3);
|
|
|
|
return buf;
|
|
|
|
}
|
|
|
|
|
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 71330720b6efdda2fcfd3e9c0cb45f89e32e5670
"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-13 01:23:07 +00:00
|
|
|
/* 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)
|
2017-12-23 18:59:02 +00:00
|
|
|
{
|
|
|
|
switch (a5) {
|
|
|
|
case 0:
|
|
|
|
/* all phones must implement A5/0, see 3GPP TS 43.020 4.9 */
|
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 71330720b6efdda2fcfd3e9c0cb45f89e32e5670
"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-13 01:23:07 +00:00
|
|
|
return 1;
|
2017-12-23 18:59:02 +00:00
|
|
|
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");
|
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 71330720b6efdda2fcfd3e9c0cb45f89e32e5670
"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-13 01:23:07 +00:00
|
|
|
return -1;
|
2017-12-23 18:59:02 +00:00
|
|
|
} else {
|
|
|
|
if (cm->classmark1.a5_1)
|
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 71330720b6efdda2fcfd3e9c0cb45f89e32e5670
"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-13 01:23:07 +00:00
|
|
|
return 0; /* Inverted logic for this bit! */
|
2017-12-23 18:59:02 +00:00
|
|
|
else
|
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 71330720b6efdda2fcfd3e9c0cb45f89e32e5670
"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-13 01:23:07 +00:00
|
|
|
return 1;
|
2017-12-23 18:59:02 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
case 3:
|
|
|
|
/* See 3GPP TS 24.008 10.5.1.6 */
|
|
|
|
if (cm->classmark2_len < 3) {
|
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 71330720b6efdda2fcfd3e9c0cb45f89e32e5670
"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-13 01:23:07 +00:00
|
|
|
return -2;
|
2017-12-23 18:59:02 +00:00
|
|
|
} else {
|
|
|
|
if (cm->classmark2[2] & (1 << (a5-2)))
|
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 71330720b6efdda2fcfd3e9c0cb45f89e32e5670
"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-13 01:23:07 +00:00
|
|
|
return 1;
|
2017-12-23 18:59:02 +00:00
|
|
|
else
|
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 71330720b6efdda2fcfd3e9c0cb45f89e32e5670
"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-13 01:23:07 +00:00
|
|
|
return 0;
|
2017-12-23 18:59:02 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 4:
|
|
|
|
case 5:
|
|
|
|
case 6:
|
|
|
|
case 7:
|
|
|
|
/* See 3GPP TS 24.008 10.5.1.7 */
|
|
|
|
if (cm->classmark3_len < 1) {
|
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 71330720b6efdda2fcfd3e9c0cb45f89e32e5670
"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-13 01:23:07 +00:00
|
|
|
return -3;
|
2017-12-23 18:59:02 +00:00
|
|
|
} else {
|
|
|
|
if (cm->classmark3[0] & (1 << (a5-4)))
|
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 71330720b6efdda2fcfd3e9c0cb45f89e32e5670
"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-13 01:23:07 +00:00
|
|
|
return 1;
|
2017-12-23 18:59:02 +00:00
|
|
|
else
|
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 71330720b6efdda2fcfd3e9c0cb45f89e32e5670
"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-13 01:23:07 +00:00
|
|
|
return 0;
|
2017-12-23 18:59:02 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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-29 21:37:51 +00:00
|
|
|
int gsm48_conn_sendmsg(struct msgb *msg, struct ran_conn *conn, struct gsm_trans *trans)
|
2010-06-15 05:57:40 +00:00
|
|
|
{
|
|
|
|
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);
|
2018-04-09 14:35:01 +00:00
|
|
|
OMSC_LINKID_CB(msg) = trans->dlci;
|
2010-06-15 05:57:40 +00:00
|
|
|
}
|
|
|
|
|
2016-05-20 19:59:55 +00:00
|
|
|
return msc_tx_dtap(conn, msg);
|
2010-06-15 05:57:40 +00:00
|
|
|
}
|
2009-12-23 23:27:26 +00:00
|
|
|
|
2016-06-19 16:06:02 +00:00
|
|
|
/* clear all transactions globally; used in case of MNCC socket disconnect */
|
2010-12-22 22:17:50 +00:00
|
|
|
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) {
|
2010-12-23 01:47:53 +00:00
|
|
|
if (trans->protocol == protocol) {
|
|
|
|
trans->callref = 0;
|
2010-12-22 22:17:50 +00:00
|
|
|
trans_free(trans);
|
2010-12-23 01:47:53 +00:00
|
|
|
}
|
2010-12-22 22:17:50 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-12-30 13:28:30 +00:00
|
|
|
/* Chapter 9.2.14 : Send LOCATION UPDATING REJECT */
|
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-29 21:37:51 +00:00
|
|
|
static int gsm0408_loc_upd_rej(struct ran_conn *conn, uint8_t cause)
|
2008-12-23 20:25:15 +00:00
|
|
|
{
|
2010-06-15 11:40:05 +00:00
|
|
|
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;
|
|
|
|
}
|
2016-08-29 16:40:02 +00:00
|
|
|
|
mscsplit: various preparations to separate MSC from BSC
Disable large parts of the code that depend on BSC presence. The code sections
disabled by #if BEFORE_MSCSPLIT shall be modified or dropped in the course of
adding the A-interface.
Don't set msg->lchan nor msg->dst.
Don't use lchan in libmsc.
Decouple lac from bts.
Prepare entry/exit point for MSC -> BSC and MSC -> RNC communication:
Add msc_ifaces.[hc], a_iface.c, with a general msc_tx_dtap() to redirect to
different interfaces depending on the actual subscriber connection.
While iu_tx() is going to be functional fairly soon, the a_tx() is going to be
just a dummy for some time (see comment).
Add Iu specific fields in gsm_subscriber_connection: the UE connection pointer
and an indicator for the Integrity Protection status on Iu (to be fully
implemented in later commits).
Add lac member to gsm_subscriber_connection, to allow decoupling from
bts->location_area_code. The conn->lac will actually be set in iu.c in an
upcoming commit ("add iucs.[hc]").
move to libcommon-cs: gsm48_extract_mi(), gsm48_paging_extract_mi().
libmsc: duplicate gsm0808 / gsm48 functions (towards BSC).
In osmo-nitb, libmsc would directly call the functions on the BSC level, not
always via the bsc_api. When separating libmsc from libbsc, some functions are
missing from the linkage.
Hence duplicate these functions to libmsc, add an msc_ prefix for clarity, also
add a _tx to gsm0808_cipher_mode():
* add msc_gsm0808_tx_cipher_mode() (dummy/stub)
* add msc_gsm48_tx_mm_serv_ack()
* add msc_gsm48_tx_mm_serv_rej()
Call these from libmsc instead of
* gsm0808_cipher_mode()
* gsm48_tx_mm_serv_ack()
* gsm48_tx_mm_serv_rej()
Also add a comment related to msc_gsm0808_tx_cipher_mode() in two places.
Remove internal RTP streaming code; OsmoNITB supported that, but for OsmoMSC,
this will be done with an external MGCP gateway.
Remove LCHAN_MODIFY from internal MNCC state machine.
Temporarily disable all paging to be able to link libmsc without libbsc.
Skip the paging part of channel_test because the paging is now disabled.
Employ fake paging shims in order for msc_vlr_tests to still work.
msc_compl_l3(): publish in .h, tweak return value. Use new libmsc enum values
for return val, to avoid dependency on libbsc headers. Make callable from
other scopes: publish in osmo_msc.h and remove 'static' in osmo_msc.c
add gsm_encr to subscr_conn
move subscr_request to gsm_subscriber.h
subscr_request_channel() -> subscr_request_conn()
move to libmsc: osmo_stats_vty_add_cmds()
gsm_04_08: remove apply_codec_restrictions()
gsm0408_test: use NULL for root ctx
move to libbsc: gsm_bts_neighbor()
move to libbsc: lchan_next_meas_rep()
move vty config for t3212 to network level (periodic lu)
remove unneccessary linking from some tests
remove handle_abisip_signal()
abis_rsl.c: don't use libvlr from libbsc
gsm_subscriber_connection: put the LAC here, so that it is available without
accessing conn->bts. In bsc_api.c, place this lac in conn for the sake of
transition: Iu and A will use this new field to pass the LAC around, but in a
completely separate OsmoBSC this is not actually needed. It can be removed
again from osmo-bsc.git when the time has come.
Siemens MRPCI: completely drop sending the MRPCI messages for now, they shall
be added in osmo-bsc once the A-Interface code has settled. See OS#2389.
Related: OS#1845 OS#2257 OS#2389
Change-Id: Id3705236350d5f69e447046b0a764bbabc3d493c
2017-05-08 13:12:20 +00:00
|
|
|
LOGP(DMM, LOGL_INFO, "Subscriber %s: LOCATION UPDATING REJECT\n",
|
|
|
|
vlr_subscr_name(conn->vsub));
|
2009-12-21 23:41:05 +00:00
|
|
|
|
2010-06-15 05:57:40 +00:00
|
|
|
return gsm48_conn_sendmsg(msg, conn, NULL);
|
2008-12-23 20:25:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Chapter 9.2.13 : Send LOCATION UPDATE ACCEPT */
|
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-29 21:37:51 +00:00
|
|
|
static int gsm0408_loc_upd_acc(struct ran_conn *conn,
|
2016-06-19 16:06:02 +00:00
|
|
|
uint32_t send_tmsi)
|
2008-12-23 20:25:15 +00:00
|
|
|
{
|
2016-01-25 21:03:25 +00:00
|
|
|
struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 LOC UPD ACC");
|
2008-12-23 20:25:15 +00:00
|
|
|
struct gsm48_hdr *gh;
|
|
|
|
struct gsm48_loc_area_id *lai;
|
2011-04-18 15:04:00 +00:00
|
|
|
uint8_t *mid;
|
2018-02-22 03:04:54 +00:00
|
|
|
struct osmo_location_area_id laid = {
|
|
|
|
.plmn = conn->network->plmn,
|
|
|
|
.lac = conn->lac,
|
|
|
|
};
|
2016-08-29 16:40:02 +00:00
|
|
|
|
2008-12-23 20:25:15 +00:00
|
|
|
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));
|
2018-02-22 03:04:54 +00:00
|
|
|
gsm48_generate_lai2(lai, &laid);
|
2008-12-23 20:25:15 +00:00
|
|
|
|
2016-06-19 16:06:02 +00:00
|
|
|
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 */
|
2015-07-13 18:33:08 +00:00
|
|
|
uint8_t mi[10];
|
|
|
|
int len;
|
2016-06-19 16:06:02 +00:00
|
|
|
len = gsm48_generate_mid_from_imsi(mi, conn->vsub->imsi);
|
2015-07-13 18:33:08 +00:00
|
|
|
mid = msgb_put(msg, len);
|
|
|
|
memcpy(mid, mi, len);
|
2016-05-20 19:59:55 +00:00
|
|
|
DEBUGP(DMM, "-> %s LOCATION UPDATE ACCEPT\n",
|
|
|
|
vlr_subscr_name(conn->vsub));
|
2015-07-13 18:33:08 +00:00
|
|
|
} else {
|
2016-06-19 16:06:02 +00:00
|
|
|
/* Include the TMSI, which means that the MS will send a
|
|
|
|
* TMSI REALLOCATION COMPLETE, and we should wait for
|
|
|
|
* that until T3250 expiration */
|
2015-07-13 18:33:08 +00:00
|
|
|
mid = msgb_put(msg, GSM48_MID_TMSI_LEN);
|
2016-06-19 16:06:02 +00:00
|
|
|
gsm48_generate_mid_from_tmsi(mid, send_tmsi);
|
2016-05-20 19:59:55 +00:00
|
|
|
DEBUGP(DMM, "-> %s LOCATION UPDATE ACCEPT (TMSI = 0x%08x)\n",
|
|
|
|
vlr_subscr_name(conn->vsub),
|
|
|
|
send_tmsi);
|
2015-07-13 18:33:08 +00:00
|
|
|
}
|
2016-06-19 16:06:02 +00:00
|
|
|
/* TODO: Follow-on proceed */
|
|
|
|
/* TODO: CTS permission */
|
|
|
|
/* TODO: Equivalent PLMNs */
|
|
|
|
/* TODO: Emergency Number List */
|
|
|
|
/* TODO: Per-MS T3312 */
|
2008-12-23 20:25:15 +00:00
|
|
|
|
|
|
|
|
2010-06-15 06:07:27 +00:00
|
|
|
return gsm48_conn_sendmsg(msg, conn, NULL);
|
2008-12-23 20:25:15 +00:00
|
|
|
}
|
|
|
|
|
2009-02-03 12:59:45 +00:00
|
|
|
/* Transmit Chapter 9.2.10 Identity Request */
|
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-29 21:37:51 +00:00
|
|
|
static int mm_tx_identity_req(struct ran_conn *conn, uint8_t id_type)
|
2008-12-27 11:15:38 +00:00
|
|
|
{
|
2016-01-25 21:03:25 +00:00
|
|
|
struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 ID REQ");
|
2008-12-27 11:15:38 +00:00
|
|
|
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;
|
|
|
|
|
2010-06-15 06:11:01 +00:00
|
|
|
return gsm48_conn_sendmsg(msg, conn, NULL);
|
2008-12-27 11:15:38 +00:00
|
|
|
}
|
2008-12-27 10:19:37 +00:00
|
|
|
|
2009-02-03 12:59:45 +00:00
|
|
|
/* Parse Chapter 9.2.11 Identity Response */
|
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-29 21:37:51 +00:00
|
|
|
static int mm_rx_id_resp(struct ran_conn *conn, struct msgb *msg)
|
2008-12-27 11:15:38 +00:00
|
|
|
{
|
|
|
|
struct gsm48_hdr *gh = msgb_l3(msg);
|
2019-01-10 23:04:32 +00:00
|
|
|
uint8_t *mi = gh->data+1;
|
|
|
|
uint8_t mi_len = gh->data[0];
|
2008-12-27 11:15:38 +00:00
|
|
|
|
2016-06-19 16:06:02 +00:00
|
|
|
if (!conn->vsub) {
|
|
|
|
LOGP(DMM, LOGL_ERROR,
|
|
|
|
"Rx MM Identity Response: invalid: no subscriber\n");
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
2019-01-10 23:04:32 +00:00
|
|
|
DEBUGP(DMM, "IDENTITY RESPONSE: MI=%s\n", osmo_mi_name(mi, mi_len));
|
2008-12-27 11:15:38 +00:00
|
|
|
|
2011-05-06 10:12:31 +00:00
|
|
|
osmo_signal_dispatch(SS_SUBSCR, S_SUBSCR_IDENTITY, gh->data);
|
2009-12-13 11:39:18 +00:00
|
|
|
|
2019-01-10 23:04:32 +00:00
|
|
|
return vlr_subscr_rx_id_resp(conn->vsub, mi, mi_len);
|
2008-12-29 17:44:08 +00:00
|
|
|
}
|
|
|
|
|
2016-06-19 16:06:02 +00:00
|
|
|
/* Chapter 9.2.15: Receive Location Updating Request.
|
|
|
|
* Keep this function non-static for direct invocation by unit tests. */
|
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-29 21:37:51 +00:00
|
|
|
int mm_rx_loc_upd_req(struct ran_conn *conn, struct msgb *msg)
|
2008-12-23 20:25:15 +00:00
|
|
|
{
|
2016-06-19 16:06:02 +00:00
|
|
|
struct gsm_network *net = conn->network;
|
2008-12-25 23:28:35 +00:00
|
|
|
struct gsm48_hdr *gh = msgb_l3(msg);
|
2008-12-23 20:25:15 +00:00
|
|
|
struct gsm48_loc_upd_req *lu;
|
2011-04-18 15:04:00 +00:00
|
|
|
uint8_t mi_type;
|
2009-08-19 05:54:59 +00:00
|
|
|
char mi_string[GSM48_MI_SIZE];
|
2016-06-19 16:06:02 +00:00
|
|
|
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;
|
2016-05-20 19:59:55 +00:00
|
|
|
bool is_utran;
|
2008-12-25 23:28:35 +00:00
|
|
|
|
|
|
|
lu = (struct gsm48_loc_upd_req *) gh->data;
|
2008-12-23 20:25:15 +00:00
|
|
|
|
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-29 21:37:51 +00:00
|
|
|
if (ran_conn_is_establishing_auth_ciph(conn)) {
|
2019-01-04 16:42:05 +00:00
|
|
|
LOG_RAN_CONN_CAT(conn, DMM, LOGL_ERROR,
|
|
|
|
"Cannot accept another LU, conn already busy establishing authenticity;"
|
|
|
|
" extraneous LOCATION UPDATING REQUEST: MI=%s LU-type=%s\n",
|
|
|
|
osmo_mi_name(lu->mi, lu->mi_len), osmo_lu_type_name(lu->type));
|
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-03-30 22:02:14 +00:00
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
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-29 21:37:51 +00:00
|
|
|
if (ran_conn_is_accepted(conn)) {
|
2019-01-04 16:42:05 +00:00
|
|
|
LOG_RAN_CONN_CAT(conn, DMM, LOGL_ERROR,
|
|
|
|
"Cannot accept another LU, conn already established;"
|
|
|
|
" extraneous LOCATION UPDATING REQUEST: MI=%s LU-type=%s\n",
|
|
|
|
osmo_mi_name(lu->mi, lu->mi_len), osmo_lu_type_name(lu->type));
|
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-03-30 22:02:14 +00:00
|
|
|
return -EINVAL;
|
|
|
|
}
|
2016-06-19 16:06:02 +00:00
|
|
|
|
2019-01-03 01:32:14 +00:00
|
|
|
conn->complete_layer3_type = COMPLETE_LAYER3_LU;
|
|
|
|
ran_conn_update_id_from_mi(conn, lu->mi, lu->mi_len);
|
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-02 10:26:16 +00:00
|
|
|
|
2019-01-04 16:42:05 +00:00
|
|
|
LOG_RAN_CONN_CAT(conn, DMM, LOGL_DEBUG, "LOCATION UPDATING REQUEST: MI=%s LU-type=%s\n",
|
|
|
|
osmo_mi_name(lu->mi, lu->mi_len), osmo_lu_type_name(lu->type));
|
2008-12-31 18:53:57 +00:00
|
|
|
|
2011-05-06 10:12:31 +00:00
|
|
|
osmo_signal_dispatch(SS_SUBSCR, S_SUBSCR_IDENTITY, &lu->mi_len);
|
2009-12-13 11:39:18 +00:00
|
|
|
|
2009-12-21 23:41:05 +00:00
|
|
|
switch (lu->type) {
|
|
|
|
case GSM48_LUPD_NORMAL:
|
2016-05-09 19:09:47 +00:00
|
|
|
rate_ctr_inc(&conn->network->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_NORMAL]);
|
2016-06-19 16:06:02 +00:00
|
|
|
vlr_lu_type = VLR_LU_TYPE_REGULAR;
|
2009-12-21 23:41:05 +00:00
|
|
|
break;
|
|
|
|
case GSM48_LUPD_IMSI_ATT:
|
2016-05-09 19:09:47 +00:00
|
|
|
rate_ctr_inc(&conn->network->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_ATTACH]);
|
2016-06-19 16:06:02 +00:00
|
|
|
vlr_lu_type = VLR_LU_TYPE_IMSI_ATTACH;
|
2009-12-21 23:41:05 +00:00
|
|
|
break;
|
|
|
|
case GSM48_LUPD_PERIODIC:
|
2016-05-09 19:09:47 +00:00
|
|
|
rate_ctr_inc(&conn->network->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_PERIODIC]);
|
2016-06-19 16:06:02 +00:00
|
|
|
vlr_lu_type = VLR_LU_TYPE_PERIODIC;
|
2009-12-21 23:41:05 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2016-06-19 16:06:02 +00:00
|
|
|
/* 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 */
|
2010-06-10 11:36:59 +00:00
|
|
|
|
2019-01-03 01:32:14 +00:00
|
|
|
mi_type = lu->mi[0] & GSM_MI_TYPE_MASK;
|
|
|
|
gsm48_mi_to_string(mi_string, sizeof(mi_string), lu->mi, lu->mi_len);
|
2008-12-23 20:25:15 +00:00
|
|
|
switch (mi_type) {
|
|
|
|
case GSM_MI_TYPE_IMSI:
|
2016-06-19 16:06:02 +00:00
|
|
|
tmsi = GSM_RESERVED_TMSI;
|
|
|
|
imsi = mi_string;
|
2008-12-27 01:55:51 +00:00
|
|
|
break;
|
2008-12-23 20:25:15 +00:00
|
|
|
case GSM_MI_TYPE_TMSI:
|
2016-06-19 16:06:02 +00:00
|
|
|
tmsi = tmsi_from_string(mi_string);
|
|
|
|
imsi = NULL;
|
2008-12-23 20:25:15 +00:00
|
|
|
break;
|
2016-08-29 16:40:02 +00:00
|
|
|
default:
|
2019-01-04 16:42:05 +00:00
|
|
|
LOG_RAN_CONN_CAT(conn, DMM, LOGL_ERROR, "unknown mobile identity type\n");
|
2016-06-19 16:06:02 +00:00
|
|
|
tmsi = GSM_RESERVED_TMSI;
|
|
|
|
imsi = NULL;
|
2008-12-23 20:25:15 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2018-02-22 03:04:54 +00:00
|
|
|
gsm48_decode_lai2(&lu->lai, &old_lai);
|
|
|
|
new_lai.plmn = conn->network->plmn;
|
mscsplit: various preparations to separate MSC from BSC
Disable large parts of the code that depend on BSC presence. The code sections
disabled by #if BEFORE_MSCSPLIT shall be modified or dropped in the course of
adding the A-interface.
Don't set msg->lchan nor msg->dst.
Don't use lchan in libmsc.
Decouple lac from bts.
Prepare entry/exit point for MSC -> BSC and MSC -> RNC communication:
Add msc_ifaces.[hc], a_iface.c, with a general msc_tx_dtap() to redirect to
different interfaces depending on the actual subscriber connection.
While iu_tx() is going to be functional fairly soon, the a_tx() is going to be
just a dummy for some time (see comment).
Add Iu specific fields in gsm_subscriber_connection: the UE connection pointer
and an indicator for the Integrity Protection status on Iu (to be fully
implemented in later commits).
Add lac member to gsm_subscriber_connection, to allow decoupling from
bts->location_area_code. The conn->lac will actually be set in iu.c in an
upcoming commit ("add iucs.[hc]").
move to libcommon-cs: gsm48_extract_mi(), gsm48_paging_extract_mi().
libmsc: duplicate gsm0808 / gsm48 functions (towards BSC).
In osmo-nitb, libmsc would directly call the functions on the BSC level, not
always via the bsc_api. When separating libmsc from libbsc, some functions are
missing from the linkage.
Hence duplicate these functions to libmsc, add an msc_ prefix for clarity, also
add a _tx to gsm0808_cipher_mode():
* add msc_gsm0808_tx_cipher_mode() (dummy/stub)
* add msc_gsm48_tx_mm_serv_ack()
* add msc_gsm48_tx_mm_serv_rej()
Call these from libmsc instead of
* gsm0808_cipher_mode()
* gsm48_tx_mm_serv_ack()
* gsm48_tx_mm_serv_rej()
Also add a comment related to msc_gsm0808_tx_cipher_mode() in two places.
Remove internal RTP streaming code; OsmoNITB supported that, but for OsmoMSC,
this will be done with an external MGCP gateway.
Remove LCHAN_MODIFY from internal MNCC state machine.
Temporarily disable all paging to be able to link libmsc without libbsc.
Skip the paging part of channel_test because the paging is now disabled.
Employ fake paging shims in order for msc_vlr_tests to still work.
msc_compl_l3(): publish in .h, tweak return value. Use new libmsc enum values
for return val, to avoid dependency on libbsc headers. Make callable from
other scopes: publish in osmo_msc.h and remove 'static' in osmo_msc.c
add gsm_encr to subscr_conn
move subscr_request to gsm_subscriber.h
subscr_request_channel() -> subscr_request_conn()
move to libmsc: osmo_stats_vty_add_cmds()
gsm_04_08: remove apply_codec_restrictions()
gsm0408_test: use NULL for root ctx
move to libbsc: gsm_bts_neighbor()
move to libbsc: lchan_next_meas_rep()
move vty config for t3212 to network level (periodic lu)
remove unneccessary linking from some tests
remove handle_abisip_signal()
abis_rsl.c: don't use libvlr from libbsc
gsm_subscriber_connection: put the LAC here, so that it is available without
accessing conn->bts. In bsc_api.c, place this lac in conn for the sake of
transition: Iu and A will use this new field to pass the LAC around, but in a
completely separate OsmoBSC this is not actually needed. It can be removed
again from osmo-bsc.git when the time has come.
Siemens MRPCI: completely drop sending the MRPCI messages for now, they shall
be added in osmo-bsc once the A-Interface code has settled. See OS#2389.
Related: OS#1845 OS#2257 OS#2389
Change-Id: Id3705236350d5f69e447046b0a764bbabc3d493c
2017-05-08 13:12:20 +00:00
|
|
|
new_lai.lac = conn->lac;
|
2019-01-04 16:42:05 +00:00
|
|
|
LOG_RAN_CONN_CAT(conn, DMM, LOGL_DEBUG, "LU/new-LAC: %u/%u\n", old_lai.lac, new_lai.lac);
|
2016-06-19 16:06:02 +00:00
|
|
|
|
2018-12-25 23:40:18 +00:00
|
|
|
is_utran = (conn->via_ran == OSMO_RAT_UTRAN_IU);
|
2018-03-31 16:45:59 +00:00
|
|
|
lu_fsm = vlr_loc_update(conn->fi,
|
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-29 21:37:51 +00:00
|
|
|
RAN_CONN_E_ACCEPTED, RAN_CONN_E_CN_CLOSE, NULL,
|
2016-06-19 16:06:02 +00:00
|
|
|
net->vlr, conn, vlr_lu_type, tmsi, imsi,
|
|
|
|
&old_lai, &new_lai,
|
2016-05-20 19:59:55 +00:00
|
|
|
is_utran || conn->network->authentication_required,
|
2017-12-23 18:30:32 +00:00
|
|
|
is_utran || conn->network->a5_encryption_mask > 0x01,
|
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-13 01:05:52 +00:00
|
|
|
classmark1_is_r99(&lu->classmark1),
|
2016-05-20 19:59:55 +00:00
|
|
|
is_utran,
|
2016-06-19 16:06:02 +00:00
|
|
|
net->vlr->cfg.assign_tmsi);
|
|
|
|
if (!lu_fsm) {
|
2019-01-04 16:42:05 +00:00
|
|
|
LOG_RAN_CONN(conn, LOGL_ERROR, "Can't start LU FSM\n");
|
2016-06-19 16:06:02 +00:00
|
|
|
return 0;
|
2009-06-10 15:11:52 +00:00
|
|
|
}
|
|
|
|
|
2016-06-19 16:06:02 +00:00
|
|
|
/* 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) {
|
2019-01-04 16:42:05 +00:00
|
|
|
LOG_RAN_CONN(conn, LOGL_ERROR, "internal error during Location Updating attempt\n");
|
2016-06-19 16:06:02 +00:00
|
|
|
return -EIO;
|
|
|
|
}
|
2008-12-28 02:26:27 +00:00
|
|
|
|
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-13 01:05:52 +00:00
|
|
|
conn->vsub->classmark.classmark1 = lu->classmark1;
|
|
|
|
conn->vsub->classmark.classmark1_set = true;
|
|
|
|
|
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-29 21:37:51 +00:00
|
|
|
ran_conn_complete_layer_3(conn);
|
2016-06-19 16:06:02 +00:00
|
|
|
return 0;
|
2008-12-23 20:25:15 +00:00
|
|
|
}
|
|
|
|
|
2011-12-02 09:18:17 +00:00
|
|
|
/* Turn int into semi-octet representation: 98 => 0x89 */
|
2016-06-19 16:06:02 +00:00
|
|
|
/* FIXME: libosmocore/libosmogsm */
|
2011-12-02 09:18:17 +00:00
|
|
|
static uint8_t bcdify(uint8_t value)
|
2009-06-10 15:11:52 +00:00
|
|
|
{
|
2011-12-02 09:18:17 +00:00
|
|
|
uint8_t ret;
|
|
|
|
|
|
|
|
ret = value / 10;
|
|
|
|
ret |= (value % 10) << 4;
|
|
|
|
|
|
|
|
return ret;
|
2009-06-10 15:11:52 +00:00
|
|
|
}
|
2011-12-02 09:18:17 +00:00
|
|
|
|
2009-06-10 15:11:52 +00:00
|
|
|
|
2008-12-30 17:56:55 +00:00
|
|
|
/* Section 9.2.15a */
|
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-29 21:37:51 +00:00
|
|
|
int gsm48_tx_mm_info(struct ran_conn *conn)
|
2008-12-30 17:56:55 +00:00
|
|
|
{
|
2016-01-25 21:03:25 +00:00
|
|
|
struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 MM INF");
|
2008-12-30 17:56:55 +00:00
|
|
|
struct gsm48_hdr *gh;
|
2016-05-09 19:09:47 +00:00
|
|
|
struct gsm_network *net = conn->network;
|
2011-04-18 15:04:00 +00:00
|
|
|
uint8_t *ptr8;
|
2009-08-13 01:42:07 +00:00
|
|
|
int name_len, name_pad;
|
2011-12-02 09:18:17 +00:00
|
|
|
|
2009-06-10 15:11:52 +00:00
|
|
|
time_t cur_t;
|
2011-12-02 09:18:17 +00:00
|
|
|
struct tm* gmt_time;
|
|
|
|
struct tm* local_time;
|
|
|
|
int tzunits;
|
2014-01-07 14:05:16 +00:00
|
|
|
int dst = 0;
|
2008-12-30 17:56:55 +00:00
|
|
|
|
|
|
|
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) {
|
2009-08-13 01:42:07 +00:00
|
|
|
#if 0
|
2008-12-30 17:56:55 +00:00
|
|
|
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 */
|
|
|
|
|
2011-04-18 15:04:00 +00:00
|
|
|
ptr16 = (uint16_t *) msgb_put(msg, name_len*2);
|
2008-12-30 17:56:55 +00:00
|
|
|
for (i = 0; i < name_len; i++)
|
2008-12-31 23:59:18 +00:00
|
|
|
ptr16[i] = htons(net->name_long[i]);
|
2008-12-30 17:56:55 +00:00
|
|
|
|
|
|
|
/* FIXME: Use Cell Broadcast, not UCS-2, since
|
|
|
|
* UCS-2 is only supported by later revisions of the spec */
|
2009-08-13 01:42:07 +00:00
|
|
|
#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);
|
2015-01-01 11:41:17 +00:00
|
|
|
gsm_7bit_encode_n(ptr8, name_len, net->name_long, NULL);
|
2009-08-13 01:42:07 +00:00
|
|
|
|
2008-12-30 17:56:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (net->name_short) {
|
2009-08-13 01:42:07 +00:00
|
|
|
#if 0
|
2008-12-30 17:56:55 +00:00
|
|
|
name_len = strlen(net->name_short);
|
|
|
|
/* 10.5.3.5a */
|
2011-04-18 15:04:00 +00:00
|
|
|
ptr8 = (uint8_t *) msgb_put(msg, 3);
|
2009-07-19 15:51:36 +00:00
|
|
|
ptr8[0] = GSM48_IE_NAME_SHORT;
|
2008-12-30 17:56:55 +00:00
|
|
|
ptr8[1] = name_len*2 + 1;
|
|
|
|
ptr8[2] = 0x90; /* UCS2, no spare bits, no CI */
|
|
|
|
|
2011-04-18 15:04:00 +00:00
|
|
|
ptr16 = (uint16_t *) msgb_put(msg, name_len*2);
|
2008-12-30 17:56:55 +00:00
|
|
|
for (i = 0; i < name_len; i++)
|
2008-12-31 23:59:18 +00:00
|
|
|
ptr16[i] = htons(net->name_short[i]);
|
2009-08-13 01:42:07 +00:00
|
|
|
#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 */
|
2011-04-18 15:04:00 +00:00
|
|
|
ptr8 = (uint8_t *) msgb_put(msg, 3);
|
2009-08-13 01:42:07 +00:00
|
|
|
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);
|
2015-01-01 11:41:17 +00:00
|
|
|
gsm_7bit_encode_n(ptr8, name_len, net->name_short, NULL);
|
2009-08-13 01:42:07 +00:00
|
|
|
|
2008-12-30 17:56:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Section 10.5.3.9 */
|
|
|
|
cur_t = time(NULL);
|
2011-12-02 09:18:17 +00:00
|
|
|
gmt_time = gmtime(&cur_t);
|
|
|
|
|
2008-12-30 17:56:55 +00:00
|
|
|
ptr8 = msgb_put(msg, 8);
|
|
|
|
ptr8[0] = GSM48_IE_NET_TIME_TZ;
|
2011-12-02 09:18:17 +00:00
|
|
|
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);
|
|
|
|
|
2016-05-10 11:29:33 +00:00
|
|
|
if (net->tz.override) {
|
2012-07-08 14:48:11 +00:00
|
|
|
/* Convert tz.hr and tz.mn to units */
|
2016-05-10 11:29:33 +00:00
|
|
|
if (net->tz.hr < 0) {
|
|
|
|
tzunits = ((net->tz.hr/-1)*4);
|
|
|
|
tzunits = tzunits + (net->tz.mn/15);
|
2011-12-02 09:18:17 +00:00
|
|
|
ptr8[7] = bcdify(tzunits);
|
|
|
|
/* Set negative time */
|
|
|
|
ptr8[7] |= 0x08;
|
|
|
|
}
|
|
|
|
else {
|
2016-05-10 11:29:33 +00:00
|
|
|
tzunits = net->tz.hr*4;
|
|
|
|
tzunits = tzunits + (net->tz.mn/15);
|
2011-12-02 09:18:17 +00:00
|
|
|
ptr8[7] = bcdify(tzunits);
|
|
|
|
}
|
2014-01-07 14:05:16 +00:00
|
|
|
/* Convert DST value */
|
2016-05-10 11:29:33 +00:00
|
|
|
if (net->tz.dst >= 0 && net->tz.dst <= 2)
|
|
|
|
dst = net->tz.dst;
|
2011-12-02 09:18:17 +00:00
|
|
|
}
|
|
|
|
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? */
|
2012-04-08 14:59:24 +00:00
|
|
|
#ifdef HAVE_TM_GMTOFF_IN_TM
|
2017-07-05 10:57:16 +00:00
|
|
|
local_time = localtime(&cur_t);
|
2011-12-02 09:18:17 +00:00
|
|
|
tzunits = (local_time->tm_gmtoff/60)/15;
|
2012-04-08 14:59:24 +00:00
|
|
|
#else
|
2017-07-05 10:57:16 +00:00
|
|
|
/* 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;
|
2012-04-08 14:59:24 +00:00
|
|
|
#endif
|
2011-12-02 09:18:17 +00:00
|
|
|
if (tzunits < 0) {
|
|
|
|
tzunits = tzunits/-1;
|
|
|
|
ptr8[7] = bcdify(tzunits);
|
|
|
|
/* Flip it to negative */
|
|
|
|
ptr8[7] |= 0x08;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
ptr8[7] = bcdify(tzunits);
|
2014-01-07 14:05:16 +00:00
|
|
|
|
|
|
|
/* 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;
|
2011-12-02 09:18:17 +00:00
|
|
|
}
|
2008-12-30 17:56:55 +00:00
|
|
|
|
2019-01-04 16:42:05 +00:00
|
|
|
LOG_RAN_CONN(conn, LOGL_DEBUG, "Tx MM INFO\n");
|
2009-08-13 01:42:07 +00:00
|
|
|
|
2010-06-15 06:16:02 +00:00
|
|
|
return gsm48_conn_sendmsg(msg, conn, NULL);
|
2008-12-30 17:56:55 +00:00
|
|
|
}
|
|
|
|
|
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-29 21:37:51 +00:00
|
|
|
/*! Send an Authentication Request to MS on the given RAN connection
|
2017-01-26 23:25:47 +00:00
|
|
|
* 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.
|
|
|
|
*/
|
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-29 21:37:51 +00:00
|
|
|
int gsm48_tx_mm_auth_req(struct ran_conn *conn, uint8_t *rand,
|
2017-01-26 23:25:47 +00:00
|
|
|
uint8_t *autn, int key_seq)
|
2009-08-12 20:56:50 +00:00
|
|
|
{
|
2016-01-25 21:03:25 +00:00
|
|
|
struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 AUTH REQ");
|
2009-08-12 20:56:50 +00:00
|
|
|
struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
|
2009-09-27 09:10:17 +00:00
|
|
|
struct gsm48_auth_req *ar = (struct gsm48_auth_req *) msgb_put(msg, sizeof(*ar));
|
2009-08-12 20:56:50 +00:00
|
|
|
|
2019-01-04 16:42:05 +00:00
|
|
|
DEBUGP(DMM, "Tx AUTH REQ (rand = %s)\n", osmo_hexdump_nospc(rand, 16));
|
2017-01-26 23:25:47 +00:00
|
|
|
if (autn)
|
2017-02-14 16:42:25 +00:00
|
|
|
DEBUGP(DMM, " AUTH REQ (autn = %s)\n", osmo_hexdump_nospc(autn, 16));
|
2009-08-12 20:56:50 +00:00
|
|
|
|
|
|
|
gh->proto_discr = GSM48_PDISC_MM;
|
|
|
|
gh->msg_type = GSM48_MT_MM_AUTH_REQ;
|
|
|
|
|
2009-12-23 23:23:46 +00:00
|
|
|
ar->key_seq = key_seq;
|
2009-09-27 09:10:17 +00:00
|
|
|
|
2009-08-12 20:56:50 +00:00
|
|
|
/* 16 bytes RAND parameters */
|
2017-01-26 23:25:47 +00:00
|
|
|
osmo_static_assert(sizeof(ar->rand) == 16, sizeof_auth_req_r99_rand);
|
2009-08-12 20:56:50 +00:00
|
|
|
if (rand)
|
2009-09-27 09:10:17 +00:00
|
|
|
memcpy(ar->rand, rand, 16);
|
2009-08-12 20:56:50 +00:00
|
|
|
|
2017-01-26 23:25:47 +00:00
|
|
|
|
|
|
|
/* 16 bytes AUTN */
|
|
|
|
if (autn)
|
|
|
|
msgb_tlv_put(msg, GSM48_IE_AUTN, 16, autn);
|
|
|
|
|
2010-06-16 04:30:50 +00:00
|
|
|
return gsm48_conn_sendmsg(msg, conn, NULL);
|
2009-08-12 20:56:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Section 9.2.1 */
|
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-29 21:37:51 +00:00
|
|
|
int gsm48_tx_mm_auth_rej(struct ran_conn *conn)
|
2009-08-12 20:56:50 +00:00
|
|
|
{
|
|
|
|
DEBUGP(DMM, "-> AUTH REJECT\n");
|
2010-06-16 04:30:50 +00:00
|
|
|
return gsm48_tx_simple(conn, GSM48_PDISC_MM, GSM48_MT_MM_AUTH_REJ);
|
2009-08-12 20:56:50 +00:00
|
|
|
}
|
|
|
|
|
2016-06-19 16:06:02 +00:00
|
|
|
static int msc_vlr_tx_cm_serv_acc(void *msc_conn_ref);
|
2018-04-06 00:57:51 +00:00
|
|
|
static int msc_vlr_tx_cm_serv_rej(void *msc_conn_ref, enum gsm48_reject_value result);
|
2013-12-27 16:19:19 +00:00
|
|
|
|
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-29 21:37:51 +00:00
|
|
|
static int cm_serv_reuse_conn(struct ran_conn *conn, const uint8_t *mi_lv)
|
2009-12-23 23:28:46 +00:00
|
|
|
{
|
2016-06-19 16:06:02 +00:00
|
|
|
uint8_t mi_type;
|
|
|
|
char mi_string[GSM48_MI_SIZE];
|
|
|
|
uint32_t tmsi;
|
2009-12-23 23:28:46 +00:00
|
|
|
|
2016-06-19 16:06:02 +00:00
|
|
|
gsm48_mi_to_string(mi_string, sizeof(mi_string), mi_lv+1, mi_lv[0]);
|
|
|
|
mi_type = mi_lv[1] & GSM_MI_TYPE_MASK;
|
2009-12-23 23:28:46 +00:00
|
|
|
|
2016-06-19 16:06:02 +00:00
|
|
|
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;
|
|
|
|
}
|
2009-12-23 23:28:46 +00:00
|
|
|
|
2016-06-19 16:06:02 +00:00
|
|
|
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);
|
2018-04-06 00:57:51 +00:00
|
|
|
msc_vlr_tx_cm_serv_rej(conn, GSM48_REJECT_ILLEGAL_MS);
|
2016-06-19 16:06:02 +00:00
|
|
|
return -EINVAL;
|
2009-12-23 23:28:46 +00:00
|
|
|
|
2016-06-19 16:06:02 +00:00
|
|
|
accept_reuse:
|
|
|
|
DEBUGP(DMM, "%s: re-using already accepted connection\n",
|
|
|
|
vlr_subscr_name(conn->vsub));
|
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-03-30 22:02:14 +00:00
|
|
|
|
|
|
|
if (!conn->received_cm_service_request) {
|
|
|
|
conn->received_cm_service_request = true;
|
2018-11-30 00:08:36 +00:00
|
|
|
ran_conn_get(conn, RAN_CONN_USE_CM_SERVICE);
|
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-03-30 22:02:14 +00:00
|
|
|
}
|
2019-01-03 01:32:14 +00:00
|
|
|
ran_conn_update_id(conn);
|
2016-06-19 16:06:02 +00:00
|
|
|
return conn->network->vlr->ops.tx_cm_serv_acc(conn);
|
2009-12-23 23:28:46 +00:00
|
|
|
}
|
|
|
|
|
2009-01-10 03:17:30 +00:00
|
|
|
/*
|
|
|
|
* 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
|
mscsplit: various preparations to separate MSC from BSC
Disable large parts of the code that depend on BSC presence. The code sections
disabled by #if BEFORE_MSCSPLIT shall be modified or dropped in the course of
adding the A-interface.
Don't set msg->lchan nor msg->dst.
Don't use lchan in libmsc.
Decouple lac from bts.
Prepare entry/exit point for MSC -> BSC and MSC -> RNC communication:
Add msc_ifaces.[hc], a_iface.c, with a general msc_tx_dtap() to redirect to
different interfaces depending on the actual subscriber connection.
While iu_tx() is going to be functional fairly soon, the a_tx() is going to be
just a dummy for some time (see comment).
Add Iu specific fields in gsm_subscriber_connection: the UE connection pointer
and an indicator for the Integrity Protection status on Iu (to be fully
implemented in later commits).
Add lac member to gsm_subscriber_connection, to allow decoupling from
bts->location_area_code. The conn->lac will actually be set in iu.c in an
upcoming commit ("add iucs.[hc]").
move to libcommon-cs: gsm48_extract_mi(), gsm48_paging_extract_mi().
libmsc: duplicate gsm0808 / gsm48 functions (towards BSC).
In osmo-nitb, libmsc would directly call the functions on the BSC level, not
always via the bsc_api. When separating libmsc from libbsc, some functions are
missing from the linkage.
Hence duplicate these functions to libmsc, add an msc_ prefix for clarity, also
add a _tx to gsm0808_cipher_mode():
* add msc_gsm0808_tx_cipher_mode() (dummy/stub)
* add msc_gsm48_tx_mm_serv_ack()
* add msc_gsm48_tx_mm_serv_rej()
Call these from libmsc instead of
* gsm0808_cipher_mode()
* gsm48_tx_mm_serv_ack()
* gsm48_tx_mm_serv_rej()
Also add a comment related to msc_gsm0808_tx_cipher_mode() in two places.
Remove internal RTP streaming code; OsmoNITB supported that, but for OsmoMSC,
this will be done with an external MGCP gateway.
Remove LCHAN_MODIFY from internal MNCC state machine.
Temporarily disable all paging to be able to link libmsc without libbsc.
Skip the paging part of channel_test because the paging is now disabled.
Employ fake paging shims in order for msc_vlr_tests to still work.
msc_compl_l3(): publish in .h, tweak return value. Use new libmsc enum values
for return val, to avoid dependency on libbsc headers. Make callable from
other scopes: publish in osmo_msc.h and remove 'static' in osmo_msc.c
add gsm_encr to subscr_conn
move subscr_request to gsm_subscriber.h
subscr_request_channel() -> subscr_request_conn()
move to libmsc: osmo_stats_vty_add_cmds()
gsm_04_08: remove apply_codec_restrictions()
gsm0408_test: use NULL for root ctx
move to libbsc: gsm_bts_neighbor()
move to libbsc: lchan_next_meas_rep()
move vty config for t3212 to network level (periodic lu)
remove unneccessary linking from some tests
remove handle_abisip_signal()
abis_rsl.c: don't use libvlr from libbsc
gsm_subscriber_connection: put the LAC here, so that it is available without
accessing conn->bts. In bsc_api.c, place this lac in conn for the sake of
transition: Iu and A will use this new field to pass the LAC around, but in a
completely separate OsmoBSC this is not actually needed. It can be removed
again from osmo-bsc.git when the time has come.
Siemens MRPCI: completely drop sending the MRPCI messages for now, they shall
be added in osmo-bsc once the A-Interface code has settled. See OS#2389.
Related: OS#1845 OS#2257 OS#2389
Change-Id: Id3705236350d5f69e447046b0a764bbabc3d493c
2017-05-08 13:12:20 +00:00
|
|
|
* d) Set the subscriber on the conn and accept
|
2016-06-19 16:06:02 +00:00
|
|
|
*
|
|
|
|
* Keep this function non-static for direct invocation by unit tests.
|
2009-01-10 03:17:30 +00:00
|
|
|
*/
|
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-29 21:37:51 +00:00
|
|
|
int gsm48_rx_mm_serv_req(struct ran_conn *conn, struct msgb *msg)
|
2008-12-27 01:55:51 +00:00
|
|
|
{
|
2016-06-19 16:06:02 +00:00
|
|
|
struct gsm_network *net = conn->network;
|
2011-04-18 15:04:00 +00:00
|
|
|
uint8_t mi_type;
|
2008-12-27 01:55:51 +00:00
|
|
|
struct gsm48_hdr *gh = msgb_l3(msg);
|
2009-01-10 01:49:35 +00:00
|
|
|
struct gsm48_service_request *req =
|
|
|
|
(struct gsm48_service_request *)gh->data;
|
2010-05-14 00:02:08 +00:00
|
|
|
/* unfortunately in Phase1 the classmark2 length is variable */
|
2011-04-18 15:04:00 +00:00
|
|
|
uint8_t classmark2_len = gh->data[1];
|
|
|
|
uint8_t *classmark2 = gh->data+2;
|
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-03-30 22:02:14 +00:00
|
|
|
uint8_t *mi_p = classmark2 + classmark2_len;
|
|
|
|
uint8_t mi_len = *mi_p;
|
|
|
|
uint8_t *mi = mi_p + 1;
|
2016-06-19 16:06:02 +00:00
|
|
|
struct osmo_location_area_id lai;
|
2016-05-20 19:59:55 +00:00
|
|
|
bool is_utran;
|
2016-06-19 16:06:02 +00:00
|
|
|
|
2018-02-22 03:04:54 +00:00
|
|
|
lai.plmn = conn->network->plmn;
|
mscsplit: various preparations to separate MSC from BSC
Disable large parts of the code that depend on BSC presence. The code sections
disabled by #if BEFORE_MSCSPLIT shall be modified or dropped in the course of
adding the A-interface.
Don't set msg->lchan nor msg->dst.
Don't use lchan in libmsc.
Decouple lac from bts.
Prepare entry/exit point for MSC -> BSC and MSC -> RNC communication:
Add msc_ifaces.[hc], a_iface.c, with a general msc_tx_dtap() to redirect to
different interfaces depending on the actual subscriber connection.
While iu_tx() is going to be functional fairly soon, the a_tx() is going to be
just a dummy for some time (see comment).
Add Iu specific fields in gsm_subscriber_connection: the UE connection pointer
and an indicator for the Integrity Protection status on Iu (to be fully
implemented in later commits).
Add lac member to gsm_subscriber_connection, to allow decoupling from
bts->location_area_code. The conn->lac will actually be set in iu.c in an
upcoming commit ("add iucs.[hc]").
move to libcommon-cs: gsm48_extract_mi(), gsm48_paging_extract_mi().
libmsc: duplicate gsm0808 / gsm48 functions (towards BSC).
In osmo-nitb, libmsc would directly call the functions on the BSC level, not
always via the bsc_api. When separating libmsc from libbsc, some functions are
missing from the linkage.
Hence duplicate these functions to libmsc, add an msc_ prefix for clarity, also
add a _tx to gsm0808_cipher_mode():
* add msc_gsm0808_tx_cipher_mode() (dummy/stub)
* add msc_gsm48_tx_mm_serv_ack()
* add msc_gsm48_tx_mm_serv_rej()
Call these from libmsc instead of
* gsm0808_cipher_mode()
* gsm48_tx_mm_serv_ack()
* gsm48_tx_mm_serv_rej()
Also add a comment related to msc_gsm0808_tx_cipher_mode() in two places.
Remove internal RTP streaming code; OsmoNITB supported that, but for OsmoMSC,
this will be done with an external MGCP gateway.
Remove LCHAN_MODIFY from internal MNCC state machine.
Temporarily disable all paging to be able to link libmsc without libbsc.
Skip the paging part of channel_test because the paging is now disabled.
Employ fake paging shims in order for msc_vlr_tests to still work.
msc_compl_l3(): publish in .h, tweak return value. Use new libmsc enum values
for return val, to avoid dependency on libbsc headers. Make callable from
other scopes: publish in osmo_msc.h and remove 'static' in osmo_msc.c
add gsm_encr to subscr_conn
move subscr_request to gsm_subscriber.h
subscr_request_channel() -> subscr_request_conn()
move to libmsc: osmo_stats_vty_add_cmds()
gsm_04_08: remove apply_codec_restrictions()
gsm0408_test: use NULL for root ctx
move to libbsc: gsm_bts_neighbor()
move to libbsc: lchan_next_meas_rep()
move vty config for t3212 to network level (periodic lu)
remove unneccessary linking from some tests
remove handle_abisip_signal()
abis_rsl.c: don't use libvlr from libbsc
gsm_subscriber_connection: put the LAC here, so that it is available without
accessing conn->bts. In bsc_api.c, place this lac in conn for the sake of
transition: Iu and A will use this new field to pass the LAC around, but in a
completely separate OsmoBSC this is not actually needed. It can be removed
again from osmo-bsc.git when the time has come.
Siemens MRPCI: completely drop sending the MRPCI messages for now, they shall
be added in osmo-bsc once the A-Interface code has settled. See OS#2389.
Related: OS#1845 OS#2257 OS#2389
Change-Id: Id3705236350d5f69e447046b0a764bbabc3d493c
2017-05-08 13:12:20 +00:00
|
|
|
lai.lac = conn->lac;
|
2009-01-10 01:49:35 +00:00
|
|
|
|
|
|
|
if (msg->data_len < sizeof(struct gsm48_service_request*)) {
|
2019-01-04 16:42:05 +00:00
|
|
|
LOG_RAN_CONN(conn, LOGL_ERROR, "Rx CM SERVICE REQUEST: wrong message size (%u < %zu)\n",
|
|
|
|
msg->data_len, sizeof(struct gsm48_service_request*));
|
mscsplit: various preparations to separate MSC from BSC
Disable large parts of the code that depend on BSC presence. The code sections
disabled by #if BEFORE_MSCSPLIT shall be modified or dropped in the course of
adding the A-interface.
Don't set msg->lchan nor msg->dst.
Don't use lchan in libmsc.
Decouple lac from bts.
Prepare entry/exit point for MSC -> BSC and MSC -> RNC communication:
Add msc_ifaces.[hc], a_iface.c, with a general msc_tx_dtap() to redirect to
different interfaces depending on the actual subscriber connection.
While iu_tx() is going to be functional fairly soon, the a_tx() is going to be
just a dummy for some time (see comment).
Add Iu specific fields in gsm_subscriber_connection: the UE connection pointer
and an indicator for the Integrity Protection status on Iu (to be fully
implemented in later commits).
Add lac member to gsm_subscriber_connection, to allow decoupling from
bts->location_area_code. The conn->lac will actually be set in iu.c in an
upcoming commit ("add iucs.[hc]").
move to libcommon-cs: gsm48_extract_mi(), gsm48_paging_extract_mi().
libmsc: duplicate gsm0808 / gsm48 functions (towards BSC).
In osmo-nitb, libmsc would directly call the functions on the BSC level, not
always via the bsc_api. When separating libmsc from libbsc, some functions are
missing from the linkage.
Hence duplicate these functions to libmsc, add an msc_ prefix for clarity, also
add a _tx to gsm0808_cipher_mode():
* add msc_gsm0808_tx_cipher_mode() (dummy/stub)
* add msc_gsm48_tx_mm_serv_ack()
* add msc_gsm48_tx_mm_serv_rej()
Call these from libmsc instead of
* gsm0808_cipher_mode()
* gsm48_tx_mm_serv_ack()
* gsm48_tx_mm_serv_rej()
Also add a comment related to msc_gsm0808_tx_cipher_mode() in two places.
Remove internal RTP streaming code; OsmoNITB supported that, but for OsmoMSC,
this will be done with an external MGCP gateway.
Remove LCHAN_MODIFY from internal MNCC state machine.
Temporarily disable all paging to be able to link libmsc without libbsc.
Skip the paging part of channel_test because the paging is now disabled.
Employ fake paging shims in order for msc_vlr_tests to still work.
msc_compl_l3(): publish in .h, tweak return value. Use new libmsc enum values
for return val, to avoid dependency on libbsc headers. Make callable from
other scopes: publish in osmo_msc.h and remove 'static' in osmo_msc.c
add gsm_encr to subscr_conn
move subscr_request to gsm_subscriber.h
subscr_request_channel() -> subscr_request_conn()
move to libmsc: osmo_stats_vty_add_cmds()
gsm_04_08: remove apply_codec_restrictions()
gsm0408_test: use NULL for root ctx
move to libbsc: gsm_bts_neighbor()
move to libbsc: lchan_next_meas_rep()
move vty config for t3212 to network level (periodic lu)
remove unneccessary linking from some tests
remove handle_abisip_signal()
abis_rsl.c: don't use libvlr from libbsc
gsm_subscriber_connection: put the LAC here, so that it is available without
accessing conn->bts. In bsc_api.c, place this lac in conn for the sake of
transition: Iu and A will use this new field to pass the LAC around, but in a
completely separate OsmoBSC this is not actually needed. It can be removed
again from osmo-bsc.git when the time has come.
Siemens MRPCI: completely drop sending the MRPCI messages for now, they shall
be added in osmo-bsc once the A-Interface code has settled. See OS#2389.
Related: OS#1845 OS#2257 OS#2389
Change-Id: Id3705236350d5f69e447046b0a764bbabc3d493c
2017-05-08 13:12:20 +00:00
|
|
|
return msc_gsm48_tx_mm_serv_rej(conn,
|
|
|
|
GSM48_REJECT_INCORRECT_MESSAGE);
|
2009-01-10 01:49:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (msg->data_len < req->mi_len + 6) {
|
2019-01-04 16:42:05 +00:00
|
|
|
LOG_RAN_CONN(conn, LOGL_ERROR, "Rx CM SERVICE REQUEST: message does not fit in packet\n");
|
mscsplit: various preparations to separate MSC from BSC
Disable large parts of the code that depend on BSC presence. The code sections
disabled by #if BEFORE_MSCSPLIT shall be modified or dropped in the course of
adding the A-interface.
Don't set msg->lchan nor msg->dst.
Don't use lchan in libmsc.
Decouple lac from bts.
Prepare entry/exit point for MSC -> BSC and MSC -> RNC communication:
Add msc_ifaces.[hc], a_iface.c, with a general msc_tx_dtap() to redirect to
different interfaces depending on the actual subscriber connection.
While iu_tx() is going to be functional fairly soon, the a_tx() is going to be
just a dummy for some time (see comment).
Add Iu specific fields in gsm_subscriber_connection: the UE connection pointer
and an indicator for the Integrity Protection status on Iu (to be fully
implemented in later commits).
Add lac member to gsm_subscriber_connection, to allow decoupling from
bts->location_area_code. The conn->lac will actually be set in iu.c in an
upcoming commit ("add iucs.[hc]").
move to libcommon-cs: gsm48_extract_mi(), gsm48_paging_extract_mi().
libmsc: duplicate gsm0808 / gsm48 functions (towards BSC).
In osmo-nitb, libmsc would directly call the functions on the BSC level, not
always via the bsc_api. When separating libmsc from libbsc, some functions are
missing from the linkage.
Hence duplicate these functions to libmsc, add an msc_ prefix for clarity, also
add a _tx to gsm0808_cipher_mode():
* add msc_gsm0808_tx_cipher_mode() (dummy/stub)
* add msc_gsm48_tx_mm_serv_ack()
* add msc_gsm48_tx_mm_serv_rej()
Call these from libmsc instead of
* gsm0808_cipher_mode()
* gsm48_tx_mm_serv_ack()
* gsm48_tx_mm_serv_rej()
Also add a comment related to msc_gsm0808_tx_cipher_mode() in two places.
Remove internal RTP streaming code; OsmoNITB supported that, but for OsmoMSC,
this will be done with an external MGCP gateway.
Remove LCHAN_MODIFY from internal MNCC state machine.
Temporarily disable all paging to be able to link libmsc without libbsc.
Skip the paging part of channel_test because the paging is now disabled.
Employ fake paging shims in order for msc_vlr_tests to still work.
msc_compl_l3(): publish in .h, tweak return value. Use new libmsc enum values
for return val, to avoid dependency on libbsc headers. Make callable from
other scopes: publish in osmo_msc.h and remove 'static' in osmo_msc.c
add gsm_encr to subscr_conn
move subscr_request to gsm_subscriber.h
subscr_request_channel() -> subscr_request_conn()
move to libmsc: osmo_stats_vty_add_cmds()
gsm_04_08: remove apply_codec_restrictions()
gsm0408_test: use NULL for root ctx
move to libbsc: gsm_bts_neighbor()
move to libbsc: lchan_next_meas_rep()
move vty config for t3212 to network level (periodic lu)
remove unneccessary linking from some tests
remove handle_abisip_signal()
abis_rsl.c: don't use libvlr from libbsc
gsm_subscriber_connection: put the LAC here, so that it is available without
accessing conn->bts. In bsc_api.c, place this lac in conn for the sake of
transition: Iu and A will use this new field to pass the LAC around, but in a
completely separate OsmoBSC this is not actually needed. It can be removed
again from osmo-bsc.git when the time has come.
Siemens MRPCI: completely drop sending the MRPCI messages for now, they shall
be added in osmo-bsc once the A-Interface code has settled. See OS#2389.
Related: OS#1845 OS#2257 OS#2389
Change-Id: Id3705236350d5f69e447046b0a764bbabc3d493c
2017-05-08 13:12:20 +00:00
|
|
|
return msc_gsm48_tx_mm_serv_rej(conn,
|
|
|
|
GSM48_REJECT_INCORRECT_MESSAGE);
|
2009-01-10 01:49:35 +00:00
|
|
|
}
|
|
|
|
|
2019-01-04 16:42:05 +00:00
|
|
|
if (ran_conn_is_establishing_auth_ciph(conn)) {
|
|
|
|
LOG_RAN_CONN(conn, 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? */
|
|
|
|
}
|
|
|
|
|
2019-01-03 01:32:14 +00:00
|
|
|
conn->complete_layer3_type = COMPLETE_LAYER3_CM_SERVICE_REQ;
|
|
|
|
ran_conn_update_id_from_mi(conn, mi, mi_len);
|
|
|
|
LOG_RAN_CONN_CAT(conn, DMM, LOGL_DEBUG, "Rx CM SERVICE REQUEST cm_service_type=0x%02x\n",
|
|
|
|
req->cm_service_type);
|
2015-07-13 18:33:08 +00:00
|
|
|
|
2019-01-03 01:32:14 +00:00
|
|
|
mi_type = (mi && mi_len) ? (mi[0] & GSM_MI_TYPE_MASK) : GSM_MI_TYPE_NONE;
|
2018-01-24 10:23:54 +00:00
|
|
|
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 */
|
2019-01-04 16:42:05 +00:00
|
|
|
LOG_RAN_CONN(conn, LOGL_NOTICE, "Tx CM SERVICE REQUEST REJECT\n");
|
2018-01-24 10:23:54 +00:00
|
|
|
return msc_gsm48_tx_mm_serv_rej(conn, GSM48_REJECT_IMEI_NOT_ACCEPTED);
|
|
|
|
}
|
|
|
|
/* fall-through for non-emergency setup */
|
|
|
|
default:
|
2019-01-03 01:32:14 +00:00
|
|
|
LOG_RAN_CONN(conn, LOGL_ERROR, "MI type is not expected: %s\n", gsm48_mi_type_name(mi_type));
|
mscsplit: various preparations to separate MSC from BSC
Disable large parts of the code that depend on BSC presence. The code sections
disabled by #if BEFORE_MSCSPLIT shall be modified or dropped in the course of
adding the A-interface.
Don't set msg->lchan nor msg->dst.
Don't use lchan in libmsc.
Decouple lac from bts.
Prepare entry/exit point for MSC -> BSC and MSC -> RNC communication:
Add msc_ifaces.[hc], a_iface.c, with a general msc_tx_dtap() to redirect to
different interfaces depending on the actual subscriber connection.
While iu_tx() is going to be functional fairly soon, the a_tx() is going to be
just a dummy for some time (see comment).
Add Iu specific fields in gsm_subscriber_connection: the UE connection pointer
and an indicator for the Integrity Protection status on Iu (to be fully
implemented in later commits).
Add lac member to gsm_subscriber_connection, to allow decoupling from
bts->location_area_code. The conn->lac will actually be set in iu.c in an
upcoming commit ("add iucs.[hc]").
move to libcommon-cs: gsm48_extract_mi(), gsm48_paging_extract_mi().
libmsc: duplicate gsm0808 / gsm48 functions (towards BSC).
In osmo-nitb, libmsc would directly call the functions on the BSC level, not
always via the bsc_api. When separating libmsc from libbsc, some functions are
missing from the linkage.
Hence duplicate these functions to libmsc, add an msc_ prefix for clarity, also
add a _tx to gsm0808_cipher_mode():
* add msc_gsm0808_tx_cipher_mode() (dummy/stub)
* add msc_gsm48_tx_mm_serv_ack()
* add msc_gsm48_tx_mm_serv_rej()
Call these from libmsc instead of
* gsm0808_cipher_mode()
* gsm48_tx_mm_serv_ack()
* gsm48_tx_mm_serv_rej()
Also add a comment related to msc_gsm0808_tx_cipher_mode() in two places.
Remove internal RTP streaming code; OsmoNITB supported that, but for OsmoMSC,
this will be done with an external MGCP gateway.
Remove LCHAN_MODIFY from internal MNCC state machine.
Temporarily disable all paging to be able to link libmsc without libbsc.
Skip the paging part of channel_test because the paging is now disabled.
Employ fake paging shims in order for msc_vlr_tests to still work.
msc_compl_l3(): publish in .h, tweak return value. Use new libmsc enum values
for return val, to avoid dependency on libbsc headers. Make callable from
other scopes: publish in osmo_msc.h and remove 'static' in osmo_msc.c
add gsm_encr to subscr_conn
move subscr_request to gsm_subscriber.h
subscr_request_channel() -> subscr_request_conn()
move to libmsc: osmo_stats_vty_add_cmds()
gsm_04_08: remove apply_codec_restrictions()
gsm0408_test: use NULL for root ctx
move to libbsc: gsm_bts_neighbor()
move to libbsc: lchan_next_meas_rep()
move vty config for t3212 to network level (periodic lu)
remove unneccessary linking from some tests
remove handle_abisip_signal()
abis_rsl.c: don't use libvlr from libbsc
gsm_subscriber_connection: put the LAC here, so that it is available without
accessing conn->bts. In bsc_api.c, place this lac in conn for the sake of
transition: Iu and A will use this new field to pass the LAC around, but in a
completely separate OsmoBSC this is not actually needed. It can be removed
again from osmo-bsc.git when the time has come.
Siemens MRPCI: completely drop sending the MRPCI messages for now, they shall
be added in osmo-bsc once the A-Interface code has settled. See OS#2389.
Related: OS#1845 OS#2257 OS#2389
Change-Id: Id3705236350d5f69e447046b0a764bbabc3d493c
2017-05-08 13:12:20 +00:00
|
|
|
return msc_gsm48_tx_mm_serv_rej(conn,
|
|
|
|
GSM48_REJECT_INCORRECT_MESSAGE);
|
2009-01-10 01:49:35 +00:00
|
|
|
}
|
2008-12-27 21:45:37 +00:00
|
|
|
|
2018-01-24 11:49:34 +00:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
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-29 21:37:51 +00:00
|
|
|
if (ran_conn_is_accepted(conn))
|
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-03-30 22:02:14 +00:00
|
|
|
return cm_serv_reuse_conn(conn, mi_p);
|
2016-06-19 16:06:02 +00:00
|
|
|
|
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-03-30 22:02:14 +00:00
|
|
|
osmo_signal_dispatch(SS_SUBSCR, S_SUBSCR_IDENTITY, mi_p);
|
|
|
|
|
2018-12-25 23:40:18 +00:00
|
|
|
is_utran = (conn->via_ran == OSMO_RAT_UTRAN_IU);
|
2018-03-31 16:45:59 +00:00
|
|
|
vlr_proc_acc_req(conn->fi,
|
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-29 21:37:51 +00:00
|
|
|
RAN_CONN_E_ACCEPTED, RAN_CONN_E_CN_CLOSE, NULL,
|
2016-06-19 16:06:02 +00:00
|
|
|
net->vlr, conn,
|
|
|
|
VLR_PR_ARQ_T_CM_SERV_REQ, mi-1, &lai,
|
2016-05-20 19:59:55 +00:00
|
|
|
is_utran || conn->network->authentication_required,
|
2017-12-23 18:30:32 +00:00
|
|
|
is_utran || conn->network->a5_encryption_mask > 0x01,
|
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-13 01:05:52 +00:00
|
|
|
classmark2_is_r99(classmark2, classmark2_len),
|
2016-05-20 19:59:55 +00:00
|
|
|
is_utran);
|
2013-06-30 13:30:47 +00:00
|
|
|
|
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-13 01:05:52 +00:00
|
|
|
/* 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) {
|
2019-01-04 16:42:05 +00:00
|
|
|
LOG_RAN_CONN(conn, LOGL_ERROR, "subscriber not allowed to do a CM Service Request\n");
|
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-13 01:05:52 +00:00
|
|
|
return -EIO;
|
|
|
|
}
|
|
|
|
|
|
|
|
memcpy(conn->vsub->classmark.classmark2, classmark2, classmark2_len);
|
|
|
|
conn->vsub->classmark.classmark2_len = classmark2_len;
|
|
|
|
|
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-29 21:37:51 +00:00
|
|
|
ran_conn_complete_layer_3(conn);
|
2016-06-19 16:06:02 +00:00
|
|
|
return 0;
|
2008-12-27 01:55:51 +00:00
|
|
|
}
|
|
|
|
|
2018-01-24 20:40:19 +00:00
|
|
|
/* Receive a CM Re-establish Request */
|
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-29 21:37:51 +00:00
|
|
|
static int gsm48_rx_cm_reest_req(struct ran_conn *conn, struct msgb *msg)
|
2018-01-24 20:40:19 +00:00
|
|
|
{
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
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-29 21:37:51 +00:00
|
|
|
static int gsm48_rx_mm_imsi_detach_ind(struct ran_conn *conn, struct msgb *msg)
|
2009-02-22 21:14:55 +00:00
|
|
|
{
|
2016-05-09 19:09:47 +00:00
|
|
|
struct gsm_network *network = conn->network;
|
2009-02-22 21:14:55 +00:00
|
|
|
struct gsm48_hdr *gh = msgb_l3(msg);
|
|
|
|
struct gsm48_imsi_detach_ind *idi =
|
|
|
|
(struct gsm48_imsi_detach_ind *) gh->data;
|
2011-04-18 15:04:00 +00:00
|
|
|
uint8_t mi_type = idi->mi[0] & GSM_MI_TYPE_MASK;
|
2009-08-19 05:54:59 +00:00
|
|
|
char mi_string[GSM48_MI_SIZE];
|
2016-06-19 16:06:02 +00:00
|
|
|
struct vlr_subscr *vsub = NULL;
|
2009-02-22 21:14:55 +00:00
|
|
|
|
2009-08-19 05:54:59 +00:00
|
|
|
gsm48_mi_to_string(mi_string, sizeof(mi_string), idi->mi, idi->mi_len);
|
2016-06-19 16:06:02 +00:00
|
|
|
DEBUGP(DMM, "IMSI DETACH INDICATION: MI(%s)=%s\n",
|
|
|
|
gsm48_mi_type_name(mi_type), mi_string);
|
2009-02-22 21:14:55 +00:00
|
|
|
|
2016-05-09 19:09:47 +00:00
|
|
|
rate_ctr_inc(&network->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_DETACH]);
|
2009-12-21 23:41:05 +00:00
|
|
|
|
2009-02-22 21:14:55 +00:00
|
|
|
switch (mi_type) {
|
|
|
|
case GSM_MI_TYPE_TMSI:
|
2016-06-19 16:06:02 +00:00
|
|
|
vsub = vlr_subscr_find_by_tmsi(network->vlr,
|
|
|
|
tmsi_from_string(mi_string));
|
2009-02-22 21:14:55 +00:00
|
|
|
break;
|
|
|
|
case GSM_MI_TYPE_IMSI:
|
2016-06-19 16:06:02 +00:00
|
|
|
vsub = vlr_subscr_find_by_imsi(network->vlr, mi_string);
|
2009-02-22 21:14:55 +00:00
|
|
|
break;
|
|
|
|
case GSM_MI_TYPE_IMEI:
|
|
|
|
case GSM_MI_TYPE_IMEISV:
|
|
|
|
/* no sim card... FIXME: what to do ? */
|
2016-06-19 16:06:02 +00:00
|
|
|
LOGP(DMM, LOGL_ERROR, "MI(%s)=%s: unimplemented mobile identity type\n",
|
|
|
|
gsm48_mi_type_name(mi_type), mi_string);
|
2009-02-22 21:14:55 +00:00
|
|
|
break;
|
2016-08-29 16:40:02 +00:00
|
|
|
default:
|
2016-06-19 16:06:02 +00:00
|
|
|
LOGP(DMM, LOGL_ERROR, "MI(%s)=%s: unknown mobile identity type\n",
|
|
|
|
gsm48_mi_type_name(mi_type), mi_string);
|
2009-02-22 21:14:55 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2016-06-19 16:06:02 +00:00
|
|
|
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));
|
2017-12-15 02:48:48 +00:00
|
|
|
|
|
|
|
if (vsub->cs.is_paging)
|
|
|
|
subscr_paging_cancel(vsub, GSM_PAGING_EXPIRED);
|
|
|
|
|
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-13 01:05:52 +00:00
|
|
|
/* We already got Classmark 1 during Location Updating ... but well, ok */
|
|
|
|
vsub->classmark.classmark1 = idi->classmark1;
|
|
|
|
|
2016-06-19 16:06:02 +00:00
|
|
|
vlr_subscr_rx_imsi_detach(vsub);
|
|
|
|
osmo_signal_dispatch(SS_SUBSCR, S_SUBSCR_DETACHED, vsub);
|
|
|
|
vlr_subscr_put(vsub);
|
|
|
|
}
|
2009-12-20 08:58:40 +00:00
|
|
|
|
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-29 21:37:51 +00:00
|
|
|
ran_conn_close(conn, 0);
|
2009-02-22 21:14:55 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2009-06-05 20:08:20 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2017-02-03 00:22:40 +00:00
|
|
|
static int parse_gsm_auth_resp(uint8_t *res, uint8_t *res_len,
|
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-29 21:37:51 +00:00
|
|
|
struct ran_conn *conn,
|
2017-02-03 00:22:40 +00:00
|
|
|
struct msgb *msg)
|
2009-12-23 23:27:26 +00:00
|
|
|
{
|
|
|
|
struct gsm48_hdr *gh = msgb_l3(msg);
|
|
|
|
struct gsm48_auth_resp *ar = (struct gsm48_auth_resp*) gh->data;
|
2017-02-03 00:22:40 +00:00
|
|
|
|
|
|
|
if (msgb_l3len(msg) < sizeof(*gh) + sizeof(*ar)) {
|
|
|
|
LOGP(DMM, LOGL_ERROR,
|
|
|
|
"%s: MM AUTHENTICATION RESPONSE:"
|
|
|
|
" l3 length invalid: %u\n",
|
2016-06-19 16:06:02 +00:00
|
|
|
vlr_subscr_name(conn->vsub), msgb_l3len(msg));
|
2017-02-03 00:22:40 +00:00
|
|
|
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,
|
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-29 21:37:51 +00:00
|
|
|
struct ran_conn *conn,
|
2017-02-03 00:22:40 +00:00
|
|
|
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",
|
2016-06-19 16:06:02 +00:00
|
|
|
vlr_subscr_name(conn->vsub), msgb_l3len(msg));
|
2017-02-03 00:22:40 +00:00
|
|
|
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",
|
2016-06-19 16:06:02 +00:00
|
|
|
vlr_subscr_name(conn->vsub),
|
2017-02-03 00:22:40 +00:00
|
|
|
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",
|
2016-06-19 16:06:02 +00:00
|
|
|
vlr_subscr_name(conn->vsub), GSM48_IE_AUTH_RES_EXT, ie_len);
|
2017-02-03 00:22:40 +00:00
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
*res_len += ie_len;
|
|
|
|
memcpy(res + 4, &data[2], ie_len);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Chapter 9.2.3: Authentication Response */
|
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-29 21:37:51 +00:00
|
|
|
static int gsm48_rx_mm_auth_resp(struct ran_conn *conn, struct msgb *msg)
|
2017-02-03 00:22:40 +00:00
|
|
|
{
|
|
|
|
uint8_t res[16];
|
|
|
|
uint8_t res_len;
|
|
|
|
int rc;
|
2018-03-10 02:44:06 +00:00
|
|
|
bool is_umts;
|
2017-02-03 00:22:40 +00:00
|
|
|
|
2016-06-19 16:06:02 +00:00
|
|
|
if (!conn->vsub) {
|
2017-02-03 00:22:40 +00:00
|
|
|
LOGP(DMM, LOGL_ERROR,
|
|
|
|
"MM AUTHENTICATION RESPONSE: invalid: no subscriber\n");
|
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-29 21:37:51 +00:00
|
|
|
ran_conn_close(conn, GSM_CAUSE_AUTH_FAILED);
|
2017-02-03 00:22:40 +00:00
|
|
|
return -EINVAL;
|
|
|
|
}
|
2009-12-23 23:27:26 +00:00
|
|
|
|
2018-03-10 02:44:06 +00:00
|
|
|
is_umts = (msgb_l3len(msg) > sizeof(struct gsm48_hdr) + sizeof(struct gsm48_auth_resp));
|
|
|
|
|
|
|
|
if (is_umts)
|
2017-02-03 00:22:40 +00:00
|
|
|
rc = parse_umts_auth_resp(res, &res_len, conn, msg);
|
2018-03-10 02:44:06 +00:00
|
|
|
else
|
2017-02-03 00:22:40 +00:00
|
|
|
rc = parse_gsm_auth_resp(res, &res_len, conn, msg);
|
|
|
|
|
|
|
|
if (rc) {
|
2018-03-10 02:32:18 +00:00
|
|
|
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",
|
2018-03-10 02:44:06 +00:00
|
|
|
vlr_subscr_name(conn->vsub), is_umts ? "UMTS" : "GSM", rc);
|
2018-03-10 02:32:18 +00:00
|
|
|
memset(res, 0, sizeof(res));
|
|
|
|
res_len = 0;
|
2017-02-03 00:22:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
DEBUGP(DMM, "%s: MM %s AUTHENTICATION RESPONSE (%s = %s)\n",
|
2016-06-19 16:06:02 +00:00
|
|
|
vlr_subscr_name(conn->vsub),
|
2018-03-10 03:51:39 +00:00
|
|
|
is_umts ? "UMTS" : "GSM", is_umts ? "res" : "sres",
|
2017-02-03 00:22:40 +00:00
|
|
|
osmo_hexdump_nospc(res, res_len));
|
|
|
|
|
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-13 01:05:52 +00:00
|
|
|
return vlr_subscr_rx_auth_resp(conn->vsub, classmark_is_r99(&conn->vsub->classmark),
|
2018-12-25 23:40:18 +00:00
|
|
|
conn->via_ran == OSMO_RAT_UTRAN_IU,
|
2016-06-19 16:06:02 +00:00
|
|
|
res, res_len);
|
2009-12-23 23:27:26 +00:00
|
|
|
}
|
|
|
|
|
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-29 21:37:51 +00:00
|
|
|
static int gsm48_rx_mm_auth_fail(struct ran_conn *conn, struct msgb *msg)
|
2017-02-03 00:22:40 +00:00
|
|
|
{
|
|
|
|
struct gsm48_hdr *gh = msgb_l3(msg);
|
|
|
|
uint8_t cause;
|
|
|
|
uint8_t auts_tag;
|
|
|
|
uint8_t auts_len;
|
|
|
|
uint8_t *auts;
|
|
|
|
|
2016-06-19 16:06:02 +00:00
|
|
|
if (!conn->vsub) {
|
2017-02-03 00:22:40 +00:00
|
|
|
LOGP(DMM, LOGL_ERROR,
|
|
|
|
"MM R99 AUTHENTICATION FAILURE: invalid: no subscriber\n");
|
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-29 21:37:51 +00:00
|
|
|
ran_conn_close(conn, GSM_CAUSE_AUTH_FAILED);
|
2017-02-03 00:22:40 +00:00
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (msgb_l3len(msg) < sizeof(*gh) + 1) {
|
|
|
|
LOGP(DMM, LOGL_ERROR,
|
|
|
|
"%s: MM R99 AUTHENTICATION FAILURE:"
|
|
|
|
" l3 length invalid: %u\n",
|
2016-06-19 16:06:02 +00:00
|
|
|
vlr_subscr_name(conn->vsub), msgb_l3len(msg));
|
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-29 21:37:51 +00:00
|
|
|
ran_conn_close(conn, GSM_CAUSE_AUTH_FAILED);
|
2017-02-03 00:22:40 +00:00
|
|
|
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",
|
2016-06-19 16:06:02 +00:00
|
|
|
vlr_subscr_name(conn->vsub), cause);
|
|
|
|
vlr_subscr_rx_auth_fail(conn->vsub, NULL);
|
|
|
|
return 0;
|
2017-02-03 00:22:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* 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",
|
2016-06-19 16:06:02 +00:00
|
|
|
vlr_subscr_name(conn->vsub));
|
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-29 21:37:51 +00:00
|
|
|
ran_conn_close(conn, GSM_CAUSE_AUTH_FAILED);
|
2017-02-03 00:22:40 +00:00
|
|
|
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",
|
2016-06-19 16:06:02 +00:00
|
|
|
vlr_subscr_name(conn->vsub),
|
2017-02-03 00:22:40 +00:00
|
|
|
GSM48_IE_AUTS, auts_tag, auts_len);
|
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-29 21:37:51 +00:00
|
|
|
ran_conn_close(conn, GSM_CAUSE_AUTH_FAILED);
|
2017-02-03 00:22:40 +00:00
|
|
|
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",
|
2016-06-19 16:06:02 +00:00
|
|
|
vlr_subscr_name(conn->vsub), msgb_l3len(msg));
|
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-29 21:37:51 +00:00
|
|
|
ran_conn_close(conn, GSM_CAUSE_AUTH_FAILED);
|
2017-02-03 00:22:40 +00:00
|
|
|
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",
|
2016-06-19 16:06:02 +00:00
|
|
|
vlr_subscr_name(conn->vsub), osmo_hexdump_nospc(auts, 14));
|
2017-02-03 00:22:40 +00:00
|
|
|
|
2016-06-19 16:06:02 +00:00
|
|
|
return vlr_subscr_rx_auth_fail(conn->vsub, auts);
|
|
|
|
}
|
2017-02-03 00:22:40 +00:00
|
|
|
|
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-29 21:37:51 +00:00
|
|
|
static int gsm48_rx_mm_tmsi_reall_compl(struct ran_conn *conn)
|
2016-06-19 16:06:02 +00:00
|
|
|
{
|
|
|
|
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);
|
2017-02-03 00:22:40 +00:00
|
|
|
}
|
|
|
|
|
2009-02-03 12:59:45 +00:00
|
|
|
/* Receive a GSM 04.08 Mobility Management (MM) message */
|
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-29 21:37:51 +00:00
|
|
|
static int gsm0408_rcv_mm(struct ran_conn *conn, struct msgb *msg)
|
2008-12-23 20:25:15 +00:00
|
|
|
{
|
|
|
|
struct gsm48_hdr *gh = msgb_l3(msg);
|
2009-06-10 15:11:52 +00:00
|
|
|
int rc = 0;
|
2008-12-23 20:25:15 +00:00
|
|
|
|
2016-03-14 15:13:24 +00:00
|
|
|
switch (gsm48_hdr_msg_type(gh)) {
|
2008-12-23 20:25:15 +00:00
|
|
|
case GSM48_MT_MM_LOC_UPD_REQUEST:
|
2010-06-17 09:14:35 +00:00
|
|
|
rc = mm_rx_loc_upd_req(conn, msg);
|
2008-12-23 20:25:15 +00:00
|
|
|
break;
|
|
|
|
case GSM48_MT_MM_ID_RESP:
|
2010-06-17 09:14:35 +00:00
|
|
|
rc = mm_rx_id_resp(conn, msg);
|
2008-12-27 11:15:38 +00:00
|
|
|
break;
|
2008-12-23 20:25:15 +00:00
|
|
|
case GSM48_MT_MM_CM_SERV_REQ:
|
2010-06-17 09:14:35 +00:00
|
|
|
rc = gsm48_rx_mm_serv_req(conn, msg);
|
2008-12-27 01:55:51 +00:00
|
|
|
break;
|
2008-12-27 11:15:38 +00:00
|
|
|
case GSM48_MT_MM_STATUS:
|
2009-06-05 20:08:20 +00:00
|
|
|
rc = gsm48_rx_mm_status(msg);
|
2008-12-27 11:15:38 +00:00
|
|
|
break;
|
|
|
|
case GSM48_MT_MM_TMSI_REALL_COMPL:
|
2016-06-19 16:06:02 +00:00
|
|
|
rc = gsm48_rx_mm_tmsi_reall_compl(conn);
|
2009-01-06 19:47:00 +00:00
|
|
|
break;
|
2009-02-22 21:14:55 +00:00
|
|
|
case GSM48_MT_MM_IMSI_DETACH_IND:
|
2012-07-10 06:53:27 +00:00
|
|
|
rc = gsm48_rx_mm_imsi_detach_ind(conn, msg);
|
2009-02-22 21:14:55 +00:00
|
|
|
break;
|
2009-01-06 19:47:00 +00:00
|
|
|
case GSM48_MT_MM_CM_REEST_REQ:
|
2018-01-24 20:40:19 +00:00
|
|
|
rc = gsm48_rx_cm_reest_req(conn, msg);
|
2009-02-22 21:14:55 +00:00
|
|
|
break;
|
2008-12-27 11:15:38 +00:00
|
|
|
case GSM48_MT_MM_AUTH_RESP:
|
2010-06-17 09:14:35 +00:00
|
|
|
rc = gsm48_rx_mm_auth_resp(conn, msg);
|
2008-12-23 20:25:15 +00:00
|
|
|
break;
|
2017-02-03 00:22:40 +00:00
|
|
|
case GSM48_MT_MM_AUTH_FAIL:
|
|
|
|
rc = gsm48_rx_mm_auth_fail(conn, msg);
|
|
|
|
break;
|
2008-12-23 20:25:15 +00:00
|
|
|
default:
|
2009-12-24 11:13:17 +00:00
|
|
|
LOGP(DMM, LOGL_NOTICE, "Unknown GSM 04.08 MM msg type 0x%02x\n",
|
2008-12-23 20:25:15 +00:00
|
|
|
gh->msg_type);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return rc;
|
|
|
|
}
|
2009-02-03 12:59:45 +00:00
|
|
|
|
2009-02-06 12:02:13 +00:00
|
|
|
/* Receive a PAGING RESPONSE message from the MS */
|
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-29 21:37:51 +00:00
|
|
|
static int gsm48_rx_rr_pag_resp(struct ran_conn *conn, struct msgb *msg)
|
2009-02-06 12:02:13 +00:00
|
|
|
{
|
2016-06-19 16:06:02 +00:00
|
|
|
struct gsm_network *net = conn->network;
|
2009-02-06 12:02:13 +00:00
|
|
|
struct gsm48_hdr *gh = msgb_l3(msg);
|
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-13 01:05:52 +00:00
|
|
|
uint8_t classmark2_len = gh->data[1];
|
|
|
|
uint8_t *classmark2 = gh->data+2;
|
|
|
|
uint8_t *mi_lv = classmark2 + classmark2_len;
|
2016-06-19 16:06:02 +00:00
|
|
|
struct osmo_location_area_id lai;
|
2016-05-20 19:59:55 +00:00
|
|
|
bool is_utran;
|
2016-06-19 16:06:02 +00:00
|
|
|
|
2018-02-22 03:04:54 +00:00
|
|
|
lai.plmn = conn->network->plmn;
|
mscsplit: various preparations to separate MSC from BSC
Disable large parts of the code that depend on BSC presence. The code sections
disabled by #if BEFORE_MSCSPLIT shall be modified or dropped in the course of
adding the A-interface.
Don't set msg->lchan nor msg->dst.
Don't use lchan in libmsc.
Decouple lac from bts.
Prepare entry/exit point for MSC -> BSC and MSC -> RNC communication:
Add msc_ifaces.[hc], a_iface.c, with a general msc_tx_dtap() to redirect to
different interfaces depending on the actual subscriber connection.
While iu_tx() is going to be functional fairly soon, the a_tx() is going to be
just a dummy for some time (see comment).
Add Iu specific fields in gsm_subscriber_connection: the UE connection pointer
and an indicator for the Integrity Protection status on Iu (to be fully
implemented in later commits).
Add lac member to gsm_subscriber_connection, to allow decoupling from
bts->location_area_code. The conn->lac will actually be set in iu.c in an
upcoming commit ("add iucs.[hc]").
move to libcommon-cs: gsm48_extract_mi(), gsm48_paging_extract_mi().
libmsc: duplicate gsm0808 / gsm48 functions (towards BSC).
In osmo-nitb, libmsc would directly call the functions on the BSC level, not
always via the bsc_api. When separating libmsc from libbsc, some functions are
missing from the linkage.
Hence duplicate these functions to libmsc, add an msc_ prefix for clarity, also
add a _tx to gsm0808_cipher_mode():
* add msc_gsm0808_tx_cipher_mode() (dummy/stub)
* add msc_gsm48_tx_mm_serv_ack()
* add msc_gsm48_tx_mm_serv_rej()
Call these from libmsc instead of
* gsm0808_cipher_mode()
* gsm48_tx_mm_serv_ack()
* gsm48_tx_mm_serv_rej()
Also add a comment related to msc_gsm0808_tx_cipher_mode() in two places.
Remove internal RTP streaming code; OsmoNITB supported that, but for OsmoMSC,
this will be done with an external MGCP gateway.
Remove LCHAN_MODIFY from internal MNCC state machine.
Temporarily disable all paging to be able to link libmsc without libbsc.
Skip the paging part of channel_test because the paging is now disabled.
Employ fake paging shims in order for msc_vlr_tests to still work.
msc_compl_l3(): publish in .h, tweak return value. Use new libmsc enum values
for return val, to avoid dependency on libbsc headers. Make callable from
other scopes: publish in osmo_msc.h and remove 'static' in osmo_msc.c
add gsm_encr to subscr_conn
move subscr_request to gsm_subscriber.h
subscr_request_channel() -> subscr_request_conn()
move to libmsc: osmo_stats_vty_add_cmds()
gsm_04_08: remove apply_codec_restrictions()
gsm0408_test: use NULL for root ctx
move to libbsc: gsm_bts_neighbor()
move to libbsc: lchan_next_meas_rep()
move vty config for t3212 to network level (periodic lu)
remove unneccessary linking from some tests
remove handle_abisip_signal()
abis_rsl.c: don't use libvlr from libbsc
gsm_subscriber_connection: put the LAC here, so that it is available without
accessing conn->bts. In bsc_api.c, place this lac in conn for the sake of
transition: Iu and A will use this new field to pass the LAC around, but in a
completely separate OsmoBSC this is not actually needed. It can be removed
again from osmo-bsc.git when the time has come.
Siemens MRPCI: completely drop sending the MRPCI messages for now, they shall
be added in osmo-bsc once the A-Interface code has settled. See OS#2389.
Related: OS#1845 OS#2257 OS#2389
Change-Id: Id3705236350d5f69e447046b0a764bbabc3d493c
2017-05-08 13:12:20 +00:00
|
|
|
lai.lac = conn->lac;
|
2009-02-06 12:02:13 +00:00
|
|
|
|
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-29 21:37:51 +00:00
|
|
|
if (ran_conn_is_establishing_auth_ciph(conn)) {
|
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-03-30 22:02:14 +00:00
|
|
|
LOGP(DMM, LOGL_ERROR,
|
|
|
|
"Ignoring Paging Response, conn already busy establishing authenticity\n");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
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-29 21:37:51 +00:00
|
|
|
if (ran_conn_is_accepted(conn)) {
|
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-03-30 22:02:14 +00:00
|
|
|
LOGP(DMM, LOGL_ERROR, "Ignoring Paging Response, conn already established\n");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2019-01-03 01:32:14 +00:00
|
|
|
conn->complete_layer3_type = COMPLETE_LAYER3_PAGING_RESP;
|
|
|
|
ran_conn_update_id_from_mi(conn, mi_lv + 1, *mi_lv);
|
|
|
|
LOG_RAN_CONN_CAT(conn, DRR, LOGL_DEBUG, "PAGING RESPONSE\n");
|
2009-06-09 20:24:21 +00:00
|
|
|
|
2018-12-25 23:40:18 +00:00
|
|
|
is_utran = (conn->via_ran == OSMO_RAT_UTRAN_IU);
|
2018-03-31 16:45:59 +00:00
|
|
|
vlr_proc_acc_req(conn->fi,
|
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-29 21:37:51 +00:00
|
|
|
RAN_CONN_E_ACCEPTED, RAN_CONN_E_CN_CLOSE, NULL,
|
2016-06-19 16:06:02 +00:00
|
|
|
net->vlr, conn,
|
|
|
|
VLR_PR_ARQ_T_PAGING_RESP, mi_lv, &lai,
|
2016-05-20 19:59:55 +00:00
|
|
|
is_utran || conn->network->authentication_required,
|
2017-12-23 18:30:32 +00:00
|
|
|
is_utran || conn->network->a5_encryption_mask > 0x01,
|
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-13 01:05:52 +00:00
|
|
|
classmark2_is_r99(classmark2, classmark2_len),
|
2016-05-20 19:59:55 +00:00
|
|
|
is_utran);
|
2013-06-30 13:30:47 +00:00
|
|
|
|
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-13 01:05:52 +00:00
|
|
|
/* 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) {
|
2019-01-04 16:42:05 +00:00
|
|
|
LOG_RAN_CONN(conn, LOGL_ERROR, "subscriber not allowed to do a Paging Response\n");
|
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-13 01:05:52 +00:00
|
|
|
return -EIO;
|
|
|
|
}
|
|
|
|
|
|
|
|
memcpy(conn->vsub->classmark.classmark2, classmark2, classmark2_len);
|
|
|
|
conn->vsub->classmark.classmark2_len = classmark2_len;
|
|
|
|
|
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-29 21:37:51 +00:00
|
|
|
ran_conn_complete_layer_3(conn);
|
2016-05-20 19:59:55 +00:00
|
|
|
return 0;
|
2009-02-06 12:02:13 +00:00
|
|
|
}
|
|
|
|
|
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-29 21:37:51 +00:00
|
|
|
static int gsm48_rx_rr_app_info(struct ran_conn *conn, struct msgb *msg)
|
2009-08-15 21:32:44 +00:00
|
|
|
{
|
|
|
|
struct gsm48_hdr *gh = msgb_l3(msg);
|
2011-04-18 15:04:00 +00:00
|
|
|
uint8_t apdu_id_flags;
|
|
|
|
uint8_t apdu_len;
|
|
|
|
uint8_t *apdu_data;
|
2009-08-15 21:32:44 +00:00
|
|
|
|
|
|
|
apdu_id_flags = gh->data[0];
|
|
|
|
apdu_len = gh->data[1];
|
|
|
|
apdu_data = gh->data+2;
|
2016-08-29 16:40:02 +00:00
|
|
|
|
2017-02-09 18:13:02 +00:00
|
|
|
DEBUGP(DRR, "RX APPLICATION INFO id/flags=0x%02x apdu_len=%u apdu=%s\n",
|
2011-05-07 10:12:48 +00:00
|
|
|
apdu_id_flags, apdu_len, osmo_hexdump(apdu_data, apdu_len));
|
2009-08-15 21:32:44 +00:00
|
|
|
|
2016-06-19 16:06:02 +00:00
|
|
|
/* we're not using the app info blob anywhere, so ignore. */
|
|
|
|
#if 0
|
2010-06-17 09:14:35 +00:00
|
|
|
return db_apdu_blob_store(conn->subscr, apdu_id_flags, apdu_len, apdu_data);
|
2016-06-19 16:06:02 +00:00
|
|
|
#else
|
|
|
|
return 0;
|
|
|
|
#endif
|
2009-08-15 21:32:44 +00:00
|
|
|
}
|
|
|
|
|
2009-02-03 12:59:45 +00:00
|
|
|
/* Receive a GSM 04.08 Radio Resource (RR) message */
|
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-29 21:37:51 +00:00
|
|
|
static int gsm0408_rcv_rr(struct ran_conn *conn, struct msgb *msg)
|
2008-12-23 20:25:15 +00:00
|
|
|
{
|
|
|
|
struct gsm48_hdr *gh = msgb_l3(msg);
|
2009-02-06 12:02:13 +00:00
|
|
|
int rc = 0;
|
2008-12-23 20:25:15 +00:00
|
|
|
|
|
|
|
switch (gh->msg_type) {
|
|
|
|
case GSM48_MT_RR_PAG_RESP:
|
2010-06-21 02:46:44 +00:00
|
|
|
rc = gsm48_rx_rr_pag_resp(conn, msg);
|
2009-02-06 12:02:13 +00:00
|
|
|
break;
|
2009-08-15 21:32:44 +00:00
|
|
|
case GSM48_MT_RR_APP_INFO:
|
2010-06-17 09:14:35 +00:00
|
|
|
rc = gsm48_rx_rr_app_info(conn, msg);
|
2009-08-15 21:32:44 +00:00
|
|
|
break;
|
2008-12-23 20:25:15 +00:00
|
|
|
default:
|
2016-10-10 13:11:41 +00:00
|
|
|
LOGP(DRR, LOGL_NOTICE, "MSC: Unimplemented %s GSM 04.08 RR "
|
|
|
|
"message\n", gsm48_rr_msg_name(gh->msg_type));
|
2008-12-23 20:25:15 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2009-02-06 12:02:13 +00:00
|
|
|
return rc;
|
2008-12-23 20:25:15 +00:00
|
|
|
}
|
|
|
|
|
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-29 21:37:51 +00:00
|
|
|
int gsm48_send_rr_app_info(struct ran_conn *conn, uint8_t apdu_id,
|
2011-04-18 15:04:00 +00:00
|
|
|
uint8_t apdu_len, const uint8_t *apdu)
|
2009-08-15 21:32:44 +00:00
|
|
|
{
|
2016-01-25 21:03:25 +00:00
|
|
|
struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 APP INF");
|
2009-08-15 21:32:44 +00:00
|
|
|
struct gsm48_hdr *gh;
|
|
|
|
|
|
|
|
DEBUGP(DRR, "TX APPLICATION INFO id=0x%02x, len=%u\n",
|
|
|
|
apdu_id, apdu_len);
|
2016-08-29 16:40:02 +00:00
|
|
|
|
2009-08-15 21:32:44 +00:00
|
|
|
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);
|
|
|
|
|
2010-06-16 05:52:55 +00:00
|
|
|
return gsm48_conn_sendmsg(msg, conn, NULL);
|
2009-08-15 21:32:44 +00:00
|
|
|
}
|
|
|
|
|
2018-06-21 18:39:20 +00:00
|
|
|
static bool msg_is_initially_permitted(const struct gsm48_hdr *hdr)
|
2016-08-23 05:32:27 +00:00
|
|
|
{
|
2018-06-21 18:39:20 +00:00
|
|
|
uint8_t pdisc = gsm48_hdr_pdisc(hdr);
|
|
|
|
uint8_t msg_type = gsm48_hdr_msg_type(hdr);
|
2016-08-23 05:32:27 +00:00
|
|
|
|
2018-06-21 18:39:20 +00:00
|
|
|
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;
|
|
|
|
}
|
2016-08-23 05:32:27 +00:00
|
|
|
break;
|
2018-06-21 18:39:20 +00:00
|
|
|
case GSM48_PDISC_RR:
|
|
|
|
switch (msg_type) {
|
2018-12-07 15:39:52 +00:00
|
|
|
/* GSM48_MT_RR_CIPH_M_COMPL is actually handled in bssmap_rx_ciph_compl() and gets redirected in the
|
|
|
|
* BSSAP layer to ran_conn_cipher_mode_compl() (before this here is reached) */
|
2018-06-21 18:39:20 +00:00
|
|
|
case GSM48_MT_RR_PAG_RESP:
|
|
|
|
return true;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
2016-08-23 05:32:27 +00:00
|
|
|
break;
|
|
|
|
}
|
2009-02-11 11:44:12 +00:00
|
|
|
|
2018-06-21 18:39:20 +00:00
|
|
|
return false;
|
2009-06-10 15:11:52 +00:00
|
|
|
}
|
|
|
|
|
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-29 21:37:51 +00:00
|
|
|
void cm_service_request_concludes(struct ran_conn *conn,
|
2018-06-21 18:39:20 +00:00
|
|
|
struct msgb *msg)
|
2008-12-27 16:32:52 +00:00
|
|
|
{
|
|
|
|
|
2018-06-21 18:39:20 +00:00
|
|
|
/* If a CM Service Request was received before, this is the request the
|
|
|
|
* conn was opened for. No need to wait for further messages. */
|
2008-12-27 16:32:52 +00:00
|
|
|
|
2018-06-21 18:39:20 +00:00
|
|
|
if (!conn->received_cm_service_request)
|
|
|
|
return;
|
2008-12-27 16:32:52 +00:00
|
|
|
|
2018-06-21 18:39:20 +00:00
|
|
|
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);
|
2008-12-27 16:32:52 +00:00
|
|
|
|
2018-06-21 18:39:20 +00:00
|
|
|
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));
|
2009-02-16 22:52:23 +00:00
|
|
|
}
|
2018-06-21 18:39:20 +00:00
|
|
|
conn->received_cm_service_request = false;
|
2018-11-30 00:08:36 +00:00
|
|
|
ran_conn_put(conn, RAN_CONN_USE_CM_SERVICE);
|
2009-02-16 22:52:23 +00:00
|
|
|
}
|
2010-03-29 06:47:44 +00:00
|
|
|
|
2018-06-21 18:39:20 +00:00
|
|
|
/* TS 24.007 11.2.3.2.3 Message Type Octet / Duplicate Detection */
|
|
|
|
int gsm0407_pdisc_ctr_bin(uint8_t pdisc)
|
2009-06-10 15:11:52 +00:00
|
|
|
{
|
2018-06-21 18:39:20 +00:00
|
|
|
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;
|
2009-06-10 15:11:52 +00:00
|
|
|
}
|
2008-12-27 16:32:52 +00:00
|
|
|
}
|
2009-02-11 11:44:12 +00:00
|
|
|
|
2018-06-21 18:39:20 +00:00
|
|
|
/* 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)
|
2009-02-17 01:43:01 +00:00
|
|
|
{
|
2018-06-21 18:39:20 +00:00
|
|
|
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;
|
2009-06-10 15:11:52 +00:00
|
|
|
}
|
2009-02-17 01:43:01 +00:00
|
|
|
}
|
|
|
|
|
2018-06-21 18:39:20 +00:00
|
|
|
/* 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)
|
2009-06-10 15:11:52 +00:00
|
|
|
{
|
2018-06-21 18:39:20 +00:00
|
|
|
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;
|
2009-06-10 15:11:52 +00:00
|
|
|
default:
|
2018-06-21 18:39:20 +00:00
|
|
|
/* no sequence number, we cannot detect dups */
|
|
|
|
return 0;
|
2009-02-17 01:43:01 +00:00
|
|
|
}
|
2009-06-10 15:11:52 +00:00
|
|
|
}
|
2008-12-29 01:55:35 +00:00
|
|
|
|
2018-06-21 18:39:20 +00:00
|
|
|
/* TS 24.007 11.2.3.2 Message Type Octet / Duplicate Detection */
|
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-29 21:37:51 +00:00
|
|
|
static bool gsm0407_is_duplicate(struct ran_conn *conn, struct msgb *msg)
|
2016-04-25 13:22:00 +00:00
|
|
|
{
|
2018-06-21 18:39:20 +00:00
|
|
|
struct gsm48_hdr *gh;
|
|
|
|
uint8_t pdisc;
|
2018-10-21 10:55:11 +00:00
|
|
|
uint8_t n_sd, modulo;
|
|
|
|
int bin;
|
2016-04-25 13:22:00 +00:00
|
|
|
|
2018-06-21 18:39:20 +00:00
|
|
|
gh = msgb_l3(msg);
|
|
|
|
pdisc = gsm48_hdr_pdisc(gh);
|
2008-12-29 01:55:35 +00:00
|
|
|
|
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-13 01:05:52 +00:00
|
|
|
if (conn->vsub && classmark_is_r99(&conn->vsub->classmark)) {
|
2018-06-21 18:39:20 +00:00
|
|
|
modulo = gsm0407_determine_nsd_ret_modulo_r99(pdisc, gh->msg_type, &n_sd);
|
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-13 01:05:52 +00:00
|
|
|
} else { /* pre R99 */
|
|
|
|
modulo = gsm0407_determine_nsd_ret_modulo_r98(pdisc, gh->msg_type, &n_sd);
|
2018-01-24 10:06:19 +00:00
|
|
|
}
|
2018-06-21 18:39:20 +00:00
|
|
|
if (modulo == 0)
|
|
|
|
return false;
|
|
|
|
bin = gsm0407_pdisc_ctr_bin(pdisc);
|
|
|
|
if (bin < 0)
|
|
|
|
return false;
|
2009-06-10 15:11:52 +00:00
|
|
|
|
2018-06-21 18:39:20 +00:00
|
|
|
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;
|
2008-12-27 16:32:52 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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-29 21:37:51 +00:00
|
|
|
extern int gsm0408_rcv_cc(struct ran_conn *conn, struct msgb *msg);
|
2016-06-19 16:06:02 +00:00
|
|
|
|
2016-05-09 19:07:43 +00:00
|
|
|
/* Main entry point for GSM 04.08/44.008 Layer 3 data (e.g. from the BSC). */
|
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-29 21:37:51 +00:00
|
|
|
int gsm0408_dispatch(struct ran_conn *conn, struct msgb *msg)
|
2009-06-10 15:11:52 +00:00
|
|
|
{
|
2017-04-20 16:40:37 +00:00
|
|
|
struct gsm48_hdr *gh;
|
|
|
|
uint8_t pdisc;
|
2009-06-10 15:11:52 +00:00
|
|
|
int rc = 0;
|
2009-12-29 10:49:12 +00:00
|
|
|
|
2017-09-19 12:36:06 +00:00
|
|
|
OSMO_ASSERT(msg->l3h);
|
2016-05-09 19:38:51 +00:00
|
|
|
OSMO_ASSERT(conn);
|
|
|
|
OSMO_ASSERT(msg);
|
|
|
|
|
2017-04-20 16:40:37 +00:00
|
|
|
gh = msgb_l3(msg);
|
|
|
|
pdisc = gsm48_hdr_pdisc(gh);
|
|
|
|
|
2018-02-03 20:08:26 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2017-03-10 01:15:20 +00:00
|
|
|
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));
|
2016-06-19 16:06:02 +00:00
|
|
|
|
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-29 21:37:51 +00:00
|
|
|
if (!ran_conn_is_accepted(conn)
|
2016-06-19 16:06:02 +00:00
|
|
|
&& !msg_is_initially_permitted(gh)) {
|
|
|
|
LOGP(DRLL, LOGL_ERROR,
|
2017-03-10 01:15:20 +00:00
|
|
|
"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)));
|
2016-06-19 16:06:02 +00:00
|
|
|
return -EACCES;
|
|
|
|
}
|
|
|
|
|
2016-05-20 19:59:55 +00:00
|
|
|
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),
|
2018-12-25 23:40:18 +00:00
|
|
|
osmo_rat_type_name(conn->vsub->cs.attached_via_ran),
|
|
|
|
osmo_rat_type_name(conn->via_ran));
|
2016-05-20 19:59:55 +00:00
|
|
|
return -EACCES;
|
|
|
|
}
|
|
|
|
|
2017-02-27 15:56:59 +00:00
|
|
|
#if 0
|
2010-06-21 02:34:03 +00:00
|
|
|
if (silent_call_reroute(conn, msg))
|
|
|
|
return silent_call_rx(conn, msg);
|
2017-02-27 15:56:59 +00:00
|
|
|
#endif
|
2016-08-29 16:40:02 +00:00
|
|
|
|
2009-06-10 15:11:52 +00:00
|
|
|
switch (pdisc) {
|
|
|
|
case GSM48_PDISC_CC:
|
2010-06-17 09:14:35 +00:00
|
|
|
rc = gsm0408_rcv_cc(conn, msg);
|
2009-06-10 15:11:52 +00:00
|
|
|
break;
|
|
|
|
case GSM48_PDISC_MM:
|
2010-06-17 09:14:35 +00:00
|
|
|
rc = gsm0408_rcv_mm(conn, msg);
|
2009-06-10 15:11:52 +00:00
|
|
|
break;
|
|
|
|
case GSM48_PDISC_RR:
|
2010-06-17 09:14:35 +00:00
|
|
|
rc = gsm0408_rcv_rr(conn, msg);
|
2009-06-10 15:11:52 +00:00
|
|
|
break;
|
|
|
|
case GSM48_PDISC_SMS:
|
2010-06-17 08:41:25 +00:00
|
|
|
rc = gsm0411_rcv_sms(conn, msg);
|
2009-06-10 15:11:52 +00:00
|
|
|
break;
|
|
|
|
case GSM48_PDISC_MM_GPRS:
|
|
|
|
case GSM48_PDISC_SM_GPRS:
|
2009-12-24 11:13:17 +00:00
|
|
|
LOGP(DRLL, LOGL_NOTICE, "Unimplemented "
|
|
|
|
"GSM 04.08 discriminator 0x%02x\n", pdisc);
|
2016-05-09 19:38:51 +00:00
|
|
|
rc = -ENOTSUP;
|
2009-06-10 15:11:52 +00:00
|
|
|
break;
|
2009-10-16 06:32:58 +00:00
|
|
|
case GSM48_PDISC_NC_SS:
|
2018-06-11 22:24:52 +00:00
|
|
|
rc = gsm0911_rcv_nc_ss(conn, msg);
|
2009-10-16 06:32:58 +00:00
|
|
|
break;
|
2017-05-29 16:02:53 +00:00
|
|
|
case GSM48_PDISC_TEST:
|
|
|
|
rc = gsm0414_rcv_test(conn, msg);
|
|
|
|
break;
|
2009-06-10 15:11:52 +00:00
|
|
|
default:
|
2009-12-24 11:13:17 +00:00
|
|
|
LOGP(DRLL, LOGL_NOTICE, "Unknown "
|
|
|
|
"GSM 04.08 discriminator 0x%02x\n", pdisc);
|
2016-05-09 19:38:51 +00:00
|
|
|
rc = -EINVAL;
|
2009-06-10 15:11:52 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
2016-06-19 16:06:02 +00:00
|
|
|
/***********************************************************************
|
|
|
|
* VLR integration
|
|
|
|
***********************************************************************/
|
|
|
|
|
|
|
|
/* VLR asks us to send an authentication request */
|
2018-11-30 01:57:33 +00:00
|
|
|
static int msc_vlr_tx_auth_req(void *msc_conn_ref, struct vlr_auth_tuple *at,
|
2016-06-19 16:06:02 +00:00
|
|
|
bool send_autn)
|
|
|
|
{
|
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-29 21:37:51 +00:00
|
|
|
struct ran_conn *conn = msc_conn_ref;
|
2016-06-19 16:06:02 +00:00
|
|
|
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)
|
|
|
|
{
|
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-29 21:37:51 +00:00
|
|
|
struct ran_conn *conn = msc_conn_ref;
|
2016-06-19 16:06:02 +00:00
|
|
|
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)
|
|
|
|
{
|
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-29 21:37:51 +00:00
|
|
|
struct ran_conn *conn = msc_conn_ref;
|
2016-06-19 16:06:02 +00:00
|
|
|
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)
|
|
|
|
{
|
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-29 21:37:51 +00:00
|
|
|
struct ran_conn *conn = msc_conn_ref;
|
2016-06-19 16:06:02 +00:00
|
|
|
return gsm0408_loc_upd_acc(conn, send_tmsi);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* VLR asks us to transmit a Location Update Reject */
|
2018-04-06 00:57:51 +00:00
|
|
|
static int msc_vlr_tx_lu_rej(void *msc_conn_ref, enum gsm48_reject_value cause)
|
2016-06-19 16:06:02 +00:00
|
|
|
{
|
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-29 21:37:51 +00:00
|
|
|
struct ran_conn *conn = msc_conn_ref;
|
2016-06-19 16:06:02 +00:00
|
|
|
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)
|
|
|
|
{
|
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-29 21:37:51 +00:00
|
|
|
struct ran_conn *conn = msc_conn_ref;
|
2016-05-20 19:59:55 +00:00
|
|
|
return msc_gsm48_tx_mm_serv_ack(conn);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int msc_vlr_tx_common_id(void *msc_conn_ref)
|
|
|
|
{
|
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-29 21:37:51 +00:00
|
|
|
struct ran_conn *conn = msc_conn_ref;
|
2016-05-20 19:59:55 +00:00
|
|
|
return msc_tx_common_id(conn);
|
2016-06-19 16:06:02 +00:00
|
|
|
}
|
|
|
|
|
2018-03-13 20:11:49 +00:00
|
|
|
/* VLR asks us to transmit MM info. */
|
|
|
|
static int msc_vlr_tx_mm_info(void *msc_conn_ref)
|
|
|
|
{
|
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-29 21:37:51 +00:00
|
|
|
struct ran_conn *conn = msc_conn_ref;
|
2018-03-13 20:11:49 +00:00
|
|
|
if (!conn->network->send_mm_info)
|
|
|
|
return 0;
|
|
|
|
return gsm48_tx_mm_info(conn);
|
|
|
|
}
|
|
|
|
|
2016-06-19 16:06:02 +00:00
|
|
|
/* VLR asks us to transmit a CM Service Reject */
|
2018-04-06 00:57:51 +00:00
|
|
|
static int msc_vlr_tx_cm_serv_rej(void *msc_conn_ref, enum gsm48_reject_value cause)
|
2016-06-19 16:06:02 +00:00
|
|
|
{
|
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-29 21:37:51 +00:00
|
|
|
struct ran_conn *conn = msc_conn_ref;
|
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-03-30 22:02:14 +00:00
|
|
|
int rc;
|
2016-06-19 16:06:02 +00:00
|
|
|
|
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-03-30 22:02:14 +00:00
|
|
|
rc = msc_gsm48_tx_mm_serv_rej(conn, cause);
|
|
|
|
|
|
|
|
if (conn->received_cm_service_request) {
|
|
|
|
conn->received_cm_service_request = false;
|
2018-11-30 00:08:36 +00:00
|
|
|
ran_conn_put(conn, RAN_CONN_USE_CM_SERVICE);
|
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-03-30 22:02:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return rc;
|
2016-06-19 16:06:02 +00:00
|
|
|
}
|
|
|
|
|
2017-12-14 04:30:16 +00:00
|
|
|
/* 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);
|
|
|
|
|
2018-11-30 00:08:36 +00:00
|
|
|
int ran_conn_geran_set_cipher_mode(struct ran_conn *conn, bool umts_aka, bool retrieve_imeisv)
|
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 71330720b6efdda2fcfd3e9c0cb45f89e32e5670
"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-13 01:23:07 +00:00
|
|
|
{
|
2019-01-08 11:29:49 +00:00
|
|
|
struct gsm_network *net;
|
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 71330720b6efdda2fcfd3e9c0cb45f89e32e5670
"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-13 01:23:07 +00:00
|
|
|
struct gsm0808_encrypt_info ei;
|
|
|
|
int i, j = 0;
|
|
|
|
int request_classmark = 0;
|
|
|
|
int request_classmark_for_a5_n = 0;
|
2019-01-08 11:29:49 +00:00
|
|
|
struct vlr_auth_tuple *tuple;
|
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 71330720b6efdda2fcfd3e9c0cb45f89e32e5670
"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-13 01:23:07 +00:00
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2019-01-08 11:29:49 +00:00
|
|
|
net = conn->network;
|
|
|
|
tuple = conn->vsub->last_tuple;
|
|
|
|
|
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 71330720b6efdda2fcfd3e9c0cb45f89e32e5670
"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-13 01:23:07 +00:00
|
|
|
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);
|
|
|
|
|
2018-11-30 00:08:36 +00:00
|
|
|
return ran_conn_classmark_request_then_cipher_mode_cmd(conn, umts_aka, retrieve_imeisv);
|
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 71330720b6efdda2fcfd3e9c0cb45f89e32e5670
"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-13 01:23:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (ei.perm_algo_len == 0) {
|
|
|
|
LOGP(DMM, LOGL_ERROR, "%s: cannot start ciphering, no intersection "
|
2018-12-18 02:13:51 +00:00
|
|
|
"between MSC-configured and MS-supported A5 algorithms. MSC: %x MS: %s\n",
|
|
|
|
vlr_subscr_name(conn->vsub), net->a5_encryption_mask,
|
|
|
|
classmark_a5_name(&conn->vsub->classmark));
|
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 71330720b6efdda2fcfd3e9c0cb45f89e32e5670
"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-13 01:23:07 +00:00
|
|
|
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);
|
|
|
|
|
2018-11-30 03:35:50 +00:00
|
|
|
conn->geran_encr = (struct geran_encr){};
|
|
|
|
if (ei.key_len <= sizeof(conn->geran_encr.key)) {
|
|
|
|
memcpy(conn->geran_encr.key, ei.key, ei.key_len);
|
|
|
|
conn->geran_encr.key_len = ei.key_len;
|
2018-11-29 22:37:19 +00:00
|
|
|
}
|
2018-11-30 03:35:50 +00:00
|
|
|
/* conn->geran_encr.alg_id remains unknown until we receive a Cipher Mode Complete from the BSC */
|
2018-11-29 22:37:19 +00:00
|
|
|
|
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 71330720b6efdda2fcfd3e9c0cb45f89e32e5670
"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-13 01:23:07 +00:00
|
|
|
return a_iface_tx_cipher_mode(conn, &ei, retrieve_imeisv);
|
|
|
|
}
|
|
|
|
|
2018-03-02 00:50:09 +00:00
|
|
|
/* 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)
|
2016-06-19 16:06:02 +00:00
|
|
|
{
|
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-29 21:37:51 +00:00
|
|
|
struct ran_conn *conn = msc_conn_ref;
|
2016-06-19 16:06:02 +00:00
|
|
|
struct vlr_subscr *vsub;
|
2018-11-30 01:57:33 +00:00
|
|
|
struct vlr_auth_tuple *tuple;
|
2016-06-19 16:06:02 +00:00
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2016-05-20 19:59:55 +00:00
|
|
|
switch (conn->via_ran) {
|
2018-12-25 23:40:18 +00:00
|
|
|
case OSMO_RAT_GERAN_A:
|
2018-11-30 00:08:36 +00:00
|
|
|
return ran_conn_geran_set_cipher_mode(conn, umts_aka, retrieve_imeisv);
|
2017-12-14 04:30:16 +00:00
|
|
|
|
2018-12-25 23:40:18 +00:00
|
|
|
case OSMO_RAT_UTRAN_IU:
|
2016-05-20 19:59:55 +00:00
|
|
|
#ifdef BUILD_IU
|
|
|
|
DEBUGP(DMM, "-> SECURITY MODE CONTROL %s\n",
|
|
|
|
vlr_subscr_name(conn->vsub));
|
2017-07-05 13:19:52 +00:00
|
|
|
return ranap_iu_tx_sec_mode_cmd(conn->iu.ue_ctx, &tuple->vec, 0, 1);
|
2016-05-20 19:59:55 +00:00
|
|
|
#else
|
2018-12-25 23:40:18 +00:00
|
|
|
LOGP(DMM, LOGL_ERROR, "Cannot send Security Mode Control over OSMO_RAT_UTRAN_IU,"
|
2016-05-20 19:59:55 +00:00
|
|
|
" 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;
|
|
|
|
}
|
|
|
|
|
2018-11-30 00:08:36 +00:00
|
|
|
void ran_conn_rx_sec_mode_compl(struct ran_conn *conn)
|
2016-05-20 19:59:55 +00:00
|
|
|
{
|
|
|
|
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);
|
2016-06-19 16:06:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* VLR informs us that the subscriber data has somehow been modified */
|
|
|
|
static void msc_vlr_subscr_update(struct vlr_subscr *subscr)
|
|
|
|
{
|
2017-12-27 12:23:44 +00:00
|
|
|
LOGVSUBP(LOGL_NOTICE, subscr, "VLR: update for IMSI=%s (MSISDN=%s, used=%d)\n",
|
|
|
|
subscr->imsi, subscr->msisdn, subscr->use_count);
|
2019-01-03 01:32:14 +00:00
|
|
|
ran_conn_update_id_for_vsub(subscr);
|
2016-06-19 16:06:02 +00:00
|
|
|
}
|
|
|
|
|
2018-09-18 13:52:58 +00:00
|
|
|
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));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-06-19 16:06:02 +00:00
|
|
|
/* VLR informs us that the subscriber has been associated with a conn */
|
2018-12-28 20:22:32 +00:00
|
|
|
static int msc_vlr_subscr_assoc(void *msc_conn_ref,
|
2016-06-19 16:06:02 +00:00
|
|
|
struct vlr_subscr *vsub)
|
|
|
|
{
|
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-29 21:37:51 +00:00
|
|
|
struct ran_conn *conn = msc_conn_ref;
|
2018-02-12 15:51:03 +00:00
|
|
|
OSMO_ASSERT(vsub);
|
2018-12-28 20:22:32 +00:00
|
|
|
if (conn->vsub) {
|
|
|
|
if (conn->vsub == vsub)
|
2019-01-04 16:42:05 +00:00
|
|
|
LOG_RAN_CONN(conn, LOGL_NOTICE, "msc_vlr_subscr_assoc(): conn already associated with %s\n",
|
|
|
|
vlr_subscr_name(vsub));
|
2018-12-28 20:22:32 +00:00
|
|
|
else {
|
2019-01-04 16:42:05 +00:00
|
|
|
LOG_RAN_CONN(conn, LOGL_ERROR, "msc_vlr_subscr_assoc(): conn already associated with a subscriber,"
|
|
|
|
" cannot associate with %s\n", vlr_subscr_name(vsub));
|
2018-12-28 20:22:32 +00:00
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-06-19 16:06:02 +00:00
|
|
|
conn->vsub = vlr_subscr_get(vsub);
|
2018-02-12 15:51:03 +00:00
|
|
|
OSMO_ASSERT(conn->vsub);
|
2016-05-20 19:59:55 +00:00
|
|
|
conn->vsub->cs.attached_via_ran = conn->via_ran;
|
2018-09-18 13:52:58 +00:00
|
|
|
|
|
|
|
/* 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);
|
2019-01-03 01:32:14 +00:00
|
|
|
ran_conn_update_id(conn);
|
2018-12-28 20:22:32 +00:00
|
|
|
return 0;
|
2016-06-19 16:06:02 +00:00
|
|
|
}
|
|
|
|
|
2018-06-13 20:54:33 +00:00
|
|
|
static int msc_vlr_route_gsup_msg(struct vlr_subscr *vsub,
|
|
|
|
struct osmo_gsup_message *gsup_msg)
|
|
|
|
{
|
|
|
|
switch (gsup_msg->message_type) {
|
2018-06-12 01:21:20 +00:00
|
|
|
/* 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);
|
|
|
|
|
2018-11-06 22:08:18 +00:00
|
|
|
/* GSM 04.11 code implementing MO SMS */
|
|
|
|
case OSMO_GSUP_MSGT_MO_FORWARD_SM_ERROR:
|
|
|
|
case OSMO_GSUP_MSGT_MO_FORWARD_SM_RESULT:
|
|
|
|
case OSMO_GSUP_MSGT_READY_FOR_SM_ERROR:
|
|
|
|
case OSMO_GSUP_MSGT_READY_FOR_SM_RESULT:
|
|
|
|
DEBUGP(DMSC, "Routed to GSM 04.11 MO handler\n");
|
|
|
|
return gsm411_gsup_mo_handler(vsub, gsup_msg);
|
|
|
|
|
2018-11-14 18:05:53 +00:00
|
|
|
/* GSM 04.11 code implementing MT SMS */
|
|
|
|
case OSMO_GSUP_MSGT_MT_FORWARD_SM_REQUEST:
|
|
|
|
DEBUGP(DMSC, "Routed to GSM 04.11 MT handler\n");
|
|
|
|
return gsm411_gsup_mt_handler(vsub, gsup_msg);
|
|
|
|
|
2018-06-13 20:54:33 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-06-19 16:06:02 +00:00
|
|
|
/* 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,
|
2016-05-20 19:59:55 +00:00
|
|
|
.tx_common_id = msc_vlr_tx_common_id,
|
2018-03-13 20:11:49 +00:00
|
|
|
.tx_mm_info = msc_vlr_tx_mm_info,
|
2016-06-19 16:06:02 +00:00
|
|
|
.subscr_update = msc_vlr_subscr_update,
|
|
|
|
.subscr_assoc = msc_vlr_subscr_assoc,
|
2018-06-13 20:54:33 +00:00
|
|
|
.forward_gsup_msg = msc_vlr_route_gsup_msg,
|
2016-06-19 16:06:02 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/* 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)
|
|
|
|
{
|
2018-12-06 11:06:59 +00:00
|
|
|
struct ipaccess_unit *ipa_dev;
|
|
|
|
|
2016-06-19 16:06:02 +00:00
|
|
|
OSMO_ASSERT(net->vlr);
|
2018-12-06 11:06:59 +00:00
|
|
|
|
|
|
|
ipa_dev = talloc_zero(net->vlr, struct ipaccess_unit);
|
|
|
|
ipa_dev->unit_name = "MSC";
|
|
|
|
ipa_dev->serno = net->msc_ipa_name; /* NULL unless configured via VTY */
|
2018-12-06 12:16:24 +00:00
|
|
|
ipa_dev->swversion = PACKAGE_NAME "-" PACKAGE_VERSION;
|
2018-12-06 11:06:59 +00:00
|
|
|
|
|
|
|
return vlr_start(ipa_dev, net->vlr, net->gsup_server_addr_str, net->gsup_server_port);
|
2016-06-19 16:06:02 +00:00
|
|
|
}
|
2018-03-22 15:48:22 +00:00
|
|
|
|
|
|
|
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);
|
|
|
|
}
|