rtp: Move the RTP Proxy code out of RSL into the BSC/MSC domain

Instead of creating the sockets in the RSL code we will do this
in the CRCX_ACK, MDCX_ACK, DLCX_IND signal handler of gsm_04_08.
Introduce a handover signal so we can repatch the RTP sockets in
the gsm_04_08 as well.
diff --git a/openbsc/src/Makefile.am b/openbsc/src/Makefile.am
index cc69a72..c86fc26 100644
--- a/openbsc/src/Makefile.am
+++ b/openbsc/src/Makefile.am
@@ -22,7 +22,7 @@
 		trau_frame.c trau_mux.c paging.c e1_config.c e1_input.c \
 		input/misdn.c input/ipaccess.c handover_logic.c \
 		talloc_ctx.c system_information.c rest_octets.c \
-		rtp_proxy.c bts_siemens_bs11.c bts_ipaccess_nanobts.c \
+		bts_siemens_bs11.c bts_ipaccess_nanobts.c \
 		bts_unknown.c bsc_version.c bsc_api.c bsc_vty.c meas_rep.c gsm_04_80.c
 
 libmsc_a_SOURCES = gsm_subscriber.c db.c \
@@ -30,7 +30,7 @@
 		gsm_04_08.c gsm_04_11.c transaction.c \
 		token_auth.c rrlp.c ussd.c silent_call.c \
 		handover_decision.c auth.c \
-		osmo_msc.c
+		osmo_msc.c rtp_proxy.c
 
 libvty_a_SOURCES = common_vty.c
 
diff --git a/openbsc/src/abis_rsl.c b/openbsc/src/abis_rsl.c
index aa3d78a5..261181f 100644
--- a/openbsc/src/abis_rsl.c
+++ b/openbsc/src/abis_rsl.c
@@ -1768,32 +1768,9 @@
 
 	ipac_parse_rtp(lchan, &tv);
 
-	/* in case we don't use direct BTS-to-BTS RTP */
-	if (!ipacc_rtp_direct) {
-		int rc;
-		/* the BTS has successfully bound a TCH to a local ip/port,
-		 * which means we can connect our UDP socket to it */
-		if (lchan->abis_ip.rtp_socket) {
-			rtp_socket_free(lchan->abis_ip.rtp_socket);
-			lchan->abis_ip.rtp_socket = NULL;
-		}
-
-		lchan->abis_ip.rtp_socket = rtp_socket_create();
-		if (!lchan->abis_ip.rtp_socket)
-			goto out_err;
-
-		rc = rtp_socket_connect(lchan->abis_ip.rtp_socket,
-				   lchan->abis_ip.bound_ip,
-				   lchan->abis_ip.bound_port);
-		if (rc < 0)
-			goto out_err;
-	}
-
 	dispatch_signal(SS_ABISIP, S_ABISIP_CRCX_ACK, msg->lchan);
 
 	return 0;
-out_err:
-	return -EIO;
 }
 
 static int abis_rsl_rx_ipacc_mdcx_ack(struct msgb *msg)
@@ -1817,7 +1794,6 @@
 {
 	struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
 	struct tlv_parsed tv;
-	struct gsm_lchan *lchan = msg->lchan;
 
 	rsl_tlv_parse(&tv, dh->data, msgb_l2len(msg)-sizeof(*dh));
 
@@ -1825,12 +1801,6 @@
 		print_rsl_cause(LOGL_DEBUG, TLVP_VAL(&tv, RSL_IE_CAUSE),
 				TLVP_LEN(&tv, RSL_IE_CAUSE));
 
-	/* the BTS tells us a RTP stream has been disconnected */
-	if (lchan->abis_ip.rtp_socket) {
-		rtp_socket_free(lchan->abis_ip.rtp_socket);
-		lchan->abis_ip.rtp_socket = NULL;
-	}
-
 	dispatch_signal(SS_ABISIP, S_ABISIP_DLCX_IND, msg->lchan);
 
 	return 0;
diff --git a/openbsc/src/gsm_04_08.c b/openbsc/src/gsm_04_08.c
index e364a17..b5ab8aa 100644
--- a/openbsc/src/gsm_04_08.c
+++ b/openbsc/src/gsm_04_08.c
@@ -1452,6 +1452,60 @@
 
 static int tch_recv_mncc(struct gsm_network *net, u_int32_t callref, int enable);
 
+/* handle audio path for handover */
+static int handle_ho_signal(unsigned int subsys, unsigned int signal,
+			    void *handler_data, void *signal_data)
+{
+	struct rtp_socket *old_rs, *new_rs, *other_rs;
+	struct ho_signal_data *sig = signal_data;
+
+	if (subsys != SS_HO || signal != S_HANDOVER_ACK)
+		return 0;
+
+	if (ipacc_rtp_direct) {
+		LOGP(DHO, LOGL_ERROR, "unable to handover in direct RTP mode\n");
+		return 0;
+	}
+
+	/* RTP Proxy mode */
+	new_rs = sig->new_lchan->abis_ip.rtp_socket;
+	old_rs = sig->old_lchan->abis_ip.rtp_socket;
+
+	if (!new_rs) {
+		LOGP(DHO, LOGL_ERROR, "no RTP socket for new_lchan\n");
+		return -EIO;
+	}
+
+	rsl_ipacc_mdcx_to_rtpsock(sig->new_lchan);
+
+	if (!old_rs) {
+		LOGP(DHO, LOGL_ERROR, "no RTP socket for old_lchan\n");
+		return -EIO;
+	}
+
+	/* copy rx_action and reference to other sock */
+	new_rs->rx_action = old_rs->rx_action;
+	new_rs->tx_action = old_rs->tx_action;
+	new_rs->transmit = old_rs->transmit;
+
+	switch (sig->old_lchan->abis_ip.rtp_socket->rx_action) {
+	case RTP_PROXY:
+		other_rs = old_rs->proxy.other_sock;
+		rtp_socket_proxy(new_rs, other_rs);
+		/* delete reference to other end socket to prevent
+		 * rtp_socket_free() from removing the inverse reference */
+		old_rs->proxy.other_sock = NULL;
+		break;
+	case RTP_RECV_UPSTREAM:
+		new_rs->receive = old_rs->receive;
+		break;
+	case RTP_NONE:
+		break;
+	}
+
+	return 0;
+}
+
 /* some other part of the code sends us a signal */
 static int handle_abisip_signal(unsigned int subsys, unsigned int signal,
 				 void *handler_data, void *signal_data)
@@ -1470,6 +1524,24 @@
 
 	switch (signal) {
 	case S_ABISIP_CRCX_ACK:
+		/* in case we don't use direct BTS-to-BTS RTP */
+		/* the BTS has successfully bound a TCH to a local ip/port,
+		 * which means we can connect our UDP socket to it */
+		if (lchan->abis_ip.rtp_socket) {
+			rtp_socket_free(lchan->abis_ip.rtp_socket);
+			lchan->abis_ip.rtp_socket = NULL;
+		}
+
+		lchan->abis_ip.rtp_socket = rtp_socket_create();
+		if (!lchan->abis_ip.rtp_socket)
+			return -EIO;
+
+		rc = rtp_socket_connect(lchan->abis_ip.rtp_socket,
+				   lchan->abis_ip.bound_ip,
+				   lchan->abis_ip.bound_port);
+		if (rc < 0)
+			return -EIO;
+
 		/* check if any transactions on this lchan still have
 		 * a tch_recv_mncc request pending */
 		net = lchan->ts->trx->bts->network;
@@ -1480,6 +1552,14 @@
 			}
 		}
 		break;
