comparison trau-decode/parse-tfo16.c @ 31:5f98c5cae4ea

new program tfo-parse-fr16
author Mychaela Falconia <falcon@freecalypso.org>
date Wed, 28 Aug 2024 06:23:21 +0000
parents trau-decode/parse-main.c@4d1732e4a143
children
comparison
equal deleted inserted replaced
30:19039ffbe605 31:5f98c5cae4ea
1 /*
2 * This program reads a 64 kbit/s timeslot recording file and looks for
3 * TFO frames of GSM 08.62, specifically the FR/EFR kind.
4 */
5
6 #include <stdio.h>
7 #include <stdint.h>
8 #include <stdlib.h>
9 #include <string.h>
10 #include <strings.h>
11
12 static unsigned file_offset;
13
14 static enum {
15 HUNT_FOR_0,
16 HUNT_FOUND_0,
17 GOT_8_ZEROS,
18 SYNCED
19 } state;
20 static unsigned hunt_for_0_count, frame_pos_count;
21 static uint8_t in_frame_2bit[160], frame_bits[320], d_bits[260];
22
23 static void
24 unpack_dibits()
25 {
26 int i, inb;
27 uint8_t *op;
28
29 op = frame_bits;
30 for (i = 0; i < 160; i++) {
31 inb = in_frame_2bit[i];
32 if (inb & 1)
33 *op++ = 1;
34 else
35 *op++ = 0;
36 if (inb & 2)
37 *op++ = 1;
38 else
39 *op++ = 0;
40 }
41 }
42
43 static unsigned
44 bits_to_num(bits, nbits)
45 uint8_t *bits;
46 unsigned nbits;
47 {
48 unsigned accum;
49 unsigned n;
50
51 accum = 0;
52 for (n = 0; n < nbits; n++) {
53 accum <<= 1;
54 if (*bits)
55 accum |= 1;
56 bits++;
57 }
58 return accum;
59 }
60
61 static void
62 collect_d_bits()
63 {
64 bcopy(frame_bits + 33, d_bits, 15);
65 bcopy(frame_bits + 49, d_bits + 15, 15);
66 bcopy(frame_bits + 65, d_bits + 30, 15);
67 bcopy(frame_bits + 81, d_bits + 45, 15);
68 bcopy(frame_bits + 97, d_bits + 60, 15);
69 bcopy(frame_bits + 113, d_bits + 75, 15);
70 bcopy(frame_bits + 129, d_bits + 90, 15);
71 bcopy(frame_bits + 145, d_bits + 105, 15);
72 bcopy(frame_bits + 161, d_bits + 120, 15);
73 bcopy(frame_bits + 177, d_bits + 135, 15);
74 bcopy(frame_bits + 193, d_bits + 150, 15);
75 bcopy(frame_bits + 209, d_bits + 165, 15);
76 bcopy(frame_bits + 225, d_bits + 180, 15);
77 bcopy(frame_bits + 241, d_bits + 195, 15);
78 bcopy(frame_bits + 257, d_bits + 210, 15);
79 bcopy(frame_bits + 273, d_bits + 225, 15);
80 bcopy(frame_bits + 289, d_bits + 240, 15);
81 bcopy(frame_bits + 305, d_bits + 255, 5);
82 }
83
84 static void
85 process_frame()
86 {
87 unsigned c1_5eq, c6_11;
88
89 printf("Frame at 0x%x:\n", file_offset - 159);
90 printf(" C1-C5: %u%u%u%u%u", frame_bits[17], frame_bits[18],
91 frame_bits[19], frame_bits[20], frame_bits[21]);
92 c1_5eq = bits_to_num(frame_bits + 17, 4) << 1;
93 switch (c1_5eq) {
94 case 0x02:
95 fputs(" (FR UL)", stdout);
96 break;
97 case 0x1C:
98 fputs(" (FR DL)", stdout);
99 break;
100 case 0x1A:
101 fputs(" (EFR)", stdout);
102 break;
103 case 0x10:
104 fputs(" (idle UL)", stdout);
105 break;
106 case 0x0E:
107 fputs(" (idle DL)", stdout);
108 break;
109 }
110 putchar('\n');
111 c6_11 = bits_to_num(frame_bits + 22, 6);
112 printf(" C6-C11: %u\n", c6_11);
113 printf(" C12=%u C13=%u C14=%u C15=%u\n", frame_bits[28],
114 frame_bits[29], frame_bits[30], frame_bits[31]);
115 switch (c1_5eq) {
116 case 0x02:
117 case 0x1C:
118 collect_d_bits();
119 print_fr_frame(d_bits);
120 break;
121 case 0x1A:
122 collect_d_bits();
123 check_efr_crc(d_bits);
124 print_efr_frame(d_bits);
125 break;
126 }
127 printf(" C16=%u C17=%u C18=%u C19=%u C20=%u C21=%u\n",
128 frame_bits[310], frame_bits[311], frame_bits[312],
129 frame_bits[313], frame_bits[314], frame_bits[315]);
130 printf(" T1=%u T2=%u T3=%u T4=%u\n", frame_bits[316], frame_bits[317],
131 frame_bits[318], frame_bits[319]);
132 }
133
134 static int
135 check_sync_zeros()
136 {
137 int i;
138
139 for (i = 0; i < 16; i++) {
140 if (frame_bits[i])
141 return 0;
142 }
143 return 1;
144 }
145
146 static int
147 check_sync_ones_full()
148 {
149 int i;
150
151 for (i = 1; i < 20; i++) {
152 if (!frame_bits[i*16])
153 return 0;
154 }
155 return 1;
156 }
157
158 static int
159 check_sync_ones_partial()
160 {
161 int i;
162
163 for (i = 1; i < 20; i++) {
164 if ((i & 1) == 0)
165 continue;
166 if (!frame_bits[i*16])
167 return 0;
168 }
169 return 1;
170 }
171
172 static void
173 check_sync()
174 {
175 if (check_sync_zeros() && check_sync_ones_partial()) {
176 if (!check_sync_ones_full())
177 printf(" Sync pattern partially overwritten!\n");
178 return;
179 }
180 printf("Bad frame sync, returning to hunt state\n");
181 state = HUNT_FOR_0;
182 }
183
184 static void
185 byte_input(inb)
186 {
187 switch (state) {
188 case HUNT_FOR_0:
189 if (inb != 0)
190 return;
191 state = HUNT_FOUND_0;
192 hunt_for_0_count = 1;
193 return;
194 case HUNT_FOUND_0:
195 if (inb != 0) {
196 state = HUNT_FOR_0;
197 return;
198 }
199 hunt_for_0_count++;
200 if (hunt_for_0_count >= 8)
201 state = GOT_8_ZEROS;
202 return;
203 case GOT_8_ZEROS:
204 if (inb & 1) {
205 printf("Found frame sync at file offset 0x%x\n",
206 file_offset - 8);
207 bzero(in_frame_2bit, 8);
208 in_frame_2bit[8] = inb;
209 frame_pos_count = 9;
210 state = SYNCED;
211 return;
212 }
213 if (inb != 0)
214 state = HUNT_FOR_0;
215 return;
216 case SYNCED:
217 in_frame_2bit[frame_pos_count++] = inb;
218 if (frame_pos_count < 160)
219 return;
220 frame_pos_count = 0;
221 unpack_dibits();
222 process_frame();
223 check_sync();
224 return;
225 default:
226 fprintf(stderr, "BUG: bad sync state\n");
227 abort();
228 }
229 }
230
231 main(argc, argv)
232 char **argv;
233 {
234 FILE *inf;
235 int inb;
236
237 if (argc != 2) {
238 fprintf(stderr, "usage: %s binfile\n", argv[0]);
239 exit(1);
240 }
241 inf = fopen(argv[1], "r");
242 if (!inf) {
243 perror(argv[1]);
244 exit(1);
245 }
246 state = HUNT_FOR_0;
247 for (file_offset = 0; ; file_offset++) {
248 inb = getc(inf);
249 if (inb < 0)
250 break;
251 inb &= 3;
252 byte_input(inb);
253 }
254 exit(0);
255 }