<p>dexter has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.osmocom.org/12979">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">Add option to GSM HR frames to RFC5593 representation<br><br>There are different specifications around on how a GSM-HR frame should<br>be encapsulated into an RTP packet. RFC5593 specifies a ToC (Table of<br>contents byte to be prepended in front of the payload data along with<br>some additional shuffeling of the actual payload data.<br><br>The two formates can be distinguished easyly by their length. Then the<br>data can be formatted into the corresponding opposite format and vice<br>versa.<br><br>- Add new VTY rtp-patch options<br>- Add conversion function<br><br>Change-Id: Iceef19e5619f8c92dfa7c8cdecb2e9b15f0a11a1<br>Related: OS#3807<br>---<br>M include/osmocom/mgcp/mgcp.h<br>M include/osmocom/mgcp/mgcp_internal.h<br>M src/libosmo-mgcp/mgcp_network.c<br>M src/libosmo-mgcp/mgcp_protocol.c<br>M src/libosmo-mgcp/mgcp_vty.c<br>5 files changed, 124 insertions(+), 2 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.osmocom.org:29418/osmo-mgw refs/changes/79/12979/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/include/osmocom/mgcp/mgcp.h b/include/osmocom/mgcp/mgcp.h</span><br><span>index 7597af8..783cf1f 100644</span><br><span>--- a/include/osmocom/mgcp/mgcp.h</span><br><span>+++ b/include/osmocom/mgcp/mgcp.h</span><br><span>@@ -190,6 +190,7 @@</span><br><span>     /* RTP patching */</span><br><span>   int force_constant_ssrc; /* 0: don't, 1: once */</span><br><span>         int force_aligned_timing;</span><br><span style="color: hsl(120, 100%, 40%);">+     int rfc5993_hr_convert;</span><br><span> </span><br><span>  /* spec handling */</span><br><span>  int force_realloc;</span><br><span>diff --git a/include/osmocom/mgcp/mgcp_internal.h b/include/osmocom/mgcp/mgcp_internal.h</span><br><span>index 14c5f11..89a4649 100644</span><br><span>--- a/include/osmocom/mgcp/mgcp_internal.h</span><br><span>+++ b/include/osmocom/mgcp/mgcp_internal.h</span><br><span>@@ -128,6 +128,7 @@</span><br><span>        int force_constant_ssrc; /* -1: always, 0: don't, 1: once */</span><br><span>     /* should we perform align_rtp_timestamp_offset() (1) or not (0) */</span><br><span>  int force_aligned_timing;</span><br><span style="color: hsl(120, 100%, 40%);">+     int rfc5993_hr_convert;</span><br><span> </span><br><span>  /* Each end has a separate socket for RTP and RTCP */</span><br><span>        struct osmo_fd rtp;</span><br><span>diff --git a/src/libosmo-mgcp/mgcp_network.c b/src/libosmo-mgcp/mgcp_network.c</span><br><span>index 2c86f8f..09302d8 100644</span><br><span>--- a/src/libosmo-mgcp/mgcp_network.c</span><br><span>+++ b/src/libosmo-mgcp/mgcp_network.c</span><br><span>@@ -43,6 +43,7 @@</span><br><span> #include <osmocom/mgcp/mgcp_endp.h></span><br><span> #include <osmocom/mgcp/mgcp_codec.h></span><br><span> #include <osmocom/mgcp/debug.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/codec/codec.h></span><br><span> </span><br><span> </span><br><span> #define RTP_SEQ_MOD             (1 << 16)</span><br><span>@@ -651,6 +652,73 @@</span><br><span> #endif</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/* This has been ported from openbsc.git, branch sylvain/32c3_codec,</span><br><span style="color: hsl(120, 100%, 40%);">+ * commit f198259f57f868bc85726cbac3df47b143b0300f, original author is</span><br><span style="color: hsl(120, 100%, 40%);">+ * Sylvain Munaut <tnt@246tNt.com> */</span><br><span style="color: hsl(120, 100%, 40%);">+static void hr_jumble(uint8_t *dst, const uint8_t *src)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      const int p_unvoiced[] =</span><br><span style="color: hsl(120, 100%, 40%);">+          { 5, 11, 9, 8, 1, 2, 7, 7, 5, 7, 7, 5, 7, 7, 5, 7, 7, 5 };</span><br><span style="color: hsl(120, 100%, 40%);">+        const int p_voiced[] =</span><br><span style="color: hsl(120, 100%, 40%);">+            { 5, 11, 9, 8, 1, 2, 8, 9, 5, 4, 9, 5, 4, 9, 5, 4, 9, 5 };</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      int base, i, j, l, si, di;</span><br><span style="color: hsl(120, 100%, 40%);">+    int *p;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     memset(dst, 0x00, 14);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      p = (src[4] & 0x30) ? p_voiced : p_unvoiced;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    base = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+     for (i = 0; i < 18; i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+         l = p[i];</span><br><span style="color: hsl(120, 100%, 40%);">+             for (j = 0; j < l; j++) {</span><br><span style="color: hsl(120, 100%, 40%);">+                  si = base + j;</span><br><span style="color: hsl(120, 100%, 40%);">+                        di = base + l - j - 1;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                      if (src[si >> 3] & (1 << (7 - (si & 7))))</span><br><span style="color: hsl(120, 100%, 40%);">+                         dst[di >> 3] |= (1 << (7 - (di & 7)));</span><br><span style="color: hsl(120, 100%, 40%);">+                }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+           base += l;</span><br><span style="color: hsl(120, 100%, 40%);">+    }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* There are different dialects used to format and transfer voice data. When</span><br><span style="color: hsl(120, 100%, 40%);">+ * the receiving end expects GSM-HR data to be formated after RFC 5993, this</span><br><span style="color: hsl(120, 100%, 40%);">+ * function is used to convert between RFC 5993 and TS 101318, which we normally</span><br><span style="color: hsl(120, 100%, 40%);">+ * use. */</span><br><span style="color: hsl(120, 100%, 40%);">+static void rfc5993_hr_convert(struct mgcp_rtp_end *rtp_end, char *data,</span><br><span style="color: hsl(120, 100%, 40%);">+                           int *len)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   /* NOTE: *data has an overall length of RTP_BUF_SIZE, so there is</span><br><span style="color: hsl(120, 100%, 40%);">+      * plenty of space available to store the slightly larger, converted</span><br><span style="color: hsl(120, 100%, 40%);">+   * data */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  struct rtp_hdr *rtp_hdr;</span><br><span style="color: hsl(120, 100%, 40%);">+      uint8_t buf[GSM_HR_BYTES];</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  if (!rtp_end->rfc5993_hr_convert)</span><br><span style="color: hsl(120, 100%, 40%);">+          return;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     OSMO_ASSERT(*len >= sizeof(struct rtp_hdr));</span><br><span style="color: hsl(120, 100%, 40%);">+       rtp_hdr = (struct rtp_hdr *)data;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (*len == GSM_HR_BYTES + sizeof(struct rtp_hdr)) {</span><br><span style="color: hsl(120, 100%, 40%);">+          /* TS 101318 encoding => RFC 5993 encoding */</span><br><span style="color: hsl(120, 100%, 40%);">+              memcpy(buf, rtp_hdr->data, GSM_HR_BYTES);</span><br><span style="color: hsl(120, 100%, 40%);">+          hr_jumble(rtp_hdr->data + 1, buf);</span><br><span style="color: hsl(120, 100%, 40%);">+         rtp_hdr->data[0] = 0x00;</span><br><span style="color: hsl(120, 100%, 40%);">+           (*len) += 1;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        } else if (*len == GSM_HR_BYTES + sizeof(struct rtp_hdr) + 1) {</span><br><span style="color: hsl(120, 100%, 40%);">+               /* RFC 5993 encoding => TS 101318 encoding */</span><br><span style="color: hsl(120, 100%, 40%);">+              memcpy(buf, rtp_hdr->data + 1, GSM_HR_BYTES);</span><br><span style="color: hsl(120, 100%, 40%);">+              hr_jumble(rtp_hdr->data, buf);</span><br><span style="color: hsl(120, 100%, 40%);">+             (*len) -= 1;</span><br><span style="color: hsl(120, 100%, 40%);">+  }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /* Forward data to a debug tap. This is debug function that is intended for</span><br><span>  * debugging the voice traffic with tools like gstreamer */</span><br><span> static void forward_data(int fd, struct mgcp_rtp_tap *tap, const char *buf,</span><br><span>@@ -758,6 +826,9 @@</span><br><span>                    if (addr)</span><br><span>                            mgcp_patch_and_count(endp, rtp_state, rtp_end,</span><br><span>                                                    addr, buf, buflen);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                    rfc5993_hr_convert(rtp_end, buf, &buflen);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>                     LOGP(DRTP, LOGL_DEBUG,</span><br><span>                            "endpoint:0x%x process/send to %s %s "</span><br><span>                             "rtp_port:%u rtcp_port:%u\n",</span><br><span>diff --git a/src/libosmo-mgcp/mgcp_protocol.c b/src/libosmo-mgcp/mgcp_protocol.c</span><br><span>index 9f95ea4..82db02f 100644</span><br><span>--- a/src/libosmo-mgcp/mgcp_protocol.c</span><br><span>+++ b/src/libosmo-mgcp/mgcp_protocol.c</span><br><span>@@ -652,6 +652,7 @@</span><br><span> </span><br><span>  rtp->force_aligned_timing = tcfg->force_aligned_timing;</span><br><span>        rtp->force_constant_ssrc = patch_ssrc ? 1 : 0;</span><br><span style="color: hsl(120, 100%, 40%);">+     rtp->rfc5993_hr_convert = tcfg->rfc5993_hr_convert;</span><br><span> </span><br><span>        LOGP(DLMGCP, LOGL_DEBUG,</span><br><span>          "Configuring RTP endpoint: local port %d%s%s\n",</span><br><span>diff --git a/src/libosmo-mgcp/mgcp_vty.c b/src/libosmo-mgcp/mgcp_vty.c</span><br><span>index ef63b04..c07018b 100644</span><br><span>--- a/src/libosmo-mgcp/mgcp_vty.c</span><br><span>+++ b/src/libosmo-mgcp/mgcp_vty.c</span><br><span>@@ -96,13 +96,17 @@</span><br><span>       else</span><br><span>                 vty_out(vty, "  no rtcp-omit%s", VTY_NEWLINE);</span><br><span>     if (g_cfg->trunk.force_constant_ssrc</span><br><span style="color: hsl(0, 100%, 40%);">-     || g_cfg->trunk.force_aligned_timing) {</span><br><span style="color: hsl(120, 100%, 40%);">+            || g_cfg->trunk.force_aligned_timing</span><br><span style="color: hsl(120, 100%, 40%);">+       || g_cfg->trunk.rfc5993_hr_convert) {</span><br><span>                 vty_out(vty, "  %srtp-patch ssrc%s",</span><br><span>                       g_cfg->trunk.force_constant_ssrc ? "" : "no ",</span><br><span>                        VTY_NEWLINE);</span><br><span>                vty_out(vty, "  %srtp-patch timestamp%s",</span><br><span>                  g_cfg->trunk.force_aligned_timing ? "" : "no ",</span><br><span>                       VTY_NEWLINE);</span><br><span style="color: hsl(120, 100%, 40%);">+         vty_out(vty, "  %srtp-patch rfc5993hr%s",</span><br><span style="color: hsl(120, 100%, 40%);">+                   g_cfg->trunk.rfc5993_hr_convert ? "" : "no ",</span><br><span style="color: hsl(120, 100%, 40%);">+                  VTY_NEWLINE);</span><br><span>        } else</span><br><span>               vty_out(vty, "  no rtp-patch%s", VTY_NEWLINE);</span><br><span>     if (g_cfg->trunk.audio_payload != -1)</span><br><span>@@ -722,11 +726,28 @@</span><br><span>     return CMD_SUCCESS;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+DEFUN(cfg_mgcp_patch_rtp_rfc5993hr,</span><br><span style="color: hsl(120, 100%, 40%);">+      cfg_mgcp_patch_rtp_rfc5993hr_cmd,</span><br><span style="color: hsl(120, 100%, 40%);">+      "rtp-patch rfc5993hr", RTP_PATCH_STR "Convert GSM-HR to rfc5993 and back\n")</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ g_cfg->trunk.rfc5993_hr_convert = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+       return CMD_SUCCESS;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+DEFUN(cfg_mgcp_no_patch_rtp_rfc5993hr,</span><br><span style="color: hsl(120, 100%, 40%);">+      cfg_mgcp_no_patch_rtp_rfc5993hr_cmd,</span><br><span style="color: hsl(120, 100%, 40%);">+      "no rtp-patch rfc5993hr", NO_STR RTP_PATCH_STR "Convert GSM-HR to rfc5993 and back\n")</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     g_cfg->trunk.rfc5993_hr_convert = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+       return CMD_SUCCESS;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> DEFUN(cfg_mgcp_no_patch_rtp,</span><br><span>       cfg_mgcp_no_patch_rtp_cmd, "no rtp-patch", NO_STR RTP_PATCH_STR)</span><br><span> {</span><br><span>    g_cfg->trunk.force_constant_ssrc = 0;</span><br><span>     g_cfg->trunk.force_aligned_timing = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+     g_cfg->trunk.rfc5993_hr_convert = 0;</span><br><span>      return CMD_SUCCESS;</span><br><span> }</span><br><span> </span><br><span>@@ -823,13 +844,17 @@</span><br><span>                         vty_out(vty, "  rtcp-omit%s", VTY_NEWLINE);</span><br><span>                else</span><br><span>                         vty_out(vty, "  no rtcp-omit%s", VTY_NEWLINE);</span><br><span style="color: hsl(0, 100%, 40%);">-                if (trunk->force_constant_ssrc || trunk->force_aligned_timing) {</span><br><span style="color: hsl(120, 100%, 40%);">+                if (trunk->force_constant_ssrc || trunk->force_aligned_timing</span><br><span style="color: hsl(120, 100%, 40%);">+               || g_cfg->trunk.rfc5993_hr_convert) {</span><br><span>                         vty_out(vty, "  %srtp-patch ssrc%s",</span><br><span>                               trunk->force_constant_ssrc ? "" : "no ",</span><br><span>                              VTY_NEWLINE);</span><br><span>                        vty_out(vty, "  %srtp-patch timestamp%s",</span><br><span>                          trunk->force_aligned_timing ? "" : "no ",</span><br><span>                             VTY_NEWLINE);</span><br><span style="color: hsl(120, 100%, 40%);">+                 vty_out(vty, "  %srtp-patch rfc5993hr%s",</span><br><span style="color: hsl(120, 100%, 40%);">+                           trunk->rfc5993_hr_convert ? "" : "no ",</span><br><span style="color: hsl(120, 100%, 40%);">+                                VTY_NEWLINE);</span><br><span>                } else</span><br><span>                       vty_out(vty, "  no rtp-patch%s", VTY_NEWLINE);</span><br><span>             if (trunk->audio_fmtp_extra)</span><br><span>@@ -995,12 +1020,31 @@</span><br><span>     return CMD_SUCCESS;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+DEFUN(cfg_trunk_patch_rtp_rfc5993hr,</span><br><span style="color: hsl(120, 100%, 40%);">+      cfg_trunk_patch_rtp_rfc5993hr_cmd,</span><br><span style="color: hsl(120, 100%, 40%);">+      "rtp-patch rfc5993hr", RTP_PATCH_STR "Convert GSM-HR to rfc5993 and back\n")</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       struct mgcp_trunk_config *trunk = vty->index;</span><br><span style="color: hsl(120, 100%, 40%);">+      trunk->rfc5993_hr_convert = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+     return CMD_SUCCESS;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+DEFUN(cfg_trunk_no_patch_rtp_rfc5993hr,</span><br><span style="color: hsl(120, 100%, 40%);">+      cfg_trunk_no_patch_rtp_rfc5993hr_cmd,</span><br><span style="color: hsl(120, 100%, 40%);">+      "no rtp-patch rfc5993hr", NO_STR RTP_PATCH_STR "Convert GSM-HR to rfc5993 and back\n")</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   struct mgcp_trunk_config *trunk = vty->index;</span><br><span style="color: hsl(120, 100%, 40%);">+      trunk->rfc5993_hr_convert = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+     return CMD_SUCCESS;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> DEFUN(cfg_trunk_no_patch_rtp,</span><br><span>       cfg_trunk_no_patch_rtp_cmd, "no rtp-patch", NO_STR RTP_PATCH_STR)</span><br><span> {</span><br><span>  struct mgcp_trunk_config *trunk = vty->index;</span><br><span>     trunk->force_constant_ssrc = 0;</span><br><span>   trunk->force_aligned_timing = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+   trunk->rfc5993_hr_convert = 0;</span><br><span>    return CMD_SUCCESS;</span><br><span> }</span><br><span> </span><br><span>@@ -1400,6 +1444,8 @@</span><br><span>         install_element(MGCP_NODE, &cfg_mgcp_patch_rtp_ts_cmd);</span><br><span>  install_element(MGCP_NODE, &cfg_mgcp_no_patch_rtp_ts_cmd);</span><br><span>       install_element(MGCP_NODE, &cfg_mgcp_no_patch_rtp_cmd);</span><br><span style="color: hsl(120, 100%, 40%);">+   install_element(MGCP_NODE, &cfg_mgcp_patch_rtp_rfc5993hr_cmd);</span><br><span style="color: hsl(120, 100%, 40%);">+    install_element(MGCP_NODE, &cfg_mgcp_no_patch_rtp_rfc5993hr_cmd);</span><br><span>        install_element(MGCP_NODE, &cfg_mgcp_sdp_fmtp_extra_cmd);</span><br><span>        install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_send_ptime_cmd);</span><br><span>        install_element(MGCP_NODE, &cfg_mgcp_no_sdp_payload_send_ptime_cmd);</span><br><span>@@ -1431,6 +1477,8 @@</span><br><span>     install_element(TRUNK_NODE, &cfg_trunk_patch_rtp_ssrc_cmd);</span><br><span>      install_element(TRUNK_NODE, &cfg_trunk_no_patch_rtp_ssrc_cmd);</span><br><span>   install_element(TRUNK_NODE, &cfg_trunk_patch_rtp_ts_cmd);</span><br><span style="color: hsl(120, 100%, 40%);">+ install_element(TRUNK_NODE, &cfg_trunk_patch_rtp_rfc5993hr_cmd);</span><br><span style="color: hsl(120, 100%, 40%);">+  install_element(TRUNK_NODE, &cfg_trunk_no_patch_rtp_rfc5993hr_cmd);</span><br><span>      install_element(TRUNK_NODE, &cfg_trunk_no_patch_rtp_ts_cmd);</span><br><span>     install_element(TRUNK_NODE, &cfg_trunk_no_patch_rtp_cmd);</span><br><span>        install_element(TRUNK_NODE, &cfg_trunk_sdp_fmtp_extra_cmd);</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/12979">change 12979</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.osmocom.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.osmocom.org/12979"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: osmo-mgw </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>
<div style="display:none"> Gerrit-Change-Id: Iceef19e5619f8c92dfa7c8cdecb2e9b15f0a11a1 </div>
<div style="display:none"> Gerrit-Change-Number: 12979 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: dexter <pmaier@sysmocom.de> </div>