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