<p>dexter has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.osmocom.org/c/libosmocore/+/17095">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">dtx: add functions to determine DTX frame types<br><br>gsm0503_coding contains AMR decoder functions for HR and FR. Those can<br>only decode AMR payload frames but not amr DTX frames. Lets add some<br>detector functionality to be able to detect AMR DTX frames so that the<br>caller can be informed about this<br><br>Related: OS#2978<br>Change-Id: I2bbdb39ea20461ca08b2e6f1a33532cb55cd5195<br>---<br>M include/Makefile.am<br>A include/osmocom/coding/gsm0503_amr_dtx.h<br>M include/osmocom/coding/gsm0503_coding.h<br>M src/coding/Makefile.am<br>A src/coding/gsm0503_amr_dtx.c<br>M src/coding/gsm0503_coding.c<br>M src/coding/libosmocoding.map<br>M tests/Makefile.am<br>A tests/dtx/dtx_gsm0503_test.c<br>A tests/dtx/dtx_gsm0503_test.ok<br>M tests/testsuite.at<br>11 files changed, 553 insertions(+), 1 deletion(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/95/17095/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/include/Makefile.am b/include/Makefile.am</span><br><span>index b341ee3..572c880 100644</span><br><span>--- a/include/Makefile.am</span><br><span>+++ b/include/Makefile.am</span><br><span>@@ -90,6 +90,7 @@</span><br><span>                        osmocom/coding/gsm0503_mapping.h \</span><br><span>                        osmocom/coding/gsm0503_interleaving.h \</span><br><span>                        osmocom/coding/gsm0503_coding.h \</span><br><span style="color: hsl(120, 100%, 40%);">+                       osmocom/coding/gsm0503_amr_dtx.h \</span><br><span>                        osmocom/gsm/gsm0808.h \</span><br><span>                        osmocom/gsm/gsm29205.h \</span><br><span>                        osmocom/gsm/gsm0808_utils.h \</span><br><span>diff --git a/include/osmocom/coding/gsm0503_amr_dtx.h b/include/osmocom/coding/gsm0503_amr_dtx.h</span><br><span>new file mode 100644</span><br><span>index 0000000..7cf6857</span><br><span>--- /dev/null</span><br><span>+++ b/include/osmocom/coding/gsm0503_amr_dtx.h</span><br><span>@@ -0,0 +1,38 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/*! \file gsm0503_amr_dtx.h</span><br><span style="color: hsl(120, 100%, 40%);">+ *  GSM TS 05.03 coding</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%);">+#pragma once</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <stdint.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/defs.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/bits.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*! \addtogroup coding</span><br><span style="color: hsl(120, 100%, 40%);">+ *  @{</span><br><span style="color: hsl(120, 100%, 40%);">+ * \file gsm0503_amr_dtx.h */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+enum gsm0503_amr_dtx_frames {</span><br><span style="color: hsl(120, 100%, 40%);">+       AFS_SID_FIRST,</span><br><span style="color: hsl(120, 100%, 40%);">+        AFS_SID_UPDATE,</span><br><span style="color: hsl(120, 100%, 40%);">+       AFS_ONSET,</span><br><span style="color: hsl(120, 100%, 40%);">+    AHS_SID_UPDATE,</span><br><span style="color: hsl(120, 100%, 40%);">+       AHS_SID_FIRST_P1,</span><br><span style="color: hsl(120, 100%, 40%);">+     AHS_SID_FIRST_P2,</span><br><span style="color: hsl(120, 100%, 40%);">+     AHS_ONSET,</span><br><span style="color: hsl(120, 100%, 40%);">+    AHS_SID_FIRST_INH,</span><br><span style="color: hsl(120, 100%, 40%);">+    AHS_SID_UPDATE_INH,</span><br><span style="color: hsl(120, 100%, 40%);">+   AMR_OTHER,</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%);">+extern const struct value_string gsm0503_amr_dtx_frame_names[];</span><br><span style="color: hsl(120, 100%, 40%);">+static inline const char *gsm0503_amr_dtx_frame_name(uint8_t frame)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     return get_value_string(gsm0503_amr_dtx_frame_names, frame);</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%);">+uint8_t gsm0503_detect_afs_dtx_frame(ubit_t * ubits);</span><br><span style="color: hsl(120, 100%, 40%);">+uint8_t gsm0503_detect_ahs_dtx_frame(ubit_t * ubits);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*! @} */</span><br><span>diff --git a/include/osmocom/coding/gsm0503_coding.h b/include/osmocom/coding/gsm0503_coding.h</span><br><span>index 98038f8..2afa049 100644</span><br><span>--- a/include/osmocom/coding/gsm0503_coding.h</span><br><span>+++ b/include/osmocom/coding/gsm0503_coding.h</span><br><span>@@ -58,12 +58,18 @@</span><br><span> int gsm0503_tch_afs_decode(uint8_t *tch_data, const sbit_t *bursts,</span><br><span>   int codec_mode_req, uint8_t *codec, int codecs, uint8_t *ft,</span><br><span>         uint8_t *cmr, int *n_errors, int *n_bits_total);</span><br><span style="color: hsl(120, 100%, 40%);">+int gsm0503_tch_afs_decode_dtx(uint8_t *tch_data, const sbit_t *bursts,</span><br><span style="color: hsl(120, 100%, 40%);">+     int codec_mode_req, uint8_t *codec, int codecs, uint8_t *ft,</span><br><span style="color: hsl(120, 100%, 40%);">+  uint8_t *cmr, int *n_errors, int *n_bits_total, uint8_t *dtx);</span><br><span> </span><br><span> int gsm0503_tch_ahs_encode(ubit_t *bursts, const uint8_t *tch_data, int len,</span><br><span>   int codec_mode_req, uint8_t *codec, int codecs, uint8_t ft, uint8_t cmr);</span><br><span> int gsm0503_tch_ahs_decode(uint8_t *tch_data, const sbit_t *bursts, int odd,</span><br><span>    int codec_mode_req, uint8_t *codec, int codecs, uint8_t *ft,</span><br><span>         uint8_t *cmr, int *n_errors, int *n_bits_total);</span><br><span style="color: hsl(120, 100%, 40%);">+int gsm0503_tch_ahs_decode_dtx(uint8_t *tch_data, const sbit_t *bursts, int odd,</span><br><span style="color: hsl(120, 100%, 40%);">+    int codec_mode_req, uint8_t *codec, int codecs, uint8_t *ft,</span><br><span style="color: hsl(120, 100%, 40%);">+  uint8_t *cmr, int *n_errors, int *n_bits_total, uint8_t *dtx);</span><br><span> </span><br><span> int gsm0503_rach_ext_encode(ubit_t *burst, uint16_t ra, uint8_t bsic, bool is_11bit);</span><br><span> int gsm0503_rach_encode(ubit_t *burst, const uint8_t *ra, uint8_t bsic) OSMO_DEPRECATED("Use gsm0503_rach_ext_encode() instead");</span><br><span>diff --git a/src/coding/Makefile.am b/src/coding/Makefile.am</span><br><span>index f47fe45..b023668 100644</span><br><span>--- a/src/coding/Makefile.am</span><br><span>+++ b/src/coding/Makefile.am</span><br><span>@@ -20,7 +20,8 @@</span><br><span>  gsm0503_mapping.c \</span><br><span>  gsm0503_tables.c \</span><br><span>   gsm0503_parity.c \</span><br><span style="color: hsl(0, 100%, 40%);">-      gsm0503_coding.c</span><br><span style="color: hsl(120, 100%, 40%);">+      gsm0503_coding.c \</span><br><span style="color: hsl(120, 100%, 40%);">+    gsm0503_amr_dtx.c</span><br><span> libosmocoding_la_LDFLAGS = \</span><br><span>    $(LTLDFLAGS_OSMOCODING) \</span><br><span>    -version-info \</span><br><span>diff --git a/src/coding/gsm0503_amr_dtx.c b/src/coding/gsm0503_amr_dtx.c</span><br><span>new file mode 100644</span><br><span>index 0000000..57aaf80</span><br><span>--- /dev/null</span><br><span>+++ b/src/coding/gsm0503_amr_dtx.c</span><br><span>@@ -0,0 +1,282 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+ * (C) 2016 by sysmocom - s.f.m.c. GmbH, Author: Philipp Maier</span><br><span style="color: hsl(120, 100%, 40%);">+ * All Rights Reserved</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * SPDX-License-Identifier: GPL-2.0+</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is free software; you can redistribute it and/or modify</span><br><span style="color: hsl(120, 100%, 40%);">+ * it under the terms of the GNU General Public License as published by</span><br><span style="color: hsl(120, 100%, 40%);">+ * the Free Software Foundation; either version 2 of the License, or</span><br><span style="color: hsl(120, 100%, 40%);">+ * (at your option) any later version.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is distributed in the hope that it will be useful,</span><br><span style="color: hsl(120, 100%, 40%);">+ * but WITHOUT ANY WARRANTY; without even the implied warranty of</span><br><span style="color: hsl(120, 100%, 40%);">+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the</span><br><span style="color: hsl(120, 100%, 40%);">+ * GNU General Public License for more details.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * You should have received a copy of the GNU General Public License</span><br><span style="color: hsl(120, 100%, 40%);">+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.</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%);">+#include <stdio.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <stdint.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <string.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <stdlib.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/utils.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/coding/gsm0503_amr_dtx.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+const struct value_string gsm0503_amr_dtx_frame_names[] = {</span><br><span style="color: hsl(120, 100%, 40%);">+        { AFS_SID_FIRST, "AFS_SID_FIRST" },</span><br><span style="color: hsl(120, 100%, 40%);">+ { AFS_SID_UPDATE, "AFS_SID_UPDATE" },</span><br><span style="color: hsl(120, 100%, 40%);">+       { AFS_ONSET, "AFS_ONSET" },</span><br><span style="color: hsl(120, 100%, 40%);">+ { AHS_SID_UPDATE, "AHS_SID_UPDATE" },</span><br><span style="color: hsl(120, 100%, 40%);">+       { AHS_SID_FIRST_P1, "AHS_SID_FIRST_P1" },</span><br><span style="color: hsl(120, 100%, 40%);">+   { AHS_SID_FIRST_P2, "AHS_SID_FIRST_P2" },</span><br><span style="color: hsl(120, 100%, 40%);">+   { AHS_ONSET, "AHS_ONSET" },</span><br><span style="color: hsl(120, 100%, 40%);">+ { AHS_SID_FIRST_INH, "AHS_SID_FIRST_INH" },</span><br><span style="color: hsl(120, 100%, 40%);">+ { AHS_SID_UPDATE_INH, "AHS_SID_UPDATE_INH" },</span><br><span style="color: hsl(120, 100%, 40%);">+       { AMR_OTHER, "NON DTX FRAME (OTHER)" },</span><br><span style="color: hsl(120, 100%, 40%);">+     { 0, NULL }</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%);">+static bool detect_afs_id_marker(ubit_t * ubits, uint8_t offset, uint8_t count)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ unsigned int i, k;</span><br><span style="color: hsl(120, 100%, 40%);">+    ubit_t id_marker[] = { 0, 1, 0, 0, 1, 1, 1, 1, 0 };</span><br><span style="color: hsl(120, 100%, 40%);">+   unsigned int id_bit_nr = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+   unsigned int errors = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    /* Override coded in-band data */</span><br><span style="color: hsl(120, 100%, 40%);">+     ubits += offset;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    /* Check for identification marker bits */</span><br><span style="color: hsl(120, 100%, 40%);">+    for (i = 0; i < count; i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+              for (k = 0; k < 4; k++) {</span><br><span style="color: hsl(120, 100%, 40%);">+                  if (id_marker[id_bit_nr % 9] != *ubits)</span><br><span style="color: hsl(120, 100%, 40%);">+                               errors++;</span><br><span style="color: hsl(120, 100%, 40%);">+                     id_bit_nr++;</span><br><span style="color: hsl(120, 100%, 40%);">+                  ubits++;</span><br><span style="color: hsl(120, 100%, 40%);">+              }</span><br><span style="color: hsl(120, 100%, 40%);">+             ubits += 4;</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%);">+   /* The identification marker bits are unprotected, so it is likely</span><br><span style="color: hsl(120, 100%, 40%);">+     * that some of them are errornous, we will tolerate up to 1/8</span><br><span style="color: hsl(120, 100%, 40%);">+         * of errors in total */</span><br><span style="color: hsl(120, 100%, 40%);">+      if (errors < count * 4 / 8)</span><br><span style="color: hsl(120, 100%, 40%);">+                return true;</span><br><span style="color: hsl(120, 100%, 40%);">+  return false;</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%);">+static bool detect_ahs_id_marker(ubit_t * ubits, ubit_t * id_marker)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   unsigned int i, k;</span><br><span style="color: hsl(120, 100%, 40%);">+    unsigned int errors = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    /* Override coded in-band data */</span><br><span style="color: hsl(120, 100%, 40%);">+     ubits += 16;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        /* Check for identification marker bits */</span><br><span style="color: hsl(120, 100%, 40%);">+    for (i = 0; i < 23; i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+         for (k = 0; k < 9; k++) {</span><br><span style="color: hsl(120, 100%, 40%);">+                  if (id_marker[k] != *ubits)</span><br><span style="color: hsl(120, 100%, 40%);">+                           errors++;</span><br><span style="color: hsl(120, 100%, 40%);">+                     ubits++;</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%);">+   /* Tolerate up to 1/8 errornous bits */</span><br><span style="color: hsl(120, 100%, 40%);">+       if (errors < 23 * 8 / 8)</span><br><span style="color: hsl(120, 100%, 40%);">+           return true;</span><br><span style="color: hsl(120, 100%, 40%);">+  return false;</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%);">+static bool detect_interleaved_ahs_id_marker(ubit_t * ubits, ubit_t * id_marker)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       unsigned int i, k;</span><br><span style="color: hsl(120, 100%, 40%);">+    unsigned int errors = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    /* Override coded in-band data */</span><br><span style="color: hsl(120, 100%, 40%);">+     ubits += 16 * 2;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    /* Align to even bits */</span><br><span style="color: hsl(120, 100%, 40%);">+      ubits++;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    /* Check for identification marker bits */</span><br><span style="color: hsl(120, 100%, 40%);">+    for (i = 0; i < 23; i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+         for (k = 0; k < 9; k++) {</span><br><span style="color: hsl(120, 100%, 40%);">+                  if (id_marker[k] != *ubits)</span><br><span style="color: hsl(120, 100%, 40%);">+                           errors++;</span><br><span style="color: hsl(120, 100%, 40%);">+                     ubits += 2;</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%);">+   /* Tolerate up to 1/8 errornous bits */</span><br><span style="color: hsl(120, 100%, 40%);">+       if (errors < 23 * 8 / 8)</span><br><span style="color: hsl(120, 100%, 40%);">+           return true;</span><br><span style="color: hsl(120, 100%, 40%);">+  return false;</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%);">+static unsigned int check_afs_coded_inband_bits(ubit_t * ubits, uint8_t offset)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+        unsigned int i, k;</span><br><span style="color: hsl(120, 100%, 40%);">+    unsigned int ones[4] = { 0, 0, 0, 0 };</span><br><span style="color: hsl(120, 100%, 40%);">+        unsigned int error = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     ubits += 4 + offset;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        for (i = 0; i < 14; i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+         for (k = 0; k < 4; k++) {</span><br><span style="color: hsl(120, 100%, 40%);">+                  ones[k] += ubits[k];</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%);">+           ubits += 32;</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%);">+   for (k = 0; k < 4; k++) {</span><br><span style="color: hsl(120, 100%, 40%);">+          if (ones[k] > 7)</span><br><span style="color: hsl(120, 100%, 40%);">+                   error += 14 - ones[k];</span><br><span style="color: hsl(120, 100%, 40%);">+                else</span><br><span style="color: hsl(120, 100%, 40%);">+                  error += ones[k];</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+     return error;</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%);">+static unsigned int check_ahs_coded_inband_bits(ubit_t * ubits, bool even_bits)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+        unsigned int i, k;</span><br><span style="color: hsl(120, 100%, 40%);">+    unsigned int ones[16] =</span><br><span style="color: hsl(120, 100%, 40%);">+           { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };</span><br><span style="color: hsl(120, 100%, 40%);">+       unsigned int error = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     if (even_bits)</span><br><span style="color: hsl(120, 100%, 40%);">+                ubits++;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    for (i = 0; i < 7; i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+          for (k = 0; k < 16; k++) {</span><br><span style="color: hsl(120, 100%, 40%);">+                 ones[k] += ubits[0];</span><br><span style="color: hsl(120, 100%, 40%);">+                  ubits += 2;</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%);">+   for (k = 0; k < 16; k++) {</span><br><span style="color: hsl(120, 100%, 40%);">+         if (ones[k] > 3)</span><br><span style="color: hsl(120, 100%, 40%);">+                   error += 7 - ones[k];</span><br><span style="color: hsl(120, 100%, 40%);">+         else</span><br><span style="color: hsl(120, 100%, 40%);">+                  error += ones[k];</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%);">+   return error;</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%);">+/* Detect a an FR AMR SID_FIRST frame by its identifcation marker */</span><br><span style="color: hsl(120, 100%, 40%);">+static inline bool detect_afs_sid_first(ubit_t * ubits)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+  return detect_afs_id_marker(ubits, 32, 53);</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%);">+/* Detect an FR AMR SID_FIRST frame by its identification marker */</span><br><span style="color: hsl(120, 100%, 40%);">+static inline bool detect_afs_sid_update(ubit_t * ubits)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+    return detect_afs_id_marker(ubits, 36, 36);</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%);">+/* Detect an FR AMR SID_FIRST frame by its repeating coded inband data */</span><br><span style="color: hsl(120, 100%, 40%);">+static inline bool detect_afs_onset(ubit_t * ubits)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   unsigned int error = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     error += check_afs_coded_inband_bits(ubits, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+       error += check_afs_coded_inband_bits(ubits, 8);</span><br><span style="color: hsl(120, 100%, 40%);">+       error += check_afs_coded_inband_bits(ubits, 16);</span><br><span style="color: hsl(120, 100%, 40%);">+      error += check_afs_coded_inband_bits(ubits, 24);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    if (error > 14 * 4 * 4 / 8)</span><br><span style="color: hsl(120, 100%, 40%);">+                return false;</span><br><span style="color: hsl(120, 100%, 40%);">+ return true;</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%);">+/* Detect an HR AMR SID UPDATE frame by its identification marker */</span><br><span style="color: hsl(120, 100%, 40%);">+static inline bool detect_ahs_sid_update(ubit_t * ubits)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+  ubit_t id_marker[] = { 1, 0, 1, 1, 0, 0, 0, 0, 1 };</span><br><span style="color: hsl(120, 100%, 40%);">+   return detect_ahs_id_marker(ubits, id_marker);</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%);">+/* Detect an HR AMR SID FIRST (part 1) frame by its identification marker */</span><br><span style="color: hsl(120, 100%, 40%);">+static inline bool detect_ahs_sid_first_p1(ubit_t * ubits)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      ubit_t id_marker[] = { 0, 1, 0, 0, 1, 1, 1, 1, 0 };</span><br><span style="color: hsl(120, 100%, 40%);">+   return detect_ahs_id_marker(ubits, id_marker);</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%);">+/* Detect an HR AMR SID FIRST (part 2) frame by its repeating coded inband data */</span><br><span style="color: hsl(120, 100%, 40%);">+static inline bool detect_ahs_sid_first_p2(ubit_t * ubits)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+        unsigned int error = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+       error = check_ahs_coded_inband_bits(ubits, false);</span><br><span style="color: hsl(120, 100%, 40%);">+    if (error > 7 * 16 / 8)</span><br><span style="color: hsl(120, 100%, 40%);">+            return false;</span><br><span style="color: hsl(120, 100%, 40%);">+ return true;</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%);">+/* Detect an HR AMR ONSET frame by its repeating coded inband data */</span><br><span style="color: hsl(120, 100%, 40%);">+static inline bool detect_ahs_onset(ubit_t * ubits)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      unsigned int error = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+       error = check_ahs_coded_inband_bits(ubits, true);</span><br><span style="color: hsl(120, 100%, 40%);">+     if (error > 7 * 16 / 8)</span><br><span style="color: hsl(120, 100%, 40%);">+            return false;</span><br><span style="color: hsl(120, 100%, 40%);">+ return true;</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%);">+/* Detect an HR AMR SID FIRST INHIBIT frame by its identification marker */</span><br><span style="color: hsl(120, 100%, 40%);">+static inline bool detect_ahs_sid_first_inh(ubit_t * ubits)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+        ubit_t id_marker[] = { 1, 0, 1, 1, 0, 0, 0, 0, 1 };</span><br><span style="color: hsl(120, 100%, 40%);">+   return detect_interleaved_ahs_id_marker(ubits, id_marker);</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%);">+/* Detect an HR AMR SID UPDATE INHIBIT frame by its identification marker */</span><br><span style="color: hsl(120, 100%, 40%);">+static inline bool detect_ahs_sid_update_inh(ubit_t * ubits)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+        ubit_t id_marker[] = { 0, 1, 0, 0, 1, 1, 1, 1, 0 };</span><br><span style="color: hsl(120, 100%, 40%);">+   return detect_interleaved_ahs_id_marker(ubits, id_marker);</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%);">+/*! Detect FR AMR DTX frame in unmapped, deinterleaved frame bits</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[in] ubits input bits (456 bit max)</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \returns dtx frame type */</span><br><span style="color: hsl(120, 100%, 40%);">+uint8_t gsm0503_detect_afs_dtx_frame(ubit_t * ubits)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+    if (detect_afs_sid_first(ubits))</span><br><span style="color: hsl(120, 100%, 40%);">+              return AFS_SID_FIRST;</span><br><span style="color: hsl(120, 100%, 40%);">+ if (detect_afs_sid_update(ubits))</span><br><span style="color: hsl(120, 100%, 40%);">+             return AFS_SID_UPDATE;</span><br><span style="color: hsl(120, 100%, 40%);">+        if (detect_afs_onset(ubits))</span><br><span style="color: hsl(120, 100%, 40%);">+          return AFS_ONSET;</span><br><span style="color: hsl(120, 100%, 40%);">+     return AMR_OTHER;</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%);">+/*! Detect HR AMR DTX frame in unmapped, deinterleaved frame bits</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[in] ubits input bits (456 bit max)</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \returns dtx frame type */</span><br><span style="color: hsl(120, 100%, 40%);">+uint8_t gsm0503_detect_ahs_dtx_frame(ubit_t * ubits)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     if (detect_ahs_sid_update(ubits))</span><br><span style="color: hsl(120, 100%, 40%);">+             return AHS_SID_UPDATE;</span><br><span style="color: hsl(120, 100%, 40%);">+        if (detect_ahs_sid_first_inh(ubits))</span><br><span style="color: hsl(120, 100%, 40%);">+          return AHS_SID_FIRST_INH;</span><br><span style="color: hsl(120, 100%, 40%);">+     if (detect_ahs_sid_update_inh(ubits))</span><br><span style="color: hsl(120, 100%, 40%);">+         return AHS_SID_UPDATE_INH;</span><br><span style="color: hsl(120, 100%, 40%);">+    if (detect_ahs_sid_first_p1(ubits))</span><br><span style="color: hsl(120, 100%, 40%);">+           return AHS_SID_FIRST_P1;</span><br><span style="color: hsl(120, 100%, 40%);">+      if (detect_ahs_sid_first_p2(ubits))</span><br><span style="color: hsl(120, 100%, 40%);">+           return AHS_SID_FIRST_P2;</span><br><span style="color: hsl(120, 100%, 40%);">+      if (detect_ahs_onset(ubits))</span><br><span style="color: hsl(120, 100%, 40%);">+          return AHS_ONSET;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   return AMR_OTHER;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span>diff --git a/src/coding/gsm0503_coding.c b/src/coding/gsm0503_coding.c</span><br><span>index 7385d23..d95bcaf 100644</span><br><span>--- a/src/coding/gsm0503_coding.c</span><br><span>+++ b/src/coding/gsm0503_coding.c</span><br><span>@@ -47,6 +47,7 @@</span><br><span> #include <osmocom/coding/gsm0503_tables.h></span><br><span> #include <osmocom/coding/gsm0503_coding.h></span><br><span> #include <osmocom/coding/gsm0503_parity.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/coding/gsm0503_amr_dtx.h></span><br><span> </span><br><span> /*! \mainpage libosmocoding Documentation</span><br><span>  *</span><br><span>@@ -2094,6 +2095,7 @@</span><br><span>  *  \param[out] cmr Output in \a codec_mode_req = 1</span><br><span>  *  \param[out] n_errors Number of detected bit errors</span><br><span>  *  \param[out] n_bits_total Total number of bits</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[out] dtx DTX frame type</span><br><span>  *  \returns (>=4) length of bytes used in \a tch_data output buffer; ([0,3])</span><br><span>  *          codec out of range; negative on error</span><br><span>  */</span><br><span>@@ -2101,9 +2103,33 @@</span><br><span>   int codec_mode_req, uint8_t *codec, int codecs, uint8_t *ft,</span><br><span>         uint8_t *cmr, int *n_errors, int *n_bits_total)</span><br><span> {</span><br><span style="color: hsl(120, 100%, 40%);">+  return gsm0503_tch_afs_decode_dtx(tch_data, bursts, codec_mode_req,</span><br><span style="color: hsl(120, 100%, 40%);">+                                     codec, codecs, ft, cmr, n_errors,</span><br><span style="color: hsl(120, 100%, 40%);">+                                     n_bits_total, NULL);</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%);">+/*! Perform channel decoding of a TCH/AFS channel according TS 05.03</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[out] tch_data Codec frame in RTP payload format</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[in] bursts buffer containing the symbols of 8 bursts</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[in] codec_mode_req is this CMR (1) or CMC (0)</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[in] codec array of active codecs (active codec set)</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[in] codecs number of codecs in \a codec</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param ft Frame Type; Input if \a codec_mode_req = 1, Output *  otherwise</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[out] cmr Output in \a codec_mode_req = 1</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[out] n_errors Number of detected bit errors</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[out] n_bits_total Total number of bits</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[out] dtx DTX frame type</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \returns (>=4) length of bytes used in \a tch_data output buffer; ([0,3])</span><br><span style="color: hsl(120, 100%, 40%);">+ *        codec out of range; negative on error</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+int gsm0503_tch_afs_decode_dtx(uint8_t *tch_data, const sbit_t *bursts,</span><br><span style="color: hsl(120, 100%, 40%);">+      int codec_mode_req, uint8_t *codec, int codecs, uint8_t *ft,</span><br><span style="color: hsl(120, 100%, 40%);">+  uint8_t *cmr, int *n_errors, int *n_bits_total, uint8_t *dtx)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span>     sbit_t iB[912], cB[456], h;</span><br><span>  ubit_t d[244], p[6], conv[250];</span><br><span>      int i, j, k, best = 0, rv, len, steal = 0, id = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+    ubit_t cBd[456];</span><br><span>     *n_errors = 0; *n_bits_total = 0;</span><br><span> </span><br><span>        for (i=0; i<8; i++) {</span><br><span>@@ -2133,6 +2159,15 @@</span><br><span>            }</span><br><span>    }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ /* Determine the DTX frame type (SID_UPDATE, ONSET etc...) */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (dtx) {</span><br><span style="color: hsl(120, 100%, 40%);">+            osmo_sbit2ubit(cBd, cB, 456);</span><br><span style="color: hsl(120, 100%, 40%);">+         for (i = 0; i < 456; i++)</span><br><span style="color: hsl(120, 100%, 40%);">+                  printf("%u", cBd[i]);</span><br><span style="color: hsl(120, 100%, 40%);">+               printf("\n");</span><br><span style="color: hsl(120, 100%, 40%);">+               *dtx = gsm0503_detect_afs_dtx_frame(cBd);</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>  /* Check if indicated codec fits into range of codecs */</span><br><span>     if (id >= codecs) {</span><br><span>               /* Codec mode out of range, return id */</span><br><span>@@ -2480,9 +2515,34 @@</span><br><span>    int codec_mode_req, uint8_t *codec, int codecs, uint8_t *ft,</span><br><span>         uint8_t *cmr, int *n_errors, int *n_bits_total)</span><br><span> {</span><br><span style="color: hsl(120, 100%, 40%);">+  return gsm0503_tch_ahs_decode_dtx(tch_data, bursts, odd, codec_mode_req,</span><br><span style="color: hsl(120, 100%, 40%);">+                                        codec, codecs, ft, cmr, n_errors,</span><br><span style="color: hsl(120, 100%, 40%);">+                                     n_bits_total, NULL);</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%);">+/*! Perform channel decoding of a TCH/AFS channel according TS 05.03</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[out] tch_data Codec frame in RTP payload format</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[in] bursts buffer containing the symbols of 8 bursts</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[in] odd Is this an odd (1) or even (0) frame number?</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[in] codec_mode_req is this CMR (1) or CMC (0)</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[in] codec array of active codecs (active codec set)</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[in] codecs number of codecs in \a codec</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param ft Frame Type; Input if \a codec_mode_req = 1, Output *  otherwise</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[out] cmr Output in \a codec_mode_req = 1</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[out] n_errors Number of detected bit errors</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[out] n_bits_total Total number of bits</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[out] dtx DTX frame type</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \returns (>=4) length of bytes used in \a tch_data output buffer; ([0,3])</span><br><span style="color: hsl(120, 100%, 40%);">+ *               codec out of range; negative on error</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+int gsm0503_tch_ahs_decode_dtx(uint8_t *tch_data, const sbit_t *bursts, int odd,</span><br><span style="color: hsl(120, 100%, 40%);">+     int codec_mode_req, uint8_t *codec, int codecs, uint8_t *ft,</span><br><span style="color: hsl(120, 100%, 40%);">+  uint8_t *cmr, int *n_errors, int *n_bits_total, uint8_t *dtx)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span>     sbit_t iB[912], cB[456], h;</span><br><span>  ubit_t d[244], p[6], conv[135];</span><br><span>      int i, j, k, best = 0, rv, len, steal = 0, id = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+    ubit_t cBd[456];</span><br><span> </span><br><span>         /* only unmap the stealing bits */</span><br><span>   if (!odd) {</span><br><span>@@ -2536,6 +2596,15 @@</span><br><span>                 }</span><br><span>    }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ /* Determine the DTX frame type (SID_UPDATE, ONSET etc...) */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (dtx) {</span><br><span style="color: hsl(120, 100%, 40%);">+            osmo_sbit2ubit(cBd, cB, 456);</span><br><span style="color: hsl(120, 100%, 40%);">+         for (i = 0; i < 456; i++)</span><br><span style="color: hsl(120, 100%, 40%);">+                  printf("%u", cBd[i]);</span><br><span style="color: hsl(120, 100%, 40%);">+               printf("\n");</span><br><span style="color: hsl(120, 100%, 40%);">+               *dtx = gsm0503_detect_ahs_dtx_frame(cBd);</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>  /* Check if indicated codec fits into range of codecs */</span><br><span>     if (id >= codecs) {</span><br><span>               /* Codec mode out of range, return id */</span><br><span>diff --git a/src/coding/libosmocoding.map b/src/coding/libosmocoding.map</span><br><span>index 87b3886..42f34e4 100644</span><br><span>--- a/src/coding/libosmocoding.map</span><br><span>+++ b/src/coding/libosmocoding.map</span><br><span>@@ -106,8 +106,10 @@</span><br><span> gsm0503_tch_hr_decode;</span><br><span> gsm0503_tch_afs_encode;</span><br><span> gsm0503_tch_afs_decode;</span><br><span style="color: hsl(120, 100%, 40%);">+gsm0503_tch_afs_decode_dtx;</span><br><span> gsm0503_tch_ahs_encode;</span><br><span> gsm0503_tch_ahs_decode;</span><br><span style="color: hsl(120, 100%, 40%);">+gsm0503_tch_ahs_decode_dtx;</span><br><span> gsm0503_rach_ext_encode;</span><br><span> gsm0503_rach_ext_decode;</span><br><span> gsm0503_rach_ext_decode_ber;</span><br><span>@@ -116,6 +118,10 @@</span><br><span> gsm0503_rach_decode_ber;</span><br><span> gsm0503_sch_encode;</span><br><span> gsm0503_sch_decode;</span><br><span style="color: hsl(120, 100%, 40%);">+gsm0503_amr_dtx_frame_names;</span><br><span style="color: hsl(120, 100%, 40%);">+gsm0503_amr_dtx_frame_name;</span><br><span style="color: hsl(120, 100%, 40%);">+gsm0503_detect_afs_dtx_frame;</span><br><span style="color: hsl(120, 100%, 40%);">+gsm0503_detect_ahs_dtx_frame;</span><br><span> </span><br><span> local: *;</span><br><span> };</span><br><span>diff --git a/tests/Makefile.am b/tests/Makefile.am</span><br><span>index bf7017b..0d0327a 100644</span><br><span>--- a/tests/Makefile.am</span><br><span>+++ b/tests/Makefile.am</span><br><span>@@ -34,6 +34,7 @@</span><br><span>            use_count/use_count_test                               \</span><br><span>             context/context_test                                   \</span><br><span>                  gsm0502/gsm0502_test                                      \</span><br><span style="color: hsl(120, 100%, 40%);">+                 dtx/dtx_gsm0503_test                                        \</span><br><span>             $(NULL)</span><br><span> </span><br><span> if ENABLE_MSGFILE</span><br><span>@@ -114,6 +115,10 @@</span><br><span> gsm0502_gsm0502_test_SOURCES = gsm0502/gsm0502_test.c</span><br><span> gsm0502_gsm0502_test_LDADD = $(LDADD) $(top_builddir)/src/gsm/libosmogsm.la</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+dtx_dtx_gsm0503_test_SOURCES = dtx/dtx_gsm0503_test.c</span><br><span style="color: hsl(120, 100%, 40%);">+dtx_dtx_gsm0503_test_LDADD = $(LDADD) $(top_builddir)/src/gsm/libosmogsm.la \</span><br><span style="color: hsl(120, 100%, 40%);">+                         $(top_builddir)/src/coding/libosmocoding.la</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> conv_conv_gsm0503_test_SOURCES = conv/conv_gsm0503_test.c conv/conv.c conv/gsm0503_test_vectors.c</span><br><span> conv_conv_gsm0503_test_LDADD = $(LDADD) $(top_builddir)/src/gsm/libgsmint.la</span><br><span> conv_conv_gsm0503_test_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_srcdir)/tests/conv</span><br><span>@@ -339,6 +344,7 @@</span><br><span>              use_count/use_count_test.ok use_count/use_count_test.err \</span><br><span>           context/context_test.ok \</span><br><span>            gsm0502/gsm0502_test.ok \</span><br><span style="color: hsl(120, 100%, 40%);">+             dtx/dtx_gsm0503_test.ok \</span><br><span>            exec/exec_test.ok exec/exec_test.err \</span><br><span>       $(NULL)</span><br><span> </span><br><span>diff --git a/tests/dtx/dtx_gsm0503_test.c b/tests/dtx/dtx_gsm0503_test.c</span><br><span>new file mode 100644</span><br><span>index 0000000..7e634e2</span><br><span>--- /dev/null</span><br><span>+++ b/tests/dtx/dtx_gsm0503_test.c</span><br><span>@@ -0,0 +1,126 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+ * (C) 2019 by sysmocom s.f.m.c. GmbH <info@sysmocom.de></span><br><span style="color: hsl(120, 100%, 40%);">+ * Author: Philipp Maier <pmaier@sysmocom.de></span><br><span style="color: hsl(120, 100%, 40%);">+ * All Rights Reserved</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * SPDX-License-Identifier: GPL-2.0+</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is free software; you can redistribute it and/or modify</span><br><span style="color: hsl(120, 100%, 40%);">+ * it under the terms of the GNU General Public License as published by</span><br><span style="color: hsl(120, 100%, 40%);">+ * the Free Software Foundation; either version 2 of the License, or</span><br><span style="color: hsl(120, 100%, 40%);">+ * (at your option) any later version.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is distributed in the hope that it will be useful,</span><br><span style="color: hsl(120, 100%, 40%);">+ * but WITHOUT ANY WARRANTY; without even the implied warranty of</span><br><span style="color: hsl(120, 100%, 40%);">+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the</span><br><span style="color: hsl(120, 100%, 40%);">+ * GNU General Public License for more details.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * You should have received a copy of the GNU General Public License along</span><br><span style="color: hsl(120, 100%, 40%);">+ * with this program; if not, write to the Free Software Foundation, Inc.,</span><br><span style="color: hsl(120, 100%, 40%);">+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.</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%);">+#include <string.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <stdio.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <stdint.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/utils.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/coding/gsm0503_amr_dtx.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+char sample_afs_sid_frame[] =</span><br><span style="color: hsl(120, 100%, 40%);">+    {</span><br><span style="color: hsl(120, 100%, 40%);">+"111111110000000011001100101010100100010011111111001000100111011110011001001100111100110010011001111011100100010011111111001000100111011110011001001100111100110010011001111011100100010011111111001000100111011110011001001100111100110010011001111011100100010011111111001000100111011110011001001100111100110010011001111011100100010011111111001000100111011110011001001100111100110010011001111011100100010011111111001000100111011110011001001100111100110010011001"</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%);">+char sample_afs_sid_update_frame[] =</span><br><span style="color: hsl(120, 100%, 40%);">+    {</span><br><span style="color: hsl(120, 100%, 40%);">+"111111110000000011001100101010100000010000001111111100101011011110001001000000110111110000001001011111101111010011001111100000101000011111001001111100110111110011111001001111101100010001001111000000100100011100111001100000111000110000111001010011101111010011111111010000101100011100111001111100110111110011111001110011101000010010001111110000100000011111001001011100110011110010111001101111100011010001111111001100100100011111111001000000110000110000001001"</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%);">+char sample_afs_onset_frame[] =</span><br><span style="color: hsl(120, 100%, 40%);">+    {</span><br><span style="color: hsl(120, 100%, 40%);">+"111111110000000011001100101010100000111100000000111111000100101000111111100000000111110010001010001111110100000011111100111110100100111111000000110011001011101001001111011100001011110000001010010011111100000000111100111110101000111110110000111111000000101011111111010000001100110000111010111111111000000010111100000010100100111100110000100011001000101000111111101100001011110000111010011111110011000010111100101110101100111111000000010011001111101000001111"</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%);">+char sample_ahs_sid_update_frame[] =</span><br><span style="color: hsl(120, 100%, 40%);">+    {</span><br><span style="color: hsl(120, 100%, 40%);">+"111100001100101010110000110110000110110000110110000110110000110110000110110000110110000110110000110110000110110000110110000110110000110110000110110000110110000110110000110110000110110000110110000110110000110110000110110000110110100011001000011010000000000000001111010010000000000001000000000010110000000011001000000000000000100000101000000000000000001010100000010010000000000010000111110001110110110011001101000000000100100011001000001010000100100000000011"</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%);">+char sample_ahs_sid_first_p1_frame[] =</span><br><span style="color: hsl(120, 100%, 40%);">+    {</span><br><span style="color: hsl(120, 100%, 40%);">+"111100001100101001001111001001111001001111001001111001001111001001111001001111001001111001001111001001111001001111001001111001001111001001111001001111001001111001001111001001111001001111001001111001001111001001111001001111001001001011010110001101100101001110001111001110100110010000111101110110110000100100011111001001110000011110110001010010101100001010100000111101110110001010000111110001110110110011001101001111000011101001010011100011000111010110000011"</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%);">+char sample_ahs_sid_first_p2_frame[] =</span><br><span style="color: hsl(120, 100%, 40%);">+    {</span><br><span style="color: hsl(120, 100%, 40%);">+"111110100100000010100000110111001110101100000100101001011101100011101010010000001010010010001100101010100100010111110101110011011110101000010100111000001001110111101110010101001110000010001101101011110000000011100100110110011111100011001000001101100101001110001111001110100110010000111101110110110000100100011111001001110000011110110001010010101100001010100000111101110110001010000111110001110110110011001101001111000011101001010011100011000111010110000011"</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%);">+char sample_ahs_onset_frame[] =</span><br><span style="color: hsl(120, 100%, 40%);">+    {</span><br><span style="color: hsl(120, 100%, 40%);">+"111101011000101001010000111001000111011110000000011110001110010011011111100000101101101001101110011111010000000001010010110001101101110100000010011110101100010001011101101010000111100011101100111101011010100011110010110001001111100011001000011010000000000000001010010010000000000001000000000000100000000011001000000000000000100000101000000000000000010010000101010010000000000010101100111110101000110110011001000000000100100011001000001010000100100000001100"</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%);">+char sample_sid_first_inh_frame[] =</span><br><span style="color: hsl(120, 100%, 40%);">+    {</span><br><span style="color: hsl(120, 100%, 40%);">+"xBxBxBxBxBxBxBxBxBxBxBxBxBxBxBxBx1x0x1x1x0x0x0x0x1x1x0x1x1x0x0x0x0x1x1x0x1x1x0x0x0x0x1x1x0x1x1x0x0x0x0x1x1x0x1x1x0x0x0x0x1x1x0x1x1x0x0x0x0x1x1x0x1x1x0x0x0x0x1x1x0x1x1x0x0x0x0x1x1x0x1x1x0x0x0x0x1x1x0x1x1x0x0x0x0x1x1x0x1x1x0x0x0x0x1x1x0x1x1x0x0x0x0x1x1x0x1x1x0x0x0x0x1x1x0x1x1x0x0x0x0x1x1x0x1x1x0x0x0x0x1x1x0x1x1x0x0x0x0x1x1x0x1x1x0x0x0x0x1x1x0x1x1x0x0x0x0x1x1x0x1x1x0x0x0x0x1x1x0x1x1x0x0x0x0x1x1x0x1x1x0x0x0x0x1x1x0x1x1x0x0x0x0x1x1x0x1x1x0x0x0x0x1x1x0x1x1x0"</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%);">+char sample_sid_update_inh_frame[] =</span><br><span style="color: hsl(120, 100%, 40%);">+    {</span><br><span style="color: hsl(120, 100%, 40%);">+"xBxBxBxBxBxBxBxBxBxBxBxBxBxBxBxBx0x1x0x0x1x1x1x1x0x0x1x0x0x1x1x1x1x0x0x1x0x0x1x1x1x1x0x0x1x0x0x1x1x1x1x0x0x1x0x0x1x1x1x1x0x0x1x0x0x1x1x1x1x0x0x1x0x0x1x1x1x1x0x0x1x0x0x1x1x1x1x0x0x1x0x0x1x1x1x1x0x0x1x0x0x1x1x1x1x0x0x1x0x0x1x1x1x1x0x0x1x0x0x1x1x1x1x0x0x1x0x0x1x1x1x1x0x0x1x0x0x1x1x1x1x0x0x1x0x0x1x1x1x1x0x0x1x0x0x1x1x1x1x0x0x1x0x0x1x1x1x1x0x0x1x0x0x1x1x1x1x0x0x1x0x0x1x1x1x1x0x0x1x0x0x1x1x1x1x0x0x1x0x0x1x1x1x1x0x0x1x0x0x1x1x1x1x0x0x1x0x0x1x1x1x1x0x0x1x0x0x1"</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%);">+unsigned int string_to_ubit(ubit_t * ubits, char *string)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ unsigned int len;</span><br><span style="color: hsl(120, 100%, 40%);">+     unsigned int i;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     len = strlen(string);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       for (i = 0; i < len; i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+                ubits[i] = string[i] & 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%);">+   return len;</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%);">+void test_gsm0503_detect_afs_dtx_frame(char *string)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     ubit_t ubits[512];</span><br><span style="color: hsl(120, 100%, 40%);">+    uint8_t dtx_frame_type;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     string_to_ubit(ubits, string);</span><br><span style="color: hsl(120, 100%, 40%);">+        dtx_frame_type = gsm0503_detect_afs_dtx_frame(ubits);</span><br><span style="color: hsl(120, 100%, 40%);">+ printf(" ==> %u, %s\n", dtx_frame_type,</span><br><span style="color: hsl(120, 100%, 40%);">+         gsm0503_amr_dtx_frame_name(dtx_frame_type));</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%);">+void test_gsm0503_detect_ahs_dtx_frame(char *string)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     ubit_t ubits[512];</span><br><span style="color: hsl(120, 100%, 40%);">+    uint8_t dtx_frame_type;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     string_to_ubit(ubits, string);</span><br><span style="color: hsl(120, 100%, 40%);">+        dtx_frame_type = gsm0503_detect_ahs_dtx_frame(ubits);</span><br><span style="color: hsl(120, 100%, 40%);">+ printf(" ==> %u, %s\n", dtx_frame_type,</span><br><span style="color: hsl(120, 100%, 40%);">+         gsm0503_amr_dtx_frame_name(dtx_frame_type));</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%);">+int main(int argc, char **argv)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+  printf("FR AMR DTX FRAMES:\n");</span><br><span style="color: hsl(120, 100%, 40%);">+     test_gsm0503_detect_afs_dtx_frame(sample_afs_sid_frame);</span><br><span style="color: hsl(120, 100%, 40%);">+      test_gsm0503_detect_afs_dtx_frame(sample_afs_sid_update_frame);</span><br><span style="color: hsl(120, 100%, 40%);">+       test_gsm0503_detect_afs_dtx_frame(sample_afs_onset_frame);</span><br><span style="color: hsl(120, 100%, 40%);">+    printf("HR AMR DTX FRAMES:\n");</span><br><span style="color: hsl(120, 100%, 40%);">+     test_gsm0503_detect_ahs_dtx_frame(sample_ahs_sid_update_frame);</span><br><span style="color: hsl(120, 100%, 40%);">+       test_gsm0503_detect_ahs_dtx_frame(sample_ahs_sid_first_p1_frame);</span><br><span style="color: hsl(120, 100%, 40%);">+     test_gsm0503_detect_ahs_dtx_frame(sample_ahs_sid_first_p2_frame);</span><br><span style="color: hsl(120, 100%, 40%);">+     test_gsm0503_detect_ahs_dtx_frame(sample_ahs_onset_frame);</span><br><span style="color: hsl(120, 100%, 40%);">+    test_gsm0503_detect_ahs_dtx_frame(sample_sid_first_inh_frame);</span><br><span style="color: hsl(120, 100%, 40%);">+        test_gsm0503_detect_ahs_dtx_frame(sample_sid_update_inh_frame);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     return EXIT_SUCCESS;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span>diff --git a/tests/dtx/dtx_gsm0503_test.ok b/tests/dtx/dtx_gsm0503_test.ok</span><br><span>new file mode 100644</span><br><span>index 0000000..4544043</span><br><span>--- /dev/null</span><br><span>+++ b/tests/dtx/dtx_gsm0503_test.ok</span><br><span>@@ -0,0 +1,11 @@</span><br><span style="color: hsl(120, 100%, 40%);">+FR AMR DTX FRAMES:</span><br><span style="color: hsl(120, 100%, 40%);">+ ==> 0, AFS_SID_FIRST</span><br><span style="color: hsl(120, 100%, 40%);">+ ==> 1, AFS_SID_UPDATE</span><br><span style="color: hsl(120, 100%, 40%);">+ ==> 2, AFS_ONSET</span><br><span style="color: hsl(120, 100%, 40%);">+HR AMR DTX FRAMES:</span><br><span style="color: hsl(120, 100%, 40%);">+ ==> 3, AHS_SID_UPDATE</span><br><span style="color: hsl(120, 100%, 40%);">+ ==> 4, AHS_SID_FIRST_P1</span><br><span style="color: hsl(120, 100%, 40%);">+ ==> 5, AHS_SID_FIRST_P2</span><br><span style="color: hsl(120, 100%, 40%);">+ ==> 6, AHS_ONSET</span><br><span style="color: hsl(120, 100%, 40%);">+ ==> 7, AHS_SID_FIRST_INH</span><br><span style="color: hsl(120, 100%, 40%);">+ ==> 8, AHS_SID_UPDATE_INH</span><br><span>diff --git a/tests/testsuite.at b/tests/testsuite.at</span><br><span>index cb83ab9..bab5730 100644</span><br><span>--- a/tests/testsuite.at</span><br><span>+++ b/tests/testsuite.at</span><br><span>@@ -132,6 +132,12 @@</span><br><span> AT_CHECK([$abs_top_builddir/tests/gsm0502/gsm0502_test], [0], [expout], [ignore])</span><br><span> AT_CLEANUP</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+AT_SETUP([dtx])</span><br><span style="color: hsl(120, 100%, 40%);">+AT_KEYWORDS([dtx])</span><br><span style="color: hsl(120, 100%, 40%);">+cat $abs_srcdir/dtx/dtx_gsm0503_test.ok > expout</span><br><span style="color: hsl(120, 100%, 40%);">+AT_CHECK([$abs_top_builddir/tests/dtx/dtx_gsm0503_test], [0], [expout], [ignore])</span><br><span style="color: hsl(120, 100%, 40%);">+AT_CLEANUP</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> AT_SETUP([gsm0808])</span><br><span> AT_KEYWORDS([gsm0808])</span><br><span> cat $abs_srcdir/gsm0808/gsm0808_test.ok > expout</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/libosmocore/+/17095">change 17095</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/c/libosmocore/+/17095"/><meta itemprop="name" content="View Change"/></div></div>

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