diff options
author | Holger Hans Peter Freyther <zecke@selfish.org> | 2010-11-06 23:50:06 +0100 |
---|---|---|
committer | Holger Hans Peter Freyther <zecke@selfish.org> | 2010-11-15 20:06:49 +0100 |
commit | 00f4cc22c8a51c076b4a6a8103d4fddaa5efb3c4 (patch) | |
tree | 02e61d56859eb161eb01262c574f21ce127f9b90 /openbsc/src/bsc | |
parent | ca5c022a3278194ba4a1d8235a31e7cc94f12f42 (diff) |
bsc: Implement closing the connections when the MSC goes missing
Refactor the closing code of the CC timeout to a new function,
also make sure that the SCCP Connection is forced closed before
we destruct the connection for real.
Diffstat (limited to 'openbsc/src/bsc')
-rw-r--r-- | openbsc/src/bsc/osmo_bsc_sccp.c | 48 |
1 files changed, 40 insertions, 8 deletions
diff --git a/openbsc/src/bsc/osmo_bsc_sccp.c b/openbsc/src/bsc/osmo_bsc_sccp.c index b397b095e..ab0112b18 100644 --- a/openbsc/src/bsc/osmo_bsc_sccp.c +++ b/openbsc/src/bsc/osmo_bsc_sccp.c @@ -25,6 +25,7 @@ #include <openbsc/osmo_bsc_grace.h> #include <openbsc/osmo_msc_data.h> #include <openbsc/debug.h> +#include <openbsc/signal.h> #include <osmocore/gsm0808.h> #include <osmocore/talloc.h> @@ -46,6 +47,19 @@ static void msc_outgoing_sccp_state(struct sccp_connection *conn, int old_state) { } +static void bsc_sccp_force_free(struct osmo_bsc_sccp_con *data) +{ + if (data->conn) { + gsm0808_clear(data->conn); + subscr_con_free(data->conn); + data->conn = NULL; + } + + sccp_connection_force_free(data->sccp); + data->sccp = NULL; + bsc_delete_connection(data); +} + static void sccp_it_timeout(void *_data) { struct osmo_bsc_sccp_con *data = @@ -64,14 +78,7 @@ static void sccp_cc_timeout(void *_data) return; LOGP(DMSC, LOGL_ERROR, "The connection was never established.\n"); - - - if (data->conn) { - gsm0808_clear(data->conn); - subscr_con_free(data->conn); - data->conn = NULL; - } - bsc_delete_connection(data); + bsc_sccp_force_free(data); } static void msc_sccp_write_ipa(struct sccp_connection *conn, struct msgb *msg, void *data) @@ -198,6 +205,29 @@ int bsc_delete_connection(struct osmo_bsc_sccp_con *sccp) return 0; } +static void bsc_close_connections(struct bsc_msc_connection *msc_con) +{ + struct osmo_bsc_sccp_con *con, *tmp; + + llist_for_each_entry_safe(con, tmp, &active_connections, entry) + bsc_sccp_force_free(con); +} + +static int handle_msc_signal(unsigned int subsys, unsigned int signal, + void *handler_data, void *signal_data) +{ + struct osmo_msc_data *data; + + if (subsys != SS_MSC) + return 0; + + data = (struct osmo_msc_data *) signal_data; + if (signal == S_MSC_LOST) + bsc_close_connections(data->msc_con); + + return 0; +} + int osmo_bsc_sccp_init(struct gsm_network *gsmnet) { sccp_set_log_area(DSCCP); @@ -205,5 +235,7 @@ int osmo_bsc_sccp_init(struct gsm_network *gsmnet) sccp_connection_set_incoming(&sccp_ssn_bssap, msc_sccp_accept, NULL); sccp_set_read(&sccp_ssn_bssap, msc_sccp_read, NULL); + register_signal_handler(SS_MSC, handle_msc_signal, gsmnet); + return 0; } |