aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@gnumonks.org>2011-08-14 14:33:10 +0200
committerHarald Welte <laforge@gnumonks.org>2011-08-14 16:24:14 +0200
commitd406a847c4e80aa7e0e849116b3124e6be47b88b (patch)
treebf9f5c5d8ddfa0974368bab1a8d243a4729e8eee
parent571a9488e8075af4d46046c7a39666e2bf7b04c7 (diff)
rsl: add timer to release channel if we don't get release req ack/nackcamp2011
This patch adds a timer to release the channel after 4 seconds if we don't get a release request ack/nack from the BTS. This should fix the problem with channels in release request state in the Nokia metrostation.
-rw-r--r--openbsc/include/openbsc/chan_alloc.h3
-rw-r--r--openbsc/include/openbsc/gsm_data_shared.h1
-rw-r--r--openbsc/src/libbsc/abis_rsl.c4
-rw-r--r--openbsc/src/libbsc/chan_alloc.c19
4 files changed, 26 insertions, 1 deletions
diff --git a/openbsc/include/openbsc/chan_alloc.h b/openbsc/include/openbsc/chan_alloc.h
index 5eda312ac..443e39bb3 100644
--- a/openbsc/include/openbsc/chan_alloc.h
+++ b/openbsc/include/openbsc/chan_alloc.h
@@ -48,6 +48,9 @@ void lchan_reset(struct gsm_lchan *lchan);
/* Release the given lchan */
int lchan_release(struct gsm_lchan *lchan, int sach_deact, int reason);
+/* Schedule release request timer */
+void lchan_timer_rel_req_schedule(struct gsm_lchan *lchan);
+
struct load_counter {
unsigned int total;
unsigned int used;
diff --git a/openbsc/include/openbsc/gsm_data_shared.h b/openbsc/include/openbsc/gsm_data_shared.h
index 89375cf42..099b8082a 100644
--- a/openbsc/include/openbsc/gsm_data_shared.h
+++ b/openbsc/include/openbsc/gsm_data_shared.h
@@ -183,6 +183,7 @@ struct gsm_lchan {
struct osmo_timer_list T3111;
struct osmo_timer_list error_timer;
struct osmo_timer_list act_timer;
+ struct osmo_timer_list rel_timer;
/* table of neighbor cell measurements */
struct neigh_meas_proc neigh_meas[MAX_NEIGH_MEAS];
diff --git a/openbsc/src/libbsc/abis_rsl.c b/openbsc/src/libbsc/abis_rsl.c
index cb2c9bcc5..8b06f2f51 100644
--- a/openbsc/src/libbsc/abis_rsl.c
+++ b/openbsc/src/libbsc/abis_rsl.c
@@ -655,6 +655,7 @@ static int rsl_rx_rf_chan_rel_ack(struct gsm_lchan *lchan)
DEBUGP(DRSL, "%s RF CHANNEL RELEASE ACK\n", gsm_lchan_name(lchan));
osmo_timer_del(&lchan->act_timer);
+ osmo_timer_del(&lchan->rel_timer);
if (lchan->state != LCHAN_S_REL_REQ && lchan->state != LCHAN_S_REL_ERR)
LOGP(DRSL, LOGL_NOTICE, "%s CHAN REL ACK but state %s\n",
@@ -798,7 +799,8 @@ int rsl_release_request(struct gsm_lchan *lchan, uint8_t link_id, uint8_t reason
/* 0 is normal release, 1 is local end */
msgb_tv_put(msg, RSL_IE_RELEASE_MODE, reason);
- /* FIXME: start some timer in case we don't receive a REL ACK ? */
+ /* Start some timer in case we don't receive a REL ACK ? */
+ lchan_timer_rel_req_schedule(lchan);
msg->trx = lchan->ts->trx;
diff --git a/openbsc/src/libbsc/chan_alloc.c b/openbsc/src/libbsc/chan_alloc.c
index 6f4fe20f8..d0fd9ae33 100644
--- a/openbsc/src/libbsc/chan_alloc.c
+++ b/openbsc/src/libbsc/chan_alloc.c
@@ -397,6 +397,8 @@ static void _lchan_handle_release(struct gsm_lchan *lchan)
if (lchan->sach_deact) {
gsm48_send_rr_release(lchan);
+ /* Make sure we don't stay in release request state forever. */
+ lchan_timer_rel_req_schedule(lchan);
return;
}
@@ -509,3 +511,20 @@ void network_chan_load(struct pchan_load *pl, struct gsm_network *net)
bts_chan_load(pl, bts);
}
+static void lchan_rel_tmr_cb(void *data)
+{
+ struct gsm_lchan *lchan = data;
+
+ LOGP(DRSL, LOGL_NOTICE, "%s Timeout while in release request state!\n",
+ gsm_lchan_name(lchan));
+
+ rsl_lchan_set_state(lchan, LCHAN_S_NONE);
+ lchan_free(lchan);
+}
+
+void lchan_timer_rel_req_schedule(struct gsm_lchan *lchan)
+{
+ lchan->rel_timer.cb = lchan_rel_tmr_cb;
+ lchan->rel_timer.data = lchan;
+ osmo_timer_schedule(&lchan->rel_timer, 4, 0);
+}