comparison trau-decode/trau-hr-dump.c @ 28:9bcdb091c24d

trau-decode: new program trau-hr-dump
author Mychaela Falconia <falcon@freecalypso.org>
date Sun, 18 Aug 2024 08:37:02 +0000
parents trau-decode/trau-sync8.c@f508dacf2cf9
children 61181373875d
comparison
equal deleted inserted replaced
27:f508dacf2cf9 28:9bcdb091c24d
1 /*
2 * This program reads a 64 kbit/s timeslot recording file, examines one
3 * of the eight 8 kbit/s subslots (selected), looks for the sync pattern of
4 * GSM 08.61, decodes each frame as HRv1 speech and dumps everything it
5 * decodes.
6 */
7
8 #include <sys/types.h>
9 #include <sys/file.h>
10 #include <sys/stat.h>
11 #include <stdio.h>
12 #include <stdint.h>
13 #include <stdlib.h>
14 #include <string.h>
15 #include <strings.h>
16 #include <unistd.h>
17 #include "gsmhr_unpack.h"
18 #include "osmo_bits.h"
19
20 /*
21 * EFR TRAU parity (also used for HR)
22 *
23 * g(x) = x^3 + x^1 + 1
24 */
25 static const struct osmo_crc8gen_code gsm0860_efr_crc3 = {
26 .bits = 3,
27 .poly = 0x3,
28 .init = 0x0,
29 .remainder = 0x7,
30 };
31
32 static uint8_t *filebuf;
33 static unsigned total_size;
34
35 static void
36 read_ts_file(filename, subslot_arg)
37 char *filename, *subslot_arg;
38 {
39 FILE *inf;
40 struct stat st;
41 int subslot, right_shift;
42 unsigned n;
43 uint8_t *dp;
44 int b;
45
46 inf = fopen(filename, "r");
47 if (!inf) {
48 perror(filename);
49 exit(1);
50 }
51 fstat(fileno(inf), &st);
52 if (!S_ISREG(st.st_mode)) {
53 fprintf(stderr, "error: %s is not a regular file\n", filename);
54 exit(1);
55 }
56 total_size = st.st_size;
57 if (total_size < 160) {
58 fprintf(stderr, "error: %s is too short\n", filename);
59 exit(1);
60 }
61 filebuf = malloc(total_size);
62 if (!filebuf) {
63 perror("malloc of file size");
64 exit(1);
65 }
66 subslot = atoi(subslot_arg);
67 if (subslot < 0 || subslot > 7) {
68 fprintf(stderr, "error: invalid subslot argument\n");
69 exit(1);
70 }
71 right_shift = 7 - subslot;
72 dp = filebuf;
73 for (n = 0; n < total_size; n++) {
74 b = getc(inf);
75 if (b < 0) {
76 fprintf(stderr,
77 "error: getc() returned EOF contrary to st_size\n");
78 exit(1);
79 }
80 *dp++ = (b >> right_shift) & 1;
81 }
82 fclose(inf);
83 }
84
85 static int
86 check_sync(pos)
87 unsigned pos;
88 {
89 uint8_t *cand = filebuf + pos;
90 unsigned n;
91
92 for (n = 0; n < 8; n++) {
93 if (cand[n])
94 return 0;
95 }
96 if (!cand[8])
97 return 0;
98 if (cand[16])
99 return 0;
100 if (!cand[17])
101 return 0;
102 for (n = 3; n < 20; n++) {
103 if (!cand[n * 8])
104 return 0;
105 }
106 return 1;
107 }
108
109 static int
110 bit_parity(bits, nbits)
111 ubit_t *bits;
112 unsigned nbits;
113 {
114 unsigned n, sum;
115
116 sum = 0;
117 for (n = 0; n < nbits; n++)
118 sum += bits[n];
119 return sum & 1;
120 }
121
122 static void
123 bits2bytes(bits, bytes, nbytes)
124 ubit_t *bits;
125 uint8_t *bytes;
126 unsigned nbytes;
127 {
128 unsigned n, m, acc;
129
130 for (n = 0; n < nbytes; n++) {
131 acc = 0;
132 for (m = 0; m < 8; m++) {
133 acc <<= 1;
134 acc |= *bits++;
135 }
136 *bytes++ = acc;
137 }
138 }
139
140 static void
141 process_frame(pos)
142 unsigned pos;
143 {
144 ubit_t *frame = filebuf + pos;
145 ubit_t xc_bits[6], dbits[112];
146 uint8_t hr_bytes[14];
147 int16_t params[18];
148 int crc_stat;
149
150 printf("Frame at 0x%x:\n", pos);
151 printf(" C1-C4: %u%u%u%u OP %s\n", frame[9], frame[10], frame[11],
152 frame[12], bit_parity(frame + 9, 5) ? "good" : "bad");
153 bcopy(frame + 14, xc_bits, 2);
154 bcopy(frame + 18, xc_bits + 2, 4);
155 printf(" XC1-XC5: %u%u%u%u%u OP %s\n", xc_bits[0], xc_bits[1],
156 xc_bits[2], xc_bits[3], xc_bits[4],
157 bit_parity(xc_bits, 6) ? "good" : "bad");
158 bcopy(frame + 22, dbits, 2);
159 bcopy(frame + 25, dbits + 2, 7);
160 bcopy(frame + 33, dbits + 9, 7);
161 bcopy(frame + 41, dbits + 16, 7);
162 bcopy(frame + 49, dbits + 23, 7);
163 bcopy(frame + 57, dbits + 30, 7);
164 bcopy(frame + 65, dbits + 37, 7);
165 bcopy(frame + 76, dbits + 44, 4);
166 bcopy(frame + 81, dbits + 48, 7);
167 bcopy(frame + 89, dbits + 55, 7);
168 bcopy(frame + 97, dbits + 62, 7);
169 bcopy(frame + 105, dbits + 69, 7);
170 bcopy(frame + 113, dbits + 76, 7);
171 bcopy(frame + 121, dbits + 83, 7);
172 bcopy(frame + 129, dbits + 90, 7);
173 bcopy(frame + 137, dbits + 97, 7);
174 bcopy(frame + 145, dbits + 104, 7);
175 dbits[111] = frame[153];
176 crc_stat = osmo_crc8gen_check_bits(&gsm0860_efr_crc3, dbits, 44,
177 frame + 73);
178 printf(" CRC %s\n", crc_stat ? "bad" : "good");
179 bits2bytes(dbits, hr_bytes, 14);
180 gsmhr_unpack_ts101318(hr_bytes, params);
181 printf(" R0=%02x LPC=%03x,%03x,%02x Int=%x Mode=%x\n", params[0],
182 params[1], params[2], params[3], params[4], params[5]);
183 printf(params[5] ? " s1=%02x,%03x,%02x" : " s1=%02x,%02x,%02x",
184 params[6], params[7], params[8]);
185 printf(params[5] ? " s2=%x,%03x,%02x" : " s2=%02x,%02x,%02x",
186 params[9], params[10], params[11]);
187 printf(params[5] ? " s3=%x,%03x,%02x" : " s3=%02x,%02x,%02x",
188 params[12], params[13], params[14]);
189 printf(params[5] ? " s4=%x,%03x,%02x\n" : " s4=%02x,%02x,%02x\n",
190 params[15], params[16], params[17]);
191 printf(" C6-C9: %u%u%u%u\n", frame[154], frame[155], frame[156],
192 frame[157]);
193 printf(" T1=%u T2=%u\n", frame[158], frame[159]);
194 }
195
196 static void
197 process_filebuf()
198 {
199 unsigned p, endp;
200 int sync = 0, match;
201
202 endp = total_size - 160;
203 for (p = 0; p < endp; ) {
204 match = check_sync(p);
205 if (match != sync) {
206 printf("# %s frame sync at file offset 0x%x\n",
207 match ? "Acquired" : "Lost", p);
208 }
209 if (match) {
210 process_frame(p);
211 if (!filebuf[p+158] && !filebuf[p+159]) {
212 printf(
213 "# both T bits equal 0, shifting frame alignment\n");
214 p += 158;
215 } else
216 p += 160;
217 } else
218 p++;
219 sync = match;
220 }
221 }
222
223 main(argc, argv)
224 char **argv;
225 {
226 if (argc != 3) {
227 fprintf(stderr, "usage: %s binfile subslot\n", argv[0]);
228 exit(1);
229 }
230 read_ts_file(argv[1], argv[2]);
231 process_filebuf();
232 exit(0);
233 }