From fa49b6a40b08e52f9562b6f4fb339483ad019fdf Mon Sep 17 00:00:00 2001 From: "David E. Tiller" <3858971+dtiller@users.noreply.github.com> Date: Mon, 4 Apr 2022 18:53:27 -0400 Subject: [PATCH] Starting to look like a real project. --- src/atest.c | 9 + src/bch.c | 8 +- src/bch3a.c | 620 ------------------------------------------------ src/bchapply.c | 176 ++++++++++++++ src/direwolf.c | 1 - src/eotd_defs.h | 14 ++ src/hdlc_rec.c | 13 +- src/mkpkts.sh | 4 - src/pkttest.c | 91 +++---- 9 files changed, 258 insertions(+), 678 deletions(-) delete mode 100644 src/bch3a.c create mode 100644 src/bchapply.c create mode 100644 src/eotd_defs.h delete mode 100644 src/mkpkts.sh diff --git a/src/atest.c b/src/atest.c index 5c19775..79c20fd 100644 --- a/src/atest.c +++ b/src/atest.c @@ -280,6 +280,9 @@ int main (int argc, char *argv[]) else if (strcasecmp(optarg, "EAS") == 0) { B_opt = 23456; // See special case below. } + else if (strcasecmp(optarg, "EOTD") == 0) { + B_opt = 34567; + } else { B_opt = atoi(optarg); } @@ -475,6 +478,12 @@ int main (int argc, char *argv[]) my_audio_config.achan[0].space_freq = 1563; // Actually 1562.5 - logic 0. strlcpy (my_audio_config.achan[0].profiles, "D", sizeof(my_audio_config.achan[0].profiles)); } + else if (my_audio_config.achan[0].baud == 34567) { + my_audio_config.achan[0].modem_type = MODEM_EOTD; + my_audio_config.achan[0].baud = 1200; + my_audio_config.achan[0].mark_freq = 1200; + my_audio_config.achan[0].space_freq = 1800; + } else { my_audio_config.achan[0].modem_type = MODEM_SCRAMBLE; my_audio_config.achan[0].mark_freq = 0; diff --git a/src/bch.c b/src/bch.c index 92ea0b4..beddea8 100644 --- a/src/bch.c +++ b/src/bch.c @@ -1,3 +1,7 @@ +/* BCH processing, library-style. Copyright (2022) David E. Tiller, K4DET + This file was adapted from a program written by Robert Morelos-Zaragoza + (robert@spectra.eng.hawaii.edu) whose original Copyright appears below. +*/ /* * File: bch3.c * Title: Encoder/decoder for binary BCH codes in C (Version 3.1) @@ -147,7 +151,7 @@ int init_bch(bch_t *bch, int m, int length, int t) { * * alpha=2 is the primitive element of GF(2**m) */ - register int i, mask; + register int mask; bch->alpha_to = malloc(n * sizeof(int)); bch->index_of = malloc(n * sizeof(int)); @@ -339,7 +343,7 @@ int apply_bch(const bch_t *bch, int *recd) { register int i, j, u, q, t2, count = 0, syn_error = 0; int elp[1026][1024], d[1026], l[1026], u_lu[1026], s[1025]; - int root[200], loc[200], err[1024], reg[201]; + int root[200], loc[200], reg[201]; t2 = 2 * bch->t; diff --git a/src/bch3a.c b/src/bch3a.c deleted file mode 100644 index e376cb5..0000000 --- a/src/bch3a.c +++ /dev/null @@ -1,620 +0,0 @@ -/* - * File: bch3.c - * Title: Encoder/decoder for binary BCH codes in C (Version 3.1) - * Author: Robert Morelos-Zaragoza - * Date: August 1994 - * Revised: June 13, 1997 - * - * =============== Encoder/Decoder for binary BCH codes in C ================= - * - * Version 1: Original program. The user provides the generator polynomial - * of the code (cumbersome!). - * Version 2: Computes the generator polynomial of the code. - * Version 3: No need to input the coefficients of a primitive polynomial of - * degree m, used to construct the Galois Field GF(2**m). The - * program now works for any binary BCH code of length such that: - * 2**(m-1) - 1 < length <= 2**m - 1 - * - * Note: You may have to change the size of the arrays to make it work. - * - * The encoding and decoding methods used in this program are based on the - * book "Error Control Coding: Fundamentals and Applications", by Lin and - * Costello, Prentice Hall, 1983. - * - * Thanks to Patrick Boyle (pboyle@era.com) for his observation that 'bch2.c' - * did not work for lengths other than 2**m-1 which led to this new version. - * Portions of this program are from 'rs.c', a Reed-Solomon encoder/decoder - * in C, written by Simon Rockliff (simon@augean.ua.oz.au) on 21/9/89. The - * previous version of the BCH encoder/decoder in C, 'bch2.c', was written by - * Robert Morelos-Zaragoza (robert@spectra.eng.hawaii.edu) on 5/19/92. - * - * NOTE: - * The author is not responsible for any malfunctioning of - * this program, nor for any damage caused by it. Please include the - * original program along with these comments in any redistribution. - * - * For more information, suggestions, or other ideas on implementing error - * correcting codes, please contact me at: - * - * Robert Morelos-Zaragoza - * 5120 Woodway, Suite 7036 - * Houston, Texas 77056 - * - * email: r.morelos-zaragoza@ieee.org - * - * COPYRIGHT NOTICE: This computer program is free for non-commercial purposes. - * You may implement this program for any non-commercial application. You may - * also implement this program for commercial purposes, provided that you - * obtain my written permission. Any modification of this program is covered - * by this copyright. - * - * == Copyright (c) 1994-7, Robert Morelos-Zaragoza. All rights reserved. == - * - * m = order of the Galois field GF(2**m) - * n = 2**m - 1 = size of the multiplicative group of GF(2**m) - * length = length of the BCH code - * t = error correcting capability (max. no. of errors the code corrects) - * d = 2*t + 1 = designed min. distance = no. of consecutive roots of g(x) + 1 - * k = n - deg(g(x)) = dimension (no. of information bits/codeword) of the code - * p[] = coefficients of a primitive polynomial used to generate GF(2**m) - * g[] = coefficients of the generator polynomial, g(x) - * alpha_to [] = log table of GF(2**m) - * index_of[] = antilog table of GF(2**m) - * data[] = information bits = coefficients of data polynomial, i(x) - * bb[] = coefficients of redundancy polynomial x^(length-k) i(x) modulo g(x) - * numerr = number of errors - * errpos[] = error positions - * recd[] = coefficients of the received polynomial - * decerror = number of decoding errors (in _message_ positions) - * - */ - -#include -#include -#include -#include - -int m, n, length, k, t, d; -int p[21]; -int alpha_to[1048576], index_of[1048576], g[548576]; -int recd[1048576], data[1048576], bb[548576]; -int seed; -int numerr, errpos[1024], decerror = 0; -int orig_recd[1048576]; - -uint64_t packets[] = { - -#define ALL_DATA -/* GOOD TEST */ 0xb217a2b953ddc552, /* random example from bch3 program */ -#ifdef ALL_DATA - 0xf05a6a6a016333d0, /* g001-cut-lenthened_457.938M.wav */ - 0xf081526b71a56308, /* 1st in eotd_received_data */ -/* 3 errors */ 0xf085506a01e56e84, /* 2nd in eotd_received_data */ -/* fixed */ 0xf085506a01e50684, /* 2nd, but with the bits fixed */ -#endif -#ifdef ALL_DATA - 0xf085595a01e56e84, /* 3rd */ - 0xf134501a01e566fe, /* 4th */ - 0xf0eb10ea016e541c, /* 5th */ - 0xf0ea5cea016e550e, /* 6th */ - 0xe021101a0132bce4, /* Sun Mar 20 05:41:00 2022 */ - 0xf042505bcfd564e4, /* Sun Mar 20 12:58:43 2022 */ - 0xf08c10aa01737b1a, /* Sun Mar 20 13:35:48 2022 */ - 0xf08c10b1c0e09064, /* Sun Mar 20 13:37:05 2022 */ - 0xf08c106a01647ae8, /* Sun Mar 20 13:37:48 2022 */ - 0x508c126a01647ae8, -#endif - }; - -void -read_p() -/* - * Read m, the degree of a primitive polynomial p(x) used to compute the - * Galois field GF(2**m). Get precomputed coefficients p[] of p(x). Read - * the code length. - */ -{ - int i, ninf; - - printf("bch3: An encoder/decoder for binary BCH codes\n"); - printf("Copyright (c) 1994-7. Robert Morelos-Zaragoza.\n"); - printf("This program is free, please read first the copyright notice.\n"); - printf("\nFirst, enter a value of m such that the code length is\n"); - printf("2**(m-1) - 1 < length <= 2**m - 1\n\n"); - do { - //printf("Enter m (between 2 and 20): "); - //scanf("%d", &m); - m = 6; - } while ( !(m>1) || !(m<21) ); - for (i=1; ininf)) ); */ - length = 63; -} - - -void -generate_gf() -/* - * Generate field GF(2**m) from the irreducible polynomial p(X) with - * coefficients in p[0]..p[m]. - * - * Lookup tables: - * index->polynomial form: alpha_to[] contains j=alpha^i; - * polynomial form -> index form: index_of[j=alpha^i] = i - * - * alpha=2 is the primitive element of GF(2**m) - */ -{ - register int i, mask; - - mask = 1; - alpha_to[m] = 0; - for (i = 0; i < m; i++) { - alpha_to[i] = mask; - index_of[alpha_to[i]] = i; - if (p[i] != 0) - alpha_to[m] ^= mask; - mask <<= 1; - } - index_of[alpha_to[m]] = m; - mask >>= 1; - for (i = m + 1; i < n; i++) { - if (alpha_to[i - 1] >= mask) - alpha_to[i] = alpha_to[m] ^ ((alpha_to[i - 1] ^ mask) << 1); - else - alpha_to[i] = alpha_to[i - 1] << 1; - index_of[alpha_to[i]] = i; - } - index_of[0] = -1; -} - - -void -gen_poly() -/* - * Compute the generator polynomial of a binary BCH code. Fist generate the - * cycle sets modulo 2**m - 1, cycle[][] = (i, 2*i, 4*i, ..., 2^l*i). Then - * determine those cycle sets that contain integers in the set of (d-1) - * consecutive integers {1..(d-1)}. The generator polynomial is calculated - * as the product of linear factors of the form (x+alpha^i), for every i in - * the above cycle sets. - */ -{ - register int ii, jj, ll, kaux; - register int test, aux, nocycles, root, noterms, rdncy; - int cycle[1024][21], size[1024], min[1024], zeros[1024]; - - /* Generate cycle sets modulo n, n = 2**m - 1 */ - cycle[0][0] = 0; - size[0] = 1; - cycle[1][0] = 1; - size[1] = 1; - jj = 1; /* cycle set index */ - if (m > 9) { - printf("Computing cycle sets modulo %d\n", n); - printf("(This may take some time)...\n"); - } - do { - /* Generate the jj-th cycle set */ - ii = 0; - do { - ii++; - cycle[jj][ii] = (cycle[jj][ii - 1] * 2) % n; - size[jj]++; - aux = (cycle[jj][ii] * 2) % n; - } while (aux != cycle[jj][0]); - /* Next cycle set representative */ - ll = 0; - do { - ll++; - test = 0; - for (ii = 1; ((ii <= jj) && (!test)); ii++) - /* Examine previous cycle sets */ - for (kaux = 0; ((kaux < size[ii]) && (!test)); kaux++) - if (ll == cycle[ii][kaux]) - test = 1; - } while ((test) && (ll < (n - 1))); - if (!(test)) { - jj++; /* next cycle set index */ - cycle[jj][0] = ll; - size[jj] = 1; - } - } while (ll < (n - 1)); - nocycles = jj; /* number of cycle sets modulo n */ - - //printf("Enter the error correcting capability, t: "); - //scanf("%d", &t); - t =3; - - d = 2 * t + 1; - - /* Search for roots 1, 2, ..., d-1 in cycle sets */ - kaux = 0; - rdncy = 0; - for (ii = 1; ii <= nocycles; ii++) { - min[kaux] = 0; - test = 0; - for (jj = 0; ((jj < size[ii]) && (!test)); jj++) - for (root = 1; ((root < d) && (!test)); root++) - if (root == cycle[ii][jj]) { - test = 1; - min[kaux] = ii; - } - if (min[kaux]) { - rdncy += size[min[kaux]]; - kaux++; - } - } - noterms = kaux; - kaux = 1; - for (ii = 0; ii < noterms; ii++) - for (jj = 0; jj < size[min[ii]]; jj++) { - zeros[kaux] = cycle[min[ii]][jj]; - kaux++; - } - - k = length - rdncy; - - if (k<0) - { - printf("Parameters invalid!\n"); - exit(0); - } - - printf("This is a (%d, %d, %d) binary BCH code\n", length, k, d); - - /* Compute the generator polynomial */ - g[0] = alpha_to[zeros[1]]; - g[1] = 1; /* g(x) = (X + zeros[1]) initially */ - for (ii = 2; ii <= rdncy; ii++) { - g[ii] = 1; - for (jj = ii - 1; jj > 0; jj--) - if (g[jj] != 0) - g[jj] = g[jj - 1] ^ alpha_to[(index_of[g[jj]] + zeros[ii]) % n]; - else - g[jj] = g[jj - 1]; - g[0] = alpha_to[(index_of[g[0]] + zeros[ii]) % n]; - } - printf("Generator polynomial:\ng(x) = "); - for (ii = 0; ii <= rdncy; ii++) { - printf("%d", g[ii]); - } - printf("\n"); -} - - -void -encode_bch() -/* - * Compute redundacy bb[], the coefficients of b(x). The redundancy - * polynomial b(x) is the remainder after dividing x^(length-k)*data(x) - * by the generator polynomial g(x). - */ -{ - register int i, j; - register int feedback; - - for (i = 0; i < length - k; i++) - bb[i] = 0; - for (i = k - 1; i >= 0; i--) { - feedback = data[i] ^ bb[length - k - 1]; - if (feedback != 0) { - for (j = length - k - 1; j > 0; j--) - if (g[j] != 0) - bb[j] = bb[j - 1] ^ feedback; - else - bb[j] = bb[j - 1]; - bb[0] = g[0] && feedback; - } else { - for (j = length - k - 1; j > 0; j--) - bb[j] = bb[j - 1]; - bb[0] = 0; - } - } -} - - -/* zero = success */ -int -decode_bch() -/* - * Simon Rockliff's implementation of Berlekamp's algorithm. - * - * Assume we have received bits in recd[i], i=0..(n-1). - * - * Compute the 2*t syndromes by substituting alpha^i into rec(X) and - * evaluating, storing the syndromes in s[i], i=1..2t (leave s[0] zero) . - * Then we use the Berlekamp algorithm to find the error location polynomial - * elp[i]. - * - * If the degree of the elp is >t, then we cannot correct all the errors, and - * we have detected an uncorrectable error pattern. We output the information - * bits uncorrected. - * - * If the degree of elp is <=t, we substitute alpha^i , i=1..n into the elp - * to get the roots, hence the inverse roots, the error location numbers. - * This step is usually called "Chien's search". - * - * If the number of errors located is not equal the degree of the elp, then - * the decoder assumes that there are more than t errors and cannot correct - * them, only detect them. We output the information bits uncorrected. - */ -{ - register int i, j, u, q, t2, count = 0, syn_error = 0; - int elp[1026][1024], d[1026], l[1026], u_lu[1026], s[1025]; - int root[200], loc[200], err[1024], reg[201]; - - t2 = 2 * t; - - /* first form the syndromes */ - printf("S(x) = "); - for (i = 1; i <= t2; i++) { - s[i] = 0; - for (j = 0; j < length; j++) - if (recd[j] != 0) - s[i] ^= alpha_to[(i * j) % n]; - if (s[i] != 0) - syn_error = 1; /* set error flag if non-zero syndrome */ -/* - * Note: If the code is used only for ERROR DETECTION, then - * exit program here indicating the presence of errors. - */ - /* convert syndrome from polynomial form to index form */ - s[i] = index_of[s[i]]; - printf("%3d ", s[i]); - } - printf("\n"); - - if (syn_error) { /* if there are errors, try to correct them */ - /* - * Compute the error location polynomial via the Berlekamp - * iterative algorithm. Following the terminology of Lin and - * Costello's book : d[u] is the 'mu'th discrepancy, where - * u='mu'+1 and 'mu' (the Greek letter!) is the step number - * ranging from -1 to 2*t (see L&C), l[u] is the degree of - * the elp at that step, and u_l[u] is the difference between - * the step number and the degree of the elp. - */ - /* initialise table entries */ - d[0] = 0; /* index form */ - d[1] = s[1]; /* index form */ - elp[0][0] = 0; /* index form */ - elp[1][0] = 1; /* polynomial form */ - for (i = 1; i < t2; i++) { - elp[0][i] = -1; /* index form */ - elp[1][i] = 0; /* polynomial form */ - } - l[0] = 0; - l[1] = 0; - u_lu[0] = -1; - u_lu[1] = 0; - u = 0; - - do { - u++; - if (d[u] == -1) { - l[u + 1] = l[u]; - for (i = 0; i <= l[u]; i++) { - elp[u + 1][i] = elp[u][i]; - elp[u][i] = index_of[elp[u][i]]; - } - } else - /* - * search for words with greatest u_lu[q] for - * which d[q]!=0 - */ - { - q = u - 1; - while ((d[q] == -1) && (q > 0)) - q--; - /* have found first non-zero d[q] */ - if (q > 0) { - j = q; - do { - j--; - if ((d[j] != -1) && (u_lu[q] < u_lu[j])) - q = j; - } while (j > 0); - } - - /* - * have now found q such that d[u]!=0 and - * u_lu[q] is maximum - */ - /* store degree of new elp polynomial */ - if (l[u] > l[q] + u - q) - l[u + 1] = l[u]; - else - l[u + 1] = l[q] + u - q; - - /* form new elp(x) */ - for (i = 0; i < t2; i++) - elp[u + 1][i] = 0; - for (i = 0; i <= l[q]; i++) - if (elp[q][i] != -1) - elp[u + 1][i + u - q] = - alpha_to[(d[u] + n - d[q] + elp[q][i]) % n]; - for (i = 0; i <= l[u]; i++) { - elp[u + 1][i] ^= elp[u][i]; - elp[u][i] = index_of[elp[u][i]]; - } - } - u_lu[u + 1] = u - l[u + 1]; - - /* form (u+1)th discrepancy */ - if (u < t2) { - /* no discrepancy computed on last iteration */ - if (s[u + 1] != -1) - d[u + 1] = alpha_to[s[u + 1]]; - else - d[u + 1] = 0; - for (i = 1; i <= l[u + 1]; i++) - if ((s[u + 1 - i] != -1) && (elp[u + 1][i] != 0)) - d[u + 1] ^= alpha_to[(s[u + 1 - i] - + index_of[elp[u + 1][i]]) % n]; - /* put d[u+1] into index form */ - d[u + 1] = index_of[d[u + 1]]; - } - } while ((u < t2) && (l[u + 1] <= t)); - - u++; - if (l[u] <= t) {/* Can correct errors */ - /* put elp into index form */ - for (i = 0; i <= l[u]; i++) - elp[u][i] = index_of[elp[u][i]]; - - printf("sigma(x) = "); - for (i = 0; i <= l[u]; i++) - printf("%3d ", elp[u][i]); - printf("\n"); - printf("Roots: "); - - /* Chien search: find roots of the error location polynomial */ - for (i = 1; i <= l[u]; i++) - reg[i] = elp[u][i]; - count = 0; - for (i = 1; i <= n; i++) { - q = 1; - for (j = 1; j <= l[u]; j++) - if (reg[j] != -1) { - reg[j] = (reg[j] + j) % n; - q ^= alpha_to[reg[j]]; - } - if (!q) { /* store root and error - * location number indices */ - root[count] = i; - loc[count] = n - i; - count++; - printf("%3d ", n - i); - } - } - printf("\n"); - if (count == l[u]) - /* no. roots = degree of elp hence <= t errors */ - for (i = 0; i < l[u]; i++) - recd[loc[i]] ^= 1; - else { /* elp has degree >t hence cannot solve */ - printf("Incomplete decoding: errors detected\n"); - return 1; - } - } - } - return 0; -} - -void setup(int idx) { - uint64_t pkt = packets[idx]; - printf("\n\nPACKET %llx\n", pkt); - printf("-------------------------\n"); - pkt >>= 1; // Lose dummy bit */ - - /* Move BCH code over */ - for (int i = length - k - 1; i >= 0; i--) { - recd[i] = pkt & 0x01; - pkt >>= 1; - } - - /* Move data over */ - for (int i = length - 1; i >= length - k; i--) { - recd[i] = pkt & 0x01; - data[i - length + k] = recd[i]; - pkt >>= 1; - } -} - -int main() -{ - int i; - - read_p(); /* Read m */ - generate_gf(); /* Construct the Galois Field GF(2**m) */ - gen_poly(); /* Compute the generator polynomial of BCH code */ - -for (int count = 0; count < sizeof(packets) / sizeof(uint64_t); count++) { - setup(count); - memcpy(&orig_recd, recd, sizeof(recd)); - - int result = decode_bch(); /* DECODE received codeword recd[] */ - - printf("n=%d, k=%d, length=%d\n", n, k, length); - printf("Results:\n"); - printf("\noriginal pkt: "); - for (int i = 0; i < length; i++) { - if (i == length - k) printf(" "); - printf("%d", orig_recd[i]); - } - printf("\n"); - - if (result) continue; - /* - * DECODING ERRORS? we compare only the data portion - */ - for (i = length - k; i < length; i++) - if (data[i - length + k] != recd[i]) - decerror++; - if (decerror) { - printf("There were %d decoding errors in message positions\n", decerror); - continue; - } - - /* - * print out original and decoded data - */ - printf("recovered pkt: "); - for (i = 0; i < length; i++) { - if (i == length - k) printf(" "); - printf("%1d", recd[i]); - } - printf("\n"); - - - int flag = 0; - printf("------------ "); - for (int jj = 0; jj < length; jj++) { - if (jj == length - k) printf(" "); - if (orig_recd[jj] != recd[jj]) { - printf("^"); - //printf("bit %d: expected %d calc: %d\n", jj, orig_recd[jj], recd[jj]); - flag++; - } else { - printf(" "); - } - } - printf("\n%d ERRORS.\n", flag); - - - } -} diff --git a/src/bchapply.c b/src/bchapply.c new file mode 100644 index 0000000..80a15f4 --- /dev/null +++ b/src/bchapply.c @@ -0,0 +1,176 @@ +#include +#include +#include "bch.h" + +#define SHOW_BYTES + +int test(bch_t *bch, char *msg, int *bits, int length) { + int corrected = 0; + int temp_bits[length]; + uint8_t bytes[8]; + + memcpy(temp_bits, bits, length * sizeof(int)); +#ifdef SHOW_BYTES + bits_to_bytes(temp_bits, bytes, length); + print_bytes(msg, bytes, 8); +#else + print_bits(msg, temp_bits, length); +#endif + corrected = apply_bch(bch, temp_bits); + + if (corrected >= 0) { + printf("corrected %d ", corrected); +#ifdef SHOW_BYTES + bits_to_bytes(temp_bits, bytes, length); + printf("CORR "); + print_bytes(msg, bytes, 8); +#else + print_bits(msg, temp_bits, length); +#endif + printf("\n"); + } else { + printf("invalid.\n"); + } + + return corrected >= 0; +} + +int main(int argc, char **argv) { + bch_t bch; + uint8_t bytes[8]; + int m, length, t; + int data_len, crc_len; + + + if (argc != 4) { + fprintf(stderr, "Expecting 3 arguments.\n"); + return -1; + } + + sscanf(argv[1], "%d", &m); + sscanf(argv[2], "%d", &length); + sscanf(argv[3], "%d", &t); + + int orig_bits[length+1]; + + init_bch(&bch, m, length, t); + data_len = bch.k; + crc_len = bch.length - bch.k; + +printf("m=%d, length=%d, n=%d, k=%d, t=%d\n", bch.m, bch.length, bch.n, bch.k, bch.t); +printf("data_len=%d, crc_len=%d\n", data_len, crc_len); + +// +// THIS IS THE LSB-FIRST VERSION +// +fprintf(stderr, "Enter HCB+ATAD _WITH_ the parity bit intact.\n"); + while (1) { + for (int i = 0; i < 8; i++) { + int temp; + int status = scanf("%x ", &temp); + bytes[i] = temp; + if (status == EOF) { + return 0; + } + + if (status != 1) { + fprintf(stderr, "Error: %d", status); + } +printf("%0x ", bytes[i]); + } +printf("\n"); + + int temp[length]; + + // HCB + ATAD + bytes_to_bits(bytes, orig_bits, length+1); + memcpy(temp, orig_bits+1, length * sizeof(int)); + print_bits("atad: ", temp + crc_len, data_len); + printf("\n"); + print_bits("hcb: ", temp, crc_len); + printf("\n"); + + test(&bch, "HCB+ATAD: ", temp, length); + + // ATAD+HCB + bytes_to_bits(bytes, orig_bits, length+1); + swap_format(orig_bits+1, temp, crc_len, length); + print_bits("atad: ", temp, data_len); + printf("\n"); + print_bits("hcb: ", temp+data_len, crc_len); + printf("\n"); + test(&bch, "ATAD+HCB: ", temp, length); + + // DATA + BCH + bytes_to_bits(bytes, orig_bits, length+1); + rotate_bits(orig_bits+1, temp, length); + print_bits("data: ", temp, data_len); + printf("\n"); + print_bits("bch: ", temp+data_len, crc_len); + printf("\n"); + test(&bch, "DATA+BCH: ", temp, length); + + // BCH+DATA + int swap[length]; + bytes_to_bits(bytes, orig_bits, length+1); + rotate_bits(orig_bits+1, temp, length); + // now DATA+BCH + swap_format(temp, swap, data_len, length); + // now BCH + DATA + print_bits("data: ", swap + crc_len, data_len); + printf("\n"); + print_bits("bch: ", swap, crc_len); + printf("\n"); + test(&bch, "BCH+DATA: ", swap, length); + + int rot[length]; + // DATA + HCB + bytes_to_bits(bytes, orig_bits, length+1); + memcpy(rot+data_len, orig_bits + 1, crc_len * sizeof(int)); + rotate_bits(orig_bits+1+crc_len, temp, data_len); + memcpy(rot, temp, data_len * sizeof(int)); + print_bits("data: ", rot, data_len); + printf("\n"); + print_bits("hcb: ", rot+data_len, crc_len); + printf("\n"); + // Now DATA+HCB + test(&bch, "DATA+HCB: ", rot, length); + + // ATAD+BCH + bytes_to_bits(bytes, orig_bits, length+1); + // h+a + memcpy(rot, orig_bits+1+crc_len, data_len * sizeof(int)); + rotate_bits(orig_bits+1, temp, crc_len); + memcpy(rot+data_len, temp, crc_len * sizeof(int)); + // Now ATAD+BCH + print_bits("atad: ", rot, data_len); + printf("\n"); + print_bits("bch: ", rot+data_len, crc_len); + printf("\n"); + test(&bch, "ATAD+BCH: ", rot, length); + + // HCB+DATA + bytes_to_bits(bytes, orig_bits, length+1); + memcpy(rot, orig_bits+1, crc_len * sizeof(int)); + rotate_bits(orig_bits+1+crc_len, temp, data_len); + memcpy(rot+crc_len, temp, data_len * sizeof(int)); + print_bits("data: ", rot+crc_len, data_len); + printf("\n"); + print_bits("hcb: ", rot, crc_len); + printf("\n"); + // Now HCB+DATA + test(&bch, "HCB+DATA: ", rot, length); + + // BCH+ATAD + bytes_to_bits(bytes, orig_bits, length+1); + memcpy(rot+crc_len, orig_bits+1+crc_len, data_len * sizeof(int)); + rotate_bits(orig_bits+1, temp, crc_len); + memcpy(rot, temp, crc_len * sizeof(int)); + print_bits("atad: ", rot + crc_len, data_len); + printf("\n"); + print_bits("bch: ", rot, crc_len); + printf("\n"); + // Now BCH+ATAD + test(&bch, "BCH+ATAD: ", rot, length); + } +} diff --git a/src/direwolf.c b/src/direwolf.c index 579eb4a..589307c 100644 --- a/src/direwolf.c +++ b/src/direwolf.c @@ -768,7 +768,6 @@ int main (int argc, char *argv[]) audio_config.achan[0].baud = 1200; audio_config.achan[0].mark_freq = 1200; audio_config.achan[0].space_freq = 1800; - // strlcpy (audio_config.achan[0].profiles, "D", sizeof(audio_config.achan[0].profiles)); } else { audio_config.achan[0].modem_type = MODEM_SCRAMBLE; diff --git a/src/eotd_defs.h b/src/eotd_defs.h new file mode 100644 index 0000000..1ed2622 --- /dev/null +++ b/src/eotd_defs.h @@ -0,0 +1,14 @@ +#ifndef __EOTD_DEFS +#define __EOTD_DEFS +#define EOTD_LENGTH 8 + +#define EOTD_PREAMBLE_AND_BARKER_CODE 0x48eaaaaa00000000ULL +#define EOTD_PREAMBLE_MASK 0xffffffff00000000ULL + +#define HOTD_PREAMBLE_AND_BARKER_CODE 0x9488f1aa00000000ULL +#define HOTD_PREAMBLE_MASK 0xffffffff00000000ULL + +#define EOTD_TYPE_F2R 'F' +#define EOTD_TYPE_R2F 'R' + +#endif diff --git a/src/hdlc_rec.c b/src/hdlc_rec.c index 4d47b10..6c2b164 100644 --- a/src/hdlc_rec.c +++ b/src/hdlc_rec.c @@ -55,10 +55,6 @@ //#define DEBUG3 1 /* monitor the data detect signal. */ -#undef EOTD_DEBUG - - - /* * Minimum & maximum sizes of an AX.25 frame including the 2 octet FCS. */ @@ -418,6 +414,9 @@ int is_eotd_valid(struct hdlc_state_s *H) { The apply_bch funtion requires the packet in int[63] format, with the bits arranged in either BCH+ATAD or ATAD+BCH format. Very odd. We'll use the first one. + + The HCB for R2F packets must be XOR-ed with 0EED4 - since we have a leading dummy bit, + we XOR with 0EED4 >> 1. */ static uint8_t r2f_mask[] = {0x07, 0x76, 0xa0 }; static bch_t *bch_r2f = NULL; @@ -459,11 +458,9 @@ int is_eotd_valid(struct hdlc_state_s *H) { } else { temp_bch = bch_r2f; // The HCB needs to be XOR'ed with a special constant. -print_bytes("IN BYTES: ", H->frame_buf, H->frame_len);printf("\n"); for (int i = 0; i < sizeof(r2f_mask); i++) { H->frame_buf[i] ^= r2f_mask[i]; } -print_bytes("XOR BYTES: ", H->frame_buf, H->frame_len);printf("\n"); } int crc_len = temp_bch->n - temp_bch->k; @@ -473,17 +470,13 @@ print_bytes("XOR BYTES: ", H->frame_buf, H->frame_len);printf("\n"); // +1 is to skip the dummy/parity bit. rotate_bits(bits + 1 , temp_bits, crc_len); memcpy(bits + 1, temp_bits, crc_len * sizeof(int)); -print_bits("BCH+ATAD : ", bits, 64);printf("\n"); // Note: bits are changed in-place. int corrected = apply_bch(temp_bch, bits + 1); -printf("Corrected %d\n", corrected); // Put back in HCB+ATAD format rotate_bits(bits + 1, temp_bits, crc_len); memcpy(bits + 1, temp_bits, crc_len * sizeof(int)); -print_bits("COR BITS: ", bits, 64);printf("\n"); bits_to_bytes(bits, H->frame_buf, 64); -print_bytes("COR BYTES: ", H->frame_buf, H->frame_len);printf("\n"); return corrected; } diff --git a/src/mkpkts.sh b/src/mkpkts.sh deleted file mode 100644 index 38679b9..0000000 --- a/src/mkpkts.sh +++ /dev/null @@ -1,4 +0,0 @@ -DATA_DIR=../build -cut -c22-41,54-56,59-61,64-66,69-71,74-76,79-81,84-86,89-90 $DATA_DIR/all.out >$DATA_DIR/all.cut -cut -d' ' -f5- $DATA_DIR/all.cut > $DATA_DIR/all.pkts -./pkttest < $DATA_DIR/all.pkts > $DATA_DIR/all.good diff --git a/src/pkttest.c b/src/pkttest.c index 7ab839b..c15885e 100644 --- a/src/pkttest.c +++ b/src/pkttest.c @@ -1,25 +1,60 @@ #include +#include #include "bch.h" +#include "eotd.h" +#include "eotd_defs.h" + +void dump(uint8_t *bytes, char type) { + unsigned char eotd[9]; + for (int i = 0; i < 8; i++) { + eotd[i] = bytes[i] & 0xff; + } + eotd[8] = type; + // Slice packet + char buffer[512]; + eotd_to_text(eotd, 9, buffer, sizeof(buffer)); + printf("%s\n", buffer); +}; + +void rotate_bytes(uint8_t *src, uint8_t *dest, int count) { + for (int i = 0; i < count; i++) { + dest[count - i - 1] = rotate_byte(src[i]); + } +} int main(int argc, char **argv) { bch_t bch; - int bytes[8]; + uint8_t bytes[8]; int bits[63]; + int m, length, t; + int count = 0; + int rev = 0; + char type = EOTD_TYPE_R2F; - init_bch(&bch, 6, 63, 3); -#ifdef ARGS - if (argc != 9) { - fprintf(stderr, "Expecting 8 arguments.\n"); + + if (argc < 5) { + fprintf(stderr, "Expecting 4+ arguments - m, length, t, type (F or R) and optionally rev to reverse the input bytes.\n"); return -1; } - for (int i = 0; i < 8; i++) { - sscanf(argv[i + 1], "%x", bytes + i); + sscanf(argv[1], "%d", &m); + sscanf(argv[2], "%d", &length); + sscanf(argv[3], "%d", &t); + sscanf(argv[4], "%c", &type); + + if (argc > 5) { + if (strcasecmp(argv[5], "rev") == 0) { + rev = 1; + } } -#else + + init_bch(&bch, m, length, t); + while (1) { for (int i = 0; i < 8; i++) { - int status = scanf("%x ", bytes + i); + int t; + int status = scanf("%x ", &t); + bytes[i] = t; if (status == EOF) { return 0; } @@ -28,41 +63,15 @@ int main(int argc, char **argv) { fprintf(stderr, "Error: %d", status); } } -#endif - // UNEEDED - // swap_format(bits, 45, 63); - bytes_to_bits(bytes, bits, 63); - int corrected = apply_bch(&bch, bits); - if (corrected >= 0) { -#ifdef DEBUG - printf("%d corrected\n", corrected); - for (int i = 0; i < 8; i++) { - printf("%02x ", bytes[i]); + if (rev) { + uint8_t temp[8]; + rotate_bytes(bytes, temp, 8); + memcpy(bytes, temp, 8); } - printf("\n"); -#endif - bits_to_bytes(bits, bytes, 63); - for (int i = 0; i < 8; i++) { - printf("%02x ", bytes[i]); - } - // Slice packet - printf("chain=%1x,",(bytes[0] >> 6) & 0x03); - printf("devst=%1x,",(bytes[0] >> 4) & 0x03); - printf("msgid=%1x,",(bytes[0] >> 1) & 0x07); - printf("uaddr=%03x,",((bytes[0] & 0x01) << 16) | (bytes[1] << 8) | (bytes[2])); - printf("bpres=%d,",(bytes[3] >> 1) & 0x07f); - printf("dbit1=%02x,",((bytes[3] & 0x01) << 7) | ((bytes[4] >> 1) & 0x7f)); - printf("confm=%x,",(bytes[5] >> 7) & 0x01); - printf("dbit2=%x,",(bytes[5] >> 6) & 0x01); - printf("motdt=%x,",(bytes[5] >> 5) & 0x01); - printf("ltbat=%x,",(bytes[5] >> 4) & 0x01); - printf("ltsta=%x",(bytes[5] >> 3) & 0x01); - printf("\n"); + printf("%04d,", count++); + dump(bytes, type); } -#ifndef ARGS - } -#endif return 0; }