mirror of https://github.com/wb2osz/direwolf.git
				
				
				
			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:
		
							parent
							
								
									971383adfa
								
							
						
					
					
						commit
						2ea1a1892f
					
				| 
						 | 
				
			
			@ -278,6 +278,7 @@ list(APPEND gen_packets_SOURCES
 | 
			
		|||
  dtmf.c
 | 
			
		||||
  textcolor.c
 | 
			
		||||
  dsp.c
 | 
			
		||||
  eotd_send.c
 | 
			
		||||
  )
 | 
			
		||||
 | 
			
		||||
add_executable(gen_packets
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,6 @@
 | 
			
		|||
#ifndef __EOTD_SEND_H
 | 
			
		||||
#define __EOTD_SEND_H
 | 
			
		||||
 | 
			
		||||
int eotd_send_block (int chan, char *str, char type);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -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)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue