FreeCalypso > hg > gsm-net-reveng
comparison 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 |
comparison
equal
deleted
inserted
replaced
28:9bcdb091c24d | 29:fec87477e60b |
---|---|
1 /* | |
2 * This program reads a raw binary file that contains a recording of | |
3 * a T1/E1 timeslot on the MSC side of a TRAU, analyzes it looking for | |
4 * TFO IS messages, and prints whatever it finds. | |
5 */ | |
6 | |
7 #include <stdio.h> | |
8 #include <stdint.h> | |
9 #include <stdlib.h> | |
10 #include <string.h> | |
11 #include <strings.h> | |
12 | |
13 static uint8_t is_hunt_buf[320]; | |
14 static int is_state; | |
15 static unsigned is_hunt_fill; | |
16 static unsigned is_offset; | |
17 static unsigned is_file_offset; | |
18 static unsigned is_bit_count; | |
19 static unsigned is_rx_word; | |
20 | |
21 static const u_char hdr_pattern[20] = {0, 1, 0, 1, 0, 1, 1, 0, 1, 0, | |
22 0, 1, 1, 0, 1, 0, 1, 0, 0, 1}; | |
23 | |
24 static void | |
25 is_rx_hunt(cur_file_offset) | |
26 unsigned cur_file_offset; | |
27 { | |
28 unsigned offset, n; | |
29 | |
30 for (offset = 0; offset < 16; offset++) { | |
31 for (n = 0; n < 20; n++) | |
32 if ((is_hunt_buf[offset + n*16] & 1) != hdr_pattern[n]) | |
33 break; | |
34 if (n == 20) | |
35 break; | |
36 } | |
37 if (n != 20) | |
38 return; | |
39 is_offset = offset; | |
40 is_file_offset = cur_file_offset - 19*16 + offset; | |
41 is_state = 1; | |
42 is_bit_count = 0; | |
43 is_rx_word = 0; | |
44 is_hunt_fill = 0; | |
45 } | |
46 | |
47 static void | |
48 is_process_cmd() | |
49 { | |
50 int cont; | |
51 | |
52 printf("0x%x: ", is_file_offset); | |
53 switch (is_rx_word) { | |
54 case 0x05D: | |
55 printf("IS_REQ\n"); | |
56 cont = 1; | |
57 break; | |
58 case 0x0BA: | |
59 printf("IS_ACK\n"); | |
60 cont = 1; | |
61 break; | |
62 case 0x0E7: | |
63 printf("IS_IPE\n"); | |
64 cont = 1; | |
65 break; | |
66 case 0x129: | |
67 printf("IS_FILL\n"); | |
68 cont = 0; | |
69 break; | |
70 case 0x174: | |
71 printf("IS_DUP\n"); | |
72 cont = 0; | |
73 break; | |
74 case 0x193: | |
75 printf("IS_SYL\n"); | |
76 cont = 0; | |
77 break; | |
78 default: | |
79 printf("unknown IS_Command 0x%03X\n", is_rx_word); | |
80 cont = 0; | |
81 } | |
82 if (cont) { | |
83 is_state = 2; | |
84 is_bit_count = 0; | |
85 is_rx_word = 0; | |
86 } else | |
87 is_state = 0; | |
88 } | |
89 | |
90 static void | |
91 is_process_ext() | |
92 { | |
93 printf(" IS_Extension: 0x%05X", is_rx_word); | |
94 if (is_rx_word & 0x80200) { | |
95 printf(" (bad sync)\n"); | |
96 is_state = 0; | |
97 return; | |
98 } | |
99 switch (is_rx_word & 3) { | |
100 case 0: | |
101 printf(" (final)\n"); | |
102 is_state = 0; | |
103 return; | |
104 case 3: | |
105 printf(" (continue)\n"); | |
106 is_state = 2; | |
107 is_bit_count = 0; | |
108 is_rx_word = 0; | |
109 return; | |
110 default: | |
111 printf(" (bad EX)\n"); | |
112 is_state = 0; | |
113 } | |
114 } | |
115 | |
116 static void | |
117 is_rx_process(input, cur_file_offset) | |
118 uint8_t *input; | |
119 unsigned cur_file_offset; | |
120 { | |
121 unsigned new_bit; | |
122 | |
123 memmove(is_hunt_buf, is_hunt_buf + 16, 304); | |
124 memcpy(is_hunt_buf + 304, input, 16); | |
125 if (!is_state) { | |
126 if (is_hunt_fill < 20) | |
127 is_hunt_fill++; | |
128 if (is_hunt_fill == 20) | |
129 is_rx_hunt(cur_file_offset); | |
130 return; | |
131 } | |
132 new_bit = input[is_offset] & 1; | |
133 is_rx_word <<= 1; | |
134 is_rx_word |= new_bit; | |
135 is_bit_count++; | |
136 if (is_state == 1 && is_bit_count == 10) | |
137 is_process_cmd(); | |
138 else if (is_state == 2 && is_bit_count == 20) | |
139 is_process_ext(); | |
140 } | |
141 | |
142 main(argc, argv) | |
143 char **argv; | |
144 { | |
145 FILE *inf; | |
146 uint8_t chunk[16]; | |
147 unsigned file_offset; | |
148 int cc; | |
149 | |
150 if (argc != 2) { | |
151 fprintf(stderr, "usage: %s pcm-capture-file\n", argv[0]); | |
152 exit(1); | |
153 } | |
154 inf = fopen(argv[1], "r"); | |
155 if (!inf) { | |
156 perror(argv[1]); | |
157 exit(1); | |
158 } | |
159 for (file_offset = 0; ; file_offset += 16) { | |
160 cc = fread(chunk, 1, 16, inf); | |
161 if (cc == 0) | |
162 break; | |
163 if (cc != 16) { | |
164 fprintf(stderr, | |
165 "error: read of 16 bytes returned %d\n", cc); | |
166 exit(1); | |
167 } | |
168 is_rx_process(chunk, file_offset); | |
169 } | |
170 exit(0); | |
171 } |