2 * Copyright © 2012 Keith Packard <keithp@keithp.com>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 2 of the License.
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * General Public License for more details.
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write to the Free Software Foundation, Inc.,
15 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
26 #define RANDOM_MAX 0x7fffffff
31 return (double) random() / (double) RANDOM_MAX;
35 gaussian_random(double mean, double dev)
37 static int save_x_valid = 0;
49 double normal_x1, normal_x2;
52 normal_x1 = 2 * rand_real () - 1;
53 normal_x2 = 2 * rand_real () - 1;
54 w = normal_x1*normal_x1 + normal_x2*normal_x2;
55 } while (w >= 1 || w < 1E-30);
57 w = sqrt(log(w)*(-2./w));
60 * normal_x1 and normal_x2 are independent normally
61 * distributed variates
65 /* save normal_x2 for next call */
66 save_x = normal_x2 * w;
69 return x * dev + mean;
72 #define PREPARE_LEN(input_len) ((input_len) + AO_FEC_PREPARE_EXTRA)
73 #define ENCODE_LEN(input_len) (PREPARE_LEN(input_len) * 2)
74 #define DECODE_LEN(input_len) ((input_len) + AO_FEC_PREPARE_EXTRA)
75 #define EXPAND_LEN(input_len) (ENCODE_LEN(input_len) * 8)
78 ao_expand(uint8_t *bits, int bits_len, uint8_t *bytes)
83 for (i = 0; i < bits_len; i++) {
85 for (bit = 7; bit >= 0; bit--)
86 *bytes++ = ((b >> bit) & 1) * 0xff;
93 ao_fuzz (uint8_t *in, int in_len, uint8_t *out, double dev)
98 for (i = 0; i < in_len; i++) {
99 double error = gaussian_random(0, dev);
100 uint8_t byte = in[i];
118 ao_random_data(uint8_t *out, uint8_t out_len)
120 uint8_t len = random() % (out_len + 1);
123 for (i = 0; i < len; i++)
130 main(int argc, char **argv)
134 uint8_t original[120];
135 uint8_t original_len;
137 uint8_t encode[ENCODE_LEN(sizeof(original))];
140 uint8_t transmit[EXPAND_LEN(sizeof(original))];
143 uint8_t receive[EXPAND_LEN(sizeof(original))];
144 int receive_len, receive_errors;
146 uint8_t decode[DECODE_LEN(sizeof(original))];
153 for (trial = 0; trial < 10000; trial++) {
155 /* Compute some random data */
156 original_len = ao_random_data(original, sizeof(original));
159 encode_len = ao_fec_encode(original, original_len, encode);
161 /* Expand from 1-bit-per-symbol to 1-byte-per-symbol */
162 transmit_len = ao_expand(encode, encode_len, transmit);
164 /* Add gaussian noise to the signal */
165 receive_errors = ao_fuzz(transmit, transmit_len, receive, 0x30);
166 receive_len = transmit_len;
169 decode_len = ao_fec_decode(receive, receive_len, decode);
171 /* Check to see if we received the right data */
174 if (decode_len < original_len + 2) {
175 printf ("len mis-match\n");
179 if (!ao_fec_check_crc(decode, original_len)) {
180 printf ("crc mis-match\n");
184 if (memcmp(original, decode, original_len) != 0) {
185 printf ("data mis-match\n");
189 printf ("Errors: %d\n", receive_errors);
190 ao_fec_dump_bytes(original, original_len, "Input");
191 ao_fec_dump_bytes(decode, original_len, "Decode");