Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature - add end-of-train and head-of-train message decoding #387

Open
wants to merge 40 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
709f229
Initial checkin for EOTD support.
dtiller Mar 18, 2022
c491655
More framework.
dtiller Mar 19, 2022
7bde86f
#ifdef'ed debugging.
dtiller Mar 19, 2022
507f04e
Added date tag for debugging.
dtiller Mar 20, 2022
3b17d45
#ifdef'ed a lot of stuff.
dtiller Mar 20, 2022
26ac27b
Added beginnings of BCH processing.
dtiller Mar 20, 2022
d898d1b
Added derived code to calc/apply BCH codes.
dtiller Mar 21, 2022
be0f9c4
debug and comment changes.
dtiller Mar 21, 2022
475f951
Put original program back for reference. Added fixed codes.
dtiller Mar 21, 2022
53d5b2b
checked return status and found that we _can_ use 'forward' packets (…
dtiller Mar 22, 2022
a707fc8
Cleaned up output.
dtiller Mar 22, 2022
5be9e44
Closer. Lots of ACCA data to chew on.
dtiller Mar 22, 2022
742dfb4
Last checkin before trying dev branch.
dtiller Mar 29, 2022
98b8949
Slight fixes before switching to uint64_t and MSB processing.
dtiller Mar 30, 2022
7d58e40
New branch for 64 bit processing. Probably not needed.
dtiller Mar 30, 2022
2cf23db
Default buffer was _way_ too small.
dtiller Apr 2, 2022
1fb18ed
changes for 64 bit uint. Not sure I like them.
dtiller Apr 2, 2022
07209b5
First fully-working BCH code.
dtiller Apr 4, 2022
fa49b6a
Starting to look like a real project.
dtiller Apr 4, 2022
7646fc5
Shortened timestamp.
dtiller Apr 4, 2022
9871ba8
Added f2r decoder.
dtiller Apr 5, 2022
72708ec
Added mS to time.
dtiller Apr 5, 2022
09d2d5f
Added ARM logic.
dtiller Apr 5, 2022
a12f9e0
Added option block processing.
dtiller Apr 5, 2022
b17d987
Merge branch 'wb2osz:master' into feat-EOTD-master
dtiller Apr 5, 2022
27c97e3
Debian needs stdint.h in more places.
dtiller Apr 6, 2022
16d102e
Cleanup and changes to fix DTMF message.
dtiller Apr 6, 2022
f20fcd0
Debian is _picky_. Fixed a few warnings.
dtiller Apr 6, 2022
971383a
Deleted unneeded file.
dtiller Apr 6, 2022
2ea1a18
Added support for gen_packets.
dtiller Apr 7, 2022
89bc82b
Moved unit_addr closer to the beginning so it's always in the same pl…
dtiller Apr 8, 2022
1d7a4b9
Changed FRONT>REAR to dir=f2r, etc for consistency.
dtiller Apr 8, 2022
c4ccbdc
Added msg re: BCH code and added protective #ifndefs.
dtiller Apr 9, 2022
52298c1
Made -e flag imply the right (wrong\!) mark and space freqs and baud …
dtiller Apr 9, 2022
67d5900
Removed unused variable.
dtiller Apr 9, 2022
2048747
Added XOR for t=3 packets, added more verbiage, removed variable-leng…
dtiller Apr 9, 2022
6c8cf2a
Added pkttest and bchapply to the CMake system.
dtiller Apr 9, 2022
52d3d84
Deleted spurious executable.
dtiller Apr 9, 2022
b17f6f0
Fixed CMake issue and missing inttypes.h
dtiller Apr 29, 2022
c8d8977
Fixed typo.
dtiller May 14, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
First fully-working BCH code.
  • Loading branch information
dtiller committed Apr 4, 2022
commit 07209b5f224fc8864c7efeea276784571a822f9a
2 changes: 2 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ list(APPEND direwolf_SOURCES
dwgpsd.c
mheard.c
eotd.c
bch.c
)

if(LINUX)
Expand Down Expand Up @@ -319,6 +320,7 @@ list(APPEND atest_SOURCES
tt_text.c
textcolor.c
eotd.c
bch.c
)

if(WIN32 OR CYGWIN)
Expand Down
147 changes: 9 additions & 138 deletions src/bch.c
Original file line number Diff line number Diff line change
Expand Up @@ -518,7 +518,7 @@ int apply_bch(const bch_t *bch, int *recd)
}

