You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
123 lines
2.9 KiB
123 lines
2.9 KiB
4 months ago
|
/* 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;
|
||
|
}
|