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