blob: df83d3e4888f58f08bddd3f044144bed6a49fe20 [file] [log] [blame]
ptrkrysik8038b2e2014-12-15 23:10:48 +01001/*
2 The Hacker's Choice - http://www.thc.org
3 Part of THC's GSM SCANNER PROJECT
4*/
5
piotrfaacc722014-07-20 23:48:32 +02006//#include "system.h"
7#include <stdio.h>
8#include <stdlib.h>
9#include <unistd.h>
10#include <string.h>
11#include <ctype.h>
12
13//#include <exception>
14//#include <stdexcept>
15#include <math.h>
16//#include "burst_types.h"
17#include "cch.h"
18#include "fire_crc.h"
19
20
21/*
22 * GSM SACCH -- Slow Associated Control Channel
23 *
24 * These messages are encoded exactly the same as on the BCCH.
25 * (Broadcast Control Channel.)
26 *
27 * Input: 184 bits
28 *
29 * 1. Add parity and flushing bits. (Output 184 + 40 + 4 = 228 bit)
30 * 2. Convolutional encode. (Output 228 * 2 = 456 bit)
31 * 3. Interleave. (Output 456 bit)
32 * 4. Map on bursts. (4 x 156 bit bursts with each 2x57 bit content data)
33 */
34
35
36/*
37 * Parity (FIRE) for the GSM SACCH channel.
38 *
39 * g(x) = (x^23 + 1)(x^17 + x^3 + 1)
40 * = x^40 + x^26 + x^23 + x^17 + x^3 + 1
41 */
42
43static const unsigned char parity_polynomial[PARITY_SIZE + 1] = {
44 1, 0, 0, 0, 0, 0, 0, 0,
45 0, 0, 0, 0, 0, 0, 1, 0,
46 0, 1, 0, 0, 0, 0, 0, 1,
47 0, 0, 0, 0, 0, 0, 0, 0,
48 0, 0, 0, 0, 0, 1, 0, 0,
49 1
50};
51
52// remainder after dividing data polynomial by g(x)
53static const unsigned char parity_remainder[PARITY_SIZE] = {
54 1, 1, 1, 1, 1, 1, 1, 1,
55 1, 1, 1, 1, 1, 1, 1, 1,
56 1, 1, 1, 1, 1, 1, 1, 1,
57 1, 1, 1, 1, 1, 1, 1, 1,
58 1, 1, 1, 1, 1, 1, 1, 1
59};
60
61
62/*
63static void parity_encode(unsigned char *d, unsigned char *p) {
64
65 int i;
66 unsigned char buf[DATA_BLOCK_SIZE + PARITY_SIZE], *q;
67
68 memcpy(buf, d, DATA_BLOCK_SIZE);
69 memset(buf + DATA_BLOCK_SIZE, 0, PARITY_SIZE);
70
71 for(q = buf; q < buf + DATA_BLOCK_SIZE; q++)
72 if(*q)
73 for(i = 0; i < PARITY_SIZE + 1; i++)
74 q[i] ^= parity_polynomial[i];
75 for(i = 0; i < PARITY_SIZE; i++)
76 p[i] = !buf[DATA_BLOCK_SIZE + i];
77}
78 */
79
80
81int parity_check(unsigned char *d) {
82
83 unsigned int i;
84 unsigned char buf[DATA_BLOCK_SIZE + PARITY_SIZE], *q;
85
86 memcpy(buf, d, DATA_BLOCK_SIZE + PARITY_SIZE);
87
88 for(q = buf; q < buf + DATA_BLOCK_SIZE; q++)
89 if(*q)
90 for(i = 0; i < PARITY_SIZE + 1; i++)
91 q[i] ^= parity_polynomial[i];
92 return memcmp(buf + DATA_BLOCK_SIZE, parity_remainder, PARITY_SIZE);
93}
94
95
96/*
97 * Convolutional encoding and Viterbi decoding for the GSM SACCH channel.
98 */
99
100/*
101 * Convolutional encoding:
102 *
103 * G_0 = 1 + x^3 + x^4
104 * G_1 = 1 + x + x^3 + x^4
105 *
106 * i.e.,
107 *
108 * c_{2k} = u_k + u_{k - 3} + u_{k - 4}
109 * c_{2k + 1} = u_k + u_{k - 1} + u_{k - 3} + u_{k - 4}
110 */
111#define K 5
112#define MAX_ERROR (2 * CONV_INPUT_SIZE + 1)
113
114
115/*
116 * Given the current state and input bit, what are the output bits?
117 *
118 * encode[current_state][input_bit]
119 */
120static const unsigned int encode[1 << (K - 1)][2] = {
121 {0, 3}, {3, 0}, {3, 0}, {0, 3},
122 {0, 3}, {3, 0}, {3, 0}, {0, 3},
123 {1, 2}, {2, 1}, {2, 1}, {1, 2},
124 {1, 2}, {2, 1}, {2, 1}, {1, 2}
125};
126
127
128/*
129 * Given the current state and input bit, what is the next state?
130 *
131 * next_state[current_state][input_bit]
132 */
133static const unsigned int next_state[1 << (K - 1)][2] = {
134 {0, 8}, {0, 8}, {1, 9}, {1, 9},
135 {2, 10}, {2, 10}, {3, 11}, {3, 11},
136 {4, 12}, {4, 12}, {5, 13}, {5, 13},
137 {6, 14}, {6, 14}, {7, 15}, {7, 15}
138};
139
140
141/*
142 * Given the previous state and the current state, what input bit caused
143 * the transition? If it is impossible to transition between the two
144 * states, the value is 2.
145 *
146 * prev_next_state[previous_state][current_state]
147 */
148static const unsigned int prev_next_state[1 << (K - 1)][1 << (K - 1)] = {
149 { 0, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2},
150 { 0, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2},
151 { 2, 0, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2},
152 { 2, 0, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2},
153 { 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2},
154 { 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2},
155 { 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2},
156 { 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2},
157 { 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2},
158 { 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2},
159 { 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2},
160 { 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2},
161 { 2, 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 1, 2},
162 { 2, 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 1, 2},
163 { 2, 2, 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 1},
164 { 2, 2, 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 1}
165};
166
167
168static inline unsigned int hamming_distance2(unsigned int w) {
169
170 return (w & 1) + !!(w & 2);
171}
172
173
174/*
175static void conv_encode(unsigned char *data, unsigned char *output) {
176
177 unsigned int i, state = 0, o;
178
179 // encode data
180 for(i = 0; i < CONV_INPUT_SIZE; i++) {
181 o = encode[state][data[i]];
182 state = next_state[state][data[i]];
183 *output++ = !!(o & 2);
184 *output++ = o & 1;
185 }
186}
187 */
188
189
190int conv_decode(unsigned char *output, unsigned char *data) {
191
192 int i, t;
193 unsigned int rdata, state, nstate, b, o, distance, accumulated_error,
194 min_state, min_error, cur_state;
195
196 unsigned int ae[1 << (K - 1)]; // accumulated error
197 unsigned int nae[1 << (K - 1)]; // next accumulated error
198 unsigned int state_history[1 << (K - 1)][CONV_INPUT_SIZE + 1];
199
200 // initialize accumulated error, assume starting state is 0
201 for(i = 0; i < (1 << (K - 1)); i++){
202 ae[i] = nae[i] = MAX_ERROR;
203 }
204
205 ae[0] = 0;
206
207 // build trellis
208 for(t = 0; t < CONV_INPUT_SIZE; t++) {
209
210 // get received data symbol
211 rdata = (data[2 * t] << 1) | data[2 * t + 1];
212
213 // for each state
214 for(state = 0; state < (1 << (K - 1)); state++) {
215
216 // make sure this state is possible
217 if(ae[state] >= MAX_ERROR)
218 continue;
219
220 // find all states we lead to
221 for(b = 0; b < 2; b++) {
222
223 // get next state given input bit b
224 nstate = next_state[state][b];
225
226 // find output for this transition
227 o = encode[state][b];
228
229 // calculate distance from received data
230 distance = hamming_distance2(rdata ^ o);
231
232 // choose surviving path
233 accumulated_error = ae[state] + distance;
234 if(accumulated_error < nae[nstate]) {
235
236 // save error for surviving state
237 nae[nstate] = accumulated_error;
238
239 // update state history
240 state_history[nstate][t + 1] = state;
241 }
242 }
243 }
244
245 // get accumulated error ready for next time slice
246 for(i = 0; i < (1 << (K - 1)); i++) {
247 ae[i] = nae[i];
248 nae[i] = MAX_ERROR;
249 }
250 }
251
252 // the final state is the state with the fewest errors
253 min_state = (unsigned int)-1;
254 min_error = MAX_ERROR;
255 for(i = 0; i < (1 << (K - 1)); i++) {
256 if(ae[i] < min_error) {
257 min_state = i;
258 min_error = ae[i];
259 }
260 }
261
262 // trace the path
263 cur_state = min_state;
264 for(t = CONV_INPUT_SIZE; t >= 1; t--) {
265 min_state = cur_state;
266 cur_state = state_history[cur_state][t]; // get previous
267 output[t - 1] = prev_next_state[cur_state][min_state];
268 }
269
270 // return the number of errors detected (hard-decision)
271 return min_error;
272}
273
274
275/*
276 * GSM SACCH interleaving and burst mapping
277 *
278 * Interleaving:
279 *
280 * Given 456 coded input bits, form 4 blocks of 114 bits:
281 *
282 * i(B, j) = c(n, k) k = 0, ..., 455
283 * n = 0, ..., N, N + 1, ...
284 * B = B_0 + 4n + (k mod 4)
285 * j = 2(49k mod 57) + ((k mod 8) div 4)
286 *
287 * Mapping on Burst:
288 *
289 * e(B, j) = i(B, j)
290 * e(B, 59 + j) = i(B, 57 + j) j = 0, ..., 56
291 * e(B, 57) = h_l(B)
292 * e(B, 58) = h_n(B)
293 *
294 * Where h_l(B) and h_n(B) are bits in burst B indicating flags.
295 */
296
297/*
298static void interleave(unsigned char *data, unsigned char *iBLOCK) {
299
300 int j, k, B;
301
302 // for each bit in input data
303 for(k = 0; k < CONV_SIZE; k++) {
304 B = k % 4;
305 j = 2 * ((49 * k) % 57) + ((k % 8) / 4);
306 iBLOCK[B * iBLOCK_SIZE + j] = data[k];
307 }
308}
309 */
310
311
312#if 0
313static void decode_interleave(unsigned char *data, unsigned char *iBLOCK) {
314
315 int j, k, B;
316
317 for(k = 0; k < CONV_SIZE; k++) {
318 B = k % 4;
319 j = 2 * ((49 * k) % 57) + ((k % 8) / 4);
320 data[k] = iBLOCK[B * iBLOCK_SIZE + j];
321 }
322}
323
324#endif
325
326/*
327static void burstmap(unsigned char *iBLOCK, unsigned char *eBLOCK,
328 unsigned char hl, unsigned char hn) {
329
330 int j;
331
332 for(j = 0; j < 57; j++) {
333 eBLOCK[j] = iBLOCK[j];
334 eBLOCK[j + 59] = iBLOCK[j + 57];
335 }
336 eBLOCK[57] = hl;
337 eBLOCK[58] = hn;
338}
339 */
340
341
342static void decode_burstmap(unsigned char *iBLOCK, unsigned char *eBLOCK,
343 unsigned char *hl, unsigned char *hn) {
344
345 int j;
346
347 for(j = 0; j < 57; j++) {
348 iBLOCK[j] = eBLOCK[j];
349 iBLOCK[j + 57] = eBLOCK[j + 59];
350 }
351 *hl = eBLOCK[57];
352 *hn = eBLOCK[58];
353}
354
355
356/*
357 * Transmitted bits are sent least-significant first.
358 */
359static int compress_bits(unsigned char *dbuf, unsigned int dbuf_len,
360 unsigned char *sbuf, unsigned int sbuf_len) {
361
362 unsigned int i, j, c, pos = 0;
363
364 if(dbuf_len < ((sbuf_len + 7) >> 3))
365 return -1;
366
367 for(i = 0; i < sbuf_len; i += 8) {
368 for(j = 0, c = 0; (j < 8) && (i + j < sbuf_len); j++)
369 c |= (!!sbuf[i + j]) << j;
370 dbuf[pos++] = c & 0xff;
371 }
372 return pos;
373}
374
375
376#if 0
377int get_ns_l3_len(unsigned char *data, unsigned int datalen) {
378
379 if((data[0] & 3) != 1) {
380 fprintf(stderr, "error: get_ns_l3_len: pseudo-length reserved "
381 "bits bad (%2.2x)\n", data[0] & 3);
382 return -1;
383 }
384 return (data[0] >> 2);
385}
386
387#endif
388
389
390/*static unsigned char *decode_sacch(GS_CTX *ctx, unsigned char *burst, unsigned int *datalen) {*/
391
392/* int errors, len, data_size;*/
393/* unsigned char conv_data[CONV_SIZE], iBLOCK[BLOCKS][iBLOCK_SIZE],*/
394/* hl, hn, decoded_data[PARITY_OUTPUT_SIZE];*/
395/* FC_CTX fc_ctx;*/
396
397/* data_size = sizeof ctx->msg;*/
398/* if(datalen)*/
399/* *datalen = 0;*/
400
401/* // unmap the bursts*/
402/* decode_burstmap(iBLOCK[0], burst, &hl, &hn); // XXX ignore stealing bits*/
403/* decode_burstmap(iBLOCK[1], burst + 116, &hl, &hn);*/
404/* decode_burstmap(iBLOCK[2], burst + 116 * 2, &hl, &hn);*/
405/* decode_burstmap(iBLOCK[3], burst + 116 * 3, &hl, &hn);*/
406
407/* // remove interleave*/
408/* interleave_decode(&ctx->interleave_ctx, conv_data, (unsigned char *)iBLOCK);*/
409/* //decode_interleave(conv_data, (unsigned char *)iBLOCK);*/
410
411/* // Viterbi decode*/
412/* errors = conv_decode(decoded_data, conv_data);*/
413/* //DEBUGF("conv_decode: %d\n", errors);*/
414
415/* // check parity*/
416/* // If parity check error detected try to fix it.*/
417/* if (parity_check(decoded_data))*/
418/* {*/
419/* unsigned char crc_result[224];*/
420/* if (FC_check_crc(&fc_ctx, decoded_data, crc_result) == 0)*/
421/* {*/
422/* errors = -1;*/
423/* //DEBUGF("error: sacch: parity error (%d fn=%d)\n",*/
424/* // errors, ctx->fn);*/
425/* return NULL;*/
426/* } else {*/
427/* //DEBUGF("Successfully corrected parity bits! (errors=%d fn=%d)\n",*/
428/* // errors, ctx->fn);*/
429/* memcpy(decoded_data, crc_result, sizeof crc_result);*/
430/* errors = 0;*/
431/* }*/
432/* }*/
433
434/* if (errors)*/
435/* printf("WRN: errors=%d fn=%d\n", errors, ctx->fn);*/
436
437/* if((len = compress_bits(ctx->msg, data_size, decoded_data,*/
438/* DATA_BLOCK_SIZE)) < 0) {*/
439/* fprintf(stderr, "error: compress_bits\n");*/
440/* return NULL;*/
441/* }*/
442/* if(len < data_size) {*/
443/* fprintf(stderr, "error: buf too small (%d < %d)\n",*/
444/* sizeof(ctx->msg), len);*/
445/* return NULL;*/
446/* }*/
447
448/* if(datalen)*/
449/* *datalen = (unsigned int)len;*/
450/* return ctx->msg;*/
451/*}*/
452
453
454/*
455 * decode_cch
456 *
457 * Decode a "common" control channel. Most control channels use
458 * the same burst, interleave, Viterbi and parity configuration.
459 * The documentation for the control channels defines SACCH first
460 * and then just keeps referring to that.
461 *
462 * The current (investigated) list is as follows:
463 *
464 * BCCH Norm
465 * BCCH Ext
466 * PCH
467 * AGCH
468 * CBCH (SDCCH/4)
469 * CBCH (SDCCH/8)
470 * SDCCH/4
471 * SACCH/C4
472 * SDCCH/8
473 * SACCH/C8
474 *
475 * We provide two functions, one for where all four bursts are
476 * contiguous, and one where they aren't.
477 */
478/*unsigned char *decode_cch(GS_CTX *ctx, unsigned char *burst, unsigned int *datalen) {*/
479
480/* return decode_sacch(ctx, burst, datalen);*/
481/*}*/
482
483
484#if 0
485unsigned char *decode_cch(GS_CTX *ctx, unsigned char *e, unsigned int *datalen) {
486
487 return decode_sacch(ctx, e, e + eBLOCK_SIZE, e + 2 * eBLOCK_SIZE,
488 e + 3 * eBLOCK_SIZE, datalen);
489}
490#endif
491
492/*unsigned char *decode_facch(GS_CTX *ctx, unsigned char *burst, unsigned int *datalen, int offset) {*/
493
494/* int errors, len, data_size;*/
495/* unsigned char conv_data[CONV_SIZE], iBLOCK[BLOCKS * 2][iBLOCK_SIZE],*/
496/* hl, hn, decoded_data[PARITY_OUTPUT_SIZE];*/
497/* FC_CTX fc_ctx;*/
498
499/* data_size = sizeof ctx->msg;*/
500/* if(datalen)*/
501/* *datalen = 0;*/
502
503/* // unmap the bursts*/
504/* decode_burstmap(iBLOCK[0], burst, &hl, &hn); // XXX ignore stealing bits*/
505/* decode_burstmap(iBLOCK[1], burst + 116, &hl, &hn);*/
506/* decode_burstmap(iBLOCK[2], burst + 116 * 2, &hl, &hn);*/
507/* decode_burstmap(iBLOCK[3], burst + 116 * 3, &hl, &hn);*/
508/* decode_burstmap(iBLOCK[4], burst + 116 * 4, &hl, &hn);*/
509/* decode_burstmap(iBLOCK[5], burst + 116 * 5, &hl, &hn);*/
510/* decode_burstmap(iBLOCK[6], burst + 116 * 6, &hl, &hn);*/
511/* decode_burstmap(iBLOCK[7], burst + 116 * 7, &hl, &hn);*/
512
513/* // remove interleave*/
514/* if (offset == 0)*/
515/* interleave_decode(&ctx->interleave_facch_f1_ctx, conv_data, (unsigned char *)iBLOCK);*/
516/* else*/
517/* interleave_decode(&ctx->interleave_facch_f2_ctx, conv_data, (unsigned char *)iBLOCK);*/
518/* //decode_interleave(conv_data, (unsigned char *)iBLOCK);*/
519
520/* // Viterbi decode*/
521/* errors = conv_decode(decoded_data, conv_data);*/
522/* //DEBUGF("conv_decode: %d\n", errors);*/
523
524/* // check parity*/
525/* // If parity check error detected try to fix it.*/
526/* if (parity_check(decoded_data)) {*/
527/* FC_init(&fc_ctx, 40, 184);*/
528/* unsigned char crc_result[224];*/
529/* if (FC_check_crc(&fc_ctx, decoded_data, crc_result) == 0)*/
530/* {*/
531/* //DEBUGF("error: sacch: parity error (errors=%d fn=%d)\n", errors, ctx->fn);*/
532/* errors = -1;*/
533/* return NULL;*/
534/* } else {*/
535/* //DEBUGF("Successfully corrected parity bits! (errors=%d fn=%d)\n", errors, ctx->fn);*/
536/* memcpy(decoded_data, crc_result, sizeof crc_result);*/
537/* errors = 0;*/
538/* }*/
539/* }*/
540
541/* if (errors)*/
542/* fprintf(stderr, "WRN: errors=%d fn=%d\n", errors, ctx->fn);*/
543
544/* if ((len = compress_bits(ctx->msg, data_size, decoded_data,*/
545/* DATA_BLOCK_SIZE)) < 0) {*/
546/* fprintf(stderr, "error: compress_bits\n");*/
547/* return NULL;*/
548/* }*/
549/* if (len < data_size) {*/
550/* fprintf(stderr, "error: buf too small (%d < %d)\n",*/
551/* sizeof(ctx->msg), len);*/
552/* return NULL;*/
553/* }*/
554
555/* if (datalen)*/
556/* *datalen = (unsigned int)len;*/
557/* return ctx->msg;*/
558/*}*/