Switch from GPLv2 to GPLv2+
[fw/altos] / src / test / ao_fec_test.c
index e8d3d8b194eb8095b4537461bc98deb69875b576..cbced6ae31435fb870ee8c599c02d88f9d564d5a 100644 (file)
@@ -3,7 +3,8 @@
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
  *
  * This program is distributed in the hope that it will be useful, but
  * WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -74,6 +75,12 @@ gaussian_random(double mean, double dev)
 #define DECODE_LEN(input_len)          ((input_len) + AO_FEC_PREPARE_EXTRA)
 #define EXPAND_LEN(input_len)          (ENCODE_LEN(input_len) * 8)
 
+static uint8_t ao_bit(uint8_t b) {
+       if (b)
+               return 0x00;
+       return 0xff;
+}
+
 static int
 ao_expand(uint8_t *bits, int bits_len, uint8_t *bytes)
 {
@@ -83,7 +90,7 @@ ao_expand(uint8_t *bits, int bits_len, uint8_t *bytes)
        for (i = 0; i < bits_len; i++) {
                b = bits[i];
                for (bit = 7; bit >= 0; bit--)
-                       *bytes++ = ((b >> bit) & 1) * 0xff;
+                       *bytes++ = ao_bit ((b >> bit) & 1);
        }
 
        return bits_len * 8;
@@ -94,6 +101,7 @@ ao_fuzz (uint8_t *in, int in_len, uint8_t *out, double dev)
 {
        int     i;
        int     errors = 0;
+       int     s;
        
        for (i = 0; i < in_len; i++) {
                double  error = gaussian_random(0, dev);
@@ -109,6 +117,24 @@ ao_fuzz (uint8_t *in, int in_len, uint8_t *out, double dev)
                        else
                                byte -= error;
                }
+
+               /* abcd efgh    8
+                * abcd efga    7
+                * abcd efab    6
+                * abcd eabc    5
+                * abcd abcd    4
+                * abca bcab    3
+                * abab abab    2
+                * aaaa aaaa    1
+                */
+
+#define SAVE           8
+#define SAVE_MASK      (((1 << SAVE) - 1) << (8 - SAVE))
+
+               byte &= SAVE_MASK;
+               for (s = SAVE; s < 8; s += SAVE)
+                       byte |= byte >> s;
+
                out[i] = byte;
        }
        return errors;
@@ -127,7 +153,7 @@ ao_random_data(uint8_t      *out, uint8_t out_len)
 
 
 static uint8_t real_packet[] = {
- 0x00, 0x40, 0x38, 0xcd, 0x38, 0x3d, 0x34, 0xca, 0x31, 0xc3, 0xc1, 0xc6, 0x35, 0xcc, 0x3a, 0x3c,
+ 0x40, 0x38, 0xcd, 0x38, 0x3d, 0x34, 0xca, 0x31, 0xc3, 0xc1, 0xc6, 0x35, 0xcc, 0x3a, 0x3c,
  0x3c, 0x3d, 0x3c, 0x37, 0xc5, 0xc1, 0xc0, 0xc1, 0xc1, 0xc3, 0xc0, 0xc1, 0xc6, 0x38, 0x3b, 0xc6,
  0xc0, 0xc6, 0x32, 0xc9, 0xc9, 0x34, 0xcf, 0x35, 0xcf, 0x3a, 0x3b, 0xc6, 0xc7, 0x35, 0xcf, 0x36,
  0xce, 0x37, 0xc8, 0xc8, 0x3a, 0x3c, 0xc9, 0xc8, 0x3a, 0x3c, 0xcc, 0x32, 0xcd, 0x32, 0xce, 0x32,
@@ -258,24 +284,30 @@ static uint8_t real_packet[] = {
 };
 
 
-void
+int
 ao_real_packet(void)
 {
        uint8_t decode[64];
-       uint8_t decode_len;
-       int off;
+       int     ok;
 
-       for (off = 0; off < sizeof (real_packet) - 576;  off++) {
-               decode_len = ao_fec_decode(real_packet+off, 576, decode, 34, NULL);
+       ok = ao_fec_decode(real_packet, 576, decode, 34, NULL);
 
-               if (ao_fec_check_crc(decode, 32)) {
-                       printf ("match at %d\n", off);
+       if (ok && decode[33] == AO_FEC_DECODE_CRC_OK) {
+               printf ("match\n");
 
-                       ao_fec_dump_bytes(decode, decode_len, "Decode");
-               }
+               ao_fec_dump_bytes(decode, 34, "Decode");
+       } else {
+               printf ("actual packet crc error\n");
+               ok = 0;
        }
+       return ok;
 }
 
+#define EXPECT_DECODE_FAIL     0
+#define EXPECT_CRC_MISMATCH    6386
+#define EXPECT_DATA_MISMATCH   0
+#define NOISE_AMOUNT           0x50
+
 int
 main(int argc, char **argv)
 {
@@ -291,17 +323,21 @@ main(int argc, char **argv)
        int             transmit_len;
 
        uint8_t         receive[EXPAND_LEN(sizeof(original))];
-       int             receive_len, receive_errors;
+       int             receive_len;
 
        uint8_t         decode[DECODE_LEN(sizeof(original))];
-       int             decode_len;
+       int             decode_ok;
 
        int             errors = 0;
-       int             error;
+       int             decode_fail = 0;
+       int             crc_mismatch = 0;
+       int             data_mismatch = 0;
+
+       if (!ao_real_packet())
+               errors++;
 
-       ao_real_packet(); exit(0);
        srandom(0);
-       for (trial = 0; trial < 10000; trial++) {
+       for (trial = 0; trial < 100000; trial++) {
 
                /* Compute some random data */
                original_len = ao_random_data(original, sizeof(original));
@@ -313,35 +349,37 @@ main(int argc, char **argv)
                transmit_len = ao_expand(encode, encode_len, transmit);
 
                /* Add gaussian noise to the signal */
-               receive_errors = ao_fuzz(transmit, transmit_len, receive, 0x30);
+               (void) ao_fuzz(transmit, transmit_len, receive, NOISE_AMOUNT);
                receive_len = transmit_len;
                
                /* Decode it */
-               decode_len = ao_fec_decode(receive, receive_len, decode, original_len + 2, NULL);
+               decode_ok = ao_fec_decode(receive, receive_len, decode, original_len + 2, NULL);
 
                /* Check to see if we received the right data */
-               error = 0;
 
-               if (decode_len < original_len + 2) {
-                       printf ("len mis-match\n");
-                       error++;
-               }
+               if (!decode_ok)
+                       decode_fail++;
+               else if (decode[original_len +1] != AO_FEC_DECODE_CRC_OK)
+                       crc_mismatch++;
+               else if (memcmp(original, decode, original_len) != 0)
+                       data_mismatch++;
+       }
 
-               if (!ao_fec_check_crc(decode, original_len)) {
-                       printf ("crc mis-match\n");
-                       error++;
-               }
 
-               if (memcmp(original, decode, original_len) != 0) {
-                       printf ("data mis-match\n");
-                       error++;
-               }
-               if (error) {
-                       printf ("Errors: %d\n", receive_errors);
-                       ao_fec_dump_bytes(original, original_len, "Input");
-                       ao_fec_dump_bytes(decode, original_len, "Decode");
-                       errors += error;
-               }
+       printf ("%d packets coded\n", trial);
+       printf ("decode_fail %d crc_mismatch %d data_mismatch %d\n",
+               decode_fail, crc_mismatch, data_mismatch);
+       if (decode_fail != EXPECT_DECODE_FAIL) {
+               printf ("expected %d decode failures\n", EXPECT_DECODE_FAIL);
+               errors++;
+       }
+       if (crc_mismatch != EXPECT_CRC_MISMATCH) {
+               printf ("expected %d crc mismatch\n", EXPECT_CRC_MISMATCH);
+               errors++;
+       }
+       if (data_mismatch != EXPECT_DATA_MISMATCH) {
+               printf ("expected %d data mismatch\n", EXPECT_DATA_MISMATCH);
+               errors++;
        }
        return errors;
 }