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.
This commit is contained in:
Holger Hans Peter Freyther 2013-05-01 18:44:04 +02:00
parent e152a46f6e
commit 2177624ca9
1 changed files with 27 additions and 4 deletions

View File

@ -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));