/* LEFT justified in hex */
void bytes_to_bits(const int *bytes, int *bit_dest, int num_bits) {
void bytes_to_bits(const uint8_t *bytes, int *bit_dest, int num_bits) {
for (int i = 0; i < num_bits; i++) {
int index = i / 8;
int bit_pos = 7 - (i % 8);
Expand All @@ -527,7 +527,7 @@ void bytes_to_bits(const int *bytes, int *bit_dest, int num_bits) {
}
}

void bits_to_bytes(const int *bits, int *byte_dest, int num_bits) {
void bits_to_bytes(const int *bits, uint8_t *byte_dest, int num_bits) {

int index;

Expand All @@ -540,8 +540,6 @@ void bits_to_bytes(const int *bits, int *byte_dest, int num_bits) {
byte_dest[index] <<= 1;
byte_dest[index] |= (bits[i] & 0x01);
}

byte_dest[index] <<= 8 - (num_bits % 8);
}

void swap_format(const int *bits, int *dest, int cutoff, int num_bits) {
Expand All @@ -555,8 +553,8 @@ void swap_format(const int *bits, int *dest, int cutoff, int num_bits) {
}
}

int rotate_byte(int x) {
int y = 0;
uint8_t rotate_byte(uint8_t x) {
uint8_t y = 0;

for (int i = 0; i < 8; i++) {
y <<= 1;
Expand All @@ -583,143 +581,16 @@ void dump_bch(const bch_t *bch) {
printf("m: %d length: %d t: %d n: %d k: %d\n", bch->m, bch->length, bch->t, bch->n, bch->k);
}

void print_array(const char *msg, const char *format, const int *bytes, int num_bytes) {
void print_bytes(const char *msg, const uint8_t *bytes, int num_bytes) {
printf("%s", msg);
for (int i = 0; i < num_bytes; i++) {
printf(format, bytes[i]);
printf("%02x ", bytes[i]);
}
}

void print_bytes(const char *msg, const int *bytes, int num_bytes) {
print_array(msg, "%02x ", bytes, num_bytes);
}

void print_bits(const char *msg, const int *bits, int num_bits) {
print_array(msg, "%d ", bits, num_bits);
}

#undef MAIN
#undef TEST_BYTES_TO_BITS
#define TEST_SWAP
#ifdef MAIN
int main()
{
int test[][8] = {
/* 0 errors */ { 0xb2, 0x17, 0xa2, 0xb9, 0x53, 0xdd, 0xc5, 0x52 }, /* perfect random test */
{ 0xf0, 0x5a, 0x6a, 0x6a, 0x01, 0x63, 0x33, 0xd0 }, /* g001-cut-lenthened_457.938M.wav */
{ 0xf0, 0x81, 0x52, 0x6b, 0x71, 0xa5, 0x63, 0x08 }, /* 1st in eotd_received_data */
/* 3 errors */ { 0xf0, 0x85, 0x50, 0x6a, 0x01, 0xe5, 0x6e, 0x84 }, /* 2nd in eotd_received_data - 3 bad bits */
/* 0 errors */ { 0xf0, 0x85, 0x50, 0x6a, 0x01, 0xe5, 0x06, 0x84 }, /* 2nd, but with the bits fixed */
/* 3 errors */ { 0xf0, 0x85, 0x59, 0x5a, 0x01, 0xe5, 0x6e, 0x84 }, /* 3rd - 3 bad bits */
/* 0 errors */ { 0xb0, 0x85, 0x59, 0x5a, 0x11, 0xe5, 0x6f, 0x84 }, /* 3rd fixed */
{ 0xf1, 0x34, 0x50, 0x1a, 0x01, 0xe5, 0x66, 0xfe }, /* 4th */
{ 0xf0, 0xeb, 0x10, 0xea, 0x01, 0x6e, 0x54, 0x1c }, /* 5th */
{ 0xf0, 0xea, 0x5c, 0xea, 0x01, 0x6e, 0x55, 0x0e }, /* 6th */
{ 0xe0, 0x21, 0x10, 0x1a, 0x01, 0x32, 0xbc, 0xe4 }, /* Sun Mar 20 05:41:00 2022 */
{ 0xf0, 0x42, 0x50, 0x5b, 0xcf, 0xd5, 0x64, 0xe4 }, /* Sun Mar 20 12:58:43 2022 */
{ 0xf0, 0x8c, 0x10, 0xaa, 0x01, 0x73, 0x7b, 0x1a }, /* Sun Mar 20 13:35:48 2022 */
{ 0xf0, 0x8c, 0x10, 0xb1, 0xc0, 0xe0, 0x90, 0x64 }, /* Sun Mar 20 13:37:05 2022 */
/* 3 errors */ { 0xf0, 0x8c, 0x10, 0x6a, 0x01, 0x64, 0x7a, 0xe8 }, /* Sun Mar 20 13:37:48 2022 - 3 bad bits */
/* 0 errors */ { 0x50, 0x8c, 0x12, 0x6a, 0x01, 0x64, 0x7a, 0xe8 }, /* Sun Mar 20 13:37:48 2022 with bits fixed */
};

int bits[63];
int temp[8];
bch_t bch;

init_bch(&bch, 6, 63, 3);

for (int count = 0; count < sizeof(test) / sizeof(*test); count++) {
bytes_to_bits(test[count], bits, 63);

printf("--------------------------\nORIG pkt [%d] ", count);
for (int i = 0; i < 8; i++) {
printf("%02x ", test[count][i]);
}
printf("\n");

#ifdef TEST_BYTES_TO_BITS

printf("ORIG pkt[%d] bits\n", count);
for (int i = 0; i < 63; i++) {
printf("%d ", bits[i]);
}
printf("\n");

bits_to_bytes(bits, temp, 63);
printf("bits_to_bytes pkt [%d]\n", count);
for (int i = 0; i < 8; i++) {
printf("%02x ", temp[i]);
}
printf("\n");

#endif

#ifdef TEST_GENERATE
int bch_code[18];
generate_bch(&bch, bits, bch_code);
printf("generated BCH\n");
for (int i = 0; i < 18; i++) {
printf("%d ", bch_code[i]);
}
printf("\n");
#endif

#ifdef TEST_SWAP
printf("orig: ");
for (int i = 0; i < 63; i++) {
printf("%d ", bits[i]);
}
printf("\n");

swap_format(bits, 45, 63);

printf("rev: ");
for (int i = 0; i < 63; i++) {
printf("%d ", bits[i]);
}
printf("\n");
#endif
#ifdef TEST_APPLY
int recv[63];

for (int i = 0; i < 63; i++) {
recv[i] = bits[i];
}
/*
printf("rearranged packet [%d]: ", count);
for (int i = 0; i < 63; i++) {
printf("%d ", recv[i]);
}
printf("\n");

bits_to_bytes(recv, temp, 63);

printf("original [%d] bytes: ", count);
for (int i = 0; i < 8; i++) {
printf("%02x ", temp[i]);
}
printf("\n");
*/
int corrected = apply_bch(&bch, recv);

if (corrected >= 0) {
/*
printf("corrected [%d] packet: ", corrected);
for (int i = 0; i < 63; i++) {
printf("%d ", recv[i]);
}
printf("\n");
*/
bits_to_bytes(recv, temp, 63);

printf("corrected [%d] bytes: ", corrected);
for (int i = 0; i < 8; i++) {
printf("%02x ", temp[i]);
}
printf("\n");
}
#endif
printf("%s", msg);
for (int i = 0; i < num_bits; i++) {
printf("%d ", bits[i]);
}
}
#endif
9 changes: 5 additions & 4 deletions src/bch.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#ifndef __BCH_H
#define __BCH_H
#include <stdlib.h>

struct bch {
int m; // 2^m - 1 is max length, n
Expand All @@ -21,17 +22,17 @@ void generate_bch(bch_t *bch, const int *data, int *bb);

int apply_bch(const bch_t *bch, int *recd);

void bytes_to_bits(const int *bytes, int *bit_dest, int num_bits);
void bytes_to_bits(const uint8_t *bytes, int *bit_dest, int num_bits);

void bits_to_bytes(const int *bits, int *byte_dest, int num_bits);
void bits_to_bytes(const int *bits, uint8_t *byte_dest, int num_bits);

void swap_format(const int *bits, int *dest, int cutoff, int num_bits);

int rotate_byte(int x);
uint8_t rotate_byte(uint8_t x);

void rotate_bits(const int *in, int *out, int num_bits);

void print_bytes(const char *msg, const int *bytes, int num_bytes);
void print_bytes(const char *msg, const uint8_t *bytes, int num_bytes);

void print_bits(const char *msg, const int *bits, int num_bits);

Expand Down
8 changes: 6 additions & 2 deletions src/eotd.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
#include "eotd_defs.h"
#include "eotd.h"

#define EOTD_RAW
#undef EOTD_RAW
#define EOTD_TIMESTAMP
#define EOTD_APPEND_HEX

Expand Down Expand Up @@ -283,7 +283,11 @@ void eotd_to_text (unsigned char *eotd, int eotd_len, char *text, int text_size)
add_comma(text, text_size);
snprintf(hex, sizeof(hex), "%llx", pkt);
strlcat(text, "hex=", text_size);
strlcat(text, hex, text_size);
for (int i = 56; i >= 0; i -= 8) {
sprintf(hex, "%02x ", (unsigned char) (pkt >> i) & 0xff);
strlcat(text, hex, text_size);
}
text[strlen(text) - 1] = '\0'; // zap trailing space
#endif
#else
char temp[8];
Expand Down
92 changes: 87 additions & 5 deletions src/hdlc_rec.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
#include <assert.h>
#include <string.h>
#include <stdint.h> // uint64_t
#include <stdlib.h>

//#include "tune.h"
#include "demod.h"
Expand All @@ -46,6 +47,7 @@
#include "demod_9600.h" /* for descramble() */
#include "ptt.h"
#include "fx25.h"
#include "bch.h"
#include "eotd_defs.h"


Expand Down Expand Up @@ -233,7 +235,6 @@ static int my_rand (void) {
static void eas_rec_bit (int chan, int subchan, int slice, int raw, int future_use)
{
struct hdlc_state_s *H;

/*
* Different state information for each channel / subchannel / slice.
*/
Expand Down Expand Up @@ -408,6 +409,85 @@ a good modem here and providing a result when it is received.

*/


int is_eotd_valid(struct hdlc_state_s *H) {
/*
The data as received in the frame buffer is in HCB+ATAD format; that is, the first
(leftmost) bit is the dummy bit or odd parity bit (which is the last bit transmitted)
followed by the BCH code (LSB first, so HCB) followed by the DATA, LSB first (ATAD).

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.
*/
static uint8_t r2f_mask[] = {0x07, 0x76, 0xa0 };
static bch_t *bch_r2f = NULL;
static bch_t *bch_f2r = NULL;

int bits[64];

assert(H != NULL);
// +1 for 'type' byte at end
assert(H->frame_len == EOTD_LENGTH + 1);

if(bch_r2f == NULL) {
bch_r2f = malloc(sizeof(bch_t));
int status = init_bch(bch_r2f, 6, 63, 3);
if (status != 0) {
fprintf(stderr, "BCH_R2F initialization failed: %d", status);
free(bch_r2f);
bch_r2f = NULL;
return status;
}
}

if(bch_f2r == NULL) {
bch_f2r = malloc(sizeof(bch_t));
int status = init_bch(bch_f2r, 6, 63, 6);
if (status != 0) {
fprintf(stderr, "BCH_F2R initialization failed: %d", status);
free(bch_f2r);
bch_f2r = NULL;
return status;
}
}

int temp_bits[64];
bch_t *temp_bch;

if (H->eotd_type == EOTD_TYPE_F2R) {
temp_bch = bch_f2r;
} 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;

bytes_to_bits(H->frame_buf, bits, 64);

// +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;
}

/***********************************************************************************
*
* Name: eotd_rec_bit
Expand Down Expand Up @@ -480,17 +560,19 @@ dw_printf("chan=%d subchan=%d slice=%d raw=%d\n", chan, subchan, slice, raw);
H->frame_buf[EOTD_LENGTH] = H->eotd_type;
done = 1;
#ifdef EOTD_DEBUG
for (int ii=0; ii < EOTD_MAX_LENGTH; ii++) {dw_printf("%02x ", H->frame_buf[ii]); } dw_printf("\n");
for (int ii=0; ii < EOTD_LENGTH; ii++) {dw_printf("%02x ", H->frame_buf[ii]); } dw_printf("\n");
#endif
}
}

if (done) {
#ifdef DEBUG_E
dw_printf ("frame_buf %d = %s\n", slice, H->frame_buf);
dw_printf ("frame_buf %d = %*s\n", slice, H->frame_len, H->frame_buf);
#endif
alevel_t alevel = demod_get_audio_level (chan, subchan);
multi_modem_process_rec_frame (chan, subchan, slice, H->frame_buf, H->frame_len, alevel, 0, 0);
if (is_eotd_valid(H) >= 0) {
alevel_t alevel = demod_get_audio_level (chan, subchan);
multi_modem_process_rec_frame (chan, subchan, slice, H->frame_buf, H->frame_len, alevel, 0, 0);
}

H->eotd_acc = 0;
H->eotd_gathering = 0;
Expand Down