blob: ab651d4313916a1d4633fef2be0732795fee8067 [file] [log] [blame]
Sylvain Munaut29eb92d2011-11-24 17:48:42 +01001#include <stdio.h>
2#include <stdlib.h>
Jacob Erlbeck3c761c82013-08-14 18:13:46 +02003#include <string.h>
Sylvain Munaut29eb92d2011-11-24 17:48:42 +01004#include <time.h>
5
6#include <osmocom/core/bits.h>
7#include <osmocom/core/conv.h>
8#include <osmocom/core/utils.h>
9
10#define MAX_LEN_BITS 512
11#define MAX_LEN_BYTES (512/8)
12
13
14/* ------------------------------------------------------------------------ */
15/* Test codes */
16/* ------------------------------------------------------------------------ */
17
18/* GSM xCCH -> Non-recursive code, flushed, not punctured */
19static const uint8_t conv_gsm_xcch_next_output[][2] = {
20 { 0, 3 }, { 1, 2 }, { 0, 3 }, { 1, 2 },
21 { 3, 0 }, { 2, 1 }, { 3, 0 }, { 2, 1 },
22 { 3, 0 }, { 2, 1 }, { 3, 0 }, { 2, 1 },
23 { 0, 3 }, { 1, 2 }, { 0, 3 }, { 1, 2 },
24};
25
26static const uint8_t conv_gsm_xcch_next_state[][2] = {
27 { 0, 1 }, { 2, 3 }, { 4, 5 }, { 6, 7 },
28 { 8, 9 }, { 10, 11 }, { 12, 13 }, { 14, 15 },
29 { 0, 1 }, { 2, 3 }, { 4, 5 }, { 6, 7 },
30 { 8, 9 }, { 10, 11 }, { 12, 13 }, { 14, 15 },
31};
32
33static const struct osmo_conv_code conv_gsm_xcch = {
34 .N = 2,
35 .K = 5,
36 .len = 224,
37 .term = CONV_TERM_FLUSH,
38 .next_output = conv_gsm_xcch_next_output,
39 .next_state = conv_gsm_xcch_next_state,
40};
41
42
43/* GSM TCH/AFS 7.95 -> Recursive code, flushed, with puncturing */
44static const uint8_t conv_gsm_tch_afs_7_95_next_output[][2] = {
45 { 0, 7 }, { 3, 4 }, { 2, 5 }, { 1, 6 },
46 { 2, 5 }, { 1, 6 }, { 0, 7 }, { 3, 4 },
47 { 3, 4 }, { 0, 7 }, { 1, 6 }, { 2, 5 },
48 { 1, 6 }, { 2, 5 }, { 3, 4 }, { 0, 7 },
49 { 3, 4 }, { 0, 7 }, { 1, 6 }, { 2, 5 },
50 { 1, 6 }, { 2, 5 }, { 3, 4 }, { 0, 7 },
51 { 0, 7 }, { 3, 4 }, { 2, 5 }, { 1, 6 },
52 { 2, 5 }, { 1, 6 }, { 0, 7 }, { 3, 4 },
53 { 0, 7 }, { 3, 4 }, { 2, 5 }, { 1, 6 },
54 { 2, 5 }, { 1, 6 }, { 0, 7 }, { 3, 4 },
55 { 3, 4 }, { 0, 7 }, { 1, 6 }, { 2, 5 },
56 { 1, 6 }, { 2, 5 }, { 3, 4 }, { 0, 7 },
57 { 3, 4 }, { 0, 7 }, { 1, 6 }, { 2, 5 },
58 { 1, 6 }, { 2, 5 }, { 3, 4 }, { 0, 7 },
59 { 0, 7 }, { 3, 4 }, { 2, 5 }, { 1, 6 },
60 { 2, 5 }, { 1, 6 }, { 0, 7 }, { 3, 4 },
61};
62
63static const uint8_t conv_gsm_tch_afs_7_95_next_state[][2] = {
64 { 0, 1 }, { 2, 3 }, { 5, 4 }, { 7, 6 },
65 { 9, 8 }, { 11, 10 }, { 12, 13 }, { 14, 15 },
66 { 16, 17 }, { 18, 19 }, { 21, 20 }, { 23, 22 },
67 { 25, 24 }, { 27, 26 }, { 28, 29 }, { 30, 31 },
68 { 33, 32 }, { 35, 34 }, { 36, 37 }, { 38, 39 },
69 { 40, 41 }, { 42, 43 }, { 45, 44 }, { 47, 46 },
70 { 49, 48 }, { 51, 50 }, { 52, 53 }, { 54, 55 },
71 { 56, 57 }, { 58, 59 }, { 61, 60 }, { 63, 62 },
72 { 1, 0 }, { 3, 2 }, { 4, 5 }, { 6, 7 },
73 { 8, 9 }, { 10, 11 }, { 13, 12 }, { 15, 14 },
74 { 17, 16 }, { 19, 18 }, { 20, 21 }, { 22, 23 },
75 { 24, 25 }, { 26, 27 }, { 29, 28 }, { 31, 30 },
76 { 32, 33 }, { 34, 35 }, { 37, 36 }, { 39, 38 },
77 { 41, 40 }, { 43, 42 }, { 44, 45 }, { 46, 47 },
78 { 48, 49 }, { 50, 51 }, { 53, 52 }, { 55, 54 },
79 { 57, 56 }, { 59, 58 }, { 60, 61 }, { 62, 63 },
80};
81
82static const uint8_t conv_gsm_tch_afs_7_95_next_term_output[] = {
83 0, 3, 5, 6, 5, 6, 0, 3, 3, 0, 6, 5, 6, 5, 3, 0,
84 4, 7, 1, 2, 1, 2, 4, 7, 7, 4, 2, 1, 2, 1, 7, 4,
85 7, 4, 2, 1, 2, 1, 7, 4, 4, 7, 1, 2, 1, 2, 4, 7,
86 3, 0, 6, 5, 6, 5, 3, 0, 0, 3, 5, 6, 5, 6, 0, 3,
87};
88
89static const uint8_t conv_gsm_tch_afs_7_95_next_term_state[] = {
90 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30,
91 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62,
92 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30,
93 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62,
94};
95
96static int conv_gsm_tch_afs_7_95_puncture[] = {
97 1, 2, 4, 5, 8, 22, 70, 118, 166, 214, 262, 310,
98 317, 319, 325, 332, 334, 341, 343, 349, 356, 358, 365, 367,
99 373, 380, 382, 385, 389, 391, 397, 404, 406, 409, 413, 415,
100 421, 428, 430, 433, 437, 439, 445, 452, 454, 457, 461, 463,
101 469, 476, 478, 481, 485, 487, 490, 493, 500, 502, 503, 505,
102 506, 508, 509, 511, 512,
103 -1, /* end */
104};
105
106static const struct osmo_conv_code conv_gsm_tch_afs_7_95 = {
107 .N = 3,
108 .K = 7,
109 .len = 165,
110 .term = CONV_TERM_FLUSH,
111 .next_output = conv_gsm_tch_afs_7_95_next_output,
112 .next_state = conv_gsm_tch_afs_7_95_next_state,
113 .next_term_output = conv_gsm_tch_afs_7_95_next_term_output,
114 .next_term_state = conv_gsm_tch_afs_7_95_next_term_state,
115 .puncture = conv_gsm_tch_afs_7_95_puncture,
116};
117
118
119/* GMR-1 TCH3 Speech -> Non recursive code, tail-biting, punctured */
120static const uint8_t conv_gmr1_tch3_speech_next_output[][2] = {
121 { 0, 3 }, { 1, 2 }, { 3, 0 }, { 2, 1 },
122 { 3, 0 }, { 2, 1 }, { 0, 3 }, { 1, 2 },
123 { 0, 3 }, { 1, 2 }, { 3, 0 }, { 2, 1 },
124 { 3, 0 }, { 2, 1 }, { 0, 3 }, { 1, 2 },
125 { 2, 1 }, { 3, 0 }, { 1, 2 }, { 0, 3 },
126 { 1, 2 }, { 0, 3 }, { 2, 1 }, { 3, 0 },
127 { 2, 1 }, { 3, 0 }, { 1, 2 }, { 0, 3 },
128 { 1, 2 }, { 0, 3 }, { 2, 1 }, { 3, 0 },
129 { 3, 0 }, { 2, 1 }, { 0, 3 }, { 1, 2 },
130 { 0, 3 }, { 1, 2 }, { 3, 0 }, { 2, 1 },
131 { 3, 0 }, { 2, 1 }, { 0, 3 }, { 1, 2 },
132 { 0, 3 }, { 1, 2 }, { 3, 0 }, { 2, 1 },
133 { 1, 2 }, { 0, 3 }, { 2, 1 }, { 3, 0 },
134 { 2, 1 }, { 3, 0 }, { 1, 2 }, { 0, 3 },
135 { 1, 2 }, { 0, 3 }, { 2, 1 }, { 3, 0 },
136 { 2, 1 }, { 3, 0 }, { 1, 2 }, { 0, 3 },
137};
138
139static const uint8_t conv_gmr1_tch3_speech_next_state[][2] = {
140 { 0, 1 }, { 2, 3 }, { 4, 5 }, { 6, 7 },
141 { 8, 9 }, { 10, 11 }, { 12, 13 }, { 14, 15 },
142 { 16, 17 }, { 18, 19 }, { 20, 21 }, { 22, 23 },
143 { 24, 25 }, { 26, 27 }, { 28, 29 }, { 30, 31 },
144 { 32, 33 }, { 34, 35 }, { 36, 37 }, { 38, 39 },
145 { 40, 41 }, { 42, 43 }, { 44, 45 }, { 46, 47 },
146 { 48, 49 }, { 50, 51 }, { 52, 53 }, { 54, 55 },
147 { 56, 57 }, { 58, 59 }, { 60, 61 }, { 62, 63 },
148 { 0, 1 }, { 2, 3 }, { 4, 5 }, { 6, 7 },
149 { 8, 9 }, { 10, 11 }, { 12, 13 }, { 14, 15 },
150 { 16, 17 }, { 18, 19 }, { 20, 21 }, { 22, 23 },
151 { 24, 25 }, { 26, 27 }, { 28, 29 }, { 30, 31 },
152 { 32, 33 }, { 34, 35 }, { 36, 37 }, { 38, 39 },
153 { 40, 41 }, { 42, 43 }, { 44, 45 }, { 46, 47 },
154 { 48, 49 }, { 50, 51 }, { 52, 53 }, { 54, 55 },
155 { 56, 57 }, { 58, 59 }, { 60, 61 }, { 62, 63 },
156};
157
158static const int conv_gmr1_tch3_speech_puncture[] = {
159 3, 7, 11, 15, 19, 23, 27, 31, 35, 39, 43, 47,
160 51, 55, 59, 63, 67, 71, 75, 79, 83, 87, 91, 95,
161 -1, /* end */
162};
163
164static const struct osmo_conv_code conv_gmr1_tch3_speech = {
165 .N = 2,
166 .K = 7,
167 .len = 48,
168 .term = CONV_TERM_TAIL_BITING,
169 .next_output = conv_gmr1_tch3_speech_next_output,
170 .next_state = conv_gmr1_tch3_speech_next_state,
171 .puncture = conv_gmr1_tch3_speech_puncture,
172};
173
174
175/* WiMax FCH -> Non recursive code, tail-biting, non-punctured */
176static const uint8_t conv_wimax_fch_next_output[][2] = {
177 { 0, 3 }, { 2, 1 }, { 3, 0 }, { 1, 2 },
178 { 3, 0 }, { 1, 2 }, { 0, 3 }, { 2, 1 },
179 { 0, 3 }, { 2, 1 }, { 3, 0 }, { 1, 2 },
180 { 3, 0 }, { 1, 2 }, { 0, 3 }, { 2, 1 },
181 { 1, 2 }, { 3, 0 }, { 2, 1 }, { 0, 3 },
182 { 2, 1 }, { 0, 3 }, { 1, 2 }, { 3, 0 },
183 { 1, 2 }, { 3, 0 }, { 2, 1 }, { 0, 3 },
184 { 2, 1 }, { 0, 3 }, { 1, 2 }, { 3, 0 },
185 { 3, 0 }, { 1, 2 }, { 0, 3 }, { 2, 1 },
186 { 0, 3 }, { 2, 1 }, { 3, 0 }, { 1, 2 },
187 { 3, 0 }, { 1, 2 }, { 0, 3 }, { 2, 1 },
188 { 0, 3 }, { 2, 1 }, { 3, 0 }, { 1, 2 },
189 { 2, 1 }, { 0, 3 }, { 1, 2 }, { 3, 0 },
190 { 1, 2 }, { 3, 0 }, { 2, 1 }, { 0, 3 },
191 { 2, 1 }, { 0, 3 }, { 1, 2 }, { 3, 0 },
192 { 1, 2 }, { 3, 0 }, { 2, 1 }, { 0, 3 },
193};
194
195static const uint8_t conv_wimax_fch_next_state[][2] = {
196 { 0, 1 }, { 2, 3 }, { 4, 5 }, { 6, 7 },
197 { 8, 9 }, { 10, 11 }, { 12, 13 }, { 14, 15 },
198 { 16, 17 }, { 18, 19 }, { 20, 21 }, { 22, 23 },
199 { 24, 25 }, { 26, 27 }, { 28, 29 }, { 30, 31 },
200 { 32, 33 }, { 34, 35 }, { 36, 37 }, { 38, 39 },
201 { 40, 41 }, { 42, 43 }, { 44, 45 }, { 46, 47 },
202 { 48, 49 }, { 50, 51 }, { 52, 53 }, { 54, 55 },
203 { 56, 57 }, { 58, 59 }, { 60, 61 }, { 62, 63 },
204 { 0, 1 }, { 2, 3 }, { 4, 5 }, { 6, 7 },
205 { 8, 9 }, { 10, 11 }, { 12, 13 }, { 14, 15 },
206 { 16, 17 }, { 18, 19 }, { 20, 21 }, { 22, 23 },
207 { 24, 25 }, { 26, 27 }, { 28, 29 }, { 30, 31 },
208 { 32, 33 }, { 34, 35 }, { 36, 37 }, { 38, 39 },
209 { 40, 41 }, { 42, 43 }, { 44, 45 }, { 46, 47 },
210 { 48, 49 }, { 50, 51 }, { 52, 53 }, { 54, 55 },
211 { 56, 57 }, { 58, 59 }, { 60, 61 }, { 62, 63 },
212};
213
214static const struct osmo_conv_code conv_wimax_fch = {
215 .N = 2,
216 .K = 7,
217 .len = 48,
218 .term = CONV_TERM_TAIL_BITING,
219 .next_output = conv_wimax_fch_next_output,
220 .next_state = conv_wimax_fch_next_state,
221};
222
223
224/* Random code -> Non recursive code, direct truncation, non-punctured */
225static const struct osmo_conv_code conv_trunc = {
226 .N = 2,
227 .K = 5,
228 .len = 224,
229 .term = CONV_TERM_TRUNCATION,
230 .next_output = conv_gsm_xcch_next_output,
231 .next_state = conv_gsm_xcch_next_state,
232};
233
234
235/* ------------------------------------------------------------------------ */
236/* Test vectors */
237/* ------------------------------------------------------------------------ */
238
239struct conv_test_vector {
240 const char *name;
241 const struct osmo_conv_code *code;
242 int in_len;
243 int out_len;
244 int has_vec;
245 pbit_t vec_in[MAX_LEN_BYTES];
246 pbit_t vec_out[MAX_LEN_BYTES];
247};
248
249static const struct conv_test_vector tests[] = {
250 {
251 .name = "GSM xCCH (non-recursive, flushed, not punctured)",
252 .code = &conv_gsm_xcch,
253 .in_len = 224,
254 .out_len = 456,
255 .has_vec = 1,
256 .vec_in = { 0xf3, 0x1d, 0xb4, 0x0c, 0x4d, 0x1d, 0x9d, 0xae,
257 0xc0, 0x0a, 0x42, 0x57, 0x13, 0x60, 0x80, 0x96,
258 0xef, 0x23, 0x7e, 0x4c, 0x1d, 0x96, 0x24, 0x19,
259 0x17, 0xf2, 0x44, 0x99 },
260 .vec_out = { 0xe9, 0x4d, 0x70, 0xab, 0xa2, 0x87, 0xf0, 0xe7,
261 0x04, 0x14, 0x7c, 0xab, 0xaf, 0x6b, 0xa1, 0x16,
262 0xeb, 0x30, 0x00, 0xde, 0xc8, 0xfd, 0x0b, 0x85,
263 0x80, 0x41, 0x4a, 0xcc, 0xd3, 0xc0, 0xd0, 0xb6,
264 0x26, 0xe5, 0x4e, 0x32, 0x49, 0x69, 0x38, 0x17,
265 0x33, 0xab, 0xaf, 0xb6, 0xc1, 0x08, 0xf3, 0x9f,
266 0x8c, 0x75, 0x6a, 0x4e, 0x08, 0xc4, 0x20, 0x5f,
267 0x8f },
268 },
269 {
270 .name = "GSM TCH/AFS 7.95 (recursive, flushed, punctured)",
271 .code = &conv_gsm_tch_afs_7_95,
272 .in_len = 165,
273 .out_len = 448,
274 .has_vec = 1,
275 .vec_in = { 0x87, 0x66, 0xc3, 0x58, 0x09, 0xd4, 0x06, 0x59,
276 0x10, 0xbf, 0x6b, 0x7f, 0xc8, 0xed, 0x72, 0xaa,
277 0xc1, 0x3d, 0xf3, 0x1e, 0xb0 },
278 .vec_out = { 0x92, 0xbc, 0xde, 0xa0, 0xde, 0xbe, 0x01, 0x2f,
279 0xbe, 0xe4, 0x61, 0x32, 0x4d, 0x4f, 0xdc, 0x41,
280 0x43, 0x0d, 0x15, 0xe0, 0x23, 0xdd, 0x18, 0x91,
281 0xe5, 0x36, 0x2d, 0xb7, 0xd9, 0x78, 0xb8, 0xb1,
282 0xb7, 0xcb, 0x2f, 0xc0, 0x52, 0x8f, 0xe2, 0x8c,
283 0x6f, 0xa6, 0x79, 0x88, 0xed, 0x0c, 0x2e, 0x9e,
284 0xa1, 0x5f, 0x45, 0x4a, 0xfb, 0xe6, 0x5a, 0x9c },
285 },
286 {
287 .name = "GMR-1 TCH3 Speech (non-recursive, tail-biting, punctured)",
288 .code = &conv_gmr1_tch3_speech,
289 .in_len = 48,
290 .out_len = 72,
291 .has_vec = 1,
292 .vec_in = { 0x4d, 0xcb, 0xfc, 0x72, 0xf4, 0x8c },
293 .vec_out = { 0xc0, 0x86, 0x63, 0x4b, 0x8b, 0xd4, 0x6a, 0x76, 0xb2 },
294 },
295 {
296 .name = "WiMax FCH (non-recursive, tail-biting, not punctured)",
297 .code = &conv_wimax_fch,
298 .in_len = 48,
299 .out_len = 96,
300 .has_vec = 1,
301 .vec_in = { 0xfc, 0xa0, 0xa0, 0xfc, 0xa0, 0xa0 },
302 .vec_out = { 0x19, 0x42, 0x8a, 0xed, 0x21, 0xed, 0x19, 0x42,
303 0x8a, 0xed, 0x21, 0xed },
304 },
305 {
306 .name = "??? (non-recursive, direct truncation, not punctured)",
307 .code = &conv_trunc,
308 .in_len = 224,
309 .out_len = 448,
310 .has_vec = 1,
311 .vec_in = { 0xe5, 0xe0, 0x85, 0x7e, 0xf7, 0x08, 0x19, 0x5a,
312 0xb9, 0xad, 0x82, 0x37, 0x98, 0x8b, 0x26, 0xb9,
313 0x81, 0x26, 0x9c, 0x75, 0xaf, 0xf3, 0xcb, 0x07,
314 0xac, 0x63, 0xe2, 0x9c,
315 },
316 .vec_out = { 0xea, 0x3b, 0x55, 0x0c, 0xd3, 0xf7, 0x85, 0x69,
317 0xe5, 0x79, 0x83, 0xd3, 0xc3, 0x9f, 0xb8, 0x61,
318 0x21, 0x63, 0x51, 0x18, 0xac, 0xcd, 0x32, 0x49,
319 0x53, 0x5c, 0x13, 0x1d, 0xbe, 0x05, 0x11, 0x63,
320 0x5c, 0xc3, 0x42, 0x05, 0x1c, 0x68, 0x0a, 0xb4,
321 0x61, 0x15, 0xaa, 0x4d, 0x94, 0xed, 0xb3, 0x3a,
322 0x5d, 0x1b, 0x09, 0xc2, 0x99, 0x01, 0xec, 0x68 },
323 },
324 { /* end */ },
325};
326
327
328
329
330/* ------------------------------------------------------------------------ */
331/* Main */
332/* ------------------------------------------------------------------------ */
333
334static void
335fill_random(ubit_t *b, int n)
336{
337 int i;
338 for (i=0; i<n; i++)
339 b[i] = random() & 1;
340}
341
342static void
343ubit_to_sbit(sbit_t *dst, ubit_t *src, int n)
344{
345 int i;
346 for (i=0; i<n; i++)
347 dst[i] = src[i] ? -127 : 127;
348}
349
350static void
351sbit_to_ubit(ubit_t *dst, sbit_t *src, int n)
352{
353 int i;
354 for (i=0; i<n; i++)
355 dst[i] = src[i] < 0;
356}
357
358
Jacob Erlbeck3c761c82013-08-14 18:13:46 +0200359int main(int argc, char *argv[])
Sylvain Munaut29eb92d2011-11-24 17:48:42 +0100360{
361 const struct conv_test_vector *tst;
362 ubit_t *bu0, *bu1;
363 sbit_t *bs;
364
365 srandom(time(NULL));
366
367 bu0 = malloc(sizeof(ubit_t) * MAX_LEN_BITS);
368 bu1 = malloc(sizeof(ubit_t) * MAX_LEN_BITS);
369 bs = malloc(sizeof(sbit_t) * MAX_LEN_BITS);
370
371 for (tst=tests; tst->name; tst++)
372 {
373 int i,l;
374
375 /* Test name */
376 printf("[+] Testing: %s\n", tst->name);
377
378 /* Check length */
379 l = osmo_conv_get_input_length(tst->code, 0);
380 printf("[.] Input length : ret = %3d exp = %3d -> %s\n",
381 l, tst->in_len, l == tst->in_len ? "OK" : "Bad !");
382
383 if (l != tst->in_len) {
384 fprintf(stderr, "[!] Failure for input length computation\n");
385 return -1;
386 }
387
388 l = osmo_conv_get_output_length(tst->code, 0);
389 printf("[.] Output length : ret = %3d exp = %3d -> %s\n",
390 l, tst->out_len, l == tst->out_len ? "OK" : "Bad !");
391
392 if (l != tst->out_len) {
393 fprintf(stderr, "[!] Failure for output length computation\n");
394 return -1;
395 }
396
397 /* Check pre-computed vector */
398 if (tst->has_vec) {
399 printf("[.] Pre computed vector checks:\n");
400
401 printf("[..] Encoding: ");
402
403 osmo_pbit2ubit(bu0, tst->vec_in, tst->in_len);
404
405 l = osmo_conv_encode(tst->code, bu0, bu1);
406 if (l != tst->out_len) {
407 printf("ERROR !\n");
408 fprintf(stderr, "[!] Failed encoding length check\n");
409 return -1;
410 }
411
412 osmo_pbit2ubit(bu0, tst->vec_out, tst->out_len);
413
414 if (memcmp(bu0, bu1, tst->out_len)) {
415 printf("ERROR !\n");
416 fprintf(stderr, "[!] Failed encoding: Results don't match\n");
417 return -1;
418 };
419
420 printf("OK\n");
421
422
423 printf("[..] Decoding: ");
424
425 ubit_to_sbit(bs, bu0, l);
426
427 l = osmo_conv_decode(tst->code, bs, bu1);
428 if (l != 0) {
429 printf("ERROR !\n");
430 fprintf(stderr, "[!] Failed decoding: non-zero path (%d)\n", l);
431 return -1;
432 }
433
434 osmo_pbit2ubit(bu0, tst->vec_in, tst->in_len);
435
436 if (memcmp(bu0, bu1, tst->in_len)) {
437 printf("ERROR !\n");
438 fprintf(stderr, "[!] Failed decoding: Results don't match\n");
439 return -1;
440 }
441
442 printf("OK\n");
443 }
444
445 /* Check random vector */
446 printf("[.] Random vector checks:\n");
447
448 for (i=0; i<3; i++) {
449 printf("[..] Encoding / Decoding cycle : ");
450
451 fill_random(bu0, tst->in_len);
452
453 l = osmo_conv_encode(tst->code, bu0, bu1);
454 if (l != tst->out_len) {
455 printf("ERROR !\n");
456 fprintf(stderr, "[!] Failed encoding length check\n");
457 return -1;
458 }
459
460 ubit_to_sbit(bs, bu1, l);
461
462 l = osmo_conv_decode(tst->code, bs, bu1);
463 if (l != 0) {
464 printf("ERROR !\n");
465 fprintf(stderr, "[!] Failed decoding: non-zero path (%d)\n", l);
466 return -1;
467 }
468
469 if (memcmp(bu0, bu1, tst->in_len)) {
470 printf("ERROR !\n");
471 fprintf(stderr, "[!] Failed decoding: Results don't match\n");
472 return -1;
473 }
474
475 printf("OK\n");
476 }
477
478 /* Spacing */
479 printf("\n");
480 }
481
482 free(bs);
483 free(bu1);
484 free(bu0);
485
486 return 0;
487}