1 /*
2  * Copyright (c) 2007 - 2015 Joseph Gaeddert
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a copy
5  * of this software and associated documentation files (the "Software"), to deal
6  * in the Software without restriction, including without limitation the rights
7  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8  * copies of the Software, and to permit persons to whom the Software is
9  * furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20  * THE SOFTWARE.
21  */
22 
23 #include <stdlib.h>
24 #include <stdio.h>
25 
26 #include "autotest/autotest.h"
27 #include "liquid.internal.h"
28 
29 //
30 // AUTOTEST: SEC-DEC (72,64) codec (no errors)
31 //
autotest_secded7264_codec_e0()32 void autotest_secded7264_codec_e0()
33 {
34     // arrays
35     unsigned char sym_org[8];   // original symbol
36     unsigned char sym_enc[9];   // encoded symbol
37     unsigned char sym_dec[8];   // decoded symbol
38 
39     // generate symbol
40     sym_org[0] = rand() & 0xff;
41     sym_org[1] = rand() & 0xff;
42     sym_org[2] = rand() & 0xff;
43     sym_org[3] = rand() & 0xff;
44     sym_org[4] = rand() & 0xff;
45     sym_org[5] = rand() & 0xff;
46     sym_org[6] = rand() & 0xff;
47     sym_org[7] = rand() & 0xff;
48 
49     // encoded symbol
50     fec_secded7264_encode_symbol(sym_org, sym_enc);
51 
52     // decoded symbol
53     fec_secded7264_decode_symbol(sym_enc, sym_dec);
54 
55     // validate data are the same
56     CONTEND_EQUALITY(sym_org[0], sym_dec[0]);
57     CONTEND_EQUALITY(sym_org[1], sym_dec[1]);
58     CONTEND_EQUALITY(sym_org[2], sym_dec[2]);
59     CONTEND_EQUALITY(sym_org[3], sym_dec[3]);
60     CONTEND_EQUALITY(sym_org[4], sym_dec[4]);
61     CONTEND_EQUALITY(sym_org[5], sym_dec[5]);
62     CONTEND_EQUALITY(sym_org[6], sym_dec[6]);
63     CONTEND_EQUALITY(sym_org[7], sym_dec[7]);
64 }
65 
66 //
67 // AUTOTEST: SEC-DEC (72,64) codec (single error)
68 //
autotest_secded7264_codec_e1()69 void autotest_secded7264_codec_e1()
70 {
71     // arrays
72     unsigned char sym_org[8];   // original symbol
73     unsigned char sym_enc[9];   // encoded symbol
74     unsigned char e[9];         // error vector
75     unsigned char sym_rec[9];   // received symbol
76     unsigned char sym_dec[8];   // decoded symbol
77 
78     unsigned int i;
79     unsigned int k; // error location
80 
81     for (k=0; k<72; k++) {
82         // generate symbol
83         for (i=0; i<8; i++)
84             sym_org[i] = rand() & 0xff;
85 
86         // encoded symbol
87         fec_secded7264_encode_symbol(sym_org, sym_enc);
88 
89         // generate error vector (single error)
90         for (i=0; i<9; i++)
91             e[i] = 0;
92         div_t d = div(k,8);
93         e[9-d.quot-1] = 1 << d.rem;   // flip bit at index k
94 
95         // received symbol
96         for (i=0; i<9; i++)
97             sym_rec[i] = sym_enc[i] ^ e[i];
98 
99         // decoded symbol
100         fec_secded7264_decode_symbol(sym_rec, sym_dec);
101 
102         // validate data are the same
103         for (i=0; i<8; i++)
104             CONTEND_EQUALITY(sym_org[i], sym_dec[i]);
105     }
106 }
107 
108 //
109 // AUTOTEST: SEC-DEC (72,64) codec (double error detection)
110 //
autotest_secded7264_codec_e2()111 void autotest_secded7264_codec_e2()
112 {
113     // total combinations of double errors: nchoosek(72,2) = 2556
114 
115     // arrays
116     unsigned char sym_org[8];   // original symbol
117     unsigned char sym_enc[9];   // encoded symbol
118     unsigned char e[9];         // error vector
119     unsigned char sym_rec[9];   // received symbol
120     unsigned char sym_dec[8];   // decoded symbol
121 
122     unsigned int i;
123     unsigned int j;
124     unsigned int k;
125 
126     for (j=0; j<72-1; j++) {
127 #if 0
128         if (liquid_autotest_verbose)
129             printf("***** %2u *****\n", j);
130 #endif
131 
132         for (k=0; k<72-1-j; k++) {
133             // generate symbol
134             for (i=0; i<8; i++)
135                 sym_org[i] = rand() & 0xff;
136 
137             // encoded symbol
138             fec_secded7264_encode_symbol(sym_org, sym_enc);
139 
140             // generate error vector (single error)
141             for (i=0; i<9; i++)
142                 e[i] = 0;
143 
144             div_t dj = div(j,8);
145             e[9-dj.quot-1] |= 1 << dj.rem;
146 
147             div_t dk = div(k+j+1,8);
148             e[9-dk.quot-1] |= 1 << dk.rem;
149 
150             // received symbol
151             for (i=0; i<9; i++)
152                 sym_rec[i] = sym_enc[i] ^ e[i];
153 
154             // decoded symbol
155             int syndrome_flag = fec_secded7264_decode_symbol(sym_rec, sym_dec);
156 
157 #if 0
158             if (liquid_autotest_verbose) {
159                 // print error vector
160                 printf("%3u, e = ", k);
161                 liquid_print_bitstring(e[0], 8);
162                 liquid_print_bitstring(e[1], 8);
163                 liquid_print_bitstring(e[2], 8);
164                 liquid_print_bitstring(e[3], 8);
165                 liquid_print_bitstring(e[4], 8);
166                 liquid_print_bitstring(e[5], 8);
167                 liquid_print_bitstring(e[6], 8);
168                 liquid_print_bitstring(e[7], 8);
169                 liquid_print_bitstring(e[8], 8);
170                 printf(" flag=%2d\n", syndrome_flag);
171             }
172 #endif
173 
174             // validate syndrome flag is '2'
175             CONTEND_EQUALITY(syndrome_flag, 2);
176         }
177     }
178 }
179 
180