aboutsummaryrefslogtreecommitdiffstats
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
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.
-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;