FreeCalypso > hg > gsm-net-reveng
comparison trau-parse.c @ 0:131e0f1972bb
beginning of trau-parse program
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Fri, 24 May 2024 07:17:23 +0000 |
parents | |
children | b0dcd48a1c8a |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:131e0f1972bb |
---|---|
1 /* | |
2 * This program reads a 64 kbit/s timeslot recording file, examines one | |
3 * of the four 16 kbit/s subslots (selected), looks for GSM 08.60 TRAU | |
4 * frames, and dumps 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 unsigned file_offset; | |
14 | |
15 static enum { | |
16 HUNT_FOR_0, | |
17 HUNT_FOUND_0, | |
18 GOT_8_ZEROS, | |
19 SYNCED | |
20 } state; | |
21 static unsigned hunt_for_0_count, frame_pos_count; | |
22 static uint8_t in_frame_2bit[160], frame_bits[320]; | |
23 | |
24 static void | |
25 unpack_dibits() | |
26 { | |
27 int i, inb; | |
28 uint8_t *op; | |
29 | |
30 op = frame_bits; | |
31 for (i = 0; i < 160; i++) { | |
32 inb = in_frame_2bit[i]; | |
33 if (inb & 2) | |
34 *op++ = 1; | |
35 else | |
36 *op++ = 0; | |
37 if (inb & 1) | |
38 *op++ = 1; | |
39 else | |
40 *op++ = 0; | |
41 } | |
42 } | |
43 | |
44 static unsigned | |
45 bits_to_num(bits, nbits) | |
46 uint8_t *bits; | |
47 unsigned nbits; | |
48 { | |
49 unsigned accum; | |
50 unsigned n; | |
51 | |
52 accum = 0; | |
53 for (n = 0; n < nbits; n++) { | |
54 accum <<= 1; | |
55 if (*bits) | |
56 accum |= 1; | |
57 bits++; | |
58 } | |
59 return accum; | |
60 } | |
61 | |
62 static void | |
63 process_frame() | |
64 { | |
65 unsigned c1_5, c6_11; | |
66 | |
67 printf("Frame at 0x%x:\n", file_offset - 160); | |
68 printf(" C1-C5: %u%u%u%u%u", frame_bits[17], frame_bits[18], | |
69 frame_bits[19], frame_bits[20], frame_bits[21]); | |
70 c1_5 = bits_to_num(frame_bits + 17); | |
71 switch (c1_5) { | |
72 case 0x02: | |
73 fputs(" (FR UL)", stdout); | |
74 break; | |
75 case 0x1C: | |
76 fputs(" (FR DL)", stdout); | |
77 break; | |
78 case 0x1E: | |
79 fputs(" (EFR)", stdout); | |
80 break; | |
81 case 0x10: | |
82 fputs(" (idle UL)", stdout); | |
83 break; | |
84 case 0x0E: | |
85 fputs(" (idle DL)", stdout); | |
86 break; | |
87 } | |
88 putchar('\n'); | |
89 c6_11 = bits_to_num(frame_bits + 22); | |
90 printf(" C6-C11: %u\n", c6_11); | |
91 printf(" C12=%u C13=%u C14=%u C15=%u\n", frame_bits[28], | |
92 frame_bits[29], frame_bits[30], frame_bits[31]); | |
93 /* payload to be handled */ | |
94 printf(" C16=%u C17=%u C18=%u C19=%u C20=%u C21=%u\n", | |
95 frame_bits[310], frame_bits[311], frame_bits[312], | |
96 frame_bits[313], frame_bits[314], frame_bits[315]); | |
97 printf(" T1=%u T2=%u T3=%u T4=%u\n", frame_bits[316], frame_bits[317], | |
98 frame_bits[318], frame_bits[319]); | |
99 } | |
100 | |
101 static int | |
102 check_sync_zeros() | |
103 { | |
104 int i; | |
105 | |
106 for (i = 0; i < 16; i++) { | |
107 if (frame_bits[i]) | |
108 return 0; | |
109 } | |
110 return 1; | |
111 } | |
112 | |
113 static int | |
114 check_sync_ones() | |
115 { | |
116 int i; | |
117 | |
118 for (i = 1; i < 20; i++) { | |
119 if (!frame_bits[i*16]) | |
120 return 0; | |
121 } | |
122 return 1; | |
123 } | |
124 | |
125 static void | |
126 check_sync() | |
127 { | |
128 if (check_sync_zeros() && check_sync_ones()) | |
129 return; | |
130 printf("Bad frame sync, returning to hunt state\n"); | |
131 state = HUNT_FOR_0; | |
132 } | |
133 | |
134 static void | |
135 byte_input(inb) | |
136 { | |
137 switch (state) { | |
138 case HUNT_FOR_0: | |
139 if (inb != 0) | |
140 return; | |
141 state = HUNT_FOUND_0; | |
142 hunt_for_0_count = 1; | |
143 return; | |
144 case HUNT_FOUND_0: | |
145 if (inb != 0) { | |
146 state = HUNT_FOR_0; | |
147 return; | |
148 } | |
149 hunt_for_0_count++; | |
150 if (hunt_for_0_count >= 8) | |
151 state = GOT_8_ZEROS; | |
152 return; | |
153 case GOT_8_ZEROS: | |
154 if (inb & 2) { | |
155 printf("Found frame sync at file offset 0x%x\n", | |
156 file_offset - 8); | |
157 bzero(in_frame_2bit, 8); | |
158 in_frame_2bit[8] = inb; | |
159 frame_pos_count = 9; | |
160 state = SYNCED; | |
161 return; | |
162 } | |
163 if (inb != 0) | |
164 state = HUNT_FOR_0; | |
165 return; | |
166 case SYNCED: | |
167 in_frame_2bit[frame_pos_count++] = inb; | |
168 if (frame_pos_count < 160) | |
169 return; | |
170 frame_pos_count = 0; | |
171 unpack_dibits(); | |
172 process_frame(); | |
173 check_sync(); | |
174 return; | |
175 default: | |
176 fprintf(stderr, "BUG: bad sync state\n"); | |
177 abort(); | |
178 } | |
179 } | |
180 | |
181 main(argc, argv) | |
182 char **argv; | |
183 { | |
184 FILE *inf; | |
185 int subslot, right_shift; | |
186 int inb; | |
187 | |
188 if (argc != 3) { | |
189 fprintf(stderr, "usage: %s binfile subslot\n", argv[0]); | |
190 exit(1); | |
191 } | |
192 inf = fopen(argv[1], "r"); | |
193 if (!inf) { | |
194 perror(argv[1]); | |
195 exit(1); | |
196 } | |
197 subslot = atoi(argv[2]); | |
198 if (subslot < 0 || subslot > 3) { | |
199 fprintf(stderr, "error: invalid subslot argument\n"); | |
200 exit(1); | |
201 } | |
202 right_shift = (3 - subslot) * 2; | |
203 state = HUNT_FOR_0; | |
204 for (file_offset = 0; ; file_offset++) { | |
205 inb = getc(inf); | |
206 if (inb < 0) | |
207 break; | |
208 inb >>= right_shift; | |
209 inb &= 3; | |
210 byte_input(inb); | |
211 } | |
212 exit(0); | |
213 } |