aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHolger Hans Peter Freyther <zecke@selfish.org>2010-09-16 20:48:15 +0800
committerHolger Hans Peter Freyther <zecke@selfish.org>2010-09-16 20:53:04 +0800
commitaaa40b868896b77f47890c0b21fe4a6baa34adb6 (patch)
treedd2c7391b5abf2b490b49266e7414b7d045feee0
parent2f9d1ef39ac66acfe7796db985377ef80a627d82 (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.
-rw-r--r--openbsc/src/bsc_api.c34
-rw-r--r--openbsc/src/gsm_04_08.c2
-rw-r--r--openbsc/src/osmo_msc.c1
3 files changed, 30 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;
}
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);
}