view trau-decode/trau-sync8.c @ 43:95acde708ce2

trau-parse: add knowledge of HR-data frame types
author Mychaela Falconia <falcon@freecalypso.org>
date Thu, 12 Sep 2024 23:59:16 +0000
parents f508dacf2cf9
children b15dfdc62ceb
line wrap: on
line source

/*
 * This program reads a 64 kbit/s timeslot recording file, examines one
 * of the eight 8 kbit/s subslots (selected), looks for the sync pattern of
 * GSM 08.61 (HRv1 speech or HR data), and dumps each synced frame
 * as a hex line.
 */

#include <sys/types.h>
#include <sys/file.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <unistd.h>

static uint8_t *filebuf;
static unsigned total_size;

static void
read_ts_file(filename, subslot_arg)
	char *filename, *subslot_arg;
{
	FILE *inf;
	struct stat st;
	int subslot, right_shift;
	unsigned n;
	uint8_t *dp;
	int b;

	inf = fopen(filename, "r");
	if (!inf) {
		perror(filename);
		exit(1);
	}
	fstat(fileno(inf), &st);
	if (!S_ISREG(st.st_mode)) {
		fprintf(stderr, "error: %s is not a regular file\n", filename);
		exit(1);
	}
	total_size = st.st_size;
	if (total_size < 160) {
		fprintf(stderr, "error: %s is too short\n", filename);
		exit(1);
	}
	filebuf = malloc(total_size);
	if (!filebuf) {
		perror("malloc of file size");
		exit(1);
	}
	subslot = atoi(subslot_arg);
	if (subslot < 0 || subslot > 7) {
		fprintf(stderr, "error: invalid subslot argument\n");
		exit(1);
	}
	right_shift = 7 - subslot;
	dp = filebuf;
	for (n = 0; n < total_size; n++) {
		b = getc(inf);
		if (b < 0) {
			fprintf(stderr,
			"error: getc() returned EOF contrary to st_size\n");
			exit(1);
		}
		*dp++ = (b >> right_shift) & 1;
	}
	fclose(inf);
}

static int
check_sync(pos)
	unsigned pos;
{
	uint8_t *cand = filebuf + pos;
	unsigned n;

	for (n = 0; n < 8; n++) {
		if (cand[n])
			return 0;
	}
	if (!cand[8])
		return 0;
	if (cand[16])
		return 0;
	if (!cand[17])
		return 0;
	for (n = 3; n < 20; n++) {
		if (!cand[n * 8])
			return 0;
	}
	return 1;
}

static void
process_frame(pos)
	unsigned pos;
{
	uint8_t *sp = filebuf + pos;
	unsigned n, m, d;

	for (n = 0; n < 40; n++) {
		d = 0;
		for (m = 0; m < 4; m++) {
			d <<= 1;
			d |= *sp++;
		}
		printf("%x", d);
	}
	putchar('\n');
}

static void
process_filebuf()
{
	unsigned p, endp;
	int sync = 0, match;

	endp = total_size - 160;
	for (p = 0; p < endp; ) {
		match = check_sync(p);
		if (match != sync) {
			printf("# %s frame sync at file offset 0x%x\n",
				match ? "Acquired" : "Lost", p);
		}
		if (match) {
			process_frame(p);
			if (!filebuf[p+158] && !filebuf[p+159]) {
				printf(
			  "# both T bits equal 0, shifting frame alignment\n");
				p += 158;
			} else
				p += 160;
		} else
			p++;
		sync = match;
	}
}

main(argc, argv)
	char **argv;
{
	if (argc != 3) {
		fprintf(stderr, "usage: %s binfile subslot\n", argv[0]);
		exit(1);
	}
	read_ts_file(argv[1], argv[2]);
	process_filebuf();
	exit(0);
}