gsm_04_08_cc: Add global guard timer for MNCC

The external MNCC handler may hang indefinitely in cases where the remote
end of the MNCC ceases to work properly. Add a global guard timer to
make sure the call reaches ACTIVE state.

Change-Id: I7375d1e17cd746aac4eadfe1e587e82cf1630d3d
Related: OS#3599
This commit is contained in:
Philipp Maier 2018-10-10 17:00:49 +02:00
parent f6400737f9
commit 9ca7b31cbf
6 changed files with 94 additions and 0 deletions

View File

@ -332,6 +332,9 @@ struct gsm_network {
/* Periodic location update default value */
uint8_t t3212;
/* Global MNCC guard timer value */
int mncc_guard_timeout;
struct {
struct mgcp_client_conf conf;
struct mgcp_client *client;

View File

@ -69,6 +69,7 @@ struct gsm_trans {
int Tcurrent; /* current CC timer */
int T308_second; /* used to send release again */
struct osmo_timer_list timer;
struct osmo_timer_list timer_guard;
struct gsm_mncc msg; /* stores setup/disconnect/release message */
} cc;
struct {

View File

@ -73,6 +73,43 @@
static uint32_t new_callref = 0x80000001;
static void gsm48_cc_guard_timeout(void *arg)
{
struct gsm_trans *trans = arg;
DEBUGP(DCC, "(sub %s) guard timeout expired\n",
vlr_subscr_msisdn_or_name(trans->vsub));
trans_free(trans);
return;
}
static void gsm48_stop_guard_timer(struct gsm_trans *trans)
{
if (osmo_timer_pending(&trans->cc.timer_guard)) {
DEBUGP(DCC, "(sub %s) stopping pending guard timer\n",
vlr_subscr_msisdn_or_name(trans->vsub));
osmo_timer_del(&trans->cc.timer_guard);
}
}
static void gsm48_start_guard_timer(struct gsm_trans *trans)
{
/* NOTE: The purpose of this timer is to prevent the cc state machine
* from hanging in cases where mncc, gsm48 or both become unresponsive
* for some reason. The timer is started initially with the setup from
* the gsm48 side and then re-started with every incoming mncc message.
* Once the mncc state reaches its active state the timer is stopped.
* So if the cc state machine does not show any activity for an
* extended amount of time during call setup or teardown the guard
* timer will time out and hard-clear the connection. */
if (osmo_timer_pending(&trans->cc.timer_guard))
gsm48_stop_guard_timer(trans);
DEBUGP(DCC, "(sub %s) starting guard timer with %d seconds\n",
vlr_subscr_msisdn_or_name(trans->vsub),
trans->net->mncc_guard_timeout);
osmo_timer_setup(&trans->cc.timer_guard, gsm48_cc_guard_timeout, trans);
osmo_timer_schedule(&trans->cc.timer_guard,
trans->net->mncc_guard_timeout, 0);
}
/* Call Control */
@ -149,6 +186,10 @@ static void new_cc_state(struct gsm_trans *trans, int state)
count_statistics(trans, state);
trans->cc.state = state;
/* Stop the guard timer when a call reaches the active state */
if (state == GSM_CSTATE_ACTIVE)
gsm48_stop_guard_timer(trans);
}
static int gsm48_cc_tx_status(struct gsm_trans *trans, void *arg)
@ -259,6 +300,8 @@ void _gsm48_cc_trans_free(struct gsm_trans *trans)
}
if (trans->cc.state != GSM_CSTATE_NULL)
new_cc_state(trans, GSM_CSTATE_NULL);
gsm48_stop_guard_timer(trans);
}
static int gsm48_cc_tx_setup(struct gsm_trans *trans, void *arg);
@ -474,6 +517,8 @@ static int gsm48_cc_rx_setup(struct gsm_trans *trans, struct msgb *msg)
struct tlv_parsed tp;
struct gsm_mncc setup;
gsm48_start_guard_timer(trans);
memset(&setup, 0, sizeof(struct gsm_mncc));
setup.callref = trans->callref;
@ -1970,6 +2015,8 @@ int mncc_tx_to_cc(struct gsm_network *net, int msg_type, void *arg)
log_set_context(LOG_CTX_VLR_SUBSCR, trans->vsub);
}
gsm48_start_guard_timer(trans);
if (trans->conn)
conn = trans->conn;

