FreeCalypso > hg > gsm-net-reveng
view trau-decode/trau-hr-dump.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 | e78c6b1ecb91 |
children |
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, decodes each frame as HRv1 speech and dumps everything it * decodes. */ #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 int include_raw; 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 dump_raw_frame(frame_bits) uint8_t *frame_bits; { uint8_t *sp = frame_bits; 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_frame(pos) unsigned pos; { uint8_t *frame = filebuf + pos; printf("Frame at 0x%x:\n", pos); if (include_raw) dump_raw_frame(frame); print_gsmhr_frame(frame); } 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; { char *filename, *subslot_arg; switch (argc) { case 3: if (argv[1][0] == '-') goto usage; filename = argv[1]; subslot_arg = argv[2]; include_raw = 0; break; case 4: if (strcmp(argv[1], "-r")) goto usage; if (argv[2][0] == '-') goto usage; filename = argv[2]; subslot_arg = argv[3]; include_raw = 1; break; default: usage: fprintf(stderr, "usage: %s [-r] binfile subslot\n", argv[0]); exit(1); } read_ts_file(filename, subslot_arg); process_filebuf(); exit(0); }