view efrtest/dlcap-parse.c @ 553:ebcf414b7d99

doc/TFO-transform: describe details for FRv1, both modes
author Mychaela Falconia <falcon@freecalypso.org>
date Mon, 07 Oct 2024 08:24:24 +0000
parents b98aebd94d1f
children
line wrap: on
line source

/*
 * This program reads a TCH/EFS downlink capture produced with FreeCalypso tools
 * (fw version with TCH downlink sniffing feature and fc-shell tch record),
 * parses the frame bits according to our current understanding, and dumps
 * everything in human-readable form for further analysis.
 */

#include <ctype.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include "../libgsmefr/gsm_efr.h"

static void
process_record(lineno, fn_mod_104, status_words, tidsp_bytes)
	int lineno;
	unsigned fn_mod_104;
	uint16_t *status_words;
	uint8_t *tidsp_bytes;
{
	uint8_t efr_bytes[EFR_RTP_FRAME_LEN];
	int16_t params[EFR_NUM_PARAMS];
	int i, j, n;

	printf("#%d: fn=%u DSP %04X %04X %04X\n", lineno, fn_mod_104,
		status_words[0], status_words[1], status_words[2]);
	efr_tidsp_to_std(tidsp_bytes, efr_bytes);
	fputs("  bits ", stdout);
	for (i = 0; i < 33; i++)
		printf("%02X", tidsp_bytes[i]);
	printf(" SID=%d\n", EFR_sid_classify(efr_bytes));
	printf("  rept-bits %u %u %u %u\n", (tidsp_bytes[23] & 0x38) >> 3,
		tidsp_bytes[23] & 7, (tidsp_bytes[24] & 0xE0) >> 5,
		(tidsp_bytes[24] & 0x1C) >> 2);
	EFR_frame2params(efr_bytes, params);
	fputs("  LPC", stdout);
	n = 0;
	for (i = 0; i < 5; i++)
		printf(" %d", params[n++]);
	putchar('\n');
	for (i = 0; i < 4; i++) {
		putchar(' ');
		for (j = 0; j < 13; j++)
			printf(" %d", params[n++]);
		putchar('\n');
	}
}

main(argc, argv)
	char **argv;
{
	FILE *inf;
	char linebuf[128];
	int lineno, rc;
	uint16_t status_words[3];
	uint8_t tidsp_bytes[33];
	unsigned fn_mod_104;

	if (argc != 2) {
		fprintf(stderr, "usage: %s dlcap-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++) {
		/* support both old and new formats */
		if (isxdigit(linebuf[0]) && isxdigit(linebuf[1]) &&
		    isxdigit(linebuf[2]) && isxdigit(linebuf[3])) {
			rc = parse_dlcap_common(linebuf, status_words,
						tidsp_bytes);
			if (rc < 0) {
invalid:			fprintf(stderr,
				"error: %s is not in the expected format\n",
					argv[1]);
				exit(1);
			}
			fn_mod_104 = 0;		/* won't have TAF */
		} else if (!strncmp(linebuf, "EFR ", 4)) {
			rc = parse_dlcap_common(linebuf + 4, status_words,
						tidsp_bytes);
			if (rc < 0)
				goto invalid;
			if (linebuf[85] != ' ')
				goto invalid;
			if (!isdigit(linebuf[86]))
				goto invalid;
			fn_mod_104 = strtoul(linebuf + 86, 0, 10);
		} else
			goto invalid;
		process_record(lineno, fn_mod_104, status_words, tidsp_bytes);
	}
	exit(0);
}