handover: Call bsc_handover_clear from gsm0808_clear

The bsc_handover_clear will release an in-progress handover
and free the lchana and the data associated with this handover
diff --git a/openbsc/include/openbsc/handover.h b/openbsc/include/openbsc/handover.h
index 8ab1b06..5d71057 100644
--- a/openbsc/include/openbsc/handover.h
+++ b/openbsc/include/openbsc/handover.h
@@ -1,8 +1,14 @@
 #ifndef _HANDOVER_H
 #define _HANDOVER_H
+
+struct gsm_subscriber_connection;
+
 /* Hand over the specified logical channel to the specified new BTS.
  * This is the main entry point for the actual handover algorithm,
  * after it has decided it wants to initiate HO to a specific BTS */
 int bsc_handover_start(struct gsm_lchan *old_lchan, struct gsm_bts *bts);
 
+/* clear any operation for this connection */
+void bsc_clear_handover(struct gsm_subscriber_connection *conn);
+
 #endif /* _HANDOVER_H */
diff --git a/openbsc/src/bsc_api.c b/openbsc/src/bsc_api.c
index 9c1d090..856dc61 100644
--- a/openbsc/src/bsc_api.c
+++ b/openbsc/src/bsc_api.c
@@ -28,6 +28,7 @@
 #include <openbsc/signal.h>
 #include <openbsc/abis_rsl.h>
 #include <openbsc/chan_alloc.h>
+#include <openbsc/handover.h>
 
 #include <osmocore/talloc.h>
 
@@ -115,6 +116,8 @@
 {
 	struct gsm_lchan *lchan;
 
+	bsc_clear_handover(conn);
+
 	lchan = conn->lchan;
 	subscr_con_free(conn);
 	lchan_release(lchan, 1, 0);
diff --git a/openbsc/src/chan_alloc.c b/openbsc/src/chan_alloc.c
index 675cbbb..dda5ff2 100644
--- a/openbsc/src/chan_alloc.c
+++ b/openbsc/src/chan_alloc.c
@@ -478,13 +478,8 @@
 	}
 
 
-	/* Release a handover that might be in operation */
-	if (conn->ho_lchan) {
-		conn->ho_lchan->conn = NULL;
-		lchan_release(conn->ho_lchan, 0, 1);
-		conn->ho_lchan = NULL;
-	}
-
+	if (conn->ho_lchan)
+		LOGP(DNM, LOGL_ERROR, "The ho_lchan should have been cleared.\n");
 
 	lchan = conn->lchan;
 	talloc_free(conn);
diff --git a/openbsc/src/handover_logic.c b/openbsc/src/handover_logic.c
index 42dc5d8..cdb0664 100644
--- a/openbsc/src/handover_logic.c
+++ b/openbsc/src/handover_logic.c
@@ -149,6 +149,30 @@
 	return 0;
 }
 
+void bsc_clear_handover(struct gsm_subscriber_connection *conn)
+{
+	struct bsc_handover *ho;
+
+	ho = bsc_ho_by_new_lchan(conn->ho_lchan);
+
+
+	if (!ho && conn->ho_lchan)
+		LOGP(DHO, LOGL_ERROR, "BUG: We lost some state.\n");
+
+	if (!ho) {
+		LOGP(DHO, LOGL_ERROR, "unable to find HO record\n");
+		return;
+	}
+
+	conn->ho_lchan->conn = NULL;
+	conn->ho_lchan = NULL;
+	lchan_release(ho->new_lchan, 0, 1);
+
+	bsc_del_timer(&ho->T3103);
+	llist_del(&ho->list);
+	talloc_free(ho);
+}
+
 /* T3103 expired: Handover has failed without HO COMPLETE or HO FAIL */
 static void ho_T3103_cb(void *_ho)
 {