Added support for gen_packets.

**** NOTE THAN THE MARK AND SPACE FREQUENCIES ARE BACKWARDS in gen_tone.c.

Lines 228-229 correctly set f1_change_per_sample to the MARK frequency and
f2_change_per_sample the space frequency.

Line 383, however, sends MARK on 0 and SPACE on 1:

tone_phase[chan] += dat ? f2_change_per_sample[chan] : f1_change_per_sample[chan];

As such, you have to generate packets like this:

	gen_packets -e R -m 1800 -s 1200 -o test.wav eotd.data

EOTD input to the program consists of lines of 8 byte packets in HCB+ATAD
format; i.e. the format that direwolf appends to the decoded packet.

Ex: 81 b0 32 fb 31 23 73 8f

A new option has been added to atest: -e type. That enables EOTD generation and
the 'type' signifies 'R'ear to front or 'F'ront to rear decoding.

Using "atest -B EOTD test.wav" the above packet decodes to:

DECODED[1] 0:00.123 EOTD audio level = 49(30/31)
[0] EOTD>APDW16:{DRREAR>FRONT:ts=2022-04-07T10:02:00.350,chain=ONLY,block=BASIC,devbat=OK,msgid=ONEWAY,unit_addr=18151,brake_status=GO(49 psig),disc_bits=f6,valve=OPERATIONAL,confirm=UPDATE,disc_bit_1=1,motion=STOPPED/NOT_MONITORED,light_batt=OK/NOT_MONITORED,light=ON,hex=81 b0 32 fb 31 23 73 8f
This commit is contained in:
David E. Tiller 2022-04-07 10:03:49 -04:00
parent 971383adfa
commit 2ea1a1892f
6 changed files with 149 additions and 7 deletions

View File

@ -278,6 +278,7 @@ list(APPEND gen_packets_SOURCES
dtmf.c
textcolor.c
dsp.c
eotd_send.c
)
add_executable(gen_packets

View File

@ -63,7 +63,7 @@ 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");
fprintf(stderr, "Enter HCB+ATAD _WITH_ the parity bit intact and XOR already applied.\n");
while (1) {
for (int i = 0; i < 8; i++) {
int temp;

102
src/eotd_send.c Normal file
View File

@ -0,0 +1,102 @@
#include "direwolf.h"
#include <stdio.h>
#include "eotd_send.h"
#include "audio.h"
#include "gen_tone.h"
#include "eotd_defs.h"
#define EOTD_SILENCE_SAMPLES 1000
//#define EOTD_SEND_DEBUG
static int eotd_fs[] = {1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0};
static int hotd_fs[] = {1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1 };
void my_tone_gen_put_bit (int chan, int bit) {
#ifdef EOTD_SEND_DEBUG
printf("mytone bit %d\n", bit);
#endif
tone_gen_put_bit (chan, bit);
}
void my_gen_tone_put_sample (int chan, int a, int sam) {
#ifdef EOTD_SEND_DEBUG
printf("mysilence sample %d\n", sam);
#endif
gen_tone_put_sample (chan, a, sam);
}
void send_preamble(int chan, char type) {
int bit = 0;
int preamble_count;
int fs_count;
int *fs;
if (type == EOTD_TYPE_R2F) {
bit = 0;
preamble_count = 69;
fs_count = sizeof(eotd_fs) / sizeof(int);
fs = eotd_fs;
} else {
preamble_count = 456;
fs_count = sizeof(hotd_fs) / sizeof(int);
fs = hotd_fs;
}
for (int i = 0; i < preamble_count; i++) {
my_tone_gen_put_bit (chan, bit);
bit ^= 1;
}
#ifdef EOTD_SEND_DEBUG
printf("end-of-preamble\n");
#endif
// send FS
for (int i = 0; i < fs_count; i++) {
my_tone_gen_put_bit (chan, fs[i]);
}
#ifdef EOTD_SEND_DEBUG
printf("end-of-fs\n");
#endif
}
void send_silence(int chan) {
int a = ACHAN2ADEV(chan);
for (int i = 0; i < EOTD_SILENCE_SAMPLES; i++) {
my_gen_tone_put_sample (chan, a, 0);
}
}
int eotd_send_block (int chan, char *str, char type) {
unsigned int b[EOTD_LENGTH];
int status = sscanf(str, "%x %x %x %x %x %x %x %x", b, b+1, b+2, b+3, b+4, b+5, b+6, b+7);
if (status != EOTD_LENGTH) {
fprintf(stderr, "Error: expected 8, read %d", status);
return -1;
}
send_preamble(chan, type);
for (int i = 7; i >= 0; i--) {
int byte = b[i]; // Copy this non-destructively so we can repeat it later, per spec.
for (int j = 0; j < 8; j++) {
int bit = byte & 0x01;
byte >>= 1;
my_tone_gen_put_bit (chan, bit);
}
}
#ifdef EOTD_SEND_DEBUG
printf("end-of-data\n");
#endif
send_silence(chan);
return 0;
}

6
src/eotd_send.h Normal file
View File

@ -0,0 +1,6 @@
#ifndef __EOTD_SEND_H
#define __EOTD_SEND_H
int eotd_send_block (int chan, char *str, char type);
#endif

View File

@ -76,6 +76,8 @@
#include "morse.h"
#include "dtmf.h"
#include "fx25.h"
#include "eotd_send.h"
#include "eotd_defs.h"
/* Own random number generator so we can get */
@ -97,6 +99,10 @@ static int audio_file_close (void);
static int g_add_noise = 0;
static float g_noise_level = 0;
static int g_morse_wpm = 0; /* Send morse code at this speed. */
static int g_eotd_type = 0;
static int byte_count; /* Number of data bytes written to file. */
/* Will be written to header when file is closed. */
static struct audio_s modem;
@ -115,6 +121,11 @@ static void send_packet (char *str)
morse_send (0, str, g_morse_wpm, 100, 100);
}
else if (g_eotd_type > 0) {
for (c=0; c<modem.adev[0].num_channels; c++) {
eotd_send_block (c, str, g_eotd_type);
}
}
else {
pp = ax25_from_text (str, 1);
if (pp == NULL) {
@ -227,7 +238,7 @@ int main(int argc, char **argv)
/* ':' following option character means arg is required. */
c = getopt_long(argc, argv, "gjJm:s:a:b:B:r:n:N:o:z:82M:X:",
c = getopt_long(argc, argv, "gjJm:s:a:b:B:r:n:N:o:z:82M:X:e:",
long_options, &option_index);
if (c == -1)
break;
@ -462,6 +473,15 @@ int main(int argc, char **argv)
usage (argv);
break;
case 'e':
g_eotd_type = optarg[0];
if (g_eotd_type != EOTD_TYPE_F2R && g_eotd_type != EOTD_TYPE_R2F) {
text_color_set(DW_COLOR_ERROR);
dw_printf ("EOTD type must be %c or %c\n", EOTD_TYPE_F2R, EOTD_TYPE_R2F);
exit(EXIT_FAILURE);
}
break;
default:
/* Should not be here. */
@ -757,9 +777,6 @@ static FILE *out_fp = NULL;
static struct wav_header header;
static int byte_count; /* Number of data bytes written to file. */
/* Will be written to header when file is closed. */
static int audio_file_open (char *fname, struct audio_s *pa)
{

View File

@ -50,6 +50,7 @@
#include "bch.h"
#include "eotd_defs.h"
//#define EOTD_DEBUG
//#define TEST 1 /* Define for unit testing. */
@ -473,11 +474,20 @@ int is_eotd_valid(struct hdlc_state_s *H) {
// Note: bits are changed in-place.
int corrected = apply_bch(temp_bch, bits + 1);
// Put back in HCB+ATAD format
rotate_bits(bits + 1, temp_bits, crc_len);
memcpy(bits + 1, temp_bits, crc_len * sizeof(int));
bits_to_bytes(bits, H->frame_buf, 64);
// Put the XOR-ed bits back.
if (H->eotd_type == EOTD_TYPE_R2F) {
// The HCB needs to be XOR'ed with a special constant.
for (int i = 0; i < sizeof(r2f_mask); i++) {
H->frame_buf[i] ^= r2f_mask[i];
}
}
return corrected;
}
@ -515,7 +525,8 @@ static void eotd_rec_bit (int chan, int subchan, int slice, int raw, int future_
H = &hdlc_state[chan][subchan][slice];
#ifdef EOTD_DEBUG
dw_printf("chan=%d subchan=%d slice=%d raw=%d\n", chan, subchan, slice, raw);
// dw_printf("chan=%d subchan=%d slice=%d raw=%d\n", chan, subchan, slice, raw);
dw_printf("%d ", raw);
#endif
//dw_printf ("slice %d = %d\n", slice, raw);
@ -565,7 +576,12 @@ for (int ii=0; ii < EOTD_LENGTH; ii++) {dw_printf("%02x ", H->frame_buf[ii]); }
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);
}
} else {
#ifdef EOTD_DEBUG
print_bytes("BCH failed for packet (type byte appended) ", H->frame_buf, H->frame_len);
#endif
}
H->eotd_acc = 0;
H->eotd_gathering = 0;