[handover] Introduce new handover related LCHAN signals

This introduces the signals S_LCHAN_ACTIVATE_{ACK,NACK} and
S_LCAN_HANDOVER_{FAIL,COMPL,DETECT} as well as code that actually issues
those signals.  The signals are relevant for a yet-to-be-written handover
control logic.
diff --git a/openbsc/include/openbsc/signal.h b/openbsc/include/openbsc/signal.h
index fee9d5b..fbd61ae 100644
--- a/openbsc/include/openbsc/signal.h
+++ b/openbsc/include/openbsc/signal.h
@@ -78,6 +78,11 @@
 	 * signal handler.
 	 */
 	S_LCHAN_UNEXPECTED_RELEASE,
+	S_LCHAN_ACTIVATE_ACK,		/* 08.58 Channel Activate ACK */
+	S_LCHAN_ACTIVATE_NACK,		/* 08.58 Channel Activate NACK */
+	S_LCHAN_HANDOVER_COMPL,		/* 04.08 Handover Completed */
+	S_LCHAN_HANDOVER_FAIL,		/* 04.08 Handover Failed */
+	S_LCHAN_HANDOVER_DETECT,	/* 08.58 Handover Detect */
 };
 
 /* SS_SUBSCR signals */
diff --git a/openbsc/src/abis_rsl.c b/openbsc/src/abis_rsl.c
index 743dc5f..8033a3c 100644
--- a/openbsc/src/abis_rsl.c
+++ b/openbsc/src/abis_rsl.c
@@ -907,7 +907,9 @@
 	 * to assign the activated channel to the MS */
 	if (rslh->ie_chan != RSL_IE_CHAN_NR)
 		return -EINVAL;
-	
+
+	dispatch_signal(SS_LCHAN, S_LCHAN_ACTIVATE_ACK, msg->lchan);
+
 	return 0;
 }
 
@@ -926,6 +928,8 @@
 		print_rsl_cause(TLVP_VAL(&tp, RSL_IE_CAUSE),
 				TLVP_LEN(&tp, RSL_IE_CAUSE));
 
+	dispatch_signal(SS_LCHAN, S_LCHAN_ACTIVATE_NACK, msg->lchan);
+
 	lchan_free(msg->lchan);
 	return 0;
 }
@@ -1050,6 +1054,27 @@
 	return 0;
 }
 
+/* Chapter 8.4.7 */
+static int rsl_rx_hando_det(struct msgb *msg)
+{
+	struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
+	struct tlv_parsed tp;
+
+	DEBUGP(DRSL, "HANDOVER DETECT ");
+
+	rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
+
+	if (TLVP_PRESENT(&tp, RSL_IE_ACCESS_DELAY))
+		DEBUGPC(DRSL, "access delay = %u\n",
+			*TLVP_VAL(&tp, RSL_IE_ACCESS_DELAY));
+	else
+		DEBUGPC(DRSL, "\n");
+
+	dispatch_signal(SS_LCHAN, S_LCHAN_HANDOVER_DETECT, msg->lchan);
+
+	return 0;
+}
+
 static int abis_rsl_rx_dchan(struct msgb *msg)
 {
 	struct abis_rsl_dchan_hdr *rslh = msgb_l2(msg);
@@ -1077,6 +1102,9 @@
 	case RSL_MT_MEAS_RES:
 		rc = rsl_rx_meas_res(msg);
 		break;
+	case RSL_MT_HANDO_DET:
+		rc = rsl_rx_hando_det(msg);
+		break;
 	case RSL_MT_RF_CHAN_REL_ACK:
 		DEBUGPC(DRSL, "RF CHANNEL RELEASE ACK\n");
 		lchan_free(msg->lchan);
diff --git a/openbsc/src/gsm_04_08.c b/openbsc/src/gsm_04_08.c
index eeeb739..e225bf3 100644
--- a/openbsc/src/gsm_04_08.c
+++ b/openbsc/src/gsm_04_08.c
@@ -1563,6 +1563,33 @@
 	return db_apdu_blob_store(msg->lchan->subscr, apdu_id_flags, apdu_len, apdu_data);
 }
 
+/* Chapter 9.1.16 Handover complete */
+static gsm48_rx_rr_ho_compl(struct msgb *msg)
+{
+	struct gsm48_hdr *gh = msgb_l3(msg);
+
+	DEBUGP(DRR, "HANDOVER COMPLETE cause = %s\n",
+		rr_cause_name(gh->data[0]));
+
+	dispatch_signal(SS_LCHAN, S_LCHAN_HANDOVER_COMPL, msg->lchan);
+	/* FIXME: release old channel */
+
+	return 0;
+}
+
+/* Chapter 9.1.17 Handover Failure */
+static gsm48_rx_rr_ho_fail(struct msgb *msg)
+{
+	struct gsm48_hdr *gh = msgb_l3(msg);
+
+	DEBUGP(DRR, "HANDOVER FAILED cause = %s\n",
+		rr_cause_name(gh->data[0]));
+
+	dispatch_signal(SS_LCHAN, S_LCHAN_HANDOVER_FAIL, msg->lchan);
+	/* FIXME: release allocated new channel */
+
+	return 0;
+}
 
 /* Receive a GSM 04.08 Radio Resource (RR) message */
 static int gsm0408_rcv_rr(struct msgb *msg)
@@ -1597,12 +1624,10 @@
 		/* FIXME: check for MI (if any) */
 		break;
 	case GSM48_MT_RR_HANDO_COMPL:
-		DEBUGP(DRR, "HANDOVER COMPLETE\n");
-		/* FIXME: release old channel */
+		rc = gsm48_rx_rr_ho_compl(msg);
 		break;
 	case GSM48_MT_RR_HANDO_FAIL:
-		DEBUGP(DRR, "HANDOVER FAILED\n");
-		/* FIXME: release allocated new channel */
+		rc = gsm48_rx_rr_ho_fail(msg);
 		break;
 	default:
 		fprintf(stderr, "Unimplemented GSM 04.08 RR msg type 0x%02x\n",