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