diff trau-decode/parse-efr.c @ 4:d9c095357c32

trau-parse: check and report EFR CRC
author Mychaela Falconia <falcon@freecalypso.org>
date Fri, 24 May 2024 09:16:35 +0000
parents
children bf5c9fb431b8
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/trau-decode/parse-efr.c	Fri May 24 09:16:35 2024 +0000
@@ -0,0 +1,85 @@
+/*
+ * This module implements the EFR decoding part of trau-parse.
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+#include <gsm_efr.h>
+#include "osmo_bits.h"
+
+/*
+ * EFR TRAU parity
+ *
+ * g(x) = x^3 + x^1 + 1
+ */
+static const struct osmo_crc8gen_code gsm0860_efr_crc3 = {
+	.bits = 3,
+	.poly = 0x3,
+	.init = 0x0,
+	.remainder = 0x7,
+};
+
+/* re-combine EFR parity bits */
+static inline void efr_parity_bits_1(ubit_t *check_bits, const ubit_t *d_bits)
+{
+	memcpy(check_bits + 0 , d_bits + 0, 22);
+	memcpy(check_bits + 22 , d_bits + 24, 3);
+	check_bits[25] = d_bits[28];
+}
+
+static inline void efr_parity_bits_2(ubit_t *check_bits, const ubit_t *d_bits)
+{
+	memcpy(check_bits + 0 , d_bits + 42, 10);
+	memcpy(check_bits + 10 , d_bits + 90, 2);
+}
+
+static inline void efr_parity_bits_3(ubit_t *check_bits, const ubit_t *d_bits)
+{
+	memcpy(check_bits + 0 , d_bits + 98, 5);
+	check_bits[5] = d_bits[104];
+	memcpy(check_bits + 6 , d_bits + 143, 2);
+}
+
+static inline void efr_parity_bits_4(ubit_t *check_bits, const ubit_t *d_bits)
+{
+	memcpy(check_bits + 0 , d_bits + 151, 10);
+	memcpy(check_bits + 10 , d_bits + 199, 2);
+}
+
+static inline void efr_parity_bits_5(ubit_t *check_bits, const ubit_t *d_bits)
+{
+	memcpy(check_bits + 0 , d_bits + 207, 5);
+	check_bits[5] = d_bits[213];
+	memcpy(check_bits + 6 , d_bits + 252, 2);
+}
+
+void
+check_efr_crc(d_bits)
+	ubit_t *d_bits;
+{
+	ubit_t check_bits[26];
+	int rc1, rc2, rc3, rc4, rc5;
+
+	efr_parity_bits_1(check_bits, d_bits);
+	rc1 = osmo_crc8gen_check_bits(&gsm0860_efr_crc3, check_bits, 26,
+					d_bits + 39);
+	efr_parity_bits_2(check_bits, d_bits);
+	rc2 = osmo_crc8gen_check_bits(&gsm0860_efr_crc3, check_bits, 12,
+					d_bits + 95);
+	efr_parity_bits_3(check_bits, d_bits);
+	rc3 = osmo_crc8gen_check_bits(&gsm0860_efr_crc3, check_bits, 8,
+					d_bits + 148);
+	efr_parity_bits_4(check_bits, d_bits);
+	rc4 = osmo_crc8gen_check_bits(&gsm0860_efr_crc3, check_bits, 12,
+					d_bits + 204);
+	efr_parity_bits_5(check_bits, d_bits);
+	rc5 = osmo_crc8gen_check_bits(&gsm0860_efr_crc3, check_bits, 8,
+					d_bits + 257);
+	printf("  D1=%u CRC: %s %s %s %s %s\n", d_bits[0],
+		rc1 ? "bad" : "good", rc2 ? "bad" : "good",
+		rc3 ? "bad" : "good", rc4 ? "bad" : "good",
+		rc5 ? "bad" : "good");
+}