1 /* Exercise an RS codec a specified number of times using random
2 * data and error patterns
3 *
4 * Copyright 2002 Phil Karn, KA9Q
5 * May be used under the terms of the GNU General Public License (GPL)
6 */
7 #define FLAG_ERASURE 1 /* Randomly flag 50% of errors as erasures */
8
9 #ifdef HAVE_CONFIG_H
10 #include <config.h>
11 #endif
12
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <string.h>
16
17 #ifdef FIXED
18 #include "fixed.h"
19 #define EXERCISE exercise_8
20 #elif defined(CCSDS)
21 #include "ccsds.h"
22 #include "fixed.h"
23 #define EXERCISE exercise_ccsds
24 #elif defined(BIGSYM)
25 #include "int.h"
26 #define EXERCISE exercise_int
27 #else
28 #include "char.h"
29 #define EXERCISE exercise_char
30 #endif
31
32 #ifdef FIXED
33 #define PRINTPARM printf("(255,223):");
34 #elif defined(CCSDS)
35 #define PRINTPARM printf("CCSDS (255,223):");
36 #else
37 #define PRINTPARM printf("(%d,%d):", rs->nn, rs->nn - rs->nroots);
38 #endif
39
40 /* Exercise the RS codec passed as an argument */
EXERCISE(void * p,int trials)41 int EXERCISE(
42 #if !defined(CCSDS) && !defined(FIXED)
43 void* p,
44 #endif
45 int trials)
46 {
47 #if !defined(CCSDS) && !defined(FIXED)
48 struct rs* rs = (struct rs*)p;
49 #endif
50 #if MAX_ARRAY
51 DTYPE block[MAX_ARRAY], tblock[MAX_ARRAY];
52 unsigned int i;
53 int errors;
54 int errlocs[MAX_ARRAY];
55 int derrlocs[MAX_ARRAY];
56 #else
57 DTYPE block[NN], tblock[NN];
58 unsigned int i;
59 int errors;
60 int errlocs[NN];
61 int derrlocs[NROOTS];
62 #endif
63 int derrors;
64 int errval, errloc;
65 int erasures;
66 int decoder_errors = 0;
67
68 while (trials-- != 0) {
69 /* Test up to the error correction capacity of the code */
70 for (errors = 0; (unsigned int)errors <= NROOTS / 2; errors++) {
71
72 /* Load block with random data and encode */
73 for (i = 0; i < NN - NROOTS; i++)
74 block[i] = rand() & NN;
75
76 #if defined(CCSDS) || defined(FIXED)
77 ENCODE_RS(&block[0], &block[NN - NROOTS]);
78 #else
79 ENCODE_RS(rs, &block[0], &block[NN - NROOTS]);
80 #endif
81
82 /* Make temp copy, seed with errors */
83 memcpy(tblock, block, sizeof(tblock));
84 memset(errlocs, 0, sizeof(errlocs));
85 memset(derrlocs, 0, sizeof(derrlocs));
86 erasures = 0;
87 for (i = 0; i < (unsigned int)errors; i++) {
88 do {
89 errval = rand() & NN;
90 } while (errval == 0); /* Error value must be nonzero */
91
92 do {
93 errloc = rand() % NN;
94 } while (errlocs[errloc] !=
95 0); /* Must not choose the same location twice */
96
97 errlocs[errloc] = 1;
98
99 #if FLAG_ERASURE
100 if (rand() & 1) /* 50-50 chance */
101 derrlocs[erasures++] = errloc;
102 #endif
103 tblock[errloc] ^= errval;
104 }
105
106 /* Decode the errored block */
107 #if defined(CCSDS) || defined(FIXED)
108 derrors = DECODE_RS(tblock, derrlocs, erasures);
109 #else
110 derrors = DECODE_RS(rs, tblock, derrlocs, erasures);
111 #endif
112
113 if (derrors != errors) {
114 PRINTPARM
115 printf(" decoder says %d errors, true number is %d\n", derrors, errors);
116 decoder_errors++;
117 }
118 for (i = 0; i < (unsigned int)derrors; i++) {
119 if (errlocs[derrlocs[i]] == 0) {
120 PRINTPARM
121 printf(" decoder indicates error in location %d without error\n", i);
122 decoder_errors++;
123 }
124 }
125 if (memcmp(tblock, block, sizeof(tblock)) != 0) {
126 PRINTPARM
127 printf(" uncorrected errors! output ^ input:");
128 decoder_errors++;
129 for (i = 0; i < NN; i++)
130 printf(" %02x", tblock[i] ^ block[i]);
131 printf("\n");
132 }
133 }
134 }
135 return decoder_errors;
136 }
137