Pau Espin Pedrol has uploaded this change for review. ( 
https://gerrit.osmocom.org/9212


Change subject: legacy-mgcp: Add jitter buffer on the uplink receiver
......................................................................

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
---
M include/osmocom/legacy_mgcp/mgcp.h
M include/osmocom/legacy_mgcp/mgcp_internal.h
M src/libosmo-legacy-mgcp/mgcp_network.c
M src/libosmo-legacy-mgcp/mgcp_protocol.c
M src/libosmo-legacy-mgcp/mgcp_vty.c
5 files changed, 156 insertions(+), 3 deletions(-)



  git pull ssh://gerrit.osmocom.org:29418/osmo-mgw refs/changes/12/9212/1

diff --git a/include/osmocom/legacy_mgcp/mgcp.h 
b/include/osmocom/legacy_mgcp/mgcp.h
index 147a0d5..7490e37 100644
--- a/include/osmocom/legacy_mgcp/mgcp.h
+++ b/include/osmocom/legacy_mgcp/mgcp.h
@@ -243,6 +243,12 @@
         * message.
         */
        uint16_t osmux_dummy;
+
+       /* Use a jitterbuffer on the bts-side receiver */
+       bool bts_use_jibuf;
+       /* Minimum and maximum buffer size for the jitter buffer, in ms */
+       uint32_t bts_jitter_delay_min;
+       uint32_t bts_jitter_delay_max;
 };

 /* config management */
diff --git a/include/osmocom/legacy_mgcp/mgcp_internal.h 
b/include/osmocom/legacy_mgcp/mgcp_internal.h
index dcc75f1..956bee0 100644
--- a/include/osmocom/legacy_mgcp/mgcp_internal.h
+++ b/include/osmocom/legacy_mgcp/mgcp_internal.h
@@ -25,6 +25,7 @@
 #include <string.h>

 #include <osmocom/core/select.h>
+#include <osmocom/netif/jibuf.h>

 #define CI_UNUSED 0

@@ -198,6 +199,14 @@
                        uint32_t octets;
                } stats;
        } osmux;
+
+       /* Jitter buffer */
+       struct osmo_jibuf* bts_jb;
+       /* Use a jitterbuffer on the bts-side receiver */
+       bool bts_use_jibuf;
+       /* Minimum and maximum buffer size for the jitter buffer, in ms */
+       uint32_t bts_jitter_delay_min;
+       uint32_t bts_jitter_delay_max;
 };

 #define for_each_line(line, save)                      \
@@ -335,3 +344,8 @@
 }

 int mgcp_msg_terminate_nul(struct msgb *msg);
+
+/**
+ * Internal jitter buffer related
+ */
+void mgcp_dejitter_udp_send(struct msgb *msg, void *data);
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;
diff --git a/src/libosmo-legacy-mgcp/mgcp_protocol.c 
b/src/libosmo-legacy-mgcp/mgcp_protocol.c
index 4e82233..854b4ba 100644
--- a/src/libosmo-legacy-mgcp/mgcp_protocol.c
+++ b/src/libosmo-legacy-mgcp/mgcp_protocol.c
@@ -863,6 +863,11 @@
                goto error2;
        }

+       /* Apply Jiter buffer settings for this endpoint, they can be overriden 
by CRCX policy later */
+       endp->bts_use_jibuf = endp->cfg->bts_use_jibuf;
+       endp->bts_jitter_delay_min = endp->cfg->bts_jitter_delay_min;
+       endp->bts_jitter_delay_max = endp->cfg->bts_jitter_delay_max;
+
        endp->allocated = 1;

        /* set up RTP media parameters */
@@ -898,6 +903,13 @@
                case MGCP_POLICY_DEFER:
                        /* stop processing */
                        create_transcoder(endp);
+                       /* Set up jitter buffer if required after policy has 
updated jibuf endp values */
+                       if (endp->bts_use_jibuf) {
+                               endp->bts_jb = 
osmo_jibuf_alloc(tcfg->endpoints);
+                               osmo_jibuf_set_min_delay(endp->bts_jb, 
endp->bts_jitter_delay_min);
+                               osmo_jibuf_set_max_delay(endp->bts_jb, 
endp->bts_jitter_delay_max);
+                               osmo_jibuf_set_dequeue_cb(endp->bts_jb, 
mgcp_dejitter_udp_send, &endp->net_end);
+                       }
                        return NULL;
                        break;
                case MGCP_POLICY_CONT:
