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 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 */ 37 int EXERCISE( 38 #if !defined(CCSDS) && !defined(FIXED) 39 void *p, 40 #endif 41 int 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 } 123