1 //
2 // fec_example.c
3 //
4 // This example demonstrates the interface for forward error-
5 // correction (FEC) codes.  A buffer of data bytes is encoded and
6 // corrupted with several errors.  The decoder then attempts to
7 // recover the original data set.  The user may select the FEC
8 // scheme from the command-line interface.
9 // SEE ALSO: crc_example.c
10 //           checksum_example.c
11 //           packetizer_example.c
12 //
13 
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <string.h>
17 #include <getopt.h>
18 
19 #include "liquid.h"
20 
21 // print usage/help message
usage()22 void usage()
23 {
24     printf("fec_example [options]\n");
25     printf("  u/h   : print usage\n");
26     printf("  n     : input data size (number of uncoded bytes)\n");
27     printf("  c     : coding scheme, (h74 default):\n");
28     liquid_print_fec_schemes();
29 }
30 
31 
main(int argc,char * argv[])32 int main(int argc, char*argv[])
33 {
34     // options
35     unsigned int n = 4;                     // data length (bytes)
36     unsigned int nmax = 2048;               // maximum data length
37     fec_scheme fs = LIQUID_FEC_HAMMING74;   // error-correcting scheme
38 
39     int dopt;
40     while((dopt = getopt(argc,argv,"uhn:c:")) != EOF){
41         switch (dopt) {
42         case 'h':
43         case 'u': usage(); return 0;
44         case 'n': n = atoi(optarg); break;
45         case 'c':
46             fs = liquid_getopt_str2fec(optarg);
47             if (fs == LIQUID_FEC_UNKNOWN) {
48                 fprintf(stderr,"error: unknown/unsupported fec scheme \"%s\"\n\n",optarg);
49                 exit(1);
50             }
51             break;
52         default:
53             exit(1);
54         }
55     }
56 
57     // ensure proper data length
58     n = (n > nmax) ? nmax : n;
59 
60     // create arrays
61     unsigned int n_enc = fec_get_enc_msg_length(fs,n);
62     printf("dec msg len : %u\n", n);
63     printf("enc msg len : %u\n", n_enc);
64     unsigned char data[n];          // original data message
65     unsigned char msg_enc[n_enc];   // encoded data message
66     unsigned char msg_cor[n_enc];   // corrupted data message
67     unsigned char msg_dec[n];       // decoded data message
68 
69     // create object
70     fec q = fec_create(fs,NULL);
71     fec_print(q);
72 
73     unsigned int i;
74 
75     // create message
76     for (i=0; i<n; i++)
77         data[i] = rand() & 0xff;
78 
79     // encode message
80     fec_encode(q, n, data, msg_enc);
81 
82     // corrupt encoded message
83     memmove(msg_cor, msg_enc, n_enc);
84     msg_cor[0] ^= 0x04; // position 5
85 #if 0
86     msg_cor[1] ^= 0x04; //
87     msg_cor[2] ^= 0x02; //
88     msg_cor[3] ^= 0x01; //
89     msg_cor[4] ^= 0x80; //
90     msg_cor[5] ^= 0x40; //
91     msg_cor[6] ^= 0x20; //
92     msg_cor[7] ^= 0x10; //
93 #endif
94 
95     // decode message
96     fec_decode(q, n, msg_cor, msg_dec);
97 
98     printf("original message:  [%3u] ",n);
99     for (i=0; i<n; i++)
100         printf(" %.2X", (unsigned int) (data[i]));
101     printf("\n");
102 
103     printf("encoded message:   [%3u] ",n_enc);
104     for (i=0; i<n_enc; i++)
105         printf(" %.2X", (unsigned int) (msg_enc[i]));
106     printf("\n");
107 
108     printf("corrupted message: [%3u] ",n_enc);
109     for (i=0; i<n_enc; i++)
110         printf("%c%.2X", msg_cor[i]==msg_enc[i] ? ' ' : '*', (unsigned int) (msg_cor[i]));
111     printf("\n");
112 
113     printf("decoded message:   [%3u] ",n);
114     for (i=0; i<n; i++)
115         printf("%c%.2X", msg_dec[i] == data[i] ? ' ' : '*', (unsigned int) (msg_dec[i]));
116     printf("\n");
117     printf("\n");
118 
119     // count bit errors
120     unsigned int j, num_sym_errors=0, num_bit_errors=0;
121     unsigned char e;
122     for (i=0; i<n; i++) {
123         num_sym_errors += (data[i] == msg_dec[i]) ? 0 : 1;
124 
125         e = data[i] ^ msg_dec[i];
126         for (j=0; j<8; j++) {
127             num_bit_errors += e & 0x01;
128             e >>= 1;
129         }
130     }
131 
132     //printf("number of symbol errors detected: %d\n", num_errors_detected);
133     printf("number of symbol errors received: %3u / %3u\n", num_sym_errors, n);
134     printf("number of bit errors received:    %3u / %3u\n", num_bit_errors, n*8);
135 
136     // clean up objects
137     fec_destroy(q);
138 
139     return 0;
140 }
141 
142