legacy-mgcp: Add jitter buffer on the uplink receiver

Default usage values are defined in mgcp node, and can be per-BSC
overriden on each bsc node

This commit is a forward-port of openbsc.git Change-Id
Ibf3932adc07442fb5e9c7a06404853f9d0a20959.

Change-Id: Ie19a64ac09f9d51f2434ad0d7925610fc919a90e
diff --git a/src/libosmo-legacy-mgcp/mgcp_network.c b/src/libosmo-legacy-mgcp/mgcp_network.c
index 8ccfb42..7b161d2 100644
--- a/src/libosmo-legacy-mgcp/mgcp_network.c
+++ b/src/libosmo-legacy-mgcp/mgcp_network.c
@@ -584,6 +584,36 @@
 	return rc;
 }
 
+void mgcp_dejitter_udp_send(struct msgb *msg, void *data)
+{
+	struct mgcp_rtp_end *rtp_end = (struct mgcp_rtp_end *) data;
+
+	int rc = mgcp_udp_send(rtp_end->rtp.fd, &rtp_end->addr,
+			   rtp_end->rtp_port, (char*) msg->data, msg->len);
+	if (rc != msg->len)
+		LOGP(DLMGCP, LOGL_ERROR,
+			"Failed to send data after jitter buffer: %d\n", rc);
+	msgb_free(msg);
+}
+
+static int enqueue_dejitter(struct osmo_jibuf *jb, struct mgcp_rtp_end *rtp_end, char *buf, int len)
+{
+	struct msgb *msg;
+	msg = msgb_alloc(len, "mgcp-jibuf");
+	if (!msg)
+		return -1;
+
+	memcpy(msg->data, buf, len);
+	msgb_put(msg, len);
+
+	if (osmo_jibuf_enqueue(jb, msg) < 0) {
+		rtp_end->dropped_packets += 1;
+		msgb_free(msg);
+	}
+
+	return len;
+}
+
 int mgcp_send(struct mgcp_endpoint *endp, int dest, int is_rtp,
 	      struct sockaddr_in *addr, char *buf, int rc)
 {
@@ -591,6 +621,7 @@
 	struct mgcp_rtp_end *rtp_end;
 	struct mgcp_rtp_state *rtp_state;
 	int tap_idx;
+	struct osmo_jibuf *jb;
 
 	LOGP(DLMGCP, LOGL_DEBUG,
 	     "endpoint %x dest %s tcfg->audio_loop %d endp->conn_mode %d (== loopback: %d)\n",
@@ -612,10 +643,12 @@
 		rtp_end = &endp->net_end;
 		rtp_state = &endp->bts_state;
 		tap_idx = MGCP_TAP_NET_OUT;
+		jb = endp->bts_jb;
 	} else {
 		rtp_end = &endp->bts_end;
 		rtp_state = &endp->net_state;
 		tap_idx = MGCP_TAP_BTS_OUT;
+		jb = NULL;
 	}
 	LOGP(DLMGCP, LOGL_DEBUG,
 	     "endpoint %x dest %s net_end %s %d %d bts_end %s %d %d rtp_end %s %d %d\n",
@@ -680,9 +713,12 @@
 				rtp_state->patched_first_rtp_payload = true;
 			}
 
-			rc = mgcp_udp_send(rtp_end->rtp.fd,
-					   &rtp_end->addr,
-					   rtp_end->rtp_port, buf, len);
+			if (jb)
+				rc = enqueue_dejitter(jb, rtp_end, buf, len);
+			else
+				rc = mgcp_udp_send(rtp_end->rtp.fd,
+						   &rtp_end->addr,
+						   rtp_end->rtp_port, buf, len);
 
 			if (rc <= 0)
 				return rc;