From 6edf7b9a5180db37521a3a60f5f95ec2ec0e3ef1 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Fri, 23 Apr 2010 18:09:01 +0800 Subject: bsc_msc_ip: Add a timeout for waiting for the CC of the network Start a timeout to wait for the CC of the network and if it does not come in time we will abort the connection and take down the allocated lchans. --- openbsc/include/openbsc/gsm_data.h | 1 + openbsc/src/bsc_msc_ip.c | 66 ++++++++++++++++++++++++++------------ 2 files changed, 47 insertions(+), 20 deletions(-) diff --git a/openbsc/include/openbsc/gsm_data.h b/openbsc/include/openbsc/gsm_data.h index 5fd5ccd3b..d922f1e29 100644 --- a/openbsc/include/openbsc/gsm_data.h +++ b/openbsc/include/openbsc/gsm_data.h @@ -132,6 +132,7 @@ struct bss_sccp_connection_data { struct timer_list T10; /* for SCCP ... */ + struct timer_list sccp_cc_timeout; struct timer_list sccp_it; /* audio handling */ diff --git a/openbsc/src/bsc_msc_ip.c b/openbsc/src/bsc_msc_ip.c index 46796c192..858a15c54 100644 --- a/openbsc/src/bsc_msc_ip.c +++ b/openbsc/src/bsc_msc_ip.c @@ -112,6 +112,41 @@ static void sccp_it_fired(void *_data) bsc_schedule_timer(&data->sccp_it, SCCP_IT_TIMER, 0); } +static void bss_force_close(struct bss_sccp_connection_data *bss) +{ + if (bss->lchan) { + bss->lchan->msc_data = NULL; + put_subscr_con(&bss->lchan->conn, 0); + bss->lchan = NULL; + } + + if (bss->secondary_lchan) { + bss->secondary_lchan->msc_data = NULL; + put_subscr_con(&bss->secondary_lchan->conn, 0); + bss->secondary_lchan = NULL; + } + + /* force the close by poking stuff */ + if (bss->sccp) { + sccp_connection_force_free(bss->sccp); + bss->sccp = NULL; + } + + bss_sccp_free_data(bss); +} + +/* check if this connection was ever confirmed and then recycle */ +static void sccp_check_cc(void *_data) +{ + struct bss_sccp_connection_data *data = _data; + + if (data->sccp->connection_state >= SCCP_CONNECTION_STATE_ESTABLISHED) + return; + + LOGP(DMSC, LOGL_ERROR, "The connection was never established\n"); + bss_force_close(data); +} + /* GSM subscriber drop-ins */ extern struct llist_head *subscr_bsc_active_subscriber(void); @@ -200,8 +235,12 @@ void msc_outgoing_sccp_state(struct sccp_connection *conn, int old_state) LOGP(DMSC, LOGL_DEBUG, "Connection established: %p\n", conn); - /* start the inactivity test timer */ con_data = (struct bss_sccp_connection_data *) conn->data_ctx; + + /* stop the CC timeout */ + bsc_del_timer(&con_data->sccp_cc_timeout); + + /* start the inactivity test timer */ con_data->sccp_it.cb = sccp_it_fired; con_data->sccp_it.data = con_data; bsc_schedule_timer(&con_data->sccp_it, SCCP_IT_TIMER, 0); @@ -263,6 +302,11 @@ static int open_sccp_connection(struct msgb *layer3) sccp_connection->data_ctx = con_data; layer3->lchan->msc_data = con_data; + /* Make sure we open the connection */ + con_data->sccp_cc_timeout.data = con_data; + con_data->sccp_cc_timeout.cb = sccp_check_cc; + bsc_schedule_timer(&con_data->sccp_cc_timeout, 10, 0); + /* FIXME: Use transaction for this */ use_subscr_con(&layer3->lchan->conn); sccp_connection_connect(sccp_connection, &sccp_ssn_bssap, data); @@ -820,25 +864,7 @@ static void msc_connection_was_lost(struct bsc_msc_connection *msc) LOGP(DMSC, LOGL_ERROR, "Lost MSC connection. Freing stuff.\n"); llist_for_each_entry_safe(bss, tmp, &active_connections, active_connections) { - if (bss->lchan) { - bss->lchan->msc_data = NULL; - put_subscr_con(&bss->lchan->conn, 0); - bss->lchan = NULL; - } - - if (bss->secondary_lchan) { - bss->secondary_lchan->msc_data = NULL; - put_subscr_con(&bss->secondary_lchan->conn, 0); - bss->secondary_lchan = NULL; - } - - /* force the close by poking stuff */ - if (bss->sccp) { - sccp_connection_force_free(bss->sccp); - bss->sccp = NULL; - } - - bss_sccp_free_data(bss); + bss_force_close(bss); } msc->is_authenticated = 0; -- cgit v1.2.3