aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/openbsc/abis_rsl.h2
-rw-r--r--include/openbsc/chan_alloc.h3
-rw-r--r--src/chan_alloc.c28
-rw-r--r--src/gsm_04_08.c4
-rw-r--r--tests/gsm0408/gsm0408_test.c1
5 files changed, 22 insertions, 16 deletions
diff --git a/include/openbsc/abis_rsl.h b/include/openbsc/abis_rsl.h
index a0e8cba62..e7fea8088 100644
--- a/include/openbsc/abis_rsl.h
+++ b/include/openbsc/abis_rsl.h
@@ -345,7 +345,6 @@ int rsl_chan_activate(struct gsm_bts *bts, u_int8_t chan_nr,
u_int8_t ta);
int rsl_chan_activate_tch_f(struct gsm_bts_trx_ts *ts);
int rsl_chan_activate_sdcch(struct gsm_bts_trx_ts *ts);
-int rsl_chan_release(struct gsm_lchan *lchan);
int rsl_paging_cmd(struct gsm_bts *bts, u_int8_t paging_group, u_int8_t len,
u_int8_t *ms_ident, u_int8_t chan_needed);
int rsl_paging_cmd_imsi(struct gsm_bts *bts, u_int8_t chan_needed, const char *imsi_str);
@@ -357,6 +356,7 @@ int abis_rsl_rcvmsg(struct msgb *msg);
/* to be provided by external code */
int abis_rsl_sendmsg(struct msgb *msg);
+int rsl_chan_release(struct gsm_lchan *lchan);
#endif /* RSL_MT_H */
diff --git a/include/openbsc/chan_alloc.h b/include/openbsc/chan_alloc.h
index 0cbd03e72..0c6d63e64 100644
--- a/include/openbsc/chan_alloc.h
+++ b/include/openbsc/chan_alloc.h
@@ -19,4 +19,7 @@ struct gsm_lchan *lchan_alloc(struct gsm_bts *bts, enum gsm_chan_t type);
/* Free a logical channel (SDCCH, TCH, ...) */
void lchan_free(struct gsm_lchan *lchan);
+/* Consider releasing the channel */
+int lchan_auto_release(struct gsm_lchan *lchan);
+
#endif /* _CHAN_ALLOC_H */
diff --git a/src/chan_alloc.c b/src/chan_alloc.c
index bb71d35d9..98588b18f 100644
--- a/src/chan_alloc.c
+++ b/src/chan_alloc.c
@@ -29,6 +29,7 @@
#include <openbsc/gsm_data.h>
#include <openbsc/chan_alloc.h>
#include <openbsc/abis_nm.h>
+#include <openbsc/abis_rsl.h>
#include <openbsc/debug.h>
static void auto_release_channel(void *_lchan);
@@ -196,28 +197,29 @@ void lchan_free(struct gsm_lchan *lchan)
* channel using it */
}
-/*
- * Auto release the channel when the use count is zero
- */
-static void auto_release_channel(void *_lchan)
+/* Consider releasing the channel now */
+int lchan_auto_release(struct gsm_lchan *lchan)
{
- struct gsm_lchan *lchan = _lchan;
- /*
- * Busy...
- */
if (lchan->use_count > 0) {
- schedule_timer(&lchan->release_timer, LCHAN_RELEASE_TIMEOUT);
- return;
+ return 0;
}
- /*
- * spoofed? message
- */
+ /* spoofed? message */
if (lchan->use_count < 0) {
DEBUGP(DRLL, "Channel count is negative: %d\n", lchan->use_count);
}
DEBUGP(DRLL, "Recylcing the channel with: %d (%x)\n", lchan->nr, lchan->nr);
rsl_chan_release(lchan);
+ return 1;
+}
+
+/* Auto release the channel when the use count is zero */
+static void auto_release_channel(void *_lchan)
+{
+ struct gsm_lchan *lchan = _lchan;
+
+ if (!lchan_auto_release(lchan))
+ schedule_timer(&lchan->release_timer, LCHAN_RELEASE_TIMEOUT);
}
diff --git a/src/gsm_04_08.c b/src/gsm_04_08.c
index fc7457943..61080b454 100644
--- a/src/gsm_04_08.c
+++ b/src/gsm_04_08.c
@@ -98,12 +98,12 @@ static void release_loc_updating_req(struct gsm_lchan *lchan)
static void allocate_loc_updating_req(struct gsm_lchan *lchan)
{
+ use_lchan(lchan);
release_loc_updating_req(lchan);
lchan->loc_operation = (struct gsm_loc_updating_operation *)
malloc(sizeof(*lchan->loc_operation));
memset(lchan->loc_operation, 0, sizeof(*lchan->loc_operation));
- use_lchan(lchan);
}
static void parse_lai(struct gsm_lai *lai, const struct gsm48_loc_area_id *lai48)
@@ -397,7 +397,7 @@ static void loc_upd_rej_cb(void *data)
release_loc_updating_req(lchan);
gsm0408_loc_upd_rej(lchan, reject_cause);
- rsl_chan_release(lchan);
+ lchan_auto_release(lchan);
}
static void schedule_reject(struct gsm_lchan *lchan)
diff --git a/tests/gsm0408/gsm0408_test.c b/tests/gsm0408/gsm0408_test.c
index af625377c..0fe13108e 100644
--- a/tests/gsm0408/gsm0408_test.c
+++ b/tests/gsm0408/gsm0408_test.c
@@ -80,3 +80,4 @@ void db_create_subscriber(void) {}
void rsl_chan_release(void) {}
void msgb_alloc(void) {}
void gsm0411_send_sms(void) {}
+void lchan_auto_release(void) {}