diff options
author | Holger Hans Peter Freyther <zecke@selfish.org> | 2010-09-16 20:48:15 +0800 |
---|---|---|
committer | Holger Hans Peter Freyther <zecke@selfish.org> | 2010-09-16 20:53:04 +0800 |
commit | aaa40b868896b77f47890c0b21fe4a6baa34adb6 (patch) | |
tree | dd2c7391b5abf2b490b49266e7414b7d045feee0 /openbsc/src/bsc_api.c | |
parent | 2f9d1ef39ac66acfe7796db985377ef80a627d82 (diff) |
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.
Diffstat (limited to 'openbsc/src/bsc_api.c')
-rw-r--r-- | openbsc/src/bsc_api.c | 34 |
1 files changed, 27 insertions, 7 deletions
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; } |