aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHarald Welte <laforge@gnumonks.org>2011-08-10 23:26:33 +0200
committerHarald Welte <laforge@gnumonks.org>2011-08-11 17:21:23 +0200
commite8bd9e885dc50f671d2c4af4267b56c84bf7bb6d (patch)
treebf7b5e09ae846630bc2bdebfe33c07758310a4b2
parent5da9b52d069af235d2c7c9d04166abda5a26231b (diff)
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.
-rw-r--r--openbsc/include/openbsc/gsm_data_shared.h1
-rw-r--r--openbsc/src/libbsc/abis_rsl.c38
2 files changed, 38 insertions, 1 deletions
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 "