aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHolger Hans Peter Freyther <zecke@selfish.org>2013-05-01 18:44:04 +0200
committerHolger Hans Peter Freyther <zecke@selfish.org>2013-05-02 19:36:29 +0200
commit2177624ca998c9a35595681c1595693544357b49 (patch)
treef06538f78f23f22c10912bea41bf4a9bfd49e031
parente152a46f6e171976f9adb20f5e11d44769ba7a31 (diff)
channels: Mark channels as broken that time out on activation/release
A channel that fails to send an ACK/NACK/REL within the four second timeout is now marked as broken. In case the release comes in late it will be ignored. The lchan should already been freed and for now we don't want to trust the channel. In the future we might want to send a "release" for a channel that got activated ack late and just set the state to none on a channel that is released acked late. The late ACK and REL has been tested with two manual tests using the fakebts. The channels remained blocked even after having received the ACK message here. The NACK case has not been manually tested.
-rw-r--r--openbsc/src/libbsc/abis_rsl.c31
1 files changed, 27 insertions, 4 deletions
diff --git a/openbsc/src/libbsc/abis_rsl.c b/openbsc/src/libbsc/abis_rsl.c
index 644706f7b..7aae590fc 100644
--- a/openbsc/src/libbsc/abis_rsl.c
+++ b/openbsc/src/libbsc/abis_rsl.c
@@ -196,10 +196,11 @@ static void lchan_act_tmr_cb(void *data)
{
struct gsm_lchan *lchan = data;
- LOGP(DRSL, LOGL_ERROR, "%s Timeout during activation!\n",
+ LOGP(DRSL, LOGL_ERROR,
+ "%s Timeout during activation. Marked as broken.\n",
gsm_lchan_name(lchan));
- rsl_lchan_set_state(lchan, LCHAN_S_NONE);
+ rsl_lchan_set_state(lchan, LCHAN_S_BROKEN);
lchan_free(lchan);
}
@@ -207,10 +208,12 @@ static void lchan_deact_tmr_cb(void *data)
{
struct gsm_lchan *lchan = data;
- LOGP(DRSL, LOGL_ERROR, "%s Timeout during deactivation!\n",
+ LOGP(DRSL, LOGL_ERROR,
+ "%s Timeout during deactivation! Marked as broken.\n",
gsm_lchan_name(lchan));
- do_lchan_free(lchan);
+ rsl_lchan_set_state(lchan, LCHAN_S_BROKEN);
+ lchan_free(lchan);
}
@@ -737,6 +740,13 @@ static int rsl_rx_rf_chan_rel_ack(struct gsm_lchan *lchan)
osmo_timer_del(&lchan->act_timer);
osmo_timer_del(&lchan->T3111);
+ if (lchan->state == LCHAN_S_BROKEN) {
+ /* we are leaving this channel broken for now */
+ LOGP(DRSL, LOGL_NOTICE, "%s CHAN REL ACK for broken channel.\n",
+ gsm_lchan_name(lchan));
+ return 0;
+ }
+
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",
gsm_lchan_name(lchan),
@@ -907,6 +917,12 @@ static int rsl_rx_chan_act_ack(struct msgb *msg)
osmo_timer_del(&msg->lchan->act_timer);
+ if (msg->lchan->state == LCHAN_S_BROKEN) {
+ LOGP(DRSL, LOGL_NOTICE, "%s CHAN ACT ACK for broken channel.\n",
+ gsm_lchan_name(msg->lchan));
+ return 0;
+ }
+
if (msg->lchan->state != LCHAN_S_ACT_REQ)
LOGP(DRSL, LOGL_NOTICE, "%s CHAN ACT ACK, but state %s\n",
gsm_lchan_name(msg->lchan),
@@ -933,6 +949,13 @@ static int rsl_rx_chan_act_nack(struct msgb *msg)
osmo_timer_del(&msg->lchan->act_timer);
+ if (msg->lchan->state == LCHAN_S_BROKEN) {
+ LOGP(DRSL, LOGL_ERROR,
+ "%s CHANNEL ACTIVATE NACK for broken channel.\n",
+ gsm_lchan_name(msg->lchan));
+ return -1;
+ }
+
LOGP(DRSL, LOGL_ERROR, "%s CHANNEL ACTIVATE NACK ",
gsm_lchan_name(msg->lchan));