bsc: Clear the hand-over in case the new_lchan is failing

When the new_lchan for handover is failing we should stop the
handover operation. This is fixing a crash that we get a timeout
on the lchan and have no conn set to it. Introduce a flag to
the bsc_clear_handover to not free the lchan. In case the ho_lchan
is failing we do not want to call lchan_release as it would
reset the state.
diff --git a/openbsc/include/openbsc/handover.h b/openbsc/include/openbsc/handover.h
index 5d71057..9d9a90b 100644
--- a/openbsc/include/openbsc/handover.h
+++ b/openbsc/include/openbsc/handover.h
@@ -9,6 +9,6 @@
 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);
+void bsc_clear_handover(struct gsm_subscriber_connection *conn, int free_lchan);
 
 #endif /* _HANDOVER_H */
diff --git a/openbsc/src/bsc_api.c b/openbsc/src/bsc_api.c
index 73b29b5..a9e5f71 100644
--- a/openbsc/src/bsc_api.c
+++ b/openbsc/src/bsc_api.c
@@ -520,7 +520,7 @@
 int gsm0808_clear(struct gsm_subscriber_connection *conn)
 {
 	if (conn->ho_lchan)
-		bsc_clear_handover(conn);
+		bsc_clear_handover(conn, 1);
 
 	if (conn->secondary_lchan)
 		lchan_release(conn->secondary_lchan, 0, 1);
@@ -633,8 +633,10 @@
 	/* now give up all channels */
 	if (conn->lchan == lchan)
 		conn->lchan = NULL;
-	if (conn->ho_lchan == lchan)
+	if (conn->ho_lchan == lchan) {
+		bsc_clear_handover(conn, 0);
 		conn->ho_lchan = NULL;
+	}
 	lchan->conn = NULL;
 
 	gsm0808_clear(conn);
diff --git a/openbsc/src/handover_logic.c b/openbsc/src/handover_logic.c
index 44a6933..c2e3f8c 100644
--- a/openbsc/src/handover_logic.c
+++ b/openbsc/src/handover_logic.c
@@ -149,7 +149,7 @@
 	return 0;
 }
 
-void bsc_clear_handover(struct gsm_subscriber_connection *conn)
+void bsc_clear_handover(struct gsm_subscriber_connection *conn, int free_lchan)
 {
 	struct bsc_handover *ho;
 
@@ -166,7 +166,9 @@
 
 	conn->ho_lchan->conn = NULL;
 	conn->ho_lchan = NULL;
-	lchan_release(ho->new_lchan, 0, 1);
+
+	if (free_lchan)
+		lchan_release(ho->new_lchan, 0, 1);
 
 	bsc_del_timer(&ho->T3103);
 	llist_del(&ho->list);