dtx: add decoding for AMR-DTX frames

gsm0503_coding contains AMR decoder functions for HR and FR. Those can
only decode AMR payload frames but not amr DTX frames. Lets add
functionality to detect DTX frames. Also lets add decoding for SID_UPDATE
frames as well as error checking for the SID frame recognition patterns.

Related: OS#2978
Change-Id: I2bbdb39ea20461ca08b2e6f1a33532cb55cd5195
diff --git a/include/Makefile.am b/include/Makefile.am
index b341ee3..572c880 100644
--- a/include/Makefile.am
+++ b/include/Makefile.am
@@ -90,6 +90,7 @@
                        osmocom/coding/gsm0503_mapping.h \
                        osmocom/coding/gsm0503_interleaving.h \
                        osmocom/coding/gsm0503_coding.h \
+                       osmocom/coding/gsm0503_amr_dtx.h \
                        osmocom/gsm/gsm0808.h \
                        osmocom/gsm/gsm29205.h \
                        osmocom/gsm/gsm0808_utils.h \
diff --git a/include/osmocom/coding/gsm0503_amr_dtx.h b/include/osmocom/coding/gsm0503_amr_dtx.h
new file mode 100644
index 0000000..f048a6e
--- /dev/null
+++ b/include/osmocom/coding/gsm0503_amr_dtx.h
@@ -0,0 +1,40 @@
+/*! \file gsm0503_amr_dtx.h
+ *  GSM TS 05.03 coding
+ */
+
+#pragma once
+
+#include <stdint.h>
+
+#include <osmocom/core/defs.h>
+#include <osmocom/core/bits.h>
+
+/*! \addtogroup coding
+ *  @{
+ * \file gsm0503_amr_dtx.h */
+
+enum gsm0503_amr_dtx_frames {
+	AMR_OTHER,
+	AFS_SID_FIRST,
+	AFS_SID_UPDATE,
+	AFS_SID_UPDATE_CN,
+	AFS_ONSET,
+	AHS_SID_UPDATE,
+	AHS_SID_UPDATE_CN,
+	AHS_SID_FIRST_P1,
+	AHS_SID_FIRST_P2,
+	AHS_ONSET,
+	AHS_SID_FIRST_INH,
+	AHS_SID_UPDATE_INH,
+};
+
+extern const struct value_string gsm0503_amr_dtx_frame_names[];
+static inline const char *gsm0503_amr_dtx_frame_name(enum gsm0503_amr_dtx_frames frame)
+{
+	return get_value_string(gsm0503_amr_dtx_frame_names, frame);
+}
+
+enum gsm0503_amr_dtx_frames gsm0503_detect_afs_dtx_frame(int *n_errors, int *n_bits_total, const ubit_t *ubits);
+enum gsm0503_amr_dtx_frames gsm0503_detect_ahs_dtx_frame(int *n_errors, int *n_bits_total, const ubit_t *ubits);
+
+/*! @} */
diff --git a/include/osmocom/coding/gsm0503_coding.h b/include/osmocom/coding/gsm0503_coding.h
index 98038f8..2afa049 100644
--- a/include/osmocom/coding/gsm0503_coding.h
+++ b/include/osmocom/coding/gsm0503_coding.h
@@ -58,12 +58,18 @@
 int gsm0503_tch_afs_decode(uint8_t *tch_data, const sbit_t *bursts,
 	int codec_mode_req, uint8_t *codec, int codecs, uint8_t *ft,
 	uint8_t *cmr, int *n_errors, int *n_bits_total);
+int gsm0503_tch_afs_decode_dtx(uint8_t *tch_data, const sbit_t *bursts,
+	int codec_mode_req, uint8_t *codec, int codecs, uint8_t *ft,
+	uint8_t *cmr, int *n_errors, int *n_bits_total, uint8_t *dtx);
 
 int gsm0503_tch_ahs_encode(ubit_t *bursts, const uint8_t *tch_data, int len,
 	int codec_mode_req, uint8_t *codec, int codecs, uint8_t ft, uint8_t cmr);
 int gsm0503_tch_ahs_decode(uint8_t *tch_data, const sbit_t *bursts, int odd,
 	int codec_mode_req, uint8_t *codec, int codecs, uint8_t *ft,
 	uint8_t *cmr, int *n_errors, int *n_bits_total);
+int gsm0503_tch_ahs_decode_dtx(uint8_t *tch_data, const sbit_t *bursts, int odd,
+	int codec_mode_req, uint8_t *codec, int codecs, uint8_t *ft,
+	uint8_t *cmr, int *n_errors, int *n_bits_total, uint8_t *dtx);
 
 int gsm0503_rach_ext_encode(ubit_t *burst, uint16_t ra, uint8_t bsic, bool is_11bit);
 int gsm0503_rach_encode(ubit_t *burst, const uint8_t *ra, uint8_t bsic) OSMO_DEPRECATED("Use gsm0503_rach_ext_encode() instead");