2010-03-23 06:40:46 +00:00
|
|
|
/* GSM 08.08 like API for OpenBSC. The bridge from MSC to BSC */
|
|
|
|
|
2011-08-06 04:42:00 +00:00
|
|
|
/* (C) 2010-2011 by Holger Hans Peter Freyther
|
|
|
|
* (C) 2010-2011 by On-Waves
|
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) 2009,2017 by Harald Welte <laforge@gnumonks.org>
|
2010-03-23 06:40:46 +00:00
|
|
|
*
|
|
|
|
* All Rights Reserved
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
2011-01-01 14:25:50 +00:00
|
|
|
* it under the terms of the GNU Affero General Public License as published by
|
|
|
|
* the Free Software Foundation; either version 3 of the License, or
|
2010-03-23 06:40:46 +00:00
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
2011-01-01 14:25:50 +00:00
|
|
|
* GNU Affero General Public License for more details.
|
2010-03-23 06:40:46 +00:00
|
|
|
*
|
2011-01-01 14:25:50 +00:00
|
|
|
* You should have received a copy of the GNU Affero General Public License
|
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
2010-03-23 06:40:46 +00:00
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2017-09-04 13:15:32 +00:00
|
|
|
#include <osmocom/bsc/bsc_api.h>
|
|
|
|
#include <osmocom/bsc/bsc_rll.h>
|
|
|
|
#include <osmocom/bsc/gsm_data.h>
|
|
|
|
#include <osmocom/bsc/signal.h>
|
|
|
|
#include <osmocom/bsc/abis_rsl.h>
|
|
|
|
#include <osmocom/bsc/chan_alloc.h>
|
|
|
|
#include <osmocom/bsc/handover.h>
|
|
|
|
#include <osmocom/bsc/debug.h>
|
|
|
|
#include <osmocom/bsc/gsm_04_08_utils.h>
|
2017-12-14 02:50:26 +00:00
|
|
|
#include <osmocom/bsc/bsc_subscriber.h>
|
2018-02-12 15:45:39 +00:00
|
|
|
#include <osmocom/bsc/penalty_timers.h>
|
2018-01-28 01:45:46 +00:00
|
|
|
#include <osmocom/bsc/osmo_bsc_sigtran.h>
|
2010-03-23 06:40:46 +00:00
|
|
|
|
2011-03-22 15:47:59 +00:00
|
|
|
#include <osmocom/gsm/protocol/gsm_08_08.h>
|
2016-10-10 13:11:41 +00:00
|
|
|
#include <osmocom/gsm/gsm48.h>
|
2010-11-04 10:18:03 +00:00
|
|
|
|
2011-03-22 15:47:59 +00:00
|
|
|
#include <osmocom/core/talloc.h>
|
2010-06-14 10:20:15 +00:00
|
|
|
|
2010-11-14 15:19:48 +00:00
|
|
|
#define GSM0808_T10_VALUE 6, 0
|
|
|
|
|
2013-06-17 09:58:30 +00:00
|
|
|
#define HO_DTAP_CACHE_MSGB_CB_LINK_ID 0
|
|
|
|
#define HO_DTAP_CACHE_MSGB_CB_ALLOW_SACCH 1
|
2010-09-15 16:53:37 +00:00
|
|
|
|
2010-06-15 03:20:52 +00:00
|
|
|
static void rll_ind_cb(struct gsm_lchan *, uint8_t, void *, enum bsc_rllr_ind);
|
|
|
|
static void send_sapi_reject(struct gsm_subscriber_connection *conn, int link_id);
|
2010-11-14 18:29:42 +00:00
|
|
|
static void handle_release(struct gsm_subscriber_connection *conn, struct bsc_api *bsc, struct gsm_lchan *lchan);
|
2010-11-14 15:19:48 +00:00
|
|
|
static void handle_chan_ack(struct gsm_subscriber_connection *conn, struct bsc_api *bsc, struct gsm_lchan *lchan);
|
|
|
|
static void handle_chan_nack(struct gsm_subscriber_connection *conn, struct bsc_api *bsc, struct gsm_lchan *lchan);
|
2010-06-15 03:20:52 +00:00
|
|
|
|
2017-05-27 12:08:20 +00:00
|
|
|
/*! \brief Determine and apply AMR multi-rate configuration to lchan
|
|
|
|
* Determine which AMR multi-rate configuration to use and apply it to
|
|
|
|
* the lchan (so it can be communicated to BTS and MS during channel
|
|
|
|
* activation.
|
|
|
|
* \param[in] conn subscriber connection (used to resolve bsc_api)
|
|
|
|
* \param[out] lchan logical channel to which to apply mr config
|
|
|
|
* \param[in] full_rate whether to use full-rate (1) or half-rate (0) config
|
2011-08-06 04:42:00 +00:00
|
|
|
*/
|
|
|
|
static void handle_mr_config(struct gsm_subscriber_connection *conn,
|
2014-01-19 10:47:44 +00:00
|
|
|
struct gsm_lchan *lchan, int full_rate)
|
2011-08-06 04:42:00 +00:00
|
|
|
{
|
2011-08-06 05:00:52 +00:00
|
|
|
struct bsc_api *api;
|
2016-05-09 19:09:47 +00:00
|
|
|
api = conn->network->bsc_api;
|
2014-01-19 10:47:44 +00:00
|
|
|
struct amr_multirate_conf *mr;
|
|
|
|
struct gsm48_multi_rate_conf *mr_conf;
|
2011-08-06 05:00:52 +00:00
|
|
|
|
2017-05-27 12:08:20 +00:00
|
|
|
/* BSC api override for this method, used in OsmoBSC mode with
|
|
|
|
* bsc_mr_config() to use MSC-specific/specified configuration */
|
2011-08-06 05:00:52 +00:00
|
|
|
if (api->mr_config)
|
2015-09-24 14:26:01 +00:00
|
|
|
return api->mr_config(conn, lchan, full_rate);
|
2011-08-06 05:00:52 +00:00
|
|
|
|
2017-05-27 12:08:20 +00:00
|
|
|
/* NITB case: use the BTS-specic multi-rate configuration from
|
|
|
|
* the vty/configuration file */
|
2014-01-19 10:47:44 +00:00
|
|
|
if (full_rate)
|
|
|
|
mr = &lchan->ts->trx->bts->mr_full;
|
|
|
|
else
|
|
|
|
mr = &lchan->ts->trx->bts->mr_half;
|
|
|
|
|
|
|
|
mr_conf = (struct gsm48_multi_rate_conf *) mr->gsm48_ie;
|
|
|
|
mr_conf->ver = 1;
|
|
|
|
|
|
|
|
/* default, if no AMR codec defined */
|
|
|
|
if (!mr->gsm48_ie[1]) {
|
|
|
|
mr_conf->icmi = 1;
|
|
|
|
mr_conf->m5_90 = 1;
|
|
|
|
}
|
2017-05-27 12:08:20 +00:00
|
|
|
/* store encoded MR config IE lchan for both MS (uplink) and BTS
|
|
|
|
* (downlink) directions */
|
2015-09-24 09:30:58 +00:00
|
|
|
gsm48_multirate_config(lchan->mr_ms_lv, mr, mr->ms_mode);
|
|
|
|
gsm48_multirate_config(lchan->mr_bts_lv, mr, mr->bts_mode);
|
2011-08-06 04:42:00 +00:00
|
|
|
}
|
|
|
|
|
2010-11-14 15:19:48 +00:00
|
|
|
/*
|
|
|
|
* Start a new assignment and make sure that it is completed within T10 either
|
|
|
|
* positively, negatively or by the timeout.
|
|
|
|
*
|
|
|
|
* 1.) allocate a new lchan
|
|
|
|
* 2.) copy the encryption key and other data from the
|
|
|
|
* old to the new channel.
|
|
|
|
* 3.) RSL Channel Activate this channel and wait
|
|
|
|
*
|
|
|
|
* -> Signal handler for the LCHAN
|
|
|
|
* 4.) Send GSM 04.08 assignment command to the MS
|
|
|
|
*
|
|
|
|
* -> Assignment Complete/Assignment Failure
|
|
|
|
* 5.) Release the SDCCH, continue signalling on the new link
|
|
|
|
*/
|
|
|
|
static int handle_new_assignment(struct gsm_subscriber_connection *conn, int chan_mode, int full_rate)
|
|
|
|
{
|
|
|
|
struct gsm_lchan *new_lchan;
|
2013-06-12 06:20:36 +00:00
|
|
|
enum gsm_chan_t chan_type;
|
2010-11-14 15:19:48 +00:00
|
|
|
|
|
|
|
chan_type = full_rate ? GSM_LCHAN_TCH_F : GSM_LCHAN_TCH_H;
|
|
|
|
|
2017-12-18 17:44:25 +00:00
|
|
|
new_lchan = lchan_alloc(conn_get_bts(conn), chan_type, 0);
|
2010-11-14 15:19:48 +00:00
|
|
|
|
|
|
|
if (!new_lchan) {
|
2018-04-10 23:43:41 +00:00
|
|
|
LOGP(DMSC, LOGL_NOTICE, "%s No free channel for %s\n",
|
|
|
|
bsc_subscr_name(conn->bsub), gsm_lchant_name(chan_type));
|
2010-11-14 15:19:48 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2013-06-12 06:20:36 +00:00
|
|
|
/* check if we are on TCH/F and requested TCH/H, but got TCH/F */
|
|
|
|
if (conn->lchan->type == new_lchan->type
|
|
|
|
&& chan_type != new_lchan->type) {
|
2018-04-10 23:43:41 +00:00
|
|
|
LOGPLCHAN(conn->lchan, DHO, LOGL_NOTICE,
|
|
|
|
"-> %s Will not re-assign to identical channel type, %s was requested\n",
|
|
|
|
gsm_lchan_name(new_lchan), gsm_lchant_name(chan_type));
|
2013-06-12 06:20:36 +00:00
|
|
|
lchan_free(new_lchan);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2010-11-14 15:19:48 +00:00
|
|
|
/* copy old data to the new channel */
|
|
|
|
memcpy(&new_lchan->encr, &conn->lchan->encr, sizeof(new_lchan->encr));
|
|
|
|
new_lchan->ms_power = conn->lchan->ms_power;
|
|
|
|
new_lchan->bs_power = conn->lchan->bs_power;
|
2013-10-11 10:55:35 +00:00
|
|
|
new_lchan->rqd_ta = conn->lchan->rqd_ta;
|
2010-11-14 15:19:48 +00:00
|
|
|
|
|
|
|
/* copy new data to it */
|
|
|
|
new_lchan->tch_mode = chan_mode;
|
2013-06-12 06:26:50 +00:00
|
|
|
new_lchan->rsl_cmode = (chan_mode == GSM48_CMODE_SIGN) ?
|
|
|
|
RSL_CMOD_SPD_SIGN : RSL_CMOD_SPD_SPEECH;
|
2010-11-14 15:19:48 +00:00
|
|
|
|
|
|
|
/* handle AMR correctly */
|
2011-08-06 04:42:00 +00:00
|
|
|
if (chan_mode == GSM48_CMODE_SPEECH_AMR)
|
2014-01-19 10:47:44 +00:00
|
|
|
handle_mr_config(conn, new_lchan, full_rate);
|
2010-11-14 15:19:48 +00:00
|
|
|
|
2013-10-11 10:55:35 +00:00
|
|
|
if (rsl_chan_activate_lchan(new_lchan, 0x1, 0) < 0) {
|
2018-04-10 23:43:41 +00:00
|
|
|
LOGPLCHAN(new_lchan, DHO, LOGL_ERROR, "could not activate channel\n");
|
2010-11-14 15:19:48 +00:00
|
|
|
lchan_free(new_lchan);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* remember that we have the channel */
|
|
|
|
conn->secondary_lchan = new_lchan;
|
|
|
|
new_lchan->conn = conn;
|
|
|
|
return 0;
|
|
|
|
}
|
2010-11-04 11:06:57 +00:00
|
|
|
|
2013-06-17 09:58:30 +00:00
|
|
|
static void ho_dtap_cache_add(struct gsm_subscriber_connection *conn, struct msgb *msg,
|
|
|
|
int link_id, bool allow_sacch)
|
|
|
|
{
|
|
|
|
if (conn->ho_dtap_cache_len >= 23) {
|
|
|
|
LOGP(DHO, LOGL_ERROR, "%s: Cannot cache more DTAP messages,"
|
|
|
|
" already reached sane maximum of %u cached messages\n",
|
|
|
|
bsc_subscr_name(conn->bsub), conn->ho_dtap_cache_len);
|
|
|
|
msgb_free(msg);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
conn->ho_dtap_cache_len ++;
|
|
|
|
LOGP(DHO, LOGL_DEBUG, "%s: Caching DTAP message during ho/ass (%u)\n",
|
|
|
|
bsc_subscr_name(conn->bsub), conn->ho_dtap_cache_len);
|
|
|
|
msg->cb[HO_DTAP_CACHE_MSGB_CB_LINK_ID] = (unsigned long)link_id;
|
|
|
|
msg->cb[HO_DTAP_CACHE_MSGB_CB_ALLOW_SACCH] = allow_sacch ? 1 : 0;
|
|
|
|
msgb_enqueue(&conn->ho_dtap_cache, msg);
|
|
|
|
}
|
|
|
|
|
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
|
|
|
void ho_dtap_cache_flush(struct gsm_subscriber_connection *conn, int send)
|
2013-06-17 09:58:30 +00:00
|
|
|
{
|
|
|
|
struct msgb *msg;
|
|
|
|
unsigned int flushed_count = 0;
|
|
|
|
|
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->secondary_lchan || conn->ho) {
|
2013-06-17 09:58:30 +00:00
|
|
|
LOGP(DHO, LOGL_ERROR, "%s: Cannot send cached DTAP messages, handover/assignment is still ongoing\n",
|
|
|
|
bsc_subscr_name(conn->bsub));
|
|
|
|
send = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
while ((msg = msgb_dequeue(&conn->ho_dtap_cache))) {
|
|
|
|
conn->ho_dtap_cache_len --;
|
|
|
|
flushed_count ++;
|
|
|
|
if (send) {
|
|
|
|
int link_id = (int)msg->cb[HO_DTAP_CACHE_MSGB_CB_LINK_ID];
|
|
|
|
bool allow_sacch = !!msg->cb[HO_DTAP_CACHE_MSGB_CB_ALLOW_SACCH];
|
|
|
|
LOGP(DHO, LOGL_DEBUG, "%s: Sending cached DTAP message after handover/assignment (%u/%u)\n",
|
|
|
|
bsc_subscr_name(conn->bsub), flushed_count, conn->ho_dtap_cache_len);
|
|
|
|
gsm0808_submit_dtap(conn, msg, link_id, allow_sacch);
|
|
|
|
} else
|
|
|
|
msgb_free(msg);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-06-14 10:20:15 +00:00
|
|
|
int bsc_api_init(struct gsm_network *network, struct bsc_api *api)
|
|
|
|
{
|
|
|
|
network->bsc_api = api;
|
|
|
|
return 0;
|
|
|
|
}
|
2010-03-23 06:40:46 +00:00
|
|
|
|
2011-09-12 23:02:09 +00:00
|
|
|
/*! \brief process incoming 08.08 DTAP from MSC (send via BTS to MS) */
|
2010-03-23 06:40:46 +00:00
|
|
|
int gsm0808_submit_dtap(struct gsm_subscriber_connection *conn,
|
2012-04-18 16:58:36 +00:00
|
|
|
struct msgb *msg, int link_id, int allow_sacch)
|
2010-03-23 06:40:46 +00:00
|
|
|
{
|
2010-12-27 09:55:45 +00:00
|
|
|
uint8_t sapi;
|
|
|
|
|
|
|
|
|
|
|
|
if (!conn->lchan) {
|
|
|
|
LOGP(DMSC, LOGL_ERROR,
|
2018-04-10 23:43:41 +00:00
|
|
|
"%s Called submit dtap without an lchan.\n",
|
|
|
|
bsc_subscr_name(conn->bsub));
|
2010-12-27 09:55:45 +00:00
|
|
|
msgb_free(msg);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2013-06-17 09:58:30 +00:00
|
|
|
/* buffer message during assignment / handover */
|
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->secondary_lchan || conn->ho) {
|
2013-06-17 09:58:30 +00:00
|
|
|
ho_dtap_cache_add(conn, msg, link_id, !! allow_sacch);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2010-12-27 09:55:45 +00:00
|
|
|
sapi = link_id & 0x7;
|
2010-03-23 06:40:46 +00:00
|
|
|
msg->lchan = conn->lchan;
|
2011-08-17 20:43:54 +00:00
|
|
|
msg->dst = msg->lchan->ts->trx->rsl_link;
|
2010-06-15 03:20:52 +00:00
|
|
|
|
2010-11-10 09:16:02 +00:00
|
|
|
/* If we are on a TCH and need to submit a SMS (on SAPI=3) we need to use the SACH */
|
2012-04-18 16:58:36 +00:00
|
|
|
if (allow_sacch && sapi != 0) {
|
2010-11-10 09:16:02 +00:00
|
|
|
if (conn->lchan->type == GSM_LCHAN_TCH_F || conn->lchan->type == GSM_LCHAN_TCH_H)
|
|
|
|
link_id |= 0x40;
|
|
|
|
}
|
|
|
|
|
2010-06-17 09:48:13 +00:00
|
|
|
msg->l3h = msg->data;
|
2011-09-12 23:02:09 +00:00
|
|
|
/* is requested SAPI already up? */
|
2010-06-15 03:20:52 +00:00
|
|
|
if (conn->lchan->sapis[sapi] == LCHAN_SAPI_UNUSED) {
|
2011-09-12 23:02:09 +00:00
|
|
|
/* Establish L2 for additional SAPI */
|
2010-06-15 03:20:52 +00:00
|
|
|
OBSC_LINKID_CB(msg) = link_id;
|
|
|
|
if (rll_establish(msg->lchan, sapi, rll_ind_cb, msg) != 0) {
|
|
|
|
msgb_free(msg);
|
|
|
|
send_sapi_reject(conn, link_id);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
} else {
|
2011-09-12 23:02:09 +00:00
|
|
|
/* Directly forward via RLL/RSL to BTS */
|
2010-06-15 03:20:52 +00:00
|
|
|
return rsl_data_request(msg, link_id);
|
|
|
|
}
|
2010-03-23 06:40:46 +00:00
|
|
|
}
|
2010-06-14 10:03:06 +00:00
|
|
|
|
2012-04-07 11:25:47 +00:00
|
|
|
/*
|
|
|
|
* \brief Check if the given channel is compatible with the mode/fullrate
|
|
|
|
*/
|
|
|
|
static int chan_compat_with_mode(struct gsm_lchan *lchan, int chan_mode, int full_rate)
|
|
|
|
{
|
2012-08-24 13:21:35 +00:00
|
|
|
switch (chan_mode) {
|
|
|
|
case GSM48_CMODE_SIGN:
|
2018-01-28 16:40:49 +00:00
|
|
|
switch (lchan->type) {
|
|
|
|
case GSM_LCHAN_TCH_F:
|
|
|
|
case GSM_LCHAN_TCH_H:
|
|
|
|
case GSM_LCHAN_SDCCH:
|
|
|
|
return 1;
|
2018-02-27 11:38:28 +00:00
|
|
|
default:
|
|
|
|
return 0;
|
2018-01-28 16:40:49 +00:00
|
|
|
}
|
2012-08-24 13:21:35 +00:00
|
|
|
case GSM48_CMODE_SPEECH_V1:
|
|
|
|
case GSM48_CMODE_SPEECH_AMR:
|
|
|
|
case GSM48_CMODE_DATA_3k6:
|
|
|
|
case GSM48_CMODE_DATA_6k0:
|
|
|
|
/* these services can all run on TCH/H, but we may have
|
|
|
|
* an explicit override by the 'full_rate' argument */
|
|
|
|
switch (lchan->type) {
|
|
|
|
case GSM_LCHAN_TCH_F:
|
2018-02-27 11:38:28 +00:00
|
|
|
return full_rate ? 1 : 0;
|
2012-08-24 13:21:35 +00:00
|
|
|
case GSM_LCHAN_TCH_H:
|
2018-02-27 11:38:28 +00:00
|
|
|
return full_rate ? 0 : 1;
|
2012-08-24 13:21:35 +00:00
|
|
|
default:
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
case GSM48_CMODE_DATA_12k0:
|
|
|
|
case GSM48_CMODE_DATA_14k5:
|
|
|
|
case GSM48_CMODE_SPEECH_EFR:
|
|
|
|
/* these services all explicitly require a TCH/F */
|
2018-02-27 11:38:28 +00:00
|
|
|
return (lchan->type == GSM_LCHAN_TCH_F) ? 1 : 0;
|
|
|
|
default:
|
|
|
|
return 0;
|
2012-08-24 13:21:35 +00:00
|
|
|
}
|
2012-04-07 11:25:47 +00:00
|
|
|
}
|
|
|
|
|
2018-05-03 17:03:03 +00:00
|
|
|
/*! Send a GSM08.08 Assignment Request. Right now this does not contain the
|
|
|
|
* audio codec type or the allowed rates for the config. In case the current
|
|
|
|
* channel does not allow the selected mode a new one will be allocated.
|
|
|
|
* \param[out] conn related subscriber connection
|
|
|
|
* \param[in] chan_mode mode of the channel (see enum gsm48_chan_mode)
|
|
|
|
* \param[in] full_rate select full rate or half rate channel
|
|
|
|
* \returns 0 on success, 1 when no operation is neccessary, -1 on failure */
|
2010-11-10 09:01:20 +00:00
|
|
|
int gsm0808_assign_req(struct gsm_subscriber_connection *conn, int chan_mode, int full_rate)
|
2010-07-23 08:49:38 +00:00
|
|
|
{
|
2018-05-03 17:03:03 +00:00
|
|
|
/* TODO: Add multirate configuration, make it work for more than audio. */
|
|
|
|
|
2010-07-23 08:49:38 +00:00
|
|
|
struct bsc_api *api;
|
2016-05-09 19:09:47 +00:00
|
|
|
api = conn->network->bsc_api;
|
2010-07-23 08:49:38 +00:00
|
|
|
|
2012-08-24 13:08:23 +00:00
|
|
|
if (!chan_compat_with_mode(conn->lchan, chan_mode, full_rate)) {
|
2010-11-14 15:19:48 +00:00
|
|
|
if (handle_new_assignment(conn, chan_mode, full_rate) != 0)
|
|
|
|
goto error;
|
2010-11-10 10:07:12 +00:00
|
|
|
} else {
|
2018-05-03 17:03:03 +00:00
|
|
|
/* Check if the channel is already in the requested mode, if
|
|
|
|
* yes, we skip unnecessary channel mode modify operations. */
|
|
|
|
if (conn->lchan->tch_mode == chan_mode)
|
|
|
|
return 1;
|
|
|
|
|
2011-08-06 04:42:00 +00:00
|
|
|
if (chan_mode == GSM48_CMODE_SPEECH_AMR)
|
2014-01-19 10:47:44 +00:00
|
|
|
handle_mr_config(conn, conn->lchan, full_rate);
|
2010-11-10 10:07:12 +00:00
|
|
|
|
2018-04-10 23:43:41 +00:00
|
|
|
LOGPLCHAN(conn->lchan, DMSC, LOGL_NOTICE,
|
|
|
|
"Sending ChanModify for speech: %s\n",
|
|
|
|
get_value_string(gsm48_chan_mode_names, chan_mode));
|
2010-11-14 15:19:48 +00:00
|
|
|
gsm48_lchan_modify(conn->lchan, chan_mode);
|
2010-11-10 10:07:12 +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
|
|
|
/* we expect the caller will manage T10 */
|
2010-07-23 08:49:38 +00:00
|
|
|
return 0;
|
2010-11-14 15:19:48 +00:00
|
|
|
|
|
|
|
error:
|
|
|
|
api->assign_fail(conn, 0, NULL);
|
|
|
|
return -1;
|
2010-07-23 08:49:38 +00:00
|
|
|
}
|
|
|
|
|
2010-06-16 06:10:45 +00:00
|
|
|
int gsm0808_page(struct gsm_bts *bts, unsigned int page_group, unsigned int mi_len,
|
|
|
|
uint8_t *mi, int chan_type)
|
|
|
|
{
|
2016-11-17 19:54:04 +00:00
|
|
|
return rsl_paging_cmd(bts, page_group, mi_len, mi, chan_type, false);
|
2010-06-16 06:10:45 +00:00
|
|
|
}
|
|
|
|
|
2010-11-14 15:19:48 +00:00
|
|
|
static void handle_ass_compl(struct gsm_subscriber_connection *conn,
|
|
|
|
struct msgb *msg)
|
|
|
|
{
|
|
|
|
struct gsm48_hdr *gh;
|
2016-05-09 19:09:47 +00:00
|
|
|
struct bsc_api *api = conn->network->bsc_api;
|
2010-11-14 15:19:48 +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
|
|
|
if (conn->ho) {
|
2013-06-02 18:46:32 +00:00
|
|
|
struct lchan_signal_data sig;
|
|
|
|
struct gsm48_hdr *gh = msgb_l3(msg);
|
|
|
|
|
2018-04-10 23:43:41 +00:00
|
|
|
LOGPLCHAN(msg->lchan, DRR, LOGL_DEBUG, "ASSIGNMENT COMPLETE cause = %s\n",
|
|
|
|
rr_cause_name(gh->data[0]));
|
2013-06-02 18:46:32 +00:00
|
|
|
|
|
|
|
sig.lchan = msg->lchan;
|
|
|
|
sig.mr = NULL;
|
|
|
|
osmo_signal_dispatch(SS_LCHAN, S_LCHAN_ASSIGNMENT_COMPL, &sig);
|
|
|
|
/* FIXME: release old channel */
|
|
|
|
|
2013-06-17 09:58:30 +00:00
|
|
|
/* send pending messages, if any */
|
|
|
|
ho_dtap_cache_flush(conn, 1);
|
|
|
|
|
2013-06-02 18:46:32 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2010-11-14 15:19:48 +00:00
|
|
|
if (conn->secondary_lchan != msg->lchan) {
|
2018-04-10 23:43:41 +00:00
|
|
|
LOGPLCHAN(msg->lchan, DMSC, LOGL_ERROR,
|
|
|
|
"Assignment Compl should occur on second lchan.\n");
|
2010-11-14 15:19:48 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
gh = msgb_l3(msg);
|
|
|
|
if (msgb_l3len(msg) - sizeof(*gh) != 1) {
|
2018-04-10 23:43:41 +00:00
|
|
|
LOGPLCHAN(msg->lchan, DMSC, LOGL_ERROR, "Assignment Compl invalid: %zu\n",
|
|
|
|
msgb_l3len(msg) - sizeof(*gh));
|
2010-11-14 15:19:48 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* swap channels */
|
2011-05-06 10:11:06 +00:00
|
|
|
osmo_timer_del(&conn->T10);
|
2010-11-14 15:19:48 +00:00
|
|
|
|
2012-12-06 11:20:56 +00:00
|
|
|
lchan_release(conn->lchan, 0, RSL_REL_LOCAL_END);
|
2010-11-14 15:19:48 +00:00
|
|
|
conn->lchan = conn->secondary_lchan;
|
|
|
|
conn->secondary_lchan = NULL;
|
|
|
|
|
2013-06-17 09:58:30 +00:00
|
|
|
/* send pending messages, if any */
|
|
|
|
ho_dtap_cache_flush(conn, 1);
|
|
|
|
|
2017-12-18 17:44:25 +00:00
|
|
|
if (is_ipaccess_bts(conn_get_bts(conn)) && conn->lchan->tch_mode != GSM48_CMODE_SIGN)
|
2010-11-14 15:19:48 +00:00
|
|
|
rsl_ipacc_crcx(conn->lchan);
|
|
|
|
|
2018-03-21 21:11:32 +00:00
|
|
|
api->assign_compl(conn, gh->data[0]);
|
2010-11-14 15:19:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void handle_ass_fail(struct gsm_subscriber_connection *conn,
|
|
|
|
struct msgb *msg)
|
|
|
|
{
|
2016-05-09 19:09:47 +00:00
|
|
|
struct bsc_api *api = conn->network->bsc_api;
|
2010-11-14 15:19:48 +00:00
|
|
|
uint8_t *rr_failure;
|
|
|
|
struct gsm48_hdr *gh;
|
|
|
|
|
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->ho) {
|
2013-06-02 18:46:32 +00:00
|
|
|
struct lchan_signal_data sig;
|
|
|
|
struct gsm48_hdr *gh = msgb_l3(msg);
|
|
|
|
|
2018-04-10 23:43:41 +00:00
|
|
|
LOGPLCHAN(msg->lchan, DRR, LOGL_DEBUG, "ASSIGNMENT FAILED cause = %s\n",
|
|
|
|
rr_cause_name(gh->data[0]));
|
2013-06-02 18:46:32 +00:00
|
|
|
|
|
|
|
sig.lchan = msg->lchan;
|
|
|
|
sig.mr = NULL;
|
|
|
|
osmo_signal_dispatch(SS_LCHAN, S_LCHAN_ASSIGNMENT_FAIL, &sig);
|
|
|
|
/* FIXME: release allocated new channel */
|
|
|
|
|
2013-06-17 09:58:30 +00:00
|
|
|
/* send pending messages, if any */
|
|
|
|
ho_dtap_cache_flush(conn, 1);
|
|
|
|
|
2013-06-02 18:46:32 +00:00
|
|
|
return;
|
|
|
|
}
|
2010-11-14 15:19:48 +00:00
|
|
|
|
|
|
|
if (conn->lchan != msg->lchan) {
|
2018-04-10 23:43:41 +00:00
|
|
|
LOGPLCHAN(msg->lchan, DMSC, LOGL_ERROR,
|
|
|
|
"Assignment failure should occur on primary lchan.\n");
|
2010-11-14 15:19:48 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* stop the timer and release it */
|
2011-05-06 10:11:06 +00:00
|
|
|
osmo_timer_del(&conn->T10);
|
bsc_api: Fix NULL secondary_lchan access in handle_ass_fail
Related: OW#3893
Program terminated with signal SIGSEGV, Segmentation fault.
0 gsm_lchan_name (lchan=lchan@entry=0x0) at gsm_data_shared.c:342
(gdb) bt
0 gsm_lchan_name (lchan=lchan@entry=0x0) at gsm_data_shared.c:342
1 0x0805ab80 in lchan_release (lchan=0x0, sacch_deact=sacch_deact@entry=0, mode=mode@entry=RSL_REL_LOCAL_END)
at chan_alloc.c:410
2 0x0805c1dd in handle_ass_fail (msg=0x94142b8, conn=0x9251048) at bsc_api.c:459
3 dispatch_dtap (msg=0x94142b8, link_id=0 '\000', conn=0x9251048) at bsc_api.c:598
4 gsm0408_rcvmsg (msg=msg@entry=0x94142b8, link_id=0 '\000') at bsc_api.c:658
5 0x08058ca2 in abis_rsl_rx_rll (msg=0x94142b8) at abis_rsl.c:1686
6 abis_rsl_rcvmsg (msg=0x94142b8) at abis_rsl.c:2097
7 0xb7e8cf9a in handle_ts1_read (bfd=0x94e8e08) at input/ipaccess.c:271
8 ipaccess_fd_cb (bfd=0x94e8e08, what=1) at input/ipaccess.c:386
9 0xb7ee8434 in osmo_select_main (polling=polling@entry=0) at select.c:158
10 0x0804bd7c in main (argc=6, argv=0xbfc27144) at osmo_bsc_main.c:272
(gdb) print lchan
$2 = (const struct gsm_lchan *) 0x0
Possible scenario in which this crash can appear:
1- gsm0808_assign_req() calls handle_new_assignment() which sends an CHAN
ACTIVATE msg and arms T10 timer.
2- ACTIVATE ACK is received (handle_chan_ack), which calls
gsm48_send_rr_ass_cmd() which sends an ASSIGNMENT CMD, and doesn't
disable/modify T10 timer.
3- T10 timeout is triggered (assignment_t10_timeout()), which sets
conn->secondary_lchan = NULL
4- Immediately after, the ASSIGNMENT FAILURE message (which might have been
already queued) is processed in handle_ass_fail, and then the crash occurs.
This race condition is not an issue for handle_ass_compl() path because there's
this check there which would trigger most probably if secondary_lchan is NULL:
"if (conn->secondary_lchan != msg->lchan)"
Change-Id: I3798b36c628f75d4e8bc7b0996c27d695d53fbb1
2017-10-16 08:50:43 +00:00
|
|
|
if (conn->secondary_lchan) {
|
|
|
|
lchan_release(conn->secondary_lchan, 0, RSL_REL_LOCAL_END);
|
|
|
|
conn->secondary_lchan = NULL;
|
|
|
|
}
|
2010-11-14 15:19:48 +00:00
|
|
|
|
2013-06-17 09:58:30 +00:00
|
|
|
/* send pending messages, if any */
|
|
|
|
ho_dtap_cache_flush(conn, 1);
|
|
|
|
|
2010-11-14 15:19:48 +00:00
|
|
|
gh = msgb_l3(msg);
|
|
|
|
if (msgb_l3len(msg) - sizeof(*gh) != 1) {
|
2018-04-10 23:43:41 +00:00
|
|
|
LOGPLCHAN(conn->lchan, DMSC, LOGL_ERROR, "assignment failure unhandled: %zu\n",
|
|
|
|
msgb_l3len(msg) - sizeof(*gh));
|
2010-11-14 15:19:48 +00:00
|
|
|
rr_failure = NULL;
|
|
|
|
} else {
|
|
|
|
rr_failure = &gh->data[0];
|
|
|
|
}
|
|
|
|
|
|
|
|
api->assign_fail(conn,
|
|
|
|
GSM0808_CAUSE_RADIO_INTERFACE_MESSAGE_FAILURE,
|
|
|
|
rr_failure);
|
|
|
|
}
|
|
|
|
|
2012-01-23 09:28:35 +00:00
|
|
|
static void handle_classmark_chg(struct gsm_subscriber_connection *conn,
|
|
|
|
struct msgb *msg)
|
|
|
|
{
|
|
|
|
struct bsc_api *api = msg->lchan->ts->trx->bts->network->bsc_api;
|
|
|
|
struct gsm48_hdr *gh = msgb_l3(msg);
|
|
|
|
unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
|
|
|
|
uint8_t cm2_len, cm3_len = 0;
|
|
|
|
uint8_t *cm2, *cm3 = NULL;
|
|
|
|
|
2018-04-10 23:43:41 +00:00
|
|
|
LOGPLCHAN(msg->lchan, DRR, LOGL_DEBUG, "CLASSMARK CHANGE ");
|
2012-01-23 09:28:35 +00:00
|
|
|
|
|
|
|
/* classmark 2 */
|
|
|
|
cm2_len = gh->data[0];
|
|
|
|
cm2 = &gh->data[1];
|
|
|
|
DEBUGPC(DRR, "CM2(len=%u) ", cm2_len);
|
|
|
|
|
|
|
|
if (payload_len > cm2_len + 1) {
|
|
|
|
/* we must have a classmark3 */
|
|
|
|
if (gh->data[cm2_len+1] != 0x20) {
|
|
|
|
DEBUGPC(DRR, "ERR CM3 TAG\n");
|
2012-01-23 15:40:24 +00:00
|
|
|
return;
|
2012-01-23 09:28:35 +00:00
|
|
|
}
|
|
|
|
if (cm2_len > 3) {
|
|
|
|
DEBUGPC(DRR, "CM2 too long!\n");
|
2012-01-23 15:40:24 +00:00
|
|
|
return;
|
2012-01-23 09:28:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
cm3_len = gh->data[cm2_len+2];
|
|
|
|
cm3 = &gh->data[cm2_len+3];
|
|
|
|
if (cm3_len > 14) {
|
|
|
|
DEBUGPC(DRR, "CM3 len %u too long!\n", cm3_len);
|
2012-01-23 15:40:24 +00:00
|
|
|
return;
|
2012-01-23 09:28:35 +00:00
|
|
|
}
|
|
|
|
DEBUGPC(DRR, "CM3(len=%u)\n", cm3_len);
|
|
|
|
}
|
|
|
|
api->classmark_chg(conn, cm2, cm2_len, cm3, cm3_len);
|
|
|
|
}
|
|
|
|
|
2012-01-23 15:40:24 +00:00
|
|
|
/* Chapter 9.1.16 Handover complete */
|
|
|
|
static void handle_rr_ho_compl(struct msgb *msg)
|
|
|
|
{
|
|
|
|
struct lchan_signal_data sig;
|
|
|
|
struct gsm48_hdr *gh = msgb_l3(msg);
|
|
|
|
|
2018-04-10 23:43:41 +00:00
|
|
|
LOGPLCHAN(msg->lchan, DRR, LOGL_DEBUG,
|
|
|
|
"HANDOVER COMPLETE cause = %s\n", rr_cause_name(gh->data[0]));
|
2012-01-23 15:40:24 +00:00
|
|
|
|
|
|
|
sig.lchan = msg->lchan;
|
|
|
|
sig.mr = NULL;
|
|
|
|
osmo_signal_dispatch(SS_LCHAN, S_LCHAN_HANDOVER_COMPL, &sig);
|
|
|
|
/* FIXME: release old channel */
|
2013-06-17 09:58:30 +00:00
|
|
|
|
|
|
|
/* send pending messages, if any */
|
|
|
|
ho_dtap_cache_flush(msg->lchan->conn, 1);
|
2012-01-23 15:40:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Chapter 9.1.17 Handover Failure */
|
|
|
|
static void handle_rr_ho_fail(struct msgb *msg)
|
|
|
|
{
|
|
|
|
struct lchan_signal_data sig;
|
|
|
|
struct gsm48_hdr *gh = msgb_l3(msg);
|
|
|
|
|
2018-04-10 23:43:41 +00:00
|
|
|
/* Log on both RR and HO categories: it is an RR message, but is still quite important when
|
|
|
|
* filtering on HO. */
|
|
|
|
LOGPLCHAN(msg->lchan, DRR, LOGL_DEBUG,
|
|
|
|
"HANDOVER FAILED cause = %s\n", rr_cause_name(gh->data[0]));
|
|
|
|
LOGPLCHAN(msg->lchan, DHO, LOGL_DEBUG,
|
|
|
|
"HANDOVER FAILED cause = %s\n", rr_cause_name(gh->data[0]));
|
2012-01-23 15:40:24 +00:00
|
|
|
|
|
|
|
sig.lchan = msg->lchan;
|
|
|
|
sig.mr = NULL;
|
|
|
|
osmo_signal_dispatch(SS_LCHAN, S_LCHAN_HANDOVER_FAIL, &sig);
|
|
|
|
/* FIXME: release allocated new channel */
|
2013-06-17 09:58:30 +00:00
|
|
|
|
|
|
|
/* send pending messages, if any */
|
|
|
|
ho_dtap_cache_flush(msg->lchan->conn, 1);
|
2012-01-23 15:40:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-11-04 11:18:00 +00:00
|
|
|
static void dispatch_dtap(struct gsm_subscriber_connection *conn,
|
|
|
|
uint8_t link_id, struct msgb *msg)
|
2010-11-04 10:18:03 +00:00
|
|
|
{
|
|
|
|
struct bsc_api *api = msg->lchan->ts->trx->bts->network->bsc_api;
|
|
|
|
struct gsm48_hdr *gh;
|
|
|
|
uint8_t pdisc;
|
2016-03-14 15:13:24 +00:00
|
|
|
uint8_t msg_type;
|
2010-11-04 10:18:03 +00:00
|
|
|
int rc;
|
|
|
|
|
|
|
|
if (msgb_l3len(msg) < sizeof(*gh)) {
|
2018-04-10 23:43:41 +00:00
|
|
|
LOGP(DMSC, LOGL_ERROR, "(%s) Message too short for a GSM48 header.\n",
|
|
|
|
bsc_subscr_name(conn->bsub));
|
2010-11-04 10:18:03 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
gh = msgb_l3(msg);
|
2016-03-14 15:13:24 +00:00
|
|
|
pdisc = gsm48_hdr_pdisc(gh);
|
|
|
|
msg_type = gsm48_hdr_msg_type(gh);
|
2012-01-23 15:40:24 +00:00
|
|
|
|
|
|
|
/* the idea is to handle all RR messages here, and only hand
|
|
|
|
* MM/CC/SMS-CP/LCS up to the MSC. Some messages like PAGING
|
|
|
|
* RESPONSE or CM SERVICE REQUEST will not be covered here, as
|
|
|
|
* they are only possible in the first L3 message of each L2
|
|
|
|
* channel, i.e. 'conn' will not exist and gsm0408_rcvmsg()
|
|
|
|
* will call api->compl_l3() for it */
|
2010-11-04 10:18:03 +00:00
|
|
|
switch (pdisc) {
|
|
|
|
case GSM48_PDISC_RR:
|
2016-03-14 15:13:24 +00:00
|
|
|
switch (msg_type) {
|
2012-01-23 15:40:24 +00:00
|
|
|
case GSM48_MT_RR_GPRS_SUSP_REQ:
|
2018-04-10 23:43:41 +00:00
|
|
|
LOGPLCHAN(msg->lchan, DRR, LOGL_DEBUG,
|
|
|
|
"%s\n", gsm48_rr_msg_name(GSM48_MT_RR_GPRS_SUSP_REQ));
|
2012-01-23 15:40:24 +00:00
|
|
|
break;
|
|
|
|
case GSM48_MT_RR_STATUS:
|
2018-04-10 23:43:41 +00:00
|
|
|
LOGPLCHAN(msg->lchan, DRR, LOGL_NOTICE,
|
|
|
|
"%s (cause: %s)\n", gsm48_rr_msg_name(GSM48_MT_RR_STATUS),
|
|
|
|
rr_cause_name(gh->data[0]));
|
2012-01-23 15:40:24 +00:00
|
|
|
break;
|
|
|
|
case GSM48_MT_RR_MEAS_REP:
|
|
|
|
/* This shouldn't actually end up here, as RSL treats
|
|
|
|
* L3 Info of 08.58 MEASUREMENT REPORT different by calling
|
|
|
|
* directly into gsm48_parse_meas_rep */
|
2018-04-10 23:43:41 +00:00
|
|
|
LOGPLCHAN(msg->lchan, DMEAS, LOGL_ERROR,
|
|
|
|
"DIRECT GSM48 MEASUREMENT REPORT ?!?\n");
|
2018-03-17 20:40:32 +00:00
|
|
|
gsm48_tx_rr_status(conn, GSM48_RR_CAUSE_MSG_TYPE_N_COMPAT);
|
2012-01-23 15:40:24 +00:00
|
|
|
break;
|
|
|
|
case GSM48_MT_RR_HANDO_COMPL:
|
|
|
|
handle_rr_ho_compl(msg);
|
|
|
|
break;
|
|
|
|
case GSM48_MT_RR_HANDO_FAIL:
|
|
|
|
handle_rr_ho_fail(msg);
|
|
|
|
break;
|
2010-11-04 10:18:03 +00:00
|
|
|
case GSM48_MT_RR_CIPH_M_COMPL:
|
|
|
|
if (api->cipher_mode_compl)
|
2012-01-23 15:40:24 +00:00
|
|
|
api->cipher_mode_compl(conn, msg,
|
2010-11-04 10:18:03 +00:00
|
|
|
conn->lchan->encr.alg_id);
|
|
|
|
break;
|
|
|
|
case GSM48_MT_RR_ASS_COMPL:
|
2010-11-14 15:19:48 +00:00
|
|
|
handle_ass_compl(conn, msg);
|
2010-11-04 10:18:03 +00:00
|
|
|
break;
|
|
|
|
case GSM48_MT_RR_ASS_FAIL:
|
2010-11-14 15:19:48 +00:00
|
|
|
handle_ass_fail(conn, msg);
|
2010-11-04 10:18:03 +00:00
|
|
|
break;
|
|
|
|
case GSM48_MT_RR_CHAN_MODE_MODIF_ACK:
|
2011-05-06 10:11:06 +00:00
|
|
|
osmo_timer_del(&conn->T10);
|
2010-11-04 10:18:03 +00:00
|
|
|
rc = gsm48_rx_rr_modif_ack(msg);
|
2011-12-27 11:31:02 +00:00
|
|
|
if (rc < 0) {
|
2010-11-04 10:18:03 +00:00
|
|
|
api->assign_fail(conn,
|
2010-11-05 09:37:17 +00:00
|
|
|
GSM0808_CAUSE_NO_RADIO_RESOURCE_AVAILABLE,
|
|
|
|
NULL);
|
2011-12-27 11:31:02 +00:00
|
|
|
} else if (rc >= 0) {
|
2018-03-21 21:11:32 +00:00
|
|
|
api->assign_compl(conn, 0);
|
2011-12-27 11:31:02 +00:00
|
|
|
}
|
2010-11-04 10:18:03 +00:00
|
|
|
break;
|
2012-01-23 09:28:35 +00:00
|
|
|
case GSM48_MT_RR_CLSM_CHG:
|
|
|
|
handle_classmark_chg(conn, msg);
|
|
|
|
break;
|
2012-07-16 11:20:53 +00:00
|
|
|
case GSM48_MT_RR_APP_INFO:
|
|
|
|
/* Passing RR APP INFO to MSC, not quite
|
|
|
|
* according to spec */
|
|
|
|
if (api->dtap)
|
|
|
|
api->dtap(conn, link_id, msg);
|
|
|
|
break;
|
2012-01-23 15:40:24 +00:00
|
|
|
default:
|
2018-02-23 17:38:24 +00:00
|
|
|
/* Drop unknown RR message */
|
2018-04-10 23:43:41 +00:00
|
|
|
LOGPLCHAN(msg->lchan, DRR, LOGL_NOTICE,
|
|
|
|
"Dropping %s 04.08 RR message\n", gsm48_rr_msg_name(msg_type));
|
2018-03-17 20:40:32 +00:00
|
|
|
gsm48_tx_rr_status(conn, GSM48_RR_CAUSE_MSG_TYPE_N);
|
|
|
|
break;
|
2010-11-04 10:18:03 +00:00
|
|
|
}
|
|
|
|
break;
|
2012-01-23 15:40:24 +00:00
|
|
|
default:
|
|
|
|
if (api->dtap)
|
|
|
|
api->dtap(conn, link_id, msg);
|
2010-11-04 10:18:03 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-09-12 23:02:09 +00:00
|
|
|
/*! \brief RSL has received a DATA INDICATION with L3 from MS */
|
2010-06-17 08:41:25 +00:00
|
|
|
int gsm0408_rcvmsg(struct msgb *msg, uint8_t link_id)
|
|
|
|
{
|
|
|
|
int rc;
|
|
|
|
struct bsc_api *api = msg->lchan->ts->trx->bts->network->bsc_api;
|
2010-06-28 07:47:12 +00:00
|
|
|
struct gsm_lchan *lchan;
|
2010-06-17 08:41:25 +00:00
|
|
|
|
2010-06-28 07:47:12 +00:00
|
|
|
lchan = msg->lchan;
|
2010-07-05 03:38:37 +00:00
|
|
|
if (lchan->state != LCHAN_S_ACTIVE) {
|
2018-04-10 23:43:41 +00:00
|
|
|
LOGPLCHAN(msg->lchan, DRSL, LOGL_INFO, "Got data in non active state, discarding.\n");
|
2010-07-05 03:38:37 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-06-28 07:47:12 +00:00
|
|
|
if (lchan->conn) {
|
2011-09-12 23:02:09 +00:00
|
|
|
/* if we already have a connection, forward via DTAP to
|
|
|
|
* MSC */
|
2010-11-04 11:18:00 +00:00
|
|
|
dispatch_dtap(lchan->conn, link_id, msg);
|
2010-06-17 08:41:25 +00:00
|
|
|
} else {
|
2011-09-12 23:02:09 +00:00
|
|
|
/* allocate a new connection */
|
2010-06-28 07:47:12 +00:00
|
|
|
rc = BSC_API_CONN_POL_REJECT;
|
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
|
|
|
lchan->conn = bsc_subscr_con_allocate(msg->lchan->ts->trx->bts->network);
|
2011-01-16 17:15:26 +00:00
|
|
|
if (!lchan->conn) {
|
2012-12-06 11:20:56 +00:00
|
|
|
lchan_release(lchan, 1, RSL_REL_NORMAL);
|
2011-01-16 17:15:26 +00:00
|
|
|
return -1;
|
|
|
|
}
|
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
|
|
|
lchan->conn->lchan = lchan;
|
2010-06-28 07:47:12 +00:00
|
|
|
|
2011-09-12 23:02:09 +00:00
|
|
|
/* fwd via bsc_api to send COMPLETE L3 INFO to MSC */
|
2011-01-16 17:15:26 +00:00
|
|
|
rc = api->compl_l3(lchan->conn, msg, 0);
|
2010-06-28 07:47:12 +00:00
|
|
|
|
|
|
|
if (rc != BSC_API_CONN_POL_ACCEPT) {
|
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_dispatch(lchan->conn->fi, FIXME, NULL);
|
2010-06-28 07:47:12 +00:00
|
|
|
}
|
2010-06-17 08:41:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2011-09-12 23:02:09 +00:00
|
|
|
/*! \brief We received a GSM 08.08 CIPHER MODE from the MSC */
|
2010-07-23 08:55:24 +00:00
|
|
|
int gsm0808_cipher_mode(struct gsm_subscriber_connection *conn, int cipher,
|
2010-11-10 08:42:50 +00:00
|
|
|
const uint8_t *key, int len, int include_imeisv)
|
2010-07-23 08:55:24 +00:00
|
|
|
{
|
2010-11-10 09:25:34 +00:00
|
|
|
if (cipher > 0 && key == NULL) {
|
2018-04-10 23:43:41 +00:00
|
|
|
LOGP(DRSL, LOGL_ERROR, "%s: Need to have an encryption key.\n",
|
|
|
|
bsc_subscr_name(conn->bsub));
|
2010-11-10 09:25:34 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (len > MAX_A5_KEY_LEN) {
|
2018-04-10 23:43:41 +00:00
|
|
|
LOGP(DRSL, LOGL_ERROR, "%s: The key is too long: %d\n",
|
|
|
|
bsc_subscr_name(conn->bsub), len);
|
2010-11-10 09:25:34 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2017-12-14 02:50:26 +00:00
|
|
|
LOGP(DRSL, LOGL_DEBUG, "(subscr %s) Cipher Mode: cipher=%d key=%s include_imeisv=%d\n",
|
|
|
|
bsc_subscr_name(conn->bsub), cipher, osmo_hexdump_nospc(key, len), include_imeisv);
|
|
|
|
|
2010-11-10 09:25:34 +00:00
|
|
|
conn->lchan->encr.alg_id = RSL_ENC_ALG_A5(cipher);
|
|
|
|
if (key) {
|
|
|
|
conn->lchan->encr.key_len = len;
|
|
|
|
memcpy(conn->lchan->encr.key, key, len);
|
|
|
|
}
|
|
|
|
|
|
|
|
return gsm48_send_rr_ciph_mode(conn->lchan, include_imeisv);
|
2010-07-23 08:55:24 +00:00
|
|
|
}
|
|
|
|
|
2010-09-16 12:48:15 +00:00
|
|
|
/*
|
|
|
|
* Release all occupied RF Channels but stay around for more.
|
|
|
|
*/
|
2010-09-17 22:44:24 +00:00
|
|
|
int gsm0808_clear(struct gsm_subscriber_connection *conn)
|
2010-06-28 09:09:29 +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
|
|
|
if (conn->ho)
|
2010-12-27 12:46:48 +00:00
|
|
|
bsc_clear_handover(conn, 1);
|
2010-09-16 14:49:37 +00:00
|
|
|
|
2010-11-14 15:19:48 +00:00
|
|
|
if (conn->secondary_lchan)
|
2012-12-06 11:20:56 +00:00
|
|
|
lchan_release(conn->secondary_lchan, 0, RSL_REL_LOCAL_END);
|
2010-11-14 15:19:48 +00:00
|
|
|
|
2010-11-14 15:04:46 +00:00
|
|
|
if (conn->lchan)
|
2012-12-06 11:20:56 +00:00
|
|
|
lchan_release(conn->lchan, 1, RSL_REL_NORMAL);
|
2010-06-30 04:17:35 +00:00
|
|
|
|
2010-09-16 12:48:15 +00:00
|
|
|
conn->lchan = NULL;
|
2010-11-14 15:19:48 +00:00
|
|
|
conn->secondary_lchan = NULL;
|
2010-09-16 12:48:15 +00:00
|
|
|
|
2011-05-06 10:11:06 +00:00
|
|
|
osmo_timer_del(&conn->T10);
|
2010-11-14 15:19:48 +00:00
|
|
|
|
2010-06-28 09:09:29 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2010-06-15 03:20:52 +00:00
|
|
|
static void send_sapi_reject(struct gsm_subscriber_connection *conn, int link_id)
|
|
|
|
{
|
|
|
|
struct bsc_api *api;
|
|
|
|
|
2010-06-28 07:47:12 +00:00
|
|
|
if (!conn)
|
|
|
|
return;
|
|
|
|
|
2016-05-09 19:09:47 +00:00
|
|
|
api = conn->network->bsc_api;
|
2010-06-15 03:20:52 +00:00
|
|
|
if (!api || !api->sapi_n_reject)
|
|
|
|
return;
|
|
|
|
|
|
|
|
api->sapi_n_reject(conn, link_id);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void rll_ind_cb(struct gsm_lchan *lchan, uint8_t link_id, void *_data, enum bsc_rllr_ind rllr_ind)
|
|
|
|
{
|
|
|
|
struct msgb *msg = _data;
|
|
|
|
|
2010-11-10 09:59:05 +00:00
|
|
|
/*
|
|
|
|
* There seems to be a small window that the RLL timer can
|
|
|
|
* fire after a lchan_release call and before the S_CHALLOC_FREED
|
|
|
|
* is called. Check if a conn is set before proceeding.
|
|
|
|
*/
|
|
|
|
if (!lchan->conn)
|
|
|
|
return;
|
|
|
|
|
2010-06-15 03:20:52 +00:00
|
|
|
switch (rllr_ind) {
|
|
|
|
case BSC_RLLR_IND_EST_CONF:
|
|
|
|
rsl_data_request(msg, OBSC_LINKID_CB(msg));
|
|
|
|
break;
|
|
|
|
case BSC_RLLR_IND_REL_IND:
|
|
|
|
case BSC_RLLR_IND_ERR_IND:
|
|
|
|
case BSC_RLLR_IND_TIMEOUT:
|
2010-06-28 07:47:12 +00:00
|
|
|
send_sapi_reject(lchan->conn, OBSC_LINKID_CB(msg));
|
2010-06-15 03:20:52 +00:00
|
|
|
msgb_free(msg);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-06-14 10:20:15 +00:00
|
|
|
static int bsc_handle_lchan_signal(unsigned int subsys, unsigned int signal,
|
|
|
|
void *handler_data, void *signal_data)
|
|
|
|
{
|
|
|
|
struct bsc_api *bsc;
|
|
|
|
struct gsm_lchan *lchan;
|
2010-12-27 12:28:20 +00:00
|
|
|
struct lchan_signal_data *lchan_data;
|
2010-06-14 10:20:15 +00:00
|
|
|
|
2010-11-14 18:29:42 +00:00
|
|
|
if (subsys != SS_LCHAN)
|
2010-06-14 10:20:15 +00:00
|
|
|
return 0;
|
|
|
|
|
2010-12-27 11:30:12 +00:00
|
|
|
|
2010-12-27 12:28:20 +00:00
|
|
|
lchan_data = signal_data;
|
|
|
|
if (!lchan_data->lchan || !lchan_data->lchan->conn)
|
2010-06-14 10:20:15 +00:00
|
|
|
return 0;
|
|
|
|
|
2010-12-27 12:28:20 +00:00
|
|
|
lchan = lchan_data->lchan;
|
2010-06-14 10:20:15 +00:00
|
|
|
bsc = lchan->ts->trx->bts->network->bsc_api;
|
2010-09-16 12:48:15 +00:00
|
|
|
if (!bsc)
|
2010-06-14 10:20:15 +00:00
|
|
|
return 0;
|
|
|
|
|
2010-11-14 18:29:42 +00:00
|
|
|
switch (signal) {
|
|
|
|
case S_LCHAN_UNEXPECTED_RELEASE:
|
|
|
|
handle_release(lchan->conn, bsc, lchan);
|
|
|
|
break;
|
2010-11-14 15:19:48 +00:00
|
|
|
case S_LCHAN_ACTIVATE_ACK:
|
|
|
|
handle_chan_ack(lchan->conn, bsc, lchan);
|
|
|
|
break;
|
|
|
|
case S_LCHAN_ACTIVATE_NACK:
|
|
|
|
handle_chan_nack(lchan->conn, bsc, lchan);
|
|
|
|
break;
|
2010-11-14 18:29:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void handle_release(struct gsm_subscriber_connection *conn,
|
|
|
|
struct bsc_api *bsc, struct gsm_lchan *lchan)
|
|
|
|
{
|
2010-11-14 15:19:48 +00:00
|
|
|
if (conn->secondary_lchan == lchan) {
|
2011-05-06 10:11:06 +00:00
|
|
|
osmo_timer_del(&conn->T10);
|
2010-11-14 15:19:48 +00:00
|
|
|
conn->secondary_lchan = NULL;
|
|
|
|
|
|
|
|
bsc->assign_fail(conn,
|
|
|
|
GSM0808_CAUSE_RADIO_INTERFACE_FAILURE,
|
|
|
|
NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* clear the connection now */
|
|
|
|
if (bsc->clear_request)
|
2018-03-16 23:48:24 +00:00
|
|
|
bsc->clear_request(conn, 0);
|
2010-11-14 15:19:48 +00:00
|
|
|
|
2010-12-26 21:12:53 +00:00
|
|
|
/* now give up all channels */
|
|
|
|
if (conn->lchan == lchan)
|
|
|
|
conn->lchan = NULL;
|
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->ho && conn->ho->new_lchan == lchan)
|
2010-12-27 12:46:48 +00:00
|
|
|
bsc_clear_handover(conn, 0);
|
2010-12-26 21:12:53 +00:00
|
|
|
lchan->conn = NULL;
|
2010-06-14 10:20:15 +00:00
|
|
|
}
|
|
|
|
|
2010-11-14 15:19:48 +00:00
|
|
|
static void handle_chan_ack(struct gsm_subscriber_connection *conn,
|
|
|
|
struct bsc_api *api, struct gsm_lchan *lchan)
|
|
|
|
{
|
|
|
|
if (conn->secondary_lchan != lchan)
|
|
|
|
return;
|
|
|
|
|
2018-04-10 23:43:41 +00:00
|
|
|
LOGPLCHAN(lchan, DMSC, LOGL_NOTICE, "Sending RR Assignment\n");
|
2011-09-03 12:11:24 +00:00
|
|
|
gsm48_send_rr_ass_cmd(conn->lchan, lchan, lchan->ms_power);
|
2010-11-14 15:19:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void handle_chan_nack(struct gsm_subscriber_connection *conn,
|
|
|
|
struct bsc_api *api, struct gsm_lchan *lchan)
|
|
|
|
{
|
|
|
|
if (conn->secondary_lchan != lchan)
|
|
|
|
return;
|
|
|
|
|
2018-04-10 23:43:41 +00:00
|
|
|
LOGPLCHAN(lchan, DMSC, LOGL_ERROR, "Channel activation failed. Waiting for timeout now\n");
|
2010-11-14 15:19:48 +00:00
|
|
|
conn->secondary_lchan->conn = NULL;
|
|
|
|
conn->secondary_lchan = NULL;
|
|
|
|
}
|
|
|
|
|
2010-06-14 10:20:15 +00:00
|
|
|
static __attribute__((constructor)) void on_dso_load_bsc(void)
|
|
|
|
{
|
2011-05-06 10:12:31 +00:00
|
|
|
osmo_signal_register_handler(SS_LCHAN, bsc_handle_lchan_signal, NULL);
|
2010-06-15 03:20:24 +00:00
|
|
|
}
|