view trau-decode/parse-hex16.c @ 84:5173515e1cc8 default tip

trau-decode: new program trau-parse-hex
author Mychaela Falconia <falcon@freecalypso.org>
date Tue, 25 Feb 2025 05:36:25 +0000
parents trau-decode/trau-hr-dump-hex.c@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-16k frame.  These TRAU-16k 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 < 80; n++) {
		x = decode_hex_digit(hex[n]);
		for (m = 8; m; m >>= 1) {
			if (x & m)
				*bits++ = 1;
			else
				*bits++ = 0;
		}
	}
}

static unsigned
bits_to_num(bits, nbits)
	uint8_t *bits;
	unsigned nbits;
{
	unsigned accum;
	unsigned n;

	accum = 0;
	for (n = 0; n < nbits; n++) {
		accum <<= 1;
		if (*bits)
			accum |= 1;
		bits++;
	}
	return accum;
}

static void
process_frame(frame_bits)
	uint8_t *frame_bits;
{
	unsigned c1_5, c6_11;

	printf("  C1-C5: %u%u%u%u%u", frame_bits[17], frame_bits[18],
		frame_bits[19], frame_bits[20], frame_bits[21]);
	c1_5 = bits_to_num(frame_bits + 17, 5);
	switch (c1_5) {
	case 0x02:
		fputs(" (FR UL)", stdout);
		break;
	case 0x1C:
		fputs(" (FR DL)", stdout);
		break;
	case 0x1A:
		fputs(" (EFR)", stdout);
		break;
	case 0x10:
		fputs(" (idle UL)", stdout);
		break;
	case 0x0E:
		fputs(" (idle DL)", stdout);
		break;
	case 0x08:
		fputs(" (data UL)", stdout);
		break;
	case 0x16:
		fputs(" (data DL)", stdout);
		break;
	case 0x09:
		fputs(" (HR data UL)", stdout);
		break;
	case 0x17:
		fputs(" (HR data DL)", stdout);
		break;
	case 0x14:
		fputs(" (D144 sync)", stdout);
		break;
	case 0x1F:
		fputs(" (E-TRAU)", stdout);
		break;
	case 0x06:
		fputs(" (AMR)", stdout);
		break;
	}
	putchar('\n');
	switch (c1_5) {
	case 0x02:
	case 0x1C:
	case 0x1A:
	case 0x10:
	case 0x0E:
		c6_11 = bits_to_num(frame_bits + 22, 6);
		printf("  C6-C11: %u\n", c6_11);
		printf("  C12=%u C13=%u C14=%u C15=%u\n", frame_bits[28],
			frame_bits[29], frame_bits[30], frame_bits[31]);
		print_fr_efr_frame(frame_bits, c1_5);
		printf("  C16=%u C17=%u C18=%u C19=%u C20=%u C21=%u\n",
			frame_bits[310], frame_bits[311], frame_bits[312],
			frame_bits[313], frame_bits[314], frame_bits[315]);
		printf("  T1=%u T2=%u T3=%u T4=%u\n", frame_bits[316],
			frame_bits[317], frame_bits[318], frame_bits[319]);
		break;
	case 0x08:
	case 0x09:
	case 0x16:
	case 0x17:
	case 0x14:
		print_data_frame(frame_bits);
		break;
	case 0x1F:
		print_edata_frame(frame_bits);
		break;
	case 0x06:
		print_amr_frame(frame_bits);
		break;
	default:
		printf("  C6-C15: %u%u%u%u%u%u%u%u%u%u\n", frame_bits[22],
			frame_bits[23], frame_bits[24], frame_bits[25],
			frame_bits[26], frame_bits[27], frame_bits[28],
			frame_bits[29], frame_bits[30], frame_bits[31]);
		printf("  C16=%u C17=%u C18=%u C19=%u C20=%u C21=%u\n",
			frame_bits[310], frame_bits[311], frame_bits[312],
			frame_bits[313], frame_bits[314], frame_bits[315]);
		printf("  T1=%u T2=%u T3=%u T4=%u\n", frame_bits[316],
			frame_bits[317], frame_bits[318], frame_bits[319]);
	}
}

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

	printf("line %d:\n%s\n", lineno, hex_frame);
	hex2bits(hex_frame, frame_bits);
	process_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 < 80; 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);
}