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 }