comparison trau-decode/parse-main.c @ 2:b2ef2c80fef1

trau-parse: add FR decoding
author Mychaela Falconia <falcon@freecalypso.org>
date Fri, 24 May 2024 08:11:25 +0000
parents trau-parse.c@b0dcd48a1c8a
children d9c095357c32
comparison
equal deleted inserted replaced
1:b0dcd48a1c8a 2:b2ef2c80fef1
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], d_bits[260];
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 collect_d_bits()
64 {
65 bcopy(frame_bits + 33, d_bits, 15);
66 bcopy(frame_bits + 49, d_bits + 15, 15);
67 bcopy(frame_bits + 65, d_bits + 30, 15);
68 bcopy(frame_bits + 81, d_bits + 45, 15);
69 bcopy(frame_bits + 97, d_bits + 60, 15);
70 bcopy(frame_bits + 113, d_bits + 75, 15);
71 bcopy(frame_bits + 129, d_bits + 90, 15);
72 bcopy(frame_bits + 145, d_bits + 105, 15);
73 bcopy(frame_bits + 161, d_bits + 120, 15);
74 bcopy(frame_bits + 177, d_bits + 135, 15);
75 bcopy(frame_bits + 193, d_bits + 150, 15);
76 bcopy(frame_bits + 209, d_bits + 165, 15);
77 bcopy(frame_bits + 225, d_bits + 180, 15);
78 bcopy(frame_bits + 241, d_bits + 195, 15);
79 bcopy(frame_bits + 257, d_bits + 210, 15);
80 bcopy(frame_bits + 273, d_bits + 225, 15);
81 bcopy(frame_bits + 289, d_bits + 240, 15);
82 bcopy(frame_bits + 305, d_bits + 255, 5);
83 }
84
85 static void
86 process_frame()
87 {
88 unsigned c1_5, c6_11;
89
90 printf("Frame at 0x%x:\n", file_offset - 160);
91 printf(" C1-C5: %u%u%u%u%u", frame_bits[17], frame_bits[18],
92 frame_bits[19], frame_bits[20], frame_bits[21]);
93 c1_5 = bits_to_num(frame_bits + 17, 5);
94 switch (c1_5) {
95 case 0x02:
96 fputs(" (FR UL)", stdout);
97 break;
98 case 0x1C:
99 fputs(" (FR DL)", stdout);
100 break;
101 case 0x1A:
102 fputs(" (EFR)", stdout);
103 break;
104 case 0x10:
105 fputs(" (idle UL)", stdout);
106 break;
107 case 0x0E:
108 fputs(" (idle DL)", stdout);
109 break;
110 }
111 putchar('\n');
112 c6_11 = bits_to_num(frame_bits + 22, 6);
113 printf(" C6-C11: %u\n", c6_11);
114 printf(" C12=%u C13=%u C14=%u C15=%u\n", frame_bits[28],
115 frame_bits[29], frame_bits[30], frame_bits[31]);
116 switch (c1_5) {
117 case 0x02:
118 case 0x1C:
119 collect_d_bits();
120 print_fr_frame(d_bits);
121 break;
122 }
123 printf(" C16=%u C17=%u C18=%u C19=%u C20=%u C21=%u\n",
124 frame_bits[310], frame_bits[311], frame_bits[312],
125 frame_bits[313], frame_bits[314], frame_bits[315]);
126 printf(" T1=%u T2=%u T3=%u T4=%u\n", frame_bits[316], frame_bits[317],
127 frame_bits[318], frame_bits[319]);
128 }
129
130 static int
131 check_sync_zeros()
132 {
133 int i;
134
135 for (i = 0; i < 16; i++) {
136 if (frame_bits[i])
137 return 0;
138 }
139 return 1;
140 }
141
142 static int
143 check_sync_ones()
144 {
145 int i;
146
147 for (i = 1; i < 20; i++) {
148 if (!frame_bits[i*16])
149 return 0;
150 }
151 return 1;
152 }
153
154 static void
155 check_sync()
156 {
157 if (check_sync_zeros() && check_sync_ones())
158 return;
159 printf("Bad frame sync, returning to hunt state\n");
160 state = HUNT_FOR_0;
161 }
162
163 static void
164 byte_input(inb)
165 {
166 switch (state) {
167 case HUNT_FOR_0:
168 if (inb != 0)
169 return;
170 state = HUNT_FOUND_0;
171 hunt_for_0_count = 1;
172 return;
173 case HUNT_FOUND_0:
174 if (inb != 0) {
175 state = HUNT_FOR_0;
176 return;
177 }
178 hunt_for_0_count++;
179 if (hunt_for_0_count >= 8)
180 state = GOT_8_ZEROS;
181 return;
182 case GOT_8_ZEROS:
183 if (inb & 2) {
184 printf("Found frame sync at file offset 0x%x\n",
185 file_offset - 8);
186 bzero(in_frame_2bit, 8);
187 in_frame_2bit[8] = inb;
188 frame_pos_count = 9;
189 state = SYNCED;
190 return;
191 }
192 if (inb != 0)
193 state = HUNT_FOR_0;
194 return;
195 case SYNCED:
196 in_frame_2bit[frame_pos_count++] = inb;
197 if (frame_pos_count < 160)
198 return;
199 frame_pos_count = 0;
200 unpack_dibits();
201 process_frame();
202 check_sync();
203 return;
204 default:
205 fprintf(stderr, "BUG: bad sync state\n");
206 abort();
207 }
208 }
209
210 main(argc, argv)
211 char **argv;
212 {
213 FILE *inf;
214 int subslot, right_shift;
215 int inb;
216
217 if (argc != 3) {
218 fprintf(stderr, "usage: %s binfile subslot\n", argv[0]);
219 exit(1);
220 }
221 inf = fopen(argv[1], "r");
222 if (!inf) {
223 perror(argv[1]);
224 exit(1);
225 }
226 subslot = atoi(argv[2]);
227 if (subslot < 0 || subslot > 3) {
228 fprintf(stderr, "error: invalid subslot argument\n");
229 exit(1);
230 }
231 right_shift = (3 - subslot) * 2;
232 state = HUNT_FOR_0;
233 for (file_offset = 0; ; file_offset++) {
234 inb = getc(inf);
235 if (inb < 0)
236 break;
237 inb >>= right_shift;
238 inb &= 3;
239 byte_input(inb);
240 }
241 exit(0);
242 }