Home | History | Annotate | Download | only in fec
      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