diff tfo/tfo-trace-msg.c @ 29:fec87477e60b

new program tfo-trace-msg
author Mychaela Falconia <falcon@freecalypso.org>
date Wed, 28 Aug 2024 02:28:37 +0000
parents
children 19039ffbe605
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tfo/tfo-trace-msg.c	Wed Aug 28 02:28:37 2024 +0000
@@ -0,0 +1,171 @@
+/*
+ * This program reads a raw binary file that contains a recording of
+ * a T1/E1 timeslot on the MSC side of a TRAU, analyzes it looking for
+ * TFO IS messages, and prints whatever it finds.
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+
+static uint8_t is_hunt_buf[320];
+static int is_state;
+static unsigned is_hunt_fill;
+static unsigned is_offset;
+static unsigned is_file_offset;
+static unsigned is_bit_count;
+static unsigned is_rx_word;
+
+static const u_char hdr_pattern[20] =	{0, 1, 0, 1, 0, 1, 1, 0, 1, 0,
+					 0, 1, 1, 0, 1, 0, 1, 0, 0, 1};
+
+static void
+is_rx_hunt(cur_file_offset)
+	unsigned cur_file_offset;
+{
+	unsigned offset, n;
+
+	for (offset = 0; offset < 16; offset++) {
+		for (n = 0; n < 20; n++)
+			if ((is_hunt_buf[offset + n*16] & 1) != hdr_pattern[n])
+				break;
+		if (n == 20)
+			break;
+	}
+	if (n != 20)
+		return;
+	is_offset = offset;
+	is_file_offset = cur_file_offset - 19*16 + offset;
+	is_state = 1;
+	is_bit_count = 0;
+	is_rx_word = 0;
+	is_hunt_fill = 0;
+}
+
+static void
+is_process_cmd()
+{
+	int cont;
+
+	printf("0x%x: ", is_file_offset);
+	switch (is_rx_word) {
+	case 0x05D:
+		printf("IS_REQ\n");
+		cont = 1;
+		break;
+	case 0x0BA:
+		printf("IS_ACK\n");
+		cont = 1;
+		break;
+	case 0x0E7:
+		printf("IS_IPE\n");
+		cont = 1;
+		break;
+	case 0x129:
+		printf("IS_FILL\n");
+		cont = 0;
+		break;
+	case 0x174:
+		printf("IS_DUP\n");
+		cont = 0;
+		break;
+	case 0x193:
+		printf("IS_SYL\n");
+		cont = 0;
+		break;
+	default:
+		printf("unknown IS_Command 0x%03X\n", is_rx_word);
+		cont = 0;
+	}
+	if (cont) {
+		is_state = 2;
+		is_bit_count = 0;
+		is_rx_word = 0;
+	} else
+		is_state = 0;
+}
+
+static void
+is_process_ext()
+{
+	printf("  IS_Extension: 0x%05X", is_rx_word);
+	if (is_rx_word & 0x80200) {
+		printf(" (bad sync)\n");
+		is_state = 0;
+		return;
+	}
+	switch (is_rx_word & 3) {
+	case 0:
+		printf(" (final)\n");
+		is_state = 0;
+		return;
+	case 3:
+		printf(" (continue)\n");
+		is_state = 2;
+		is_bit_count = 0;
+		is_rx_word = 0;
+		return;
+	default:
+		printf(" (bad EX)\n");
+		is_state = 0;
+	}
+}
+
+static void
+is_rx_process(input, cur_file_offset)
+	uint8_t *input;
+	unsigned cur_file_offset;
+{
+	unsigned new_bit;
+
+	memmove(is_hunt_buf, is_hunt_buf + 16, 304);
+	memcpy(is_hunt_buf + 304, input, 16);
+	if (!is_state) {
+		if (is_hunt_fill < 20)
+			is_hunt_fill++;
+		if (is_hunt_fill == 20)
+			is_rx_hunt(cur_file_offset);
+		return;
+	}
+	new_bit = input[is_offset] & 1;
+	is_rx_word <<= 1;
+	is_rx_word |= new_bit;
+	is_bit_count++;
+	if (is_state == 1 && is_bit_count == 10)
+		is_process_cmd();
+	else if (is_state == 2 && is_bit_count == 20)
+		is_process_ext();
+}
+
+main(argc, argv)
+	char **argv;
+{
+	FILE *inf;
+	uint8_t chunk[16];
+	unsigned file_offset;
+	int cc;
+
+	if (argc != 2) {
+		fprintf(stderr, "usage: %s pcm-capture-file\n", argv[0]);
+		exit(1);
+	}
+	inf = fopen(argv[1], "r");
+	if (!inf) {
+		perror(argv[1]);
+		exit(1);
+	}
+	for (file_offset = 0; ; file_offset += 16) {
+		cc = fread(chunk, 1, 16, inf);
+		if (cc == 0)
+			break;
+		if (cc != 16) {
+			fprintf(stderr,
+				"error: read of 16 bytes returned %d\n", cc);
+			exit(1);
+		}
+		is_rx_process(chunk, file_offset);
+	}
+	exit(0);
+}