View File

@ -333,6 +333,16 @@ DEFUN(cfg_msc, cfg_msc_cmd,
return CMD_SUCCESS;
}
DEFUN(cfg_msc_mncc_guard_timeout,
cfg_msc_mncc_guard_timeout_cmd,
"mncc-guard-timeout <0-255>",
"Set global guard timer for mncc interface activity\n"
"guard timer value (sec.)")
{
gsmnet->mncc_guard_timeout = atoi(argv[0]);
return CMD_SUCCESS;
}
DEFUN(cfg_msc_assign_tmsi, cfg_msc_assign_tmsi_cmd,
"assign-tmsi",
"Assign TMSI during Location Updating.\n")
@ -421,6 +431,8 @@ DEFUN(cfg_msc_emergency_msisdn, cfg_msc_emergency_msisdn_cmd,
static int config_write_msc(struct vty *vty)
{
vty_out(vty, "msc%s", VTY_NEWLINE);
vty_out(vty, " mncc-guard-timeout %i%s",
gsmnet->mncc_guard_timeout, VTY_NEWLINE);
vty_out(vty, " %sassign-tmsi%s",
gsmnet->vlr->cfg.assign_tmsi? "" : "no ", VTY_NEWLINE);
@ -1415,6 +1427,7 @@ void msc_vty_init(struct gsm_network *msc_network)
install_element(CONFIG_NODE, &cfg_msc_cmd);
install_node(&msc_node, config_write_msc);
install_element(MSC_NODE, &cfg_msc_assign_tmsi_cmd);
install_element(MSC_NODE, &cfg_msc_mncc_guard_timeout_cmd);
install_element(MSC_NODE, &cfg_msc_no_assign_tmsi_cmd);
install_element(MSC_NODE, &cfg_msc_auth_tuple_max_reuse_count_cmd);
install_element(MSC_NODE, &cfg_msc_auth_tuple_reuse_on_error_cmd);

View File

@ -54,6 +54,8 @@ struct gsm_network *gsm_network_init(void *ctx, mncc_recv_cb_t mncc_recv)
/* Use 30 min periodic update interval as sane default */
net->t3212 = 5;
net->mncc_guard_timeout = 180;
net->paging_response_timer = MSC_PAGING_RESPONSE_TIMER_DEFAULT;
INIT_LLIST_HEAD(&net->trans_list);

View File

@ -277,6 +277,7 @@ DREF VLR subscr MSISDN:42342 usage increases to: 3
DREF MSISDN:42342: MSC conn use + trans_cc == 3 (0x1a: dtap,cm_service,trans_cc)
DMM MSISDN:42342: rx msg GSM48_MT_CC_SETUP: received_cm_service_request changes to false
DREF MSISDN:42342: MSC conn use - cm_service == 2 (0x12: dtap,trans_cc)
DCC (sub 42342) starting guard timer with 180 seconds
DCC (ti 08 sub MSISDN:42342) new state NULL -> INITIATED
DCC Subscriber MSISDN:42342 (42342) sends SETUP to 123
DMNCC transmit message MNCC_SETUP_IND
@ -287,6 +288,8 @@ DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_ACCEPTED}: state_c
DREF MSISDN:42342: MSC conn use - dtap == 1 (0x10: trans_cc)
- MNCC says that's fine
DMNCC receive message MNCC_CALL_PROC_REQ
DCC (sub 42342) stopping pending guard timer
DCC (sub 42342) starting guard timer with 180 seconds
DCC (ti 08 sub 42342) Received 'MNCC_CALL_PROC_REQ' from MNCC in state 1 (INITIATED)
DCC (ti 08 sub MSISDN:42342) new state INITIATED -> MO_CALL_PROC
DMSC msc_tx 2 bytes to MSISDN:42342 via RAN_UTRAN_IU
@ -296,12 +299,16 @@ DMSC msc_tx 2 bytes to MSISDN:42342 via RAN_UTRAN_IU
- Total time passed: 1.000023 s
- The other call leg got established (not shown here), MNCC tells us so
DMNCC receive message MNCC_ALERT_REQ
DCC (sub 42342) stopping pending guard timer
DCC (sub 42342) starting guard timer with 180 seconds
DCC (ti 08 sub 42342) Received 'MNCC_ALERT_REQ' from MNCC in state 3 (MO_CALL_PROC)
DCC (ti 08 sub MSISDN:42342) new state MO_CALL_PROC -> CALL_DELIVERED
DMSC msc_tx 2 bytes to MSISDN:42342 via RAN_UTRAN_IU
- DTAP --RAN_UTRAN_IU--> MS: GSM48_MT_CC_ALERTING: 8301
- DTAP matches expected message
DMNCC receive message MNCC_SETUP_RSP
DCC (sub 42342) stopping pending guard timer
DCC (sub 42342) starting guard timer with 180 seconds
DCC (ti 08 sub 42342) Received 'MNCC_SETUP_RSP' from MNCC in state 4 (CALL_DELIVERED)
DCC starting timer T313 with 30 seconds
DCC (ti 08 sub MSISDN:42342) new state CALL_DELIVERED -> CONNECT_IND
@ -314,6 +321,7 @@ DREF MSISDN:42342: MSC conn use + dtap == 2 (0x12: dtap,trans_cc)
DRLL Dispatching 04.08 message GSM48_MT_CC_CONNECT_ACK (0x3:0xf)
DCC stopping pending timer T313
DCC (ti 08 sub MSISDN:42342) new state CONNECT_IND -> ACTIVE
DCC (sub 42342) stopping pending guard timer
DMNCC transmit message MNCC_SETUP_COMPL_IND
DCC Sending 'MNCC_SETUP_COMPL_IND' to MNCC.
MSC --> MNCC: callref 0x80000001: MNCC_SETUP_COMPL_IND
@ -334,6 +342,7 @@ DCC Sending 'MNCC_DISC_IND' to MNCC.
DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_COMMUNICATING}: Received Event SUBSCR_CONN_E_COMMUNICATING
DREF MSISDN:42342: MSC conn use - dtap == 1 (0x10: trans_cc)
DMNCC receive message MNCC_REL_REQ
DCC (sub 42342) starting guard timer with 180 seconds
DCC (ti 08 sub 42342) Received 'MNCC_REL_REQ' from MNCC in state 12 (DISCONNECT_IND)
DCC starting timer T308 with 10 seconds
DCC (ti 08 sub MSISDN:42342) new state DISCONNECT_IND -> RELEASE_REQ
@ -349,6 +358,7 @@ DCC Sending 'MNCC_REL_CNF' to MNCC.
MSC --> MNCC: callref 0x80000001: MNCC_REL_CNF
MS <--Call Release-- MSC: subscr=MSISDN:42342 callref=0x0
DCC (ti 08 sub MSISDN:42342) new state RELEASE_REQ -> NULL
DCC (sub 42342) stopping pending guard timer
DREF VLR subscr MSISDN:42342 usage decreases to: 2
DREF MSISDN:42342: MSC conn use - trans_cc == 1 (0x2: dtap)
DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_COMMUNICATING}: Received Event SUBSCR_CONN_E_COMMUNICATING
@ -697,8 +707,10 @@ DCC Sending 'MNCC_SETUP_CNF' to MNCC.
DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_COMMUNICATING}: Received Event SUBSCR_CONN_E_COMMUNICATING
DREF MSISDN:42342: MSC conn use - dtap == 1 (0x10: trans_cc)
DMNCC receive message MNCC_SETUP_COMPL_REQ
DCC (sub 42342) starting guard timer with 180 seconds
DCC (ti 00 sub 42342) Received 'MNCC_SETUP_COMPL_REQ' from MNCC in state 8 (CONNECT_REQUEST)
DCC (ti 00 sub MSISDN:42342) new state CONNECT_REQUEST -> ACTIVE
DCC (sub 42342) stopping pending guard timer
DMSC msc_tx 2 bytes to MSISDN:42342 via RAN_UTRAN_IU
- DTAP --RAN_UTRAN_IU--> MS: GSM48_MT_CC_CONNECT_ACK: 030f
- DTAP matches expected message
@ -717,6 +729,7 @@ DCC Sending 'MNCC_DISC_IND' to MNCC.
DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_COMMUNICATING}: Received Event SUBSCR_CONN_E_COMMUNICATING
DREF MSISDN:42342: MSC conn use - dtap == 1 (0x10: trans_cc)
DMNCC receive message MNCC_REL_REQ
DCC (sub 42342) starting guard timer with 180 seconds
DCC (ti 00 sub 42342) Received 'MNCC_REL_REQ' from MNCC in state 12 (DISCONNECT_IND)
DCC starting timer T308 with 10 seconds
DCC (ti 00 sub MSISDN:42342) new state DISCONNECT_IND -> RELEASE_REQ
@ -732,6 +745,7 @@ DCC Sending 'MNCC_REL_CNF' to MNCC.
MSC --> MNCC: callref 0x423: MNCC_REL_CNF
MS <--Call Release-- MSC: subscr=MSISDN:42342 callref=0x0
DCC (ti 00 sub MSISDN:42342) new state RELEASE_REQ -> NULL
DCC (sub 42342) stopping pending guard timer
DREF VLR subscr MSISDN:42342 usage decreases to: 2
DREF MSISDN:42342: MSC conn use - trans_cc == 1 (0x2: dtap)
DMM Subscr_Conn(PAGING_RESP:901700000010650){SUBSCR_CONN_S_COMMUNICATING}: Received Event SUBSCR_CONN_E_COMMUNICATING
@ -1078,6 +1092,7 @@ DREF VLR subscr MSISDN:42342 usage decreases to: 3
DCC stopping pending timer T301
MS <--Call Release-- MSC: subscr=MSISDN:42342 callref=0x423
DMNCC receive message MNCC_REL_REQ
DCC (sub 42342) starting guard timer with 180 seconds
DCC (ti 00 sub 42342) Received 'MNCC_REL_REQ' from MNCC in state 7 (CALL_RECEIVED)
DCC starting timer T308 with 10 seconds
DCC (ti 00 sub MSISDN:42342) new state CALL_RECEIVED -> RELEASE_REQ
@ -1089,6 +1104,7 @@ DCC Sending 'MNCC_REL_CNF' to MNCC.
MSC --> MNCC: callref 0x423: MNCC_REL_CNF
DCC stopping pending timer T308
DCC (ti 00 sub MSISDN:42342) new state RELEASE_REQ -> NULL
DCC (sub 42342) stopping pending guard timer
DREF VLR subscr MSISDN:42342 usage decreases to: 2
DREF MSISDN:42342: MSC conn use - trans_cc == 1 (0x100: release)
- Iu Release --RAN_UTRAN_IU--> MS
@ -1389,6 +1405,7 @@ DREF VLR subscr MSISDN:42342 usage increases to: 3
DREF MSISDN:42342: MSC conn use + trans_cc == 3 (0x1a: dtap,cm_service,trans_cc)
DMM MSISDN:42342: rx msg GSM48_MT_CC_SETUP: received_cm_service_request changes to false
DREF MSISDN:42342: MSC conn use - cm_service == 2 (0x12: dtap,trans_cc)
DCC (sub 42342) starting guard timer with 180 seconds
DCC (ti 08 sub MSISDN:42342) new state NULL -> INITIATED
DCC Subscriber MSISDN:42342 (42342) sends SETUP to 123
DMNCC transmit message MNCC_SETUP_IND
@ -1399,6 +1416,8 @@ DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_ACCEPTED}: state_c
DREF MSISDN:42342: MSC conn use - dtap == 1 (0x10: trans_cc)
- MNCC says that's fine
DMNCC receive message MNCC_CALL_PROC_REQ
DCC (sub 42342) stopping pending guard timer
DCC (sub 42342) starting guard timer with 180 seconds
DCC (ti 08 sub 42342) Received 'MNCC_CALL_PROC_REQ' from MNCC in state 1 (INITIATED)
DCC (ti 08 sub MSISDN:42342) new state INITIATED -> MO_CALL_PROC
DMSC msc_tx 2 bytes to MSISDN:42342 via RAN_UTRAN_IU
@ -1407,6 +1426,8 @@ DMSC msc_tx 2 bytes to MSISDN:42342 via RAN_UTRAN_IU
MS <--Call Assignment-- MSC: subscr=MSISDN:42342 callref=0x80000002
- But the other side's MSISDN could not be resolved, MNCC tells us to cancel
DMNCC receive message MNCC_REL_REQ
DCC (sub 42342) stopping pending guard timer
DCC (sub 42342) starting guard timer with 180 seconds
DCC (ti 08 sub 42342) Received 'MNCC_REL_REQ' from MNCC in state 3 (MO_CALL_PROC)
DCC starting timer T308 with 10 seconds
DCC (ti 08 sub MSISDN:42342) new state MO_CALL_PROC -> RELEASE_REQ
@ -1427,6 +1448,7 @@ DCC Sending 'MNCC_REL_CNF' to MNCC.
MSC --> MNCC: callref 0x80000002: MNCC_REL_CNF
MS <--Call Release-- MSC: subscr=MSISDN:42342 callref=0x0
DCC (ti 08 sub MSISDN:42342) new state RELEASE_REQ -> NULL
DCC (sub 42342) stopping pending guard timer
DREF VLR subscr MSISDN:42342 usage decreases to: 2
DREF MSISDN:42342: MSC conn use - trans_cc == 1 (0x2: dtap)
DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_COMMUNICATING}: Received Event SUBSCR_CONN_E_COMMUNICATING
@ -1733,6 +1755,7 @@ DREF VLR subscr MSISDN:42342 usage increases to: 3
DREF MSISDN:42342: MSC conn use + trans_cc == 3 (0x1a: dtap,cm_service,trans_cc)
DMM MSISDN:42342: rx msg GSM48_MT_CC_SETUP: received_cm_service_request changes to false
DREF MSISDN:42342: MSC conn use - cm_service == 2 (0x12: dtap,trans_cc)
DCC (sub 42342) starting guard timer with 180 seconds
DCC (ti 08 sub MSISDN:42342) new state NULL -> INITIATED
DCC Subscriber MSISDN:42342 (42342) sends SETUP to 123
DMNCC transmit message MNCC_SETUP_IND
@ -1743,6 +1766,8 @@ DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_ACCEPTED}: state_c
DREF MSISDN:42342: MSC conn use - dtap == 1 (0x10: trans_cc)
- MNCC says that's fine
DMNCC receive message MNCC_CALL_PROC_REQ
DCC (sub 42342) stopping pending guard timer
DCC (sub 42342) starting guard timer with 180 seconds
DCC (ti 08 sub 42342) Received 'MNCC_CALL_PROC_REQ' from MNCC in state 1 (INITIATED)
DCC (ti 08 sub MSISDN:42342) new state INITIATED -> MO_CALL_PROC
DMSC msc_tx 2 bytes to MSISDN:42342 via RAN_UTRAN_IU
@ -1751,6 +1776,8 @@ DMSC msc_tx 2 bytes to MSISDN:42342 via RAN_UTRAN_IU
MS <--Call Assignment-- MSC: subscr=MSISDN:42342 callref=0x80000003
- But the other side's MSISDN could not be resolved, MNCC tells us to cancel
DMNCC receive message MNCC_REL_REQ
DCC (sub 42342) stopping pending guard timer
DCC (sub 42342) starting guard timer with 180 seconds
DCC (ti 08 sub 42342) Received 'MNCC_REL_REQ' from MNCC in state 3 (MO_CALL_PROC)
DCC starting timer T308 with 10 seconds
DCC (ti 08 sub MSISDN:42342) new state MO_CALL_PROC -> RELEASE_REQ
@ -1770,6 +1797,7 @@ DMNCC transmit message MNCC_REL_CNF
DCC Sending 'MNCC_REL_CNF' to MNCC.
MSC --> MNCC: callref 0x80000003: MNCC_REL_CNF
DCC (ti 08 sub MSISDN:42342) new state RELEASE_REQ -> NULL
DCC (sub 42342) stopping pending guard timer
DREF VLR subscr MSISDN:42342 usage decreases to: 2
DREF MSISDN:42342: MSC conn use - trans_cc == 0 (0x0: )
DMM Subscr_Conn(CM_SERVICE_REQ:901700000010650){SUBSCR_CONN_S_COMMUNICATING}: Received Event SUBSCR_CONN_E_UNUSED