FreeCalypso > hg > gsm-net-reveng
diff tfo/tfo-trace-msg.c @ 29:fec87477e60b
new program tfo-trace-msg
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Wed, 28 Aug 2024 02:28:37 +0000 |
parents | |
children | 19039ffbe605 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tfo/tfo-trace-msg.c Wed Aug 28 02:28:37 2024 +0000 @@ -0,0 +1,171 @@ +/* + * This program reads a raw binary file that contains a recording of + * a T1/E1 timeslot on the MSC side of a TRAU, analyzes it looking for + * TFO IS messages, and prints whatever it finds. + */ + +#include <stdio.h> +#include <stdint.h> +#include <stdlib.h> +#include <string.h> +#include <strings.h> + +static uint8_t is_hunt_buf[320]; +static int is_state; +static unsigned is_hunt_fill; +static unsigned is_offset; +static unsigned is_file_offset; +static unsigned is_bit_count; +static unsigned is_rx_word; + +static const u_char hdr_pattern[20] = {0, 1, 0, 1, 0, 1, 1, 0, 1, 0, + 0, 1, 1, 0, 1, 0, 1, 0, 0, 1}; + +static void +is_rx_hunt(cur_file_offset) + unsigned cur_file_offset; +{ + unsigned offset, n; + + for (offset = 0; offset < 16; offset++) { + for (n = 0; n < 20; n++) + if ((is_hunt_buf[offset + n*16] & 1) != hdr_pattern[n]) + break; + if (n == 20) + break; + } + if (n != 20) + return; + is_offset = offset; + is_file_offset = cur_file_offset - 19*16 + offset; + is_state = 1; + is_bit_count = 0; + is_rx_word = 0; + is_hunt_fill = 0; +} + +static void +is_process_cmd() +{ + int cont; + + printf("0x%x: ", is_file_offset); + switch (is_rx_word) { + case 0x05D: + printf("IS_REQ\n"); + cont = 1; + break; + case 0x0BA: + printf("IS_ACK\n"); + cont = 1; + break; + case 0x0E7: + printf("IS_IPE\n"); + cont = 1; + break; + case 0x129: + printf("IS_FILL\n"); + cont = 0; + break; + case 0x174: + printf("IS_DUP\n"); + cont = 0; + break; + case 0x193: + printf("IS_SYL\n"); + cont = 0; + break; + default: + printf("unknown IS_Command 0x%03X\n", is_rx_word); + cont = 0; + } + if (cont) { + is_state = 2; + is_bit_count = 0; + is_rx_word = 0; + } else + is_state = 0; +} + +static void +is_process_ext() +{ + printf(" IS_Extension: 0x%05X", is_rx_word); + if (is_rx_word & 0x80200) { + printf(" (bad sync)\n"); + is_state = 0; + return; + } + switch (is_rx_word & 3) { + case 0: + printf(" (final)\n"); + is_state = 0; + return; + case 3: + printf(" (continue)\n"); + is_state = 2; + is_bit_count = 0; + is_rx_word = 0; + return; + default: + printf(" (bad EX)\n"); + is_state = 0; + } +} + +static void +is_rx_process(input, cur_file_offset) + uint8_t *input; + unsigned cur_file_offset; +{ + unsigned new_bit; + + memmove(is_hunt_buf, is_hunt_buf + 16, 304); + memcpy(is_hunt_buf + 304, input, 16); + if (!is_state) { + if (is_hunt_fill < 20) + is_hunt_fill++; + if (is_hunt_fill == 20) + is_rx_hunt(cur_file_offset); + return; + } + new_bit = input[is_offset] & 1; + is_rx_word <<= 1; + is_rx_word |= new_bit; + is_bit_count++; + if (is_state == 1 && is_bit_count == 10) + is_process_cmd(); + else if (is_state == 2 && is_bit_count == 20) + is_process_ext(); +} + +main(argc, argv) + char **argv; +{ + FILE *inf; + uint8_t chunk[16]; + unsigned file_offset; + int cc; + + if (argc != 2) { + fprintf(stderr, "usage: %s pcm-capture-file\n", argv[0]); + exit(1); + } + inf = fopen(argv[1], "r"); + if (!inf) { + perror(argv[1]); + exit(1); + } + for (file_offset = 0; ; file_offset += 16) { + cc = fread(chunk, 1, 16, inf); + if (cc == 0) + break; + if (cc != 16) { + fprintf(stderr, + "error: read of 16 bytes returned %d\n", cc); + exit(1); + } + is_rx_process(chunk, file_offset); + } + exit(0); +}