From aaa40b868896b77f47890c0b21fe4a6baa34adb6 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Thu, 16 Sep 2010 20:48:15 +0800 Subject: bsc_api: Do not free the subscriber conn on clear and clear request Do not free the GSM Subscriber Connection when a channel is failing or if a clear is requested, instead just give up _all_ the channels, reset them to NULL and free the remaining channels. --- openbsc/src/bsc_api.c | 34 +++++++++++++++++++++++++++------- openbsc/src/gsm_04_08.c | 2 ++ openbsc/src/osmo_msc.c | 1 + 3 files changed, 30 insertions(+), 7 deletions(-) (limited to 'openbsc') diff --git a/openbsc/src/bsc_api.c b/openbsc/src/bsc_api.c index 5048f2b96..576440f9d 100644 --- a/openbsc/src/bsc_api.c +++ b/openbsc/src/bsc_api.c @@ -184,15 +184,25 @@ int gsm0808_cipher_mode(struct gsm_subscriber_connection *conn, int cipher, return -1; } +/* + * Release all occupied RF Channels but stay around for more. + */ int gsm0808_clear(struct gsm_subscriber_connection* conn) { struct gsm_lchan *lchan; - bsc_clear_handover(conn); - lchan = conn->lchan; - subscr_con_free(conn); - lchan_release(lchan, 1, 0); + conn->lchan = NULL; + conn->ho_lchan = NULL; + conn->bts = NULL; + + if (conn->ho_lchan) + bsc_clear_handover(conn); + if (conn->lchan) + lchan_release(lchan, 1, 0); + conn->lchan->conn = NULL; + conn->lchan = NULL; + return 0; } @@ -232,6 +242,7 @@ static int bsc_handle_lchan_signal(unsigned int subsys, unsigned int signal, { struct bsc_api *bsc; struct gsm_lchan *lchan; + struct gsm_subscriber_connection *conn; if (subsys != SS_LCHAN || signal != S_LCHAN_UNEXPECTED_RELEASE) return 0; @@ -241,11 +252,20 @@ static int bsc_handle_lchan_signal(unsigned int subsys, unsigned int signal, return 0; bsc = lchan->ts->trx->bts->network->bsc_api; - if (!bsc || !bsc->clear_request) + if (!bsc) return 0; - bsc->clear_request(lchan->conn, 0); - subscr_con_free(lchan->conn); + conn = lchan->conn; + if (bsc->clear_request) + bsc->clear_request(conn, 0); + + /* now give up all channels */ + if (conn->lchan == lchan) + conn->lchan = NULL; + if (conn->ho_lchan == lchan) + conn->ho_lchan = NULL; + gsm0808_clear(conn); + return 0; } diff --git a/openbsc/src/gsm_04_08.c b/openbsc/src/gsm_04_08.c index f022c04a9..b451be748 100644 --- a/openbsc/src/gsm_04_08.c +++ b/openbsc/src/gsm_04_08.c @@ -326,6 +326,8 @@ void gsm0408_clear_request(struct gsm_subscriber_connection* conn, uint32_t caus if (trans->conn == conn) trans_free(trans); } + + subscr_con_free(conn); } /* Chapter 9.2.14 : Send LOCATION UPDATING REJECT */ diff --git a/openbsc/src/osmo_msc.c b/openbsc/src/osmo_msc.c index 6543a61dc..97f36f54e 100644 --- a/openbsc/src/osmo_msc.c +++ b/openbsc/src/osmo_msc.c @@ -92,4 +92,5 @@ void msc_release_connection(struct gsm_subscriber_connection *conn) /* no more connections, asking to release the channel */ conn->in_release = 1; gsm0808_clear(conn); + subscr_con_free(conn); } -- cgit v1.2.3