<p>Harald Welte <strong>merged</strong> this change.</p><p><a href="https://gerrit.osmocom.org/12979">View Change</a></p><div style="white-space:pre-wrap">Approvals:
  Jenkins Builder: Verified
  tnt: Looks good to me, but someone else must approve
  Daniel Willmann: Looks good to me, approved
  Harald Welte: Looks good to me, approved

</div><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.<br><br>The two formats can be distinguished easily 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, 96 insertions(+), 2 deletions(-)<br><br></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..5886a65 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%);">+     bool 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..a6239c2 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%);">+     bool 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..33738bc 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,40 @@</span><br><span> #endif</span><br><span> }</span><br><span> </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_endpoint *endp, char *data, 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%);">+</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%);">+              memmove(rtp_hdr->data + 1, rtp_hdr->data, GSM_HR_BYTES);</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%);">+              memmove(rtp_hdr->data, rtp_hdr->data + 1, GSM_HR_BYTES);</span><br><span style="color: hsl(120, 100%, 40%);">+                (*len) -= 1;</span><br><span style="color: hsl(120, 100%, 40%);">+  } else {</span><br><span style="color: hsl(120, 100%, 40%);">+              /* It is possible that multiple payloads occur in one RTP</span><br><span style="color: hsl(120, 100%, 40%);">+              * packet. This is not supported yet. */</span><br><span style="color: hsl(120, 100%, 40%);">+              LOGP(DRTP, LOGL_ERROR,</span><br><span style="color: hsl(120, 100%, 40%);">+                     "endpoint:0x%x cannot figure out how to convert RTP packet\n",</span><br><span style="color: hsl(120, 100%, 40%);">+              ENDPOINT_NUMBER(endp));</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 +793,12 @@</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%);">+                    if (rtp_end->rfc5993_hr_convert</span><br><span style="color: hsl(120, 100%, 40%);">+                        && strcmp(conn_src->end.codec->subtype_name,</span><br><span style="color: hsl(120, 100%, 40%);">+                                      "GSM-HR-08") == 0)</span><br><span style="color: hsl(120, 100%, 40%);">+                            rfc5993_hr_convert(endp, 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..a47376b 100644</span><br><span>--- a/src/libosmo-mgcp/mgcp_vty.c</span><br><span>+++ b/src/libosmo-mgcp/mgcp_vty.c</span><br><span>@@ -37,6 +37,8 @@</span><br><span> #define RTCP_OMIT_STR "Drop RTCP packets in both directions\n"</span><br><span> #define RTP_PATCH_STR "Modify RTP packet header in both directions\n"</span><br><span> #define RTP_KEEPALIVE_STR "Send dummy UDP packet to net RTP destination\n"</span><br><span style="color: hsl(120, 100%, 40%);">+#define RTP_TS101318_RFC5993_CONV_STR "Convert GSM-HR from TS101318 to RFC5993 and vice versa\n"</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> </span><br><span> static struct mgcp_config *g_cfg = NULL;</span><br><span> </span><br><span>@@ -96,13 +98,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 +728,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 RTP_TS101318_RFC5993_CONV_STR)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+    g_cfg->trunk.rfc5993_hr_convert = true;</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 RTP_TS101318_RFC5993_CONV_STR)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+        g_cfg->trunk.rfc5993_hr_convert = false;</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 = false;</span><br><span>  return CMD_SUCCESS;</span><br><span> }</span><br><span> </span><br><span>@@ -823,13 +846,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 +1022,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 RTP_TS101318_RFC5993_CONV_STR)</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 = true;</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 RTP_TS101318_RFC5993_CONV_STR)</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 = false;</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 = false;</span><br><span>        return CMD_SUCCESS;</span><br><span> }</span><br><span> </span><br><span>@@ -1400,6 +1446,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 +1479,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: merged </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: 4 </div>
<div style="display:none"> Gerrit-Owner: dexter <pmaier@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: Daniel Willmann <dwillmann@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: Harald Welte <laforge@gnumonks.org> </div>
<div style="display:none"> Gerrit-Reviewer: Jenkins Builder (1000002) </div>
<div style="display:none"> Gerrit-Reviewer: Pau Espin Pedrol <pespin@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: dexter <pmaier@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: tnt <tnt@246tNt.com> </div>