From e8bd9e885dc50f671d2c4af4267b56c84bf7bb6d Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Wed, 10 Aug 2011 23:26:33 +0200 Subject: RSL: add timer for lchan activation/deactivation without BTS response The timer callback will simply reset the lchan state to NONE in order to prevent channels getting stuck in 'activation requested' or 'deactivation requested' states. --- openbsc/include/openbsc/gsm_data_shared.h | 1 + openbsc/src/libbsc/abis_rsl.c | 38 ++++++++++++++++++++++++++++++- 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/openbsc/include/openbsc/gsm_data_shared.h b/openbsc/include/openbsc/gsm_data_shared.h index e3ab5f483..89375cf42 100644 --- a/openbsc/include/openbsc/gsm_data_shared.h +++ b/openbsc/include/openbsc/gsm_data_shared.h @@ -182,6 +182,7 @@ struct gsm_lchan { struct osmo_timer_list T3101; struct osmo_timer_list T3111; struct osmo_timer_list error_timer; + struct osmo_timer_list act_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 f20b4f2b5..8a326def9 100644 --- a/openbsc/src/libbsc/abis_rsl.c +++ b/openbsc/src/libbsc/abis_rsl.c @@ -178,6 +178,27 @@ static void print_rsl_cause(int lvl, const uint8_t *cause_v, uint8_t cause_len) LOGPC(DRSL, lvl, "%02x ", cause_v[i]); } +static void lchan_act_tmr_cb(void *data) +{ + struct gsm_lchan *lchan = data; + + LOGP(DRSL, LOGL_NOTICE, "%s Timeout during activation!\n", + gsm_lchan_name(lchan)); + + lchan->state = LCHAN_S_NONE; +} + +static void lchan_deact_tmr_cb(void *data) +{ + struct gsm_lchan *lchan = data; + + LOGP(DRSL, LOGL_NOTICE, "%s Timeout during deactivation!\n", + gsm_lchan_name(lchan)); + + lchan->state = LCHAN_S_NONE; +} + + /* Send a BCCH_INFO message as per Chapter 8.5.1 */ int rsl_bcch_info(struct gsm_bts_trx *trx, uint8_t type, const uint8_t *data, int len) @@ -609,6 +630,11 @@ static int rsl_rf_chan_release(struct gsm_lchan *lchan, int error) msg->trx->bts->network->T3111 + 2, 0); } + /* Start another timer or assume the BTS sends a ACK/NACK? */ + lchan->act_timer.cb = lchan_deact_tmr_cb; + lchan->act_timer.data = lchan; + osmo_timer_schedule(&lchan->act_timer, 4, 0); + rc = abis_rsl_sendmsg(msg); /* BTS will respond by RF CHAN REL ACK */ @@ -626,6 +652,8 @@ 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); + 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), @@ -791,6 +819,8 @@ static int rsl_rx_chan_act_ack(struct msgb *msg) if (rslh->ie_chan != RSL_IE_CHAN_NR) return -EINVAL; + osmo_timer_del(&msg->lchan->act_timer); + 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), @@ -815,6 +845,8 @@ static int rsl_rx_chan_act_nack(struct msgb *msg) struct abis_rsl_dchan_hdr *dh = msgb_l2(msg); struct tlv_parsed tp; + osmo_timer_del(&msg->lchan->act_timer); + LOGP(DRSL, LOGL_ERROR, "%s CHANNEL ACTIVATE NACK", gsm_lchan_name(msg->lchan)); @@ -1257,7 +1289,11 @@ static int rsl_rx_chan_rqd(struct msgb *msg) lchan->rsl_cmode = RSL_CMOD_SPD_SIGN; lchan->tch_mode = GSM48_CMODE_SIGN; - /* FIXME: Start another timer or assume the BTS sends a ACK/NACK? */ + /* Start another timer or assume the BTS sends a ACK/NACK? */ + lchan->act_timer.cb = lchan_act_tmr_cb; + lchan->act_timer.data = lchan; + osmo_timer_schedule(&lchan->act_timer, 4, 0); + rsl_chan_activate_lchan(lchan, 0x00, rqd_ta, 0); DEBUGP(DRSL, "%s Activating ARFCN(%u) SS(%u) lctype %s " -- cgit v1.2.3