lchan: Remember why a channel is broken using static strings

Remember why a channel is being marked as broken. So we can
maybe understand what happend.
diff --git a/openbsc/include/openbsc/abis_rsl.h b/openbsc/include/openbsc/abis_rsl.h
index 1609c48..b27595e 100644
--- a/openbsc/include/openbsc/abis_rsl.h
+++ b/openbsc/include/openbsc/abis_rsl.h
@@ -71,6 +71,7 @@
 			enum rsl_rel_mode release_mode);
 
 int rsl_lchan_set_state(struct gsm_lchan *lchan, int);
+int rsl_lchan_mark_broken(struct gsm_lchan *lchan, const char *broken);
 
 /* to be provided by external code */
 int rsl_deact_sacch(struct gsm_lchan *lchan);
diff --git a/openbsc/include/openbsc/gsm_data_shared.h b/openbsc/include/openbsc/gsm_data_shared.h
index 54dda1f..ac54fb2 100644
--- a/openbsc/include/openbsc/gsm_data_shared.h
+++ b/openbsc/include/openbsc/gsm_data_shared.h
@@ -195,6 +195,7 @@
 	enum lchan_csd_mode csd_mode;
 	/* State */
 	enum gsm_lchan_state state;
+	const char *broken_reason;
 	/* Power levels for MS and BTS */
 	uint8_t bs_power;
 	uint8_t ms_power;
diff --git a/openbsc/src/libbsc/abis_rsl.c b/openbsc/src/libbsc/abis_rsl.c
index ae405c9..479323d 100644
--- a/openbsc/src/libbsc/abis_rsl.c
+++ b/openbsc/src/libbsc/abis_rsl.c
@@ -210,7 +210,7 @@
 		"%s Timeout during activation. Marked as broken.\n",
 		gsm_lchan_name(lchan));
 
-	rsl_lchan_set_state(lchan, LCHAN_S_BROKEN);
+	rsl_lchan_mark_broken(lchan, "activation timeout");
 	lchan_free(lchan);
 }
 
@@ -222,7 +222,7 @@
 		"%s Timeout during deactivation! Marked as broken.\n",
 		gsm_lchan_name(lchan));
 
-	rsl_lchan_set_state(lchan, LCHAN_S_BROKEN);
+	rsl_lchan_mark_broken(lchan, "de-activation timeout");
 	lchan_free(lchan);
 }
 
@@ -943,6 +943,13 @@
 	return 0;
 }
 
+int rsl_lchan_mark_broken(struct gsm_lchan *lchan, const char *reason)
+{
+	lchan->state = LCHAN_S_BROKEN;
+	lchan->broken_reason = reason;
+	return 0;
+}
+
 int rsl_lchan_set_state(struct gsm_lchan *lchan, int state)
 {
 	lchan->state = state;
@@ -1013,13 +1020,14 @@
 		print_rsl_cause(LOGL_ERROR, cause,
 				TLVP_LEN(&tp, RSL_IE_CAUSE));
 		msg->lchan->error_cause = *cause;
-		if (*cause != RSL_ERR_RCH_ALR_ACTV_ALLOC)
-			rsl_lchan_set_state(msg->lchan, LCHAN_S_BROKEN);
-		else
+		if (*cause != RSL_ERR_RCH_ALR_ACTV_ALLOC) {
+			rsl_lchan_mark_broken(msg->lchan, "NACK on activation");
+		} else
 			rsl_rf_chan_release(msg->lchan, 1, SACCH_DEACTIVATE);
 
-	} else
-		rsl_lchan_set_state(msg->lchan, LCHAN_S_BROKEN);
+	} else {
+		rsl_lchan_mark_broken(msg->lchan, "NACK on activation no IE");
+	}
 
 	LOGPC(DRSL, LOGL_ERROR, "\n");
 
diff --git a/openbsc/src/libbsc/bsc_vty.c b/openbsc/src/libbsc/bsc_vty.c
index 0e38a7c..3e7ac58 100644
--- a/openbsc/src/libbsc/bsc_vty.c
+++ b/openbsc/src/libbsc/bsc_vty.c
@@ -959,9 +959,12 @@
 	vty_out(vty, "BTS %u, TRX %u, Timeslot %u, Lchan %u: Type %s%s",
 		lchan->ts->trx->bts->nr, lchan->ts->trx->nr, lchan->ts->nr,
 		lchan->nr, gsm_lchant_name(lchan->type), VTY_NEWLINE);
-	vty_out(vty, "  Connection: %u, State: %s%s",
+	vty_out(vty, "  Connection: %u, State: %s%s%s%s",
 		lchan->conn ? 1: 0,
-		gsm_lchans_name(lchan->state), VTY_NEWLINE);
+		gsm_lchans_name(lchan->state),
+		lchan->state == LCHAN_S_BROKEN ? " Error reason: " : "",
+		lchan->state == LCHAN_S_BROKEN ? lchan->broken_reason : "",
+		VTY_NEWLINE);
 	vty_out(vty, "  BS Power: %u dBm, MS Power: %u dBm%s",
 		lchan->ts->trx->nominal_power - lchan->ts->trx->max_power_red
 		- lchan->bs_power*2,
diff --git a/openbsc/src/libbsc/chan_alloc.c b/openbsc/src/libbsc/chan_alloc.c
index c86556b..d8f9087 100644
--- a/openbsc/src/libbsc/chan_alloc.c
+++ b/openbsc/src/libbsc/chan_alloc.c
@@ -198,6 +198,8 @@
 
 		/* clear multi rate config */
 		memset(&lchan->mr_conf, 0, sizeof(lchan->mr_conf));
+
+		lchan->broken_reason = "";
 	} else {
 		struct challoc_signal_data sig;
 		sig.bts = bts;