diff frtest/dlcap-sync.c @ 474:285381a001fc

new program gsmfr-dlcap-sync
author Mychaela Falconia <falcon@freecalypso.org>
date Wed, 15 May 2024 06:20:59 +0000
parents efrtest/dlcap-sync.c@d80ccb3c3970
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/frtest/dlcap-sync.c	Wed May 15 06:20:59 2024 +0000
@@ -0,0 +1,106 @@
+/*
+ * This program reads a TCH/FS downlink capture file from a FreeCalypso GSM MS
+ * that was produced in a session in which seqsync PCMA or PCMU input
+ * (seqsyn_[au].inp) was fed into the test call from IP-PSTN side.  It looks
+ * for FRv1 DHF followed by specific frame patterns given by ETSI in
+ * syn???_[au].cod files, and reports what it finds.  Matches indicate
+ * a particular alignment between the input sequence and encoder frame
+ * boundaries, if the network speech transcoder implements the encoder
+ * homing feature which is optional for FRv1.
+ */
+
+#include <ctype.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+#include "../libgsmfr2/tw_gsmfr.h"
+
+extern const uint8_t sync_from_pcma[160*33];
+extern const uint8_t sync_from_pcmu[160*33];
+
+static int
+check_for_match(input, table)
+	const uint8_t *input, *table;
+{
+	unsigned n;
+
+	for (n = 0; n < 160; n++) {
+		if (!bcmp(input, table + n * 33, 33))
+			return n;
+	}
+	return -1;
+}
+
+main(argc, argv)
+	char **argv;
+{
+	FILE *inf;
+	char linebuf[128];
+	int lineno, rc;
+	uint16_t status_words[3];
+	uint8_t tidsp_bytes[33], libgsm_bytes[33];
+	const uint8_t *match_table;
+	int dhf_state;
+
+	if (argc != 3) {
+usage:		fprintf(stderr, "usage: %s dlcap-file alaw|ulaw\n", argv[0]);
+		exit(1);
+	}
+	inf = fopen(argv[1], "r");
+	if (!inf) {
+		perror(argv[1]);
+		exit(1);
+	}
+	if (!strcmp(argv[2], "alaw"))
+		match_table = sync_from_pcma;
+	else if (!strcmp(argv[2], "ulaw"))
+		match_table = sync_from_pcmu;
+	else
+		goto usage;
+	dhf_state = 0;
+	for (lineno = 1; fgets(linebuf, sizeof linebuf, inf); lineno++) {
+		/* support both old and new formats */
+		if (isxdigit(linebuf[0]) && isxdigit(linebuf[1]) &&
+		    isxdigit(linebuf[2]) && isxdigit(linebuf[3])) {
+			rc = parse_dlcap_common(linebuf, status_words,
+						tidsp_bytes);
+			if (rc < 0) {
+invalid:			fprintf(stderr,
+				"error: %s is not in the expected format\n",
+					argv[1]);
+				exit(1);
+			}
+		} else if (!strncmp(linebuf, "FR ", 3)) {
+			rc = parse_dlcap_common(linebuf + 3, status_words,
+						tidsp_bytes);
+			if (rc < 0)
+				goto invalid;
+			if (linebuf[84] != ' ')
+				goto invalid;
+			if (!isdigit(linebuf[85]))
+				goto invalid;
+		} else
+			goto invalid;
+		if ((status_words[0] & 0xC004) != 0xC000) {
+			dhf_state = 0;
+			continue;
+		}
+		gsm0610_tidsp_to_libgsm(tidsp_bytes, libgsm_bytes);
+		if (!bcmp(libgsm_bytes, gsmfr_decoder_homing_frame, 33)) {
+			dhf_state = 1;
+			continue;
+		}
+		if (!dhf_state)
+			continue;
+		rc = check_for_match(libgsm_bytes, match_table);
+		if (rc >= 0 && rc <= 159) {
+			printf(
+			"line %d: match to expected sync frame for offset %d\n",
+				lineno, rc);
+		}
+		dhf_state = 0;
+	}
+	exit(0);
+}