blob: 6f141dd42445905906c1cbe5f084217ef70d888a [file] [log] [blame]
piotr437f5462014-02-04 17:57:25 +01001#include "system.h"
2#include <stdio.h>
3#include <stdlib.h>
4#include <unistd.h>
5#include <string.h>
6#include "gsm_constants.h"
7
8/*
9 * Synchronization channel.
10 *
11 * Timeslot Repeat length Frame Number (mod repeat length)
12 * 0 51 1, 11, 21, 31, 41
13 */
14
15/*
16 * Parity (FIRE) for the GSM SCH.
17 *
18 * g(x) = x^10 + x^8 + x^6 + x^5 + x^4 + x^2 + 1
19 */
20#define DATA_BLOCK_SIZE 25
21#define PARITY_SIZE 10
22#define TAIL_BITS_SIZE 4
23#define PARITY_OUTPUT_SIZE (DATA_BLOCK_SIZE + PARITY_SIZE + TAIL_BITS_SIZE)
24
25static const unsigned char parity_polynomial[PARITY_SIZE + 1] = {
26 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1
27};
28
29static const unsigned char parity_remainder[PARITY_SIZE] = {
30 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
31};
32
33
34static void parity_encode(unsigned char *d, unsigned char *p)
35{
36
37 unsigned int i;
38 unsigned char buf[DATA_BLOCK_SIZE + PARITY_SIZE], *q;
39
40 memcpy(buf, d, DATA_BLOCK_SIZE);
41 memset(buf + DATA_BLOCK_SIZE, 0, PARITY_SIZE);
42
43 for (q = buf; q < buf + DATA_BLOCK_SIZE; q++)
44 if (*q)
45 for (i = 0; i < PARITY_SIZE + 1; i++)
46 q[i] ^= parity_polynomial[i];
47 for (i = 0; i < PARITY_SIZE; i++)
48 p[i] = !buf[DATA_BLOCK_SIZE + i];
49}
50
51
52static int parity_check(unsigned char *d)
53{
54
55 unsigned int i;
56 unsigned char buf[DATA_BLOCK_SIZE + PARITY_SIZE], *q;
57
58 memcpy(buf, d, DATA_BLOCK_SIZE + PARITY_SIZE);
59
60 for (q = buf; q < buf + DATA_BLOCK_SIZE; q++)
61 if (*q)
62 for (i = 0; i < PARITY_SIZE + 1; i++)
63 q[i] ^= parity_polynomial[i];
64 return memcmp(buf + DATA_BLOCK_SIZE, parity_remainder, PARITY_SIZE);
65}
66
67
68/*
69 * Convolutional encoding and Viterbi decoding for the GSM SCH.
70 * (Equivalent to the GSM SACCH.)
71 *
72 * G_0 = 1 + x^3 + x^4
73 * G_1 = 1 + x + x^3 + x^4
74 *
75 * i.e.,
76 *
77 * c_{2k} = u_k + u_{k - 3} + u_{k - 4}
78 * c_{2k + 1} = u_k + u_{k - 1} + u_{k - 3} + u_{k - 4}
79 */
80#define CONV_INPUT_SIZE PARITY_OUTPUT_SIZE
81#define CONV_SIZE (2 * CONV_INPUT_SIZE)
82#define K 5
83#define MAX_ERROR (2 * CONV_INPUT_SIZE + 1)
84
85
86/*
87 * Given the current state and input bit, what are the output bits?
88 *
89 * encode[current_state][input_bit]
90 */
91static const unsigned int encode[1 << (K - 1)][2] = {
92 {0, 3}, {3, 0}, {3, 0}, {0, 3},
93 {0, 3}, {3, 0}, {3, 0}, {0, 3},
94 {1, 2}, {2, 1}, {2, 1}, {1, 2},
95 {1, 2}, {2, 1}, {2, 1}, {1, 2}
96};
97
98
99/*
100 * Given the current state and input bit, what is the next state?
101 *
102 * next_state[current_state][input_bit]
103 */
104static const unsigned int next_state[1 << (K - 1)][2] = {
105 {0, 8}, {0, 8}, {1, 9}, {1, 9},
106 {2, 10}, {2, 10}, {3, 11}, {3, 11},
107 {4, 12}, {4, 12}, {5, 13}, {5, 13},
108 {6, 14}, {6, 14}, {7, 15}, {7, 15}
109};
110
111
112/*
113 * Given the previous state and the current state, what input bit caused
114 * the transition? If it is impossible to transition between the two
115 * states, the value is 2.
116 *
117 * prev_next_state[previous_state][current_state]
118 */
119static const unsigned int prev_next_state[1 << (K - 1)][1 << (K - 1)] = {
120 { 0, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2},
121 { 0, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2},
122 { 2, 0, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2},
123 { 2, 0, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2},
124 { 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2},
125 { 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2},
126 { 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2},
127 { 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2},
128 { 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2},
129 { 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2},
130 { 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2},
131 { 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2},
132 { 2, 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 1, 2},
133 { 2, 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 1, 2},
134 { 2, 2, 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 1},
135 { 2, 2, 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 1}
136};
137
138
139static inline unsigned int hamming_distance2(unsigned int w)
140{
141
142 return (w & 1) + !!(w & 2);
143}
144
145
146static void conv_encode(unsigned char *data, unsigned char *output)
147{
148
149 unsigned int i, state = 0, o;
150
151 // encode data
152 for (i = 0; i < CONV_INPUT_SIZE; i++) {
153 o = encode[state][data[i]];
154 state = next_state[state][data[i]];
155 *output++ = !!(o & 2);
156 *output++ = o & 1;
157 }
158}
159
160
161static int conv_decode(unsigned char *data, unsigned char *output)
162{
163
164 int i, t;
165 unsigned int rdata, state, nstate, b, o, distance, accumulated_error,
166 min_state, min_error, cur_state;
167
168 unsigned int ae[1 << (K - 1)];
169 unsigned int nae[1 << (K - 1)]; // next accumulated error
170 unsigned int state_history[1 << (K - 1)][CONV_INPUT_SIZE + 1];
171
172 // initialize accumulated error, assume starting state is 0
173 for (i = 0; i < (1 << (K - 1)); i++)
174 ae[i] = nae[i] = MAX_ERROR;
175 ae[0] = 0;
176
177 // build trellis
178 for (t = 0; t < CONV_INPUT_SIZE; t++) {
179
180 // get received data symbol
181 rdata = (data[2 * t] << 1) | data[2 * t + 1];
182
183 // for each state
184 for (state = 0; state < (1 << (K - 1)); state++) {
185
186 // make sure this state is possible
187 if (ae[state] >= MAX_ERROR)
188 continue;
189
190 // find all states we lead to
191 for (b = 0; b < 2; b++) {
192
193 // get next state given input bit b
194 nstate = next_state[state][b];
195
196 // find output for this transition
197 o = encode[state][b];
198
199 // calculate distance from received data
200 distance = hamming_distance2(rdata ^ o);
201
202 // choose surviving path
203 accumulated_error = ae[state] + distance;
204 if (accumulated_error < nae[nstate]) {
205
206 // save error for surviving state
207 nae[nstate] = accumulated_error;
208
209 // update state history
210 state_history[nstate][t + 1] = state;
211 }
212 }
213 }
214
215 // get accumulated error ready for next time slice
216 for (i = 0; i < (1 << (K - 1)); i++) {
217 ae[i] = nae[i];
218 nae[i] = MAX_ERROR;
219 }
220 }
221
222 // the final state is the state with the fewest errors
223 min_state = (unsigned int) - 1;
224 min_error = MAX_ERROR;
225 for (i = 0; i < (1 << (K - 1)); i++) {
226 if (ae[i] < min_error) {
227 min_state = i;
228 min_error = ae[i];
229 }
230 }
231
232 // trace the path
233 cur_state = min_state;
234 for (t = CONV_INPUT_SIZE; t >= 1; t--) {
235 min_state = cur_state;
236 cur_state = state_history[cur_state][t]; // get previous
237 output[t - 1] = prev_next_state[cur_state][min_state];
238 }
239
240 // return the number of errors detected (hard-decision)
241 return min_error;
242}
243
244
245int decode_sch(const unsigned char *buf, int * t1_o, int * t2_o, int * t3_o, int * ncc_o, int * bcc_o)
246{
247
248 int errors, t1, t2, t3p, t3, ncc, bcc;
249 unsigned char data[CONV_SIZE], decoded_data[PARITY_OUTPUT_SIZE];
250
251 // extract encoded data from synchronization burst
252 /* buf, 39 bit */
253 /* buf + 39 + 64 = 103, 39 */
254 memcpy(data, buf, SCH_DATA_LEN);
255 memcpy(data + SCH_DATA_LEN, buf + SCH_DATA_LEN + N_SYNC_BITS, SCH_DATA_LEN);
256
257 // Viterbi decode
258 if (errors = conv_decode(data, decoded_data)) {
259 // fprintf(stderr, "error: sch: conv_decode (%d)\n", errors);
260 DEBUGF("ERR: conv_decode %d\n", errors);
261 return errors;
262 }
263
264 // check parity
265 if (parity_check(decoded_data)) {
266 // fprintf(stderr, "error: sch: parity failed\n");
267 DEBUGF("ERR: parity_check failed\n");
268 return 1;
269 }
270
271 // Synchronization channel information, 44.018 page 171. (V7.2.0)
272 ncc =
273 (decoded_data[ 7] << 2) |
274 (decoded_data[ 6] << 1) |
275 (decoded_data[ 5] << 0);
276 bcc =
277 (decoded_data[ 4] << 2) |
278 (decoded_data[ 3] << 1) |
279 (decoded_data[ 2] << 0);
280 t1 =
281 (decoded_data[ 1] << 10) |
282 (decoded_data[ 0] << 9) |
283 (decoded_data[15] << 8) |
284 (decoded_data[14] << 7) |
285 (decoded_data[13] << 6) |
286 (decoded_data[12] << 5) |
287 (decoded_data[11] << 4) |
288 (decoded_data[10] << 3) |
289 (decoded_data[ 9] << 2) |
290 (decoded_data[ 8] << 1) |
291 (decoded_data[23] << 0);
292 t2 =
293 (decoded_data[22] << 4) |
294 (decoded_data[21] << 3) |
295 (decoded_data[20] << 2) |
296 (decoded_data[19] << 1) |
297 (decoded_data[18] << 0);
298 t3p =
299 (decoded_data[17] << 2) |
300 (decoded_data[16] << 1) |
301 (decoded_data[24] << 0);
302
303 t3 = 10 * t3p + 1;
304
305 // modulo arithmetic t3 - t2 mod 26
306// tt = ((t3 + 26) - t2) % 26;
307
308// fn = (51 * 26 * t1) + (51 * tt) + t3;
309
310 /*
311 * BSIC: Base Station Identification Code
312 * BCC: Base station Color Code
313 * NCC: Network Color Code
314 *
315 * FN: Frame Number
316 */
317
318// printf("bsic: %x (bcc: %u; ncc: %u)\tFN: %u\n", bsic, bsic & 7,
319// (bsic >> 3) & 7, fn);
320
321// if (fn_o)
322// *fn_o = fn;
323// if (bsic_o)
324 if (t1_o && t2_o && t3_o && ncc_o && bcc_o) {
325 *t1_o = t1;
326 *t2_o = t2;
327 *t3_o = t3;
328 *bcc_o = bcc;
329 *ncc_o = ncc;
330 }
331
332 return 0;
333}