introduce an osmo_fsm for gsm_subscriber_connection
In the current implementation of osmo-bsc, the subscriber connection is
not handled (very) statefully. However, there is some state keeping in the
code that handles the mgcp connection, but there are still to much loose ends
which allow odd situations to happen, which then lead severe error situations
(see also closes tags at the end) This commit adds a number of improvements
to fix those problems.
- Use an osmo-fsm to control the gsm_subscriber_connection state and
make sure that certain operations can only take place at certain states
(e.g let connection oriented SCCP traffic only pass when an SCCP connection
actually exists.
Remove the old osmo_bsc_mgcp.c code. Use the recently developed MGCP client
FSM to handle the MGCP connections.
Also make sure that stuff that already works does not break. This in
particular refers to the internal handover capability and the respective
unit-tests.
See also OS#2823, OS#2768 and OS#2898
- Fix logic to permit assignment to a signalling channel. (OS#2762)
- Introduce T993210 to release lchan + subscr_conn if MSC fails to respond
The GSM specs don't have an explicit timer for this, so let's introdcue
a custom timer (hence starting with 99).
This timeout catches the following situation:
* we send a SCCP CR with COMPL_L3_INFO from the MS to the MSC,
* the MSC doesn't respond (e.g. SCCP routing failure, program down, ...)
The MS is supposed to timeout with T3210, 3220 or 3230. But the BSC
shouldn't trust the MS but have some timer on its own.
SCCP would have a timer T(conn est), but that one is specified to be
1-2min and hence rather long.
See also: OS#2775
- Terminate bsc_subscr_conn_fsm on SCCP N-DISC.ind from MSC
If the MSC is disconnecting the SCCP channel, we must terminate the FSM
which in turn will release all lchan's and other state.
This makes TC_chan_rel_hard_rlsd pass, see also OS#2731
As a side-effect, this fixes TC_chan_act_ack_est_ind_refused(),
where the MSC is answering with CREF to our CR/COMPL_L3.
- Release subscriber connection on RLL RELEASE IND of SAPI0 on main DCCH
The subscriber connection isn't really useful for anything after the
SAPI0 main signalling link has been released. We could try to
re-establish, but our best option is probably simply releasing the
subscriber_conn and anything related to it.
This will make TC_chan_rel_rll_rel_ind pass, see also OS#2730
This commit has been tested using the BSC_Tests TTCN3 testsuit and the
following tests were passed:
TC_chan_act_noreply
TC_chan_act_ack_noest
TC_chan_act_ack_est_ind_noreply
TC_chan_act_ack_est_ind_refused
TC_chan_act_nack
TC_chan_exhaustion
TC_ctrl
TC_chan_rel_conn_fail
TC_chan_rel_hard_clear
TC_chan_rel_hard_rlsd
TC_chan_rel_a_reset
TC_rll_est_ind_inact_lchan
TC_rll_est_ind_inval_sapi1
TC_rll_est_ind_inval_sapi3
TC_rll_est_ind_inval_sacch
TC_assignment_cic_only
TC_assignment_csd
TC_assignment_ctm
TC_assignment_fr_a5_0
TC_assignment_fr_a5_1_codec_missing
TC_assignment_fr_a5_1
TC_assignment_fr_a5_3
TC_assignment_fr_a5_4
TC_paging_imsi_nochan
TC_paging_tmsi_nochan
TC_paging_tmsi_any
TC_paging_tmsi_sdcch
TC_paging_tmsi_tch_f
TC_paging_tmsi_tch_hf
TC_paging_imsi_nochan_cgi
TC_paging_imsi_nochan_lac_ci
TC_paging_imsi_nochan_ci
TC_paging_imsi_nochan_lai
TC_paging_imsi_nochan_lac
TC_paging_imsi_nochan_all
TC_paging_imsi_nochan_plmn_lac_rnc
TC_paging_imsi_nochan_rnc
TC_paging_imsi_nochan_lac_rnc
TC_paging_imsi_nochan_lacs
TC_paging_imsi_nochan_lacs_empty
TC_paging_imsi_a_reset
TC_paging_counter
TC_rsl_drop_counter
TC_classmark
TC_unsol_ass_fail
TC_unsol_ass_compl
TC_unsol_ho_fail
TC_err_82_short_msg
TC_ho_int
Authors:
Harald Welte <laforge@gnumonks.org>
Philipp Maier <pmaier@sysmocom.de>
Neels Hofmeyr <neels@hofmeyr.de>
Closes: OS#2730
Closes: OS#2731
Closes: OS#2762
Closes: OS#2768
Closes: OS#2775
Closes: OS#2823
Closes: OS#2898
Closes: OS#2936
Change-Id: I68286d26e2014048b054f39ef29c35fef420cc97
2018-01-28 02:04:16 +00:00
|
|
|
/* (C) 2017 by sysmocom s.f.m.c. GmbH, Author: Philipp Maier
|
2018-05-27 09:53:43 +00:00
|
|
|
* (C) 2017-2018 by Harald Welte <laforge@gnumonks.org>
|
2017-04-09 10:32:51 +00:00
|
|
|
* All Rights Reserved
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU Affero General Public License as published by
|
|
|
|
* the Free Software Foundation; either version 3 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU Affero General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Affero General Public License
|
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <osmocom/core/utils.h>
|
|
|
|
#include <osmocom/core/logging.h>
|
introduce an osmo_fsm for gsm_subscriber_connection
In the current implementation of osmo-bsc, the subscriber connection is
not handled (very) statefully. However, there is some state keeping in the
code that handles the mgcp connection, but there are still to much loose ends
which allow odd situations to happen, which then lead severe error situations
(see also closes tags at the end) This commit adds a number of improvements
to fix those problems.
- Use an osmo-fsm to control the gsm_subscriber_connection state and
make sure that certain operations can only take place at certain states
(e.g let connection oriented SCCP traffic only pass when an SCCP connection
actually exists.
Remove the old osmo_bsc_mgcp.c code. Use the recently developed MGCP client
FSM to handle the MGCP connections.
Also make sure that stuff that already works does not break. This in
particular refers to the internal handover capability and the respective
unit-tests.
See also OS#2823, OS#2768 and OS#2898
- Fix logic to permit assignment to a signalling channel. (OS#2762)
- Introduce T993210 to release lchan + subscr_conn if MSC fails to respond
The GSM specs don't have an explicit timer for this, so let's introdcue
a custom timer (hence starting with 99).
This timeout catches the following situation:
* we send a SCCP CR with COMPL_L3_INFO from the MS to the MSC,
* the MSC doesn't respond (e.g. SCCP routing failure, program down, ...)
The MS is supposed to timeout with T3210, 3220 or 3230. But the BSC
shouldn't trust the MS but have some timer on its own.
SCCP would have a timer T(conn est), but that one is specified to be
1-2min and hence rather long.
See also: OS#2775
- Terminate bsc_subscr_conn_fsm on SCCP N-DISC.ind from MSC
If the MSC is disconnecting the SCCP channel, we must terminate the FSM
which in turn will release all lchan's and other state.
This makes TC_chan_rel_hard_rlsd pass, see also OS#2731
As a side-effect, this fixes TC_chan_act_ack_est_ind_refused(),
where the MSC is answering with CREF to our CR/COMPL_L3.
- Release subscriber connection on RLL RELEASE IND of SAPI0 on main DCCH
The subscriber connection isn't really useful for anything after the
SAPI0 main signalling link has been released. We could try to
re-establish, but our best option is probably simply releasing the
subscriber_conn and anything related to it.
This will make TC_chan_rel_rll_rel_ind pass, see also OS#2730
This commit has been tested using the BSC_Tests TTCN3 testsuit and the
following tests were passed:
TC_chan_act_noreply
TC_chan_act_ack_noest
TC_chan_act_ack_est_ind_noreply
TC_chan_act_ack_est_ind_refused
TC_chan_act_nack
TC_chan_exhaustion
TC_ctrl
TC_chan_rel_conn_fail
TC_chan_rel_hard_clear
TC_chan_rel_hard_rlsd
TC_chan_rel_a_reset
TC_rll_est_ind_inact_lchan
TC_rll_est_ind_inval_sapi1
TC_rll_est_ind_inval_sapi3
TC_rll_est_ind_inval_sacch
TC_assignment_cic_only
TC_assignment_csd
TC_assignment_ctm
TC_assignment_fr_a5_0
TC_assignment_fr_a5_1_codec_missing
TC_assignment_fr_a5_1
TC_assignment_fr_a5_3
TC_assignment_fr_a5_4
TC_paging_imsi_nochan
TC_paging_tmsi_nochan
TC_paging_tmsi_any
TC_paging_tmsi_sdcch
TC_paging_tmsi_tch_f
TC_paging_tmsi_tch_hf
TC_paging_imsi_nochan_cgi
TC_paging_imsi_nochan_lac_ci
TC_paging_imsi_nochan_ci
TC_paging_imsi_nochan_lai
TC_paging_imsi_nochan_lac
TC_paging_imsi_nochan_all
TC_paging_imsi_nochan_plmn_lac_rnc
TC_paging_imsi_nochan_rnc
TC_paging_imsi_nochan_lac_rnc
TC_paging_imsi_nochan_lacs
TC_paging_imsi_nochan_lacs_empty
TC_paging_imsi_a_reset
TC_paging_counter
TC_rsl_drop_counter
TC_classmark
TC_unsol_ass_fail
TC_unsol_ass_compl
TC_unsol_ho_fail
TC_err_82_short_msg
TC_ho_int
Authors:
Harald Welte <laforge@gnumonks.org>
Philipp Maier <pmaier@sysmocom.de>
Neels Hofmeyr <neels@hofmeyr.de>
Closes: OS#2730
Closes: OS#2731
Closes: OS#2762
Closes: OS#2768
Closes: OS#2775
Closes: OS#2823
Closes: OS#2898
Closes: OS#2936
Change-Id: I68286d26e2014048b054f39ef29c35fef420cc97
2018-01-28 02:04:16 +00:00
|
|
|
#include <osmocom/core/fsm.h>
|
2017-04-09 10:32:51 +00:00
|
|
|
#include <osmocom/sigtran/osmo_ss7.h>
|
|
|
|
#include <osmocom/sigtran/sccp_sap.h>
|
|
|
|
#include <osmocom/core/linuxlist.h>
|
|
|
|
#include <osmocom/gsm/gsm0808.h>
|
2018-05-26 20:42:29 +00:00
|
|
|
#include <osmocom/gsm/protocol/ipaccess.h>
|
2017-04-09 10:32:51 +00:00
|
|
|
#include <osmocom/core/msgb.h>
|
2017-09-04 13:15:32 +00:00
|
|
|
#include <osmocom/bsc/bsc_msc_data.h>
|
|
|
|
#include <osmocom/bsc/debug.h>
|
|
|
|
#include <osmocom/bsc/osmo_bsc.h>
|
|
|
|
#include <osmocom/bsc/osmo_bsc_grace.h>
|
|
|
|
#include <osmocom/bsc/osmo_bsc_sigtran.h>
|
|
|
|
#include <osmocom/bsc/a_reset.h>
|
introduce an osmo_fsm for gsm_subscriber_connection
In the current implementation of osmo-bsc, the subscriber connection is
not handled (very) statefully. However, there is some state keeping in the
code that handles the mgcp connection, but there are still to much loose ends
which allow odd situations to happen, which then lead severe error situations
(see also closes tags at the end) This commit adds a number of improvements
to fix those problems.
- Use an osmo-fsm to control the gsm_subscriber_connection state and
make sure that certain operations can only take place at certain states
(e.g let connection oriented SCCP traffic only pass when an SCCP connection
actually exists.
Remove the old osmo_bsc_mgcp.c code. Use the recently developed MGCP client
FSM to handle the MGCP connections.
Also make sure that stuff that already works does not break. This in
particular refers to the internal handover capability and the respective
unit-tests.
See also OS#2823, OS#2768 and OS#2898
- Fix logic to permit assignment to a signalling channel. (OS#2762)
- Introduce T993210 to release lchan + subscr_conn if MSC fails to respond
The GSM specs don't have an explicit timer for this, so let's introdcue
a custom timer (hence starting with 99).
This timeout catches the following situation:
* we send a SCCP CR with COMPL_L3_INFO from the MS to the MSC,
* the MSC doesn't respond (e.g. SCCP routing failure, program down, ...)
The MS is supposed to timeout with T3210, 3220 or 3230. But the BSC
shouldn't trust the MS but have some timer on its own.
SCCP would have a timer T(conn est), but that one is specified to be
1-2min and hence rather long.
See also: OS#2775
- Terminate bsc_subscr_conn_fsm on SCCP N-DISC.ind from MSC
If the MSC is disconnecting the SCCP channel, we must terminate the FSM
which in turn will release all lchan's and other state.
This makes TC_chan_rel_hard_rlsd pass, see also OS#2731
As a side-effect, this fixes TC_chan_act_ack_est_ind_refused(),
where the MSC is answering with CREF to our CR/COMPL_L3.
- Release subscriber connection on RLL RELEASE IND of SAPI0 on main DCCH
The subscriber connection isn't really useful for anything after the
SAPI0 main signalling link has been released. We could try to
re-establish, but our best option is probably simply releasing the
subscriber_conn and anything related to it.
This will make TC_chan_rel_rll_rel_ind pass, see also OS#2730
This commit has been tested using the BSC_Tests TTCN3 testsuit and the
following tests were passed:
TC_chan_act_noreply
TC_chan_act_ack_noest
TC_chan_act_ack_est_ind_noreply
TC_chan_act_ack_est_ind_refused
TC_chan_act_nack
TC_chan_exhaustion
TC_ctrl
TC_chan_rel_conn_fail
TC_chan_rel_hard_clear
TC_chan_rel_hard_rlsd
TC_chan_rel_a_reset
TC_rll_est_ind_inact_lchan
TC_rll_est_ind_inval_sapi1
TC_rll_est_ind_inval_sapi3
TC_rll_est_ind_inval_sacch
TC_assignment_cic_only
TC_assignment_csd
TC_assignment_ctm
TC_assignment_fr_a5_0
TC_assignment_fr_a5_1_codec_missing
TC_assignment_fr_a5_1
TC_assignment_fr_a5_3
TC_assignment_fr_a5_4
TC_paging_imsi_nochan
TC_paging_tmsi_nochan
TC_paging_tmsi_any
TC_paging_tmsi_sdcch
TC_paging_tmsi_tch_f
TC_paging_tmsi_tch_hf
TC_paging_imsi_nochan_cgi
TC_paging_imsi_nochan_lac_ci
TC_paging_imsi_nochan_ci
TC_paging_imsi_nochan_lai
TC_paging_imsi_nochan_lac
TC_paging_imsi_nochan_all
TC_paging_imsi_nochan_plmn_lac_rnc
TC_paging_imsi_nochan_rnc
TC_paging_imsi_nochan_lac_rnc
TC_paging_imsi_nochan_lacs
TC_paging_imsi_nochan_lacs_empty
TC_paging_imsi_a_reset
TC_paging_counter
TC_rsl_drop_counter
TC_classmark
TC_unsol_ass_fail
TC_unsol_ass_compl
TC_unsol_ho_fail
TC_err_82_short_msg
TC_ho_int
Authors:
Harald Welte <laforge@gnumonks.org>
Philipp Maier <pmaier@sysmocom.de>
Neels Hofmeyr <neels@hofmeyr.de>
Closes: OS#2730
Closes: OS#2731
Closes: OS#2762
Closes: OS#2768
Closes: OS#2775
Closes: OS#2823
Closes: OS#2898
Closes: OS#2936
Change-Id: I68286d26e2014048b054f39ef29c35fef420cc97
2018-01-28 02:04:16 +00:00
|
|
|
#include <osmocom/bsc/bsc_subscr_conn_fsm.h>
|
2018-05-27 09:53:43 +00:00
|
|
|
#include <osmocom/bsc/gsm_data.h>
|
2020-07-15 18:53:16 +00:00
|
|
|
#include <osmocom/bsc/bts.h>
|
2018-08-29 11:31:56 +00:00
|
|
|
#include <osmocom/mgcp_client/mgcp_common.h>
|
2017-04-09 10:32:51 +00:00
|
|
|
|
|
|
|
/* A pointer to a list with all involved MSCs
|
|
|
|
* (a copy of the pointer location submitted with osmo_bsc_sigtran_init() */
|
|
|
|
static struct llist_head *msc_list;
|
|
|
|
|
2020-08-20 10:32:54 +00:00
|
|
|
#define DEFAULT_ASP_LOCAL_IP "localhost"
|
|
|
|
#define DEFAULT_ASP_REMOTE_IP "localhost"
|
2017-04-09 10:32:51 +00:00
|
|
|
|
|
|
|
/* The SCCP stack will not assign connection IDs to us automatically, we
|
|
|
|
* will do this ourselves using a counter variable, that counts one up
|
|
|
|
* for every new connection */
|
|
|
|
static uint32_t conn_id_counter;
|
|
|
|
|
|
|
|
/* Helper function to Check if the given connection id is already assigned */
|
2018-01-28 01:45:46 +00:00
|
|
|
static struct gsm_subscriber_connection *get_bsc_conn_by_conn_id(int conn_id)
|
2017-04-09 10:32:51 +00:00
|
|
|
{
|
|
|
|
conn_id &= 0xFFFFFF;
|
2018-01-28 01:45:46 +00:00
|
|
|
struct gsm_subscriber_connection *conn;
|
2017-04-09 10:32:51 +00:00
|
|
|
|
2018-01-28 01:45:46 +00:00
|
|
|
llist_for_each_entry(conn, &bsc_gsmnet->subscr_conns, entry) {
|
|
|
|
if (conn->sccp.conn_id == conn_id)
|
|
|
|
return conn;
|
2017-04-09 10:32:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Pick a free connection id */
|
|
|
|
static int pick_free_conn_id(const struct bsc_msc_data *msc)
|
|
|
|
{
|
|
|
|
int conn_id = conn_id_counter;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = 0; i < 0xFFFFFF; i++) {
|
|
|
|
conn_id++;
|
|
|
|
conn_id &= 0xFFFFFF;
|
|
|
|
if (get_bsc_conn_by_conn_id(conn_id) == false) {
|
|
|
|
conn_id_counter = conn_id;
|
|
|
|
return conn_id;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2019-04-16 18:04:35 +00:00
|
|
|
/* Patch regular BSSMAP RESET to add extra T to announce Osmux support (osmocom extension) */
|
|
|
|
static void _gsm0808_extend_announce_osmux(struct msgb *msg)
|
|
|
|
{
|
|
|
|
OSMO_ASSERT(msg->l3h[1] == msgb_l3len(msg) - 2); /*TL not in len */
|
|
|
|
msgb_put_u8(msg, GSM0808_IE_OSMO_OSMUX_SUPPORT);
|
|
|
|
msg->l3h[1] = msgb_l3len(msg) - 2;
|
|
|
|
}
|
|
|
|
|
2017-04-09 10:32:51 +00:00
|
|
|
/* Send reset to MSC */
|
|
|
|
static void osmo_bsc_sigtran_tx_reset(const struct bsc_msc_data *msc)
|
|
|
|
{
|
|
|
|
struct osmo_ss7_instance *ss7;
|
|
|
|
struct msgb *msg;
|
|
|
|
|
|
|
|
ss7 = osmo_ss7_instance_find(msc->a.cs7_instance);
|
|
|
|
OSMO_ASSERT(ss7);
|
|
|
|
LOGP(DMSC, LOGL_NOTICE, "Sending RESET to MSC: %s\n", osmo_sccp_addr_name(ss7, &msc->a.msc_addr));
|
|
|
|
msg = gsm0808_create_reset();
|
2019-04-16 18:04:35 +00:00
|
|
|
|
2019-06-06 14:56:19 +00:00
|
|
|
if (msc_is_aoip(msc) && msc->use_osmux != OSMUX_USAGE_OFF)
|
2019-04-16 18:04:35 +00:00
|
|
|
_gsm0808_extend_announce_osmux(msg);
|
|
|
|
|
2020-05-09 18:27:40 +00:00
|
|
|
rate_ctr_inc(&msc->msc_ctrs->ctr[MSC_CTR_BSSMAP_TX_UDT_RESET]);
|
2017-04-09 10:32:51 +00:00
|
|
|
osmo_sccp_tx_unitdata_msg(msc->a.sccp_user, &msc->a.bsc_addr,
|
|
|
|
&msc->a.msc_addr, msg);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Send reset-ack to MSC */
|
|
|
|
void osmo_bsc_sigtran_tx_reset_ack(const struct bsc_msc_data *msc)
|
|
|
|
{
|
|
|
|
struct osmo_ss7_instance *ss7;
|
|
|
|
struct msgb *msg;
|
|
|
|
OSMO_ASSERT(msc);
|
|
|
|
|
|
|
|
ss7 = osmo_ss7_instance_find(msc->a.cs7_instance);
|
|
|
|
OSMO_ASSERT(ss7);
|
|
|
|
LOGP(DMSC, LOGL_NOTICE, "Sending RESET ACK to MSC: %s\n", osmo_sccp_addr_name(ss7, &msc->a.msc_addr));
|
|
|
|
msg = gsm0808_create_reset_ack();
|
2019-04-16 18:04:35 +00:00
|
|
|
|
2019-06-06 14:56:19 +00:00
|
|
|
if (msc_is_aoip(msc) && msc->use_osmux != OSMUX_USAGE_OFF)
|
2019-04-16 18:04:35 +00:00
|
|
|
_gsm0808_extend_announce_osmux(msg);
|
|
|
|
|
2020-05-09 18:27:40 +00:00
|
|
|
rate_ctr_inc(&msc->msc_ctrs->ctr[MSC_CTR_BSSMAP_TX_UDT_RESET_ACK]);
|
2017-04-09 10:32:51 +00:00
|
|
|
osmo_sccp_tx_unitdata_msg(msc->a.sccp_user, &msc->a.bsc_addr,
|
|
|
|
&msc->a.msc_addr, msg);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Find an MSC by its sigtran point code */
|
|
|
|
static struct bsc_msc_data *get_msc_by_addr(const struct osmo_sccp_addr *msc_addr)
|
|
|
|
{
|
|
|
|
struct osmo_ss7_instance *ss7;
|
|
|
|
struct bsc_msc_data *msc;
|
|
|
|
llist_for_each_entry(msc, msc_list, entry) {
|
|
|
|
if (memcmp(msc_addr, &msc->a.msc_addr, sizeof(*msc_addr)) == 0)
|
|
|
|
return msc;
|
|
|
|
}
|
|
|
|
|
|
|
|
ss7 = osmo_ss7_instance_find(msc->a.cs7_instance);
|
|
|
|
LOGP(DMSC, LOGL_ERROR, "Unable to find MSC data under address: %s\n", osmo_sccp_addr_name(ss7, msc_addr));
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2020-05-07 22:51:35 +00:00
|
|
|
/* Received data from MSC, use the connection id which MSC it is */
|
introduce an osmo_fsm for gsm_subscriber_connection
In the current implementation of osmo-bsc, the subscriber connection is
not handled (very) statefully. However, there is some state keeping in the
code that handles the mgcp connection, but there are still to much loose ends
which allow odd situations to happen, which then lead severe error situations
(see also closes tags at the end) This commit adds a number of improvements
to fix those problems.
- Use an osmo-fsm to control the gsm_subscriber_connection state and
make sure that certain operations can only take place at certain states
(e.g let connection oriented SCCP traffic only pass when an SCCP connection
actually exists.
Remove the old osmo_bsc_mgcp.c code. Use the recently developed MGCP client
FSM to handle the MGCP connections.
Also make sure that stuff that already works does not break. This in
particular refers to the internal handover capability and the respective
unit-tests.
See also OS#2823, OS#2768 and OS#2898
- Fix logic to permit assignment to a signalling channel. (OS#2762)
- Introduce T993210 to release lchan + subscr_conn if MSC fails to respond
The GSM specs don't have an explicit timer for this, so let's introdcue
a custom timer (hence starting with 99).
This timeout catches the following situation:
* we send a SCCP CR with COMPL_L3_INFO from the MS to the MSC,
* the MSC doesn't respond (e.g. SCCP routing failure, program down, ...)
The MS is supposed to timeout with T3210, 3220 or 3230. But the BSC
shouldn't trust the MS but have some timer on its own.
SCCP would have a timer T(conn est), but that one is specified to be
1-2min and hence rather long.
See also: OS#2775
- Terminate bsc_subscr_conn_fsm on SCCP N-DISC.ind from MSC
If the MSC is disconnecting the SCCP channel, we must terminate the FSM
which in turn will release all lchan's and other state.
This makes TC_chan_rel_hard_rlsd pass, see also OS#2731
As a side-effect, this fixes TC_chan_act_ack_est_ind_refused(),
where the MSC is answering with CREF to our CR/COMPL_L3.
- Release subscriber connection on RLL RELEASE IND of SAPI0 on main DCCH
The subscriber connection isn't really useful for anything after the
SAPI0 main signalling link has been released. We could try to
re-establish, but our best option is probably simply releasing the
subscriber_conn and anything related to it.
This will make TC_chan_rel_rll_rel_ind pass, see also OS#2730
This commit has been tested using the BSC_Tests TTCN3 testsuit and the
following tests were passed:
TC_chan_act_noreply
TC_chan_act_ack_noest
TC_chan_act_ack_est_ind_noreply
TC_chan_act_ack_est_ind_refused
TC_chan_act_nack
TC_chan_exhaustion
TC_ctrl
TC_chan_rel_conn_fail
TC_chan_rel_hard_clear
TC_chan_rel_hard_rlsd
TC_chan_rel_a_reset
TC_rll_est_ind_inact_lchan
TC_rll_est_ind_inval_sapi1
TC_rll_est_ind_inval_sapi3
TC_rll_est_ind_inval_sacch
TC_assignment_cic_only
TC_assignment_csd
TC_assignment_ctm
TC_assignment_fr_a5_0
TC_assignment_fr_a5_1_codec_missing
TC_assignment_fr_a5_1
TC_assignment_fr_a5_3
TC_assignment_fr_a5_4
TC_paging_imsi_nochan
TC_paging_tmsi_nochan
TC_paging_tmsi_any
TC_paging_tmsi_sdcch
TC_paging_tmsi_tch_f
TC_paging_tmsi_tch_hf
TC_paging_imsi_nochan_cgi
TC_paging_imsi_nochan_lac_ci
TC_paging_imsi_nochan_ci
TC_paging_imsi_nochan_lai
TC_paging_imsi_nochan_lac
TC_paging_imsi_nochan_all
TC_paging_imsi_nochan_plmn_lac_rnc
TC_paging_imsi_nochan_rnc
TC_paging_imsi_nochan_lac_rnc
TC_paging_imsi_nochan_lacs
TC_paging_imsi_nochan_lacs_empty
TC_paging_imsi_a_reset
TC_paging_counter
TC_rsl_drop_counter
TC_classmark
TC_unsol_ass_fail
TC_unsol_ass_compl
TC_unsol_ho_fail
TC_err_82_short_msg
TC_ho_int
Authors:
Harald Welte <laforge@gnumonks.org>
Philipp Maier <pmaier@sysmocom.de>
Neels Hofmeyr <neels@hofmeyr.de>
Closes: OS#2730
Closes: OS#2731
Closes: OS#2762
Closes: OS#2768
Closes: OS#2775
Closes: OS#2823
Closes: OS#2898
Closes: OS#2936
Change-Id: I68286d26e2014048b054f39ef29c35fef420cc97
2018-01-28 02:04:16 +00:00
|
|
|
static int handle_data_from_msc(struct gsm_subscriber_connection *conn, struct msgb *msg)
|
2017-04-09 10:32:51 +00:00
|
|
|
{
|
introduce an osmo_fsm for gsm_subscriber_connection
In the current implementation of osmo-bsc, the subscriber connection is
not handled (very) statefully. However, there is some state keeping in the
code that handles the mgcp connection, but there are still to much loose ends
which allow odd situations to happen, which then lead severe error situations
(see also closes tags at the end) This commit adds a number of improvements
to fix those problems.
- Use an osmo-fsm to control the gsm_subscriber_connection state and
make sure that certain operations can only take place at certain states
(e.g let connection oriented SCCP traffic only pass when an SCCP connection
actually exists.
Remove the old osmo_bsc_mgcp.c code. Use the recently developed MGCP client
FSM to handle the MGCP connections.
Also make sure that stuff that already works does not break. This in
particular refers to the internal handover capability and the respective
unit-tests.
See also OS#2823, OS#2768 and OS#2898
- Fix logic to permit assignment to a signalling channel. (OS#2762)
- Introduce T993210 to release lchan + subscr_conn if MSC fails to respond
The GSM specs don't have an explicit timer for this, so let's introdcue
a custom timer (hence starting with 99).
This timeout catches the following situation:
* we send a SCCP CR with COMPL_L3_INFO from the MS to the MSC,
* the MSC doesn't respond (e.g. SCCP routing failure, program down, ...)
The MS is supposed to timeout with T3210, 3220 or 3230. But the BSC
shouldn't trust the MS but have some timer on its own.
SCCP would have a timer T(conn est), but that one is specified to be
1-2min and hence rather long.
See also: OS#2775
- Terminate bsc_subscr_conn_fsm on SCCP N-DISC.ind from MSC
If the MSC is disconnecting the SCCP channel, we must terminate the FSM
which in turn will release all lchan's and other state.
This makes TC_chan_rel_hard_rlsd pass, see also OS#2731
As a side-effect, this fixes TC_chan_act_ack_est_ind_refused(),
where the MSC is answering with CREF to our CR/COMPL_L3.
- Release subscriber connection on RLL RELEASE IND of SAPI0 on main DCCH
The subscriber connection isn't really useful for anything after the
SAPI0 main signalling link has been released. We could try to
re-establish, but our best option is probably simply releasing the
subscriber_conn and anything related to it.
This will make TC_chan_rel_rll_rel_ind pass, see also OS#2730
This commit has been tested using the BSC_Tests TTCN3 testsuit and the
following tests were passed:
TC_chan_act_noreply
TC_chan_act_ack_noest
TC_chan_act_ack_est_ind_noreply
TC_chan_act_ack_est_ind_refused
TC_chan_act_nack
TC_chan_exhaustion
TC_ctrl
TC_chan_rel_conn_fail
TC_chan_rel_hard_clear
TC_chan_rel_hard_rlsd
TC_chan_rel_a_reset
TC_rll_est_ind_inact_lchan
TC_rll_est_ind_inval_sapi1
TC_rll_est_ind_inval_sapi3
TC_rll_est_ind_inval_sacch
TC_assignment_cic_only
TC_assignment_csd
TC_assignment_ctm
TC_assignment_fr_a5_0
TC_assignment_fr_a5_1_codec_missing
TC_assignment_fr_a5_1
TC_assignment_fr_a5_3
TC_assignment_fr_a5_4
TC_paging_imsi_nochan
TC_paging_tmsi_nochan
TC_paging_tmsi_any
TC_paging_tmsi_sdcch
TC_paging_tmsi_tch_f
TC_paging_tmsi_tch_hf
TC_paging_imsi_nochan_cgi
TC_paging_imsi_nochan_lac_ci
TC_paging_imsi_nochan_ci
TC_paging_imsi_nochan_lai
TC_paging_imsi_nochan_lac
TC_paging_imsi_nochan_all
TC_paging_imsi_nochan_plmn_lac_rnc
TC_paging_imsi_nochan_rnc
TC_paging_imsi_nochan_lac_rnc
TC_paging_imsi_nochan_lacs
TC_paging_imsi_nochan_lacs_empty
TC_paging_imsi_a_reset
TC_paging_counter
TC_rsl_drop_counter
TC_classmark
TC_unsol_ass_fail
TC_unsol_ass_compl
TC_unsol_ho_fail
TC_err_82_short_msg
TC_ho_int
Authors:
Harald Welte <laforge@gnumonks.org>
Philipp Maier <pmaier@sysmocom.de>
Neels Hofmeyr <neels@hofmeyr.de>
Closes: OS#2730
Closes: OS#2731
Closes: OS#2762
Closes: OS#2768
Closes: OS#2775
Closes: OS#2823
Closes: OS#2898
Closes: OS#2936
Change-Id: I68286d26e2014048b054f39ef29c35fef420cc97
2018-01-28 02:04:16 +00:00
|
|
|
msg->l3h = msgb_l2(msg);
|
|
|
|
return bsc_handle_dt(conn, msg, msgb_l2len(msg));
|
2017-04-09 10:32:51 +00:00
|
|
|
}
|
|
|
|
|
2020-05-07 22:51:35 +00:00
|
|
|
/* Received unitdata from MSC, use the point code to determine which MSC it is */
|
2017-04-09 10:32:51 +00:00
|
|
|
static int handle_unitdata_from_msc(const struct osmo_sccp_addr *msc_addr, struct msgb *msg,
|
|
|
|
const struct osmo_sccp_user *scu)
|
|
|
|
{
|
|
|
|
struct osmo_ss7_instance *ss7;
|
|
|
|
struct bsc_msc_data *msc = get_msc_by_addr(msc_addr);
|
|
|
|
int rc = -EINVAL;
|
|
|
|
|
|
|
|
if (msc) {
|
|
|
|
msg->l3h = msgb_l2(msg);
|
|
|
|
rc = bsc_handle_udt(msc, msg, msgb_l2len(msg));
|
|
|
|
} else {
|
|
|
|
ss7 = osmo_sccp_get_ss7(osmo_sccp_get_sccp(scu));
|
|
|
|
OSMO_ASSERT(ss7);
|
|
|
|
LOGP(DMSC, LOGL_NOTICE, "incoming unitdata data from unknown remote address: %s\n",
|
|
|
|
osmo_sccp_addr_name(ss7, msc_addr));
|
|
|
|
}
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
large refactoring: use FSMs for lchans; add inter-BSC HO
Add FSMs:
- timeslot_fsm: handle dynamic timeslots and OML+RSL availability.
- lchan_fsm: handle an individual lchan activation, RTP stream and release,
signal the appropriate calling FSMs on success, failure, release.
- mgw_endpoint_fsm: handle one entire endpoint with several CI.
- assignment_fsm: BSSMAP Assignment Request.
- handover_fsm: all of intra, inter-MO and inter-MT handover.
Above FSMs absorb large parts of the gscon FSM. The gscon FSM was surpassing
the maximum amount events (32), and it is more logical to treat assignment,
handover and MGW procedures in separate FSMs.
- Add logging macros for each FSM type:
- LOG_TS()
- LOG_LCHAN()
- LOG_MGWEP(), LOG_CI()
- LOG_ASSIGNMENT()
- LOG_HO()
These log with the osmo_fsm_inst where present.
New style decision: logging without a final newline char is awkward,
especially for gsmtap logging and when other logs interleave LOGPC() calls;
we have various cases where the final \n goes missing, and also this invokes
the log category checking N times instead of once.
So I decided to make these macros *always* append a newline, but only if
there is no final newline yet. I hope that the compiler optimizes the
strlen() of the constant format strings away. Thus I can log with or without
typing "\n" and always get an \n termination anyway.
General:
- replace osmo_timers, state enums and program-wide osmo_signal_dispatch()
with dedicated FSM timeouts, states and events.
- introduce a common way to handle Tnnn timers: gsm_timers.h/.c: struct T_def.
These can be used (with some macro magic) to define a state's timeout once,
and not make mistakes for each osmo_fsm_inst_state_chg().
Details:
bsc_subscr_conn_fsm.c:
- move most states of this FSM to lchan_fsm, assignment_fsm, handover_fsm and
mgw_endpoint_fsm.
- There is exactly one state for an ongoing Assignment, with all details
handled in conn->assignment.fi. The state relies on the assignment_fsm's
timeout.
- There is one state for an ongoing Handover; except for an incoming Handover
from a remote BSS, the gscon remains in ST_INIT until the new lchan and conn
are both established.
- move bssmap_add_lcls_status() to osmo_bsc_lcls.c
abis_rsl.c:
- move all dynamic timeslot logic away into timeslot_fsm. Only keep plain send/receive functions in
abis_rsl.c
- reduce some rsl functions to merely send a message, rename to "_tx_".
- rsl_ipacc_mdcx(): add '_tx_' in the name; move parts that change the lchan state out into the
lchan_fsm, the lchan->abis_ip.* are now set there prior to invoking this function.
- move all timers and error/release handling away into various FSMs.
- tweak ipa_smod_s_for_lchan() and ipa_rtp_pt_for_lchan() to not require an
lchan passed, but just mode,type that they require. Rename to
ipacc_speech_mode*() and ipacc_payload_type().
- add rsl_forward_layer3_info, used for inter-BSC HO MO, to just send the RR
message received during BSSMAP Handover Command.
- move various logging to LOG_LCHAN() in order to log with the lchan FSM instance.
One drawback is that the lchan FSM is limited to one logging category, i.e. this moves some logging
from DRR to DRSL. It might actually make sense to combine those categories.
- lose LOGP...LOGPC logging cascades: they are bad for gsmtap logging and for performance.
- handle_classmark_chg(): change logging, move cm2 len check out of the cm3 condition (I hope that's
correct).
- gsm48_send_ho_cmd(): split off gsm48_make_ho_cmd() which doesn't send right away, so that during
inter-bsc HO we can make an RR Handover Command to send via the MSC to the remote BSS.
assignment_fsm.c:
- the Chan Mode Modify in case of re-using the same lchan is not implemented
yet, because this was also missing in the previous implementation (OS#3357).
osmo_bsc_api.c:
- simplify bsc_mr_config() and move to lchan_fsm.c, the only caller; rename to
lchan_mr_config(). (bsc_mr_config() used to copy the values to mr_bts_lv
twice, once by member assignment and then again with a memcpy.)
- During handover, we used to copy the MR config from the old lchan. Since we
may handover between FR and HR, rather set the MR Config anew every time, so
that FR rates are always available on FR lchans, and never on HR lchans.
Depends: I03ee7ce840ecfa0b6a33358e7385528aabd4873f (libosmocore),
I1f2918418c38918c5ac70acaa51a47adfca12b5e (libosmocore)
Change-Id: I82e3f918295daa83274a4cf803f046979f284366
2018-05-14 16:14:15 +00:00
|
|
|
static int handle_n_connect_from_msc(struct osmo_sccp_user *scu, struct osmo_scu_prim *scu_prim)
|
|
|
|
{
|
|
|
|
struct bsc_msc_data *msc = get_msc_by_addr(&scu_prim->u.connect.calling_addr);
|
|
|
|
struct gsm_subscriber_connection *conn;
|
|
|
|
int rc = 0;
|
|
|
|
|
|
|
|
conn = get_bsc_conn_by_conn_id(scu_prim->u.connect.conn_id);
|
|
|
|
if (conn) {
|
|
|
|
LOGP(DMSC, LOGL_NOTICE,
|
|
|
|
"(calling_addr=%s conn_id=%u) N-CONNECT.ind with already used conn_id, ignoring\n",
|
|
|
|
osmo_sccp_addr_dump(&scu_prim->u.connect.calling_addr),
|
|
|
|
scu_prim->u.connect.conn_id);
|
|
|
|
/* The situation is illogical. A conn was already established with this conn id, if we
|
|
|
|
* would like to reply with a disconn onto this conn id, we would close the existing
|
|
|
|
* conn. So just ignore this impossible N-CONNECT completely (including the BSSMAP PDU). */
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!msc) {
|
|
|
|
LOGP(DMSC, LOGL_NOTICE, "(calling_addr=%s conn_id=%u) N-CONNECT.ind from unknown MSC\n",
|
|
|
|
osmo_sccp_addr_dump(&scu_prim->u.connect.calling_addr),
|
|
|
|
scu_prim->u.connect.conn_id);
|
|
|
|
rc = -ENOENT;
|
|
|
|
goto refuse;
|
|
|
|
}
|
|
|
|
|
2019-03-13 03:46:46 +00:00
|
|
|
LOGP(DMSC, LOGL_DEBUG, "(calling_addr=%s conn_id=%u) N-CONNECT.ind from MSC %d\n",
|
|
|
|
osmo_sccp_addr_dump(&scu_prim->u.connect.calling_addr),
|
|
|
|
scu_prim->u.connect.conn_id, msc->nr);
|
|
|
|
|
large refactoring: use FSMs for lchans; add inter-BSC HO
Add FSMs:
- timeslot_fsm: handle dynamic timeslots and OML+RSL availability.
- lchan_fsm: handle an individual lchan activation, RTP stream and release,
signal the appropriate calling FSMs on success, failure, release.
- mgw_endpoint_fsm: handle one entire endpoint with several CI.
- assignment_fsm: BSSMAP Assignment Request.
- handover_fsm: all of intra, inter-MO and inter-MT handover.
Above FSMs absorb large parts of the gscon FSM. The gscon FSM was surpassing
the maximum amount events (32), and it is more logical to treat assignment,
handover and MGW procedures in separate FSMs.
- Add logging macros for each FSM type:
- LOG_TS()
- LOG_LCHAN()
- LOG_MGWEP(), LOG_CI()
- LOG_ASSIGNMENT()
- LOG_HO()
These log with the osmo_fsm_inst where present.
New style decision: logging without a final newline char is awkward,
especially for gsmtap logging and when other logs interleave LOGPC() calls;
we have various cases where the final \n goes missing, and also this invokes
the log category checking N times instead of once.
So I decided to make these macros *always* append a newline, but only if
there is no final newline yet. I hope that the compiler optimizes the
strlen() of the constant format strings away. Thus I can log with or without
typing "\n" and always get an \n termination anyway.
General:
- replace osmo_timers, state enums and program-wide osmo_signal_dispatch()
with dedicated FSM timeouts, states and events.
- introduce a common way to handle Tnnn timers: gsm_timers.h/.c: struct T_def.
These can be used (with some macro magic) to define a state's timeout once,
and not make mistakes for each osmo_fsm_inst_state_chg().
Details:
bsc_subscr_conn_fsm.c:
- move most states of this FSM to lchan_fsm, assignment_fsm, handover_fsm and
mgw_endpoint_fsm.
- There is exactly one state for an ongoing Assignment, with all details
handled in conn->assignment.fi. The state relies on the assignment_fsm's
timeout.
- There is one state for an ongoing Handover; except for an incoming Handover
from a remote BSS, the gscon remains in ST_INIT until the new lchan and conn
are both established.
- move bssmap_add_lcls_status() to osmo_bsc_lcls.c
abis_rsl.c:
- move all dynamic timeslot logic away into timeslot_fsm. Only keep plain send/receive functions in
abis_rsl.c
- reduce some rsl functions to merely send a message, rename to "_tx_".
- rsl_ipacc_mdcx(): add '_tx_' in the name; move parts that change the lchan state out into the
lchan_fsm, the lchan->abis_ip.* are now set there prior to invoking this function.
- move all timers and error/release handling away into various FSMs.
- tweak ipa_smod_s_for_lchan() and ipa_rtp_pt_for_lchan() to not require an
lchan passed, but just mode,type that they require. Rename to
ipacc_speech_mode*() and ipacc_payload_type().
- add rsl_forward_layer3_info, used for inter-BSC HO MO, to just send the RR
message received during BSSMAP Handover Command.
- move various logging to LOG_LCHAN() in order to log with the lchan FSM instance.
One drawback is that the lchan FSM is limited to one logging category, i.e. this moves some logging
from DRR to DRSL. It might actually make sense to combine those categories.
- lose LOGP...LOGPC logging cascades: they are bad for gsmtap logging and for performance.
- handle_classmark_chg(): change logging, move cm2 len check out of the cm3 condition (I hope that's
correct).
- gsm48_send_ho_cmd(): split off gsm48_make_ho_cmd() which doesn't send right away, so that during
inter-bsc HO we can make an RR Handover Command to send via the MSC to the remote BSS.
assignment_fsm.c:
- the Chan Mode Modify in case of re-using the same lchan is not implemented
yet, because this was also missing in the previous implementation (OS#3357).
osmo_bsc_api.c:
- simplify bsc_mr_config() and move to lchan_fsm.c, the only caller; rename to
lchan_mr_config(). (bsc_mr_config() used to copy the values to mr_bts_lv
twice, once by member assignment and then again with a memcpy.)
- During handover, we used to copy the MR config from the old lchan. Since we
may handover between FR and HR, rather set the MR Config anew every time, so
that FR rates are always available on FR lchans, and never on HR lchans.
Depends: I03ee7ce840ecfa0b6a33358e7385528aabd4873f (libosmocore),
I1f2918418c38918c5ac70acaa51a47adfca12b5e (libosmocore)
Change-Id: I82e3f918295daa83274a4cf803f046979f284366
2018-05-14 16:14:15 +00:00
|
|
|
conn = bsc_subscr_con_allocate(bsc_gsmnet);
|
|
|
|
if (!conn)
|
|
|
|
return -ENOMEM;
|
|
|
|
conn->sccp.msc = msc;
|
|
|
|
conn->sccp.conn_id = scu_prim->u.connect.conn_id;
|
|
|
|
|
|
|
|
/* Take actions asked for by the enclosed PDU */
|
|
|
|
osmo_fsm_inst_dispatch(conn->fi, GSCON_EV_A_CONN_IND, scu_prim);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
refuse:
|
|
|
|
osmo_sccp_tx_disconn(scu, scu_prim->u.connect.conn_id, &scu_prim->u.connect.called_addr, 0);
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
2020-05-08 19:47:17 +00:00
|
|
|
/* Callback function, called by the SCCP stack when data arrives */
|
2017-04-09 10:32:51 +00:00
|
|
|
static int sccp_sap_up(struct osmo_prim_hdr *oph, void *_scu)
|
|
|
|
{
|
|
|
|
struct osmo_scu_prim *scu_prim = (struct osmo_scu_prim *)oph;
|
|
|
|
struct osmo_sccp_user *scu = _scu;
|
2018-01-28 01:45:46 +00:00
|
|
|
struct gsm_subscriber_connection *conn;
|
2017-04-09 10:32:51 +00:00
|
|
|
int rc = 0;
|
|
|
|
|
|
|
|
switch (OSMO_PRIM_HDR(&scu_prim->oph)) {
|
|
|
|
case OSMO_PRIM(OSMO_SCU_PRIM_N_UNITDATA, PRIM_OP_INDICATION):
|
|
|
|
/* Handle inbound UNITDATA */
|
|
|
|
DEBUGP(DMSC, "N-UNITDATA.ind(%s)\n", osmo_hexdump(msgb_l2(oph->msg), msgb_l2len(oph->msg)));
|
|
|
|
rc = handle_unitdata_from_msc(&scu_prim->u.unitdata.calling_addr, oph->msg, scu);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case OSMO_PRIM(OSMO_SCU_PRIM_N_CONNECT, PRIM_OP_INDICATION):
|
introduce an osmo_fsm for gsm_subscriber_connection
In the current implementation of osmo-bsc, the subscriber connection is
not handled (very) statefully. However, there is some state keeping in the
code that handles the mgcp connection, but there are still to much loose ends
which allow odd situations to happen, which then lead severe error situations
(see also closes tags at the end) This commit adds a number of improvements
to fix those problems.
- Use an osmo-fsm to control the gsm_subscriber_connection state and
make sure that certain operations can only take place at certain states
(e.g let connection oriented SCCP traffic only pass when an SCCP connection
actually exists.
Remove the old osmo_bsc_mgcp.c code. Use the recently developed MGCP client
FSM to handle the MGCP connections.
Also make sure that stuff that already works does not break. This in
particular refers to the internal handover capability and the respective
unit-tests.
See also OS#2823, OS#2768 and OS#2898
- Fix logic to permit assignment to a signalling channel. (OS#2762)
- Introduce T993210 to release lchan + subscr_conn if MSC fails to respond
The GSM specs don't have an explicit timer for this, so let's introdcue
a custom timer (hence starting with 99).
This timeout catches the following situation:
* we send a SCCP CR with COMPL_L3_INFO from the MS to the MSC,
* the MSC doesn't respond (e.g. SCCP routing failure, program down, ...)
The MS is supposed to timeout with T3210, 3220 or 3230. But the BSC
shouldn't trust the MS but have some timer on its own.
SCCP would have a timer T(conn est), but that one is specified to be
1-2min and hence rather long.
See also: OS#2775
- Terminate bsc_subscr_conn_fsm on SCCP N-DISC.ind from MSC
If the MSC is disconnecting the SCCP channel, we must terminate the FSM
which in turn will release all lchan's and other state.
This makes TC_chan_rel_hard_rlsd pass, see also OS#2731
As a side-effect, this fixes TC_chan_act_ack_est_ind_refused(),
where the MSC is answering with CREF to our CR/COMPL_L3.
- Release subscriber connection on RLL RELEASE IND of SAPI0 on main DCCH
The subscriber connection isn't really useful for anything after the
SAPI0 main signalling link has been released. We could try to
re-establish, but our best option is probably simply releasing the
subscriber_conn and anything related to it.
This will make TC_chan_rel_rll_rel_ind pass, see also OS#2730
This commit has been tested using the BSC_Tests TTCN3 testsuit and the
following tests were passed:
TC_chan_act_noreply
TC_chan_act_ack_noest
TC_chan_act_ack_est_ind_noreply
TC_chan_act_ack_est_ind_refused
TC_chan_act_nack
TC_chan_exhaustion
TC_ctrl
TC_chan_rel_conn_fail
TC_chan_rel_hard_clear
TC_chan_rel_hard_rlsd
TC_chan_rel_a_reset
TC_rll_est_ind_inact_lchan
TC_rll_est_ind_inval_sapi1
TC_rll_est_ind_inval_sapi3
TC_rll_est_ind_inval_sacch
TC_assignment_cic_only
TC_assignment_csd
TC_assignment_ctm
TC_assignment_fr_a5_0
TC_assignment_fr_a5_1_codec_missing
TC_assignment_fr_a5_1
TC_assignment_fr_a5_3
TC_assignment_fr_a5_4
TC_paging_imsi_nochan
TC_paging_tmsi_nochan
TC_paging_tmsi_any
TC_paging_tmsi_sdcch
TC_paging_tmsi_tch_f
TC_paging_tmsi_tch_hf
TC_paging_imsi_nochan_cgi
TC_paging_imsi_nochan_lac_ci
TC_paging_imsi_nochan_ci
TC_paging_imsi_nochan_lai
TC_paging_imsi_nochan_lac
TC_paging_imsi_nochan_all
TC_paging_imsi_nochan_plmn_lac_rnc
TC_paging_imsi_nochan_rnc
TC_paging_imsi_nochan_lac_rnc
TC_paging_imsi_nochan_lacs
TC_paging_imsi_nochan_lacs_empty
TC_paging_imsi_a_reset
TC_paging_counter
TC_rsl_drop_counter
TC_classmark
TC_unsol_ass_fail
TC_unsol_ass_compl
TC_unsol_ho_fail
TC_err_82_short_msg
TC_ho_int
Authors:
Harald Welte <laforge@gnumonks.org>
Philipp Maier <pmaier@sysmocom.de>
Neels Hofmeyr <neels@hofmeyr.de>
Closes: OS#2730
Closes: OS#2731
Closes: OS#2762
Closes: OS#2768
Closes: OS#2775
Closes: OS#2823
Closes: OS#2898
Closes: OS#2936
Change-Id: I68286d26e2014048b054f39ef29c35fef420cc97
2018-01-28 02:04:16 +00:00
|
|
|
/* Handle inbound connections */
|
2017-04-09 10:32:51 +00:00
|
|
|
DEBUGP(DMSC, "N-CONNECT.ind(X->%u)\n", scu_prim->u.connect.conn_id);
|
large refactoring: use FSMs for lchans; add inter-BSC HO
Add FSMs:
- timeslot_fsm: handle dynamic timeslots and OML+RSL availability.
- lchan_fsm: handle an individual lchan activation, RTP stream and release,
signal the appropriate calling FSMs on success, failure, release.
- mgw_endpoint_fsm: handle one entire endpoint with several CI.
- assignment_fsm: BSSMAP Assignment Request.
- handover_fsm: all of intra, inter-MO and inter-MT handover.
Above FSMs absorb large parts of the gscon FSM. The gscon FSM was surpassing
the maximum amount events (32), and it is more logical to treat assignment,
handover and MGW procedures in separate FSMs.
- Add logging macros for each FSM type:
- LOG_TS()
- LOG_LCHAN()
- LOG_MGWEP(), LOG_CI()
- LOG_ASSIGNMENT()
- LOG_HO()
These log with the osmo_fsm_inst where present.
New style decision: logging without a final newline char is awkward,
especially for gsmtap logging and when other logs interleave LOGPC() calls;
we have various cases where the final \n goes missing, and also this invokes
the log category checking N times instead of once.
So I decided to make these macros *always* append a newline, but only if
there is no final newline yet. I hope that the compiler optimizes the
strlen() of the constant format strings away. Thus I can log with or without
typing "\n" and always get an \n termination anyway.
General:
- replace osmo_timers, state enums and program-wide osmo_signal_dispatch()
with dedicated FSM timeouts, states and events.
- introduce a common way to handle Tnnn timers: gsm_timers.h/.c: struct T_def.
These can be used (with some macro magic) to define a state's timeout once,
and not make mistakes for each osmo_fsm_inst_state_chg().
Details:
bsc_subscr_conn_fsm.c:
- move most states of this FSM to lchan_fsm, assignment_fsm, handover_fsm and
mgw_endpoint_fsm.
- There is exactly one state for an ongoing Assignment, with all details
handled in conn->assignment.fi. The state relies on the assignment_fsm's
timeout.
- There is one state for an ongoing Handover; except for an incoming Handover
from a remote BSS, the gscon remains in ST_INIT until the new lchan and conn
are both established.
- move bssmap_add_lcls_status() to osmo_bsc_lcls.c
abis_rsl.c:
- move all dynamic timeslot logic away into timeslot_fsm. Only keep plain send/receive functions in
abis_rsl.c
- reduce some rsl functions to merely send a message, rename to "_tx_".
- rsl_ipacc_mdcx(): add '_tx_' in the name; move parts that change the lchan state out into the
lchan_fsm, the lchan->abis_ip.* are now set there prior to invoking this function.
- move all timers and error/release handling away into various FSMs.
- tweak ipa_smod_s_for_lchan() and ipa_rtp_pt_for_lchan() to not require an
lchan passed, but just mode,type that they require. Rename to
ipacc_speech_mode*() and ipacc_payload_type().
- add rsl_forward_layer3_info, used for inter-BSC HO MO, to just send the RR
message received during BSSMAP Handover Command.
- move various logging to LOG_LCHAN() in order to log with the lchan FSM instance.
One drawback is that the lchan FSM is limited to one logging category, i.e. this moves some logging
from DRR to DRSL. It might actually make sense to combine those categories.
- lose LOGP...LOGPC logging cascades: they are bad for gsmtap logging and for performance.
- handle_classmark_chg(): change logging, move cm2 len check out of the cm3 condition (I hope that's
correct).
- gsm48_send_ho_cmd(): split off gsm48_make_ho_cmd() which doesn't send right away, so that during
inter-bsc HO we can make an RR Handover Command to send via the MSC to the remote BSS.
assignment_fsm.c:
- the Chan Mode Modify in case of re-using the same lchan is not implemented
yet, because this was also missing in the previous implementation (OS#3357).
osmo_bsc_api.c:
- simplify bsc_mr_config() and move to lchan_fsm.c, the only caller; rename to
lchan_mr_config(). (bsc_mr_config() used to copy the values to mr_bts_lv
twice, once by member assignment and then again with a memcpy.)
- During handover, we used to copy the MR config from the old lchan. Since we
may handover between FR and HR, rather set the MR Config anew every time, so
that FR rates are always available on FR lchans, and never on HR lchans.
Depends: I03ee7ce840ecfa0b6a33358e7385528aabd4873f (libosmocore),
I1f2918418c38918c5ac70acaa51a47adfca12b5e (libosmocore)
Change-Id: I82e3f918295daa83274a4cf803f046979f284366
2018-05-14 16:14:15 +00:00
|
|
|
rc = handle_n_connect_from_msc(scu, scu_prim);
|
2017-04-09 10:32:51 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case OSMO_PRIM(OSMO_SCU_PRIM_N_CONNECT, PRIM_OP_CONFIRM):
|
|
|
|
/* Handle outbound connection confirmation */
|
introduce an osmo_fsm for gsm_subscriber_connection
In the current implementation of osmo-bsc, the subscriber connection is
not handled (very) statefully. However, there is some state keeping in the
code that handles the mgcp connection, but there are still to much loose ends
which allow odd situations to happen, which then lead severe error situations
(see also closes tags at the end) This commit adds a number of improvements
to fix those problems.
- Use an osmo-fsm to control the gsm_subscriber_connection state and
make sure that certain operations can only take place at certain states
(e.g let connection oriented SCCP traffic only pass when an SCCP connection
actually exists.
Remove the old osmo_bsc_mgcp.c code. Use the recently developed MGCP client
FSM to handle the MGCP connections.
Also make sure that stuff that already works does not break. This in
particular refers to the internal handover capability and the respective
unit-tests.
See also OS#2823, OS#2768 and OS#2898
- Fix logic to permit assignment to a signalling channel. (OS#2762)
- Introduce T993210 to release lchan + subscr_conn if MSC fails to respond
The GSM specs don't have an explicit timer for this, so let's introdcue
a custom timer (hence starting with 99).
This timeout catches the following situation:
* we send a SCCP CR with COMPL_L3_INFO from the MS to the MSC,
* the MSC doesn't respond (e.g. SCCP routing failure, program down, ...)
The MS is supposed to timeout with T3210, 3220 or 3230. But the BSC
shouldn't trust the MS but have some timer on its own.
SCCP would have a timer T(conn est), but that one is specified to be
1-2min and hence rather long.
See also: OS#2775
- Terminate bsc_subscr_conn_fsm on SCCP N-DISC.ind from MSC
If the MSC is disconnecting the SCCP channel, we must terminate the FSM
which in turn will release all lchan's and other state.
This makes TC_chan_rel_hard_rlsd pass, see also OS#2731
As a side-effect, this fixes TC_chan_act_ack_est_ind_refused(),
where the MSC is answering with CREF to our CR/COMPL_L3.
- Release subscriber connection on RLL RELEASE IND of SAPI0 on main DCCH
The subscriber connection isn't really useful for anything after the
SAPI0 main signalling link has been released. We could try to
re-establish, but our best option is probably simply releasing the
subscriber_conn and anything related to it.
This will make TC_chan_rel_rll_rel_ind pass, see also OS#2730
This commit has been tested using the BSC_Tests TTCN3 testsuit and the
following tests were passed:
TC_chan_act_noreply
TC_chan_act_ack_noest
TC_chan_act_ack_est_ind_noreply
TC_chan_act_ack_est_ind_refused
TC_chan_act_nack
TC_chan_exhaustion
TC_ctrl
TC_chan_rel_conn_fail
TC_chan_rel_hard_clear
TC_chan_rel_hard_rlsd
TC_chan_rel_a_reset
TC_rll_est_ind_inact_lchan
TC_rll_est_ind_inval_sapi1
TC_rll_est_ind_inval_sapi3
TC_rll_est_ind_inval_sacch
TC_assignment_cic_only
TC_assignment_csd
TC_assignment_ctm
TC_assignment_fr_a5_0
TC_assignment_fr_a5_1_codec_missing
TC_assignment_fr_a5_1
TC_assignment_fr_a5_3
TC_assignment_fr_a5_4
TC_paging_imsi_nochan
TC_paging_tmsi_nochan
TC_paging_tmsi_any
TC_paging_tmsi_sdcch
TC_paging_tmsi_tch_f
TC_paging_tmsi_tch_hf
TC_paging_imsi_nochan_cgi
TC_paging_imsi_nochan_lac_ci
TC_paging_imsi_nochan_ci
TC_paging_imsi_nochan_lai
TC_paging_imsi_nochan_lac
TC_paging_imsi_nochan_all
TC_paging_imsi_nochan_plmn_lac_rnc
TC_paging_imsi_nochan_rnc
TC_paging_imsi_nochan_lac_rnc
TC_paging_imsi_nochan_lacs
TC_paging_imsi_nochan_lacs_empty
TC_paging_imsi_a_reset
TC_paging_counter
TC_rsl_drop_counter
TC_classmark
TC_unsol_ass_fail
TC_unsol_ass_compl
TC_unsol_ho_fail
TC_err_82_short_msg
TC_ho_int
Authors:
Harald Welte <laforge@gnumonks.org>
Philipp Maier <pmaier@sysmocom.de>
Neels Hofmeyr <neels@hofmeyr.de>
Closes: OS#2730
Closes: OS#2731
Closes: OS#2762
Closes: OS#2768
Closes: OS#2775
Closes: OS#2823
Closes: OS#2898
Closes: OS#2936
Change-Id: I68286d26e2014048b054f39ef29c35fef420cc97
2018-01-28 02:04:16 +00:00
|
|
|
DEBUGP(DMSC, "N-CONNECT.cnf(%u, %s)\n", scu_prim->u.connect.conn_id,
|
|
|
|
osmo_hexdump(msgb_l2(oph->msg), msgb_l2len(oph->msg)));
|
2018-01-28 01:45:46 +00:00
|
|
|
conn = get_bsc_conn_by_conn_id(scu_prim->u.connect.conn_id);
|
introduce an osmo_fsm for gsm_subscriber_connection
In the current implementation of osmo-bsc, the subscriber connection is
not handled (very) statefully. However, there is some state keeping in the
code that handles the mgcp connection, but there are still to much loose ends
which allow odd situations to happen, which then lead severe error situations
(see also closes tags at the end) This commit adds a number of improvements
to fix those problems.
- Use an osmo-fsm to control the gsm_subscriber_connection state and
make sure that certain operations can only take place at certain states
(e.g let connection oriented SCCP traffic only pass when an SCCP connection
actually exists.
Remove the old osmo_bsc_mgcp.c code. Use the recently developed MGCP client
FSM to handle the MGCP connections.
Also make sure that stuff that already works does not break. This in
particular refers to the internal handover capability and the respective
unit-tests.
See also OS#2823, OS#2768 and OS#2898
- Fix logic to permit assignment to a signalling channel. (OS#2762)
- Introduce T993210 to release lchan + subscr_conn if MSC fails to respond
The GSM specs don't have an explicit timer for this, so let's introdcue
a custom timer (hence starting with 99).
This timeout catches the following situation:
* we send a SCCP CR with COMPL_L3_INFO from the MS to the MSC,
* the MSC doesn't respond (e.g. SCCP routing failure, program down, ...)
The MS is supposed to timeout with T3210, 3220 or 3230. But the BSC
shouldn't trust the MS but have some timer on its own.
SCCP would have a timer T(conn est), but that one is specified to be
1-2min and hence rather long.
See also: OS#2775
- Terminate bsc_subscr_conn_fsm on SCCP N-DISC.ind from MSC
If the MSC is disconnecting the SCCP channel, we must terminate the FSM
which in turn will release all lchan's and other state.
This makes TC_chan_rel_hard_rlsd pass, see also OS#2731
As a side-effect, this fixes TC_chan_act_ack_est_ind_refused(),
where the MSC is answering with CREF to our CR/COMPL_L3.
- Release subscriber connection on RLL RELEASE IND of SAPI0 on main DCCH
The subscriber connection isn't really useful for anything after the
SAPI0 main signalling link has been released. We could try to
re-establish, but our best option is probably simply releasing the
subscriber_conn and anything related to it.
This will make TC_chan_rel_rll_rel_ind pass, see also OS#2730
This commit has been tested using the BSC_Tests TTCN3 testsuit and the
following tests were passed:
TC_chan_act_noreply
TC_chan_act_ack_noest
TC_chan_act_ack_est_ind_noreply
TC_chan_act_ack_est_ind_refused
TC_chan_act_nack
TC_chan_exhaustion
TC_ctrl
TC_chan_rel_conn_fail
TC_chan_rel_hard_clear
TC_chan_rel_hard_rlsd
TC_chan_rel_a_reset
TC_rll_est_ind_inact_lchan
TC_rll_est_ind_inval_sapi1
TC_rll_est_ind_inval_sapi3
TC_rll_est_ind_inval_sacch
TC_assignment_cic_only
TC_assignment_csd
TC_assignment_ctm
TC_assignment_fr_a5_0
TC_assignment_fr_a5_1_codec_missing
TC_assignment_fr_a5_1
TC_assignment_fr_a5_3
TC_assignment_fr_a5_4
TC_paging_imsi_nochan
TC_paging_tmsi_nochan
TC_paging_tmsi_any
TC_paging_tmsi_sdcch
TC_paging_tmsi_tch_f
TC_paging_tmsi_tch_hf
TC_paging_imsi_nochan_cgi
TC_paging_imsi_nochan_lac_ci
TC_paging_imsi_nochan_ci
TC_paging_imsi_nochan_lai
TC_paging_imsi_nochan_lac
TC_paging_imsi_nochan_all
TC_paging_imsi_nochan_plmn_lac_rnc
TC_paging_imsi_nochan_rnc
TC_paging_imsi_nochan_lac_rnc
TC_paging_imsi_nochan_lacs
TC_paging_imsi_nochan_lacs_empty
TC_paging_imsi_a_reset
TC_paging_counter
TC_rsl_drop_counter
TC_classmark
TC_unsol_ass_fail
TC_unsol_ass_compl
TC_unsol_ho_fail
TC_err_82_short_msg
TC_ho_int
Authors:
Harald Welte <laforge@gnumonks.org>
Philipp Maier <pmaier@sysmocom.de>
Neels Hofmeyr <neels@hofmeyr.de>
Closes: OS#2730
Closes: OS#2731
Closes: OS#2762
Closes: OS#2768
Closes: OS#2775
Closes: OS#2823
Closes: OS#2898
Closes: OS#2936
Change-Id: I68286d26e2014048b054f39ef29c35fef420cc97
2018-01-28 02:04:16 +00:00
|
|
|
if (conn) {
|
|
|
|
osmo_fsm_inst_dispatch(conn->fi, GSCON_EV_A_CONN_CFM, scu_prim);
|
2018-01-28 01:45:46 +00:00
|
|
|
conn->sccp.state = SUBSCR_SCCP_ST_CONNECTED;
|
introduce an osmo_fsm for gsm_subscriber_connection
In the current implementation of osmo-bsc, the subscriber connection is
not handled (very) statefully. However, there is some state keeping in the
code that handles the mgcp connection, but there are still to much loose ends
which allow odd situations to happen, which then lead severe error situations
(see also closes tags at the end) This commit adds a number of improvements
to fix those problems.
- Use an osmo-fsm to control the gsm_subscriber_connection state and
make sure that certain operations can only take place at certain states
(e.g let connection oriented SCCP traffic only pass when an SCCP connection
actually exists.
Remove the old osmo_bsc_mgcp.c code. Use the recently developed MGCP client
FSM to handle the MGCP connections.
Also make sure that stuff that already works does not break. This in
particular refers to the internal handover capability and the respective
unit-tests.
See also OS#2823, OS#2768 and OS#2898
- Fix logic to permit assignment to a signalling channel. (OS#2762)
- Introduce T993210 to release lchan + subscr_conn if MSC fails to respond
The GSM specs don't have an explicit timer for this, so let's introdcue
a custom timer (hence starting with 99).
This timeout catches the following situation:
* we send a SCCP CR with COMPL_L3_INFO from the MS to the MSC,
* the MSC doesn't respond (e.g. SCCP routing failure, program down, ...)
The MS is supposed to timeout with T3210, 3220 or 3230. But the BSC
shouldn't trust the MS but have some timer on its own.
SCCP would have a timer T(conn est), but that one is specified to be
1-2min and hence rather long.
See also: OS#2775
- Terminate bsc_subscr_conn_fsm on SCCP N-DISC.ind from MSC
If the MSC is disconnecting the SCCP channel, we must terminate the FSM
which in turn will release all lchan's and other state.
This makes TC_chan_rel_hard_rlsd pass, see also OS#2731
As a side-effect, this fixes TC_chan_act_ack_est_ind_refused(),
where the MSC is answering with CREF to our CR/COMPL_L3.
- Release subscriber connection on RLL RELEASE IND of SAPI0 on main DCCH
The subscriber connection isn't really useful for anything after the
SAPI0 main signalling link has been released. We could try to
re-establish, but our best option is probably simply releasing the
subscriber_conn and anything related to it.
This will make TC_chan_rel_rll_rel_ind pass, see also OS#2730
This commit has been tested using the BSC_Tests TTCN3 testsuit and the
following tests were passed:
TC_chan_act_noreply
TC_chan_act_ack_noest
TC_chan_act_ack_est_ind_noreply
TC_chan_act_ack_est_ind_refused
TC_chan_act_nack
TC_chan_exhaustion
TC_ctrl
TC_chan_rel_conn_fail
TC_chan_rel_hard_clear
TC_chan_rel_hard_rlsd
TC_chan_rel_a_reset
TC_rll_est_ind_inact_lchan
TC_rll_est_ind_inval_sapi1
TC_rll_est_ind_inval_sapi3
TC_rll_est_ind_inval_sacch
TC_assignment_cic_only
TC_assignment_csd
TC_assignment_ctm
TC_assignment_fr_a5_0
TC_assignment_fr_a5_1_codec_missing
TC_assignment_fr_a5_1
TC_assignment_fr_a5_3
TC_assignment_fr_a5_4
TC_paging_imsi_nochan
TC_paging_tmsi_nochan
TC_paging_tmsi_any
TC_paging_tmsi_sdcch
TC_paging_tmsi_tch_f
TC_paging_tmsi_tch_hf
TC_paging_imsi_nochan_cgi
TC_paging_imsi_nochan_lac_ci
TC_paging_imsi_nochan_ci
TC_paging_imsi_nochan_lai
TC_paging_imsi_nochan_lac
TC_paging_imsi_nochan_all
TC_paging_imsi_nochan_plmn_lac_rnc
TC_paging_imsi_nochan_rnc
TC_paging_imsi_nochan_lac_rnc
TC_paging_imsi_nochan_lacs
TC_paging_imsi_nochan_lacs_empty
TC_paging_imsi_a_reset
TC_paging_counter
TC_rsl_drop_counter
TC_classmark
TC_unsol_ass_fail
TC_unsol_ass_compl
TC_unsol_ho_fail
TC_err_82_short_msg
TC_ho_int
Authors:
Harald Welte <laforge@gnumonks.org>
Philipp Maier <pmaier@sysmocom.de>
Neels Hofmeyr <neels@hofmeyr.de>
Closes: OS#2730
Closes: OS#2731
Closes: OS#2762
Closes: OS#2768
Closes: OS#2775
Closes: OS#2823
Closes: OS#2898
Closes: OS#2936
Change-Id: I68286d26e2014048b054f39ef29c35fef420cc97
2018-01-28 02:04:16 +00:00
|
|
|
if (msgb_l2len(oph->msg) > 0)
|
|
|
|
handle_data_from_msc(conn, oph->msg);
|
|
|
|
} else {
|
large refactoring: use FSMs for lchans; add inter-BSC HO
Add FSMs:
- timeslot_fsm: handle dynamic timeslots and OML+RSL availability.
- lchan_fsm: handle an individual lchan activation, RTP stream and release,
signal the appropriate calling FSMs on success, failure, release.
- mgw_endpoint_fsm: handle one entire endpoint with several CI.
- assignment_fsm: BSSMAP Assignment Request.
- handover_fsm: all of intra, inter-MO and inter-MT handover.
Above FSMs absorb large parts of the gscon FSM. The gscon FSM was surpassing
the maximum amount events (32), and it is more logical to treat assignment,
handover and MGW procedures in separate FSMs.
- Add logging macros for each FSM type:
- LOG_TS()
- LOG_LCHAN()
- LOG_MGWEP(), LOG_CI()
- LOG_ASSIGNMENT()
- LOG_HO()
These log with the osmo_fsm_inst where present.
New style decision: logging without a final newline char is awkward,
especially for gsmtap logging and when other logs interleave LOGPC() calls;
we have various cases where the final \n goes missing, and also this invokes
the log category checking N times instead of once.
So I decided to make these macros *always* append a newline, but only if
there is no final newline yet. I hope that the compiler optimizes the
strlen() of the constant format strings away. Thus I can log with or without
typing "\n" and always get an \n termination anyway.
General:
- replace osmo_timers, state enums and program-wide osmo_signal_dispatch()
with dedicated FSM timeouts, states and events.
- introduce a common way to handle Tnnn timers: gsm_timers.h/.c: struct T_def.
These can be used (with some macro magic) to define a state's timeout once,
and not make mistakes for each osmo_fsm_inst_state_chg().
Details:
bsc_subscr_conn_fsm.c:
- move most states of this FSM to lchan_fsm, assignment_fsm, handover_fsm and
mgw_endpoint_fsm.
- There is exactly one state for an ongoing Assignment, with all details
handled in conn->assignment.fi. The state relies on the assignment_fsm's
timeout.
- There is one state for an ongoing Handover; except for an incoming Handover
from a remote BSS, the gscon remains in ST_INIT until the new lchan and conn
are both established.
- move bssmap_add_lcls_status() to osmo_bsc_lcls.c
abis_rsl.c:
- move all dynamic timeslot logic away into timeslot_fsm. Only keep plain send/receive functions in
abis_rsl.c
- reduce some rsl functions to merely send a message, rename to "_tx_".
- rsl_ipacc_mdcx(): add '_tx_' in the name; move parts that change the lchan state out into the
lchan_fsm, the lchan->abis_ip.* are now set there prior to invoking this function.
- move all timers and error/release handling away into various FSMs.
- tweak ipa_smod_s_for_lchan() and ipa_rtp_pt_for_lchan() to not require an
lchan passed, but just mode,type that they require. Rename to
ipacc_speech_mode*() and ipacc_payload_type().
- add rsl_forward_layer3_info, used for inter-BSC HO MO, to just send the RR
message received during BSSMAP Handover Command.
- move various logging to LOG_LCHAN() in order to log with the lchan FSM instance.
One drawback is that the lchan FSM is limited to one logging category, i.e. this moves some logging
from DRR to DRSL. It might actually make sense to combine those categories.
- lose LOGP...LOGPC logging cascades: they are bad for gsmtap logging and for performance.
- handle_classmark_chg(): change logging, move cm2 len check out of the cm3 condition (I hope that's
correct).
- gsm48_send_ho_cmd(): split off gsm48_make_ho_cmd() which doesn't send right away, so that during
inter-bsc HO we can make an RR Handover Command to send via the MSC to the remote BSS.
assignment_fsm.c:
- the Chan Mode Modify in case of re-using the same lchan is not implemented
yet, because this was also missing in the previous implementation (OS#3357).
osmo_bsc_api.c:
- simplify bsc_mr_config() and move to lchan_fsm.c, the only caller; rename to
lchan_mr_config(). (bsc_mr_config() used to copy the values to mr_bts_lv
twice, once by member assignment and then again with a memcpy.)
- During handover, we used to copy the MR config from the old lchan. Since we
may handover between FR and HR, rather set the MR Config anew every time, so
that FR rates are always available on FR lchans, and never on HR lchans.
Depends: I03ee7ce840ecfa0b6a33358e7385528aabd4873f (libosmocore),
I1f2918418c38918c5ac70acaa51a47adfca12b5e (libosmocore)
Change-Id: I82e3f918295daa83274a4cf803f046979f284366
2018-05-14 16:14:15 +00:00
|
|
|
LOGP(DMSC, LOGL_ERROR, "N-CONNECT.cfm(%u, %s) for unknown conn?!?\n",
|
introduce an osmo_fsm for gsm_subscriber_connection
In the current implementation of osmo-bsc, the subscriber connection is
not handled (very) statefully. However, there is some state keeping in the
code that handles the mgcp connection, but there are still to much loose ends
which allow odd situations to happen, which then lead severe error situations
(see also closes tags at the end) This commit adds a number of improvements
to fix those problems.
- Use an osmo-fsm to control the gsm_subscriber_connection state and
make sure that certain operations can only take place at certain states
(e.g let connection oriented SCCP traffic only pass when an SCCP connection
actually exists.
Remove the old osmo_bsc_mgcp.c code. Use the recently developed MGCP client
FSM to handle the MGCP connections.
Also make sure that stuff that already works does not break. This in
particular refers to the internal handover capability and the respective
unit-tests.
See also OS#2823, OS#2768 and OS#2898
- Fix logic to permit assignment to a signalling channel. (OS#2762)
- Introduce T993210 to release lchan + subscr_conn if MSC fails to respond
The GSM specs don't have an explicit timer for this, so let's introdcue
a custom timer (hence starting with 99).
This timeout catches the following situation:
* we send a SCCP CR with COMPL_L3_INFO from the MS to the MSC,
* the MSC doesn't respond (e.g. SCCP routing failure, program down, ...)
The MS is supposed to timeout with T3210, 3220 or 3230. But the BSC
shouldn't trust the MS but have some timer on its own.
SCCP would have a timer T(conn est), but that one is specified to be
1-2min and hence rather long.
See also: OS#2775
- Terminate bsc_subscr_conn_fsm on SCCP N-DISC.ind from MSC
If the MSC is disconnecting the SCCP channel, we must terminate the FSM
which in turn will release all lchan's and other state.
This makes TC_chan_rel_hard_rlsd pass, see also OS#2731
As a side-effect, this fixes TC_chan_act_ack_est_ind_refused(),
where the MSC is answering with CREF to our CR/COMPL_L3.
- Release subscriber connection on RLL RELEASE IND of SAPI0 on main DCCH
The subscriber connection isn't really useful for anything after the
SAPI0 main signalling link has been released. We could try to
re-establish, but our best option is probably simply releasing the
subscriber_conn and anything related to it.
This will make TC_chan_rel_rll_rel_ind pass, see also OS#2730
This commit has been tested using the BSC_Tests TTCN3 testsuit and the
following tests were passed:
TC_chan_act_noreply
TC_chan_act_ack_noest
TC_chan_act_ack_est_ind_noreply
TC_chan_act_ack_est_ind_refused
TC_chan_act_nack
TC_chan_exhaustion
TC_ctrl
TC_chan_rel_conn_fail
TC_chan_rel_hard_clear
TC_chan_rel_hard_rlsd
TC_chan_rel_a_reset
TC_rll_est_ind_inact_lchan
TC_rll_est_ind_inval_sapi1
TC_rll_est_ind_inval_sapi3
TC_rll_est_ind_inval_sacch
TC_assignment_cic_only
TC_assignment_csd
TC_assignment_ctm
TC_assignment_fr_a5_0
TC_assignment_fr_a5_1_codec_missing
TC_assignment_fr_a5_1
TC_assignment_fr_a5_3
TC_assignment_fr_a5_4
TC_paging_imsi_nochan
TC_paging_tmsi_nochan
TC_paging_tmsi_any
TC_paging_tmsi_sdcch
TC_paging_tmsi_tch_f
TC_paging_tmsi_tch_hf
TC_paging_imsi_nochan_cgi
TC_paging_imsi_nochan_lac_ci
TC_paging_imsi_nochan_ci
TC_paging_imsi_nochan_lai
TC_paging_imsi_nochan_lac
TC_paging_imsi_nochan_all
TC_paging_imsi_nochan_plmn_lac_rnc
TC_paging_imsi_nochan_rnc
TC_paging_imsi_nochan_lac_rnc
TC_paging_imsi_nochan_lacs
TC_paging_imsi_nochan_lacs_empty
TC_paging_imsi_a_reset
TC_paging_counter
TC_rsl_drop_counter
TC_classmark
TC_unsol_ass_fail
TC_unsol_ass_compl
TC_unsol_ho_fail
TC_err_82_short_msg
TC_ho_int
Authors:
Harald Welte <laforge@gnumonks.org>
Philipp Maier <pmaier@sysmocom.de>
Neels Hofmeyr <neels@hofmeyr.de>
Closes: OS#2730
Closes: OS#2731
Closes: OS#2762
Closes: OS#2768
Closes: OS#2775
Closes: OS#2823
Closes: OS#2898
Closes: OS#2936
Change-Id: I68286d26e2014048b054f39ef29c35fef420cc97
2018-01-28 02:04:16 +00:00
|
|
|
scu_prim->u.connect.conn_id, osmo_hexdump(msgb_l2(oph->msg),
|
|
|
|
msgb_l2len(oph->msg)));
|
|
|
|
}
|
2017-04-09 10:32:51 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case OSMO_PRIM(OSMO_SCU_PRIM_N_DATA, PRIM_OP_INDICATION):
|
|
|
|
/* Handle incoming connection oriented data */
|
|
|
|
DEBUGP(DMSC, "N-DATA.ind(%u, %s)\n", scu_prim->u.data.conn_id,
|
|
|
|
osmo_hexdump(msgb_l2(oph->msg), msgb_l2len(oph->msg)));
|
|
|
|
|
|
|
|
/* Incoming data is a sign of a vital connection */
|
introduce an osmo_fsm for gsm_subscriber_connection
In the current implementation of osmo-bsc, the subscriber connection is
not handled (very) statefully. However, there is some state keeping in the
code that handles the mgcp connection, but there are still to much loose ends
which allow odd situations to happen, which then lead severe error situations
(see also closes tags at the end) This commit adds a number of improvements
to fix those problems.
- Use an osmo-fsm to control the gsm_subscriber_connection state and
make sure that certain operations can only take place at certain states
(e.g let connection oriented SCCP traffic only pass when an SCCP connection
actually exists.
Remove the old osmo_bsc_mgcp.c code. Use the recently developed MGCP client
FSM to handle the MGCP connections.
Also make sure that stuff that already works does not break. This in
particular refers to the internal handover capability and the respective
unit-tests.
See also OS#2823, OS#2768 and OS#2898
- Fix logic to permit assignment to a signalling channel. (OS#2762)
- Introduce T993210 to release lchan + subscr_conn if MSC fails to respond
The GSM specs don't have an explicit timer for this, so let's introdcue
a custom timer (hence starting with 99).
This timeout catches the following situation:
* we send a SCCP CR with COMPL_L3_INFO from the MS to the MSC,
* the MSC doesn't respond (e.g. SCCP routing failure, program down, ...)
The MS is supposed to timeout with T3210, 3220 or 3230. But the BSC
shouldn't trust the MS but have some timer on its own.
SCCP would have a timer T(conn est), but that one is specified to be
1-2min and hence rather long.
See also: OS#2775
- Terminate bsc_subscr_conn_fsm on SCCP N-DISC.ind from MSC
If the MSC is disconnecting the SCCP channel, we must terminate the FSM
which in turn will release all lchan's and other state.
This makes TC_chan_rel_hard_rlsd pass, see also OS#2731
As a side-effect, this fixes TC_chan_act_ack_est_ind_refused(),
where the MSC is answering with CREF to our CR/COMPL_L3.
- Release subscriber connection on RLL RELEASE IND of SAPI0 on main DCCH
The subscriber connection isn't really useful for anything after the
SAPI0 main signalling link has been released. We could try to
re-establish, but our best option is probably simply releasing the
subscriber_conn and anything related to it.
This will make TC_chan_rel_rll_rel_ind pass, see also OS#2730
This commit has been tested using the BSC_Tests TTCN3 testsuit and the
following tests were passed:
TC_chan_act_noreply
TC_chan_act_ack_noest
TC_chan_act_ack_est_ind_noreply
TC_chan_act_ack_est_ind_refused
TC_chan_act_nack
TC_chan_exhaustion
TC_ctrl
TC_chan_rel_conn_fail
TC_chan_rel_hard_clear
TC_chan_rel_hard_rlsd
TC_chan_rel_a_reset
TC_rll_est_ind_inact_lchan
TC_rll_est_ind_inval_sapi1
TC_rll_est_ind_inval_sapi3
TC_rll_est_ind_inval_sacch
TC_assignment_cic_only
TC_assignment_csd
TC_assignment_ctm
TC_assignment_fr_a5_0
TC_assignment_fr_a5_1_codec_missing
TC_assignment_fr_a5_1
TC_assignment_fr_a5_3
TC_assignment_fr_a5_4
TC_paging_imsi_nochan
TC_paging_tmsi_nochan
TC_paging_tmsi_any
TC_paging_tmsi_sdcch
TC_paging_tmsi_tch_f
TC_paging_tmsi_tch_hf
TC_paging_imsi_nochan_cgi
TC_paging_imsi_nochan_lac_ci
TC_paging_imsi_nochan_ci
TC_paging_imsi_nochan_lai
TC_paging_imsi_nochan_lac
TC_paging_imsi_nochan_all
TC_paging_imsi_nochan_plmn_lac_rnc
TC_paging_imsi_nochan_rnc
TC_paging_imsi_nochan_lac_rnc
TC_paging_imsi_nochan_lacs
TC_paging_imsi_nochan_lacs_empty
TC_paging_imsi_a_reset
TC_paging_counter
TC_rsl_drop_counter
TC_classmark
TC_unsol_ass_fail
TC_unsol_ass_compl
TC_unsol_ho_fail
TC_err_82_short_msg
TC_ho_int
Authors:
Harald Welte <laforge@gnumonks.org>
Philipp Maier <pmaier@sysmocom.de>
Neels Hofmeyr <neels@hofmeyr.de>
Closes: OS#2730
Closes: OS#2731
Closes: OS#2762
Closes: OS#2768
Closes: OS#2775
Closes: OS#2823
Closes: OS#2898
Closes: OS#2936
Change-Id: I68286d26e2014048b054f39ef29c35fef420cc97
2018-01-28 02:04:16 +00:00
|
|
|
conn = get_bsc_conn_by_conn_id(scu_prim->u.data.conn_id);
|
|
|
|
if (conn) {
|
2018-08-07 09:31:51 +00:00
|
|
|
a_reset_conn_success(conn->sccp.msc);
|
introduce an osmo_fsm for gsm_subscriber_connection
In the current implementation of osmo-bsc, the subscriber connection is
not handled (very) statefully. However, there is some state keeping in the
code that handles the mgcp connection, but there are still to much loose ends
which allow odd situations to happen, which then lead severe error situations
(see also closes tags at the end) This commit adds a number of improvements
to fix those problems.
- Use an osmo-fsm to control the gsm_subscriber_connection state and
make sure that certain operations can only take place at certain states
(e.g let connection oriented SCCP traffic only pass when an SCCP connection
actually exists.
Remove the old osmo_bsc_mgcp.c code. Use the recently developed MGCP client
FSM to handle the MGCP connections.
Also make sure that stuff that already works does not break. This in
particular refers to the internal handover capability and the respective
unit-tests.
See also OS#2823, OS#2768 and OS#2898
- Fix logic to permit assignment to a signalling channel. (OS#2762)
- Introduce T993210 to release lchan + subscr_conn if MSC fails to respond
The GSM specs don't have an explicit timer for this, so let's introdcue
a custom timer (hence starting with 99).
This timeout catches the following situation:
* we send a SCCP CR with COMPL_L3_INFO from the MS to the MSC,
* the MSC doesn't respond (e.g. SCCP routing failure, program down, ...)
The MS is supposed to timeout with T3210, 3220 or 3230. But the BSC
shouldn't trust the MS but have some timer on its own.
SCCP would have a timer T(conn est), but that one is specified to be
1-2min and hence rather long.
See also: OS#2775
- Terminate bsc_subscr_conn_fsm on SCCP N-DISC.ind from MSC
If the MSC is disconnecting the SCCP channel, we must terminate the FSM
which in turn will release all lchan's and other state.
This makes TC_chan_rel_hard_rlsd pass, see also OS#2731
As a side-effect, this fixes TC_chan_act_ack_est_ind_refused(),
where the MSC is answering with CREF to our CR/COMPL_L3.
- Release subscriber connection on RLL RELEASE IND of SAPI0 on main DCCH
The subscriber connection isn't really useful for anything after the
SAPI0 main signalling link has been released. We could try to
re-establish, but our best option is probably simply releasing the
subscriber_conn and anything related to it.
This will make TC_chan_rel_rll_rel_ind pass, see also OS#2730
This commit has been tested using the BSC_Tests TTCN3 testsuit and the
following tests were passed:
TC_chan_act_noreply
TC_chan_act_ack_noest
TC_chan_act_ack_est_ind_noreply
TC_chan_act_ack_est_ind_refused
TC_chan_act_nack
TC_chan_exhaustion
TC_ctrl
TC_chan_rel_conn_fail
TC_chan_rel_hard_clear
TC_chan_rel_hard_rlsd
TC_chan_rel_a_reset
TC_rll_est_ind_inact_lchan
TC_rll_est_ind_inval_sapi1
TC_rll_est_ind_inval_sapi3
TC_rll_est_ind_inval_sacch
TC_assignment_cic_only
TC_assignment_csd
TC_assignment_ctm
TC_assignment_fr_a5_0
TC_assignment_fr_a5_1_codec_missing
TC_assignment_fr_a5_1
TC_assignment_fr_a5_3
TC_assignment_fr_a5_4
TC_paging_imsi_nochan
TC_paging_tmsi_nochan
TC_paging_tmsi_any
TC_paging_tmsi_sdcch
TC_paging_tmsi_tch_f
TC_paging_tmsi_tch_hf
TC_paging_imsi_nochan_cgi
TC_paging_imsi_nochan_lac_ci
TC_paging_imsi_nochan_ci
TC_paging_imsi_nochan_lai
TC_paging_imsi_nochan_lac
TC_paging_imsi_nochan_all
TC_paging_imsi_nochan_plmn_lac_rnc
TC_paging_imsi_nochan_rnc
TC_paging_imsi_nochan_lac_rnc
TC_paging_imsi_nochan_lacs
TC_paging_imsi_nochan_lacs_empty
TC_paging_imsi_a_reset
TC_paging_counter
TC_rsl_drop_counter
TC_classmark
TC_unsol_ass_fail
TC_unsol_ass_compl
TC_unsol_ho_fail
TC_err_82_short_msg
TC_ho_int
Authors:
Harald Welte <laforge@gnumonks.org>
Philipp Maier <pmaier@sysmocom.de>
Neels Hofmeyr <neels@hofmeyr.de>
Closes: OS#2730
Closes: OS#2731
Closes: OS#2762
Closes: OS#2768
Closes: OS#2775
Closes: OS#2823
Closes: OS#2898
Closes: OS#2936
Change-Id: I68286d26e2014048b054f39ef29c35fef420cc97
2018-01-28 02:04:16 +00:00
|
|
|
handle_data_from_msc(conn, oph->msg);
|
|
|
|
}
|
2017-04-09 10:32:51 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case OSMO_PRIM(OSMO_SCU_PRIM_N_DISCONNECT, PRIM_OP_INDICATION):
|
introduce an osmo_fsm for gsm_subscriber_connection
In the current implementation of osmo-bsc, the subscriber connection is
not handled (very) statefully. However, there is some state keeping in the
code that handles the mgcp connection, but there are still to much loose ends
which allow odd situations to happen, which then lead severe error situations
(see also closes tags at the end) This commit adds a number of improvements
to fix those problems.
- Use an osmo-fsm to control the gsm_subscriber_connection state and
make sure that certain operations can only take place at certain states
(e.g let connection oriented SCCP traffic only pass when an SCCP connection
actually exists.
Remove the old osmo_bsc_mgcp.c code. Use the recently developed MGCP client
FSM to handle the MGCP connections.
Also make sure that stuff that already works does not break. This in
particular refers to the internal handover capability and the respective
unit-tests.
See also OS#2823, OS#2768 and OS#2898
- Fix logic to permit assignment to a signalling channel. (OS#2762)
- Introduce T993210 to release lchan + subscr_conn if MSC fails to respond
The GSM specs don't have an explicit timer for this, so let's introdcue
a custom timer (hence starting with 99).
This timeout catches the following situation:
* we send a SCCP CR with COMPL_L3_INFO from the MS to the MSC,
* the MSC doesn't respond (e.g. SCCP routing failure, program down, ...)
The MS is supposed to timeout with T3210, 3220 or 3230. But the BSC
shouldn't trust the MS but have some timer on its own.
SCCP would have a timer T(conn est), but that one is specified to be
1-2min and hence rather long.
See also: OS#2775
- Terminate bsc_subscr_conn_fsm on SCCP N-DISC.ind from MSC
If the MSC is disconnecting the SCCP channel, we must terminate the FSM
which in turn will release all lchan's and other state.
This makes TC_chan_rel_hard_rlsd pass, see also OS#2731
As a side-effect, this fixes TC_chan_act_ack_est_ind_refused(),
where the MSC is answering with CREF to our CR/COMPL_L3.
- Release subscriber connection on RLL RELEASE IND of SAPI0 on main DCCH
The subscriber connection isn't really useful for anything after the
SAPI0 main signalling link has been released. We could try to
re-establish, but our best option is probably simply releasing the
subscriber_conn and anything related to it.
This will make TC_chan_rel_rll_rel_ind pass, see also OS#2730
This commit has been tested using the BSC_Tests TTCN3 testsuit and the
following tests were passed:
TC_chan_act_noreply
TC_chan_act_ack_noest
TC_chan_act_ack_est_ind_noreply
TC_chan_act_ack_est_ind_refused
TC_chan_act_nack
TC_chan_exhaustion
TC_ctrl
TC_chan_rel_conn_fail
TC_chan_rel_hard_clear
TC_chan_rel_hard_rlsd
TC_chan_rel_a_reset
TC_rll_est_ind_inact_lchan
TC_rll_est_ind_inval_sapi1
TC_rll_est_ind_inval_sapi3
TC_rll_est_ind_inval_sacch
TC_assignment_cic_only
TC_assignment_csd
TC_assignment_ctm
TC_assignment_fr_a5_0
TC_assignment_fr_a5_1_codec_missing
TC_assignment_fr_a5_1
TC_assignment_fr_a5_3
TC_assignment_fr_a5_4
TC_paging_imsi_nochan
TC_paging_tmsi_nochan
TC_paging_tmsi_any
TC_paging_tmsi_sdcch
TC_paging_tmsi_tch_f
TC_paging_tmsi_tch_hf
TC_paging_imsi_nochan_cgi
TC_paging_imsi_nochan_lac_ci
TC_paging_imsi_nochan_ci
TC_paging_imsi_nochan_lai
TC_paging_imsi_nochan_lac
TC_paging_imsi_nochan_all
TC_paging_imsi_nochan_plmn_lac_rnc
TC_paging_imsi_nochan_rnc
TC_paging_imsi_nochan_lac_rnc
TC_paging_imsi_nochan_lacs
TC_paging_imsi_nochan_lacs_empty
TC_paging_imsi_a_reset
TC_paging_counter
TC_rsl_drop_counter
TC_classmark
TC_unsol_ass_fail
TC_unsol_ass_compl
TC_unsol_ho_fail
TC_err_82_short_msg
TC_ho_int
Authors:
Harald Welte <laforge@gnumonks.org>
Philipp Maier <pmaier@sysmocom.de>
Neels Hofmeyr <neels@hofmeyr.de>
Closes: OS#2730
Closes: OS#2731
Closes: OS#2762
Closes: OS#2768
Closes: OS#2775
Closes: OS#2823
Closes: OS#2898
Closes: OS#2936
Change-Id: I68286d26e2014048b054f39ef29c35fef420cc97
2018-01-28 02:04:16 +00:00
|
|
|
DEBUGP(DMSC, "N-DISCONNECT.ind(%u, %s, cause=%i)\n", scu_prim->u.disconnect.conn_id,
|
|
|
|
osmo_hexdump(msgb_l2(oph->msg), msgb_l2len(oph->msg)),
|
|
|
|
scu_prim->u.disconnect.cause);
|
2017-04-09 10:32:51 +00:00
|
|
|
/* indication of disconnect */
|
2018-01-28 01:45:46 +00:00
|
|
|
conn = get_bsc_conn_by_conn_id(scu_prim->u.disconnect.conn_id);
|
introduce an osmo_fsm for gsm_subscriber_connection
In the current implementation of osmo-bsc, the subscriber connection is
not handled (very) statefully. However, there is some state keeping in the
code that handles the mgcp connection, but there are still to much loose ends
which allow odd situations to happen, which then lead severe error situations
(see also closes tags at the end) This commit adds a number of improvements
to fix those problems.
- Use an osmo-fsm to control the gsm_subscriber_connection state and
make sure that certain operations can only take place at certain states
(e.g let connection oriented SCCP traffic only pass when an SCCP connection
actually exists.
Remove the old osmo_bsc_mgcp.c code. Use the recently developed MGCP client
FSM to handle the MGCP connections.
Also make sure that stuff that already works does not break. This in
particular refers to the internal handover capability and the respective
unit-tests.
See also OS#2823, OS#2768 and OS#2898
- Fix logic to permit assignment to a signalling channel. (OS#2762)
- Introduce T993210 to release lchan + subscr_conn if MSC fails to respond
The GSM specs don't have an explicit timer for this, so let's introdcue
a custom timer (hence starting with 99).
This timeout catches the following situation:
* we send a SCCP CR with COMPL_L3_INFO from the MS to the MSC,
* the MSC doesn't respond (e.g. SCCP routing failure, program down, ...)
The MS is supposed to timeout with T3210, 3220 or 3230. But the BSC
shouldn't trust the MS but have some timer on its own.
SCCP would have a timer T(conn est), but that one is specified to be
1-2min and hence rather long.
See also: OS#2775
- Terminate bsc_subscr_conn_fsm on SCCP N-DISC.ind from MSC
If the MSC is disconnecting the SCCP channel, we must terminate the FSM
which in turn will release all lchan's and other state.
This makes TC_chan_rel_hard_rlsd pass, see also OS#2731
As a side-effect, this fixes TC_chan_act_ack_est_ind_refused(),
where the MSC is answering with CREF to our CR/COMPL_L3.
- Release subscriber connection on RLL RELEASE IND of SAPI0 on main DCCH
The subscriber connection isn't really useful for anything after the
SAPI0 main signalling link has been released. We could try to
re-establish, but our best option is probably simply releasing the
subscriber_conn and anything related to it.
This will make TC_chan_rel_rll_rel_ind pass, see also OS#2730
This commit has been tested using the BSC_Tests TTCN3 testsuit and the
following tests were passed:
TC_chan_act_noreply
TC_chan_act_ack_noest
TC_chan_act_ack_est_ind_noreply
TC_chan_act_ack_est_ind_refused
TC_chan_act_nack
TC_chan_exhaustion
TC_ctrl
TC_chan_rel_conn_fail
TC_chan_rel_hard_clear
TC_chan_rel_hard_rlsd
TC_chan_rel_a_reset
TC_rll_est_ind_inact_lchan
TC_rll_est_ind_inval_sapi1
TC_rll_est_ind_inval_sapi3
TC_rll_est_ind_inval_sacch
TC_assignment_cic_only
TC_assignment_csd
TC_assignment_ctm
TC_assignment_fr_a5_0
TC_assignment_fr_a5_1_codec_missing
TC_assignment_fr_a5_1
TC_assignment_fr_a5_3
TC_assignment_fr_a5_4
TC_paging_imsi_nochan
TC_paging_tmsi_nochan
TC_paging_tmsi_any
TC_paging_tmsi_sdcch
TC_paging_tmsi_tch_f
TC_paging_tmsi_tch_hf
TC_paging_imsi_nochan_cgi
TC_paging_imsi_nochan_lac_ci
TC_paging_imsi_nochan_ci
TC_paging_imsi_nochan_lai
TC_paging_imsi_nochan_lac
TC_paging_imsi_nochan_all
TC_paging_imsi_nochan_plmn_lac_rnc
TC_paging_imsi_nochan_rnc
TC_paging_imsi_nochan_lac_rnc
TC_paging_imsi_nochan_lacs
TC_paging_imsi_nochan_lacs_empty
TC_paging_imsi_a_reset
TC_paging_counter
TC_rsl_drop_counter
TC_classmark
TC_unsol_ass_fail
TC_unsol_ass_compl
TC_unsol_ho_fail
TC_err_82_short_msg
TC_ho_int
Authors:
Harald Welte <laforge@gnumonks.org>
Philipp Maier <pmaier@sysmocom.de>
Neels Hofmeyr <neels@hofmeyr.de>
Closes: OS#2730
Closes: OS#2731
Closes: OS#2762
Closes: OS#2768
Closes: OS#2775
Closes: OS#2823
Closes: OS#2898
Closes: OS#2936
Change-Id: I68286d26e2014048b054f39ef29c35fef420cc97
2018-01-28 02:04:16 +00:00
|
|
|
if (conn) {
|
2018-01-28 01:45:46 +00:00
|
|
|
conn->sccp.state = SUBSCR_SCCP_ST_NONE;
|
introduce an osmo_fsm for gsm_subscriber_connection
In the current implementation of osmo-bsc, the subscriber connection is
not handled (very) statefully. However, there is some state keeping in the
code that handles the mgcp connection, but there are still to much loose ends
which allow odd situations to happen, which then lead severe error situations
(see also closes tags at the end) This commit adds a number of improvements
to fix those problems.
- Use an osmo-fsm to control the gsm_subscriber_connection state and
make sure that certain operations can only take place at certain states
(e.g let connection oriented SCCP traffic only pass when an SCCP connection
actually exists.
Remove the old osmo_bsc_mgcp.c code. Use the recently developed MGCP client
FSM to handle the MGCP connections.
Also make sure that stuff that already works does not break. This in
particular refers to the internal handover capability and the respective
unit-tests.
See also OS#2823, OS#2768 and OS#2898
- Fix logic to permit assignment to a signalling channel. (OS#2762)
- Introduce T993210 to release lchan + subscr_conn if MSC fails to respond
The GSM specs don't have an explicit timer for this, so let's introdcue
a custom timer (hence starting with 99).
This timeout catches the following situation:
* we send a SCCP CR with COMPL_L3_INFO from the MS to the MSC,
* the MSC doesn't respond (e.g. SCCP routing failure, program down, ...)
The MS is supposed to timeout with T3210, 3220 or 3230. But the BSC
shouldn't trust the MS but have some timer on its own.
SCCP would have a timer T(conn est), but that one is specified to be
1-2min and hence rather long.
See also: OS#2775
- Terminate bsc_subscr_conn_fsm on SCCP N-DISC.ind from MSC
If the MSC is disconnecting the SCCP channel, we must terminate the FSM
which in turn will release all lchan's and other state.
This makes TC_chan_rel_hard_rlsd pass, see also OS#2731
As a side-effect, this fixes TC_chan_act_ack_est_ind_refused(),
where the MSC is answering with CREF to our CR/COMPL_L3.
- Release subscriber connection on RLL RELEASE IND of SAPI0 on main DCCH
The subscriber connection isn't really useful for anything after the
SAPI0 main signalling link has been released. We could try to
re-establish, but our best option is probably simply releasing the
subscriber_conn and anything related to it.
This will make TC_chan_rel_rll_rel_ind pass, see also OS#2730
This commit has been tested using the BSC_Tests TTCN3 testsuit and the
following tests were passed:
TC_chan_act_noreply
TC_chan_act_ack_noest
TC_chan_act_ack_est_ind_noreply
TC_chan_act_ack_est_ind_refused
TC_chan_act_nack
TC_chan_exhaustion
TC_ctrl
TC_chan_rel_conn_fail
TC_chan_rel_hard_clear
TC_chan_rel_hard_rlsd
TC_chan_rel_a_reset
TC_rll_est_ind_inact_lchan
TC_rll_est_ind_inval_sapi1
TC_rll_est_ind_inval_sapi3
TC_rll_est_ind_inval_sacch
TC_assignment_cic_only
TC_assignment_csd
TC_assignment_ctm
TC_assignment_fr_a5_0
TC_assignment_fr_a5_1_codec_missing
TC_assignment_fr_a5_1
TC_assignment_fr_a5_3
TC_assignment_fr_a5_4
TC_paging_imsi_nochan
TC_paging_tmsi_nochan
TC_paging_tmsi_any
TC_paging_tmsi_sdcch
TC_paging_tmsi_tch_f
TC_paging_tmsi_tch_hf
TC_paging_imsi_nochan_cgi
TC_paging_imsi_nochan_lac_ci
TC_paging_imsi_nochan_ci
TC_paging_imsi_nochan_lai
TC_paging_imsi_nochan_lac
TC_paging_imsi_nochan_all
TC_paging_imsi_nochan_plmn_lac_rnc
TC_paging_imsi_nochan_rnc
TC_paging_imsi_nochan_lac_rnc
TC_paging_imsi_nochan_lacs
TC_paging_imsi_nochan_lacs_empty
TC_paging_imsi_a_reset
TC_paging_counter
TC_rsl_drop_counter
TC_classmark
TC_unsol_ass_fail
TC_unsol_ass_compl
TC_unsol_ho_fail
TC_err_82_short_msg
TC_ho_int
Authors:
Harald Welte <laforge@gnumonks.org>
Philipp Maier <pmaier@sysmocom.de>
Neels Hofmeyr <neels@hofmeyr.de>
Closes: OS#2730
Closes: OS#2731
Closes: OS#2762
Closes: OS#2768
Closes: OS#2775
Closes: OS#2823
Closes: OS#2898
Closes: OS#2936
Change-Id: I68286d26e2014048b054f39ef29c35fef420cc97
2018-01-28 02:04:16 +00:00
|
|
|
if (msgb_l2len(oph->msg) > 0)
|
|
|
|
handle_data_from_msc(conn, oph->msg);
|
|
|
|
osmo_fsm_inst_dispatch(conn->fi, GSCON_EV_A_DISC_IND, scu_prim);
|
2017-04-09 10:32:51 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
2018-01-24 13:10:51 +00:00
|
|
|
LOGP(DMSC, LOGL_ERROR, "Unhandled SIGTRAN operation %s on primitive %u\n",
|
|
|
|
get_value_string(osmo_prim_op_names, oph->operation), oph->primitive);
|
2017-04-09 10:32:51 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
msgb_free(oph->msg);
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Allocate resources to make a new connection oriented sigtran connection
|
|
|
|
* (not the connection ittself!) */
|
|
|
|
enum bsc_con osmo_bsc_sigtran_new_conn(struct gsm_subscriber_connection *conn, struct bsc_msc_data *msc)
|
|
|
|
{
|
|
|
|
struct osmo_ss7_instance *ss7;
|
2017-12-18 17:44:25 +00:00
|
|
|
struct gsm_bts *bts = conn_get_bts(conn);
|
2017-04-09 10:32:51 +00:00
|
|
|
|
|
|
|
OSMO_ASSERT(conn);
|
|
|
|
OSMO_ASSERT(msc);
|
|
|
|
|
|
|
|
ss7 = osmo_ss7_instance_find(msc->a.cs7_instance);
|
|
|
|
OSMO_ASSERT(ss7);
|
2020-08-12 22:06:57 +00:00
|
|
|
LOGP(DMSC, LOGL_INFO, "Initializing resources for new SCCP connection to MSC %d: %s...\n",
|
|
|
|
msc->nr, osmo_sccp_addr_name(ss7, &msc->a.msc_addr));
|
2017-04-09 10:32:51 +00:00
|
|
|
|
2018-08-07 09:31:51 +00:00
|
|
|
if (a_reset_conn_ready(msc) == false) {
|
2020-08-12 22:06:57 +00:00
|
|
|
LOGP(DMSC, LOGL_ERROR, "MSC %d is not connected. Dropping.\n", msc->nr);
|
2017-04-09 10:32:51 +00:00
|
|
|
return BSC_CON_REJECT_NO_LINK;
|
|
|
|
}
|
|
|
|
|
2020-06-18 15:29:56 +00:00
|
|
|
if (bts && !bsc_grace_allow_new_connection(bts->network, bts)) {
|
2017-04-09 10:32:51 +00:00
|
|
|
LOGP(DMSC, LOGL_NOTICE, "BSC in grace period. No new connections.\n");
|
|
|
|
return BSC_CON_REJECT_RF_GRACE;
|
|
|
|
}
|
|
|
|
|
2018-01-28 01:45:46 +00:00
|
|
|
conn->sccp.msc = msc;
|
2017-04-09 10:32:51 +00:00
|
|
|
|
|
|
|
return BSC_CON_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Open a new connection oriented sigtran connection */
|
2018-01-28 01:45:46 +00:00
|
|
|
int osmo_bsc_sigtran_open_conn(struct gsm_subscriber_connection *conn, struct msgb *msg)
|
2017-04-09 10:32:51 +00:00
|
|
|
{
|
|
|
|
struct osmo_ss7_instance *ss7;
|
|
|
|
struct bsc_msc_data *msc;
|
|
|
|
int conn_id;
|
|
|
|
int rc;
|
|
|
|
|
|
|
|
OSMO_ASSERT(conn);
|
|
|
|
OSMO_ASSERT(msg);
|
2018-01-28 01:45:46 +00:00
|
|
|
OSMO_ASSERT(conn->sccp.msc);
|
|
|
|
OSMO_ASSERT(conn->sccp.conn_id == -1);
|
2017-04-09 10:32:51 +00:00
|
|
|
|
2018-01-28 01:45:46 +00:00
|
|
|
msc = conn->sccp.msc;
|
2017-04-09 10:32:51 +00:00
|
|
|
|
2018-08-07 09:31:51 +00:00
|
|
|
if (a_reset_conn_ready(msc) == false) {
|
2017-04-09 10:32:51 +00:00
|
|
|
LOGP(DMSC, LOGL_ERROR, "MSC is not connected. Dropping.\n");
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
2018-01-28 01:45:46 +00:00
|
|
|
conn->sccp.conn_id = conn_id = pick_free_conn_id(msc);
|
|
|
|
if (conn->sccp.conn_id < 0) {
|
|
|
|
LOGP(DMSC, LOGL_ERROR, "Unable to allocate SCCP Connection ID\n");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
LOGP(DMSC, LOGL_DEBUG, "Allocated new connection id: %d\n", conn->sccp.conn_id);
|
2017-04-09 10:32:51 +00:00
|
|
|
ss7 = osmo_ss7_instance_find(msc->a.cs7_instance);
|
|
|
|
OSMO_ASSERT(ss7);
|
2020-05-16 14:56:05 +00:00
|
|
|
LOGP(DMSC, LOGL_INFO, "Opening new SCCP connection (id=%i) to MSC: %s\n", conn_id,
|
2017-04-09 10:32:51 +00:00
|
|
|
osmo_sccp_addr_name(ss7, &msc->a.msc_addr));
|
|
|
|
|
|
|
|
rc = osmo_sccp_tx_conn_req_msg(msc->a.sccp_user, conn_id, &msc->a.bsc_addr,
|
|
|
|
&msc->a.msc_addr, msg);
|
2018-01-28 01:45:46 +00:00
|
|
|
if (rc >= 0)
|
|
|
|
conn->sccp.state = SUBSCR_SCCP_ST_WAIT_CONN_CONF;
|
2017-04-09 10:32:51 +00:00
|
|
|
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
2018-08-07 10:06:05 +00:00
|
|
|
/* Send data to MSC, the function will take ownership of *msg */
|
2018-01-28 01:45:46 +00:00
|
|
|
int osmo_bsc_sigtran_send(struct gsm_subscriber_connection *conn, struct msgb *msg)
|
2017-04-09 10:32:51 +00:00
|
|
|
{
|
|
|
|
struct osmo_ss7_instance *ss7;
|
|
|
|
int conn_id;
|
|
|
|
int rc;
|
|
|
|
struct bsc_msc_data *msc;
|
|
|
|
|
|
|
|
OSMO_ASSERT(conn);
|
|
|
|
OSMO_ASSERT(msg);
|
2018-08-06 14:34:32 +00:00
|
|
|
|
|
|
|
if (!conn->sccp.msc) {
|
|
|
|
LOGP(DMSC, LOGL_ERROR, "MSC is not connected. Dropping.\n");
|
|
|
|
msgb_free(msg);
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
2017-04-09 10:32:51 +00:00
|
|
|
|
2018-01-28 01:45:46 +00:00
|
|
|
msc = conn->sccp.msc;
|
2017-04-09 10:32:51 +00:00
|
|
|
|
2017-10-23 09:36:50 +00:00
|
|
|
/* Log the type of the message we are sending. This is just
|
|
|
|
* informative, do not stop if detecting the type fails */
|
|
|
|
if (msg->len >= 3) {
|
|
|
|
switch (msg->data[0]) {
|
|
|
|
case BSSAP_MSG_BSS_MANAGEMENT:
|
2020-05-09 18:27:40 +00:00
|
|
|
rate_ctr_inc(&msc->msc_ctrs->ctr[MSC_CTR_BSSMAP_TX_BSS_MANAGEMENT]);
|
2018-08-27 23:03:27 +00:00
|
|
|
LOGP(DMSC, LOGL_INFO, "Tx MSC: BSSMAP: %s\n",
|
|
|
|
gsm0808_bssmap_name(msg->data[2]));
|
2017-10-23 09:36:50 +00:00
|
|
|
break;
|
|
|
|
case BSSAP_MSG_DTAP:
|
2020-05-09 18:27:40 +00:00
|
|
|
rate_ctr_inc(&msc->msc_ctrs->ctr[MSC_CTR_BSSMAP_TX_DTAP]);
|
2018-08-27 23:03:27 +00:00
|
|
|
LOGP(DMSC, LOGL_INFO, "Tx MSC: DTAP\n");
|
2017-10-23 09:36:50 +00:00
|
|
|
break;
|
|
|
|
default:
|
2020-05-09 18:27:40 +00:00
|
|
|
rate_ctr_inc(&msc->msc_ctrs->ctr[MSC_CTR_BSSMAP_TX_UNKNOWN]);
|
2018-08-27 23:03:27 +00:00
|
|
|
LOGP(DMSC, LOGL_ERROR, "Tx MSC: unknown message type: 0x%x\n",
|
|
|
|
msg->data[0]);
|
2017-10-23 09:36:50 +00:00
|
|
|
}
|
2020-05-09 18:27:40 +00:00
|
|
|
} else {
|
|
|
|
rate_ctr_inc(&msc->msc_ctrs->ctr[MSC_CTR_BSSMAP_TX_SHORT]);
|
2018-08-27 23:03:27 +00:00
|
|
|
LOGP(DMSC, LOGL_ERROR, "Tx MSC: message too short: %u\n", msg->len);
|
2020-05-09 18:27:40 +00:00
|
|
|
}
|
2017-10-23 09:36:50 +00:00
|
|
|
|
2018-08-07 09:31:51 +00:00
|
|
|
if (a_reset_conn_ready(msc) == false) {
|
2020-05-09 18:27:40 +00:00
|
|
|
rate_ctr_inc(&msc->msc_ctrs->ctr[MSC_CTR_BSSMAP_TX_ERR_CONN_NOT_READY]);
|
2017-04-09 10:32:51 +00:00
|
|
|
LOGP(DMSC, LOGL_ERROR, "MSC is not connected. Dropping.\n");
|
2018-08-07 10:06:05 +00:00
|
|
|
msgb_free(msg);
|
2017-04-09 10:32:51 +00:00
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
2018-01-28 01:45:46 +00:00
|
|
|
conn_id = conn->sccp.conn_id;
|
2017-04-09 10:32:51 +00:00
|
|
|
|
|
|
|
ss7 = osmo_ss7_instance_find(msc->a.cs7_instance);
|
|
|
|
OSMO_ASSERT(ss7);
|
2017-10-23 09:51:14 +00:00
|
|
|
LOGP(DMSC, LOGL_DEBUG, "Sending connection (id=%i) oriented data to MSC: %s (%s)\n",
|
|
|
|
conn_id, osmo_sccp_addr_name(ss7, &msc->a.msc_addr), osmo_hexdump(msg->data, msg->len));
|
2017-04-09 10:32:51 +00:00
|
|
|
|
|
|
|
rc = osmo_sccp_tx_data_msg(msc->a.sccp_user, conn_id, msg);
|
2020-05-09 18:27:40 +00:00
|
|
|
if (rc >= 0)
|
|
|
|
rate_ctr_inc(&msc->msc_ctrs->ctr[MSC_CTR_BSSMAP_TX_SUCCESS]);
|
|
|
|
else
|
|
|
|
rate_ctr_inc(&msc->msc_ctrs->ctr[MSC_CTR_BSSMAP_TX_ERR_SEND]);
|
2017-04-09 10:32:51 +00:00
|
|
|
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Close all open sigtran connections and channels */
|
|
|
|
void osmo_bsc_sigtran_reset(const struct bsc_msc_data *msc)
|
|
|
|
{
|
2018-01-28 01:45:46 +00:00
|
|
|
struct gsm_subscriber_connection *conn, *conn_temp;
|
2017-04-09 10:32:51 +00:00
|
|
|
OSMO_ASSERT(msc);
|
|
|
|
|
|
|
|
/* Close all open connections */
|
2018-01-28 01:45:46 +00:00
|
|
|
llist_for_each_entry_safe(conn, conn_temp, &bsc_gsmnet->subscr_conns, entry) {
|
2017-04-09 10:32:51 +00:00
|
|
|
|
|
|
|
/* We only may close connections which actually belong to this
|
|
|
|
* MSC. All other open connections are left untouched */
|
2018-01-28 01:45:46 +00:00
|
|
|
if (conn->sccp.msc == msc) {
|
2017-04-09 10:32:51 +00:00
|
|
|
/* Take down all occopied RF channels */
|
|
|
|
/* Disconnect all Sigtran connections */
|
|
|
|
/* Delete subscriber connection */
|
introduce an osmo_fsm for gsm_subscriber_connection
In the current implementation of osmo-bsc, the subscriber connection is
not handled (very) statefully. However, there is some state keeping in the
code that handles the mgcp connection, but there are still to much loose ends
which allow odd situations to happen, which then lead severe error situations
(see also closes tags at the end) This commit adds a number of improvements
to fix those problems.
- Use an osmo-fsm to control the gsm_subscriber_connection state and
make sure that certain operations can only take place at certain states
(e.g let connection oriented SCCP traffic only pass when an SCCP connection
actually exists.
Remove the old osmo_bsc_mgcp.c code. Use the recently developed MGCP client
FSM to handle the MGCP connections.
Also make sure that stuff that already works does not break. This in
particular refers to the internal handover capability and the respective
unit-tests.
See also OS#2823, OS#2768 and OS#2898
- Fix logic to permit assignment to a signalling channel. (OS#2762)
- Introduce T993210 to release lchan + subscr_conn if MSC fails to respond
The GSM specs don't have an explicit timer for this, so let's introdcue
a custom timer (hence starting with 99).
This timeout catches the following situation:
* we send a SCCP CR with COMPL_L3_INFO from the MS to the MSC,
* the MSC doesn't respond (e.g. SCCP routing failure, program down, ...)
The MS is supposed to timeout with T3210, 3220 or 3230. But the BSC
shouldn't trust the MS but have some timer on its own.
SCCP would have a timer T(conn est), but that one is specified to be
1-2min and hence rather long.
See also: OS#2775
- Terminate bsc_subscr_conn_fsm on SCCP N-DISC.ind from MSC
If the MSC is disconnecting the SCCP channel, we must terminate the FSM
which in turn will release all lchan's and other state.
This makes TC_chan_rel_hard_rlsd pass, see also OS#2731
As a side-effect, this fixes TC_chan_act_ack_est_ind_refused(),
where the MSC is answering with CREF to our CR/COMPL_L3.
- Release subscriber connection on RLL RELEASE IND of SAPI0 on main DCCH
The subscriber connection isn't really useful for anything after the
SAPI0 main signalling link has been released. We could try to
re-establish, but our best option is probably simply releasing the
subscriber_conn and anything related to it.
This will make TC_chan_rel_rll_rel_ind pass, see also OS#2730
This commit has been tested using the BSC_Tests TTCN3 testsuit and the
following tests were passed:
TC_chan_act_noreply
TC_chan_act_ack_noest
TC_chan_act_ack_est_ind_noreply
TC_chan_act_ack_est_ind_refused
TC_chan_act_nack
TC_chan_exhaustion
TC_ctrl
TC_chan_rel_conn_fail
TC_chan_rel_hard_clear
TC_chan_rel_hard_rlsd
TC_chan_rel_a_reset
TC_rll_est_ind_inact_lchan
TC_rll_est_ind_inval_sapi1
TC_rll_est_ind_inval_sapi3
TC_rll_est_ind_inval_sacch
TC_assignment_cic_only
TC_assignment_csd
TC_assignment_ctm
TC_assignment_fr_a5_0
TC_assignment_fr_a5_1_codec_missing
TC_assignment_fr_a5_1
TC_assignment_fr_a5_3
TC_assignment_fr_a5_4
TC_paging_imsi_nochan
TC_paging_tmsi_nochan
TC_paging_tmsi_any
TC_paging_tmsi_sdcch
TC_paging_tmsi_tch_f
TC_paging_tmsi_tch_hf
TC_paging_imsi_nochan_cgi
TC_paging_imsi_nochan_lac_ci
TC_paging_imsi_nochan_ci
TC_paging_imsi_nochan_lai
TC_paging_imsi_nochan_lac
TC_paging_imsi_nochan_all
TC_paging_imsi_nochan_plmn_lac_rnc
TC_paging_imsi_nochan_rnc
TC_paging_imsi_nochan_lac_rnc
TC_paging_imsi_nochan_lacs
TC_paging_imsi_nochan_lacs_empty
TC_paging_imsi_a_reset
TC_paging_counter
TC_rsl_drop_counter
TC_classmark
TC_unsol_ass_fail
TC_unsol_ass_compl
TC_unsol_ho_fail
TC_err_82_short_msg
TC_ho_int
Authors:
Harald Welte <laforge@gnumonks.org>
Philipp Maier <pmaier@sysmocom.de>
Neels Hofmeyr <neels@hofmeyr.de>
Closes: OS#2730
Closes: OS#2731
Closes: OS#2762
Closes: OS#2768
Closes: OS#2775
Closes: OS#2823
Closes: OS#2898
Closes: OS#2936
Change-Id: I68286d26e2014048b054f39ef29c35fef420cc97
2018-01-28 02:04:16 +00:00
|
|
|
osmo_fsm_inst_term(conn->fi, OSMO_FSM_TERM_REQUEST, NULL);
|
2017-04-09 10:32:51 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Callback function: Close all open connections */
|
|
|
|
static void osmo_bsc_sigtran_reset_cb(const void *priv)
|
|
|
|
{
|
|
|
|
struct bsc_msc_data *msc = (struct bsc_msc_data*) priv;
|
|
|
|
|
|
|
|
/* Shut down all ongoing traffic */
|
|
|
|
osmo_bsc_sigtran_reset(msc);
|
|
|
|
|
|
|
|
/* Send reset to MSC */
|
|
|
|
osmo_bsc_sigtran_tx_reset(msc);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Default point-code to be used as local address (BSC) */
|
|
|
|
#define BSC_DEFAULT_PC "0.23.3"
|
|
|
|
|
|
|
|
/* Default point-code to be used as remote address (MSC) */
|
|
|
|
#define MSC_DEFAULT_PC "0.23.1"
|
|
|
|
|
2018-06-08 18:33:22 +00:00
|
|
|
static int asp_rx_unknown(struct osmo_ss7_asp *asp, int ppid_mux, struct msgb *msg);
|
|
|
|
|
2019-11-13 21:10:41 +00:00
|
|
|
/* Initialize osmo sigtran backhaul */
|
2017-04-09 10:32:51 +00:00
|
|
|
int osmo_bsc_sigtran_init(struct llist_head *mscs)
|
|
|
|
{
|
|
|
|
struct bsc_msc_data *msc;
|
|
|
|
uint32_t default_pc;
|
create ASP+AS only once per cs7 instance
Refactor osmo_bsc_sigtran_init(): invoke osmo_sccp_simple_client_on_ss7_id()
exactly once per cs7 instance.
When introducing MSC pooling to the ttcn3-bsc-tests, it became apparent that
osmo-bsc rapidly huts down and re-creates the SCTP link for each configured
MSC. This manifested in an osmo-stp crash (fixed in libosmo-sccp
I9b3ae6dfcf6efeabb7fb6c33503d1d7924fec2fa). I first tried to fix it by only
restarting an ASP when it wasn't found in the AS yet, but that created obscure
problems described in OS#4635 which in turn completely broke ttcn3-msc-tests.
This solution keeps osmo_sccp_simple_client_on_ss7_id() unchanged and instead
invokes it exactly once per cs7 instance.
Keep the same auto-config logic, but change and improve the mechanisms to
achieve it:
Replace the fail_on_next_invalid_cfg flag with a more accurate check against
remote PC collisions between configured MSCs. Before this patch, the code made
sure that at most one MSC lacks an explicit remote address (and cs7 instance),
so that no two MSCs get the same default remote PC. This patch more accurately
checks that no two MSCs use the same remote PC on the same cs7 instance,
period, whether implicitly or explicitly configured.
Before this patch, the logic amounted to creating cs7 instance 0 implicitly,
but it was not very obvious: If an 'msc' has an msc-addr configured, it is
associated with the cs7 instance that has this addr in its address book. If it
has no msc-addr configured, then msc->a.cs7_instance_valid == false. In that
case, msc->a.cs7_instance is still 0 (from talloc_zero) and hence
osmo_sccp_simple_client_on_ss7_id(ss7_id = 0) created cs7 instance 0. In this
patch, that logic remains unchanged, but is written out more explicitly: if any
msc has no cs7 instance associated, make sure to create cs7 instance 0
beforehand.
Then iterate all osmo_ss7_instances. If at least one MSC uses it, set up the
SCCP client on it and connect all MSCs as appropriate.
Related: OS#4625 OS#4635
Change-Id: I16f4f7f447f69525a2f57c4649ab295112904d6a
2020-06-25 00:40:47 +00:00
|
|
|
struct osmo_ss7_instance *inst;
|
|
|
|
int create_instance_0_for_msc_nr = -1;
|
2017-04-09 10:32:51 +00:00
|
|
|
|
2018-06-08 18:33:22 +00:00
|
|
|
osmo_ss7_register_rx_unknown_cb(&asp_rx_unknown);
|
|
|
|
|
2017-04-09 10:32:51 +00:00
|
|
|
OSMO_ASSERT(mscs);
|
|
|
|
msc_list = mscs;
|
|
|
|
|
create ASP+AS only once per cs7 instance
Refactor osmo_bsc_sigtran_init(): invoke osmo_sccp_simple_client_on_ss7_id()
exactly once per cs7 instance.
When introducing MSC pooling to the ttcn3-bsc-tests, it became apparent that
osmo-bsc rapidly huts down and re-creates the SCTP link for each configured
MSC. This manifested in an osmo-stp crash (fixed in libosmo-sccp
I9b3ae6dfcf6efeabb7fb6c33503d1d7924fec2fa). I first tried to fix it by only
restarting an ASP when it wasn't found in the AS yet, but that created obscure
problems described in OS#4635 which in turn completely broke ttcn3-msc-tests.
This solution keeps osmo_sccp_simple_client_on_ss7_id() unchanged and instead
invokes it exactly once per cs7 instance.
Keep the same auto-config logic, but change and improve the mechanisms to
achieve it:
Replace the fail_on_next_invalid_cfg flag with a more accurate check against
remote PC collisions between configured MSCs. Before this patch, the code made
sure that at most one MSC lacks an explicit remote address (and cs7 instance),
so that no two MSCs get the same default remote PC. This patch more accurately
checks that no two MSCs use the same remote PC on the same cs7 instance,
period, whether implicitly or explicitly configured.
Before this patch, the logic amounted to creating cs7 instance 0 implicitly,
but it was not very obvious: If an 'msc' has an msc-addr configured, it is
associated with the cs7 instance that has this addr in its address book. If it
has no msc-addr configured, then msc->a.cs7_instance_valid == false. In that
case, msc->a.cs7_instance is still 0 (from talloc_zero) and hence
osmo_sccp_simple_client_on_ss7_id(ss7_id = 0) created cs7 instance 0. In this
patch, that logic remains unchanged, but is written out more explicitly: if any
msc has no cs7 instance associated, make sure to create cs7 instance 0
beforehand.
Then iterate all osmo_ss7_instances. If at least one MSC uses it, set up the
SCCP client on it and connect all MSCs as appropriate.
Related: OS#4625 OS#4635
Change-Id: I16f4f7f447f69525a2f57c4649ab295112904d6a
2020-06-25 00:40:47 +00:00
|
|
|
/* Guard against multiple MSCs with identical config */
|
2017-04-09 10:32:51 +00:00
|
|
|
llist_for_each_entry(msc, msc_list, entry) {
|
create ASP+AS only once per cs7 instance
Refactor osmo_bsc_sigtran_init(): invoke osmo_sccp_simple_client_on_ss7_id()
exactly once per cs7 instance.
When introducing MSC pooling to the ttcn3-bsc-tests, it became apparent that
osmo-bsc rapidly huts down and re-creates the SCTP link for each configured
MSC. This manifested in an osmo-stp crash (fixed in libosmo-sccp
I9b3ae6dfcf6efeabb7fb6c33503d1d7924fec2fa). I first tried to fix it by only
restarting an ASP when it wasn't found in the AS yet, but that created obscure
problems described in OS#4635 which in turn completely broke ttcn3-msc-tests.
This solution keeps osmo_sccp_simple_client_on_ss7_id() unchanged and instead
invokes it exactly once per cs7 instance.
Keep the same auto-config logic, but change and improve the mechanisms to
achieve it:
Replace the fail_on_next_invalid_cfg flag with a more accurate check against
remote PC collisions between configured MSCs. Before this patch, the code made
sure that at most one MSC lacks an explicit remote address (and cs7 instance),
so that no two MSCs get the same default remote PC. This patch more accurately
checks that no two MSCs use the same remote PC on the same cs7 instance,
period, whether implicitly or explicitly configured.
Before this patch, the logic amounted to creating cs7 instance 0 implicitly,
but it was not very obvious: If an 'msc' has an msc-addr configured, it is
associated with the cs7 instance that has this addr in its address book. If it
has no msc-addr configured, then msc->a.cs7_instance_valid == false. In that
case, msc->a.cs7_instance is still 0 (from talloc_zero) and hence
osmo_sccp_simple_client_on_ss7_id(ss7_id = 0) created cs7 instance 0. In this
patch, that logic remains unchanged, but is written out more explicitly: if any
msc has no cs7 instance associated, make sure to create cs7 instance 0
beforehand.
Then iterate all osmo_ss7_instances. If at least one MSC uses it, set up the
SCCP client on it and connect all MSCs as appropriate.
Related: OS#4625 OS#4635
Change-Id: I16f4f7f447f69525a2f57c4649ab295112904d6a
2020-06-25 00:40:47 +00:00
|
|
|
struct bsc_msc_data *msc2;
|
2017-04-09 10:32:51 +00:00
|
|
|
|
create ASP+AS only once per cs7 instance
Refactor osmo_bsc_sigtran_init(): invoke osmo_sccp_simple_client_on_ss7_id()
exactly once per cs7 instance.
When introducing MSC pooling to the ttcn3-bsc-tests, it became apparent that
osmo-bsc rapidly huts down and re-creates the SCTP link for each configured
MSC. This manifested in an osmo-stp crash (fixed in libosmo-sccp
I9b3ae6dfcf6efeabb7fb6c33503d1d7924fec2fa). I first tried to fix it by only
restarting an ASP when it wasn't found in the AS yet, but that created obscure
problems described in OS#4635 which in turn completely broke ttcn3-msc-tests.
This solution keeps osmo_sccp_simple_client_on_ss7_id() unchanged and instead
invokes it exactly once per cs7 instance.
Keep the same auto-config logic, but change and improve the mechanisms to
achieve it:
Replace the fail_on_next_invalid_cfg flag with a more accurate check against
remote PC collisions between configured MSCs. Before this patch, the code made
sure that at most one MSC lacks an explicit remote address (and cs7 instance),
so that no two MSCs get the same default remote PC. This patch more accurately
checks that no two MSCs use the same remote PC on the same cs7 instance,
period, whether implicitly or explicitly configured.
Before this patch, the logic amounted to creating cs7 instance 0 implicitly,
but it was not very obvious: If an 'msc' has an msc-addr configured, it is
associated with the cs7 instance that has this addr in its address book. If it
has no msc-addr configured, then msc->a.cs7_instance_valid == false. In that
case, msc->a.cs7_instance is still 0 (from talloc_zero) and hence
osmo_sccp_simple_client_on_ss7_id(ss7_id = 0) created cs7 instance 0. In this
patch, that logic remains unchanged, but is written out more explicitly: if any
msc has no cs7 instance associated, make sure to create cs7 instance 0
beforehand.
Then iterate all osmo_ss7_instances. If at least one MSC uses it, set up the
SCCP client on it and connect all MSCs as appropriate.
Related: OS#4625 OS#4635
Change-Id: I16f4f7f447f69525a2f57c4649ab295112904d6a
2020-06-25 00:40:47 +00:00
|
|
|
/* An MSC with invalid cs7 instance defaults to cs7 instance 0 */
|
|
|
|
uint32_t msc_inst = (msc->a.cs7_instance_valid ? msc->a.cs7_instance : 0);
|
2017-04-09 10:32:51 +00:00
|
|
|
|
create ASP+AS only once per cs7 instance
Refactor osmo_bsc_sigtran_init(): invoke osmo_sccp_simple_client_on_ss7_id()
exactly once per cs7 instance.
When introducing MSC pooling to the ttcn3-bsc-tests, it became apparent that
osmo-bsc rapidly huts down and re-creates the SCTP link for each configured
MSC. This manifested in an osmo-stp crash (fixed in libosmo-sccp
I9b3ae6dfcf6efeabb7fb6c33503d1d7924fec2fa). I first tried to fix it by only
restarting an ASP when it wasn't found in the AS yet, but that created obscure
problems described in OS#4635 which in turn completely broke ttcn3-msc-tests.
This solution keeps osmo_sccp_simple_client_on_ss7_id() unchanged and instead
invokes it exactly once per cs7 instance.
Keep the same auto-config logic, but change and improve the mechanisms to
achieve it:
Replace the fail_on_next_invalid_cfg flag with a more accurate check against
remote PC collisions between configured MSCs. Before this patch, the code made
sure that at most one MSC lacks an explicit remote address (and cs7 instance),
so that no two MSCs get the same default remote PC. This patch more accurately
checks that no two MSCs use the same remote PC on the same cs7 instance,
period, whether implicitly or explicitly configured.
Before this patch, the logic amounted to creating cs7 instance 0 implicitly,
but it was not very obvious: If an 'msc' has an msc-addr configured, it is
associated with the cs7 instance that has this addr in its address book. If it
has no msc-addr configured, then msc->a.cs7_instance_valid == false. In that
case, msc->a.cs7_instance is still 0 (from talloc_zero) and hence
osmo_sccp_simple_client_on_ss7_id(ss7_id = 0) created cs7 instance 0. In this
patch, that logic remains unchanged, but is written out more explicitly: if any
msc has no cs7 instance associated, make sure to create cs7 instance 0
beforehand.
Then iterate all osmo_ss7_instances. If at least one MSC uses it, set up the
SCCP client on it and connect all MSCs as appropriate.
Related: OS#4625 OS#4635
Change-Id: I16f4f7f447f69525a2f57c4649ab295112904d6a
2020-06-25 00:40:47 +00:00
|
|
|
if (!msc->a.cs7_instance_valid)
|
|
|
|
create_instance_0_for_msc_nr = msc->nr;
|
2017-04-09 10:32:51 +00:00
|
|
|
|
osmo-bsc: SCCP addrs: default only if unset, reject invalid
So far, if the user entered an invalid SCCP address in the config, the
osmo_bsc_sigtran_init() code simply replaced that with the default, i.e.
running with a completely different address than the user may intend.
Use the default SCCP addresses only when they are unset by the user.
Default MSC addr: set directly, do not detour via cs7 instance PC. The default
MSC SCCP addr is just a point code + SSN, deriving it from the cs7 instance
first is a confusing step. Just set the PC and SSN, and done.
Using default addresses does not constitute an "auto configuration": if we set
up a cs7 instance automatically, we do not want to have to create a second one
automatically, to prevent "auto-confusion", and want to bail instead. But for
each MSC on its own, using default SCCP addresses makes sense and is orthogonal
to automatic cs7 instance creation. Hence drop the auto config semantics from
the default SCCP address parts.
Always validate the SCCP addresses we will end up using, and bail immediately
if they are erratic. i.e. don't overwrite a non-empty invalid SCCP address with
defaults, but straight bail.
Beneficial side effects:
- Fix some grammar ultra confusion in log messages.
- Add context: log the MSC number the logging refers to.
- Drop code dup: since we're always logging the used SCCP addresses, might as
well log those once, unconditionally, in the end.
Change-Id: Iadbc2e9740457e1b389b7e7ad9c94274e7d8cb11
2017-11-08 00:03:07 +00:00
|
|
|
/* If unset, use default SCCP address for the MSC */
|
|
|
|
if (!msc->a.msc_addr.presence)
|
|
|
|
osmo_sccp_make_addr_pc_ssn(&msc->a.msc_addr,
|
|
|
|
osmo_ss7_pointcode_parse(NULL, MSC_DEFAULT_PC),
|
2017-12-18 16:57:35 +00:00
|
|
|
OSMO_SCCP_SSN_BSSAP);
|
2017-04-09 10:32:51 +00:00
|
|
|
|
create ASP+AS only once per cs7 instance
Refactor osmo_bsc_sigtran_init(): invoke osmo_sccp_simple_client_on_ss7_id()
exactly once per cs7 instance.
When introducing MSC pooling to the ttcn3-bsc-tests, it became apparent that
osmo-bsc rapidly huts down and re-creates the SCTP link for each configured
MSC. This manifested in an osmo-stp crash (fixed in libosmo-sccp
I9b3ae6dfcf6efeabb7fb6c33503d1d7924fec2fa). I first tried to fix it by only
restarting an ASP when it wasn't found in the AS yet, but that created obscure
problems described in OS#4635 which in turn completely broke ttcn3-msc-tests.
This solution keeps osmo_sccp_simple_client_on_ss7_id() unchanged and instead
invokes it exactly once per cs7 instance.
Keep the same auto-config logic, but change and improve the mechanisms to
achieve it:
Replace the fail_on_next_invalid_cfg flag with a more accurate check against
remote PC collisions between configured MSCs. Before this patch, the code made
sure that at most one MSC lacks an explicit remote address (and cs7 instance),
so that no two MSCs get the same default remote PC. This patch more accurately
checks that no two MSCs use the same remote PC on the same cs7 instance,
period, whether implicitly or explicitly configured.
Before this patch, the logic amounted to creating cs7 instance 0 implicitly,
but it was not very obvious: If an 'msc' has an msc-addr configured, it is
associated with the cs7 instance that has this addr in its address book. If it
has no msc-addr configured, then msc->a.cs7_instance_valid == false. In that
case, msc->a.cs7_instance is still 0 (from talloc_zero) and hence
osmo_sccp_simple_client_on_ss7_id(ss7_id = 0) created cs7 instance 0. In this
patch, that logic remains unchanged, but is written out more explicitly: if any
msc has no cs7 instance associated, make sure to create cs7 instance 0
beforehand.
Then iterate all osmo_ss7_instances. If at least one MSC uses it, set up the
SCCP client on it and connect all MSCs as appropriate.
Related: OS#4625 OS#4635
Change-Id: I16f4f7f447f69525a2f57c4649ab295112904d6a
2020-06-25 00:40:47 +00:00
|
|
|
/* (more optimally, we'd only iterate the remaining other mscs after this msc, but this happens only
|
|
|
|
* during startup, so nevermind that complexity and rather check each pair twice. That also ensures to
|
|
|
|
* compare all MSCs that have no explicit msc_addr set, see osmo_sccp_make_addr_pc_ssn() above.) */
|
|
|
|
llist_for_each_entry(msc2, msc_list, entry) {
|
|
|
|
uint32_t msc2_inst;
|
|
|
|
|
|
|
|
if (msc2 == msc)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
msc2_inst = (msc2->a.cs7_instance_valid ? msc2->a.cs7_instance : 0);
|
|
|
|
if (msc_inst != msc2_inst)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (osmo_sccp_addr_cmp(&msc->a.msc_addr, &msc2->a.msc_addr, OSMO_SCCP_ADDR_T_PC) == 0) {
|
|
|
|
LOGP(DMSC, LOGL_ERROR, "'msc %d' and 'msc %d' cannot use the same remote PC"
|
|
|
|
" %s on the same cs7 instance %u\n",
|
|
|
|
msc->nr, msc2->nr, osmo_sccp_addr_dump(&msc->a.msc_addr), msc_inst);
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (create_instance_0_for_msc_nr >= 0 && !osmo_ss7_instance_find(0)) {
|
|
|
|
LOGP(DMSC, LOGL_NOTICE, "To auto-configure msc %d, creating cs7 instance 0 implicitly\n",
|
|
|
|
create_instance_0_for_msc_nr);
|
|
|
|
OSMO_ASSERT(osmo_ss7_instance_find_or_create(tall_bsc_ctx, 0));
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Set up exactly one SCCP user and one ASP+AS per cs7 instance.
|
|
|
|
* Iterate cs7 instance indexes and see for each one whether an MSC is configured for it.
|
|
|
|
* The 'msc' / 'msc-addr' command selects the cs7 instance used for an MSC.
|
|
|
|
*/
|
|
|
|
llist_for_each_entry(inst, &osmo_ss7_instances, list) {
|
|
|
|
char inst_name[32];
|
|
|
|
enum osmo_ss7_asp_protocol used_proto = OSMO_SS7_ASP_PROT_NONE;
|
|
|
|
int prev_msc_nr;
|
|
|
|
|
|
|
|
struct osmo_sccp_instance *sccp;
|
|
|
|
|
|
|
|
llist_for_each_entry(msc, msc_list, entry) {
|
|
|
|
/* An MSC with invalid cs7 instance id defaults to cs7 instance 0 */
|
|
|
|
if ((inst->cfg.id != msc->a.cs7_instance)
|
|
|
|
&& !(inst->cfg.id == 0 && !msc->a.cs7_instance_valid))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
/* This msc runs on this cs7 inst. Check the asp_proto. */
|
|
|
|
if (used_proto != OSMO_SS7_ASP_PROT_NONE
|
|
|
|
&& used_proto != msc->a.asp_proto) {
|
|
|
|
LOGP(DMSC, LOGL_ERROR, "'msc %d' and 'msc %d' with differing ASP protocols"
|
|
|
|
" %s and %s cannot use the same cs7 instance %u\n",
|
|
|
|
prev_msc_nr, msc->nr,
|
|
|
|
osmo_ss7_asp_protocol_name(used_proto),
|
|
|
|
osmo_ss7_asp_protocol_name(msc->a.asp_proto),
|
|
|
|
inst->cfg.id);
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
used_proto = msc->a.asp_proto;
|
|
|
|
prev_msc_nr = msc->nr;
|
|
|
|
/* still run through the other MSCs to catch asp_proto mismatches */
|
|
|
|
}
|
|
|
|
|
|
|
|
if (used_proto == OSMO_SS7_ASP_PROT_NONE) {
|
|
|
|
/* This instance has no MSC associated with it */
|
|
|
|
LOGP(DMSC, LOGL_ERROR, "cs7 instance %u has no MSCs configured to run on it\n", inst->cfg.id);
|
|
|
|
continue;
|
2017-04-09 10:32:51 +00:00
|
|
|
}
|
|
|
|
|
create ASP+AS only once per cs7 instance
Refactor osmo_bsc_sigtran_init(): invoke osmo_sccp_simple_client_on_ss7_id()
exactly once per cs7 instance.
When introducing MSC pooling to the ttcn3-bsc-tests, it became apparent that
osmo-bsc rapidly huts down and re-creates the SCTP link for each configured
MSC. This manifested in an osmo-stp crash (fixed in libosmo-sccp
I9b3ae6dfcf6efeabb7fb6c33503d1d7924fec2fa). I first tried to fix it by only
restarting an ASP when it wasn't found in the AS yet, but that created obscure
problems described in OS#4635 which in turn completely broke ttcn3-msc-tests.
This solution keeps osmo_sccp_simple_client_on_ss7_id() unchanged and instead
invokes it exactly once per cs7 instance.
Keep the same auto-config logic, but change and improve the mechanisms to
achieve it:
Replace the fail_on_next_invalid_cfg flag with a more accurate check against
remote PC collisions between configured MSCs. Before this patch, the code made
sure that at most one MSC lacks an explicit remote address (and cs7 instance),
so that no two MSCs get the same default remote PC. This patch more accurately
checks that no two MSCs use the same remote PC on the same cs7 instance,
period, whether implicitly or explicitly configured.
Before this patch, the logic amounted to creating cs7 instance 0 implicitly,
but it was not very obvious: If an 'msc' has an msc-addr configured, it is
associated with the cs7 instance that has this addr in its address book. If it
has no msc-addr configured, then msc->a.cs7_instance_valid == false. In that
case, msc->a.cs7_instance is still 0 (from talloc_zero) and hence
osmo_sccp_simple_client_on_ss7_id(ss7_id = 0) created cs7 instance 0. In this
patch, that logic remains unchanged, but is written out more explicitly: if any
msc has no cs7 instance associated, make sure to create cs7 instance 0
beforehand.
Then iterate all osmo_ss7_instances. If at least one MSC uses it, set up the
SCCP client on it and connect all MSCs as appropriate.
Related: OS#4625 OS#4635
Change-Id: I16f4f7f447f69525a2f57c4649ab295112904d6a
2020-06-25 00:40:47 +00:00
|
|
|
snprintf(inst_name, sizeof(inst_name), "A-%u-%s", inst->cfg.id, osmo_ss7_asp_protocol_name(used_proto));
|
|
|
|
LOGP(DMSC, LOGL_NOTICE, "Initializing SCCP connection for A/%s on cs7 instance %u\n",
|
|
|
|
osmo_ss7_asp_protocol_name(used_proto), inst->cfg.id);
|
|
|
|
|
|
|
|
/* SS7 Protocol stack */
|
|
|
|
default_pc = osmo_ss7_pointcode_parse(NULL, BSC_DEFAULT_PC);
|
2020-08-20 10:32:54 +00:00
|
|
|
sccp = osmo_sccp_simple_client_on_ss7_id(tall_bsc_ctx, inst->cfg.id, inst_name,
|
|
|
|
default_pc, used_proto,
|
|
|
|
0, DEFAULT_ASP_LOCAL_IP,
|
create ASP+AS only once per cs7 instance
Refactor osmo_bsc_sigtran_init(): invoke osmo_sccp_simple_client_on_ss7_id()
exactly once per cs7 instance.
When introducing MSC pooling to the ttcn3-bsc-tests, it became apparent that
osmo-bsc rapidly huts down and re-creates the SCTP link for each configured
MSC. This manifested in an osmo-stp crash (fixed in libosmo-sccp
I9b3ae6dfcf6efeabb7fb6c33503d1d7924fec2fa). I first tried to fix it by only
restarting an ASP when it wasn't found in the AS yet, but that created obscure
problems described in OS#4635 which in turn completely broke ttcn3-msc-tests.
This solution keeps osmo_sccp_simple_client_on_ss7_id() unchanged and instead
invokes it exactly once per cs7 instance.
Keep the same auto-config logic, but change and improve the mechanisms to
achieve it:
Replace the fail_on_next_invalid_cfg flag with a more accurate check against
remote PC collisions between configured MSCs. Before this patch, the code made
sure that at most one MSC lacks an explicit remote address (and cs7 instance),
so that no two MSCs get the same default remote PC. This patch more accurately
checks that no two MSCs use the same remote PC on the same cs7 instance,
period, whether implicitly or explicitly configured.
Before this patch, the logic amounted to creating cs7 instance 0 implicitly,
but it was not very obvious: If an 'msc' has an msc-addr configured, it is
associated with the cs7 instance that has this addr in its address book. If it
has no msc-addr configured, then msc->a.cs7_instance_valid == false. In that
case, msc->a.cs7_instance is still 0 (from talloc_zero) and hence
osmo_sccp_simple_client_on_ss7_id(ss7_id = 0) created cs7 instance 0. In this
patch, that logic remains unchanged, but is written out more explicitly: if any
msc has no cs7 instance associated, make sure to create cs7 instance 0
beforehand.
Then iterate all osmo_ss7_instances. If at least one MSC uses it, set up the
SCCP client on it and connect all MSCs as appropriate.
Related: OS#4625 OS#4635
Change-Id: I16f4f7f447f69525a2f57c4649ab295112904d6a
2020-06-25 00:40:47 +00:00
|
|
|
0, DEFAULT_ASP_REMOTE_IP);
|
|
|
|
if (!sccp)
|
2017-04-09 10:32:51 +00:00
|
|
|
return -EINVAL;
|
|
|
|
|
create ASP+AS only once per cs7 instance
Refactor osmo_bsc_sigtran_init(): invoke osmo_sccp_simple_client_on_ss7_id()
exactly once per cs7 instance.
When introducing MSC pooling to the ttcn3-bsc-tests, it became apparent that
osmo-bsc rapidly huts down and re-creates the SCTP link for each configured
MSC. This manifested in an osmo-stp crash (fixed in libosmo-sccp
I9b3ae6dfcf6efeabb7fb6c33503d1d7924fec2fa). I first tried to fix it by only
restarting an ASP when it wasn't found in the AS yet, but that created obscure
problems described in OS#4635 which in turn completely broke ttcn3-msc-tests.
This solution keeps osmo_sccp_simple_client_on_ss7_id() unchanged and instead
invokes it exactly once per cs7 instance.
Keep the same auto-config logic, but change and improve the mechanisms to
achieve it:
Replace the fail_on_next_invalid_cfg flag with a more accurate check against
remote PC collisions between configured MSCs. Before this patch, the code made
sure that at most one MSC lacks an explicit remote address (and cs7 instance),
so that no two MSCs get the same default remote PC. This patch more accurately
checks that no two MSCs use the same remote PC on the same cs7 instance,
period, whether implicitly or explicitly configured.
Before this patch, the logic amounted to creating cs7 instance 0 implicitly,
but it was not very obvious: If an 'msc' has an msc-addr configured, it is
associated with the cs7 instance that has this addr in its address book. If it
has no msc-addr configured, then msc->a.cs7_instance_valid == false. In that
case, msc->a.cs7_instance is still 0 (from talloc_zero) and hence
osmo_sccp_simple_client_on_ss7_id(ss7_id = 0) created cs7 instance 0. In this
patch, that logic remains unchanged, but is written out more explicitly: if any
msc has no cs7 instance associated, make sure to create cs7 instance 0
beforehand.
Then iterate all osmo_ss7_instances. If at least one MSC uses it, set up the
SCCP client on it and connect all MSCs as appropriate.
Related: OS#4625 OS#4635
Change-Id: I16f4f7f447f69525a2f57c4649ab295112904d6a
2020-06-25 00:40:47 +00:00
|
|
|
/* Now that the SCCP client is set up, configure all MSCs on this cs7 instance to use it */
|
|
|
|
llist_for_each_entry(msc, msc_list, entry) {
|
|
|
|
char msc_name[32];
|
|
|
|
|
|
|
|
/* Skip MSCs that don't run on this cs7 instance */
|
|
|
|
if ((inst->cfg.id != msc->a.cs7_instance)
|
|
|
|
&& !(inst->cfg.id == 0 && !msc->a.cs7_instance_valid))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
snprintf(msc_name, sizeof(msc_name), "msc-%d", msc->nr);
|
|
|
|
|
|
|
|
msc->a.sccp = sccp;
|
|
|
|
|
|
|
|
/* In SCCPlite, the MSC side of the MGW endpoint is configured by the MSC. Since we have
|
|
|
|
* no way to figure out which CallID ('C:') the MSC will issue in its CRCX command, set
|
|
|
|
* an X-Osmo-IGN flag telling osmo-mgw to ignore CallID mismatches for this endpoint.
|
|
|
|
* If an explicit VTY command has already indicated whether or not to send X-Osmo-IGN, do
|
|
|
|
* not overwrite that setting. */
|
|
|
|
if (msc_is_sccplite(msc) && !msc->x_osmo_ign_configured)
|
|
|
|
msc->x_osmo_ign |= MGCP_X_OSMO_IGN_CALLID;
|
|
|
|
|
|
|
|
/* If unset, use default local SCCP address */
|
|
|
|
if (!msc->a.bsc_addr.presence)
|
|
|
|
osmo_sccp_local_addr_by_instance(&msc->a.bsc_addr, sccp,
|
|
|
|
OSMO_SCCP_SSN_BSSAP);
|
|
|
|
|
|
|
|
if (!osmo_sccp_check_addr(&msc->a.bsc_addr, OSMO_SCCP_ADDR_T_SSN | OSMO_SCCP_ADDR_T_PC)) {
|
|
|
|
LOGP(DMSC, LOGL_ERROR,
|
|
|
|
"%s %s: invalid local (BSC) SCCP address: %s\n",
|
|
|
|
inst_name, msc_name, osmo_sccp_inst_addr_name(sccp, &msc->a.bsc_addr));
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!osmo_sccp_check_addr(&msc->a.msc_addr, OSMO_SCCP_ADDR_T_SSN | OSMO_SCCP_ADDR_T_PC)) {
|
|
|
|
LOGP(DMSC, LOGL_ERROR,
|
|
|
|
"%s %s: invalid remote (MSC) SCCP address: %s\n",
|
|
|
|
inst_name, msc_name, osmo_sccp_inst_addr_name(sccp, &msc->a.msc_addr));
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
LOGP(DMSC, LOGL_NOTICE, "%s %s: local (BSC) SCCP address: %s\n",
|
|
|
|
inst_name, msc_name, osmo_sccp_inst_addr_name(sccp, &msc->a.bsc_addr));
|
|
|
|
LOGP(DMSC, LOGL_NOTICE, "%s %s: remote (MSC) SCCP address: %s\n",
|
|
|
|
inst_name, msc_name, osmo_sccp_inst_addr_name(sccp, &msc->a.msc_addr));
|
|
|
|
|
|
|
|
/* Bind SCCP user. Bind only one user per sccp_instance and bsc_addr. */
|
|
|
|
msc->a.sccp_user = osmo_sccp_user_find(sccp, msc->a.bsc_addr.ssn, msc->a.bsc_addr.pc);
|
|
|
|
LOGP(DMSC, LOGL_NOTICE, "%s %s: %s\n", inst_name, msc_name,
|
|
|
|
msc->a.sccp_user ? "user already bound for this SCCP instance" : "binding SCCP user");
|
|
|
|
if (!msc->a.sccp_user)
|
|
|
|
msc->a.sccp_user = osmo_sccp_user_bind(sccp, msc_name, sccp_sap_up, msc->a.bsc_addr.ssn);
|
|
|
|
if (!msc->a.sccp_user)
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
/* Start MSC-Reset procedure */
|
|
|
|
a_reset_alloc(msc, msc_name, osmo_bsc_sigtran_reset_cb);
|
|
|
|
}
|
2017-04-09 10:32:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
2018-05-26 20:42:29 +00:00
|
|
|
|
|
|
|
/* this function receives all messages received on an ASP for a PPID / StreamID that
|
|
|
|
* libosmo-sigtran doesn't know about, such as piggy-backed CTRL and/or MGCP */
|
2018-06-08 18:33:22 +00:00
|
|
|
static int asp_rx_unknown(struct osmo_ss7_asp *asp, int ppid_mux, struct msgb *msg)
|
2018-05-26 20:42:29 +00:00
|
|
|
{
|
|
|
|
struct ipaccess_head *iph;
|
|
|
|
struct ipaccess_head_ext *iph_ext;
|
|
|
|
|
|
|
|
if (asp->cfg.proto != OSMO_SS7_ASP_PROT_IPA) {
|
|
|
|
msgb_free(msg);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (ppid_mux) {
|
|
|
|
case IPAC_PROTO_OSMO:
|
|
|
|
if (msg->len < sizeof(*iph) + sizeof(*iph_ext)) {
|
|
|
|
LOGP(DMSC, LOGL_ERROR, "The message is too short.\n");
|
|
|
|
msgb_free(msg);
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
iph = (struct ipaccess_head *) msg->data;
|
|
|
|
iph_ext = (struct ipaccess_head_ext *) iph->data;
|
|
|
|
msg->l2h = iph_ext->data;
|
|
|
|
switch (iph_ext->proto) {
|
|
|
|
case IPAC_PROTO_EXT_CTRL:
|
|
|
|
return bsc_sccplite_rx_ctrl(asp, msg);
|
2018-05-26 20:56:59 +00:00
|
|
|
case IPAC_PROTO_EXT_MGCP:
|
|
|
|
return bsc_sccplite_rx_mgcp(asp, msg);
|
2018-05-26 20:42:29 +00:00
|
|
|
}
|
|
|
|
break;
|
2018-05-26 20:56:59 +00:00
|
|
|
case IPAC_PROTO_MGCP_OLD:
|
|
|
|
return bsc_sccplite_rx_mgcp(asp, msg);
|
2018-05-26 20:42:29 +00:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
msgb_free(msg);
|
|
|
|
return 0; /* OSMO_SS7_UNKNOWN? */
|
|
|
|
}
|