<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>