osmo-bsc/include/osmocom/bsc/handover.h

103 lines
3.9 KiB
C
Raw Normal View History

#pragma once
HO: introduce ho decision callbacks Instead of reacting on S_LCHAN* signals in the handover decision code, introduce callbacks for the handover decision to be invoked by handover_logic.c at the appropriate time. The rationale is explained in a comment to struct handover_decision_callbacks, quoting: " All events that are interesting for handover decision are actually communicated by S_LCHAN_* signals, so theoretically, each handover algorithm could evaluate those. However, handover_logic.c cleans up handover operation state upon receiving some of these signals. To allow a handover decision algorithm to take advantage of e.g. the struct bsc_handover before it is discarded, the handover decision event handler needs to be invoked before handover_logic.c discards the state. For example, if the handover decision wants to place a penalty timer upon a handover failure, it still needs to know which target cell the handover failed for; handover_logic.c erases that knowledge on handover failure, since it needs to clean up the lchan's handover state. The most explicit and safest way to ensure the correct order of event handling is to invoke the handover decision algorithm's actions from handover_logic.c itself, before cleaning up. This struct provides the callback functions for this purpose. For consistency, also handle signals in this way that aren't actually in danger of interference from handover_logic.c (which also saves repeated lookup of handover state for lchans). Thus, handover decision algorithms should not register any signal handler at all. " Also: - Publish struct bsc_handover to use it as argument to above callbacks. - Add enum hodec_id to struct bsc_handover, to be able to signal the appropriate hodec algorithm per event. - Add hodec_id argument to bsc_handover_start*() to be placed in the bsc_handover struct. - Publish the LOGPHO logging macros in handover.h along with struct bsc_handover, convenient for logging in callback implementations. Replace handover_decision.c's signal handler with a registered handover_decision_callbacks instance. (Upcoming handover_decision_2 will use all of the callbacks introduced here.) Change-Id: Id5b64504007fe03e0406a4b395cd0359232b77d2
2018-02-15 13:10:12 +00:00
#include <stdint.h>
#include <osmocom/core/linuxlist.h>
#include <osmocom/core/timer.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/gsm/gsm_utils.h>
HO: introduce ho decision callbacks Instead of reacting on S_LCHAN* signals in the handover decision code, introduce callbacks for the handover decision to be invoked by handover_logic.c at the appropriate time. The rationale is explained in a comment to struct handover_decision_callbacks, quoting: " All events that are interesting for handover decision are actually communicated by S_LCHAN_* signals, so theoretically, each handover algorithm could evaluate those. However, handover_logic.c cleans up handover operation state upon receiving some of these signals. To allow a handover decision algorithm to take advantage of e.g. the struct bsc_handover before it is discarded, the handover decision event handler needs to be invoked before handover_logic.c discards the state. For example, if the handover decision wants to place a penalty timer upon a handover failure, it still needs to know which target cell the handover failed for; handover_logic.c erases that knowledge on handover failure, since it needs to clean up the lchan's handover state. The most explicit and safest way to ensure the correct order of event handling is to invoke the handover decision algorithm's actions from handover_logic.c itself, before cleaning up. This struct provides the callback functions for this purpose. For consistency, also handle signals in this way that aren't actually in danger of interference from handover_logic.c (which also saves repeated lookup of handover state for lchans). Thus, handover decision algorithms should not register any signal handler at all. " Also: - Publish struct bsc_handover to use it as argument to above callbacks. - Add enum hodec_id to struct bsc_handover, to be able to signal the appropriate hodec algorithm per event. - Add hodec_id argument to bsc_handover_start*() to be placed in the bsc_handover struct. - Publish the LOGPHO logging macros in handover.h along with struct bsc_handover, convenient for logging in callback implementations. Replace handover_decision.c's signal handler with a registered handover_decision_callbacks instance. (Upcoming handover_decision_2 will use all of the callbacks introduced here.) Change-Id: Id5b64504007fe03e0406a4b395cd0359232b77d2
2018-02-15 13:10:12 +00:00
#include <osmocom/bsc/neighbor_ident.h>
struct gsm_lchan;
struct gsm_bts;
struct gsm_subscriber_connection;
introduce an osmo_fsm for gsm_subscriber_connection In the current implementation of osmo-bsc, the subscriber connection is not handled (very) statefully. However, there is some state keeping in the code that handles the mgcp connection, but there are still to much loose ends which allow odd situations to happen, which then lead severe error situations (see also closes tags at the end) This commit adds a number of improvements to fix those problems. - Use an osmo-fsm to control the gsm_subscriber_connection state and make sure that certain operations can only take place at certain states (e.g let connection oriented SCCP traffic only pass when an SCCP connection actually exists. Remove the old osmo_bsc_mgcp.c code. Use the recently developed MGCP client FSM to handle the MGCP connections. Also make sure that stuff that already works does not break. This in particular refers to the internal handover capability and the respective unit-tests. See also OS#2823, OS#2768 and OS#2898 - Fix logic to permit assignment to a signalling channel. (OS#2762) - Introduce T993210 to release lchan + subscr_conn if MSC fails to respond The GSM specs don't have an explicit timer for this, so let's introdcue a custom timer (hence starting with 99). This timeout catches the following situation: * we send a SCCP CR with COMPL_L3_INFO from the MS to the MSC, * the MSC doesn't respond (e.g. SCCP routing failure, program down, ...) The MS is supposed to timeout with T3210, 3220 or 3230. But the BSC shouldn't trust the MS but have some timer on its own. SCCP would have a timer T(conn est), but that one is specified to be 1-2min and hence rather long. See also: OS#2775 - Terminate bsc_subscr_conn_fsm on SCCP N-DISC.ind from MSC If the MSC is disconnecting the SCCP channel, we must terminate the FSM which in turn will release all lchan's and other state. This makes TC_chan_rel_hard_rlsd pass, see also OS#2731 As a side-effect, this fixes TC_chan_act_ack_est_ind_refused(), where the MSC is answering with CREF to our CR/COMPL_L3. - Release subscriber connection on RLL RELEASE IND of SAPI0 on main DCCH The subscriber connection isn't really useful for anything after the SAPI0 main signalling link has been released. We could try to re-establish, but our best option is probably simply releasing the subscriber_conn and anything related to it. This will make TC_chan_rel_rll_rel_ind pass, see also OS#2730 This commit has been tested using the BSC_Tests TTCN3 testsuit and the following tests were passed: TC_chan_act_noreply TC_chan_act_ack_noest TC_chan_act_ack_est_ind_noreply TC_chan_act_ack_est_ind_refused TC_chan_act_nack TC_chan_exhaustion TC_ctrl TC_chan_rel_conn_fail TC_chan_rel_hard_clear TC_chan_rel_hard_rlsd TC_chan_rel_a_reset TC_rll_est_ind_inact_lchan TC_rll_est_ind_inval_sapi1 TC_rll_est_ind_inval_sapi3 TC_rll_est_ind_inval_sacch TC_assignment_cic_only TC_assignment_csd TC_assignment_ctm TC_assignment_fr_a5_0 TC_assignment_fr_a5_1_codec_missing TC_assignment_fr_a5_1 TC_assignment_fr_a5_3 TC_assignment_fr_a5_4 TC_paging_imsi_nochan TC_paging_tmsi_nochan TC_paging_tmsi_any TC_paging_tmsi_sdcch TC_paging_tmsi_tch_f TC_paging_tmsi_tch_hf TC_paging_imsi_nochan_cgi TC_paging_imsi_nochan_lac_ci TC_paging_imsi_nochan_ci TC_paging_imsi_nochan_lai TC_paging_imsi_nochan_lac TC_paging_imsi_nochan_all TC_paging_imsi_nochan_plmn_lac_rnc TC_paging_imsi_nochan_rnc TC_paging_imsi_nochan_lac_rnc TC_paging_imsi_nochan_lacs TC_paging_imsi_nochan_lacs_empty TC_paging_imsi_a_reset TC_paging_counter TC_rsl_drop_counter TC_classmark TC_unsol_ass_fail TC_unsol_ass_compl TC_unsol_ho_fail TC_err_82_short_msg TC_ho_int Authors: Harald Welte <laforge@gnumonks.org> Philipp Maier <pmaier@sysmocom.de> Neels Hofmeyr <neels@hofmeyr.de> Closes: OS#2730 Closes: OS#2731 Closes: OS#2762 Closes: OS#2768 Closes: OS#2775 Closes: OS#2823 Closes: OS#2898 Closes: OS#2936 Change-Id: I68286d26e2014048b054f39ef29c35fef420cc97
2018-01-28 02:04:16 +00:00
struct gsm_meas_rep mr;
HO: introduce ho decision callbacks Instead of reacting on S_LCHAN* signals in the handover decision code, introduce callbacks for the handover decision to be invoked by handover_logic.c at the appropriate time. The rationale is explained in a comment to struct handover_decision_callbacks, quoting: " All events that are interesting for handover decision are actually communicated by S_LCHAN_* signals, so theoretically, each handover algorithm could evaluate those. However, handover_logic.c cleans up handover operation state upon receiving some of these signals. To allow a handover decision algorithm to take advantage of e.g. the struct bsc_handover before it is discarded, the handover decision event handler needs to be invoked before handover_logic.c discards the state. For example, if the handover decision wants to place a penalty timer upon a handover failure, it still needs to know which target cell the handover failed for; handover_logic.c erases that knowledge on handover failure, since it needs to clean up the lchan's handover state. The most explicit and safest way to ensure the correct order of event handling is to invoke the handover decision algorithm's actions from handover_logic.c itself, before cleaning up. This struct provides the callback functions for this purpose. For consistency, also handle signals in this way that aren't actually in danger of interference from handover_logic.c (which also saves repeated lookup of handover state for lchans). Thus, handover decision algorithms should not register any signal handler at all. " Also: - Publish struct bsc_handover to use it as argument to above callbacks. - Add enum hodec_id to struct bsc_handover, to be able to signal the appropriate hodec algorithm per event. - Add hodec_id argument to bsc_handover_start*() to be placed in the bsc_handover struct. - Publish the LOGPHO logging macros in handover.h along with struct bsc_handover, convenient for logging in callback implementations. Replace handover_decision.c's signal handler with a registered handover_decision_callbacks instance. (Upcoming handover_decision_2 will use all of the callbacks introduced here.) Change-Id: Id5b64504007fe03e0406a4b395cd0359232b77d2
2018-02-15 13:10:12 +00:00
#define LOGPHOLCHANTOLCHAN(old_lchan, new_lchan, level, fmt, args...) \
hodec2 log: less verbose, more concise logging Drop numerous log statements that merely bloat the ho decision log. Logging HO candidates: log more compact in a single line, do not use LOGPC and multiline output. The result is more useful information in a quarter of the log lines. LOGPHOLCHAN(), LOGPHOLCHANTOBTS(): - log lchan->type instead of lchan->ts->pchan - always log the speech mode ===== Before ===== DHODEC handover_decision_2.c:1131 (lchan 0.010 TCH/F) (subscr IMSI:000001) MEASUREMENT REPORT (1 neighbors) DHODEC handover_decision_2.c:1136 (lchan 0.010 TCH/F) (subscr IMSI:000001) 0: arfcn=871 bsic=63 neigh_idx=0 rxlev=30 flags=0 DHODEC handover_decision_2.c:261 (lchan 0.010 TCH/F) (subscr IMSI:000001) neigh 871 rxlev=30 last_seen_nr=3 DHODEC handover_decision_2.c:1158 (lchan 0.010 TCH/F) (subscr IMSI:000001) HODEC2: evaluating measurement report DHODEC handover_decision_2.c:1175 (lchan 0.010 TCH/F) (subscr IMSI:000001) Measurement report: average RX level = -110 DHODEC handover_decision_2.c:1190 (lchan 0.010 TCH/F) (subscr IMSI:000001) Virtually improving RX level from -110 to -105, due to AFS bias DHODEC handover_decision_2.c:1220 (lchan 0.010 TCH/F) (subscr IMSI:000001) Attempting handover/assignment due to low rxlev DHODEC handover_decision_2.c:899 (lchan 0.010 TCH/F) (subscr IMSI:000001) Collecting candidates for Assignment and Handover DHODEC handover_decision_2.c:407 (lchan 0.010 TCH/F)->(BTS 0) (subscr IMSI:000001) tch_mode='SPEECH_AMR' type='TCH_F' DHODEC handover_decision_2.c:313 (lchan 0.010 TCH/F) (subscr IMSI:000001) FR3 supported DHODEC handover_decision_2.c:313 (lchan 0.010 TCH/F) (subscr IMSI:000001) HR3 supported DHODEC handover_decision_2.c:489 (lchan 0.010 TCH/F)->(BTS 0) (subscr IMSI:000001) removing TCH/F, already on TCH/F in this cell DHODEC handover_decision_2.c:573 (lchan 0.010 TCH/F)->(BTS 0) (subscr IMSI:000001) TCH/H would not be congested after HO DHODEC handover_decision_2.c:605 (lchan 0.010 TCH/F)->(BTS 0) (subscr IMSI:000001) TCH/H would not be less congested in target than source cell after HO DHODEC handover_decision_2.c:609 (lchan 0.010 TCH/F)->(BTS 0) (subscr IMSI:000001) requirements=0x30 DHODEC handover_decision_2.c:704 - current BTS 0, RX level -110 DHODEC handover_decision_2.c:707 o free TCH/F slots 3, minimum required 0 DHODEC handover_decision_2.c:709 o free TCH/H slots 4, minimum required 0 DHODEC handover_decision_2.c:714 o no requirement fulfilled for TCHF (no assignment possible) DHODEC handover_decision_2.c:737 o requirement A B fulfilled for TCHH (not congested after assignment) DHODEC handover_decision_2.c:407 (lchan 0.010 TCH/F)->(BTS 1) (subscr IMSI:000001) tch_mode='SPEECH_AMR' type='TCH_F' DHODEC handover_decision_2.c:313 (lchan 0.010 TCH/F) (subscr IMSI:000001) FR3 supported DHODEC handover_decision_2.c:313 (lchan 0.010 TCH/F) (subscr IMSI:000001) HR3 supported DHODEC handover_decision_2.c:563 (lchan 0.010 TCH/F)->(BTS 1) (subscr IMSI:000001) TCH/F would not be congested after HO DHODEC handover_decision_2.c:573 (lchan 0.010 TCH/F)->(BTS 1) (subscr IMSI:000001) TCH/H would not be congested after HO DHODEC handover_decision_2.c:595 (lchan 0.010 TCH/F)->(BTS 1) (subscr IMSI:000001) TCH/F would not be less congested in target than source cell after HO DHODEC handover_decision_2.c:605 (lchan 0.010 TCH/F)->(BTS 1) (subscr IMSI:000001) TCH/H would not be less congested in target than source cell after HO DHODEC handover_decision_2.c:609 (lchan 0.010 TCH/F)->(BTS 1) (subscr IMSI:000001) requirements=0x33 DHODEC handover_decision_2.c:701 - neighbor BTS 1, RX level -110 -> -80 DHODEC handover_decision_2.c:707 o free TCH/F slots 4, minimum required 0 DHODEC handover_decision_2.c:709 o free TCH/H slots 4, minimum required 0 DHODEC handover_decision_2.c:712 o requirement A B fulfilled for TCHF (not congested after handover) DHODEC handover_decision_2.c:737 o requirement A B fulfilled for TCHH (not congested after handover) DHODEC handover_decision_2.c:914 (lchan 0.010 TCH/F) (subscr IMSI:000001) adding 2 candidates from 1 neighbors, total 2 DHODEC handover_decision_2.c:1020 (lchan 0.010 TCH/F)->(BTS 1) (subscr IMSI:000001) Best candidate, RX level -80 DHODEC handover_decision_2.c:625 (lchan 0.010 TCH/F)->(BTS 1) (subscr IMSI:000001) Triggering Handover DHODEC handover_decision_2.c:688 (lchan 0.010 TCH/F)->(BTS 1) (subscr IMSI:000001) Triggering handover to TCH/F, due to low rxlevel DHO handover_logic.c:133 (BTS 0 trx 0 ts 1 lchan 0 TCH/F)->(BTS 1 lchan TCH_F) Initiating Handover... DMSC handover_logic.c:135 SUBSCR_CONN[0x612000000520]{ACTIVE}: Received Event HO_START DHODEC handover_logic.c:172 (BTS 0 trx 0 arfcn 870 ts 1 lchan 0 TCH/F)->(BTS 1 trx 0 arfcn 871 ts 1 lchan 0 TCH/F) (subscr IMSI:000001) Triggering Handover ===== After ===== DHODEC handover_decision_2.c:1039 (lchan 0.010 TCH_F SPEECH_AMR) (subscr IMSI:000001) MEASUREMENT REPORT (1 neighbors) DHODEC handover_decision_2.c:1044 (lchan 0.010 TCH_F SPEECH_AMR) (subscr IMSI:000001) 0: arfcn=871 bsic=63 neigh_idx=0 rxlev=30 flags=0 DHODEC handover_decision_2.c:1097 (lchan 0.010 TCH_F SPEECH_AMR) (subscr IMSI:000001) Avg RX level = -110 dBm, +5 dBm AFS bias = -105 dBm; Avg RX quality = -1 (invalid), +0 AFS bias = -1 DHODEC handover_decision_2.c:1122 (lchan 0.010 TCH_F SPEECH_AMR) (subscr IMSI:000001) RX level is TOO LOW: -105 < -100 DHODEC handover_decision_2.c:677 (lchan 0.010 TCH_F SPEECH_AMR)->(BTS 0) (subscr IMSI:000001) RX level -110; TCH/F={free 3 (want 0), [-] not a candidate}; TCH/H={free 4 (want 0), [ABC] good} DHODEC handover_decision_2.c:671 (lchan 0.010 TCH_F SPEECH_AMR)->(BTS 1) (subscr IMSI:000001) RX level -110 -> -80; TCH/F={free 4 (want 0), [ABC] good}; TCH/H={free 4 (want 0), [ABC] good} DHODEC handover_decision_2.c:928 (lchan 0.010 TCH_F SPEECH_AMR)->(BTS 1) (subscr IMSI:000001) Best candidate, RX level -80 DHODEC handover_decision_2.c:641 (lchan 0.010 TCH_F SPEECH_AMR)->(BTS 1) (subscr IMSI:000001) Triggering handover to TCH/F, due to low rxlevel DMSC handover_logic.c:125 SUBSCR_CONN[0x612000000520]{ACTIVE}: Received Event HO_START DHODEC handover_logic.c:169 (BTS 0 trx 0 arfcn 870 ts 1 lchan 0 TCH_F SPEECH_AMR)->(BTS 1 trx 0 arfcn 871 ts 1 lchan 0 TCH/F) (subscr IMSI:000001) Triggering Handover Change-Id: If1add9b57a051d32b67a4a08ab47a9655aa9dd17
2018-07-19 14:14:09 +00:00
LOGP(DHODEC, level, "(BTS %u trx %u arfcn %u ts %u lchan %u %s %s)->(BTS %u trx %u arfcn %u ts %u lchan %u %s) (subscr %s) " fmt, \
HO: introduce ho decision callbacks Instead of reacting on S_LCHAN* signals in the handover decision code, introduce callbacks for the handover decision to be invoked by handover_logic.c at the appropriate time. The rationale is explained in a comment to struct handover_decision_callbacks, quoting: " All events that are interesting for handover decision are actually communicated by S_LCHAN_* signals, so theoretically, each handover algorithm could evaluate those. However, handover_logic.c cleans up handover operation state upon receiving some of these signals. To allow a handover decision algorithm to take advantage of e.g. the struct bsc_handover before it is discarded, the handover decision event handler needs to be invoked before handover_logic.c discards the state. For example, if the handover decision wants to place a penalty timer upon a handover failure, it still needs to know which target cell the handover failed for; handover_logic.c erases that knowledge on handover failure, since it needs to clean up the lchan's handover state. The most explicit and safest way to ensure the correct order of event handling is to invoke the handover decision algorithm's actions from handover_logic.c itself, before cleaning up. This struct provides the callback functions for this purpose. For consistency, also handle signals in this way that aren't actually in danger of interference from handover_logic.c (which also saves repeated lookup of handover state for lchans). Thus, handover decision algorithms should not register any signal handler at all. " Also: - Publish struct bsc_handover to use it as argument to above callbacks. - Add enum hodec_id to struct bsc_handover, to be able to signal the appropriate hodec algorithm per event. - Add hodec_id argument to bsc_handover_start*() to be placed in the bsc_handover struct. - Publish the LOGPHO logging macros in handover.h along with struct bsc_handover, convenient for logging in callback implementations. Replace handover_decision.c's signal handler with a registered handover_decision_callbacks instance. (Upcoming handover_decision_2 will use all of the callbacks introduced here.) Change-Id: Id5b64504007fe03e0406a4b395cd0359232b77d2
2018-02-15 13:10:12 +00:00
old_lchan->ts->trx->bts->nr, \
old_lchan->ts->trx->nr, \
old_lchan->ts->trx->arfcn, \
old_lchan->ts->nr, \
old_lchan->nr, \
hodec2 log: less verbose, more concise logging Drop numerous log statements that merely bloat the ho decision log. Logging HO candidates: log more compact in a single line, do not use LOGPC and multiline output. The result is more useful information in a quarter of the log lines. LOGPHOLCHAN(), LOGPHOLCHANTOBTS(): - log lchan->type instead of lchan->ts->pchan - always log the speech mode ===== Before ===== DHODEC handover_decision_2.c:1131 (lchan 0.010 TCH/F) (subscr IMSI:000001) MEASUREMENT REPORT (1 neighbors) DHODEC handover_decision_2.c:1136 (lchan 0.010 TCH/F) (subscr IMSI:000001) 0: arfcn=871 bsic=63 neigh_idx=0 rxlev=30 flags=0 DHODEC handover_decision_2.c:261 (lchan 0.010 TCH/F) (subscr IMSI:000001) neigh 871 rxlev=30 last_seen_nr=3 DHODEC handover_decision_2.c:1158 (lchan 0.010 TCH/F) (subscr IMSI:000001) HODEC2: evaluating measurement report DHODEC handover_decision_2.c:1175 (lchan 0.010 TCH/F) (subscr IMSI:000001) Measurement report: average RX level = -110 DHODEC handover_decision_2.c:1190 (lchan 0.010 TCH/F) (subscr IMSI:000001) Virtually improving RX level from -110 to -105, due to AFS bias DHODEC handover_decision_2.c:1220 (lchan 0.010 TCH/F) (subscr IMSI:000001) Attempting handover/assignment due to low rxlev DHODEC handover_decision_2.c:899 (lchan 0.010 TCH/F) (subscr IMSI:000001) Collecting candidates for Assignment and Handover DHODEC handover_decision_2.c:407 (lchan 0.010 TCH/F)->(BTS 0) (subscr IMSI:000001) tch_mode='SPEECH_AMR' type='TCH_F' DHODEC handover_decision_2.c:313 (lchan 0.010 TCH/F) (subscr IMSI:000001) FR3 supported DHODEC handover_decision_2.c:313 (lchan 0.010 TCH/F) (subscr IMSI:000001) HR3 supported DHODEC handover_decision_2.c:489 (lchan 0.010 TCH/F)->(BTS 0) (subscr IMSI:000001) removing TCH/F, already on TCH/F in this cell DHODEC handover_decision_2.c:573 (lchan 0.010 TCH/F)->(BTS 0) (subscr IMSI:000001) TCH/H would not be congested after HO DHODEC handover_decision_2.c:605 (lchan 0.010 TCH/F)->(BTS 0) (subscr IMSI:000001) TCH/H would not be less congested in target than source cell after HO DHODEC handover_decision_2.c:609 (lchan 0.010 TCH/F)->(BTS 0) (subscr IMSI:000001) requirements=0x30 DHODEC handover_decision_2.c:704 - current BTS 0, RX level -110 DHODEC handover_decision_2.c:707 o free TCH/F slots 3, minimum required 0 DHODEC handover_decision_2.c:709 o free TCH/H slots 4, minimum required 0 DHODEC handover_decision_2.c:714 o no requirement fulfilled for TCHF (no assignment possible) DHODEC handover_decision_2.c:737 o requirement A B fulfilled for TCHH (not congested after assignment) DHODEC handover_decision_2.c:407 (lchan 0.010 TCH/F)->(BTS 1) (subscr IMSI:000001) tch_mode='SPEECH_AMR' type='TCH_F' DHODEC handover_decision_2.c:313 (lchan 0.010 TCH/F) (subscr IMSI:000001) FR3 supported DHODEC handover_decision_2.c:313 (lchan 0.010 TCH/F) (subscr IMSI:000001) HR3 supported DHODEC handover_decision_2.c:563 (lchan 0.010 TCH/F)->(BTS 1) (subscr IMSI:000001) TCH/F would not be congested after HO DHODEC handover_decision_2.c:573 (lchan 0.010 TCH/F)->(BTS 1) (subscr IMSI:000001) TCH/H would not be congested after HO DHODEC handover_decision_2.c:595 (lchan 0.010 TCH/F)->(BTS 1) (subscr IMSI:000001) TCH/F would not be less congested in target than source cell after HO DHODEC handover_decision_2.c:605 (lchan 0.010 TCH/F)->(BTS 1) (subscr IMSI:000001) TCH/H would not be less congested in target than source cell after HO DHODEC handover_decision_2.c:609 (lchan 0.010 TCH/F)->(BTS 1) (subscr IMSI:000001) requirements=0x33 DHODEC handover_decision_2.c:701 - neighbor BTS 1, RX level -110 -> -80 DHODEC handover_decision_2.c:707 o free TCH/F slots 4, minimum required 0 DHODEC handover_decision_2.c:709 o free TCH/H slots 4, minimum required 0 DHODEC handover_decision_2.c:712 o requirement A B fulfilled for TCHF (not congested after handover) DHODEC handover_decision_2.c:737 o requirement A B fulfilled for TCHH (not congested after handover) DHODEC handover_decision_2.c:914 (lchan 0.010 TCH/F) (subscr IMSI:000001) adding 2 candidates from 1 neighbors, total 2 DHODEC handover_decision_2.c:1020 (lchan 0.010 TCH/F)->(BTS 1) (subscr IMSI:000001) Best candidate, RX level -80 DHODEC handover_decision_2.c:625 (lchan 0.010 TCH/F)->(BTS 1) (subscr IMSI:000001) Triggering Handover DHODEC handover_decision_2.c:688 (lchan 0.010 TCH/F)->(BTS 1) (subscr IMSI:000001) Triggering handover to TCH/F, due to low rxlevel DHO handover_logic.c:133 (BTS 0 trx 0 ts 1 lchan 0 TCH/F)->(BTS 1 lchan TCH_F) Initiating Handover... DMSC handover_logic.c:135 SUBSCR_CONN[0x612000000520]{ACTIVE}: Received Event HO_START DHODEC handover_logic.c:172 (BTS 0 trx 0 arfcn 870 ts 1 lchan 0 TCH/F)->(BTS 1 trx 0 arfcn 871 ts 1 lchan 0 TCH/F) (subscr IMSI:000001) Triggering Handover ===== After ===== DHODEC handover_decision_2.c:1039 (lchan 0.010 TCH_F SPEECH_AMR) (subscr IMSI:000001) MEASUREMENT REPORT (1 neighbors) DHODEC handover_decision_2.c:1044 (lchan 0.010 TCH_F SPEECH_AMR) (subscr IMSI:000001) 0: arfcn=871 bsic=63 neigh_idx=0 rxlev=30 flags=0 DHODEC handover_decision_2.c:1097 (lchan 0.010 TCH_F SPEECH_AMR) (subscr IMSI:000001) Avg RX level = -110 dBm, +5 dBm AFS bias = -105 dBm; Avg RX quality = -1 (invalid), +0 AFS bias = -1 DHODEC handover_decision_2.c:1122 (lchan 0.010 TCH_F SPEECH_AMR) (subscr IMSI:000001) RX level is TOO LOW: -105 < -100 DHODEC handover_decision_2.c:677 (lchan 0.010 TCH_F SPEECH_AMR)->(BTS 0) (subscr IMSI:000001) RX level -110; TCH/F={free 3 (want 0), [-] not a candidate}; TCH/H={free 4 (want 0), [ABC] good} DHODEC handover_decision_2.c:671 (lchan 0.010 TCH_F SPEECH_AMR)->(BTS 1) (subscr IMSI:000001) RX level -110 -> -80; TCH/F={free 4 (want 0), [ABC] good}; TCH/H={free 4 (want 0), [ABC] good} DHODEC handover_decision_2.c:928 (lchan 0.010 TCH_F SPEECH_AMR)->(BTS 1) (subscr IMSI:000001) Best candidate, RX level -80 DHODEC handover_decision_2.c:641 (lchan 0.010 TCH_F SPEECH_AMR)->(BTS 1) (subscr IMSI:000001) Triggering handover to TCH/F, due to low rxlevel DMSC handover_logic.c:125 SUBSCR_CONN[0x612000000520]{ACTIVE}: Received Event HO_START DHODEC handover_logic.c:169 (BTS 0 trx 0 arfcn 870 ts 1 lchan 0 TCH_F SPEECH_AMR)->(BTS 1 trx 0 arfcn 871 ts 1 lchan 0 TCH/F) (subscr IMSI:000001) Triggering Handover Change-Id: If1add9b57a051d32b67a4a08ab47a9655aa9dd17
2018-07-19 14:14:09 +00:00
gsm_lchant_name(old_lchan->type), \
gsm48_chan_mode_name(old_lchan->tch_mode), \
HO: introduce ho decision callbacks Instead of reacting on S_LCHAN* signals in the handover decision code, introduce callbacks for the handover decision to be invoked by handover_logic.c at the appropriate time. The rationale is explained in a comment to struct handover_decision_callbacks, quoting: " All events that are interesting for handover decision are actually communicated by S_LCHAN_* signals, so theoretically, each handover algorithm could evaluate those. However, handover_logic.c cleans up handover operation state upon receiving some of these signals. To allow a handover decision algorithm to take advantage of e.g. the struct bsc_handover before it is discarded, the handover decision event handler needs to be invoked before handover_logic.c discards the state. For example, if the handover decision wants to place a penalty timer upon a handover failure, it still needs to know which target cell the handover failed for; handover_logic.c erases that knowledge on handover failure, since it needs to clean up the lchan's handover state. The most explicit and safest way to ensure the correct order of event handling is to invoke the handover decision algorithm's actions from handover_logic.c itself, before cleaning up. This struct provides the callback functions for this purpose. For consistency, also handle signals in this way that aren't actually in danger of interference from handover_logic.c (which also saves repeated lookup of handover state for lchans). Thus, handover decision algorithms should not register any signal handler at all. " Also: - Publish struct bsc_handover to use it as argument to above callbacks. - Add enum hodec_id to struct bsc_handover, to be able to signal the appropriate hodec algorithm per event. - Add hodec_id argument to bsc_handover_start*() to be placed in the bsc_handover struct. - Publish the LOGPHO logging macros in handover.h along with struct bsc_handover, convenient for logging in callback implementations. Replace handover_decision.c's signal handler with a registered handover_decision_callbacks instance. (Upcoming handover_decision_2 will use all of the callbacks introduced here.) Change-Id: Id5b64504007fe03e0406a4b395cd0359232b77d2
2018-02-15 13:10:12 +00:00
new_lchan->ts->trx->bts->nr, \
new_lchan->ts->trx->nr, \
new_lchan->ts->trx->arfcn, \
new_lchan->ts->nr, \
new_lchan->nr, \
gsm_pchan_name(new_lchan->ts->pchan), \
bsc_subscr_name(old_lchan->conn? old_lchan->conn->bsub : NULL), \
## args)
#define LOGPHO(struct_bsc_handover, level, fmt, args ...) \
LOGPHOLCHANTOLCHAN(struct_bsc_handover->old_lchan, struct_bsc_handover->new_lchan, level, fmt, ## args)
enum hodec_id {
HODEC_NONE,
HODEC1 = 1,
HODEC2 = 2,
};
struct bsc_handover {
struct llist_head 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
/* Initial details of what is requested */
HO: introduce ho decision callbacks Instead of reacting on S_LCHAN* signals in the handover decision code, introduce callbacks for the handover decision to be invoked by handover_logic.c at the appropriate time. The rationale is explained in a comment to struct handover_decision_callbacks, quoting: " All events that are interesting for handover decision are actually communicated by S_LCHAN_* signals, so theoretically, each handover algorithm could evaluate those. However, handover_logic.c cleans up handover operation state upon receiving some of these signals. To allow a handover decision algorithm to take advantage of e.g. the struct bsc_handover before it is discarded, the handover decision event handler needs to be invoked before handover_logic.c discards the state. For example, if the handover decision wants to place a penalty timer upon a handover failure, it still needs to know which target cell the handover failed for; handover_logic.c erases that knowledge on handover failure, since it needs to clean up the lchan's handover state. The most explicit and safest way to ensure the correct order of event handling is to invoke the handover decision algorithm's actions from handover_logic.c itself, before cleaning up. This struct provides the callback functions for this purpose. For consistency, also handle signals in this way that aren't actually in danger of interference from handover_logic.c (which also saves repeated lookup of handover state for lchans). Thus, handover decision algorithms should not register any signal handler at all. " Also: - Publish struct bsc_handover to use it as argument to above callbacks. - Add enum hodec_id to struct bsc_handover, to be able to signal the appropriate hodec algorithm per event. - Add hodec_id argument to bsc_handover_start*() to be placed in the bsc_handover struct. - Publish the LOGPHO logging macros in handover.h along with struct bsc_handover, convenient for logging in callback implementations. Replace handover_decision.c's signal handler with a registered handover_decision_callbacks instance. (Upcoming handover_decision_2 will use all of the callbacks introduced here.) Change-Id: Id5b64504007fe03e0406a4b395cd0359232b77d2
2018-02-15 13:10:12 +00:00
struct gsm_lchan *old_lchan;
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
struct gsm_bts *new_bts;
enum gsm_chan_t new_lchan_type;
bool async;
HO: introduce ho decision callbacks Instead of reacting on S_LCHAN* signals in the handover decision code, introduce callbacks for the handover decision to be invoked by handover_logic.c at the appropriate time. The rationale is explained in a comment to struct handover_decision_callbacks, quoting: " All events that are interesting for handover decision are actually communicated by S_LCHAN_* signals, so theoretically, each handover algorithm could evaluate those. However, handover_logic.c cleans up handover operation state upon receiving some of these signals. To allow a handover decision algorithm to take advantage of e.g. the struct bsc_handover before it is discarded, the handover decision event handler needs to be invoked before handover_logic.c discards the state. For example, if the handover decision wants to place a penalty timer upon a handover failure, it still needs to know which target cell the handover failed for; handover_logic.c erases that knowledge on handover failure, since it needs to clean up the lchan's handover state. The most explicit and safest way to ensure the correct order of event handling is to invoke the handover decision algorithm's actions from handover_logic.c itself, before cleaning up. This struct provides the callback functions for this purpose. For consistency, also handle signals in this way that aren't actually in danger of interference from handover_logic.c (which also saves repeated lookup of handover state for lchans). Thus, handover decision algorithms should not register any signal handler at all. " Also: - Publish struct bsc_handover to use it as argument to above callbacks. - Add enum hodec_id to struct bsc_handover, to be able to signal the appropriate hodec algorithm per event. - Add hodec_id argument to bsc_handover_start*() to be placed in the bsc_handover struct. - Publish the LOGPHO logging macros in handover.h along with struct bsc_handover, convenient for logging in callback implementations. Replace handover_decision.c's signal handler with a registered handover_decision_callbacks instance. (Upcoming handover_decision_2 will use all of the callbacks introduced here.) Change-Id: Id5b64504007fe03e0406a4b395cd0359232b77d2
2018-02-15 13:10:12 +00:00
introduce an osmo_fsm for gsm_subscriber_connection In the current implementation of osmo-bsc, the subscriber connection is not handled (very) statefully. However, there is some state keeping in the code that handles the mgcp connection, but there are still to much loose ends which allow odd situations to happen, which then lead severe error situations (see also closes tags at the end) This commit adds a number of improvements to fix those problems. - Use an osmo-fsm to control the gsm_subscriber_connection state and make sure that certain operations can only take place at certain states (e.g let connection oriented SCCP traffic only pass when an SCCP connection actually exists. Remove the old osmo_bsc_mgcp.c code. Use the recently developed MGCP client FSM to handle the MGCP connections. Also make sure that stuff that already works does not break. This in particular refers to the internal handover capability and the respective unit-tests. See also OS#2823, OS#2768 and OS#2898 - Fix logic to permit assignment to a signalling channel. (OS#2762) - Introduce T993210 to release lchan + subscr_conn if MSC fails to respond The GSM specs don't have an explicit timer for this, so let's introdcue a custom timer (hence starting with 99). This timeout catches the following situation: * we send a SCCP CR with COMPL_L3_INFO from the MS to the MSC, * the MSC doesn't respond (e.g. SCCP routing failure, program down, ...) The MS is supposed to timeout with T3210, 3220 or 3230. But the BSC shouldn't trust the MS but have some timer on its own. SCCP would have a timer T(conn est), but that one is specified to be 1-2min and hence rather long. See also: OS#2775 - Terminate bsc_subscr_conn_fsm on SCCP N-DISC.ind from MSC If the MSC is disconnecting the SCCP channel, we must terminate the FSM which in turn will release all lchan's and other state. This makes TC_chan_rel_hard_rlsd pass, see also OS#2731 As a side-effect, this fixes TC_chan_act_ack_est_ind_refused(), where the MSC is answering with CREF to our CR/COMPL_L3. - Release subscriber connection on RLL RELEASE IND of SAPI0 on main DCCH The subscriber connection isn't really useful for anything after the SAPI0 main signalling link has been released. We could try to re-establish, but our best option is probably simply releasing the subscriber_conn and anything related to it. This will make TC_chan_rel_rll_rel_ind pass, see also OS#2730 This commit has been tested using the BSC_Tests TTCN3 testsuit and the following tests were passed: TC_chan_act_noreply TC_chan_act_ack_noest TC_chan_act_ack_est_ind_noreply TC_chan_act_ack_est_ind_refused TC_chan_act_nack TC_chan_exhaustion TC_ctrl TC_chan_rel_conn_fail TC_chan_rel_hard_clear TC_chan_rel_hard_rlsd TC_chan_rel_a_reset TC_rll_est_ind_inact_lchan TC_rll_est_ind_inval_sapi1 TC_rll_est_ind_inval_sapi3 TC_rll_est_ind_inval_sacch TC_assignment_cic_only TC_assignment_csd TC_assignment_ctm TC_assignment_fr_a5_0 TC_assignment_fr_a5_1_codec_missing TC_assignment_fr_a5_1 TC_assignment_fr_a5_3 TC_assignment_fr_a5_4 TC_paging_imsi_nochan TC_paging_tmsi_nochan TC_paging_tmsi_any TC_paging_tmsi_sdcch TC_paging_tmsi_tch_f TC_paging_tmsi_tch_hf TC_paging_imsi_nochan_cgi TC_paging_imsi_nochan_lac_ci TC_paging_imsi_nochan_ci TC_paging_imsi_nochan_lai TC_paging_imsi_nochan_lac TC_paging_imsi_nochan_all TC_paging_imsi_nochan_plmn_lac_rnc TC_paging_imsi_nochan_rnc TC_paging_imsi_nochan_lac_rnc TC_paging_imsi_nochan_lacs TC_paging_imsi_nochan_lacs_empty TC_paging_imsi_a_reset TC_paging_counter TC_rsl_drop_counter TC_classmark TC_unsol_ass_fail TC_unsol_ass_compl TC_unsol_ho_fail TC_err_82_short_msg TC_ho_int Authors: Harald Welte <laforge@gnumonks.org> Philipp Maier <pmaier@sysmocom.de> Neels Hofmeyr <neels@hofmeyr.de> Closes: OS#2730 Closes: OS#2731 Closes: OS#2762 Closes: OS#2768 Closes: OS#2775 Closes: OS#2823 Closes: OS#2898 Closes: OS#2936 Change-Id: I68286d26e2014048b054f39ef29c35fef420cc97
2018-01-28 02:04:16 +00:00
/* Derived and resulting state */
HO: introduce ho decision callbacks Instead of reacting on S_LCHAN* signals in the handover decision code, introduce callbacks for the handover decision to be invoked by handover_logic.c at the appropriate time. The rationale is explained in a comment to struct handover_decision_callbacks, quoting: " All events that are interesting for handover decision are actually communicated by S_LCHAN_* signals, so theoretically, each handover algorithm could evaluate those. However, handover_logic.c cleans up handover operation state upon receiving some of these signals. To allow a handover decision algorithm to take advantage of e.g. the struct bsc_handover before it is discarded, the handover decision event handler needs to be invoked before handover_logic.c discards the state. For example, if the handover decision wants to place a penalty timer upon a handover failure, it still needs to know which target cell the handover failed for; handover_logic.c erases that knowledge on handover failure, since it needs to clean up the lchan's handover state. The most explicit and safest way to ensure the correct order of event handling is to invoke the handover decision algorithm's actions from handover_logic.c itself, before cleaning up. This struct provides the callback functions for this purpose. For consistency, also handle signals in this way that aren't actually in danger of interference from handover_logic.c (which also saves repeated lookup of handover state for lchans). Thus, handover decision algorithms should not register any signal handler at all. " Also: - Publish struct bsc_handover to use it as argument to above callbacks. - Add enum hodec_id to struct bsc_handover, to be able to signal the appropriate hodec algorithm per event. - Add hodec_id argument to bsc_handover_start*() to be placed in the bsc_handover struct. - Publish the LOGPHO logging macros in handover.h along with struct bsc_handover, convenient for logging in callback implementations. Replace handover_decision.c's signal handler with a registered handover_decision_callbacks instance. (Upcoming handover_decision_2 will use all of the callbacks introduced here.) Change-Id: Id5b64504007fe03e0406a4b395cd0359232b77d2
2018-02-15 13:10:12 +00:00
bool inter_cell;
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
uint8_t ho_ref;
enum hodec_id from_hodec_id;
struct gsm_lchan *new_lchan;
struct osmo_timer_list T3103;
HO: introduce ho decision callbacks Instead of reacting on S_LCHAN* signals in the handover decision code, introduce callbacks for the handover decision to be invoked by handover_logic.c at the appropriate time. The rationale is explained in a comment to struct handover_decision_callbacks, quoting: " All events that are interesting for handover decision are actually communicated by S_LCHAN_* signals, so theoretically, each handover algorithm could evaluate those. However, handover_logic.c cleans up handover operation state upon receiving some of these signals. To allow a handover decision algorithm to take advantage of e.g. the struct bsc_handover before it is discarded, the handover decision event handler needs to be invoked before handover_logic.c discards the state. For example, if the handover decision wants to place a penalty timer upon a handover failure, it still needs to know which target cell the handover failed for; handover_logic.c erases that knowledge on handover failure, since it needs to clean up the lchan's handover state. The most explicit and safest way to ensure the correct order of event handling is to invoke the handover decision algorithm's actions from handover_logic.c itself, before cleaning up. This struct provides the callback functions for this purpose. For consistency, also handle signals in this way that aren't actually in danger of interference from handover_logic.c (which also saves repeated lookup of handover state for lchans). Thus, handover decision algorithms should not register any signal handler at all. " Also: - Publish struct bsc_handover to use it as argument to above callbacks. - Add enum hodec_id to struct bsc_handover, to be able to signal the appropriate hodec algorithm per event. - Add hodec_id argument to bsc_handover_start*() to be placed in the bsc_handover struct. - Publish the LOGPHO logging macros in handover.h along with struct bsc_handover, convenient for logging in callback implementations. Replace handover_decision.c's signal handler with a registered handover_decision_callbacks instance. (Upcoming handover_decision_2 will use all of the callbacks introduced here.) Change-Id: Id5b64504007fe03e0406a4b395cd0359232b77d2
2018-02-15 13:10:12 +00:00
};
int bsc_handover_start(enum hodec_id from_hodec_id, struct gsm_lchan *old_lchan, struct gsm_bts *new_bts,
enum gsm_chan_t new_lchan_type);
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
int bsc_handover_start_gscon(struct gsm_subscriber_connection *conn);
void bsc_clear_handover(struct gsm_subscriber_connection *conn, int free_lchan);
struct gsm_lchan *bsc_handover_pending(struct gsm_lchan *new_lchan);
int bsc_ho_count(struct gsm_bts *bts, bool inter_cell);
HO: introduce ho decision callbacks Instead of reacting on S_LCHAN* signals in the handover decision code, introduce callbacks for the handover decision to be invoked by handover_logic.c at the appropriate time. The rationale is explained in a comment to struct handover_decision_callbacks, quoting: " All events that are interesting for handover decision are actually communicated by S_LCHAN_* signals, so theoretically, each handover algorithm could evaluate those. However, handover_logic.c cleans up handover operation state upon receiving some of these signals. To allow a handover decision algorithm to take advantage of e.g. the struct bsc_handover before it is discarded, the handover decision event handler needs to be invoked before handover_logic.c discards the state. For example, if the handover decision wants to place a penalty timer upon a handover failure, it still needs to know which target cell the handover failed for; handover_logic.c erases that knowledge on handover failure, since it needs to clean up the lchan's handover state. The most explicit and safest way to ensure the correct order of event handling is to invoke the handover decision algorithm's actions from handover_logic.c itself, before cleaning up. This struct provides the callback functions for this purpose. For consistency, also handle signals in this way that aren't actually in danger of interference from handover_logic.c (which also saves repeated lookup of handover state for lchans). Thus, handover decision algorithms should not register any signal handler at all. " Also: - Publish struct bsc_handover to use it as argument to above callbacks. - Add enum hodec_id to struct bsc_handover, to be able to signal the appropriate hodec algorithm per event. - Add hodec_id argument to bsc_handover_start*() to be placed in the bsc_handover struct. - Publish the LOGPHO logging macros in handover.h along with struct bsc_handover, convenient for logging in callback implementations. Replace handover_decision.c's signal handler with a registered handover_decision_callbacks instance. (Upcoming handover_decision_2 will use all of the callbacks introduced here.) Change-Id: Id5b64504007fe03e0406a4b395cd0359232b77d2
2018-02-15 13:10:12 +00:00
/* Handover decision algorithms' actions to take on incoming handover-relevant events.
*
* All events that are interesting for handover decision are actually communicated by S_LCHAN_* signals,
* so theoretically, each handover algorithm could evaluate those. However, handover_logic.c cleans up
* handover operation state upon receiving some of these signals. To allow a handover decision algorithm
* to take advantage of e.g. the struct bsc_handover before it is discarded, the handover decision event
* handler needs to be invoked before handover_logic.c discards the state. For example, if the handover
* decision wants to place a penalty timer upon a handover failure, it still needs to know which target
* cell the handover failed for; handover_logic.c erases that knowledge on handover failure, since it
* needs to clean up the lchan's handover state.
*
* The most explicit and safest way to ensure the correct order of event handling is to invoke the
* handover decision algorithm's actions from handover_logic.c itself, before cleaning up. This struct
* provides the callback functions for this purpose.
*
* For consistency, also handle signals in this way that aren't actually in danger of interference from
* handover_logic.c (which also saves repeated lookup of handover state for lchans). Thus, handover
* decision algorithms should not register any signal handler at all.
*/
struct handover_decision_callbacks {
struct llist_head entry;
int hodec_id;
void (*on_measurement_report)(struct gsm_meas_rep *mr);
void (*on_ho_chan_activ_nack)(struct bsc_handover *ho);
void (*on_ho_failure)(struct bsc_handover *ho);
};
void handover_decision_callbacks_register(struct handover_decision_callbacks *hdc);
struct handover_decision_callbacks *handover_decision_callbacks_get(int hodec_id);
struct gsm_bts *bts_by_neighbor_ident(const struct gsm_network *net,
const struct neighbor_ident_key *search_for);
struct neighbor_ident_key *bts_ident_key(const struct gsm_bts *bts);