aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHolger Hans Peter Freyther <zecke@selfish.org>2009-11-17 20:42:09 +0100
committerHolger Hans Peter Freyther <zecke@selfish.org>2009-11-20 17:40:28 +0100
commit80fb260a604fe49517d968ae1e9c0cc78a18b5de (patch)
tree8199744f03a992eb549b66cb8d6aa78e366aeb7c
parent55a0716da7d06860addfba1812c309eac6d82f1a (diff)
[lchan] Release the channel ones its' usecount drops to zero
Remove the timer handling from the LCHAN and release the channel ones the use count is dropping to zero. Change code that was sending/using the lchan after the release and change the send data method to warn in case the lchan is used after it has been freed.
-rw-r--r--openbsc/include/openbsc/chan_alloc.h26
-rw-r--r--openbsc/include/openbsc/gsm_data.h23
-rw-r--r--openbsc/src/abis_rsl.c4
-rw-r--r--openbsc/src/bsc_msc_ip.c1
-rw-r--r--openbsc/src/bssap.c1
-rw-r--r--openbsc/src/chan_alloc.c27
-rw-r--r--openbsc/src/gsm_04_08.c5
-rw-r--r--openbsc/src/gsm_subscriber_base.c1
-rw-r--r--openbsc/src/transaction.c7
-rw-r--r--openbsc/tests/channel/channel_test.c1
10 files changed, 44 insertions, 52 deletions
diff --git a/openbsc/include/openbsc/chan_alloc.h b/openbsc/include/openbsc/chan_alloc.h
index 38855d1ee..ef42fe1c5 100644
--- a/openbsc/include/openbsc/chan_alloc.h
+++ b/openbsc/include/openbsc/chan_alloc.h
@@ -23,6 +23,28 @@
#include "gsm_subscriber.h"
+/*
+ * Refcounting for the lchan. If the refcount drops to zero
+ * the channel will send a RSL release request.
+ */
+#define use_lchan(lchan) \
+ do { lchan->use_count++; \
+ DEBUGP(DCC, "lchan (bts=%d,trx=%d,ts=%d,ch=%d) increases usage to: %d\n", \
+ lchan->ts->trx->bts->nr, lchan->ts->trx->nr, lchan->ts->nr, \
+ lchan->nr, lchan->use_count); \
+ } while(0);
+
+#define put_lchan(lchan) \
+ do { lchan->use_count--; \
+ DEBUGP(DCC, "lchan (bts=%d,trx=%d,ts=%d,ch=%d) decreases usage to: %d\n", \
+ lchan->ts->trx->bts->nr, lchan->ts->trx->nr, lchan->ts->nr, \
+ lchan->nr, lchan->use_count); \
+ if (lchan->use_count <= 0) \
+ _lchan_release(lchan); \
+ } while(0);
+
+
+
/* Special allocator for C0 of BTS */
struct gsm_bts_trx_ts *ts_c0_alloc(struct gsm_bts *bts,
enum gsm_phys_chan_config pchan);
@@ -46,7 +68,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);
+/* internal.. do not use */
+int _lchan_release(struct gsm_lchan *lchan);
#endif /* _CHAN_ALLOC_H */
diff --git a/openbsc/include/openbsc/gsm_data.h b/openbsc/include/openbsc/gsm_data.h
index 1e66fa482..34bead6ed 100644
--- a/openbsc/include/openbsc/gsm_data.h
+++ b/openbsc/include/openbsc/gsm_data.h
@@ -85,26 +85,6 @@ typedef int gsm_cbfn(unsigned int hooknum,
struct msgb *msg,
void *data, void *param);
-/*
- * Use the channel. As side effect the lchannel recycle timer
- * will be started.
- */
-#define LCHAN_RELEASE_TIMEOUT 20, 0
-#define use_lchan(lchan) \
- do { lchan->use_count++; \
- DEBUGP(DCC, "lchan (bts=%d,trx=%d,ts=%d,ch=%d) increases usage to: %d\n", \
- lchan->ts->trx->bts->nr, lchan->ts->trx->nr, lchan->ts->nr, \
- lchan->nr, lchan->use_count); \
- bsc_schedule_timer(&lchan->release_timer, LCHAN_RELEASE_TIMEOUT); } while(0);
-
-#define put_lchan(lchan) \
- do { lchan->use_count--; \
- DEBUGP(DCC, "lchan (bts=%d,trx=%d,ts=%d,ch=%d) decreases usage to: %d\n", \
- lchan->ts->trx->bts->nr, lchan->ts->trx->nr, lchan->ts->nr, \
- lchan->nr, lchan->use_count); \
- } while(0);
-
-
/* communications link with a BTS */
struct gsm_bts_link {
struct gsm_bts *bts;
@@ -203,9 +183,6 @@ struct gsm_lchan {
/* To whom we are allocated at the moment */
struct gsm_subscriber *subscr;
- /* Timer started to release the channel */
- struct timer_list release_timer;
-
struct timer_list T3101;
/* Established data link layer services */
diff --git a/openbsc/src/abis_rsl.c b/openbsc/src/abis_rsl.c
index ef3dfae25..4df2ce1aa 100644
--- a/openbsc/src/abis_rsl.c
+++ b/openbsc/src/abis_rsl.c
@@ -837,6 +837,10 @@ int rsl_data_request(struct msgb *msg, u_int8_t link_id)
return -EINVAL;
}
+ if (msg->lchan->use_count <= 0) {
+ DEBUGP(DRSL, "BUG: Trying to send data on unused lchan\n");
+ }
+
/* First push the L3 IE tag and length */
msgb_tv16_push(msg, RSL_IE_L3_INFO, l3_len);
diff --git a/openbsc/src/bsc_msc_ip.c b/openbsc/src/bsc_msc_ip.c
index dc1445b6a..0d441ebbc 100644
--- a/openbsc/src/bsc_msc_ip.c
+++ b/openbsc/src/bsc_msc_ip.c
@@ -44,6 +44,7 @@
#include <openbsc/bssap.h>
#include <openbsc/paging.h>
#include <openbsc/signal.h>
+#include <openbsc/chan_alloc.h>
#include <sccp/sccp.h>
diff --git a/openbsc/src/bssap.c b/openbsc/src/bssap.c
index 14b6bb64f..39f7d046d 100644
--- a/openbsc/src/bssap.c
+++ b/openbsc/src/bssap.c
@@ -28,6 +28,7 @@
#include <openbsc/signal.h>
#include <openbsc/tlv.h>
#include <openbsc/paging.h>
+#include <openbsc/chan_alloc.h>
#include <sccp/sccp.h>
diff --git a/openbsc/src/chan_alloc.c b/openbsc/src/chan_alloc.c
index 0b9d4199d..b4f080585 100644
--- a/openbsc/src/chan_alloc.c
+++ b/openbsc/src/chan_alloc.c
@@ -33,8 +33,6 @@
#include <openbsc/debug.h>
#include <openbsc/signal.h>
-static void auto_release_channel(void *_lchan);
-
struct gsm_bts_trx_ts *ts_c0_alloc(struct gsm_bts *bts,
enum gsm_phys_chan_config pchan)
{
@@ -221,10 +219,6 @@ struct gsm_lchan *lchan_alloc(struct gsm_bts *bts, enum gsm_chan_t type)
/* clear any msc reference */
lchan->msc_data = NULL;
- /* Configure the time and start it so it will be closed */
- lchan->release_timer.cb = auto_release_channel;
- lchan->release_timer.data = lchan;
- bsc_schedule_timer(&lchan->release_timer, LCHAN_RELEASE_TIMEOUT);
}
return lchan;
@@ -245,44 +239,35 @@ void lchan_free(struct gsm_lchan *lchan)
lchan->use_count = 0;
}
- /* stop the timer */
- bsc_del_timer(&lchan->release_timer);
-
/* FIXME: ts_free() the timeslot, if we're the last logical
* channel using it */
}
/* Consider releasing the channel now */
-int lchan_auto_release(struct gsm_lchan *lchan)
+int _lchan_release(struct gsm_lchan *lchan)
{
if (lchan->use_count > 0) {
+ DEBUGP(DRLL, "BUG: _lchan_release called without zero use_count.\n");
return 0;
}
/* Assume we have GSM04.08 running and send a release */
if (lchan->subscr) {
+ ++lchan->use_count;
gsm48_send_rr_release(lchan);
+ --lchan->use_count;
}
/* spoofed? message */
if (lchan->use_count < 0) {
- DEBUGP(DRLL, "Channel count is negative: %d\n", lchan->use_count);
+ DEBUGP(DRLL, "BUG: channel count is negative: %d\n", lchan->use_count);
}
- DEBUGP(DRLL, "Recycling the channel with: %d (%x)\n", lchan->nr, lchan->nr);
+ DEBUGP(DRLL, "Releasing the channel with: %d (%x)\n", lchan->nr, lchan->nr);
rsl_release_request(lchan, 0);
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))
- bsc_schedule_timer(&lchan->release_timer, LCHAN_RELEASE_TIMEOUT);
-}
-
struct gsm_lchan* lchan_find(struct gsm_bts *bts, struct gsm_subscriber *subscr) {
struct gsm_bts_trx *trx;
int ts_no, lchan_no;
diff --git a/openbsc/src/gsm_04_08.c b/openbsc/src/gsm_04_08.c
index 1f8235411..6be83da6c 100644
--- a/openbsc/src/gsm_04_08.c
+++ b/openbsc/src/gsm_04_08.c
@@ -296,13 +296,13 @@ static int gsm0408_authorize(struct gsm_lchan *lchan, struct msgb *msg)
int rc;
db_subscriber_alloc_tmsi(lchan->subscr);
- release_loc_updating_req(lchan);
rc = gsm0408_loc_upd_acc(msg->lchan, lchan->subscr->tmsi);
/* call subscr_update after putting the loc_upd_acc
* in the transmit queue, since S_SUBSCR_ATTACHED might
* trigger further action like SMS delivery */
subscr_update(lchan->subscr, msg->trx->bts,
GSM_SUBSCRIBER_UPDATE_ATTACHED);
+ release_loc_updating_req(lchan);
return rc;
}
@@ -972,9 +972,8 @@ static void loc_upd_rej_cb(void *data)
{
struct gsm_lchan *lchan = data;
- release_loc_updating_req(lchan);
gsm0408_loc_upd_rej(lchan, reject_cause);
- lchan_auto_release(lchan);
+ release_loc_updating_req(lchan);
}
static void schedule_reject(struct gsm_lchan *lchan)
diff --git a/openbsc/src/gsm_subscriber_base.c b/openbsc/src/gsm_subscriber_base.c
index 2255b127b..929834e42 100644
--- a/openbsc/src/gsm_subscriber_base.c
+++ b/openbsc/src/gsm_subscriber_base.c
@@ -32,6 +32,7 @@
#include <openbsc/paging.h>
#include <openbsc/debug.h>
#include <openbsc/paging.h>
+#include <openbsc/chan_alloc.h>
LLIST_HEAD(active_subscribers);
void *tall_subscr_ctx;
diff --git a/openbsc/src/transaction.c b/openbsc/src/transaction.c
index 04eaa3c99..03735d4a4 100644
--- a/openbsc/src/transaction.c
+++ b/openbsc/src/transaction.c
@@ -28,6 +28,7 @@
#include <openbsc/gsm_04_08.h>
#include <openbsc/mncc.h>
#include <openbsc/paging.h>
+#include <openbsc/chan_alloc.h>
void *tall_trans_ctx;
@@ -95,14 +96,14 @@ void trans_free(struct gsm_trans *trans)
break;
}
- if (trans->lchan)
- put_lchan(trans->lchan);
-
if (!trans->lchan && trans->subscr && trans->subscr->net) {
/* Stop paging on all bts' */
paging_request_stop(NULL, trans->subscr, NULL);
}
+ if (trans->lchan)
+ put_lchan(trans->lchan);
+
if (trans->subscr)
subscr_put(trans->subscr);
diff --git a/openbsc/tests/channel/channel_test.c b/openbsc/tests/channel/channel_test.c
index 1b01878b5..ed0f3ad57 100644
--- a/openbsc/tests/channel/channel_test.c
+++ b/openbsc/tests/channel/channel_test.c
@@ -76,4 +76,5 @@ int main(int argc, char** argv)
void nm_state_event() {}
void input_event() {}
void sms_alloc() {}
+void _lchan_release() {}