@@ -906,6 +918,14 @@
                }
        }

+       /* Set up jitter buffer if required after policy has updated jibuf endp 
values */
+       if (endp->bts_use_jibuf) {
+               endp->bts_jb = osmo_jibuf_alloc(tcfg->endpoints);
+               osmo_jibuf_set_min_delay(endp->bts_jb, 
endp->bts_jitter_delay_min);
+               osmo_jibuf_set_max_delay(endp->bts_jb, 
endp->bts_jitter_delay_max);
+               osmo_jibuf_set_dequeue_cb(endp->bts_jb, mgcp_dejitter_udp_send, 
&endp->net_end);
+       }
+
        LOGP(DLMGCP, LOGL_DEBUG, "Creating endpoint on: 0x%x CI: %u port: 
%u/%u\n",
                ENDPOINT_NUMBER(endp), endp->ci,
                endp->net_end.local_port, endp->bts_end.local_port);
@@ -1373,6 +1393,9 @@
 void mgcp_release_endp(struct mgcp_endpoint *endp)
 {
        LOGP(DLMGCP, LOGL_DEBUG, "Releasing endpoint on: 0x%x\n", 
ENDPOINT_NUMBER(endp));
+       if (endp->bts_jb)
+               osmo_jibuf_delete(endp->bts_jb);
+       endp->bts_jb = NULL;
        endp->ci = CI_UNUSED;
        endp->allocated = 0;

diff --git a/src/libosmo-legacy-mgcp/mgcp_vty.c 
b/src/libosmo-legacy-mgcp/mgcp_vty.c
index 7b11422..be884cb 100644
--- a/src/libosmo-legacy-mgcp/mgcp_vty.c
+++ b/src/libosmo-legacy-mgcp/mgcp_vty.c
@@ -29,6 +29,7 @@
 #include <osmocom/legacy_mgcp/vty.h>

 #include <string.h>
+#include <inttypes.h>

 #define RTCP_OMIT_STR "Drop RTCP packets in both directions\n"
 #define RTP_PATCH_STR "Modify RTP packet header in both directions\n"
@@ -164,6 +165,13 @@
                vty_out(vty, "  osmux dummy %s%s",
                        g_cfg->osmux_dummy ? "on" : "off", VTY_NEWLINE);
        }
+       if (g_cfg->bts_use_jibuf)
+               vty_out(vty, "  bts-jitter-buffer%s", VTY_NEWLINE);
+       if (g_cfg->bts_jitter_delay_min)
+               vty_out(vty, "  bts-jitter-delay-min %"PRIu32"%s", 
g_cfg->bts_jitter_delay_min, VTY_NEWLINE);
+       if (g_cfg->bts_jitter_delay_max)
+               vty_out(vty, "  bts-jitter-delay-max %"PRIu32"%s", 
g_cfg->bts_jitter_delay_max, VTY_NEWLINE);
+
        return CMD_SUCCESS;
 }

@@ -241,6 +249,11 @@

        if (g_cfg->osmux)
                vty_out(vty, "Osmux used CID: %d%s", osmux_used_cid(), 
VTY_NEWLINE);
+       vty_out(vty, "Jitter Buffer by default on Uplink : %s%s",
+               g_cfg->bts_use_jibuf ? "on" : "off", VTY_NEWLINE);
+       if (g_cfg->bts_use_jibuf)
+               vty_out(vty, "Jitter Buffer delays: min=%"PRIu32" 
max=%"PRIu32"%s",
+               g_cfg->bts_jitter_delay_min, g_cfg->bts_jitter_delay_max, 
VTY_NEWLINE);

        return CMD_SUCCESS;
 }
@@ -1344,6 +1357,63 @@
        return CMD_SUCCESS;
 }

