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.
diff --git a/openbsc/include/openbsc/gsm_data_shared.h b/openbsc/include/openbsc/gsm_data_shared.h
index e3ab5f4..89375cf 100644
--- a/openbsc/include/openbsc/gsm_data_shared.h
+++ b/openbsc/include/openbsc/gsm_data_shared.h
@@ -182,6 +182,7 @@
 	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 f20b4f2..8a326de 100644
--- a/openbsc/src/libbsc/abis_rsl.c
+++ b/openbsc/src/libbsc/abis_rsl.c
@@ -178,6 +178,27 @@
 		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 @@
 				   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 @@
 
 	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 @@
 	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 @@
 	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 @@
 	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 "