aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc
diff options
context:
space:
mode:
authorHolger Hans Peter Freyther <zecke@selfish.org>2010-04-23 18:09:01 +0800
committerHolger Hans Peter Freyther <zecke@selfish.org>2010-04-23 18:22:26 +0800
commit6edf7b9a5180db37521a3a60f5f95ec2ec0e3ef1 (patch)
treed9a5c117b3e0da0fc7c371fa6b21709f26080948 /openbsc
parente4045679a8bc746c5fb2a85872ca074f02add241 (diff)
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.
Diffstat (limited to 'openbsc')
-rw-r--r--openbsc/include/openbsc/gsm_data.h1
-rw-r--r--openbsc/src/bsc_msc_ip.c66
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;