FreeCalypso > hg > gsm-net-reveng
view trau-decode/parse-new8.c @ 114:4ff5c798c75d
trau-decode: new program trau-parse-n8
| author | Mychaela Falconia <falcon@freecalypso.org> |
|---|---|
| date | Mon, 22 Dec 2025 08:28:44 +0000 |
| parents | trau-decode/amr8-readbin.c@028307356ba9 |
| 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 all possible sync * patterns (classic HR and TRAU-AMR-8k), and decodes whatever it finds. */ #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> static uint8_t *filebuf; static unsigned total_size; 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 is_classic_hr(cand) uint8_t *cand; { 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 int check_sync(pos, cont) unsigned pos; { uint8_t *cand = filebuf + pos; if (is_classic_hr(cand)) return 1; if (is_amr_low(cand)) return 1; if (!cont) return 0; if (is_amr_67(cand)) return 1; if (is_amr_74(cand)) return 1; return 0; } static void dump_raw_nibbles(bits, num_bits) uint8_t *bits; unsigned num_bits; { uint8_t *sp = bits; unsigned remain = num_bits; if (remain >= 4) { while (remain >= 4) { printf("%x", (sp[0] << 3) | (sp[1] << 2) | (sp[2] << 1) | sp[3]); sp += 4; remain -= 4; } putchar('\n'); } if (remain) { fputs("dribble ", stdout); while (remain) { printf("%u", *sp++); remain--; } putchar('\n'); } } static int process_frame(pos) unsigned pos; { uint8_t *frame = filebuf + pos; printf("Frame at 0x%x:\n", pos); dump_raw_nibbles(frame, 160); if (is_classic_hr(frame)) return print_gsmhr_frame(frame); else return print_amr8_frame(frame); } static void process_filebuf() { unsigned p, nf_pos = 0, nf_accum = 0; int match, num_t_bits; int in_sync = 0; for (p = 0; p < total_size; ) { if ((total_size - p) >= 160) match = check_sync(p, in_sync); else match = 0; if (match) { if (nf_accum) { printf("Non-frame at 0x%x:\n", nf_pos); dump_raw_nibbles(filebuf + nf_pos, nf_accum); } num_t_bits = process_frame(p); if (num_t_bits == 2 && !filebuf[p+158] && !filebuf[p+159]) { puts("advance of 250 us"); p += 158; } else if (num_t_bits == 2 && filebuf[p+158] && !filebuf[p+159]) { puts("advance of 125 us"); p += 159; } else if (num_t_bits == 1 && !filebuf[p+159]) { puts("advance of 125 us"); p += 159; } else p += 160; nf_pos = p; nf_accum = 0; in_sync = 1; } else { p++; nf_accum++; if (nf_accum >= 320) { printf("Non-frame at 0x%x:\n", nf_pos); dump_raw_nibbles(filebuf + nf_pos, nf_accum); nf_pos = p; nf_accum = 0; } in_sync = 0; } } if (nf_accum) { printf("Non-frame at 0x%x:\n", nf_pos); dump_raw_nibbles(filebuf + nf_pos, nf_accum); } } main(argc, argv) char **argv; { if (argc != 3) { fprintf(stderr, "usage: %s binfile subslot\n", argv[0]); exit(1); } read_ts_file(argv[1], argv[2]); process_filebuf(); exit(0); }
