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