view v110/v110-dump16.c @ 59:323a4b75a32d

atrau-parse: add blank separator lines to output for better readability
author Mychaela Falconia <falcon@freecalypso.org>
date Wed, 25 Sep 2024 17:52:26 +0000
parents 796cc2d94204
children
line wrap: on
line source

/*
 * This program reads a 64 kbit/s timeslot recording file, examines it
 * as V.110 with 16 kbit/s intermediate rate, locates 80-bit V.110 frames
 * and dumps them in a mostly raw form.
 */

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

static const uint8_t *filebuf;
static unsigned total_size;

static void
read_ts_file(filename)
	char *filename;
{
	int fd;
	struct stat st;

	fd = open(filename, O_RDONLY);
	if (fd < 0) {
		perror(filename);
		exit(1);
	}
	fstat(fd, &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 < 40) {
		fprintf(stderr, "error: %s is too short\n", filename);
		exit(1);
	}
	filebuf = mmap(NULL, total_size, PROT_READ, MAP_PRIVATE, fd, 0);
	if (filebuf == MAP_FAILED) {
		perror("mmap");
		exit(1);
	}
	close(fd);
}

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

	for (n = 0; n < 4; n++) {
		if (cand[n] & 0xC0)
			return 0;
	}
	for (n = 1; n < 10; n++) {
		if (!(cand[n * 4] & 0x80))
			return 0;
	}
	return 1;
}

static unsigned
extract_data_byte(pos)
	unsigned pos;
{
	const uint8_t *src = filebuf + pos;
	unsigned accum;
	unsigned n;

	accum = 0;
	for (n = 0; n < 4; n++) {
		accum <<= 1;
		if (*src & 0x80)
			accum |= 1;
		accum <<= 1;
		if (*src & 0x40)
			accum |= 1;
		src++;
	}
	return accum;
}

static void
process_frame(pos)
	unsigned pos;
{
	unsigned nb;

	printf("Frame at 0x%x:", pos);
	pos += 4;
	for (nb = 0; nb < 9; nb++) {
		printf(" %02X", extract_data_byte(pos));
		pos += 4;
	}
	putchar('\n');
}

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

	endp = total_size - 40;
	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);
			p += 40;
		} else
			p++;
		sync = match;
	}
}

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