FreeCalypso > hg > gsm-net-reveng
view trau-decode/extr-main.c @ 28:9bcdb091c24d default tip
trau-decode: new program trau-hr-dump
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Sun, 18 Aug 2024 08:37:02 +0000 |
parents | 0565aaa84b17 |
children |
line wrap: on
line source
/* * This program reads a 64 kbit/s timeslot recording file with a focus * on a single sub-timeslot just like trau-parse, but it needs to be * invoked with a starting and ending offset for the frame-aligned * portion of interest (found with trau-parse), and it saves (converts) * the selected stream of TRAU-UL frames to a Themyscira gsmx file. */ #include <sys/types.h> #include <stdio.h> #include <stdint.h> #include <stdlib.h> #include <string.h> #include <strings.h> static void reduce_to_subslot(buf, right_shift) uint8_t *buf; { unsigned n; for (n = 0; n < 160; n++) { buf[n] >>= right_shift; buf[n] &= 3; } } static void unpack_dibits(dibits, frame_bits) uint8_t *dibits, *frame_bits; { int i, inb; uint8_t *op; op = frame_bits; for (i = 0; i < 160; i++) { inb = dibits[i]; if (inb & 2) *op++ = 1; else *op++ = 0; if (inb & 1) *op++ = 1; else *op++ = 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 collect_d_bits(frame_bits, d_bits) uint8_t *frame_bits, *d_bits; { bcopy(frame_bits + 33, d_bits, 15); bcopy(frame_bits + 49, d_bits + 15, 15); bcopy(frame_bits + 65, d_bits + 30, 15); bcopy(frame_bits + 81, d_bits + 45, 15); bcopy(frame_bits + 97, d_bits + 60, 15); bcopy(frame_bits + 113, d_bits + 75, 15); bcopy(frame_bits + 129, d_bits + 90, 15); bcopy(frame_bits + 145, d_bits + 105, 15); bcopy(frame_bits + 161, d_bits + 120, 15); bcopy(frame_bits + 177, d_bits + 135, 15); bcopy(frame_bits + 193, d_bits + 150, 15); bcopy(frame_bits + 209, d_bits + 165, 15); bcopy(frame_bits + 225, d_bits + 180, 15); bcopy(frame_bits + 241, d_bits + 195, 15); bcopy(frame_bits + 257, d_bits + 210, 15); bcopy(frame_bits + 273, d_bits + 225, 15); bcopy(frame_bits + 289, d_bits + 240, 15); bcopy(frame_bits + 305, d_bits + 255, 5); } static void process_frame(cur_offset, dibits, outf) u_long cur_offset; uint8_t *dibits; FILE *outf; { uint8_t frame_bits[320], d_bits[260]; unsigned c1_5; unpack_dibits(dibits, frame_bits); if (frame_bits[28]) { /* C12 aka BFI */ putc(0xBF, outf); putc(frame_bits[31], outf); /* C15 aka TAF */ return; } collect_d_bits(frame_bits, d_bits); c1_5 = bits_to_num(frame_bits + 17, 5); switch (c1_5) { case 0x02: convert_fr_frame(d_bits, outf); break; case 0x1A: convert_efr_frame(d_bits, outf); break; default: fprintf(stderr, "error: unknown frame type 0x%x at file offset 0x%lx\n", c1_5, cur_offset); exit(1); } } main(argc, argv) char **argv; { FILE *inf, *outf; int subslot, right_shift; u_long start_offset, end_offset, cur_offset; uint8_t readbuf[160]; int cc; if (argc != 6) { fprintf(stderr, "usage: %s binfile subslot start end outfile\n", argv[0]); exit(1); } inf = fopen(argv[1], "r"); if (!inf) { perror(argv[1]); exit(1); } subslot = atoi(argv[2]); if (subslot < 0 || subslot > 3) { fprintf(stderr, "error: invalid subslot argument\n"); exit(1); } right_shift = (3 - subslot) * 2; start_offset = strtoul(argv[3], 0, 0); fseek(inf, start_offset, SEEK_SET); end_offset = strtoul(argv[4], 0, 0); outf = fopen(argv[5], "w"); if (!outf) { perror(argv[5]); exit(1); } for (cur_offset = start_offset; ; cur_offset += 160) { if (end_offset && cur_offset >= end_offset) break; cc = fread(readbuf, 1, 160, inf); if (cc < 160) break; reduce_to_subslot(readbuf, right_shift); process_frame(cur_offset, readbuf, outf); } exit(0); }