[mgcp] Move the network bits to a separate file...

This change separates the protocol from the actual network code
(bind, forward data). This will allow to more easily hook up the
RTP code from OpenBSC and to not use local sockets at all.
diff --git a/openbsc/src/mgcp/mgcp_protocol.c b/openbsc/src/mgcp/mgcp_protocol.c
index f7588cd..aaa9bc5 100644
--- a/openbsc/src/mgcp/mgcp_protocol.c
+++ b/openbsc/src/mgcp/mgcp_protocol.c
@@ -30,9 +30,6 @@
 #include <limits.h>
 #include <unistd.h>
 
-#include <sys/socket.h>
-#include <arpa/inet.h>
-
 #include <openbsc/debug.h>
 #include <openbsc/msgb.h>
 #include <openbsc/talloc.h>
@@ -41,8 +38,6 @@
 #include <openbsc/mgcp.h>
 #include <openbsc/mgcp_internal.h>
 
-#warning "Make use of the rtp proxy code"
-
 enum mgcp_connection_mode {
 	MGCP_CONN_NONE = 0,
 	MGCP_CONN_RECV_ONLY = 1,
@@ -50,16 +45,6 @@
 	MGCP_CONN_RECV_SEND = MGCP_CONN_RECV_ONLY | MGCP_CONN_SEND_ONLY,
 };
 
