2010-06-15 03:52:51 +00:00
|
|
|
/* main MSC management code... */
|
|
|
|
|
|
|
|
/*
|
2013-06-30 13:30:47 +00:00
|
|
|
* (C) 2010,2013 by Holger Hans Peter Freyther <zecke@selfish.org>
|
2010-10-06 12:37:09 +00:00
|
|
|
* (C) 2010 by On-Waves
|
2010-06-15 03:52:51 +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
|
2010-06-15 03:52:51 +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.
|
2010-06-15 03:52:51 +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/>.
|
2010-06-15 03:52:51 +00:00
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2017-09-04 13:04:35 +00:00
|
|
|
#include <osmocom/msc/osmo_msc.h>
|
|
|
|
#include <osmocom/msc/debug.h>
|
|
|
|
#include <osmocom/msc/transaction.h>
|
|
|
|
#include <osmocom/msc/db.h>
|
|
|
|
#include <osmocom/msc/vlr.h>
|
|
|
|
#include <osmocom/msc/osmo_msc.h>
|
|
|
|
#include <osmocom/msc/a_iface.h>
|
2017-09-15 09:22:30 +00:00
|
|
|
#include <osmocom/msc/gsm_04_08.h>
|
2017-09-04 13:04:35 +00:00
|
|
|
#include <osmocom/msc/gsm_04_11.h>
|
2010-06-15 04:03:10 +00:00
|
|
|
|
2017-07-05 13:19:52 +00:00
|
|
|
#include "../../bscconfig.h"
|
|
|
|
#ifdef BUILD_IU
|
|
|
|
#include <osmocom/ranap/iu_client.h>
|
|
|
|
#else
|
2017-09-04 13:04:35 +00:00
|
|
|
#include <osmocom/msc/iu_dummy.h>
|
2017-07-05 13:19:52 +00:00
|
|
|
#endif
|
|
|
|
|
2016-06-19 16:06:02 +00:00
|
|
|
/* Receive a SAPI-N-REJECT from BSC */
|
2017-04-09 10:32:51 +00:00
|
|
|
void msc_sapi_n_reject(struct gsm_subscriber_connection *conn, int dlci)
|
2010-06-15 03:52:51 +00:00
|
|
|
{
|
2010-06-15 04:03:10 +00:00
|
|
|
int sapi = dlci & 0x7;
|
|
|
|
|
|
|
|
if (sapi == UM_SAPI_SMS)
|
|
|
|
gsm411_sapi_n_reject(conn);
|
2010-06-15 03:52:51 +00:00
|
|
|
}
|
|
|
|
|
2016-06-19 16:06:02 +00:00
|
|
|
static void subscr_conn_bump(struct gsm_subscriber_connection *conn)
|
|
|
|
{
|
|
|
|
if (!conn)
|
|
|
|
return;
|
|
|
|
if (!conn->conn_fsm)
|
|
|
|
return;
|
|
|
|
if (!(conn->conn_fsm->state == SUBSCR_CONN_S_ACCEPTED
|
2016-05-20 19:59:55 +00:00
|
|
|
|| conn->conn_fsm->state == SUBSCR_CONN_S_COMMUNICATING)) {
|
|
|
|
DEBUGP(DMM, "%s: bump: conn still being established (%s)\n",
|
|
|
|
vlr_subscr_name(conn->vsub),
|
|
|
|
osmo_fsm_inst_state_name(conn->conn_fsm));
|
2016-06-19 16:06:02 +00:00
|
|
|
return;
|
2016-05-20 19:59:55 +00:00
|
|
|
}
|
2016-06-19 16:06:02 +00:00
|
|
|
osmo_fsm_inst_dispatch(conn->conn_fsm, SUBSCR_CONN_E_BUMP, NULL);
|
2010-06-15 05:16:52 +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
|
|
|
/* receive a Level 3 Complete message and return MSC_CONN_ACCEPT or
|
|
|
|
* MSC_CONN_REJECT */
|
2016-05-20 19:59:55 +00:00
|
|
|
int msc_compl_l3(struct gsm_subscriber_connection *conn,
|
|
|
|
struct msgb *msg, uint16_t chosen_channel)
|
2010-06-17 08:41:25 +00:00
|
|
|
{
|
2017-11-22 13:33:12 +00:00
|
|
|
msc_subscr_conn_get(conn, MSC_CONN_USE_COMPL_L3);
|
2010-06-17 08:41:25 +00:00
|
|
|
gsm0408_dispatch(conn, msg);
|
|
|
|
|
2016-06-19 16:06:02 +00:00
|
|
|
/* Bump whether the conn wants to be closed */
|
|
|
|
subscr_conn_bump(conn);
|
|
|
|
|
|
|
|
/* If this should be kept, the conn->conn_fsm has placed a use_count */
|
2017-11-22 13:33:12 +00:00
|
|
|
msc_subscr_conn_put(conn, MSC_CONN_USE_COMPL_L3);
|
2016-05-20 19:59:55 +00:00
|
|
|
|
|
|
|
/* Always return acceptance, because even if the conn was not accepted,
|
|
|
|
* we assumed ownership of it and the caller shall not interfere with
|
|
|
|
* that. We may even already have discarded the conn. */
|
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_CONN_ACCEPT;
|
2016-06-19 16:06:02 +00:00
|
|
|
|
|
|
|
#if 0
|
2016-02-10 09:42:20 +00:00
|
|
|
/*
|
|
|
|
* If this is a silent call we want the channel to remain open as long as
|
|
|
|
* possible and this is why we accept this connection regardless of any
|
|
|
|
* pending transaction or ongoing operation.
|
|
|
|
*/
|
2012-11-23 20:33:15 +00:00
|
|
|
if (conn->silent_call)
|
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_CONN_ACCEPT;
|
|
|
|
if (conn->loc_operation || conn->sec_operation || conn->anch_operation)
|
|
|
|
return MSC_CONN_ACCEPT;
|
2012-11-23 20:33:15 +00:00
|
|
|
if (trans_has_conn(conn))
|
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_CONN_ACCEPT;
|
2014-01-30 20:01:12 +00:00
|
|
|
|
|
|
|
LOGP(DRR, LOGL_INFO, "MSC Complete L3: Rejecting connection.\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_CONN_REJECT;
|
2016-06-19 16:06:02 +00:00
|
|
|
#endif
|
2010-06-17 08:41:25 +00:00
|
|
|
}
|
|
|
|
|
2016-06-19 16:06:02 +00:00
|
|
|
/* Receive a DTAP message from BSC */
|
2016-05-20 19:59:55 +00:00
|
|
|
void msc_dtap(struct gsm_subscriber_connection *conn, uint8_t link_id, struct msgb *msg)
|
2010-06-17 08:41:25 +00:00
|
|
|
{
|
2017-11-22 13:33:12 +00:00
|
|
|
msc_subscr_conn_get(conn, MSC_CONN_USE_DTAP);
|
2010-06-17 08:41:25 +00:00
|
|
|
gsm0408_dispatch(conn, msg);
|
2016-06-19 16:06:02 +00:00
|
|
|
|
|
|
|
/* Bump whether the conn wants to be closed */
|
|
|
|
subscr_conn_bump(conn);
|
2017-11-22 13:33:12 +00:00
|
|
|
msc_subscr_conn_put(conn, MSC_CONN_USE_DTAP);
|
2010-06-17 08:41:25 +00:00
|
|
|
}
|
|
|
|
|
2016-06-19 16:06:02 +00:00
|
|
|
/* Receive an ASSIGNMENT COMPLETE from BSC */
|
2017-04-09 10:32:51 +00:00
|
|
|
void msc_assign_compl(struct gsm_subscriber_connection *conn,
|
|
|
|
uint8_t rr_cause, uint8_t chosen_channel,
|
|
|
|
uint8_t encr_alg_id, uint8_t speec)
|
2011-12-27 11:31:02 +00:00
|
|
|
{
|
2014-01-30 20:01:12 +00:00
|
|
|
LOGP(DRR, LOGL_DEBUG, "MSC assign complete (do nothing).\n");
|
2011-12-27 11:31:02 +00:00
|
|
|
}
|
|
|
|
|
2016-06-19 16:06:02 +00:00
|
|
|
/* Receive an ASSIGNMENT FAILURE from BSC */
|
2017-04-09 10:32:51 +00:00
|
|
|
void msc_assign_fail(struct gsm_subscriber_connection *conn,
|
|
|
|
uint8_t cause, uint8_t *rr_cause)
|
2011-12-27 11:31:02 +00:00
|
|
|
{
|
2014-01-30 20:01:12 +00:00
|
|
|
LOGP(DRR, LOGL_DEBUG, "MSC assign failure (do nothing).\n");
|
2011-12-27 11:31:02 +00:00
|
|
|
}
|
|
|
|
|
2016-06-19 16:06:02 +00:00
|
|
|
/* Receive a CLASSMARK CHANGE from BSC */
|
2017-04-09 10:32:51 +00:00
|
|
|
void msc_classmark_chg(struct gsm_subscriber_connection *conn,
|
|
|
|
const uint8_t *cm2, uint8_t cm2_len,
|
|
|
|
const uint8_t *cm3, uint8_t cm3_len)
|
2012-01-23 09:28:35 +00:00
|
|
|
{
|
2016-06-19 16:06:02 +00:00
|
|
|
if (cm2 && cm2_len) {
|
|
|
|
if (cm2_len > sizeof(conn->classmark.classmark2)) {
|
|
|
|
LOGP(DRR, LOGL_NOTICE, "%s: classmark2 is %u bytes, truncating at %zu bytes\n",
|
|
|
|
vlr_subscr_name(conn->vsub), cm2_len, sizeof(conn->classmark.classmark2));
|
|
|
|
cm2_len = sizeof(conn->classmark.classmark2);
|
2012-01-23 09:28:35 +00:00
|
|
|
}
|
2016-06-19 16:06:02 +00:00
|
|
|
conn->classmark.classmark2_len = cm2_len;
|
|
|
|
memcpy(conn->classmark.classmark2, cm2, cm2_len);
|
|
|
|
}
|
|
|
|
if (cm3 && cm3_len) {
|
|
|
|
if (cm3_len > sizeof(conn->classmark.classmark3)) {
|
|
|
|
LOGP(DRR, LOGL_NOTICE, "%s: classmark3 is %u bytes, truncating at %zu bytes\n",
|
|
|
|
vlr_subscr_name(conn->vsub), cm3_len, sizeof(conn->classmark.classmark3));
|
|
|
|
cm3_len = sizeof(conn->classmark.classmark3);
|
|
|
|
}
|
|
|
|
conn->classmark.classmark3_len = cm3_len;
|
|
|
|
memcpy(conn->classmark.classmark3, cm3, cm3_len);
|
2012-01-23 09:28:35 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-06-19 16:06:02 +00:00
|
|
|
/* Receive a CIPHERING MODE COMPLETE from BSC */
|
2016-05-20 19:59:55 +00:00
|
|
|
void msc_cipher_mode_compl(struct gsm_subscriber_connection *conn,
|
|
|
|
struct msgb *msg, uint8_t alg_id)
|
2012-01-23 15:40:24 +00:00
|
|
|
{
|
2016-06-19 16:06:02 +00:00
|
|
|
struct vlr_ciph_result ciph_res = { .cause = VLR_CIPH_REJECT };
|
|
|
|
|
|
|
|
if (!conn) {
|
2018-01-24 21:38:06 +00:00
|
|
|
LOGP(DRR, LOGL_ERROR, "invalid: rx Ciphering Mode Complete on NULL conn\n");
|
2016-06-19 16:06:02 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (!conn->vsub) {
|
2018-01-24 21:38:06 +00:00
|
|
|
LOGP(DRR, LOGL_ERROR, "invalid: rx Ciphering Mode Complete for NULL subscr\n");
|
2012-01-23 15:40:24 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2018-01-24 21:38:06 +00:00
|
|
|
DEBUGP(DRR, "%s: CIPHERING MODE COMPLETE\n", vlr_subscr_name(conn->vsub));
|
2012-01-23 15:40:24 +00:00
|
|
|
|
2018-01-24 21:38:06 +00:00
|
|
|
if (msg) {
|
|
|
|
struct gsm48_hdr *gh = msgb_l3(msg);
|
|
|
|
unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
|
|
|
|
struct tlv_parsed tp;
|
|
|
|
uint8_t mi_type;
|
|
|
|
char imeisv[GSM48_MI_SIZE] = "";
|
|
|
|
|
|
|
|
if (!gh) {
|
|
|
|
LOGP(DRR, LOGL_ERROR, "invalid: msgb without l3 header\n");
|
|
|
|
return;
|
|
|
|
}
|
2012-01-23 15:40:24 +00:00
|
|
|
|
2018-01-24 21:38:06 +00:00
|
|
|
tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len, 0, 0);
|
|
|
|
|
|
|
|
/* bearer capability */
|
|
|
|
if (TLVP_PRESENT(&tp, GSM48_IE_MOBILE_ID)) {
|
|
|
|
mi_type = TLVP_VAL(&tp, GSM48_IE_MOBILE_ID)[0] & GSM_MI_TYPE_MASK;
|
|
|
|
if (mi_type == GSM_MI_TYPE_IMEISV
|
|
|
|
&& TLVP_LEN(&tp, GSM48_IE_MOBILE_ID) > 0) {
|
|
|
|
gsm48_mi_to_string(imeisv, sizeof(imeisv),
|
|
|
|
TLVP_VAL(&tp, GSM48_IE_MOBILE_ID),
|
|
|
|
TLVP_LEN(&tp, GSM48_IE_MOBILE_ID));
|
|
|
|
ciph_res.imeisv = imeisv;
|
|
|
|
}
|
2016-06-19 16:06:02 +00:00
|
|
|
}
|
2012-01-23 15:40:24 +00:00
|
|
|
}
|
|
|
|
|
2016-06-19 16:06:02 +00:00
|
|
|
ciph_res.cause = VLR_CIPH_COMPL;
|
|
|
|
vlr_subscr_rx_ciph_res(conn->vsub, &ciph_res);
|
|
|
|
}
|
|
|
|
|
|
|
|
struct gsm_subscriber_connection *msc_subscr_con_allocate(struct gsm_network *network)
|
|
|
|
{
|
|
|
|
struct gsm_subscriber_connection *conn;
|
|
|
|
|
|
|
|
conn = talloc_zero(network, struct gsm_subscriber_connection);
|
|
|
|
if (!conn)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
conn->network = network;
|
|
|
|
llist_add_tail(&conn->entry, &network->subscr_conns);
|
|
|
|
return conn;
|
|
|
|
}
|
|
|
|
|
|
|
|
void msc_subscr_cleanup(struct vlr_subscr *vsub)
|
|
|
|
{
|
|
|
|
if (!vsub)
|
|
|
|
return;
|
|
|
|
vsub->lu_fsm = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
void msc_subscr_con_cleanup(struct gsm_subscriber_connection *conn)
|
|
|
|
{
|
|
|
|
if (!conn)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (conn->vsub) {
|
|
|
|
DEBUGP(DRLL, "subscr %s: Freeing subscriber connection\n",
|
|
|
|
vlr_subscr_name(conn->vsub));
|
|
|
|
msc_subscr_cleanup(conn->vsub);
|
|
|
|
vlr_subscr_put(conn->vsub);
|
|
|
|
conn->vsub = NULL;
|
|
|
|
} else
|
|
|
|
DEBUGP(DRLL, "Freeing subscriber connection"
|
|
|
|
" with NULL subscriber\n");
|
|
|
|
|
|
|
|
if (!conn->conn_fsm)
|
|
|
|
return;
|
|
|
|
|
|
|
|
osmo_fsm_inst_term(conn->conn_fsm,
|
|
|
|
(conn->conn_fsm->state == SUBSCR_CONN_S_RELEASED)
|
|
|
|
? OSMO_FSM_TERM_REGULAR
|
|
|
|
: OSMO_FSM_TERM_ERROR,
|
|
|
|
NULL);
|
2012-01-23 15:40:24 +00:00
|
|
|
}
|
|
|
|
|
2016-06-19 16:06:02 +00:00
|
|
|
void msc_subscr_con_free(struct gsm_subscriber_connection *conn)
|
|
|
|
{
|
|
|
|
if (!conn)
|
|
|
|
return;
|
|
|
|
|
|
|
|
msc_subscr_con_cleanup(conn);
|
2012-01-23 09:28:35 +00:00
|
|
|
|
2016-06-19 16:06:02 +00:00
|
|
|
llist_del(&conn->entry);
|
|
|
|
talloc_free(conn);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Receive a CLEAR REQUEST from BSC */
|
2017-04-09 10:32:51 +00:00
|
|
|
int msc_clear_request(struct gsm_subscriber_connection *conn, uint32_t cause)
|
2016-06-19 16:06:02 +00:00
|
|
|
{
|
|
|
|
msc_subscr_conn_close(conn, cause);
|
|
|
|
return 1;
|
|
|
|
}
|
2012-01-23 09:28:35 +00:00
|
|
|
|
2016-06-19 16:06:02 +00:00
|
|
|
static void msc_subscr_conn_release_all(struct gsm_subscriber_connection *conn, uint32_t cause)
|
2010-06-28 09:09:29 +00:00
|
|
|
{
|
|
|
|
if (conn->in_release)
|
|
|
|
return;
|
2016-06-19 16:06:02 +00:00
|
|
|
conn->in_release = true;
|
|
|
|
|
|
|
|
/* If we're closing in a middle of a trans, we need to clean up */
|
|
|
|
trans_conn_closed(conn);
|
|
|
|
|
|
|
|
switch (conn->via_ran) {
|
|
|
|
case RAN_UTRAN_IU:
|
2017-07-05 13:19:52 +00:00
|
|
|
ranap_iu_tx_release(conn->iu.ue_ctx, NULL);
|
2016-05-20 19:59:55 +00:00
|
|
|
/* FIXME: keep the conn until the Iu Release Outcome is
|
|
|
|
* received from the UE, or a timeout expires. For now, the log
|
|
|
|
* says "unknown UE" for each release outcome. */
|
2016-06-19 16:06:02 +00:00
|
|
|
break;
|
|
|
|
case RAN_GERAN_A:
|
2017-04-09 10:32:51 +00:00
|
|
|
a_iface_tx_clear_cmd(conn);
|
2016-06-19 16:06:02 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
LOGP(DMM, LOGL_ERROR, "%s: Unknown RAN type, cannot tx release/clear\n",
|
|
|
|
vlr_subscr_name(conn->vsub));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2010-06-28 09:09:29 +00:00
|
|
|
|
2016-06-19 16:06:02 +00:00
|
|
|
/* If the conn->conn_fsm is still present, dispatch SUBSCR_CONN_E_CN_CLOSE
|
|
|
|
* event to gracefully terminate the connection. If the conn_fsm is already
|
|
|
|
* cleared, call msc_subscr_conn_release_all() to take release actions.
|
|
|
|
* \param cause a GSM_CAUSE_* constant, e.g. GSM_CAUSE_AUTH_FAILED.
|
|
|
|
*/
|
|
|
|
void msc_subscr_conn_close(struct gsm_subscriber_connection *conn,
|
|
|
|
uint32_t cause)
|
|
|
|
{
|
|
|
|
if (!conn)
|
2010-06-28 09:09:29 +00:00
|
|
|
return;
|
2016-06-19 16:06:02 +00:00
|
|
|
if (conn->in_release) {
|
|
|
|
DEBUGP(DMM, "msc_subscr_conn_close(vsub=%s, cause=%u):"
|
|
|
|
" already dispatching release, ignore.\n",
|
|
|
|
vlr_subscr_name(conn->vsub), cause);
|
2010-06-28 09:09:29 +00:00
|
|
|
return;
|
2016-06-19 16:06:02 +00:00
|
|
|
}
|
|
|
|
if (!conn->conn_fsm) {
|
|
|
|
DEBUGP(DMM, "msc_subscr_conn_close(vsub=%s, cause=%u): no conn fsm,"
|
|
|
|
" releasing directly without release event.\n",
|
|
|
|
vlr_subscr_name(conn->vsub), cause);
|
|
|
|
/* In case of an IMSI Detach, we don't have conn_fsm. Release
|
|
|
|
* anyway to ensure a timely Iu Release / BSSMAP Clear. */
|
|
|
|
msc_subscr_conn_release_all(conn, cause);
|
2012-11-23 20:33:15 +00:00
|
|
|
return;
|
2016-06-19 16:06:02 +00:00
|
|
|
}
|
|
|
|
if (conn->conn_fsm->state == SUBSCR_CONN_S_RELEASED) {
|
|
|
|
DEBUGP(DMM, "msc_subscr_conn_close(vsub=%s, cause=%u):"
|
|
|
|
" conn fsm already releasing, ignore.\n",
|
|
|
|
vlr_subscr_name(conn->vsub), cause);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
osmo_fsm_inst_dispatch(conn->conn_fsm, SUBSCR_CONN_E_CN_CLOSE, &cause);
|
|
|
|
}
|
2010-06-28 09:09:29 +00:00
|
|
|
|
2016-06-19 16:06:02 +00:00
|
|
|
/* increment the ref-count. Needs to be called by every user */
|
|
|
|
struct gsm_subscriber_connection *
|
|
|
|
_msc_subscr_conn_get(struct gsm_subscriber_connection *conn,
|
2017-11-22 13:33:12 +00:00
|
|
|
enum msc_subscr_conn_use balance_token,
|
2016-06-19 16:06:02 +00:00
|
|
|
const char *file, int line)
|
|
|
|
{
|
|
|
|
OSMO_ASSERT(conn);
|
2013-06-30 13:30:47 +00:00
|
|
|
|
2016-06-19 16:06:02 +00:00
|
|
|
if (conn->in_release)
|
2017-11-22 13:44:35 +00:00
|
|
|
LOGPSRC(DREF, LOGL_ERROR, file, line,
|
|
|
|
"%s: MSC conn use error: using conn that is already in release (%s)\n",
|
|
|
|
vlr_subscr_name(conn->vsub),
|
|
|
|
msc_subscr_conn_use_name(balance_token));
|
2013-06-30 13:30:47 +00:00
|
|
|
|
2017-11-22 13:33:12 +00:00
|
|
|
if (balance_token != MSC_CONN_USE_UNTRACKED) {
|
|
|
|
uint32_t flag = 1 << balance_token;
|
|
|
|
OSMO_ASSERT(balance_token < 32);
|
|
|
|
if (conn->use_tokens & flag)
|
|
|
|
LOGPSRC(DREF, LOGL_ERROR, file, line,
|
|
|
|
"%s: MSC conn use error: using an already used token: %s\n",
|
|
|
|
vlr_subscr_name(conn->vsub),
|
|
|
|
msc_subscr_conn_use_name(balance_token));
|
|
|
|
conn->use_tokens |= flag;
|
|
|
|
}
|
|
|
|
|
2016-06-19 16:06:02 +00:00
|
|
|
conn->use_count++;
|
|
|
|
LOGPSRC(DREF, LOGL_DEBUG, file, line,
|
2017-11-22 13:33:12 +00:00
|
|
|
"%s: MSC conn use + %s == %u (0x%x)\n",
|
|
|
|
vlr_subscr_name(conn->vsub), msc_subscr_conn_use_name(balance_token),
|
|
|
|
conn->use_count, conn->use_tokens);
|
2016-06-19 16:06:02 +00:00
|
|
|
|
|
|
|
return conn;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* decrement the ref-count. Once it reaches zero, we release */
|
|
|
|
void _msc_subscr_conn_put(struct gsm_subscriber_connection *conn,
|
2017-11-22 13:33:12 +00:00
|
|
|
enum msc_subscr_conn_use balance_token,
|
2016-06-19 16:06:02 +00:00
|
|
|
const char *file, int line)
|
|
|
|
{
|
|
|
|
OSMO_ASSERT(conn);
|
|
|
|
|
2017-11-22 13:33:12 +00:00
|
|
|
if (balance_token != MSC_CONN_USE_UNTRACKED) {
|
|
|
|
uint32_t flag = 1 << balance_token;
|
|
|
|
OSMO_ASSERT(balance_token < 32);
|
|
|
|
if (!(conn->use_tokens & flag))
|
|
|
|
LOGPSRC(DREF, LOGL_ERROR, file, line,
|
|
|
|
"%s: MSC conn use error: freeing an unused token: %s\n",
|
|
|
|
vlr_subscr_name(conn->vsub),
|
|
|
|
msc_subscr_conn_use_name(balance_token));
|
|
|
|
conn->use_tokens &= ~flag;
|
|
|
|
}
|
|
|
|
|
2016-06-19 16:06:02 +00:00
|
|
|
if (conn->use_count == 0) {
|
|
|
|
LOGPSRC(DREF, LOGL_ERROR, file, line,
|
2017-11-22 13:33:12 +00:00
|
|
|
"%s: MSC conn use - %s failed: is already 0\n",
|
|
|
|
vlr_subscr_name(conn->vsub),
|
|
|
|
msc_subscr_conn_use_name(balance_token));
|
2016-06-19 16:06:02 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
conn->use_count--;
|
|
|
|
LOGPSRC(DREF, LOGL_DEBUG, file, line,
|
2017-11-22 13:33:12 +00:00
|
|
|
"%s: MSC conn use - %s == %u (0x%x)\n",
|
|
|
|
vlr_subscr_name(conn->vsub), msc_subscr_conn_use_name(balance_token),
|
|
|
|
conn->use_count, conn->use_tokens);
|
2016-06-19 16:06:02 +00:00
|
|
|
|
2016-05-20 19:59:55 +00:00
|
|
|
if (conn->use_count == 0)
|
|
|
|
msc_subscr_con_free(conn);
|
|
|
|
}
|
|
|
|
|
2017-11-22 13:33:12 +00:00
|
|
|
const struct value_string msc_subscr_conn_use_names[] = {
|
|
|
|
{MSC_CONN_USE_UNTRACKED, "UNTRACKED"},
|
|
|
|
{MSC_CONN_USE_COMPL_L3, "compl_l3"},
|
|
|
|
{MSC_CONN_USE_DTAP, "dtap"},
|
|
|
|
{MSC_CONN_USE_FSM, "fsm"},
|
|
|
|
{MSC_CONN_USE_TRANS_CC, "trans_cc"},
|
|
|
|
{MSC_CONN_USE_TRANS_SMS, "trans_sms"},
|
|
|
|
{MSC_CONN_USE_TRANS_USSD, "trans_ussd"},
|
|
|
|
{MSC_CONN_USE_SILENT_CALL, "silent_call"},
|
|
|
|
{0, NULL},
|
|
|
|
};
|
|
|
|
|
2016-05-20 19:59:55 +00:00
|
|
|
void msc_stop_paging(struct vlr_subscr *vsub)
|
|
|
|
{
|
|
|
|
DEBUGP(DPAG, "Paging can stop for %s\n", vlr_subscr_name(vsub));
|
|
|
|
/* tell BSCs and RNCs to stop paging? How? */
|
2010-06-28 09:09:29 +00:00
|
|
|
}
|