1 /*---------------------------------------------------------------------------*\
2
3 FILE........: fsk_get_test_bits.c
4 AUTHOR......: Brady O'Brien
5 DATE CREATED: January 2016
6
7 Generates a pseudorandom sequence of bits for testing of fsk_mod and
8 fsk_demod.
9
10 \*---------------------------------------------------------------------------*/
11
12
13 /*
14 Copyright (C) 2016 David Rowe
15
16 All rights reserved.
17
18 This program is free software; you can redistribute it and/or modify
19 it under the terms of the GNU Lesser General Public License version 2.1, as
20 published by the Free Software Foundation. This program is
21 distributed in the hope that it will be useful, but WITHOUT ANY
22 WARRANTY; without even the implied warranty of MERCHANTABILITY or
23 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
24 License for more details.
25
26 You should have received a copy of the GNU Lesser General Public License
27 along with this program; if not, see <http://www.gnu.org/licenses/>.
28 */
29
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
33 #include <getopt.h>
34 #include "fsk.h"
35
36 #define TEST_FRAME_SIZE 100 /* must match fsk_get_test_bits.c */
37
38 #define VALID_PACKET_BER_THRESH 0.1
39
main(int argc,char * argv[])40 int main(int argc,char *argv[]){
41 int bitcnt,biterr,i,errs,packetcnt;
42 int framesize = TEST_FRAME_SIZE;
43 float valid_packet_ber_thresh = VALID_PACKET_BER_THRESH;
44 int packet_pass_thresh = 0;
45 float ber_pass_thresh = 0;
46 FILE *fin;
47 uint8_t *bitbuf_tx, *bitbuf_rx, abyte, abit;
48 int verbose = 1;
49 int packed_in = 0;
50
51 char usage[] = "usage: %s [-f frameSizeBits] [-t VaildFrameBERThreshold] [-b BERPass] [-p numPacketsPass] [-k] InputOneBitPerByte\n"
52 " [-k] packet byte input\n";
53
54 int opt;
55 while ((opt = getopt(argc, argv, "f:b:p:hqt:k")) != -1) {
56 switch (opt) {
57 case 't':
58 valid_packet_ber_thresh = atof(optarg);
59 break;
60 case 'b':
61 ber_pass_thresh = atof(optarg);
62 break;
63 case 'p':
64 packet_pass_thresh = atoi(optarg);
65 break;
66 case 'f':
67 framesize = atoi(optarg);
68 break;
69 case 'q':
70 verbose = 0;
71 break;
72 case 'k':
73 packed_in = 1;
74 break;
75 case 'h':
76 default:
77 fprintf(stderr, usage, argv[0]);
78 exit(1);
79 }
80 }
81 if (argc == 1) {
82 fprintf(stderr, usage, argv[0]);
83 exit(1);
84 }
85
86 int bits_per_byte = 1;
87 if (packed_in) {
88 if (framesize % 8) {
89 fprintf(stderr, "framesize (-f) must be a multiple of 8 for packed byte input (-k)\n");
90 exit(1);
91 }
92 bits_per_byte = 8;
93 }
94
95 char *fname = argv[optind++];
96 if ((strcmp(fname,"-")==0) || (argc<2)){
97 fin = stdin;
98 } else {
99 fin = fopen(fname,"r");
100 }
101
102 if(fin==NULL){
103 fprintf(stderr,"Couldn't open input file: %s\n", argv[1]);
104 exit(1);
105 }
106
107 /* allocate buffers for processing */
108 bitbuf_tx = (uint8_t*)malloc(sizeof(uint8_t)*framesize);
109 bitbuf_rx = (uint8_t*)malloc(sizeof(uint8_t)*framesize);
110
111 /* Generate known tx frame from known seed */
112 srand(158324);
113 for(i=0; i<framesize; i++){
114 bitbuf_tx[i] = rand()&0x1;
115 bitbuf_rx[i] = 0;
116 }
117
118 bitcnt = 0; biterr = 0; packetcnt = 0;
119 float ber = 0.5;
120
121 while(fread(&abyte,sizeof(uint8_t),1,fin)>0){
122
123 for (int b=0; b<bits_per_byte; b++) {
124 abit = (abyte >> ((bits_per_byte-1)-b)) & 0x1;
125
126 /* update sliding window of input bits */
127
128 for(i=0; i<framesize-1; i++) {
129 bitbuf_rx[i] = bitbuf_rx[i+1];
130 }
131 bitbuf_rx[framesize-1] = abit;
132
133 /* compare to know tx frame. If they are time aligned, there
134 will be a fairly low bit error rate */
135
136 errs = 0;
137 for(i=0; i<framesize; i++) {
138 if (bitbuf_rx[i] != bitbuf_tx[i]) {
139 errs++;
140 }
141 }
142 if (errs < valid_packet_ber_thresh * framesize) {
143 /* OK, we have a valid packet, so lets count errors */
144 packetcnt++;
145 bitcnt += framesize;
146 biterr += errs;
147 ber = (float)biterr/(float)bitcnt;
148 if (verbose) {
149 fprintf(stderr,"[%04d] BER %5.3f, bits tested %6d, bit errors %6d errs: %4d \n",
150 packetcnt, ber, bitcnt, biterr, errs);
151 }
152 }
153 }
154 }
155
156 free(bitbuf_rx);
157 free(bitbuf_tx);
158
159 fclose(fin);
160
161 fprintf(stderr,"[%04d] BER %5.3f, bits tested %6d, bit errors %6d\n", packetcnt, ber, bitcnt, biterr);
162 if ((packetcnt >= packet_pass_thresh) && (ber <= ber_pass_thresh)) {
163 fprintf(stderr,"PASS\n");
164 return 0;
165 }
166 else {
167 fprintf(stderr,"FAIL\n");
168 return 1;
169 }
170 }
171