-enum {
-	DEST_NETWORK = 0,
-	DEST_BTS = 1,
-};
-
-enum {
-	PROTO_RTP,
-	PROTO_RTCP,
-};
-
 /**
  * Macro for tokenizing MGCP messages and SDP in one go.
  *
@@ -140,168 +125,6 @@
 	return abs(rand());
 }
 
-static int udp_send(int fd, struct in_addr *addr, int port, char *buf, int len)
-{
-	struct sockaddr_in out;
-	out.sin_family = AF_INET;
-	out.sin_port = port;
-	memcpy(&out.sin_addr, addr, sizeof(*addr));
-
-	return sendto(fd, buf, len, 0, (struct sockaddr *)&out, sizeof(out));
-}
-
-/*
- * There is data coming. We will have to figure out if it
- * came from the BTS or the MediaGateway of the MSC. On top
- * of that we need to figure out if it was RTP or RTCP.
- *
- * Currently we do not communicate with the BSC so we have
- * no idea where the BTS is listening for RTP and need to
- * do the classic routing trick. Wait for the first packet
- * from the BTS and then go ahead.
- */
-static int rtp_data_cb(struct bsc_fd *fd, unsigned int what)
-{
-	char buf[4096];
-	struct sockaddr_in addr;
-	socklen_t slen = sizeof(addr);
-	struct mgcp_endpoint *endp;
-	struct mgcp_config *cfg;
-	int rc, dest, proto;
-
-	endp = (struct mgcp_endpoint *) fd->data;
-	cfg = endp->cfg;
-
-	rc = recvfrom(fd->fd, &buf, sizeof(buf), 0,
-			    (struct sockaddr *) &addr, &slen);
-	if (rc < 0) {
-		LOGP(DMGCP, LOGL_ERROR, "Failed to receive message on: 0x%x\n",
-			ENDPOINT_NUMBER(endp));
-		return -1;
-	}
-
-	/* do not forward aynthing... maybe there is a packet from the bts */
-	if (endp->ci == CI_UNUSED) {
-		LOGP(DMGCP, LOGL_ERROR, "Unknown message on endpoint: 0x%x\n", ENDPOINT_NUMBER(endp));
-		return -1;
-	}
-
-	/*
-	 * Figure out where to forward it to. This code assumes that we
-	 * have received the Connection Modify and know who is a legitimate
-	 * partner. According to the spec we could attempt to forward even
-	 * after the Create Connection but we will not as we are not really
-	 * able to tell if this is legitimate.
-	 */
-	#warning "Slight spec violation. With connection mode recvonly we should attempt to forward."
-	dest = memcmp(&addr.sin_addr, &endp->remote, sizeof(addr.sin_addr)) == 0 &&
-                    (endp->net_rtp == addr.sin_port || endp->net_rtcp == addr.sin_port)
-			? DEST_BTS : DEST_NETWORK;
-	proto = fd == &endp->local_rtp ? PROTO_RTP : PROTO_RTCP;
-
-	/* We have no idea who called us, maybe it is the BTS. */
-	if (dest == DEST_NETWORK && (endp->bts_rtp == 0 || cfg->forward_ip)) {
-		/* it was the BTS... */
-		if (!cfg->bts_ip || memcmp(&addr.sin_addr, &cfg->bts_in, sizeof(cfg->bts_in)) == 0) {
-			if (fd == &endp->local_rtp) {
-				endp->bts_rtp = addr.sin_port;
-			} else {
-				endp->bts_rtcp = addr.sin_port;
-			}
-
-			endp->bts = addr.sin_addr;
-			LOGP(DMGCP, LOGL_NOTICE, "Found BTS for endpoint: 0x%x on port: %d/%d\n",
-				ENDPOINT_NUMBER(endp), ntohs(endp->bts_rtp), ntohs(endp->bts_rtcp));
-		}
-	}
-
-	/* dispatch */
-	if (cfg->audio_loop)
-		dest = !dest;
-
-	if (dest == DEST_NETWORK) {
-		return udp_send(fd->fd, &endp->remote,
-			     proto == PROTO_RTP ? endp->net_rtp : endp->net_rtcp,
-			     buf, rc);
-	} else {
-		return udp_send(fd->fd, &endp->bts,
-			     proto == PROTO_RTP ? endp->bts_rtp : endp->bts_rtcp,
-			     buf, rc);
-	}
-}
-
-static int create_bind(const char *source_addr, struct bsc_fd *fd, int port)
-{
-	struct sockaddr_in addr;
-	int on = 1;
-
-	fd->fd = socket(AF_INET, SOCK_DGRAM, 0);
-	if (fd->fd < 0) {
-		LOGP(DMGCP, LOGL_ERROR, "Failed to create UDP port.\n");
-		return -1;
-	}
-
-	setsockopt(fd->fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
-	memset(&addr, 0, sizeof(addr));
-	addr.sin_family = AF_INET;
-	addr.sin_port = htons(port);
-	inet_aton(source_addr, &addr.sin_addr);
-
-	if (bind(fd->fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
-		return -1;
-	}
-
-	return 0;
-}
-
-static int bind_rtp(struct mgcp_endpoint *endp)
-{
-	struct mgcp_config *cfg = endp->cfg;
-
-	if (create_bind(cfg->source_addr, &endp->local_rtp, endp->rtp_port) != 0) {
-		LOGP(DMGCP, LOGL_ERROR, "Failed to create RTP port: %s:%d on 0x%x\n",
-		       cfg->source_addr, endp->rtp_port, ENDPOINT_NUMBER(endp));
-		goto cleanup0;
-	}
-
-	if (create_bind(cfg->source_addr, &endp->local_rtcp, endp->rtp_port + 1) != 0) {
-		LOGP(DMGCP, LOGL_ERROR, "Failed to create RTCP port: %s:%d on 0x%x\n",
-		       cfg->source_addr, endp->rtp_port + 1, ENDPOINT_NUMBER(endp));
-		goto cleanup1;
-	}
-
-	endp->local_rtp.cb = rtp_data_cb;
-	endp->local_rtp.data = endp;
-	endp->local_rtp.when = BSC_FD_READ;
-	if (bsc_register_fd(&endp->local_rtp) != 0) {
-		LOGP(DMGCP, LOGL_ERROR, "Failed to register RTP port %d on 0x%x\n",
-			endp->rtp_port, ENDPOINT_NUMBER(endp));
-		goto cleanup2;
-	}
-
-	endp->local_rtcp.cb = rtp_data_cb;
-	endp->local_rtcp.data = endp;
-	endp->local_rtcp.when = BSC_FD_READ;
-	if (bsc_register_fd(&endp->local_rtcp) != 0) {
-		LOGP(DMGCP, LOGL_ERROR, "Failed to register RTCP port %d on 0x%x\n",
-			endp->rtp_port + 1, ENDPOINT_NUMBER(endp));
-		goto cleanup3;
-	}
-
-	return 0;
-
-cleanup3:
-	bsc_unregister_fd(&endp->local_rtp);
-cleanup2:
-	close(endp->local_rtcp.fd);
-	endp->local_rtcp.fd = -1;
-cleanup1:
-	close(endp->local_rtp.fd);
-	endp->local_rtp.fd = -1;
-cleanup0:
-	return -1;
-}
-
 /*
  * array of function pointers for handling various
  * messages. In the future this might be binary sorted
@@ -575,6 +398,7 @@
 	const char *trans_id;
 	struct mgcp_endpoint *endp;
 	int error_code = 500;
+	int port;
 
 	found = analyze_header(cfg, msg, data_ptrs, ARRAY_SIZE(data_ptrs), &trans_id, &endp);
 	if (found != 0)
@@ -618,8 +442,10 @@
 	memset(&endp->remote, 0, sizeof(endp->remote));
 
 	/* bind to the port now */
-	endp->rtp_port = rtp_calculate_port(ENDPOINT_NUMBER(endp), cfg->rtp_base_port);
-	if (!cfg->early_bind && bind_rtp(endp) != 0)
+	port = rtp_calculate_port(ENDPOINT_NUMBER(endp), cfg->rtp_base_port);
+	if (cfg->early_bind)
+		endp->rtp_port = port;
+	else if (mgcp_bind_rtp_port(endp, port) != 0)
 		goto error2;
 
 	/* assign a local call identifier or fail */
@@ -841,9 +667,3 @@
 
 	return 0;
 }
-
-int mgcp_bind_rtp_port(struct mgcp_endpoint *endp, int rtp_port)
-{
-	endp->rtp_port = rtp_port;
-	return bind_rtp(endp);
-}