+	case S_ABISIP_DLCX_IND:
+		/* the BTS tells us a RTP stream has been disconnected */
+		if (lchan->abis_ip.rtp_socket) {
+			rtp_socket_free(lchan->abis_ip.rtp_socket);
+			lchan->abis_ip.rtp_socket = NULL;
+		}
+
+		break;
 	}
 
 	return 0;
@@ -3226,5 +3306,6 @@
  */
 static __attribute__((constructor)) void on_dso_load_0408(void)
 {
+	register_signal_handler(SS_HO, handle_ho_signal, NULL);
 	register_signal_handler(SS_ABISIP, handle_abisip_signal, NULL);
 }
diff --git a/openbsc/src/handover_logic.c b/openbsc/src/handover_logic.c
index 8e8b9db..44a6933 100644
--- a/openbsc/src/handover_logic.c
+++ b/openbsc/src/handover_logic.c
@@ -332,7 +332,7 @@
 static int ho_ipac_crcx_ack(struct gsm_lchan *new_lchan)
 {
 	struct bsc_handover *ho;
-	struct rtp_socket *old_rs, *new_rs, *other_rs;
+	struct ho_signal_data sig_ho;
 
 	ho = bsc_ho_by_new_lchan(new_lchan);
 	if (!ho) {
@@ -340,47 +340,9 @@
 		return 0;
 	}
 
-	if (ipacc_rtp_direct) {
-		LOGP(DHO, LOGL_ERROR, "unable to handover in direct RTP mode\n");
-		return 0;
-	}
-
-	/* RTP Proxy mode */
-	new_rs = new_lchan->abis_ip.rtp_socket;
-	old_rs = ho->old_lchan->abis_ip.rtp_socket;
-
-	if (!new_rs) {
-		LOGP(DHO, LOGL_ERROR, "no RTP socket for new_lchan\n");
-		return -EIO;
-	}
-
-	rsl_ipacc_mdcx_to_rtpsock(new_lchan);
-
-	if (!old_rs) {
-		LOGP(DHO, LOGL_ERROR, "no RTP socket for old_lchan\n");
-		return -EIO;
-	}
-
-	/* copy rx_action and reference to other sock */
-	new_rs->rx_action = old_rs->rx_action;
-	new_rs->tx_action = old_rs->tx_action;
-	new_rs->transmit = old_rs->transmit;
-
-	switch (ho->old_lchan->abis_ip.rtp_socket->rx_action) {
-	case RTP_PROXY:
-		other_rs = old_rs->proxy.other_sock;
-		rtp_socket_proxy(new_rs, other_rs);
-		/* delete reference to other end socket to prevent
-		 * rtp_socket_free() from removing the inverse reference */
-		old_rs->proxy.other_sock = NULL;
-		break;
-	case RTP_RECV_UPSTREAM:
-		new_rs->receive = old_rs->receive;
-		break;
-	case RTP_NONE:
-		break;
-	}
-
+	sig_ho.old_lchan = ho->old_lchan;
+	sig_ho.new_lchan = new_lchan;
+	dispatch_signal(SS_HO, S_HANDOVER_ACK, &sig_ho);
 	return 0;
 }