FreeCalypso > hg > gsm-net-reveng
view trau-decode/parse-main.c @ 31:5f98c5cae4ea
new program tfo-parse-fr16
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Wed, 28 Aug 2024 06:23:21 +0000 |
parents | 4d1732e4a143 |
children | d7674c80426c |
line wrap: on
line source
/* * This program reads a 64 kbit/s timeslot recording file, examines one * of the four 16 kbit/s subslots (selected), looks for GSM 08.60 TRAU * frames, and dumps whatever it finds. */ #include <stdio.h> #include <stdint.h> #include <stdlib.h> #include <string.h> #include <strings.h> static unsigned file_offset; static enum { HUNT_FOR_0, HUNT_FOUND_0, GOT_8_ZEROS, SYNCED } state; static unsigned hunt_for_0_count, frame_pos_count; static uint8_t in_frame_2bit[160], frame_bits[320], d_bits[260]; static void unpack_dibits() { int i, inb; uint8_t *op; op = frame_bits; for (i = 0; i < 160; i++) { inb = in_frame_2bit[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() { 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() { unsigned c1_5, c6_11; printf("Frame at 0x%x:\n", file_offset - 159); 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; } putchar('\n'); 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]); switch (c1_5) { case 0x02: case 0x1C: collect_d_bits(); print_fr_frame(d_bits); break; case 0x1A: collect_d_bits(); check_efr_crc(d_bits); print_efr_frame(d_bits); break; } 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 int check_sync_zeros() { int i; for (i = 0; i < 16; i++) { if (frame_bits[i]) return 0; } return 1; } static int check_sync_ones() { int i; for (i = 1; i < 20; i++) { if (!frame_bits[i*16]) return 0; } return 1; } static void check_sync() { if (check_sync_zeros() && check_sync_ones()) return; printf("Bad frame sync, returning to hunt state\n"); state = HUNT_FOR_0; } static void byte_input(inb) { switch (state) { case HUNT_FOR_0: if (inb != 0) return; state = HUNT_FOUND_0; hunt_for_0_count = 1; return; case HUNT_FOUND_0: if (inb != 0) { state = HUNT_FOR_0; return; } hunt_for_0_count++; if (hunt_for_0_count >= 8) state = GOT_8_ZEROS; return; case GOT_8_ZEROS: if (inb & 2) { printf("Found frame sync at file offset 0x%x\n", file_offset - 8); bzero(in_frame_2bit, 8); in_frame_2bit[8] = inb; frame_pos_count = 9; state = SYNCED; return; } if (inb != 0) state = HUNT_FOR_0; return; case SYNCED: in_frame_2bit[frame_pos_count++] = inb; if (frame_pos_count < 160) return; frame_pos_count = 0; unpack_dibits(); process_frame(); check_sync(); return; default: fprintf(stderr, "BUG: bad sync state\n"); abort(); } } main(argc, argv) char **argv; { FILE *inf; int subslot, right_shift; int inb; if (argc != 3) { fprintf(stderr, "usage: %s binfile subslot\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; state = HUNT_FOR_0; for (file_offset = 0; ; file_offset++) { inb = getc(inf); if (inb < 0) break; inb >>= right_shift; inb &= 3; byte_input(inb); } exit(0); }