2010-11-09 22:28:33 +00:00
|
|
|
/* GSM 08.08 BSSMAP handling */
|
2012-12-03 14:32:54 +00:00
|
|
|
/* (C) 2009-2012 by Holger Hans Peter Freyther <zecke@selfish.org>
|
|
|
|
* (C) 2009-2012 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) 2017 by Harald Welte <laforge@gnumonks.org>
|
2010-11-09 22:28:33 +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-11-09 22:28:33 +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-11-09 22:28:33 +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-11-09 22:28:33 +00:00
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2019-04-23 16:37:37 +00:00
|
|
|
#include <osmocom/core/sockaddr_str.h>
|
|
|
|
#include <osmocom/mgcp_client/mgcp_client_endpoint_fsm.h>
|
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
|
|
|
|
2017-09-04 13:15:32 +00:00
|
|
|
#include <osmocom/bsc/osmo_bsc.h>
|
|
|
|
#include <osmocom/bsc/osmo_bsc_grace.h>
|
|
|
|
#include <osmocom/bsc/osmo_bsc_rf.h>
|
|
|
|
#include <osmocom/bsc/debug.h>
|
|
|
|
#include <osmocom/bsc/bsc_subscriber.h>
|
|
|
|
#include <osmocom/bsc/paging.h>
|
2018-07-24 14:18:15 +00:00
|
|
|
#include <osmocom/bsc/gsm_04_08_rr.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-07-13 07:17:07 +00:00
|
|
|
#include <osmocom/bsc/codec_pref.h>
|
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
|
|
|
#include <osmocom/bsc/abis_rsl.h>
|
|
|
|
#include <osmocom/bsc/handover_fsm.h>
|
2020-07-15 18:53:16 +00:00
|
|
|
#include <osmocom/bsc/bts.h>
|
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
|
|
|
|
|
|
|
#include <osmocom/gsm/protocol/gsm_08_08.h>
|
2011-03-23 17:26:56 +00:00
|
|
|
#include <osmocom/gsm/gsm0808.h>
|
2017-09-04 13:15:32 +00:00
|
|
|
#include <osmocom/bsc/osmo_bsc_sigtran.h>
|
2018-05-29 23:39:43 +00:00
|
|
|
#include <osmocom/bsc/osmo_bsc_lcls.h>
|
2017-09-04 13:15:32 +00:00
|
|
|
#include <osmocom/bsc/a_reset.h>
|
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
|
|
|
#include <osmocom/bsc/handover.h>
|
2018-05-29 23:39:43 +00:00
|
|
|
#include <osmocom/core/fsm.h>
|
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
|
|
|
#include <osmocom/core/socket.h>
|
2019-03-14 03:36:40 +00:00
|
|
|
#include <osmocom/core/sockaddr_str.h>
|
2020-09-17 15:54:39 +00:00
|
|
|
#include <osmocom/bsc/lcs_loc_req.h>
|
2020-10-09 15:18:29 +00:00
|
|
|
#include <osmocom/bsc/bssmap_reset.h>
|
2017-04-09 10:32:51 +00:00
|
|
|
|
|
|
|
#define IP_V4_ADDR_LEN 4
|
2010-11-09 22:28:33 +00:00
|
|
|
|
2010-11-10 09:07:30 +00:00
|
|
|
/*
|
|
|
|
* helpers for the assignment command
|
|
|
|
*/
|
2017-04-09 10:32:51 +00:00
|
|
|
|
2019-04-16 18:03:15 +00:00
|
|
|
/* We expect MSC to provide use with an Osmocom extension TLV in BSSMAP_RESET to
|
|
|
|
* announce Osmux support */
|
|
|
|
static void update_msc_osmux_support(struct bsc_msc_data *msc,
|
|
|
|
struct msgb *msg, unsigned int length)
|
|
|
|
{
|
|
|
|
struct tlv_parsed tp;
|
|
|
|
int rc;
|
|
|
|
bool old_value = msc->remote_supports_osmux;
|
|
|
|
|
|
|
|
rc = tlv_parse(&tp, gsm0808_att_tlvdef(), msg->l4h + 1, length - 1, 0, 0);
|
|
|
|
if (rc < 0)
|
|
|
|
LOGP(DMSC, LOGL_NOTICE, "Failed parsing TLV looking for Osmux support\n");
|
|
|
|
|
|
|
|
msc->remote_supports_osmux = !!TLVP_PRESENT(&tp, GSM0808_IE_OSMO_OSMUX_SUPPORT);
|
|
|
|
|
|
|
|
if (old_value != msc->remote_supports_osmux)
|
|
|
|
LOGP(DMSC, LOGL_INFO, "MSC detected AoIP Osmux support changed: %d->%d\n",
|
|
|
|
old_value, msc->remote_supports_osmux);
|
|
|
|
}
|
2010-11-10 09:07:30 +00:00
|
|
|
|
2017-02-23 20:57:23 +00:00
|
|
|
static int bssmap_handle_reset_ack(struct bsc_msc_data *msc,
|
2010-11-10 08:24:37 +00:00
|
|
|
struct msgb *msg, unsigned int length)
|
|
|
|
{
|
2017-04-09 10:32:51 +00:00
|
|
|
LOGP(DMSC, LOGL_NOTICE, "RESET ACK from MSC: %s\n",
|
|
|
|
osmo_sccp_addr_name(osmo_ss7_instance_find(msc->a.cs7_instance),
|
|
|
|
&msc->a.msc_addr));
|
|
|
|
|
|
|
|
/* Inform the FSM that controls the RESET/RESET-ACK procedure
|
|
|
|
* that we have successfully received the reset-ack message */
|
2018-08-07 09:31:51 +00:00
|
|
|
a_reset_ack_confirm(msc);
|
2017-04-09 10:32:51 +00:00
|
|
|
|
2019-04-16 18:03:15 +00:00
|
|
|
update_msc_osmux_support(msc, msg, length);
|
|
|
|
|
2017-04-09 10:32:51 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Handle MSC sided reset */
|
|
|
|
static int bssmap_handle_reset(struct bsc_msc_data *msc,
|
|
|
|
struct msgb *msg, unsigned int length)
|
|
|
|
{
|
|
|
|
LOGP(DMSC, LOGL_NOTICE, "RESET from MSC: %s\n",
|
|
|
|
osmo_sccp_addr_name(osmo_ss7_instance_find(msc->a.cs7_instance),
|
|
|
|
&msc->a.msc_addr));
|
|
|
|
|
2019-04-16 18:03:15 +00:00
|
|
|
update_msc_osmux_support(msc, msg, length);
|
|
|
|
|
2020-10-09 15:18:29 +00:00
|
|
|
if (!msc->a.bssmap_reset) {
|
|
|
|
LOGP(DMSC, LOGL_ERROR, "(msc%d) missing RESET FSM\n", msc->nr);
|
|
|
|
/* Make sure to shut down all open connections, if any */
|
|
|
|
osmo_bsc_sigtran_reset(msc);
|
|
|
|
return -1;
|
|
|
|
}
|
2017-04-09 10:32:51 +00:00
|
|
|
|
2020-10-09 15:18:29 +00:00
|
|
|
/* Normal case: let the reset FSM orchestrate link down / link up callbacks. */
|
|
|
|
return osmo_fsm_inst_dispatch(msc->a.bssmap_reset->fi, BSSMAP_RESET_EV_RX_RESET, NULL);
|
2010-11-10 08:24:37 +00:00
|
|
|
}
|
|
|
|
|
2018-01-11 13:53:18 +00:00
|
|
|
/* Page a subscriber based on TMSI and LAC via the specified BTS.
|
|
|
|
* The msc parameter is the MSC which issued the corresponding paging request.
|
2018-03-27 11:22:06 +00:00
|
|
|
* Log an error if paging failed. */
|
|
|
|
static void
|
2020-09-18 00:49:15 +00:00
|
|
|
page_subscriber(const struct bsc_paging_params *params, struct gsm_bts *bts, uint32_t lac)
|
2018-01-05 16:22:11 +00:00
|
|
|
{
|
2018-01-11 13:53:18 +00:00
|
|
|
int ret;
|
2018-01-05 16:22:11 +00:00
|
|
|
|
2020-09-14 13:08:21 +00:00
|
|
|
if (!bsc_grace_allow_new_connection(bsc_gsmnet, bts)) {
|
2020-09-18 00:49:15 +00:00
|
|
|
LOG_PAGING_BTS(params, bts, DMSC, LOGL_DEBUG, "RF-locked: not paging on this BTS\n");
|
2020-09-14 13:08:21 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2020-09-18 00:49:15 +00:00
|
|
|
LOG_PAGING_BTS(params, bts, DMSC, LOGL_INFO, "Paging on LAC %u\n", lac);
|
2018-03-27 11:22:06 +00:00
|
|
|
|
2020-09-18 02:02:13 +00:00
|
|
|
ret = paging_request_bts(params, bts);
|
2018-03-27 11:22:06 +00:00
|
|
|
if (ret == 0)
|
2020-09-18 00:49:15 +00:00
|
|
|
LOG_PAGING_BTS(params, bts, DMSC, LOGL_INFO,
|
|
|
|
"Paging request failed, or repeated paging on LAC %u\n", lac);
|
2018-01-05 16:22:11 +00:00
|
|
|
}
|
|
|
|
|
2018-01-16 14:18:27 +00:00
|
|
|
static void
|
2020-09-18 00:49:15 +00:00
|
|
|
page_all_bts(const struct bsc_paging_params *params)
|
2018-01-16 14:18:27 +00:00
|
|
|
{
|
|
|
|
struct gsm_bts *bts;
|
2020-09-18 00:49:15 +00:00
|
|
|
llist_for_each_entry(bts, &bsc_gsmnet->bts_list, list)
|
|
|
|
page_subscriber(params, bts, GSM_LAC_RESERVED_ALL_BTS);
|
2018-01-16 14:18:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2020-09-18 00:49:15 +00:00
|
|
|
page_cgi(const struct bsc_paging_params *params)
|
2018-01-16 14:18:27 +00:00
|
|
|
{
|
2018-03-14 15:34:48 +00:00
|
|
|
int i;
|
2020-09-18 00:49:15 +00:00
|
|
|
for (i = 0; i < params->cil.id_list_len; i++) {
|
|
|
|
const struct osmo_cell_global_id *id = ¶ms->cil.id_list[i].global;
|
|
|
|
if (!osmo_plmn_cmp(&id->lai.plmn, &bsc_gsmnet->plmn)) {
|
2018-01-16 14:18:27 +00:00
|
|
|
int paged = 0;
|
|
|
|
struct gsm_bts *bts;
|
2020-09-18 00:49:15 +00:00
|
|
|
llist_for_each_entry(bts, &bsc_gsmnet->bts_list, list) {
|
2018-03-14 15:34:48 +00:00
|
|
|
if (bts->location_area_code != id->lai.lac)
|
2018-01-16 14:18:27 +00:00
|
|
|
continue;
|
2018-03-14 15:34:48 +00:00
|
|
|
if (bts->cell_identity != id->cell_identity)
|
2018-01-16 14:18:27 +00:00
|
|
|
continue;
|
2020-09-18 00:49:15 +00:00
|
|
|
page_subscriber(params, bts, id->lai.lac);
|
2018-01-16 14:18:27 +00:00
|
|
|
paged = 1;
|
|
|
|
}
|
|
|
|
if (!paged) {
|
2020-09-18 00:49:15 +00:00
|
|
|
LOG_PAGING(params, DMSC, LOGL_NOTICE, "BTS with LAC %u and CI %u not found\n",
|
|
|
|
id->lai.lac, id->cell_identity);
|
2018-01-16 14:18:27 +00:00
|
|
|
}
|
|
|
|
} else {
|
2020-09-18 00:49:15 +00:00
|
|
|
LOG_PAGING(params, DMSC, LOGL_DEBUG,
|
|
|
|
"MCC-MNC in Cell Identifier List (%s) do not match our network (%s)\n",
|
|
|
|
osmo_plmn_name_c(OTC_SELECT, &id->lai.plmn),
|
|
|
|
osmo_plmn_name_c(OTC_SELECT, &bsc_gsmnet->plmn));
|
2018-01-16 14:18:27 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2020-09-18 00:49:15 +00:00
|
|
|
page_lac_and_ci(const struct bsc_paging_params *params)
|
2018-01-16 14:18:27 +00:00
|
|
|
{
|
2018-03-14 15:34:48 +00:00
|
|
|
int i;
|
|
|
|
|
2020-09-18 00:49:15 +00:00
|
|
|
for (i = 0; i < params->cil.id_list_len; i++) {
|
|
|
|
const struct osmo_lac_and_ci_id *id = ¶ms->cil.id_list[i].lac_and_ci;
|
2018-01-16 14:18:27 +00:00
|
|
|
int paged = 0;
|
|
|
|
struct gsm_bts *bts;
|
2020-09-18 00:49:15 +00:00
|
|
|
llist_for_each_entry(bts, &bsc_gsmnet->bts_list, list) {
|
2018-03-14 15:34:48 +00:00
|
|
|
if (bts->location_area_code != id->lac)
|
2018-01-16 14:18:27 +00:00
|
|
|
continue;
|
2018-03-14 15:34:48 +00:00
|
|
|
if (bts->cell_identity != id->ci)
|
2018-01-16 14:18:27 +00:00
|
|
|
continue;
|
2020-09-18 00:49:15 +00:00
|
|
|
page_subscriber(params, bts, id->lac);
|
2018-01-16 14:18:27 +00:00
|
|
|
paged = 1;
|
|
|
|
}
|
|
|
|
if (!paged) {
|
2020-09-18 00:49:15 +00:00
|
|
|
LOG_PAGING(params, DMSC, LOGL_NOTICE, "BTS with LAC %u and CI %u not found\n", id->lac, id->ci);
|
2018-01-16 14:18:27 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2020-09-18 00:49:15 +00:00
|
|
|
page_ci(const struct bsc_paging_params *params)
|
2018-01-16 14:18:27 +00:00
|
|
|
{
|
2018-03-14 15:34:48 +00:00
|
|
|
int i;
|
|
|
|
|
2020-09-18 00:49:15 +00:00
|
|
|
for (i = 0; i < params->cil.id_list_len; i++) {
|
|
|
|
uint16_t ci = params->cil.id_list[i].ci;
|
2018-01-16 14:18:27 +00:00
|
|
|
int paged = 0;
|
|
|
|
struct gsm_bts *bts;
|
2020-09-18 00:49:15 +00:00
|
|
|
llist_for_each_entry(bts, &bsc_gsmnet->bts_list, list) {
|
2018-01-16 14:18:27 +00:00
|
|
|
if (bts->cell_identity != ci)
|
|
|
|
continue;
|
2020-09-18 00:49:15 +00:00
|
|
|
page_subscriber(params, bts, GSM_LAC_RESERVED_ALL_BTS);
|
2018-01-16 14:18:27 +00:00
|
|
|
paged = 1;
|
|
|
|
}
|
|
|
|
if (!paged) {
|
2020-09-18 00:49:15 +00:00
|
|
|
LOG_PAGING(params, DMSC, LOGL_NOTICE, "BTS with CI %u not found\n", ci);
|
2018-01-16 14:18:27 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2020-09-18 00:49:15 +00:00
|
|
|
page_lai_and_lac(const struct bsc_paging_params *params)
|
2018-01-16 14:18:27 +00:00
|
|
|
{
|
2018-03-14 15:34:48 +00:00
|
|
|
int i;
|
|
|
|
|
2020-09-18 00:49:15 +00:00
|
|
|
for (i = 0; i < params->cil.id_list_len; i++) {
|
|
|
|
const struct osmo_location_area_id *id = ¶ms->cil.id_list[i].lai_and_lac;
|
|
|
|
if (!osmo_plmn_cmp(&id->plmn, &bsc_gsmnet->plmn)) {
|
2018-01-16 14:18:27 +00:00
|
|
|
int paged = 0;
|
|
|
|
struct gsm_bts *bts;
|
2020-09-18 00:49:15 +00:00
|
|
|
llist_for_each_entry(bts, &bsc_gsmnet->bts_list, list) {
|
2018-03-14 15:34:48 +00:00
|
|
|
if (bts->location_area_code != id->lac)
|
2018-01-16 14:18:27 +00:00
|
|
|
continue;
|
2020-09-18 00:49:15 +00:00
|
|
|
page_subscriber(params, bts, id->lac);
|
2018-01-16 14:18:27 +00:00
|
|
|
paged = 1;
|
|
|
|
}
|
|
|
|
if (!paged) {
|
2020-09-18 00:49:15 +00:00
|
|
|
LOG_PAGING(params, DMSC, LOGL_NOTICE, "BTS with LAC %u not found\n", id->lac);
|
2018-01-16 14:18:27 +00:00
|
|
|
}
|
|
|
|
} else {
|
2020-09-18 00:49:15 +00:00
|
|
|
LOG_PAGING(params, DMSC, LOGL_DEBUG,
|
|
|
|
"MCC-MNC in Cell Identifier List (%s) do not match our network (%s)\n",
|
|
|
|
osmo_plmn_name_c(OTC_SELECT, &id->plmn),
|
|
|
|
osmo_plmn_name_c(OTC_SELECT, &bsc_gsmnet->plmn));
|
2018-01-16 14:18:27 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2020-09-18 00:49:15 +00:00
|
|
|
page_lac(const struct bsc_paging_params *params)
|
2018-01-16 14:18:27 +00:00
|
|
|
{
|
2018-03-14 15:34:48 +00:00
|
|
|
int i;
|
|
|
|
|
2020-09-18 00:49:15 +00:00
|
|
|
for (i = 0; i < params->cil.id_list_len; i++) {
|
|
|
|
uint16_t lac = params->cil.id_list[i].lac;
|
2018-01-16 14:18:27 +00:00
|
|
|
int paged = 0;
|
|
|
|
struct gsm_bts *bts;
|
2020-09-18 00:49:15 +00:00
|
|
|
llist_for_each_entry(bts, &bsc_gsmnet->bts_list, list) {
|
2018-01-16 14:18:27 +00:00
|
|
|
if (bts->location_area_code != lac)
|
|
|
|
continue;
|
2020-09-18 00:49:15 +00:00
|
|
|
page_subscriber(params, bts, lac);
|
2018-01-16 14:18:27 +00:00
|
|
|
paged = 1;
|
|
|
|
}
|
|
|
|
if (!paged) {
|
2020-09-18 00:49:15 +00:00
|
|
|
LOG_PAGING(params, DMSC, LOGL_NOTICE, "BTS with LAC %u not found\n", lac);
|
2018-01-16 14:18:27 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-11-10 08:24:37 +00:00
|
|
|
/* GSM 08.08 § 3.2.1.19 */
|
2017-02-23 20:57:23 +00:00
|
|
|
static int bssmap_handle_paging(struct bsc_msc_data *msc,
|
2010-11-10 08:24:37 +00:00
|
|
|
struct msgb *msg, unsigned int payload_length)
|
|
|
|
{
|
|
|
|
struct tlv_parsed tp;
|
|
|
|
uint8_t data_length;
|
2018-01-05 16:22:11 +00:00
|
|
|
int remain;
|
2010-11-10 08:24:37 +00:00
|
|
|
const uint8_t *data;
|
2020-09-18 00:49:15 +00:00
|
|
|
struct bsc_paging_params paging = {
|
2020-09-18 00:49:21 +00:00
|
|
|
.reason = BSC_PAGING_FROM_CN,
|
2020-09-18 00:49:15 +00:00
|
|
|
.msc = msc,
|
|
|
|
.tmsi = GSM_RESERVED_TMSI,
|
|
|
|
};
|
2010-11-10 08:24:37 +00:00
|
|
|
|
|
|
|
tlv_parse(&tp, gsm0808_att_tlvdef(), msg->l4h + 1, payload_length - 1, 0, 0);
|
2018-01-05 16:22:11 +00:00
|
|
|
remain = payload_length - 1;
|
2010-11-10 08:24:37 +00:00
|
|
|
|
|
|
|
if (!TLVP_PRESENT(&tp, GSM0808_IE_IMSI)) {
|
2012-08-03 09:05:29 +00:00
|
|
|
LOGP(DMSC, LOGL_ERROR, "Mandatory IMSI not present.\n");
|
2010-11-10 08:24:37 +00:00
|
|
|
return -1;
|
|
|
|
} else if ((TLVP_VAL(&tp, GSM0808_IE_IMSI)[0] & GSM_MI_TYPE_MASK) != GSM_MI_TYPE_IMSI) {
|
|
|
|
LOGP(DMSC, LOGL_ERROR, "Wrong content in the IMSI\n");
|
|
|
|
return -1;
|
|
|
|
}
|
2018-01-05 16:22:11 +00:00
|
|
|
remain -= TLVP_LEN(&tp, GSM0808_IE_IMSI);
|
2010-11-10 08:24:37 +00:00
|
|
|
|
|
|
|
if (!TLVP_PRESENT(&tp, GSM0808_IE_CELL_IDENTIFIER_LIST)) {
|
2012-08-03 09:05:29 +00:00
|
|
|
LOGP(DMSC, LOGL_ERROR, "Mandatory CELL IDENTIFIER LIST not present.\n");
|
2010-11-10 08:24:37 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2012-01-20 16:20:51 +00:00
|
|
|
if (TLVP_PRESENT(&tp, GSM0808_IE_TMSI) &&
|
|
|
|
TLVP_LEN(&tp, GSM0808_IE_TMSI) == 4) {
|
2020-09-18 00:49:15 +00:00
|
|
|
paging.tmsi = ntohl(tlvp_val32_unal(&tp, GSM0808_IE_TMSI));
|
2018-01-05 16:22:11 +00:00
|
|
|
remain -= TLVP_LEN(&tp, GSM0808_IE_TMSI);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (remain <= 0) {
|
|
|
|
LOGP(DMSC, LOGL_ERROR, "Payload too short.\n");
|
|
|
|
return -1;
|
2010-11-10 08:24:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* parse the IMSI
|
|
|
|
*/
|
2020-09-18 00:49:15 +00:00
|
|
|
if (osmo_mobile_identity_decode(&paging.imsi, TLVP_VAL(&tp, GSM0808_IE_IMSI), TLVP_LEN(&tp, GSM0808_IE_IMSI), false)
|
|
|
|
|| paging.imsi.type != GSM_MI_TYPE_IMSI) {
|
2020-05-29 01:53:59 +00:00
|
|
|
LOGP(DMSC, LOGL_ERROR, "Paging: could not parse IMSI\n");
|
|
|
|
return -1;
|
|
|
|
}
|
2010-11-10 08:24:37 +00:00
|
|
|
|
|
|
|
/*
|
2017-11-07 02:38:28 +00:00
|
|
|
* There are various cell identifier list types defined at 3GPP TS § 08.08, we don't support all
|
|
|
|
* of them yet. To not disrupt paging operation just because we're lacking some implementation,
|
|
|
|
* interpret any unknown cell identifier type as "page the entire BSS".
|
2010-11-10 08:24:37 +00:00
|
|
|
*/
|
|
|
|
data_length = TLVP_LEN(&tp, GSM0808_IE_CELL_IDENTIFIER_LIST);
|
|
|
|
data = TLVP_VAL(&tp, GSM0808_IE_CELL_IDENTIFIER_LIST);
|
2020-09-18 00:49:15 +00:00
|
|
|
if (gsm0808_dec_cell_id_list2(&paging.cil, data, data_length) < 0) {
|
|
|
|
LOG_PAGING(&paging, DMSC, LOGL_ERROR, "Could not parse Cell Identifier List\n");
|
2018-01-05 16:22:11 +00:00
|
|
|
return -1;
|
|
|
|
}
|
2020-09-18 00:49:15 +00:00
|
|
|
if (paging.cil.id_discr == CELL_IDENT_BSS && data_length != 1) {
|
|
|
|
LOG_PAGING(&paging, DMSC, LOGL_ERROR, "Cell Identifier List for BSS (0x%x)"
|
|
|
|
" has invalid length: %u, paging entire BSS anyway (%s)\n",
|
|
|
|
CELL_IDENT_BSS, data_length, osmo_hexdump(data, data_length));
|
|
|
|
}
|
2018-03-14 15:34:48 +00:00
|
|
|
remain = 0;
|
2018-01-05 16:22:11 +00:00
|
|
|
|
|
|
|
if (TLVP_PRESENT(&tp, GSM0808_IE_CHANNEL_NEEDED) && TLVP_LEN(&tp, GSM0808_IE_CHANNEL_NEEDED) == 1)
|
2020-09-18 00:49:15 +00:00
|
|
|
paging.chan_needed = TLVP_VAL(&tp, GSM0808_IE_CHANNEL_NEEDED)[0] & 0x03;
|
2018-01-05 16:22:11 +00:00
|
|
|
|
|
|
|
if (TLVP_PRESENT(&tp, GSM0808_IE_EMLPP_PRIORITY)) {
|
2020-09-18 00:49:15 +00:00
|
|
|
LOG_PAGING(&paging, DMSC, LOGL_ERROR, "eMLPP IE present, but eMLPP is not handled\n");
|
2010-11-10 08:24:37 +00:00
|
|
|
}
|
|
|
|
|
2020-09-18 00:49:32 +00:00
|
|
|
return bsc_paging_start(&paging);
|
|
|
|
}
|
|
|
|
|
|
|
|
int bsc_paging_start(struct bsc_paging_params *params)
|
|
|
|
{
|
|
|
|
rate_ctr_inc(&bsc_gsmnet->bsc_ctrs->ctr[BSC_CTR_PAGING_ATTEMPTED]);
|
2018-02-23 16:57:13 +00:00
|
|
|
|
2020-09-18 02:02:13 +00:00
|
|
|
if (!params->bsub) {
|
2020-09-15 01:03:58 +00:00
|
|
|
params->bsub = bsc_subscr_find_or_create_by_imsi(bsc_gsmnet->bsc_subscribers, params->imsi.imsi,
|
|
|
|
BSUB_USE_PAGING_START);
|
2020-09-18 02:02:13 +00:00
|
|
|
if (!params->bsub) {
|
|
|
|
LOG_PAGING(params, DMSC, LOGL_ERROR, "Paging request failed: Could not allocate subscriber\n");
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (params->tmsi != GSM_RESERVED_TMSI)
|
|
|
|
params->bsub->tmsi = params->tmsi;
|
|
|
|
log_set_context(LOG_CTX_BSC_SUBSCR, params->bsub);
|
|
|
|
|
2020-09-18 00:49:15 +00:00
|
|
|
switch (params->cil.id_discr) {
|
2018-01-09 15:09:08 +00:00
|
|
|
case CELL_IDENT_NO_CELL:
|
2020-09-18 00:49:15 +00:00
|
|
|
page_all_bts(params);
|
2018-02-23 12:06:05 +00:00
|
|
|
break;
|
2018-01-09 15:09:08 +00:00
|
|
|
|
2018-01-16 14:18:27 +00:00
|
|
|
case CELL_IDENT_WHOLE_GLOBAL:
|
2020-09-18 00:49:15 +00:00
|
|
|
page_cgi(params);
|
2018-01-11 16:49:02 +00:00
|
|
|
break;
|
2018-01-09 16:50:56 +00:00
|
|
|
|
2018-01-16 14:18:27 +00:00
|
|
|
case CELL_IDENT_LAC_AND_CI:
|
2020-09-18 00:49:15 +00:00
|
|
|
page_lac_and_ci(params);
|
2018-01-16 14:18:27 +00:00
|
|
|
break;
|
2018-01-09 16:50:56 +00:00
|
|
|
|
2018-01-16 14:18:27 +00:00
|
|
|
case CELL_IDENT_CI:
|
2020-09-18 00:49:15 +00:00
|
|
|
page_ci(params);
|
2018-01-09 16:50:56 +00:00
|
|
|
break;
|
|
|
|
|
2018-01-16 14:18:27 +00:00
|
|
|
case CELL_IDENT_LAI_AND_LAC:
|
2020-09-18 00:49:15 +00:00
|
|
|
page_lai_and_lac(params);
|
2018-01-05 16:22:11 +00:00
|
|
|
break;
|
|
|
|
|
2017-11-07 02:38:28 +00:00
|
|
|
case CELL_IDENT_LAC:
|
2020-09-18 00:49:15 +00:00
|
|
|
page_lac(params);
|
2017-11-07 02:38:28 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case CELL_IDENT_BSS:
|
2020-09-18 00:49:15 +00:00
|
|
|
page_all_bts(params);
|
2017-11-07 02:38:28 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
2020-09-18 00:49:15 +00:00
|
|
|
LOG_PAGING(params, DMSC, LOGL_NOTICE,
|
|
|
|
"unimplemented Cell Identifier List type (0x%x), paging entire BSS instead\n",
|
|
|
|
params->cil.id_discr);
|
|
|
|
page_all_bts(params);
|
2017-11-07 02:38:28 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2020-09-15 01:03:58 +00:00
|
|
|
bsc_subscr_put(params->bsub, BSUB_USE_PAGING_START);
|
2020-09-18 02:02:13 +00:00
|
|
|
log_set_context(LOG_CTX_BSC_SUBSCR, NULL);
|
2010-11-15 08:16:09 +00:00
|
|
|
return 0;
|
2010-11-10 08:24:37 +00:00
|
|
|
}
|
|
|
|
|
2017-12-23 16:30:18 +00:00
|
|
|
/* select the best cipher permitted by the intersection of both masks */
|
|
|
|
static int select_best_cipher(uint8_t msc_mask, uint8_t bsc_mask)
|
|
|
|
{
|
2021-01-25 16:59:06 +00:00
|
|
|
/* A5/7 ... A5/3: We assume higher is better,
|
|
|
|
* but: A5/1 is better than A5/2, which is better than A5/0 */
|
|
|
|
const uint8_t codec_strength[8] = { 7, 6, 5, 4, 3, 1, 2, 0 };
|
2017-12-23 16:30:18 +00:00
|
|
|
uint8_t intersection = msc_mask & bsc_mask;
|
|
|
|
int i;
|
|
|
|
|
2021-01-25 16:59:06 +00:00
|
|
|
for (i = 0; i < ARRAY_SIZE(codec_strength); i++) {
|
|
|
|
uint8_t codec = codec_strength[i];
|
|
|
|
if (intersection & (1 << codec))
|
|
|
|
return codec;
|
2017-12-23 16:30:18 +00:00
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2018-07-24 15:13:03 +00:00
|
|
|
/*! We received a GSM 08.08 CIPHER MODE from the MSC */
|
|
|
|
static int gsm0808_cipher_mode(struct gsm_subscriber_connection *conn, int cipher,
|
|
|
|
const uint8_t *key, int len, int include_imeisv)
|
|
|
|
{
|
|
|
|
if (cipher > 0 && key == NULL) {
|
|
|
|
LOGP(DRSL, LOGL_ERROR, "%s: Need to have an encryption key.\n",
|
|
|
|
bsc_subscr_name(conn->bsub));
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (len > MAX_A5_KEY_LEN) {
|
|
|
|
LOGP(DRSL, LOGL_ERROR, "%s: The key is too long: %d\n",
|
|
|
|
bsc_subscr_name(conn->bsub), len);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2019-02-03 11:11:12 +00:00
|
|
|
static int bssmap_handle_clear_cmd(struct gsm_subscriber_connection *conn,
|
|
|
|
struct msgb *msg, unsigned int length)
|
|
|
|
{
|
|
|
|
struct tlv_parsed tp;
|
2021-04-12 18:19:30 +00:00
|
|
|
enum gsm0808_cause cause_0808;
|
2019-02-03 11:11:12 +00:00
|
|
|
|
|
|
|
tlv_parse(&tp, gsm0808_att_tlvdef(), msg->l4h + 1, length - 1, 0, 0);
|
|
|
|
|
2021-04-12 18:19:30 +00:00
|
|
|
cause_0808 = gsm0808_get_cause(&tp);
|
|
|
|
if (cause_0808 < 0) {
|
RR Channel Release: pass Cause code from BSSMAP Clear to the BTS
In lchan.release, add 'cause_rr', and set RR Channel Release message's cause
value to lchan.release.cause_rr.
In lchan_release(), do not set lchan.release.rsl_error_cause to the RR cause
value, these are unrelated. Store in new lchan.release.cause_rr instead. The
rsl_error_cause is apparently only used for logging, except for one place in
lchan_fsm_wait_activ_ack() that compares it to RSL_ERR_RCH_ALR_ACTV_ALLOC, so
there should not be a functional difference by this fix.
Propagate the BSSMAP Clear Command cause to the RR Channel Release:
Add struct gscon_clear_cmd_data as event data for GSCON_EV_A_CLEAR_CMD -- so
far it sent the is_csfb flag, add the gsm0808_cause; invoking the event happens
in bssmap_handle_clear_cmd().
Adjust event handling in gscon_fsm_allstate(); there, pass the cause to
gscon_release_lchans(). In gscon_release_lchans(), pass the cause to
gscon_release_lchan(), and then lchan_release(), which sets the new
lchan.release.cause_rr to the passed cause value.
As soon as the lchan FSM enters the proper state, it calls
gsm48_send_rr_release(). There, set the cause value in the encoded message to
lchan.release.cause_rr.
Interworking with osmo-msc: so far, osmo-msc fails to set the Clear Command
cause code for normal release, it just passes 0 which amounts to
GSM0808_CAUSE_RADIO_INTERFACE_MESSAGE_FAILURE. Before this patch, osmo-bsc
always sent GSM48_RR_CAUSE_NORMAL in the RR Channel Release, and after this
patch it will receive 0 == GSM0808_CAUSE_RADIO_INTERFACE_MESSAGE_FAILURE from
osmo-msc and more accurately translate that to GSM48_RR_CAUSE_PROT_ERROR_UNSPC.
This means in practice that we will now see an error cause in RR Channel
Release instead of GSM48_RR_CAUSE_NORMAL when working with osmo-msc. For
changing osmo-msc to send GSM0808_CAUSE_CALL_CONTROL instead (which translates
to GSM48_RR_CAUSE_NORMAL), see OS#4664 and change-id
I1347ed72ae7d7ea73a557b866e764819c5ef8c42 (osmo-msc).
A test for this is in Ie6c99f28b610a67f2d59ec00b3541940e882251b
(osmo-ttcn3-hacks).
Related: SYS#4872
Change-Id: I734cc55c501d61bbdadee81a223b26f9df57f959
2020-07-09 13:54:40 +00:00
|
|
|
LOGPFSML(conn->fi, LOGL_ERROR, "Clear Command: Mandatory Cause IE not present.\n");
|
|
|
|
/* Clear anyway, but without a proper cause. */
|
2021-04-12 18:19:30 +00:00
|
|
|
cause_0808 = GSM0808_CAUSE_RADIO_INTERFACE_MESSAGE_FAILURE;
|
RR Channel Release: pass Cause code from BSSMAP Clear to the BTS
In lchan.release, add 'cause_rr', and set RR Channel Release message's cause
value to lchan.release.cause_rr.
In lchan_release(), do not set lchan.release.rsl_error_cause to the RR cause
value, these are unrelated. Store in new lchan.release.cause_rr instead. The
rsl_error_cause is apparently only used for logging, except for one place in
lchan_fsm_wait_activ_ack() that compares it to RSL_ERR_RCH_ALR_ACTV_ALLOC, so
there should not be a functional difference by this fix.
Propagate the BSSMAP Clear Command cause to the RR Channel Release:
Add struct gscon_clear_cmd_data as event data for GSCON_EV_A_CLEAR_CMD -- so
far it sent the is_csfb flag, add the gsm0808_cause; invoking the event happens
in bssmap_handle_clear_cmd().
Adjust event handling in gscon_fsm_allstate(); there, pass the cause to
gscon_release_lchans(). In gscon_release_lchans(), pass the cause to
gscon_release_lchan(), and then lchan_release(), which sets the new
lchan.release.cause_rr to the passed cause value.
As soon as the lchan FSM enters the proper state, it calls
gsm48_send_rr_release(). There, set the cause value in the encoded message to
lchan.release.cause_rr.
Interworking with osmo-msc: so far, osmo-msc fails to set the Clear Command
cause code for normal release, it just passes 0 which amounts to
GSM0808_CAUSE_RADIO_INTERFACE_MESSAGE_FAILURE. Before this patch, osmo-bsc
always sent GSM48_RR_CAUSE_NORMAL in the RR Channel Release, and after this
patch it will receive 0 == GSM0808_CAUSE_RADIO_INTERFACE_MESSAGE_FAILURE from
osmo-msc and more accurately translate that to GSM48_RR_CAUSE_PROT_ERROR_UNSPC.
This means in practice that we will now see an error cause in RR Channel
Release instead of GSM48_RR_CAUSE_NORMAL when working with osmo-msc. For
changing osmo-msc to send GSM0808_CAUSE_CALL_CONTROL instead (which translates
to GSM48_RR_CAUSE_NORMAL), see OS#4664 and change-id
I1347ed72ae7d7ea73a557b866e764819c5ef8c42 (osmo-msc).
A test for this is in Ie6c99f28b610a67f2d59ec00b3541940e882251b
(osmo-ttcn3-hacks).
Related: SYS#4872
Change-Id: I734cc55c501d61bbdadee81a223b26f9df57f959
2020-07-09 13:54:40 +00:00
|
|
|
}
|
|
|
|
|
2021-04-12 18:19:30 +00:00
|
|
|
if (TLVP_PRESENT(&tp, GSM0808_IE_CSFB_INDICATION) &&
|
|
|
|
!conn->last_eutran_plmn_valid) {
|
|
|
|
LOGPFSML(conn->fi, LOGL_NOTICE,
|
|
|
|
"Clear Command: CSFB Indication present, "
|
|
|
|
"but subscriber has no Last Used E-UTRAN PLMN Id! "
|
|
|
|
"This probably means MSC doesn't support proper return "
|
|
|
|
"to the last used PLMN after CS fallback.\n");
|
|
|
|
}
|
2019-02-03 11:11:12 +00:00
|
|
|
|
2021-04-12 18:19:30 +00:00
|
|
|
osmo_fsm_inst_dispatch(conn->fi, GSCON_EV_A_CLEAR_CMD, &cause_0808);
|
2019-02-03 11:11:12 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2010-11-10 08:44:34 +00:00
|
|
|
/*
|
2018-10-17 12:35:21 +00:00
|
|
|
* GSM 08.08 § 3.1.14 cipher mode handling. We will have to pick
|
2010-11-10 08:44:34 +00:00
|
|
|
* the cipher to be used for this. In case we are already using
|
|
|
|
* a cipher we will have to send cipher mode reject to the MSC,
|
|
|
|
* otherwise we will have to pick something that we and the MS
|
|
|
|
* is supporting. Currently we are doing it in a rather static
|
2017-12-18 17:11:51 +00:00
|
|
|
* way by picking one encryption or no encryption.
|
2010-11-10 08:44:34 +00:00
|
|
|
*/
|
2018-01-28 01:45:46 +00:00
|
|
|
static int bssmap_handle_cipher_mode(struct gsm_subscriber_connection *conn,
|
2010-11-10 08:44:34 +00:00
|
|
|
struct msgb *msg, unsigned int payload_length)
|
|
|
|
{
|
|
|
|
uint16_t len;
|
|
|
|
const uint8_t *data;
|
|
|
|
struct tlv_parsed tp;
|
|
|
|
struct msgb *resp;
|
|
|
|
int reject_cause = -1;
|
|
|
|
int include_imeisv = 1;
|
2018-01-07 17:35:40 +00:00
|
|
|
const uint8_t *enc_key;
|
2017-12-14 04:16:10 +00:00
|
|
|
uint16_t enc_key_len;
|
|
|
|
uint8_t enc_bits_msc;
|
2017-12-23 16:30:18 +00:00
|
|
|
int chosen_cipher;
|
2010-11-10 08:44:34 +00:00
|
|
|
|
2020-11-09 15:54:13 +00:00
|
|
|
if (!conn || !conn->lchan) {
|
2010-11-10 08:44:34 +00:00
|
|
|
LOGP(DMSC, LOGL_ERROR, "No lchan/msc_data in cipher mode command.\n");
|
2018-10-21 10:50:09 +00:00
|
|
|
return -1;
|
2010-11-10 08:44:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (conn->ciphering_handled) {
|
|
|
|
LOGP(DMSC, LOGL_ERROR, "Already seen ciphering command. Protocol Error.\n");
|
2018-10-23 12:17:45 +00:00
|
|
|
reject_cause = GSM0808_CAUSE_PROTOCOL_ERROR_BETWEEN_BSS_AND_MSC;
|
2010-11-10 08:44:34 +00:00
|
|
|
goto reject;
|
|
|
|
}
|
|
|
|
|
|
|
|
conn->ciphering_handled = 1;
|
|
|
|
|
|
|
|
tlv_parse(&tp, gsm0808_att_tlvdef(), msg->l4h + 1, payload_length - 1, 0, 0);
|
|
|
|
if (!TLVP_PRESENT(&tp, GSM0808_IE_ENCRYPTION_INFORMATION)) {
|
|
|
|
LOGP(DMSC, LOGL_ERROR, "IE Encryption Information missing.\n");
|
2018-10-23 12:17:45 +00:00
|
|
|
reject_cause = GSM0808_CAUSE_INFORMATION_ELEMENT_OR_FIELD_MISSING;
|
2010-11-10 08:44:34 +00:00
|
|
|
goto reject;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* check if our global setting is allowed
|
|
|
|
* - Currently we check for A5/0 and A5/1
|
|
|
|
* - Copy the key if that is necessary
|
|
|
|
* - Otherwise reject
|
|
|
|
*/
|
|
|
|
len = TLVP_LEN(&tp, GSM0808_IE_ENCRYPTION_INFORMATION);
|
|
|
|
if (len < 1) {
|
|
|
|
LOGP(DMSC, LOGL_ERROR, "IE Encryption Information is too short.\n");
|
2018-10-23 12:17:45 +00:00
|
|
|
reject_cause = GSM0808_CAUSE_INCORRECT_VALUE;
|
2010-11-10 08:44:34 +00:00
|
|
|
goto reject;
|
|
|
|
}
|
|
|
|
|
|
|
|
data = TLVP_VAL(&tp, GSM0808_IE_ENCRYPTION_INFORMATION);
|
2017-12-14 04:16:10 +00:00
|
|
|
enc_bits_msc = data[0];
|
|
|
|
enc_key = &data[1];
|
|
|
|
enc_key_len = len - 1;
|
2010-11-10 08:44:34 +00:00
|
|
|
|
|
|
|
if (TLVP_PRESENT(&tp, GSM0808_IE_CIPHER_RESPONSE_MODE))
|
|
|
|
include_imeisv = TLVP_VAL(&tp, GSM0808_IE_CIPHER_RESPONSE_MODE)[0] & 0x1;
|
|
|
|
|
2017-12-14 04:16:10 +00:00
|
|
|
/* Identical to the GSM0808_IE_ENCRYPTION_INFORMATION above:
|
|
|
|
* a5_encryption == 0 --> 0x01
|
|
|
|
* a5_encryption == 1 --> 0x02
|
|
|
|
* a5_encryption == 2 --> 0x04 ... */
|
|
|
|
enc_bits_msc = data[0];
|
|
|
|
|
2017-12-23 16:30:18 +00:00
|
|
|
/* The bit-mask of permitted ciphers from the MSC (sent in ASSIGNMENT COMMAND) is intersected
|
|
|
|
* with the vty-configured mask a the BSC. Finally, the best (highest) possible cipher is
|
|
|
|
* chosen. */
|
2020-06-18 15:29:56 +00:00
|
|
|
chosen_cipher = select_best_cipher(enc_bits_msc, bsc_gsmnet->a5_encryption_mask);
|
2017-12-23 16:30:18 +00:00
|
|
|
if (chosen_cipher < 0) {
|
|
|
|
LOGP(DMSC, LOGL_ERROR, "Reject: no overlapping A5 ciphers between BSC (0x%02x) "
|
2020-06-18 15:29:56 +00:00
|
|
|
"and MSC (0x%02x)\n", bsc_gsmnet->a5_encryption_mask, enc_bits_msc);
|
2017-12-14 04:16:10 +00:00
|
|
|
reject_cause = GSM0808_CAUSE_CIPHERING_ALGORITHM_NOT_SUPPORTED;
|
2010-11-10 08:44:34 +00:00
|
|
|
goto reject;
|
|
|
|
}
|
|
|
|
|
2017-12-14 04:16:10 +00:00
|
|
|
/* To complete the confusion, gsm0808_cipher_mode again expects the encryption as a number
|
|
|
|
* from 0 to 7. */
|
2017-12-23 16:30:18 +00:00
|
|
|
if (gsm0808_cipher_mode(conn, chosen_cipher, enc_key, enc_key_len,
|
2017-12-14 04:16:10 +00:00
|
|
|
include_imeisv)) {
|
|
|
|
reject_cause = GSM0808_CAUSE_PROTOCOL_ERROR_BETWEEN_BSS_AND_MSC;
|
|
|
|
goto reject;
|
|
|
|
}
|
2011-07-11 22:03:43 +00:00
|
|
|
return 0;
|
|
|
|
|
2010-11-10 08:44:34 +00:00
|
|
|
reject:
|
|
|
|
resp = gsm0808_create_cipher_reject(reject_cause);
|
|
|
|
if (!resp) {
|
|
|
|
LOGP(DMSC, LOGL_ERROR, "Sending the cipher reject failed.\n");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2020-05-09 18:27:40 +00:00
|
|
|
rate_ctr_inc(&conn->sccp.msc->msc_ctrs->ctr[MSC_CTR_BSSMAP_TX_DT1_CIPHER_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
|
|
|
osmo_fsm_inst_dispatch(conn->fi, GSCON_EV_TX_SCCP, resp);
|
2010-11-10 08:44:34 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2018-05-29 23:39:43 +00:00
|
|
|
/* handle LCLS specific IES in BSSMAP ASS REQ */
|
|
|
|
static void bssmap_handle_ass_req_lcls(struct gsm_subscriber_connection *conn,
|
|
|
|
const struct tlv_parsed *tp)
|
|
|
|
{
|
2020-02-12 15:37:56 +00:00
|
|
|
const uint8_t *config, *control, *gcr;
|
|
|
|
uint8_t gcr_len;
|
|
|
|
|
|
|
|
/* TS 48.008 sec 3.2.2.115 Global Call Reference */
|
|
|
|
if (TLVP_PRESENT(tp, GSM0808_IE_GLOBAL_CALL_REF)) {
|
|
|
|
gcr = TLVP_VAL(tp, GSM0808_IE_GLOBAL_CALL_REF);
|
|
|
|
gcr_len = TLVP_LEN(tp, GSM0808_IE_GLOBAL_CALL_REF);
|
|
|
|
if (gcr_len > sizeof(conn->lcls.global_call_ref)) {
|
|
|
|
LOGPFSML(conn->fi, LOGL_ERROR, "Global Call Ref IE of %u bytes is too long: %s\n",
|
|
|
|
gcr_len, osmo_hexdump_nospc(gcr, gcr_len));
|
|
|
|
} else if (gcr_len < 13) { /* FIXME: document this magic value 13 */
|
|
|
|
LOGPFSML(conn->fi, LOGL_ERROR, "Global Call Ref IE of %u bytes is too short: %s\n",
|
|
|
|
gcr_len, osmo_hexdump_nospc(gcr, gcr_len));
|
|
|
|
} else {
|
2018-11-08 14:17:21 +00:00
|
|
|
LOGPFSM(conn->fi, "Setting GCR to %s\n", osmo_hexdump_nospc(gcr, gcr_len));
|
|
|
|
memcpy(&conn->lcls.global_call_ref, gcr, gcr_len);
|
|
|
|
conn->lcls.global_call_ref_len = gcr_len;
|
2020-02-12 15:37:56 +00:00
|
|
|
}
|
2018-05-29 23:39:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
config = TLVP_VAL_MINLEN(tp, GSM0808_IE_LCLS_CONFIG, 1);
|
|
|
|
control = TLVP_VAL_MINLEN(tp, GSM0808_IE_LCLS_CONN_STATUS_CTRL, 1);
|
|
|
|
|
|
|
|
if (config || control) {
|
|
|
|
LOGPFSM(conn->fi, "BSSMAP ASS REQ contains LCLS (%s / %s)\n",
|
|
|
|
config ? gsm0808_lcls_config_name(*config) : "NULL",
|
|
|
|
control ? gsm0808_lcls_control_name(*control) : "NULL");
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Update the LCLS state with Config + CSC (if any) */
|
|
|
|
lcls_update_config(conn, config, control);
|
|
|
|
|
|
|
|
/* Do not attempt to perform correlation yet, as during processing of the ASS REQ
|
|
|
|
* we don't have the MGCP/MGW connections yet, and hence couldn't enable LS. */
|
|
|
|
}
|
|
|
|
|
|
|
|
/* TS 48.008 3.2.1.91 */
|
|
|
|
static int bssmap_handle_lcls_connect_ctrl(struct gsm_subscriber_connection *conn,
|
|
|
|
struct msgb *msg, unsigned int length)
|
|
|
|
{
|
|
|
|
struct msgb *resp;
|
|
|
|
struct tlv_parsed tp;
|
|
|
|
const uint8_t *config, *control;
|
|
|
|
int rc;
|
|
|
|
|
|
|
|
OSMO_ASSERT(conn);
|
|
|
|
|
|
|
|
rc = tlv_parse(&tp, gsm0808_att_tlvdef(), msg->l4h + 1, length - 1, 0, 0);
|
|
|
|
if (rc < 0) {
|
|
|
|
LOGPFSML(conn->fi, LOGL_ERROR, "Error parsing TLVs of LCLS CONNT CTRL: %s\n",
|
|
|
|
msgb_hexdump(msg));
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
config = TLVP_VAL_MINLEN(&tp, GSM0808_IE_LCLS_CONFIG, 1);
|
|
|
|
control = TLVP_VAL_MINLEN(&tp, GSM0808_IE_LCLS_CONN_STATUS_CTRL, 1);
|
|
|
|
|
|
|
|
LOGPFSM(conn->fi, "Rx LCLS CONNECT CTRL (%s / %s)\n",
|
|
|
|
config ? gsm0808_lcls_config_name(*config) : "NULL",
|
|
|
|
control ? gsm0808_lcls_control_name(*control) : "NULL");
|
|
|
|
|
|
|
|
if (conn->lcls.global_call_ref_len == 0) {
|
|
|
|
LOGPFSML(conn->fi, LOGL_ERROR, "Ignoring LCLS as no GCR was set before\n");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
/* Update the LCLS state with Config + CSC (if any) */
|
|
|
|
lcls_update_config(conn, TLVP_VAL_MINLEN(&tp, GSM0808_IE_LCLS_CONFIG, 1),
|
|
|
|
TLVP_VAL_MINLEN(&tp, GSM0808_IE_LCLS_CONN_STATUS_CTRL, 1));
|
|
|
|
lcls_apply_config(conn);
|
|
|
|
|
|
|
|
LOGPFSM(conn->fi, "Tx LCLS CONNECT CTRL ACK (%s)\n",
|
|
|
|
gsm0808_lcls_status_name(lcls_get_status(conn)));
|
|
|
|
resp = gsm0808_create_lcls_conn_ctrl_ack(lcls_get_status(conn));
|
2020-05-09 18:27:40 +00:00
|
|
|
rate_ctr_inc(&conn->sccp.msc->msc_ctrs->ctr[MSC_CTR_BSSMAP_TX_DT1_LCLS_CONNECT_CTRL_ACK]);
|
2018-05-29 23:39:43 +00:00
|
|
|
osmo_fsm_inst_dispatch(conn->fi, GSCON_EV_TX_SCCP, resp);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2019-11-13 21:10:41 +00:00
|
|
|
/* Select a preferred and an alternative codec rate depending on the available
|
2019-01-22 10:29:06 +00:00
|
|
|
* capabilities. This decision does not include the actual channel load yet,
|
2019-11-13 21:10:41 +00:00
|
|
|
* this is also the reason why the result is a preferred and an alternate
|
2019-01-22 10:29:06 +00:00
|
|
|
* setting. The final decision is made in assignment_fsm.c when the actual
|
|
|
|
* lchan is requested. The preferred lchan will be requested first. If we
|
|
|
|
* find an alternate setting here, this one will be tried secondly if our
|
2019-11-13 21:10:41 +00:00
|
|
|
* primary choice fails. */
|
2019-01-22 10:29:06 +00:00
|
|
|
static int select_codecs(struct assignment_request *req, struct gsm0808_channel_type *ct,
|
|
|
|
struct gsm_subscriber_connection *conn)
|
|
|
|
{
|
2019-03-07 15:32:02 +00:00
|
|
|
int rc, i, nc = 0;
|
2019-01-22 10:29:06 +00:00
|
|
|
struct bsc_msc_data *msc;
|
2020-06-18 15:29:56 +00:00
|
|
|
struct gsm_bts *bts = conn_get_bts(conn);
|
|
|
|
|
|
|
|
if (!bts) {
|
|
|
|
LOGP(DMSC, LOGL_ERROR, "No lchan, cannot select codecs\n");
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
2019-01-22 10:29:06 +00:00
|
|
|
|
|
|
|
msc = conn->sccp.msc;
|
|
|
|
|
|
|
|
switch (ct->ch_rate_type) {
|
|
|
|
case GSM0808_SPEECH_FULL_BM:
|
2021-04-27 23:17:14 +00:00
|
|
|
rc = match_codec_pref(&req->ch_mode_rate_list[nc], ct, &conn->codec_list, msc, bts,
|
2019-01-22 10:29:06 +00:00
|
|
|
RATE_PREF_FR);
|
2021-04-28 15:22:57 +00:00
|
|
|
nc += (rc == 0) ? 1 : 0;
|
2019-01-22 10:29:06 +00:00
|
|
|
break;
|
|
|
|
case GSM0808_SPEECH_HALF_LM:
|
2021-04-27 23:17:14 +00:00
|
|
|
rc = match_codec_pref(&req->ch_mode_rate_list[nc], ct, &conn->codec_list, msc, bts,
|
2019-01-22 10:29:06 +00:00
|
|
|
RATE_PREF_HR);
|
2021-04-28 15:22:57 +00:00
|
|
|
nc += (rc == 0) ? 1 : 0;
|
2019-01-22 10:29:06 +00:00
|
|
|
break;
|
|
|
|
case GSM0808_SPEECH_PERM:
|
|
|
|
case GSM0808_SPEECH_PERM_NO_CHANGE:
|
|
|
|
case GSM0808_SPEECH_FULL_PREF_NO_CHANGE:
|
|
|
|
case GSM0808_SPEECH_FULL_PREF:
|
2021-04-27 23:17:14 +00:00
|
|
|
rc = match_codec_pref(&req->ch_mode_rate_list[nc], ct, &conn->codec_list, msc, bts,
|
2019-01-22 10:29:06 +00:00
|
|
|
RATE_PREF_FR);
|
2021-04-28 15:22:57 +00:00
|
|
|
nc += (rc == 0) ? 1 : 0;
|
2021-04-27 23:17:14 +00:00
|
|
|
rc = match_codec_pref(&req->ch_mode_rate_list[nc], ct, &conn->codec_list, msc, bts,
|
2019-01-22 10:29:06 +00:00
|
|
|
RATE_PREF_HR);
|
2021-04-28 15:22:57 +00:00
|
|
|
nc += (rc == 0) ? 1 : 0;
|
2019-01-22 10:29:06 +00:00
|
|
|
break;
|
|
|
|
case GSM0808_SPEECH_HALF_PREF_NO_CHANGE:
|
|
|
|
case GSM0808_SPEECH_HALF_PREF:
|
2021-04-27 23:17:14 +00:00
|
|
|
rc = match_codec_pref(&req->ch_mode_rate_list[nc], ct, &conn->codec_list, msc, bts,
|
2019-01-22 10:29:06 +00:00
|
|
|
RATE_PREF_HR);
|
2021-04-28 15:22:57 +00:00
|
|
|
nc += (rc == 0) ? 1 : 0;
|
2021-04-27 23:17:14 +00:00
|
|
|
rc = match_codec_pref(&req->ch_mode_rate_list[nc], ct, &conn->codec_list, msc, bts,
|
2019-01-22 10:29:06 +00:00
|
|
|
RATE_PREF_FR);
|
2021-04-28 15:22:57 +00:00
|
|
|
nc += (rc == 0) ? 1 : 0;
|
2019-01-22 10:29:06 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
rc = -EINVAL;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2019-03-07 15:32:02 +00:00
|
|
|
if (!nc) {
|
2019-01-22 10:29:06 +00:00
|
|
|
LOGP(DMSC, LOGL_ERROR, "No supported audio type found for channel_type ="
|
|
|
|
" { ch_indctr=0x%x, ch_rate_type=0x%x, perm_spch=[%s] }\n",
|
|
|
|
ct->ch_indctr, ct->ch_rate_type, osmo_hexdump(ct->perm_spch, ct->perm_spch_len));
|
|
|
|
/* TODO: actually output codec names, e.g. implement
|
|
|
|
* gsm0808_permitted_speech_names[] and iterate perm_spch. */
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
2019-03-07 15:32:02 +00:00
|
|
|
for (i = 0; i < nc; i++ ) {
|
|
|
|
DEBUGP(DMSC, "Found matching audio type (pref=%d): %s %s for channel_type ="
|
2019-01-22 10:29:06 +00:00
|
|
|
" { ch_indctr=0x%x, ch_rate_type=0x%x, perm_spch=[ %s] }\n",
|
2019-03-07 15:32:02 +00:00
|
|
|
i,
|
2021-04-27 23:17:14 +00:00
|
|
|
req->ch_mode_rate_list[i].chan_rate == CH_RATE_FULL ? "full rate" : "half rate",
|
|
|
|
get_value_string(gsm48_chan_mode_names, req->ch_mode_rate_list[i].chan_mode),
|
2019-03-14 22:11:45 +00:00
|
|
|
ct->ch_indctr, ct->ch_rate_type, osmo_hexdump(ct->perm_spch, ct->perm_spch_len));
|
2019-03-07 15:32:02 +00:00
|
|
|
}
|
|
|
|
|
2019-03-07 15:32:02 +00:00
|
|
|
req->n_ch_mode_rate = nc;
|
|
|
|
|
2019-03-14 22:11:45 +00:00
|
|
|
return 0;
|
2019-03-07 15:32:02 +00:00
|
|
|
}
|
|
|
|
|
2019-03-07 15:32:02 +00:00
|
|
|
static int select_sign_chan(struct assignment_request *req, struct gsm0808_channel_type *ct)
|
|
|
|
{
|
|
|
|
int i, nc = 0;
|
|
|
|
|
|
|
|
switch (ct->ch_rate_type) {
|
|
|
|
case GSM0808_SIGN_ANY:
|
2021-04-27 23:17:14 +00:00
|
|
|
req->ch_mode_rate_list[nc++].chan_rate = CH_RATE_SDCCH;
|
|
|
|
req->ch_mode_rate_list[nc++].chan_rate = CH_RATE_HALF;
|
|
|
|
req->ch_mode_rate_list[nc++].chan_rate = CH_RATE_FULL;
|
2019-03-07 15:32:02 +00:00
|
|
|
break;
|
|
|
|
case GSM0808_SIGN_SDCCH:
|
2021-04-27 23:17:14 +00:00
|
|
|
req->ch_mode_rate_list[nc++].chan_rate = CH_RATE_SDCCH;
|
2019-03-07 15:32:02 +00:00
|
|
|
break;
|
|
|
|
case GSM0808_SIGN_SDCCH_FULL_BM:
|
2021-04-27 23:17:14 +00:00
|
|
|
req->ch_mode_rate_list[nc++].chan_rate = CH_RATE_SDCCH;
|
|
|
|
req->ch_mode_rate_list[nc++].chan_rate = CH_RATE_FULL;
|
2019-03-07 15:32:02 +00:00
|
|
|
break;
|
|
|
|
case GSM0808_SIGN_SDCCH_HALF_LM:
|
2021-04-27 23:17:14 +00:00
|
|
|
req->ch_mode_rate_list[nc++].chan_rate = CH_RATE_SDCCH;
|
|
|
|
req->ch_mode_rate_list[nc++].chan_rate = CH_RATE_HALF;
|
2019-03-07 15:32:02 +00:00
|
|
|
break;
|
|
|
|
case GSM0808_SIGN_FULL_BM:
|
2021-04-27 23:17:14 +00:00
|
|
|
req->ch_mode_rate_list[nc++].chan_rate = CH_RATE_FULL;
|
2019-03-07 15:32:02 +00:00
|
|
|
break;
|
|
|
|
case GSM0808_SIGN_HALF_LM:
|
2021-04-27 23:17:14 +00:00
|
|
|
req->ch_mode_rate_list[nc++].chan_rate = CH_RATE_HALF;
|
2019-03-07 15:32:02 +00:00
|
|
|
break;
|
|
|
|
case GSM0808_SIGN_FULL_PREF:
|
|
|
|
case GSM0808_SIGN_FULL_PREF_NO_CHANGE:
|
2021-04-27 23:17:14 +00:00
|
|
|
req->ch_mode_rate_list[nc++].chan_rate = CH_RATE_FULL;
|
|
|
|
req->ch_mode_rate_list[nc++].chan_rate = CH_RATE_HALF;
|
2019-03-07 15:32:02 +00:00
|
|
|
break;
|
|
|
|
case GSM0808_SIGN_HALF_PREF:
|
|
|
|
case GSM0808_SIGN_HALF_PREF_NO_CHANGE:
|
2021-04-27 23:17:14 +00:00
|
|
|
req->ch_mode_rate_list[nc++].chan_rate = CH_RATE_HALF;
|
|
|
|
req->ch_mode_rate_list[nc++].chan_rate = CH_RATE_FULL;
|
2019-03-07 15:32:02 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 0; i < nc; i++)
|
2021-04-27 23:17:14 +00:00
|
|
|
req->ch_mode_rate_list[i].chan_mode = GSM48_CMODE_SIGN;
|
2019-03-07 15:32:02 +00:00
|
|
|
|
|
|
|
req->n_ch_mode_rate = nc;
|
|
|
|
|
|
|
|
return nc > 0 ? 0 : -EINVAL;
|
|
|
|
}
|
|
|
|
|
2010-11-10 09:07:30 +00:00
|
|
|
/*
|
|
|
|
* Handle the assignment request message.
|
|
|
|
*
|
|
|
|
* See §3.2.1.1 for the message type
|
|
|
|
*/
|
2018-01-28 01:45:46 +00:00
|
|
|
static int bssmap_handle_assignm_req(struct gsm_subscriber_connection *conn,
|
2010-11-10 09:07:30 +00:00
|
|
|
struct msgb *msg, unsigned int length)
|
|
|
|
{
|
|
|
|
struct msgb *resp;
|
|
|
|
struct tlv_parsed tp;
|
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
|
|
|
uint16_t cic = 0;
|
2017-04-09 10:32:51 +00:00
|
|
|
bool aoip = false;
|
2019-04-16 18:05:32 +00:00
|
|
|
bool use_osmux = false;
|
|
|
|
uint8_t osmux_cid = 0;
|
2017-04-09 10:32:51 +00:00
|
|
|
struct sockaddr_storage rtp_addr;
|
|
|
|
struct gsm0808_channel_type ct;
|
2017-12-23 00:22:03 +00:00
|
|
|
uint8_t cause;
|
2017-04-09 10:32:51 +00:00
|
|
|
int 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
|
|
|
struct assignment_request req = {};
|
2010-11-10 09:07:30 +00:00
|
|
|
|
2018-01-28 01:45:46 +00:00
|
|
|
if (!conn) {
|
2017-04-09 10:32:51 +00:00
|
|
|
LOGP(DMSC, LOGL_ERROR,
|
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
|
|
|
"No lchan/msc_data in Assignment Request\n");
|
2010-11-10 09:07:30 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
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
|
|
|
aoip = gscon_is_aoip(conn);
|
2017-04-09 10:32:51 +00:00
|
|
|
|
2010-11-10 09:07:30 +00:00
|
|
|
tlv_parse(&tp, gsm0808_att_tlvdef(), msg->l4h + 1, length - 1, 0, 0);
|
|
|
|
|
2017-04-09 10:32:51 +00:00
|
|
|
/* Check for channel type element, if its missing, immediately reject */
|
2010-11-10 09:07:30 +00:00
|
|
|
if (!TLVP_PRESENT(&tp, GSM0808_IE_CHANNEL_TYPE)) {
|
2012-08-03 09:05:29 +00:00
|
|
|
LOGP(DMSC, LOGL_ERROR, "Mandatory channel type not present.\n");
|
2017-12-23 00:22:03 +00:00
|
|
|
cause = GSM0808_CAUSE_INFORMATION_ELEMENT_OR_FIELD_MISSING;
|
2010-11-10 09:07:30 +00:00
|
|
|
goto reject;
|
|
|
|
}
|
|
|
|
|
2017-12-23 00:07:45 +00:00
|
|
|
/* Decode Channel Type element */
|
|
|
|
rc = gsm0808_dec_channel_type(&ct, TLVP_VAL(&tp, GSM0808_IE_CHANNEL_TYPE),
|
|
|
|
TLVP_LEN(&tp, GSM0808_IE_CHANNEL_TYPE));
|
|
|
|
if (rc < 0) {
|
|
|
|
LOGP(DMSC, LOGL_ERROR, "unable to decode channel type.\n");
|
2017-12-23 00:22:03 +00:00
|
|
|
cause = GSM0808_CAUSE_INCORRECT_VALUE;
|
2017-12-23 00:07:45 +00:00
|
|
|
goto reject;
|
|
|
|
}
|
|
|
|
|
2018-05-29 23:39:43 +00:00
|
|
|
bssmap_handle_ass_req_lcls(conn, &tp);
|
|
|
|
|
2017-12-23 00:07:45 +00:00
|
|
|
/* Currently we only support a limited subset of all
|
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
|
|
|
* possible channel types, such as multi-slot or CSD */
|
|
|
|
switch (ct.ch_indctr) {
|
|
|
|
case GSM0808_CHAN_DATA:
|
2017-12-23 00:07:45 +00:00
|
|
|
LOGP(DMSC, LOGL_ERROR, "Unsupported channel type, currently only speech is supported!\n");
|
2017-12-23 00:22:03 +00:00
|
|
|
cause = GSM0808_CAUSE_REQ_CODEC_TYPE_OR_CONFIG_NOT_SUPP;
|
2017-12-23 00:07:45 +00:00
|
|
|
goto 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
|
|
|
case GSM0808_CHAN_SPEECH:
|
|
|
|
if (TLVP_PRESENT(&tp, GSM0808_IE_CIRCUIT_IDENTITY_CODE)) {
|
2018-06-05 19:46:35 +00:00
|
|
|
/* CIC is permitted in both AoIP and SCCPlite */
|
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
|
|
|
cic = osmo_load16be(TLVP_VAL(&tp, GSM0808_IE_CIRCUIT_IDENTITY_CODE));
|
2018-06-05 19:46:35 +00:00
|
|
|
} else {
|
|
|
|
if (!aoip) {
|
|
|
|
/* no CIC but SCCPlite: illegal */
|
|
|
|
LOGP(DMSC, LOGL_ERROR, "SCCPlite MSC, but no CIC in ASSIGN REQ?\n");
|
|
|
|
cause = GSM0808_CAUSE_INFORMATION_ELEMENT_OR_FIELD_MISSING;
|
|
|
|
goto reject;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (TLVP_PRESENT(&tp, GSM0808_IE_AOIP_TRASP_ADDR)) {
|
|
|
|
if (!aoip) {
|
|
|
|
/* SCCPlite and AoIP transport address: illegal */
|
|
|
|
LOGP(DMSC, LOGL_ERROR, "AoIP Transport address over IPA ?!?\n");
|
|
|
|
cause = GSM0808_CAUSE_INCORRECT_VALUE;
|
|
|
|
goto 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
|
|
|
/* Decode AoIP transport address element */
|
|
|
|
rc = gsm0808_dec_aoip_trasp_addr(&rtp_addr,
|
|
|
|
TLVP_VAL(&tp, GSM0808_IE_AOIP_TRASP_ADDR),
|
|
|
|
TLVP_LEN(&tp, GSM0808_IE_AOIP_TRASP_ADDR));
|
|
|
|
if (rc < 0) {
|
|
|
|
LOGP(DMSC, LOGL_ERROR, "Unable to decode AoIP transport address.\n");
|
|
|
|
cause = GSM0808_CAUSE_INCORRECT_VALUE;
|
|
|
|
goto reject;
|
|
|
|
}
|
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
|
|
|
} else if (aoip) {
|
|
|
|
/* no AoIP transport level address but AoIP transport: illegal */
|
|
|
|
LOGP(DMSC, LOGL_ERROR, "AoIP transport address missing in ASSIGN REQ, "
|
|
|
|
"audio would not work; rejecting\n");
|
|
|
|
cause = GSM0808_CAUSE_INFORMATION_ELEMENT_OR_FIELD_MISSING;
|
|
|
|
goto reject;
|
2017-04-09 10:32:51 +00:00
|
|
|
}
|
2010-11-10 09:07:30 +00:00
|
|
|
|
2019-04-16 18:05:32 +00:00
|
|
|
if (TLVP_PRESENT(&tp, GSM0808_IE_OSMO_OSMUX_CID)) {
|
|
|
|
if (conn->sccp.msc->use_osmux == OSMUX_USAGE_OFF) {
|
|
|
|
LOGP(DMSC, LOGL_ERROR, "MSC using Osmux but we have it disabled.\n");
|
|
|
|
cause = GSM0808_CAUSE_INCORRECT_VALUE;
|
|
|
|
goto reject;
|
|
|
|
}
|
|
|
|
use_osmux = true;
|
|
|
|
rc = gsm0808_dec_osmux_cid(&osmux_cid,
|
|
|
|
TLVP_VAL(&tp, GSM0808_IE_OSMO_OSMUX_CID),
|
|
|
|
TLVP_LEN(&tp, GSM0808_IE_OSMO_OSMUX_CID));
|
|
|
|
if (rc < 0) {
|
|
|
|
LOGP(DMSC, LOGL_ERROR, "Unable to decode Osmux CID.\n");
|
|
|
|
cause = GSM0808_CAUSE_INCORRECT_VALUE;
|
|
|
|
goto reject;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (conn->sccp.msc->use_osmux == OSMUX_USAGE_ONLY) {
|
|
|
|
LOGP(DMSC, LOGL_ERROR, "MSC not using Osmux but we are forced to use it.\n");
|
|
|
|
cause = GSM0808_CAUSE_INCORRECT_VALUE;
|
|
|
|
goto reject;
|
|
|
|
} else if (conn->sccp.msc->use_osmux == OSMUX_USAGE_ON)
|
|
|
|
LOGP(DMSC, LOGL_NOTICE, "MSC not using Osmux but we have Osmux enabled.\n");
|
|
|
|
}
|
|
|
|
|
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
|
|
|
/* Decode speech codec list. First set len = 0. */
|
|
|
|
conn->codec_list = (struct gsm0808_speech_codec_list){};
|
|
|
|
/* Check for speech codec list element */
|
|
|
|
if (TLVP_PRESENT(&tp, GSM0808_IE_SPEECH_CODEC_LIST)) {
|
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
|
|
|
/* Decode Speech Codec list */
|
|
|
|
rc = gsm0808_dec_speech_codec_list(&conn->codec_list,
|
|
|
|
TLVP_VAL(&tp, GSM0808_IE_SPEECH_CODEC_LIST),
|
|
|
|
TLVP_LEN(&tp, GSM0808_IE_SPEECH_CODEC_LIST));
|
|
|
|
if (rc < 0) {
|
|
|
|
LOGP(DMSC, LOGL_ERROR, "Unable to decode speech codec list\n");
|
|
|
|
cause = GSM0808_CAUSE_INCORRECT_VALUE;
|
|
|
|
goto reject;
|
|
|
|
}
|
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
|
|
|
}
|
|
|
|
|
|
|
|
if (aoip && !conn->codec_list.len) {
|
|
|
|
LOGP(DMSC, LOGL_ERROR, "%s: AoIP speech mode Assignment Request:"
|
|
|
|
" Missing or empty Speech Codec List IE\n", bsc_subscr_name(conn->bsub));
|
|
|
|
cause = GSM0808_CAUSE_INFORMATION_ELEMENT_OR_FIELD_MISSING;
|
|
|
|
goto reject;
|
2017-04-09 10:32:51 +00:00
|
|
|
}
|
2010-11-10 09:07:30 +00:00
|
|
|
|
2019-01-22 10:29:06 +00:00
|
|
|
req = (struct assignment_request){
|
2021-05-01 02:52:05 +00:00
|
|
|
.assign_for = ASSIGN_FOR_BSSMAP_REQ,
|
2019-01-22 10:29:06 +00:00
|
|
|
.aoip = aoip,
|
|
|
|
.msc_assigned_cic = cic,
|
2019-04-16 18:05:32 +00:00
|
|
|
.use_osmux = use_osmux,
|
|
|
|
.osmux_cid = osmux_cid,
|
2019-01-22 10:29:06 +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
|
|
|
/* Match codec information from the assignment command against the
|
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
|
|
|
* local preferences of the BSC and BTS */
|
2019-01-22 10:29:06 +00:00
|
|
|
rc = select_codecs(&req, &ct, conn);
|
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 (rc < 0) {
|
|
|
|
cause = GSM0808_CAUSE_REQ_CODEC_TYPE_OR_CONFIG_UNAVAIL;
|
2017-09-27 13:51:34 +00:00
|
|
|
goto 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
|
|
|
if (aoip) {
|
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
|
|
|
unsigned int rc = osmo_sockaddr_to_str_and_uint(req.msc_rtp_addr,
|
|
|
|
sizeof(req.msc_rtp_addr),
|
|
|
|
&req.msc_rtp_port,
|
|
|
|
(const struct sockaddr*)&rtp_addr);
|
|
|
|
if (!rc || rc >= sizeof(req.msc_rtp_addr)) {
|
|
|
|
LOGP(DMSC, LOGL_ERROR, "Assignment request: RTP address is too long\n");
|
|
|
|
cause = GSM0808_CAUSE_REQ_CODEC_TYPE_OR_CONFIG_UNAVAIL;
|
|
|
|
goto 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
|
|
|
}
|
|
|
|
break;
|
|
|
|
case GSM0808_CHAN_SIGN:
|
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
|
|
|
req = (struct assignment_request){
|
2021-05-01 02:52:05 +00:00
|
|
|
.assign_for = ASSIGN_FOR_BSSMAP_REQ,
|
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
|
|
|
.aoip = aoip,
|
|
|
|
};
|
2019-03-07 15:32:02 +00:00
|
|
|
|
|
|
|
rc = select_sign_chan(&req, &ct);
|
|
|
|
if (rc < 0) {
|
|
|
|
cause = GSM0808_CAUSE_INCORRECT_VALUE;
|
|
|
|
goto 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
|
|
|
break;
|
|
|
|
default:
|
|
|
|
cause = GSM0808_CAUSE_INVALID_MESSAGE_CONTENTS;
|
|
|
|
goto reject;
|
2017-04-09 10:32:51 +00:00
|
|
|
}
|
2010-11-10 09:07:30 +00:00
|
|
|
|
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
|
|
|
return osmo_fsm_inst_dispatch(conn->fi, GSCON_EV_ASSIGNMENT_START, &req);
|
|
|
|
|
2010-11-10 09:07:30 +00:00
|
|
|
reject:
|
2017-12-23 00:22:03 +00:00
|
|
|
resp = gsm0808_create_assignment_failure(cause, NULL);
|
2017-12-23 00:26:01 +00:00
|
|
|
OSMO_ASSERT(resp);
|
2010-11-10 09:07:30 +00:00
|
|
|
|
2020-05-09 18:27:40 +00:00
|
|
|
rate_ctr_inc(&conn->sccp.msc->msc_ctrs->ctr[MSC_CTR_BSSMAP_TX_DT1_ASSIGMENT_FAILURE]);
|
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(conn->fi, GSCON_EV_TX_SCCP, resp);
|
2010-11-10 09:07:30 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
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
|
|
|
/* Handle Handover Command message, part of inter-BSC handover:
|
|
|
|
* This BSS sent a Handover Required message.
|
|
|
|
* The MSC contacts the remote BSS and receives from it an RR Handover Command; this BSSMAP Handover
|
|
|
|
* Command passes the RR Handover Command over to us and it's our job to forward to the MS.
|
|
|
|
*
|
|
|
|
* See 3GPP TS 48.008 §3.2.1.11
|
|
|
|
*/
|
|
|
|
static int bssmap_handle_handover_cmd(struct gsm_subscriber_connection *conn,
|
|
|
|
struct msgb *msg, unsigned int length)
|
|
|
|
{
|
|
|
|
struct tlv_parsed tp;
|
|
|
|
|
|
|
|
if (!conn->ho.fi) {
|
|
|
|
LOGPFSML(conn->fi, LOGL_ERROR,
|
|
|
|
"Received Handover Command, but no handover was requested\n");
|
|
|
|
/* Should we actually allow the MSC to make us handover without us having requested it
|
|
|
|
* first? Doesn't make any practical sense AFAICT. */
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
tlv_parse(&tp, gsm0808_att_tlvdef(), msg->l4h + 1, length - 1, 0, 0);
|
|
|
|
|
|
|
|
/* Check for channel type element, if its missing, immediately reject */
|
|
|
|
if (!TLVP_PRESENT(&tp, GSM0808_IE_LAYER_3_INFORMATION)) {
|
|
|
|
LOGPFSML(conn->fi, LOGL_ERROR,
|
|
|
|
"Received Handover Command,"
|
|
|
|
" but mandatory IE not present: Layer 3 Information\n");
|
|
|
|
goto reject;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Due to constness, need to declare this after tlv_parse(). */
|
|
|
|
struct ho_out_rx_bssmap_ho_command rx = {
|
|
|
|
.l3_info = TLVP_VAL(&tp, GSM0808_IE_LAYER_3_INFORMATION),
|
|
|
|
.l3_info_len = TLVP_LEN(&tp, GSM0808_IE_LAYER_3_INFORMATION),
|
|
|
|
};
|
|
|
|
|
|
|
|
osmo_fsm_inst_dispatch(conn->ho.fi, HO_OUT_EV_BSSMAP_HO_COMMAND, &rx);
|
|
|
|
return 0;
|
|
|
|
reject:
|
|
|
|
/* No "Handover Command Reject" message or similar is specified, so we cannot reply in case of
|
|
|
|
* failure. Or is there?? */
|
|
|
|
handover_end(conn, HO_RESULT_ERROR);
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
2020-05-12 21:47:03 +00:00
|
|
|
/* Handle Confusion message, MSC indicating an error to us:
|
|
|
|
*
|
|
|
|
* See 3GPP TS 48.008 §3.2.1.45
|
|
|
|
*/
|
|
|
|
static int bssmap_handle_confusion(struct gsm_subscriber_connection *conn,
|
|
|
|
struct msgb *msg, unsigned int length)
|
|
|
|
{
|
|
|
|
struct tlv_parsed tp;
|
|
|
|
int diag_len;
|
|
|
|
enum gsm0808_cause cause;
|
|
|
|
enum gsm0808_cause_class cause_class;
|
|
|
|
struct gsm0808_diagnostics *diag;
|
|
|
|
|
|
|
|
osmo_bssap_tlv_parse(&tp, msg->l4h + 1, length - 1);
|
|
|
|
|
|
|
|
/* Check for the Cause and Diagnostic mandatory elements */
|
|
|
|
if (!TLVP_PRESENT(&tp, GSM0808_IE_CAUSE) || !TLVP_PRESENT(&tp, GSM0808_IE_DIAGNOSTIC)) {
|
|
|
|
LOGPFSML(conn->fi, LOGL_ERROR,
|
|
|
|
"Received BSSMAP Confusion message,"
|
|
|
|
" but either Cause or Diagnostic mandatory IE is not present: %s\n",
|
|
|
|
osmo_hexdump(msg->l4h, length));
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
diag_len = TLVP_LEN(&tp, GSM0808_IE_DIAGNOSTIC);
|
|
|
|
if (diag_len < 5) {
|
|
|
|
LOGPFSML(conn->fi, LOGL_ERROR,
|
|
|
|
"Received BSSMAP Confusion message with short Diagnostic length: %d (expected > 5)\n",
|
|
|
|
diag_len);
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
cause = gsm0808_get_cause(&tp);
|
|
|
|
cause_class = gsm0808_cause_class(cause);
|
|
|
|
diag = (struct gsm0808_diagnostics *)TLVP_VAL(&tp, GSM0808_IE_DIAGNOSTIC);
|
|
|
|
|
|
|
|
LOGPFSML(conn->fi, LOGL_ERROR,
|
|
|
|
"Received BSSMAP Confusion: class 0x%x (%s), cause 0x%x (%s), "
|
|
|
|
"error octet %d (%s), error bit %d (%s), original message: %s\n",
|
|
|
|
cause_class, gsm0808_cause_class_name(cause_class),
|
|
|
|
cause, gsm0808_cause_name(cause),
|
|
|
|
diag->error_pointer_octet,
|
|
|
|
gsm0808_diagnostics_octet_location_str(diag->error_pointer_octet),
|
|
|
|
diag->error_pointer_bit,
|
|
|
|
gsm0808_diagnostics_bit_location_str(diag->error_pointer_bit),
|
|
|
|
osmo_hexdump(diag->msg, diag_len-2));
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2020-06-21 16:00:23 +00:00
|
|
|
/* Common ID; 3GPP TS 48.008 3.2.1.68 */
|
|
|
|
static int bssmap_handle_common_id(struct gsm_subscriber_connection *conn,
|
|
|
|
struct msgb *msg, unsigned int length)
|
|
|
|
{
|
|
|
|
struct tlv_parsed tp;
|
|
|
|
|
|
|
|
osmo_bssap_tlv_parse(&tp, msg->l4h + 1, length - 1);
|
|
|
|
|
|
|
|
/* Check for the mandatory elements */
|
|
|
|
if (!TLVP_PRESENT(&tp, GSM0808_IE_IMSI)) {
|
|
|
|
LOGPFSML(conn->fi, LOGL_ERROR,
|
|
|
|
"CommonID: missing mandatory IMSI IE: %s\n",
|
|
|
|
osmo_hexdump(msg->l4h, length));
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
2021-04-12 17:48:39 +00:00
|
|
|
osmo_fsm_inst_dispatch(conn->fi, GSCON_EV_A_COMMON_ID_IND, &tp);
|
2020-06-21 16:00:23 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2017-02-23 20:57:23 +00:00
|
|
|
static int bssmap_rcvmsg_udt(struct bsc_msc_data *msc,
|
2010-11-10 08:24:37 +00:00
|
|
|
struct msgb *msg, unsigned int length)
|
|
|
|
{
|
|
|
|
int ret = 0;
|
2020-05-07 23:37:47 +00:00
|
|
|
struct rate_ctr *ctrs = msc->msc_ctrs->ctr;
|
2010-11-10 08:24:37 +00:00
|
|
|
|
|
|
|
if (length < 1) {
|
|
|
|
LOGP(DMSC, LOGL_ERROR, "Not enough room: %d\n", length);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2011-07-11 16:18:35 +00:00
|
|
|
LOGP(DMSC, LOGL_INFO, "Rx MSC UDT BSSMAP %s\n",
|
|
|
|
gsm0808_bssmap_name(msg->l4h[0]));
|
|
|
|
|
2010-11-10 08:24:37 +00:00
|
|
|
switch (msg->l4h[0]) {
|
|
|
|
case BSS_MAP_MSG_RESET_ACKNOWLEDGE:
|
2020-05-07 23:37:47 +00:00
|
|
|
rate_ctr_inc(&ctrs[MSC_CTR_BSSMAP_RX_UDT_RESET_ACKNOWLEDGE]);
|
2011-06-08 13:52:07 +00:00
|
|
|
ret = bssmap_handle_reset_ack(msc, msg, length);
|
2010-11-10 08:24:37 +00:00
|
|
|
break;
|
2017-04-09 10:32:51 +00:00
|
|
|
case BSS_MAP_MSG_RESET:
|
2020-05-07 23:37:47 +00:00
|
|
|
rate_ctr_inc(&ctrs[MSC_CTR_BSSMAP_RX_UDT_RESET]);
|
2017-04-09 10:32:51 +00:00
|
|
|
ret = bssmap_handle_reset(msc, msg, length);
|
|
|
|
break;
|
2010-11-10 08:24:37 +00:00
|
|
|
case BSS_MAP_MSG_PAGING:
|
2020-05-07 23:37:47 +00:00
|
|
|
rate_ctr_inc(&ctrs[MSC_CTR_BSSMAP_RX_UDT_PAGING]);
|
2013-01-07 16:30:13 +00:00
|
|
|
ret = bssmap_handle_paging(msc, msg, length);
|
2010-11-10 08:24:37 +00:00
|
|
|
break;
|
2017-11-11 14:58:17 +00:00
|
|
|
default:
|
2020-05-07 23:37:47 +00:00
|
|
|
rate_ctr_inc(&ctrs[MSC_CTR_BSSMAP_RX_UDT_UNKNOWN]);
|
2017-11-11 14:58:17 +00:00
|
|
|
LOGP(DMSC, LOGL_NOTICE, "Received unimplemented BSSMAP UDT %s\n",
|
|
|
|
gsm0808_bssmap_name(msg->l4h[0]));
|
|
|
|
break;
|
2010-11-10 08:24:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2018-01-28 01:45:46 +00:00
|
|
|
static int bssmap_rcvmsg_dt1(struct gsm_subscriber_connection *conn,
|
2010-11-10 08:24:37 +00:00
|
|
|
struct msgb *msg, unsigned int length)
|
|
|
|
{
|
2010-11-10 08:34:47 +00:00
|
|
|
int ret = 0;
|
2020-05-07 23:37:47 +00:00
|
|
|
struct rate_ctr *ctrs = conn->sccp.msc->msc_ctrs->ctr;
|
2010-11-10 08:34:47 +00:00
|
|
|
|
|
|
|
if (length < 1) {
|
|
|
|
LOGP(DMSC, LOGL_ERROR, "Not enough room: %d\n", length);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2011-07-11 16:18:35 +00:00
|
|
|
LOGP(DMSC, LOGL_INFO, "Rx MSC DT1 BSSMAP %s\n",
|
|
|
|
gsm0808_bssmap_name(msg->l4h[0]));
|
|
|
|
|
2010-11-10 08:34:47 +00:00
|
|
|
switch (msg->l4h[0]) {
|
|
|
|
case BSS_MAP_MSG_CLEAR_CMD:
|
2020-05-07 23:37:47 +00:00
|
|
|
rate_ctr_inc(&ctrs[MSC_CTR_BSSMAP_RX_DT1_CLEAR_CMD]);
|
2019-02-03 11:11:12 +00:00
|
|
|
ret = bssmap_handle_clear_cmd(conn, msg, length);
|
2010-11-10 08:34:47 +00:00
|
|
|
break;
|
2010-11-10 08:44:34 +00:00
|
|
|
case BSS_MAP_MSG_CIPHER_MODE_CMD:
|
2020-05-07 23:37:47 +00:00
|
|
|
rate_ctr_inc(&ctrs[MSC_CTR_BSSMAP_RX_DT1_CIPHER_MODE_CMD]);
|
2010-11-10 08:44:34 +00:00
|
|
|
ret = bssmap_handle_cipher_mode(conn, msg, length);
|
|
|
|
break;
|
2010-11-10 09:07:30 +00:00
|
|
|
case BSS_MAP_MSG_ASSIGMENT_RQST:
|
2020-05-07 23:37:47 +00:00
|
|
|
rate_ctr_inc(&ctrs[MSC_CTR_BSSMAP_RX_DT1_ASSIGMENT_RQST]);
|
2010-11-10 09:07:30 +00:00
|
|
|
ret = bssmap_handle_assignm_req(conn, msg, length);
|
|
|
|
break;
|
2018-05-29 23:39:43 +00:00
|
|
|
case BSS_MAP_MSG_LCLS_CONNECT_CTRL:
|
2020-05-07 23:37:47 +00:00
|
|
|
rate_ctr_inc(&ctrs[MSC_CTR_BSSMAP_RX_DT1_LCLS_CONNECT_CTRL]);
|
2018-05-29 23:39:43 +00:00
|
|
|
ret = bssmap_handle_lcls_connect_ctrl(conn, msg, length);
|
|
|
|
break;
|
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
|
|
|
case BSS_MAP_MSG_HANDOVER_CMD:
|
2020-05-07 23:37:47 +00:00
|
|
|
rate_ctr_inc(&ctrs[MSC_CTR_BSSMAP_RX_DT1_HANDOVER_CMD]);
|
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
|
|
|
ret = bssmap_handle_handover_cmd(conn, msg, length);
|
|
|
|
break;
|
2018-09-13 03:19:32 +00:00
|
|
|
case BSS_MAP_MSG_CLASSMARK_RQST:
|
2020-05-07 23:37:47 +00:00
|
|
|
rate_ctr_inc(&ctrs[MSC_CTR_BSSMAP_RX_DT1_CLASSMARK_RQST]);
|
2018-09-13 03:19:32 +00:00
|
|
|
ret = gsm48_send_rr_classmark_enquiry(conn->lchan);
|
|
|
|
break;
|
2020-05-12 21:47:03 +00:00
|
|
|
case BSS_MAP_MSG_CONFUSION:
|
|
|
|
rate_ctr_inc(&ctrs[MSC_CTR_BSSMAP_RX_DT1_CONFUSION]);
|
|
|
|
ret = bssmap_handle_confusion(conn, msg, length);
|
|
|
|
break;
|
2020-06-21 16:00:23 +00:00
|
|
|
case BSS_MAP_MSG_COMMON_ID:
|
|
|
|
rate_ctr_inc(&ctrs[MSC_CTR_BSSMAP_RX_DT1_COMMON_ID]);
|
|
|
|
ret = bssmap_handle_common_id(conn, msg, length);
|
|
|
|
break;
|
2020-09-17 15:54:39 +00:00
|
|
|
case BSS_MAP_MSG_PERFORM_LOCATION_RQST:
|
|
|
|
rate_ctr_inc(&ctrs[MSC_CTR_BSSMAP_RX_DT1_PERFORM_LOCATION_REQUEST]);
|
|
|
|
lcs_loc_req_start(conn, msg);
|
|
|
|
ret = 0;
|
|
|
|
break;
|
|
|
|
case BSS_MAP_MSG_PERFORM_LOCATION_ABORT:
|
|
|
|
rate_ctr_inc(&ctrs[MSC_CTR_BSSMAP_RX_DT1_PERFORM_LOCATION_ABORT]);
|
|
|
|
if (conn->lcs.loc_req) {
|
|
|
|
ret = osmo_fsm_inst_dispatch(conn->lcs.loc_req->fi, LCS_LOC_REQ_EV_RX_A_PERFORM_LOCATION_ABORT,
|
|
|
|
msg);
|
|
|
|
} else {
|
|
|
|
LOGP(DMSC, LOGL_ERROR, "Rx BSSMAP Perform Location Abort without ongoing Location Request\n");
|
|
|
|
ret = 0;
|
|
|
|
}
|
|
|
|
break;
|
2010-11-10 08:34:47 +00:00
|
|
|
default:
|
2020-05-07 23:37:47 +00:00
|
|
|
rate_ctr_inc(&ctrs[MSC_CTR_BSSMAP_RX_DT1_UNKNOWN]);
|
2011-07-11 15:56:34 +00:00
|
|
|
LOGP(DMSC, LOGL_NOTICE, "Unimplemented msg type: %s\n",
|
|
|
|
gsm0808_bssmap_name(msg->l4h[0]));
|
2010-11-10 08:34:47 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
2010-11-10 08:24:37 +00:00
|
|
|
}
|
|
|
|
|
RSL/BSSAP: fix: properly convert between RSL Link ID and DLCI
Data Link Connection Identifier (DLCI) is defined in 3GPP TS 48.006,
section 9.3.2, and coded as follows:
.... .SSS - SAPI value used on the radio link;
CC.. .... - control channel identification:
00.. .... - indicates that the control channel is not further specified,
10.. .... - represents the FACCH or the SDCCH,
11.. .... - represents the SACCH,
other values are reserved.
RSL Link Identifier is defined in 3GPP TS 3GPP TS 48.058,
section 9.3.2, and coded as follows:
.... .SSS - SAPI value used on the radio link;
...P P... - priority for SAPI0 messages;
CC.. .... - control channel identification:
00.. .... - main signalling channel (FACCH or SDCCH),
01.. .... - SACCH,
other values are reserved.
As can be seen, CC bits in both DLCI and RSL Link Identifier
are coded differently. Therefore, we cannot just assign
one identifier to another, we need to do conversion.
I noticed that osmo-bsc indicates DLCI '01000011'B for SMS
messages sent over SACCH/F (SAPI3), and this is wrong because
'01'B is reserved. Let's fix this.
P.S. Interesting coincidence: section 9.3.2 in both documents.
Change-Id: If4d479a54cad467f53b49065c1c435a4471ac7d2
Related: Ica69ae95b47a67ba99ba9cc36629b6bd210d11e4
Related: OS#3716
2020-10-01 14:10:51 +00:00
|
|
|
/* RSL Link Identifier is defined in 3GPP TS 3GPP TS 48.058, section 9.3.2.
|
|
|
|
* .... .SSS - SAPI value used on the radio link;
|
|
|
|
* ...P P... - priority for SAPI0 messages;
|
|
|
|
* CC.. .... - control channel identification:
|
|
|
|
* 00.. .... - main signalling channel (FACCH or SDCCH),
|
|
|
|
* 01.. .... - SACCH,
|
|
|
|
* other values are reserved. */
|
|
|
|
#define DLCI2RSL_LINK_ID(dlci) \
|
|
|
|
((dlci & 0xc0) == 0xc0 ? 0x40 : 0x00) | (dlci & 0x07)
|
|
|
|
|
2018-01-28 01:45:46 +00:00
|
|
|
static int dtap_rcvmsg(struct gsm_subscriber_connection *conn,
|
2010-11-10 08:24:37 +00:00
|
|
|
struct msgb *msg, unsigned int length)
|
|
|
|
{
|
2010-11-10 09:17:05 +00:00
|
|
|
struct dtap_header *header;
|
|
|
|
struct msgb *gsm48;
|
|
|
|
uint8_t *data;
|
2020-05-21 23:08:26 +00:00
|
|
|
int dtap_rc;
|
2020-05-10 19:43:03 +00:00
|
|
|
struct rate_ctr *ctrs;
|
2010-11-10 09:17:05 +00:00
|
|
|
|
2011-07-11 16:18:35 +00:00
|
|
|
LOGP(DMSC, LOGL_DEBUG, "Rx MSC DTAP: %s\n",
|
|
|
|
osmo_hexdump(msg->l3h, length));
|
|
|
|
|
2018-01-28 01:45:46 +00:00
|
|
|
if (!conn) {
|
2010-11-10 09:17:05 +00:00
|
|
|
LOGP(DMSC, LOGL_ERROR, "No subscriber connection available\n");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2020-05-10 19:43:03 +00:00
|
|
|
ctrs = conn->sccp.msc->msc_ctrs->ctr;
|
2010-11-10 09:17:05 +00:00
|
|
|
header = (struct dtap_header *) msg->l3h;
|
|
|
|
if (sizeof(*header) >= length) {
|
2020-05-09 22:49:34 +00:00
|
|
|
rate_ctr_inc(&ctrs[MSC_CTR_BSSMAP_RX_DT1_DTAP_ERROR]);
|
2020-05-07 23:37:01 +00:00
|
|
|
LOGP(DMSC, LOGL_ERROR, "The DTAP header does not fit. Wanted: %zu got: %u, hex: %s\n",
|
|
|
|
sizeof(*header), length, osmo_hexdump(msg->l3h, length));
|
|
|
|
return -1;
|
2010-11-10 09:17:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (header->length > length - sizeof(*header)) {
|
2020-05-09 22:49:34 +00:00
|
|
|
rate_ctr_inc(&ctrs[MSC_CTR_BSSMAP_RX_DT1_DTAP_ERROR]);
|
2020-05-07 23:37:01 +00:00
|
|
|
LOGP(DMSC, LOGL_ERROR, "The DTAP l4 information does not fit. Wanted: %u got: %zu, hex: %s\n",
|
|
|
|
header->length, length - sizeof(*header), osmo_hexdump(msg->l3h, length));
|
2010-11-10 09:17:05 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2020-05-09 22:49:34 +00:00
|
|
|
rate_ctr_inc(&ctrs[MSC_CTR_BSSMAP_RX_DT1_DTAP]);
|
2019-11-27 11:09:38 +00:00
|
|
|
LOGP(DMSC, LOGL_INFO, "Rx MSC DTAP, SAPI: %s CHAN: %u\n", gsm0406_dlci_sapi_name(header->dlci_sapi), header->dlci_cc);
|
2010-11-10 09:17:05 +00:00
|
|
|
|
|
|
|
/* forward the data */
|
2016-01-25 21:03:25 +00:00
|
|
|
gsm48 = gsm48_msgb_alloc_name("GSM 04.08 DTAP RCV");
|
2010-11-10 09:17:05 +00:00
|
|
|
if (!gsm48) {
|
|
|
|
LOGP(DMSC, LOGL_ERROR, "Allocation of the message failed.\n");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
gsm48->l3h = gsm48->data;
|
|
|
|
data = msgb_put(gsm48, length - sizeof(*header));
|
|
|
|
memcpy(data, msg->l3h + sizeof(*header), length - sizeof(*header));
|
|
|
|
|
|
|
|
/* pass it to the filter for extra actions */
|
2020-05-21 23:08:26 +00:00
|
|
|
bsc_scan_msc_msg(conn, gsm48);
|
RSL/BSSAP: fix: properly convert between RSL Link ID and DLCI
Data Link Connection Identifier (DLCI) is defined in 3GPP TS 48.006,
section 9.3.2, and coded as follows:
.... .SSS - SAPI value used on the radio link;
CC.. .... - control channel identification:
00.. .... - indicates that the control channel is not further specified,
10.. .... - represents the FACCH or the SDCCH,
11.. .... - represents the SACCH,
other values are reserved.
RSL Link Identifier is defined in 3GPP TS 3GPP TS 48.058,
section 9.3.2, and coded as follows:
.... .SSS - SAPI value used on the radio link;
...P P... - priority for SAPI0 messages;
CC.. .... - control channel identification:
00.. .... - main signalling channel (FACCH or SDCCH),
01.. .... - SACCH,
other values are reserved.
As can be seen, CC bits in both DLCI and RSL Link Identifier
are coded differently. Therefore, we cannot just assign
one identifier to another, we need to do conversion.
I noticed that osmo-bsc indicates DLCI '01000011'B for SMS
messages sent over SACCH/F (SAPI3), and this is wrong because
'01'B is reserved. Let's fix this.
P.S. Interesting coincidence: section 9.3.2 in both documents.
Change-Id: If4d479a54cad467f53b49065c1c435a4471ac7d2
Related: Ica69ae95b47a67ba99ba9cc36629b6bd210d11e4
Related: OS#3716
2020-10-01 14:10:51 +00:00
|
|
|
|
|
|
|
/* convert DLCI to RSL link ID, store in msg->cb */
|
|
|
|
OBSC_LINKID_CB(gsm48) = DLCI2RSL_LINK_ID(header->link_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
|
|
|
dtap_rc = osmo_fsm_inst_dispatch(conn->fi, GSCON_EV_MT_DTAP, gsm48);
|
2012-12-03 14:32:54 +00:00
|
|
|
return dtap_rc;
|
2010-11-10 08:24:37 +00:00
|
|
|
}
|
|
|
|
|
2017-02-23 20:57:23 +00:00
|
|
|
int bsc_handle_udt(struct bsc_msc_data *msc,
|
2010-11-09 22:28:33 +00:00
|
|
|
struct msgb *msgb, unsigned int length)
|
|
|
|
{
|
|
|
|
struct bssmap_header *bs;
|
|
|
|
|
2011-07-11 16:18:35 +00:00
|
|
|
LOGP(DMSC, LOGL_DEBUG, "Rx MSC UDT: %s\n",
|
2011-05-07 10:12:48 +00:00
|
|
|
osmo_hexdump(msgb->l3h, length));
|
2010-11-09 22:28:33 +00:00
|
|
|
|
|
|
|
if (length < sizeof(*bs)) {
|
|
|
|
LOGP(DMSC, LOGL_ERROR, "The header is too short.\n");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
bs = (struct bssmap_header *) msgb->l3h;
|
|
|
|
if (bs->length < length - sizeof(*bs))
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
switch (bs->type) {
|
|
|
|
case BSSAP_MSG_BSS_MANAGEMENT:
|
2010-11-10 08:24:37 +00:00
|
|
|
msgb->l4h = &msgb->l3h[sizeof(*bs)];
|
2011-06-08 13:52:07 +00:00
|
|
|
bssmap_rcvmsg_udt(msc, msgb, length - sizeof(*bs));
|
2010-11-09 22:28:33 +00:00
|
|
|
break;
|
|
|
|
default:
|
2011-07-11 15:56:34 +00:00
|
|
|
LOGP(DMSC, LOGL_NOTICE, "Unimplemented msg type: %s\n",
|
|
|
|
gsm0808_bssmap_name(bs->type));
|
2010-11-09 22:28:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2019-03-18 15:35:29 +00:00
|
|
|
/* Extract and verify the length information from the BSSMAP header. */
|
|
|
|
static unsigned int bssmap_msg_len(struct msgb *msg, unsigned int length,
|
|
|
|
const struct gsm_subscriber_connection *conn)
|
|
|
|
{
|
|
|
|
unsigned int expected_len;
|
|
|
|
unsigned int calculated_len;
|
|
|
|
struct bssmap_header *bssmap_header;
|
|
|
|
|
|
|
|
bssmap_header = (struct bssmap_header *)msg->l3h;
|
|
|
|
|
|
|
|
calculated_len = length - sizeof(struct bssmap_header);
|
|
|
|
expected_len = bssmap_header->length;
|
|
|
|
|
|
|
|
/* In case of contradictory length information, decide for the
|
|
|
|
* shorter length */
|
|
|
|
if (calculated_len > expected_len) {
|
|
|
|
LOGPFSML(conn->fi, LOGL_NOTICE,
|
|
|
|
"BSSMAP message contains extra data, expected %u bytes, got %u bytes, truncated\n",
|
|
|
|
expected_len, calculated_len);
|
|
|
|
return expected_len;
|
|
|
|
} else if (calculated_len < expected_len) {
|
|
|
|
LOGPFSML(conn->fi, LOGL_NOTICE,
|
|
|
|
"Short BSSMAP message, expected %u bytes, got %u bytes\n",
|
|
|
|
expected_len, calculated_len);
|
|
|
|
return calculated_len;
|
|
|
|
}
|
|
|
|
|
|
|
|
return expected_len;
|
|
|
|
}
|
|
|
|
|
2018-01-28 01:45:46 +00:00
|
|
|
int bsc_handle_dt(struct gsm_subscriber_connection *conn,
|
2017-04-09 10:32:51 +00:00
|
|
|
struct msgb *msg, unsigned int len)
|
2010-11-09 22:28:33 +00:00
|
|
|
{
|
2018-12-11 15:50:59 +00:00
|
|
|
log_set_context(LOG_CTX_BSC_SUBSCR, conn->bsub);
|
|
|
|
|
2010-11-10 08:24:37 +00:00
|
|
|
if (len < sizeof(struct bssmap_header)) {
|
|
|
|
LOGP(DMSC, LOGL_ERROR, "The header is too short.\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (msg->l3h[0]) {
|
|
|
|
case BSSAP_MSG_BSS_MANAGEMENT:
|
|
|
|
msg->l4h = &msg->l3h[sizeof(struct bssmap_header)];
|
2019-03-18 15:35:29 +00:00
|
|
|
bssmap_rcvmsg_dt1(conn, msg, bssmap_msg_len(msg, len, conn));
|
2010-11-10 08:24:37 +00:00
|
|
|
break;
|
|
|
|
case BSSAP_MSG_DTAP:
|
|
|
|
dtap_rcvmsg(conn, msg, len);
|
|
|
|
break;
|
|
|
|
default:
|
2011-07-11 16:18:35 +00:00
|
|
|
LOGP(DMSC, LOGL_NOTICE, "Unimplemented BSSAP msg type: %s\n",
|
|
|
|
gsm0808_bssap_name(msg->l3h[0]));
|
2010-11-10 08:24:37 +00:00
|
|
|
}
|
|
|
|
|
2018-12-11 15:50:59 +00:00
|
|
|
log_set_context(LOG_CTX_BSC_SUBSCR, NULL);
|
2010-11-09 22:28:33 +00:00
|
|
|
return -1;
|
|
|
|
}
|
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
|
|
|
|
|
|
|
int bsc_tx_bssmap_ho_required(struct gsm_lchan *lchan, const struct gsm0808_cell_id_list2 *target_cells)
|
|
|
|
{
|
|
|
|
int rc;
|
|
|
|
struct msgb *msg;
|
2021-04-14 19:30:01 +00:00
|
|
|
struct gsm_subscriber_connection *conn = lchan->conn;
|
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
|
|
|
struct gsm0808_handover_required params = {
|
|
|
|
.cause = GSM0808_CAUSE_BETTER_CELL,
|
|
|
|
.cil = *target_cells,
|
|
|
|
.current_channel_type_1_present = true,
|
|
|
|
.current_channel_type_1 = gsm0808_current_channel_type_1(lchan->type),
|
|
|
|
};
|
|
|
|
|
2021-04-14 19:30:01 +00:00
|
|
|
if (conn->last_eutran_plmn_valid) {
|
|
|
|
params.old_bss_to_new_bss_info_present = true;
|
|
|
|
params.old_bss_to_new_bss_info.last_eutran_plmn_id_present = true;
|
|
|
|
params.old_bss_to_new_bss_info.last_eutran_plmn_id = conn->last_eutran_plmn;
|
|
|
|
}
|
|
|
|
|
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
|
|
|
switch (lchan->type) {
|
|
|
|
case GSM_LCHAN_TCH_F:
|
|
|
|
case GSM_LCHAN_TCH_H:
|
|
|
|
params.speech_version_used_present = true;
|
|
|
|
params.speech_version_used = gsm0808_permitted_speech(lchan->type,
|
2021-04-27 23:17:14 +00:00
|
|
|
lchan->current_ch_mode_rate.chan_mode);
|
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
|
|
|
if (!params.speech_version_used) {
|
|
|
|
LOG_HO(lchan->conn, LOGL_ERROR, "Cannot encode Speech Version (Used)"
|
|
|
|
" for BSSMAP Handover Required message\n");
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
msg = gsm0808_create_handover_required(¶ms);
|
|
|
|
if (!msg) {
|
2021-04-14 19:30:01 +00:00
|
|
|
LOG_HO(conn, LOGL_ERROR, "Cannot compose BSSMAP Handover Required message\n");
|
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
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
2021-04-14 19:30:01 +00:00
|
|
|
rate_ctr_inc(&conn->sccp.msc->msc_ctrs->ctr[MSC_CTR_BSSMAP_TX_DT1_HANDOVER_REQUIRED]);
|
|
|
|
rc = gscon_sigtran_send(conn, msg);
|
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
|
|
|
if (rc) {
|
2021-04-14 19:30:01 +00:00
|
|
|
LOG_HO(conn, LOGL_ERROR, "Cannot send BSSMAP Handover Required message\n");
|
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
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Inter-BSC MT HO, new BSS has allocated a channel and sends the RR Handover Command via MSC to the old
|
|
|
|
* BSS, encapsulated in a BSSMAP Handover Request Acknowledge. */
|
|
|
|
int bsc_tx_bssmap_ho_request_ack(struct gsm_subscriber_connection *conn, struct msgb *rr_ho_command)
|
|
|
|
{
|
|
|
|
struct msgb *msg;
|
|
|
|
struct gsm_lchan *new_lchan = conn->ho.new_lchan;
|
2019-03-14 03:36:40 +00:00
|
|
|
struct sockaddr_storage ss;
|
|
|
|
struct gsm0808_handover_request_ack params = {
|
|
|
|
.l3_info = rr_ho_command->data,
|
|
|
|
.l3_info_len = rr_ho_command->len,
|
|
|
|
.chosen_channel_present = true,
|
2021-04-27 23:17:14 +00:00
|
|
|
.chosen_channel = gsm0808_chosen_channel(new_lchan->type, new_lchan->current_ch_mode_rate.chan_mode),
|
2019-03-14 03:36:40 +00:00
|
|
|
.chosen_encr_alg = new_lchan->encr.alg_id,
|
2021-04-27 23:17:14 +00:00
|
|
|
.chosen_speech_version = gsm0808_permitted_speech(new_lchan->type,
|
|
|
|
new_lchan->current_ch_mode_rate.chan_mode),
|
2019-03-14 03:36:40 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
if (gscon_is_aoip(conn)) {
|
|
|
|
struct osmo_sockaddr_str to_msc_rtp;
|
|
|
|
const struct mgcp_conn_peer *rtp_info = osmo_mgcpc_ep_ci_get_rtp_info(conn->user_plane.mgw_endpoint_ci_msc);
|
|
|
|
if (!rtp_info) {
|
|
|
|
LOG_HO(conn, LOGL_ERROR,
|
|
|
|
"Handover Request Acknowledge: no RTP address known to send as"
|
|
|
|
" AoIP Transport Layer Address\n");
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
if (osmo_sockaddr_str_from_str(&to_msc_rtp, rtp_info->addr, rtp_info->port)) {
|
|
|
|
LOG_HO(conn, LOGL_ERROR, "Handover Request Acknowledge: cannot encode AoIP Transport Layer\n");
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
if (osmo_sockaddr_str_to_sockaddr(&to_msc_rtp, &ss)) {
|
|
|
|
LOG_HO(conn, LOGL_ERROR, "Handover Request Acknowledge: cannot encode AoIP Transport Layer\n");
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
params.aoip_transport_layer = &ss;
|
|
|
|
}
|
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
|
|
|
|
2020-05-09 18:27:40 +00:00
|
|
|
rate_ctr_inc(&conn->sccp.msc->msc_ctrs->ctr[MSC_CTR_BSSMAP_TX_DT1_HANDOVER_RQST_ACKNOWLEDGE]);
|
2018-08-27 20:17:07 +00:00
|
|
|
LOG_HO(conn, LOGL_DEBUG, "Sending BSSMAP Handover Request Acknowledge\n");
|
2019-03-14 03:36:40 +00:00
|
|
|
msg = gsm0808_create_handover_request_ack2(¶ms);
|
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
|
|
|
msgb_free(rr_ho_command);
|
|
|
|
if (!msg)
|
|
|
|
return -ENOMEM;
|
|
|
|
return osmo_bsc_sigtran_send(conn, msg);
|
|
|
|
}
|
|
|
|
|
|
|
|
int bsc_tx_bssmap_ho_detect(struct gsm_subscriber_connection *conn)
|
|
|
|
{
|
|
|
|
struct msgb *msg;
|
|
|
|
msg = gsm0808_create_handover_detect();
|
|
|
|
if (!msg)
|
|
|
|
return -ENOMEM;
|
|
|
|
|
2020-05-09 18:27:40 +00:00
|
|
|
rate_ctr_inc(&conn->sccp.msc->msc_ctrs->ctr[MSC_CTR_BSSMAP_TX_DT1_HANDOVER_DETECT]);
|
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
|
|
|
return osmo_bsc_sigtran_send(conn, msg);
|
|
|
|
}
|
|
|
|
|
|
|
|
enum handover_result bsc_tx_bssmap_ho_complete(struct gsm_subscriber_connection *conn,
|
|
|
|
struct gsm_lchan *lchan)
|
|
|
|
{
|
|
|
|
int rc;
|
|
|
|
struct msgb *msg;
|
|
|
|
struct handover *ho = &conn->ho;
|
|
|
|
enum gsm0808_lcls_status lcls_status = lcls_get_status(conn);
|
|
|
|
|
|
|
|
struct gsm0808_handover_complete params = {
|
|
|
|
.chosen_encr_alg_present = true,
|
|
|
|
.chosen_encr_alg = lchan->encr.alg_id,
|
|
|
|
|
|
|
|
.chosen_channel_present = true,
|
2021-04-27 23:17:14 +00:00
|
|
|
.chosen_channel = gsm0808_chosen_channel(lchan->type, lchan->current_ch_mode_rate.chan_mode),
|
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
|
|
|
|
|
|
|
.lcls_bss_status_present = (lcls_status != 0xff),
|
|
|
|
.lcls_bss_status = lcls_status,
|
|
|
|
};
|
|
|
|
|
|
|
|
/* speech_codec_chosen */
|
make sure early lchan act failure resets the lchan
Fix crash after AMR configuration fails.
The crash is due to an assertion that finds a non-NULL conn in the lchan, when
re-using an lchan that has failed in AMR configuration earlier on. That is
because the AMR config still happens in state UNUSED.
DCHAN ERROR lchan(0-0-2-TCH_F_TCH_H_PDCH-0)[0x6120000066a0]{UNUSED}: (type=TCH_F) lchan allocation failed in state UNUSED: Can not generate multirate configuration IE
...
DCHAN DEBUG lchan(0-0-2-TCH_F_TCH_H_PDCH-0)[0x6120000066a0]{UNUSED}: (type=TCH_F) After failure handling, already in state UNUSED
...
...
DCHAN DEBUG lchan(0-0-2-TCH_F_TCH_H_PDCH-0)[0x6120000066a0]{UNUSED}: Received Event LCHAN_EV_ACTIVATE (lchan_fsm.c:324)
Assert failed !lchan->conn ../../../../src/osmo-bsc/src/osmo-bsc/lchan_fsm.c:491
The FSM design idea is that when returning to the UNUSED state, all lchan state
is cleared. However, when calling lchan_activate(), a failure may happen still
in state UNUSED, so that we don't transition *back* to UNUSED properly.
So, first transition out of UNUSED before failures can happen. (Other ways to
solve this would be to invoke lchan clearing even if already in UNUSED, but
semantically, transitioning first makes more sense.)
Upon LCHAN_EV_ACTIVATE, just remember the lchan_activate_info and transition to
WAIT_TS_READY, so that on lchan_fail(), we can normally transition back to
UNUSED and clear the lchan.
Move the initial lchan activation code to lchan_fsm_wait_ts_ready_onenter().
Also, there is a bit of duplication of members of the lchan->activate (lchan
state) and the lchan_activate_info (passed to lchan_activate()) structs. The
fix for this also removes the dup:
Add struct lchan_activate_info as child struct at lchan->activate.info, drop
the other lchan->activate members that would dup .info.*. Move struct
lchan_activate_info declaration to gsm_data.h.
Apply the new '.info' member struct throughout the code.
Related: OS#3737
Change-Id: Ide665b10fa3f4583059c55346db8da833959e3cc
2018-12-19 16:19:02 +00:00
|
|
|
if (ho->new_lchan->activate.info.requires_voice_stream && gscon_is_aoip(conn)) {
|
2021-04-27 23:17:14 +00:00
|
|
|
int perm_spch = gsm0808_permitted_speech(lchan->type, lchan->current_ch_mode_rate.chan_mode);
|
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
|
|
|
params.speech_codec_chosen_present = true;
|
|
|
|
rc = gsm0808_speech_codec_from_chan_type(¶ms.speech_codec_chosen, perm_spch);
|
|
|
|
if (rc) {
|
|
|
|
LOG_HO(conn, LOGL_ERROR, "Unable to compose Speech Codec (Chosen)\n");
|
|
|
|
return HO_RESULT_ERROR;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
msg = gsm0808_create_handover_complete(¶ms);
|
|
|
|
if (!msg) {
|
|
|
|
LOG_HO(conn, LOGL_ERROR, "Unable to compose BSSMAP Handover Complete message\n");
|
|
|
|
return HO_RESULT_ERROR;
|
|
|
|
}
|
|
|
|
|
2020-05-09 18:27:40 +00:00
|
|
|
rate_ctr_inc(&conn->sccp.msc->msc_ctrs->ctr[MSC_CTR_BSSMAP_TX_DT1_HANDOVER_COMPLETE]);
|
2018-09-06 15:09:58 +00:00
|
|
|
rc = osmo_bsc_sigtran_send(conn, msg);
|
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
|
|
|
if (rc) {
|
|
|
|
LOG_HO(conn, LOGL_ERROR, "Cannot send BSSMAP Handover Complete message\n");
|
|
|
|
return HO_RESULT_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
return HO_RESULT_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
void bsc_tx_bssmap_ho_failure(struct gsm_subscriber_connection *conn)
|
|
|
|
{
|
|
|
|
int rc;
|
|
|
|
struct msgb *msg;
|
|
|
|
struct gsm0808_handover_failure params = {};
|
|
|
|
|
|
|
|
msg = gsm0808_create_handover_failure(¶ms);
|
|
|
|
if (!msg) {
|
|
|
|
LOG_HO(conn, LOGL_ERROR, "Unable to compose BSSMAP Handover Failure message\n");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2020-05-09 18:27:40 +00:00
|
|
|
rate_ctr_inc(&conn->sccp.msc->msc_ctrs->ctr[MSC_CTR_BSSMAP_TX_DT1_HANDOVER_FAILURE]);
|
2018-08-27 23:01:35 +00:00
|
|
|
rc = osmo_bsc_sigtran_send(conn, msg);
|
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
|
|
|
if (rc)
|
|
|
|
LOG_HO(conn, LOGL_ERROR, "Cannot send BSSMAP Handover Failure message (rc=%d %s)\n",
|
|
|
|
rc, strerror(-rc));
|
|
|
|
}
|