/* 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 Lesser General Public License (LGPL) */ #define FLAG_ERASURE 1 /* Randomly flag 50% of errors as erasures */ #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 data_t block[NN],tblock[NN]; int i; int errors; int errlocs[NN]; int derrlocs[NROOTS]; 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],0); #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,0); #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",derrlocs[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; }