+#define DEJITTER_STR "Uplink Jitter Buffer"
+DEFUN(cfg_mgcp_bts_use_jibuf,
+      cfg_mgcp_bts_use_jibuf_cmd,
+      "bts-jitter-buffer",
+      DEJITTER_STR "\n")
+{
+       g_cfg->bts_use_jibuf = true;
+       return CMD_SUCCESS;
+}
+
+DEFUN(cfg_mgcp_no_bts_use_jibuf,
+      cfg_mgcp_no_bts_use_jibuf_cmd,
+      "no bts-jitter-buffer",
+      NO_STR DEJITTER_STR "\n")
+{
+       g_cfg->bts_use_jibuf = false;
+       return CMD_SUCCESS;
+}
+
+DEFUN(cfg_mgcp_bts_jitter_delay_min,
+      cfg_mgcp_bts_jitter_delay_min_cmd,
+      "bts-jitter-buffer-delay-min <1-65535>",
+      DEJITTER_STR " Minimum Delay in ms\n" "Minimum Delay in ms\n")
+{
+       g_cfg->bts_jitter_delay_min = atoi(argv[0]);
+       if (!g_cfg->bts_jitter_delay_min) {
+               vty_out(vty, "bts-jitter-buffer-delay-min cannot be zero.%s", 
VTY_NEWLINE);
+               return CMD_WARNING;
+       }
+       if (g_cfg->bts_jitter_delay_min && g_cfg->bts_jitter_delay_max &&
+           g_cfg->bts_jitter_delay_min > g_cfg->bts_jitter_delay_max) {
+               vty_out(vty, "bts-jitter-buffer-delay-min cannot be bigger than 
" \
+                       "bts-jitter-buffer-delay-max.%s", VTY_NEWLINE);
+               return CMD_WARNING;
+       }
+       return CMD_SUCCESS;
+}
+
+DEFUN(cfg_mgcp_bts_jitter_delay_max,
+      cfg_mgcp_bts_jitter_delay_max_cmd,
+      "bts-jitter-buffer-delay-max <1-65535>",
+      DEJITTER_STR " Maximum Delay in ms\n" "Maximum Delay in ms\n")
+{
+       g_cfg->bts_jitter_delay_max = atoi(argv[0]);
+       if (!g_cfg->bts_jitter_delay_max) {
+               vty_out(vty, "bts-jitter-buffer-delay-max cannot be zero.%s", 
VTY_NEWLINE);
+               return CMD_WARNING;
+       }
+       if (g_cfg->bts_jitter_delay_min && g_cfg->bts_jitter_delay_max &&
+           g_cfg->bts_jitter_delay_min > g_cfg->bts_jitter_delay_max) {
+               vty_out(vty, "bts-jitter-buffer-delay-max cannot be smaller 
than " \
+                       "bts-jitter-buffer-delay-min.%s", VTY_NEWLINE);
+               return CMD_WARNING;
+       }
+       return CMD_SUCCESS;
+}
+
 int mgcp_vty_init(void)
 {
        install_element_ve(&show_mgcp_cmd);
@@ -1411,6 +1481,10 @@
        install_element(MGCP_NODE, &cfg_mgcp_osmux_dummy_cmd);
        install_element(MGCP_NODE, &cfg_mgcp_allow_transcoding_cmd);
        install_element(MGCP_NODE, &cfg_mgcp_no_allow_transcoding_cmd);
+       install_element(MGCP_NODE, &cfg_mgcp_bts_use_jibuf_cmd);
+       install_element(MGCP_NODE, &cfg_mgcp_no_bts_use_jibuf_cmd);
+       install_element(MGCP_NODE, &cfg_mgcp_bts_jitter_delay_min_cmd);
+       install_element(MGCP_NODE, &cfg_mgcp_bts_jitter_delay_max_cmd);

 
        install_element(MGCP_NODE, &cfg_mgcp_trunk_cmd);

--
To view, visit https://gerrit.osmocom.org/9212
To unsubscribe, or for help writing mail filters, visit 
https://gerrit.osmocom.org/settings

Gerrit-Project: osmo-mgw
Gerrit-Branch: master
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ie19a64ac09f9d51f2434ad0d7925610fc919a90e
Gerrit-Change-Number: 9212
Gerrit-PatchSet: 1
Gerrit-Owner: Pau Espin Pedrol <pes...@sysmocom.de>

Reply via email to