aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc/src/bssap.c
diff options
context:
space:
mode:
authorHolger Hans Peter Freyther <zecke@selfish.org>2010-04-08 21:29:31 +0200
committerHolger Hans Peter Freyther <zecke@selfish.org>2010-04-08 21:29:31 +0200
commitb2c55c49a82a9564122a9a11c5049a45a0da2025 (patch)
tree8e95a21dd73732599533ad58e589cf717dc4e1f2 /openbsc/src/bssap.c
parent8dc241959c1de81a75d7334d6d2a82c75de626d0 (diff)
bsc_msc_ip: Attempt to handle assignment failures more properly
1.) when we do get a assignment failure from the MS. It is coming on the old channel and not the new one. Fix the comparison. Also always reset the msc_data to NULL before dropping the reference 2.) the LCHAN signal handler in bssap.c claims that the T10 expire cb should free the secondary channel. It currently does not do it and we have to do it now... the whole thing was not tested and even after this commit this behavior is not heavily excercised... with OsmocoreBB we would be able to do this in the future.
Diffstat (limited to 'openbsc/src/bssap.c')
-rw-r--r--openbsc/src/bssap.c35
1 files changed, 35 insertions, 0 deletions
diff --git a/openbsc/src/bssap.c b/openbsc/src/bssap.c
index ee51a392f..edbe66717 100644
--- a/openbsc/src/bssap.c
+++ b/openbsc/src/bssap.c
@@ -295,14 +295,48 @@ reject:
}
/*
+ * handle network failures... and free the secondary lchan
+ */
+static void bssmap_free_secondary(struct bss_sccp_connection_data *data)
+{
+ struct gsm_lchan *lchan;
+
+ if (!data || !data->secondary_lchan)
+ return;
+
+ lchan = data->secondary_lchan;
+ if (lchan->msc_data != data) {
+ LOGP(DMSC, LOGL_ERROR, "MSC data does not match on lchan and cb.\n");
+ data->secondary_lchan = NULL;
+ }
+
+ /* give up additional data */
+ lchan->msc_data->secondary_lchan = NULL;
+ if (lchan->msc_data->lchan == lchan)
+ lchan->msc_data->lchan = NULL;
+ lchan->msc_data = NULL;
+
+ /* give up the new channel to not do a SACCH deactivate */
+ subscr_put(lchan->conn.subscr);
+ lchan->conn.subscr = NULL;
+ put_subscr_con(&lchan->conn, 1);
+}
+
+/*
* Handle the network configurable T10 parameter
*/
static void bssmap_t10_fired(void *_conn)
{
+ struct bss_sccp_connection_data *msc_data;
struct sccp_connection *conn = (struct sccp_connection *) _conn;
struct msgb *resp;
LOGP(DMSC, LOGL_ERROR, "T10 fired, assignment failed: %p\n", conn);
+
+ /* free the secondary channel if we have one */
+ msc_data = conn->data_ctx;
+ bssmap_free_secondary(msc_data);
+
resp = bssmap_create_assignment_failure(
GSM0808_CAUSE_NO_RADIO_RESOURCE_AVAILABLE, NULL);
if (!resp) {
@@ -1293,6 +1327,7 @@ void gsm0808_send_assignment_failure(struct gsm_lchan *lchan, u_int8_t cause, u_
struct msgb *resp;
bsc_del_timer(&lchan->msc_data->T10);
+ bssmap_free_secondary(lchan->msc_data);
resp = bssmap_create_assignment_failure(cause, rr_value);
if (!resp) {
LOGP(DMSC, LOGL_ERROR, "Allocation failure: %p\n", lchan_get_sccp(lchan));