1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174
|
//
// bpacketsync_example.c
//
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <getopt.h>
#include "liquid.h"
int callback(unsigned char * _payload,
int _payload_valid,
unsigned int _payload_len,
framesyncstats_s _stats,
void * _userdata)
{
printf("callback invoked, payload (%u bytes) : %s\n",
_payload_len,
_payload_valid ? "valid" : "INVALID!");
// copy data if valid
if (_payload_valid) {
unsigned char * msg_dec = (unsigned char*) _userdata;
memmove(msg_dec, _payload, _payload_len*sizeof(unsigned char));
}
return 0;
}
// print usage/help message
void usage()
{
printf("bpacketsync_example [options]\n");
printf(" u/h : print usage\n");
printf(" n : input data size (number of uncoded bytes): 8 default\n");
printf(" e : bit error rate of channel, default: 0\n");
printf(" v : data integrity check: crc32 default\n");
liquid_print_crc_schemes();
printf(" c : coding scheme (inner): h74 default\n");
printf(" k : coding scheme (outer): none default\n");
liquid_print_fec_schemes();
}
int main(int argc, char*argv[]) {
srand(time(NULL));
// options
unsigned int n=8; // original data message length
crc_scheme check = LIQUID_CRC_32; // data integrity check
fec_scheme fec0 = LIQUID_FEC_HAMMING74; // inner code
fec_scheme fec1 = LIQUID_FEC_NONE; // outer code
float bit_error_rate = 0.0f; // bit error rate
// read command-line options
int dopt;
while((dopt = getopt(argc,argv,"uhn:e:v:c:k:")) != EOF){
switch (dopt) {
case 'h':
case 'u': usage(); return 0;
case 'n': n = atoi(optarg); break;
case 'e': bit_error_rate = atof(optarg); break;
case 'v':
// data integrity check
check = liquid_getopt_str2crc(optarg);
if (check == LIQUID_CRC_UNKNOWN) {
fprintf(stderr,"error: unknown/unsupported CRC scheme \"%s\"\n\n",optarg);
exit(1);
}
break;
case 'c':
// inner FEC scheme
fec0 = liquid_getopt_str2fec(optarg);
if (fec0 == LIQUID_FEC_UNKNOWN) {
fprintf(stderr,"error: unknown/unsupported inner FEC scheme \"%s\"\n\n",optarg);
exit(1);
}
break;
case 'k':
// outer FEC scheme
fec1 = liquid_getopt_str2fec(optarg);
if (fec1 == LIQUID_FEC_UNKNOWN) {
fprintf(stderr,"error: unknown/unsupported outer FEC scheme \"%s\"\n\n",optarg);
exit(1);
}
break;
default:
exit(1);
}
}
// validate input
if (n == 0) {
fprintf(stderr,"error: %s, packet length must be greater than zero\n", argv[0]);
exit(1);
} else if (bit_error_rate < 0.0f || bit_error_rate > 1.0f) {
fprintf(stderr,"error: %s, channel bit error rate must be in [0,1]\n", argv[0]);
exit(1);
}
// create packet generator
bpacketgen pg = bpacketgen_create(0, n, check, fec0, fec1);
bpacketgen_print(pg);
unsigned int i;
// compute packet length
unsigned int k = bpacketgen_get_packet_len(pg);
// initialize arrays
unsigned char msg_org[n]; // original message
unsigned char msg_enc[k]; // encoded message
unsigned char msg_rec[k+1]; // received message
unsigned char msg_dec[n]; // decoded message
// create packet synchronizer
bpacketsync ps = bpacketsync_create(0, callback, (void*)msg_dec);
bpacketsync_print(ps);
// initialize original data message
for (i=0; i<n; i++)
msg_org[i] = rand() % 256;
//
// encode packet
//
bpacketgen_encode(pg,msg_org,msg_enc);
//
// channel
//
// add delay
msg_rec[0] = rand() & 0xff; // initialize first byte as random
memmove(&msg_rec[1], msg_enc, k*sizeof(unsigned char));
liquid_lbshift(msg_rec, (k+1)*sizeof(unsigned char), rand()%8); // random shift
// add random errors
for (i=0; i<k+1; i++) {
unsigned int j;
for (j=0; j<8; j++) {
if (randf() < bit_error_rate)
msg_rec[i] ^= 1 << (8-j-1);
}
}
//
// run packet synchronizer
//
// push random bits through synchronizer
for (i=0; i<100; i++)
bpacketsync_execute_byte(ps, rand() & 0xff);
// push packet through synchronizer
for (i=0; i<k+1; i++)
bpacketsync_execute_byte(ps, msg_rec[i]);
//
// count errors
//
unsigned int num_bit_errors = 0;
for (i=0; i<n; i++)
num_bit_errors += count_bit_errors(msg_org[i], msg_dec[i]);
printf("number of bit errors received: %4u / %4u\n", num_bit_errors, n*8);
// clean up allocated objects
bpacketgen_destroy(pg);
bpacketsync_destroy(ps);
return 0;
}
|