view trau-decode/trau-hr-dump-hex.c @ 83:5e2ecfd45fc3 default tip

trau-parse: AMR 7k40 CRC
author Mychaela Falconia <falcon@freecalypso.org>
date Sun, 09 Feb 2025 03:22:47 +0000
parents b518ab15b518
children
line wrap: on
line source

/*
 * This program reads a line-based text file in an ad hoc hex format
 * where each line represents a TRAU-8k frame.  These TRAU-8k frames
 * are then decoded.
 */

#include <ctype.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>

static int
decode_hex_digit(c)
{
	if (isdigit(c))
		return c - '0';
	else if (isupper(c))
		return c - 'A' + 10;
	else
		return c - 'a' + 10;
}

static void
hex2bits(hex, bits)
	char *hex;
	uint8_t *bits;
{
	unsigned n, m, x;

	for (n = 0; n < 40; n++) {
		x = decode_hex_digit(hex[n]);
		for (m = 8; m; m >>= 1) {
			if (x & m)
				*bits++ = 1;
			else
				*bits++ = 0;
		}
	}
}

static void
process_record(hex_frame, lineno)
	char *hex_frame;
{
	uint8_t frame_bits[160];

	printf("line %d: %s\n", lineno, hex_frame);
	hex2bits(hex_frame, frame_bits);
	print_gsmhr_frame(frame_bits);
}

static void
process_line(linebuf, filename, lineno)
	char *linebuf, *filename;
{
	char *cp, *np;
	unsigned n;

	for (cp = linebuf; isspace(*cp); cp++)
		;
	if (*cp == '\0' || *cp == '#')
		return;
	np = cp;
	for (n = 0; n < 40; n++) {
		if (!isxdigit(*cp))
			goto inv;
		cp++;
	}
	if (*cp) {
		if (!isspace(*cp))
			goto inv;
		*cp++ = '\0';
	}
	while (isspace(*cp))
		cp++;
	if (*cp != '\0' && *cp != '#')
		goto inv;
	process_record(np, lineno);
	return;

inv:	fprintf(stderr, "%s line %d: invalid syntax\n", filename, lineno);
	exit(1);
}

main(argc, argv)
	char **argv;
{
	FILE *inf;
	char linebuf[128];
	int lineno;

	if (argc != 2) {
		fprintf(stderr, "usage: %s hex-file\n", argv[0]);
		exit(1);
	}
	inf = fopen(argv[1], "r");
	if (!inf) {
		perror(argv[1]);
		exit(1);
	}
	for (lineno = 1; fgets(linebuf, sizeof linebuf, inf); lineno++)
		process_line(linebuf, argv[1], lineno);
	exit(0);
}